summaryrefslogtreecommitdiffstats
path: root/tests/experiments/generic/byte-address-ptr.slang
blob: 33096b70f4632913ced7471c7fe19ec6c28adcc9 (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
77
78
79
80
81
82
83
84
85
86
87
//DISABLE_TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -shaderobj

/* The purpose of these tests is to use generics to be able to traverse
a 'linked list' of different related types. 

tests/current-bugs/generic/byte-address-ptr.slang(77): note 99999: an internal error threw an exception while working on code near this location
(0): error 99999: Slang compilation aborted due to an exception of class Slang::InternalError: assert failure: witnessTableVal->getOp() != kIROp_StructKey
*/

//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out,name outputBuffer

//TEST_INPUT:ubuffer(data=[0]):name=gB
ByteAddressBuffer gB;

enum Type : int
{
    A,
    B,
    C,
};

interface IBase 
{
    static bool isType(Type type);
};

struct Base : IBase
{
    static bool isType(Type type) { return true; }
    Type type;
};

struct Ptr
{
    Type getType() { return gB.Load<Base>(offset).type; }
    
    __generic<T : IBase>
    bool isType() { return T::isType(getType()); }
    // Changing to T : IBase causes an internal compiler crash
    __generic<T : IBase>
    T as()
    {
        bool isOk = isType<T>();
        // I want a way to assert!
        // assert(isOk);
        return gB.Load<T>(offset);
    }
    int offset;
};

struct A : Base
{
    static bool isType(Type type) { return type == Type::A; }
    Ptr next;
    int something;
};

struct B : Base
{
    static bool isType(Type type) { return type == Type::C || type == Type::B; }
    int someData;
};

struct C : B
{
    static bool isType(Type type) { return type == Type::C; }
    int somethingElse;
};

RWStructuredBuffer<int> outputBuffer;

[numthreads(4, 1, 1)]
void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID)
{    
    Ptr ptr = { 0 };
    int total = 0;
    
    while (ptr.isType<A>())    
    {
        A a = ptr.as<A>();
        total += a.something;

        ptr = a.next;
    }

    outputBuffer[dispatchThreadID.x] = total;
}