summaryrefslogtreecommitdiffstats
path: root/source/slang/emit.cpp
diff options
context:
space:
mode:
authorTim Foley <tfoleyNV@users.noreply.github.com>2018-06-04 15:12:56 -0700
committerGitHub <noreply@github.com>2018-06-04 15:12:56 -0700
commit8b16bbf64a082d30d496453f948f65605e58a014 (patch)
treee9e2e40a31c5bdcf6d6ce3decece5129a25021df /source/slang/emit.cpp
parent698ba86962d10d927d7ac4eb781e05e33f08c9eb (diff)
Emit directives to control matrix layout (#590)
The HLSL/GLSL output by Slang should try to be robust against whatever flags somebody uses to compile it. Therefore, we will go ahead and output a target-language-specific directive to control the default matrix layout mode so that we can override whatever might be specified via flags. Also, as long as we are at it, this change goes ahead and makes Slang unconditionally emit row/column-major layout modifiers on all matrices (and arrays of matrices) whereas before these were only being output sometimes (the code to do it seemed buggy to me...).
Diffstat (limited to 'source/slang/emit.cpp')
-rw-r--r--source/slang/emit.cpp82
1 files changed, 74 insertions, 8 deletions
diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp
index af2fa68dc..e0f71aafe 100644
--- a/source/slang/emit.cpp
+++ b/source/slang/emit.cpp
@@ -979,7 +979,7 @@ struct EmitVisitor
case CodeGenTarget::GLSL_Vulkan_OneDesc:
{
// Need to special case if there is a single element in the vector
- // as there is no such thing in glsl as vec1
+ // as there is no such thing in glsl as vec1
IRInst* elementCountInst = vecType->getElementCount();
if (elementCountInst->op != kIROp_IntLit)
@@ -1914,6 +1914,68 @@ struct EmitVisitor
// TODO: handle other cases...
}
+ /// Emit directives to control overall layout computation for the emitted code.
+ void emitLayoutDirectives(TargetRequest* targetReq)
+ {
+ // We are going to emit the target-language-specific directives
+ // needed to get the default matrix layout to match what was requested
+ // for the given target.
+ //
+ // Note: we do not rely on the defaults for the target language,
+ // because a user could take the HLSL/GLSL generated by Slang and pass
+ // it to another compiler with non-default options specified on
+ // the command line, leading to all kinds of trouble.
+ //
+ // TODO: We need an approach to "global" layout directives that will work
+ // in the presence of multiple modules. If modules A and B were each
+ // compiled with different assumptions about how layout is performed,
+ // then types/variables defined in those modules should be emitted in
+ // a way that is consistent with that layout...
+
+ auto matrixLayoutMode = targetReq->defaultMatrixLayoutMode;
+
+ switch(context->shared->target)
+ {
+ default:
+ return;
+
+ case CodeGenTarget::GLSL:
+ // Reminder: the meaning of row/column major layout
+ // in our semantics is the *opposite* of what GLSL
+ // calls them, because what they call "columns"
+ // are what we call "rows."
+ //
+ switch(matrixLayoutMode)
+ {
+ case kMatrixLayoutMode_RowMajor:
+ default:
+ Emit("layout(column_major) uniform;\n");
+ Emit("layout(column_major) buffer;\n");
+ break;
+
+ case kMatrixLayoutMode_ColumnMajor:
+ Emit("layout(row_major) uniform;\n");
+ Emit("layout(row_major) buffer;\n");
+ break;
+ }
+ break;
+
+ case CodeGenTarget::HLSL:
+ switch(matrixLayoutMode)
+ {
+ case kMatrixLayoutMode_RowMajor:
+ default:
+ Emit("#pragma pack_matrix(row_major)\n");
+ break;
+
+ case kMatrixLayoutMode_ColumnMajor:
+ Emit("#pragma pack_matrix(column_major)\n");
+ break;
+ }
+ break;
+ }
+ }
+
// Utility code for generating unique IDs as needed
// during the emit process (e.g., for declarations
// that didn't origianlly have names, but now need to).
@@ -4611,12 +4673,15 @@ struct EmitVisitor
EmitContext* ctx,
VarLayout* layout)
{
- // We need to handle the case where the variable has
- // a matrix type, and has been given a non-standard
- // layout attribute (for HLSL, `row_major` is the
- // non-standard layout).
+ // When a variable has a matrix type, we want to emit an explicit
+ // layout qualifier based on what the layout has been computed to be.
//
- if (auto matrixTypeLayout = layout->typeLayout.As<MatrixTypeLayout>())
+
+ auto typeLayout = layout->typeLayout;
+ while(auto arrayTypeLayout = typeLayout.As<ArrayTypeLayout>())
+ typeLayout = arrayTypeLayout->elementTypeLayout;
+
+ if (auto matrixTypeLayout = typeLayout.As<MatrixTypeLayout>())
{
auto target = ctx->shared->target;
@@ -4626,7 +4691,6 @@ struct EmitVisitor
switch (matrixTypeLayout->mode)
{
case kMatrixLayoutMode_ColumnMajor:
- if(target == CodeGenTarget::GLSL)
emit("column_major ");
break;
@@ -4645,7 +4709,6 @@ struct EmitVisitor
switch (matrixTypeLayout->mode)
{
case kMatrixLayoutMode_ColumnMajor:
- if(target == CodeGenTarget::GLSL)
emit("layout(row_major)\n");
break;
@@ -5815,6 +5878,9 @@ String emitEntryPoint(
// There may be global-scope modifiers that we should emit now
visitor.emitGLSLPreprocessorDirectives(translationUnitSyntax);
+
+ visitor.emitLayoutDirectives(targetRequest);
+
String prefix = sharedContext.sb.ProduceString();