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