yum-mirror/slang

Making it easier to work with shaders

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

Yong HeWarning on lossy implicit casts. (#2367)adaea0e99

master
4.1 KiB157 linesraw
1// unbounded-arrays.hlsl
2
3//TEST:COMPARE_HLSL:-profile cs_5_1 -entry main
4//TEST:REFLECTION:-profile cs_5_1 -target hlsl -no-codegen -D__SLANG__
5
6//
7// This test is trying to make sure that we correctly compute
8// reflection/layout information for shaders that make use
9// of unbounded arrays of resources.
10//
11// We will begin by declaring various "simple" global arrays
12// of resource/sampler types and try out variations on binding
13// them to registers/spaces or not.
14//
15// We will want to confirm that Slang generates the bindings
16// we expect, and we will do this by enforcing explicit
17// bindings on all parameters in the HLSL baseline we'll
18// compare against:
19//
20
21    #ifdef __SLANG__
22        #define REGISTER(x, y) /* empty */
23    #else
24        #define REGISTER(x,y) : register(x,y)
25        #define aa aa_0
26        #define b0 b0_0
27        #define b1 b1_0
28        #define bb bb_0
29        #define c0 c0_0
30        #define cc cc_0
31        #define data data_0
32    #endif
33
34// First, let's just declare a simple unbounded array of samplers.
35// We expect this to be given its own register and space (for D3D12)
36//
37
38    SamplerState aa[] REGISTER(s0, space2);
39
40//
41// Next, we will try to declare an array of resources with an explicit
42// `register` binding. This should be set to start at that register in
43// space zero (the default space), and should therefore "claim" all
44// registers from that point on.
45//
46
47    Texture2D bb[] : register(t2);
48
49//
50// If we have assigned register t2 and beyond in space zero to `bb`,
51// then we should still be able to put other resources in there explicitly:
52//
53
54    Texture2D b0 : register(t0);
55    Texture2D b1 : register(t1, space0);
56
57//
58// It should also be possible to give an unbounded array an explicit
59// register and space, and again it should be poossible to fill
60// in the space before the unbounded array:
61//
62
63    TextureCube cc[] : register(t1, space1);
64    Texture2D c0 : register(t0, space1);
65
66//
67// As a final detail, we should allow the user to specify the space
68// and no register, which should be interpreted as requesting *any*
69// register in the given space.
70//
71// TODO: Implement support for this case.
72//
73
74//    SamplerState dd[] : register(space5);
75
76//
77// With the simple cases out of the way, we will look at cases
78// that involve structures and nested arrays.
79//
80// The first case we'll test is a structure type that contains
81// two or more resources:
82//
83
84    struct X
85    {
86        Texture3D t;
87        SamplerState s;
88    };
89
90//
91// The simple case should Just Work, even though the same
92// syntax will fail when used with fxc (so we have to
93// provide a hand-written expansion for the baseline).
94//
95
96    #ifdef __SLANG__
97        X ee[];
98    #else
99        Texture3D ee_t_0[] REGISTER(t0, space3);
100        SamplerState ee_s_0[] REGISTER(s0, space4);
101    #endif
102
103//
104// TODO: we should probably test interactions with explicit
105// bindings for a structrure.
106//
107// TODO: we should also test cases that mix resource and
108// non-resource types, but we can't currently have an unbounded
109// array of uniform data (in HLSL at least).
110//
111// TODO: should test arrays-of-arrays cases.
112//
113
114
115//
116// We'll close things out with a dummy entry point just
117// to allow this file to be compiled with fxc/dxc.
118//
119
120    float4 use(Texture2D t, SamplerState s, float4 u)
121    {
122        return t.SampleLevel(s, u.xy + u.z, u.w);
123    }
124
125    float4 use(Texture3D t, SamplerState s, float4 u)
126    {
127        return t.SampleLevel(s, u.xyz, u.w);
128    }
129
130    float4 use(TextureCube t, SamplerState s, float4 u)
131    {
132        return t.SampleLevel(s, u.xyz, u.w);
133    }
134
135    RWStructuredBuffer<float4> data;
136
137    [numthreads(4,1,1)]
138    void main(uint3 tid : SV_DispatchThreadID)
139    {
140        int idx = int(tid.x);
141        float4 tmp = data[idx];
142
143        SamplerState s = aa[idx];
144
145        tmp = use(bb[idx],  s, tmp);
146        tmp = use(b0,       s, tmp);
147        tmp = use(b1,       s, tmp);
148        tmp = use(cc[idx],  s, tmp);
149        tmp = use(c0,       s, tmp);
150
151#ifdef __SLANG__
152        tmp = use(ee[idx].t, ee[idx].s, tmp);
153#else
154        tmp = use(ee_t_0[idx], ee_s_0[idx], tmp);
155#endif
156        data[idx] = tmp;
157    }