Commit 9cf6c070 by Jamie Madill Committed by Shannon Woods

Refactor code for generating structure strings to a separate function.

This could fix a potential regression, which might define structs multiple times in generated HLSL. TRAC #23271 Signed-off-by: Nicolas Capens Signed-off-by: Shannon Woods Authored-by: Jamie Madill
parent 010fffa8
...@@ -218,11 +218,13 @@ TString OutputHLSL::interfaceBlockMemberTypeString(const TType &memberType) ...@@ -218,11 +218,13 @@ TString OutputHLSL::interfaceBlockMemberTypeString(const TType &memberType)
if (memberType.isMatrix()) if (memberType.isMatrix())
{ {
return " row_major " + typeString(memberType); // Use HLSL row-major packing for GLSL column-major matrices
return "row_major " + typeString(memberType);
} }
else if (memberType.getBasicType() == EbtStruct) else if (memberType.getBasicType() == EbtStruct)
{ {
return "rm" + typeString(memberType); // Use HLSL row-major packing for GLSL column-major matrices
return structureTypeName(memberType, true);
} }
else else
{ {
...@@ -2920,21 +2922,7 @@ TString OutputHLSL::typeString(const TType &type) ...@@ -2920,21 +2922,7 @@ TString OutputHLSL::typeString(const TType &type)
} }
else // Nameless structure, define in place else // Nameless structure, define in place
{ {
const TTypeList &fields = *type.getStruct(); return structureString(type, false);
TString string = "struct\n"
"{\n";
for (unsigned int i = 0; i < fields.size(); i++)
{
const TType &field = *fields[i].type;
string += " " + typeString(field) + " " + decorate(field.getFieldName()) + arrayString(field) + ";\n";
}
string += "} ";
return string;
} }
} }
else if (type.isMatrix()) else if (type.isMatrix())
...@@ -3041,6 +3029,58 @@ TString OutputHLSL::initializer(const TType &type) ...@@ -3041,6 +3029,58 @@ TString OutputHLSL::initializer(const TType &type)
return "{" + string + "}"; return "{" + string + "}";
} }
TString OutputHLSL::structureString(const TType &structType, bool useHLSLRowMajorPacking)
{
ASSERT(structType.getStruct());
const TTypeList &fields = *structType.getStruct();
const bool isNameless = (structType.getTypeName() == "");
const TString &structName = structureTypeName(structType, useHLSLRowMajorPacking);
const TString declareString = (isNameless ? "struct" : "struct " + structName);
TString structure;
structure += declareString + "\n"
"{\n";
for (unsigned int i = 0; i < fields.size(); i++)
{
const TType &field = *fields[i].type;
structure += " " + structureTypeName(field, useHLSLRowMajorPacking) + " " +
decorateField(field.getFieldName(), structType) + arrayString(field) + ";\n";
}
// Nameless structs do not finish with a semicolon and newline, to leave room for an instance variable
structure += (isNameless ? "} " : "};\n");
return structure;
}
TString OutputHLSL::structureTypeName(const TType &structType, bool useHLSLRowMajorPacking)
{
if (structType.getBasicType() != EbtStruct)
{
return typeString(structType);
}
if (structType.getTypeName() == "")
{
return "";
}
TString prefix = "";
// Structs packed with row-major matrices in HLSL are prefixed with "rm"
// GLSL column-major maps to HLSL row-major, and the converse is true
if (useHLSLRowMajorPacking)
{
prefix += "rm";
}
return prefix + typeString(structType);
}
void OutputHLSL::addConstructor(const TType &type, const TString &name, const TIntermSequence *parameters) void OutputHLSL::addConstructor(const TType &type, const TString &name, const TIntermSequence *parameters)
{ {
if (name == "") if (name == "")
...@@ -3067,32 +3107,20 @@ void OutputHLSL::addConstructor(const TType &type, const TString &name, const TI ...@@ -3067,32 +3107,20 @@ void OutputHLSL::addConstructor(const TType &type, const TString &name, const TI
{ {
mStructNames.insert(decorate(name)); mStructNames.insert(decorate(name));
TString structure; const TString &structure = structureString(type, false);
structure += "{\n";
const TTypeList &fields = *type.getStruct();
for (unsigned int i = 0; i < fields.size(); i++)
{
const TType &field = *fields[i].type;
structure += " " + typeString(field) + " " + decorateField(field.getFieldName(), type) + arrayString(field) + ";\n";
}
structure += "};\n";
if (std::find(mStructDeclarations.begin(), mStructDeclarations.end(), structure) == mStructDeclarations.end()) if (std::find(mStructDeclarations.begin(), mStructDeclarations.end(), structure) == mStructDeclarations.end())
{ {
TString columnMajorString = "struct " + decorate(name) + "\n" + structure; // Add row-major packed struct for interface blocks
TString rowMajorString = "#pragma pack_matrix(row_major)\n" TString rowMajorString = "#pragma pack_matrix(row_major)\n" +
"struct rm" + decorate(name) + "\n" + structureString(type, true) +
structure +
"#pragma pack_matrix(column_major)\n"; "#pragma pack_matrix(column_major)\n";
mStructDeclarations.push_back(columnMajorString); mStructDeclarations.push_back(structure);
mStructDeclarations.push_back(rowMajorString); mStructDeclarations.push_back(rowMajorString);
} }
const TTypeList &fields = *type.getStruct();
for (unsigned int i = 0; i < fields.size(); i++) for (unsigned int i = 0; i < fields.size(); i++)
{ {
ctorParameters.push_back(*fields[i].type); ctorParameters.push_back(*fields[i].type);
......
...@@ -40,6 +40,8 @@ class OutputHLSL : public TIntermTraverser ...@@ -40,6 +40,8 @@ class OutputHLSL : public TIntermTraverser
TString typeString(const TType &type); TString typeString(const TType &type);
TString textureString(const TType &type); TString textureString(const TType &type);
TString interpolationString(TQualifier qualifier); TString interpolationString(TQualifier qualifier);
TString structureString(const TType &structType, bool useHLSLRowMajorPacking);
TString structureTypeName(const TType &structType, bool useHLSLRowMajorPacking);
static TString qualifierString(TQualifier qualifier); static TString qualifierString(TQualifier qualifier);
static TString arrayString(const TType &type); static TString arrayString(const TType &type);
static TString initializer(const TType &type); static TString initializer(const TType &type);
......
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