xref: /aosp_15_r20/external/mesa3d/src/amd/compiler/tests/test_d3d11_derivs.cpp (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright © 2023 Valve Corporation
3  *
4  * SPDX-License-Identifier: MIT
5  */
6 #include "helpers.h"
7 #include "test_d3d11_derivs-spirv.h"
8 
9 using namespace aco;
10 
11 BEGIN_TEST(d3d11_derivs.simple)
12    // clang-format off
13    QoShaderModuleCreateInfo vs = qoShaderModuleCreateInfoGLSL(VERTEX,
14       layout(location = 0) in vec2 in_coord;
15       layout(location = 0) out vec2 out_coord;
16       void main() {
17          out_coord = in_coord;
18       }
19    );
20    QoShaderModuleCreateInfo fs = qoShaderModuleCreateInfoGLSL(FRAGMENT,
21       layout(location = 0) in vec2 in_coord;
22       layout(location = 0) out vec4 out_color;
23       layout(binding = 0) uniform sampler2D tex;
24       void main() {
25          out_color = vec4(0.0);
26          if (gl_FragCoord.x > 1.0)
27             out_color = texture(tex, in_coord);
28       }
29    );
30    // clang-format on
31 
32    PipelineBuilder pbld(get_vk_device(GFX10_3));
33    pbld.add_vsfs(vs, fs);
34 
35    //>> v1: %x = v_interp_p2_f32 %_, %_:m0, (kill)%_ attr0.x
36    //>> v1: %y = v_interp_p2_f32 (kill)%_, (kill)%_:m0, (kill)%_ attr0.y
37    //>> lv2: %wqm = p_start_linear_vgpr (kill)%x, (kill)%y
38    //>> BB1
39    //>> v4: %_ = image_sample (kill)%_, (kill)%_, v1: undef, (latekill)%wqm 2d
40    //>> BB2
41    //>> BB6
42    //>> p_end_linear_vgpr (kill)%wqm
43    pbld.print_ir(VK_SHADER_STAGE_FRAGMENT_BIT, "ACO IR");
44 
45    //>> v_interp_p2_f32_e32 v#rx_tmp, v#_, attr0.x                                         ; $_
46    //>> v_interp_p2_f32_e32 v#ry_tmp, v#_, attr0.y                                         ; $_
47    //>> v_mov_b32_e32 v#rx, v#rx_tmp                                                       ; $_
48    //>> v_mov_b32_e32 v#ry, v#ry_tmp                                                       ; $_
49    //>> image_sample v[#_:#_], v[#rx:#ry], s[#_:#_], s[#_:#_] dmask:0xf dim:SQ_RSRC_IMG_2D ; $_ $_
50    pbld.print_ir(VK_SHADER_STAGE_FRAGMENT_BIT, "Assembly");
51 END_TEST
52 
53 BEGIN_TEST(d3d11_derivs.constant)
54    // clang-format off
55    QoShaderModuleCreateInfo vs = qoShaderModuleCreateInfoGLSL(VERTEX,
56       layout(location = 0) in float in_coord;
57       layout(location = 0) out float out_coord;
58       void main() {
59          out_coord = in_coord;
60       }
61    );
62    QoShaderModuleCreateInfo fs = qoShaderModuleCreateInfoGLSL(FRAGMENT,
63       layout(location = 0) in float in_coord;
64       layout(location = 0) out vec4 out_color;
65       layout(binding = 0) uniform sampler2D tex;
66       void main() {
67          out_color = vec4(0.0);
68          if (gl_FragCoord.x > 1.0)
69             out_color = texture(tex, vec2(in_coord, -0.5));
70       }
71    );
72    // clang-format on
73 
74    PipelineBuilder pbld(get_vk_device(GFX10_3));
75    pbld.add_vsfs(vs, fs);
76 
77    //>> v1: %x = v_interp_p2_f32 (kill)%_, (kill)%_:m0, (kill)%_ attr0.x
78    //>> lv2: %wqm = p_start_linear_vgpr (kill)%x, -0.5
79    //>> BB1
80    //>> v4: %_ = image_sample (kill)%_, (kill)%_, v1: undef, (latekill)%wqm 2d
81    //>> BB2
82    //>> BB6
83    //>> p_end_linear_vgpr (kill)%wqm
84    pbld.print_ir(VK_SHADER_STAGE_FRAGMENT_BIT, "ACO IR");
85 
86    //>> v_interp_p2_f32_e32 v#rx_tmp, v#_, attr0.x                                         ; $_
87    //>> v_mov_b32_e32 v#ry, -0.5                                                           ; $_
88    //>> v_mov_b32_e32 v#rx, v#rx_tmp                                                       ; $_
89    //>> image_sample v[#_:#_], v[#rx:#ry], s[#_:#_], s[#_:#_] dmask:0xf dim:SQ_RSRC_IMG_2D ; $_ $_
90    pbld.print_ir(VK_SHADER_STAGE_FRAGMENT_BIT, "Assembly");
91 END_TEST
92 
93 BEGIN_TEST(d3d11_derivs.discard)
94    // clang-format off
95    QoShaderModuleCreateInfo vs = qoShaderModuleCreateInfoGLSL(VERTEX,
96       layout(location = 0) in vec2 in_coord;
97       layout(location = 0) out vec2 out_coord;
98       void main() {
99          out_coord = in_coord;
100       }
101    );
102    QoShaderModuleCreateInfo fs = qoShaderModuleCreateInfoGLSL(FRAGMENT,
103       layout(location = 0) in vec2 in_coord;
104       layout(location = 0) out vec4 out_color;
105       layout(binding = 0) uniform sampler2D tex;
106       void main() {
107          if (gl_FragCoord.y > 1.0)
108             discard;
109          out_color = texture(tex, in_coord);
110       }
111    );
112    // clang-format on
113 
114    PipelineBuilder pbld(get_vk_device(GFX10_3));
115    pbld.add_vsfs(vs, fs);
116 
117    /* The discard gets emitted as demote_if. */
118    //>> s2: %_:exec,  s1: %cond:scc = s_wqm_b64 %_
119    //>> p_exit_early_if (kill)%cond:scc
120    //>> v4: %_ = image_sample (kill)%_, (kill)%_, v1: undef, (kill)%_, (kill)%_ 2d
121    pbld.print_ir(VK_SHADER_STAGE_FRAGMENT_BIT, "ACO IR");
122 END_TEST
123 
124 BEGIN_TEST(d3d11_derivs.bias)
125    // clang-format off
126    QoShaderModuleCreateInfo vs = qoShaderModuleCreateInfoGLSL(VERTEX,
127       layout(location = 0) in vec2 in_coord;
128       layout(location = 0) out vec2 out_coord;
129       void main() {
130          out_coord = in_coord;
131       }
132    );
133    QoShaderModuleCreateInfo fs = qoShaderModuleCreateInfoGLSL(FRAGMENT,
134       layout(location = 0) in vec2 in_coord;
135       layout(location = 0) out vec4 out_color;
136       layout(binding = 0) uniform sampler2D tex;
137       void main() {
138          out_color = vec4(0.0);
139          if (gl_FragCoord.x > 1.0)
140             out_color = texture(tex, in_coord, gl_FragCoord.x);
141       }
142    );
143    // clang-format on
144 
145    PipelineBuilder pbld(get_vk_device(GFX10_3));
146    pbld.add_vsfs(vs, fs);
147 
148    //>> s2: %_:s[0-1], s1: %_:s[2], s1: %_:s[3], s1: %_:s[4], v2: %_:v[0-1], v1: %bias:v[2] = p_startpgm
149    //>> lv3: %wqm = p_start_linear_vgpr v1: undef, (kill)%_, (kill)%_
150    //>> BB1
151    //>> v4: %_ = image_sample_b (kill)%_, (kill)%_, v1: undef, (latekill)%wqm, (kill)%bias 2d
152    //>> BB2
153    //>> BB6
154    //>> p_end_linear_vgpr (kill)%wqm
155    pbld.print_ir(VK_SHADER_STAGE_FRAGMENT_BIT, "ACO IR");
156 
157    //>> v_interp_p2_f32_e32 v#rx_tmp, v#_, attr0.x                                                   ; $_
158    //>> v_interp_p2_f32_e32 v#ry_tmp, v#_, attr0.y                                                   ; $_
159    //>> v_mov_b32_e32 v#rx, v#rx_tmp                                                                 ; $_
160    //>> v_mov_b32_e32 v#ry, v#ry_tmp                                                                 ; $_
161    //>> BB1:
162    //>> image_sample_b v[#_:#_], [v#rb, v#rx, v#ry], s[#_:#_], s[#_:#_] dmask:0xf dim:SQ_RSRC_IMG_2D ; $_ $_ $_
163    pbld.print_ir(VK_SHADER_STAGE_FRAGMENT_BIT, "Assembly");
164 END_TEST
165 
166 BEGIN_TEST(d3d11_derivs.offset)
167    // clang-format off
168    QoShaderModuleCreateInfo vs = qoShaderModuleCreateInfoGLSL(VERTEX,
169       layout(location = 0) in vec2 in_coord;
170       layout(location = 0) out vec2 out_coord;
171       void main() {
172          out_coord = in_coord;
173       }
174    );
175    QoShaderModuleCreateInfo fs = qoShaderModuleCreateInfoGLSL(FRAGMENT,
176       layout(location = 0) in vec2 in_coord;
177       layout(location = 0) out vec4 out_color;
178       layout(binding = 0) uniform sampler2D tex;
179       void main() {
180          out_color = vec4(0.0);
181          if (gl_FragCoord.x > 1.0)
182             out_color = textureOffset(tex, in_coord, ivec2(1, 2));
183       }
184    );
185    // clang-format on
186 
187    /* Use GFX9 because we should have at least one test which doesn't use NSA. */
188    PipelineBuilder pbld(get_vk_device(GFX9));
189    pbld.add_vsfs(vs, fs);
190 
191    //>> lv3: %wqm = p_start_linear_vgpr v1: undef, (kill)%_, (kill)%_
192    //>> BB1
193    //>> v1: %offset = p_parallelcopy 0x201
194    //>> v4: %_ = image_sample_o (kill)%_, (kill)%_, v1: undef, (latekill)%wqm, (kill)%offset 2d
195    //>> BB2
196    //>> BB6
197    //>> p_end_linear_vgpr (kill)%wqm
198    pbld.print_ir(VK_SHADER_STAGE_FRAGMENT_BIT, "ACO IR");
199 
200    //>> v_interp_p2_f32_e32 v#rx_tmp, v#_, attr0.x                        ; $_
201    //>> v_interp_p2_f32_e32 v#ry_tmp, v#_, attr0.y                        ; $_
202    //>> v_mov_b32_e32 v#rx, v#rx_tmp                                      ; $_
203    //>> v_mov_b32_e32 v#ry, v#ry_tmp                                      ; $_
204    //>> BB1:
205    //>> v_mov_b32_e32 v#ro_tmp, 0x201                                     ; $_ $_
206    //>> v_mov_b32_e32 v#ro, v#r0_tmp                                      ; $_
207    //; success = ro+1 == rx and ro+2 == ry
208    //>> image_sample_o v[#_:#_], v[#ro:#rx], s[#_:#_], s[#_:#_] dmask:0xf ; $_ $_
209    pbld.print_ir(VK_SHADER_STAGE_FRAGMENT_BIT, "Assembly");
210 END_TEST
211 
212 BEGIN_TEST(d3d11_derivs.array)
213    // clang-format off
214    QoShaderModuleCreateInfo vs = qoShaderModuleCreateInfoGLSL(VERTEX,
215       layout(location = 0) in vec3 in_coord;
216       layout(location = 0) out vec3 out_coord;
217       void main() {
218          out_coord = in_coord;
219       }
220    );
221    QoShaderModuleCreateInfo fs = qoShaderModuleCreateInfoGLSL(FRAGMENT,
222       layout(location = 0) in vec3 in_coord;
223       layout(location = 0) out vec4 out_color;
224       layout(binding = 0) uniform sampler2DArray tex;
225       void main() {
226          out_color = vec4(0.0);
227          if (gl_FragCoord.x > 1.0)
228             out_color = texture(tex, in_coord);
229       }
230    );
231    // clang-format on
232 
233    PipelineBuilder pbld(get_vk_device(GFX10_3));
234    pbld.add_vsfs(vs, fs);
235 
236    //>> v1: %layer = v_rndne_f32 (kill)%_
237    //>> lv3: %wqm = p_start_linear_vgpr (kill)%_, (kill)%_, (kill)%layer
238    //>> BB1
239    //>> v4: %_ = image_sample (kill)%_, (kill)%_, v1: undef, (latekill)%wqm 2darray da
240    //>> BB2
241    //>> BB6
242    //>> p_end_linear_vgpr (kill)%wqm
243    pbld.print_ir(VK_SHADER_STAGE_FRAGMENT_BIT, "ACO IR");
244 
245    //>> v_interp_p2_f32_e32 v#rl_tmp, v#_, attr0.z                                               ; $_
246    //>> v_interp_p2_f32_e32 v#rx_tmp, v#_, attr0.x                                               ; $_
247    //>> v_interp_p2_f32_e32 v#ry_tmp, v#_, attr0.y                                               ; $_
248    //>> v_rndne_f32_e32 v#rl_tmp, v#rl_tmp                                                       ; $_
249    //>> v_mov_b32_e32 v#rx, v#rx_tmp                                                             ; $_
250    //>> v_mov_b32_e32 v#ry, v#ry_tmp                                                             ; $_
251    //>> v_mov_b32_e32 v#rl, v#rl_tmp                                                             ; $_
252    //>> BB1:
253    //; success = rx+1 == ry and rx+2 == rl
254    //>> image_sample v[#_:#_], v[#rx:#rl], s[#_:#_], s[#_:#_] dmask:0xf dim:SQ_RSRC_IMG_2D_ARRAY ; $_ $_
255    pbld.print_ir(VK_SHADER_STAGE_FRAGMENT_BIT, "Assembly");
256 END_TEST
257 
258 BEGIN_TEST(d3d11_derivs.bias_array)
259    // clang-format off
260    QoShaderModuleCreateInfo vs = qoShaderModuleCreateInfoGLSL(VERTEX,
261       layout(location = 0) in vec3 in_coord;
262       layout(location = 0) out vec3 out_coord;
263       void main() {
264          out_coord = in_coord;
265       }
266    );
267    QoShaderModuleCreateInfo fs = qoShaderModuleCreateInfoGLSL(FRAGMENT,
268       layout(location = 0) in vec3 in_coord;
269       layout(location = 0) out vec4 out_color;
270       layout(binding = 0) uniform sampler2DArray tex;
271       void main() {
272          out_color = vec4(0.0);
273          if (gl_FragCoord.x > 1.0)
274             out_color = texture(tex, in_coord, gl_FragCoord.x);
275       }
276    );
277    // clang-format on
278 
279    PipelineBuilder pbld(get_vk_device(GFX10_3));
280    pbld.add_vsfs(vs, fs);
281 
282    //>> s2: %_:s[0-1], s1: %_:s[2], s1: %_:s[3], s1: %_:s[4], v2: %_:v[0-1], v1: %bias:v[2] = p_startpgm
283    //>> v1: %layer = v_rndne_f32 (kill)%_
284    //>> lv4: %wqm = p_start_linear_vgpr v1: undef, (kill)%_, (kill)%_, (kill)%layer
285    //>> BB1
286    //>> v4: %_ = image_sample_b (kill)%_, (kill)%_, v1: undef, (latekill)%wqm, (kill)%bias 2darray da
287    //>> BB2
288    //>> BB6
289    //>> p_end_linear_vgpr (kill)%wqm
290    pbld.print_ir(VK_SHADER_STAGE_FRAGMENT_BIT, "ACO IR");
291 
292    //>> v_interp_p2_f32_e32 v#rl_tmp, v#_, attr0.z                                                             ; $_
293    //>> v_interp_p2_f32_e32 v#rx_tmp, v#_, attr0.x                                                             ; $_
294    //>> v_interp_p2_f32_e32 v#ry_tmp, v#_, attr0.y                                                             ; $_
295    //>> v_rndne_f32_e32 v#rl_tmp, v#rl_tmp                                                                     ; $_
296    //>> v_mov_b32_e32 v#rx, v#rx_tmp                                                                           ; $_
297    //>> v_mov_b32_e32 v#ry, v#ry_tmp                                                                           ; $_
298    //>> v_mov_b32_e32 v#rl, v#rl_tmp                                                                           ; $_
299    //>> BB1:
300    //>> image_sample_b v[#_:#_], [v2, v#rx, v#ry, v#rl], s[#_:#_], s[#_:#_] dmask:0xf dim:SQ_RSRC_IMG_2D_ARRAY ; $_ $_ $_
301    pbld.print_ir(VK_SHADER_STAGE_FRAGMENT_BIT, "Assembly");
302 END_TEST
303 
304 BEGIN_TEST(d3d11_derivs._1d_gfx9)
305    // clang-format off
306    QoShaderModuleCreateInfo vs = qoShaderModuleCreateInfoGLSL(VERTEX,
307       layout(location = 0) in float in_coord;
308       layout(location = 0) out float out_coord;
309       void main() {
310          out_coord = in_coord;
311       }
312    );
313    QoShaderModuleCreateInfo fs = qoShaderModuleCreateInfoGLSL(FRAGMENT,
314       layout(location = 0) in float in_coord;
315       layout(location = 0) out vec4 out_color;
316       layout(binding = 0) uniform sampler1D tex;
317       void main() {
318          out_color = vec4(0.0);
319          if (gl_FragCoord.x > 1.0)
320             out_color = texture(tex, in_coord);
321       }
322    );
323    // clang-format on
324 
325    PipelineBuilder pbld(get_vk_device(GFX9));
326    pbld.add_vsfs(vs, fs);
327 
328    //>> v1: %x = v_interp_p2_f32 (kill)%_, (kill)%_:m0, (kill)%_ attr0.x
329    //>> lv2: %wqm = p_start_linear_vgpr (kill)%x, 0.5
330    //>> BB1
331    //>> v4: %_ = image_sample (kill)%_, (kill)%_, v1: undef, (latekill)%wqm 2d
332    //>> BB2
333    //>> BB6
334    //>> p_end_linear_vgpr (kill)%wqm
335    pbld.print_ir(VK_SHADER_STAGE_FRAGMENT_BIT, "ACO IR");
336 
337    //>> v_interp_p2_f32_e32 v#rx_tmp, v#_, attr0.x                ; $_
338    //>> v_mov_b32_e32 v#ry, 0.5                                   ; $_
339    //>> v_mov_b32_e32 v#rx, v#rx_tmp                              ; $_
340    //; success = rx+1 == ry
341    //>> image_sample v[#_:#_], v#rx, s[#_:#_], s[#_:#_] dmask:0xf ; $_ $_
342    pbld.print_ir(VK_SHADER_STAGE_FRAGMENT_BIT, "Assembly");
343 END_TEST
344 
345 BEGIN_TEST(d3d11_derivs._1d_array_gfx9)
346    // clang-format off
347    QoShaderModuleCreateInfo vs = qoShaderModuleCreateInfoGLSL(VERTEX,
348       layout(location = 0) in vec2 in_coord;
349       layout(location = 0) out vec2 out_coord;
350       void main() {
351          out_coord = in_coord;
352       }
353    );
354    QoShaderModuleCreateInfo fs = qoShaderModuleCreateInfoGLSL(FRAGMENT,
355       layout(location = 0) in vec2 in_coord;
356       layout(location = 0) out vec4 out_color;
357       layout(binding = 0) uniform sampler1DArray tex;
358       void main() {
359          out_color = vec4(0.0);
360          if (gl_FragCoord.x > 1.0)
361             out_color = texture(tex, in_coord);
362       }
363    );
364    // clang-format on
365 
366    PipelineBuilder pbld(get_vk_device(GFX9));
367    pbld.add_vsfs(vs, fs);
368 
369    //>> v1: %layer = v_rndne_f32 (kill)%_
370    //>> v1: %x = v_interp_p2_f32 (kill)%_, (kill)%_:m0, (kill)%_ attr0.x
371    //>> lv3: %wqm = p_start_linear_vgpr (kill)%x, 0.5, (kill)%layer
372    //>> BB1
373    //>> v4: %_ = image_sample (kill)%_, (kill)%_, v1: undef, (latekill)%wqm 2darray da
374    //>> BB2
375    //>> BB6
376    //>> p_end_linear_vgpr (kill)%wqm
377    pbld.print_ir(VK_SHADER_STAGE_FRAGMENT_BIT, "ACO IR");
378 
379    //>> v_interp_p2_f32_e32 v#rl_tmp, v#_, attr0.y                   ; $_
380    //>> v_interp_p2_f32_e32 v#rx_tmp, v#_, attr0.x                   ; $_
381    //>> v_rndne_f32_e32 v#rl_tmp, v#rl_tmp                           ; $_
382    //>> v_mov_b32_e32 v#ry, 0.5                                      ; $_
383    //>> v_mov_b32_e32 v#rx, v#rx_tmp                                 ; $_
384    //>> v_mov_b32_e32 v#rl, v#rl_tmp                                 ; $_
385    //>> BB1:
386    //; success = rx+1 == ry and rx+2 == rl
387    //>> image_sample v[#_:#_], v#rx, s[#_:#_], s[#_:#_] dmask:0xf da ; $_ $_
388    pbld.print_ir(VK_SHADER_STAGE_FRAGMENT_BIT, "Assembly");
389 END_TEST
390 
391 BEGIN_TEST(d3d11_derivs.cube)
392    // clang-format off
393    QoShaderModuleCreateInfo vs = qoShaderModuleCreateInfoGLSL(VERTEX,
394       layout(location = 0) in vec3 in_coord;
395       layout(location = 0) out vec3 out_coord;
396       void main() {
397          out_coord = in_coord;
398       }
399    );
400    QoShaderModuleCreateInfo fs = qoShaderModuleCreateInfoGLSL(FRAGMENT,
401       layout(location = 0) in vec3 in_coord;
402       layout(location = 0) out vec4 out_color;
403       layout(binding = 0) uniform samplerCube tex;
404       void main() {
405          out_color = vec4(0.0);
406          if (gl_FragCoord.x > 1.0)
407             out_color = texture(tex, in_coord);
408       }
409    );
410    // clang-format on
411 
412    PipelineBuilder pbld(get_vk_device(GFX10_3));
413    pbld.add_vsfs(vs, fs);
414 
415    //>> v1: %face = v_cubeid_f32 (kill)%_, (kill)%_, (kill)%_
416    //>> v1: %x = v_fmaak_f32 (kill)%_, %_, 0x3fc00000
417    //>> v1: %y = v_fmaak_f32 (kill)%_, (kill)%_, 0x3fc00000
418    //>> lv3: %wqm = p_start_linear_vgpr (kill)%x, (kill)%y, (kill)%face
419    //>> BB1
420    //>> v4: %_ = image_sample (kill)%_, (kill)%_, v1: undef, (latekill)%wqm cube da
421    //>> BB2
422    //>> BB6
423    //>> p_end_linear_vgpr (kill)%wqm
424    pbld.print_ir(VK_SHADER_STAGE_FRAGMENT_BIT, "ACO IR");
425 
426    //>> v_cubeid_f32 v#rf_tmp, v#_, v#_, v#_                                                 ; $_ $_
427    //>> v_mov_b32_e32 v#rf, v#rf_tmp                                                         ; $_
428    //>> v_fmaak_f32 v#rx_tmp, v#_, v#_, 0x3fc00000                                           ; $_ $_
429    //>> v_fmaak_f32 v#ry_tmp, v#_, v#_, 0x3fc00000                                           ; $_ $_
430    //>> v_lshrrev_b64 v[#rx:#ry], 0, v[#rx_tmp:#ry_tmp]                                      ; $_ $_
431    //; success = rx+1 == ry and rx+2 == rf
432    //>> image_sample v[#_:#_], v[#rx:#rf], s[#_:#_], s[#_:#_] dmask:0xf dim:SQ_RSRC_IMG_CUBE ; $_ $_
433    pbld.print_ir(VK_SHADER_STAGE_FRAGMENT_BIT, "Assembly");
434 END_TEST
435 
436 BEGIN_TEST(d3d11_derivs.cube_array)
437    // clang-format off
438    QoShaderModuleCreateInfo vs = qoShaderModuleCreateInfoGLSL(VERTEX,
439       layout(location = 0) in vec4 in_coord;
440       layout(location = 0) out vec4 out_coord;
441       void main() {
442          out_coord = in_coord;
443       }
444    );
445    QoShaderModuleCreateInfo fs = qoShaderModuleCreateInfoGLSL(FRAGMENT,
446       layout(location = 0) in vec4 in_coord;
447       layout(location = 0) out vec4 out_color;
448       layout(binding = 0) uniform samplerCubeArray tex;
449       void main() {
450          out_color = vec4(0.0);
451          if (gl_FragCoord.x > 1.0)
452             out_color = texture(tex, in_coord);
453       }
454    );
455    // clang-format on
456 
457    PipelineBuilder pbld(get_vk_device(GFX10_3));
458    pbld.add_vsfs(vs, fs);
459 
460    //>> v1: %face = v_cubeid_f32 (kill)%_, (kill)%_, (kill)%_
461    //>> v1: %x = v_fmaak_f32 (kill)%_, %_, 0x3fc00000
462    //>> v1: %y = v_fmaak_f32 (kill)%_, (kill)%_, 0x3fc00000
463    //>> v1: %layer = v_rndne_f32 (kill)%_
464    //>> v1: %face_layer = v_fmamk_f32 (kill)%layer, (kill)%face, 0x41000000
465    //>> lv3: %wqm = p_start_linear_vgpr (kill)%x, (kill)%y, (kill)%face_layer
466    //>> BB1
467    //>> v4: %_ = image_sample (kill)%_, (kill)%_, v1: undef, (latekill)%wqm cube da
468    //>> BB2
469    //>> BB6
470    //>> p_end_linear_vgpr (kill)%wqm
471    pbld.print_ir(VK_SHADER_STAGE_FRAGMENT_BIT, "ACO IR");
472 
473    //>> v_cubeid_f32 v#rf, v#_, v#_, v#_                                                      ; $_ $_
474 
475    //>> v_fmaak_f32 v#rx_tmp, v#_, v#_, 0x3fc00000                                            ; $_ $_
476    //>> v_fmaak_f32 v#ry_tmp, v#_, v#_, 0x3fc00000                                            ; $_ $_
477    //>> v_fmamk_f32 v#rlf_tmp, v#rl, 0x41000000, v#rf                                         ; $_ $_
478    //>> v_lshrrev_b64 v[#rx:#ry], 0, v[#rx_tmp:#ry_tmp]                                       ; $_ $_
479    //>> v_mov_b32_e32 v#rlf, v#rlf_tmp                                                        ; $_
480 
481    //>> BB1:
482    //; success = rx+1 == ry and rx+2 == rlf
483    //>> image_sample v[#_:#_], v[#rx:#rlf], s[#_:#_], s[#_:#_] dmask:0xf dim:SQ_RSRC_IMG_CUBE ; $_ $_
484    pbld.print_ir(VK_SHADER_STAGE_FRAGMENT_BIT, "Assembly");
485 END_TEST
486 
487 BEGIN_TEST(d3d11_derivs.dfdxy)
488    // clang-format off
489    QoShaderModuleCreateInfo vs = qoShaderModuleCreateInfoGLSL(VERTEX,
490       layout(location = 0) in vec2 in_coord;
491       layout(location = 0) out vec2 out_coord;
492       void main() {
493          out_coord = in_coord;
494       }
495    );
496    QoShaderModuleCreateInfo fs = qoShaderModuleCreateInfoGLSL(FRAGMENT,
497       layout(location = 0) in vec2 in_coord;
498       layout(location = 0) out vec4 out_color;
499       layout(binding = 0) uniform sampler2D tex;
500       void main() {
501          out_color = vec4(0.0);
502          if (gl_FragCoord.x > 1.0)
503             out_color = vec4(dFdxFine(in_coord.x), dFdyCoarse(in_coord.y), textureLod(tex, vec2(0.5), 0.0).xy);
504       }
505    );
506    // clang-format on
507 
508    PipelineBuilder pbld(get_vk_device(GFX10_3));
509    pbld.add_vsfs(vs, fs);
510 
511    /* Must be before BB1 */
512    //>> v1: %_ = v_subrev_f32 (kill)%_, (kill)%_ quad_perm:[0,0,2,2] bound_ctrl:1 fi
513    //>> v1: %_ = v_subrev_f32 (kill)%_, (kill)%_ quad_perm:[0,0,0,0] bound_ctrl:1 fi
514    //>> BB1
515    pbld.print_ir(VK_SHADER_STAGE_FRAGMENT_BIT, "ACO IR");
516 END_TEST
517 
518 /* Ensure the BC optimize transform is done after ac_nir_lower_tex. */
519 BEGIN_TEST(d3d11_derivs.bc_optimize)
520    // clang-format off
521    QoShaderModuleCreateInfo vs = qoShaderModuleCreateInfoGLSL(VERTEX,
522       layout(location = 0) in vec2 in_coord;
523       layout(location = 0) out vec2 out_coord;
524       void main() {
525          out_coord = in_coord;
526       }
527    );
528    QoShaderModuleCreateInfo fs = qoShaderModuleCreateInfoGLSL(FRAGMENT,
529       layout(location = 0) in vec2 in_coord;
530       layout(location = 0) out vec4 out_color;
531       layout(binding = 0) uniform sampler2D tex;
532       void main() {
533          out_color = vec4(0.0);
534          if (gl_FragCoord.x > 1.0)
535             out_color = texture(tex, vec2(in_coord.x, interpolateAtCentroid(in_coord.y)));
536       }
537    );
538    // clang-format on
539 
540    PipelineBuilder pbld(get_vk_device(GFX10_3));
541    pbld.add_vsfs(vs, fs);
542 
543    //>> v1: %y_coord2 = v_cndmask_b32 (kill)%_, %_, (kill)%_
544    //>> v1: %x = v_interp_p2_f32 (kill)%_, %_:m0, (kill)%_ attr0.x
545    //>> v1: %y = v_interp_p2_f32 (kill)%y_coord2, (kill)%_:m0, (kill)%_ attr0.y
546    //>> lv2: %wqm = p_start_linear_vgpr (kill)%x, (kill)%y
547    //>> BB1
548    //>> v4: %_ = image_sample (kill)%_, (kill)%_, v1: undef, (latekill)%wqm 2d
549    //>> BB2
550    //>> BB6
551    //>> p_end_linear_vgpr (kill)%wqm
552    pbld.print_ir(VK_SHADER_STAGE_FRAGMENT_BIT, "ACO IR");
553 END_TEST
554 
555 BEGIN_TEST(d3d11_derivs.get_lod)
556    // clang-format off
557    QoShaderModuleCreateInfo vs = qoShaderModuleCreateInfoGLSL(VERTEX,
558       layout(location = 0) in vec2 in_coord;
559       layout(location = 0) out vec2 out_coord;
560       void main() {
561          out_coord = in_coord;
562       }
563    );
564    QoShaderModuleCreateInfo fs = qoShaderModuleCreateInfoGLSL(FRAGMENT,
565       layout(location = 0) in vec2 in_coord;
566       layout(location = 0) out vec2 out_color;
567       layout(binding = 0) uniform sampler2D tex;
568       void main() {
569          out_color = vec2(0.0);
570          if (gl_FragCoord.x > 1.0)
571             out_color = textureQueryLod(tex, in_coord);
572       }
573    );
574    // clang-format on
575 
576    PipelineBuilder pbld(get_vk_device(GFX10_3));
577    pbld.add_vsfs(vs, fs);
578 
579    //>> v1: %x = v_interp_p2_f32 %_, %_:m0, (kill)%_ attr0.x
580    //>> v1: %y = v_interp_p2_f32 (kill)%_, (kill)%_:m0, (kill)%_ attr0.y
581    //>> lv2: %wqm = p_start_linear_vgpr %x, %y
582    //>> v1: %x12_m_x0 = v_subrev_f32 (kill)%x, (kill)%x quad_perm:[0,0,0,0] bound_ctrl:1 fi
583    //>> v1: %x1_m_x0 = v_mov_b32 %x12_m_x0 quad_perm:[1,1,1,1] bound_ctrl:1 fi
584    //>> v1: %x2_m_x0 = v_mov_b32 (kill)%x12_m_x0 quad_perm:[2,2,2,2] bound_ctrl:1 fi
585    //>> v1: %y12_m_y0 = v_subrev_f32 (kill)%y, (kill)%y quad_perm:[0,0,0,0] bound_ctrl:1 fi
586    //>> v1: %y1_m_y0 = v_mov_b32 %y12_m_x0 quad_perm:[1,1,1,1] bound_ctrl:1 fi
587    //>> v1: %y2_m_y0 = v_mov_b32 (kill)%y12_m_x0 quad_perm:[2,2,2,2] bound_ctrl:1 fi
588    //>> BB1
589    //>> v2: %_ = image_get_lod (kill)%_, (kill)%_, v1: undef, (latekill)%wqm 2d
590    //>> BB2
591    //>> BB6
592    //>> p_end_linear_vgpr (kill)%wqm
593    pbld.print_ir(VK_SHADER_STAGE_FRAGMENT_BIT, "ACO IR");
594 END_TEST
595 
596 BEGIN_TEST(d3d11_derivs.nsa_max)
597    for (amd_gfx_level lvl : {GFX10, GFX10_3, GFX11}) {
598       if (!setup_cs(NULL, lvl))
599          continue;
600 
601       PhysReg reg_v0{256};
602       PhysReg reg_v6{256 + 6};
603       PhysReg reg_v7{256 + 7};
604       PhysReg reg_v8{256 + 8};
605       PhysReg reg_s0{0};
606       PhysReg reg_s8{8};
607 
608       //>> p_unit_test 0
609       bld.pseudo(aco_opcode::p_unit_test, Operand::zero());
610 
611       //~gfx10! v2: %_:v[0-1] = v_lshrrev_b64 0, %_:v[6-7]
612       //~gfx10! v1: %_:v[2] = v_mov_b32 %_:v[8]
613       //~gfx10! v4: %_:v[0-3] = image_sample_c_b_o  %0:s[0-7], %0:s[8-11],  v1: undef, %_:v[0-5] 2darray da
614 
615       //~gfx10_3! v4: %_:v[0-3] = image_sample_c_b_o  %0:s[0-7], %0:s[8-11],  v1: undef, %_:v[6], %_:v[7], %_:v[8], %_:v[3], %_:v[4], %_:v[5] 2darray da
616 
617       //~gfx11! v4: %_:v[0-3] = image_sample_c_b_o  %0:s[0-7], %0:s[8-11],  v1: undef, %_:v[6], %_:v[7], %_:v[8], %_:v[3], %_:v[4-5] 2darray da
618 
619       Instruction* instr =
620          bld.mimg(aco_opcode::image_sample_c_b_o, Definition(reg_v0, v4), Operand(reg_s0, s8),
621                   Operand(reg_s8, s4), Operand(v1), Operand(reg_v0, v6.as_linear()),
622                   Operand(reg_v6, v1), Operand(reg_v7, v1), Operand(reg_v8, v1));
623       instr->mimg().dim = ac_image_2darray;
624       instr->mimg().da = true;
625       instr->mimg().strict_wqm = true;
626 
627       finish_to_hw_instr_test();
628    }
629 END_TEST
630