diff options
| author | ArielG-NV <159081215+ArielG-NV@users.noreply.github.com> | 2025-05-16 11:57:17 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-05-16 18:57:17 +0000 |
| commit | 0244c96d637f47fa264d441a82d3dca78889373b (patch) | |
| tree | 86bf0a8922ebdfd727494bc06e3069df464fe682 /tests | |
| parent | 0651ffb6489282f0f902ec5f630821a7b9d848bb (diff) | |
Fix correct bindings for bindless resource model [SPIRV and GLSL] (#7131)
Fix correct bindings for bindless resource model [spirv and glsl]
fixes: #6952
Problem:
* Currently all bindless objects are placed in the same set (fine) and same binding (incorrect behavior for vulkan). This is incorrect since as per [spec](https://registry.khronos.org/vulkan/specs/latest/man/html/VkDescriptorType.html), only 1 resource type may be written to each index inside a set (these rules are loosened with VK_EXT_mutable_descriptor_type)
* This means currently generated bindings do not work in practice if we (for example) use `Sampler2D.Handle` and `Texture1D.Handle` in a shader since we would place 2 incompatible objects in the same binding-index and set.
Solution:
* `__getDynamicResourceHeap` was modified to allow bindings to chosen dynamically for a descriptor
* use `IOpaqueDescriptor` to check compile-time information of resource types so that we can identify different resources
* Using this information of `IOpaqueDescriptor`, we modify `defaultGetDescriptorFromHandle` to provide a binding model (1 resource per binding-index) which produces legal spirv/glsl.
* To support `VK_EXT_mutable_descriptor_type` the function `defaultGetDescriptorFromHandle` has a set of options (`BindlessDescriptorOptions`) for a user to pick-from to support their binding model. Capabilities are not used here for flexibility purposes (specifically old shaders mixed with modern vulkan extensions).
Other changes:
* Added `TexelBuffer` DescriptorKind to aid in generating correct bindings
* format code
* Add to docs bindless changes, make AccelerationStructure use its handle directly, adjust tests accordingly
---------
Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
Diffstat (limited to 'tests')
3 files changed, 239 insertions, 1 deletions
diff --git a/tests/language-feature/descriptor-handle/desc-handle-2.slang b/tests/language-feature/descriptor-handle/desc-handle-2.slang index fa7f73b31..f9eb02cbe 100644 --- a/tests/language-feature/descriptor-handle/desc-handle-2.slang +++ b/tests/language-feature/descriptor-handle/desc-handle-2.slang @@ -1,6 +1,6 @@ //TEST:SIMPLE(filecheck=SPV): -target spirv -bindless-space-index 101 -// SPV: OpDecorate %__slang_resource_heap{{.*}} Binding 0 +// SPV: OpDecorate %__slang_resource_heap{{.*}} Binding 1 // SPV: OpDecorate %__slang_resource_heap{{.*}} DescriptorSet 101 // SPV: OpImageSample diff --git a/tests/language-feature/descriptor-handle/desc-handle-default.slang b/tests/language-feature/descriptor-handle/desc-handle-default.slang new file mode 100644 index 000000000..d442fb610 --- /dev/null +++ b/tests/language-feature/descriptor-handle/desc-handle-default.slang @@ -0,0 +1,159 @@ +//TEST:SIMPLE(filecheck=SAMPLER): -target spirv -stage compute -entry computeMain -DSAMPLER +//TEST:SIMPLE(filecheck=COMBINED_IMAGE_SAMPLER): -target spirv -stage compute -entry computeMain -DCOMBINED_IMAGE_SAMPLER +//TEST:SIMPLE(filecheck=SAMPLED_IMAGE): -target spirv -stage compute -entry computeMain -DSAMPLED_IMAGE +//TEST:SIMPLE(filecheck=STORAGE_IMAGE): -target spirv -stage compute -entry computeMain -DSTORAGE_IMAGE +//TEST:SIMPLE(filecheck=UNIFORM_TEXEL_BUFFER): -target spirv -stage compute -entry computeMain -DUNIFORM_TEXEL_BUFFER +//TEST:SIMPLE(filecheck=STORAGE_TEXEL_BUFFER): -target spirv -stage compute -entry computeMain -DSTORAGE_TEXEL_BUFFER +//TEST:SIMPLE(filecheck=UNIFORM_BUFFER): -target spirv -stage compute -entry computeMain -DUNIFORM_BUFFER +//TEST:SIMPLE(filecheck=STORAGE_BUFFER): -target spirv -stage compute -entry computeMain -DSTORAGE_BUFFER +//TEST:SIMPLE(filecheck=ACCELERATION_STRUCTURE): -target spirv -stage compute -entry computeMain -DACCELERATION_STRUCTURE +//TEST:SIMPLE(filecheck=SAMPLED_IMAGE): -target spirv -stage compute -entry computeMain -DSAMPLED_IMAGE +//TEST:SIMPLE(filecheck=MIX): -target spirv -stage compute -entry computeMain -DSAMPLER -DSTORAGE_TEXEL_BUFFER -DUNIFORM_BUFFER -DACCELERATION_STRUCTURE + +// To intentionally fill up binding slots +[[vk::binding(0, 1)]] +RWTexture1D<float> t1; + +[[vk::binding(0, 2)]] +RWTexture1D<float> t2; + +[[vk::binding(0, 4)]] +RWTexture1D<float> t3; + +[[vk::binding(1, 4)]] +Texture1D<float> t4; + +//MIX-DAG: OpDecorate %__slang_resource_heap{{.*}} Binding 0 +//MIX-DAG: OpDecorate %__slang_resource_heap{{.*}} Binding 5 +//MIX-DAG: OpDecorate %__slang_resource_heap{{.*}} Binding 6 + +//MIX-NOT: OpDecorate %__slang_resource_heap{{.*}} Binding 1 +//MIX-NOT: OpDecorate %__slang_resource_heap{{.*}} Binding 2 +//MIX-NOT: OpDecorate %__slang_resource_heap{{.*}} Binding 3 +//MIX-NOT: OpDecorate %__slang_resource_heap{{.*}} Binding 4 +//MIX-NOT: OpDecorate %__slang_resource_heap{{.*}} Binding 7 +//MIX-NOT: OpDecorate %__slang_resource_heap{{.*}} Binding 8 + +#ifdef SAMPLER +//SAMPLER: OpDecorate %__slang_resource_heap{{.*}} Binding 0 +//SAMPLER-NEXT: OpDecorate %__slang_resource_heap{{.*}} DescriptorSet 3 + +//SAMPLER-NOT: OpDecorate %__slang_resource_heap{{.*}} Binding 1 +//SAMPLER-NOT: OpDecorate %__slang_resource_heap{{.*}} Binding 2 +//SAMPLER-NOT: OpDecorate %__slang_resource_heap{{.*}} Binding 3 +//SAMPLER-NOT: OpDecorate %__slang_resource_heap{{.*}} Binding 4 +//SAMPLER-NOT: OpDecorate %__slang_resource_heap{{.*}} Binding 5 +//SAMPLER-NOT: OpDecorate %__slang_resource_heap{{.*}} Binding 6 +//SAMPLER-NOT: OpDecorate %__slang_resource_heap{{.*}} Binding 7 +//SAMPLER-NOT: OpDecorate %__slang_resource_heap{{.*}} Binding 8 +uniform SamplerState.Handle sampler; +#endif + +#ifdef COMBINED_IMAGE_SAMPLER +//COMBINED_IMAGE_SAMPLER: OpDecorate %__slang_resource_heap{{.*}} Binding 1 +//COMBINED_IMAGE_SAMPLER-NEXT: OpDecorate %__slang_resource_heap{{.*}} DescriptorSet 3 +uniform Sampler1DShadow.Handle combinedSampler; +#endif + +#ifdef SAMPLED_IMAGE +//SAMPLED_IMAGE: OpDecorate %__slang_resource_heap{{.*}} Binding 2 +//SAMPLED_IMAGE-NEXT: OpDecorate %__slang_resource_heap{{.*}} DescriptorSet 3 +uniform Texture1D<float>.Handle texture; +#endif + +#ifdef STORAGE_IMAGE +//STORAGE_IMAGE: OpDecorate %__slang_resource_heap{{.*}} Binding 3 +//STORAGE_IMAGE-NEXT: OpDecorate %__slang_resource_heap{{.*}} DescriptorSet 3 +uniform RWTexture1D<float>.Handle rwTexture1; +uniform RWTexture2D<float>.Handle rwTexture2; +#endif + +#ifdef UNIFORM_TEXEL_BUFFER +//UNIFORM_TEXEL_BUFFER: OpDecorate %__slang_resource_heap{{.*}} Binding 4 +//UNIFORM_TEXEL_BUFFER-NEXT: OpDecorate %__slang_resource_heap{{.*}} DescriptorSet 3 +uniform Buffer<float>.Handle texelBuffer; +#endif + +#ifdef STORAGE_TEXEL_BUFFER +//STORAGE_TEXEL_BUFFER: OpDecorate %__slang_resource_heap{{.*}} Binding 5 +//STORAGE_TEXEL_BUFFER-NEXT: OpDecorate %__slang_resource_heap{{.*}} DescriptorSet 3 +uniform RWBuffer<float>.Handle rwTexelBuffer; +#endif + +#ifdef UNIFORM_BUFFER +//UNIFORM_BUFFER: OpDecorate %__slang_resource_heap{{.*}} Binding 6 +//UNIFORM_BUFFER-NEXT: OpDecorate %__slang_resource_heap{{.*}} DescriptorSet 3 +struct Data +{ + float v; +} +uniform ConstantBuffer<Data>.Handle buffer1; +uniform StructuredBuffer<float>.Handle buffer2; +#endif + +#ifdef STORAGE_BUFFER +//STORAGE_BUFFER: OpDecorate %__slang_resource_heap{{.*}} Binding 7 +//STORAGE_BUFFER-NEXT: OpDecorate %__slang_resource_heap{{.*}} DescriptorSet 3 +uniform RWStructuredBuffer<float>.Handle rwBuffer; +#endif + +#ifdef ACCELERATION_STRUCTURE +//ACCELERATION_STRUCTURE-NOT: OpDecorate %__slang_resource_heap{{.*}} Binding 8 +//ACCELERATION_STRUCTURE: OpConvertUToAccelerationStructureKHR +uniform RaytracingAccelerationStructure.Handle rayAcceleration; +#endif + +[shader("compute")] +void computeMain() +{ + + t1[0] = t2[0] + t2[0] + t4[0]; + +#ifdef SAMPLER + t1[2] = t4.Sample(sampler, 0); +#endif + +#ifdef COMBINED_IMAGE_SAMPLER + t1[8] = combinedSampler.Sample(0); +#endif + +#ifdef SAMPLED_IMAGE + t1[0] = texture[0]; +#endif + +#ifdef STORAGE_IMAGE + t1[11] = rwTexture1[0]; + t1[12] = rwTexture2[0]; +#endif + +#ifdef UNIFORM_TEXEL_BUFFER + t1[10] = texelBuffer[0]; +#endif + +#ifdef STORAGE_TEXEL_BUFFER + t1[9] = rwTexelBuffer[0]; +#endif + +#ifdef UNIFORM_BUFFER + t1[4] = (*buffer1).v; + t1[6] = buffer2[0]; +#endif + +#ifdef STORAGE_BUFFER + t1[0] += rwBuffer[0]; +#endif + +#ifdef ACCELERATION_STRUCTURE + RayDesc ray; + ray.Origin = float3(0.1f, 0.1f, 0.0f); + ray.Direction = float3(0.0f, 0.0f, 1.0f); + ray.TMin = 0.0f; + ray.TMax = 100.0f; + RayQuery<RAY_FLAG_FORCE_NON_OPAQUE> rq; + rq.TraceRayInline(rayAcceleration, RAY_FLAG_FORCE_NON_OPAQUE, 0xff, ray); + bool proceed = rq.Proceed(); + rq.CommitNonOpaqueTriangleHit(); + rq.Abort(); + t1[13] = (float)rq.RayFlags(); +#endif +}
\ No newline at end of file diff --git a/tests/language-feature/descriptor-handle/desc-handle-vk-mutable-descriptor.slang b/tests/language-feature/descriptor-handle/desc-handle-vk-mutable-descriptor.slang new file mode 100644 index 000000000..8fc2d3283 --- /dev/null +++ b/tests/language-feature/descriptor-handle/desc-handle-vk-mutable-descriptor.slang @@ -0,0 +1,79 @@ +//TEST:SIMPLE(filecheck=CHECK): -target spirv -stage compute -entry computeMain + +// To intentionally fill up binding slots +[[vk::binding(0, 1)]] +RWTexture1D<float> t1; + +[[vk::binding(0, 2)]] +RWTexture1D<float> t2; + +[[vk::binding(0, 4)]] +RWTexture1D<float> t3; + +[[vk::binding(1, 4)]] +Texture1D<float> t4; + +//CHECK-DAG: OpDecorate %__slang_resource_heap{{.*}} Binding 0 +//CHECK-DAG: OpDecorate %__slang_resource_heap{{.*}} Binding 1 +//CHECK-DAG: OpDecorate %__slang_resource_heap{{.*}} Binding 2 +//CHECK-DAG: OpConvertUToAccelerationStructureKHR + +//CHECK-NOT: OpDecorate %__slang_resource_heap{{.*}} Binding 3 +//CHECK-NOT: OpDecorate %__slang_resource_heap{{.*}} Binding 4 +//CHECK-NOT: OpDecorate %__slang_resource_heap{{.*}} Binding 5 +//CHECK-NOT: OpDecorate %__slang_resource_heap{{.*}} Binding 6 +//CHECK-NOT: OpDecorate %__slang_resource_heap{{.*}} Binding 7 +//CHECK-NOT: OpDecorate %__slang_resource_heap{{.*}} Binding 8 +//CHECK-NOT: OpDecorate %__slang_resource_heap{{.*}} Binding 9 +export T getDescriptorFromHandle<T:IOpaqueDescriptor>(DescriptorHandle<T> handleValue) +{ + return defaultGetDescriptorFromHandle(handleValue, BindlessDescriptorOptions.VkMutable); +} + +uniform SamplerState.Handle sampler; +uniform Sampler1DShadow.Handle combinedSampler; +uniform Texture1D<float>.Handle texture; +uniform RWTexture1D<float>.Handle rwTexture1; +uniform RWTexture2D<float>.Handle rwTexture2; +uniform Buffer<float>.Handle texelBuffer; +uniform RWBuffer<float>.Handle rwTexelBuffer; + +struct Data +{ + float v; +} +uniform ConstantBuffer<Data>.Handle buffer1; +uniform StructuredBuffer<float>.Handle buffer2; +uniform RWStructuredBuffer<float>.Handle rwBuffer; +uniform RaytracingAccelerationStructure.Handle rayAcceleration; + + +[shader("compute")] +void computeMain() +{ + + t1[0] = t2[0] + t2[0] + t4[0]; + t1[2] = t4.Sample(sampler, 0); + t1[8] = combinedSampler.Sample(0); + t1[0] = texture[0]; + t1[11] = rwTexture1[0]; + t1[12] = rwTexture2[0]; + t1[10] = texelBuffer[0]; + t1[9] = rwTexelBuffer[0]; + t1[4] = (*buffer1).v; + t1[6] = buffer2[0]; + t1[0] += rwBuffer[0]; + + RayDesc ray; + ray.Origin = float3(0.1f, 0.1f, 0.0f); + ray.Direction = float3(0.0f, 0.0f, 1.0f); + ray.TMin = 0.0f; + ray.TMax = 100.0f; + RayQuery<RAY_FLAG_FORCE_NON_OPAQUE> rq; + rq.TraceRayInline(rayAcceleration, RAY_FLAG_FORCE_NON_OPAQUE, 0xff, ray); + bool proceed = rq.Proceed(); + rq.CommitNonOpaqueTriangleHit(); + rq.Abort(); + t1[13] = (float)rq.RayFlags(); + +}
\ No newline at end of file |
