summaryrefslogtreecommitdiff
path: root/source/slang/slang-ir-metadata.cpp
diff options
context:
space:
mode:
authorAlexey Panteleev <alpanteleev@nvidia.com>2022-05-18 10:57:37 -0700
committerGitHub <noreply@github.com>2022-05-18 10:57:37 -0700
commit69cb6e8f300d77e74bd2c7dfe15d12e10b38f512 (patch)
treec2d23f2883acb28407106a096b55c64111f098b1 /source/slang/slang-ir-metadata.cpp
parent1148564b9cdbbc8fec4fbecf65b0af60aa6af344 (diff)
Support for querying which parameters are used in emitted code (#2239)
See https://github.com/shader-slang/slang/issues/2213
Diffstat (limited to 'source/slang/slang-ir-metadata.cpp')
-rw-r--r--source/slang/slang-ir-metadata.cpp77
1 files changed, 77 insertions, 0 deletions
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<ShaderBindingRange>& 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<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.usedBindings, kind, spaceIndex, registerIndex, count);
+ }
+ }
+ }
+}
+
+
+}