diff options
| author | Yong He <yonghe@outlook.com> | 2025-02-28 22:46:56 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-02-28 22:46:56 -0800 |
| commit | dd9d24d29c4a9e05a4510eb9959fafa0ed36618b (patch) | |
| tree | 240e2e4ecd8fc15fa835db4377670ec7fdf90e71 /tests/bugs | |
| parent | 700c38ae7c16a49de7f720ae3b1940df5b2b4b33 (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')
| -rw-r--r-- | tests/bugs/gh-6482-interface-method-existential-specialize.slang | 93 |
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 |
