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 8 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
43 changes: 40 additions & 3 deletions source/slang/slang-ir-glsl-legalize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3275,6 +3275,9 @@ void legalizeEntryPointParameterForGLSL(
ptrType->getAddressSpace() == AddressSpace::Input ||
ptrType->getAddressSpace() == AddressSpace::BuiltinInput);

//DEBUG
// printf("Before global value for varying input:\n");
//pp->getModule()->getModuleInst()->dump();
auto globalValue = createGLSLGlobalVaryings(
context,
codeGenContext,
Expand All @@ -3284,9 +3287,16 @@ void legalizeEntryPointParameterForGLSL(
LayoutResourceKind::VaryingInput,
stage,
pp);

// DEBUG
// Dump IR
//printf("Created global value for varying input:\n");
// pp->getModule()->getModuleInst()->dump();
tryReplaceUsesOfStageInput(context, globalValue, pp);
#if 0
for (auto dec : pp->getDecorations())
{

if (dec->getOp() != kIROp_GlobalVariableShadowingGlobalParameterDecoration)
continue;
auto globalVar = dec->getOperand(0);
Expand All @@ -3298,13 +3308,34 @@ void legalizeEntryPointParameterForGLSL(
{
for (auto elem : tupleVal->elements)
{
if (elem.key == key)
// check if elem is a tuple
if (elem.val.flavor == ScalarizedVal::Flavor::tuple)
{
realGlobalVar = elem.val.irValue;
break;
if (auto tupleVal = as<ScalarizedTupleValImpl>(elem.val.impl))
{
for (auto elem2 : tupleVal->elements)
{
if (elem2.key == key)
{
realGlobalVar = elem2.val.irValue;
break;
}
}
}
}
else
{
if (elem.key == key)
{
realGlobalVar = elem.val.irValue;
break;
}
}
}
}

//if (!realGlobalVar)
// printf("Warning: Could not find real global var for shadowing decoration\n");
SLANG_ASSERT(realGlobalVar);

// Remove all stores into the global var introduced during
Expand All @@ -3331,6 +3362,12 @@ void legalizeEntryPointParameterForGLSL(
globalVar->replaceUsesWith(realGlobalVar);
globalVar->removeAndDeallocate();
}

// Dump IR
//printf("Replaced global accessed with shadow:\n");
//pp->getModule()->getModuleInst()->dump();
//printf("printed\n");
#endif
}
else
{
Expand Down
32 changes: 27 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,25 @@ 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 +111,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 +157,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