From b6422e50cb19f7f790f29678ba22f31b0b305511 Mon Sep 17 00:00:00 2001 From: Yong He Date: Tue, 30 Sep 2025 14:13:53 -0700 Subject: Handle getEquivalentStructuredBuffer(castDynamicResource) in byte address legalization pass. (#8567) This is crash that be triggered by providing custom `getDescriptorFromHandle` and use it to return access a ByteAddressBuffer from a bindless handle. Closes #8355. --- source/slang/slang-ir-byte-address-legalize.cpp | 13 ++++++++ .../byte-address-buffer-handle.slang | 38 ++++++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 tests/language-feature/descriptor-handle/byte-address-buffer-handle.slang diff --git a/source/slang/slang-ir-byte-address-legalize.cpp b/source/slang/slang-ir-byte-address-legalize.cpp index baafc7e7f..15cbb6ca0 100644 --- a/source/slang/slang-ir-byte-address-legalize.cpp +++ b/source/slang/slang-ir-byte-address-legalize.cpp @@ -941,6 +941,19 @@ struct ByteAddressBufferLegalizationContext { return getEquivalentStructuredBufferParam(elementType, byteAddressBufferParam); } + else if (auto castDynamicResource = as(byteAddressBuffer)) + { + // If the underlying structured buffer is a CastDynamicResource, + // we can simply cast the dynamic resource into the byte address buffer type instead. + auto arg = castDynamicResource->getOperand(0); + return m_builder.emitIntrinsicInst( + getEquivalentStructuredBufferParamType( + elementType, + byteAddressBuffer->getDataType()), + kIROp_CastDynamicResource, + 1, + &arg); + } if (byteAddressBuffer->getOp() == kIROp_GetElement) { diff --git a/tests/language-feature/descriptor-handle/byte-address-buffer-handle.slang b/tests/language-feature/descriptor-handle/byte-address-buffer-handle.slang new file mode 100644 index 000000000..eccba9723 --- /dev/null +++ b/tests/language-feature/descriptor-handle/byte-address-buffer-handle.slang @@ -0,0 +1,38 @@ +//TEST:SIMPLE(filecheck=CHECK): -target spirv + +// CHECK: OpAccessChain %_ptr_StorageBuffer_RWStructuredBuffer %resourceHandles + +[vk::binding(0, 0)] +__DynamicResource<__DynamicResourceKind.General> resourceHandles[]; + +[vk::binding(0, 1)] +__DynamicResource<__DynamicResourceKind.Sampler> samplerHandles[]; + +export T getDescriptorFromHandle(DescriptorHandle handle) where T : IOpaqueDescriptor +{ + __target_switch + { + case spirv: + if (T.kind == DescriptorKind.Sampler) { + return samplerHandles[((uint2)handle).x].asOpaqueDescriptor(); + } + else { + return resourceHandles[((uint2)handle).x].asOpaqueDescriptor(); + } + default: + return defaultGetDescriptorFromHandle(handle); + } +} + +// test.slang +struct PushConstant +{ + RWByteAddressBuffer.Handle test_buffer; +}; +[[vk::push_constant]] PushConstant constant; + +[shader("fragment")] +void main_test_fs(float2 fragment_coord: SV_Position, out float4 color: SV_Target) +{ + color = float4(constant.test_buffer.Load(0), 1.0); +} -- cgit v1.2.3