summaryrefslogtreecommitdiffstats
path: root/src/plugins/renderers/rhi/renderer/pipelineuboset.cpp
diff options
context:
space:
mode:
authorPaul Lemire <paul.lemire@kdab.com>2020-11-27 10:53:06 +0100
committerPaul Lemire <paul.lemire@kdab.com>2020-11-28 10:13:23 +0100
commitcf6b181227b02b23050198d21c54bd03eacd3b55 (patch)
tree50b70657d76b0a110aec49af6710a85c1c48213d /src/plugins/renderers/rhi/renderer/pipelineuboset.cpp
parent6fac2818ac283c1db0af51a5d8c556fa8afc61ae (diff)
RHI: handle uniforms of type arrays properly
We weren't handling the possible array stride for uniform arrays. For a float[8], the GPU might expect each float to fit in a vec4 slot. We therefore have to handle that when uploading the values otherwise we could end having data in what the GPU believe is padding data. This required modifying the UniformValue object to report the number of elements it contains as it might not necessarely be the same as the array dimension reported by the shader introspection. Note: it seems that the arrayStride might not be reported properly. To work around that, if we know we are dealing with an array, we compute the stride ourselves. Pick-to: 6.0 Change-Id: I12b5379927dd47be888a40db58c2e5aba6e0730b Reviewed-by: Mike Krus <mike.krus@kdab.com>
Diffstat (limited to 'src/plugins/renderers/rhi/renderer/pipelineuboset.cpp')
-rw-r--r--src/plugins/renderers/rhi/renderer/pipelineuboset.cpp30
1 files changed, 30 insertions, 0 deletions
diff --git a/src/plugins/renderers/rhi/renderer/pipelineuboset.cpp b/src/plugins/renderers/rhi/renderer/pipelineuboset.cpp
index 0031d927d..0578c6a09 100644
--- a/src/plugins/renderers/rhi/renderer/pipelineuboset.cpp
+++ b/src/plugins/renderers/rhi/renderer/pipelineuboset.cpp
@@ -444,6 +444,33 @@ QByteArray rawDataForUniformValue(const QShaderDescription::BlockVariable &block
? QByteArray(value.constData<char>(), std::min(value.byteSize(), blockVariable.size))
: QByteArray::fromRawData(value.constData<char>(), std::min(value.byteSize(), blockVariable.size));
const int matrixStride = blockVariable.matrixStride;
+ int arrayStride = blockVariable.arrayStride;
+ const int firstArrayDim = !blockVariable.arrayDims.empty() ? blockVariable.arrayDims.first() : 0;
+
+ if (blockVariable.arrayDims.size() > 1)
+ qCWarning(Backend) << "Multi Dimension arrays not handled yet";
+
+ if (arrayStride != 0 && matrixStride != 0)
+ qCWarning(Backend) << "Arrays of matrices not handled yet";
+
+ // Special cases for arrays
+ if (firstArrayDim > 0) {
+ // It appears that for a float myArray[8]; stride is reported as being
+ // 0 but expected size 128 bytes which means 16 bytes per float
+ // In that case we compute the arrayStride ourselves
+ if (arrayStride == 0)
+ arrayStride = blockVariable.size / firstArrayDim;
+ if (arrayStride != 0) {
+ QByteArray newRawData(firstArrayDim * arrayStride, '\0');
+ const int byteSizePerEntry = value.elementByteSize();
+ for (int i = 0, m = std::min(firstArrayDim, value.elementCount()); i < m; ++i) {
+ std::memcpy(newRawData.data() + i * arrayStride,
+ rawData.constData() + i * byteSizePerEntry,
+ byteSizePerEntry);
+ }
+ return newRawData;
+ }
+ }
// Special cases for matrices which might have to be aligned to a vec4 stride
if (matrixStride != 0 && value.byteSize() % matrixStride != 0) {
@@ -457,6 +484,9 @@ QByteArray rawDataForUniformValue(const QShaderDescription::BlockVariable &block
}
return newRawData;
}
+
+ // Note: we currently don't handle array of matrices
+
return rawData;
}