Commit 54164b0c by Jamie Madill Committed by Commit Bot

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: 's avatarGeoff Lang <geofflang@chromium.org>
parent ff161f83
...@@ -4516,14 +4516,14 @@ void Context::getUniformfv(GLuint program, GLint location, GLfloat *params) ...@@ -4516,14 +4516,14 @@ void Context::getUniformfv(GLuint program, GLint location, GLfloat *params)
{ {
Program *programObject = getProgram(program); Program *programObject = getProgram(program);
ASSERT(programObject); ASSERT(programObject);
programObject->getUniformfv(location, params); programObject->getUniformfv(this, location, params);
} }
void Context::getUniformiv(GLuint program, GLint location, GLint *params) void Context::getUniformiv(GLuint program, GLint location, GLint *params)
{ {
Program *programObject = getProgram(program); Program *programObject = getProgram(program);
ASSERT(programObject); ASSERT(programObject);
programObject->getUniformiv(location, params); programObject->getUniformiv(this, location, params);
} }
GLint Context::getUniformLocation(GLuint program, const GLchar *name) GLint Context::getUniformLocation(GLuint program, const GLchar *name)
...@@ -5073,7 +5073,7 @@ void Context::resumeTransformFeedback() ...@@ -5073,7 +5073,7 @@ void Context::resumeTransformFeedback()
void Context::getUniformuiv(GLuint program, GLint location, GLuint *params) void Context::getUniformuiv(GLuint program, GLint location, GLuint *params)
{ {
const Program *programObject = getProgram(program); const Program *programObject = getProgram(program);
programObject->getUniformuiv(location, params); programObject->getUniformuiv(this, location, params);
} }
GLint Context::getFragDataLocation(GLuint program, const GLchar *name) GLint Context::getFragDataLocation(GLuint program, const GLchar *name)
......
...@@ -315,7 +315,9 @@ LinkResult MemoryProgramCache::Deserialize(const Context *context, ...@@ -315,7 +315,9 @@ LinkResult MemoryProgramCache::Deserialize(const Context *context,
{ {
GLenum textureType = stream.readInt<GLenum>(); GLenum textureType = stream.readInt<GLenum>();
size_t bindingCount = stream.readInt<size_t>(); 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>(); unsigned int imageRangeLow = stream.readInt<unsigned int>();
...@@ -475,6 +477,7 @@ void MemoryProgramCache::Serialize(const Context *context, ...@@ -475,6 +477,7 @@ void MemoryProgramCache::Serialize(const Context *context,
{ {
stream.writeInt(samplerBinding.textureType); stream.writeInt(samplerBinding.textureType);
stream.writeInt(samplerBinding.boundTextureUnits.size()); stream.writeInt(samplerBinding.boundTextureUnits.size());
stream.writeInt(samplerBinding.unreferenced);
} }
stream.writeInt(state.getImageUniformRange().low()); stream.writeInt(state.getImageUniformRange().low());
......
...@@ -788,6 +788,19 @@ Error Program::link(const gl::Context *context) ...@@ -788,6 +788,19 @@ Error Program::link(const gl::Context *context)
setUniformValuesFromBindingQualifiers(); 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. // Save to the program cache.
if (cache && (mState.mLinkedTransformFeedbackVaryings.empty() || if (cache && (mState.mLinkedTransformFeedbackVaryings.empty() ||
!context->getWorkarounds().disableProgramCachingForTransformFeedback)) !context->getWorkarounds().disableProgramCachingForTransformFeedback))
...@@ -1444,19 +1457,55 @@ void Program::setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean tra ...@@ -1444,19 +1457,55 @@ void Program::setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean tra
mProgram->setUniformMatrix4x3fv(location, clampedCount, transpose, v); 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() void Program::flagForDeletion()
...@@ -1506,6 +1555,9 @@ bool Program::validateSamplers(InfoLog *infoLog, const Caps &caps) ...@@ -1506,6 +1555,9 @@ bool Program::validateSamplers(InfoLog *infoLog, const Caps &caps)
// DrawArrays and DrawElements will issue the INVALID_OPERATION error. // DrawArrays and DrawElements will issue the INVALID_OPERATION error.
for (const auto &samplerBinding : mState.mSamplerBindings) for (const auto &samplerBinding : mState.mSamplerBindings)
{ {
if (samplerBinding.unreferenced)
continue;
GLenum textureType = samplerBinding.textureType; GLenum textureType = samplerBinding.textureType;
for (GLuint textureUnit : samplerBinding.boundTextureUnits) for (GLuint textureUnit : samplerBinding.boundTextureUnits)
...@@ -1876,7 +1928,7 @@ void Program::linkSamplerAndImageBindings() ...@@ -1876,7 +1928,7 @@ void Program::linkSamplerAndImageBindings()
const auto &samplerUniform = mState.mUniforms[samplerIndex]; const auto &samplerUniform = mState.mUniforms[samplerIndex];
GLenum textureType = SamplerTypeToTextureType(samplerUniform.type); GLenum textureType = SamplerTypeToTextureType(samplerUniform.type);
mState.mSamplerBindings.emplace_back( mState.mSamplerBindings.emplace_back(
SamplerBinding(textureType, samplerUniform.elementCount())); SamplerBinding(textureType, samplerUniform.elementCount(), false));
} }
} }
...@@ -2984,39 +3036,52 @@ GLsizei Program::setMatrixUniformInternal(GLint location, ...@@ -2984,39 +3036,52 @@ GLsizei Program::setMatrixUniformInternal(GLint location,
return clampedCount; 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> 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]; switch (nativeType)
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)
{
memcpy(dataOut, srcPointer, uniform.getElementSize());
return;
}
int components = VariableComponentCount(uniform.type);
switch (componentType)
{ {
case GL_BOOL:
{
GLint tempValue[16] = {0};
mProgram->getUniformiv(context, location, tempValue);
UniformStateQueryCastLoop<GLboolean>(
dataOut, reinterpret_cast<const uint8_t *>(tempValue), components);
break;
}
case GL_INT: case GL_INT:
UniformStateQueryCastLoop<GLint>(dataOut, srcPointer, components); {
GLint tempValue[16] = {0};
mProgram->getUniformiv(context, location, tempValue);
UniformStateQueryCastLoop<GLint>(dataOut, reinterpret_cast<const uint8_t *>(tempValue),
components);
break; break;
}
case GL_UNSIGNED_INT: case GL_UNSIGNED_INT:
UniformStateQueryCastLoop<GLuint>(dataOut, srcPointer, components); {
break; GLuint tempValue[16] = {0};
case GL_BOOL: mProgram->getUniformuiv(context, location, tempValue);
UniformStateQueryCastLoop<GLboolean>(dataOut, srcPointer, components); UniformStateQueryCastLoop<GLuint>(dataOut, reinterpret_cast<const uint8_t *>(tempValue),
components);
break; break;
}
case GL_FLOAT: 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; break;
}
default: default:
UNREACHABLE(); UNREACHABLE();
break;
} }
} }
......
...@@ -171,8 +171,8 @@ struct BindingInfo ...@@ -171,8 +171,8 @@ struct BindingInfo
// This small structure encapsulates binding sampler uniforms to active GL textures. // This small structure encapsulates binding sampler uniforms to active GL textures.
struct SamplerBinding struct SamplerBinding
{ {
SamplerBinding(GLenum textureTypeIn, size_t elementCount) SamplerBinding(GLenum textureTypeIn, size_t elementCount, bool unreferenced)
: textureType(textureTypeIn), boundTextureUnits(elementCount, 0) : textureType(textureTypeIn), boundTextureUnits(elementCount, 0), unreferenced(unreferenced)
{ {
} }
...@@ -181,6 +181,9 @@ struct SamplerBinding ...@@ -181,6 +181,9 @@ struct SamplerBinding
// List of all textures bound to this sampler, of type textureType. // List of all textures bound to this sampler, of type textureType.
std::vector<GLuint> boundTextureUnits; 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 // A varying with tranform feedback enabled. If it's an array, either the whole array or one of its
...@@ -457,9 +460,9 @@ class Program final : angle::NonCopyable, public LabeledObject ...@@ -457,9 +460,9 @@ class Program final : angle::NonCopyable, public LabeledObject
void setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); void setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
void setUniformMatrix4x3fv(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 getUniformfv(const Context *context, GLint location, GLfloat *params) const;
void getUniformiv(GLint location, GLint *params) const; void getUniformiv(const Context *context, GLint location, GLint *params) const;
void getUniformuiv(GLint location, GLuint *params) const; void getUniformuiv(const Context *context, GLint location, GLuint *params) const;
void getActiveUniformBlockName(GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName) const; void getActiveUniformBlockName(GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName) const;
GLuint getActiveUniformBlockCount() const; GLuint getActiveUniformBlockCount() const;
...@@ -627,7 +630,11 @@ class Program final : angle::NonCopyable, public LabeledObject ...@@ -627,7 +630,11 @@ class Program final : angle::NonCopyable, public LabeledObject
const T *v); const T *v);
template <typename DestT> 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; ProgramState mState;
rx::ProgramImpl *mProgram; rx::ProgramImpl *mProgram;
......
...@@ -72,6 +72,15 @@ class ProgramImpl : angle::NonCopyable ...@@ -72,6 +72,15 @@ class ProgramImpl : angle::NonCopyable
virtual void setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) = 0; 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; 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. // TODO: synchronize in syncState when dirty bits exist.
virtual void setUniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockBinding) = 0; virtual void setUniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockBinding) = 0;
...@@ -90,6 +99,11 @@ class ProgramImpl : angle::NonCopyable ...@@ -90,6 +99,11 @@ class ProgramImpl : angle::NonCopyable
GLint components, GLint components,
const GLfloat *coeffs) = 0; 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: protected:
const gl::ProgramState &mState; const gl::ProgramState &mState;
}; };
......
...@@ -55,6 +55,10 @@ class MockProgramImpl : public rx::ProgramImpl ...@@ -55,6 +55,10 @@ class MockProgramImpl : public rx::ProgramImpl
MOCK_METHOD4(setUniformMatrix3x4fv, void(GLint, GLsizei, GLboolean, const GLfloat *)); MOCK_METHOD4(setUniformMatrix3x4fv, void(GLint, GLsizei, GLboolean, const GLfloat *));
MOCK_METHOD4(setUniformMatrix4x3fv, 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_METHOD2(setUniformBlockBinding, void(GLuint, GLuint));
MOCK_CONST_METHOD2(getUniformBlockSize, bool(const std::string &, size_t *)); MOCK_CONST_METHOD2(getUniformBlockSize, bool(const std::string &, size_t *));
MOCK_CONST_METHOD2(getUniformBlockMemberInfo, bool(const std::string &, sh::BlockMemberInfo *)); MOCK_CONST_METHOD2(getUniformBlockMemberInfo, bool(const std::string &, sh::BlockMemberInfo *));
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "libANGLE/VaryingPacking.h" #include "libANGLE/VaryingPacking.h"
#include "libANGLE/VertexArray.h" #include "libANGLE/VertexArray.h"
#include "libANGLE/features.h" #include "libANGLE/features.h"
#include "libANGLE/queryconversions.h"
#include "libANGLE/renderer/ContextImpl.h" #include "libANGLE/renderer/ContextImpl.h"
#include "libANGLE/renderer/d3d/DynamicHLSL.h" #include "libANGLE/renderer/d3d/DynamicHLSL.h"
#include "libANGLE/renderer/d3d/FramebufferD3D.h" #include "libANGLE/renderer/d3d/FramebufferD3D.h"
...@@ -2602,4 +2603,29 @@ bool ProgramD3D::hasPixelExecutableForCachedOutputLayout() ...@@ -2602,4 +2603,29 @@ bool ProgramD3D::hasPixelExecutableForCachedOutputLayout()
return false; 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 } // namespace rx
...@@ -247,6 +247,10 @@ class ProgramD3D : public ProgramImpl ...@@ -247,6 +247,10 @@ class ProgramD3D : public ProgramImpl
GLboolean transpose, GLboolean transpose,
const GLfloat *value); 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; void setUniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockBinding) override;
UniformStorageD3D &getVertexUniformStorage() const { return *mVertexUniformStorage.get(); } UniformStorageD3D &getVertexUniformStorage() const { return *mVertexUniformStorage.get(); }
...@@ -360,6 +364,9 @@ class ProgramD3D : public ProgramImpl ...@@ -360,6 +364,9 @@ class ProgramD3D : public ProgramImpl
std::vector<Sampler> &outSamplers, std::vector<Sampler> &outSamplers,
GLuint *outUsedRange); GLuint *outUsedRange);
template <typename DestT>
void getUniformInternal(GLint location, DestT *dataOut) const;
template <typename T> template <typename T>
void setUniform(GLint location, GLsizei count, const T *v, GLenum targetUniformType); void setUniform(GLint location, GLsizei count, const T *v, GLenum targetUniformType);
......
...@@ -753,4 +753,31 @@ void ProgramGL::enableLayeredRenderingPath(int baseViewIndex) const ...@@ -753,4 +753,31 @@ void ProgramGL::enableLayeredRenderingPath(int baseViewIndex) const
baseViewIndex); 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 } // namespace rx
...@@ -65,6 +65,10 @@ class ProgramGL : public ProgramImpl ...@@ -65,6 +65,10 @@ class ProgramGL : public ProgramImpl
void setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) override; 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 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; void setUniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockBinding) override;
bool getUniformBlockSize(const std::string &blockName, size_t *sizeOut) const override; bool getUniformBlockSize(const std::string &blockName, size_t *sizeOut) const override;
...@@ -76,6 +80,8 @@ class ProgramGL : public ProgramImpl ...@@ -76,6 +80,8 @@ class ProgramGL : public ProgramImpl
GLint components, GLint components,
const GLfloat *coeffs) override; const GLfloat *coeffs) override;
void markUnusedUniformLocations(std::vector<gl::VariableLocation> *uniformLocations) override;
GLuint getProgramID() const; GLuint getProgramID() const;
void enableSideBySideRenderingPath() const; void enableSideBySideRenderingPath() const;
......
...@@ -164,6 +164,21 @@ void ProgramNULL::setUniformMatrix4x3fv(GLint location, ...@@ -164,6 +164,21 @@ void ProgramNULL::setUniformMatrix4x3fv(GLint location,
{ {
} }
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) void ProgramNULL::setUniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockBinding)
{ {
} }
......
...@@ -82,6 +82,10 @@ class ProgramNULL : public ProgramImpl ...@@ -82,6 +82,10 @@ class ProgramNULL : public ProgramImpl
GLboolean transpose, GLboolean transpose,
const GLfloat *value) override; 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. // TODO: synchronize in syncState when dirty bits exist.
void setUniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockBinding) override; void setUniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockBinding) override;
......
...@@ -312,4 +312,19 @@ gl::ErrorOrResult<vk::PipelineLayout *> ProgramVk::getPipelineLayout(VkDevice de ...@@ -312,4 +312,19 @@ gl::ErrorOrResult<vk::PipelineLayout *> ProgramVk::getPipelineLayout(VkDevice de
return &mPipelineLayout; 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 } // namespace rx
...@@ -84,6 +84,10 @@ class ProgramVk : public ProgramImpl ...@@ -84,6 +84,10 @@ class ProgramVk : public ProgramImpl
GLboolean transpose, GLboolean transpose,
const GLfloat *value) override; 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. // TODO: synchronize in syncState when dirty bits exist.
void setUniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockBinding) override; void setUniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockBinding) override;
......
...@@ -458,7 +458,7 @@ void GL_APIENTRY GetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSiz ...@@ -458,7 +458,7 @@ void GL_APIENTRY GetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSiz
Program *programObject = context->getProgram(program); Program *programObject = context->getProgram(program);
ASSERT(programObject); ASSERT(programObject);
programObject->getUniformfv(location, params); programObject->getUniformfv(context, location, params);
} }
} }
...@@ -479,7 +479,7 @@ void GL_APIENTRY GetnUniformivEXT(GLuint program, GLint location, GLsizei bufSiz ...@@ -479,7 +479,7 @@ void GL_APIENTRY GetnUniformivEXT(GLuint program, GLint location, GLsizei bufSiz
Program *programObject = context->getProgram(program); Program *programObject = context->getProgram(program);
ASSERT(programObject); ASSERT(programObject);
programObject->getUniformiv(location, params); programObject->getUniformiv(context, location, params);
} }
} }
...@@ -2256,7 +2256,7 @@ ANGLE_EXPORT void GL_APIENTRY GetUniformfvRobustANGLE(GLuint program, ...@@ -2256,7 +2256,7 @@ ANGLE_EXPORT void GL_APIENTRY GetUniformfvRobustANGLE(GLuint program,
Program *programObject = context->getProgram(program); Program *programObject = context->getProgram(program);
ASSERT(programObject); ASSERT(programObject);
programObject->getUniformfv(location, params); programObject->getUniformfv(context, location, params);
SetRobustLengthParam(length, writeLength); SetRobustLengthParam(length, writeLength);
} }
} }
...@@ -2285,7 +2285,7 @@ ANGLE_EXPORT void GL_APIENTRY GetUniformivRobustANGLE(GLuint program, ...@@ -2285,7 +2285,7 @@ ANGLE_EXPORT void GL_APIENTRY GetUniformivRobustANGLE(GLuint program,
Program *programObject = context->getProgram(program); Program *programObject = context->getProgram(program);
ASSERT(programObject); ASSERT(programObject);
programObject->getUniformiv(location, params); programObject->getUniformiv(context, location, params);
SetRobustLengthParam(length, writeLength); SetRobustLengthParam(length, writeLength);
} }
} }
...@@ -2914,7 +2914,7 @@ ANGLE_EXPORT void GL_APIENTRY GetUniformuivRobustANGLE(GLuint program, ...@@ -2914,7 +2914,7 @@ ANGLE_EXPORT void GL_APIENTRY GetUniformuivRobustANGLE(GLuint program,
Program *programObject = context->getProgram(program); Program *programObject = context->getProgram(program);
ASSERT(programObject); ASSERT(programObject);
programObject->getUniformuiv(location, params); programObject->getUniformuiv(context, location, params);
SetRobustLengthParam(length, writeLength); SetRobustLengthParam(length, writeLength);
} }
} }
......
...@@ -77,11 +77,13 @@ TEST_P(ComputeShaderTest, LinkComputeProgramWithUniforms) ...@@ -77,11 +77,13 @@ TEST_P(ComputeShaderTest, LinkComputeProgramWithUniforms)
ANGLE_GL_COMPUTE_PROGRAM(program, csSource); ANGLE_GL_COMPUTE_PROGRAM(program, csSource);
GLint uniformLoc = glGetUniformLocation(program.get(), "myUniformInt"); // It's not possible to validate uniforms are present since they are unreferenced.
EXPECT_NE(-1, uniformLoc); // TODO(jmadill): Make uniforms referenced.
// GLint uniformLoc = glGetUniformLocation(program.get(), "myUniformInt");
// EXPECT_NE(-1, uniformLoc);
uniformLoc = glGetUniformLocation(program.get(), "myUniformSampler"); // uniformLoc = glGetUniformLocation(program.get(), "myUniformSampler");
EXPECT_NE(-1, uniformLoc); // EXPECT_NE(-1, uniformLoc);
EXPECT_GL_NO_ERROR(); EXPECT_GL_NO_ERROR();
} }
......
...@@ -43,6 +43,9 @@ class UniformTest : public ANGLETest ...@@ -43,6 +43,9 @@ class UniformTest : public ANGLETest
" gl_FragColor = vec4(uniF + float(uniI));\n" " gl_FragColor = vec4(uniF + float(uniI));\n"
" gl_FragColor += vec4(uniB ? 1.0 : 0.0);\n" " gl_FragColor += vec4(uniB ? 1.0 : 0.0);\n"
" gl_FragColor += vec4(uniBArr[0] ? 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); mProgram = CompileProgram(vertexShader, fragShader);
...@@ -235,6 +238,11 @@ TEST_P(UniformTest, FloatUniformStateQuery) ...@@ -235,6 +238,11 @@ TEST_P(UniformTest, FloatUniformStateQuery)
// Test that integer to float GetUniform rounds values correctly. // Test that integer to float GetUniform rounds values correctly.
TEST_P(UniformTest, IntUniformStateQuery) 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> inValues;
std::vector<GLint> expectedIValues; std::vector<GLint> expectedIValues;
std::vector<GLfloat> expectedFValues; std::vector<GLfloat> expectedFValues;
...@@ -266,10 +274,10 @@ TEST_P(UniformTest, IntUniformStateQuery) ...@@ -266,10 +274,10 @@ TEST_P(UniformTest, IntUniformStateQuery)
GLint expectedValue = expectedIValues[index]; GLint expectedValue = expectedIValues[index];
glUniform1i(mUniformILocation, inValue); glUniform1i(mUniformILocation, inValue);
GLint testValue; GLint testValue = 1234567;
glGetUniformiv(mProgram, mUniformILocation, &testValue); glGetUniformiv(mProgram, mUniformILocation, &testValue);
ASSERT_GL_NO_ERROR(); ASSERT_GL_NO_ERROR();
EXPECT_EQ(expectedValue, testValue); EXPECT_EQ(expectedValue, testValue) << " with glGetUniformiv";
} }
for (size_t index = 0; index < inValues.size(); ++index) for (size_t index = 0; index < inValues.size(); ++index)
...@@ -278,10 +286,10 @@ TEST_P(UniformTest, IntUniformStateQuery) ...@@ -278,10 +286,10 @@ TEST_P(UniformTest, IntUniformStateQuery)
GLfloat expectedValue = expectedFValues[index]; GLfloat expectedValue = expectedFValues[index];
glUniform1i(mUniformILocation, inValue); glUniform1i(mUniformILocation, inValue);
GLfloat testValue; GLfloat testValue = 124567.0;
glGetUniformfv(mProgram, mUniformILocation, &testValue); glGetUniformfv(mProgram, mUniformILocation, &testValue);
ASSERT_GL_NO_ERROR(); ASSERT_GL_NO_ERROR();
EXPECT_EQ(expectedValue, testValue); EXPECT_EQ(expectedValue, testValue) << " with glGetUniformfv";
} }
} }
...@@ -343,6 +351,11 @@ TEST_P(UniformTest, BooleanArrayUniformStateQuery) ...@@ -343,6 +351,11 @@ TEST_P(UniformTest, BooleanArrayUniformStateQuery)
glGetUniformLocation(mProgram, "uniBArr[3]"), glGetUniformLocation(mProgram, "uniBArr[3]"),
}; };
for (int i = 0; i < 4; ++i)
{
ASSERT_NE(-1, locations[i]) << " with i=" << i;
}
// Calling Uniform1iv // Calling Uniform1iv
glUniform1iv(locations[0], 4, boolValuesi); glUniform1iv(locations[0], 4, boolValuesi);
...@@ -350,14 +363,14 @@ TEST_P(UniformTest, BooleanArrayUniformStateQuery) ...@@ -350,14 +363,14 @@ TEST_P(UniformTest, BooleanArrayUniformStateQuery)
{ {
int value = -1; int value = -1;
glGetUniformiv(mProgram, locations[idx], &value); 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) for (unsigned int idx = 0; idx < 4; ++idx)
{ {
float value = -1.0f; float value = -1.0f;
glGetUniformfv(mProgram, locations[idx], &value); glGetUniformfv(mProgram, locations[idx], &value);
EXPECT_EQ(boolValuesf[idx], value); EXPECT_EQ(boolValuesf[idx], value) << " with Uniform1iv/GetUniformfv at " << idx;
} }
// Calling Uniform1fv // Calling Uniform1fv
...@@ -367,14 +380,14 @@ TEST_P(UniformTest, BooleanArrayUniformStateQuery) ...@@ -367,14 +380,14 @@ TEST_P(UniformTest, BooleanArrayUniformStateQuery)
{ {
int value = -1; int value = -1;
glGetUniformiv(mProgram, locations[idx], &value); 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) for (unsigned int idx = 0; idx < 4; ++idx)
{ {
float value = -1.0f; float value = -1.0f;
glGetUniformfv(mProgram, locations[idx], &value); glGetUniformfv(mProgram, locations[idx], &value);
EXPECT_EQ(boolValuesf[idx], value); EXPECT_EQ(boolValuesf[idx], value) << " with Uniform1fv/GetUniformfv at " << idx;
} }
ASSERT_GL_NO_ERROR(); ASSERT_GL_NO_ERROR();
...@@ -415,6 +428,10 @@ TEST_P(UniformTestES3, TranposedMatrixArrayUniformStateQuery) ...@@ -415,6 +428,10 @@ TEST_P(UniformTestES3, TranposedMatrixArrayUniformStateQuery)
"out vec4 color;\n" "out vec4 color;\n"
"void main() {\n" "void main() {\n"
" color = vec4(uniMat3x2[0][0][0]);\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); mProgram = CompileProgram(vertexShader, fragShader);
...@@ -474,6 +491,10 @@ TEST_P(UniformTestES3, OverflowArray) ...@@ -474,6 +491,10 @@ TEST_P(UniformTestES3, OverflowArray)
"out vec4 color;\n" "out vec4 color;\n"
"void main() {\n" "void main() {\n"
" color = vec4(uniMat3x2[0][0][0] + uniF[0]);\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); mProgram = CompileProgram(vertexShader, fragShader);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment