diff options
-rw-r--r-- | src/gui/rhi/qrhigles2.cpp | 67 | ||||
-rw-r--r-- | src/gui/rhi/qrhigles2_p_p.h | 9 |
2 files changed, 63 insertions, 13 deletions
diff --git a/src/gui/rhi/qrhigles2.cpp b/src/gui/rhi/qrhigles2.cpp index e4490ceedb..3fb2ec38a7 100644 --- a/src/gui/rhi/qrhigles2.cpp +++ b/src/gui/rhi/qrhigles2.cpp @@ -2927,21 +2927,64 @@ bool QRhiGles2::linkProgram(GLuint program) return true; } -void QRhiGles2::gatherUniforms(GLuint program, const QShaderDescription::UniformBlock &ub, +void QRhiGles2::registerUniformIfActive(const QShaderDescription::BlockVariable &var, + const QByteArray &namePrefix, + int binding, + int baseOffset, + GLuint program, + QVector<QGles2UniformDescription> *dst) +{ + if (var.type == QShaderDescription::Struct) { + qWarning("Nested structs are not supported at the moment. '%s' ignored.", + qPrintable(var.name)); + return; + } + QGles2UniformDescription uniform; + uniform.type = var.type; + const QByteArray name = namePrefix + var.name.toUtf8(); + uniform.glslLocation = f->glGetUniformLocation(program, name.constData()); + if (uniform.glslLocation >= 0) { + uniform.binding = binding; + uniform.offset = uint(baseOffset + var.offset); + uniform.size = var.size; + dst->append(uniform); + } +} + +void QRhiGles2::gatherUniforms(GLuint program, + const QShaderDescription::UniformBlock &ub, QVector<QGles2UniformDescription> *dst) { - const QByteArray prefix = ub.structName.toUtf8() + '.'; + QByteArray prefix = ub.structName.toUtf8() + '.'; for (const QShaderDescription::BlockVariable &blockMember : ub.members) { - // ### no array support for now - QGles2UniformDescription uniform; - uniform.type = blockMember.type; - const QByteArray name = prefix + blockMember.name.toUtf8(); - uniform.glslLocation = f->glGetUniformLocation(program, name.constData()); - if (uniform.glslLocation >= 0) { - uniform.binding = ub.binding; - uniform.offset = uint(blockMember.offset); - uniform.size = blockMember.size; - dst->append(uniform); + if (blockMember.type == QShaderDescription::Struct) { + prefix += blockMember.name.toUtf8(); + const int baseOffset = blockMember.offset; + if (blockMember.arrayDims.isEmpty()) { + for (const QShaderDescription::BlockVariable &structMember : blockMember.structMembers) + registerUniformIfActive(structMember, prefix, ub.binding, baseOffset, program, dst); + } else { + if (blockMember.arrayDims.count() > 1) { + qWarning("Array of struct '%s' has more than one dimension. Only the first dimension is used.", + qPrintable(blockMember.name)); + } + const int dim = blockMember.arrayDims.first(); + const int elemSize = blockMember.size / dim; + int elemOffset = baseOffset; + for (int di = 0; di < dim; ++di) { + const QByteArray arrayPrefix = prefix + '[' + QByteArray::number(di) + ']' + '.'; + for (const QShaderDescription::BlockVariable &structMember : blockMember.structMembers) + registerUniformIfActive(structMember, arrayPrefix, ub.binding, elemOffset, program, dst); + elemOffset += elemSize; + } + } + } else { + if (!blockMember.arrayDims.isEmpty()) { + qWarning("Arrays are only supported for structs at the moment. '%s' ignored.", + qPrintable(blockMember.name)); + continue; + } + registerUniformIfActive(blockMember, prefix, ub.binding, 0, program, dst); } } } diff --git a/src/gui/rhi/qrhigles2_p_p.h b/src/gui/rhi/qrhigles2_p_p.h index 0283fadb4e..4a98011d3d 100644 --- a/src/gui/rhi/qrhigles2_p_p.h +++ b/src/gui/rhi/qrhigles2_p_p.h @@ -706,7 +706,14 @@ public: QByteArray shaderSource(const QRhiShaderStage &shaderStage, int *glslVersion); bool compileShader(GLuint program, const QRhiShaderStage &shaderStage, int *glslVersion); bool linkProgram(GLuint program); - void gatherUniforms(GLuint program, const QShaderDescription::UniformBlock &ub, + void registerUniformIfActive(const QShaderDescription::BlockVariable &var, + const QByteArray &namePrefix, + int binding, + int baseOffset, + GLuint program, + QVector<QGles2UniformDescription> *dst); + void gatherUniforms(GLuint program, + const QShaderDescription::UniformBlock &ub, QVector<QGles2UniformDescription> *dst); void gatherSamplers(GLuint program, const QShaderDescription::InOutVariable &v, QVector<QGles2SamplerDescription> *dst); |