1 /* 2 * Copyright © 2020 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 <llvm/Config/llvm-config.h> 25 26 #include "helpers.h" 27 #include "test_isel-spirv.h" 28 29 using namespace aco; 30 31 BEGIN_TEST(isel.interp.simple) 32 QoShaderModuleCreateInfo vs = qoShaderModuleCreateInfoGLSL(VERTEX, 33 layout(location = 0) in vec4 in_color; 34 layout(location = 0) out vec4 out_color; 35 void main() { out_color = in_color; 36 } 37 ); 38 QoShaderModuleCreateInfo fs = qoShaderModuleCreateInfoGLSL(FRAGMENT, 39 layout(location = 0) in vec4 in_color; 40 layout(location = 0) out vec4 out_color; 41 void main() { 42 //>> v1: %a_tmp = v_interp_p1_f32 %bx, %pm:m0 attr0.w 43 //! v1: %a = v_interp_p2_f32 %by, %pm:m0, (kill)%a_tmp attr0.w 44 //! v1: %r_tmp = v_interp_p1_f32 %bx, %pm:m0 attr0.x 45 //! v1: %r = v_interp_p2_f32 %by, %pm:m0, (kill)%r_tmp attr0.x 46 //! v1: %g_tmp = v_interp_p1_f32 %bx, %pm:m0 attr0.y 47 //! v1: %g = v_interp_p2_f32 %by, %pm:m0, (kill)%g_tmp attr0.y 48 //! v1: %b_tmp = v_interp_p1_f32 (kill)%bx, %pm:m0 attr0.z 49 //! v1: %b = v_interp_p2_f32 (kill)%by, (kill)%pm:m0, (kill)%b_tmp attr0.z 50 //! exp (kill)%r, (kill)%g, (kill)%b, (kill)%a mrt0 51 out_color = in_color; 52 } 53 ); 54 55 PipelineBuilder pbld(get_vk_device(GFX9)); 56 pbld.add_vsfs(vs, fs); 57 pbld.print_ir(VK_SHADER_STAGE_FRAGMENT_BIT, "ACO IR"); 58 END_TEST 59 60 BEGIN_TEST(isel.compute.simple) 61 for (unsigned i = GFX7; i <= GFX8; i++) { 62 if (!set_variant((amd_gfx_level)i)) 63 continue; 64 65 QoShaderModuleCreateInfo cs = qoShaderModuleCreateInfoGLSL(COMPUTE, 66 layout(local_size_x=1) in; 67 layout(binding=0) buffer Buf { 68 uint res; 69 }; 70 void main() { 71 //>> v1: %data = p_parallelcopy 42 72 //! buffer_store_dword (kill)%_, v1: undef, 0, (kill)%data disable_wqm storage:buffer 73 res = 42; 74 } 75 ); 76 77 PipelineBuilder pbld(get_vk_device((amd_gfx_level)i)); 78 pbld.add_cs(cs); 79 pbld.print_ir(VK_SHADER_STAGE_COMPUTE_BIT, "ACO IR", true); 80 } 81 END_TEST 82 83 BEGIN_TEST(isel.gs.no_outputs) 84 for (unsigned i = GFX8; i <= GFX10; i++) { 85 if (!set_variant((amd_gfx_level)i)) 86 continue; 87 88 QoShaderModuleCreateInfo vs = qoShaderModuleCreateInfoGLSL(VERTEX, 89 void main() {} 90 ); 91 92 QoShaderModuleCreateInfo gs = qoShaderModuleCreateInfoGLSL(GEOMETRY, 93 layout(points) in; 94 layout(points, max_vertices = 1) out; 95 96 void main() { 97 EmitVertex(); 98 EndPrimitive(); 99 } 100 ); 101 102 PipelineBuilder pbld(get_vk_device((amd_gfx_level)i)); 103 pbld.add_stage(VK_SHADER_STAGE_VERTEX_BIT, vs); 104 pbld.add_stage(VK_SHADER_STAGE_GEOMETRY_BIT, gs); 105 pbld.create_pipeline(); 106 107 //! success 108 fprintf(output, "success\n"); 109 } 110 END_TEST 111 112 BEGIN_TEST(isel.gs.no_verts) 113 for (unsigned i = GFX8; i <= GFX10; i++) { 114 if (!set_variant((amd_gfx_level)i)) 115 continue; 116 117 QoShaderModuleCreateInfo vs = qoShaderModuleCreateInfoGLSL(VERTEX, 118 void main() {} 119 ); 120 121 QoShaderModuleCreateInfo gs = qoShaderModuleCreateInfoGLSL(GEOMETRY, 122 layout(points) in; 123 layout(points, max_vertices = 0) out; 124 125 void main() {} 126 ); 127 128 PipelineBuilder pbld(get_vk_device((amd_gfx_level)i)); 129 pbld.add_stage(VK_SHADER_STAGE_VERTEX_BIT, vs); 130 pbld.add_stage(VK_SHADER_STAGE_GEOMETRY_BIT, gs); 131 pbld.create_pipeline(); 132 133 //! success 134 fprintf(output, "success\n"); 135 } 136 END_TEST 137 138 BEGIN_TEST(isel.sparse.clause) 139 for (unsigned i = GFX10_3; i <= GFX10_3; i++) { 140 if (!set_variant((amd_gfx_level)i)) 141 continue; 142 143 QoShaderModuleCreateInfo cs = qoShaderModuleCreateInfoGLSL(COMPUTE, 144 QO_EXTENSION GL_ARB_sparse_texture2 : require 145 layout(local_size_x=1) in; 146 layout(binding=0) uniform sampler2D tex; 147 layout(binding=1) buffer Buf { 148 vec4 res[4]; 149 uint code[4]; 150 }; 151 void main() { 152 //! llvm_version: #llvm_ver 153 //; if llvm_ver >= 12: 154 //; funcs['sample_res'] = lambda _: 'v[#_:#_]' 155 //; funcs['sample_coords'] = lambda _: '[v#_, v#_, v#_]' 156 //; else: 157 //; funcs['sample_res'] = lambda _: 'v#_' 158 //; funcs['sample_coords'] = lambda _: '[v#_, v#_, v#_, v#_]' 159 //>> v5: (noCSE)%zero0 = p_create_vector 0, 0, 0, 0, 0 160 //>> v5: %_ = image_sample_lz_o %_, %_, (kill)%zero0, (kill)%_, %_, %_ dmask:xyzw 2d tfe 161 //>> v5: (noCSE)%zero1 = p_create_vector 0, 0, 0, 0, 0 162 //>> v5: %_ = image_sample_lz_o %_, %_, (kill)%zero1, (kill)%_, %_, %_ dmask:xyzw 2d tfe 163 //>> v5: (noCSE)%zero2 = p_create_vector 0, 0, 0, 0, 0 164 //>> v5: %_ = image_sample_lz_o %_, %_, (kill)%zero2, (kill)%_, %_, %_ dmask:xyzw 2d tfe 165 //>> v5: (noCSE)%zero3 = p_create_vector 0, 0, 0, 0, 0 166 //>> v5: %_ = image_sample_lz_o (kill)%_, (kill)%_, (kill)%zero3, (kill)%_, (kill)%_, (kill)%_ dmask:xyzw 2d tfe 167 //>> s_clause 0x3 168 //! image_sample_lz_o @sample_res, @sample_coords, @s256(img), @s128(samp) dmask:0xf dim:SQ_RSRC_IMG_2D tfe 169 //! image_sample_lz_o @sample_res, @sample_coords, @s256(img), @s128(samp) dmask:0xf dim:SQ_RSRC_IMG_2D tfe 170 //! image_sample_lz_o @sample_res, @sample_coords, @s256(img), @s128(samp) dmask:0xf dim:SQ_RSRC_IMG_2D tfe 171 //! image_sample_lz_o @sample_res, @sample_coords, @s256(img), @s128(samp) dmask:0xf dim:SQ_RSRC_IMG_2D tfe 172 code[0] = sparseTextureOffsetARB(tex, vec2(0.5), ivec2(1, 0), res[0]); 173 code[1] = sparseTextureOffsetARB(tex, vec2(0.5), ivec2(2, 0), res[1]); 174 code[2] = sparseTextureOffsetARB(tex, vec2(0.5), ivec2(3, 0), res[2]); 175 code[3] = sparseTextureOffsetARB(tex, vec2(0.5), ivec2(4, 0), res[3]); 176 } 177 ); 178 179 fprintf(output, "llvm_version: %u\n", LLVM_VERSION_MAJOR); 180 181 PipelineBuilder pbld(get_vk_device((amd_gfx_level)i)); 182 pbld.add_cs(cs); 183 pbld.print_ir(VK_SHADER_STAGE_COMPUTE_BIT, "ACO IR", true); 184 pbld.print_ir(VK_SHADER_STAGE_COMPUTE_BIT, "Assembly", true); 185 } 186 END_TEST 187 188 BEGIN_TEST(isel.discard_early_exit.mrtz) 189 QoShaderModuleCreateInfo vs = qoShaderModuleCreateInfoGLSL(VERTEX, 190 void main() {} 191 ); 192 QoShaderModuleCreateInfo fs = qoShaderModuleCreateInfoGLSL(FRAGMENT, 193 void main() { 194 if (gl_FragCoord.w > 0.5) 195 discard; 196 gl_FragDepth = 1.0 / gl_FragCoord.z; 197 } 198 ); 199 200 /* On GFX11, the discard early exit must use mrtz if the shader exports only depth. */ 201 //>> exp mrtz v0, off, off, off done ; $_ $_ 202 //! s_endpgm ; $_ 203 //! BB1: 204 //! exp mrtz off, off, off, off done ; $_ $_ 205 //! s_endpgm ; $_ 206 207 PipelineBuilder pbld(get_vk_device(GFX11)); 208 pbld.add_vsfs(vs, fs); 209 pbld.print_ir(VK_SHADER_STAGE_FRAGMENT_BIT, "Assembly"); 210 END_TEST 211 212 BEGIN_TEST(isel.discard_early_exit.mrt0) 213 QoShaderModuleCreateInfo vs = qoShaderModuleCreateInfoGLSL(VERTEX, 214 void main() {} 215 ); 216 QoShaderModuleCreateInfo fs = qoShaderModuleCreateInfoGLSL(FRAGMENT, 217 layout(location = 0) out vec4 out_color; 218 void main() { 219 if (gl_FragCoord.w > 0.5) 220 discard; 221 out_color = vec4(1.0 / gl_FragCoord.z); 222 } 223 ); 224 225 /* On GFX11, the discard early exit must use mrt0 if the shader exports color. */ 226 //>> exp mrt0 v0, v0, v0, v0 done ; $_ $_ 227 //! s_endpgm ; $_ 228 //! BB1: 229 //! exp mrt0 off, off, off, off done ; $_ $_ 230 //! s_endpgm ; $_ 231 232 PipelineBuilder pbld(get_vk_device(GFX11)); 233 pbld.add_vsfs(vs, fs); 234 pbld.print_ir(VK_SHADER_STAGE_FRAGMENT_BIT, "Assembly"); 235 END_TEST 236 237 BEGIN_TEST(isel.s_bfe_mask_bits) 238 QoShaderModuleCreateInfo cs = qoShaderModuleCreateInfoGLSL(COMPUTE, 239 layout(local_size_x=1) in; 240 layout(binding=0) buffer Buf { 241 int res; 242 }; 243 void main() { 244 //>> s1: %bits, s1: (kill)%_:scc = s_and_b32 (kill)%_, 31 245 //! s1: %src1 = s_pack_ll_b32_b16 0, (kill)%bits 246 //! s1: %_, s1: (kill)%_:scc = s_bfe_i32 0xdeadbeef, (kill)%src1 247 res = bitfieldExtract(0xdeadbeef, 0, res & 0x1f); 248 } 249 ); 250 251 PipelineBuilder pbld(get_vk_device(GFX10_3)); 252 pbld.add_cs(cs); 253 pbld.print_ir(VK_SHADER_STAGE_COMPUTE_BIT, "ACO IR", true); 254 END_TEST 255