Make the Program's semantic index D3D-only.
This concept isn't strictly necessary for GL-side validation. Instead
we can use a bitset to track active attribs, and determine is a
particular location is active.
BUG=angleproject:1123
Change-Id: If7a920a3071672116bafffb3368671f721723b65
Reviewed-on: https://chromium-review.googlesource.com/294570
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Tested-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/Program.cpp b/src/libANGLE/Program.cpp
index 1dcd5ea..44e2e67 100644
--- a/src/libANGLE/Program.cpp
+++ b/src/libANGLE/Program.cpp
@@ -355,6 +355,7 @@
}
mData.mAttributes.clear();
+ mData.mActiveAttribLocationsMask.reset();
mData.mTransformFeedbackVaryingVars.clear();
mProgram->reset();
@@ -403,11 +404,9 @@
return Error(GL_NO_ERROR);
}
- // TODO(jmadill): replace MAX_VERTEX_ATTRIBS
- for (int i = 0; i < MAX_VERTEX_ATTRIBS; ++i)
- {
- stream.readInt(&mProgram->getSemanticIndexes()[i]);
- }
+ static_assert(MAX_VERTEX_ATTRIBS <= sizeof(unsigned long) * 8,
+ "Too many vertex attribs for mask");
+ mData.mActiveAttribLocationsMask = stream.readInt<unsigned long>();
unsigned int attribCount = stream.readInt<unsigned int>();
ASSERT(mData.mAttributes.empty());
@@ -450,11 +449,7 @@
stream.writeInt(ANGLE_MINOR_VERSION);
stream.writeBytes(reinterpret_cast<const unsigned char*>(ANGLE_COMMIT_HASH), ANGLE_COMMIT_HASH_SIZE);
- // TODO(jmadill): replace MAX_VERTEX_ATTRIBS
- for (unsigned int i = 0; i < MAX_VERTEX_ATTRIBS; ++i)
- {
- stream.writeInt(mProgram->getSemanticIndexes()[i]);
- }
+ stream.writeInt(mData.mActiveAttribLocationsMask.to_ulong());
stream.writeInt(mData.mAttributes.size());
for (const sh::Attribute &attrib : mData.mAttributes)
@@ -594,16 +589,11 @@
return static_cast<GLuint>(-1);
}
-const int *Program::getSemanticIndexes() const
+bool Program::isAttribLocationActive(size_t attribLocation) const
{
- return mProgram->getSemanticIndexes();
-}
-
-int Program::getSemanticIndex(int attributeIndex) const
-{
- ASSERT(attributeIndex >= 0 && attributeIndex < MAX_VERTEX_ATTRIBS);
-
- return mProgram->getSemanticIndexes()[attributeIndex];
+ ASSERT(attribLocation >= 0 &&
+ static_cast<size_t>(attribLocation) < mData.mActiveAttribLocationsMask.size());
+ return mData.mActiveAttribLocationsMask[attribLocation];
}
void Program::getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
@@ -1313,9 +1303,9 @@
if (attribute.location != -1)
{
// Location is set by glBindAttribLocation or by location layout qualifier
- const int rows = VariableRegisterCount(attribute.type);
+ const int regs = VariableRegisterCount(attribute.type);
- if (static_cast<GLuint>(rows + attribute.location) > maxAttribs)
+ if (static_cast<GLuint>(regs + attribute.location) > maxAttribs)
{
infoLog << "Active attribute (" << attribute.name << ") at location "
<< attribute.location << " is too big to fit";
@@ -1323,10 +1313,10 @@
return false;
}
- for (int row = 0; row < rows; row++)
+ for (int reg = 0; reg < regs; reg++)
{
- const int rowLocation = attribute.location + row;
- sh::ShaderVariable *linkedAttribute = usedAttribMap[rowLocation];
+ const int regLocation = attribute.location + reg;
+ sh::ShaderVariable *linkedAttribute = usedAttribMap[regLocation];
// In GLSL 3.00, attribute aliasing produces a link error
// In GLSL 1.00, attribute aliasing is allowed, but ANGLE currently has a bug
@@ -1336,16 +1326,16 @@
// if (mProgram->getShaderVersion() >= 300)
{
infoLog << "Attribute '" << attribute.name << "' aliases attribute '"
- << linkedAttribute->name << "' at location " << rowLocation;
+ << linkedAttribute->name << "' at location " << regLocation;
return false;
}
}
else
{
- usedAttribMap[rowLocation] = &attribute;
+ usedAttribMap[regLocation] = &attribute;
}
- usedLocations |= 1 << rowLocation;
+ usedLocations |= 1 << regLocation;
}
}
}
@@ -1358,10 +1348,10 @@
// Not set by glBindAttribLocation or by location layout qualifier
if (attribute.location == -1)
{
- int rows = VariableRegisterCount(attribute.type);
- int availableIndex = AllocateFirstFreeBits(&usedLocations, rows, maxAttribs);
+ int regs = VariableRegisterCount(attribute.type);
+ int availableIndex = AllocateFirstFreeBits(&usedLocations, regs, maxAttribs);
- if (availableIndex == -1 || static_cast<GLuint>(availableIndex + rows) > maxAttribs)
+ if (availableIndex == -1 || static_cast<GLuint>(availableIndex + regs) > maxAttribs)
{
infoLog << "Too many active attributes (" << attribute.name << ")";
return false;
@@ -1371,18 +1361,15 @@
}
}
- // TODO(jmadill): make semantic index D3D-only
for (const sh::Attribute &attribute : mData.mAttributes)
{
ASSERT(attribute.staticUse);
+ ASSERT(attribute.location != -1);
+ int regs = VariableRegisterCount(attribute.type);
- unsigned int attributeIndex = attribute.location;
- int index = vertexShader->getSemanticIndex(attribute.name);
- int rows = VariableRegisterCount(attribute.type);
-
- for (int r = 0; r < rows; r++)
+ for (int r = 0; r < regs; r++)
{
- mProgram->getSemanticIndexes()[attributeIndex++] = index++;
+ mData.mActiveAttribLocationsMask.set(attribute.location + r);
}
}