summaryrefslogtreecommitdiffstats
path: root/source/slang
diff options
context:
space:
mode:
authorcheneym2 <acheney@nvidia.com>2025-02-13 19:07:55 -0500
committerGitHub <noreply@github.com>2025-02-13 16:07:55 -0800
commit944c19b408f20e6c5495678028f62e4e7040aa3b (patch)
tree9e062c40fc0412c0eee0e4818a9703c5d5e21065 /source/slang
parent4c8edd7fbe63100294301a2e210dad21e5263b8a (diff)
Add support for GLSL interface blocks (#6351)
Adds support for input GLSL interface blocks. closes #5535 Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
Diffstat (limited to 'source/slang')
-rw-r--r--source/slang/slang-ir-glsl-legalize.cpp87
-rw-r--r--source/slang/slang-ir-translate-glsl-global-var.cpp33
2 files changed, 84 insertions, 36 deletions
diff --git a/source/slang/slang-ir-glsl-legalize.cpp b/source/slang/slang-ir-glsl-legalize.cpp
index 3ca441f96..67300dbe6 100644
--- a/source/slang/slang-ir-glsl-legalize.cpp
+++ b/source/slang/slang-ir-glsl-legalize.cpp
@@ -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)
{
@@ -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,
+ [&](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();
}
}
diff --git a/source/slang/slang-ir-translate-glsl-global-var.cpp b/source/slang/slang-ir-translate-glsl-global-var.cpp
index 7b2b8d1ee..80ed3c3e4 100644
--- a/source/slang/slang-ir-translate-glsl-global-var.cpp
+++ b/source/slang/slang-ir-translate-glsl-global-var.cpp
@@ -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>())
{
@@ -94,9 +112,12 @@ struct GlobalVarTranslationContext
}
else
{
- fieldTypeLayout.addResourceUsage(
- LayoutResourceKind::VaryingInput,
- LayoutSize(1));
+ if (!hasExistingLayout)
+ {
+ fieldTypeLayoutBuilder.addResourceUsage(
+ LayoutResourceKind::VaryingInput,
+ LayoutSize(1));
+ }
if (auto layoutDecor = findVarLayout(input))
{
if (auto offsetAttr =
@@ -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