summaryrefslogtreecommitdiffstats
path: root/src/render/renderers/opengl
diff options
context:
space:
mode:
authorPaul Lemire <paul.lemire@kdab.com>2018-09-21 07:53:11 +0200
committerPaul Lemire <paul.lemire@kdab.com>2018-09-21 07:54:37 +0000
commit9486a8a4b60a678280db2c625064ca78b3aaf489 (patch)
tree45ac30029bbe12a3d98d373bdb8cf48c174ab422 /src/render/renderers/opengl
parent9884d3bffcdee9c6aabc51b036554947873b11c4 (diff)
Complete ES 3.1 and 3.2 helpers
Which didn't handle indirect drawing, compute and tessellation Since ES 3.1/3.2 don't provide API for glShaderStorageBlockBinding, code was adjusted to use the default binding points and not require that API. Change-Id: Ie4dcd05f0a1d72e4a25f49b5fae138dc605ba5e3 Task-number: QTBUG-70660 Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
Diffstat (limited to 'src/render/renderers/opengl')
-rw-r--r--src/render/renderers/opengl/graphicshelpers/graphicshelperes3_1.cpp168
-rw-r--r--src/render/renderers/opengl/graphicshelpers/graphicshelperes3_1_p.h8
-rw-r--r--src/render/renderers/opengl/graphicshelpers/graphicshelperes3_2.cpp20
-rw-r--r--src/render/renderers/opengl/graphicshelpers/graphicshelperes3_2_p.h3
-rw-r--r--src/render/renderers/opengl/graphicshelpers/submissioncontext.cpp10
-rw-r--r--src/render/renderers/opengl/renderer/renderview.cpp1
-rw-r--r--src/render/renderers/opengl/renderer/shaderparameterpack_p.h1
7 files changed, 208 insertions, 3 deletions
diff --git a/src/render/renderers/opengl/graphicshelpers/graphicshelperes3_1.cpp b/src/render/renderers/opengl/graphicshelpers/graphicshelperes3_1.cpp
index 135e83aec..a555b67ef 100644
--- a/src/render/renderers/opengl/graphicshelpers/graphicshelperes3_1.cpp
+++ b/src/render/renderers/opengl/graphicshelpers/graphicshelperes3_1.cpp
@@ -53,10 +53,114 @@ QT_BEGIN_NAMESPACE
#ifndef GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE
#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A
#endif
+#ifndef GL_ACTIVE_RESOURCES
+#define GL_ACTIVE_RESOURCES 0x92F5
+#endif
+#ifndef GL_BUFFER_BINDING
+#define GL_BUFFER_BINDING 0x9302
+#endif
+#ifndef GL_BUFFER_DATA_SIZE
+#define GL_BUFFER_DATA_SIZE 0x9303
+#endif
+#ifndef GL_NUM_ACTIVE_VARIABLES
+#define GL_NUM_ACTIVE_VARIABLES 0x9304
+#endif
+#ifndef GL_SHADER_STORAGE_BLOCK
+#define GL_SHADER_STORAGE_BLOCK 0x92E6
+#endif
+#ifndef GL_ALL_BARRIER_BITS
+#define GL_ALL_BARRIER_BITS 0xFFFFFFFF
+#endif
+#ifndef GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT
+#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT 0x00000001
+#endif
+#ifndef GL_ELEMENT_ARRAY_BARRIER_BIT
+#define GL_ELEMENT_ARRAY_BARRIER_BIT 0x00000002
+#endif
+#ifndef GL_UNIFORM_BARRIER_BIT
+#define GL_UNIFORM_BARRIER_BIT 0x00000004
+#endif
+#ifndef GL_TEXTURE_FETCH_BARRIER_BIT
+#define GL_TEXTURE_FETCH_BARRIER_BIT 0x00000008
+#endif
+#ifndef GL_SHADER_IMAGE_ACCESS_BARRIER_BIT
+#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT 0x00000020
+#endif
+#ifndef GL_COMMAND_BARRIER_BIT
+#define GL_COMMAND_BARRIER_BIT 0x00000040
+#endif
+#ifndef GL_PIXEL_BUFFER_BARRIER_BIT
+#define GL_PIXEL_BUFFER_BARRIER_BIT 0x00000080
+#endif
+#ifndef GL_TEXTURE_UPDATE_BARRIER_BIT
+#define GL_TEXTURE_UPDATE_BARRIER_BIT 0x00000100
+#endif
+#ifndef GL_BUFFER_UPDATE_BARRIER_BIT
+#define GL_BUFFER_UPDATE_BARRIER_BIT 0x00000200
+#endif
+#ifndef GL_FRAMEBUFFER_BARRIER_BIT
+#define GL_FRAMEBUFFER_BARRIER_BIT 0x00000400
+#endif
+#ifndef GL_TRANSFORM_FEEDBACK_BARRIER_BIT
+#define GL_TRANSFORM_FEEDBACK_BARRIER_BIT 0x00000800
+#endif
+#ifndef GL_ATOMIC_COUNTER_BARRIER_BIT
+#define GL_ATOMIC_COUNTER_BARRIER_BIT 0x00001000
+#endif
+#ifndef GL_SHADER_STORAGE_BARRIER_BIT
+#define GL_SHADER_STORAGE_BARRIER_BIT 0x00002000
+#endif
+
namespace Qt3DRender {
namespace Render {
+namespace {
+
+GLbitfield memoryBarrierGLBitfield(QMemoryBarrier::Operations barriers)
+{
+ GLbitfield bits = 0;
+
+ if (barriers.testFlag(QMemoryBarrier::All)) {
+ bits |= GL_ALL_BARRIER_BITS;
+ return bits;
+ }
+
+ if (barriers.testFlag(QMemoryBarrier::VertexAttributeArray))
+ bits |= GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT;
+ if (barriers.testFlag(QMemoryBarrier::ElementArray))
+ bits |= GL_ELEMENT_ARRAY_BARRIER_BIT;
+ if (barriers.testFlag(QMemoryBarrier::Uniform))
+ bits |= GL_UNIFORM_BARRIER_BIT;
+ if (barriers.testFlag(QMemoryBarrier::TextureFetch))
+ bits |= GL_TEXTURE_FETCH_BARRIER_BIT;
+ if (barriers.testFlag(QMemoryBarrier::ShaderImageAccess))
+ bits |= GL_SHADER_IMAGE_ACCESS_BARRIER_BIT;
+ if (barriers.testFlag(QMemoryBarrier::Command))
+ bits |= GL_COMMAND_BARRIER_BIT;
+ if (barriers.testFlag(QMemoryBarrier::PixelBuffer))
+ bits |= GL_PIXEL_BUFFER_BARRIER_BIT;
+ if (barriers.testFlag(QMemoryBarrier::TextureUpdate))
+ bits |= GL_TEXTURE_UPDATE_BARRIER_BIT;
+ if (barriers.testFlag(QMemoryBarrier::BufferUpdate))
+ bits |= GL_BUFFER_UPDATE_BARRIER_BIT;
+ if (barriers.testFlag(QMemoryBarrier::FrameBuffer))
+ bits |= GL_FRAMEBUFFER_BARRIER_BIT;
+ if (barriers.testFlag(QMemoryBarrier::TransformFeedback))
+ bits |= GL_TRANSFORM_FEEDBACK_BARRIER_BIT;
+ if (barriers.testFlag(QMemoryBarrier::AtomicCounter))
+ bits |= GL_ATOMIC_COUNTER_BARRIER_BIT;
+ if (barriers.testFlag(QMemoryBarrier::ShaderStorage))
+ bits |= GL_SHADER_STORAGE_BARRIER_BIT;
+ if (barriers.testFlag(QMemoryBarrier::QueryBuffer))
+ qWarning() << "QueryBuffer barrier not supported by ES 3.1";
+
+ return bits;
+}
+
+} // anonymous
+
+
GraphicsHelperES3_1::GraphicsHelperES3_1()
{
}
@@ -65,6 +169,70 @@ GraphicsHelperES3_1::~GraphicsHelperES3_1()
{
}
+bool GraphicsHelperES3_1::supportsFeature(GraphicsHelperInterface::Feature feature) const
+{
+ switch (feature) {
+ case GraphicsHelperInterface::Compute:
+ case GraphicsHelperInterface::ShaderStorageObject:
+ case GraphicsHelperInterface::IndirectDrawing:
+ return true;
+ default:
+ break;
+ }
+ return GraphicsHelperES3::supportsFeature(feature);
+}
+
+void GraphicsHelperES3_1::dispatchCompute(GLuint wx, GLuint wy, GLuint wz)
+{
+ m_extraFuncs->glDispatchCompute(wx, wy, wz);
+}
+
+void GraphicsHelperES3_1::memoryBarrier(QMemoryBarrier::Operations barriers)
+{
+ m_extraFuncs->glMemoryBarrier(memoryBarrierGLBitfield(barriers));
+}
+
+void GraphicsHelperES3_1::drawArraysIndirect(GLenum mode, void *indirect)
+{
+ m_extraFuncs->glDrawArraysIndirect(mode, indirect);
+}
+
+void GraphicsHelperES3_1::drawElementsIndirect(GLenum mode, GLenum type, void *indirect)
+{
+ m_extraFuncs->glDrawElementsIndirect(mode, type, indirect);
+}
+
+void GraphicsHelperES3_1::bindShaderStorageBlock(GLuint , GLuint , GLuint )
+{
+ // ES 3.1 has no API for that, bindings have to be specified directly in the shader
+ // with layout(std430, binding = 3)
+ qWarning() << "ES 3.1 has no bindShaderStorageBlock API, it uses binding declaration from the shader storage block";
+}
+
+QVector<ShaderStorageBlock> GraphicsHelperES3_1::programShaderStorageBlocks(GLuint programId)
+{
+ QVector<ShaderStorageBlock> blocks;
+ GLint nbrActiveShaderStorageBlocks = 0;
+ m_extraFuncs->glGetProgramInterfaceiv(programId, GL_SHADER_STORAGE_BLOCK, GL_ACTIVE_RESOURCES, &nbrActiveShaderStorageBlocks);
+ blocks.reserve(nbrActiveShaderStorageBlocks);
+ for (GLint i = 0; i < nbrActiveShaderStorageBlocks; ++i) {
+ QByteArray storageBlockName(256, '\0');
+ GLsizei length = 0;
+ ShaderStorageBlock storageBlock;
+ m_extraFuncs->glGetProgramResourceName(programId, GL_SHADER_STORAGE_BLOCK, i, 256, &length, storageBlockName.data());
+ storageBlock.m_index = i;
+ storageBlock.m_name = QString::fromUtf8(storageBlockName.left(length));
+ GLenum prop = GL_BUFFER_BINDING;
+ m_extraFuncs->glGetProgramResourceiv(programId, GL_SHADER_STORAGE_BLOCK, i, 1, &prop, 4, NULL, &storageBlock.m_binding);
+ prop = GL_BUFFER_DATA_SIZE;
+ m_extraFuncs->glGetProgramResourceiv(programId, GL_SHADER_STORAGE_BLOCK, i, 1, &prop, 4, NULL, &storageBlock.m_size);
+ prop = GL_NUM_ACTIVE_VARIABLES;
+ m_extraFuncs->glGetProgramResourceiv(programId, GL_SHADER_STORAGE_BLOCK, i, 1, &prop, 4, NULL, &storageBlock.m_activeVariablesCount);
+ blocks.push_back(storageBlock);
+ }
+ return blocks;
+}
+
UniformType GraphicsHelperES3_1::uniformTypeFromGLType(GLenum glType)
{
switch (glType) {
diff --git a/src/render/renderers/opengl/graphicshelpers/graphicshelperes3_1_p.h b/src/render/renderers/opengl/graphicshelpers/graphicshelperes3_1_p.h
index 70a584380..2c130fbf5 100644
--- a/src/render/renderers/opengl/graphicshelpers/graphicshelperes3_1_p.h
+++ b/src/render/renderers/opengl/graphicshelpers/graphicshelperes3_1_p.h
@@ -64,6 +64,14 @@ public:
GraphicsHelperES3_1();
~GraphicsHelperES3_1();
+ bool supportsFeature(Feature feature) const override;
+ void dispatchCompute(GLuint wx, GLuint wy, GLuint wz) override;
+ void memoryBarrier(QMemoryBarrier::Operations barriers) override;
+ void drawArraysIndirect(GLenum mode,void *indirect) override;
+ void drawElementsIndirect(GLenum mode, GLenum type, void *indirect) override;
+ void bindShaderStorageBlock(GLuint programId, GLuint shaderStorageBlockIndex, GLuint shaderStorageBlockBinding) override;
+ QVector<ShaderStorageBlock> programShaderStorageBlocks(GLuint programId) override;
+
// QGraphicHelperInterface interface
UniformType uniformTypeFromGLType(GLenum glType) override;
uint uniformByteSize(const ShaderUniform &description) override;
diff --git a/src/render/renderers/opengl/graphicshelpers/graphicshelperes3_2.cpp b/src/render/renderers/opengl/graphicshelpers/graphicshelperes3_2.cpp
index 6290d091d..9dce08e4f 100644
--- a/src/render/renderers/opengl/graphicshelpers/graphicshelperes3_2.cpp
+++ b/src/render/renderers/opengl/graphicshelpers/graphicshelperes3_2.cpp
@@ -52,6 +52,10 @@ QT_BEGIN_NAMESPACE
#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A
#endif
+#ifndef GL_PATCH_VERTICES
+#define GL_PATCH_VERTICES 36466
+#endif
+
namespace Qt3DRender {
namespace Render {
@@ -63,6 +67,17 @@ GraphicsHelperES3_2::~GraphicsHelperES3_2()
{
}
+bool GraphicsHelperES3_2::supportsFeature(GraphicsHelperInterface::Feature feature) const
+{
+ switch (feature) {
+ case GraphicsHelperInterface::Tessellation:
+ return true;
+ default:
+ break;
+ }
+ return GraphicsHelperES3_1::supportsFeature(feature);
+}
+
bool GraphicsHelperES3_2::frameBufferNeedsRenderBuffer(const Attachment &attachment)
{
Q_UNUSED(attachment);
@@ -97,6 +112,11 @@ void GraphicsHelperES3_2::bindFrameBufferAttachment(QOpenGLTexture *texture, con
texture->release();
}
+void GraphicsHelperES3_2::setVerticesPerPatch(GLint verticesPerPatch)
+{
+ m_extraFuncs->glPatchParameteri(GL_PATCH_VERTICES, verticesPerPatch);
+}
+
} // 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 787bba5f0..ed71b1e3e 100644
--- a/src/render/renderers/opengl/graphicshelpers/graphicshelperes3_2_p.h
+++ b/src/render/renderers/opengl/graphicshelpers/graphicshelperes3_2_p.h
@@ -64,9 +64,12 @@ public:
GraphicsHelperES3_2();
~GraphicsHelperES3_2();
+ bool supportsFeature(Feature feature) const override;
+
// QGraphicHelperInterface interface
void bindFrameBufferAttachment(QOpenGLTexture *texture, const Attachment &attachment) override;
bool frameBufferNeedsRenderBuffer(const Attachment &attachment) override;
+ void setVerticesPerPatch(GLint verticesPerPatch) override;
};
} // namespace Render
diff --git a/src/render/renderers/opengl/graphicshelpers/submissioncontext.cpp b/src/render/renderers/opengl/graphicshelpers/submissioncontext.cpp
index 7bb0713ee..26ee94305 100644
--- a/src/render/renderers/opengl/graphicshelpers/submissioncontext.cpp
+++ b/src/render/renderers/opengl/graphicshelpers/submissioncontext.cpp
@@ -1291,15 +1291,19 @@ bool SubmissionContext::setParameters(ShaderParameterPack &parameterPack)
// Bind Shader Storage block to SSBO and update SSBO
const QVector<BlockToSSBO> blockToSSBOs = parameterPack.shaderStorageBuffers();
- int ssboIndex = 0;
for (const BlockToSSBO b : blockToSSBOs) {
Buffer *cpuBuffer = m_renderer->nodeManagers()->bufferManager()->lookupResource(b.m_bufferID);
GLBuffer *ssbo = glBufferForRenderBuffer(cpuBuffer, GLBuffer::ShaderStorageBuffer);
- bindShaderStorageBlock(shader->programId(), b.m_blockIndex, ssboIndex);
+
+ // bindShaderStorageBlock
+ // This is currently not required as we are introspecting the bindingIndex
+ // value from the shaders and not replacing them, making such a call useless
+ // bindShaderStorageBlock(shader->programId(), b.m_blockIndex, b.m_bindingIndex);
+
// Needed to avoid conflict where the buffer would already
// be bound as a VertexArray
bindGLBuffer(ssbo, GLBuffer::ShaderStorageBuffer);
- ssbo->bindBufferBase(this, ssboIndex++, GLBuffer::ShaderStorageBuffer);
+ ssbo->bindBufferBase(this, b.m_bindingIndex, GLBuffer::ShaderStorageBuffer);
// TO DO: Make sure that there's enough binding points
}
diff --git a/src/render/renderers/opengl/renderer/renderview.cpp b/src/render/renderers/opengl/renderer/renderview.cpp
index c29448570..66299e430 100644
--- a/src/render/renderers/opengl/renderer/renderview.cpp
+++ b/src/render/renderers/opengl/renderer/renderview.cpp
@@ -884,6 +884,7 @@ void RenderView::setShaderStorageValue(ShaderParameterPack &uniformPack,
BlockToSSBO shaderStorageBlock;
shaderStorageBlock.m_blockIndex = block.m_index;
shaderStorageBlock.m_bufferID = buffer->peerId();
+ shaderStorageBlock.m_bindingIndex = block.m_binding;
uniformPack.setShaderStorageBuffer(shaderStorageBlock);
// Buffer update to GL buffer will be done at render time
}
diff --git a/src/render/renderers/opengl/renderer/shaderparameterpack_p.h b/src/render/renderers/opengl/renderer/shaderparameterpack_p.h
index 5703bb17b..fe9ab3995 100644
--- a/src/render/renderers/opengl/renderer/shaderparameterpack_p.h
+++ b/src/render/renderers/opengl/renderer/shaderparameterpack_p.h
@@ -83,6 +83,7 @@ QT3D_DECLARE_TYPEINFO_2(Qt3DRender, Render, BlockToUBO, Q_MOVABLE_TYPE)
struct BlockToSSBO {
int m_blockIndex;
+ int m_bindingIndex;
Qt3DCore::QNodeId m_bufferID;
};
QT3D_DECLARE_TYPEINFO_2(Qt3DRender, Render, BlockToSSBO, Q_PRIMITIVE_TYPE)