summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2025-01-27 18:17:16 -0800
committerGitHub <noreply@github.com>2025-01-27 18:17:16 -0800
commitf030a5ab62235152055fe8a616dd6d0d7ba1c275 (patch)
treee4851bd271a04feaa8c3dc9eeb228d3550b9b56e
parentda3dc98f96cc7be2accb5c6f86aa6f6e5502bada (diff)
Properly plumbing layout for global varyings. (#6198)
* Properly plumbing layout for global varyings. * Fix test.
-rw-r--r--source/slang/slang-check-decl.cpp39
-rw-r--r--source/slang/slang-check-shader.cpp14
-rw-r--r--source/slang/slang-ir-translate-glsl-global-var.cpp29
-rw-r--r--source/slang/slang-lower-to-ir.cpp4
-rw-r--r--source/slang/slang-parameter-binding.cpp28
-rw-r--r--tests/glsl/in-layout.slang23
6 files changed, 106 insertions, 31 deletions
diff --git a/source/slang/slang-check-decl.cpp b/source/slang/slang-check-decl.cpp
index 3453d0538..33319ca8f 100644
--- a/source/slang/slang-check-decl.cpp
+++ b/source/slang/slang-check-decl.cpp
@@ -842,26 +842,29 @@ bool isGlobalShaderParameter(VarDeclBase* decl)
if (!isGlobalDecl(decl))
return false;
- // A global variable marked `static` indicates a traditional
- // global variable (albeit one that is implicitly local to
- // the translation unit)
- //
- if (decl->hasModifier<HLSLStaticModifier>())
- return false;
+ for (auto modifier : decl->modifiers)
+ {
+ // A global variable marked `static` indicates a traditional
+ // global variable (albeit one that is implicitly local to
+ // the translation unit)
+ //
+ if (as<HLSLStaticModifier>(modifier))
+ return false;
- // While not normally allowed, out variables are not constant
- // parameters, this can happen for example in GLSL mode
- if (decl->hasModifier<OutModifier>())
- return false;
- if (decl->hasModifier<InModifier>())
- return false;
+ // While not normally allowed, out variables are not constant
+ // parameters, this can happen for example in GLSL mode
+ if (as<OutModifier>(modifier))
+ return false;
+ if (as<InModifier>(modifier))
+ return false;
- // The `groupshared` modifier indicates that a variable cannot
- // be a shader parameters, but is instead transient storage
- // allocated for the duration of a thread-group's execution.
- //
- if (decl->hasModifier<HLSLGroupSharedModifier>())
- return false;
+ // The `groupshared` modifier indicates that a variable cannot
+ // be a shader parameters, but is instead transient storage
+ // allocated for the duration of a thread-group's execution.
+ //
+ if (as<HLSLGroupSharedModifier>(modifier))
+ return false;
+ }
return true;
}
diff --git a/source/slang/slang-check-shader.cpp b/source/slang/slang-check-shader.cpp
index c9e190469..d04c72e15 100644
--- a/source/slang/slang-check-shader.cpp
+++ b/source/slang/slang-check-shader.cpp
@@ -741,7 +741,19 @@ void Module::_collectShaderParams()
// things like `static` globals and `groupshared` variables.
//
if (!isGlobalShaderParameter(globalVar))
- continue;
+ {
+ bool isVarying = false;
+ for (auto m : globalVar->modifiers)
+ {
+ if (as<InModifier>(m) || as<OutModifier>(m))
+ {
+ isVarying = true;
+ break;
+ }
+ }
+ if (!isVarying)
+ continue;
+ }
// At this point we know we have a global shader parameter.
diff --git a/source/slang/slang-ir-translate-glsl-global-var.cpp b/source/slang/slang-ir-translate-glsl-global-var.cpp
index 077cdb98d..7b2b8d1ee 100644
--- a/source/slang/slang-ir-translate-glsl-global-var.cpp
+++ b/source/slang/slang-ir-translate-glsl-global-var.cpp
@@ -86,11 +86,6 @@ struct GlobalVarTranslationContext
IRTypeLayout::Builder fieldTypeLayout(&builder);
IRVarLayout::Builder varLayoutBuilder(&builder, fieldTypeLayout.build());
varLayoutBuilder.setStage(entryPointDecor->getProfile().getStage());
- if (auto locationDecoration = input->findDecoration<IRGLSLLocationDecoration>())
- {
- varLayoutBuilder.findOrAddResourceInfo(LayoutResourceKind::VaryingInput)
- ->offset = (UInt)getIntVal(locationDecoration->getLocation());
- }
if (auto semanticDecor = input->findDecoration<IRSemanticDecoration>())
{
varLayoutBuilder.setSystemValueSemantic(
@@ -102,6 +97,16 @@ struct GlobalVarTranslationContext
fieldTypeLayout.addResourceUsage(
LayoutResourceKind::VaryingInput,
LayoutSize(1));
+ if (auto layoutDecor = findVarLayout(input))
+ {
+ if (auto offsetAttr =
+ layoutDecor->findOffsetAttr(LayoutResourceKind::VaryingInput))
+ {
+ varLayoutBuilder
+ .findOrAddResourceInfo(LayoutResourceKind::VaryingInput)
+ ->offset = (UInt)offsetAttr->getOffset();
+ }
+ }
if (entryPointDecor->getProfile().getStage() == Stage::Fragment)
{
varLayoutBuilder.setUserSemantic("COLOR", inputVarIndex);
@@ -180,13 +185,15 @@ struct GlobalVarTranslationContext
fieldTypeLayout.addResourceUsage(
LayoutResourceKind::VaryingOutput,
LayoutSize(1));
-
- if (auto locationDecoration =
- output->findDecoration<IRGLSLLocationDecoration>())
+ if (auto layoutDecor = findVarLayout(output))
{
- varLayoutBuilder
- .findOrAddResourceInfo(LayoutResourceKind::VaryingOutput)
- ->offset = (UInt)getIntVal(locationDecoration->getLocation());
+ if (auto offsetAttr =
+ layoutDecor->findOffsetAttr(LayoutResourceKind::VaryingOutput))
+ {
+ varLayoutBuilder
+ .findOrAddResourceInfo(LayoutResourceKind::VaryingOutput)
+ ->offset = (UInt)offsetAttr->getOffset();
+ }
}
if (entryPointDecor->getProfile().getStage() == Stage::Fragment)
{
diff --git a/source/slang/slang-lower-to-ir.cpp b/source/slang/slang-lower-to-ir.cpp
index a12a09a2b..7281b55be 100644
--- a/source/slang/slang-lower-to-ir.cpp
+++ b/source/slang/slang-lower-to-ir.cpp
@@ -12209,7 +12209,9 @@ RefPtr<IRModule> TargetProgram::createIRModuleForLayout(DiagnosticSink* sink)
// has been emitted to this module, so that we will have something
// to decorate.
//
- auto irVar = getSimpleVal(context, ensureDecl(context, varDecl.getDecl()));
+ auto irVar = materialize(context, ensureDecl(context, varDecl.getDecl())).val;
+ if (!irVar)
+ SLANG_UNEXPECTED("unhandled value flavor");
auto irLayout = lowerVarLayout(context, varLayout);
diff --git a/source/slang/slang-parameter-binding.cpp b/source/slang/slang-parameter-binding.cpp
index 825e0f4af..55c487e4e 100644
--- a/source/slang/slang-parameter-binding.cpp
+++ b/source/slang/slang-parameter-binding.cpp
@@ -712,6 +712,15 @@ RefPtr<TypeLayout> getTypeLayoutForGlobalShaderParameter(
return createTypeLayoutWith(layoutContext, specializationConstantRule, type);
}
+ if (varDecl->hasModifier<InModifier>())
+ {
+ return createTypeLayoutWith(layoutContext, rules->getVaryingInputRules(), type);
+ }
+ else if (varDecl->hasModifier<OutModifier>())
+ {
+ return createTypeLayoutWith(layoutContext, rules->getVaryingOutputRules(), type);
+ }
+
// TODO(tfoley): there may be other cases that we need to handle here
// An "ordinary" global variable is implicitly a uniform
@@ -1120,6 +1129,25 @@ static void addExplicitParameterBindings_GLSL(
return;
}
+ if (auto foundVaryingInput = typeLayout->FindResourceInfo(LayoutResourceKind::VaryingInput))
+ {
+ info[kResInfo].resInfo = foundVaryingInput;
+
+ if (auto layoutAttr = varDecl.getDecl()->findModifier<GLSLLocationAttribute>())
+ info[kResInfo].semanticInfo.index = layoutAttr->value;
+ else
+ return;
+ }
+ if (auto foundVaryingOutput = typeLayout->FindResourceInfo(LayoutResourceKind::VaryingOutput))
+ {
+ info[kResInfo].resInfo = foundVaryingOutput;
+
+ if (auto layoutAttr = varDecl.getDecl()->findModifier<GLSLLocationAttribute>())
+ info[kResInfo].semanticInfo.index = layoutAttr->value;
+ else
+ return;
+ }
+
// For remaining cases, we only want to apply GLSL-style layout modifers
// when compiling for Khronos and WGSL targets.
//
diff --git a/tests/glsl/in-layout.slang b/tests/glsl/in-layout.slang
new file mode 100644
index 000000000..651948c69
--- /dev/null
+++ b/tests/glsl/in-layout.slang
@@ -0,0 +1,23 @@
+//TEST:SIMPLE(filecheck=CHECK): -target spirv -entry main -stage fragment
+
+// Test that we can mix explicit and implicit locations for global varyings.
+
+#version 450
+layout(location=1) in vec4 color_0;
+in vec2 texcoord_0;
+in vec2 texCoord_1;
+
+out vec4 out1;
+
+// CHECK-DAG: OpDecorate %color_0 Location 1
+
+// CHECK-DAG: OpDecorate %texcoord_0 Location 0
+
+// CHECK-DAG: OpDecorate %texCoord_1 Location 2
+
+// CHECK-DAG: OpDecorate %entryPointParam_main_out1 Location 0
+
+void main()
+{
+ out1 = vec4(color_0.rg, texcoord_0 + texCoord_1);
+} \ No newline at end of file