Re-land "Move shader attributes into Program shared data."
Re-land with a fix for a warning in 32-bit Windows.
Making the Program own the attribs, and the Impl only see a read-only
copy cleans up the Impl object. It also allows us to more cleanly
isolate certain coded into D3D.
BUG=angleproject:1123
Change-Id: I73bda4b6d9e675d87d087d44757c598437d607f2
Reviewed-on: https://chromium-review.googlesource.com/295191
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Tested-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/Program.cpp b/src/libANGLE/Program.cpp
index cea9df1..7c6b8c3 100644
--- a/src/libANGLE/Program.cpp
+++ b/src/libANGLE/Program.cpp
@@ -163,7 +163,6 @@
Program::Program(rx::ImplFactory *factory, ResourceManager *manager, GLuint handle)
: mProgram(factory->createProgram(mData)),
- mLinkedAttributes(gl::MAX_VERTEX_ATTRIBS),
mValidated(false),
mLinked(false),
mDeleteStatus(false),
@@ -356,7 +355,7 @@
}
}
- mLinkedAttributes.assign(mLinkedAttributes.size(), sh::Attribute());
+ mData.mAttributes.clear();
mData.mTransformFeedbackVaryingVars.clear();
mProgram->reset();
@@ -408,20 +407,21 @@
// TODO(jmadill): replace MAX_VERTEX_ATTRIBS
for (int i = 0; i < MAX_VERTEX_ATTRIBS; ++i)
{
- stream.readInt(&mLinkedAttributes[i].type);
- stream.readString(&mLinkedAttributes[i].name);
stream.readInt(&mProgram->getSemanticIndexes()[i]);
}
unsigned int attribCount = stream.readInt<unsigned int>();
+ ASSERT(mData.mAttributes.empty());
for (unsigned int attribIndex = 0; attribIndex < attribCount; ++attribIndex)
{
- GLenum type = stream.readInt<GLenum>();
- GLenum precision = stream.readInt<GLenum>();
- std::string name = stream.readString();
- GLint arraySize = stream.readInt<GLint>();
- int location = stream.readInt<int>();
- mProgram->setShaderAttribute(attribIndex, type, precision, name, arraySize, location);
+ sh::Attribute attrib;
+ 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);
}
stream.readInt(&mData.mTransformFeedbackBufferMode);
@@ -454,20 +454,18 @@
// TODO(jmadill): replace MAX_VERTEX_ATTRIBS
for (unsigned int i = 0; i < MAX_VERTEX_ATTRIBS; ++i)
{
- stream.writeInt(mLinkedAttributes[i].type);
- stream.writeString(mLinkedAttributes[i].name);
stream.writeInt(mProgram->getSemanticIndexes()[i]);
}
- const auto &shaderAttributes = mProgram->getShaderAttributes();
- stream.writeInt(shaderAttributes.size());
- for (const auto &attrib : shaderAttributes)
+ stream.writeInt(mData.mAttributes.size());
+ for (const sh::Attribute &attrib : mData.mAttributes)
{
stream.writeInt(attrib.type);
stream.writeInt(attrib.precision);
stream.writeString(attrib.name);
stream.writeInt(attrib.arraySize);
stream.writeInt(attrib.location);
+ stream.writeInt(attrib.staticUse);
}
stream.writeInt(mData.mTransformFeedbackBufferMode);
@@ -586,11 +584,11 @@
GLuint Program::getAttributeLocation(const std::string &name)
{
- for (size_t index = 0; index < mLinkedAttributes.size(); index++)
+ for (const sh::Attribute &attribute : mData.mAttributes)
{
- if (mLinkedAttributes[index].name == name)
+ if (attribute.name == name && attribute.staticUse)
{
- return static_cast<GLuint>(index);
+ return attribute.location;
}
}
@@ -611,45 +609,7 @@
void Program::getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
{
- if (mLinked)
- {
- // Skip over inactive attributes
- unsigned int activeAttribute = 0;
- unsigned int attribute;
- for (attribute = 0; attribute < static_cast<unsigned int>(mLinkedAttributes.size());
- attribute++)
- {
- if (mLinkedAttributes[attribute].name.empty())
- {
- continue;
- }
-
- if (activeAttribute == index)
- {
- break;
- }
-
- activeAttribute++;
- }
-
- if (bufsize > 0)
- {
- const char *string = mLinkedAttributes[attribute].name.c_str();
-
- strncpy(name, string, bufsize);
- name[bufsize - 1] = '\0';
-
- if (length)
- {
- *length = static_cast<GLsizei>(strlen(name));
- }
- }
-
- *size = 1; // Always a single 'type' instance
-
- *type = mLinkedAttributes[attribute].type;
- }
- else
+ if (!mLinked)
{
if (bufsize > 0)
{
@@ -663,22 +623,57 @@
*type = GL_NONE;
*size = 1;
+ return;
}
+
+ size_t attributeIndex = 0;
+
+ for (const sh::Attribute &attribute : mData.mAttributes)
+ {
+ // Skip over inactive attributes
+ if (attribute.staticUse)
+ {
+ if (static_cast<size_t>(index) == attributeIndex)
+ {
+ break;
+ }
+ attributeIndex++;
+ }
+ }
+
+ ASSERT(index == attributeIndex && attributeIndex < mData.mAttributes.size());
+ const sh::Attribute &attrib = mData.mAttributes[attributeIndex];
+
+ if (bufsize > 0)
+ {
+ const char *string = attrib.name.c_str();
+
+ strncpy(name, string, bufsize);
+ name[bufsize - 1] = '\0';
+
+ if (length)
+ {
+ *length = static_cast<GLsizei>(strlen(name));
+ }
+ }
+
+ // Always a single 'type' instance
+ *size = 1;
+ *type = attrib.type;
}
GLint Program::getActiveAttributeCount()
{
- int count = 0;
-
- if (mLinked)
+ if (!mLinked)
{
- for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
- {
- if (!mLinkedAttributes[attributeIndex].name.empty())
- {
- count++;
- }
- }
+ return 0;
+ }
+
+ GLint count = 0;
+
+ for (const sh::Attribute &attrib : mData.mAttributes)
+ {
+ count += (attrib.staticUse ? 1 : 0);
}
return count;
@@ -686,22 +681,22 @@
GLint Program::getActiveAttributeMaxLength()
{
- GLint maxLength = 0;
-
- if (mLinked)
+ if (!mLinked)
{
- for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
+ return 0;
+ }
+
+ size_t maxLength = 0;
+
+ for (const sh::Attribute &attrib : mData.mAttributes)
+ {
+ if (attrib.staticUse)
{
- if (!mLinkedAttributes[attributeIndex].name.empty())
- {
- maxLength = std::max(
- static_cast<GLint>(mLinkedAttributes[attributeIndex].name.length() + 1),
- maxLength);
- }
+ maxLength = std::max(attrib.name.length() + 1, maxLength);
}
}
- return maxLength;
+ return static_cast<GLint>(maxLength);
}
GLint Program::getFragDataLocation(const std::string &name) const
@@ -1292,73 +1287,77 @@
const Shader *vertexShader)
{
unsigned int usedLocations = 0;
- const std::vector<sh::Attribute> &shaderAttributes = vertexShader->getActiveAttributes();
+ mData.mAttributes = vertexShader->getActiveAttributes();
GLuint maxAttribs = data.caps->maxVertexAttributes;
// TODO(jmadill): handle aliasing robustly
- if (shaderAttributes.size() > maxAttribs)
+ if (mData.mAttributes.size() > maxAttribs)
{
infoLog << "Too many vertex attributes.";
return false;
}
- // Link attributes that have a binding location
- for (unsigned int attributeIndex = 0; attributeIndex < shaderAttributes.size(); attributeIndex++)
- {
- const sh::Attribute &attribute = shaderAttributes[attributeIndex];
+ std::vector<sh::Attribute *> usedAttribMap(data.caps->maxVertexAttributes, nullptr);
+ // Link attributes that have a binding location
+ for (sh::Attribute &attribute : mData.mAttributes)
+ {
+ // TODO(jmadill): do staticUse filtering step here, or not at all
ASSERT(attribute.staticUse);
- const int location = attribute.location == -1 ? attributeBindings.getAttributeBinding(attribute.name) : attribute.location;
-
- mProgram->setShaderAttribute(attributeIndex, attribute);
-
- if (location != -1) // Set by glBindAttribLocation or by location layout qualifier
+ int bindingLocation = attributeBindings.getAttributeBinding(attribute.name);
+ if (attribute.location == -1 && bindingLocation != -1)
{
+ attribute.location = bindingLocation;
+ }
+
+ if (attribute.location != -1)
+ {
+ // Location is set by glBindAttribLocation or by location layout qualifier
const int rows = VariableRegisterCount(attribute.type);
- if (static_cast<GLuint>(rows + location) > maxAttribs)
+ if (static_cast<GLuint>(rows + attribute.location) > maxAttribs)
{
infoLog << "Active attribute (" << attribute.name << ") at location "
- << location << " is too big to fit";
+ << attribute.location << " is too big to fit";
return false;
}
for (int row = 0; row < rows; row++)
{
- const int rowLocation = location + row;
- sh::ShaderVariable *linkedAttribute = &mLinkedAttributes[rowLocation];
+ const int rowLocation = attribute.location + row;
+ sh::ShaderVariable *linkedAttribute = usedAttribMap[rowLocation];
// In GLSL 3.00, attribute aliasing produces a link error
// In GLSL 1.00, attribute aliasing is allowed, but ANGLE currently has a bug
- // TODO(jmadill): fix aliasing on ES2
- // if (mProgram->getShaderVersion() >= 300)
+ if (linkedAttribute)
{
- if (!linkedAttribute->name.empty())
+ // TODO(jmadill): fix aliasing on ES2
+ // if (mProgram->getShaderVersion() >= 300)
{
infoLog << "Attribute '" << attribute.name << "' aliases attribute '"
<< linkedAttribute->name << "' at location " << rowLocation;
return false;
}
}
+ else
+ {
+ usedAttribMap[rowLocation] = &attribute;
+ }
- *linkedAttribute = attribute;
usedLocations |= 1 << rowLocation;
}
}
}
// Link attributes that don't have a binding location
- for (unsigned int attributeIndex = 0; attributeIndex < shaderAttributes.size(); attributeIndex++)
+ for (sh::Attribute &attribute : mData.mAttributes)
{
- const sh::Attribute &attribute = shaderAttributes[attributeIndex];
-
ASSERT(attribute.staticUse);
- const int location = attribute.location == -1 ? attributeBindings.getAttributeBinding(attribute.name) : attribute.location;
-
- if (location == -1) // Not set by glBindAttribLocation or by location layout qualifier
+ // Not set by glBindAttribLocation or by location layout qualifier
+ if (attribute.location == -1)
{
int rows = VariableRegisterCount(attribute.type);
int availableIndex = AllocateFirstFreeBits(&usedLocations, rows, maxAttribs);
@@ -1366,17 +1365,21 @@
if (availableIndex == -1 || static_cast<GLuint>(availableIndex + rows) > maxAttribs)
{
infoLog << "Too many active attributes (" << attribute.name << ")";
- return false; // Fail to link
+ return false;
}
- mLinkedAttributes[availableIndex] = attribute;
+ attribute.location = availableIndex;
}
}
- for (GLuint attributeIndex = 0; attributeIndex < maxAttribs;)
+ // TODO(jmadill): make semantic index D3D-only
+ for (const sh::Attribute &attribute : mData.mAttributes)
{
- int index = vertexShader->getSemanticIndex(mLinkedAttributes[attributeIndex].name);
- int rows = VariableRegisterCount(mLinkedAttributes[attributeIndex].type);
+ ASSERT(attribute.staticUse);
+
+ unsigned int attributeIndex = attribute.location;
+ int index = vertexShader->getSemanticIndex(attribute.name);
+ int rows = VariableRegisterCount(attribute.type);
for (int r = 0; r < rows; r++)
{