yum-mirror/slang

Making it easier to work with shaders

git clone https://git.yummers.dev/yum-mirror/slang

Yong HeSupport generic constraints that are dependent on another generic param. (#4091)1863fe1de

master
2.1 KiB64 linesraw
1//TEST(compute):COMPARE_COMPUTE(filecheck-buffer=CHECK): -shaderobj -output-using-type
2//TEST(compute):COMPARE_COMPUTE(filecheck-buffer=CHECK): -vk -shaderobj -output-using-type
3
4// Test that we can compile a generic function with a generic type constraint that is dependent on an
5// outer generic type parameter.
6
7namespace ns{
8
9    public interface IBinaryElementWiseFunction<T>
10    {
11        public static T call(const in T lhs, const in T rhs);
12    }
13    public struct AddOp<T : IArithmetic> : IBinaryElementWiseFunction<T>
14    {
15        public static  T call(const in T lhs, const in T rhs)
16        {
17            return lhs + rhs; 
18        }
19    }
20    public struct BinaryElementWiseInputData<T : IArithmetic>
21    {
22        T lhs;
23        T rhs;
24
25        // Note: `U` is constrainted by `IBinaryElementWiseFunction<T>`, which is dependent on `T`,
26        // that is another generic type parameter defined on the outer type.
27        // This eventually leads to a IRGeneric where one param has a type that is dependent on
28        // another param.
29        // In this case, the IR for `test` after generic flattening will be:
30        // ```
31        // %g_test = IRGeneric
32        // {
33        //     IRBlock
34        //     {
35        //          %T = IRParam : Type;
36        //          %T_w = IRParam : IRWitnessTableType<IArithmetic>;
37        //          %U = IRParam : Type;
38        //          %U_w = IRRaram : IRWitnessTableType<%s>; // note that the type here is a forward reference to %s
39        //          %s = specialize(%IBinaryElementWiseFunction, %T) // %s is dependent on %T.
40        //          ...
41        //     }
42        // }
43        // 
44        public T test<U : IBinaryElementWiseFunction<T>>(U x)
45        {
46            return x.call(lhs ,rhs);
47        }
48    }
49}
50
51
52//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out,name=outputBuffer
53RWStructuredBuffer<int> outputBuffer;
54
55[shader("compute")]
56[numthreads(1,1,1)]
57void computeMain(uint3 threadId: SV_DispatchThreadID)
58{
59    ns::BinaryElementWiseInputData<int> cb;
60    cb.lhs = threadId.x + 1;
61    cb.rhs = 2;
62    // CHECK: 3
63    outputBuffer[0] = cb.test(ns::AddOp<int>());
64}