Support arrays of arrays in the API
The ShaderVariable class that is used as an interface between the
compiler and the rest of the code gets arrays of arrays support.
Array of array variables are passed from the compiler just like any
other variables. However, when stored in Program state each innermost
array constitutes a separate variable. This is done to make the
implementation match the GLES specification for program interface
query APIs.
This will be tested more fully once support for parsing arrays of
arrays lands in the compiler.
TEST=angle_end2end_tests, angle_unittests
BUG=angleproject:2125
Change-Id: I0f7159000f039be92a87a52b3b68cd9a215a21cb
Reviewed-on: https://chromium-review.googlesource.com/684742
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/Program.cpp b/src/libANGLE/Program.cpp
index c5a379c..9531c1f 100644
--- a/src/libANGLE/Program.cpp
+++ b/src/libANGLE/Program.cpp
@@ -106,7 +106,6 @@
}
}
-
template <typename VarT>
GLuint GetResourceIndexFromName(const std::vector<VarT> &list, const std::string &name)
{
@@ -1375,7 +1374,7 @@
CopyStringToBuffer(name, string, bufsize, length);
}
- *size = uniform.elementCount();
+ *size = clampCast<GLint>(uniform.getBasicTypeElementCount());
*type = uniform.type;
}
else
@@ -2078,12 +2077,13 @@
auto &imageUniform = mState.mUniforms[imageIndex];
if (imageUniform.binding == -1)
{
- mState.mImageBindings.emplace_back(ImageBinding(imageUniform.elementCount()));
+ mState.mImageBindings.emplace_back(
+ ImageBinding(imageUniform.getBasicTypeElementCount()));
}
else
{
mState.mImageBindings.emplace_back(
- ImageBinding(imageUniform.binding, imageUniform.elementCount()));
+ ImageBinding(imageUniform.binding, imageUniform.getBasicTypeElementCount()));
}
}
@@ -2103,7 +2103,7 @@
const auto &samplerUniform = mState.mUniforms[samplerIndex];
GLenum textureType = SamplerTypeToTextureType(samplerUniform.type);
mState.mSamplerBindings.emplace_back(
- SamplerBinding(textureType, samplerUniform.elementCount(), false));
+ SamplerBinding(textureType, samplerUniform.getBasicTypeElementCount(), false));
}
}
@@ -2455,7 +2455,7 @@
infoLog << "Types for " << variableName << " differ between vertex and fragment shaders";
return false;
}
- if (vertexVariable.arraySize != fragmentVariable.arraySize)
+ if (vertexVariable.arraySizes != fragmentVariable.arraySizes)
{
infoLog << "Array sizes for " << variableName << " differ between vertex and fragment shaders";
return false;
@@ -2649,8 +2649,12 @@
uniqueNames.insert(tfVaryingName);
// TODO(jmadill): Investigate implementation limits on D3D11
+
+ // GLSL ES 3.10 section 4.3.6: A vertex output can't be an array of arrays.
+ ASSERT(!varying->isArrayOfArrays());
size_t elementCount =
- ((varying->isArray() && subscripts.empty()) ? varying->elementCount() : 1);
+ ((varying->isArray() && subscripts.empty()) ? varying->getOutermostArraySize()
+ : 1);
size_t componentCount = VariableComponentCount(varying->type) * elementCount;
if (mState.mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS &&
componentCount > caps.maxTransformFeedbackSeparateComponents)
@@ -2786,8 +2790,11 @@
unsigned int baseLocation =
(outputVariable.location == -1 ? 0u
: static_cast<unsigned int>(outputVariable.location));
- for (unsigned int elementIndex = 0; elementIndex < outputVariable.elementCount();
- elementIndex++)
+
+ // GLSL ES 3.10 section 4.3.6: Output variables cannot be arrays of arrays or arrays of
+ // structures, so we may use getBasicTypeElementCount().
+ unsigned int elementCount = outputVariable.getBasicTypeElementCount();
+ for (unsigned int elementIndex = 0; elementIndex < elementCount; elementIndex++)
{
const unsigned int location = baseLocation + elementIndex;
if (location >= mState.mOutputVariableTypes.size())
@@ -2829,8 +2836,10 @@
(outputVariable.location == -1 ? 0u
: static_cast<unsigned int>(outputVariable.location));
- for (unsigned int elementIndex = 0; elementIndex < outputVariable.elementCount();
- elementIndex++)
+ // GLSL ES 3.10 section 4.3.6: Output variables cannot be arrays of arrays or arrays of
+ // structures, so we may use getBasicTypeElementCount().
+ unsigned int elementCount = outputVariable.getBasicTypeElementCount();
+ for (unsigned int elementIndex = 0; elementIndex < elementCount; elementIndex++)
{
const unsigned int location = baseLocation + elementIndex;
if (location >= mState.mOutputLocations.size())
@@ -2863,8 +2872,8 @@
GLint location = getUniformLocation(samplerUniform.name);
ASSERT(location != -1);
std::vector<GLint> boundTextureUnits;
- for (unsigned int elementIndex = 0; elementIndex < samplerUniform.elementCount();
- ++elementIndex)
+ for (unsigned int elementIndex = 0;
+ elementIndex < samplerUniform.getBasicTypeElementCount(); ++elementIndex)
{
boundTextureUnits.push_back(samplerUniform.binding + elementIndex);
}
@@ -2926,7 +2935,8 @@
// OpenGL ES 3.0.4 spec pg 67: "Values for any array element that exceeds the highest array
// element index used, as reported by GetActiveUniform, will be ignored by the GL."
- unsigned int remainingElements = linkedUniform.elementCount() - locationInfo.arrayIndex;
+ unsigned int remainingElements =
+ linkedUniform.getBasicTypeElementCount() - locationInfo.arrayIndex;
GLsizei maxElementCount =
static_cast<GLsizei>(remainingElements * linkedUniform.getElementComponents());
@@ -2955,7 +2965,8 @@
// OpenGL ES 3.0.4 spec pg 67: "Values for any array element that exceeds the highest array
// element index used, as reported by GetActiveUniform, will be ignored by the GL."
- unsigned int remainingElements = linkedUniform.elementCount() - locationInfo.arrayIndex;
+ unsigned int remainingElements =
+ linkedUniform.getBasicTypeElementCount() - locationInfo.arrayIndex;
return std::min(count, static_cast<GLsizei>(remainingElements));
}