Commit e4075c9c by Jamie Madill Committed by Shannon Woods

Add padding to nested structs packed with standard layout, to address HLSL's…

Add padding to nested structs packed with standard layout, to address HLSL's more liberal packing rules. TRAC #23327 Signed-off-by: Geoff Lang Signed-off-by: Shannon Woods Authored-by: Jamie Madill
parent c835df68
...@@ -323,7 +323,7 @@ TString OutputHLSL::std140PrePaddingString(const TType &type, int *elementIndex) ...@@ -323,7 +323,7 @@ TString OutputHLSL::std140PrePaddingString(const TType &type, int *elementIndex)
return padding; return padding;
} }
TString OutputHLSL::std140PostPaddingString(const TType &type) TString OutputHLSL::std140PostPaddingString(const TType &type, bool useHLSLRowMajorPacking)
{ {
if (!type.isMatrix() && !type.isArray() && type.getBasicType() != EbtStruct) if (!type.isMatrix() && !type.isArray() && type.getBasicType() != EbtStruct)
{ {
...@@ -334,13 +334,25 @@ TString OutputHLSL::std140PostPaddingString(const TType &type) ...@@ -334,13 +334,25 @@ TString OutputHLSL::std140PostPaddingString(const TType &type)
if (type.isMatrix()) if (type.isMatrix())
{ {
const bool isRowMajorMatrix = (type.getLayoutQualifier().matrixPacking == EmpRowMajor); // This method can also be called from structureString, which does not use layout qualifiers.
// Thus, use the method parameter for determining the matrix packing.
//
// Note HLSL row major packing corresponds to GL API column-major, and vice-versa, since we
// wish to always transpose GL matrices to play well with HLSL's matrix array indexing.
//
const bool isRowMajorMatrix = !useHLSLRowMajorPacking;
const GLenum glType = glVariableType(type); const GLenum glType = glVariableType(type);
numComponents = gl::MatrixComponentCount(glType, isRowMajorMatrix); numComponents = gl::MatrixComponentCount(glType, isRowMajorMatrix);
} }
else if (type.getBasicType() == EbtStruct) else if (type.getBasicType() == EbtStruct)
{ {
// TODO const TString &structName = structureTypeName(type, useHLSLRowMajorPacking, true);
numComponents = mStd140StructElementIndexes[structName];
if (numComponents == 0)
{
return "";
}
} }
else else
{ {
...@@ -378,7 +390,8 @@ TString OutputHLSL::interfaceBlockMemberString(const TTypeList &typeList, TLayou ...@@ -378,7 +390,8 @@ TString OutputHLSL::interfaceBlockMemberString(const TTypeList &typeList, TLayou
// 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
if (blockStorage == EbsStd140) if (blockStorage == EbsStd140)
{ {
hlsl += std140PostPaddingString(memberType); const bool useHLSLRowMajorPacking = (memberType.getLayoutQualifier().matrixPacking == EmpColumnMajor);
hlsl += std140PostPaddingString(memberType, useHLSLRowMajorPacking);
} }
} }
...@@ -2928,13 +2941,19 @@ TString OutputHLSL::structureString(const TType &structType, bool useHLSLRowMajo ...@@ -2928,13 +2941,19 @@ TString OutputHLSL::structureString(const TType &structType, bool useHLSLRowMajo
if (useStd140Packing) if (useStd140Packing)
{ {
structure += std140PostPaddingString(field); structure += std140PostPaddingString(field, useHLSLRowMajorPacking);
} }
} }
// 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
structure += (isNameless ? "} " : "};\n"); structure += (isNameless ? "} " : "};\n");
// Add remaining element index to the global map, for use with nested structs in standard layouts
if (useStd140Packing)
{
mStd140StructElementIndexes[structName] = elementIndex;
}
return structure; return structure;
} }
......
...@@ -198,7 +198,7 @@ class OutputHLSL : public TIntermTraverser ...@@ -198,7 +198,7 @@ class OutputHLSL : public TIntermTraverser
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);
TString std140PrePaddingString(const TType &type, int *elementIndex); TString std140PrePaddingString(const TType &type, int *elementIndex);
TString std140PostPaddingString(const TType &type); TString std140PostPaddingString(const TType &type, bool useHLSLRowMajorPacking);
static GLenum glVariableType(const TType &type); static GLenum glVariableType(const TType &type);
static GLenum glVariablePrecision(const TType &type); static GLenum glVariablePrecision(const TType &type);
...@@ -210,6 +210,7 @@ class OutputHLSL : public TIntermTraverser ...@@ -210,6 +210,7 @@ class OutputHLSL : public TIntermTraverser
ActiveInterfaceBlocks mActiveInterfaceBlocks; ActiveInterfaceBlocks mActiveInterfaceBlocks;
ActiveShaderVariables mActiveOutputVariables; ActiveShaderVariables mActiveOutputVariables;
ActiveShaderVariables mActiveAttributes; ActiveShaderVariables mActiveAttributes;
std::map<TString, int> mStd140StructElementIndexes;
}; };
} }
......
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