summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorJay Kwak <82421531+jkwak-work@users.noreply.github.com>2025-02-19 22:17:30 -0800
committerGitHub <noreply@github.com>2025-02-19 22:17:30 -0800
commit187ec444486ecf24d1baf897d179de4ee1b6b864 (patch)
treefc22e12854f6b3f3aaa6bc1a58656499b836a085 /source
parent0460eb6a0b9e62c3145ab9c43d03751e19a49d8e (diff)
Support for dynamic array of textures access for Texture footprint. (#6392)
* Support for dynamic array of textures access for Texture footprint. * Do a check for DXIL for dynamic array/footprint. * format code (#40) --------- Co-authored-by: jsmall-nvidia <jsmall@nvidia.com> Co-authored-by: slangbot <ellieh+slangbot@nvidia.com> Co-authored-by: Yong He <yonghe@outlook.com>
Diffstat (limited to 'source')
-rw-r--r--source/slang/slang-ir-lower-binding-query.cpp113
1 files changed, 112 insertions, 1 deletions
diff --git a/source/slang/slang-ir-lower-binding-query.cpp b/source/slang/slang-ir-lower-binding-query.cpp
index 0935f1e54..541640aaf 100644
--- a/source/slang/slang-ir-lower-binding-query.cpp
+++ b/source/slang/slang-ir-lower-binding-query.cpp
@@ -288,7 +288,118 @@ struct BindingQueryLoweringContext : public WorkListPass
//
OpaqueValueInfo computeOpaqueValueInfo(IRInst* opaqueValue)
{
- if (auto globalParam = as<IRGlobalParam>(opaqueValue))
+ if (auto getElement = as<IRGetElement>(opaqueValue))
+ {
+ IRInst* baseInst = getElement->getBase();
+ IRInst* indexInst = getElement->getIndex();
+
+ IRInst* elementType = getElement->getDataType();
+
+ // TODO(JS): This a hack to make this work for arrays of resource type.
+ // It won't work in the general case as it stands because we would need
+ // to propogate layout kind types needed at usage sites.
+ // Without knowing the resource kind that is being processed it's not possible
+ // to accumulate the calculation.
+ //
+ // So presumably we need to request a binding query for a specific resource kind.
+ // We could do this by making the type of the binding query hold the type.
+
+ // We need to add instructions which will work out the binding for the base
+ OpaqueValueInfo baseInfo = findOrComputeOpaqueValueInfo(baseInst);
+
+ // If we couldn't find it we are done
+ if (baseInfo.registerIndex == nullptr || baseInfo.registerSpace == nullptr)
+ {
+ return baseInfo;
+ }
+
+
+ LayoutResourceKind kind = LayoutResourceKind::None;
+ Index stride = 1;
+
+ if (auto resourceType = as<IRResourceType>(elementType))
+ {
+ const auto shape = resourceType->getShape();
+
+ switch (shape)
+ {
+ case SLANG_TEXTURE_1D:
+ case SLANG_TEXTURE_2D:
+ case SLANG_TEXTURE_3D:
+ case SLANG_TEXTURE_CUBE:
+ case SLANG_STRUCTURED_BUFFER:
+ case SLANG_BYTE_ADDRESS_BUFFER:
+ case SLANG_TEXTURE_BUFFER:
+ {
+ const auto access = resourceType->getAccess();
+ bool isReadOnly = (access == SLANG_RESOURCE_ACCESS_READ);
+
+ kind = isReadOnly ? LayoutResourceKind::ShaderResource
+ : LayoutResourceKind::UnorderedAccess;
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ else if (as<IRSamplerStateTypeBase>(elementType))
+ {
+ kind = LayoutResourceKind::SamplerState;
+ }
+ else if (as<IRConstantBufferType>(elementType))
+ {
+ kind = LayoutResourceKind::ConstantBuffer;
+ }
+
+ if (kind == LayoutResourceKind::None)
+ {
+ // Can't determine the kind
+ return OpaqueValueInfo();
+ }
+
+ // If the element type has type layout we can try and use that
+ if (auto layoutDecoration = elementType->findDecoration<IRLayoutDecoration>())
+ {
+ // We have to calculate
+ if (auto elementTypeLayout = as<IRTypeLayout>(layoutDecoration->getLayout()))
+ {
+ IRTypeSizeAttr* sizeAttr = elementTypeLayout->findSizeAttr(kind);
+ sizeAttr = sizeAttr ? sizeAttr
+ : elementTypeLayout->findSizeAttr(
+ LayoutResourceKind::DescriptorTableSlot);
+
+ if (!sizeAttr)
+ {
+ // Couldn't work it out
+ return OpaqueValueInfo();
+ }
+
+ // TODO(JS): Perhaps we have to do something else if not finite?
+ stride = sizeAttr->getFiniteSize();
+ }
+ }
+
+ SLANG_UNUSED(indexInst);
+
+ // Okay we need to create an instruction which is
+ // base + stride * index
+
+ IRBuilder builder(module);
+
+ builder.setInsertBefore(opaqueValue);
+
+ auto calcRegisterInst = builder.emitAdd(
+ indexType,
+ builder.emitMul(indexType, builder.getIntValue(indexType, stride), indexInst),
+ baseInfo.registerIndex);
+
+ OpaqueValueInfo finalInfo;
+ finalInfo.registerIndex = calcRegisterInst;
+ finalInfo.registerSpace = baseInfo.registerSpace;
+
+ return finalInfo;
+ }
+ else if (auto globalParam = as<IRGlobalParam>(opaqueValue))
{
// The simple/base case is when we have a global shader
// parameter that has layout information attached.