Add getUniform impl methods.
This will let us remove some of the uniform data management code in
the GL front-end, and simplify the GL back-end. It will also enable
us to implement uniform data more efficiently in the D3D11 back-end,
and probably Vulkan back-end later.
This also implements a new impl method for the ProgramGL class to
flag optimized-out uniforms as no longer used, post-link. This is
important because otherwise the optimized uniforms get assigned
valid locations, and then the getUniform calls are expected to
succeed.
We also use a workaround for uniform value queries for the GL
back-end. It seems as though some drivers (seen on NVIDIA and AMD)
may not properly clamp to the maximum representable integer value
when querying out-of-range floating point values. Work around this by
always calling the driver with the proper type and then casting the
value in ANGLE.
BUG=angleproject:1390
Change-Id: I03dc2382e7af52455c356a2bf3971a4d1bd46ec6
Reviewed-on: https://chromium-review.googlesource.com/616785
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libANGLE/Context.cpp b/src/libANGLE/Context.cpp
index b84ba00..137b7c1 100644
--- a/src/libANGLE/Context.cpp
+++ b/src/libANGLE/Context.cpp
@@ -4516,14 +4516,14 @@
{
Program *programObject = getProgram(program);
ASSERT(programObject);
- programObject->getUniformfv(location, params);
+ programObject->getUniformfv(this, location, params);
}
void Context::getUniformiv(GLuint program, GLint location, GLint *params)
{
Program *programObject = getProgram(program);
ASSERT(programObject);
- programObject->getUniformiv(location, params);
+ programObject->getUniformiv(this, location, params);
}
GLint Context::getUniformLocation(GLuint program, const GLchar *name)
@@ -5073,7 +5073,7 @@
void Context::getUniformuiv(GLuint program, GLint location, GLuint *params)
{
const Program *programObject = getProgram(program);
- programObject->getUniformuiv(location, params);
+ programObject->getUniformuiv(this, location, params);
}
GLint Context::getFragDataLocation(GLuint program, const GLchar *name)
diff --git a/src/libANGLE/MemoryProgramCache.cpp b/src/libANGLE/MemoryProgramCache.cpp
index c8d92e5..b6c2d73 100644
--- a/src/libANGLE/MemoryProgramCache.cpp
+++ b/src/libANGLE/MemoryProgramCache.cpp
@@ -315,7 +315,9 @@
{
GLenum textureType = stream.readInt<GLenum>();
size_t bindingCount = stream.readInt<size_t>();
- state->mSamplerBindings.emplace_back(SamplerBinding(textureType, bindingCount));
+ bool unreferenced = stream.readBool();
+ state->mSamplerBindings.emplace_back(
+ SamplerBinding(textureType, bindingCount, unreferenced));
}
unsigned int imageRangeLow = stream.readInt<unsigned int>();
@@ -475,6 +477,7 @@
{
stream.writeInt(samplerBinding.textureType);
stream.writeInt(samplerBinding.boundTextureUnits.size());
+ stream.writeInt(samplerBinding.unreferenced);
}
stream.writeInt(state.getImageUniformRange().low());
diff --git a/src/libANGLE/Program.cpp b/src/libANGLE/Program.cpp
index 1f47b9d..cc37d2f 100644
--- a/src/libANGLE/Program.cpp
+++ b/src/libANGLE/Program.cpp
@@ -788,6 +788,19 @@
setUniformValuesFromBindingQualifiers();
+ // Mark implementation-specific unreferenced uniforms as ignored.
+ mProgram->markUnusedUniformLocations(&mState.mUniformLocations);
+
+ // Update sampler bindings with unreferenced uniforms.
+ for (const auto &location : mState.mUniformLocations)
+ {
+ if (!location.used && mState.isSamplerUniformIndex(location.index))
+ {
+ GLuint samplerIndex = mState.getSamplerIndexFromUniformIndex(location.index);
+ mState.mSamplerBindings[samplerIndex].unreferenced = true;
+ }
+ }
+
// Save to the program cache.
if (cache && (mState.mLinkedTransformFeedbackVaryings.empty() ||
!context->getWorkarounds().disableProgramCachingForTransformFeedback))
@@ -1444,19 +1457,55 @@
mProgram->setUniformMatrix4x3fv(location, clampedCount, transpose, v);
}
-void Program::getUniformfv(GLint location, GLfloat *v) const
+void Program::getUniformfv(const Context *context, GLint location, GLfloat *v) const
{
- getUniformInternal(location, v);
+ const auto &uniformLocation = mState.getUniformLocations()[location];
+ const auto &uniform = mState.getUniforms()[uniformLocation.index];
+
+ GLenum nativeType = gl::VariableComponentType(uniform.type);
+ if (nativeType == GL_FLOAT)
+ {
+ mProgram->getUniformfv(context, location, v);
+ }
+ else
+ {
+ getUniformInternal(context, v, location, nativeType,
+ gl::VariableComponentCount(uniform.type));
+ }
}
-void Program::getUniformiv(GLint location, GLint *v) const
+void Program::getUniformiv(const Context *context, GLint location, GLint *v) const
{
- getUniformInternal(location, v);
+ const auto &uniformLocation = mState.getUniformLocations()[location];
+ const auto &uniform = mState.getUniforms()[uniformLocation.index];
+
+ GLenum nativeType = gl::VariableComponentType(uniform.type);
+ if (nativeType == GL_INT || nativeType == GL_BOOL)
+ {
+ mProgram->getUniformiv(context, location, v);
+ }
+ else
+ {
+ getUniformInternal(context, v, location, nativeType,
+ gl::VariableComponentCount(uniform.type));
+ }
}
-void Program::getUniformuiv(GLint location, GLuint *v) const
+void Program::getUniformuiv(const Context *context, GLint location, GLuint *v) const
{
- getUniformInternal(location, v);
+ const auto &uniformLocation = mState.getUniformLocations()[location];
+ const auto &uniform = mState.getUniforms()[uniformLocation.index];
+
+ GLenum nativeType = gl::VariableComponentType(uniform.type);
+ if (nativeType == GL_UNSIGNED_INT)
+ {
+ mProgram->getUniformuiv(context, location, v);
+ }
+ else
+ {
+ getUniformInternal(context, v, location, nativeType,
+ gl::VariableComponentCount(uniform.type));
+ }
}
void Program::flagForDeletion()
@@ -1506,6 +1555,9 @@
// DrawArrays and DrawElements will issue the INVALID_OPERATION error.
for (const auto &samplerBinding : mState.mSamplerBindings)
{
+ if (samplerBinding.unreferenced)
+ continue;
+
GLenum textureType = samplerBinding.textureType;
for (GLuint textureUnit : samplerBinding.boundTextureUnits)
@@ -1876,7 +1928,7 @@
const auto &samplerUniform = mState.mUniforms[samplerIndex];
GLenum textureType = SamplerTypeToTextureType(samplerUniform.type);
mState.mSamplerBindings.emplace_back(
- SamplerBinding(textureType, samplerUniform.elementCount()));
+ SamplerBinding(textureType, samplerUniform.elementCount(), false));
}
}
@@ -2984,39 +3036,52 @@
return clampedCount;
}
+// Driver differences mean that doing the uniform value cast ourselves gives consistent results.
+// EG: on NVIDIA drivers, it was observed that getUniformi for MAX_INT+1 returned MIN_INT.
template <typename DestT>
-void Program::getUniformInternal(GLint location, DestT *dataOut) const
+void Program::getUniformInternal(const Context *context,
+ DestT *dataOut,
+ GLint location,
+ GLenum nativeType,
+ int components) const
{
- const VariableLocation &locationInfo = mState.mUniformLocations[location];
- const LinkedUniform &uniform = mState.mUniforms[locationInfo.index];
-
- const uint8_t *srcPointer = uniform.getDataPtrToElement(locationInfo.element);
-
- GLenum componentType = VariableComponentType(uniform.type);
- if (componentType == GLTypeToGLenum<DestT>::value)
+ switch (nativeType)
{
- memcpy(dataOut, srcPointer, uniform.getElementSize());
- return;
- }
-
- int components = VariableComponentCount(uniform.type);
-
- switch (componentType)
- {
- case GL_INT:
- UniformStateQueryCastLoop<GLint>(dataOut, srcPointer, components);
- break;
- case GL_UNSIGNED_INT:
- UniformStateQueryCastLoop<GLuint>(dataOut, srcPointer, components);
- break;
case GL_BOOL:
- UniformStateQueryCastLoop<GLboolean>(dataOut, srcPointer, components);
+ {
+ GLint tempValue[16] = {0};
+ mProgram->getUniformiv(context, location, tempValue);
+ UniformStateQueryCastLoop<GLboolean>(
+ dataOut, reinterpret_cast<const uint8_t *>(tempValue), components);
break;
+ }
+ case GL_INT:
+ {
+ GLint tempValue[16] = {0};
+ mProgram->getUniformiv(context, location, tempValue);
+ UniformStateQueryCastLoop<GLint>(dataOut, reinterpret_cast<const uint8_t *>(tempValue),
+ components);
+ break;
+ }
+ case GL_UNSIGNED_INT:
+ {
+ GLuint tempValue[16] = {0};
+ mProgram->getUniformuiv(context, location, tempValue);
+ UniformStateQueryCastLoop<GLuint>(dataOut, reinterpret_cast<const uint8_t *>(tempValue),
+ components);
+ break;
+ }
case GL_FLOAT:
- UniformStateQueryCastLoop<GLfloat>(dataOut, srcPointer, components);
+ {
+ GLfloat tempValue[16] = {0};
+ mProgram->getUniformfv(context, location, tempValue);
+ UniformStateQueryCastLoop<GLfloat>(
+ dataOut, reinterpret_cast<const uint8_t *>(tempValue), components);
break;
+ }
default:
UNREACHABLE();
+ break;
}
}
diff --git a/src/libANGLE/Program.h b/src/libANGLE/Program.h
index 3690fb7..fb97643 100644
--- a/src/libANGLE/Program.h
+++ b/src/libANGLE/Program.h
@@ -171,8 +171,8 @@
// This small structure encapsulates binding sampler uniforms to active GL textures.
struct SamplerBinding
{
- SamplerBinding(GLenum textureTypeIn, size_t elementCount)
- : textureType(textureTypeIn), boundTextureUnits(elementCount, 0)
+ SamplerBinding(GLenum textureTypeIn, size_t elementCount, bool unreferenced)
+ : textureType(textureTypeIn), boundTextureUnits(elementCount, 0), unreferenced(unreferenced)
{
}
@@ -181,6 +181,9 @@
// List of all textures bound to this sampler, of type textureType.
std::vector<GLuint> boundTextureUnits;
+
+ // A note if this sampler is an unreferenced uniform.
+ bool unreferenced;
};
// A varying with tranform feedback enabled. If it's an array, either the whole array or one of its
@@ -457,9 +460,9 @@
void setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
void setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
- void getUniformfv(GLint location, GLfloat *params) const;
- void getUniformiv(GLint location, GLint *params) const;
- void getUniformuiv(GLint location, GLuint *params) const;
+ void getUniformfv(const Context *context, GLint location, GLfloat *params) const;
+ void getUniformiv(const Context *context, GLint location, GLint *params) const;
+ void getUniformuiv(const Context *context, GLint location, GLuint *params) const;
void getActiveUniformBlockName(GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName) const;
GLuint getActiveUniformBlockCount() const;
@@ -627,7 +630,11 @@
const T *v);
template <typename DestT>
- void getUniformInternal(GLint location, DestT *dataOut) const;
+ void getUniformInternal(const Context *context,
+ DestT *dataOut,
+ GLint location,
+ GLenum nativeType,
+ int components) const;
ProgramState mState;
rx::ProgramImpl *mProgram;
diff --git a/src/libANGLE/renderer/ProgramImpl.h b/src/libANGLE/renderer/ProgramImpl.h
index d2b7118..b32b93b 100644
--- a/src/libANGLE/renderer/ProgramImpl.h
+++ b/src/libANGLE/renderer/ProgramImpl.h
@@ -72,6 +72,15 @@
virtual void setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) = 0;
virtual void setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) = 0;
+ // Done in the back-end to avoid having to keep a system copy of uniform data.
+ virtual void getUniformfv(const gl::Context *context,
+ GLint location,
+ GLfloat *params) const = 0;
+ virtual void getUniformiv(const gl::Context *context, GLint location, GLint *params) const = 0;
+ virtual void getUniformuiv(const gl::Context *context,
+ GLint location,
+ GLuint *params) const = 0;
+
// TODO: synchronize in syncState when dirty bits exist.
virtual void setUniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockBinding) = 0;
@@ -90,6 +99,11 @@
GLint components,
const GLfloat *coeffs) = 0;
+ // Implementation-specific method for ignoring unreferenced uniforms. Some implementations may
+ // perform more extensive analysis and ignore some locations that ANGLE doesn't detect as
+ // unreferenced. This method is not required to be overriden by a back-end.
+ virtual void markUnusedUniformLocations(std::vector<gl::VariableLocation> *uniformLocations) {}
+
protected:
const gl::ProgramState &mState;
};
diff --git a/src/libANGLE/renderer/ProgramImpl_mock.h b/src/libANGLE/renderer/ProgramImpl_mock.h
index 8883ca4..9587dbd 100644
--- a/src/libANGLE/renderer/ProgramImpl_mock.h
+++ b/src/libANGLE/renderer/ProgramImpl_mock.h
@@ -55,6 +55,10 @@
MOCK_METHOD4(setUniformMatrix3x4fv, void(GLint, GLsizei, GLboolean, const GLfloat *));
MOCK_METHOD4(setUniformMatrix4x3fv, void(GLint, GLsizei, GLboolean, const GLfloat *));
+ MOCK_CONST_METHOD3(getUniformfv, void(const gl::Context *, GLint, GLfloat *));
+ MOCK_CONST_METHOD3(getUniformiv, void(const gl::Context *, GLint, GLint *));
+ MOCK_CONST_METHOD3(getUniformuiv, void(const gl::Context *, GLint, GLuint *));
+
MOCK_METHOD2(setUniformBlockBinding, void(GLuint, GLuint));
MOCK_CONST_METHOD2(getUniformBlockSize, bool(const std::string &, size_t *));
MOCK_CONST_METHOD2(getUniformBlockMemberInfo, bool(const std::string &, sh::BlockMemberInfo *));
diff --git a/src/libANGLE/renderer/d3d/ProgramD3D.cpp b/src/libANGLE/renderer/d3d/ProgramD3D.cpp
index 3c4c432..dfe0665 100644
--- a/src/libANGLE/renderer/d3d/ProgramD3D.cpp
+++ b/src/libANGLE/renderer/d3d/ProgramD3D.cpp
@@ -18,6 +18,7 @@
#include "libANGLE/VaryingPacking.h"
#include "libANGLE/VertexArray.h"
#include "libANGLE/features.h"
+#include "libANGLE/queryconversions.h"
#include "libANGLE/renderer/ContextImpl.h"
#include "libANGLE/renderer/d3d/DynamicHLSL.h"
#include "libANGLE/renderer/d3d/FramebufferD3D.h"
@@ -2602,4 +2603,29 @@
return false;
}
+template <typename DestT>
+void ProgramD3D::getUniformInternal(GLint location, DestT *dataOut) const
+{
+ const gl::VariableLocation &locationInfo = mState.getUniformLocations()[location];
+ const gl::LinkedUniform &uniform = mState.getUniforms()[locationInfo.index];
+
+ const uint8_t *srcPointer = uniform.getDataPtrToElement(locationInfo.element);
+ memcpy(dataOut, srcPointer, uniform.getElementSize());
+}
+
+void ProgramD3D::getUniformfv(const gl::Context *context, GLint location, GLfloat *params) const
+{
+ getUniformInternal(location, params);
+}
+
+void ProgramD3D::getUniformiv(const gl::Context *context, GLint location, GLint *params) const
+{
+ getUniformInternal(location, params);
+}
+
+void ProgramD3D::getUniformuiv(const gl::Context *context, GLint location, GLuint *params) const
+{
+ getUniformInternal(location, params);
+}
+
} // namespace rx
diff --git a/src/libANGLE/renderer/d3d/ProgramD3D.h b/src/libANGLE/renderer/d3d/ProgramD3D.h
index bc27b31..eb24bbc 100644
--- a/src/libANGLE/renderer/d3d/ProgramD3D.h
+++ b/src/libANGLE/renderer/d3d/ProgramD3D.h
@@ -247,6 +247,10 @@
GLboolean transpose,
const GLfloat *value);
+ void getUniformfv(const gl::Context *context, GLint location, GLfloat *params) const override;
+ void getUniformiv(const gl::Context *context, GLint location, GLint *params) const override;
+ void getUniformuiv(const gl::Context *context, GLint location, GLuint *params) const override;
+
void setUniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockBinding) override;
UniformStorageD3D &getVertexUniformStorage() const { return *mVertexUniformStorage.get(); }
@@ -360,6 +364,9 @@
std::vector<Sampler> &outSamplers,
GLuint *outUsedRange);
+ template <typename DestT>
+ void getUniformInternal(GLint location, DestT *dataOut) const;
+
template <typename T>
void setUniform(GLint location, GLsizei count, const T *v, GLenum targetUniformType);
diff --git a/src/libANGLE/renderer/gl/ProgramGL.cpp b/src/libANGLE/renderer/gl/ProgramGL.cpp
index 3c1fe40..2e3c64b 100644
--- a/src/libANGLE/renderer/gl/ProgramGL.cpp
+++ b/src/libANGLE/renderer/gl/ProgramGL.cpp
@@ -753,4 +753,31 @@
baseViewIndex);
}
+void ProgramGL::getUniformfv(const gl::Context *context, GLint location, GLfloat *params) const
+{
+ mFunctions->getUniformfv(mProgramID, uniLoc(location), params);
+}
+
+void ProgramGL::getUniformiv(const gl::Context *context, GLint location, GLint *params) const
+{
+ mFunctions->getUniformiv(mProgramID, uniLoc(location), params);
+}
+
+void ProgramGL::getUniformuiv(const gl::Context *context, GLint location, GLuint *params) const
+{
+ mFunctions->getUniformuiv(mProgramID, uniLoc(location), params);
+}
+
+void ProgramGL::markUnusedUniformLocations(std::vector<gl::VariableLocation> *uniformLocations)
+{
+ GLint maxLocation = static_cast<GLint>(uniformLocations->size());
+ for (GLint location = 0; location < maxLocation; ++location)
+ {
+ if (uniLoc(location) == -1)
+ {
+ (*uniformLocations)[location].used = false;
+ }
+ }
+}
+
} // namespace rx
diff --git a/src/libANGLE/renderer/gl/ProgramGL.h b/src/libANGLE/renderer/gl/ProgramGL.h
index ea8acf8..01a20db 100644
--- a/src/libANGLE/renderer/gl/ProgramGL.h
+++ b/src/libANGLE/renderer/gl/ProgramGL.h
@@ -65,6 +65,10 @@
void setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) override;
void setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) override;
+ void getUniformfv(const gl::Context *context, GLint location, GLfloat *params) const override;
+ void getUniformiv(const gl::Context *context, GLint location, GLint *params) const override;
+ void getUniformuiv(const gl::Context *context, GLint location, GLuint *params) const override;
+
void setUniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockBinding) override;
bool getUniformBlockSize(const std::string &blockName, size_t *sizeOut) const override;
@@ -76,6 +80,8 @@
GLint components,
const GLfloat *coeffs) override;
+ void markUnusedUniformLocations(std::vector<gl::VariableLocation> *uniformLocations) override;
+
GLuint getProgramID() const;
void enableSideBySideRenderingPath() const;
diff --git a/src/libANGLE/renderer/null/ProgramNULL.cpp b/src/libANGLE/renderer/null/ProgramNULL.cpp
index cee30dd..1bdc09b 100644
--- a/src/libANGLE/renderer/null/ProgramNULL.cpp
+++ b/src/libANGLE/renderer/null/ProgramNULL.cpp
@@ -164,6 +164,21 @@
{
}
+void ProgramNULL::getUniformfv(const gl::Context *context, GLint location, GLfloat *params) const
+{
+ // TODO(jmadill): Write some values.
+}
+
+void ProgramNULL::getUniformiv(const gl::Context *context, GLint location, GLint *params) const
+{
+ // TODO(jmadill): Write some values.
+}
+
+void ProgramNULL::getUniformuiv(const gl::Context *context, GLint location, GLuint *params) const
+{
+ // TODO(jmadill): Write some values.
+}
+
void ProgramNULL::setUniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockBinding)
{
}
diff --git a/src/libANGLE/renderer/null/ProgramNULL.h b/src/libANGLE/renderer/null/ProgramNULL.h
index 363d334..b7c8d7f 100644
--- a/src/libANGLE/renderer/null/ProgramNULL.h
+++ b/src/libANGLE/renderer/null/ProgramNULL.h
@@ -82,6 +82,10 @@
GLboolean transpose,
const GLfloat *value) override;
+ void getUniformfv(const gl::Context *context, GLint location, GLfloat *params) const override;
+ void getUniformiv(const gl::Context *context, GLint location, GLint *params) const override;
+ void getUniformuiv(const gl::Context *context, GLint location, GLuint *params) const override;
+
// TODO: synchronize in syncState when dirty bits exist.
void setUniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockBinding) override;
diff --git a/src/libANGLE/renderer/vulkan/ProgramVk.cpp b/src/libANGLE/renderer/vulkan/ProgramVk.cpp
index 36cbb29..7f1bddd 100644
--- a/src/libANGLE/renderer/vulkan/ProgramVk.cpp
+++ b/src/libANGLE/renderer/vulkan/ProgramVk.cpp
@@ -312,4 +312,19 @@
return &mPipelineLayout;
}
+void ProgramVk::getUniformfv(const gl::Context *context, GLint location, GLfloat *params) const
+{
+ UNIMPLEMENTED();
+}
+
+void ProgramVk::getUniformiv(const gl::Context *context, GLint location, GLint *params) const
+{
+ UNIMPLEMENTED();
+}
+
+void ProgramVk::getUniformuiv(const gl::Context *context, GLint location, GLuint *params) const
+{
+ UNIMPLEMENTED();
+}
+
} // namespace rx
diff --git a/src/libANGLE/renderer/vulkan/ProgramVk.h b/src/libANGLE/renderer/vulkan/ProgramVk.h
index c24cc3f..50550c7 100644
--- a/src/libANGLE/renderer/vulkan/ProgramVk.h
+++ b/src/libANGLE/renderer/vulkan/ProgramVk.h
@@ -84,6 +84,10 @@
GLboolean transpose,
const GLfloat *value) override;
+ void getUniformfv(const gl::Context *context, GLint location, GLfloat *params) const override;
+ void getUniformiv(const gl::Context *context, GLint location, GLint *params) const override;
+ void getUniformuiv(const gl::Context *context, GLint location, GLuint *params) const override;
+
// TODO: synchronize in syncState when dirty bits exist.
void setUniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockBinding) override;
diff --git a/src/libGLESv2/entry_points_gles_2_0_ext.cpp b/src/libGLESv2/entry_points_gles_2_0_ext.cpp
index 11f5f13..0def420 100644
--- a/src/libGLESv2/entry_points_gles_2_0_ext.cpp
+++ b/src/libGLESv2/entry_points_gles_2_0_ext.cpp
@@ -458,7 +458,7 @@
Program *programObject = context->getProgram(program);
ASSERT(programObject);
- programObject->getUniformfv(location, params);
+ programObject->getUniformfv(context, location, params);
}
}
@@ -479,7 +479,7 @@
Program *programObject = context->getProgram(program);
ASSERT(programObject);
- programObject->getUniformiv(location, params);
+ programObject->getUniformiv(context, location, params);
}
}
@@ -2256,7 +2256,7 @@
Program *programObject = context->getProgram(program);
ASSERT(programObject);
- programObject->getUniformfv(location, params);
+ programObject->getUniformfv(context, location, params);
SetRobustLengthParam(length, writeLength);
}
}
@@ -2285,7 +2285,7 @@
Program *programObject = context->getProgram(program);
ASSERT(programObject);
- programObject->getUniformiv(location, params);
+ programObject->getUniformiv(context, location, params);
SetRobustLengthParam(length, writeLength);
}
}
@@ -2914,7 +2914,7 @@
Program *programObject = context->getProgram(program);
ASSERT(programObject);
- programObject->getUniformuiv(location, params);
+ programObject->getUniformuiv(context, location, params);
SetRobustLengthParam(length, writeLength);
}
}
diff --git a/src/tests/gl_tests/ComputeShaderTest.cpp b/src/tests/gl_tests/ComputeShaderTest.cpp
index f7326a2..7e677ee 100644
--- a/src/tests/gl_tests/ComputeShaderTest.cpp
+++ b/src/tests/gl_tests/ComputeShaderTest.cpp
@@ -77,11 +77,13 @@
ANGLE_GL_COMPUTE_PROGRAM(program, csSource);
- GLint uniformLoc = glGetUniformLocation(program.get(), "myUniformInt");
- EXPECT_NE(-1, uniformLoc);
+ // It's not possible to validate uniforms are present since they are unreferenced.
+ // TODO(jmadill): Make uniforms referenced.
+ // GLint uniformLoc = glGetUniformLocation(program.get(), "myUniformInt");
+ // EXPECT_NE(-1, uniformLoc);
- uniformLoc = glGetUniformLocation(program.get(), "myUniformSampler");
- EXPECT_NE(-1, uniformLoc);
+ // uniformLoc = glGetUniformLocation(program.get(), "myUniformSampler");
+ // EXPECT_NE(-1, uniformLoc);
EXPECT_GL_NO_ERROR();
}
diff --git a/src/tests/gl_tests/UniformTest.cpp b/src/tests/gl_tests/UniformTest.cpp
index 4ecc3d7..80534d0 100644
--- a/src/tests/gl_tests/UniformTest.cpp
+++ b/src/tests/gl_tests/UniformTest.cpp
@@ -43,6 +43,9 @@
" gl_FragColor = vec4(uniF + float(uniI));\n"
" gl_FragColor += vec4(uniB ? 1.0 : 0.0);\n"
" gl_FragColor += vec4(uniBArr[0] ? 1.0 : 0.0);\n"
+ " gl_FragColor += vec4(uniBArr[1] ? 1.0 : 0.0);\n"
+ " gl_FragColor += vec4(uniBArr[2] ? 1.0 : 0.0);\n"
+ " gl_FragColor += vec4(uniBArr[3] ? 1.0 : 0.0);\n"
"}";
mProgram = CompileProgram(vertexShader, fragShader);
@@ -235,6 +238,11 @@
// Test that integer to float GetUniform rounds values correctly.
TEST_P(UniformTest, IntUniformStateQuery)
{
+ // Qualcomm seems to have a bug where integer uniforms are internally stored as float, and
+ // large values are rounded to the nearest float representation of an integer.
+ // TODO(jmadill): Lift this suppression when/if the bug is fixed.
+ ANGLE_SKIP_TEST_IF(IsAndroid() && IsOpenGLES());
+
std::vector<GLint> inValues;
std::vector<GLint> expectedIValues;
std::vector<GLfloat> expectedFValues;
@@ -266,10 +274,10 @@
GLint expectedValue = expectedIValues[index];
glUniform1i(mUniformILocation, inValue);
- GLint testValue;
+ GLint testValue = 1234567;
glGetUniformiv(mProgram, mUniformILocation, &testValue);
ASSERT_GL_NO_ERROR();
- EXPECT_EQ(expectedValue, testValue);
+ EXPECT_EQ(expectedValue, testValue) << " with glGetUniformiv";
}
for (size_t index = 0; index < inValues.size(); ++index)
@@ -278,10 +286,10 @@
GLfloat expectedValue = expectedFValues[index];
glUniform1i(mUniformILocation, inValue);
- GLfloat testValue;
+ GLfloat testValue = 124567.0;
glGetUniformfv(mProgram, mUniformILocation, &testValue);
ASSERT_GL_NO_ERROR();
- EXPECT_EQ(expectedValue, testValue);
+ EXPECT_EQ(expectedValue, testValue) << " with glGetUniformfv";
}
}
@@ -343,6 +351,11 @@
glGetUniformLocation(mProgram, "uniBArr[3]"),
};
+ for (int i = 0; i < 4; ++i)
+ {
+ ASSERT_NE(-1, locations[i]) << " with i=" << i;
+ }
+
// Calling Uniform1iv
glUniform1iv(locations[0], 4, boolValuesi);
@@ -350,14 +363,14 @@
{
int value = -1;
glGetUniformiv(mProgram, locations[idx], &value);
- EXPECT_EQ(boolValuesi[idx], value);
+ EXPECT_EQ(boolValuesi[idx], value) << " with Uniform1iv/GetUniformiv at " << idx;
}
for (unsigned int idx = 0; idx < 4; ++idx)
{
float value = -1.0f;
glGetUniformfv(mProgram, locations[idx], &value);
- EXPECT_EQ(boolValuesf[idx], value);
+ EXPECT_EQ(boolValuesf[idx], value) << " with Uniform1iv/GetUniformfv at " << idx;
}
// Calling Uniform1fv
@@ -367,14 +380,14 @@
{
int value = -1;
glGetUniformiv(mProgram, locations[idx], &value);
- EXPECT_EQ(boolValuesi[idx], value);
+ EXPECT_EQ(boolValuesi[idx], value) << " with Uniform1fv/GetUniformiv at " << idx;
}
for (unsigned int idx = 0; idx < 4; ++idx)
{
float value = -1.0f;
glGetUniformfv(mProgram, locations[idx], &value);
- EXPECT_EQ(boolValuesf[idx], value);
+ EXPECT_EQ(boolValuesf[idx], value) << " with Uniform1fv/GetUniformfv at " << idx;
}
ASSERT_GL_NO_ERROR();
@@ -415,6 +428,10 @@
"out vec4 color;\n"
"void main() {\n"
" color = vec4(uniMat3x2[0][0][0]);\n"
+ " color += vec4(uniMat3x2[1][0][0]);\n"
+ " color += vec4(uniMat3x2[2][0][0]);\n"
+ " color += vec4(uniMat3x2[3][0][0]);\n"
+ " color += vec4(uniMat3x2[4][0][0]);\n"
"}";
mProgram = CompileProgram(vertexShader, fragShader);
@@ -474,6 +491,10 @@
"out vec4 color;\n"
"void main() {\n"
" color = vec4(uniMat3x2[0][0][0] + uniF[0]);\n"
+ " color = vec4(uniMat3x2[1][0][0] + uniF[1]);\n"
+ " color = vec4(uniMat3x2[2][0][0] + uniF[2]);\n"
+ " color = vec4(uniMat3x2[3][0][0] + uniF[3]);\n"
+ " color = vec4(uniMat3x2[4][0][0] + uniF[4]);\n"
"}";
mProgram = CompileProgram(vertexShader, fragShader);