diff options
| -rw-r--r-- | examples/reflection-api/README.md | 3 | ||||
| -rw-r--r-- | examples/reflection-api/main.cpp | 5 | ||||
| -rw-r--r-- | source/compiler-core/slang-artifact-associated-impl.h | 3 | ||||
| -rw-r--r-- | source/slang/slang-ir-metadata.cpp | 70 | ||||
| -rw-r--r-- | tools/slang-unit-test/unit-test-parameter-usage-reflection.cpp | 21 |
5 files changed, 69 insertions, 33 deletions
diff --git a/examples/reflection-api/README.md b/examples/reflection-api/README.md index 9dc5f1745..f37ec4b69 100644 --- a/examples/reflection-api/README.md +++ b/examples/reflection-api/README.md @@ -4,3 +4,6 @@ Slang Reflection API Example This example shows basic usage of the Slang reflection API to traverse the parameters of a program, including type and layout information. + +This example is a companion Slang reflection API documentation: +https://shader-slang.org/slang/user-guide/compiling.html diff --git a/examples/reflection-api/main.cpp b/examples/reflection-api/main.cpp index 9d773fffd..5c157b797 100644 --- a/examples/reflection-api/main.cpp +++ b/examples/reflection-api/main.cpp @@ -7,9 +7,8 @@ // This example uses the Slang reflection API to travserse the structure // of the parameters of a Slang program and their types. // -// This program is a companion to a document on the Slang reflection API. -// Once that document is published, this paragraph will be updated to -// properly link to that document. +// This program is a companion Slang reflection API documentation: +// https://shader-slang.org/slang/user-guide/compiling.html // // Boilerplate // ----------- diff --git a/source/compiler-core/slang-artifact-associated-impl.h b/source/compiler-core/slang-artifact-associated-impl.h index 8a89f865b..0418b2018 100644 --- a/source/compiler-core/slang-artifact-associated-impl.h +++ b/source/compiler-core/slang-artifact-associated-impl.h @@ -163,6 +163,9 @@ struct ShaderBindingRange case slang::UnorderedAccess: case slang::SamplerState: case slang::DescriptorTableSlot: + case slang::VaryingInput: + case slang::VaryingOutput: + case slang::SpecializationConstant: return true; default: return false; diff --git a/source/slang/slang-ir-metadata.cpp b/source/slang/slang-ir-metadata.cpp index 7f0c82471..7348c06fd 100644 --- a/source/slang/slang-ir-metadata.cpp +++ b/source/slang/slang-ir-metadata.cpp @@ -43,6 +43,41 @@ static void _insertBinding( ranges.add(newRange); } +void collectMetadataFromInst(IRInst* param, ArtifactPostEmitMetadata& outMetadata) +{ + auto layoutDecoration = param->findDecoration<IRLayoutDecoration>(); + if (!layoutDecoration) + return; + + auto varLayout = as<IRVarLayout>(layoutDecoration->getLayout()); + if (!varLayout) + return; + + for (auto sizeAttr : varLayout->getTypeLayout()->getSizeAttrs()) + { + auto kind = sizeAttr->getResourceKind(); + + // Only track resource types that we can reliably track, such as textures. + // Do not track individual uniforms, for example. + if (!ShaderBindingRange::isUsageTracked(kind)) + continue; + + if (auto offsetAttr = varLayout->findOffsetAttr(kind)) + { + // Get the binding information from this attribute and insert it into the list + auto spaceIndex = offsetAttr->getSpace(); + if (auto spaceAttr = varLayout->findOffsetAttr(LayoutResourceKind::RegisterSpace)) + { + spaceIndex += spaceAttr->getOffset(); + } + auto registerIndex = offsetAttr->getOffset(); + auto size = sizeAttr->getSize(); + auto count = size.isFinite() ? size.getFiniteValue() : 0; + _insertBinding(outMetadata.m_usedBindings, kind, spaceIndex, registerIndex, count); + } + } +} + // Collects the metadata from the provided IR module, saves it in outMetadata. void collectMetadata(const IRModule* irModule, ArtifactPostEmitMetadata& outMetadata) { @@ -57,39 +92,18 @@ void collectMetadata(const IRModule* irModule, ArtifactPostEmitMetadata& outMeta auto name = func->findDecoration<IRExportDecoration>()->getMangledName(); outMetadata.m_exportedFunctionMangledNames.add(name); } + + // Collect metadata from entrypoint params. + for (auto param : func->getParams()) + { + collectMetadataFromInst(param, outMetadata); + } } auto param = as<IRGlobalParam>(inst); if (!param) continue; - - auto layoutDecoration = param->findDecoration<IRLayoutDecoration>(); - if (!layoutDecoration) - continue; - - auto varLayout = as<IRVarLayout>(layoutDecoration->getLayout()); - if (!varLayout) - continue; - - for (auto sizeAttr : varLayout->getTypeLayout()->getSizeAttrs()) - { - auto kind = sizeAttr->getResourceKind(); - - // Only track resource types that we can reliably track, such as textures. - // Do not track individual uniforms, for example. - if (!ShaderBindingRange::isUsageTracked(kind)) - continue; - - if (auto offsetAttr = varLayout->findOffsetAttr(kind)) - { - // Get the binding information from this attribute and insert it into the list - auto spaceIndex = offsetAttr->getSpace(); - auto registerIndex = offsetAttr->getOffset(); - auto size = sizeAttr->getSize(); - auto count = size.isFinite() ? size.getFiniteValue() : 0; - _insertBinding(outMetadata.m_usedBindings, kind, spaceIndex, registerIndex, count); - } - } + collectMetadataFromInst(param, outMetadata); } } diff --git a/tools/slang-unit-test/unit-test-parameter-usage-reflection.cpp b/tools/slang-unit-test/unit-test-parameter-usage-reflection.cpp index ce9df5a42..e4a89a277 100644 --- a/tools/slang-unit-test/unit-test-parameter-usage-reflection.cpp +++ b/tools/slang-unit-test/unit-test-parameter-usage-reflection.cpp @@ -18,10 +18,15 @@ SLANG_UNIT_TEST(isParameterLocationUsedReflection) // Source for a module that contains an undecorated entrypoint. const char* userSourceBody = R"( Texture2D g_tex : register(t0); + struct Params { + Texture2D tex2; + Texture2D tex3; + }; + ParameterBlock<Params> gParams; [shader("fragment")] - float4 fragMain(float4 pos:SV_Position) : SV_Target + float4 fragMain(float4 pos:SV_Position, float unused:COLOR0, float4 used:COLOR1) : SV_Target { - return g_tex.Load(int3(0, 0, 0)); + return g_tex.Load(int3(0, 0, 0)) + gParams.tex3.Load(int3(0)) + used; } )"; @@ -75,4 +80,16 @@ SLANG_UNIT_TEST(isParameterLocationUsedReflection) metadata->isParameterLocationUsed(SLANG_PARAMETER_CATEGORY_DESCRIPTOR_TABLE_SLOT, 0, 1, isUsed); SLANG_CHECK(!isUsed); + + metadata->isParameterLocationUsed(SLANG_PARAMETER_CATEGORY_DESCRIPTOR_TABLE_SLOT, 1, 0, isUsed); + SLANG_CHECK(!isUsed); + + metadata->isParameterLocationUsed(SLANG_PARAMETER_CATEGORY_DESCRIPTOR_TABLE_SLOT, 1, 1, isUsed); + SLANG_CHECK(isUsed); + + metadata->isParameterLocationUsed(SLANG_PARAMETER_CATEGORY_VARYING_INPUT, 0, 0, isUsed); + SLANG_CHECK(!isUsed); + + metadata->isParameterLocationUsed(SLANG_PARAMETER_CATEGORY_VARYING_INPUT, 0, 1, isUsed); + SLANG_CHECK(isUsed); } |
