From bfc713530a6354ce786d3f9bd0f4567844e7240f Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Fri, 7 Jan 2022 15:26:53 +0100 Subject: rhi: Add queries for vertex input/output limits MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mainly because we do have legacy code in the Qt 5 graphical effects that tries to dynamically determine the max number of varyings. Make it easier to port such code. Change-Id: I846cab2c2fe7b4cd473b5ced0146ca36f1c8169b Reviewed-by: Qt CI Bot Reviewed-by: Christian Strømme --- src/gui/rhi/qrhi.cpp | 10 ++++++++++ src/gui/rhi/qrhi_p.h | 4 +++- src/gui/rhi/qrhid3d11.cpp | 8 ++++++++ src/gui/rhi/qrhigles2.cpp | 33 +++++++++++++++++++++++++++++++++ src/gui/rhi/qrhigles2_p_p.h | 4 ++++ src/gui/rhi/qrhimetal.mm | 4 ++++ src/gui/rhi/qrhinull.cpp | 4 ++++ src/gui/rhi/qrhivulkan.cpp | 4 ++++ 8 files changed, 70 insertions(+), 1 deletion(-) (limited to 'src/gui/rhi') diff --git a/src/gui/rhi/qrhi.cpp b/src/gui/rhi/qrhi.cpp index 1585b4bbc0..ebb930bfa4 100644 --- a/src/gui/rhi/qrhi.cpp +++ b/src/gui/rhi/qrhi.cpp @@ -792,6 +792,16 @@ Q_LOGGING_CATEGORY(QRHI_LOG_INFO, "qt.rhi.general") 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). + + \value MaxVertexInputs The number of input attributes to the vertex shader. + The location in a QRhiVertexInputAttribute must be in range \c{[0, + MaxVertexInputs-1]}. The value may be as low as 8 with OpenGL ES 2.0. + Elsewhere, typical values are 16, 31, or 32. + + \value MaxVertexOutputs The maximum number of outputs (4 component vector + \c out variables) from the vertex shader. The value may be as low as 8 with + OpenGL ES 2.0, and 15 with OpenGL ES 3.0 and some Metal devices. Elsewhere, + a typical value is 32. */ /*! diff --git a/src/gui/rhi/qrhi_p.h b/src/gui/rhi/qrhi_p.h index e19ebbfe26..dc788dd1e8 100644 --- a/src/gui/rhi/qrhi_p.h +++ b/src/gui/rhi/qrhi_p.h @@ -1678,7 +1678,9 @@ public: MaxThreadGroupY, MaxThreadGroupZ, TextureArraySizeMax, - MaxUniformBufferRange + MaxUniformBufferRange, + MaxVertexInputs, + MaxVertexOutputs }; ~QRhi(); diff --git a/src/gui/rhi/qrhid3d11.cpp b/src/gui/rhi/qrhid3d11.cpp index 04544bc3b2..814ef05dd1 100644 --- a/src/gui/rhi/qrhid3d11.cpp +++ b/src/gui/rhi/qrhid3d11.cpp @@ -124,6 +124,10 @@ QT_BEGIN_NAMESPACE #define D3D11_1_UAV_SLOT_COUNT 64 #endif +#ifndef D3D11_VS_INPUT_REGISTER_COUNT +#define D3D11_VS_INPUT_REGISTER_COUNT 32 +#endif + QRhiD3D11::QRhiD3D11(QRhiD3D11InitParams *params, QRhiD3D11NativeHandles *importParams) : ofr(this), deviceCurse(this) @@ -583,6 +587,10 @@ int QRhiD3D11::resourceLimit(QRhi::ResourceLimit limit) const return D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION; case QRhi::MaxUniformBufferRange: return 65536; + case QRhi::MaxVertexInputs: + return D3D11_VS_INPUT_REGISTER_COUNT; + case QRhi::MaxVertexOutputs: + return D3D11_VS_OUTPUT_REGISTER_COUNT; default: Q_UNREACHABLE(); return 0; diff --git a/src/gui/rhi/qrhigles2.cpp b/src/gui/rhi/qrhigles2.cpp index b698ee369b..3cbda98e04 100644 --- a/src/gui/rhi/qrhigles2.cpp +++ b/src/gui/rhi/qrhigles2.cpp @@ -430,6 +430,18 @@ QT_BEGIN_NAMESPACE #define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 #endif +#ifndef GL_MAX_VARYING_COMPONENTS +#define GL_MAX_VARYING_COMPONENTS 0x8B4B +#endif + +#ifndef GL_MAX_VARYING_FLOATS +#define GL_MAX_VARYING_FLOATS 0x8B4B +#endif + +#ifndef GL_MAX_VARYING_VECTORS +#define GL_MAX_VARYING_VECTORS 0x8DFC +#endif + /*! Constructs a new QRhiGles2InitParams. @@ -849,6 +861,23 @@ bool QRhiGles2::create(QRhi::Flags flags) caps.maxUniformVectors = qMin(maxVertexUniformComponents, maxFragmentUniformComponents) / 4; } + f->glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &caps.maxVertexInputs); + + if (caps.gles) { + f->glGetIntegerv(GL_MAX_VARYING_VECTORS, &caps.maxVertexOutputs); + } else if (caps.ctxMajor >= 3) { + GLint components = 0; + f->glGetIntegerv(GL_MAX_VARYING_COMPONENTS, &components); + caps.maxVertexOutputs = components / 4; + } else { + // OpenGL before 3.0 only has this, and not the same as + // MAX_VARYING_COMPONENTS strictly speaking, but will do. + GLint components = 0; + f->glGetIntegerv(GL_MAX_VARYING_FLOATS, &components); + if (components > 0) + caps.maxVertexOutputs = components / 4; + } + if (!caps.gles) { f->glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); f->glEnable(GL_POINT_SPRITE); @@ -1239,6 +1268,10 @@ int QRhiGles2::resourceLimit(QRhi::ResourceLimit limit) const return 2048; case QRhi::MaxUniformBufferRange: return int(qMin(INT_MAX, caps.maxUniformVectors * qint64(16))); + case QRhi::MaxVertexInputs: + return caps.maxVertexInputs; + case QRhi::MaxVertexOutputs: + return caps.maxVertexOutputs; default: Q_UNREACHABLE(); return 0; diff --git a/src/gui/rhi/qrhigles2_p_p.h b/src/gui/rhi/qrhigles2_p_p.h index 750626f9c5..c34f0023b0 100644 --- a/src/gui/rhi/qrhigles2_p_p.h +++ b/src/gui/rhi/qrhigles2_p_p.h @@ -930,6 +930,8 @@ public: maxThreadGroupsY(0), maxThreadGroupsZ(0), maxUniformVectors(4096), + maxVertexInputs(8), + maxVertexOutputs(8), msaaRenderBuffer(false), multisampledTexture(false), npotTextureFull(true), @@ -974,6 +976,8 @@ public: int maxThreadGroupsY; int maxThreadGroupsZ; int maxUniformVectors; + int maxVertexInputs; + int maxVertexOutputs; // 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 e825f56943..b52117c15c 100644 --- a/src/gui/rhi/qrhimetal.mm +++ b/src/gui/rhi/qrhimetal.mm @@ -654,6 +654,10 @@ int QRhiMetal::resourceLimit(QRhi::ResourceLimit limit) const return 2048; case QRhi::MaxUniformBufferRange: return 65536; + case QRhi::MaxVertexInputs: + return 31; + case QRhi::MaxVertexOutputs: + return 15; // use the minimum from MTLGPUFamily1/2/3 default: Q_UNREACHABLE(); return 0; diff --git a/src/gui/rhi/qrhinull.cpp b/src/gui/rhi/qrhinull.cpp index 7ef3b4a8ed..9544878350 100644 --- a/src/gui/rhi/qrhinull.cpp +++ b/src/gui/rhi/qrhinull.cpp @@ -165,6 +165,10 @@ int QRhiNull::resourceLimit(QRhi::ResourceLimit limit) const return 2048; case QRhi::MaxUniformBufferRange: return 65536; + case QRhi::MaxVertexInputs: + return 32; + case QRhi::MaxVertexOutputs: + return 32; default: Q_UNREACHABLE(); return 0; diff --git a/src/gui/rhi/qrhivulkan.cpp b/src/gui/rhi/qrhivulkan.cpp index 3f6119bb97..38c49e5283 100644 --- a/src/gui/rhi/qrhivulkan.cpp +++ b/src/gui/rhi/qrhivulkan.cpp @@ -4336,6 +4336,10 @@ int QRhiVulkan::resourceLimit(QRhi::ResourceLimit limit) const return int(physDevProperties.limits.maxImageArrayLayers); case QRhi::MaxUniformBufferRange: return int(qMin(INT_MAX, physDevProperties.limits.maxUniformBufferRange)); + case QRhi::MaxVertexInputs: + return physDevProperties.limits.maxVertexInputAttributes; + case QRhi::MaxVertexOutputs: + return physDevProperties.limits.maxVertexOutputComponents / 4; default: Q_UNREACHABLE(); return 0; -- cgit v1.2.3