summaryrefslogtreecommitdiffstats
path: root/tests/bugs/gh-6482-interface-method-existential-specialize.slang
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2025-02-28 22:46:56 -0800
committerGitHub <noreply@github.com>2025-02-28 22:46:56 -0800
commitdd9d24d29c4a9e05a4510eb9959fafa0ed36618b (patch)
tree240e2e4ecd8fc15fa835db4377670ec7fdf90e71 /tests/bugs/gh-6482-interface-method-existential-specialize.slang
parent700c38ae7c16a49de7f720ae3b1940df5b2b4b33 (diff)
Allow partial specialization of existential arguments. (#6487)
* Allow partial specialization of existential arguments. * Fix. * Add test case for improved diagnostics. * Fix compile error. * Fix tests. * Fix. * Fix test. * Fix compile issue. * Fix typo. * Address comment.
Diffstat (limited to 'tests/bugs/gh-6482-interface-method-existential-specialize.slang')
-rw-r--r--tests/bugs/gh-6482-interface-method-existential-specialize.slang93
1 files changed, 93 insertions, 0 deletions
diff --git a/tests/bugs/gh-6482-interface-method-existential-specialize.slang b/tests/bugs/gh-6482-interface-method-existential-specialize.slang
new file mode 100644
index 000000000..d01e5b7ff
--- /dev/null
+++ b/tests/bugs/gh-6482-interface-method-existential-specialize.slang
@@ -0,0 +1,93 @@
+//TEST:SIMPLE(filecheck=CHECK): -target spirv
+
+// This is a test that checks that we can apply partial specialization to a function
+// that takes existential parameters.
+
+// CHECK: OpRayQueryProceedKHR
+// CHECK: OpImageWrite
+
+public interface IRandom {
+ [mutating] uint32_t next_uint();
+ [mutating] float next_float();
+};
+
+public struct TEA : IRandom {
+ int val;
+ public __init(uint32_t v0, uint32_t v1) {}
+ [mutating] public uint32_t next_uint() {
+ return val++;
+ }
+ [mutating] public float next_float() {
+ return val++;
+ }
+};
+
+public interface IScene {
+ property RaytracingAccelerationStructure as;
+};
+
+// The Scene type contains a resource field, if dynamic dispatch code were generated
+// for this type, we will get a compile error.
+struct Scene : IScene {
+ RaytracingAccelerationStructure as;
+};
+
+public interface IIntegrator {
+
+ // This function takes two existential parameters, `scene` and `rng`.
+ // if we call this function with `rng` being dynamic, and `scene` being static,
+ // we should still be able to specialize the `sample` function with the statically known
+ // type of `scene`.
+ public float3 sample(IScene scene, RayDesc ray, IRandom rng);
+};
+namespace integrator {
+ public struct NoShading : IIntegrator {
+ public float3 sample(IScene scene, RayDesc _ray, IRandom rng) {
+ return float3( 0.0f, 0.0f, 0.0f );
+ }
+ };
+
+ struct Test {
+
+ float4 sample(IScene scene, RayDesc _ray, IRandom rng, int pixel_aabb_uv, uint3 id) {
+ float4 grad = { 0.0f, 0.0f, 0.0f, 1.0f };
+
+ RayDesc ray = _ray; uint32_t depth = 0;
+ RayQuery<0> rayQuery;
+ while (rayQuery.Proceed()) {
+ float rand = rng.next_float();
+
+ IIntegrator integrator = integrator::NoShading();
+
+ // Here `rng` is mutating in the loop, so its type is dynamic and we need
+ // to generate dynamic dispatch code around it.
+ // But this shouldn't result in `scene` being dynamic as well.
+ // We should still be able to specialize `integrator.sample` with the statically
+ // known type of `scene`.
+ // If this doesn't happen, then the compiler will try to synthesize dynamic dispatch
+ // logic for `scene` and fail to compile.
+ let color_in = integrator.sample(scene, {}, rng);
+ let color_out = integrator.sample(scene, {}, rng);
+ grad.xyz += color_out;
+ }
+ return grad;
+ }
+ };
+};
+
+[[vk::binding(0, 0)]] RWTexture2D<float4> output;
+
+[vk::constant_id(0)] const int WGS_X = 1;
+[vk::constant_id(1)] const int WGS_Y = 1;
+[shader("compute"), numthreads(WGS_X, WGS_Y, 1)]
+void main(
+ uint3 id : SV_DispatchThreadID
+)
+{
+ IRandom rng = TEA(id.y * id.x, 1);
+ Scene scene = { RaytracingAccelerationStructure(0) };
+
+ integrator::Test integrator = integrator::Test();
+ float4 grad = integrator.sample(scene, {}, rng, {}, id);
+ output[id.xy] += float4(grad.xyz, grad.w);
+} \ No newline at end of file