diff options
| author | cheneym2 <acheney@nvidia.com> | 2025-02-13 19:07:55 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-02-13 16:07:55 -0800 |
| commit | 944c19b408f20e6c5495678028f62e4e7040aa3b (patch) | |
| tree | 9e062c40fc0412c0eee0e4818a9703c5d5e21065 /source/slang | |
| parent | 4c8edd7fbe63100294301a2e210dad21e5263b8a (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.cpp | 87 | ||||
| -rw-r--r-- | source/slang/slang-ir-translate-glsl-global-var.cpp | 33 |
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 |
