summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJulius Ikkala <julius.ikkala@gmail.com>2025-09-23 06:17:01 +0300
committerGitHub <noreply@github.com>2025-09-23 03:17:01 +0000
commit9e34c6d949e97fc87a0a7be4ab37092b586aee9d (patch)
treedee1891fc3e5a2e0633d8d367747b932d9bf9922
parentc35b763f811298a6e9c61a4a8eaf805ea98bd608 (diff)
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.
-rw-r--r--source/slang/slang-ir-translate-global-varying-var.cpp33
-rw-r--r--tests/glsl/interface-block.glsl14
2 files changed, 32 insertions, 15 deletions
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<IRPtrTypeBase>(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<IRLayoutDecoration>())
+ {
+ if (auto existingVarLayout =
+ as<IRVarLayout>(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<IRSemanticDecoration>())
{
@@ -301,9 +313,6 @@ struct GlobalVarTranslationContext
}
else
{
- fieldTypeLayout.addResourceUsage(
- LayoutResourceKind::VaryingOutput,
- LayoutSize(1));
if (auto layoutDecor = findVarLayout(output))
{
if (auto offsetAttr =
diff --git a/tests/glsl/interface-block.glsl b/tests/glsl/interface-block.glsl
index 3d18db6c7..8378de7bf 100644
--- a/tests/glsl/interface-block.glsl
+++ b/tests/glsl/interface-block.glsl
@@ -1,7 +1,10 @@
//TEST:SIMPLE(filecheck=CHECK_GLSL): -target glsl -stage fragment -entry fragmentMain -allow-glsl
//CHECK_GLSL: layout(location = 0)
-//CHECK_GLSL: out vec4 entryPointParam_fragmentMain_out1_0;
+//CHECK_GLSL: out vec4 entryPointParam_fragmentMain_cd_out1_0;
+
+//CHECK_GLSL: layout(location = 1)
+//CHECK_GLSL: out vec4 entryPointParam_fragmentMain_cd_out2_0;
//CHECK_GLSL: layout(location = 0)
//CHECK_GLSL: in vec2 vd_texcoord_0_0;
@@ -28,10 +31,15 @@ in VertexData
innerData inner;
} vd;
-out vec4 out1;
+out ColorData
+{
+ vec4 out1;
+ vec4 out2;
+} cd;
void fragmentMain()
{
- out1 = vec4(vd.texcoord_0, vd.texcoord_1.x, vd.inner.texcoord_2.y);
+ cd.out1 = vec4(vd.texcoord_0, vd.texcoord_1.x, vd.inner.texcoord_2.y);
+ cd.out2 = vec4(vd.texcoord_1, vd.texcoord_0.x, vd.inner.texcoord_2.y);
}