From 9e34c6d949e97fc87a0a7be4ab37092b586aee9d Mon Sep 17 00:00:00 2001 From: Julius Ikkala Date: Tue, 23 Sep 2025 06:17:01 +0300 Subject: Fix varying output structs in GLSL source (#8501) Closes #8500. `slang-ir-translate-global-varying-var.cpp` turns the global varying outputs into a struct that's returned from the entry point. Currently, there's a problem when one of the outputs is a struct. It always creates a generic `IRTypeLayout`, even when a correct type layout already exists. Somehow, this appears to work when the global varying outputs aren't structs. The crash occurs in `slang-ir-glsl-legalize.cpp:createGLSLGlobalVaryingsImpl()`. It correctly handles the generated outer struct, but when that contains an inner struct, it's been given a non-struct type layout and crashes. This PR uses the correct layout if found, instead of generating a broken placeholder. This matches the behaviour that has already been implemented for inputs. Additionally, I removed a call to `addResourceUsage` from both the input and output side. I can't see any way in which it would've affected anything, the layout builder is never used after that call and it doesn't retroactively modify the layout that was already created. --- .../slang-ir-translate-global-varying-var.cpp | 33 ++++++++++++++-------- 1 file changed, 21 insertions(+), 12 deletions(-) (limited to 'source') diff --git a/source/slang/slang-ir-translate-global-varying-var.cpp b/source/slang/slang-ir-translate-global-varying-var.cpp index c899de653..6b8c4842b 100644 --- a/source/slang/slang-ir-translate-global-varying-var.cpp +++ b/source/slang/slang-ir-translate-global-varying-var.cpp @@ -184,13 +184,6 @@ struct GlobalVarTranslationContext } else { - if (!hasExistingLayout) - { - fieldTypeLayoutBuilder.addResourceUsage( - LayoutResourceKind::VaryingInput, - LayoutSize(1)); - } - // Start off the offset as nextOffset. If the global "in"s have existing // offsetAttr's, we will add the offsets from those as well. auto resInfo = @@ -290,8 +283,27 @@ struct GlobalVarTranslationContext auto key = builder.createStructKey(); auto ptrType = as(output->getDataType()); builder.createStructField(resultType, key, ptrType->getValueType()); - IRTypeLayout::Builder fieldTypeLayout(&builder); - IRVarLayout::Builder varLayoutBuilder(&builder, fieldTypeLayout.build()); + + IRTypeLayout::Builder fieldTypeLayoutBuilder(&builder); + IRTypeLayout* fieldTypeLayout = nullptr; + bool hasExistingLayout = false; + if (auto existingLayoutDecoration = + output->findDecoration()) + { + if (auto existingVarLayout = + as(existingLayoutDecoration->getLayout())) + { + fieldTypeLayout = existingVarLayout->getTypeLayout(); + hasExistingLayout = true; + } + } + + if (!hasExistingLayout) + { + fieldTypeLayout = fieldTypeLayoutBuilder.build(); + } + + IRVarLayout::Builder varLayoutBuilder(&builder, fieldTypeLayout); varLayoutBuilder.setStage(entryPointDecor->getProfile().getStage()); if (auto semanticDecor = output->findDecoration()) { @@ -301,9 +313,6 @@ struct GlobalVarTranslationContext } else { - fieldTypeLayout.addResourceUsage( - LayoutResourceKind::VaryingOutput, - LayoutSize(1)); if (auto layoutDecor = findVarLayout(output)) { if (auto offsetAttr = -- cgit v1.2.3