diff options
Diffstat (limited to 'src/render/renderers/opengl/graphicshelpers')
22 files changed, 938 insertions, 9 deletions
diff --git a/src/render/renderers/opengl/graphicshelpers/graphicscontext.cpp b/src/render/renderers/opengl/graphicshelpers/graphicscontext.cpp index be8f861e3..f4bd8b871 100644 --- a/src/render/renderers/opengl/graphicshelpers/graphicscontext.cpp +++ b/src/render/renderers/opengl/graphicshelpers/graphicscontext.cpp @@ -92,6 +92,10 @@ QT_BEGIN_NAMESPACE #define GL_DRAW_FRAMEBUFFER 0x8CA9 #endif +#ifndef GL_MAX_IMAGE_UNITS +#define GL_MAX_IMAGE_UNITS 0x8F38 +#endif + namespace { QOpenGLShader::ShaderType shaderType(Qt3DRender::QShaderProgram::ShaderType type) @@ -125,6 +129,7 @@ GraphicsContext::GraphicsContext() : m_initialized(false) , m_supportsVAO(false) , m_maxTextureUnits(0) + , m_maxImageUnits(0) , m_defaultFBO(0) , m_gl(nullptr) , m_glHelper(nullptr) @@ -152,6 +157,8 @@ void GraphicsContext::initialize() m_gl->functions()->glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &m_maxTextureUnits); qCDebug(Backend) << "context supports" << m_maxTextureUnits << "texture units"; + m_gl->functions()->glGetIntegerv(GL_MAX_IMAGE_UNITS, &m_maxImageUnits); + qCDebug(Backend) << "context supports" << m_maxImageUnits << "image units"; if (m_gl->format().majorVersion() >= 3) { m_supportsVAO = true; @@ -335,6 +342,11 @@ void GraphicsContext::activateDrawBuffers(const AttachmentPack &attachments) } } +void GraphicsContext::rasterMode(GLenum faceMode, GLenum rasterMode) +{ + m_glHelper->rasterMode(faceMode, rasterMode); +} + /*! * \internal * Finds the highest supported opengl version and internally use the most optimized @@ -555,6 +567,11 @@ void GraphicsContext::bindFramebuffer(GLuint fbo, GraphicsHelperInterface::FBOBi m_glHelper->bindFrameBufferObject(fbo, mode); } +void GraphicsContext::depthRange(GLdouble nearValue, GLdouble farValue) +{ + m_glHelper->depthRange(nearValue, farValue); +} + void GraphicsContext::depthTest(GLenum mode) { m_glHelper->depthTest(mode); @@ -577,6 +594,19 @@ void GraphicsContext::bindFragOutputs(GLuint shader, const QHash<QString, int> & m_glHelper->bindFragDataLocation(shader, outputs); } +void GraphicsContext::bindImageTexture(GLuint imageUnit, GLuint texture, + GLint mipLevel, GLboolean layered, + GLint layer, GLenum access, GLenum format) +{ + m_glHelper->bindImageTexture(imageUnit, + texture, + mipLevel, + layered, + layer, + access, + format); +} + void GraphicsContext::bindUniformBlock(GLuint programId, GLuint uniformBlockIndex, GLuint uniformBlockBinding) { m_glHelper->bindUniformBlock(programId, uniformBlockIndex, uniformBlockBinding); @@ -652,11 +682,17 @@ GLint GraphicsContext::maxClipPlaneCount() return m_glHelper->maxClipPlaneCount(); } -GLint GraphicsContext::maxTextureUnitsCount() +GLint GraphicsContext::maxTextureUnitsCount() const { return m_maxTextureUnits; } +GLint GraphicsContext::maxImageUnitsCount() const +{ + return m_maxImageUnits; +} + + void GraphicsContext::enablePrimitiveRestart(int restartIndex) { if (m_glHelper->supportsFeature(GraphicsHelperInterface::PrimitiveRestart)) @@ -759,6 +795,7 @@ void GraphicsContext::applyUniform(const ShaderUniform &description, const Unifo break; case UniformType::Sampler: + case UniformType::Image: case UniformType::Int: applyUniformHelper<UniformType::Int>(description, v); break; diff --git a/src/render/renderers/opengl/graphicshelpers/graphicscontext_p.h b/src/render/renderers/opengl/graphicshelpers/graphicscontext_p.h index 73d1f316c..2f4df2e22 100644 --- a/src/render/renderers/opengl/graphicshelpers/graphicscontext_p.h +++ b/src/render/renderers/opengl/graphicshelpers/graphicscontext_p.h @@ -123,6 +123,7 @@ public: void bindFramebuffer(GLuint fbo, GraphicsHelperInterface::FBOBindMode mode); void bindBufferBase(GLenum target, GLuint bindingIndex, GLuint buffer); void bindFragOutputs(GLuint shader, const QHash<QString, int> &outputs); + void bindImageTexture(GLuint imageUnit, GLuint texture, GLint mipLevel, GLboolean layered, GLint layer, GLenum access, GLenum format); void bindUniformBlock(GLuint programId, GLuint uniformBlockIndex, GLuint uniformBlockBinding); void bindShaderStorageBlock(GLuint programId, GLuint shaderStorageBlockIndex, GLuint shaderStorageBlockBinding); void blendEquation(GLenum mode); @@ -134,6 +135,7 @@ public: void clearColor(const QColor &color); void clearDepthValue(float depth); void clearStencilValue(int stencil); + void depthRange(GLdouble nearValue, GLdouble farValue); void depthMask(GLenum mode); void depthTest(GLenum mode); void disableClipPlane(int clipPlane); @@ -154,7 +156,8 @@ public: void enablePrimitiveRestart(int restartIndex); void frontFace(GLenum mode); GLint maxClipPlaneCount(); - GLint maxTextureUnitsCount(); + GLint maxTextureUnitsCount() const; + GLint maxImageUnitsCount() const; void pointSize(bool programmable, GLfloat value); void readBuffer(GLenum mode); void drawBuffer(GLenum mode); @@ -166,6 +169,7 @@ public: void setVerticesPerPatch(GLint verticesPerPatch); void memoryBarrier(QMemoryBarrier::Operations barriers); void activateDrawBuffers(const AttachmentPack &attachments); + void rasterMode(GLenum faceMode, GLenum rasterMode); // Helper methods static GLint elementType(GLint type); @@ -183,6 +187,7 @@ public: bool m_initialized; bool m_supportsVAO; GLint m_maxTextureUnits; + GLint m_maxImageUnits; GLuint m_defaultFBO; QOpenGLContext *m_gl; GraphicsHelperInterface *m_glHelper; diff --git a/src/render/renderers/opengl/graphicshelpers/graphicshelperes2.cpp b/src/render/renderers/opengl/graphicshelpers/graphicshelperes2.cpp index 71540b1ad..5f77dd376 100644 --- a/src/render/renderers/opengl/graphicshelpers/graphicshelperes2.cpp +++ b/src/render/renderers/opengl/graphicshelpers/graphicshelperes2.cpp @@ -345,6 +345,13 @@ void GraphicsHelperES2::deleteSync(void *) qWarning() << "Fences are not supported by OpenGL ES 2.0 (since OpenGL ES 3.0)"; } +void GraphicsHelperES2::rasterMode(GLenum faceMode, GLenum rasterMode) +{ + Q_UNUSED(faceMode); + Q_UNUSED(rasterMode); + qWarning() << "glPolyonMode is not supported with OpenGL ES"; +} + void GraphicsHelperES2::blendEquation(GLenum mode) { m_funcs->glBlendEquation(mode); @@ -394,6 +401,11 @@ void GraphicsHelperES2::depthMask(GLenum mode) m_funcs->glDepthMask(mode); } +void GraphicsHelperES2::depthRange(GLdouble nearValue, GLdouble farValue) +{ + m_funcs->glDepthRangef(static_cast<float>(nearValue), static_cast<float>(farValue)); +} + void GraphicsHelperES2::frontFace(GLenum mode) { m_funcs->glFrontFace(mode); @@ -435,6 +447,21 @@ void GraphicsHelperES2::bindFrameBufferObject(GLuint frameBufferId, FBOBindMode m_funcs->glBindFramebuffer(GL_FRAMEBUFFER, frameBufferId); } +void GraphicsHelperES2::bindImageTexture(GLuint imageUnit, GLuint texture, + GLint mipLevel, GLboolean layered, + GLint layer, GLenum access, GLenum format) +{ + Q_UNUSED(imageUnit) + Q_UNUSED(texture) + Q_UNUSED(mipLevel) + Q_UNUSED(layered) + Q_UNUSED(layer) + Q_UNUSED(access) + Q_UNUSED(format) + qWarning() << "Shader Images are not supported by ES 2.0 (since ES 3.1)"; + +} + GLuint GraphicsHelperES2::boundFrameBufferObject() { GLint id = 0; diff --git a/src/render/renderers/opengl/graphicshelpers/graphicshelperes2_p.h b/src/render/renderers/opengl/graphicshelpers/graphicshelperes2_p.h index 8c8dd34e9..882931ad9 100644 --- a/src/render/renderers/opengl/graphicshelpers/graphicshelperes2_p.h +++ b/src/render/renderers/opengl/graphicshelpers/graphicshelperes2_p.h @@ -76,6 +76,7 @@ public: void bindFrameBufferAttachment(QOpenGLTexture *texture, const Attachment &attachment) override; void bindFrameBufferAttachment(RenderBuffer *renderBuffer, const Attachment &attachment) override; void bindFrameBufferObject(GLuint frameBufferId, FBOBindMode mode) override; + void bindImageTexture(GLuint imageUnit, GLuint texture, GLint mipLevel, GLboolean layered, GLint layer, GLenum access, GLenum format) override; void bindShaderStorageBlock(GLuint programId, GLuint shaderStorageBlockIndex, GLuint shaderStorageBlockBinding) override; void bindUniformBlock(GLuint programId, GLuint uniformBlockIndex, GLuint uniformBlockBinding) override; void blendEquation(GLenum mode) override; @@ -88,6 +89,7 @@ public: void clearBufferf(GLint drawbuffer, const QVector4D &values) override; GLuint createFrameBufferObject() override; void depthMask(GLenum mode) override; + void depthRange(GLdouble nearValue, GLdouble farValue) override; void depthTest(GLenum mode) override; void disableClipPlane(int clipPlane) override; void disablei(GLenum cap, GLuint index) override; @@ -131,6 +133,7 @@ public: void vertexAttributePointer(GLenum shaderDataType, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer) override; void readBuffer(GLenum mode) override; void drawBuffer(GLenum mode) override; + void rasterMode(GLenum faceMode, GLenum rasterMode) override; void *fenceSync() override; void clientWaitSync(void *sync, GLuint64 nanoSecTimeout) override; diff --git a/src/render/renderers/opengl/graphicshelpers/graphicshelperes3_1.cpp b/src/render/renderers/opengl/graphicshelpers/graphicshelperes3_1.cpp index a555b67ef..9c424d962 100644 --- a/src/render/renderers/opengl/graphicshelpers/graphicshelperes3_1.cpp +++ b/src/render/renderers/opengl/graphicshelpers/graphicshelperes3_1.cpp @@ -110,6 +110,42 @@ QT_BEGIN_NAMESPACE #ifndef GL_SHADER_STORAGE_BARRIER_BIT #define GL_SHADER_STORAGE_BARRIER_BIT 0x00002000 #endif +#ifndef GL_IMAGE_2D +#define GL_IMAGE_2D 0x904D +#endif +#ifndef GL_IMAGE_3D +#define GL_IMAGE_3D 0x904E +#endif +#ifndef GL_IMAGE_CUBE +#define GL_IMAGE_CUBE 0x9050 +#endif +#ifndef GL_IMAGE_2D_ARRAY +#define GL_IMAGE_2D_ARRAY 0x9053 +#endif +#ifndef GL_INT_IMAGE_2D +#define GL_INT_IMAGE_2D 0x9058 +#endif +#ifndef GL_INT_IMAGE_3D +#define GL_INT_IMAGE_3D 0x9059 +#endif +#ifndef GL_INT_IMAGE_CUBE +#define GL_INT_IMAGE_CUBE 0x905B +#endif +#ifndef GL_INT_IMAGE_2D_ARRAY +#define GL_INT_IMAGE_2D_ARRAY 0x905E +#endif +#ifndef GL_UNSIGNED_INT_IMAGE_2D +#define GL_UNSIGNED_INT_IMAGE_2D 0x9063 +#endif +#ifndef GL_UNSIGNED_INT_IMAGE_3D +#define GL_UNSIGNED_INT_IMAGE_3D 0x9064 +#endif +#ifndef GL_UNSIGNED_INT_IMAGE_CUBE +#define GL_UNSIGNED_INT_IMAGE_CUBE 0x9066 +#endif +#ifndef GL_UNSIGNED_INT_IMAGE_2D_ARRAY +#define GL_UNSIGNED_INT_IMAGE_2D_ARRAY 0x9069 +#endif namespace Qt3DRender { @@ -175,6 +211,7 @@ bool GraphicsHelperES3_1::supportsFeature(GraphicsHelperInterface::Feature featu case GraphicsHelperInterface::Compute: case GraphicsHelperInterface::ShaderStorageObject: case GraphicsHelperInterface::IndirectDrawing: + case GraphicsHelperInterface::ShaderImage: return true; default: break; @@ -182,6 +219,19 @@ bool GraphicsHelperES3_1::supportsFeature(GraphicsHelperInterface::Feature featu return GraphicsHelperES3::supportsFeature(feature); } +void GraphicsHelperES3_1::bindImageTexture(GLuint imageUnit, GLuint texture, + GLint mipLevel, GLboolean layered, + GLint layer, GLenum access, GLenum format) +{ + m_extraFuncs->glBindImageTexture(imageUnit, + texture, + mipLevel, + layered, + layer, + access, + format); +} + void GraphicsHelperES3_1::dispatchCompute(GLuint wx, GLuint wy, GLuint wz) { m_extraFuncs->glDispatchCompute(wx, wy, wz); @@ -240,6 +290,19 @@ UniformType GraphicsHelperES3_1::uniformTypeFromGLType(GLenum glType) case GL_INT_SAMPLER_2D_MULTISAMPLE: case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE: return UniformType::Sampler; + case GL_IMAGE_2D: + case GL_IMAGE_3D: + case GL_IMAGE_CUBE: + case GL_IMAGE_2D_ARRAY: + case GL_INT_IMAGE_2D: + case GL_INT_IMAGE_3D: + case GL_INT_IMAGE_CUBE: + case GL_INT_IMAGE_2D_ARRAY: + case GL_UNSIGNED_INT_IMAGE_2D: + case GL_UNSIGNED_INT_IMAGE_3D: + case GL_UNSIGNED_INT_IMAGE_CUBE: + case GL_UNSIGNED_INT_IMAGE_2D_ARRAY: + return UniformType::Image; default: return GraphicsHelperES3::uniformTypeFromGLType(glType); @@ -254,6 +317,18 @@ uint GraphicsHelperES3_1::uniformByteSize(const ShaderUniform &description) case GL_SAMPLER_2D_MULTISAMPLE: case GL_INT_SAMPLER_2D_MULTISAMPLE: case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE: + case GL_IMAGE_2D: + case GL_IMAGE_3D: + case GL_IMAGE_CUBE: + case GL_IMAGE_2D_ARRAY: + case GL_INT_IMAGE_2D: + case GL_INT_IMAGE_3D: + case GL_INT_IMAGE_CUBE: + case GL_INT_IMAGE_2D_ARRAY: + case GL_UNSIGNED_INT_IMAGE_2D: + case GL_UNSIGNED_INT_IMAGE_3D: + case GL_UNSIGNED_INT_IMAGE_CUBE: + case GL_UNSIGNED_INT_IMAGE_2D_ARRAY: rawByteSize = 4; break; diff --git a/src/render/renderers/opengl/graphicshelpers/graphicshelperes3_1_p.h b/src/render/renderers/opengl/graphicshelpers/graphicshelperes3_1_p.h index 2c130fbf5..43d9ae7dd 100644 --- a/src/render/renderers/opengl/graphicshelpers/graphicshelperes3_1_p.h +++ b/src/render/renderers/opengl/graphicshelpers/graphicshelperes3_1_p.h @@ -65,6 +65,7 @@ public: ~GraphicsHelperES3_1(); bool supportsFeature(Feature feature) const override; + void bindImageTexture(GLuint imageUnit, GLuint texture, GLint mipLevel, GLboolean layered, GLint layer, GLenum access, GLenum format) override; void dispatchCompute(GLuint wx, GLuint wy, GLuint wz) override; void memoryBarrier(QMemoryBarrier::Operations barriers) override; void drawArraysIndirect(GLenum mode,void *indirect) override; diff --git a/src/render/renderers/opengl/graphicshelpers/graphicshelperes3_2.cpp b/src/render/renderers/opengl/graphicshelpers/graphicshelperes3_2.cpp index 56da249f2..9d0988410 100644 --- a/src/render/renderers/opengl/graphicshelpers/graphicshelperes3_2.cpp +++ b/src/render/renderers/opengl/graphicshelpers/graphicshelperes3_2.cpp @@ -56,6 +56,25 @@ QT_BEGIN_NAMESPACE #define GL_PATCH_VERTICES 36466 #endif +#ifndef GL_IMAGE_BUFFER +#define GL_IMAGE_BUFFER 0x9051 +#endif +#ifndef GL_IMAGE_CUBE_MAP_ARRAY +#define GL_IMAGE_CUBE_MAP_ARRAY 0x9054 +#endif +#ifndef GL_INT_IMAGE_BUFFER +#define GL_INT_IMAGE_BUFFER 0x905C +#endif +#ifndef GL_INT_IMAGE_CUBE_MAP_ARRAY +#define GL_INT_IMAGE_CUBE_MAP_ARRAY 0x905F +#endif +#ifndef GL_UNSIGNED_INT_IMAGE_BUFFER +#define GL_UNSIGNED_INT_IMAGE_BUFFER 0x9067 +#endif +#ifndef GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY +#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY 0x906A +#endif + namespace Qt3DRender { namespace Render { @@ -130,6 +149,44 @@ void GraphicsHelperES3_2::drawElementsInstancedBaseVertexBaseInstance(GLenum pri baseVertex); } +UniformType GraphicsHelperES3_2::uniformTypeFromGLType(GLenum glType) +{ + switch (glType) { + case GL_IMAGE_BUFFER: + case GL_IMAGE_CUBE_MAP_ARRAY: + case GL_INT_IMAGE_BUFFER: + case GL_INT_IMAGE_CUBE_MAP_ARRAY: + case GL_UNSIGNED_INT_IMAGE_BUFFER: + case GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY: + return UniformType::Image; + + default: + return GraphicsHelperES3_1::uniformTypeFromGLType(glType); + } +} + +uint GraphicsHelperES3_2::uniformByteSize(const ShaderUniform &description) +{ + uint rawByteSize = 0; + + switch (description.m_type) { + case GL_IMAGE_BUFFER: + case GL_IMAGE_CUBE_MAP_ARRAY: + case GL_INT_IMAGE_BUFFER: + case GL_INT_IMAGE_CUBE_MAP_ARRAY: + case GL_UNSIGNED_INT_IMAGE_BUFFER: + case GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY: + rawByteSize = 4; + break; + + default: + rawByteSize = GraphicsHelperES3_1::uniformByteSize(description); + break; + } + + return rawByteSize; +} + } // namespace Render } // namespace Qt3DRender diff --git a/src/render/renderers/opengl/graphicshelpers/graphicshelperes3_2_p.h b/src/render/renderers/opengl/graphicshelpers/graphicshelperes3_2_p.h index 259864379..6b1a893d4 100644 --- a/src/render/renderers/opengl/graphicshelpers/graphicshelperes3_2_p.h +++ b/src/render/renderers/opengl/graphicshelpers/graphicshelperes3_2_p.h @@ -71,6 +71,9 @@ public: bool frameBufferNeedsRenderBuffer(const Attachment &attachment) override; void setVerticesPerPatch(GLint verticesPerPatch) override; void drawElementsInstancedBaseVertexBaseInstance(GLenum primitiveType, GLsizei primitiveCount, GLint indexType, void *indices, GLsizei instances, GLint baseVertex = 0, GLint baseInstance = 0) override; + UniformType uniformTypeFromGLType(GLenum glType) override; + uint uniformByteSize(const ShaderUniform &description) override; + }; } // namespace Render diff --git a/src/render/renderers/opengl/graphicshelpers/graphicshelpergl2.cpp b/src/render/renderers/opengl/graphicshelpers/graphicshelpergl2.cpp index b6f3412b2..b9ee16acb 100644 --- a/src/render/renderers/opengl/graphicshelpers/graphicshelpergl2.cpp +++ b/src/render/renderers/opengl/graphicshelpers/graphicshelpergl2.cpp @@ -299,6 +299,11 @@ void GraphicsHelperGL2::deleteSync(void *) qWarning() << "Fences are not supported by OpenGL 2.0 (since OpenGL 3.2)"; } +void GraphicsHelperGL2::rasterMode(GLenum faceMode, GLenum rasterMode) +{ + m_funcs->glPolygonMode(faceMode, rasterMode); +} + void GraphicsHelperGL2::blendEquation(GLenum mode) { m_funcs->glBlendEquation(mode); @@ -341,6 +346,11 @@ void GraphicsHelperGL2::depthMask(GLenum mode) m_funcs->glDepthMask(mode); } +void GraphicsHelperGL2::depthRange(GLdouble nearValue, GLdouble farValue) +{ + m_funcs->glDepthRange(nearValue, farValue); +} + void GraphicsHelperGL2::frontFace(GLenum mode) { m_funcs->glFrontFace(mode); @@ -480,6 +490,21 @@ void GraphicsHelperGL2::bindFrameBufferObject(GLuint frameBufferId, FBOBindMode } } +void GraphicsHelperGL2::bindImageTexture(GLuint imageUnit, GLuint texture, + GLint mipLevel, GLboolean layered, + GLint layer, GLenum access, GLenum format) +{ + Q_UNUSED(imageUnit) + Q_UNUSED(texture) + Q_UNUSED(mipLevel) + Q_UNUSED(layered) + Q_UNUSED(layer) + Q_UNUSED(access) + Q_UNUSED(format) + qWarning() << "Shader Images are not supported by OpenGL 2.0 (since OpenGL 4.2)"; + +} + GLuint GraphicsHelperGL2::boundFrameBufferObject() { GLint id = 0; diff --git a/src/render/renderers/opengl/graphicshelpers/graphicshelpergl2_p.h b/src/render/renderers/opengl/graphicshelpers/graphicshelpergl2_p.h index b142b2623..eb85b8537 100644 --- a/src/render/renderers/opengl/graphicshelpers/graphicshelpergl2_p.h +++ b/src/render/renderers/opengl/graphicshelpers/graphicshelpergl2_p.h @@ -76,6 +76,7 @@ public: void bindFrameBufferAttachment(QOpenGLTexture *texture, const Attachment &attachment) override; void bindFrameBufferAttachment(RenderBuffer *renderBuffer, const Attachment &attachment) override; void bindFrameBufferObject(GLuint frameBufferId, FBOBindMode mode) override; + void bindImageTexture(GLuint imageUnit, GLuint texture, GLint mipLevel, GLboolean layered, GLint layer, GLenum access, GLenum format) override; void bindShaderStorageBlock(GLuint programId, GLuint shaderStorageBlockIndex, GLuint shaderStorageBlockBinding) override; void bindUniformBlock(GLuint programId, GLuint uniformBlockIndex, GLuint uniformBlockBinding) override; void blendEquation(GLenum mode) override; @@ -88,6 +89,7 @@ public: void clearBufferf(GLint drawbuffer, const QVector4D &values) override; GLuint createFrameBufferObject() override; void depthMask(GLenum mode) override; + void depthRange(GLdouble nearValue, GLdouble farValue) override; void depthTest(GLenum mode) override; void disableClipPlane(int clipPlane) override; void disablei(GLenum cap, GLuint index) override; @@ -131,6 +133,7 @@ public: void vertexAttributePointer(GLenum shaderDataType, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer) override; void readBuffer(GLenum mode) override; void drawBuffer(GLenum mode) override; + void rasterMode(GLenum faceMode, GLenum rasterMode) override; void *fenceSync() override; void clientWaitSync(void *sync, GLuint64 nanoSecTimeout) override; diff --git a/src/render/renderers/opengl/graphicshelpers/graphicshelpergl3_2.cpp b/src/render/renderers/opengl/graphicshelpers/graphicshelpergl3_2.cpp index 5ff1a2ba5..f20491358 100644 --- a/src/render/renderers/opengl/graphicshelpers/graphicshelpergl3_2.cpp +++ b/src/render/renderers/opengl/graphicshelpers/graphicshelpergl3_2.cpp @@ -365,6 +365,11 @@ void GraphicsHelperGL3_2::deleteSync(void *sync) m_funcs->glDeleteSync(static_cast<GLsync>(sync)); } +void GraphicsHelperGL3_2::rasterMode(GLenum faceMode, GLenum rasterMode) +{ + m_funcs->glPolygonMode(faceMode, rasterMode); +} + void GraphicsHelperGL3_2::blendEquation(GLenum mode) { m_funcs->glBlendEquation(mode); @@ -406,6 +411,11 @@ void GraphicsHelperGL3_2::depthMask(GLenum mode) m_funcs->glDepthMask(mode); } +void GraphicsHelperGL3_2::depthRange(GLdouble nearValue, GLdouble farValue) +{ + m_funcs->glDepthRange(nearValue, farValue); +} + void GraphicsHelperGL3_2::frontFace(GLenum mode) { m_funcs->glFrontFace(mode); @@ -452,6 +462,21 @@ void GraphicsHelperGL3_2::bindFrameBufferObject(GLuint frameBufferId, FBOBindMod } } +void GraphicsHelperGL3_2::bindImageTexture(GLuint imageUnit, GLuint texture, + GLint mipLevel, GLboolean layered, + GLint layer, GLenum access, GLenum format) +{ + Q_UNUSED(imageUnit) + Q_UNUSED(texture) + Q_UNUSED(mipLevel) + Q_UNUSED(layered) + Q_UNUSED(layer) + Q_UNUSED(access) + Q_UNUSED(format) + qWarning() << "Shader Images are not supported by OpenGL 3.2 (since OpenGL 4.2)"; + +} + GLuint GraphicsHelperGL3_2::boundFrameBufferObject() { GLint id = 0; diff --git a/src/render/renderers/opengl/graphicshelpers/graphicshelpergl3_2_p.h b/src/render/renderers/opengl/graphicshelpers/graphicshelpergl3_2_p.h index 9e81345ad..914afc9ff 100644 --- a/src/render/renderers/opengl/graphicshelpers/graphicshelpergl3_2_p.h +++ b/src/render/renderers/opengl/graphicshelpers/graphicshelpergl3_2_p.h @@ -78,6 +78,7 @@ public: void bindFrameBufferAttachment(QOpenGLTexture *texture, const Attachment &attachment) override; void bindFrameBufferAttachment(RenderBuffer *renderBuffer, const Attachment &attachment) override; void bindFrameBufferObject(GLuint frameBufferId, FBOBindMode mode) override; + void bindImageTexture(GLuint imageUnit, GLuint texture, GLint mipLevel, GLboolean layered, GLint layer, GLenum access, GLenum format) override; void bindShaderStorageBlock(GLuint programId, GLuint shaderStorageBlockIndex, GLuint shaderStorageBlockBinding) override; void bindUniformBlock(GLuint programId, GLuint uniformBlockIndex, GLuint uniformBlockBinding) override; void blendEquation(GLenum mode) override; @@ -90,6 +91,7 @@ public: void clearBufferf(GLint drawbuffer, const QVector4D &values) override; GLuint createFrameBufferObject() override; void depthMask(GLenum mode) override; + void depthRange(GLdouble nearValue, GLdouble farValue) override; void depthTest(GLenum mode) override; void disableClipPlane(int clipPlane) override; void disablei(GLenum cap, GLuint index) override; @@ -133,6 +135,7 @@ public: void vertexAttributePointer(GLenum shaderDataType, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer) override; void readBuffer(GLenum mode) override; void drawBuffer(GLenum mode) override; + void rasterMode(GLenum faceMode, GLenum rasterMode) override; void *fenceSync() override; void clientWaitSync(void *sync, GLuint64 nanoSecTimeout) override; diff --git a/src/render/renderers/opengl/graphicshelpers/graphicshelpergl3_3.cpp b/src/render/renderers/opengl/graphicshelpers/graphicshelpergl3_3.cpp index 81081943d..ddffb38e2 100644 --- a/src/render/renderers/opengl/graphicshelpers/graphicshelpergl3_3.cpp +++ b/src/render/renderers/opengl/graphicshelpers/graphicshelpergl3_3.cpp @@ -361,6 +361,11 @@ void GraphicsHelperGL3_3::deleteSync(void *sync) m_funcs->glDeleteSync(static_cast<GLsync>(sync)); } +void GraphicsHelperGL3_3::rasterMode(GLenum faceMode, GLenum rasterMode) +{ + m_funcs->glPolygonMode(faceMode, rasterMode); +} + void GraphicsHelperGL3_3::blendEquation(GLenum mode) { m_funcs->glBlendEquation(mode); @@ -402,6 +407,11 @@ void GraphicsHelperGL3_3::depthMask(GLenum mode) m_funcs->glDepthMask(mode); } +void GraphicsHelperGL3_3::depthRange(GLdouble nearValue, GLdouble farValue) +{ + m_funcs->glDepthRange(nearValue, farValue); +} + void GraphicsHelperGL3_3::frontFace(GLenum mode) { m_funcs->glFrontFace(mode); @@ -546,6 +556,20 @@ void GraphicsHelperGL3_3::bindShaderStorageBlock(GLuint programId, GLuint shader qWarning() << "SSBO are not supported by OpenGL 3.3 (since OpenGL 4.3)"; } +void GraphicsHelperGL3_3::bindImageTexture(GLuint imageUnit, GLuint texture, + GLint mipLevel, GLboolean layered, + GLint layer, GLenum access, GLenum format) +{ + Q_UNUSED(imageUnit) + Q_UNUSED(texture) + Q_UNUSED(mipLevel) + Q_UNUSED(layered) + Q_UNUSED(layer) + Q_UNUSED(access) + Q_UNUSED(format) + qWarning() << "Shader Images are not supported by OpenGL 3.3 (since OpenGL 4.2)"; +} + void GraphicsHelperGL3_3::bindBufferBase(GLenum target, GLuint index, GLuint buffer) { m_funcs->glBindBufferBase(target, index, buffer); diff --git a/src/render/renderers/opengl/graphicshelpers/graphicshelpergl3_3_p.h b/src/render/renderers/opengl/graphicshelpers/graphicshelpergl3_3_p.h index c480e5258..4dbf6fe7b 100644 --- a/src/render/renderers/opengl/graphicshelpers/graphicshelpergl3_3_p.h +++ b/src/render/renderers/opengl/graphicshelpers/graphicshelpergl3_3_p.h @@ -79,6 +79,7 @@ public: void bindFrameBufferAttachment(RenderBuffer *renderBuffer, const Attachment &attachment) override; void bindFrameBufferObject(GLuint frameBufferId, FBOBindMode mode) override; void bindShaderStorageBlock(GLuint programId, GLuint shaderStorageBlockIndex, GLuint shaderStorageBlockBinding) override; + void bindImageTexture(GLuint imageUnit, GLuint texture, GLint mipLevel, GLboolean layered, GLint layer, GLenum access, GLenum format) override; void bindUniformBlock(GLuint programId, GLuint uniformBlockIndex, GLuint uniformBlockBinding) override; void blendEquation(GLenum mode) override; void blendFunci(GLuint buf, GLenum sfactor, GLenum dfactor) override; @@ -90,6 +91,7 @@ public: void clearBufferf(GLint drawbuffer, const QVector4D &values) override; GLuint createFrameBufferObject() override; void depthMask(GLenum mode) override; + void depthRange(GLdouble nearValue, GLdouble farValue) override; void depthTest(GLenum mode) override; void disableClipPlane(int clipPlane) override; void disablei(GLenum cap, GLuint index) override; @@ -133,6 +135,7 @@ public: void vertexAttributePointer(GLenum shaderDataType, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer) override; void readBuffer(GLenum mode) override; void drawBuffer(GLenum mode) override; + void rasterMode(GLenum faceMode, GLenum rasterMode) override; void *fenceSync() override; void clientWaitSync(void *sync, GLuint64 nanoSecTimeout) override; diff --git a/src/render/renderers/opengl/graphicshelpers/graphicshelpergl4.cpp b/src/render/renderers/opengl/graphicshelpers/graphicshelpergl4.cpp index 22cbf7428..60caed273 100644 --- a/src/render/renderers/opengl/graphicshelpers/graphicshelpergl4.cpp +++ b/src/render/renderers/opengl/graphicshelpers/graphicshelpergl4.cpp @@ -79,6 +79,39 @@ # define GL_ATOMIC_COUNTER_BARRIER_BIT 0x00001000 # define GL_SHADER_STORAGE_BARRIER_BIT 0x00002000 # define GL_QUERY_BUFFER_BARRIER_BIT 0x00008000 +# define GL_IMAGE_1D 0x904C +# define GL_IMAGE_2D 0x904D +# define GL_IMAGE_3D 0x904E +# define GL_IMAGE_2D_RECT 0x904F +# define GL_IMAGE_CUBE 0x9050 +# define GL_IMAGE_BUFFER 0x9051 +# define GL_IMAGE_1D_ARRAY 0x9052 +# define GL_IMAGE_2D_ARRAY 0x9053 +# define GL_IMAGE_CUBE_MAP_ARRAY 0x9054 +# define GL_IMAGE_2D_MULTISAMPLE 0x9055 +# define GL_IMAGE_2D_MULTISAMPLE_ARRAY 0x9056 +# define GL_INT_IMAGE_1D 0x9057 +# define GL_INT_IMAGE_2D 0x9058 +# define GL_INT_IMAGE_3D 0x9059 +# define GL_INT_IMAGE_2D_RECT 0x905A +# define GL_INT_IMAGE_CUBE 0x905B +# define GL_INT_IMAGE_BUFFER 0x905C +# define GL_INT_IMAGE_1D_ARRAY 0x905D +# define GL_INT_IMAGE_2D_ARRAY 0x905E +# define GL_INT_IMAGE_CUBE_MAP_ARRAY 0x905F +# define GL_INT_IMAGE_2D_MULTISAMPLE 0x9060 +# define GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x9061 +# define GL_UNSIGNED_INT_IMAGE_1D 0x9062 +# define GL_UNSIGNED_INT_IMAGE_2D 0x9063 +# define GL_UNSIGNED_INT_IMAGE_3D 0x9064 +# define GL_UNSIGNED_INT_IMAGE_2D_RECT 0x9065 +# define GL_UNSIGNED_INT_IMAGE_CUBE 0x9066 +# define GL_UNSIGNED_INT_IMAGE_BUFFER 0x9067 +# define GL_UNSIGNED_INT_IMAGE_1D_ARRAY 0x9068 +# define GL_UNSIGNED_INT_IMAGE_2D_ARRAY 0x9069 +# define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY 0x906A +# define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE 0x906B +# define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x906C # endif QT_BEGIN_NAMESPACE @@ -433,6 +466,11 @@ void GraphicsHelperGL4::deleteSync(void *sync) m_funcs->glDeleteSync(static_cast<GLsync>(sync)); } +void GraphicsHelperGL4::rasterMode(GLenum faceMode, GLenum rasterMode) +{ + m_funcs->glPolygonMode(faceMode, rasterMode); +} + void GraphicsHelperGL4::glUniform1fv(GLint location, GLsizei count, const GLfloat *values) { m_funcs->glUniform1fv(location, count, values); @@ -630,6 +668,42 @@ UniformType GraphicsHelperGL4::uniformTypeFromGLType(GLenum type) case GL_UNSIGNED_INT_SAMPLER_CUBE: case GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY: return UniformType::Sampler; + + case GL_IMAGE_1D: + case GL_IMAGE_2D: + case GL_IMAGE_3D: + case GL_IMAGE_2D_RECT: + case GL_IMAGE_CUBE: + case GL_IMAGE_BUFFER: + case GL_IMAGE_1D_ARRAY: + case GL_IMAGE_2D_ARRAY: + case GL_IMAGE_CUBE_MAP_ARRAY: + case GL_IMAGE_2D_MULTISAMPLE: + case GL_IMAGE_2D_MULTISAMPLE_ARRAY: + case GL_INT_IMAGE_1D: + case GL_INT_IMAGE_2D: + case GL_INT_IMAGE_3D: + case GL_INT_IMAGE_2D_RECT: + case GL_INT_IMAGE_CUBE: + case GL_INT_IMAGE_BUFFER: + case GL_INT_IMAGE_1D_ARRAY: + case GL_INT_IMAGE_2D_ARRAY: + case GL_INT_IMAGE_CUBE_MAP_ARRAY: + case GL_INT_IMAGE_2D_MULTISAMPLE: + case GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY: + case GL_UNSIGNED_INT_IMAGE_1D: + case GL_UNSIGNED_INT_IMAGE_2D: + case GL_UNSIGNED_INT_IMAGE_3D: + case GL_UNSIGNED_INT_IMAGE_2D_RECT: + case GL_UNSIGNED_INT_IMAGE_CUBE: + case GL_UNSIGNED_INT_IMAGE_BUFFER: + case GL_UNSIGNED_INT_IMAGE_1D_ARRAY: + case GL_UNSIGNED_INT_IMAGE_2D_ARRAY: + case GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY: + case GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE: + case GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY: + return UniformType::Image; + default: // TO DO: Add support for Doubles and Images Q_UNREACHABLE(); @@ -668,6 +742,11 @@ void GraphicsHelperGL4::depthMask(GLenum mode) m_funcs->glDepthMask(mode); } +void GraphicsHelperGL4::depthRange(GLdouble nearValue, GLdouble farValue) +{ + m_funcs->glDepthRange(nearValue, farValue); +} + void GraphicsHelperGL4::frontFace(GLenum mode) { m_funcs->glFrontFace(mode); @@ -714,6 +793,19 @@ void GraphicsHelperGL4::bindFrameBufferObject(GLuint frameBufferId, FBOBindMode } } +void GraphicsHelperGL4::bindImageTexture(GLuint imageUnit, GLuint texture, + GLint mipLevel, GLboolean layered, + GLint layer, GLenum access, GLenum format) +{ + m_funcs->glBindImageTexture(imageUnit, + texture, + mipLevel, + layered, + layer, + access, + format); +} + GLuint GraphicsHelperGL4::boundFrameBufferObject() { GLint id = 0; @@ -781,6 +873,7 @@ bool GraphicsHelperGL4::supportsFeature(GraphicsHelperInterface::Feature feature case IndirectDrawing: case MapBuffer: case Fences: + case ShaderImage: return true; default: return false; @@ -1009,7 +1102,40 @@ void GraphicsHelperGL4::buildUniformBuffer(const QVariant &v, const ShaderUnifor case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE: case GL_SAMPLER_2D_MULTISAMPLE_ARRAY: case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: - case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: { + case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: + case GL_IMAGE_1D: + case GL_IMAGE_2D: + case GL_IMAGE_3D: + case GL_IMAGE_2D_RECT: + case GL_IMAGE_CUBE: + case GL_IMAGE_BUFFER: + case GL_IMAGE_1D_ARRAY: + case GL_IMAGE_2D_ARRAY: + case GL_IMAGE_CUBE_MAP_ARRAY: + case GL_IMAGE_2D_MULTISAMPLE: + case GL_IMAGE_2D_MULTISAMPLE_ARRAY: + case GL_INT_IMAGE_1D: + case GL_INT_IMAGE_2D: + case GL_INT_IMAGE_3D: + case GL_INT_IMAGE_2D_RECT: + case GL_INT_IMAGE_CUBE: + case GL_INT_IMAGE_BUFFER: + case GL_INT_IMAGE_1D_ARRAY: + case GL_INT_IMAGE_2D_ARRAY: + case GL_INT_IMAGE_CUBE_MAP_ARRAY: + case GL_INT_IMAGE_2D_MULTISAMPLE: + case GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY: + case GL_UNSIGNED_INT_IMAGE_1D: + case GL_UNSIGNED_INT_IMAGE_2D: + case GL_UNSIGNED_INT_IMAGE_3D: + case GL_UNSIGNED_INT_IMAGE_2D_RECT: + case GL_UNSIGNED_INT_IMAGE_CUBE: + case GL_UNSIGNED_INT_IMAGE_BUFFER: + case GL_UNSIGNED_INT_IMAGE_1D_ARRAY: + case GL_UNSIGNED_INT_IMAGE_2D_ARRAY: + case GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY: + case GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE: + case GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY: { Q_ASSERT(description.m_size == 1); int value = v.toInt(); QGraphicsUtils::fillDataArray<GLint>(bufferData, &value, description, 1); @@ -1139,8 +1265,47 @@ uint GraphicsHelperGL4::uniformByteSize(const ShaderUniform &description) case GL_SAMPLER_2D_MULTISAMPLE_ARRAY: case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: + case GL_IMAGE_1D: + case GL_IMAGE_2D: + case GL_IMAGE_3D: + case GL_IMAGE_2D_RECT: + case GL_IMAGE_CUBE: + case GL_IMAGE_BUFFER: + case GL_IMAGE_1D_ARRAY: + case GL_IMAGE_2D_ARRAY: + case GL_IMAGE_CUBE_MAP_ARRAY: + case GL_IMAGE_2D_MULTISAMPLE: + case GL_IMAGE_2D_MULTISAMPLE_ARRAY: + case GL_INT_IMAGE_1D: + case GL_INT_IMAGE_2D: + case GL_INT_IMAGE_3D: + case GL_INT_IMAGE_2D_RECT: + case GL_INT_IMAGE_CUBE: + case GL_INT_IMAGE_BUFFER: + case GL_INT_IMAGE_1D_ARRAY: + case GL_INT_IMAGE_2D_ARRAY: + case GL_INT_IMAGE_CUBE_MAP_ARRAY: + case GL_INT_IMAGE_2D_MULTISAMPLE: + case GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY: + case GL_UNSIGNED_INT_IMAGE_1D: + case GL_UNSIGNED_INT_IMAGE_2D: + case GL_UNSIGNED_INT_IMAGE_3D: + case GL_UNSIGNED_INT_IMAGE_2D_RECT: + case GL_UNSIGNED_INT_IMAGE_CUBE: + case GL_UNSIGNED_INT_IMAGE_BUFFER: + case GL_UNSIGNED_INT_IMAGE_1D_ARRAY: + case GL_UNSIGNED_INT_IMAGE_2D_ARRAY: + case GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY: + case GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE: + case GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY: rawByteSize = 4; break; + + default: { + qWarning() << Q_FUNC_INFO << "unable to deduce rawByteSize for uniform type:" << description.m_type << "for uniform" << description.m_name; + break; + } + } return arrayStride ? rawByteSize * arrayStride : rawByteSize; diff --git a/src/render/renderers/opengl/graphicshelpers/graphicshelpergl4_p.h b/src/render/renderers/opengl/graphicshelpers/graphicshelpergl4_p.h index da62f4212..d3ce0d079 100644 --- a/src/render/renderers/opengl/graphicshelpers/graphicshelpergl4_p.h +++ b/src/render/renderers/opengl/graphicshelpers/graphicshelpergl4_p.h @@ -76,6 +76,7 @@ public: void bindFrameBufferAttachment(QOpenGLTexture *texture, const Attachment &attachment) override; void bindFrameBufferAttachment(RenderBuffer *renderBuffer, const Attachment &attachment) override; void bindFrameBufferObject(GLuint frameBufferId, FBOBindMode mode) override; + void bindImageTexture(GLuint imageUnit, GLuint texture, GLint mipLevel, GLboolean layered, GLint layer, GLenum access, GLenum format) override; void bindShaderStorageBlock(GLuint programId, GLuint shaderStorageBlockIndex, GLuint shaderStorageBlockBinding) override; void bindUniformBlock(GLuint programId, GLuint uniformBlockIndex, GLuint uniformBlockBinding) override; void blendEquation(GLenum mode) override; @@ -88,6 +89,7 @@ public: void clearBufferf(GLint drawbuffer, const QVector4D &values) override; GLuint createFrameBufferObject() override; void depthMask(GLenum mode) override; + void depthRange(GLdouble nearValue, GLdouble farValue) override; void depthTest(GLenum mode) override; void disableClipPlane(int clipPlane) override; void disablei(GLenum cap, GLuint index) override; @@ -131,6 +133,7 @@ public: void vertexAttributePointer(GLenum shaderDataType, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer) override; void readBuffer(GLenum mode) override; void drawBuffer(GLenum mode) override; + void rasterMode(GLenum faceMode, GLenum rasterMode) override; void *fenceSync() override; void clientWaitSync(void *sync, GLuint64 nanoSecTimeout) override; diff --git a/src/render/renderers/opengl/graphicshelpers/graphicshelperinterface_p.h b/src/render/renderers/opengl/graphicshelpers/graphicshelperinterface_p.h index 2a1688b7f..21146c32b 100644 --- a/src/render/renderers/opengl/graphicshelpers/graphicshelperinterface_p.h +++ b/src/render/renderers/opengl/graphicshelpers/graphicshelperinterface_p.h @@ -83,7 +83,8 @@ public: BlitFramebuffer, IndirectDrawing, MapBuffer, - Fences + Fences, + ShaderImage }; enum FBOBindMode { @@ -100,6 +101,7 @@ public: virtual void bindFrameBufferAttachment(QOpenGLTexture *texture, const Attachment &attachment) = 0; virtual void bindFrameBufferAttachment(RenderBuffer *renderBuffer, const Attachment &attachment) = 0; virtual void bindFrameBufferObject(GLuint frameBufferId, FBOBindMode mode) = 0; + virtual void bindImageTexture(GLuint imageUnit, GLuint texture, GLint mipLevel, GLboolean layered, GLint layer, GLenum access, GLenum format) = 0; virtual void bindShaderStorageBlock(GLuint programId, GLuint shaderStorageBlockIndex, GLuint shaderStorageBlockBinding) = 0; virtual void bindUniformBlock(GLuint programId, GLuint uniformBlockIndex, GLuint uniformBlockBinding) = 0; virtual void blendEquation(GLenum mode) = 0; @@ -111,6 +113,7 @@ public: virtual bool checkFrameBufferComplete() = 0; virtual void clearBufferf(GLint drawbuffer, const QVector4D &values) = 0; virtual GLuint createFrameBufferObject() = 0; + virtual void depthRange(GLdouble nearValue, GLdouble farValue) = 0; virtual void depthMask(GLenum mode) = 0; virtual void depthTest(GLenum mode) = 0; virtual void disableClipPlane(int clipPlane) = 0; @@ -155,6 +158,7 @@ public: virtual void vertexAttributePointer(GLenum shaderDataType, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer) = 0; virtual void readBuffer(GLenum mode) = 0; virtual void drawBuffer(GLenum mode) = 0; + virtual void rasterMode(GLenum faceMode, GLenum rasterMode) = 0; virtual void *fenceSync() = 0; virtual void clientWaitSync(void *sync, GLuint64 nanoSecTimeout) = 0; diff --git a/src/render/renderers/opengl/graphicshelpers/graphicshelpers.pri b/src/render/renderers/opengl/graphicshelpers/graphicshelpers.pri index ad08038c9..f2f7274d7 100644 --- a/src/render/renderers/opengl/graphicshelpers/graphicshelpers.pri +++ b/src/render/renderers/opengl/graphicshelpers/graphicshelpers.pri @@ -14,6 +14,7 @@ HEADERS += \ $$PWD/graphicshelpergl3_3_p.h \ $$PWD/graphicshelpergl4_p.h \ $$PWD/graphicshelpergl3_2_p.h \ + $$PWD/imagesubmissioncontext_p.h \ $$PWD/submissioncontext_p.h \ $$PWD/texturesubmissioncontext_p.h @@ -27,5 +28,6 @@ SOURCES += \ $$PWD/graphicshelpergl3_3.cpp \ $$PWD/graphicshelpergl4.cpp \ $$PWD/graphicshelpergl3_2.cpp \ + $$PWD/imagesubmissioncontext.cpp \ $$PWD/submissioncontext.cpp \ $$PWD/texturesubmissioncontext.cpp diff --git a/src/render/renderers/opengl/graphicshelpers/imagesubmissioncontext.cpp b/src/render/renderers/opengl/graphicshelpers/imagesubmissioncontext.cpp new file mode 100644 index 000000000..a5633c306 --- /dev/null +++ b/src/render/renderers/opengl/graphicshelpers/imagesubmissioncontext.cpp @@ -0,0 +1,304 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Klaralvdalens Datakonsult AB (KDAB). +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "imagesubmissioncontext_p.h" +#include <Qt3DRender/private/graphicscontext_p.h> +#include <Qt3DRender/private/gltexture_p.h> +#include <Qt3DRender/private/shaderimage_p.h> +#include <Qt3DRender/qshaderimage.h> + +QT_BEGIN_NAMESPACE + +// ES 3.1+ or GL 4.2+ +#ifndef GL_READ_ONLY +#define GL_READ_ONLY 0x88B8 +#endif +#ifndef GL_WRITE_ONLY +#define GL_WRITE_ONLY 0x88B9 +#endif +#ifndef GL_READ_WRITE +#define GL_READ_WRITE 0x88BA +#endif + +namespace Qt3DRender { +namespace Render { + +class GraphicsContext; +class GLTexture; + +namespace { + +GLenum glAccessEnumForShaderImageAccess(QShaderImage::Access access) +{ + switch (access) { + case QShaderImage::ReadOnly: + return GL_READ_ONLY; + case QShaderImage::WriteOnly: + return GL_WRITE_ONLY; + case QShaderImage::ReadWrite: + return GL_READ_WRITE; + } +} + +GLenum glImageFormatToGL(QShaderImage::ImageFormat format) +{ + // Right now we can abuse from the fact that the ImageFormat enum values + // have been assigned the same value as the GL enum + return GLenum(format); +} + +GLenum glImageFormatForShaderImageFormat(QShaderImage::ImageFormat format, + QAbstractTexture::TextureFormat textureFormat) +{ + Q_ASSERT_X(format != QShaderImage::NoFormat, Q_FUNC_INFO, "Valid image format or Automatic expected"); + + if (format != QShaderImage::Automatic) + return glImageFormatToGL(format); + + // Otherwise try to mind to best texture format + switch (textureFormat) { + case QAbstractTexture::R8_UNorm: + return glImageFormatToGL(QShaderImage::R8_UNorm); + case QAbstractTexture::RG8_UNorm: + return glImageFormatToGL(QShaderImage::RG8_UNorm); + case QAbstractTexture::RGBA8_UNorm: + return glImageFormatToGL(QShaderImage::RGBA8_UNorm); + + case QAbstractTexture::R16_UNorm: + return glImageFormatToGL(QShaderImage::R16_UNorm); + case QAbstractTexture::RG16_UNorm: + return glImageFormatToGL(QShaderImage::RG16_UNorm); + case QAbstractTexture::RGBA16_UNorm: + return glImageFormatToGL(QShaderImage::RGBA16_UNorm); + + case QAbstractTexture::R8_SNorm: + return glImageFormatToGL(QShaderImage::R8_SNorm); + case QAbstractTexture::RG8_SNorm: + return glImageFormatToGL(QShaderImage::RG8_SNorm); + case QAbstractTexture::RGBA8_SNorm: + return glImageFormatToGL(QShaderImage::RGBA8_SNorm); + + case QAbstractTexture::R16_SNorm: + return glImageFormatToGL(QShaderImage::R16_SNorm); + case QAbstractTexture::RG16_SNorm: + return glImageFormatToGL(QShaderImage::RG16_SNorm); + case QAbstractTexture::RGBA16_SNorm: + return glImageFormatToGL(QShaderImage::RGBA16_SNorm); + + case QAbstractTexture::R8U: + return glImageFormatToGL(QShaderImage::R8U); + case QAbstractTexture::RG8U: + return glImageFormatToGL(QShaderImage::RG8U); + case QAbstractTexture::RGBA8U: + return glImageFormatToGL(QShaderImage::RGBA8U); + + case QAbstractTexture::R16U: + return glImageFormatToGL(QShaderImage::R16U); + case QAbstractTexture::RG16U: + return glImageFormatToGL(QShaderImage::RG16U); + case QAbstractTexture::RGBA16U: + return glImageFormatToGL(QShaderImage::RGBA16U); + + case QAbstractTexture::R32U: + return glImageFormatToGL(QShaderImage::R32U); + case QAbstractTexture::RG32U: + return glImageFormatToGL(QShaderImage::RG32U); + case QAbstractTexture::RGBA32U: + return glImageFormatToGL(QShaderImage::RGBA32U); + + case QAbstractTexture::R8I: + return glImageFormatToGL(QShaderImage::R8I); + case QAbstractTexture::RG8I: + return glImageFormatToGL(QShaderImage::RG8I); + case QAbstractTexture::RGBA8I: + return glImageFormatToGL(QShaderImage::RGBA8I); + + case QAbstractTexture::R16I: + return glImageFormatToGL(QShaderImage::R16I); + case QAbstractTexture::RG16I: + return glImageFormatToGL(QShaderImage::RG16I); + case QAbstractTexture::RGBA16I: + return glImageFormatToGL(QShaderImage::RGBA16I); + + case QAbstractTexture::R32I: + return glImageFormatToGL(QShaderImage::R32I); + case QAbstractTexture::RG32I: + return glImageFormatToGL(QShaderImage::RG32I); + case QAbstractTexture::RGBA32I: + return glImageFormatToGL(QShaderImage::RGBA32I); + + case QAbstractTexture::R16F: + return glImageFormatToGL(QShaderImage::R16F); + case QAbstractTexture::RG16F: + return glImageFormatToGL(QShaderImage::RG16F); + case QAbstractTexture::RGBA16F: + return glImageFormatToGL(QShaderImage::RGBA16F); + + case QAbstractTexture::R32F: + return glImageFormatToGL(QShaderImage::R32F); + case QAbstractTexture::RG32F: + return glImageFormatToGL(QShaderImage::RG32F); + case QAbstractTexture::RGBA32F: + return glImageFormatToGL(QShaderImage::RGBA32F); + + case QAbstractTexture::RG11B10F: + return glImageFormatToGL(QShaderImage::RG11B10F); + case QAbstractTexture::RGB10A2: + return glImageFormatToGL(QShaderImage::RGB10A2); + case QAbstractTexture::RGB10A2U: + return glImageFormatToGL(QShaderImage::RGB10A2U); + + default: + qWarning() << "Cannot map Texture format" << textureFormat << "to a valid Image Format"; + Q_UNREACHABLE(); + return GL_NONE; + } +} + +} // anonymous + +ImageSubmissionContext::ImageSubmissionContext() + : m_ctx(nullptr) +{ +} + +void ImageSubmissionContext::initialize(GraphicsContext *context) +{ + m_ctx = context; + m_activeImages.resize(m_ctx->maxImageUnitsCount()); +} + +void ImageSubmissionContext::endDrawing() +{ + // Reduce score of all active Images + decayImageScores(); +} + +// Return Image Unit for Image +// If Image was used previously and recently, it will return the last used unit +// for that image. Otherwise it will try to return the image unit the least used. +int ImageSubmissionContext::activateImage(ShaderImage *image, GLTexture *tex) +{ + const int onUnit = assignUnitForImage(image->peerId()); + + if (onUnit < 0) { + qWarning() << "Unable to find available image unit"; + return -1; + } + + QOpenGLTexture *glTex = tex->getGLTexture(); + if (glTex == nullptr) { + qWarning() << "Unable to retrieve valid texture for Image"; + return -1; + } + + // Bind Image against Texture and resolve Image Format + m_ctx->bindImageTexture(onUnit, + glTex->textureId(), + image->mipLevel(), + image->layered(), + image->layer(), + glAccessEnumForShaderImageAccess(image->access()), + glImageFormatForShaderImageFormat(image->format(), + tex->properties().format)); + + // Store information about the Texture/Image on ActiveImage for given + // image unit + m_activeImages[onUnit].shaderImageId = image->peerId(); + m_activeImages[onUnit].texture = tex; + m_activeImages[onUnit].score = 200; + m_activeImages[onUnit].pinned = true; + + return onUnit; +} + +// Unset pinned Active Image and reduce their score +void ImageSubmissionContext::deactivateImages() +{ + for (int u = 0, m = m_activeImages.size(); u < m; ++u) { + if (m_activeImages[u].pinned) { + m_activeImages[u].pinned = false; + m_activeImages[u].score = qMax(m_activeImages[u].score - 1, 0); + return; + } + } +} + +// Reduce score of all active images (pinned or not) +void ImageSubmissionContext::decayImageScores() +{ + for (int u = 0, m = m_activeImages.size(); u < m; ++u) + m_activeImages[u].score = qMax(m_activeImages[u].score - 1, 0); +} + +int ImageSubmissionContext::assignUnitForImage(Qt3DCore::QNodeId shaderImageId) +{ + int lowestScoredUnit = -1; + int lowestScore = 0xfffffff; + + const int m = m_activeImages.size(); + for (int u = 0; u < m; ++u) { + if (m_activeImages[u].shaderImageId == shaderImageId) + return u; + } + + for (int u = 0; u < m; ++u) { + // No image is currently active on the image unit + // we save the image unit with the texture that has been on there + // the longest time while not being used + if (!m_activeImages[u].pinned) { + const int score = m_activeImages[u].score; + if (score < lowestScore) { + lowestScore = score; + lowestScoredUnit = u; + } + } + } + + if (lowestScoredUnit == -1) + qCWarning(Backend) << Q_FUNC_INFO << "No free image units!"; + + return lowestScoredUnit; +} + + +} // namespace Render +} // namespace Qt3DRender + +QT_END_NAMESPACE diff --git a/src/render/renderers/opengl/graphicshelpers/imagesubmissioncontext_p.h b/src/render/renderers/opengl/graphicshelpers/imagesubmissioncontext_p.h new file mode 100644 index 000000000..6d39f469b --- /dev/null +++ b/src/render/renderers/opengl/graphicshelpers/imagesubmissioncontext_p.h @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Klaralvdalens Datakonsult AB (KDAB). +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DRENDER_RENDER_IMAGESUBMISSIONCONTEXT_P_H +#define QT3DRENDER_RENDER_IMAGESUBMISSIONCONTEXT_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <Qt3DCore/QNodeId> + +QT_BEGIN_NAMESPACE + +namespace Qt3DRender { +namespace Render { + +class GraphicsContext; +class GLTexture; +class ShaderImage; + +class Q_AUTOTEST_EXPORT ImageSubmissionContext +{ +public: + ImageSubmissionContext(); + + void initialize(GraphicsContext *context); + void endDrawing(); + int activateImage(ShaderImage *image, GLTexture *tex); + void deactivateImages(); + +private: + void decayImageScores(); + int assignUnitForImage(Qt3DCore::QNodeId shaderImageId); + + struct ActiveImage + { + Qt3DCore::QNodeId shaderImageId; + GLTexture *texture = nullptr; + int score = 0; + bool pinned = false; + }; + QVector<ActiveImage> m_activeImages; + GraphicsContext *m_ctx; +}; + +} // namespace Render +} // namespace Qt3DRender + +QT_END_NAMESPACE + +#endif // QT3DRENDER_RENDER_IMAGESUBMISSIONCONTEXT_P_H diff --git a/src/render/renderers/opengl/graphicshelpers/submissioncontext.cpp b/src/render/renderers/opengl/graphicshelpers/submissioncontext.cpp index 1a2971a3f..bedc7f61c 100644 --- a/src/render/renderers/opengl/graphicshelpers/submissioncontext.cpp +++ b/src/render/renderers/opengl/graphicshelpers/submissioncontext.cpp @@ -212,6 +212,12 @@ void applyStateHelper<MSAAEnabled>(const MSAAEnabled *state, SubmissionContext * gc->setMSAAEnabled(std::get<0>(state->values())); } +template<> +void applyStateHelper<DepthRange>(const DepthRange *state, SubmissionContext *gc) +{ + const auto values = state->values(); + gc->depthRange(std::get<0>(values), std::get<1>(values)); +} template<> void applyStateHelper<DepthTest>(const DepthTest *state, SubmissionContext *gc) @@ -219,6 +225,11 @@ void applyStateHelper<DepthTest>(const DepthTest *state, SubmissionContext *gc) gc->depthTest(std::get<0>(state->values())); } +template<> +void applyStateHelper<RasterMode>(const RasterMode *state, SubmissionContext *gc) +{ + gc->rasterMode(std::get<0>(state->values()), std::get<1>(state->values())); +} template<> void applyStateHelper<NoDepthMask>(const NoDepthMask *state, SubmissionContext *gc) @@ -226,7 +237,6 @@ void applyStateHelper<NoDepthMask>(const NoDepthMask *state, SubmissionContext * gc->depthMask(std::get<0>(state->values())); } - template<> void applyStateHelper<CullFace>(const CullFace *state, SubmissionContext *gc) { @@ -379,6 +389,7 @@ void SubmissionContext::initialize() { GraphicsContext::initialize(); m_textureContext.initialize(this); + m_imageContext.initialize(this); } void SubmissionContext::resolveRenderTargetFormat() @@ -469,6 +480,7 @@ void SubmissionContext::endDrawing(bool swapBuffers) if (m_ownCurrent) m_gl->doneCurrent(); m_textureContext.endDrawing(); + m_imageContext.endDrawing(); } void SubmissionContext::activateRenderTarget(Qt3DCore::QNodeId renderTargetNodeId, const AttachmentPack &attachments, GLuint defaultFboId) @@ -854,6 +866,7 @@ void SubmissionContext::setActiveMaterial(Material *rmat) return; m_textureContext.deactivateTexturesWithScope(TextureSubmissionContext::TextureScopeMaterial); + m_imageContext.deactivateImages(); m_material = rmat; } @@ -911,6 +924,16 @@ void SubmissionContext::applyState(const StateVariant &stateVariant) break; } + case DepthRangeMask: { + applyStateHelper<DepthRange>(static_cast<const DepthRange *>(stateVariant.constState()), this); + break; + } + + case RasterModeMask: { + applyStateHelper<RasterMode>(static_cast<const RasterMode *>(stateVariant.constState()), this); + break; + } + case FrontFaceStateMask: { applyStateHelper<FrontFace>(static_cast<const FrontFace *>(stateVariant.constState()), this); break; @@ -993,6 +1016,9 @@ void SubmissionContext::resetMasked(qint64 maskOfStatesToReset) if (maskOfStatesToReset & StencilTestStateMask) funcs->glDisable(GL_STENCIL_TEST); + if (maskOfStatesToReset & DepthRangeMask) + depthRange(0.0f, 1.0f); + if (maskOfStatesToReset & DepthTestStateMask) funcs->glDisable(GL_DEPTH_TEST); @@ -1034,6 +1060,11 @@ void SubmissionContext::resetMasked(qint64 maskOfStatesToReset) if (maskOfStatesToReset & LineWidthMask) funcs->glLineWidth(1.0f); + +#ifndef QT_OPENGL_ES_2 + if (maskOfStatesToReset & RasterModeMask) + m_glHelper->rasterMode(GL_FRONT_AND_BACK, GL_FILL); +#endif } void SubmissionContext::applyStateSet(RenderStateSet *ss) @@ -1132,11 +1163,13 @@ bool SubmissionContext::setParameters(ShaderParameterPack ¶meterPack) // Update the uniforms with the correct texture unit id's PackUniformHash &uniformValues = parameterPack.uniforms(); + // Fill Texture Uniform Value with proper texture units + // so that they can be applied as regular uniforms in a second step for (int i = 0; i < parameterPack.textures().size(); ++i) { - const ShaderParameterPack::NamedTexture &namedTex = parameterPack.textures().at(i); + const ShaderParameterPack::NamedResource &namedTex = parameterPack.textures().at(i); // Given a Texture QNodeId, we retrieve the associated shared GLTexture if (uniformValues.contains(namedTex.glslNameId)) { - GLTexture *t = manager->glTextureManager()->lookupResource(namedTex.texId); + GLTexture *t = manager->glTextureManager()->lookupResource(namedTex.nodeId); if (t != nullptr) { UniformValue &texUniform = uniformValues[namedTex.glslNameId]; if (texUniform.valueType() == UniformValue::TextureValue) { @@ -1146,6 +1179,34 @@ bool SubmissionContext::setParameters(ShaderParameterPack ¶meterPack) if (namedTex.glslNameId != irradianceId && namedTex.glslNameId != specularId) { // Only return false if we are not dealing with env light textures + qWarning() << "Unable to find suitable Texture Unit"; + return false; + } + } + } + } + } + } + + // Fill Image Uniform Value with proper image units + // so that they can be applied as regular uniforms in a second step + for (int i = 0; i < parameterPack.images().size(); ++i) { + const ShaderParameterPack::NamedResource &namedTex = parameterPack.images().at(i); + // Given a Texture QNodeId, we retrieve the associated shared GLTexture + if (uniformValues.contains(namedTex.glslNameId)) { + ShaderImage *img = manager->shaderImageManager()->lookupResource(namedTex.nodeId); + if (img != nullptr) { + GLTexture *t = manager->glTextureManager()->lookupResource(img->textureId()); + if (t == nullptr) { + qWarning() << "Shader Image referencing invalid texture"; + continue; + } else { + UniformValue &imgUniform = uniformValues[namedTex.glslNameId]; + if (imgUniform.valueType() == UniformValue::ShaderImageValue) { + const int imgUnit = m_imageContext.activateImage(img, t); + imgUniform.data<int>()[namedTex.uniformArrayIndex] = imgUnit; + if (imgUnit == -1) { + qWarning() << "Unable to bind Image to Texture"; return false; } } @@ -1201,8 +1262,10 @@ bool SubmissionContext::setParameters(ShaderParameterPack ¶meterPack) // be un activeUniforms if there wasn't a matching value const UniformValue &v = values[uniform.m_nameId]; - // skip invalid textures - if (v.valueType() == UniformValue::TextureValue && *v.constData<int>() == -1) + // skip invalid textures/images + if ((v.valueType() == UniformValue::TextureValue || + v.valueType() == UniformValue::ShaderImageValue) && + *v.constData<int>() == -1) continue; applyUniform(uniform, v); diff --git a/src/render/renderers/opengl/graphicshelpers/submissioncontext_p.h b/src/render/renderers/opengl/graphicshelpers/submissioncontext_p.h index 844e62f15..a8700dd3a 100644 --- a/src/render/renderers/opengl/graphicshelpers/submissioncontext_p.h +++ b/src/render/renderers/opengl/graphicshelpers/submissioncontext_p.h @@ -55,6 +55,7 @@ #include <Qt3DRender/private/graphicscontext_p.h> #include <Qt3DRender/private/texturesubmissioncontext_p.h> +#include <Qt3DRender/private/imagesubmissioncontext_p.h> #include <Qt3DRender/qclearbuffers.h> #include <Qt3DRender/private/glbuffer_p.h> #include <Qt3DRender/qattribute.h> @@ -204,6 +205,7 @@ private: QByteArray m_uboTempArray; TextureSubmissionContext m_textureContext; + ImageSubmissionContext m_imageContext; // Attributes friend class OpenGLVertexArrayObject; |