Commit defb674a by Jamie Madill Committed by Shannon Woods

Add a new path for querying active attributes from the shader translator, for…

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
parent bb22e508
......@@ -37,7 +37,7 @@ extern "C" {
// Version number for shader translation API.
// It is incremented everytime the API changes.
#define ANGLE_SH_VERSION 114
#define ANGLE_SH_VERSION 115
//
// The names of the following enums have been derived by replacing GL prefix
......@@ -133,6 +133,7 @@ typedef enum {
SH_SHADER_VERSION = 0x6005,
SH_ACTIVE_INTERFACE_BLOCKS_ARRAY = 0x6006,
SH_ACTIVE_OUTPUT_VARIABLES_ARRAY = 0x6007,
SH_ACTIVE_ATTRIBUTES_ARRAY = 0x6008,
} ShShaderInfo;
// Compile options.
......
......@@ -161,6 +161,11 @@ const ActiveShaderVariables &OutputHLSL::getOutputVariables() const
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 @@ void OutputHLSL::header()
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)
......
......@@ -35,6 +35,7 @@ class OutputHLSL : public TIntermTraverser
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 @@ class OutputHLSL : public TIntermTraverser
ActiveUniforms mActiveUniforms;
ActiveInterfaceBlocks mActiveInterfaceBlocks;
ActiveShaderVariables mActiveOutputVariables;
ActiveShaderVariables mActiveAttributes;
};
}
......
......@@ -382,6 +382,9 @@ void ShGetInfoPointer(const ShHandle handle, ShShaderInfo pname, void** params)
case SH_ACTIVE_OUTPUT_VARIABLES_ARRAY:
*params = (void*)&translator->getOutputVariables();
break;
case SH_ACTIVE_ATTRIBUTES_ARRAY:
*params = (void*)&translator->getAttributes();
break;
default: UNREACHABLE();
}
}
......@@ -23,4 +23,5 @@ void TranslatorHLSL::translate(TIntermNode *root)
mActiveUniforms = outputHLSL.getUniforms();
mActiveInterfaceBlocks = outputHLSL.getInterfaceBlocks();
mActiveOutputVariables = outputHLSL.getOutputVariables();
mActiveAttributes = outputHLSL.getAttributes();
}
......@@ -18,6 +18,7 @@ public:
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 @@ protected:
sh::ActiveUniforms mActiveUniforms;
sh::ActiveInterfaceBlocks mActiveInterfaceBlocks;
sh::ActiveShaderVariables mActiveOutputVariables;
sh::ActiveShaderVariables mActiveAttributes;
ShShaderOutput mOutputType;
};
......
......@@ -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),
......
......@@ -19,6 +19,7 @@ namespace sh
struct ShaderVariable
{
ShaderVariable();
ShaderVariable(GLenum type, GLenum precision, const char *name, unsigned int arraySize, int location);
GLenum type;
......
......@@ -1210,12 +1210,14 @@ bool ProgramBinary::linkVaryings(InfoLog &infoLog, int registers, const Varying
"{\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 @@ bool ProgramBinary::linkVaryings(InfoLog &infoLog, int registers, const Varying
"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::link(InfoLog &infoLog, const AttributeBindings &attributeBin
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 @@ bool ProgramBinary::linkAttributes(InfoLog &infoLog, const AttributeBindings &at
// 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 @@ bool ProgramBinary::linkAttributes(InfoLog &infoLog, const AttributeBindings &at
}
// 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;
}
}
......
......@@ -186,7 +186,7 @@ class ProgramBinary : public RefCountObject
rx::ShaderExecutable *mVertexExecutable;
rx::ShaderExecutable *mGeometryExecutable;
Attribute mLinkedAttribute[MAX_VERTEX_ATTRIBS];
sh::ShaderVariable mLinkedAttribute[MAX_VERTEX_ATTRIBS];
int mSemanticIndex[MAX_VERTEX_ATTRIBS];
struct Sampler
......
......@@ -628,7 +628,7 @@ void VertexShader::uncompile()
Shader::uncompile();
// set by ParseAttributes
mAttributes.clear();
mActiveAttributes.clear();
}
void VertexShader::compile()
......@@ -645,14 +645,16 @@ int VertexShader::getSemanticIndex(const std::string &attributeName)
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 @@ void VertexShader::parseAttributes()
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;
}
}
......
......@@ -141,22 +141,6 @@ class Shader
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 @@ class VertexShader : public Shader
void parseAttributes();
AttributeArray mAttributes;
sh::ActiveShaderVariables mActiveAttributes;
};
class FragmentShader : public Shader
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment