diff options
| author | Yong He <yonghe@outlook.com> | 2025-01-27 18:17:16 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-01-27 18:17:16 -0800 |
| commit | f030a5ab62235152055fe8a616dd6d0d7ba1c275 (patch) | |
| tree | e4851bd271a04feaa8c3dc9eeb228d3550b9b56e | |
| parent | da3dc98f96cc7be2accb5c6f86aa6f6e5502bada (diff) | |
Properly plumbing layout for global varyings. (#6198)
* Properly plumbing layout for global varyings.
* Fix test.
| -rw-r--r-- | source/slang/slang-check-decl.cpp | 39 | ||||
| -rw-r--r-- | source/slang/slang-check-shader.cpp | 14 | ||||
| -rw-r--r-- | source/slang/slang-ir-translate-glsl-global-var.cpp | 29 | ||||
| -rw-r--r-- | source/slang/slang-lower-to-ir.cpp | 4 | ||||
| -rw-r--r-- | source/slang/slang-parameter-binding.cpp | 28 | ||||
| -rw-r--r-- | tests/glsl/in-layout.slang | 23 |
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 |
