Commit c835df68 by Jamie Madill Committed by Shannon Woods

Add support for structs in uniform blocks with standard layout.

TRAC #23327 Signed-off-by: Geoff Lang Signed-off-by: Shannon Woods Authored-by: Jamie Madill
parent 6fb09f6c
...@@ -253,7 +253,7 @@ TString OutputHLSL::interfaceBlockInstanceString(const TType& interfaceBlockType ...@@ -253,7 +253,7 @@ TString OutputHLSL::interfaceBlockInstanceString(const TType& interfaceBlockType
} }
} }
TString OutputHLSL::interfaceBlockMemberTypeString(const TType &memberType) TString OutputHLSL::interfaceBlockMemberTypeString(const TType &memberType, TLayoutBlockStorage blockStorage)
{ {
const TLayoutMatrixPacking matrixPacking = memberType.getLayoutQualifier().matrixPacking; const TLayoutMatrixPacking matrixPacking = memberType.getLayoutQualifier().matrixPacking;
ASSERT(matrixPacking != EmpUnspecified); ASSERT(matrixPacking != EmpUnspecified);
...@@ -267,7 +267,7 @@ TString OutputHLSL::interfaceBlockMemberTypeString(const TType &memberType) ...@@ -267,7 +267,7 @@ TString OutputHLSL::interfaceBlockMemberTypeString(const TType &memberType)
else if (memberType.getBasicType() == EbtStruct) else if (memberType.getBasicType() == EbtStruct)
{ {
// Use HLSL row-major packing for GLSL column-major matrices // Use HLSL row-major packing for GLSL column-major matrices
return structureTypeName(memberType, matrixPacking == EmpColumnMajor); return structureTypeName(memberType, matrixPacking == EmpColumnMajor, blockStorage == EbsStd140);
} }
else else
{ {
...@@ -325,21 +325,26 @@ TString OutputHLSL::std140PrePaddingString(const TType &type, int *elementIndex) ...@@ -325,21 +325,26 @@ TString OutputHLSL::std140PrePaddingString(const TType &type, int *elementIndex)
TString OutputHLSL::std140PostPaddingString(const TType &type) TString OutputHLSL::std140PostPaddingString(const TType &type)
{ {
if (!type.isMatrix() && !type.isArray()) if (!type.isMatrix() && !type.isArray() && type.getBasicType() != EbtStruct)
{ {
return ""; return "";
} }
const GLenum glType = glVariableType(type);
int numComponents = 0; int numComponents = 0;
if (type.isMatrix()) if (type.isMatrix())
{ {
const bool isRowMajorMatrix = (type.getLayoutQualifier().matrixPacking == EmpRowMajor); const bool isRowMajorMatrix = (type.getLayoutQualifier().matrixPacking == EmpRowMajor);
const GLenum glType = glVariableType(type);
numComponents = gl::MatrixComponentCount(glType, isRowMajorMatrix); numComponents = gl::MatrixComponentCount(glType, isRowMajorMatrix);
} }
else if (type.getBasicType() == EbtStruct)
{
// TODO
}
else else
{ {
const GLenum glType = glVariableType(type);
numComponents = gl::UniformComponentCount(glType); numComponents = gl::UniformComponentCount(glType);
} }
...@@ -363,18 +368,11 @@ TString OutputHLSL::interfaceBlockMemberString(const TTypeList &typeList, TLayou ...@@ -363,18 +368,11 @@ TString OutputHLSL::interfaceBlockMemberString(const TTypeList &typeList, TLayou
if (blockStorage == EbsStd140) if (blockStorage == EbsStd140)
{ {
if (memberType.getBasicType() == EbtStruct) // 2 and 3 component vector types in some cases need pre-padding
{ hlsl += std140PrePaddingString(memberType, &elementIndex);
UNIMPLEMENTED();
}
else
{
// 2 and 3 component vector types in some cases need pre-padding
hlsl += std140PrePaddingString(memberType, &elementIndex);
}
} }
hlsl += " " + interfaceBlockMemberTypeString(memberType) + hlsl += " " + interfaceBlockMemberTypeString(memberType, blockStorage) +
" " + decorate(memberType.getFieldName()) + arrayString(memberType) + ";\n"; " " + decorate(memberType.getFieldName()) + arrayString(memberType) + ";\n";
// must pad out after matrices and arrays, where HLSL usually allows itself room to pack stuff // must pad out after matrices and arrays, where HLSL usually allows itself room to pack stuff
...@@ -2782,7 +2780,7 @@ TString OutputHLSL::typeString(const TType &type) ...@@ -2782,7 +2780,7 @@ TString OutputHLSL::typeString(const TType &type)
} }
else // Nameless structure, define in place else // Nameless structure, define in place
{ {
return structureString(type, false); return structureString(type, false, false);
} }
} }
else if (type.isMatrix()) else if (type.isMatrix())
...@@ -2900,13 +2898,13 @@ TString OutputHLSL::initializer(const TType &type) ...@@ -2900,13 +2898,13 @@ TString OutputHLSL::initializer(const TType &type)
return "{" + string + "}"; return "{" + string + "}";
} }
TString OutputHLSL::structureString(const TType &structType, bool useHLSLRowMajorPacking) TString OutputHLSL::structureString(const TType &structType, bool useHLSLRowMajorPacking, bool useStd140Packing)
{ {
ASSERT(structType.getStruct()); ASSERT(structType.getStruct());
const TTypeList &fields = *structType.getStruct(); const TTypeList &fields = *structType.getStruct();
const bool isNameless = (structType.getTypeName() == ""); const bool isNameless = (structType.getTypeName() == "");
const TString &structName = structureTypeName(structType, useHLSLRowMajorPacking); const TString &structName = structureTypeName(structType, useHLSLRowMajorPacking, useStd140Packing);
const TString declareString = (isNameless ? "struct" : "struct " + structName); const TString declareString = (isNameless ? "struct" : "struct " + structName);
...@@ -2914,12 +2912,24 @@ TString OutputHLSL::structureString(const TType &structType, bool useHLSLRowMajo ...@@ -2914,12 +2912,24 @@ TString OutputHLSL::structureString(const TType &structType, bool useHLSLRowMajo
structure += declareString + "\n" structure += declareString + "\n"
"{\n"; "{\n";
int elementIndex = 0;
for (unsigned int i = 0; i < fields.size(); i++) for (unsigned int i = 0; i < fields.size(); i++)
{ {
const TType &field = *fields[i].type; const TType &field = *fields[i].type;
structure += " " + structureTypeName(field, useHLSLRowMajorPacking) + " " + if (useStd140Packing)
{
structure += std140PrePaddingString(field, &elementIndex);
}
structure += " " + structureTypeName(field, useHLSLRowMajorPacking, useStd140Packing) + " " +
decorateField(field.getFieldName(), structType) + arrayString(field) + ";\n"; decorateField(field.getFieldName(), structType) + arrayString(field) + ";\n";
if (useStd140Packing)
{
structure += std140PostPaddingString(field);
}
} }
// Nameless structs do not finish with a semicolon and newline, to leave room for an instance variable // Nameless structs do not finish with a semicolon and newline, to leave room for an instance variable
...@@ -2928,7 +2938,7 @@ TString OutputHLSL::structureString(const TType &structType, bool useHLSLRowMajo ...@@ -2928,7 +2938,7 @@ TString OutputHLSL::structureString(const TType &structType, bool useHLSLRowMajo
return structure; return structure;
} }
TString OutputHLSL::structureTypeName(const TType &structType, bool useHLSLRowMajorPacking) TString OutputHLSL::structureTypeName(const TType &structType, bool useHLSLRowMajorPacking, bool useStd140Packing)
{ {
if (structType.getBasicType() != EbtStruct) if (structType.getBasicType() != EbtStruct)
{ {
...@@ -2944,8 +2954,15 @@ TString OutputHLSL::structureTypeName(const TType &structType, bool useHLSLRowMa ...@@ -2944,8 +2954,15 @@ TString OutputHLSL::structureTypeName(const TType &structType, bool useHLSLRowMa
// Structs packed with row-major matrices in HLSL are prefixed with "rm" // 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 // GLSL column-major maps to HLSL row-major, and the converse is true
if (useStd140Packing)
{
prefix += "std";
}
if (useHLSLRowMajorPacking) if (useHLSLRowMajorPacking)
{ {
if (prefix != "") prefix += "_";
prefix += "rm"; prefix += "rm";
} }
...@@ -2978,17 +2995,27 @@ void OutputHLSL::addConstructor(const TType &type, const TString &name, const TI ...@@ -2978,17 +2995,27 @@ void OutputHLSL::addConstructor(const TType &type, const TString &name, const TI
{ {
mStructNames.insert(decorate(name)); mStructNames.insert(decorate(name));
const TString &structure = structureString(type, false); const TString &structure = structureString(type, false, false);
if (std::find(mStructDeclarations.begin(), mStructDeclarations.end(), structure) == mStructDeclarations.end()) if (std::find(mStructDeclarations.begin(), mStructDeclarations.end(), structure) == mStructDeclarations.end())
{ {
// Add row-major packed struct for interface blocks // Add row-major packed struct for interface blocks
TString rowMajorString = "#pragma pack_matrix(row_major)\n" + TString rowMajorString = "#pragma pack_matrix(row_major)\n" +
structureString(type, true) + structureString(type, true, false) +
"#pragma pack_matrix(column_major)\n"; "#pragma pack_matrix(column_major)\n";
const TString &std140Prefix = "std";
TString std140String = structureString(type, false, true);
const TString &std140RowMajorPrefix = "std_rm";
TString std140RowMajorString = "#pragma pack_matrix(row_major)\n" +
structureString(type, true, true) +
"#pragma pack_matrix(column_major)\n";
mStructDeclarations.push_back(structure); mStructDeclarations.push_back(structure);
mStructDeclarations.push_back(rowMajorString); mStructDeclarations.push_back(rowMajorString);
mStructDeclarations.push_back(std140String);
mStructDeclarations.push_back(std140RowMajorString);
} }
const TTypeList &fields = *type.getStruct(); const TTypeList &fields = *type.getStruct();
......
...@@ -40,8 +40,8 @@ class OutputHLSL : public TIntermTraverser ...@@ -40,8 +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 structureString(const TType &structType, bool useHLSLRowMajorPacking, bool useStd140Packing);
TString structureTypeName(const TType &structType, bool useHLSLRowMajorPacking); TString structureTypeName(const TType &structType, bool useHLSLRowMajorPacking, bool useStd140Packing);
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);
...@@ -193,7 +193,7 @@ class OutputHLSL : public TIntermTraverser ...@@ -193,7 +193,7 @@ class OutputHLSL : public TIntermTraverser
TString decoratePrivate(const TString &privateText); TString decoratePrivate(const TString &privateText);
TString interfaceBlockStructName(const TType &interfaceBlockType); TString interfaceBlockStructName(const TType &interfaceBlockType);
TString interfaceBlockInstanceString(const TType& interfaceBlockType, unsigned int arrayIndex); TString interfaceBlockInstanceString(const TType& interfaceBlockType, unsigned int arrayIndex);
TString interfaceBlockMemberTypeString(const TType &memberType); TString interfaceBlockMemberTypeString(const TType &memberType, TLayoutBlockStorage blockStorage);
TString interfaceBlockMemberString(const TTypeList &typeList, TLayoutBlockStorage blockStorage); TString interfaceBlockMemberString(const TTypeList &typeList, TLayoutBlockStorage blockStorage);
TString interfaceBlockStructString(const TType &interfaceBlockType); TString interfaceBlockStructString(const TType &interfaceBlockType);
TString interfaceBlockString(const TType &interfaceBlockType, unsigned int registerIndex, unsigned int arrayIndex); TString interfaceBlockString(const TType &interfaceBlockType, unsigned int registerIndex, unsigned int arrayIndex);
......
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