diff options
author | Laszlo Agocs <laszlo.agocs@qt.io> | 2021-11-09 13:18:15 +0100 |
---|---|---|
committer | Laszlo Agocs <laszlo.agocs@qt.io> | 2021-11-11 14:30:25 +0100 |
commit | e5af3082f217dfef4e2a7780c61d0691ec824911 (patch) | |
tree | b5bac9d52b19909f44d1b8df60a0db10d2f537c2 /src | |
parent | fde96b1568abb87e8bfbf2a54fadb5c57f722157 (diff) |
rhi: Expose the maximum uniform buffer range limit
Task-number: QTBUG-97715
Change-Id: I7f0a52c410b9b77f735fb3b7fd33141674bb0cda
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Andy Nichols <andy.nichols@qt.io>
(cherry picked from commit a8be40bd64b9258334d6936b1775bc6631fd158d)
Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/gui/rhi/qrhi.cpp | 15 | ||||
-rw-r--r-- | src/gui/rhi/qrhi_p.h | 3 | ||||
-rw-r--r-- | src/gui/rhi/qrhid3d11.cpp | 2 | ||||
-rw-r--r-- | src/gui/rhi/qrhigles2.cpp | 35 | ||||
-rw-r--r-- | src/gui/rhi/qrhigles2_p_p.h | 2 | ||||
-rw-r--r-- | src/gui/rhi/qrhimetal.mm | 2 | ||||
-rw-r--r-- | src/gui/rhi/qrhinull.cpp | 2 | ||||
-rw-r--r-- | src/gui/rhi/qrhivulkan.cpp | 2 |
8 files changed, 62 insertions, 1 deletions
diff --git a/src/gui/rhi/qrhi.cpp b/src/gui/rhi/qrhi.cpp index f8b3eab218..4c61aa259b 100644 --- a/src/gui/rhi/qrhi.cpp +++ b/src/gui/rhi/qrhi.cpp @@ -767,6 +767,12 @@ Q_LOGGING_CATEGORY(QRHI_LOG_INFO, "qt.rhi.general") \value MaxThreadGroupZ The maximum size of a work/thread group in the Z dimension. Effectively the maximum value of \c local_size_z in the compute shader. Typically 64 or 256. + + \value MaxUniformBufferRange The number of bytes that can be exposed from a + uniform buffer to the shaders at once. On OpenGL ES 2.0 and 3.0 + implementations this may be as low as 3584 bytes (224 four component, 32 + bits per component vectors). Elsewhere the value is typically 16384 (1024 + vec4s) or 65536 (4096 vec4s). */ /*! @@ -3208,6 +3214,9 @@ bool QRhiShaderResourceBinding::isLayoutCompatible(const QRhiShaderResourceBindi suitable for creating pipelines. Such a pipeline must then always be used together with another, layout compatible QRhiShaderResourceBindings with resources present passed to QRhiCommandBuffer::setShaderResources(). + + \note If the size of \a buf exceeds the limit reported for + QRhi::MaxUniformBufferRange, unexpected errors may occur. */ QRhiShaderResourceBinding QRhiShaderResourceBinding::uniformBuffer( int binding, StageFlags stage, QRhiBuffer *buf) @@ -3242,6 +3251,9 @@ QRhiShaderResourceBinding QRhiShaderResourceBinding::uniformBuffer( suitable for creating pipelines. Such a pipeline must then always be used together with another, layout compatible QRhiShaderResourceBindings with resources present passed to QRhiCommandBuffer::setShaderResources(). + + \note If \a size exceeds the limit reported for QRhi::MaxUniformBufferRange, + unexpected errors may occur. */ QRhiShaderResourceBinding QRhiShaderResourceBinding::uniformBuffer( int binding, StageFlags stage, QRhiBuffer *buf, int offset, int size) @@ -3276,6 +3288,9 @@ QRhiShaderResourceBinding QRhiShaderResourceBinding::uniformBuffer( suitable for creating pipelines. Such a pipeline must then always be used together with another, layout compatible QRhiShaderResourceBindings with resources present passed to QRhiCommandBuffer::setShaderResources(). + + \note If \a size exceeds the limit reported for QRhi::MaxUniformBufferRange, + unexpected errors may occur. */ QRhiShaderResourceBinding QRhiShaderResourceBinding::uniformBufferWithDynamicOffset( int binding, StageFlags stage, QRhiBuffer *buf, int size) diff --git a/src/gui/rhi/qrhi_p.h b/src/gui/rhi/qrhi_p.h index 17b170203b..506e36d3ce 100644 --- a/src/gui/rhi/qrhi_p.h +++ b/src/gui/rhi/qrhi_p.h @@ -1605,7 +1605,8 @@ public: MaxThreadsPerThreadGroup, MaxThreadGroupX, MaxThreadGroupY, - MaxThreadGroupZ + MaxThreadGroupZ, + MaxUniformBufferRange }; ~QRhi(); diff --git a/src/gui/rhi/qrhid3d11.cpp b/src/gui/rhi/qrhid3d11.cpp index 8e94d70502..ab9d915ece 100644 --- a/src/gui/rhi/qrhid3d11.cpp +++ b/src/gui/rhi/qrhid3d11.cpp @@ -576,6 +576,8 @@ int QRhiD3D11::resourceLimit(QRhi::ResourceLimit limit) const return D3D11_CS_THREAD_GROUP_MAX_Y; case QRhi::MaxThreadGroupZ: return D3D11_CS_THREAD_GROUP_MAX_Z; + case QRhi::MaxUniformBufferRange: + return 65536; default: Q_UNREACHABLE(); return 0; diff --git a/src/gui/rhi/qrhigles2.cpp b/src/gui/rhi/qrhigles2.cpp index 7d7e8a9226..ad134c7352 100644 --- a/src/gui/rhi/qrhigles2.cpp +++ b/src/gui/rhi/qrhigles2.cpp @@ -397,6 +397,22 @@ QT_BEGIN_NAMESPACE #define GL_TEXTURE_RECTANGLE 0x84F5 #endif +#ifndef GL_MAX_VERTEX_UNIFORM_COMPONENTS +#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A +#endif + +#ifndef GL_MAX_FRAGMENT_UNIFORM_COMPONENTS +#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49 +#endif + +#ifndef GL_MAX_VERTEX_UNIFORM_VECTORS +#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB +#endif + +#ifndef GL_MAX_FRAGMENT_UNIFORM_VECTORS +#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD +#endif + /*! Constructs a new QRhiGles2InitParams. @@ -678,6 +694,23 @@ bool QRhiGles2::create(QRhi::Flags flags) caps.texture3D = caps.ctxMajor >= 3; // 3.0 + // The ES 2.0 spec only has MAX_xxxx_VECTORS. ES 3.0 and up has both + // *VECTORS and *COMPONENTS. OpenGL 2.0-4.0 only has MAX_xxxx_COMPONENTS. + // 4.1 and above has both. What a mess. + if (caps.gles) { + GLint maxVertexUniformVectors = 0; + f->glGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, &maxVertexUniformVectors); + GLint maxFragmentUniformVectors = 0; + f->glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, &maxFragmentUniformVectors); + caps.maxUniformVectors = qMin(maxVertexUniformVectors, maxFragmentUniformVectors); + } else { + GLint maxVertexUniformComponents = 0; + f->glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS, &maxVertexUniformComponents); + GLint maxFragmentUniformComponents = 0; + f->glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, &maxFragmentUniformComponents); + caps.maxUniformVectors = qMin(maxVertexUniformComponents, maxFragmentUniformComponents) / 4; + } + if (!caps.gles) { f->glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); f->glEnable(GL_POINT_SPRITE); @@ -1105,6 +1138,8 @@ int QRhiGles2::resourceLimit(QRhi::ResourceLimit limit) const return caps.maxThreadGroupsY; case QRhi::MaxThreadGroupZ: return caps.maxThreadGroupsZ; + case QRhi::MaxUniformBufferRange: + return int(qMin<qint64>(INT_MAX, caps.maxUniformVectors * qint64(16))); default: Q_UNREACHABLE(); return 0; diff --git a/src/gui/rhi/qrhigles2_p_p.h b/src/gui/rhi/qrhigles2_p_p.h index 4d18e9c60f..6dcf374b90 100644 --- a/src/gui/rhi/qrhigles2_p_p.h +++ b/src/gui/rhi/qrhigles2_p_p.h @@ -915,6 +915,7 @@ public: maxThreadGroupsX(0), maxThreadGroupsY(0), maxThreadGroupsZ(0), + maxUniformVectors(4096), msaaRenderBuffer(false), multisampledTexture(false), npotTextureFull(true), @@ -956,6 +957,7 @@ public: int maxThreadGroupsX; int maxThreadGroupsY; int maxThreadGroupsZ; + int maxUniformVectors; // Multisample fb and blit are supported (GLES 3.0 or OpenGL 3.x). Not // the same as multisample textures! uint msaaRenderBuffer : 1; diff --git a/src/gui/rhi/qrhimetal.mm b/src/gui/rhi/qrhimetal.mm index d37a130d15..da3bd03bb1 100644 --- a/src/gui/rhi/qrhimetal.mm +++ b/src/gui/rhi/qrhimetal.mm @@ -646,6 +646,8 @@ int QRhiMetal::resourceLimit(QRhi::ResourceLimit limit) const #else return 512; #endif + case QRhi::MaxUniformBufferRange: + return 65536; default: Q_UNREACHABLE(); return 0; diff --git a/src/gui/rhi/qrhinull.cpp b/src/gui/rhi/qrhinull.cpp index 894caf8f35..f7f8f21ba7 100644 --- a/src/gui/rhi/qrhinull.cpp +++ b/src/gui/rhi/qrhinull.cpp @@ -162,6 +162,8 @@ int QRhiNull::resourceLimit(QRhi::ResourceLimit limit) const return 0; case QRhi::MaxThreadGroupZ: return 0; + case QRhi::MaxUniformBufferRange: + return 65536; default: Q_UNREACHABLE(); return 0; diff --git a/src/gui/rhi/qrhivulkan.cpp b/src/gui/rhi/qrhivulkan.cpp index 5dd7b088be..f34388a126 100644 --- a/src/gui/rhi/qrhivulkan.cpp +++ b/src/gui/rhi/qrhivulkan.cpp @@ -4299,6 +4299,8 @@ int QRhiVulkan::resourceLimit(QRhi::ResourceLimit limit) const return int(physDevProperties.limits.maxComputeWorkGroupSize[1]); case QRhi::MaxThreadGroupZ: return int(physDevProperties.limits.maxComputeWorkGroupSize[2]); + case QRhi::MaxUniformBufferRange: + return int(qMin<uint32_t>(INT_MAX, physDevProperties.limits.maxUniformBufferRange)); default: Q_UNREACHABLE(); return 0; |