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-10 13:31:05 +0100 |
commit | a8be40bd64b9258334d6936b1775bc6631fd158d (patch) | |
tree | 0a6e2f2a53db8348c118f0240cf3108e9e216c45 /src/gui/rhi | |
parent | cdf784a1c7bf9548a1aed8cbfe376b817d13640a (diff) |
rhi: Expose the maximum uniform buffer range limit
Pick-to: 6.2
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>
Diffstat (limited to 'src/gui/rhi')
-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 efa3c1893d..952183f55e 100644 --- a/src/gui/rhi/qrhi.cpp +++ b/src/gui/rhi/qrhi.cpp @@ -776,6 +776,12 @@ Q_LOGGING_CATEGORY(QRHI_LOG_INFO, "qt.rhi.general") \value TextureArraySizeMax Maximum texture array size. Typically in range 256 - 2048. Attempting to \l{QRhi::newTextureArray()}{create a texture array} with more elements will likely fail. + + \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). */ /*! @@ -3228,6 +3234,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) @@ -3262,6 +3271,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) @@ -3296,6 +3308,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 4decdd0c91..5344046841 100644 --- a/src/gui/rhi/qrhi_p.h +++ b/src/gui/rhi/qrhi_p.h @@ -1612,7 +1612,8 @@ public: MaxThreadGroupX, MaxThreadGroupY, MaxThreadGroupZ, - TextureArraySizeMax + TextureArraySizeMax, + MaxUniformBufferRange }; ~QRhi(); diff --git a/src/gui/rhi/qrhid3d11.cpp b/src/gui/rhi/qrhid3d11.cpp index 631e7f7adf..d2b217b6d4 100644 --- a/src/gui/rhi/qrhid3d11.cpp +++ b/src/gui/rhi/qrhid3d11.cpp @@ -580,6 +580,8 @@ int QRhiD3D11::resourceLimit(QRhi::ResourceLimit limit) const return D3D11_CS_THREAD_GROUP_MAX_Z; case QRhi::TextureArraySizeMax: return D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION; + 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 5259be270c..4512acb969 100644 --- a/src/gui/rhi/qrhigles2.cpp +++ b/src/gui/rhi/qrhigles2.cpp @@ -405,6 +405,22 @@ QT_BEGIN_NAMESPACE #define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF #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. @@ -694,6 +710,23 @@ bool QRhiGles2::create(QRhi::Flags flags) caps.maxTextureArraySize = 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); @@ -1125,6 +1158,8 @@ int QRhiGles2::resourceLimit(QRhi::ResourceLimit limit) const return caps.maxThreadGroupsZ; case QRhi::TextureArraySizeMax: return 2048; + 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 48f79e3c1d..c3297f488d 100644 --- a/src/gui/rhi/qrhigles2_p_p.h +++ b/src/gui/rhi/qrhigles2_p_p.h @@ -918,6 +918,7 @@ public: maxThreadGroupsX(0), maxThreadGroupsY(0), maxThreadGroupsZ(0), + maxUniformVectors(4096), msaaRenderBuffer(false), multisampledTexture(false), npotTextureFull(true), @@ -960,6 +961,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 3e4c0e08e2..169d80251d 100644 --- a/src/gui/rhi/qrhimetal.mm +++ b/src/gui/rhi/qrhimetal.mm @@ -650,6 +650,8 @@ int QRhiMetal::resourceLimit(QRhi::ResourceLimit limit) const #endif case QRhi::TextureArraySizeMax: return 2048; + 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 c160958493..b23af75bd9 100644 --- a/src/gui/rhi/qrhinull.cpp +++ b/src/gui/rhi/qrhinull.cpp @@ -164,6 +164,8 @@ int QRhiNull::resourceLimit(QRhi::ResourceLimit limit) const return 0; case QRhi::TextureArraySizeMax: return 2048; + 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 c0d5ab1c07..1cead19f77 100644 --- a/src/gui/rhi/qrhivulkan.cpp +++ b/src/gui/rhi/qrhivulkan.cpp @@ -4305,6 +4305,8 @@ int QRhiVulkan::resourceLimit(QRhi::ResourceLimit limit) const return int(physDevProperties.limits.maxComputeWorkGroupSize[2]); case QRhi::TextureArraySizeMax: return int(physDevProperties.limits.maxImageArrayLayers); + case QRhi::MaxUniformBufferRange: + return int(qMin<uint32_t>(INT_MAX, physDevProperties.limits.maxUniformBufferRange)); default: Q_UNREACHABLE(); return 0; |