summaryrefslogtreecommitdiff
path: root/tests/experiments/generic/type-to-value-4.slang
blob: 8d768b54b238a852123610314535c19923f592cf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -shaderobj

/* Test here is to try and associate a value with a type

This doesn't work without 'public' on struct B. This is necessary such that
those implementations of `IGetE` are visible for dynamic dispatch.

Otherwise the error 

> tests/experiments/generic/type-to-value-4.slang(21): error 50100: No type conformances are found for interface 'IGetE'. Code generation for current target requires at least one implementation type present in the linkage.
> interface IGetE
          ^~~~~

This is somewhat 'surprising' because the code *explicitly* instanciates B, so why is it necessary to make it 
public?

If we make both struct A and struct B public, the following code uses dynamic dispatch in order to implement e.getE(). When it does this it introduces

```HLSL
struct Tuple_0
{
    uint2 value0_0;
    uint2 value1_0;
    AnyValue16 value2_0;
};

Tuple_0 _S1;

[numthreads(4, 1, 1)]
void computeMain(uint3 dispatchThreadID_0 : SV_DISPATCHTHREADID)
{
    int _S7 = U_S3tu05IGetE4getEp0p3tu04Enum_0(_S1.value1_0);

    // ...
}
```

But _S1 is never intialized (in HLSL it becomes a Global in a constant buffer). Why does creating a local variable produce something in a constant buffer?

*/

//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out,name outputBuffer
RWStructuredBuffer<int> outputBuffer;

enum class Enum
{
    A, B
};

interface IGetE
{
	static Enum getE();    
};

struct A : IGetE
{
    static Enum getE() { return Enum::A; }
};

struct B : IGetE
{
    static Enum getE() { return Enum::B; }
};

[numthreads(4, 1, 1)]
void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID)
{
   
    // Err.. even though IGetE doesn't require an instanciation, not clear how to set it. So lets try with instanciation
    B b;
    IGetE g = b;

    let e = g.getE();

    outputBuffer[dispatchThreadID.x] = int(e);
}