Skip to content

Commit f030a5a

Browse files
authored
Properly plumbing layout for global varyings. (#6198)
* Properly plumbing layout for global varyings. * Fix test.
1 parent da3dc98 commit f030a5a

6 files changed

+106
-31
lines changed

source/slang/slang-check-decl.cpp

+21-18
Original file line numberDiff line numberDiff line change
@@ -842,26 +842,29 @@ bool isGlobalShaderParameter(VarDeclBase* decl)
842842
if (!isGlobalDecl(decl))
843843
return false;
844844

845-
// A global variable marked `static` indicates a traditional
846-
// global variable (albeit one that is implicitly local to
847-
// the translation unit)
848-
//
849-
if (decl->hasModifier<HLSLStaticModifier>())
850-
return false;
845+
for (auto modifier : decl->modifiers)
846+
{
847+
// A global variable marked `static` indicates a traditional
848+
// global variable (albeit one that is implicitly local to
849+
// the translation unit)
850+
//
851+
if (as<HLSLStaticModifier>(modifier))
852+
return false;
851853

852-
// While not normally allowed, out variables are not constant
853-
// parameters, this can happen for example in GLSL mode
854-
if (decl->hasModifier<OutModifier>())
855-
return false;
856-
if (decl->hasModifier<InModifier>())
857-
return false;
854+
// While not normally allowed, out variables are not constant
855+
// parameters, this can happen for example in GLSL mode
856+
if (as<OutModifier>(modifier))
857+
return false;
858+
if (as<InModifier>(modifier))
859+
return false;
858860

859-
// The `groupshared` modifier indicates that a variable cannot
860-
// be a shader parameters, but is instead transient storage
861-
// allocated for the duration of a thread-group's execution.
862-
//
863-
if (decl->hasModifier<HLSLGroupSharedModifier>())
864-
return false;
861+
// The `groupshared` modifier indicates that a variable cannot
862+
// be a shader parameters, but is instead transient storage
863+
// allocated for the duration of a thread-group's execution.
864+
//
865+
if (as<HLSLGroupSharedModifier>(modifier))
866+
return false;
867+
}
865868

866869
return true;
867870
}

source/slang/slang-check-shader.cpp

+13-1
Original file line numberDiff line numberDiff line change
@@ -741,7 +741,19 @@ void Module::_collectShaderParams()
741741
// things like `static` globals and `groupshared` variables.
742742
//
743743
if (!isGlobalShaderParameter(globalVar))
744-
continue;
744+
{
745+
bool isVarying = false;
746+
for (auto m : globalVar->modifiers)
747+
{
748+
if (as<InModifier>(m) || as<OutModifier>(m))
749+
{
750+
isVarying = true;
751+
break;
752+
}
753+
}
754+
if (!isVarying)
755+
continue;
756+
}
745757

746758
// At this point we know we have a global shader parameter.
747759

source/slang/slang-ir-translate-glsl-global-var.cpp

+18-11
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,6 @@ struct GlobalVarTranslationContext
8686
IRTypeLayout::Builder fieldTypeLayout(&builder);
8787
IRVarLayout::Builder varLayoutBuilder(&builder, fieldTypeLayout.build());
8888
varLayoutBuilder.setStage(entryPointDecor->getProfile().getStage());
89-
if (auto locationDecoration = input->findDecoration<IRGLSLLocationDecoration>())
90-
{
91-
varLayoutBuilder.findOrAddResourceInfo(LayoutResourceKind::VaryingInput)
92-
->offset = (UInt)getIntVal(locationDecoration->getLocation());
93-
}
9489
if (auto semanticDecor = input->findDecoration<IRSemanticDecoration>())
9590
{
9691
varLayoutBuilder.setSystemValueSemantic(
@@ -102,6 +97,16 @@ struct GlobalVarTranslationContext
10297
fieldTypeLayout.addResourceUsage(
10398
LayoutResourceKind::VaryingInput,
10499
LayoutSize(1));
100+
if (auto layoutDecor = findVarLayout(input))
101+
{
102+
if (auto offsetAttr =
103+
layoutDecor->findOffsetAttr(LayoutResourceKind::VaryingInput))
104+
{
105+
varLayoutBuilder
106+
.findOrAddResourceInfo(LayoutResourceKind::VaryingInput)
107+
->offset = (UInt)offsetAttr->getOffset();
108+
}
109+
}
105110
if (entryPointDecor->getProfile().getStage() == Stage::Fragment)
106111
{
107112
varLayoutBuilder.setUserSemantic("COLOR", inputVarIndex);
@@ -180,13 +185,15 @@ struct GlobalVarTranslationContext
180185
fieldTypeLayout.addResourceUsage(
181186
LayoutResourceKind::VaryingOutput,
182187
LayoutSize(1));
183-
184-
if (auto locationDecoration =
185-
output->findDecoration<IRGLSLLocationDecoration>())
188+
if (auto layoutDecor = findVarLayout(output))
186189
{
187-
varLayoutBuilder
188-
.findOrAddResourceInfo(LayoutResourceKind::VaryingOutput)
189-
->offset = (UInt)getIntVal(locationDecoration->getLocation());
190+
if (auto offsetAttr =
191+
layoutDecor->findOffsetAttr(LayoutResourceKind::VaryingOutput))
192+
{
193+
varLayoutBuilder
194+
.findOrAddResourceInfo(LayoutResourceKind::VaryingOutput)
195+
->offset = (UInt)offsetAttr->getOffset();
196+
}
190197
}
191198
if (entryPointDecor->getProfile().getStage() == Stage::Fragment)
192199
{

source/slang/slang-lower-to-ir.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -12209,7 +12209,9 @@ RefPtr<IRModule> TargetProgram::createIRModuleForLayout(DiagnosticSink* sink)
1220912209
// has been emitted to this module, so that we will have something
1221012210
// to decorate.
1221112211
//
12212-
auto irVar = getSimpleVal(context, ensureDecl(context, varDecl.getDecl()));
12212+
auto irVar = materialize(context, ensureDecl(context, varDecl.getDecl())).val;
12213+
if (!irVar)
12214+
SLANG_UNEXPECTED("unhandled value flavor");
1221312215

1221412216
auto irLayout = lowerVarLayout(context, varLayout);
1221512217

source/slang/slang-parameter-binding.cpp

+28
Original file line numberDiff line numberDiff line change
@@ -712,6 +712,15 @@ RefPtr<TypeLayout> getTypeLayoutForGlobalShaderParameter(
712712
return createTypeLayoutWith(layoutContext, specializationConstantRule, type);
713713
}
714714

715+
if (varDecl->hasModifier<InModifier>())
716+
{
717+
return createTypeLayoutWith(layoutContext, rules->getVaryingInputRules(), type);
718+
}
719+
else if (varDecl->hasModifier<OutModifier>())
720+
{
721+
return createTypeLayoutWith(layoutContext, rules->getVaryingOutputRules(), type);
722+
}
723+
715724
// TODO(tfoley): there may be other cases that we need to handle here
716725

717726
// An "ordinary" global variable is implicitly a uniform
@@ -1120,6 +1129,25 @@ static void addExplicitParameterBindings_GLSL(
11201129
return;
11211130
}
11221131

1132+
if (auto foundVaryingInput = typeLayout->FindResourceInfo(LayoutResourceKind::VaryingInput))
1133+
{
1134+
info[kResInfo].resInfo = foundVaryingInput;
1135+
1136+
if (auto layoutAttr = varDecl.getDecl()->findModifier<GLSLLocationAttribute>())
1137+
info[kResInfo].semanticInfo.index = layoutAttr->value;
1138+
else
1139+
return;
1140+
}
1141+
if (auto foundVaryingOutput = typeLayout->FindResourceInfo(LayoutResourceKind::VaryingOutput))
1142+
{
1143+
info[kResInfo].resInfo = foundVaryingOutput;
1144+
1145+
if (auto layoutAttr = varDecl.getDecl()->findModifier<GLSLLocationAttribute>())
1146+
info[kResInfo].semanticInfo.index = layoutAttr->value;
1147+
else
1148+
return;
1149+
}
1150+
11231151
// For remaining cases, we only want to apply GLSL-style layout modifers
11241152
// when compiling for Khronos and WGSL targets.
11251153
//

tests/glsl/in-layout.slang

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//TEST:SIMPLE(filecheck=CHECK): -target spirv -entry main -stage fragment
2+
3+
// Test that we can mix explicit and implicit locations for global varyings.
4+
5+
#version 450
6+
layout(location=1) in vec4 color_0;
7+
in vec2 texcoord_0;
8+
in vec2 texCoord_1;
9+
10+
out vec4 out1;
11+
12+
// CHECK-DAG: OpDecorate %color_0 Location 1
13+
14+
// CHECK-DAG: OpDecorate %texcoord_0 Location 0
15+
16+
// CHECK-DAG: OpDecorate %texCoord_1 Location 2
17+
18+
// CHECK-DAG: OpDecorate %entryPointParam_main_out1 Location 0
19+
20+
void main()
21+
{
22+
out1 = vec4(color_0.rg, texcoord_0 + texCoord_1);
23+
}

0 commit comments

Comments
 (0)