Add GLSL support for runtime-sized arrays in SSBOs
The GLSL parser now allows a runtime-sized array as the last member in
a shader storage block. Clamping indexing against the memory bounds is
done by determining the array length at runtime.
Runtime-sized arrays are used in dEQP tests for many compute shader
tests, so these now work on the OpenGL backend.
BUG=angleproject:1951
TEST=angle_unittests,
dEQP-GLES31.functional.shaders.linkage.shader_storage_block.*
dEQP-GLES31.functional.shaders.builtin_functions.*compute*
Change-Id: Ibecca24623ca8e4723af6f0e0421fe9711ea828d
Reviewed-on: https://chromium-review.googlesource.com/787976
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/compiler/translator/OutputGLSLBase.cpp b/src/compiler/translator/OutputGLSLBase.cpp
index 9a47287..edaf2eb 100644
--- a/src/compiler/translator/OutputGLSLBase.cpp
+++ b/src/compiler/translator/OutputGLSLBase.cpp
@@ -526,24 +526,42 @@
}
else if (visit == PostVisit)
{
- int maxSize;
TIntermTyped *left = node->getLeft();
TType leftType = left->getType();
- if (left->isArray())
- {
- // The shader will fail validation if the array length is not > 0.
- maxSize = static_cast<int>(leftType.getOutermostArraySize()) - 1;
- }
- else
- {
- maxSize = leftType.getNominalSize() - 1;
- }
-
if (mClampingStrategy == SH_CLAMP_WITH_CLAMP_INTRINSIC)
- out << "), 0.0, float(" << maxSize << ")))]";
+ out << "), 0.0, float(";
else
- out << ", 0, " << maxSize << ")]";
+ out << ", 0, ";
+
+ if (leftType.isUnsizedArray())
+ {
+ // For runtime-sized arrays in ESSL 3.10 we need to call the length method
+ // to get the length to clamp against. See ESSL 3.10 section 4.1.9. Note
+ // that a runtime-sized array expression is guaranteed not to have side
+ // effects, so it's fine to add the expression to the output twice.
+ ASSERT(mShaderVersion >= 310);
+ ASSERT(!left->hasSideEffects());
+ left->traverse(this);
+ out << ".length() - 1";
+ }
+ else
+ {
+ int maxSize;
+ if (leftType.isArray())
+ {
+ maxSize = static_cast<int>(leftType.getOutermostArraySize()) - 1;
+ }
+ else
+ {
+ maxSize = leftType.getNominalSize() - 1;
+ }
+ out << maxSize;
+ }
+ if (mClampingStrategy == SH_CLAMP_WITH_CLAMP_INTRINSIC)
+ out << ")))]";
+ else
+ out << ")]";
}
}
else