summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorArielG-NV <159081215+ArielG-NV@users.noreply.github.com>2025-05-16 11:57:17 -0700
committerGitHub <noreply@github.com>2025-05-16 18:57:17 +0000
commit0244c96d637f47fa264d441a82d3dca78889373b (patch)
tree86bf0a8922ebdfd727494bc06e3069df464fe682 /tests
parent0651ffb6489282f0f902ec5f630821a7b9d848bb (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')
-rw-r--r--tests/language-feature/descriptor-handle/desc-handle-2.slang2
-rw-r--r--tests/language-feature/descriptor-handle/desc-handle-default.slang159
-rw-r--r--tests/language-feature/descriptor-handle/desc-handle-vk-mutable-descriptor.slang79
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