ES31: Implement binding layout for uniform blocks
The binding point of uniform blocks can be specified in shaders with
this CL. See spec ESSL 3.10, section 4.4.4, page 58 for more info.
dEQP-GLES31.functional.ubo.* still can't completely pass as
the missing of arrays-of-arrays feature. Neither can
dEQP-GLES31.functional.layout_binding.ubo.* due to the incomplete
implementation of program interface APIs.
TEST=angle_end2end_tests:UniformBufferTest
BUG=angleproject:1442
Change-Id: If95d468fc109834a132b9b817730d3fdc3a615da
Reviewed-on: https://chromium-review.googlesource.com/483848
Commit-Queue: Jie A Chen <jie.a.chen@intel.com>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Olli Etuaho <oetuaho@nvidia.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/compiler/translator/ParseContext.cpp b/src/compiler/translator/ParseContext.cpp
index d849e19..9b84a3f 100644
--- a/src/compiler/translator/ParseContext.cpp
+++ b/src/compiler/translator/ParseContext.cpp
@@ -113,6 +113,7 @@
mMaxImageUnits(resources.MaxImageUnits),
mMaxCombinedTextureImageUnits(resources.MaxCombinedTextureImageUnits),
mMaxUniformLocations(resources.MaxUniformLocations),
+ mMaxUniformBufferBindings(resources.MaxUniformBufferBindings),
mDeclaringFunction(false)
{
mComputeShaderLocalSize.fill(-1);
@@ -1337,6 +1338,16 @@
}
}
+void TParseContext::checkBlockBindingIsValid(const TSourceLoc &location, int binding, int arraySize)
+{
+ int size = (arraySize == 0 ? 1 : arraySize);
+ if (binding + size > mMaxUniformBufferBindings)
+ {
+ error(location, "interface block binding greater than MAX_UNIFORM_BUFFER_BINDINGS",
+ "binding");
+ }
+}
+
void TParseContext::checkUniformLocationInRange(const TSourceLoc &location,
int objectLocationCount,
const TLayoutQualifier &layoutQualifier)
@@ -2771,8 +2782,22 @@
checkMemoryQualifierIsNotSpecified(typeQualifier.memoryQualifier, typeQualifier.line);
- // TODO(oetuaho): Remove this and support binding for blocks.
- checkBindingIsNotSpecified(typeQualifier.line, typeQualifier.layoutQualifier.binding);
+ // add array index
+ unsigned int arraySize = 0;
+ if (arrayIndex != nullptr)
+ {
+ arraySize = checkIsValidArraySize(arrayIndexLine, arrayIndex);
+ }
+
+ if (mShaderVersion < 310)
+ {
+ checkBindingIsNotSpecified(typeQualifier.line, typeQualifier.layoutQualifier.binding);
+ }
+ else
+ {
+ checkBlockBindingIsValid(typeQualifier.line, typeQualifier.layoutQualifier.binding,
+ arraySize);
+ }
checkYuvIsNotSpecified(typeQualifier.line, typeQualifier.layoutQualifier.yuv);
@@ -2832,6 +2857,7 @@
// check layout qualifiers
TLayoutQualifier fieldLayoutQualifier = fieldType->getLayoutQualifier();
checkLocationIsNotSpecified(field->line(), fieldLayoutQualifier);
+ checkBindingIsNotSpecified(field->line(), fieldLayoutQualifier.binding);
if (fieldLayoutQualifier.blockStorage != EbsUnspecified)
{
@@ -2853,13 +2879,6 @@
fieldType->setLayoutQualifier(fieldLayoutQualifier);
}
- // add array index
- unsigned int arraySize = 0;
- if (arrayIndex != nullptr)
- {
- arraySize = checkIsValidArraySize(arrayIndexLine, arrayIndex);
- }
-
TInterfaceBlock *interfaceBlock =
new TInterfaceBlock(&blockName, fieldList, instanceName, arraySize, blockLayoutQualifier);
TType interfaceBlockType(interfaceBlock, typeQualifier.qualifier, blockLayoutQualifier,