Commit 47fdd13e by Jamie Madill

Pass varyings to the GLES API from the translator using a direct pointer.

Instead of parsing them indirectly from HLSL, the pointer will allow us to more flexibly support new types, especially compound types such as structures. TRAC #23754 Signed-off-by: Nicolas Capens Signed-off-by: Shannon Woods
parent 9d2ffb1d
......@@ -37,7 +37,7 @@ extern "C" {
// Version number for shader translation API.
// It is incremented every time the API changes.
#define ANGLE_SH_VERSION 119
#define ANGLE_SH_VERSION 120
//
// The names of the following enums have been derived by replacing GL prefix
......@@ -132,21 +132,22 @@ typedef enum {
} ShDataType;
typedef enum {
SH_INFO_LOG_LENGTH = 0x8B84,
SH_OBJECT_CODE_LENGTH = 0x8B88, // GL_SHADER_SOURCE_LENGTH
SH_ACTIVE_UNIFORMS = 0x8B86,
SH_ACTIVE_UNIFORM_MAX_LENGTH = 0x8B87,
SH_ACTIVE_ATTRIBUTES = 0x8B89,
SH_ACTIVE_ATTRIBUTE_MAX_LENGTH = 0x8B8A,
SH_MAPPED_NAME_MAX_LENGTH = 0x6000,
SH_NAME_MAX_LENGTH = 0x6001,
SH_HASHED_NAME_MAX_LENGTH = 0x6002,
SH_HASHED_NAMES_COUNT = 0x6003,
SH_ACTIVE_UNIFORMS_ARRAY = 0x6004,
SH_SHADER_VERSION = 0x6005,
SH_ACTIVE_INTERFACE_BLOCKS_ARRAY = 0x6006,
SH_ACTIVE_OUTPUT_VARIABLES_ARRAY = 0x6007,
SH_ACTIVE_ATTRIBUTES_ARRAY = 0x6008,
SH_INFO_LOG_LENGTH = 0x8B84,
SH_OBJECT_CODE_LENGTH = 0x8B88, // GL_SHADER_SOURCE_LENGTH
SH_ACTIVE_UNIFORMS = 0x8B86,
SH_ACTIVE_UNIFORM_MAX_LENGTH = 0x8B87,
SH_ACTIVE_ATTRIBUTES = 0x8B89,
SH_ACTIVE_ATTRIBUTE_MAX_LENGTH = 0x8B8A,
SH_MAPPED_NAME_MAX_LENGTH = 0x6000,
SH_NAME_MAX_LENGTH = 0x6001,
SH_HASHED_NAME_MAX_LENGTH = 0x6002,
SH_HASHED_NAMES_COUNT = 0x6003,
SH_ACTIVE_UNIFORMS_ARRAY = 0x6004,
SH_SHADER_VERSION = 0x6005,
SH_ACTIVE_INTERFACE_BLOCKS_ARRAY = 0x6006,
SH_ACTIVE_OUTPUT_VARIABLES_ARRAY = 0x6007,
SH_ACTIVE_ATTRIBUTES_ARRAY = 0x6008,
SH_ACTIVE_VARYINGS_ARRAY = 0x6009,
} ShShaderInfo;
// Compile options.
......
......@@ -205,6 +205,11 @@ const std::vector<Attribute> &OutputHLSL::getAttributes() const
return mActiveAttributes;
}
const std::vector<Varying> &OutputHLSL::getVaryings() const
{
return mActiveVaryings;
}
int OutputHLSL::vectorSize(const TType &type) const
{
int elementSize = type.isMatrix() ? type.getCols() : 1;
......@@ -612,6 +617,8 @@ void OutputHLSL::header()
// Program linking depends on this exact format
varyings += "static " + interpolationString(type.getQualifier()) + " " + typeString(type) + " " +
decorate(name) + arrayString(type) + " = " + initializer(type) + ";\n";
declareVaryingToList(type, name, mActiveVaryings);
}
for (ReferencedSymbols::const_iterator attribute = mReferencedAttributes.begin(); attribute != mReferencedAttributes.end(); attribute++)
......@@ -3636,6 +3643,30 @@ void OutputHLSL::declareUniformToList(const TType &type, const TString &name, in
}
}
void OutputHLSL::declareVaryingToList(const TType &type, const TString &name, std::vector<Varying>& fieldsOut)
{
const TStructure *structure = type.getStruct();
if (!structure)
{
Varying varying(glVariableType(type), glVariablePrecision(type), name.c_str(), (unsigned int)type.getArraySize());
fieldsOut.push_back(varying);
}
else
{
Varying structVarying(GL_NONE, GL_NONE, name.c_str(), (unsigned int)type.getArraySize());
const TFieldList &fields = structure->fields();
for (size_t fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++)
{
const TField &field = *fields[fieldIndex];
declareVaryingToList(*field.type(), field.name(), structVarying.fields);
}
fieldsOut.push_back(structVarying);
}
}
void OutputHLSL::declareUniform(const TType &type, const TString &name, int index)
{
declareUniformToList(type, name, index, mActiveUniforms);
......
......@@ -36,6 +36,7 @@ class OutputHLSL : public TIntermTraverser
const ActiveInterfaceBlocks &getInterfaceBlocks() const;
const std::vector<Attribute> &getOutputVariables() const;
const std::vector<Attribute> &getAttributes() const;
const std::vector<Varying> &getVaryings() const;
TString typeString(const TType &type);
TString textureString(const TType &type);
......@@ -179,6 +180,7 @@ class OutputHLSL : public TIntermTraverser
void declareInterfaceBlockField(const TType &type, const TString &name, std::vector<InterfaceBlockField>& output);
void declareUniformToList(const TType &type, const TString &name, int registerIndex, std::vector<Uniform>& output);
void declareUniform(const TType &type, const TString &name, int index);
void declareVaryingToList(const TType &type, const TString &name, std::vector<Varying>& fieldsOut);
TString interfaceBlockFieldString(const TInterfaceBlock &interfaceBlock, const TField &field);
TString decoratePrivate(const TString &privateText);
......@@ -202,6 +204,7 @@ class OutputHLSL : public TIntermTraverser
ActiveInterfaceBlocks mActiveInterfaceBlocks;
std::vector<Attribute> mActiveOutputVariables;
std::vector<Attribute> mActiveAttributes;
std::vector<Varying> mActiveVaryings;
std::map<TString, int> mStd140StructElementIndexes;
std::map<TIntermTyped*, TString> mFlaggedStructMappedNames;
std::map<TIntermTyped*, TString> mFlaggedStructOriginalNames;
......
......@@ -386,6 +386,9 @@ void ShGetInfoPointer(const ShHandle handle, ShShaderInfo pname, void** params)
case SH_ACTIVE_ATTRIBUTES_ARRAY:
*params = (void*)&translator->getAttributes();
break;
case SH_ACTIVE_VARYINGS_ARRAY:
*params = (void*)&translator->getVaryings();
break;
default: UNREACHABLE();
}
}
......@@ -20,8 +20,10 @@ void TranslatorHLSL::translate(TIntermNode *root)
sh::OutputHLSL outputHLSL(parseContext, getResources(), mOutputType);
outputHLSL.output();
mActiveUniforms = outputHLSL.getUniforms();
mActiveInterfaceBlocks = outputHLSL.getInterfaceBlocks();
mActiveOutputVariables = outputHLSL.getOutputVariables();
mActiveAttributes = outputHLSL.getAttributes();
mActiveUniforms = outputHLSL.getUniforms();
mActiveInterfaceBlocks = outputHLSL.getInterfaceBlocks();
mActiveOutputVariables = outputHLSL.getOutputVariables();
mActiveAttributes = outputHLSL.getAttributes();
mActiveVaryings = outputHLSL.getVaryings();
}
......@@ -19,6 +19,7 @@ public:
const sh::ActiveInterfaceBlocks &getInterfaceBlocks() const { return mActiveInterfaceBlocks; }
const std::vector<sh::Attribute> &getOutputVariables() { return mActiveOutputVariables; }
const std::vector<sh::Attribute> &getAttributes() { return mActiveAttributes; }
const std::vector<sh::Varying> &getVaryings() { return mActiveVaryings; }
protected:
virtual void translate(TIntermNode* root);
......@@ -27,6 +28,7 @@ protected:
sh::ActiveInterfaceBlocks mActiveInterfaceBlocks;
std::vector<sh::Attribute> mActiveOutputVariables;
std::vector<sh::Attribute> mActiveAttributes;
std::vector<sh::Varying> mActiveVaryings;
ShShaderOutput mOutputType;
};
......
......@@ -41,6 +41,11 @@ InterfaceBlockField::InterfaceBlockField(GLenum typeIn, GLenum precisionIn, cons
{
}
Varying::Varying(GLenum typeIn, GLenum precisionIn, const char *nameIn, unsigned int arraySizeIn)
: ShaderVariable(typeIn, precisionIn, nameIn, arraySizeIn)
{
}
BlockMemberInfo::BlockMemberInfo(int offset, int arrayStride, int matrixStride, bool isRowMajorMatrix)
: offset(offset),
arrayStride(arrayStride),
......
......@@ -55,6 +55,15 @@ struct InterfaceBlockField : public ShaderVariable
bool isStruct() const { return !fields.empty(); }
};
struct Varying : public ShaderVariable
{
std::vector<Varying> fields;
Varying(GLenum typeIn, GLenum precisionIn, const char *nameIn, unsigned int arraySizeIn);
bool isStruct() const { return !fields.empty(); }
};
struct BlockMemberInfo
{
BlockMemberInfo(int offset, int arrayStride, int matrixStride, bool isRowMajorMatrix);
......
......@@ -215,60 +215,16 @@ void Shader::releaseCompiler()
ShFinalize();
}
void Shader::parseVaryings()
void Shader::parseVaryings(void *compiler)
{
if (!mHlsl.empty())
{
const std::string varyingsTitle("// Varyings");
size_t input = mHlsl.find(varyingsTitle);
if (input != std::string::npos)
{
input += varyingsTitle.length() + 1;
}
std::vector<sh::ShaderVariable> *activeVaryings;
ShGetInfoPointer(compiler, SH_ACTIVE_VARYINGS_ARRAY, reinterpret_cast<void**>(&activeVaryings));
while(input != std::string::npos)
for (unsigned int varyingIndex = 0; varyingIndex < activeVaryings->size(); varyingIndex++)
{
char string1[256];
char string2[256];
char string3[256];
int matches = sscanf(mHlsl.c_str() + input, "static %255s %255s %255s", string1, string2, string3);
char *interpolation = "linear"; // Default
char *type = string1;
char *name = string2;
if (matches == 0)
{
break;
}
else if (matches == 3)
{
if (string3[0] != '=') // Explicit interpolation qualifier
{
type = string2;
name = string3;
}
}
else UNREACHABLE();
char *array = strstr(name, "[");
int size = 1;
if (array)
{
size = atoi(array + 1);
*array = '\0';
}
mVaryings.push_back(Varying(parseInterpolation(interpolation), parseType(type), name, size, array != NULL));
const std::string semiColon(";");
input = mHlsl.find(semiColon, input);
if (input != std::string::npos)
{
input += semiColon.length() + 1;
}
mVaryings.push_back(Varying((*activeVaryings)[varyingIndex]));
}
mUsesMultipleRenderTargets = mHlsl.find("GL_USES_MRT") != std::string::npos;
......@@ -415,116 +371,6 @@ void Shader::compileToHLSL(void *compiler)
}
}
Interpolation Shader::parseInterpolation(const std::string &type)
{
if (type == "linear")
{
return Smooth;
}
else if (type == "centroid")
{
return Centroid;
}
else if (type == "nointerpolation")
{
return Flat;
}
else UNREACHABLE();
return Smooth;
}
GLenum Shader::parseType(const std::string &type)
{
if (type == "float")
{
return GL_FLOAT;
}
else if (type == "float2")
{
return GL_FLOAT_VEC2;
}
else if (type == "float3")
{
return GL_FLOAT_VEC3;
}
else if (type == "float4")
{
return GL_FLOAT_VEC4;
}
else if (type == "float2x2")
{
return GL_FLOAT_MAT2;
}
else if (type == "float3x3")
{
return GL_FLOAT_MAT3;
}
else if (type == "float4x4")
{
return GL_FLOAT_MAT4;
}
else if (type == "float2x3")
{
return GL_FLOAT_MAT2x3;
}
else if (type == "float3x2")
{
return GL_FLOAT_MAT3x2;
}
else if (type == "float2x4")
{
return GL_FLOAT_MAT2x4;
}
else if (type == "float4x2")
{
return GL_FLOAT_MAT4x2;
}
else if (type == "float3x4")
{
return GL_FLOAT_MAT3x4;
}
else if (type == "float4x3")
{
return GL_FLOAT_MAT4x3;
}
else if (type == "int")
{
return GL_INT;
}
else if (type == "int2")
{
return GL_INT_VEC2;
}
else if (type == "int3")
{
return GL_INT_VEC3;
}
else if (type == "int4")
{
return GL_INT_VEC4;
}
else if (type == "uint")
{
return GL_UNSIGNED_INT;
}
else if (type == "uint2")
{
return GL_UNSIGNED_INT_VEC2;
}
else if (type == "uint3")
{
return GL_UNSIGNED_INT_VEC3;
}
else if (type == "uint4")
{
return GL_UNSIGNED_INT_VEC4;
}
else UNREACHABLE();
return GL_NONE;
}
// [OpenGL ES SL 3.00.4] Section 11 p. 120
// Vertex Outs/Fragment Ins packing priorities
static const GLenum varyingPriorityList[] =
......@@ -624,7 +470,7 @@ void VertexShader::compile()
compileToHLSL(mVertexCompiler);
parseAttributes();
parseVaryings();
parseVaryings(mVertexCompiler);
}
int VertexShader::getSemanticIndex(const std::string &attributeName)
......@@ -678,7 +524,7 @@ void FragmentShader::compile()
uncompile();
compileToHLSL(mFragmentCompiler);
parseVaryings();
parseVaryings(mFragmentCompiler);
mVaryings.sort(compareVarying);
const std::string &hlsl = getHLSL();
......
......@@ -40,10 +40,15 @@ enum Interpolation
struct Varying
{
Varying(Interpolation interpolation, GLenum type, const std::string &name, int size, bool array)
: interpolation(interpolation), type(type), name(name), size(size), array(array), reg(-1), col(-1)
{
}
Varying(const sh::ShaderVariable &shaderVar)
: interpolation(Smooth),
type(shaderVar.type),
name("_" + shaderVar.name),
size(std::max((int)shaderVar.arraySize, 1)),
array(shaderVar.arraySize > 0),
reg(-1),
col(-1)
{}
Interpolation interpolation;
GLenum type;
......@@ -95,15 +100,13 @@ class Shader
static void releaseCompiler();
protected:
void parseVaryings();
void parseVaryings(void *compiler);
void resetVaryingsRegisterAssignment();
void compileToHLSL(void *compiler);
void getSourceImpl(const std::string &source, GLsizei bufSize, GLsizei *length, char *buffer) const;
static Interpolation parseInterpolation(const std::string &type);
static GLenum parseType(const std::string &type);
static bool compareVarying(const Varying &x, const Varying &y);
const rx::Renderer *const mRenderer;
......
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