Move shader attributes into Program shared data.
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: I469051eb066fc56e55282affa2d5398b394ab8d2
Reviewed-on: https://chromium-review.googlesource.com/293826
Tested-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/libANGLE/renderer/ProgramImpl.cpp b/src/libANGLE/renderer/ProgramImpl.cpp
index b0fd8f9..03d3c7c 100644
--- a/src/libANGLE/renderer/ProgramImpl.cpp
+++ b/src/libANGLE/renderer/ProgramImpl.cpp
@@ -135,26 +135,4 @@
SafeDeleteContainer(mUniformBlocks);
}
-void ProgramImpl::setShaderAttribute(size_t index, const sh::Attribute &attrib)
-{
- if (mShaderAttributes.size() <= index)
- {
- mShaderAttributes.resize(index + 1);
- }
- mShaderAttributes[index] = attrib;
-}
-
-void ProgramImpl::setShaderAttribute(size_t index, GLenum type, GLenum precision, const std::string &name, GLint size, int location)
-{
- if (mShaderAttributes.size() <= index)
- {
- mShaderAttributes.resize(index + 1);
- }
- mShaderAttributes[index].type = type;
- mShaderAttributes[index].precision = precision;
- mShaderAttributes[index].name = name;
- mShaderAttributes[index].arraySize = size;
- mShaderAttributes[index].location = location;
-}
-
}
diff --git a/src/libANGLE/renderer/ProgramImpl.h b/src/libANGLE/renderer/ProgramImpl.h
index e1bb357..d2f7041 100644
--- a/src/libANGLE/renderer/ProgramImpl.h
+++ b/src/libANGLE/renderer/ProgramImpl.h
@@ -85,7 +85,6 @@
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; }
- const std::vector<sh::Attribute> getShaderAttributes() { return mShaderAttributes; }
const SemanticIndexArray &getSemanticIndexes() const { return mSemanticIndex; }
std::vector<gl::LinkedUniform*> &getUniforms() { return mUniforms; }
@@ -101,9 +100,6 @@
GLuint getUniformIndex(const std::string &name) const;
GLuint getUniformBlockIndex(const std::string &name) const;
- void setShaderAttribute(size_t index, const sh::Attribute &attrib);
- void setShaderAttribute(size_t index, GLenum type, GLenum precision, const std::string &name, GLint size, int location);
-
virtual void reset();
protected:
@@ -117,9 +113,6 @@
std::vector<gl::UniformBlock*> mUniformBlocks;
SemanticIndexArray mSemanticIndex;
-
- private:
- std::vector<sh::Attribute> mShaderAttributes;
};
}
diff --git a/src/libANGLE/renderer/d3d/ProgramD3D.cpp b/src/libANGLE/renderer/d3d/ProgramD3D.cpp
index c41dc78..e4f7d54 100644
--- a/src/libANGLE/renderer/d3d/ProgramD3D.cpp
+++ b/src/libANGLE/renderer/d3d/ProgramD3D.cpp
@@ -1003,7 +1003,8 @@
}
// Generate new dynamic layout with attribute conversions
- std::string finalVertexHLSL = mDynamicHLSL->generateVertexShaderForInputLayout(mVertexHLSL, inputLayout, getShaderAttributes());
+ std::string finalVertexHLSL = mDynamicHLSL->generateVertexShaderForInputLayout(
+ mVertexHLSL, inputLayout, mData.getAttributes());
// Generate new vertex executable
ShaderExecutableD3D *vertexExecutable = NULL;
diff --git a/src/libANGLE/renderer/d3d/ProgramD3D.h b/src/libANGLE/renderer/d3d/ProgramD3D.h
index 17f7c3d..7207d8c 100644
--- a/src/libANGLE/renderer/d3d/ProgramD3D.h
+++ b/src/libANGLE/renderer/d3d/ProgramD3D.h
@@ -124,6 +124,7 @@
void sortAttributesByLayout(const std::vector<TranslatedAttribute> &unsortedAttributes,
int sortedSemanticIndicesOut[gl::MAX_VERTEX_ATTRIBS],
const rx::TranslatedAttribute *sortedAttributesOut[gl::MAX_VERTEX_ATTRIBS]) const;
+ const SemanticIndexArray &getAttributesByLayout() const { return mAttributesByLayout; }
void updateCachedInputLayout(const gl::Program *program, const gl::State &state);
const gl::InputLayout &getCachedInputLayout() const { return mCachedInputLayout; }
@@ -245,7 +246,7 @@
int mShaderVersion;
- int mAttributesByLayout[gl::MAX_VERTEX_ATTRIBS];
+ SemanticIndexArray mAttributesByLayout;
unsigned int mSerial;
diff --git a/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.cpp b/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.cpp
index 67c59a3..bae230c 100644
--- a/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.cpp
+++ b/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.cpp
@@ -46,20 +46,20 @@
return inputLayout;
}
-GLenum GetNextGLSLAttributeType(const std::vector<sh::Attribute> &linkedAttributes, int index)
+GLenum GetGLSLAttributeType(const std::vector<sh::Attribute> &shaderAttributes, int index)
{
// Count matrices differently
- int subIndex = 0;
- for (const sh::Attribute &attrib : linkedAttributes)
+ for (const sh::Attribute &attrib : shaderAttributes)
{
- if (attrib.type == GL_NONE)
+ if (attrib.location == -1)
{
continue;
}
GLenum transposedType = gl::TransposeMatrixType(attrib.type);
- subIndex += gl::VariableRowCount(transposedType);
- if (subIndex > index)
+ int rows = gl::VariableRowCount(transposedType);
+
+ if (index >= attrib.location && index < attrib.location + rows)
{
return transposedType;
}
@@ -185,6 +185,8 @@
bool instancedPointSpritesActive = programUsesInstancedPointSprites && (mode == GL_POINTS);
bool indexedPointSpriteEmulationActive = instancedPointSpritesActive && (sourceInfo != nullptr);
+ const auto &semanticToLocation = programD3D->getAttributesByLayout();
+
if (!mDevice || !mDeviceContext)
{
return gl::Error(GL_OUT_OF_MEMORY, "Internal input layout cache is not initialized.");
@@ -200,7 +202,7 @@
unsigned int firstInstancedElement = gl::MAX_VERTEX_ATTRIBS;
unsigned int nextAvailableInputSlot = 0;
- const std::vector<sh::Attribute> &linkedAttributes = program->getLinkedAttributes();
+ const std::vector<sh::Attribute> &shaderAttributes = program->getAttributes();
for (unsigned int i = 0; i < unsortedAttributes.size(); i++)
{
@@ -232,7 +234,8 @@
// Record the type of the associated vertex shader vector in our key
// This will prevent mismatched vertex shaders from using the same input layout
- GLenum glslElementType = GetNextGLSLAttributeType(linkedAttributes, inputElementCount);
+ GLenum glslElementType = GetGLSLAttributeType(
+ shaderAttributes, semanticToLocation[sortedSemanticIndices[i]]);
layout.addAttributeData(glslElementType,
sortedSemanticIndices[i],
diff --git a/src/libANGLE/renderer/gl/ProgramGL.cpp b/src/libANGLE/renderer/gl/ProgramGL.cpp
index 56fed09..1a070b6 100644
--- a/src/libANGLE/renderer/gl/ProgramGL.cpp
+++ b/src/libANGLE/renderer/gl/ProgramGL.cpp
@@ -169,34 +169,33 @@
}
}
- // Query the attribute information
- GLint activeAttributeMaxLength = 0;
- mFunctions->getProgramiv(mProgramID, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &activeAttributeMaxLength);
-
- std::vector<GLchar> attributeNameBuffer(activeAttributeMaxLength);
-
- GLint attributeCount = 0;
- mFunctions->getProgramiv(mProgramID, GL_ACTIVE_ATTRIBUTES, &attributeCount);
- for (GLint i = 0; i < attributeCount; i++)
+ for (const sh::Attribute &attribute : mData.getAttributes())
{
- GLsizei attributeNameLength = 0;
- GLint attributeSize = 0;
- GLenum attributeType = GL_NONE;
- mFunctions->getActiveAttrib(mProgramID, i, static_cast<GLsizei>(attributeNameBuffer.size()),
- &attributeNameLength, &attributeSize, &attributeType,
- &attributeNameBuffer[0]);
+ if (!attribute.staticUse)
+ continue;
- std::string attributeName(&attributeNameBuffer[0], attributeNameLength);
+ GLint realLocation = mFunctions->getAttribLocation(mProgramID, attribute.name.c_str());
- GLint location = mFunctions->getAttribLocation(mProgramID, attributeName.c_str());
-
- // TODO: determine attribute precision
- setShaderAttribute(static_cast<size_t>(i), attributeType, GL_NONE, attributeName, attributeSize, location);
-
- int attributeRegisterCount = gl::VariableRegisterCount(attributeType);
- for (int offset = 0; offset < attributeRegisterCount; offset++)
+ // Some drivers optimize attributes more aggressively.
+ if (realLocation == -1)
{
- mActiveAttributesMask.set(location + offset);
+ continue;
+ }
+
+ // TODO(jmadill): Fix this
+ ASSERT(attribute.location == realLocation);
+
+ int registerCount = gl::VariableRegisterCount(attribute.type);
+
+ if (mAttributeRealLocations.size() < attribute.location + registerCount + 1)
+ {
+ mAttributeRealLocations.resize(attribute.location + registerCount + 1, -1);
+ }
+
+ for (int offset = 0; offset < registerCount; ++offset)
+ {
+ mActiveAttributesMask.set(attribute.location + offset);
+ mAttributeRealLocations[attribute.location + offset] = realLocation + offset;
}
}
@@ -378,6 +377,7 @@
mSamplerUniformMap.clear();
mSamplerBindings.clear();
mActiveAttributesMask.reset();
+ mAttributeRealLocations.clear();
}
GLuint ProgramGL::getProgramID() const
diff --git a/src/libANGLE/renderer/gl/ProgramGL.h b/src/libANGLE/renderer/gl/ProgramGL.h
index ec4eaa6..c900c09 100644
--- a/src/libANGLE/renderer/gl/ProgramGL.h
+++ b/src/libANGLE/renderer/gl/ProgramGL.h
@@ -101,6 +101,9 @@
// An array of the samplers that are used by the program
std::vector<SamplerBindingGL> mSamplerBindings;
+ // Map from GL-layer attribute location to native location.
+ std::vector<GLint> mAttributeRealLocations;
+
// Array of attribute locations used by this program
gl::AttributesMask mActiveAttributesMask;