diff options
author | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2019-12-11 01:00:10 +0100 |
---|---|---|
committer | Edward Welbourne <edward.welbourne@qt.io> | 2019-12-11 14:50:53 +0100 |
commit | a4a7c1bcf7595e2645c570d9c824532acf524fdf (patch) | |
tree | c57de9a148d02529836e74c50e308a7ac50d8550 /src/gui/rhi | |
parent | bef74b6c3a0a9c8649ea8eb333d80015f76863e4 (diff) | |
parent | e6de661a8aa96b5905ea7ba4cd5d76bd06da3f93 (diff) |
Merge remote-tracking branch 'origin/5.15' into dev
Conflicts:
tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp
Change-Id: I6b82507bf9a80a374c40393e72f4843f1557de89
Diffstat (limited to 'src/gui/rhi')
-rw-r--r-- | src/gui/rhi/qrhigles2.cpp | 77 | ||||
-rw-r--r-- | src/gui/rhi/qrhigles2_p_p.h | 9 | ||||
-rw-r--r-- | src/gui/rhi/qrhimetal.mm | 5 |
3 files changed, 76 insertions, 15 deletions
diff --git a/src/gui/rhi/qrhigles2.cpp b/src/gui/rhi/qrhigles2.cpp index 563d59b318..3fb2ec38a7 100644 --- a/src/gui/rhi/qrhigles2.cpp +++ b/src/gui/rhi/qrhigles2.cpp @@ -2428,7 +2428,15 @@ void QRhiGles2::bindShaderResources(QRhiGraphicsPipeline *maybeGraphicsPs, QRhiC f->glUniformMatrix2fv(uniform.glslLocation, 1, GL_FALSE, reinterpret_cast<const float *>(src)); break; case QShaderDescription::Mat3: - f->glUniformMatrix3fv(uniform.glslLocation, 1, GL_FALSE, reinterpret_cast<const float *>(src)); + { + // 4 floats per column (or row, if row-major) + float mat[9]; + const float *srcMat = reinterpret_cast<const float *>(src); + memcpy(mat, srcMat, 3 * sizeof(float)); + memcpy(mat + 3, srcMat + 4, 3 * sizeof(float)); + memcpy(mat + 6, srcMat + 8, 3 * sizeof(float)); + f->glUniformMatrix3fv(uniform.glslLocation, 1, GL_FALSE, mat); + } break; case QShaderDescription::Mat4: f->glUniformMatrix4fv(uniform.glslLocation, 1, GL_FALSE, reinterpret_cast<const float *>(src)); @@ -2919,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); diff --git a/src/gui/rhi/qrhimetal.mm b/src/gui/rhi/qrhimetal.mm index 555ed5e79f..3aa68db585 100644 --- a/src/gui/rhi/qrhimetal.mm +++ b/src/gui/rhi/qrhimetal.mm @@ -3215,7 +3215,10 @@ id<MTLLibrary> QRhiMetalData::createMetalLib(const QShader &shader, QShader::Var [opts release]; // src is autoreleased - if (err) { + // if lib is null and err is non-null, we had errors (fail) + // if lib is non-null and err is non-null, we had warnings (success) + // if lib is non-null and err is null, there were no errors or warnings (success) + if (!lib) { const QString msg = QString::fromNSString(err.localizedDescription); *error = msg; return nil; |