Program: clamp the number of uniforms to be copied
Reland with a temporary test suppression.
BUG=661413
Change-Id: I552b64de754b326dcd499b84d9f337b9d015dc8e
Reviewed-on: https://chromium-review.googlesource.com/411473
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/libANGLE/Program.cpp b/src/libANGLE/Program.cpp
index 424ce23..724bcf0 100644
--- a/src/libANGLE/Program.cpp
+++ b/src/libANGLE/Program.cpp
@@ -2848,12 +2848,18 @@
LinkedUniform *linkedUniform = &mState.mUniforms[locationInfo.index];
uint8_t *destPointer = linkedUniform->getDataPtrToElement(locationInfo.element);
+ // 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.element;
+ GLsizei clampedCount = std::min(
+ count, static_cast<GLsizei>(remainingElements * linkedUniform->getElementComponents()));
+
if (VariableComponentType(linkedUniform->type) == GL_BOOL)
{
// Do a cast conversion for boolean types. From the spec:
// "The uniform is set to FALSE if the input value is 0 or 0.0f, and set to TRUE otherwise."
GLint *destAsInt = reinterpret_cast<GLint *>(destPointer);
- for (GLsizei component = 0; component < count; ++component)
+ for (GLsizei component = 0; component < clampedCount; ++component)
{
destAsInt[component] = (v[component] != static_cast<T>(0) ? GL_TRUE : GL_FALSE);
}
@@ -2861,12 +2867,12 @@
else
{
// Invalide the validation cache if we modify the sampler data.
- if (linkedUniform->isSampler() && memcmp(destPointer, v, sizeof(T) * count) != 0)
+ if (linkedUniform->isSampler() && memcmp(destPointer, v, sizeof(T) * clampedCount) != 0)
{
mCachedValidateSamplersResult.reset();
}
- memcpy(destPointer, v, sizeof(T) * count);
+ memcpy(destPointer, v, sizeof(T) * clampedCount);
}
}
@@ -2886,7 +2892,13 @@
const VariableLocation &locationInfo = mState.mUniformLocations[location];
LinkedUniform *linkedUniform = &mState.mUniforms[locationInfo.index];
T *destPtr = reinterpret_cast<T *>(linkedUniform->getDataPtrToElement(locationInfo.element));
- for (GLsizei element = 0; element < count; ++element)
+
+ // 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.element;
+ GLsizei clampedCount = std::min(count, static_cast<GLsizei>(remainingElements));
+
+ for (GLsizei element = 0; element < clampedCount; ++element)
{
size_t elementOffset = element * rows * cols;