Commit 6a264bed by LoopDawg

HLSL: implement #pragma pack_matrix(layout)

This adds support for #pragma pack_matrix() to the HLSL front end. The pragma sets the default matrix layout for subsequent unqualified matrices in structs or buffers. Explicit qualification overrides the pragma value. Matrix layout is not permitted at the structure level in HLSL, so only leaves which are matrix types can be so qualified. Note that due to the semantic (not layout) difference in first matrix indirections between HLSL and SPIR-V, the sense of row and column major are flipped. That's independent of this PR: just a factor to note. A column_major qualifier appears as a RowMajor member decoration in SPIR-V modules, and vice versa.
parent 7497e7c9
#pragma pack_matrix(row_major)
struct MyBuffer1
{
column_major float4x4 mat1;
row_major float4x4 mat2;
/*floating*/ float4x4 mat3;
};
#pragma pack_matrix(column_major)
struct MyBuffer2
{
column_major float4x4 mat1;
row_major float4x4 mat2;
/*floating*/ float4x4 mat3;
};
#pragma pack_matrix(random_string_foo)
cbuffer Example
{
MyBuffer1 g_MyBuffer1;
MyBuffer2 g_MyBuffer2;
column_major float4x4 mat1a;
};
float4 main() : SV_Target0
{
return
g_MyBuffer1.mat1[0] + g_MyBuffer1.mat2[0] + g_MyBuffer1.mat3[0] +
g_MyBuffer2.mat1[0] + g_MyBuffer2.mat2[0] + g_MyBuffer2.mat3[0];
}
...@@ -195,6 +195,7 @@ INSTANTIATE_TEST_CASE_P( ...@@ -195,6 +195,7 @@ INSTANTIATE_TEST_CASE_P(
{"hlsl.logicalConvert.frag", "main"}, {"hlsl.logicalConvert.frag", "main"},
{"hlsl.logical.unary.frag", "main"}, {"hlsl.logical.unary.frag", "main"},
{"hlsl.loopattr.frag", "main"}, {"hlsl.loopattr.frag", "main"},
{"hlsl.matpack-pragma.frag", "main"},
{"hlsl.mip.operator.frag", "main"}, {"hlsl.mip.operator.frag", "main"},
{"hlsl.mip.negative.frag", "main"}, {"hlsl.mip.negative.frag", "main"},
{"hlsl.mip.negative2.frag", "main"}, {"hlsl.mip.negative2.frag", "main"},
......
...@@ -572,6 +572,28 @@ void HlslParseContext::handlePragma(const TSourceLoc& loc, const TVector<TString ...@@ -572,6 +572,28 @@ void HlslParseContext::handlePragma(const TSourceLoc& loc, const TVector<TString
if (tokens.size() == 0) if (tokens.size() == 0)
return; return;
// These pragmas are case insensitive in HLSL, so we'll compare in lower case.
TVector<TString> lowerTokens = tokens;
for (auto it = lowerTokens.begin(); it != lowerTokens.end(); ++it)
std::transform(it->begin(), it->end(), it->begin(), ::tolower);
// Handle pack_matrix
if (tokens.size() == 4 && lowerTokens[0] == "pack_matrix" && tokens[1] == "(" && tokens[3] == ")") {
// Note that HLSL semantic order is Mrc, not Mcr like SPIR-V, so we reverse the sense.
// Row major becomes column major and vice versa.
if (lowerTokens[2] == "row_major") {
globalUniformDefaults.layoutMatrix = globalBufferDefaults.layoutMatrix = ElmColumnMajor;
} else if (lowerTokens[2] == "column_major") {
globalUniformDefaults.layoutMatrix = globalBufferDefaults.layoutMatrix = ElmRowMajor;
} else {
// unknown majorness strings are treated as (HLSL column major)==(SPIR-V row major)
warn(loc, "unknown pack_matrix pragma value", tokens[2].c_str(), "");
globalUniformDefaults.layoutMatrix = globalBufferDefaults.layoutMatrix = ElmRowMajor;
}
}
} }
// //
...@@ -7176,6 +7198,11 @@ void HlslParseContext::declareStruct(const TSourceLoc& loc, TString& structName, ...@@ -7176,6 +7198,11 @@ void HlslParseContext::declareStruct(const TSourceLoc& loc, TString& structName,
} }
if (newLists.uniform) { if (newLists.uniform) {
newMember(newUniformMember); newMember(newUniformMember);
// inherit default matrix layout (changeable via #pragma pack_matrix), if none given.
if (member->type->isMatrix() && member->type->getQualifier().layoutMatrix == ElmNone)
newUniformMember.type->getQualifier().layoutMatrix = globalUniformDefaults.layoutMatrix;
correctUniform(newUniformMember.type->getQualifier()); correctUniform(newUniformMember.type->getQualifier());
newLists.uniform->push_back(newUniformMember); newLists.uniform->push_back(newUniformMember);
} }
......
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