From 2503a59e353e5714b184b499e10969aed9f80465 Mon Sep 17 00:00:00 2001 From: Inho Lee Date: Thu, 14 May 2020 15:32:07 +0200 Subject: [PATCH] QRhiVertexInputAttribute : Add unsigned int formats for vertex input Task-number: QTBUG-83173 Change-Id: I640cd1fe74227d2cc96672d6c7aaac93e1930bcd Reviewed-by: Laszlo Agocs --- src/gui/rhi/qrhi.cpp | 7 +++++++ src/gui/rhi/qrhi_p.h | 9 +++++++-- src/gui/rhi/qrhid3d11.cpp | 10 ++++++++++ src/gui/rhi/qrhigles2.cpp | 35 +++++++++++++++++++++++++++++++++-- src/gui/rhi/qrhigles2_p_p.h | 4 +++- src/gui/rhi/qrhimetal.mm | 10 ++++++++++ src/gui/rhi/qrhivulkan.cpp | 10 ++++++++++ 7 files changed, 80 insertions(+), 5 deletions(-) diff --git a/src/gui/rhi/qrhi.cpp b/src/gui/rhi/qrhi.cpp index 798c5e1a8a..9fc2f68b11 100644 --- a/src/gui/rhi/qrhi.cpp +++ b/src/gui/rhi/qrhi.cpp @@ -589,6 +589,13 @@ Q_LOGGING_CATEGORY(QRHI_LOG_INFO, "qt.rhi.general") whenever the target mip level is not zero. In practice this feature will be unsupported with OpenGL ES 2.0, while it will likely be supported everywhere else. + + \value UIntAttributes Indicates that specifying input attributes with an unsigned + integer type for a shader pipeline is supported. When not supported, build() + will succeed but just show a warning message and the values of unsigned int + type attributes will be broken. In practice this feature will be unsupported + with OpenGL ES 2.0 and OpenGL 2.x, while it will likely be supported + everywhere else. */ /*! diff --git a/src/gui/rhi/qrhi_p.h b/src/gui/rhi/qrhi_p.h index 928d708624..a031ea4f4b 100644 --- a/src/gui/rhi/qrhi_p.h +++ b/src/gui/rhi/qrhi_p.h @@ -200,7 +200,11 @@ public: Float, UNormByte4, UNormByte2, - UNormByte + UNormByte, + UInt4, + UInt3, + UInt2, + UInt }; QRhiVertexInputAttribute() = default; @@ -1450,7 +1454,8 @@ public: ReadBackNonUniformBuffer, ReadBackNonBaseMipLevel, TexelFetch, - RenderToNonBaseMipLevel + RenderToNonBaseMipLevel, + UIntAttributes }; enum BeginFrameFlag { diff --git a/src/gui/rhi/qrhid3d11.cpp b/src/gui/rhi/qrhid3d11.cpp index d1d4745bc8..c956576096 100644 --- a/src/gui/rhi/qrhid3d11.cpp +++ b/src/gui/rhi/qrhid3d11.cpp @@ -481,6 +481,8 @@ bool QRhiD3D11::isFeatureSupported(QRhi::Feature feature) const return true; case QRhi::RenderToNonBaseMipLevel: return true; + case QRhi::UIntAttributes: + return true; default: Q_UNREACHABLE(); return false; @@ -3507,6 +3509,14 @@ static inline DXGI_FORMAT toD3DAttributeFormat(QRhiVertexInputAttribute::Format return DXGI_FORMAT_R8G8_UNORM; case QRhiVertexInputAttribute::UNormByte: return DXGI_FORMAT_R8_UNORM; + case QRhiVertexInputAttribute::UInt4: + return DXGI_FORMAT_R32G32B32A32_UINT; + case QRhiVertexInputAttribute::UInt3: + return DXGI_FORMAT_R32G32B32_UINT; + case QRhiVertexInputAttribute::UInt2: + return DXGI_FORMAT_R32G32_UINT; + case QRhiVertexInputAttribute::UInt: + return DXGI_FORMAT_R32_UINT; default: Q_UNREACHABLE(); return DXGI_FORMAT_R32G32B32A32_FLOAT; diff --git a/src/gui/rhi/qrhigles2.cpp b/src/gui/rhi/qrhigles2.cpp index 25931bfb80..eb27ca5f57 100644 --- a/src/gui/rhi/qrhigles2.cpp +++ b/src/gui/rhi/qrhigles2.cpp @@ -521,6 +521,7 @@ bool QRhiGles2::create(QRhi::Flags flags) caps.nonBaseLevelFramebufferTexture = true; caps.texelFetch = caps.ctxMajor >= 3; // 3.0 or ES 3.0 + caps.uintAttributes = caps.ctxMajor >= 3; // 3.0 or ES 3.0 if (!caps.gles) { f->glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); @@ -869,6 +870,8 @@ bool QRhiGles2::isFeatureSupported(QRhi::Feature feature) const return caps.texelFetch; case QRhi::RenderToNonBaseMipLevel: return caps.nonBaseLevelFramebufferTexture; + case QRhi::UIntAttributes: + return caps.uintAttributes; default: Q_UNREACHABLE(); return false; @@ -2162,14 +2165,42 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb) normalize = true; size = 1; break; + case QRhiVertexInputAttribute::UInt4: + type = GL_UNSIGNED_INT; + size = 4; + break; + case QRhiVertexInputAttribute::UInt3: + type = GL_UNSIGNED_INT; + size = 3; + break; + case QRhiVertexInputAttribute::UInt2: + type = GL_UNSIGNED_INT; + size = 2; + break; + case QRhiVertexInputAttribute::UInt: + type = GL_UNSIGNED_INT; + size = 1; + break; default: break; } const int locationIdx = it->location(); quint32 ofs = it->offset() + cmd.args.bindVertexBuffer.offset; - f->glVertexAttribPointer(GLuint(locationIdx), size, type, normalize, stride, - reinterpret_cast(quintptr(ofs))); + if (type == GL_UNSIGNED_INT) { + if (caps.uintAttributes) { + f->glVertexAttribIPointer(GLuint(locationIdx), size, type, stride, + reinterpret_cast(quintptr(ofs))); + } else { + qWarning("Current RHI backend does not support UIntAttributes. Check supported features."); + // This is a trick to disable this attribute + if (locationIdx < TRACKED_ATTRIB_COUNT) + enabledAttribArrays[locationIdx] = true; + } + } else { + f->glVertexAttribPointer(GLuint(locationIdx), size, type, normalize, stride, + reinterpret_cast(quintptr(ofs))); + } if (locationIdx >= TRACKED_ATTRIB_COUNT || !enabledAttribArrays[locationIdx]) { if (locationIdx < TRACKED_ATTRIB_COUNT) enabledAttribArrays[locationIdx] = true; diff --git a/src/gui/rhi/qrhigles2_p_p.h b/src/gui/rhi/qrhigles2_p_p.h index 4f64c6d0a3..65ac3ccb67 100644 --- a/src/gui/rhi/qrhigles2_p_p.h +++ b/src/gui/rhi/qrhigles2_p_p.h @@ -868,7 +868,8 @@ public: textureCompareMode(false), properMapBuffer(false), nonBaseLevelFramebufferTexture(false), - texelFetch(false) + texelFetch(false), + uintAttributes(true) { } int ctxMajor; int ctxMinor; @@ -902,6 +903,7 @@ public: uint properMapBuffer : 1; uint nonBaseLevelFramebufferTexture : 1; uint texelFetch : 1; + uint uintAttributes : 1; } caps; QGles2SwapChain *currentSwapChain = nullptr; QVector supportedCompressedFormats; diff --git a/src/gui/rhi/qrhimetal.mm b/src/gui/rhi/qrhimetal.mm index 33fe389892..a003d4815d 100644 --- a/src/gui/rhi/qrhimetal.mm +++ b/src/gui/rhi/qrhimetal.mm @@ -566,6 +566,8 @@ bool QRhiMetal::isFeatureSupported(QRhi::Feature feature) const return true; case QRhi::RenderToNonBaseMipLevel: return true; + case QRhi::UIntAttributes: + return true; default: Q_UNREACHABLE(); return false; @@ -3099,6 +3101,14 @@ static inline MTLVertexFormat toMetalAttributeFormat(QRhiVertexInputAttribute::F return MTLVertexFormatUCharNormalized; else Q_UNREACHABLE(); + case QRhiVertexInputAttribute::UInt4: + return MTLVertexFormatUInt4; + case QRhiVertexInputAttribute::UInt3: + return MTLVertexFormatUInt3; + case QRhiVertexInputAttribute::UInt2: + return MTLVertexFormatUInt2; + case QRhiVertexInputAttribute::UInt: + return MTLVertexFormatUInt; default: Q_UNREACHABLE(); return MTLVertexFormatFloat4; diff --git a/src/gui/rhi/qrhivulkan.cpp b/src/gui/rhi/qrhivulkan.cpp index 164d596d74..2158818556 100644 --- a/src/gui/rhi/qrhivulkan.cpp +++ b/src/gui/rhi/qrhivulkan.cpp @@ -4048,6 +4048,8 @@ bool QRhiVulkan::isFeatureSupported(QRhi::Feature feature) const return true; case QRhi::RenderToNonBaseMipLevel: return true; + case QRhi::UIntAttributes: + return true; default: Q_UNREACHABLE(); return false; @@ -4881,6 +4883,14 @@ static inline VkFormat toVkAttributeFormat(QRhiVertexInputAttribute::Format form return VK_FORMAT_R8G8_UNORM; case QRhiVertexInputAttribute::UNormByte: return VK_FORMAT_R8_UNORM; + case QRhiVertexInputAttribute::UInt4: + return VK_FORMAT_R32G32B32A32_UINT; + case QRhiVertexInputAttribute::UInt3: + return VK_FORMAT_R32G32B32_UINT; + case QRhiVertexInputAttribute::UInt2: + return VK_FORMAT_R32G32_UINT; + case QRhiVertexInputAttribute::UInt: + return VK_FORMAT_R32_UINT; default: Q_UNREACHABLE(); return VK_FORMAT_R32G32B32A32_SFLOAT;