QRhiVertexInputAttribute : Add unsigned int formats for vertex input

Task-number: QTBUG-83173
Change-Id: I640cd1fe74227d2cc96672d6c7aaac93e1930bcd
Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
This commit is contained in:
Inho Lee 2020-05-14 15:32:07 +02:00
parent 524d781607
commit 2503a59e35
7 changed files with 80 additions and 5 deletions

View File

@ -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 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 unsupported with OpenGL ES 2.0, while it will likely be supported everywhere
else. 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.
*/ */
/*! /*!

View File

@ -200,7 +200,11 @@ public:
Float, Float,
UNormByte4, UNormByte4,
UNormByte2, UNormByte2,
UNormByte UNormByte,
UInt4,
UInt3,
UInt2,
UInt
}; };
QRhiVertexInputAttribute() = default; QRhiVertexInputAttribute() = default;
@ -1450,7 +1454,8 @@ public:
ReadBackNonUniformBuffer, ReadBackNonUniformBuffer,
ReadBackNonBaseMipLevel, ReadBackNonBaseMipLevel,
TexelFetch, TexelFetch,
RenderToNonBaseMipLevel RenderToNonBaseMipLevel,
UIntAttributes
}; };
enum BeginFrameFlag { enum BeginFrameFlag {

View File

@ -481,6 +481,8 @@ bool QRhiD3D11::isFeatureSupported(QRhi::Feature feature) const
return true; return true;
case QRhi::RenderToNonBaseMipLevel: case QRhi::RenderToNonBaseMipLevel:
return true; return true;
case QRhi::UIntAttributes:
return true;
default: default:
Q_UNREACHABLE(); Q_UNREACHABLE();
return false; return false;
@ -3507,6 +3509,14 @@ static inline DXGI_FORMAT toD3DAttributeFormat(QRhiVertexInputAttribute::Format
return DXGI_FORMAT_R8G8_UNORM; return DXGI_FORMAT_R8G8_UNORM;
case QRhiVertexInputAttribute::UNormByte: case QRhiVertexInputAttribute::UNormByte:
return DXGI_FORMAT_R8_UNORM; 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: default:
Q_UNREACHABLE(); Q_UNREACHABLE();
return DXGI_FORMAT_R32G32B32A32_FLOAT; return DXGI_FORMAT_R32G32B32A32_FLOAT;

View File

@ -521,6 +521,7 @@ bool QRhiGles2::create(QRhi::Flags flags)
caps.nonBaseLevelFramebufferTexture = true; caps.nonBaseLevelFramebufferTexture = true;
caps.texelFetch = caps.ctxMajor >= 3; // 3.0 or ES 3.0 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) { if (!caps.gles) {
f->glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); f->glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
@ -869,6 +870,8 @@ bool QRhiGles2::isFeatureSupported(QRhi::Feature feature) const
return caps.texelFetch; return caps.texelFetch;
case QRhi::RenderToNonBaseMipLevel: case QRhi::RenderToNonBaseMipLevel:
return caps.nonBaseLevelFramebufferTexture; return caps.nonBaseLevelFramebufferTexture;
case QRhi::UIntAttributes:
return caps.uintAttributes;
default: default:
Q_UNREACHABLE(); Q_UNREACHABLE();
return false; return false;
@ -2162,14 +2165,42 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb)
normalize = true; normalize = true;
size = 1; size = 1;
break; 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: default:
break; break;
} }
const int locationIdx = it->location(); const int locationIdx = it->location();
quint32 ofs = it->offset() + cmd.args.bindVertexBuffer.offset; quint32 ofs = it->offset() + cmd.args.bindVertexBuffer.offset;
if (type == GL_UNSIGNED_INT) {
if (caps.uintAttributes) {
f->glVertexAttribIPointer(GLuint(locationIdx), size, type, stride,
reinterpret_cast<const GLvoid *>(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, f->glVertexAttribPointer(GLuint(locationIdx), size, type, normalize, stride,
reinterpret_cast<const GLvoid *>(quintptr(ofs))); reinterpret_cast<const GLvoid *>(quintptr(ofs)));
}
if (locationIdx >= TRACKED_ATTRIB_COUNT || !enabledAttribArrays[locationIdx]) { if (locationIdx >= TRACKED_ATTRIB_COUNT || !enabledAttribArrays[locationIdx]) {
if (locationIdx < TRACKED_ATTRIB_COUNT) if (locationIdx < TRACKED_ATTRIB_COUNT)
enabledAttribArrays[locationIdx] = true; enabledAttribArrays[locationIdx] = true;

View File

@ -868,7 +868,8 @@ public:
textureCompareMode(false), textureCompareMode(false),
properMapBuffer(false), properMapBuffer(false),
nonBaseLevelFramebufferTexture(false), nonBaseLevelFramebufferTexture(false),
texelFetch(false) texelFetch(false),
uintAttributes(true)
{ } { }
int ctxMajor; int ctxMajor;
int ctxMinor; int ctxMinor;
@ -902,6 +903,7 @@ public:
uint properMapBuffer : 1; uint properMapBuffer : 1;
uint nonBaseLevelFramebufferTexture : 1; uint nonBaseLevelFramebufferTexture : 1;
uint texelFetch : 1; uint texelFetch : 1;
uint uintAttributes : 1;
} caps; } caps;
QGles2SwapChain *currentSwapChain = nullptr; QGles2SwapChain *currentSwapChain = nullptr;
QVector<GLint> supportedCompressedFormats; QVector<GLint> supportedCompressedFormats;

View File

@ -566,6 +566,8 @@ bool QRhiMetal::isFeatureSupported(QRhi::Feature feature) const
return true; return true;
case QRhi::RenderToNonBaseMipLevel: case QRhi::RenderToNonBaseMipLevel:
return true; return true;
case QRhi::UIntAttributes:
return true;
default: default:
Q_UNREACHABLE(); Q_UNREACHABLE();
return false; return false;
@ -3099,6 +3101,14 @@ static inline MTLVertexFormat toMetalAttributeFormat(QRhiVertexInputAttribute::F
return MTLVertexFormatUCharNormalized; return MTLVertexFormatUCharNormalized;
else else
Q_UNREACHABLE(); Q_UNREACHABLE();
case QRhiVertexInputAttribute::UInt4:
return MTLVertexFormatUInt4;
case QRhiVertexInputAttribute::UInt3:
return MTLVertexFormatUInt3;
case QRhiVertexInputAttribute::UInt2:
return MTLVertexFormatUInt2;
case QRhiVertexInputAttribute::UInt:
return MTLVertexFormatUInt;
default: default:
Q_UNREACHABLE(); Q_UNREACHABLE();
return MTLVertexFormatFloat4; return MTLVertexFormatFloat4;

View File

@ -4048,6 +4048,8 @@ bool QRhiVulkan::isFeatureSupported(QRhi::Feature feature) const
return true; return true;
case QRhi::RenderToNonBaseMipLevel: case QRhi::RenderToNonBaseMipLevel:
return true; return true;
case QRhi::UIntAttributes:
return true;
default: default:
Q_UNREACHABLE(); Q_UNREACHABLE();
return false; return false;
@ -4881,6 +4883,14 @@ static inline VkFormat toVkAttributeFormat(QRhiVertexInputAttribute::Format form
return VK_FORMAT_R8G8_UNORM; return VK_FORMAT_R8G8_UNORM;
case QRhiVertexInputAttribute::UNormByte: case QRhiVertexInputAttribute::UNormByte:
return VK_FORMAT_R8_UNORM; 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: default:
Q_UNREACHABLE(); Q_UNREACHABLE();
return VK_FORMAT_R32G32B32A32_SFLOAT; return VK_FORMAT_R32G32B32A32_SFLOAT;