Add a new path for querying active attributes from the shader translator, for use with layout qualifier support.
TRAC #23269
Signed-off-by: Geoff Lang
Signed-off-by: Nicolas Capens
Author: Jamie Madill
diff --git a/src/compiler/OutputHLSL.cpp b/src/compiler/OutputHLSL.cpp
index b36d456..d117a30 100644
--- a/src/compiler/OutputHLSL.cpp
+++ b/src/compiler/OutputHLSL.cpp
@@ -161,6 +161,11 @@
return mActiveOutputVariables;
}
+const ActiveShaderVariables &OutputHLSL::getAttributes() const
+{
+ return mActiveAttributes;
+}
+
int OutputHLSL::vectorSize(const TType &type) const
{
int elementSize = type.isMatrix() ? type.getCols() : 1;
@@ -389,6 +394,10 @@
const TString &name = attribute->second->getSymbol();
attributes += "static " + typeString(type) + " " + decorate(name) + arrayString(type) + " = " + initializer(type) + ";\n";
+
+ ShaderVariable shaderVar(glVariableType(type), glVariablePrecision(type), name.c_str(),
+ (unsigned int)type.getArraySize(), type.getLayoutQualifier().location);
+ mActiveAttributes.push_back(shaderVar);
}
if (shaderType == SH_FRAGMENT_SHADER)
diff --git a/src/compiler/OutputHLSL.h b/src/compiler/OutputHLSL.h
index c22ad4f..6a409b4 100644
--- a/src/compiler/OutputHLSL.h
+++ b/src/compiler/OutputHLSL.h
@@ -35,6 +35,7 @@
const ActiveUniforms &getUniforms();
const ActiveInterfaceBlocks &getInterfaceBlocks() const;
const ActiveShaderVariables &getOutputVariables() const;
+ const ActiveShaderVariables &getAttributes() const;
TString typeString(const TType &type);
TString textureString(const TType &type);
@@ -195,6 +196,7 @@
ActiveUniforms mActiveUniforms;
ActiveInterfaceBlocks mActiveInterfaceBlocks;
ActiveShaderVariables mActiveOutputVariables;
+ ActiveShaderVariables mActiveAttributes;
};
}
diff --git a/src/compiler/ShaderLang.cpp b/src/compiler/ShaderLang.cpp
index 07313dd..efdcb67 100644
--- a/src/compiler/ShaderLang.cpp
+++ b/src/compiler/ShaderLang.cpp
@@ -382,6 +382,9 @@
case SH_ACTIVE_OUTPUT_VARIABLES_ARRAY:
*params = (void*)&translator->getOutputVariables();
break;
+ case SH_ACTIVE_ATTRIBUTES_ARRAY:
+ *params = (void*)&translator->getAttributes();
+ break;
default: UNREACHABLE();
}
}
diff --git a/src/compiler/TranslatorHLSL.cpp b/src/compiler/TranslatorHLSL.cpp
index 6ef91f4..83468d4 100644
--- a/src/compiler/TranslatorHLSL.cpp
+++ b/src/compiler/TranslatorHLSL.cpp
@@ -23,4 +23,5 @@
mActiveUniforms = outputHLSL.getUniforms();
mActiveInterfaceBlocks = outputHLSL.getInterfaceBlocks();
mActiveOutputVariables = outputHLSL.getOutputVariables();
+ mActiveAttributes = outputHLSL.getAttributes();
}
diff --git a/src/compiler/TranslatorHLSL.h b/src/compiler/TranslatorHLSL.h
index c031446..e53e831 100644
--- a/src/compiler/TranslatorHLSL.h
+++ b/src/compiler/TranslatorHLSL.h
@@ -18,6 +18,7 @@
const sh::ActiveUniforms &getUniforms() { return mActiveUniforms; }
const sh::ActiveInterfaceBlocks &getInterfaceBlocks() const { return mActiveInterfaceBlocks; }
const sh::ActiveShaderVariables &getOutputVariables() { return mActiveOutputVariables; }
+ const sh::ActiveShaderVariables &getAttributes() { return mActiveAttributes; }
protected:
virtual void translate(TIntermNode* root);
@@ -25,6 +26,7 @@
sh::ActiveUniforms mActiveUniforms;
sh::ActiveInterfaceBlocks mActiveInterfaceBlocks;
sh::ActiveShaderVariables mActiveOutputVariables;
+ sh::ActiveShaderVariables mActiveAttributes;
ShShaderOutput mOutputType;
};
diff --git a/src/compiler/Uniform.cpp b/src/compiler/Uniform.cpp
index 602eed5..3cd3599 100644
--- a/src/compiler/Uniform.cpp
+++ b/src/compiler/Uniform.cpp
@@ -11,6 +11,14 @@
namespace sh
{
+ShaderVariable::ShaderVariable()
+ : type(GL_NONE),
+ precision(GL_NONE),
+ arraySize(0),
+ location(-1)
+{
+}
+
ShaderVariable::ShaderVariable(GLenum type, GLenum precision, const char *name, unsigned int arraySize, int location)
: type(type),
precision(precision),
diff --git a/src/compiler/Uniform.h b/src/compiler/Uniform.h
index e43533a..ac0fdfd 100644
--- a/src/compiler/Uniform.h
+++ b/src/compiler/Uniform.h
@@ -19,6 +19,7 @@
struct ShaderVariable
{
+ ShaderVariable();
ShaderVariable(GLenum type, GLenum precision, const char *name, unsigned int arraySize, int location);
GLenum type;
diff --git a/src/libGLESv2/ProgramBinary.cpp b/src/libGLESv2/ProgramBinary.cpp
index eead8ab..34cec04 100644
--- a/src/libGLESv2/ProgramBinary.cpp
+++ b/src/libGLESv2/ProgramBinary.cpp
@@ -1210,12 +1210,14 @@
"{\n";
int semanticIndex = 0;
- for (AttributeArray::iterator attribute = vertexShader->mAttributes.begin(); attribute != vertexShader->mAttributes.end(); attribute++)
+ const sh::ActiveShaderVariables &activeAttributes = vertexShader->mActiveAttributes;
+ for (unsigned int attributeIndex = 0; attributeIndex < activeAttributes.size(); attributeIndex++)
{
- vertexHLSL += " " + gl_d3d::TypeString(TransposeMatrixType(attribute->type)) + " ";
- vertexHLSL += decorateAttribute(attribute->name) + " : TEXCOORD" + str(semanticIndex) + ";\n";
+ const sh::ShaderVariable &attribute = activeAttributes[attributeIndex];
+ vertexHLSL += " " + gl_d3d::TypeString(TransposeMatrixType(attribute.type)) + " ";
+ vertexHLSL += decorateAttribute(attribute.name) + " : TEXCOORD" + str(semanticIndex) + ";\n";
- semanticIndex += AttributeRegisterCount(attribute->type);
+ semanticIndex += AttributeRegisterCount(attribute.type);
}
vertexHLSL += "};\n"
@@ -1250,16 +1252,17 @@
"VS_OUTPUT main(VS_INPUT input)\n"
"{\n";
- for (AttributeArray::iterator attribute = vertexShader->mAttributes.begin(); attribute != vertexShader->mAttributes.end(); attribute++)
+ for (unsigned int attributeIndex = 0; attributeIndex < activeAttributes.size(); attributeIndex++)
{
- vertexHLSL += " " + decorateAttribute(attribute->name) + " = ";
+ const sh::ShaderVariable &attribute = activeAttributes[attributeIndex];
+ vertexHLSL += " " + decorateAttribute(attribute.name) + " = ";
- if (IsMatrixType(attribute->type)) // Matrix
+ if (IsMatrixType(attribute.type)) // Matrix
{
vertexHLSL += "transpose";
}
- vertexHLSL += "(input." + decorateAttribute(attribute->name) + ");\n";
+ vertexHLSL += "(input." + decorateAttribute(attribute.name) + ");\n";
}
if (vertexHLSL.find("dx_initConstantBuffers") != std::string::npos)
@@ -2065,11 +2068,13 @@
bool ProgramBinary::linkAttributes(InfoLog &infoLog, const AttributeBindings &attributeBindings, FragmentShader *fragmentShader, VertexShader *vertexShader)
{
unsigned int usedLocations = 0;
+ const sh::ActiveShaderVariables &activeAttributes = vertexShader->mActiveAttributes;
// Link attributes that have a binding location
- for (AttributeArray::iterator attribute = vertexShader->mAttributes.begin(); attribute != vertexShader->mAttributes.end(); attribute++)
+ for (unsigned int attributeIndex = 0; attributeIndex < activeAttributes.size(); attributeIndex++)
{
- int location = attributeBindings.getAttributeBinding(attribute->name);
+ const sh::ShaderVariable &attribute = activeAttributes[attributeIndex];
+ const int location = attributeBindings.getAttributeBinding(attribute.name);
if (location != -1) // Set by glBindAttribLocation
{
@@ -2078,13 +2083,13 @@
// Multiple active attributes bound to the same location; not an error
}
- mLinkedAttribute[location] = *attribute;
+ mLinkedAttribute[location] = attribute;
- int rows = AttributeRegisterCount(attribute->type);
+ int rows = AttributeRegisterCount(attribute.type);
if (rows + location > MAX_VERTEX_ATTRIBS)
{
- infoLog.append("Active attribute (%s) at location %d is too big to fit", attribute->name.c_str(), location);
+ infoLog.append("Active attribute (%s) at location %d is too big to fit", attribute.name.c_str(), location);
return false;
}
@@ -2097,23 +2102,24 @@
}
// Link attributes that don't have a binding location
- for (AttributeArray::iterator attribute = vertexShader->mAttributes.begin(); attribute != vertexShader->mAttributes.end(); attribute++)
+ for (unsigned int attributeIndex = 0; attributeIndex < activeAttributes.size(); attributeIndex++)
{
- int location = attributeBindings.getAttributeBinding(attribute->name);
+ const sh::ShaderVariable &attribute = activeAttributes[attributeIndex];
+ int location = attributeBindings.getAttributeBinding(attribute.name);
if (location == -1) // Not set by glBindAttribLocation
{
- int rows = AttributeRegisterCount(attribute->type);
+ int rows = AttributeRegisterCount(attribute.type);
int availableIndex = AllocateFirstFreeBits(&usedLocations, rows, MAX_VERTEX_ATTRIBS);
if (availableIndex == -1 || availableIndex + rows > MAX_VERTEX_ATTRIBS)
{
- infoLog.append("Too many active attributes (%s)", attribute->name.c_str());
+ infoLog.append("Too many active attributes (%s)", attribute.name.c_str());
return false; // Fail to link
}
- mLinkedAttribute[availableIndex] = *attribute;
+ mLinkedAttribute[availableIndex] = attribute;
}
}
diff --git a/src/libGLESv2/ProgramBinary.h b/src/libGLESv2/ProgramBinary.h
index a29cf93..8401483 100644
--- a/src/libGLESv2/ProgramBinary.h
+++ b/src/libGLESv2/ProgramBinary.h
@@ -186,7 +186,7 @@
rx::ShaderExecutable *mVertexExecutable;
rx::ShaderExecutable *mGeometryExecutable;
- Attribute mLinkedAttribute[MAX_VERTEX_ATTRIBS];
+ sh::ShaderVariable mLinkedAttribute[MAX_VERTEX_ATTRIBS];
int mSemanticIndex[MAX_VERTEX_ATTRIBS];
struct Sampler
diff --git a/src/libGLESv2/Shader.cpp b/src/libGLESv2/Shader.cpp
index c18706a..4ab3789 100644
--- a/src/libGLESv2/Shader.cpp
+++ b/src/libGLESv2/Shader.cpp
@@ -628,7 +628,7 @@
Shader::uncompile();
// set by ParseAttributes
- mAttributes.clear();
+ mActiveAttributes.clear();
}
void VertexShader::compile()
@@ -645,14 +645,16 @@
if (!attributeName.empty())
{
int semanticIndex = 0;
- for (AttributeArray::iterator attribute = mAttributes.begin(); attribute != mAttributes.end(); attribute++)
+ for (unsigned int attributeIndex = 0; attributeIndex < mActiveAttributes.size(); attributeIndex++)
{
- if (attribute->name == attributeName)
+ const sh::ShaderVariable &attribute = mActiveAttributes[attributeIndex];
+
+ if (attribute.name == attributeName)
{
return semanticIndex;
}
- semanticIndex += AttributeRegisterCount(attribute->type);
+ semanticIndex += AttributeRegisterCount(attribute.type);
}
}
@@ -664,24 +666,9 @@
const char *hlsl = getHLSL();
if (hlsl)
{
- const char *input = strstr(hlsl, "// Attributes") + 14;
-
- while(true)
- {
- char attributeType[256];
- char attributeName[256];
-
- int matches = sscanf(input, "static %255s _%255s", attributeType, attributeName);
-
- if (matches != 2)
- {
- break;
- }
-
- mAttributes.push_back(Attribute(parseType(attributeType), attributeName));
-
- input = strstr(input, ";") + 2;
- }
+ void *activeAttributes;
+ ShGetInfoPointer(mVertexCompiler, SH_ACTIVE_ATTRIBUTES_ARRAY, &activeAttributes);
+ mActiveAttributes = *(sh::ActiveShaderVariables*)activeAttributes;
}
}
diff --git a/src/libGLESv2/Shader.h b/src/libGLESv2/Shader.h
index e5c600a..b5df3f4 100644
--- a/src/libGLESv2/Shader.h
+++ b/src/libGLESv2/Shader.h
@@ -141,22 +141,6 @@
ResourceManager *mResourceManager;
};
-struct Attribute
-{
- Attribute() : type(GL_NONE), name("")
- {
- }
-
- Attribute(GLenum type, const std::string &name) : type(type), name(name)
- {
- }
-
- GLenum type;
- std::string name;
-};
-
-typedef std::vector<Attribute> AttributeArray;
-
class VertexShader : public Shader
{
friend class ProgramBinary;
@@ -176,7 +160,7 @@
void parseAttributes();
- AttributeArray mAttributes;
+ sh::ActiveShaderVariables mActiveAttributes;
};
class FragmentShader : public Shader