Revert "Re-re-re-land "Move Uniform and UBO info to the gl::Program layer.""
Seems to be failing the dEQP-GLES2.functional.uniform_api tests relating to boolean arrays.
BUG=angleproject:1123
This reverts commit 892a6a4b17b35e89898be8b4605c1ee595d3ae13.
Change-Id: Ifc4ce3ca806ef88a02ac6f693334ac37ce098a88
Reviewed-on: https://chromium-review.googlesource.com/298520
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Tested-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/common/mathutil.h b/src/common/mathutil.h
index fb16a1c..332ba3d 100644
--- a/src/common/mathutil.h
+++ b/src/common/mathutil.h
@@ -69,13 +69,13 @@
template <typename DestT, typename SrcT>
inline DestT clampCast(SrcT value)
{
+ // This assumes SrcT can properly represent DestT::min/max
+ // Unfortunately we can't use META_ASSERT without C++11 constexpr support
+ ASSERT(static_cast<DestT>(static_cast<SrcT>(std::numeric_limits<DestT>::min())) == std::numeric_limits<DestT>::min());
+ ASSERT(static_cast<DestT>(static_cast<SrcT>(std::numeric_limits<DestT>::max())) == std::numeric_limits<DestT>::max());
+
SrcT lo = static_cast<SrcT>(std::numeric_limits<DestT>::min());
SrcT hi = static_cast<SrcT>(std::numeric_limits<DestT>::max());
-
- // This assumes SrcT can properly represent DestT::min/max. Checking this is a bit tricky,
- // especially given floating point representations.
- ASSERT(lo < hi);
-
return static_cast<DestT>(value > lo ? (value > hi ? hi : value) : lo);
}
diff --git a/src/compiler/translator/blocklayout.h b/src/compiler/translator/blocklayout.h
index 0d0a2ed..96d3740 100644
--- a/src/compiler/translator/blocklayout.h
+++ b/src/compiler/translator/blocklayout.h
@@ -26,8 +26,6 @@
struct COMPILER_EXPORT BlockMemberInfo
{
- BlockMemberInfo() : offset(-1), arrayStride(-1), matrixStride(-1), isRowMajorMatrix(false) {}
-
BlockMemberInfo(int offset, int arrayStride, int matrixStride, bool isRowMajorMatrix)
: offset(offset),
arrayStride(arrayStride),
diff --git a/src/libANGLE/Program.cpp b/src/libANGLE/Program.cpp
index 81bbe76..30386f7 100644
--- a/src/libANGLE/Program.cpp
+++ b/src/libANGLE/Program.cpp
@@ -22,7 +22,6 @@
#include "libANGLE/features.h"
#include "libANGLE/renderer/Renderer.h"
#include "libANGLE/renderer/ProgramImpl.h"
-#include "libANGLE/queryconversions.h"
namespace gl
{
@@ -47,133 +46,8 @@
return subscript;
}
-void WriteShaderVar(BinaryOutputStream *stream, const sh::ShaderVariable &var)
-{
- stream->writeInt(var.type);
- stream->writeInt(var.precision);
- stream->writeString(var.name);
- stream->writeString(var.mappedName);
- stream->writeInt(var.arraySize);
- stream->writeInt(var.staticUse);
- stream->writeString(var.structName);
- ASSERT(var.fields.empty());
}
-void LoadShaderVar(BinaryInputStream *stream, sh::ShaderVariable *var)
-{
- var->type = stream->readInt<GLenum>();
- var->precision = stream->readInt<GLenum>();
- var->name = stream->readString();
- var->mappedName = stream->readString();
- var->arraySize = stream->readInt<unsigned int>();
- var->staticUse = stream->readBool();
- var->structName = stream->readString();
-}
-
-template <typename VarT>
-void DefineUniformBlockMembers(const std::vector<VarT> &fields,
- const std::string &prefix,
- int blockIndex,
- std::vector<LinkedUniform> *uniformsOut)
-{
- for (const VarT &field : fields)
- {
- const std::string &fieldName = (prefix.empty() ? field.name : prefix + "." + field.name);
-
- if (field.isStruct())
- {
- for (unsigned int arrayElement = 0; arrayElement < field.elementCount(); arrayElement++)
- {
- const std::string uniformElementName =
- fieldName + (field.isArray() ? ArrayString(arrayElement) : "");
- DefineUniformBlockMembers(field.fields, uniformElementName, blockIndex,
- uniformsOut);
- }
- }
- else
- {
- // TODO(jmadill): record row-majorness?
- // Block layout is recorded in the Impl.
- LinkedUniform newUniform(field.type, field.precision, fieldName, field.arraySize,
- blockIndex, sh::BlockMemberInfo::getDefaultBlockInfo());
-
- // Since block uniforms have no location, we don't need to store them in the uniform
- // locations list.
- uniformsOut->push_back(newUniform);
- }
- }
-}
-
-// This simplified cast function doesn't need to worry about advanced concepts like
-// depth range values, or casting to bool.
-template <typename DestT, typename SrcT>
-DestT UniformStateQueryCast(SrcT value);
-
-// From-Float-To-Integer Casts
-template <>
-GLint UniformStateQueryCast(GLfloat value)
-{
- return clampCast<GLint>(roundf(value));
-}
-
-template <>
-GLuint UniformStateQueryCast(GLfloat value)
-{
- return clampCast<GLuint>(roundf(value));
-}
-
-// From-Integer-to-Integer Casts
-template <>
-GLint UniformStateQueryCast(GLuint value)
-{
- return clampCast<GLint>(value);
-}
-
-template <>
-GLuint UniformStateQueryCast(GLint value)
-{
- return clampCast<GLuint>(value);
-}
-
-// From-Boolean-to-Anything Casts
-template <>
-GLfloat UniformStateQueryCast(GLboolean value)
-{
- return (value == GL_TRUE ? 1.0f : 0.0f);
-}
-
-template <>
-GLint UniformStateQueryCast(GLboolean value)
-{
- return (value == GL_TRUE ? 1 : 0);
-}
-
-template <>
-GLuint UniformStateQueryCast(GLboolean value)
-{
- return (value == GL_TRUE ? 1u : 0u);
-}
-
-// Default to static_cast
-template <typename DestT, typename SrcT>
-DestT UniformStateQueryCast(SrcT value)
-{
- return static_cast<DestT>(value);
-}
-
-template <typename SrcT, typename DestT>
-void UniformStateQueryCastLoop(DestT *dataOut, const uint8_t *srcPointer, int components)
-{
- const SrcT *typedSrcPointer = reinterpret_cast<const SrcT *>(srcPointer);
-
- for (int comp = 0; comp < components; ++comp)
- {
- dataOut[comp] = UniformStateQueryCast<DestT>(typedSrcPointer[comp]);
- }
-}
-
-} // anonymous namespace
-
AttributeBindings::AttributeBindings()
{
}
@@ -288,68 +162,6 @@
}
}
-const LinkedUniform *Program::Data::getUniformByName(const std::string &name) const
-{
- for (const LinkedUniform &linkedUniform : mUniforms)
- {
- if (linkedUniform.name == name)
- {
- return &linkedUniform;
- }
- }
-
- return nullptr;
-}
-
-GLint Program::Data::getUniformLocation(const std::string &name) const
-{
- size_t subscript = GL_INVALID_INDEX;
- std::string baseName = gl::ParseUniformName(name, &subscript);
-
- for (size_t location = 0; location < mUniformLocations.size(); ++location)
- {
- const VariableLocation &uniformLocation = mUniformLocations[location];
- const LinkedUniform &uniform = mUniforms[uniformLocation.index];
-
- if (uniform.name == baseName)
- {
- if ((uniform.isArray() && uniformLocation.element == subscript) ||
- (subscript == GL_INVALID_INDEX))
- {
- return static_cast<GLint>(location);
- }
- }
- }
-
- return -1;
-}
-
-GLuint Program::Data::getUniformIndex(const std::string &name) const
-{
- size_t subscript = GL_INVALID_INDEX;
- std::string baseName = gl::ParseUniformName(name, &subscript);
-
- // The app is not allowed to specify array indices other than 0 for arrays of basic types
- if (subscript != 0 && subscript != GL_INVALID_INDEX)
- {
- return GL_INVALID_INDEX;
- }
-
- for (size_t index = 0; index < mUniforms.size(); index++)
- {
- const LinkedUniform &uniform = mUniforms[index];
- if (uniform.name == baseName)
- {
- if (uniform.isArray() || subscript == GL_INVALID_INDEX)
- {
- return static_cast<GLuint>(index);
- }
- }
- }
-
- return GL_INVALID_INDEX;
-}
-
Program::Program(rx::ImplFactory *factory, ResourceManager *manager, GLuint handle)
: mProgram(factory->createProgram(mData)),
mValidated(false),
@@ -507,7 +319,6 @@
}
gatherTransformFeedbackVaryings(mergedVaryings);
- mProgram->gatherUniformBlockInfo(&mData.mUniformBlocks, &mData.mUniforms);
mLinked = true;
return gl::Error(GL_NO_ERROR);
@@ -547,11 +358,10 @@
mData.mAttributes.clear();
mData.mActiveAttribLocationsMask.reset();
mData.mTransformFeedbackVaryingVars.clear();
- mData.mUniforms.clear();
- mData.mUniformLocations.clear();
- mData.mUniformBlocks.clear();
mData.mOutputVariables.clear();
+ mProgram->reset();
+
mValidated = false;
mLinked = false;
@@ -605,66 +415,15 @@
for (unsigned int attribIndex = 0; attribIndex < attribCount; ++attribIndex)
{
sh::Attribute attrib;
- LoadShaderVar(&stream, &attrib);
- attrib.location = stream.readInt<int>();
+ attrib.type = stream.readInt<GLenum>();
+ attrib.precision = stream.readInt<GLenum>();
+ attrib.name = stream.readString();
+ attrib.arraySize = stream.readInt<GLint>();
+ attrib.location = stream.readInt<int>();
+ attrib.staticUse = stream.readBool();
mData.mAttributes.push_back(attrib);
}
- unsigned int uniformCount = stream.readInt<unsigned int>();
- ASSERT(mData.mUniforms.empty());
- for (unsigned int uniformIndex = 0; uniformIndex < uniformCount; ++uniformIndex)
- {
- LinkedUniform uniform;
- LoadShaderVar(&stream, &uniform);
-
- uniform.blockIndex = stream.readInt<int>();
- uniform.blockInfo.offset = stream.readInt<int>();
- uniform.blockInfo.arrayStride = stream.readInt<int>();
- uniform.blockInfo.matrixStride = stream.readInt<int>();
- uniform.blockInfo.isRowMajorMatrix = stream.readBool();
-
- mData.mUniforms.push_back(uniform);
- }
-
- const unsigned int uniformIndexCount = stream.readInt<unsigned int>();
- ASSERT(mData.mUniformLocations.empty());
- for (unsigned int uniformIndexIndex = 0; uniformIndexIndex < uniformIndexCount;
- uniformIndexIndex++)
- {
- VariableLocation variable;
- stream.readString(&variable.name);
- stream.readInt(&variable.element);
- stream.readInt(&variable.index);
-
- mData.mUniformLocations.push_back(variable);
- }
-
- unsigned int uniformBlockCount = stream.readInt<unsigned int>();
- ASSERT(mData.mUniformBlocks.empty());
- for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < uniformBlockCount;
- ++uniformBlockIndex)
- {
- UniformBlock uniformBlock;
- stream.readString(&uniformBlock.name);
- stream.readBool(&uniformBlock.isArray);
- stream.readInt(&uniformBlock.arrayElement);
- stream.readInt(&uniformBlock.dataSize);
- stream.readBool(&uniformBlock.vertexStaticUse);
- stream.readBool(&uniformBlock.fragmentStaticUse);
-
- unsigned int numMembers = stream.readInt<unsigned int>();
- for (unsigned int blockMemberIndex = 0; blockMemberIndex < numMembers; blockMemberIndex++)
- {
- uniformBlock.memberUniformIndexes.push_back(stream.readInt<unsigned int>());
- }
-
- // TODO(jmadill): Make D3D-only
- stream.readInt(&uniformBlock.psRegisterIndex);
- stream.readInt(&uniformBlock.vsRegisterIndex);
-
- mData.mUniformBlocks.push_back(uniformBlock);
- }
-
stream.readInt(&mData.mTransformFeedbackBufferMode);
unsigned int outputVarCount = stream.readInt<unsigned int>();
@@ -708,52 +467,12 @@
stream.writeInt(mData.mAttributes.size());
for (const sh::Attribute &attrib : mData.mAttributes)
{
- WriteShaderVar(&stream, attrib);
+ stream.writeInt(attrib.type);
+ stream.writeInt(attrib.precision);
+ stream.writeString(attrib.name);
+ stream.writeInt(attrib.arraySize);
stream.writeInt(attrib.location);
- }
-
- stream.writeInt(mData.mUniforms.size());
- for (const gl::LinkedUniform &uniform : mData.mUniforms)
- {
- WriteShaderVar(&stream, uniform);
-
- // FIXME: referenced
-
- stream.writeInt(uniform.blockIndex);
- stream.writeInt(uniform.blockInfo.offset);
- stream.writeInt(uniform.blockInfo.arrayStride);
- stream.writeInt(uniform.blockInfo.matrixStride);
- stream.writeInt(uniform.blockInfo.isRowMajorMatrix);
- }
-
- stream.writeInt(mData.mUniformLocations.size());
- for (const auto &variable : mData.mUniformLocations)
- {
- stream.writeString(variable.name);
- stream.writeInt(variable.element);
- stream.writeInt(variable.index);
- }
-
- stream.writeInt(mData.mUniformBlocks.size());
- for (const UniformBlock &uniformBlock : mData.mUniformBlocks)
- {
- stream.writeString(uniformBlock.name);
- stream.writeInt(uniformBlock.isArray);
- stream.writeInt(uniformBlock.arrayElement);
- stream.writeInt(uniformBlock.dataSize);
-
- stream.writeInt(uniformBlock.vertexStaticUse);
- stream.writeInt(uniformBlock.fragmentStaticUse);
-
- stream.writeInt(uniformBlock.memberUniformIndexes.size());
- for (unsigned int memberUniformIndex : uniformBlock.memberUniformIndexes)
- {
- stream.writeInt(memberUniformIndex);
- }
-
- // TODO(jmadill): make D3D-only
- stream.writeInt(uniformBlock.psRegisterIndex);
- stream.writeInt(uniformBlock.vsRegisterIndex);
+ stream.writeInt(attrib.staticUse);
}
stream.writeInt(mData.mTransformFeedbackBufferMode);
@@ -1009,14 +728,13 @@
{
if (mLinked)
{
- // index must be smaller than getActiveUniformCount()
- ASSERT(index < mData.mUniforms.size());
- const LinkedUniform &uniform = mData.mUniforms[index];
+ ASSERT(index < mProgram->getUniforms().size()); // index must be smaller than getActiveUniformCount()
+ LinkedUniform *uniform = mProgram->getUniforms()[index];
if (bufsize > 0)
{
- std::string string = uniform.name;
- if (uniform.isArray())
+ std::string string = uniform->name;
+ if (uniform->isArray())
{
string += "[0]";
}
@@ -1030,8 +748,8 @@
}
}
- *size = uniform.elementCount();
- *type = uniform.type;
+ *size = uniform->elementCount();
+ *type = uniform->type;
}
else
{
@@ -1054,7 +772,7 @@
{
if (mLinked)
{
- return static_cast<GLint>(mData.mUniforms.size());
+ return static_cast<GLint>(mProgram->getUniforms().size());
}
else
{
@@ -1064,16 +782,17 @@
GLint Program::getActiveUniformMaxLength()
{
- size_t maxLength = 0;
+ int maxLength = 0;
if (mLinked)
{
- for (const LinkedUniform &uniform : mData.mUniforms)
+ unsigned int numUniforms = static_cast<unsigned int>(mProgram->getUniforms().size());
+ for (unsigned int uniformIndex = 0; uniformIndex < numUniforms; uniformIndex++)
{
- if (!uniform.name.empty())
+ if (!mProgram->getUniforms()[uniformIndex]->name.empty())
{
- size_t length = uniform.name.length() + 1u;
- if (uniform.isArray())
+ int length = (int)(mProgram->getUniforms()[uniformIndex]->name.length() + 1);
+ if (mProgram->getUniforms()[uniformIndex]->isArray())
{
length += 3; // Counting in "[0]".
}
@@ -1082,13 +801,12 @@
}
}
- return static_cast<GLint>(maxLength);
+ return maxLength;
}
GLint Program::getActiveUniformi(GLuint index, GLenum pname) const
{
- ASSERT(static_cast<size_t>(index) < mData.mUniforms.size());
- const gl::LinkedUniform &uniform = mData.mUniforms[index];
+ const gl::LinkedUniform& uniform = *mProgram->getUniforms()[index];
switch (pname)
{
case GL_UNIFORM_TYPE: return static_cast<GLint>(uniform.type);
@@ -1108,165 +826,149 @@
bool Program::isValidUniformLocation(GLint location) const
{
- ASSERT(rx::IsIntegerCastSafe<GLint>(mData.mUniformLocations.size()));
- return (location >= 0 && static_cast<size_t>(location) < mData.mUniformLocations.size());
+ const auto &uniformIndices = mProgram->getUniformIndices();
+ ASSERT(rx::IsIntegerCastSafe<GLint>(uniformIndices.size()));
+ return (location >= 0 && uniformIndices.find(location) != uniformIndices.end());
}
-const LinkedUniform &Program::getUniformByLocation(GLint location) const
+LinkedUniform *Program::getUniformByLocation(GLint location) const
{
- ASSERT(location >= 0 && static_cast<size_t>(location) < mData.mUniformLocations.size());
- return mData.mUniforms[mData.mUniformLocations[location].index];
+ return mProgram->getUniformByLocation(location);
}
-GLint Program::getUniformLocation(const std::string &name) const
+LinkedUniform *Program::getUniformByName(const std::string &name) const
{
- return mData.getUniformLocation(name);
+ return mProgram->getUniformByName(name);
}
-GLuint Program::getUniformIndex(const std::string &name) const
+GLint Program::getUniformLocation(const std::string &name)
{
- return mData.getUniformIndex(name);
+ return mProgram->getUniformLocation(name);
+}
+
+GLuint Program::getUniformIndex(const std::string &name)
+{
+ return mProgram->getUniformIndex(name);
}
void Program::setUniform1fv(GLint location, GLsizei count, const GLfloat *v)
{
- setUniformInternal(location, count * 1, v);
mProgram->setUniform1fv(location, count, v);
}
void Program::setUniform2fv(GLint location, GLsizei count, const GLfloat *v)
{
- setUniformInternal(location, count * 2, v);
mProgram->setUniform2fv(location, count, v);
}
void Program::setUniform3fv(GLint location, GLsizei count, const GLfloat *v)
{
- setUniformInternal(location, count * 3, v);
mProgram->setUniform3fv(location, count, v);
}
void Program::setUniform4fv(GLint location, GLsizei count, const GLfloat *v)
{
- setUniformInternal(location, count * 4, v);
mProgram->setUniform4fv(location, count, v);
}
void Program::setUniform1iv(GLint location, GLsizei count, const GLint *v)
{
- setUniformInternal(location, count * 1, v);
mProgram->setUniform1iv(location, count, v);
}
void Program::setUniform2iv(GLint location, GLsizei count, const GLint *v)
{
- setUniformInternal(location, count * 2, v);
mProgram->setUniform2iv(location, count, v);
}
void Program::setUniform3iv(GLint location, GLsizei count, const GLint *v)
{
- setUniformInternal(location, count * 3, v);
mProgram->setUniform3iv(location, count, v);
}
void Program::setUniform4iv(GLint location, GLsizei count, const GLint *v)
{
- setUniformInternal(location, count * 4, v);
mProgram->setUniform4iv(location, count, v);
}
void Program::setUniform1uiv(GLint location, GLsizei count, const GLuint *v)
{
- setUniformInternal(location, count * 1, v);
mProgram->setUniform1uiv(location, count, v);
}
void Program::setUniform2uiv(GLint location, GLsizei count, const GLuint *v)
{
- setUniformInternal(location, count * 2, v);
mProgram->setUniform2uiv(location, count, v);
}
void Program::setUniform3uiv(GLint location, GLsizei count, const GLuint *v)
{
- setUniformInternal(location, count * 3, v);
mProgram->setUniform3uiv(location, count, v);
}
void Program::setUniform4uiv(GLint location, GLsizei count, const GLuint *v)
{
- setUniformInternal(location, count * 4, v);
mProgram->setUniform4uiv(location, count, v);
}
void Program::setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v)
{
- setMatrixUniformInternal<2, 2>(location, count, transpose, v);
mProgram->setUniformMatrix2fv(location, count, transpose, v);
}
void Program::setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v)
{
- setMatrixUniformInternal<3, 3>(location, count, transpose, v);
mProgram->setUniformMatrix3fv(location, count, transpose, v);
}
void Program::setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v)
{
- setMatrixUniformInternal<4, 4>(location, count, transpose, v);
mProgram->setUniformMatrix4fv(location, count, transpose, v);
}
void Program::setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v)
{
- setMatrixUniformInternal<2, 3>(location, count, transpose, v);
mProgram->setUniformMatrix2x3fv(location, count, transpose, v);
}
void Program::setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v)
{
- setMatrixUniformInternal<2, 4>(location, count, transpose, v);
mProgram->setUniformMatrix2x4fv(location, count, transpose, v);
}
void Program::setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v)
{
- setMatrixUniformInternal<3, 2>(location, count, transpose, v);
mProgram->setUniformMatrix3x2fv(location, count, transpose, v);
}
void Program::setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v)
{
- setMatrixUniformInternal<3, 4>(location, count, transpose, v);
mProgram->setUniformMatrix3x4fv(location, count, transpose, v);
}
void Program::setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v)
{
- setMatrixUniformInternal<4, 2>(location, count, transpose, v);
mProgram->setUniformMatrix4x2fv(location, count, transpose, v);
}
void Program::setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v)
{
- setMatrixUniformInternal<4, 3>(location, count, transpose, v);
mProgram->setUniformMatrix4x3fv(location, count, transpose, v);
}
void Program::getUniformfv(GLint location, GLfloat *v)
{
- getUniformInternal(location, v);
+ mProgram->getUniformfv(location, v);
}
void Program::getUniformiv(GLint location, GLint *v)
{
- getUniformInternal(location, v);
+ mProgram->getUniformiv(location, v);
}
void Program::getUniformuiv(GLint location, GLuint *v)
{
- getUniformInternal(location, v);
+ mProgram->getUniformuiv(location, v);
}
void Program::flagForDeletion()
@@ -1305,23 +1007,22 @@
GLuint Program::getActiveUniformBlockCount()
{
- return static_cast<GLuint>(mData.mUniformBlocks.size());
+ return static_cast<GLuint>(mProgram->getUniformBlocks().size());
}
void Program::getActiveUniformBlockName(GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName) const
{
- ASSERT(uniformBlockIndex <
- mData.mUniformBlocks.size()); // index must be smaller than getActiveUniformBlockCount()
+ ASSERT(uniformBlockIndex < mProgram->getUniformBlocks().size()); // index must be smaller than getActiveUniformBlockCount()
- const UniformBlock &uniformBlock = mData.mUniformBlocks[uniformBlockIndex];
+ const UniformBlock &uniformBlock = *mProgram->getUniformBlocks()[uniformBlockIndex];
if (bufSize > 0)
{
std::string string = uniformBlock.name;
- if (uniformBlock.isArray)
+ if (uniformBlock.isArrayElement())
{
- string += ArrayString(uniformBlock.arrayElement);
+ string += ArrayString(uniformBlock.elementIndex);
}
strncpy(uniformBlockName, string.c_str(), bufSize);
@@ -1336,10 +1037,9 @@
void Program::getActiveUniformBlockiv(GLuint uniformBlockIndex, GLenum pname, GLint *params) const
{
- ASSERT(uniformBlockIndex <
- mData.mUniformBlocks.size()); // index must be smaller than getActiveUniformBlockCount()
+ ASSERT(uniformBlockIndex < mProgram->getUniformBlocks().size()); // index must be smaller than getActiveUniformBlockCount()
- const UniformBlock &uniformBlock = mData.mUniformBlocks[uniformBlockIndex];
+ const UniformBlock &uniformBlock = *mProgram->getUniformBlocks()[uniformBlockIndex];
switch (pname)
{
@@ -1347,8 +1047,7 @@
*params = static_cast<GLint>(uniformBlock.dataSize);
break;
case GL_UNIFORM_BLOCK_NAME_LENGTH:
- *params =
- static_cast<GLint>(uniformBlock.name.size() + 1 + (uniformBlock.isArray ? 3 : 0));
+ *params = static_cast<GLint>(uniformBlock.name.size() + 1 + (uniformBlock.isArrayElement() ? 3 : 0));
break;
case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS:
*params = static_cast<GLint>(uniformBlock.memberUniformIndexes.size());
@@ -1362,10 +1061,10 @@
}
break;
case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
- *params = static_cast<GLint>(uniformBlock.vertexStaticUse);
+ *params = static_cast<GLint>(uniformBlock.isReferencedByVertexShader());
break;
case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:
- *params = static_cast<GLint>(uniformBlock.fragmentStaticUse);
+ *params = static_cast<GLint>(uniformBlock.isReferencedByFragmentShader());
break;
default: UNREACHABLE();
}
@@ -1377,16 +1076,17 @@
if (mLinked)
{
- unsigned int numUniformBlocks = static_cast<unsigned int>(mData.mUniformBlocks.size());
+ unsigned int numUniformBlocks =
+ static_cast<unsigned int>(mProgram->getUniformBlocks().size());
for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < numUniformBlocks; uniformBlockIndex++)
{
- const UniformBlock &uniformBlock = mData.mUniformBlocks[uniformBlockIndex];
+ const UniformBlock &uniformBlock = *mProgram->getUniformBlocks()[uniformBlockIndex];
if (!uniformBlock.name.empty())
{
const int length = static_cast<int>(uniformBlock.name.length()) + 1;
// Counting in "[0]".
- const int arrayLength = (uniformBlock.isArray ? 3 : 0);
+ const int arrayLength = (uniformBlock.isArrayElement() ? 3 : 0);
maxLength = std::max(length + arrayLength, maxLength);
}
@@ -1398,32 +1098,12 @@
GLuint Program::getUniformBlockIndex(const std::string &name)
{
- size_t subscript = GL_INVALID_INDEX;
- std::string baseName = gl::ParseUniformName(name, &subscript);
-
- unsigned int numUniformBlocks = static_cast<unsigned int>(mData.mUniformBlocks.size());
- for (unsigned int blockIndex = 0; blockIndex < numUniformBlocks; blockIndex++)
- {
- const gl::UniformBlock &uniformBlock = mData.mUniformBlocks[blockIndex];
- if (uniformBlock.name == baseName)
- {
- const bool arrayElementZero =
- (subscript == GL_INVALID_INDEX &&
- (!uniformBlock.isArray || uniformBlock.arrayElement == 0));
- if (subscript == uniformBlock.arrayElement || arrayElementZero)
- {
- return blockIndex;
- }
- }
- }
-
- return GL_INVALID_INDEX;
+ return mProgram->getUniformBlockIndex(name);
}
-const UniformBlock &Program::getUniformBlockByIndex(GLuint index) const
+const UniformBlock *Program::getUniformBlockByIndex(GLuint index) const
{
- ASSERT(index < static_cast<GLuint>(mData.mUniformBlocks.size()));
- return mData.mUniformBlocks[index];
+ return mProgram->getUniformBlockByIndex(index);
}
void Program::bindUniformBlock(GLuint uniformBlockIndex, GLuint uniformBlockBinding)
@@ -1563,17 +1243,17 @@
return true;
}
-bool Program::linkUniforms(gl::InfoLog &infoLog, const gl::Caps &caps)
+bool Program::linkUniforms(gl::InfoLog &infoLog, const gl::Caps & /*caps*/) const
{
const std::vector<sh::Uniform> &vertexUniforms = mData.mAttachedVertexShader->getUniforms();
const std::vector<sh::Uniform> &fragmentUniforms = mData.mAttachedFragmentShader->getUniforms();
// Check that uniforms defined in the vertex and fragment shaders are identical
- std::map<std::string, LinkedUniform> linkedUniforms;
+ std::map<std::string, const sh::Uniform *> linkedUniforms;
for (const sh::Uniform &vertexUniform : vertexUniforms)
{
- linkedUniforms[vertexUniform.name] = LinkedUniform(vertexUniform);
+ linkedUniforms[vertexUniform.name] = &vertexUniform;
}
for (const sh::Uniform &fragmentUniform : fragmentUniforms)
@@ -1581,45 +1261,19 @@
auto entry = linkedUniforms.find(fragmentUniform.name);
if (entry != linkedUniforms.end())
{
- LinkedUniform *vertexUniform = &entry->second;
- const std::string &uniformName = "uniform '" + vertexUniform->name + "'";
- if (!linkValidateUniforms(infoLog, uniformName, *vertexUniform, fragmentUniform))
+ const sh::Uniform &vertexUniform = *entry->second;
+ const std::string &uniformName = "uniform '" + vertexUniform.name + "'";
+ if (!linkValidateUniforms(infoLog, uniformName, vertexUniform, fragmentUniform))
{
return false;
}
}
}
- // Flatten the uniforms list (nested fields) into a simple list (no nesting).
- // Also check the maximum uniform vector and sampler counts.
- if (!flattenUniformsAndCheckCaps(caps, infoLog))
- {
- return false;
- }
-
- indexUniforms();
-
+ // TODO(jmadill): check sampler uniforms with caps
return true;
}
-void Program::indexUniforms()
-{
- for (size_t uniformIndex = 0; uniformIndex < mData.mUniforms.size(); uniformIndex++)
- {
- const gl::LinkedUniform &uniform = mData.mUniforms[uniformIndex];
-
- for (unsigned int arrayIndex = 0; arrayIndex < uniform.elementCount(); arrayIndex++)
- {
- if (!uniform.isBuiltIn())
- {
- // Assign in-order uniform locations
- mData.mUniformLocations.push_back(gl::VariableLocation(
- uniform.name, arrayIndex, static_cast<unsigned int>(uniformIndex)));
- }
- }
- }
-}
-
bool Program::linkValidateInterfaceBlockFields(InfoLog &infoLog, const std::string &uniformName, const sh::InterfaceBlockField &vertexUniform, const sh::InterfaceBlockField &fragmentUniform)
{
if (!linkValidateVariablesBase(infoLog, uniformName, vertexUniform, fragmentUniform, true))
@@ -1799,8 +1453,6 @@
}
}
- gatherInterfaceBlockInfo();
-
return true;
}
@@ -2078,288 +1730,4 @@
}
}
}
-
-bool Program::flattenUniformsAndCheckCaps(const Caps &caps, InfoLog &infoLog)
-{
- const gl::Shader *vertexShader = mData.getAttachedVertexShader();
- VectorAndSamplerCount vsCounts;
-
- for (const sh::Uniform &uniform : vertexShader->getUniforms())
- {
- if (uniform.staticUse)
- {
- vsCounts += flattenUniform(uniform, uniform.name);
- }
- }
-
- if (vsCounts.vectorCount > caps.maxVertexUniformVectors)
- {
- infoLog << "Vertex shader active uniforms exceed MAX_VERTEX_UNIFORM_VECTORS ("
- << caps.maxVertexUniformVectors << ").";
- return false;
- }
-
- if (vsCounts.samplerCount > caps.maxVertexTextureImageUnits)
- {
- infoLog << "Vertex shader sampler count exceeds MAX_VERTEX_TEXTURE_IMAGE_UNITS ("
- << caps.maxVertexTextureImageUnits << ").";
- return false;
- }
-
- const gl::Shader *fragmentShader = mData.getAttachedFragmentShader();
- VectorAndSamplerCount fsCounts;
-
- for (const sh::Uniform &uniform : fragmentShader->getUniforms())
- {
- if (uniform.staticUse)
- {
- fsCounts += flattenUniform(uniform, uniform.name);
- }
- }
-
- if (fsCounts.vectorCount > caps.maxFragmentUniformVectors)
- {
- infoLog << "Fragment shader active uniforms exceed MAX_FRAGMENT_UNIFORM_VECTORS ("
- << caps.maxFragmentUniformVectors << ").";
- return false;
- }
-
- if (fsCounts.samplerCount > caps.maxTextureImageUnits)
- {
- infoLog << "Fragment shader sampler count exceeds MAX_TEXTURE_IMAGE_UNITS ("
- << caps.maxTextureImageUnits << ").";
- return false;
- }
-
- return true;
-}
-
-Program::VectorAndSamplerCount Program::flattenUniform(const sh::ShaderVariable &uniform,
- const std::string &fullName)
-{
- VectorAndSamplerCount vectorAndSamplerCount;
-
- if (uniform.isStruct())
- {
- for (unsigned int elementIndex = 0; elementIndex < uniform.elementCount(); elementIndex++)
- {
- const std::string &elementString = (uniform.isArray() ? ArrayString(elementIndex) : "");
-
- for (size_t fieldIndex = 0; fieldIndex < uniform.fields.size(); fieldIndex++)
- {
- const sh::ShaderVariable &field = uniform.fields[fieldIndex];
- const std::string &fieldFullName = (fullName + elementString + "." + field.name);
-
- vectorAndSamplerCount += flattenUniform(field, fieldFullName);
- }
- }
-
- return vectorAndSamplerCount;
- }
-
- // Not a struct
- if (mData.getUniformByName(fullName) == nullptr)
- {
- gl::LinkedUniform linkedUniform(uniform.type, uniform.precision, fullName,
- uniform.arraySize, -1,
- sh::BlockMemberInfo::getDefaultBlockInfo());
- linkedUniform.staticUse = true;
- mData.mUniforms.push_back(linkedUniform);
- }
-
- vectorAndSamplerCount.vectorCount =
- (VariableRegisterCount(uniform.type) * uniform.elementCount());
- vectorAndSamplerCount.samplerCount = (IsSamplerType(uniform.type) ? uniform.elementCount() : 0);
-
- return vectorAndSamplerCount;
-}
-
-void Program::gatherInterfaceBlockInfo()
-{
- std::set<std::string> visitedList;
-
- const gl::Shader *vertexShader = mData.getAttachedVertexShader();
-
- ASSERT(mData.mUniformBlocks.empty());
- for (const sh::InterfaceBlock &vertexBlock : vertexShader->getInterfaceBlocks())
- {
- // Only 'packed' blocks are allowed to be considered inacive.
- if (!vertexBlock.staticUse && vertexBlock.layout == sh::BLOCKLAYOUT_PACKED)
- continue;
-
- if (visitedList.count(vertexBlock.name) > 0)
- continue;
-
- defineUniformBlock(vertexBlock, GL_VERTEX_SHADER);
- visitedList.insert(vertexBlock.name);
- }
-
- const gl::Shader *fragmentShader = mData.getAttachedFragmentShader();
-
- for (const sh::InterfaceBlock &fragmentBlock : fragmentShader->getInterfaceBlocks())
- {
- // Only 'packed' blocks are allowed to be considered inacive.
- if (!fragmentBlock.staticUse && fragmentBlock.layout == sh::BLOCKLAYOUT_PACKED)
- continue;
-
- if (visitedList.count(fragmentBlock.name) > 0)
- {
- for (gl::UniformBlock &block : mData.mUniformBlocks)
- {
- if (block.name == fragmentBlock.name)
- {
- block.fragmentStaticUse = fragmentBlock.staticUse;
- }
- }
-
- continue;
- }
-
- defineUniformBlock(fragmentBlock, GL_FRAGMENT_SHADER);
- visitedList.insert(fragmentBlock.name);
- }
-}
-
-void Program::defineUniformBlock(const sh::InterfaceBlock &interfaceBlock, GLenum shaderType)
-{
- std::string baseName;
- if (!interfaceBlock.instanceName.empty() && interfaceBlock.arraySize == 0)
- {
- baseName = interfaceBlock.instanceName;
- }
-
- int blockIndex = static_cast<int>(mData.mUniformBlocks.size());
- size_t firstBlockUniformIndex = mData.mUniforms.size();
- DefineUniformBlockMembers(interfaceBlock.fields, baseName, blockIndex, &mData.mUniforms);
- size_t lastBlockUniformIndex = mData.mUniforms.size();
-
- std::vector<unsigned int> blockUniformIndexes;
- for (size_t blockUniformIndex = firstBlockUniformIndex;
- blockUniformIndex < lastBlockUniformIndex; ++blockUniformIndex)
- {
- blockUniformIndexes.push_back(static_cast<unsigned int>(blockUniformIndex));
- }
-
- if (interfaceBlock.arraySize > 0)
- {
- for (unsigned int arrayElement = 0; arrayElement < interfaceBlock.arraySize; ++arrayElement)
- {
- UniformBlock block(interfaceBlock.name, true, arrayElement);
- block.memberUniformIndexes = blockUniformIndexes;
-
- if (shaderType == GL_VERTEX_SHADER)
- {
- block.vertexStaticUse = interfaceBlock.staticUse;
- }
- else
- {
- ASSERT(shaderType == GL_FRAGMENT_SHADER);
- block.fragmentStaticUse = interfaceBlock.staticUse;
- }
-
- mData.mUniformBlocks.push_back(block);
- }
- }
- else
- {
- UniformBlock block(interfaceBlock.name, false, 0);
- block.memberUniformIndexes = blockUniformIndexes;
-
- if (shaderType == GL_VERTEX_SHADER)
- {
- block.vertexStaticUse = interfaceBlock.staticUse;
- }
- else
- {
- ASSERT(shaderType == GL_FRAGMENT_SHADER);
- block.fragmentStaticUse = interfaceBlock.staticUse;
- }
-
- mData.mUniformBlocks.push_back(block);
- }
-}
-
-template <typename T>
-void Program::setUniformInternal(GLint location, GLsizei count, const T *v)
-{
- const VariableLocation &locationInfo = mData.mUniformLocations[location];
- LinkedUniform *linkedUniform = &mData.mUniforms[locationInfo.index];
- uint8_t *destPointer = linkedUniform->getDataPtrToElement(locationInfo.element);
-
- 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."
- GLboolean *destAsBool = reinterpret_cast<GLboolean *>(destPointer);
- for (GLsizei component = 0; component < count; ++component)
- {
- destAsBool[component] = (v[component] != static_cast<T>(0) ? GL_TRUE : GL_FALSE);
- }
- }
- else
- {
- memcpy(destPointer, v, sizeof(T) * count);
- }
-}
-
-template <size_t cols, size_t rows, typename T>
-void Program::setMatrixUniformInternal(GLint location,
- GLsizei count,
- GLboolean transpose,
- const T *v)
-{
- if (!transpose)
- {
- setUniformInternal(location, count * cols * rows, v);
- return;
- }
-
- // Perform a transposing copy.
- const VariableLocation &locationInfo = mData.mUniformLocations[location];
- LinkedUniform *linkedUniform = &mData.mUniforms[locationInfo.index];
- T *destPtr = reinterpret_cast<T *>(linkedUniform->getDataPtrToElement(locationInfo.element));
- for (size_t row = 0; row < rows; ++row)
- {
- for (size_t col = 0; col < cols; ++col)
- {
- destPtr[col * rows + row] = v[row * cols + col];
- }
- }
-}
-
-template <typename DestT>
-void Program::getUniformInternal(GLint location, DestT *dataOut) const
-{
- const VariableLocation &locationInfo = mData.mUniformLocations[location];
- const LinkedUniform &uniform = mData.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_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);
- break;
- case GL_FLOAT:
- UniformStateQueryCastLoop<GLfloat>(dataOut, srcPointer, components);
- break;
- default:
- UNREACHABLE();
- }
-}
}
diff --git a/src/libANGLE/Program.h b/src/libANGLE/Program.h
index 3dd7c46..b95d5b8 100644
--- a/src/libANGLE/Program.h
+++ b/src/libANGLE/Program.h
@@ -189,16 +189,6 @@
{
return mOutputVariables;
}
- const std::vector<LinkedUniform> &getUniforms() const { return mUniforms; }
- const std::vector<VariableLocation> &getUniformLocations() const
- {
- return mUniformLocations;
- }
- const std::vector<UniformBlock> &getUniformBlocks() const { return mUniformBlocks; }
-
- const LinkedUniform *getUniformByName(const std::string &name) const;
- GLint getUniformLocation(const std::string &name) const;
- GLuint getUniformIndex(const std::string &name) const;
private:
friend class Program;
@@ -215,12 +205,10 @@
std::vector<sh::Attribute> mAttributes;
std::bitset<MAX_VERTEX_ATTRIBS> mActiveAttribLocationsMask;
- std::vector<LinkedUniform> mUniforms;
- std::vector<VariableLocation> mUniformLocations;
- std::vector<UniformBlock> mUniformBlocks;
-
// TODO(jmadill): use unordered/hash map when available
std::map<int, VariableLocation> mOutputVariables;
+
+ // TODO(jmadill): move more state into Data.
};
Program(rx::ImplFactory *factory, ResourceManager *manager, GLuint handle);
@@ -263,10 +251,11 @@
GLint getActiveUniformMaxLength();
GLint getActiveUniformi(GLuint index, GLenum pname) const;
bool isValidUniformLocation(GLint location) const;
- const LinkedUniform &getUniformByLocation(GLint location) const;
+ LinkedUniform *getUniformByLocation(GLint location) const;
+ LinkedUniform *getUniformByName(const std::string &name) const;
- GLint getUniformLocation(const std::string &name) const;
- GLuint getUniformIndex(const std::string &name) const;
+ GLint getUniformLocation(const std::string &name);
+ GLuint getUniformIndex(const std::string &name);
void setUniform1fv(GLint location, GLsizei count, const GLfloat *v);
void setUniform2fv(GLint location, GLsizei count, const GLfloat *v);
void setUniform3fv(GLint location, GLsizei count, const GLfloat *v);
@@ -303,7 +292,7 @@
void bindUniformBlock(GLuint uniformBlockIndex, GLuint uniformBlockBinding);
GLuint getUniformBlockBinding(GLuint uniformBlockIndex) const;
- const UniformBlock &getUniformBlockByIndex(GLuint index) const;
+ const UniformBlock *getUniformBlockByIndex(GLuint index) const;
void setTransformFeedbackVaryings(GLsizei count, const GLchar *const *varyings, GLenum bufferMode);
void getTransformFeedbackVarying(GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name) const;
@@ -341,8 +330,7 @@
static bool linkVaryings(InfoLog &infoLog,
const Shader *vertexShader,
const Shader *fragmentShader);
- bool linkUniforms(gl::InfoLog &infoLog, const gl::Caps &caps);
- void indexUniforms();
+ bool linkUniforms(gl::InfoLog &infoLog, const gl::Caps &caps) const;
bool areMatchingInterfaceBlocks(gl::InfoLog &infoLog, const sh::InterfaceBlock &vertexInterfaceBlock,
const sh::InterfaceBlock &fragmentInterfaceBlock);
@@ -364,40 +352,6 @@
std::vector<const sh::Varying *> getMergedVaryings() const;
void linkOutputVariables();
- bool flattenUniformsAndCheckCaps(const Caps &caps, InfoLog &infoLog);
-
- struct VectorAndSamplerCount
- {
- VectorAndSamplerCount() : vectorCount(0), samplerCount(0) {}
- VectorAndSamplerCount(const VectorAndSamplerCount &other) = default;
- VectorAndSamplerCount &operator=(const VectorAndSamplerCount &other) = default;
-
- VectorAndSamplerCount &operator+=(const VectorAndSamplerCount &other)
- {
- vectorCount += other.vectorCount;
- samplerCount += other.samplerCount;
- return *this;
- }
-
- unsigned int vectorCount;
- unsigned int samplerCount;
- };
-
- VectorAndSamplerCount flattenUniform(const sh::ShaderVariable &uniform,
- const std::string &fullName);
-
- void gatherInterfaceBlockInfo();
- void defineUniformBlock(const sh::InterfaceBlock &interfaceBlock, GLenum shaderType);
-
- template <typename T>
- void setUniformInternal(GLint location, GLsizei count, const T *v);
-
- template <size_t cols, size_t rows, typename T>
- void setMatrixUniformInternal(GLint location, GLsizei count, GLboolean transpose, const T *v);
-
- template <typename DestT>
- void getUniformInternal(GLint location, DestT *dataOut) const;
-
Data mData;
rx::ProgramImpl *mProgram;
diff --git a/src/libANGLE/Uniform.cpp b/src/libANGLE/Uniform.cpp
index 3a20f4c..24e7f11 100644
--- a/src/libANGLE/Uniform.cpp
+++ b/src/libANGLE/Uniform.cpp
@@ -13,51 +13,55 @@
namespace gl
{
-LinkedUniform::LinkedUniform()
- : blockIndex(-1), blockInfo(sh::BlockMemberInfo::getDefaultBlockInfo())
+LinkedUniform::LinkedUniform(GLenum type, GLenum precision, const std::string &name, unsigned int arraySize,
+ const int blockIndex, const sh::BlockMemberInfo &blockInfo)
+ : type(type),
+ precision(precision),
+ name(name),
+ arraySize(arraySize),
+ blockIndex(blockIndex),
+ blockInfo(blockInfo),
+ data(NULL),
+ dirty(true),
+ psRegisterIndex(GL_INVALID_INDEX),
+ vsRegisterIndex(GL_INVALID_INDEX),
+ registerCount(0),
+ registerElement(0)
{
-}
-
-LinkedUniform::LinkedUniform(GLenum typeIn,
- GLenum precisionIn,
- const std::string &nameIn,
- unsigned int arraySizeIn,
- const int blockIndexIn,
- const sh::BlockMemberInfo &blockInfoIn)
- : blockIndex(blockIndexIn), blockInfo(blockInfoIn)
-{
- type = typeIn;
- precision = precisionIn;
- name = nameIn;
- arraySize = arraySizeIn;
-}
-
-LinkedUniform::LinkedUniform(const sh::Uniform &uniform)
- : sh::Uniform(uniform), blockIndex(-1), blockInfo(sh::BlockMemberInfo::getDefaultBlockInfo())
-{
-}
-
-LinkedUniform::LinkedUniform(const LinkedUniform &uniform)
- : sh::Uniform(uniform), blockIndex(uniform.blockIndex), blockInfo(uniform.blockInfo)
-{
- // This function is not intended to be called during runtime.
- ASSERT(uniform.mLazyData.empty());
-}
-
-LinkedUniform &LinkedUniform::operator=(const LinkedUniform &uniform)
-{
- // This function is not intended to be called during runtime.
- ASSERT(uniform.mLazyData.empty());
-
- sh::Uniform::operator=(uniform);
- blockIndex = uniform.blockIndex;
- blockInfo = uniform.blockInfo;
-
- return *this;
+ // We use data storage for default block uniforms to cache values that are sent to D3D during rendering
+ // Uniform blocks/buffers are treated separately by the Renderer (ES3 path only)
+ if (isInDefaultBlock())
+ {
+ size_t bytes = dataSize();
+ data = new unsigned char[bytes];
+ memset(data, 0, bytes);
+ registerCount = VariableRowCount(type) * elementCount();
+ }
}
LinkedUniform::~LinkedUniform()
{
+ delete[] data;
+}
+
+bool LinkedUniform::isArray() const
+{
+ return arraySize > 0;
+}
+
+unsigned int LinkedUniform::elementCount() const
+{
+ return arraySize > 0 ? arraySize : 1;
+}
+
+bool LinkedUniform::isReferencedByVertexShader() const
+{
+ return vsRegisterIndex != GL_INVALID_INDEX;
+}
+
+bool LinkedUniform::isReferencedByFragmentShader() const
+{
+ return psRegisterIndex != GL_INVALID_INDEX;
}
bool LinkedUniform::isInDefaultBlock() const
@@ -68,30 +72,7 @@
size_t LinkedUniform::dataSize() const
{
ASSERT(type != GL_STRUCT_ANGLEX);
- if (mLazyData.empty())
- {
- mLazyData.resize(VariableExternalSize(type) * elementCount());
- ASSERT(!mLazyData.empty());
- }
-
- return mLazyData.size();
-}
-
-uint8_t *LinkedUniform::data()
-{
- if (mLazyData.empty())
- {
- // dataSize() will init the data store.
- size_t size = dataSize();
- memset(mLazyData.data(), 0, size);
- }
-
- return mLazyData.data();
-}
-
-const uint8_t *LinkedUniform::data() const
-{
- return const_cast<LinkedUniform *>(this)->data();
+ return VariableInternalSize(type) * elementCount();
}
bool LinkedUniform::isSampler() const
@@ -99,48 +80,33 @@
return IsSamplerType(type);
}
-bool LinkedUniform::isField() const
+bool LinkedUniform::isBuiltIn() const
{
- return name.find('.') != std::string::npos;
+ return name.compare(0, 3, "gl_") == 0;
}
-size_t LinkedUniform::getElementSize() const
-{
- return VariableExternalSize(type);
-}
-
-uint8_t *LinkedUniform::getDataPtrToElement(size_t elementIndex)
-{
- ASSERT((!isArray() && elementIndex == 0) || (isArray() && elementIndex < arraySize));
- return data() + getElementSize() * elementIndex;
-}
-
-const uint8_t *LinkedUniform::getDataPtrToElement(size_t elementIndex) const
-{
- return const_cast<LinkedUniform *>(this)->getDataPtrToElement(elementIndex);
-}
-
-UniformBlock::UniformBlock()
- : isArray(false),
- arrayElement(0),
- dataSize(0),
- vertexStaticUse(false),
- fragmentStaticUse(false),
+UniformBlock::UniformBlock(const std::string &name, unsigned int elementIndex, unsigned int dataSize)
+ : name(name),
+ elementIndex(elementIndex),
+ dataSize(dataSize),
psRegisterIndex(GL_INVALID_INDEX),
vsRegisterIndex(GL_INVALID_INDEX)
{
}
-UniformBlock::UniformBlock(const std::string &nameIn, bool isArrayIn, unsigned int arrayElementIn)
- : name(nameIn),
- isArray(isArrayIn),
- arrayElement(arrayElementIn),
- dataSize(0),
- vertexStaticUse(false),
- fragmentStaticUse(false),
- psRegisterIndex(GL_INVALID_INDEX),
- vsRegisterIndex(GL_INVALID_INDEX)
+bool UniformBlock::isArrayElement() const
{
+ return elementIndex != GL_INVALID_INDEX;
+}
+
+bool UniformBlock::isReferencedByVertexShader() const
+{
+ return vsRegisterIndex != GL_INVALID_INDEX;
+}
+
+bool UniformBlock::isReferencedByFragmentShader() const
+{
+ return psRegisterIndex != GL_INVALID_INDEX;
}
}
diff --git a/src/libANGLE/Uniform.h b/src/libANGLE/Uniform.h
index 040c978..b73fc9d 100644
--- a/src/libANGLE/Uniform.h
+++ b/src/libANGLE/Uniform.h
@@ -12,7 +12,6 @@
#include "angle_gl.h"
#include "common/debug.h"
-#include "common/MemoryBuffer.h"
#include "compiler/translator/blocklayout.h"
#include "libANGLE/angletypes.h"
@@ -20,47 +19,53 @@
{
// Helper struct representing a single shader uniform
-struct LinkedUniform : public sh::Uniform
+struct LinkedUniform : angle::NonCopyable
{
- LinkedUniform();
LinkedUniform(GLenum type, GLenum precision, const std::string &name, unsigned int arraySize, const int blockIndex, const sh::BlockMemberInfo &blockInfo);
- LinkedUniform(const sh::Uniform &uniform);
- LinkedUniform(const LinkedUniform &uniform);
- LinkedUniform &operator=(const LinkedUniform &uniform);
+
~LinkedUniform();
- size_t dataSize() const;
- uint8_t *data();
- const uint8_t *data() const;
- bool isSampler() const;
+ bool isArray() const;
+ unsigned int elementCount() const;
+ bool isReferencedByVertexShader() const;
+ bool isReferencedByFragmentShader() const;
bool isInDefaultBlock() const;
- bool isField() const;
- size_t getElementSize() const;
- uint8_t *getDataPtrToElement(size_t elementIndex);
- const uint8_t *getDataPtrToElement(size_t elementIndex) const;
+ size_t dataSize() const;
+ bool isSampler() const;
+ bool isBuiltIn() const;
- int blockIndex;
- sh::BlockMemberInfo blockInfo;
+ const GLenum type;
+ const GLenum precision;
+ const std::string name;
+ const unsigned int arraySize;
+ const int blockIndex;
+ const sh::BlockMemberInfo blockInfo;
- private:
- mutable rx::MemoryBuffer mLazyData;
+ unsigned char *data;
+ bool dirty;
+
+ unsigned int psRegisterIndex;
+ unsigned int vsRegisterIndex;
+ unsigned int registerCount;
+
+ // Register "elements" are used for uniform structs in ES3, to appropriately identify single uniforms
+ // inside aggregate types, which are packed according C-like structure rules.
+ unsigned int registerElement;
};
// Helper struct representing a single shader uniform block
-struct UniformBlock
+struct UniformBlock : angle::NonCopyable
{
- UniformBlock();
- UniformBlock(const std::string &nameIn, bool isArrayIn, unsigned int arrayElementIn);
- UniformBlock(const UniformBlock &other) = default;
- UniformBlock &operator=(const UniformBlock &other) = default;
+ // use GL_INVALID_INDEX for non-array elements
+ UniformBlock(const std::string &name, unsigned int elementIndex, unsigned int dataSize);
- std::string name;
- bool isArray;
- unsigned int arrayElement;
- unsigned int dataSize;
+ bool isArrayElement() const;
+ bool isReferencedByVertexShader() const;
+ bool isReferencedByFragmentShader() const;
- bool vertexStaticUse;
- bool fragmentStaticUse;
+ const std::string name;
+ const unsigned int elementIndex;
+ const unsigned int dataSize;
std::vector<unsigned int> memberUniformIndexes;
diff --git a/src/libANGLE/queryconversions.cpp b/src/libANGLE/queryconversions.cpp
index 5633ce4..d18a8e1 100644
--- a/src/libANGLE/queryconversions.cpp
+++ b/src/libANGLE/queryconversions.cpp
@@ -6,24 +6,32 @@
// queryconversions.cpp: Implementation of state query cast conversions
-#include "libANGLE/queryconversions.h"
-
#include "libANGLE/Context.h"
#include "common/utilities.h"
namespace gl
{
-namespace
-{
+// Helper class for converting a GL type to a GLenum:
+// We can't use CastStateValueEnum generally, because of GLboolean + GLubyte overlap.
+// We restrict our use to CastStateValue, where it eliminates duplicate parameters.
-GLint64 ExpandFloatToInteger(GLfloat value)
+template <typename GLType>
+struct CastStateValueEnum { static GLenum mEnumForType; };
+
+template <> GLenum CastStateValueEnum<GLint>::mEnumForType = GL_INT;
+template <> GLenum CastStateValueEnum<GLuint>::mEnumForType = GL_UNSIGNED_INT;
+template <> GLenum CastStateValueEnum<GLboolean>::mEnumForType = GL_BOOL;
+template <> GLenum CastStateValueEnum<GLint64>::mEnumForType = GL_INT_64_ANGLEX;
+template <> GLenum CastStateValueEnum<GLfloat>::mEnumForType = GL_FLOAT;
+
+static GLint64 ExpandFloatToInteger(GLfloat value)
{
return static_cast<GLint64>((static_cast<double>(0xFFFFFFFFULL) * value - 1.0) / 2.0);
}
template <typename QueryT>
-QueryT ClampToQueryRange(GLint64 value)
+static QueryT ClampToQueryRange(GLint64 value)
{
const GLint64 min = static_cast<GLint64>(std::numeric_limits<QueryT>::min());
const GLint64 max = static_cast<GLint64>(std::numeric_limits<QueryT>::max());
@@ -33,8 +41,8 @@
template <typename QueryT, typename NativeT>
QueryT CastStateValueToInt(GLenum pname, NativeT value)
{
- GLenum queryType = GLTypeToGLenum<QueryT>::value;
- GLenum nativeType = GLTypeToGLenum<NativeT>::value;
+ GLenum queryType = CastStateValueEnum<QueryT>::mEnumForType;
+ GLenum nativeType = CastStateValueEnum<NativeT>::mEnumForType;
if (nativeType == GL_FLOAT)
{
@@ -64,37 +72,18 @@
template <typename QueryT, typename NativeT>
QueryT CastStateValue(GLenum pname, NativeT value)
{
- GLenum queryType = GLTypeToGLenum<QueryT>::value;
+ GLenum queryType = CastStateValueEnum<QueryT>::mEnumForType;
switch (queryType)
{
- case GL_INT:
- return CastStateValueToInt<QueryT, NativeT>(pname, value);
- case GL_INT_64_ANGLEX:
- return CastStateValueToInt<QueryT, NativeT>(pname, value);
- case GL_FLOAT:
- return static_cast<QueryT>(value);
- case GL_BOOL:
- return static_cast<QueryT>(value == static_cast<NativeT>(0) ? GL_FALSE : GL_TRUE);
- default:
- UNREACHABLE();
- return 0;
+ case GL_INT: return CastStateValueToInt<QueryT, NativeT>(pname, value);
+ case GL_INT_64_ANGLEX: return CastStateValueToInt<QueryT, NativeT>(pname, value);
+ case GL_FLOAT: return static_cast<QueryT>(value);
+ case GL_BOOL: return static_cast<QueryT>(value == static_cast<NativeT>(0) ? GL_FALSE : GL_TRUE);
+ default: UNREACHABLE(); return 0;
}
}
-} // anonymous namespace
-
-template <>
-GLenum GLTypeToGLenum<GLint>::value = GL_INT;
-template <>
-GLenum GLTypeToGLenum<GLuint>::value = GL_UNSIGNED_INT;
-template <>
-GLenum GLTypeToGLenum<GLboolean>::value = GL_BOOL;
-template <>
-GLenum GLTypeToGLenum<GLint64>::value = GL_INT_64_ANGLEX;
-template <>
-GLenum GLTypeToGLenum<GLfloat>::value = GL_FLOAT;
-
template <typename QueryT>
void CastStateValues(Context *context, GLenum nativeType, GLenum pname,
unsigned int numParams, QueryT *outParams)
diff --git a/src/libANGLE/queryconversions.h b/src/libANGLE/queryconversions.h
index e0fdbe1..da7047f 100644
--- a/src/libANGLE/queryconversions.h
+++ b/src/libANGLE/queryconversions.h
@@ -6,25 +6,8 @@
// queryconversions.h: Declaration of state query cast conversions
-#ifndef LIBANGLE_QUERY_CONVERSIONS_H_
-#define LIBANGLE_QUERY_CONVERSIONS_H_
-
-#include "angle_gl.h"
-#include "common/angleutils.h"
-
namespace gl
{
-class Context;
-
-// Helper class for converting a GL type to a GLenum:
-// We can't use CastStateValueEnum generally, because of GLboolean + GLubyte overlap.
-// We restrict our use to CastStateValue, where it eliminates duplicate parameters.
-
-template <typename GLType>
-struct GLTypeToGLenum
-{
- static GLenum value;
-};
// The GL state query API types are: bool, int, uint, float, int64
template <typename QueryT>
@@ -32,5 +15,3 @@
unsigned int numParams, QueryT *outParams);
}
-
-#endif // LIBANGLE_QUERY_CONVERSIONS_H_
diff --git a/src/libANGLE/renderer/ProgramImpl.cpp b/src/libANGLE/renderer/ProgramImpl.cpp
new file mode 100644
index 0000000..051ef16
--- /dev/null
+++ b/src/libANGLE/renderer/ProgramImpl.cpp
@@ -0,0 +1,137 @@
+//
+// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// ProgramD3D.cpp: Defines the rx::ProgramD3D class which implements rx::ProgramImpl.
+
+#include "libANGLE/renderer/ProgramImpl.h"
+
+#include "common/utilities.h"
+
+namespace rx
+{
+
+LinkResult::LinkResult(bool linkSuccess, const gl::Error &error)
+ : linkSuccess(linkSuccess),
+ error(error)
+{
+}
+
+ProgramImpl::ProgramImpl(const gl::Program::Data &data) : mData(data)
+{
+}
+
+ProgramImpl::~ProgramImpl()
+{
+ // Ensure that reset was called by the inherited class during destruction
+ ASSERT(mUniformIndex.size() == 0);
+}
+
+gl::LinkedUniform *ProgramImpl::getUniformByLocation(GLint location) const
+{
+ ASSERT(location >= 0 && mUniformIndex.find(location) != mUniformIndex.end());
+ return mUniforms[mUniformIndex.at(location).index];
+}
+
+gl::LinkedUniform *ProgramImpl::getUniformByName(const std::string &name) const
+{
+ for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++)
+ {
+ if (mUniforms[uniformIndex]->name == name)
+ {
+ return mUniforms[uniformIndex];
+ }
+ }
+
+ return NULL;
+}
+
+gl::UniformBlock *ProgramImpl::getUniformBlockByIndex(GLuint blockIndex) const
+{
+ ASSERT(blockIndex < mUniformBlocks.size());
+ return mUniformBlocks[blockIndex];
+}
+
+GLint ProgramImpl::getUniformLocation(const std::string &name) const
+{
+ size_t subscript = GL_INVALID_INDEX;
+ std::string baseName = gl::ParseUniformName(name, &subscript);
+
+ for (const auto &info : mUniformIndex)
+ {
+ GLuint location = info.first;
+ const gl::VariableLocation &uniform = info.second;
+
+ if (uniform.name == baseName)
+ {
+ const bool isArray = mUniforms[uniform.index]->isArray();
+
+ if ((isArray && uniform.element == subscript) ||
+ (subscript == GL_INVALID_INDEX))
+ {
+ return location;
+ }
+ }
+ }
+
+ return -1;
+}
+
+GLuint ProgramImpl::getUniformIndex(const std::string &name) const
+{
+ size_t subscript = GL_INVALID_INDEX;
+ std::string baseName = gl::ParseUniformName(name, &subscript);
+
+ // The app is not allowed to specify array indices other than 0 for arrays of basic types
+ if (subscript != 0 && subscript != GL_INVALID_INDEX)
+ {
+ return GL_INVALID_INDEX;
+ }
+
+ unsigned int numUniforms = static_cast<unsigned int>(mUniforms.size());
+ for (unsigned int index = 0; index < numUniforms; index++)
+ {
+ if (mUniforms[index]->name == baseName)
+ {
+ if (mUniforms[index]->isArray() || subscript == GL_INVALID_INDEX)
+ {
+ return index;
+ }
+ }
+ }
+
+ return GL_INVALID_INDEX;
+}
+
+GLuint ProgramImpl::getUniformBlockIndex(const std::string &name) const
+{
+ size_t subscript = GL_INVALID_INDEX;
+ std::string baseName = gl::ParseUniformName(name, &subscript);
+
+ unsigned int numUniformBlocks = static_cast<unsigned int>(mUniformBlocks.size());
+ for (unsigned int blockIndex = 0; blockIndex < numUniformBlocks; blockIndex++)
+ {
+ const gl::UniformBlock &uniformBlock = *mUniformBlocks[blockIndex];
+ if (uniformBlock.name == baseName)
+ {
+ const bool arrayElementZero = (subscript == GL_INVALID_INDEX && uniformBlock.elementIndex == 0);
+ if (subscript == uniformBlock.elementIndex || arrayElementZero)
+ {
+ return blockIndex;
+ }
+ }
+ }
+
+ return GL_INVALID_INDEX;
+}
+
+void ProgramImpl::reset()
+{
+ SafeDeleteContainer(mUniforms);
+ mUniformIndex.clear();
+ SafeDeleteContainer(mUniformBlocks);
+}
+
+}
diff --git a/src/libANGLE/renderer/ProgramImpl.h b/src/libANGLE/renderer/ProgramImpl.h
index 47fb9be..94da0c7 100644
--- a/src/libANGLE/renderer/ProgramImpl.h
+++ b/src/libANGLE/renderer/ProgramImpl.h
@@ -23,17 +23,16 @@
struct LinkResult
{
- LinkResult(bool linkSuccess, const gl::Error &error) : linkSuccess(linkSuccess), error(error) {}
-
bool linkSuccess;
gl::Error error;
+ LinkResult(bool linkSuccess, const gl::Error &error);
};
class ProgramImpl : angle::NonCopyable
{
public:
- ProgramImpl(const gl::Program::Data &data) : mData(data) {}
- virtual ~ProgramImpl() {}
+ ProgramImpl(const gl::Program::Data &data);
+ virtual ~ProgramImpl();
virtual int getShaderVersion() const = 0;
@@ -66,16 +65,41 @@
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 getUniformfv(GLint location, GLfloat *params) = 0;
+ virtual void getUniformiv(GLint location, GLint *params) = 0;
+ virtual void getUniformuiv(GLint location, GLuint *params) = 0;
+
// TODO: The following functions are possibly only applicable to D3D backends. The should be carefully evaluated to
// determine if they can be removed from this interface.
virtual bool validateSamplers(gl::InfoLog *infoLog, const gl::Caps &caps) = 0;
- // Gather uniform block active uniform indices, and uniform block offset info.
- virtual void gatherUniformBlockInfo(std::vector<gl::UniformBlock> *uniformBlocks,
- std::vector<gl::LinkedUniform> *uniforms) = 0;
+ const std::vector<gl::LinkedUniform*> &getUniforms() const { return mUniforms; }
+ const std::map<GLuint, gl::VariableLocation> &getUniformIndices() const { return mUniformIndex; }
+ const std::vector<gl::UniformBlock*> &getUniformBlocks() const { return mUniformBlocks; }
+
+ std::vector<gl::LinkedUniform*> &getUniforms() { return mUniforms; }
+ std::map<GLuint, gl::VariableLocation> &getUniformIndices() { return mUniformIndex; }
+ std::vector<gl::UniformBlock*> &getUniformBlocks() { return mUniformBlocks; }
+
+ gl::LinkedUniform *getUniformByLocation(GLint location) const;
+ gl::LinkedUniform *getUniformByName(const std::string &name) const;
+ gl::UniformBlock *getUniformBlockByIndex(GLuint blockIndex) const;
+
+ GLint getUniformLocation(const std::string &name) const;
+ GLuint getUniformIndex(const std::string &name) const;
+ GLuint getUniformBlockIndex(const std::string &name) const;
+
+ virtual void reset();
protected:
const gl::Program::Data &mData;
+
+ std::vector<gl::LinkedUniform*> mUniforms;
+
+ // TODO: use a hash map
+ std::map<GLuint, gl::VariableLocation> mUniformIndex;
+
+ std::vector<gl::UniformBlock*> mUniformBlocks;
};
}
diff --git a/src/libANGLE/renderer/d3d/ProgramD3D.cpp b/src/libANGLE/renderer/d3d/ProgramD3D.cpp
index d9962dc..13415a3 100644
--- a/src/libANGLE/renderer/d3d/ProgramD3D.cpp
+++ b/src/libANGLE/renderer/d3d/ProgramD3D.cpp
@@ -171,92 +171,8 @@
return packedVaryings;
}
-template <typename VarT>
-void GetUniformBlockInfo(const std::vector<VarT> &fields,
- const std::string &prefix,
- sh::BlockLayoutEncoder *encoder,
- bool inRowMajorLayout,
- std::map<std::string, sh::BlockMemberInfo> *blockInfoOut)
-{
- for (const VarT &field : fields)
- {
- const std::string &fieldName = (prefix.empty() ? field.name : prefix + "." + field.name);
-
- if (field.isStruct())
- {
- bool rowMajorLayout = (inRowMajorLayout || IsRowMajorLayout(field));
-
- for (unsigned int arrayElement = 0; arrayElement < field.elementCount(); arrayElement++)
- {
- encoder->enterAggregateType();
-
- const std::string uniformElementName =
- fieldName + (field.isArray() ? ArrayString(arrayElement) : "");
- GetUniformBlockInfo(field.fields, uniformElementName, encoder, rowMajorLayout,
- blockInfoOut);
-
- encoder->exitAggregateType();
- }
- }
- else
- {
- bool isRowMajorMatrix = (gl::IsMatrixType(field.type) && inRowMajorLayout);
- (*blockInfoOut)[fieldName] =
- encoder->encodeType(field.type, field.arraySize, isRowMajorMatrix);
- }
- }
-}
-
} // anonymous namespace
-D3DUniform::D3DUniform(GLenum typeIn,
- const std::string &nameIn,
- unsigned int arraySizeIn,
- bool defaultBlock)
- : type(typeIn),
- name(nameIn),
- arraySize(arraySizeIn),
- data(nullptr),
- dirty(true),
- psRegisterIndex(GL_INVALID_INDEX),
- vsRegisterIndex(GL_INVALID_INDEX),
- registerCount(0),
- registerElement(0)
-{
- // We use data storage for default block uniforms to cache values that are sent to D3D during
- // rendering
- // Uniform blocks/buffers are treated separately by the Renderer (ES3 path only)
- if (defaultBlock)
- {
- size_t bytes = gl::VariableInternalSize(type) * elementCount();
- data = new uint8_t[bytes];
- memset(data, 0, bytes);
-
- // TODO(jmadill): is this correct with non-square matrices?
- registerCount = gl::VariableRowCount(type) * elementCount();
- }
-}
-
-D3DUniform::~D3DUniform()
-{
- SafeDeleteArray(data);
-}
-
-bool D3DUniform::isSampler() const
-{
- return gl::IsSamplerType(type);
-}
-
-bool D3DUniform::isReferencedByVertexShader() const
-{
- return vsRegisterIndex != GL_INVALID_INDEX;
-}
-
-bool D3DUniform::isReferencedByFragmentShader() const
-{
- return psRegisterIndex != GL_INVALID_INDEX;
-}
-
ProgramD3D::VertexExecutable::VertexExecutable(const gl::InputLayout &inputLayout,
const Signature &signature,
ShaderExecutableD3D *shaderExecutable)
@@ -440,45 +356,47 @@
mDirtySamplerMapping = false;
// Retrieve sampler uniform values
- for (const D3DUniform *d3dUniform : mD3DUniforms)
+ for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++)
{
- if (!d3dUniform->dirty)
- continue;
+ gl::LinkedUniform *targetUniform = mUniforms[uniformIndex];
- if (!d3dUniform->isSampler())
- continue;
-
- int count = d3dUniform->elementCount();
- const GLint(*v)[4] = reinterpret_cast<const GLint(*)[4]>(d3dUniform->data);
-
- if (d3dUniform->isReferencedByFragmentShader())
+ if (targetUniform->dirty)
{
- unsigned int firstIndex = d3dUniform->psRegisterIndex;
-
- for (int i = 0; i < count; i++)
+ if (gl::IsSamplerType(targetUniform->type))
{
- unsigned int samplerIndex = firstIndex + i;
+ int count = targetUniform->elementCount();
+ GLint (*v)[4] = reinterpret_cast<GLint(*)[4]>(targetUniform->data);
- if (samplerIndex < mSamplersPS.size())
+ if (targetUniform->isReferencedByFragmentShader())
{
- ASSERT(mSamplersPS[samplerIndex].active);
- mSamplersPS[samplerIndex].logicalTextureUnit = v[i][0];
+ unsigned int firstIndex = targetUniform->psRegisterIndex;
+
+ for (int i = 0; i < count; i++)
+ {
+ unsigned int samplerIndex = firstIndex + i;
+
+ if (samplerIndex < mSamplersPS.size())
+ {
+ ASSERT(mSamplersPS[samplerIndex].active);
+ mSamplersPS[samplerIndex].logicalTextureUnit = v[i][0];
+ }
+ }
}
- }
- }
- if (d3dUniform->isReferencedByVertexShader())
- {
- unsigned int firstIndex = d3dUniform->vsRegisterIndex;
-
- for (int i = 0; i < count; i++)
- {
- unsigned int samplerIndex = firstIndex + i;
-
- if (samplerIndex < mSamplersVS.size())
+ if (targetUniform->isReferencedByVertexShader())
{
- ASSERT(mSamplersVS[samplerIndex].active);
- mSamplersVS[samplerIndex].logicalTextureUnit = v[i][0];
+ unsigned int firstIndex = targetUniform->vsRegisterIndex;
+
+ for (int i = 0; i < count; i++)
+ {
+ unsigned int samplerIndex = firstIndex + i;
+
+ if (samplerIndex < mSamplersVS.size())
+ {
+ ASSERT(mSamplersVS[samplerIndex].active);
+ mSamplersVS[samplerIndex].logicalTextureUnit = v[i][0];
+ }
+ }
}
}
}
@@ -587,8 +505,6 @@
LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream)
{
- reset();
-
DeviceIdentifier binaryDeviceIdentifier = { 0 };
stream->readBytes(reinterpret_cast<unsigned char*>(&binaryDeviceIdentifier), sizeof(DeviceIdentifier));
@@ -643,21 +559,79 @@
return LinkResult(false, gl::Error(GL_NO_ERROR));
}
- const auto &linkedUniforms = mData.getUniforms();
- ASSERT(mD3DUniforms.empty());
+ mUniforms.resize(uniformCount);
for (unsigned int uniformIndex = 0; uniformIndex < uniformCount; uniformIndex++)
{
- const gl::LinkedUniform &linkedUniform = linkedUniforms[uniformIndex];
+ GLenum type = stream->readInt<GLenum>();
+ GLenum precision = stream->readInt<GLenum>();
+ std::string name = stream->readString();
+ unsigned int arraySize = stream->readInt<unsigned int>();
+ int blockIndex = stream->readInt<int>();
- D3DUniform *d3dUniform =
- new D3DUniform(linkedUniform.type, linkedUniform.name, linkedUniform.arraySize,
- linkedUniform.isInDefaultBlock());
- stream->readInt(&d3dUniform->psRegisterIndex);
- stream->readInt(&d3dUniform->vsRegisterIndex);
- stream->readInt(&d3dUniform->registerCount);
- stream->readInt(&d3dUniform->registerElement);
+ int offset = stream->readInt<int>();
+ int arrayStride = stream->readInt<int>();
+ int matrixStride = stream->readInt<int>();
+ bool isRowMajorMatrix = stream->readBool();
- mD3DUniforms.push_back(d3dUniform);
+ const sh::BlockMemberInfo blockInfo(offset, arrayStride, matrixStride, isRowMajorMatrix);
+
+ gl::LinkedUniform *uniform = new gl::LinkedUniform(type, precision, name, arraySize, blockIndex, blockInfo);
+
+ stream->readInt(&uniform->psRegisterIndex);
+ stream->readInt(&uniform->vsRegisterIndex);
+ stream->readInt(&uniform->registerCount);
+ stream->readInt(&uniform->registerElement);
+
+ mUniforms[uniformIndex] = uniform;
+ }
+
+ const unsigned int uniformIndexCount = stream->readInt<unsigned int>();
+ if (stream->error())
+ {
+ infoLog << "Invalid program binary.";
+ return LinkResult(false, gl::Error(GL_NO_ERROR));
+ }
+
+ for (unsigned int uniformIndexIndex = 0; uniformIndexIndex < uniformIndexCount; uniformIndexIndex++)
+ {
+ GLuint location;
+ stream->readInt(&location);
+
+ gl::VariableLocation variable;
+ stream->readString(&variable.name);
+ stream->readInt(&variable.element);
+ stream->readInt(&variable.index);
+
+ mUniformIndex[location] = variable;
+ }
+
+ unsigned int uniformBlockCount = stream->readInt<unsigned int>();
+ if (stream->error())
+ {
+ infoLog << "Invalid program binary.";
+ return LinkResult(false, gl::Error(GL_NO_ERROR));
+ }
+
+ mUniformBlocks.resize(uniformBlockCount);
+ for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < uniformBlockCount; ++uniformBlockIndex)
+ {
+ std::string name = stream->readString();
+ unsigned int elementIndex = stream->readInt<unsigned int>();
+ unsigned int dataSize = stream->readInt<unsigned int>();
+
+ gl::UniformBlock *uniformBlock = new gl::UniformBlock(name, elementIndex, dataSize);
+
+ stream->readInt(&uniformBlock->psRegisterIndex);
+ stream->readInt(&uniformBlock->vsRegisterIndex);
+
+ unsigned int numMembers = stream->readInt<unsigned int>();
+ uniformBlock->memberUniformIndexes.resize(numMembers);
+ for (unsigned int blockMemberIndex = 0; blockMemberIndex < numMembers; blockMemberIndex++)
+ {
+ stream->readInt(&uniformBlock->memberUniformIndexes[blockMemberIndex]);
+ }
+
+ mUniformBlocks[uniformBlockIndex] = uniformBlock;
}
const unsigned int transformFeedbackVaryingCount = stream->readInt<unsigned int>();
@@ -831,18 +805,59 @@
stream->writeInt(mUsedVertexSamplerRange);
stream->writeInt(mUsedPixelSamplerRange);
- stream->writeInt(mD3DUniforms.size());
- for (size_t uniformIndex = 0; uniformIndex < mD3DUniforms.size(); ++uniformIndex)
+ stream->writeInt(mUniforms.size());
+ for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); ++uniformIndex)
{
- const D3DUniform &uniform = *mD3DUniforms[uniformIndex];
+ const gl::LinkedUniform &uniform = *mUniforms[uniformIndex];
- // Type, name and arraySize are redundant, so aren't stored in the binary.
+ stream->writeInt(uniform.type);
+ stream->writeInt(uniform.precision);
+ stream->writeString(uniform.name);
+ stream->writeInt(uniform.arraySize);
+ stream->writeInt(uniform.blockIndex);
+
+ stream->writeInt(uniform.blockInfo.offset);
+ stream->writeInt(uniform.blockInfo.arrayStride);
+ stream->writeInt(uniform.blockInfo.matrixStride);
+ stream->writeInt(uniform.blockInfo.isRowMajorMatrix);
+
stream->writeInt(uniform.psRegisterIndex);
stream->writeInt(uniform.vsRegisterIndex);
stream->writeInt(uniform.registerCount);
stream->writeInt(uniform.registerElement);
}
+ stream->writeInt(mUniformIndex.size());
+ for (const auto &uniform : mUniformIndex)
+ {
+ GLuint location = uniform.first;
+ stream->writeInt(location);
+
+ const gl::VariableLocation &variable = uniform.second;
+ stream->writeString(variable.name);
+ stream->writeInt(variable.element);
+ stream->writeInt(variable.index);
+ }
+
+ stream->writeInt(mUniformBlocks.size());
+ for (size_t uniformBlockIndex = 0; uniformBlockIndex < mUniformBlocks.size(); ++uniformBlockIndex)
+ {
+ const gl::UniformBlock& uniformBlock = *mUniformBlocks[uniformBlockIndex];
+
+ stream->writeString(uniformBlock.name);
+ stream->writeInt(uniformBlock.elementIndex);
+ stream->writeInt(uniformBlock.dataSize);
+
+ stream->writeInt(uniformBlock.memberUniformIndexes.size());
+ for (unsigned int blockMemberIndex = 0; blockMemberIndex < uniformBlock.memberUniformIndexes.size(); blockMemberIndex++)
+ {
+ stream->writeInt(uniformBlock.memberUniformIndexes[blockMemberIndex]);
+ }
+
+ stream->writeInt(uniformBlock.psRegisterIndex);
+ stream->writeInt(uniformBlock.vsRegisterIndex);
+ }
+
stream->writeInt(mTransformFeedbackLinkedVaryings.size());
for (size_t i = 0; i < mTransformFeedbackLinkedVaryings.size(); i++)
{
@@ -1111,18 +1126,6 @@
LinkResult ProgramD3D::link(const gl::Data &data, gl::InfoLog &infoLog)
{
- reset();
-
- // TODO(jmadill): structures containing samplers
- for (const gl::LinkedUniform &linkedUniform : mData.getUniforms())
- {
- if (linkedUniform.isSampler() && linkedUniform.isField())
- {
- infoLog << "Structures containing samplers not currently supported in D3D.";
- return LinkResult(false, gl::Error(GL_NO_ERROR));
- }
- }
-
const gl::Shader *vertexShader = mData.getAttachedVertexShader();
const gl::Shader *fragmentShader = mData.getAttachedFragmentShader();
@@ -1172,7 +1175,12 @@
initSemanticIndex();
- assignUniformRegisters();
+ if (!defineUniforms(infoLog, *data.caps))
+ {
+ return LinkResult(false, gl::Error(GL_NO_ERROR));
+ }
+
+ defineUniformBlocks(*data.caps);
gatherTransformFeedbackVaryings(linkedVaryings);
@@ -1192,96 +1200,24 @@
return validateSamplers(infoLog, caps);
}
-void ProgramD3D::gatherUniformBlockInfo(std::vector<gl::UniformBlock> *uniformBlocks,
- std::vector<gl::LinkedUniform> *uniforms)
-{
- const gl::Shader *vertexShader = mData.getAttachedVertexShader();
-
- BlockInfoMap blockInfo;
- std::map<std::string, size_t> blockDataSizes;
-
- for (const sh::InterfaceBlock &vertexBlock : vertexShader->getInterfaceBlocks())
- {
- if (!vertexBlock.staticUse && vertexBlock.layout == sh::BLOCKLAYOUT_PACKED)
- continue;
-
- if (blockDataSizes.count(vertexBlock.name) > 0)
- continue;
-
- size_t dataSize = defineUniformBlock(vertexBlock, &blockInfo);
- blockDataSizes[vertexBlock.name] = dataSize;
- }
-
- const gl::Shader *fragmentShader = mData.getAttachedFragmentShader();
-
- for (const sh::InterfaceBlock &fragmentBlock : fragmentShader->getInterfaceBlocks())
- {
- if (!fragmentBlock.staticUse && fragmentBlock.layout == sh::BLOCKLAYOUT_PACKED)
- continue;
-
- if (blockDataSizes.count(fragmentBlock.name) > 0)
- continue;
-
- size_t dataSize = defineUniformBlock(fragmentBlock, &blockInfo);
- blockDataSizes[fragmentBlock.name] = dataSize;
- }
-
- // Copy block info out to uniforms.
- for (gl::LinkedUniform &linkedUniform : *uniforms)
- {
- const auto &infoEntry = blockInfo.find(linkedUniform.name);
-
- if (infoEntry != blockInfo.end())
- {
- linkedUniform.blockInfo = infoEntry->second;
- }
- }
-
- // Assign registers and update sizes.
- const ShaderD3D *vertexShaderD3D = GetImplAs<ShaderD3D>(vertexShader);
- const ShaderD3D *fragmentShaderD3D = GetImplAs<ShaderD3D>(fragmentShader);
-
- for (gl::UniformBlock &uniformBlock : *uniformBlocks)
- {
- unsigned int uniformBlockElement = uniformBlock.isArray ? uniformBlock.arrayElement : 0;
-
- if (uniformBlock.vertexStaticUse)
- {
- unsigned int baseRegister =
- vertexShaderD3D->getInterfaceBlockRegister(uniformBlock.name);
- uniformBlock.vsRegisterIndex = baseRegister + uniformBlockElement;
- }
-
- if (uniformBlock.fragmentStaticUse)
- {
- unsigned int baseRegister =
- fragmentShaderD3D->getInterfaceBlockRegister(uniformBlock.name);
- uniformBlock.psRegisterIndex = baseRegister + uniformBlockElement;
- }
-
- ASSERT(blockDataSizes.count(uniformBlock.name) == 1);
- uniformBlock.dataSize = static_cast<unsigned int>(blockDataSizes[uniformBlock.name]);
- }
-}
-
void ProgramD3D::initializeUniformStorage()
{
// Compute total default block size
unsigned int vertexRegisters = 0;
unsigned int fragmentRegisters = 0;
- for (const D3DUniform *d3dUniform : mD3DUniforms)
+ for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++)
{
- if (!d3dUniform->isSampler())
+ const gl::LinkedUniform &uniform = *mUniforms[uniformIndex];
+
+ if (!gl::IsSamplerType(uniform.type))
{
- if (d3dUniform->isReferencedByVertexShader())
+ if (uniform.isReferencedByVertexShader())
{
- vertexRegisters = std::max(vertexRegisters,
- d3dUniform->vsRegisterIndex + d3dUniform->registerCount);
+ vertexRegisters = std::max(vertexRegisters, uniform.vsRegisterIndex + uniform.registerCount);
}
- if (d3dUniform->isReferencedByFragmentShader())
+ if (uniform.isReferencedByFragmentShader())
{
- fragmentRegisters = std::max(
- fragmentRegisters, d3dUniform->psRegisterIndex + d3dUniform->registerCount);
+ fragmentRegisters = std::max(fragmentRegisters, uniform.psRegisterIndex + uniform.registerCount);
}
}
}
@@ -1294,15 +1230,15 @@
{
updateSamplerMapping();
- gl::Error error = mRenderer->applyUniforms(*this, mD3DUniforms);
+ gl::Error error = mRenderer->applyUniforms(*this, mUniforms);
if (error.isError())
{
return error;
}
- for (D3DUniform *d3dUniform : mD3DUniforms)
+ for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++)
{
- d3dUniform->dirty = false;
+ mUniforms[uniformIndex]->dirty = false;
}
return gl::Error(GL_NO_ERROR);
@@ -1316,22 +1252,22 @@
const unsigned int reservedBuffersInVS = mRenderer->getReservedVertexUniformBuffers();
const unsigned int reservedBuffersInFS = mRenderer->getReservedFragmentUniformBuffers();
- const auto &uniformBlocks = mData.getUniformBlocks();
- for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < uniformBlocks.size();
- uniformBlockIndex++)
+ for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < mUniformBlocks.size(); uniformBlockIndex++)
{
- const gl::UniformBlock &uniformBlock = uniformBlocks[uniformBlockIndex];
+ gl::UniformBlock *uniformBlock = mUniformBlocks[uniformBlockIndex];
GLuint blockBinding = mData.getUniformBlockBinding(uniformBlockIndex);
+ ASSERT(uniformBlock);
+
// Unnecessary to apply an unreferenced standard or shared UBO
- if (!uniformBlock.vertexStaticUse && !uniformBlock.fragmentStaticUse)
+ if (!uniformBlock->isReferencedByVertexShader() && !uniformBlock->isReferencedByFragmentShader())
{
continue;
}
- if (uniformBlock.vertexStaticUse)
+ if (uniformBlock->isReferencedByVertexShader())
{
- unsigned int registerIndex = uniformBlock.vsRegisterIndex - reservedBuffersInVS;
+ unsigned int registerIndex = uniformBlock->vsRegisterIndex - reservedBuffersInVS;
ASSERT(registerIndex < data.caps->maxVertexUniformBlocks);
if (mVertexUBOCache.size() <= registerIndex)
@@ -1343,9 +1279,9 @@
mVertexUBOCache[registerIndex] = blockBinding;
}
- if (uniformBlock.fragmentStaticUse)
+ if (uniformBlock->isReferencedByFragmentShader())
{
- unsigned int registerIndex = uniformBlock.psRegisterIndex - reservedBuffersInFS;
+ unsigned int registerIndex = uniformBlock->psRegisterIndex - reservedBuffersInFS;
ASSERT(registerIndex < data.caps->maxFragmentUniformBlocks);
if (mFragmentUBOCache.size() <= registerIndex)
@@ -1361,11 +1297,31 @@
return mRenderer->setUniformBuffers(data, mVertexUBOCache, mFragmentUBOCache);
}
+void ProgramD3D::assignUniformBlockRegister(gl::UniformBlock *uniformBlock,
+ GLenum shader,
+ unsigned int registerIndex,
+ const gl::Caps &caps)
+{
+ // Validation done in the GL-level Program.
+ if (shader == GL_VERTEX_SHADER)
+ {
+ uniformBlock->vsRegisterIndex = registerIndex;
+ ASSERT(registerIndex < caps.maxVertexUniformBlocks);
+ }
+ else if (shader == GL_FRAGMENT_SHADER)
+ {
+ uniformBlock->psRegisterIndex = registerIndex;
+ ASSERT(registerIndex < caps.maxFragmentUniformBlocks);
+ }
+ else UNREACHABLE();
+}
+
void ProgramD3D::dirtyAllUniforms()
{
- for (D3DUniform *d3dUniform : mD3DUniforms)
+ unsigned int numUniforms = static_cast<unsigned int>(mUniforms.size());
+ for (unsigned int index = 0; index < numUniforms; index++)
{
- d3dUniform->dirty = true;
+ mUniforms[index]->dirty = true;
}
}
@@ -1474,68 +1430,93 @@
setUniform(location, count, v, GL_UNSIGNED_INT_VEC4);
}
-void ProgramD3D::assignUniformRegisters()
+void ProgramD3D::getUniformfv(GLint location, GLfloat *params)
{
- const gl::Shader *vertexShader = mData.getAttachedVertexShader();
- const ShaderD3D *vertexShaderD3D = GetImplAs<ShaderD3D>(vertexShader);
-
- for (const sh::Uniform &vertexUniform : vertexShader->getUniforms())
-
- {
- if (vertexUniform.staticUse)
- {
- assignUniformRegistersBase(vertexShaderD3D, vertexUniform);
- }
- }
-
- const gl::Shader *fragmentShader = mData.getAttachedFragmentShader();
- const ShaderD3D *fragmentShaderD3D = GetImplAs<ShaderD3D>(fragmentShader);
-
- for (const sh::Uniform &fragmentUniform : fragmentShader->getUniforms())
- {
- if (fragmentUniform.staticUse)
- {
- assignUniformRegistersBase(fragmentShaderD3D, fragmentUniform);
- }
- }
-
- assignAllSamplerRegisters();
- initializeUniformStorage();
+ getUniformv(location, params, GL_FLOAT);
}
-void ProgramD3D::assignUniformRegistersBase(const ShaderD3D *shader, const sh::Uniform &uniform)
+void ProgramD3D::getUniformiv(GLint location, GLint *params)
{
- if (uniform.isBuiltIn())
+ getUniformv(location, params, GL_INT);
+}
+
+void ProgramD3D::getUniformuiv(GLint location, GLuint *params)
+{
+ getUniformv(location, params, GL_UNSIGNED_INT);
+}
+
+bool ProgramD3D::defineUniforms(gl::InfoLog &infoLog, const gl::Caps &caps)
+{
+ const gl::Shader *vertexShader = mData.getAttachedVertexShader();
+ const std::vector<sh::Uniform> &vertexUniforms = vertexShader->getUniforms();
+ const ShaderD3D *vertexShaderD3D = GetImplAs<ShaderD3D>(vertexShader);
+
+ if (vertexUniforms.size() > caps.maxVertexUniformVectors)
{
- assignUniformRegisters(shader, uniform, uniform.name, nullptr);
+ infoLog << "Vertex shader active uniforms exceed GL_MAX_VERTEX_UNIFORM_VECTORS ("
+ << caps.maxVertexUniformVectors << ").";
+ return false;
+ }
+
+ for (const sh::Uniform &uniform : vertexUniforms)
+ {
+ if (uniform.staticUse)
+ {
+ unsigned int registerBase = uniform.isBuiltIn() ? GL_INVALID_INDEX :
+ vertexShaderD3D->getUniformRegister(uniform.name);
+ defineUniformBase(vertexShaderD3D, uniform, registerBase);
+ }
+ }
+
+ const gl::Shader *fragmentShader = mData.getAttachedFragmentShader();
+ const std::vector<sh::Uniform> &fragmentUniforms = fragmentShader->getUniforms();
+ const ShaderD3D *fragmentShaderD3D = GetImplAs<ShaderD3D>(fragmentShader);
+
+ if (fragmentUniforms.size() > caps.maxFragmentUniformVectors)
+ {
+ infoLog << "Vertex shader active uniforms exceed GL_MAX_FRAGMENT_UNIFORM_VECTORS ("
+ << caps.maxFragmentUniformVectors << ").";
+ return false;
+ }
+
+ for (const sh::Uniform &uniform : fragmentUniforms)
+ {
+ if (uniform.staticUse)
+ {
+ unsigned int registerBase = uniform.isBuiltIn() ? GL_INVALID_INDEX :
+ fragmentShaderD3D->getUniformRegister(uniform.name);
+ defineUniformBase(fragmentShaderD3D, uniform, registerBase);
+ }
+ }
+
+ // TODO(jmadill): move the validation part to gl::Program
+ if (!indexUniforms(infoLog, caps))
+ {
+ return false;
+ }
+
+ initializeUniformStorage();
+
+ return true;
+}
+
+void ProgramD3D::defineUniformBase(const ShaderD3D *shader, const sh::Uniform &uniform, unsigned int uniformRegister)
+{
+ if (uniformRegister == GL_INVALID_INDEX)
+ {
+ defineUniform(shader, uniform, uniform.name, nullptr);
return;
}
- unsigned int startRegister = shader->getUniformRegister(uniform.name);
ShShaderOutput outputType = shader->getCompilerOutputType();
sh::HLSLBlockEncoder encoder(sh::HLSLBlockEncoder::GetStrategyFor(outputType));
- encoder.skipRegisters(startRegister);
+ encoder.skipRegisters(uniformRegister);
- assignUniformRegisters(shader, uniform, uniform.name, &encoder);
+ defineUniform(shader, uniform, uniform.name, &encoder);
}
-D3DUniform *ProgramD3D::getD3DUniformByName(const std::string &name)
-{
- for (D3DUniform *d3dUniform : mD3DUniforms)
- {
- if (d3dUniform->name == name)
- {
- return d3dUniform;
- }
- }
-
- return nullptr;
-}
-
-void ProgramD3D::assignUniformRegisters(const ShaderD3D *shader,
- const sh::ShaderVariable &uniform,
- const std::string &fullName,
- sh::HLSLBlockEncoder *encoder)
+void ProgramD3D::defineUniform(const ShaderD3D *shader, const sh::ShaderVariable &uniform,
+ const std::string &fullName, sh::HLSLBlockEncoder *encoder)
{
if (uniform.isStruct())
{
@@ -1551,64 +1532,82 @@
const sh::ShaderVariable &field = uniform.fields[fieldIndex];
const std::string &fieldFullName = (fullName + elementString + "." + field.name);
- assignUniformRegisters(shader, field, fieldFullName, encoder);
+ defineUniform(shader, field, fieldFullName, encoder);
}
if (encoder)
encoder->exitAggregateType();
}
- return;
}
-
- // Not a struct. Arrays are treated as aggregate types.
- if (uniform.isArray() && encoder)
+ else // Not a struct
{
- encoder->enterAggregateType();
- }
+ // Arrays are treated as aggregate types
+ if (uniform.isArray() && encoder)
+ {
+ encoder->enterAggregateType();
+ }
- // Advance the uniform offset, to track registers allocation for structs
- sh::BlockMemberInfo blockInfo =
- encoder ? encoder->encodeType(uniform.type, uniform.arraySize, false)
- : sh::BlockMemberInfo::getDefaultBlockInfo();
+ gl::LinkedUniform *linkedUniform = getUniformByName(fullName);
- D3DUniform *d3dUniform = getD3DUniformByName(fullName);
+ // Advance the uniform offset, to track registers allocation for structs
+ sh::BlockMemberInfo blockInfo = encoder ?
+ encoder->encodeType(uniform.type, uniform.arraySize, false) :
+ sh::BlockMemberInfo::getDefaultBlockInfo();
- if (!d3dUniform)
- {
- // We're building the list twice, make sure we use the same indexing. Special case
- // built-ins.
- ASSERT(fullName.compare(0, 3, "gl_") == 0 ||
- mData.getUniformIndex(fullName) == static_cast<GLint>(mD3DUniforms.size()));
+ if (!linkedUniform)
+ {
+ linkedUniform = new gl::LinkedUniform(uniform.type, uniform.precision, fullName, uniform.arraySize,
+ -1, sh::BlockMemberInfo::getDefaultBlockInfo());
+ ASSERT(linkedUniform);
- d3dUniform = new D3DUniform(uniform.type, fullName, uniform.arraySize, true);
- mD3DUniforms.push_back(d3dUniform);
+ if (encoder)
+ linkedUniform->registerElement = static_cast<unsigned int>(
+ sh::HLSLBlockEncoder::getBlockRegisterElement(blockInfo));
+ mUniforms.push_back(linkedUniform);
+ }
if (encoder)
{
- d3dUniform->registerElement =
- static_cast<unsigned int>(sh::HLSLBlockEncoder::getBlockRegisterElement(blockInfo));
+ if (shader->getShaderType() == GL_FRAGMENT_SHADER)
+ {
+ linkedUniform->psRegisterIndex =
+ static_cast<unsigned int>(sh::HLSLBlockEncoder::getBlockRegister(blockInfo));
+ }
+ else if (shader->getShaderType() == GL_VERTEX_SHADER)
+ {
+ linkedUniform->vsRegisterIndex =
+ static_cast<unsigned int>(sh::HLSLBlockEncoder::getBlockRegister(blockInfo));
+ }
+ else UNREACHABLE();
+ }
+
+ // Arrays are treated as aggregate types
+ if (uniform.isArray() && encoder)
+ {
+ encoder->exitAggregateType();
+ }
+ }
+}
+
+void ProgramD3D::defineUniformBlocks(const gl::Caps &caps)
+{
+ const gl::Shader *vertexShader = mData.getAttachedVertexShader();
+
+ for (const sh::InterfaceBlock &vertexBlock : vertexShader->getInterfaceBlocks())
+ {
+ if (vertexBlock.staticUse || vertexBlock.layout != sh::BLOCKLAYOUT_PACKED)
+ {
+ defineUniformBlock(*vertexShader, vertexBlock, caps);
}
}
- if (encoder)
- {
- unsigned int reg =
- static_cast<unsigned int>(sh::HLSLBlockEncoder::getBlockRegister(blockInfo));
- if (shader->getShaderType() == GL_FRAGMENT_SHADER)
- {
- d3dUniform->psRegisterIndex = reg;
- }
- else if (shader->getShaderType() == GL_VERTEX_SHADER)
- {
- d3dUniform->vsRegisterIndex = reg;
- }
- else
- UNREACHABLE();
+ const gl::Shader *fragmentShader = mData.getAttachedFragmentShader();
- // Arrays are treated as aggregate types
- if (uniform.isArray())
+ for (const sh::InterfaceBlock &fragmentBlock : fragmentShader->getInterfaceBlocks())
+ {
+ if (fragmentBlock.staticUse || fragmentBlock.layout != sh::BLOCKLAYOUT_PACKED)
{
- encoder->exitAggregateType();
+ defineUniformBlock(*fragmentShader, fragmentBlock, caps);
}
}
}
@@ -1624,22 +1623,22 @@
}
template <typename T>
-void ProgramD3D::setUniform(GLint location, GLsizei countIn, const T *v, GLenum targetUniformType)
+void ProgramD3D::setUniform(GLint location, GLsizei count, const T* v, GLenum targetUniformType)
{
const int components = gl::VariableComponentCount(targetUniformType);
const GLenum targetBoolType = gl::VariableBoolVectorType(targetUniformType);
- D3DUniform *targetUniform = getD3DUniformFromLocation(location);
+ gl::LinkedUniform *targetUniform = getUniformByLocation(location);
- unsigned int elementCount = targetUniform->elementCount();
- unsigned int arrayElement = mData.getUniformLocations()[location].element;
- unsigned int count = std::min(elementCount - arrayElement, static_cast<unsigned int>(countIn));
+ int elementCount = targetUniform->elementCount();
+
+ count = std::min(elementCount - (int)mUniformIndex[location].element, count);
if (targetUniform->type == targetUniformType)
{
- T *target = reinterpret_cast<T *>(targetUniform->data) + arrayElement * 4;
+ T *target = reinterpret_cast<T*>(targetUniform->data) + mUniformIndex[location].element * 4;
- for (unsigned int i = 0; i < count; i++)
+ for (int i = 0; i < count; i++)
{
T *dest = target + (i * 4);
const T *source = v + (i * components);
@@ -1656,9 +1655,9 @@
}
else if (targetUniform->type == targetBoolType)
{
- GLint *boolParams = reinterpret_cast<GLint *>(targetUniform->data) + arrayElement * 4;
+ GLint *boolParams = reinterpret_cast<GLint*>(targetUniform->data) + mUniformIndex[location].element * 4;
- for (unsigned int i = 0; i < count; i++)
+ for (int i = 0; i < count; i++)
{
GLint *dest = boolParams + (i * 4);
const T *source = v + (i * components);
@@ -1673,15 +1672,15 @@
}
}
}
- else if (targetUniform->isSampler())
+ else if (gl::IsSamplerType(targetUniform->type))
{
ASSERT(targetUniformType == GL_INT);
- GLint *target = reinterpret_cast<GLint *>(targetUniform->data) + arrayElement * 4;
+ GLint *target = reinterpret_cast<GLint*>(targetUniform->data) + mUniformIndex[location].element * 4;
bool wasDirty = targetUniform->dirty;
- for (unsigned int i = 0; i < count; i++)
+ for (int i = 0; i < count; i++)
{
GLint *dest = target + (i * 4);
const GLint *source = reinterpret_cast<const GLint*>(v) + (i * components);
@@ -1769,23 +1768,17 @@
}
template <int cols, int rows>
-void ProgramD3D::setUniformMatrixfv(GLint location,
- GLsizei countIn,
- GLboolean transpose,
- const GLfloat *value,
- GLenum targetUniformType)
+void ProgramD3D::setUniformMatrixfv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value, GLenum targetUniformType)
{
- D3DUniform *targetUniform = getD3DUniformFromLocation(location);
+ gl::LinkedUniform *targetUniform = getUniformByLocation(location);
- unsigned int elementCount = targetUniform->elementCount();
- unsigned int arrayElement = mData.getUniformLocations()[location].element;
- unsigned int count = std::min(elementCount - arrayElement, static_cast<unsigned int>(countIn));
+ int elementCount = targetUniform->elementCount();
+ count = std::min(elementCount - (int)mUniformIndex[location].element, count);
const unsigned int targetMatrixStride = (4 * rows);
- GLfloat *target =
- (GLfloat *)(targetUniform->data + arrayElement * sizeof(GLfloat) * targetMatrixStride);
+ GLfloat *target = (GLfloat*)(targetUniform->data + mUniformIndex[location].element * sizeof(GLfloat) * targetMatrixStride);
- for (unsigned int i = 0; i < count; i++)
+ for (int i = 0; i < count; i++)
{
// Internally store matrices as transposed versions to accomodate HLSL matrix indexing
if (transpose == GL_FALSE)
@@ -1801,63 +1794,186 @@
}
}
-size_t ProgramD3D::defineUniformBlock(const sh::InterfaceBlock &interfaceBlock,
- BlockInfoMap *blockInfoOut)
+template <typename T>
+void ProgramD3D::getUniformv(GLint location, T *params, GLenum uniformType)
{
- ASSERT(interfaceBlock.staticUse || interfaceBlock.layout == sh::BLOCKLAYOUT_PACKED);
+ gl::LinkedUniform *targetUniform = mUniforms[mUniformIndex[location].index];
- // define member uniforms
- sh::Std140BlockEncoder std140Encoder;
- sh::HLSLBlockEncoder hlslEncoder(sh::HLSLBlockEncoder::ENCODE_PACKED);
- sh::BlockLayoutEncoder *encoder = nullptr;
-
- if (interfaceBlock.layout == sh::BLOCKLAYOUT_STANDARD)
+ if (gl::IsMatrixType(targetUniform->type))
{
- encoder = &std140Encoder;
+ const int rows = gl::VariableRowCount(targetUniform->type);
+ const int cols = gl::VariableColumnCount(targetUniform->type);
+ transposeMatrix(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4 * rows, rows, cols, 4, rows);
+ }
+ else if (uniformType == gl::VariableComponentType(targetUniform->type))
+ {
+ unsigned int size = gl::VariableComponentCount(targetUniform->type);
+ memcpy(params, targetUniform->data + mUniformIndex[location].element * 4 * sizeof(T),
+ size * sizeof(T));
}
else
{
- encoder = &hlslEncoder;
- }
-
- GetUniformBlockInfo(interfaceBlock.fields, "", encoder, interfaceBlock.isRowMajorLayout,
- blockInfoOut);
-
- return encoder->getBlockSize();
-}
-
-void ProgramD3D::assignAllSamplerRegisters()
-{
- for (const D3DUniform *d3dUniform : mD3DUniforms)
- {
- if (d3dUniform->isSampler())
+ unsigned int size = gl::VariableComponentCount(targetUniform->type);
+ switch (gl::VariableComponentType(targetUniform->type))
{
- assignSamplerRegisters(d3dUniform);
+ case GL_BOOL:
+ {
+ GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
+
+ for (unsigned int i = 0; i < size; i++)
+ {
+ params[i] = (boolParams[i] == GL_FALSE) ? static_cast<T>(0) : static_cast<T>(1);
+ }
+ }
+ break;
+
+ case GL_FLOAT:
+ {
+ GLfloat *floatParams = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4;
+
+ for (unsigned int i = 0; i < size; i++)
+ {
+ params[i] = static_cast<T>(roundf(floatParams[i]));
+ }
+ }
+ break;
+
+ case GL_INT:
+ {
+ GLint *intParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
+
+ for (unsigned int i = 0; i < size; i++)
+ {
+ params[i] = static_cast<T>(intParams[i]);
+ }
+ }
+ break;
+
+ case GL_UNSIGNED_INT:
+ {
+ GLuint *uintParams = (GLuint*)targetUniform->data + mUniformIndex[location].element * 4;
+
+ for (unsigned int i = 0; i < size; i++)
+ {
+ params[i] = static_cast<T>(uintParams[i]);
+ }
+ }
+ break;
+
+ default: UNREACHABLE();
}
}
}
-void ProgramD3D::assignSamplerRegisters(const D3DUniform *d3dUniform)
+template <typename VarT>
+void ProgramD3D::defineUniformBlockMembers(const std::vector<VarT> &fields, const std::string &prefix, int blockIndex,
+ sh::BlockLayoutEncoder *encoder, std::vector<unsigned int> *blockUniformIndexes,
+ bool inRowMajorLayout)
{
- ASSERT(d3dUniform->isSampler());
- ASSERT(d3dUniform->vsRegisterIndex != GL_INVALID_INDEX ||
- d3dUniform->psRegisterIndex != GL_INVALID_INDEX);
-
- if (d3dUniform->vsRegisterIndex != GL_INVALID_INDEX)
+ for (unsigned int uniformIndex = 0; uniformIndex < fields.size(); uniformIndex++)
{
- AssignSamplers(d3dUniform->vsRegisterIndex, d3dUniform->type, d3dUniform->arraySize,
- mSamplersVS, &mUsedVertexSamplerRange);
- }
+ const VarT &field = fields[uniformIndex];
+ const std::string &fieldName = (prefix.empty() ? field.name : prefix + "." + field.name);
- if (d3dUniform->psRegisterIndex != GL_INVALID_INDEX)
- {
- AssignSamplers(d3dUniform->psRegisterIndex, d3dUniform->type, d3dUniform->arraySize,
- mSamplersPS, &mUsedPixelSamplerRange);
+ if (field.isStruct())
+ {
+ bool rowMajorLayout = (inRowMajorLayout || IsRowMajorLayout(field));
+
+ for (unsigned int arrayElement = 0; arrayElement < field.elementCount(); arrayElement++)
+ {
+ encoder->enterAggregateType();
+
+ const std::string uniformElementName = fieldName + (field.isArray() ? ArrayString(arrayElement) : "");
+ defineUniformBlockMembers(field.fields, uniformElementName, blockIndex, encoder, blockUniformIndexes, rowMajorLayout);
+
+ encoder->exitAggregateType();
+ }
+ }
+ else
+ {
+ bool isRowMajorMatrix = (gl::IsMatrixType(field.type) && inRowMajorLayout);
+
+ sh::BlockMemberInfo memberInfo = encoder->encodeType(field.type, field.arraySize, isRowMajorMatrix);
+
+ gl::LinkedUniform *newUniform = new gl::LinkedUniform(field.type, field.precision, fieldName, field.arraySize,
+ blockIndex, memberInfo);
+
+ // add to uniform list, but not index, since uniform block uniforms have no location
+ blockUniformIndexes->push_back(static_cast<GLenum>(mUniforms.size()));
+ mUniforms.push_back(newUniform);
+ }
}
}
-// static
-void ProgramD3D::AssignSamplers(unsigned int startSamplerIndex,
+void ProgramD3D::defineUniformBlock(const gl::Shader &shader,
+ const sh::InterfaceBlock &interfaceBlock,
+ const gl::Caps &caps)
+{
+ const ShaderD3D* shaderD3D = GetImplAs<ShaderD3D>(&shader);
+
+ // create uniform block entries if they do not exist
+ if (getUniformBlockIndex(interfaceBlock.name) == GL_INVALID_INDEX)
+ {
+ std::vector<unsigned int> blockUniformIndexes;
+ const unsigned int blockIndex = static_cast<unsigned int>(mUniformBlocks.size());
+
+ // define member uniforms
+ sh::BlockLayoutEncoder *encoder = NULL;
+
+ if (interfaceBlock.layout == sh::BLOCKLAYOUT_STANDARD)
+ {
+ encoder = new sh::Std140BlockEncoder;
+ }
+ else
+ {
+ encoder = new sh::HLSLBlockEncoder(sh::HLSLBlockEncoder::ENCODE_PACKED);
+ }
+ ASSERT(encoder);
+
+ defineUniformBlockMembers(interfaceBlock.fields, "", blockIndex, encoder, &blockUniformIndexes, interfaceBlock.isRowMajorLayout);
+
+ unsigned int dataSize = static_cast<unsigned int>(encoder->getBlockSize());
+
+ // create all the uniform blocks
+ if (interfaceBlock.arraySize > 0)
+ {
+ for (unsigned int uniformBlockElement = 0; uniformBlockElement < interfaceBlock.arraySize; uniformBlockElement++)
+ {
+ gl::UniformBlock *newUniformBlock = new gl::UniformBlock(interfaceBlock.name, uniformBlockElement, dataSize);
+ newUniformBlock->memberUniformIndexes = blockUniformIndexes;
+ mUniformBlocks.push_back(newUniformBlock);
+ }
+ }
+ else
+ {
+ gl::UniformBlock *newUniformBlock = new gl::UniformBlock(interfaceBlock.name, GL_INVALID_INDEX, dataSize);
+ newUniformBlock->memberUniformIndexes = blockUniformIndexes;
+ mUniformBlocks.push_back(newUniformBlock);
+ }
+ }
+
+ if (interfaceBlock.staticUse)
+ {
+ // Assign registers to the uniform blocks
+ const GLuint blockIndex = getUniformBlockIndex(interfaceBlock.name);
+ const unsigned int elementCount = std::max(1u, interfaceBlock.arraySize);
+ ASSERT(blockIndex != GL_INVALID_INDEX);
+ ASSERT(blockIndex + elementCount <= mUniformBlocks.size());
+
+ unsigned int interfaceBlockRegister = shaderD3D->getInterfaceBlockRegister(interfaceBlock.name);
+
+ for (unsigned int uniformBlockElement = 0; uniformBlockElement < elementCount; uniformBlockElement++)
+ {
+ gl::UniformBlock *uniformBlock = mUniformBlocks[blockIndex + uniformBlockElement];
+ ASSERT(uniformBlock->name == interfaceBlock.name);
+
+ assignUniformBlockRegister(uniformBlock, shader.getType(),
+ interfaceBlockRegister + uniformBlockElement, caps);
+ }
+ }
+}
+
+bool ProgramD3D::assignSamplers(unsigned int startSamplerIndex,
GLenum samplerType,
unsigned int samplerCount,
std::vector<Sampler> &outSamplers,
@@ -1867,18 +1983,103 @@
do
{
- ASSERT(samplerIndex < outSamplers.size());
- Sampler *sampler = &outSamplers[samplerIndex];
- sampler->active = true;
- sampler->textureType = GetTextureType(samplerType);
- sampler->logicalTextureUnit = 0;
- *outUsedRange = std::max(samplerIndex + 1, *outUsedRange);
+ if (samplerIndex < outSamplers.size())
+ {
+ Sampler& sampler = outSamplers[samplerIndex];
+ sampler.active = true;
+ sampler.textureType = GetTextureType(samplerType);
+ sampler.logicalTextureUnit = 0;
+ *outUsedRange = std::max(samplerIndex + 1, *outUsedRange);
+ }
+ else
+ {
+ return false;
+ }
+
samplerIndex++;
} while (samplerIndex < startSamplerIndex + samplerCount);
+
+ return true;
+}
+
+bool ProgramD3D::indexSamplerUniform(const gl::LinkedUniform &uniform, gl::InfoLog &infoLog, const gl::Caps &caps)
+{
+ ASSERT(gl::IsSamplerType(uniform.type));
+ ASSERT(uniform.vsRegisterIndex != GL_INVALID_INDEX || uniform.psRegisterIndex != GL_INVALID_INDEX);
+
+ if (uniform.vsRegisterIndex != GL_INVALID_INDEX)
+ {
+ if (!assignSamplers(uniform.vsRegisterIndex, uniform.type, uniform.arraySize, mSamplersVS,
+ &mUsedVertexSamplerRange))
+ {
+ infoLog << "Vertex shader sampler count exceeds the maximum vertex texture units ("
+ << mSamplersVS.size() << ").";
+ return false;
+ }
+
+ unsigned int maxVertexVectors = mRenderer->getReservedVertexUniformVectors() + caps.maxVertexUniformVectors;
+ if (uniform.vsRegisterIndex + uniform.registerCount > maxVertexVectors)
+ {
+ infoLog << "Vertex shader active uniforms exceed GL_MAX_VERTEX_UNIFORM_VECTORS ("
+ << caps.maxVertexUniformVectors << ").";
+ return false;
+ }
+ }
+
+ if (uniform.psRegisterIndex != GL_INVALID_INDEX)
+ {
+ if (!assignSamplers(uniform.psRegisterIndex, uniform.type, uniform.arraySize, mSamplersPS,
+ &mUsedPixelSamplerRange))
+ {
+ infoLog << "Pixel shader sampler count exceeds MAX_TEXTURE_IMAGE_UNITS ("
+ << mSamplersPS.size() << ").";
+ return false;
+ }
+
+ unsigned int maxFragmentVectors = mRenderer->getReservedFragmentUniformVectors() + caps.maxFragmentUniformVectors;
+ if (uniform.psRegisterIndex + uniform.registerCount > maxFragmentVectors)
+ {
+ infoLog << "Fragment shader active uniforms exceed GL_MAX_FRAGMENT_UNIFORM_VECTORS ("
+ << caps.maxFragmentUniformVectors << ").";
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool ProgramD3D::indexUniforms(gl::InfoLog &infoLog, const gl::Caps &caps)
+{
+ for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++)
+ {
+ const gl::LinkedUniform &uniform = *mUniforms[uniformIndex];
+
+ if (gl::IsSamplerType(uniform.type))
+ {
+ if (!indexSamplerUniform(uniform, infoLog, caps))
+ {
+ return false;
+ }
+ }
+
+ for (unsigned int arrayIndex = 0; arrayIndex < uniform.elementCount(); arrayIndex++)
+ {
+ if (!uniform.isBuiltIn())
+ {
+ // Assign in-order uniform locations
+ mUniformIndex[static_cast<GLuint>(mUniformIndex.size())] = gl::VariableLocation(
+ uniform.name, arrayIndex, static_cast<unsigned int>(uniformIndex));
+ }
+ }
+ }
+
+ return true;
}
void ProgramD3D::reset()
{
+ ProgramImpl::reset();
+
SafeDeleteContainer(mVertexExecutables);
SafeDeleteContainer(mPixelExecutables);
SafeDelete(mGeometryExecutable);
@@ -1893,8 +2094,6 @@
mPixelShaderKey.clear();
mUsesPointSize = false;
- SafeDeleteContainer(mD3DUniforms);
-
SafeDelete(mVertexUniformStorage);
SafeDelete(mFragmentUniformStorage);
@@ -2004,9 +2203,4 @@
}
}
}
-
-D3DUniform *ProgramD3D::getD3DUniformFromLocation(GLint location)
-{
- return mD3DUniforms[mData.getUniformLocations()[location].index];
-}
}
diff --git a/src/libANGLE/renderer/d3d/ProgramD3D.h b/src/libANGLE/renderer/d3d/ProgramD3D.h
index 5e86516..6efc654 100644
--- a/src/libANGLE/renderer/d3d/ProgramD3D.h
+++ b/src/libANGLE/renderer/d3d/ProgramD3D.h
@@ -20,6 +20,13 @@
#include "libANGLE/renderer/d3d/DynamicHLSL.h"
#include "libANGLE/renderer/d3d/WorkaroundsD3D.h"
+namespace gl
+{
+struct LinkedUniform;
+struct VariableLocation;
+struct VertexFormat;
+}
+
namespace rx
{
class RendererD3D;
@@ -32,43 +39,6 @@
#define ANGLE_COMPILE_OPTIMIZATION_LEVEL D3DCOMPILE_OPTIMIZATION_LEVEL1
#endif
-// Helper struct representing a single shader uniform
-struct D3DUniform
-{
- D3DUniform(GLenum typeIn,
- const std::string &nameIn,
- unsigned int arraySizeIn,
- bool defaultBlock);
- ~D3DUniform();
-
- bool isSampler() const;
- unsigned int elementCount() const { return std::max(1u, arraySize); }
- bool isReferencedByVertexShader() const;
- bool isReferencedByFragmentShader() const;
-
- // Duplicated from the GL layer
- GLenum type;
- std::string name;
- unsigned int arraySize;
-
- // Pointer to a system copy of the data.
- // TODO(jmadill): remove this in favor of gl::LinkedUniform::data().
- uint8_t *data;
-
- // Has the data been updated since the last sync?
- bool dirty;
-
- // Register information.
- unsigned int vsRegisterIndex;
- unsigned int psRegisterIndex;
- unsigned int registerCount;
-
- // Register "elements" are used for uniform structs in ES3, to appropriately identify single
- // uniforms
- // inside aggregate types, which are packed according C-like structure rules.
- unsigned int registerElement;
-};
-
class ProgramD3D : public ProgramImpl
{
public:
@@ -103,12 +73,13 @@
LinkResult link(const gl::Data &data, gl::InfoLog &infoLog) override;
GLboolean validate(const gl::Caps &caps, gl::InfoLog *infoLog) override;
- void gatherUniformBlockInfo(std::vector<gl::UniformBlock> *uniformBlocks,
- std::vector<gl::LinkedUniform> *uniforms) override;
-
void initializeUniformStorage();
gl::Error applyUniforms();
gl::Error applyUniformBuffers(const gl::Data &data);
+ void assignUniformBlockRegister(gl::UniformBlock *uniformBlock,
+ GLenum shader,
+ unsigned int registerIndex,
+ const gl::Caps &caps);
void dirtyAllUniforms();
void setUniform1fv(GLint location, GLsizei count, const GLfloat *v);
@@ -133,9 +104,15 @@
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);
+ void getUniformiv(GLint location, GLint *params);
+ void getUniformuiv(GLint location, GLuint *params);
+
const UniformStorageD3D &getVertexUniformStorage() const { return *mVertexUniformStorage; }
const UniformStorageD3D &getFragmentUniformStorage() const { return *mFragmentUniformStorage; }
+ void reset();
+
unsigned int getSerial() const;
void sortAttributesByLayout(const std::vector<TranslatedAttribute> &unsortedAttributes,
@@ -198,24 +175,19 @@
GLenum textureType;
};
- typedef std::map<std::string, sh::BlockMemberInfo> BlockInfoMap;
+ bool defineUniforms(gl::InfoLog &infoLog, const gl::Caps &caps);
+ void defineUniformBase(const ShaderD3D *shader, const sh::Uniform &uniform, unsigned int uniformRegister);
+ void defineUniform(const ShaderD3D *shader, const sh::ShaderVariable &uniform, const std::string &fullName,
+ sh::HLSLBlockEncoder *encoder);
+ bool indexSamplerUniform(const gl::LinkedUniform &uniform, gl::InfoLog &infoLog, const gl::Caps &caps);
+ bool indexUniforms(gl::InfoLog &infoLog, const gl::Caps &caps);
+ static bool assignSamplers(unsigned int startSamplerIndex, GLenum samplerType, unsigned int samplerCount,
+ std::vector<Sampler> &outSamplers, GLuint *outUsedRange);
- void assignUniformRegisters();
- void assignUniformRegistersBase(const ShaderD3D *shader, const sh::Uniform &uniform);
- void assignUniformRegisters(const ShaderD3D *shader,
- const sh::ShaderVariable &uniform,
- const std::string &fullName,
- sh::HLSLBlockEncoder *encoder);
- void assignAllSamplerRegisters();
- void assignSamplerRegisters(const D3DUniform *d3dUniform);
-
- static void AssignSamplers(unsigned int startSamplerIndex,
- GLenum samplerType,
- unsigned int samplerCount,
- std::vector<Sampler> &outSamplers,
- GLuint *outUsedRange);
-
- size_t defineUniformBlock(const sh::InterfaceBlock &interfaceBlock, BlockInfoMap *blockInfoOut);
+ void defineUniformBlocks(const gl::Caps &caps);
+ void defineUniformBlock(const gl::Shader &shader,
+ const sh::InterfaceBlock &interfaceBlock,
+ const gl::Caps &caps);
template <typename T>
void setUniform(GLint location, GLsizei count, const T* v, GLenum targetUniformType);
@@ -223,19 +195,23 @@
template <int cols, int rows>
void setUniformMatrixfv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value, GLenum targetUniformType);
+ template <typename T>
+ void getUniformv(GLint location, T *params, GLenum uniformType);
+
+ template <typename VarT>
+ void defineUniformBlockMembers(const std::vector<VarT> &fields, const std::string &prefix, int blockIndex,
+ sh::BlockLayoutEncoder *encoder, std::vector<unsigned int> *blockUniformIndexes,
+ bool inRowMajorLayout);
+
LinkResult compileProgramExecutables(gl::InfoLog &infoLog,
int registers,
const std::vector<PackedVarying> &packedVaryings);
void gatherTransformFeedbackVaryings(const std::vector<gl::LinkedVarying> &varyings);
- D3DUniform *getD3DUniformByName(const std::string &name);
- D3DUniform *getD3DUniformFromLocation(GLint location);
void initSemanticIndex();
void initAttributesByLayout();
- void reset();
-
RendererD3D *mRenderer;
DynamicHLSL *mDynamicHLSL;
@@ -283,7 +259,6 @@
gl::InputLayout mCachedInputLayout;
std::vector<gl::LinkedVarying> mTransformFeedbackLinkedVaryings;
- std::vector<D3DUniform *> mD3DUniforms;
static unsigned int issueSerial();
static unsigned int mCurrentSerial;
diff --git a/src/libANGLE/renderer/d3d/RendererD3D.h b/src/libANGLE/renderer/d3d/RendererD3D.h
index 87bbadd..f2629dd 100644
--- a/src/libANGLE/renderer/d3d/RendererD3D.h
+++ b/src/libANGLE/renderer/d3d/RendererD3D.h
@@ -37,10 +37,8 @@
namespace rx
{
-struct D3DUniform;
class ImageD3D;
class IndexBuffer;
-class ProgramD3D;
class RenderTargetD3D;
class ShaderExecutableD3D;
class SwapChainD3D;
@@ -159,8 +157,7 @@
const gl::Framebuffer *framebuffer,
bool rasterizerDiscard,
bool transformFeedbackActive) = 0;
- virtual gl::Error applyUniforms(const ProgramD3D &programD3D,
- const std::vector<D3DUniform *> &uniformArray) = 0;
+ virtual gl::Error applyUniforms(const ProgramImpl &program, const std::vector<gl::LinkedUniform*> &uniformArray) = 0;
virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount, bool usesPointSize) = 0;
virtual gl::Error applyVertexBuffer(const gl::State &state, GLenum mode, GLint first, GLsizei count, GLsizei instances, SourceIndexData *sourceIndexInfo) = 0;
virtual gl::Error applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo, SourceIndexData *sourceIndexInfo) = 0;
diff --git a/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp b/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp
index 6c4000f..46a6af3 100644
--- a/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp
+++ b/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp
@@ -2093,8 +2093,7 @@
return gl::Error(GL_NO_ERROR);
}
-gl::Error Renderer11::applyUniforms(const ProgramD3D &programD3D,
- const std::vector<D3DUniform *> &uniformArray)
+gl::Error Renderer11::applyUniforms(const ProgramImpl &program, const std::vector<gl::LinkedUniform*> &uniformArray)
{
unsigned int totalRegisterCountVS = 0;
unsigned int totalRegisterCountPS = 0;
@@ -2102,25 +2101,26 @@
bool vertexUniformsDirty = false;
bool pixelUniformsDirty = false;
- for (const D3DUniform *uniform : uniformArray)
+ for (size_t uniformIndex = 0; uniformIndex < uniformArray.size(); uniformIndex++)
{
- if (uniform->isReferencedByVertexShader() && !uniform->isSampler())
+ const gl::LinkedUniform &uniform = *uniformArray[uniformIndex];
+
+ if (uniform.isReferencedByVertexShader() && !uniform.isSampler())
{
- totalRegisterCountVS += uniform->registerCount;
- vertexUniformsDirty = (vertexUniformsDirty || uniform->dirty);
+ totalRegisterCountVS += uniform.registerCount;
+ vertexUniformsDirty = (vertexUniformsDirty || uniform.dirty);
}
- if (uniform->isReferencedByFragmentShader() && !uniform->isSampler())
+ if (uniform.isReferencedByFragmentShader() && !uniform.isSampler())
{
- totalRegisterCountPS += uniform->registerCount;
- pixelUniformsDirty = (pixelUniformsDirty || uniform->dirty);
+ totalRegisterCountPS += uniform.registerCount;
+ pixelUniformsDirty = (pixelUniformsDirty || uniform.dirty);
}
}
- const UniformStorage11 *vertexUniformStorage =
- GetAs<UniformStorage11>(&programD3D.getVertexUniformStorage());
- const UniformStorage11 *fragmentUniformStorage =
- GetAs<UniformStorage11>(&programD3D.getFragmentUniformStorage());
+ const ProgramD3D *programD3D = GetAs<ProgramD3D>(&program);
+ const UniformStorage11 *vertexUniformStorage = GetAs<UniformStorage11>(&programD3D->getVertexUniformStorage());
+ const UniformStorage11 *fragmentUniformStorage = GetAs<UniformStorage11>(&programD3D->getFragmentUniformStorage());
ASSERT(vertexUniformStorage);
ASSERT(fragmentUniformStorage);
@@ -2148,26 +2148,26 @@
mapPS = (float(*)[4])map.pData;
}
- for (const D3DUniform *uniform : uniformArray)
+ for (size_t uniformIndex = 0; uniformIndex < uniformArray.size(); uniformIndex++)
{
- if (uniform->isSampler())
- continue;
+ gl::LinkedUniform *uniform = uniformArray[uniformIndex];
- unsigned int componentCount = (4 - uniform->registerElement);
-
- // we assume that uniforms from structs are arranged in struct order in our uniforms list.
- // otherwise we would overwrite previously written regions of memory.
-
- if (uniform->isReferencedByVertexShader() && mapVS)
+ if (!uniform->isSampler())
{
- memcpy(&mapVS[uniform->vsRegisterIndex][uniform->registerElement], uniform->data,
- uniform->registerCount * sizeof(float) * componentCount);
- }
+ unsigned int componentCount = (4 - uniform->registerElement);
- if (uniform->isReferencedByFragmentShader() && mapPS)
- {
- memcpy(&mapPS[uniform->psRegisterIndex][uniform->registerElement], uniform->data,
- uniform->registerCount * sizeof(float) * componentCount);
+ // we assume that uniforms from structs are arranged in struct order in our uniforms list. otherwise we would
+ // overwrite previously written regions of memory.
+
+ if (uniform->isReferencedByVertexShader() && mapVS)
+ {
+ memcpy(&mapVS[uniform->vsRegisterIndex][uniform->registerElement], uniform->data, uniform->registerCount * sizeof(float) * componentCount);
+ }
+
+ if (uniform->isReferencedByFragmentShader() && mapPS)
+ {
+ memcpy(&mapPS[uniform->psRegisterIndex][uniform->registerElement], uniform->data, uniform->registerCount * sizeof(float) * componentCount);
+ }
}
}
@@ -2253,7 +2253,7 @@
}
// GSSetConstantBuffers triggers device removal on 9_3, so we should only call it if necessary
- if (programD3D.usesGeometryShader())
+ if (programD3D->usesGeometryShader())
{
// needed for the point sprite geometry shader
if (mCurrentGeometryConstantBuffer != mDriverConstantBufferPS)
diff --git a/src/libANGLE/renderer/d3d/d3d11/Renderer11.h b/src/libANGLE/renderer/d3d/d3d11/Renderer11.h
index 2bce423..6260add 100644
--- a/src/libANGLE/renderer/d3d/d3d11/Renderer11.h
+++ b/src/libANGLE/renderer/d3d/d3d11/Renderer11.h
@@ -137,8 +137,7 @@
bool rasterizerDiscard,
bool transformFeedbackActive) override;
- gl::Error applyUniforms(const ProgramD3D &programD3D,
- const std::vector<D3DUniform *> &uniformArray) override;
+ virtual gl::Error applyUniforms(const ProgramImpl &program, const std::vector<gl::LinkedUniform*> &uniformArray);
virtual gl::Error applyVertexBuffer(const gl::State &state, GLenum mode, GLint first, GLsizei count, GLsizei instances, SourceIndexData *sourceIndexInfo);
virtual gl::Error applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo, SourceIndexData *sourceIndexInfo);
void applyTransformFeedbackBuffers(const gl::State &state) override;
diff --git a/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp b/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp
index 61dec0a..8c59545 100644
--- a/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp
+++ b/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp
@@ -1910,45 +1910,46 @@
return gl::Error(GL_NO_ERROR);
}
-gl::Error Renderer9::applyUniforms(const ProgramD3D &programD3D,
- const std::vector<D3DUniform *> &uniformArray)
+gl::Error Renderer9::applyUniforms(const ProgramImpl &program, const std::vector<gl::LinkedUniform*> &uniformArray)
{
- for (const D3DUniform *targetUniform : uniformArray)
+ for (size_t uniformIndex = 0; uniformIndex < uniformArray.size(); uniformIndex++)
{
- if (!targetUniform->dirty)
- continue;
+ gl::LinkedUniform *targetUniform = uniformArray[uniformIndex];
- GLfloat *f = (GLfloat *)targetUniform->data;
- GLint *i = (GLint *)targetUniform->data;
-
- switch (targetUniform->type)
+ if (targetUniform->dirty)
{
- case GL_SAMPLER_2D:
- case GL_SAMPLER_CUBE:
+ GLfloat *f = (GLfloat*)targetUniform->data;
+ GLint *i = (GLint*)targetUniform->data;
+
+ switch (targetUniform->type)
+ {
+ case GL_SAMPLER_2D:
+ case GL_SAMPLER_CUBE:
break;
- case GL_BOOL:
- case GL_BOOL_VEC2:
- case GL_BOOL_VEC3:
- case GL_BOOL_VEC4:
+ case GL_BOOL:
+ case GL_BOOL_VEC2:
+ case GL_BOOL_VEC3:
+ case GL_BOOL_VEC4:
applyUniformnbv(targetUniform, i);
break;
- case GL_FLOAT:
- case GL_FLOAT_VEC2:
- case GL_FLOAT_VEC3:
- case GL_FLOAT_VEC4:
- case GL_FLOAT_MAT2:
- case GL_FLOAT_MAT3:
- case GL_FLOAT_MAT4:
+ case GL_FLOAT:
+ case GL_FLOAT_VEC2:
+ case GL_FLOAT_VEC3:
+ case GL_FLOAT_VEC4:
+ case GL_FLOAT_MAT2:
+ case GL_FLOAT_MAT3:
+ case GL_FLOAT_MAT4:
applyUniformnfv(targetUniform, f);
break;
- case GL_INT:
- case GL_INT_VEC2:
- case GL_INT_VEC3:
- case GL_INT_VEC4:
+ case GL_INT:
+ case GL_INT_VEC2:
+ case GL_INT_VEC3:
+ case GL_INT_VEC4:
applyUniformniv(targetUniform, i);
break;
- default:
+ default:
UNREACHABLE();
+ }
}
}
@@ -1963,7 +1964,7 @@
return gl::Error(GL_NO_ERROR);
}
-void Renderer9::applyUniformnfv(const D3DUniform *targetUniform, const GLfloat *v)
+void Renderer9::applyUniformnfv(gl::LinkedUniform *targetUniform, const GLfloat *v)
{
if (targetUniform->isReferencedByFragmentShader())
{
@@ -1976,7 +1977,7 @@
}
}
-void Renderer9::applyUniformniv(const D3DUniform *targetUniform, const GLint *v)
+void Renderer9::applyUniformniv(gl::LinkedUniform *targetUniform, const GLint *v)
{
ASSERT(targetUniform->registerCount <= MAX_VERTEX_CONSTANT_VECTORS_D3D9);
GLfloat vector[MAX_VERTEX_CONSTANT_VECTORS_D3D9][4];
@@ -1992,7 +1993,7 @@
applyUniformnfv(targetUniform, (GLfloat*)vector);
}
-void Renderer9::applyUniformnbv(const D3DUniform *targetUniform, const GLint *v)
+void Renderer9::applyUniformnbv(gl::LinkedUniform *targetUniform, const GLint *v)
{
ASSERT(targetUniform->registerCount <= MAX_VERTEX_CONSTANT_VECTORS_D3D9);
GLfloat vector[MAX_VERTEX_CONSTANT_VECTORS_D3D9][4];
diff --git a/src/libANGLE/renderer/d3d/d3d9/Renderer9.h b/src/libANGLE/renderer/d3d/d3d9/Renderer9.h
index 95d9a52..2cd84fc 100644
--- a/src/libANGLE/renderer/d3d/d3d9/Renderer9.h
+++ b/src/libANGLE/renderer/d3d/d3d9/Renderer9.h
@@ -32,12 +32,10 @@
{
class Blit9;
class IndexDataManager;
-class ProgramD3D;
class StreamingIndexBufferInterface;
class StaticIndexBufferInterface;
class VertexDataManager;
struct ClearParameters;
-struct D3DUniform;
struct TranslatedAttribute;
enum D3D9InitError
@@ -113,8 +111,7 @@
const gl::Framebuffer *framebuffer,
bool rasterizerDiscard,
bool transformFeedbackActive) override;
- gl::Error applyUniforms(const ProgramD3D &programD3D,
- const std::vector<D3DUniform *> &uniformArray) override;
+ virtual gl::Error applyUniforms(const ProgramImpl &program, const std::vector<gl::LinkedUniform*> &uniformArray);
virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount, bool usesPointSize);
virtual gl::Error applyVertexBuffer(const gl::State &state, GLenum mode, GLint first, GLsizei count, GLsizei instances, SourceIndexData *sourceInfo);
virtual gl::Error applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo, SourceIndexData *sourceIndexInfo);
@@ -261,9 +258,9 @@
void release();
- void applyUniformnfv(const D3DUniform *targetUniform, const GLfloat *v);
- void applyUniformniv(const D3DUniform *targetUniform, const GLint *v);
- void applyUniformnbv(const D3DUniform *targetUniform, const GLint *v);
+ void applyUniformnfv(gl::LinkedUniform *targetUniform, const GLfloat *v);
+ void applyUniformniv(gl::LinkedUniform *targetUniform, const GLint *v);
+ void applyUniformnbv(gl::LinkedUniform *targetUniform, const GLint *v);
gl::Error drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer);
gl::Error drawIndexedPoints(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer);
diff --git a/src/libANGLE/renderer/gl/ProgramGL.cpp b/src/libANGLE/renderer/gl/ProgramGL.cpp
index bae8389..3a70ae9 100644
--- a/src/libANGLE/renderer/gl/ProgramGL.cpp
+++ b/src/libANGLE/renderer/gl/ProgramGL.cpp
@@ -115,41 +115,68 @@
}
// Query the uniform information
- ASSERT(mUniformRealLocationMap.empty());
- const auto &uniforms = mData.getUniforms();
- for (const gl::VariableLocation &entry : mData.getUniformLocations())
+ // TODO: A lot of this logic should be done at the gl::Program level
+ GLint activeUniformMaxLength = 0;
+ mFunctions->getProgramiv(mProgramID, GL_ACTIVE_UNIFORM_MAX_LENGTH, &activeUniformMaxLength);
+
+ std::vector<GLchar> uniformNameBuffer(activeUniformMaxLength);
+
+ GLint uniformCount = 0;
+ mFunctions->getProgramiv(mProgramID, GL_ACTIVE_UNIFORMS, &uniformCount);
+ for (GLint i = 0; i < uniformCount; i++)
{
- // From the spec:
- // "Locations for sequential array indices are not required to be sequential."
- const gl::LinkedUniform &uniform = uniforms[entry.index];
- std::stringstream fullNameStr;
- fullNameStr << uniform.name;
- if (uniform.isArray())
+ GLsizei uniformNameLength = 0;
+ GLint uniformSize = 0;
+ GLenum uniformType = GL_NONE;
+ mFunctions->getActiveUniform(mProgramID, i, static_cast<GLsizei>(uniformNameBuffer.size()),
+ &uniformNameLength, &uniformSize, &uniformType,
+ &uniformNameBuffer[0]);
+
+ size_t subscript = 0;
+ std::string uniformName = gl::ParseUniformName(std::string(&uniformNameBuffer[0], uniformNameLength), &subscript);
+
+ bool isArray = uniformSize > 1 || subscript != GL_INVALID_INDEX;
+
+ for (size_t arrayIndex = 0; arrayIndex < static_cast<size_t>(uniformSize); arrayIndex++)
{
- fullNameStr << "[" << entry.element << "]";
+ std::string locationName = uniformName;
+ if (isArray)
+ {
+ locationName += "[" + Str(static_cast<int>(arrayIndex)) + "]";
+ }
+
+ GLint location = mFunctions->getUniformLocation(mProgramID, locationName.c_str());
+ if (location >= 0)
+ {
+ mUniformIndex[location] =
+ gl::VariableLocation(uniformName, static_cast<unsigned int>(arrayIndex),
+ static_cast<unsigned int>(mUniforms.size()));
+
+ // If the uniform is a sampler, track it in the sampler bindings array
+ if (gl::IsSamplerType(uniformType))
+ {
+ SamplerLocation samplerLoc;
+ samplerLoc.samplerIndex = mSamplerBindings.size();
+ samplerLoc.arrayIndex = arrayIndex;
+ mSamplerUniformMap[location] = samplerLoc;
+ }
+ }
}
- const std::string &fullName = fullNameStr.str();
- GLint realLocation = mFunctions->getUniformLocation(mProgramID, fullName.c_str());
- mUniformRealLocationMap.push_back(realLocation);
- }
+ // ANGLE uses 0 to identify an non-array uniform.
+ unsigned int arraySize = isArray ? static_cast<unsigned int>(uniformSize) : 0;
- mUniformIndexToSamplerIndex.resize(mData.getUniforms().size(), GL_INVALID_INDEX);
-
- for (size_t uniformId = 0; uniformId < uniforms.size(); ++uniformId)
- {
- const gl::LinkedUniform &linkedUniform = uniforms[uniformId];
-
- if (!linkedUniform.isSampler() || !linkedUniform.staticUse)
- continue;
-
- mUniformIndexToSamplerIndex[uniformId] = mSamplerBindings.size();
+ // TODO: determine uniform precision
+ mUniforms.push_back(new gl::LinkedUniform(uniformType, GL_NONE, uniformName, arraySize, -1, sh::BlockMemberInfo::getDefaultBlockInfo()));
// If uniform is a sampler type, insert it into the mSamplerBindings array
- SamplerBindingGL samplerBinding;
- samplerBinding.textureType = gl::SamplerTypeToTextureType(linkedUniform.type);
- samplerBinding.boundTextureUnits.resize(linkedUniform.elementCount(), 0);
- mSamplerBindings.push_back(samplerBinding);
+ if (gl::IsSamplerType(uniformType))
+ {
+ SamplerBindingGL samplerBinding;
+ samplerBinding.textureType = gl::SamplerTypeToTextureType(uniformType);
+ samplerBinding.boundTextureUnits.resize(uniformSize, 0);
+ mSamplerBindings.push_back(samplerBinding);
+ }
}
return LinkResult(true, gl::Error(GL_NO_ERROR));
@@ -164,61 +191,59 @@
void ProgramGL::setUniform1fv(GLint location, GLsizei count, const GLfloat *v)
{
mStateManager->useProgram(mProgramID);
- mFunctions->uniform1fv(uniLoc(location), count, v);
+ mFunctions->uniform1fv(location, count, v);
}
void ProgramGL::setUniform2fv(GLint location, GLsizei count, const GLfloat *v)
{
mStateManager->useProgram(mProgramID);
- mFunctions->uniform2fv(uniLoc(location), count, v);
+ mFunctions->uniform2fv(location, count, v);
}
void ProgramGL::setUniform3fv(GLint location, GLsizei count, const GLfloat *v)
{
mStateManager->useProgram(mProgramID);
- mFunctions->uniform3fv(uniLoc(location), count, v);
+ mFunctions->uniform3fv(location, count, v);
}
void ProgramGL::setUniform4fv(GLint location, GLsizei count, const GLfloat *v)
{
mStateManager->useProgram(mProgramID);
- mFunctions->uniform4fv(uniLoc(location), count, v);
+ mFunctions->uniform4fv(location, count, v);
}
void ProgramGL::setUniform1iv(GLint location, GLsizei count, const GLint *v)
{
mStateManager->useProgram(mProgramID);
- mFunctions->uniform1iv(uniLoc(location), count, v);
+ mFunctions->uniform1iv(location, count, v);
- const gl::VariableLocation &locationEntry = mData.getUniformLocations()[location];
-
- size_t samplerIndex = mUniformIndexToSamplerIndex[locationEntry.index];
- if (samplerIndex != GL_INVALID_INDEX)
+ auto iter = mSamplerUniformMap.find(location);
+ if (iter != mSamplerUniformMap.end())
{
- std::vector<GLuint> &boundTextureUnits = mSamplerBindings[samplerIndex].boundTextureUnits;
+ const SamplerLocation &samplerLoc = iter->second;
+ std::vector<GLuint> &boundTextureUnits = mSamplerBindings[samplerLoc.samplerIndex].boundTextureUnits;
- size_t copyCount =
- std::max<size_t>(count, boundTextureUnits.size() - locationEntry.element);
- std::copy(v, v + copyCount, boundTextureUnits.begin() + locationEntry.element);
+ size_t copyCount = std::max<size_t>(count, boundTextureUnits.size() - samplerLoc.arrayIndex);
+ std::copy(v, v + copyCount, boundTextureUnits.begin() + samplerLoc.arrayIndex);
}
}
void ProgramGL::setUniform2iv(GLint location, GLsizei count, const GLint *v)
{
mStateManager->useProgram(mProgramID);
- mFunctions->uniform2iv(uniLoc(location), count, v);
+ mFunctions->uniform2iv(location, count, v);
}
void ProgramGL::setUniform3iv(GLint location, GLsizei count, const GLint *v)
{
mStateManager->useProgram(mProgramID);
- mFunctions->uniform3iv(uniLoc(location), count, v);
+ mFunctions->uniform3iv(location, count, v);
}
void ProgramGL::setUniform4iv(GLint location, GLsizei count, const GLint *v)
{
mStateManager->useProgram(mProgramID);
- mFunctions->uniform4iv(uniLoc(location), count, v);
+ mFunctions->uniform4iv(location, count, v);
}
void ProgramGL::setUniform1uiv(GLint location, GLsizei count, const GLuint *v)
@@ -230,73 +255,88 @@
void ProgramGL::setUniform2uiv(GLint location, GLsizei count, const GLuint *v)
{
mStateManager->useProgram(mProgramID);
- mFunctions->uniform2uiv(uniLoc(location), count, v);
+ mFunctions->uniform2uiv(location, count, v);
}
void ProgramGL::setUniform3uiv(GLint location, GLsizei count, const GLuint *v)
{
mStateManager->useProgram(mProgramID);
- mFunctions->uniform3uiv(uniLoc(location), count, v);
+ mFunctions->uniform3uiv(location, count, v);
}
void ProgramGL::setUniform4uiv(GLint location, GLsizei count, const GLuint *v)
{
mStateManager->useProgram(mProgramID);
- mFunctions->uniform4uiv(uniLoc(location), count, v);
+ mFunctions->uniform4uiv(location, count, v);
}
void ProgramGL::setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
{
mStateManager->useProgram(mProgramID);
- mFunctions->uniformMatrix2fv(uniLoc(location), count, transpose, value);
+ mFunctions->uniformMatrix2fv(location, count, transpose, value);
}
void ProgramGL::setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
{
mStateManager->useProgram(mProgramID);
- mFunctions->uniformMatrix3fv(uniLoc(location), count, transpose, value);
+ mFunctions->uniformMatrix3fv(location, count, transpose, value);
}
void ProgramGL::setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
{
mStateManager->useProgram(mProgramID);
- mFunctions->uniformMatrix4fv(uniLoc(location), count, transpose, value);
+ mFunctions->uniformMatrix4fv(location, count, transpose, value);
}
void ProgramGL::setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
{
mStateManager->useProgram(mProgramID);
- mFunctions->uniformMatrix2x3fv(uniLoc(location), count, transpose, value);
+ mFunctions->uniformMatrix2x3fv(location, count, transpose, value);
}
void ProgramGL::setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
{
mStateManager->useProgram(mProgramID);
- mFunctions->uniformMatrix3x2fv(uniLoc(location), count, transpose, value);
+ mFunctions->uniformMatrix3x2fv(location, count, transpose, value);
}
void ProgramGL::setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
{
mStateManager->useProgram(mProgramID);
- mFunctions->uniformMatrix2x4fv(uniLoc(location), count, transpose, value);
+ mFunctions->uniformMatrix2x4fv(location, count, transpose, value);
}
void ProgramGL::setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
{
mStateManager->useProgram(mProgramID);
- mFunctions->uniformMatrix4x2fv(uniLoc(location), count, transpose, value);
+ mFunctions->uniformMatrix4x2fv(location, count, transpose, value);
}
void ProgramGL::setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
{
mStateManager->useProgram(mProgramID);
- mFunctions->uniformMatrix3x4fv(uniLoc(location), count, transpose, value);
+ mFunctions->uniformMatrix3x4fv(location, count, transpose, value);
}
void ProgramGL::setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
{
mStateManager->useProgram(mProgramID);
- mFunctions->uniformMatrix4x3fv(uniLoc(location), count, transpose, value);
+ mFunctions->uniformMatrix4x3fv(location, count, transpose, value);
+}
+
+void ProgramGL::getUniformfv(GLint location, GLfloat *params)
+{
+ mFunctions->getUniformfv(mProgramID, location, params);
+}
+
+void ProgramGL::getUniformiv(GLint location, GLint *params)
+{
+ mFunctions->getUniformiv(mProgramID, location, params);
+}
+
+void ProgramGL::getUniformuiv(GLint location, GLuint *params)
+{
+ mFunctions->getUniformuiv(mProgramID, location, params);
}
bool ProgramGL::validateSamplers(gl::InfoLog *infoLog, const gl::Caps &caps)
@@ -307,9 +347,10 @@
void ProgramGL::reset()
{
- mUniformRealLocationMap.clear();
+ ProgramImpl::reset();
+
+ mSamplerUniformMap.clear();
mSamplerBindings.clear();
- mUniformIndexToSamplerIndex.clear();
}
GLuint ProgramGL::getProgramID() const
@@ -322,9 +363,4 @@
return mSamplerBindings;
}
-void ProgramGL::gatherUniformBlockInfo(std::vector<gl::UniformBlock> * /*uniformBlocks*/,
- std::vector<gl::LinkedUniform> * /*uniforms*/)
-{
- // TODO(jmadill): Gather uniform block layout info, and data sizes.
-}
}
diff --git a/src/libANGLE/renderer/gl/ProgramGL.h b/src/libANGLE/renderer/gl/ProgramGL.h
index 9cc0a14..e83d7da 100644
--- a/src/libANGLE/renderer/gl/ProgramGL.h
+++ b/src/libANGLE/renderer/gl/ProgramGL.h
@@ -62,31 +62,32 @@
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(GLint location, GLfloat *params) override;
+ void getUniformiv(GLint location, GLint *params) override;
+ void getUniformuiv(GLint location, GLuint *params) override;
+
bool validateSamplers(gl::InfoLog *infoLog, const gl::Caps &caps) override;
- void gatherUniformBlockInfo(std::vector<gl::UniformBlock> *uniformBlocks,
- std::vector<gl::LinkedUniform> *uniforms) override;
+ void reset() override;
GLuint getProgramID() const;
const std::vector<SamplerBindingGL> &getAppliedSamplerUniforms() const;
private:
- void reset();
-
- // Helper function, makes it simpler to type.
- GLint uniLoc(GLint glLocation) const { return mUniformRealLocationMap[glLocation]; }
-
const FunctionsGL *mFunctions;
StateManagerGL *mStateManager;
- std::vector<GLint> mUniformRealLocationMap;
+ // A map from uniform location to index of mSamplerBindings and array index of the uniform
+ struct SamplerLocation
+ {
+ size_t samplerIndex;
+ size_t arrayIndex;
+ };
+ std::map<GLint, SamplerLocation> mSamplerUniformMap;
// An array of the samplers that are used by the program
std::vector<SamplerBindingGL> mSamplerBindings;
- // A map from a mData.getUniforms() index to a mSamplerBindings index.
- std::vector<size_t> mUniformIndexToSamplerIndex;
-
GLuint mProgramID;
};
diff --git a/src/libANGLE/validationES.cpp b/src/libANGLE/validationES.cpp
index b858d6f..ed642a7 100644
--- a/src/libANGLE/validationES.cpp
+++ b/src/libANGLE/validationES.cpp
@@ -1096,11 +1096,8 @@
return true;
}
-static bool ValidateUniformCommonBase(gl::Context *context,
- GLenum targetUniformType,
- GLint location,
- GLsizei count,
- const LinkedUniform **uniformOut)
+static bool ValidateUniformCommonBase(gl::Context *context, GLenum targetUniformType,
+ GLint location, GLsizei count, LinkedUniform **uniformOut)
{
if (count < 0)
{
@@ -1127,16 +1124,16 @@
return false;
}
- const LinkedUniform &uniform = program->getUniformByLocation(location);
+ LinkedUniform *uniform = program->getUniformByLocation(location);
// attempting to write an array to a non-array uniform is an INVALID_OPERATION
- if (!uniform.isArray() && count > 1)
+ if (!uniform->isArray() && count > 1)
{
context->recordError(Error(GL_INVALID_OPERATION));
return false;
}
- *uniformOut = &uniform;
+ *uniformOut = uniform;
return true;
}
@@ -1149,7 +1146,7 @@
return false;
}
- const LinkedUniform *uniform = nullptr;
+ LinkedUniform *uniform = NULL;
if (!ValidateUniformCommonBase(context, uniformType, location, count, &uniform))
{
return false;
@@ -1184,7 +1181,7 @@
return false;
}
- const LinkedUniform *uniform = nullptr;
+ LinkedUniform *uniform = NULL;
if (!ValidateUniformCommonBase(context, matrixType, location, count, &uniform))
{
return false;
@@ -1480,7 +1477,7 @@
// Uniform buffer validation
for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < program->getActiveUniformBlockCount(); uniformBlockIndex++)
{
- const gl::UniformBlock &uniformBlock = program->getUniformBlockByIndex(uniformBlockIndex);
+ const gl::UniformBlock *uniformBlock = program->getUniformBlockByIndex(uniformBlockIndex);
GLuint blockBinding = program->getUniformBlockBinding(uniformBlockIndex);
const gl::Buffer *uniformBuffer = state.getIndexedUniformBuffer(blockBinding);
@@ -1499,7 +1496,7 @@
uniformBufferSize = static_cast<size_t>(uniformBuffer->getSize());
}
- if (uniformBufferSize < uniformBlock.dataSize)
+ if (uniformBufferSize < uniformBlock->dataSize)
{
// undefined behaviour
context->recordError(Error(GL_INVALID_OPERATION, "It is undefined behaviour to use a uniform buffer that is too small."));
@@ -1899,8 +1896,8 @@
ASSERT(programObject);
// sized queries -- ensure the provided buffer is large enough
- const LinkedUniform &uniform = programObject->getUniformByLocation(location);
- size_t requiredBytes = VariableExternalSize(uniform.type);
+ LinkedUniform *uniform = programObject->getUniformByLocation(location);
+ size_t requiredBytes = VariableExternalSize(uniform->type);
if (static_cast<size_t>(bufSize) < requiredBytes)
{
context->recordError(Error(GL_INVALID_OPERATION));
diff --git a/src/libGLESv2.gypi b/src/libGLESv2.gypi
index 5bca02a..a5a6b21 100644
--- a/src/libGLESv2.gypi
+++ b/src/libGLESv2.gypi
@@ -140,6 +140,7 @@
'libANGLE/renderer/FramebufferImpl.h',
'libANGLE/renderer/ImageImpl.h',
'libANGLE/renderer/ImplFactory.h',
+ 'libANGLE/renderer/ProgramImpl.cpp',
'libANGLE/renderer/ProgramImpl.h',
'libANGLE/renderer/QueryImpl.h',
'libANGLE/renderer/RenderbufferImpl.h',
diff --git a/src/tests/deqp_support/deqp_gles2_test_expectations.txt b/src/tests/deqp_support/deqp_gles2_test_expectations.txt
index 746182e..da40c82 100644
--- a/src/tests/deqp_support/deqp_gles2_test_expectations.txt
+++ b/src/tests/deqp_support/deqp_gles2_test_expectations.txt
@@ -144,12 +144,9 @@
1031 WIN : dEQP-GLES2.functional.uniform_api.random.41 = FAIL
1031 WIN : dEQP-GLES2.functional.uniform_api.random.51 = FAIL
1031 WIN : dEQP-GLES2.functional.uniform_api.random.54 = FAIL
-1031 WIN : dEQP-GLES2.functional.uniform_api.random.61 = FAIL
1031 WIN : dEQP-GLES2.functional.uniform_api.random.72 = FAIL
1031 WIN : dEQP-GLES2.functional.uniform_api.random.79 = FAIL
1031 WIN : dEQP-GLES2.functional.uniform_api.random.82 = FAIL
-1031 WIN : dEQP-GLES2.functional.uniform_api.random.87 = FAIL
-1031 WIN : dEQP-GLES2.functional.uniform_api.random.93 = FAIL
504 WIN : dEQP-GLES2.functional.uniform_api.value.initial.get_uniform.basic_struct.sampler2D_samplerCube_* = FAIL
504 WIN : dEQP-GLES2.functional.uniform_api.value.initial.get_uniform.struct_in_array.sampler2D_samplerCube_* = FAIL
504 WIN : dEQP-GLES2.functional.uniform_api.value.initial.get_uniform.array_in_struct.sampler2D_samplerCube_* = FAIL
diff --git a/src/tests/deqp_support/deqp_gles3_test_expectations.txt b/src/tests/deqp_support/deqp_gles3_test_expectations.txt
index 2948843..87405ad 100644
--- a/src/tests/deqp_support/deqp_gles3_test_expectations.txt
+++ b/src/tests/deqp_support/deqp_gles3_test_expectations.txt
@@ -982,14 +982,11 @@
1098 WIN : dEQP-GLES3.functional.uniform_api.random.3 = FAIL
1098 WIN : dEQP-GLES3.functional.uniform_api.random.6 = FAIL
1098 WIN : dEQP-GLES3.functional.uniform_api.random.8 = FAIL
-1098 WIN : dEQP-GLES3.functional.uniform_api.random.17 = FAIL
1098 WIN : dEQP-GLES3.functional.uniform_api.random.20 = FAIL
1098 WIN : dEQP-GLES3.functional.uniform_api.random.21 = FAIL
1098 WIN : dEQP-GLES3.functional.uniform_api.random.29 = FAIL
-1098 WIN : dEQP-GLES3.functional.uniform_api.random.54 = FAIL
1098 WIN : dEQP-GLES3.functional.uniform_api.random.81 = FAIL
1098 WIN : dEQP-GLES3.functional.uniform_api.random.83 = FAIL
-1098 WIN : dEQP-GLES3.functional.uniform_api.random.87 = FAIL
1099 WIN : dEQP-GLES3.functional.attribute_location.bind_aliasing.cond_float = FAIL
1099 WIN : dEQP-GLES3.functional.attribute_location.bind_aliasing.max_cond_float = FAIL
1099 WIN : dEQP-GLES3.functional.attribute_location.bind_aliasing.cond_vec2 = FAIL
diff --git a/src/tests/gl_tests/UniformTest.cpp b/src/tests/gl_tests/UniformTest.cpp
index f8f4267..581f5ff 100644
--- a/src/tests/gl_tests/UniformTest.cpp
+++ b/src/tests/gl_tests/UniformTest.cpp
@@ -16,7 +16,11 @@
class UniformTest : public ANGLETest
{
protected:
- UniformTest() : mProgram(0), mUniformFLocation(-1), mUniformILocation(-1), mUniformBLocation(-1)
+ UniformTest()
+ : mProgram(0),
+ mUniformFLocation(-1),
+ mUniformILocation(-1),
+ mUniformBLocation(-1)
{
setWindowWidth(128);
setWindowHeight(128);
@@ -165,6 +169,13 @@
// Test that float to integer GetUniform rounds values correctly.
TEST_P(UniformTest, FloatUniformStateQuery)
{
+ // TODO(jmadill): remove this suppression once we support ANGLE-only state queries.
+ if (isAMD() && (GetParam() == ES2_OPENGL() || GetParam() == ES3_OPENGL()))
+ {
+ std::cout << "Skipping test due to a driver bug on AMD." << std::endl;
+ return;
+ }
+
std::vector<GLfloat> inValues;
std::vector<GLfloat> expectedFValues;
std::vector<GLint> expectedIValues;
@@ -203,7 +214,7 @@
for (size_t index = 0; index < inValues.size(); ++index)
{
- GLfloat inValue = inValues[index];
+ GLfloat inValue = inValues[index];
GLfloat expectedValue = expectedFValues[index];
glUniform1f(mUniformFLocation, inValue);
@@ -215,7 +226,7 @@
for (size_t index = 0; index < inValues.size(); ++index)
{
- GLfloat inValue = inValues[index];
+ GLfloat inValue = inValues[index];
GLint expectedValue = expectedIValues[index];
glUniform1f(mUniformFLocation, inValue);
@@ -229,6 +240,13 @@
// Test that integer to float GetUniform rounds values correctly.
TEST_P(UniformTest, IntUniformStateQuery)
{
+ // TODO(jmadill): remove this suppression once we support ANGLE-only state queries.
+ if ((isAMD() || isIntel()) && (GetParam() == ES2_OPENGL() || GetParam() == ES3_OPENGL()))
+ {
+ std::cout << "Skipping test due to a driver bug." << std::endl;
+ return;
+ }
+
std::vector<GLint> inValues;
std::vector<GLint> expectedIValues;
std::vector<GLfloat> expectedFValues;
@@ -256,7 +274,7 @@
for (size_t index = 0; index < inValues.size(); ++index)
{
- GLint inValue = inValues[index];
+ GLint inValue = inValues[index];
GLint expectedValue = expectedIValues[index];
glUniform1i(mUniformILocation, inValue);
@@ -268,7 +286,7 @@
for (size_t index = 0; index < inValues.size(); ++index)
{
- GLint inValue = inValues[index];
+ GLint inValue = inValues[index];
GLfloat expectedValue = expectedFValues[index];
glUniform1i(mUniformILocation, inValue);
@@ -283,10 +301,9 @@
TEST_P(UniformTest, BooleanUniformStateQuery)
{
glUseProgram(mProgram);
- GLint intValue = 0;
+ GLint intValue = 0;
GLfloat floatValue = 0.0f;
- // Calling Uniform1i
glUniform1i(mUniformBLocation, GL_FALSE);
glGetUniformiv(mProgram, mUniformBLocation, &intValue);
@@ -303,23 +320,6 @@
glGetUniformfv(mProgram, mUniformBLocation, &floatValue);
EXPECT_EQ(1.0f, floatValue);
- // Calling Uniform1f
- glUniform1f(mUniformBLocation, 0.0f);
-
- glGetUniformiv(mProgram, mUniformBLocation, &intValue);
- EXPECT_EQ(0, intValue);
-
- glGetUniformfv(mProgram, mUniformBLocation, &floatValue);
- EXPECT_EQ(0.0f, floatValue);
-
- glUniform1f(mUniformBLocation, 1.0f);
-
- glGetUniformiv(mProgram, mUniformBLocation, &intValue);
- EXPECT_EQ(1, intValue);
-
- glGetUniformfv(mProgram, mUniformBLocation, &floatValue);
- EXPECT_EQ(1.0f, floatValue);
-
ASSERT_GL_NO_ERROR();
}