Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for GLSL interface blocks #6351

Merged
merged 18 commits into from
Feb 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 56 additions & 31 deletions source/slang/slang-ir-glsl-legalize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2923,6 +2923,22 @@ void tryReplaceUsesOfStageInput(
fieldVal = element.val;
break;
}
if (auto tupleValType =
as<ScalarizedTupleValImpl>(element.val.impl))
{
for (auto tupleElement : tupleValType->elements)
{
if (tupleElement.key == fieldKey)
{
fieldVal = tupleElement.val;
break;
}
}
}
if (fieldVal.flavor != ScalarizedVal::Flavor::none)
{
break;
}
}
if (fieldVal.flavor != ScalarizedVal::Flavor::none)
{
Expand Down Expand Up @@ -3290,45 +3306,54 @@ void legalizeEntryPointParameterForGLSL(
if (dec->getOp() != kIROp_GlobalVariableShadowingGlobalParameterDecoration)
continue;
auto globalVar = dec->getOperand(0);
auto key = dec->getOperand(1);
IRInst* realGlobalVar = nullptr;
if (globalValue.flavor != ScalarizedVal::Flavor::tuple)
continue;
if (auto tupleVal = as<ScalarizedTupleValImpl>(globalValue.impl))
auto globalVarType = cast<IRPtrTypeBase>(globalVar->getDataType())->getValueType();
if (as<IRStructType>(globalVarType))
{
for (auto elem : tupleVal->elements)
{
if (elem.key == key)
{
realGlobalVar = elem.val.irValue;
break;
}
}
tryReplaceUsesOfStageInput(context, globalValue, globalVar);
}
SLANG_ASSERT(realGlobalVar);
else
{

// Remove all stores into the global var introduced during
// the initial glsl global var translation pass since we are
// going to replace the global var with a pointer to the real
// input, and it makes no sense to store values into such real
// input locations.
traverseUses(
globalVar,
[&](IRUse* use)
auto key = dec->getOperand(1);
IRInst* realGlobalVar = nullptr;
if (globalValue.flavor != ScalarizedVal::Flavor::tuple)
continue;
if (auto tupleVal = as<ScalarizedTupleValImpl>(globalValue.impl))
{
auto user = use->getUser();
if (auto store = as<IRStore>(user))
for (auto elem : tupleVal->elements)
{
if (store->getPtrUse() == use)
if (elem.key == key)
{
store->removeAndDeallocate();
realGlobalVar = elem.val.irValue;
break;
}
}
});
// we will be replacing uses of `globalVarToReplace`. We need
// globalVarToReplaceNextUse to catch the next use before it is removed from the
// list of uses.
globalVar->replaceUsesWith(realGlobalVar);
}
SLANG_ASSERT(realGlobalVar);

// Remove all stores into the global var introduced during
// the initial glsl global var translation pass since we are
// going to replace the global var with a pointer to the real
// input, and it makes no sense to store values into such real
// input locations.
traverseUses(
globalVar,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can also follow uses of any FieldAddr on the globalVar and remove the stores to those field addrs to get rid of the store to _S3 in the test case.

[&](IRUse* use)
{
auto user = use->getUser();
if (auto store = as<IRStore>(user))
{
if (store->getPtrUse() == use)
{
store->removeAndDeallocate();
}
}
});
// we will be replacing uses of `globalVarToReplace`. We need
// globalVarToReplaceNextUse to catch the next use before it is removed from the
// list of uses.
globalVar->replaceUsesWith(realGlobalVar);
}
globalVar->removeAndDeallocate();
}
}
Expand Down
33 changes: 28 additions & 5 deletions source/slang/slang-ir-translate-glsl-global-var.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,26 @@ struct GlobalVarTranslationContext
auto key = builder.createStructKey();
inputKeys.add(key);
builder.createStructField(inputStructType, key, inputType);
IRTypeLayout::Builder fieldTypeLayout(&builder);
IRVarLayout::Builder varLayoutBuilder(&builder, fieldTypeLayout.build());

IRTypeLayout::Builder fieldTypeLayoutBuilder(&builder);
IRTypeLayout* fieldTypeLayout = nullptr;
bool hasExistingLayout = false;
if (auto existingLayoutDecoration = input->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 = input->findDecoration<IRSemanticDecoration>())
{
Expand All @@ -94,9 +112,12 @@ struct GlobalVarTranslationContext
}
else
{
fieldTypeLayout.addResourceUsage(
LayoutResourceKind::VaryingInput,
LayoutSize(1));
if (!hasExistingLayout)
{
fieldTypeLayoutBuilder.addResourceUsage(
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The doubt I was having was about this call to addResourceUsage. I think it doesn't make sense if I'm pulling fieldTypeLayout from IRLayoutDecoration.

LayoutResourceKind::VaryingInput,
LayoutSize(1));
}
if (auto layoutDecor = findVarLayout(input))
{
if (auto offsetAttr =
Expand Down Expand Up @@ -137,6 +158,8 @@ struct GlobalVarTranslationContext
auto input = inputVars[i];
setInsertBeforeOrdinaryInst(&builder, firstBlock->getFirstOrdinaryInst());
auto inputType = cast<IRPtrTypeBase>(input->getDataType())->getValueType();
// TODO: This could be more efficient as a Load(FieldAddress(inputParam, i))
// operation instead of a FieldExtract(Load(inputParam)).
builder.emitStore(
input,
builder
Expand Down
37 changes: 37 additions & 0 deletions tests/glsl/interface-block.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
//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: layout(location = 0)
//CHECK_GLSL: in vec2 vd_texcoord_0_0;

//CHECK_GLSL: layout(location = 1)
//CHECK_GLSL: in vec2 vd_texcoord_1_0;

//CHECK_GLSL: layout(location = 2)
//CHECK_GLSL: in vec4 vd_inner_texcoord_2_0;

import glsl;

#version 400

struct innerData
{
vec4 texcoord_2;
};

in VertexData
{
vec2 texcoord_0;
vec2 texcoord_1;
innerData inner;
} vd;

out vec4 out1;

void fragmentMain()
{
out1 = vec4(vd.texcoord_0, vd.texcoord_1.x, vd.inner.texcoord_2.y);
}

Loading