From 69cb6e8f300d77e74bd2c7dfe15d12e10b38f512 Mon Sep 17 00:00:00 2001 From: Alexey Panteleev Date: Wed, 18 May 2022 10:57:37 -0700 Subject: Support for querying which parameters are used in emitted code (#2239) See https://github.com/shader-slang/slang/issues/2213 --- source/slang/slang-ir-metadata.cpp | 77 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 source/slang/slang-ir-metadata.cpp (limited to 'source/slang/slang-ir-metadata.cpp') diff --git a/source/slang/slang-ir-metadata.cpp b/source/slang/slang-ir-metadata.cpp new file mode 100644 index 000000000..cc5922e93 --- /dev/null +++ b/source/slang/slang-ir-metadata.cpp @@ -0,0 +1,77 @@ +// slang-ir-metadata.cpp +#include "slang-ir-metadata.h" + +#include "slang-ir.h" +#include "slang-ir-insts.h" + +namespace Slang +{ + +// This file currently implements a pass that collects information about the shader parameters that +// are referenced in the IR. It's named 'metadata' in order to support other potential code +// analysis scenarios in the future. + + +// Inserts a single resource binding (which takes `count` slots, where 0 means unbounded) into the list of resource ranges. +static void _insertBinding(List& ranges, LayoutResourceKind kind, UInt spaceIndex, UInt registerIndex, UInt count) +{ + // Construct a new range from the provided resource. + ShaderBindingRange newRange; + newRange.category = kind; + newRange.spaceIndex = spaceIndex; + newRange.registerIndex = registerIndex; + newRange.registerCount = count; + + // See if the new range is adjacent to any of the existing ranges, merge with that. + for (auto& range : ranges) + { + if (range.adjacentTo(newRange)) + { + range.mergeWith(newRange); + return; + } + } + + // No adjacent ranges found - create a new one. + ranges.add(newRange); +} + +// Collects the metadata from the provided IR module, saves it in outMetadata. +void collectMetadata(const IRModule* irModule, PostEmitMetadata& outMetadata) +{ + // Scan the instructions looking for global resource declarations + for (const auto& inst : irModule->getGlobalInsts()) + { + auto param = as(inst); + if (!param) continue; + + auto layoutDecoration = param->findDecoration(); + if (!layoutDecoration) continue; + + auto varLayout = as(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.usedBindings, kind, spaceIndex, registerIndex, count); + } + } + } +} + + +} -- cgit v1.2.3