1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright 2016 Advanced Micro Devices, Inc. 3bf215546Sopenharmony_ci * All Rights Reserved. 4bf215546Sopenharmony_ci * 5bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 6bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 7bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 8bf215546Sopenharmony_ci * on the rights to use, copy, modify, merge, publish, distribute, sub 9bf215546Sopenharmony_ci * license, and/or sell copies of the Software, and to permit persons to whom 10bf215546Sopenharmony_ci * the Software is furnished to do so, subject to the following conditions: 11bf215546Sopenharmony_ci * 12bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 13bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 14bf215546Sopenharmony_ci * Software. 15bf215546Sopenharmony_ci * 16bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 19bf215546Sopenharmony_ci * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 20bf215546Sopenharmony_ci * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 21bf215546Sopenharmony_ci * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 22bf215546Sopenharmony_ci * USE OR OTHER DEALINGS IN THE SOFTWARE. 23bf215546Sopenharmony_ci */ 24bf215546Sopenharmony_ci 25bf215546Sopenharmony_ci#include "ac_nir.h" 26bf215546Sopenharmony_ci#include "ac_nir_to_llvm.h" 27bf215546Sopenharmony_ci#include "ac_rtld.h" 28bf215546Sopenharmony_ci#include "si_pipe.h" 29bf215546Sopenharmony_ci#include "si_shader_internal.h" 30bf215546Sopenharmony_ci#include "sid.h" 31bf215546Sopenharmony_ci#include "tgsi/tgsi_from_mesa.h" 32bf215546Sopenharmony_ci#include "util/u_memory.h" 33bf215546Sopenharmony_ci 34bf215546Sopenharmony_cistruct si_llvm_diagnostics { 35bf215546Sopenharmony_ci struct util_debug_callback *debug; 36bf215546Sopenharmony_ci unsigned retval; 37bf215546Sopenharmony_ci}; 38bf215546Sopenharmony_ci 39bf215546Sopenharmony_cistatic void si_diagnostic_handler(LLVMDiagnosticInfoRef di, void *context) 40bf215546Sopenharmony_ci{ 41bf215546Sopenharmony_ci struct si_llvm_diagnostics *diag = (struct si_llvm_diagnostics *)context; 42bf215546Sopenharmony_ci LLVMDiagnosticSeverity severity = LLVMGetDiagInfoSeverity(di); 43bf215546Sopenharmony_ci const char *severity_str = NULL; 44bf215546Sopenharmony_ci 45bf215546Sopenharmony_ci switch (severity) { 46bf215546Sopenharmony_ci case LLVMDSError: 47bf215546Sopenharmony_ci severity_str = "error"; 48bf215546Sopenharmony_ci break; 49bf215546Sopenharmony_ci case LLVMDSWarning: 50bf215546Sopenharmony_ci severity_str = "warning"; 51bf215546Sopenharmony_ci break; 52bf215546Sopenharmony_ci case LLVMDSRemark: 53bf215546Sopenharmony_ci case LLVMDSNote: 54bf215546Sopenharmony_ci default: 55bf215546Sopenharmony_ci return; 56bf215546Sopenharmony_ci } 57bf215546Sopenharmony_ci 58bf215546Sopenharmony_ci char *description = LLVMGetDiagInfoDescription(di); 59bf215546Sopenharmony_ci 60bf215546Sopenharmony_ci util_debug_message(diag->debug, SHADER_INFO, "LLVM diagnostic (%s): %s", severity_str, 61bf215546Sopenharmony_ci description); 62bf215546Sopenharmony_ci 63bf215546Sopenharmony_ci if (severity == LLVMDSError) { 64bf215546Sopenharmony_ci diag->retval = 1; 65bf215546Sopenharmony_ci fprintf(stderr, "LLVM triggered Diagnostic Handler: %s\n", description); 66bf215546Sopenharmony_ci } 67bf215546Sopenharmony_ci 68bf215546Sopenharmony_ci LLVMDisposeMessage(description); 69bf215546Sopenharmony_ci} 70bf215546Sopenharmony_ci 71bf215546Sopenharmony_cibool si_compile_llvm(struct si_screen *sscreen, struct si_shader_binary *binary, 72bf215546Sopenharmony_ci struct ac_shader_config *conf, struct ac_llvm_compiler *compiler, 73bf215546Sopenharmony_ci struct ac_llvm_context *ac, struct util_debug_callback *debug, 74bf215546Sopenharmony_ci gl_shader_stage stage, const char *name, bool less_optimized) 75bf215546Sopenharmony_ci{ 76bf215546Sopenharmony_ci unsigned count = p_atomic_inc_return(&sscreen->num_compilations); 77bf215546Sopenharmony_ci 78bf215546Sopenharmony_ci if (si_can_dump_shader(sscreen, stage)) { 79bf215546Sopenharmony_ci fprintf(stderr, "radeonsi: Compiling shader %d\n", count); 80bf215546Sopenharmony_ci 81bf215546Sopenharmony_ci if (!(sscreen->debug_flags & (DBG(NO_IR) | DBG(PREOPT_IR)))) { 82bf215546Sopenharmony_ci fprintf(stderr, "%s LLVM IR:\n\n", name); 83bf215546Sopenharmony_ci ac_dump_module(ac->module); 84bf215546Sopenharmony_ci fprintf(stderr, "\n"); 85bf215546Sopenharmony_ci } 86bf215546Sopenharmony_ci } 87bf215546Sopenharmony_ci 88bf215546Sopenharmony_ci if (sscreen->record_llvm_ir) { 89bf215546Sopenharmony_ci char *ir = LLVMPrintModuleToString(ac->module); 90bf215546Sopenharmony_ci binary->llvm_ir_string = strdup(ir); 91bf215546Sopenharmony_ci LLVMDisposeMessage(ir); 92bf215546Sopenharmony_ci } 93bf215546Sopenharmony_ci 94bf215546Sopenharmony_ci if (!si_replace_shader(count, binary)) { 95bf215546Sopenharmony_ci struct ac_compiler_passes *passes = compiler->passes; 96bf215546Sopenharmony_ci 97bf215546Sopenharmony_ci if (less_optimized && compiler->low_opt_passes) 98bf215546Sopenharmony_ci passes = compiler->low_opt_passes; 99bf215546Sopenharmony_ci 100bf215546Sopenharmony_ci struct si_llvm_diagnostics diag = {debug}; 101bf215546Sopenharmony_ci LLVMContextSetDiagnosticHandler(ac->context, si_diagnostic_handler, &diag); 102bf215546Sopenharmony_ci 103bf215546Sopenharmony_ci if (!ac_compile_module_to_elf(passes, ac->module, (char **)&binary->elf_buffer, 104bf215546Sopenharmony_ci &binary->elf_size)) 105bf215546Sopenharmony_ci diag.retval = 1; 106bf215546Sopenharmony_ci 107bf215546Sopenharmony_ci if (diag.retval != 0) { 108bf215546Sopenharmony_ci util_debug_message(debug, SHADER_INFO, "LLVM compilation failed"); 109bf215546Sopenharmony_ci return false; 110bf215546Sopenharmony_ci } 111bf215546Sopenharmony_ci } 112bf215546Sopenharmony_ci 113bf215546Sopenharmony_ci struct ac_rtld_binary rtld; 114bf215546Sopenharmony_ci if (!ac_rtld_open(&rtld, (struct ac_rtld_open_info){ 115bf215546Sopenharmony_ci .info = &sscreen->info, 116bf215546Sopenharmony_ci .shader_type = stage, 117bf215546Sopenharmony_ci .wave_size = ac->wave_size, 118bf215546Sopenharmony_ci .num_parts = 1, 119bf215546Sopenharmony_ci .elf_ptrs = &binary->elf_buffer, 120bf215546Sopenharmony_ci .elf_sizes = &binary->elf_size})) 121bf215546Sopenharmony_ci return false; 122bf215546Sopenharmony_ci 123bf215546Sopenharmony_ci bool ok = ac_rtld_read_config(&sscreen->info, &rtld, conf); 124bf215546Sopenharmony_ci ac_rtld_close(&rtld); 125bf215546Sopenharmony_ci return ok; 126bf215546Sopenharmony_ci} 127bf215546Sopenharmony_ci 128bf215546Sopenharmony_civoid si_llvm_context_init(struct si_shader_context *ctx, struct si_screen *sscreen, 129bf215546Sopenharmony_ci struct ac_llvm_compiler *compiler, unsigned wave_size) 130bf215546Sopenharmony_ci{ 131bf215546Sopenharmony_ci memset(ctx, 0, sizeof(*ctx)); 132bf215546Sopenharmony_ci ctx->screen = sscreen; 133bf215546Sopenharmony_ci ctx->compiler = compiler; 134bf215546Sopenharmony_ci 135bf215546Sopenharmony_ci ac_llvm_context_init(&ctx->ac, compiler, sscreen->info.gfx_level, sscreen->info.family, 136bf215546Sopenharmony_ci sscreen->info.has_3d_cube_border_color_mipmap, AC_FLOAT_MODE_DEFAULT_OPENGL, wave_size, 64); 137bf215546Sopenharmony_ci} 138bf215546Sopenharmony_ci 139bf215546Sopenharmony_civoid si_llvm_create_func(struct si_shader_context *ctx, const char *name, LLVMTypeRef *return_types, 140bf215546Sopenharmony_ci unsigned num_return_elems, unsigned max_workgroup_size) 141bf215546Sopenharmony_ci{ 142bf215546Sopenharmony_ci LLVMTypeRef ret_type; 143bf215546Sopenharmony_ci enum ac_llvm_calling_convention call_conv; 144bf215546Sopenharmony_ci 145bf215546Sopenharmony_ci if (num_return_elems) 146bf215546Sopenharmony_ci ret_type = LLVMStructTypeInContext(ctx->ac.context, return_types, num_return_elems, true); 147bf215546Sopenharmony_ci else 148bf215546Sopenharmony_ci ret_type = ctx->ac.voidt; 149bf215546Sopenharmony_ci 150bf215546Sopenharmony_ci gl_shader_stage real_stage = ctx->stage; 151bf215546Sopenharmony_ci 152bf215546Sopenharmony_ci /* LS is merged into HS (TCS), and ES is merged into GS. */ 153bf215546Sopenharmony_ci if (ctx->screen->info.gfx_level >= GFX9 && ctx->stage <= MESA_SHADER_GEOMETRY) { 154bf215546Sopenharmony_ci if (ctx->shader->key.ge.as_ls) 155bf215546Sopenharmony_ci real_stage = MESA_SHADER_TESS_CTRL; 156bf215546Sopenharmony_ci else if (ctx->shader->key.ge.as_es || ctx->shader->key.ge.as_ngg) 157bf215546Sopenharmony_ci real_stage = MESA_SHADER_GEOMETRY; 158bf215546Sopenharmony_ci } 159bf215546Sopenharmony_ci 160bf215546Sopenharmony_ci switch (real_stage) { 161bf215546Sopenharmony_ci case MESA_SHADER_VERTEX: 162bf215546Sopenharmony_ci case MESA_SHADER_TESS_EVAL: 163bf215546Sopenharmony_ci call_conv = AC_LLVM_AMDGPU_VS; 164bf215546Sopenharmony_ci break; 165bf215546Sopenharmony_ci case MESA_SHADER_TESS_CTRL: 166bf215546Sopenharmony_ci call_conv = AC_LLVM_AMDGPU_HS; 167bf215546Sopenharmony_ci break; 168bf215546Sopenharmony_ci case MESA_SHADER_GEOMETRY: 169bf215546Sopenharmony_ci call_conv = AC_LLVM_AMDGPU_GS; 170bf215546Sopenharmony_ci break; 171bf215546Sopenharmony_ci case MESA_SHADER_FRAGMENT: 172bf215546Sopenharmony_ci call_conv = AC_LLVM_AMDGPU_PS; 173bf215546Sopenharmony_ci break; 174bf215546Sopenharmony_ci case MESA_SHADER_COMPUTE: 175bf215546Sopenharmony_ci call_conv = AC_LLVM_AMDGPU_CS; 176bf215546Sopenharmony_ci break; 177bf215546Sopenharmony_ci default: 178bf215546Sopenharmony_ci unreachable("Unhandle shader type"); 179bf215546Sopenharmony_ci } 180bf215546Sopenharmony_ci 181bf215546Sopenharmony_ci /* Setup the function */ 182bf215546Sopenharmony_ci ctx->return_type = ret_type; 183bf215546Sopenharmony_ci ctx->main_fn = ac_build_main(&ctx->args, &ctx->ac, call_conv, name, ret_type, ctx->ac.module); 184bf215546Sopenharmony_ci ctx->return_value = LLVMGetUndef(ctx->return_type); 185bf215546Sopenharmony_ci 186bf215546Sopenharmony_ci if (ctx->screen->info.address32_hi) { 187bf215546Sopenharmony_ci ac_llvm_add_target_dep_function_attr(ctx->main_fn, "amdgpu-32bit-address-high-bits", 188bf215546Sopenharmony_ci ctx->screen->info.address32_hi); 189bf215546Sopenharmony_ci } 190bf215546Sopenharmony_ci 191bf215546Sopenharmony_ci if (ctx->stage <= MESA_SHADER_GEOMETRY && ctx->shader->key.ge.as_ngg && 192bf215546Sopenharmony_ci si_shader_uses_streamout(ctx->shader)) 193bf215546Sopenharmony_ci ac_llvm_add_target_dep_function_attr(ctx->main_fn, "amdgpu-gds-size", 256); 194bf215546Sopenharmony_ci 195bf215546Sopenharmony_ci ac_llvm_set_workgroup_size(ctx->main_fn, max_workgroup_size); 196bf215546Sopenharmony_ci ac_llvm_set_target_features(ctx->main_fn, &ctx->ac); 197bf215546Sopenharmony_ci} 198bf215546Sopenharmony_ci 199bf215546Sopenharmony_civoid si_llvm_create_main_func(struct si_shader_context *ctx, bool ngg_cull_shader) 200bf215546Sopenharmony_ci{ 201bf215546Sopenharmony_ci struct si_shader *shader = ctx->shader; 202bf215546Sopenharmony_ci LLVMTypeRef returns[AC_MAX_ARGS]; 203bf215546Sopenharmony_ci unsigned i; 204bf215546Sopenharmony_ci 205bf215546Sopenharmony_ci si_init_shader_args(ctx, ngg_cull_shader); 206bf215546Sopenharmony_ci 207bf215546Sopenharmony_ci for (i = 0; i < ctx->args.num_sgprs_returned; i++) 208bf215546Sopenharmony_ci returns[i] = ctx->ac.i32; /* SGPR */ 209bf215546Sopenharmony_ci for (; i < ctx->args.return_count; i++) 210bf215546Sopenharmony_ci returns[i] = ctx->ac.f32; /* VGPR */ 211bf215546Sopenharmony_ci 212bf215546Sopenharmony_ci si_llvm_create_func(ctx, ngg_cull_shader ? "ngg_cull_main" : "main", returns, 213bf215546Sopenharmony_ci ctx->args.return_count, si_get_max_workgroup_size(shader)); 214bf215546Sopenharmony_ci 215bf215546Sopenharmony_ci /* Reserve register locations for VGPR inputs the PS prolog may need. */ 216bf215546Sopenharmony_ci if (ctx->stage == MESA_SHADER_FRAGMENT && !ctx->shader->is_monolithic) { 217bf215546Sopenharmony_ci ac_llvm_add_target_dep_function_attr( 218bf215546Sopenharmony_ci ctx->main_fn, "InitialPSInputAddr", 219bf215546Sopenharmony_ci S_0286D0_PERSP_SAMPLE_ENA(1) | S_0286D0_PERSP_CENTER_ENA(1) | 220bf215546Sopenharmony_ci S_0286D0_PERSP_CENTROID_ENA(1) | S_0286D0_LINEAR_SAMPLE_ENA(1) | 221bf215546Sopenharmony_ci S_0286D0_LINEAR_CENTER_ENA(1) | S_0286D0_LINEAR_CENTROID_ENA(1) | 222bf215546Sopenharmony_ci S_0286D0_FRONT_FACE_ENA(1) | S_0286D0_ANCILLARY_ENA(1) | 223bf215546Sopenharmony_ci S_0286D0_SAMPLE_COVERAGE_ENA(1) | S_0286D0_POS_FIXED_PT_ENA(1)); 224bf215546Sopenharmony_ci } 225bf215546Sopenharmony_ci 226bf215546Sopenharmony_ci 227bf215546Sopenharmony_ci if (ctx->stage <= MESA_SHADER_GEOMETRY && 228bf215546Sopenharmony_ci (shader->key.ge.as_ls || ctx->stage == MESA_SHADER_TESS_CTRL)) { 229bf215546Sopenharmony_ci if (USE_LDS_SYMBOLS) { 230bf215546Sopenharmony_ci /* The LSHS size is not known until draw time, so we append it 231bf215546Sopenharmony_ci * at the end of whatever LDS use there may be in the rest of 232bf215546Sopenharmony_ci * the shader (currently none, unless LLVM decides to do its 233bf215546Sopenharmony_ci * own LDS-based lowering). 234bf215546Sopenharmony_ci */ 235bf215546Sopenharmony_ci ctx->ac.lds = LLVMAddGlobalInAddressSpace(ctx->ac.module, LLVMArrayType(ctx->ac.i32, 0), 236bf215546Sopenharmony_ci "__lds_end", AC_ADDR_SPACE_LDS); 237bf215546Sopenharmony_ci LLVMSetAlignment(ctx->ac.lds, 256); 238bf215546Sopenharmony_ci } else { 239bf215546Sopenharmony_ci ac_declare_lds_as_pointer(&ctx->ac); 240bf215546Sopenharmony_ci } 241bf215546Sopenharmony_ci } 242bf215546Sopenharmony_ci 243bf215546Sopenharmony_ci /* Unlike radv, we override these arguments in the prolog, so to the 244bf215546Sopenharmony_ci * API shader they appear as normal arguments. 245bf215546Sopenharmony_ci */ 246bf215546Sopenharmony_ci if (ctx->stage == MESA_SHADER_VERTEX) { 247bf215546Sopenharmony_ci ctx->abi.vertex_id = ac_get_arg(&ctx->ac, ctx->args.vertex_id); 248bf215546Sopenharmony_ci ctx->abi.instance_id = ac_get_arg(&ctx->ac, ctx->args.instance_id); 249bf215546Sopenharmony_ci } else if (ctx->stage == MESA_SHADER_FRAGMENT) { 250bf215546Sopenharmony_ci ctx->abi.persp_centroid = ac_get_arg(&ctx->ac, ctx->args.persp_centroid); 251bf215546Sopenharmony_ci ctx->abi.linear_centroid = ac_get_arg(&ctx->ac, ctx->args.linear_centroid); 252bf215546Sopenharmony_ci } 253bf215546Sopenharmony_ci} 254bf215546Sopenharmony_ci 255bf215546Sopenharmony_civoid si_llvm_optimize_module(struct si_shader_context *ctx) 256bf215546Sopenharmony_ci{ 257bf215546Sopenharmony_ci /* Dump LLVM IR before any optimization passes */ 258bf215546Sopenharmony_ci if (ctx->screen->debug_flags & DBG(PREOPT_IR) && si_can_dump_shader(ctx->screen, ctx->stage)) 259bf215546Sopenharmony_ci LLVMDumpModule(ctx->ac.module); 260bf215546Sopenharmony_ci 261bf215546Sopenharmony_ci /* Run the pass */ 262bf215546Sopenharmony_ci LLVMRunPassManager(ctx->compiler->passmgr, ctx->ac.module); 263bf215546Sopenharmony_ci LLVMDisposeBuilder(ctx->ac.builder); 264bf215546Sopenharmony_ci} 265bf215546Sopenharmony_ci 266bf215546Sopenharmony_civoid si_llvm_dispose(struct si_shader_context *ctx) 267bf215546Sopenharmony_ci{ 268bf215546Sopenharmony_ci LLVMDisposeModule(ctx->ac.module); 269bf215546Sopenharmony_ci LLVMContextDispose(ctx->ac.context); 270bf215546Sopenharmony_ci ac_llvm_context_dispose(&ctx->ac); 271bf215546Sopenharmony_ci} 272bf215546Sopenharmony_ci 273bf215546Sopenharmony_ci/** 274bf215546Sopenharmony_ci * Load a dword from a constant buffer. 275bf215546Sopenharmony_ci */ 276bf215546Sopenharmony_ciLLVMValueRef si_buffer_load_const(struct si_shader_context *ctx, LLVMValueRef resource, 277bf215546Sopenharmony_ci LLVMValueRef offset) 278bf215546Sopenharmony_ci{ 279bf215546Sopenharmony_ci return ac_build_buffer_load(&ctx->ac, resource, 1, NULL, offset, NULL, ctx->ac.f32, 280bf215546Sopenharmony_ci 0, true, true); 281bf215546Sopenharmony_ci} 282bf215546Sopenharmony_ci 283bf215546Sopenharmony_civoid si_llvm_build_ret(struct si_shader_context *ctx, LLVMValueRef ret) 284bf215546Sopenharmony_ci{ 285bf215546Sopenharmony_ci if (LLVMGetTypeKind(LLVMTypeOf(ret)) == LLVMVoidTypeKind) 286bf215546Sopenharmony_ci LLVMBuildRetVoid(ctx->ac.builder); 287bf215546Sopenharmony_ci else 288bf215546Sopenharmony_ci LLVMBuildRet(ctx->ac.builder, ret); 289bf215546Sopenharmony_ci} 290bf215546Sopenharmony_ci 291bf215546Sopenharmony_ciLLVMValueRef si_insert_input_ret(struct si_shader_context *ctx, LLVMValueRef ret, 292bf215546Sopenharmony_ci struct ac_arg param, unsigned return_index) 293bf215546Sopenharmony_ci{ 294bf215546Sopenharmony_ci return LLVMBuildInsertValue(ctx->ac.builder, ret, ac_get_arg(&ctx->ac, param), return_index, ""); 295bf215546Sopenharmony_ci} 296bf215546Sopenharmony_ci 297bf215546Sopenharmony_ciLLVMValueRef si_insert_input_ret_float(struct si_shader_context *ctx, LLVMValueRef ret, 298bf215546Sopenharmony_ci struct ac_arg param, unsigned return_index) 299bf215546Sopenharmony_ci{ 300bf215546Sopenharmony_ci LLVMBuilderRef builder = ctx->ac.builder; 301bf215546Sopenharmony_ci LLVMValueRef p = ac_get_arg(&ctx->ac, param); 302bf215546Sopenharmony_ci 303bf215546Sopenharmony_ci return LLVMBuildInsertValue(builder, ret, ac_to_float(&ctx->ac, p), return_index, ""); 304bf215546Sopenharmony_ci} 305bf215546Sopenharmony_ci 306bf215546Sopenharmony_ciLLVMValueRef si_insert_input_ptr(struct si_shader_context *ctx, LLVMValueRef ret, 307bf215546Sopenharmony_ci struct ac_arg param, unsigned return_index) 308bf215546Sopenharmony_ci{ 309bf215546Sopenharmony_ci LLVMBuilderRef builder = ctx->ac.builder; 310bf215546Sopenharmony_ci LLVMValueRef ptr = ac_get_arg(&ctx->ac, param); 311bf215546Sopenharmony_ci ptr = LLVMBuildPtrToInt(builder, ptr, ctx->ac.i32, ""); 312bf215546Sopenharmony_ci return LLVMBuildInsertValue(builder, ret, ptr, return_index, ""); 313bf215546Sopenharmony_ci} 314bf215546Sopenharmony_ci 315bf215546Sopenharmony_ciLLVMValueRef si_prolog_get_internal_bindings(struct si_shader_context *ctx) 316bf215546Sopenharmony_ci{ 317bf215546Sopenharmony_ci LLVMValueRef ptr[2], list; 318bf215546Sopenharmony_ci bool merged_shader = si_is_merged_shader(ctx->shader); 319bf215546Sopenharmony_ci 320bf215546Sopenharmony_ci ptr[0] = LLVMGetParam(ctx->main_fn, (merged_shader ? 8 : 0) + SI_SGPR_INTERNAL_BINDINGS); 321bf215546Sopenharmony_ci list = 322bf215546Sopenharmony_ci LLVMBuildIntToPtr(ctx->ac.builder, ptr[0], ac_array_in_const32_addr_space(ctx->ac.v4i32), ""); 323bf215546Sopenharmony_ci return list; 324bf215546Sopenharmony_ci} 325bf215546Sopenharmony_ci 326bf215546Sopenharmony_ci/* Ensure that the esgs ring is declared. 327bf215546Sopenharmony_ci * 328bf215546Sopenharmony_ci * We declare it with 64KB alignment as a hint that the 329bf215546Sopenharmony_ci * pointer value will always be 0. 330bf215546Sopenharmony_ci */ 331bf215546Sopenharmony_civoid si_llvm_declare_esgs_ring(struct si_shader_context *ctx) 332bf215546Sopenharmony_ci{ 333bf215546Sopenharmony_ci if (ctx->esgs_ring) 334bf215546Sopenharmony_ci return; 335bf215546Sopenharmony_ci 336bf215546Sopenharmony_ci assert(!LLVMGetNamedGlobal(ctx->ac.module, "esgs_ring")); 337bf215546Sopenharmony_ci 338bf215546Sopenharmony_ci ctx->esgs_ring = LLVMAddGlobalInAddressSpace(ctx->ac.module, LLVMArrayType(ctx->ac.i32, 0), 339bf215546Sopenharmony_ci "esgs_ring", AC_ADDR_SPACE_LDS); 340bf215546Sopenharmony_ci LLVMSetLinkage(ctx->esgs_ring, LLVMExternalLinkage); 341bf215546Sopenharmony_ci LLVMSetAlignment(ctx->esgs_ring, 64 * 1024); 342bf215546Sopenharmony_ci} 343bf215546Sopenharmony_ci 344bf215546Sopenharmony_cistatic void si_init_exec_from_input(struct si_shader_context *ctx, struct ac_arg param, 345bf215546Sopenharmony_ci unsigned bitoffset) 346bf215546Sopenharmony_ci{ 347bf215546Sopenharmony_ci LLVMValueRef args[] = { 348bf215546Sopenharmony_ci ac_get_arg(&ctx->ac, param), 349bf215546Sopenharmony_ci LLVMConstInt(ctx->ac.i32, bitoffset, 0), 350bf215546Sopenharmony_ci }; 351bf215546Sopenharmony_ci ac_build_intrinsic(&ctx->ac, "llvm.amdgcn.init.exec.from.input", ctx->ac.voidt, args, 2, 352bf215546Sopenharmony_ci AC_FUNC_ATTR_CONVERGENT); 353bf215546Sopenharmony_ci} 354bf215546Sopenharmony_ci 355bf215546Sopenharmony_ci/** 356bf215546Sopenharmony_ci * Get the value of a shader input parameter and extract a bitfield. 357bf215546Sopenharmony_ci */ 358bf215546Sopenharmony_cistatic LLVMValueRef unpack_llvm_param(struct si_shader_context *ctx, LLVMValueRef value, 359bf215546Sopenharmony_ci unsigned rshift, unsigned bitwidth) 360bf215546Sopenharmony_ci{ 361bf215546Sopenharmony_ci if (LLVMGetTypeKind(LLVMTypeOf(value)) == LLVMFloatTypeKind) 362bf215546Sopenharmony_ci value = ac_to_integer(&ctx->ac, value); 363bf215546Sopenharmony_ci 364bf215546Sopenharmony_ci if (rshift) 365bf215546Sopenharmony_ci value = LLVMBuildLShr(ctx->ac.builder, value, LLVMConstInt(ctx->ac.i32, rshift, 0), ""); 366bf215546Sopenharmony_ci 367bf215546Sopenharmony_ci if (rshift + bitwidth < 32) { 368bf215546Sopenharmony_ci unsigned mask = (1 << bitwidth) - 1; 369bf215546Sopenharmony_ci value = LLVMBuildAnd(ctx->ac.builder, value, LLVMConstInt(ctx->ac.i32, mask, 0), ""); 370bf215546Sopenharmony_ci } 371bf215546Sopenharmony_ci 372bf215546Sopenharmony_ci return value; 373bf215546Sopenharmony_ci} 374bf215546Sopenharmony_ci 375bf215546Sopenharmony_ciLLVMValueRef si_unpack_param(struct si_shader_context *ctx, struct ac_arg param, unsigned rshift, 376bf215546Sopenharmony_ci unsigned bitwidth) 377bf215546Sopenharmony_ci{ 378bf215546Sopenharmony_ci LLVMValueRef value = ac_get_arg(&ctx->ac, param); 379bf215546Sopenharmony_ci 380bf215546Sopenharmony_ci return unpack_llvm_param(ctx, value, rshift, bitwidth); 381bf215546Sopenharmony_ci} 382bf215546Sopenharmony_ci 383bf215546Sopenharmony_ciLLVMValueRef si_get_primitive_id(struct si_shader_context *ctx, unsigned swizzle) 384bf215546Sopenharmony_ci{ 385bf215546Sopenharmony_ci if (swizzle > 0) 386bf215546Sopenharmony_ci return ctx->ac.i32_0; 387bf215546Sopenharmony_ci 388bf215546Sopenharmony_ci switch (ctx->stage) { 389bf215546Sopenharmony_ci case MESA_SHADER_VERTEX: 390bf215546Sopenharmony_ci return ac_get_arg(&ctx->ac, ctx->args.vs_prim_id); 391bf215546Sopenharmony_ci case MESA_SHADER_TESS_CTRL: 392bf215546Sopenharmony_ci return ac_get_arg(&ctx->ac, ctx->args.tcs_patch_id); 393bf215546Sopenharmony_ci case MESA_SHADER_TESS_EVAL: 394bf215546Sopenharmony_ci return ac_get_arg(&ctx->ac, ctx->args.tes_patch_id); 395bf215546Sopenharmony_ci case MESA_SHADER_GEOMETRY: 396bf215546Sopenharmony_ci return ac_get_arg(&ctx->ac, ctx->args.gs_prim_id); 397bf215546Sopenharmony_ci default: 398bf215546Sopenharmony_ci assert(0); 399bf215546Sopenharmony_ci return ctx->ac.i32_0; 400bf215546Sopenharmony_ci } 401bf215546Sopenharmony_ci} 402bf215546Sopenharmony_ci 403bf215546Sopenharmony_cistatic void si_llvm_declare_compute_memory(struct si_shader_context *ctx) 404bf215546Sopenharmony_ci{ 405bf215546Sopenharmony_ci struct si_shader_selector *sel = ctx->shader->selector; 406bf215546Sopenharmony_ci unsigned lds_size = sel->info.base.shared_size; 407bf215546Sopenharmony_ci 408bf215546Sopenharmony_ci LLVMTypeRef i8p = LLVMPointerType(ctx->ac.i8, AC_ADDR_SPACE_LDS); 409bf215546Sopenharmony_ci LLVMValueRef var; 410bf215546Sopenharmony_ci 411bf215546Sopenharmony_ci assert(!ctx->ac.lds); 412bf215546Sopenharmony_ci 413bf215546Sopenharmony_ci var = LLVMAddGlobalInAddressSpace(ctx->ac.module, LLVMArrayType(ctx->ac.i8, lds_size), 414bf215546Sopenharmony_ci "compute_lds", AC_ADDR_SPACE_LDS); 415bf215546Sopenharmony_ci LLVMSetAlignment(var, 64 * 1024); 416bf215546Sopenharmony_ci 417bf215546Sopenharmony_ci ctx->ac.lds = LLVMBuildBitCast(ctx->ac.builder, var, i8p, ""); 418bf215546Sopenharmony_ci} 419bf215546Sopenharmony_ci 420bf215546Sopenharmony_ci/** 421bf215546Sopenharmony_ci * Given a list of shader part functions, build a wrapper function that 422bf215546Sopenharmony_ci * runs them in sequence to form a monolithic shader. 423bf215546Sopenharmony_ci */ 424bf215546Sopenharmony_civoid si_build_wrapper_function(struct si_shader_context *ctx, LLVMValueRef *parts, 425bf215546Sopenharmony_ci unsigned num_parts, unsigned main_part, 426bf215546Sopenharmony_ci unsigned next_shader_first_part, bool same_thread_count) 427bf215546Sopenharmony_ci{ 428bf215546Sopenharmony_ci LLVMBuilderRef builder = ctx->ac.builder; 429bf215546Sopenharmony_ci /* PS epilog has one arg per color component; gfx9 merged shader 430bf215546Sopenharmony_ci * prologs need to forward 40 SGPRs. 431bf215546Sopenharmony_ci */ 432bf215546Sopenharmony_ci LLVMValueRef initial[AC_MAX_ARGS], out[AC_MAX_ARGS]; 433bf215546Sopenharmony_ci LLVMTypeRef function_type; 434bf215546Sopenharmony_ci unsigned num_first_params; 435bf215546Sopenharmony_ci unsigned num_out, initial_num_out; 436bf215546Sopenharmony_ci ASSERTED unsigned num_out_sgpr; /* used in debug checks */ 437bf215546Sopenharmony_ci ASSERTED unsigned initial_num_out_sgpr; /* used in debug checks */ 438bf215546Sopenharmony_ci unsigned num_sgprs, num_vgprs; 439bf215546Sopenharmony_ci unsigned gprs; 440bf215546Sopenharmony_ci 441bf215546Sopenharmony_ci memset(&ctx->args, 0, sizeof(ctx->args)); 442bf215546Sopenharmony_ci 443bf215546Sopenharmony_ci for (unsigned i = 0; i < num_parts; ++i) { 444bf215546Sopenharmony_ci ac_add_function_attr(ctx->ac.context, parts[i], -1, AC_FUNC_ATTR_ALWAYSINLINE); 445bf215546Sopenharmony_ci LLVMSetLinkage(parts[i], LLVMPrivateLinkage); 446bf215546Sopenharmony_ci } 447bf215546Sopenharmony_ci 448bf215546Sopenharmony_ci /* The parameters of the wrapper function correspond to those of the 449bf215546Sopenharmony_ci * first part in terms of SGPRs and VGPRs, but we use the types of the 450bf215546Sopenharmony_ci * main part to get the right types. This is relevant for the 451bf215546Sopenharmony_ci * dereferenceable attribute on descriptor table pointers. 452bf215546Sopenharmony_ci */ 453bf215546Sopenharmony_ci num_sgprs = 0; 454bf215546Sopenharmony_ci num_vgprs = 0; 455bf215546Sopenharmony_ci 456bf215546Sopenharmony_ci function_type = LLVMGetElementType(LLVMTypeOf(parts[0])); 457bf215546Sopenharmony_ci num_first_params = LLVMCountParamTypes(function_type); 458bf215546Sopenharmony_ci 459bf215546Sopenharmony_ci for (unsigned i = 0; i < num_first_params; ++i) { 460bf215546Sopenharmony_ci LLVMValueRef param = LLVMGetParam(parts[0], i); 461bf215546Sopenharmony_ci 462bf215546Sopenharmony_ci if (ac_is_sgpr_param(param)) { 463bf215546Sopenharmony_ci assert(num_vgprs == 0); 464bf215546Sopenharmony_ci num_sgprs += ac_get_type_size(LLVMTypeOf(param)) / 4; 465bf215546Sopenharmony_ci } else { 466bf215546Sopenharmony_ci num_vgprs += ac_get_type_size(LLVMTypeOf(param)) / 4; 467bf215546Sopenharmony_ci } 468bf215546Sopenharmony_ci } 469bf215546Sopenharmony_ci 470bf215546Sopenharmony_ci gprs = 0; 471bf215546Sopenharmony_ci while (gprs < num_sgprs + num_vgprs) { 472bf215546Sopenharmony_ci LLVMValueRef param = LLVMGetParam(parts[main_part], ctx->args.arg_count); 473bf215546Sopenharmony_ci LLVMTypeRef type = LLVMTypeOf(param); 474bf215546Sopenharmony_ci unsigned size = ac_get_type_size(type) / 4; 475bf215546Sopenharmony_ci 476bf215546Sopenharmony_ci /* This is going to get casted anyways, so we don't have to 477bf215546Sopenharmony_ci * have the exact same type. But we do have to preserve the 478bf215546Sopenharmony_ci * pointer-ness so that LLVM knows about it. 479bf215546Sopenharmony_ci */ 480bf215546Sopenharmony_ci enum ac_arg_type arg_type = AC_ARG_INT; 481bf215546Sopenharmony_ci if (LLVMGetTypeKind(type) == LLVMPointerTypeKind) { 482bf215546Sopenharmony_ci type = LLVMGetElementType(type); 483bf215546Sopenharmony_ci 484bf215546Sopenharmony_ci if (LLVMGetTypeKind(type) == LLVMVectorTypeKind) { 485bf215546Sopenharmony_ci if (LLVMGetVectorSize(type) == 4) 486bf215546Sopenharmony_ci arg_type = AC_ARG_CONST_DESC_PTR; 487bf215546Sopenharmony_ci else if (LLVMGetVectorSize(type) == 8) 488bf215546Sopenharmony_ci arg_type = AC_ARG_CONST_IMAGE_PTR; 489bf215546Sopenharmony_ci else 490bf215546Sopenharmony_ci assert(0); 491bf215546Sopenharmony_ci } else if (type == ctx->ac.f32) { 492bf215546Sopenharmony_ci arg_type = AC_ARG_CONST_FLOAT_PTR; 493bf215546Sopenharmony_ci } else { 494bf215546Sopenharmony_ci assert(0); 495bf215546Sopenharmony_ci } 496bf215546Sopenharmony_ci } 497bf215546Sopenharmony_ci 498bf215546Sopenharmony_ci ac_add_arg(&ctx->args, gprs < num_sgprs ? AC_ARG_SGPR : AC_ARG_VGPR, size, arg_type, NULL); 499bf215546Sopenharmony_ci 500bf215546Sopenharmony_ci assert(ac_is_sgpr_param(param) == (gprs < num_sgprs)); 501bf215546Sopenharmony_ci assert(gprs + size <= num_sgprs + num_vgprs && 502bf215546Sopenharmony_ci (gprs >= num_sgprs || gprs + size <= num_sgprs)); 503bf215546Sopenharmony_ci 504bf215546Sopenharmony_ci gprs += size; 505bf215546Sopenharmony_ci } 506bf215546Sopenharmony_ci 507bf215546Sopenharmony_ci /* Prepare the return type. */ 508bf215546Sopenharmony_ci unsigned num_returns = 0; 509bf215546Sopenharmony_ci LLVMTypeRef returns[AC_MAX_ARGS], last_func_type, return_type; 510bf215546Sopenharmony_ci 511bf215546Sopenharmony_ci last_func_type = LLVMGetElementType(LLVMTypeOf(parts[num_parts - 1])); 512bf215546Sopenharmony_ci return_type = LLVMGetReturnType(last_func_type); 513bf215546Sopenharmony_ci 514bf215546Sopenharmony_ci switch (LLVMGetTypeKind(return_type)) { 515bf215546Sopenharmony_ci case LLVMStructTypeKind: 516bf215546Sopenharmony_ci num_returns = LLVMCountStructElementTypes(return_type); 517bf215546Sopenharmony_ci assert(num_returns <= ARRAY_SIZE(returns)); 518bf215546Sopenharmony_ci LLVMGetStructElementTypes(return_type, returns); 519bf215546Sopenharmony_ci break; 520bf215546Sopenharmony_ci case LLVMVoidTypeKind: 521bf215546Sopenharmony_ci break; 522bf215546Sopenharmony_ci default: 523bf215546Sopenharmony_ci unreachable("unexpected type"); 524bf215546Sopenharmony_ci } 525bf215546Sopenharmony_ci 526bf215546Sopenharmony_ci si_llvm_create_func(ctx, "wrapper", returns, num_returns, 527bf215546Sopenharmony_ci si_get_max_workgroup_size(ctx->shader)); 528bf215546Sopenharmony_ci 529bf215546Sopenharmony_ci if (si_is_merged_shader(ctx->shader) && !same_thread_count) 530bf215546Sopenharmony_ci ac_init_exec_full_mask(&ctx->ac); 531bf215546Sopenharmony_ci 532bf215546Sopenharmony_ci /* Record the arguments of the function as if they were an output of 533bf215546Sopenharmony_ci * a previous part. 534bf215546Sopenharmony_ci */ 535bf215546Sopenharmony_ci num_out = 0; 536bf215546Sopenharmony_ci num_out_sgpr = 0; 537bf215546Sopenharmony_ci 538bf215546Sopenharmony_ci for (unsigned i = 0; i < ctx->args.arg_count; ++i) { 539bf215546Sopenharmony_ci LLVMValueRef param = LLVMGetParam(ctx->main_fn, i); 540bf215546Sopenharmony_ci LLVMTypeRef param_type = LLVMTypeOf(param); 541bf215546Sopenharmony_ci LLVMTypeRef out_type = ctx->args.args[i].file == AC_ARG_SGPR ? ctx->ac.i32 : ctx->ac.f32; 542bf215546Sopenharmony_ci unsigned size = ac_get_type_size(param_type) / 4; 543bf215546Sopenharmony_ci 544bf215546Sopenharmony_ci if (size == 1) { 545bf215546Sopenharmony_ci if (LLVMGetTypeKind(param_type) == LLVMPointerTypeKind) { 546bf215546Sopenharmony_ci param = LLVMBuildPtrToInt(builder, param, ctx->ac.i32, ""); 547bf215546Sopenharmony_ci param_type = ctx->ac.i32; 548bf215546Sopenharmony_ci } 549bf215546Sopenharmony_ci 550bf215546Sopenharmony_ci if (param_type != out_type) 551bf215546Sopenharmony_ci param = LLVMBuildBitCast(builder, param, out_type, ""); 552bf215546Sopenharmony_ci out[num_out++] = param; 553bf215546Sopenharmony_ci } else { 554bf215546Sopenharmony_ci LLVMTypeRef vector_type = LLVMVectorType(out_type, size); 555bf215546Sopenharmony_ci 556bf215546Sopenharmony_ci if (LLVMGetTypeKind(param_type) == LLVMPointerTypeKind) { 557bf215546Sopenharmony_ci param = LLVMBuildPtrToInt(builder, param, ctx->ac.i64, ""); 558bf215546Sopenharmony_ci param_type = ctx->ac.i64; 559bf215546Sopenharmony_ci } 560bf215546Sopenharmony_ci 561bf215546Sopenharmony_ci if (param_type != vector_type) 562bf215546Sopenharmony_ci param = LLVMBuildBitCast(builder, param, vector_type, ""); 563bf215546Sopenharmony_ci 564bf215546Sopenharmony_ci for (unsigned j = 0; j < size; ++j) 565bf215546Sopenharmony_ci out[num_out++] = 566bf215546Sopenharmony_ci LLVMBuildExtractElement(builder, param, LLVMConstInt(ctx->ac.i32, j, 0), ""); 567bf215546Sopenharmony_ci } 568bf215546Sopenharmony_ci 569bf215546Sopenharmony_ci if (ctx->args.args[i].file == AC_ARG_SGPR) 570bf215546Sopenharmony_ci num_out_sgpr = num_out; 571bf215546Sopenharmony_ci } 572bf215546Sopenharmony_ci 573bf215546Sopenharmony_ci memcpy(initial, out, sizeof(out)); 574bf215546Sopenharmony_ci initial_num_out = num_out; 575bf215546Sopenharmony_ci initial_num_out_sgpr = num_out_sgpr; 576bf215546Sopenharmony_ci 577bf215546Sopenharmony_ci /* Now chain the parts. */ 578bf215546Sopenharmony_ci LLVMValueRef ret = NULL; 579bf215546Sopenharmony_ci for (unsigned part = 0; part < num_parts; ++part) { 580bf215546Sopenharmony_ci LLVMValueRef in[AC_MAX_ARGS]; 581bf215546Sopenharmony_ci LLVMTypeRef ret_type; 582bf215546Sopenharmony_ci unsigned out_idx = 0; 583bf215546Sopenharmony_ci unsigned num_params = LLVMCountParams(parts[part]); 584bf215546Sopenharmony_ci 585bf215546Sopenharmony_ci /* Merged shaders are executed conditionally depending 586bf215546Sopenharmony_ci * on the number of enabled threads passed in the input SGPRs. */ 587bf215546Sopenharmony_ci if (si_is_multi_part_shader(ctx->shader) && part == 0) { 588bf215546Sopenharmony_ci if (same_thread_count) { 589bf215546Sopenharmony_ci struct ac_arg arg; 590bf215546Sopenharmony_ci arg.arg_index = 3; 591bf215546Sopenharmony_ci arg.used = true; 592bf215546Sopenharmony_ci 593bf215546Sopenharmony_ci si_init_exec_from_input(ctx, arg, 0); 594bf215546Sopenharmony_ci } else { 595bf215546Sopenharmony_ci LLVMValueRef ena, count = initial[3]; 596bf215546Sopenharmony_ci 597bf215546Sopenharmony_ci count = LLVMBuildAnd(builder, count, LLVMConstInt(ctx->ac.i32, 0x7f, 0), ""); 598bf215546Sopenharmony_ci ena = LLVMBuildICmp(builder, LLVMIntULT, ac_get_thread_id(&ctx->ac), count, ""); 599bf215546Sopenharmony_ci ac_build_ifcc(&ctx->ac, ena, 6506); 600bf215546Sopenharmony_ci } 601bf215546Sopenharmony_ci } 602bf215546Sopenharmony_ci 603bf215546Sopenharmony_ci /* Derive arguments for the next part from outputs of the 604bf215546Sopenharmony_ci * previous one. 605bf215546Sopenharmony_ci */ 606bf215546Sopenharmony_ci for (unsigned param_idx = 0; param_idx < num_params; ++param_idx) { 607bf215546Sopenharmony_ci LLVMValueRef param; 608bf215546Sopenharmony_ci LLVMTypeRef param_type; 609bf215546Sopenharmony_ci bool is_sgpr; 610bf215546Sopenharmony_ci unsigned param_size; 611bf215546Sopenharmony_ci LLVMValueRef arg = NULL; 612bf215546Sopenharmony_ci 613bf215546Sopenharmony_ci param = LLVMGetParam(parts[part], param_idx); 614bf215546Sopenharmony_ci param_type = LLVMTypeOf(param); 615bf215546Sopenharmony_ci param_size = ac_get_type_size(param_type) / 4; 616bf215546Sopenharmony_ci is_sgpr = ac_is_sgpr_param(param); 617bf215546Sopenharmony_ci 618bf215546Sopenharmony_ci if (is_sgpr) { 619bf215546Sopenharmony_ci ac_add_function_attr(ctx->ac.context, parts[part], param_idx + 1, AC_FUNC_ATTR_INREG); 620bf215546Sopenharmony_ci } else if (out_idx < num_out_sgpr) { 621bf215546Sopenharmony_ci /* Skip returned SGPRs the current part doesn't 622bf215546Sopenharmony_ci * declare on the input. */ 623bf215546Sopenharmony_ci out_idx = num_out_sgpr; 624bf215546Sopenharmony_ci } 625bf215546Sopenharmony_ci 626bf215546Sopenharmony_ci assert(out_idx + param_size <= (is_sgpr ? num_out_sgpr : num_out)); 627bf215546Sopenharmony_ci 628bf215546Sopenharmony_ci if (param_size == 1) 629bf215546Sopenharmony_ci arg = out[out_idx]; 630bf215546Sopenharmony_ci else 631bf215546Sopenharmony_ci arg = ac_build_gather_values(&ctx->ac, &out[out_idx], param_size); 632bf215546Sopenharmony_ci 633bf215546Sopenharmony_ci if (LLVMTypeOf(arg) != param_type) { 634bf215546Sopenharmony_ci if (LLVMGetTypeKind(param_type) == LLVMPointerTypeKind) { 635bf215546Sopenharmony_ci if (LLVMGetPointerAddressSpace(param_type) == AC_ADDR_SPACE_CONST_32BIT) { 636bf215546Sopenharmony_ci arg = LLVMBuildBitCast(builder, arg, ctx->ac.i32, ""); 637bf215546Sopenharmony_ci arg = LLVMBuildIntToPtr(builder, arg, param_type, ""); 638bf215546Sopenharmony_ci } else { 639bf215546Sopenharmony_ci arg = LLVMBuildBitCast(builder, arg, ctx->ac.i64, ""); 640bf215546Sopenharmony_ci arg = LLVMBuildIntToPtr(builder, arg, param_type, ""); 641bf215546Sopenharmony_ci } 642bf215546Sopenharmony_ci } else { 643bf215546Sopenharmony_ci arg = LLVMBuildBitCast(builder, arg, param_type, ""); 644bf215546Sopenharmony_ci } 645bf215546Sopenharmony_ci } 646bf215546Sopenharmony_ci 647bf215546Sopenharmony_ci in[param_idx] = arg; 648bf215546Sopenharmony_ci out_idx += param_size; 649bf215546Sopenharmony_ci } 650bf215546Sopenharmony_ci 651bf215546Sopenharmony_ci ret = ac_build_call(&ctx->ac, parts[part], in, num_params); 652bf215546Sopenharmony_ci 653bf215546Sopenharmony_ci if (!same_thread_count && 654bf215546Sopenharmony_ci si_is_multi_part_shader(ctx->shader) && part + 1 == next_shader_first_part) { 655bf215546Sopenharmony_ci ac_build_endif(&ctx->ac, 6506); 656bf215546Sopenharmony_ci 657bf215546Sopenharmony_ci /* The second half of the merged shader should use 658bf215546Sopenharmony_ci * the inputs from the toplevel (wrapper) function, 659bf215546Sopenharmony_ci * not the return value from the last call. 660bf215546Sopenharmony_ci * 661bf215546Sopenharmony_ci * That's because the last call was executed condi- 662bf215546Sopenharmony_ci * tionally, so we can't consume it in the main 663bf215546Sopenharmony_ci * block. 664bf215546Sopenharmony_ci */ 665bf215546Sopenharmony_ci memcpy(out, initial, sizeof(initial)); 666bf215546Sopenharmony_ci num_out = initial_num_out; 667bf215546Sopenharmony_ci num_out_sgpr = initial_num_out_sgpr; 668bf215546Sopenharmony_ci 669bf215546Sopenharmony_ci /* Execute the second shader conditionally based on the number of 670bf215546Sopenharmony_ci * enabled threads there. 671bf215546Sopenharmony_ci */ 672bf215546Sopenharmony_ci if (ctx->stage == MESA_SHADER_TESS_CTRL) { 673bf215546Sopenharmony_ci LLVMValueRef ena, count = initial[3]; 674bf215546Sopenharmony_ci 675bf215546Sopenharmony_ci count = LLVMBuildLShr(builder, count, LLVMConstInt(ctx->ac.i32, 8, 0), ""); 676bf215546Sopenharmony_ci count = LLVMBuildAnd(builder, count, LLVMConstInt(ctx->ac.i32, 0x7f, 0), ""); 677bf215546Sopenharmony_ci ena = LLVMBuildICmp(builder, LLVMIntULT, ac_get_thread_id(&ctx->ac), count, ""); 678bf215546Sopenharmony_ci ac_build_ifcc(&ctx->ac, ena, 6507); 679bf215546Sopenharmony_ci } 680bf215546Sopenharmony_ci continue; 681bf215546Sopenharmony_ci } 682bf215546Sopenharmony_ci 683bf215546Sopenharmony_ci /* Extract the returned GPRs. */ 684bf215546Sopenharmony_ci ret_type = LLVMTypeOf(ret); 685bf215546Sopenharmony_ci num_out = 0; 686bf215546Sopenharmony_ci num_out_sgpr = 0; 687bf215546Sopenharmony_ci 688bf215546Sopenharmony_ci if (LLVMGetTypeKind(ret_type) != LLVMVoidTypeKind) { 689bf215546Sopenharmony_ci assert(LLVMGetTypeKind(ret_type) == LLVMStructTypeKind); 690bf215546Sopenharmony_ci 691bf215546Sopenharmony_ci unsigned ret_size = LLVMCountStructElementTypes(ret_type); 692bf215546Sopenharmony_ci 693bf215546Sopenharmony_ci for (unsigned i = 0; i < ret_size; ++i) { 694bf215546Sopenharmony_ci LLVMValueRef val = LLVMBuildExtractValue(builder, ret, i, ""); 695bf215546Sopenharmony_ci 696bf215546Sopenharmony_ci assert(num_out < ARRAY_SIZE(out)); 697bf215546Sopenharmony_ci out[num_out++] = val; 698bf215546Sopenharmony_ci 699bf215546Sopenharmony_ci if (LLVMTypeOf(val) == ctx->ac.i32) { 700bf215546Sopenharmony_ci assert(num_out_sgpr + 1 == num_out); 701bf215546Sopenharmony_ci num_out_sgpr = num_out; 702bf215546Sopenharmony_ci } 703bf215546Sopenharmony_ci } 704bf215546Sopenharmony_ci } 705bf215546Sopenharmony_ci } 706bf215546Sopenharmony_ci 707bf215546Sopenharmony_ci /* Close the conditional wrapping the second shader. */ 708bf215546Sopenharmony_ci if (ctx->stage == MESA_SHADER_TESS_CTRL && 709bf215546Sopenharmony_ci !same_thread_count && si_is_multi_part_shader(ctx->shader)) 710bf215546Sopenharmony_ci ac_build_endif(&ctx->ac, 6507); 711bf215546Sopenharmony_ci 712bf215546Sopenharmony_ci if (LLVMGetTypeKind(LLVMTypeOf(ret)) == LLVMVoidTypeKind) 713bf215546Sopenharmony_ci LLVMBuildRetVoid(builder); 714bf215546Sopenharmony_ci else 715bf215546Sopenharmony_ci LLVMBuildRet(builder, ret); 716bf215546Sopenharmony_ci} 717bf215546Sopenharmony_ci 718bf215546Sopenharmony_cistatic LLVMValueRef si_llvm_load_intrinsic(struct ac_shader_abi *abi, nir_intrinsic_op op) 719bf215546Sopenharmony_ci{ 720bf215546Sopenharmony_ci struct si_shader_context *ctx = si_shader_context_from_abi(abi); 721bf215546Sopenharmony_ci 722bf215546Sopenharmony_ci switch (op) { 723bf215546Sopenharmony_ci case nir_intrinsic_load_first_vertex: 724bf215546Sopenharmony_ci return ac_get_arg(&ctx->ac, ctx->args.base_vertex); 725bf215546Sopenharmony_ci 726bf215546Sopenharmony_ci case nir_intrinsic_load_base_vertex: { 727bf215546Sopenharmony_ci /* For non-indexed draws, the base vertex set by the driver 728bf215546Sopenharmony_ci * (for direct draws) or the CP (for indirect draws) is the 729bf215546Sopenharmony_ci * first vertex ID, but GLSL expects 0 to be returned. 730bf215546Sopenharmony_ci */ 731bf215546Sopenharmony_ci LLVMValueRef indexed = GET_FIELD(ctx, VS_STATE_INDEXED); 732bf215546Sopenharmony_ci indexed = LLVMBuildTrunc(ctx->ac.builder, indexed, ctx->ac.i1, ""); 733bf215546Sopenharmony_ci return LLVMBuildSelect(ctx->ac.builder, indexed, ac_get_arg(&ctx->ac, ctx->args.base_vertex), 734bf215546Sopenharmony_ci ctx->ac.i32_0, ""); 735bf215546Sopenharmony_ci } 736bf215546Sopenharmony_ci 737bf215546Sopenharmony_ci case nir_intrinsic_load_workgroup_size: { 738bf215546Sopenharmony_ci assert(ctx->shader->selector->info.base.workgroup_size_variable && 739bf215546Sopenharmony_ci ctx->shader->selector->info.uses_variable_block_size); 740bf215546Sopenharmony_ci LLVMValueRef chan[3] = { 741bf215546Sopenharmony_ci si_unpack_param(ctx, ctx->block_size, 0, 10), 742bf215546Sopenharmony_ci si_unpack_param(ctx, ctx->block_size, 10, 10), 743bf215546Sopenharmony_ci si_unpack_param(ctx, ctx->block_size, 20, 10), 744bf215546Sopenharmony_ci }; 745bf215546Sopenharmony_ci return ac_build_gather_values(&ctx->ac, chan, 3); 746bf215546Sopenharmony_ci } 747bf215546Sopenharmony_ci 748bf215546Sopenharmony_ci case nir_intrinsic_load_tess_level_outer_default: 749bf215546Sopenharmony_ci case nir_intrinsic_load_tess_level_inner_default: { 750bf215546Sopenharmony_ci LLVMValueRef slot = LLVMConstInt(ctx->ac.i32, SI_HS_CONST_DEFAULT_TESS_LEVELS, 0); 751bf215546Sopenharmony_ci LLVMValueRef buf = ac_get_arg(&ctx->ac, ctx->internal_bindings); 752bf215546Sopenharmony_ci buf = ac_build_load_to_sgpr(&ctx->ac, buf, slot); 753bf215546Sopenharmony_ci int offset = op == nir_intrinsic_load_tess_level_inner_default ? 4 : 0; 754bf215546Sopenharmony_ci LLVMValueRef val[4]; 755bf215546Sopenharmony_ci 756bf215546Sopenharmony_ci for (int i = 0; i < 4; i++) 757bf215546Sopenharmony_ci val[i] = si_buffer_load_const(ctx, buf, LLVMConstInt(ctx->ac.i32, (offset + i) * 4, 0)); 758bf215546Sopenharmony_ci return ac_build_gather_values(&ctx->ac, val, 4); 759bf215546Sopenharmony_ci } 760bf215546Sopenharmony_ci 761bf215546Sopenharmony_ci case nir_intrinsic_load_patch_vertices_in: 762bf215546Sopenharmony_ci if (ctx->stage == MESA_SHADER_TESS_CTRL) 763bf215546Sopenharmony_ci return si_unpack_param(ctx, ctx->tcs_out_lds_layout, 13, 6); 764bf215546Sopenharmony_ci else if (ctx->stage == MESA_SHADER_TESS_EVAL) 765bf215546Sopenharmony_ci return si_get_num_tcs_out_vertices(ctx); 766bf215546Sopenharmony_ci else 767bf215546Sopenharmony_ci return NULL; 768bf215546Sopenharmony_ci 769bf215546Sopenharmony_ci case nir_intrinsic_load_sample_mask_in: 770bf215546Sopenharmony_ci return ac_to_integer(&ctx->ac, ac_get_arg(&ctx->ac, ctx->args.sample_coverage)); 771bf215546Sopenharmony_ci 772bf215546Sopenharmony_ci case nir_intrinsic_load_lshs_vertex_stride_amd: 773bf215546Sopenharmony_ci return LLVMBuildShl(ctx->ac.builder, si_get_tcs_in_vertex_dw_stride(ctx), 774bf215546Sopenharmony_ci LLVMConstInt(ctx->ac.i32, 2, 0), ""); 775bf215546Sopenharmony_ci 776bf215546Sopenharmony_ci case nir_intrinsic_load_tcs_num_patches_amd: 777bf215546Sopenharmony_ci return LLVMBuildAdd(ctx->ac.builder, 778bf215546Sopenharmony_ci si_unpack_param(ctx, ctx->tcs_offchip_layout, 0, 6), 779bf215546Sopenharmony_ci ctx->ac.i32_1, ""); 780bf215546Sopenharmony_ci 781bf215546Sopenharmony_ci case nir_intrinsic_load_hs_out_patch_data_offset_amd: 782bf215546Sopenharmony_ci return si_unpack_param(ctx, ctx->tcs_offchip_layout, 11, 21); 783bf215546Sopenharmony_ci 784bf215546Sopenharmony_ci case nir_intrinsic_load_ring_tess_offchip_amd: 785bf215546Sopenharmony_ci return ctx->tess_offchip_ring; 786bf215546Sopenharmony_ci 787bf215546Sopenharmony_ci case nir_intrinsic_load_ring_tess_offchip_offset_amd: 788bf215546Sopenharmony_ci return ac_get_arg(&ctx->ac, ctx->args.tess_offchip_offset); 789bf215546Sopenharmony_ci 790bf215546Sopenharmony_ci case nir_intrinsic_load_tess_rel_patch_id_amd: 791bf215546Sopenharmony_ci return si_get_rel_patch_id(ctx); 792bf215546Sopenharmony_ci 793bf215546Sopenharmony_ci case nir_intrinsic_load_ring_esgs_amd: 794bf215546Sopenharmony_ci return ctx->esgs_ring; 795bf215546Sopenharmony_ci 796bf215546Sopenharmony_ci case nir_intrinsic_load_ring_es2gs_offset_amd: 797bf215546Sopenharmony_ci return ac_get_arg(&ctx->ac, ctx->args.es2gs_offset); 798bf215546Sopenharmony_ci 799bf215546Sopenharmony_ci default: 800bf215546Sopenharmony_ci return NULL; 801bf215546Sopenharmony_ci } 802bf215546Sopenharmony_ci} 803bf215546Sopenharmony_ci 804bf215546Sopenharmony_cibool si_llvm_translate_nir(struct si_shader_context *ctx, struct si_shader *shader, 805bf215546Sopenharmony_ci struct nir_shader *nir, bool free_nir, bool ngg_cull_shader) 806bf215546Sopenharmony_ci{ 807bf215546Sopenharmony_ci struct si_shader_selector *sel = shader->selector; 808bf215546Sopenharmony_ci const struct si_shader_info *info = &sel->info; 809bf215546Sopenharmony_ci 810bf215546Sopenharmony_ci ctx->shader = shader; 811bf215546Sopenharmony_ci ctx->stage = sel->stage; 812bf215546Sopenharmony_ci 813bf215546Sopenharmony_ci ctx->num_const_buffers = info->base.num_ubos; 814bf215546Sopenharmony_ci ctx->num_shader_buffers = info->base.num_ssbos; 815bf215546Sopenharmony_ci 816bf215546Sopenharmony_ci ctx->num_samplers = BITSET_LAST_BIT(info->base.textures_used); 817bf215546Sopenharmony_ci ctx->num_images = info->base.num_images; 818bf215546Sopenharmony_ci 819bf215546Sopenharmony_ci ctx->abi.intrinsic_load = si_llvm_load_intrinsic; 820bf215546Sopenharmony_ci 821bf215546Sopenharmony_ci si_llvm_init_resource_callbacks(ctx); 822bf215546Sopenharmony_ci si_llvm_create_main_func(ctx, ngg_cull_shader); 823bf215546Sopenharmony_ci 824bf215546Sopenharmony_ci if (ctx->stage <= MESA_SHADER_GEOMETRY && 825bf215546Sopenharmony_ci (ctx->shader->key.ge.as_es || ctx->stage == MESA_SHADER_GEOMETRY)) 826bf215546Sopenharmony_ci si_preload_esgs_ring(ctx); 827bf215546Sopenharmony_ci 828bf215546Sopenharmony_ci switch (ctx->stage) { 829bf215546Sopenharmony_ci case MESA_SHADER_VERTEX: 830bf215546Sopenharmony_ci si_llvm_init_vs_callbacks(ctx, ngg_cull_shader); 831bf215546Sopenharmony_ci break; 832bf215546Sopenharmony_ci 833bf215546Sopenharmony_ci case MESA_SHADER_TESS_CTRL: 834bf215546Sopenharmony_ci si_llvm_init_tcs_callbacks(ctx); 835bf215546Sopenharmony_ci si_llvm_preload_tess_rings(ctx); 836bf215546Sopenharmony_ci break; 837bf215546Sopenharmony_ci 838bf215546Sopenharmony_ci case MESA_SHADER_TESS_EVAL: 839bf215546Sopenharmony_ci si_llvm_preload_tess_rings(ctx); 840bf215546Sopenharmony_ci break; 841bf215546Sopenharmony_ci 842bf215546Sopenharmony_ci case MESA_SHADER_GEOMETRY: 843bf215546Sopenharmony_ci si_llvm_init_gs_callbacks(ctx); 844bf215546Sopenharmony_ci 845bf215546Sopenharmony_ci if (!ctx->shader->key.ge.as_ngg) 846bf215546Sopenharmony_ci si_preload_gs_rings(ctx); 847bf215546Sopenharmony_ci 848bf215546Sopenharmony_ci for (unsigned i = 0; i < 4; i++) 849bf215546Sopenharmony_ci ctx->gs_next_vertex[i] = ac_build_alloca(&ctx->ac, ctx->ac.i32, ""); 850bf215546Sopenharmony_ci 851bf215546Sopenharmony_ci if (shader->key.ge.as_ngg) { 852bf215546Sopenharmony_ci for (unsigned i = 0; i < 4; ++i) { 853bf215546Sopenharmony_ci ctx->gs_curprim_verts[i] = ac_build_alloca(&ctx->ac, ctx->ac.i32, ""); 854bf215546Sopenharmony_ci ctx->gs_generated_prims[i] = ac_build_alloca(&ctx->ac, ctx->ac.i32, ""); 855bf215546Sopenharmony_ci } 856bf215546Sopenharmony_ci 857bf215546Sopenharmony_ci assert(!ctx->gs_ngg_scratch); 858bf215546Sopenharmony_ci LLVMTypeRef ai32 = LLVMArrayType(ctx->ac.i32, gfx10_ngg_get_scratch_dw_size(shader)); 859bf215546Sopenharmony_ci ctx->gs_ngg_scratch = 860bf215546Sopenharmony_ci LLVMAddGlobalInAddressSpace(ctx->ac.module, ai32, "ngg_scratch", AC_ADDR_SPACE_LDS); 861bf215546Sopenharmony_ci LLVMSetInitializer(ctx->gs_ngg_scratch, LLVMGetUndef(ai32)); 862bf215546Sopenharmony_ci LLVMSetAlignment(ctx->gs_ngg_scratch, 4); 863bf215546Sopenharmony_ci 864bf215546Sopenharmony_ci ctx->gs_ngg_emit = LLVMAddGlobalInAddressSpace( 865bf215546Sopenharmony_ci ctx->ac.module, LLVMArrayType(ctx->ac.i32, 0), "ngg_emit", AC_ADDR_SPACE_LDS); 866bf215546Sopenharmony_ci LLVMSetLinkage(ctx->gs_ngg_emit, LLVMExternalLinkage); 867bf215546Sopenharmony_ci LLVMSetAlignment(ctx->gs_ngg_emit, 4); 868bf215546Sopenharmony_ci } else { 869bf215546Sopenharmony_ci ctx->gs_emitted_vertices = LLVMConstInt(ctx->ac.i32, 0, false); 870bf215546Sopenharmony_ci } 871bf215546Sopenharmony_ci break; 872bf215546Sopenharmony_ci 873bf215546Sopenharmony_ci case MESA_SHADER_FRAGMENT: { 874bf215546Sopenharmony_ci si_llvm_init_ps_callbacks(ctx); 875bf215546Sopenharmony_ci 876bf215546Sopenharmony_ci unsigned colors_read = ctx->shader->selector->info.colors_read; 877bf215546Sopenharmony_ci LLVMValueRef main_fn = ctx->main_fn; 878bf215546Sopenharmony_ci 879bf215546Sopenharmony_ci LLVMValueRef undef = LLVMGetUndef(ctx->ac.f32); 880bf215546Sopenharmony_ci 881bf215546Sopenharmony_ci unsigned offset = SI_PARAM_POS_FIXED_PT + 1; 882bf215546Sopenharmony_ci 883bf215546Sopenharmony_ci if (colors_read & 0x0f) { 884bf215546Sopenharmony_ci unsigned mask = colors_read & 0x0f; 885bf215546Sopenharmony_ci LLVMValueRef values[4]; 886bf215546Sopenharmony_ci values[0] = mask & 0x1 ? LLVMGetParam(main_fn, offset++) : undef; 887bf215546Sopenharmony_ci values[1] = mask & 0x2 ? LLVMGetParam(main_fn, offset++) : undef; 888bf215546Sopenharmony_ci values[2] = mask & 0x4 ? LLVMGetParam(main_fn, offset++) : undef; 889bf215546Sopenharmony_ci values[3] = mask & 0x8 ? LLVMGetParam(main_fn, offset++) : undef; 890bf215546Sopenharmony_ci ctx->abi.color0 = ac_to_integer(&ctx->ac, ac_build_gather_values(&ctx->ac, values, 4)); 891bf215546Sopenharmony_ci } 892bf215546Sopenharmony_ci if (colors_read & 0xf0) { 893bf215546Sopenharmony_ci unsigned mask = (colors_read & 0xf0) >> 4; 894bf215546Sopenharmony_ci LLVMValueRef values[4]; 895bf215546Sopenharmony_ci values[0] = mask & 0x1 ? LLVMGetParam(main_fn, offset++) : undef; 896bf215546Sopenharmony_ci values[1] = mask & 0x2 ? LLVMGetParam(main_fn, offset++) : undef; 897bf215546Sopenharmony_ci values[2] = mask & 0x4 ? LLVMGetParam(main_fn, offset++) : undef; 898bf215546Sopenharmony_ci values[3] = mask & 0x8 ? LLVMGetParam(main_fn, offset++) : undef; 899bf215546Sopenharmony_ci ctx->abi.color1 = ac_to_integer(&ctx->ac, ac_build_gather_values(&ctx->ac, values, 4)); 900bf215546Sopenharmony_ci } 901bf215546Sopenharmony_ci 902bf215546Sopenharmony_ci ctx->abi.num_interp = si_get_ps_num_interp(shader); 903bf215546Sopenharmony_ci ctx->abi.interp_at_sample_force_center = 904bf215546Sopenharmony_ci ctx->shader->key.ps.mono.interpolate_at_sample_force_center; 905bf215546Sopenharmony_ci 906bf215546Sopenharmony_ci ctx->abi.kill_ps_if_inf_interp = 907bf215546Sopenharmony_ci ctx->screen->options.no_infinite_interp && 908bf215546Sopenharmony_ci (ctx->shader->selector->info.uses_persp_center || 909bf215546Sopenharmony_ci ctx->shader->selector->info.uses_persp_centroid || 910bf215546Sopenharmony_ci ctx->shader->selector->info.uses_persp_sample); 911bf215546Sopenharmony_ci break; 912bf215546Sopenharmony_ci } 913bf215546Sopenharmony_ci 914bf215546Sopenharmony_ci case MESA_SHADER_COMPUTE: 915bf215546Sopenharmony_ci if (nir->info.cs.user_data_components_amd) { 916bf215546Sopenharmony_ci ctx->abi.user_data = ac_get_arg(&ctx->ac, ctx->cs_user_data); 917bf215546Sopenharmony_ci ctx->abi.user_data = ac_build_expand_to_vec4(&ctx->ac, ctx->abi.user_data, 918bf215546Sopenharmony_ci nir->info.cs.user_data_components_amd); 919bf215546Sopenharmony_ci } 920bf215546Sopenharmony_ci 921bf215546Sopenharmony_ci if (ctx->shader->selector->info.base.shared_size) 922bf215546Sopenharmony_ci si_llvm_declare_compute_memory(ctx); 923bf215546Sopenharmony_ci break; 924bf215546Sopenharmony_ci 925bf215546Sopenharmony_ci default: 926bf215546Sopenharmony_ci break; 927bf215546Sopenharmony_ci } 928bf215546Sopenharmony_ci 929bf215546Sopenharmony_ci if ((ctx->stage == MESA_SHADER_VERTEX || ctx->stage == MESA_SHADER_TESS_EVAL) && 930bf215546Sopenharmony_ci shader->key.ge.as_ngg && !shader->key.ge.as_es) { 931bf215546Sopenharmony_ci /* Unconditionally declare scratch space base for streamout and 932bf215546Sopenharmony_ci * vertex compaction. Whether space is actually allocated is 933bf215546Sopenharmony_ci * determined during linking / PM4 creation. 934bf215546Sopenharmony_ci */ 935bf215546Sopenharmony_ci si_llvm_declare_esgs_ring(ctx); 936bf215546Sopenharmony_ci 937bf215546Sopenharmony_ci /* This is really only needed when streamout and / or vertex 938bf215546Sopenharmony_ci * compaction is enabled. 939bf215546Sopenharmony_ci */ 940bf215546Sopenharmony_ci if (!ctx->gs_ngg_scratch && (ctx->so.num_outputs || shader->key.ge.opt.ngg_culling)) { 941bf215546Sopenharmony_ci LLVMTypeRef asi32 = LLVMArrayType(ctx->ac.i32, gfx10_ngg_get_scratch_dw_size(shader)); 942bf215546Sopenharmony_ci ctx->gs_ngg_scratch = 943bf215546Sopenharmony_ci LLVMAddGlobalInAddressSpace(ctx->ac.module, asi32, "ngg_scratch", AC_ADDR_SPACE_LDS); 944bf215546Sopenharmony_ci LLVMSetInitializer(ctx->gs_ngg_scratch, LLVMGetUndef(asi32)); 945bf215546Sopenharmony_ci LLVMSetAlignment(ctx->gs_ngg_scratch, 4); 946bf215546Sopenharmony_ci } 947bf215546Sopenharmony_ci } 948bf215546Sopenharmony_ci 949bf215546Sopenharmony_ci /* For merged shaders (VS-TCS, VS-GS, TES-GS): */ 950bf215546Sopenharmony_ci if (ctx->screen->info.gfx_level >= GFX9 && si_is_merged_shader(shader)) { 951bf215546Sopenharmony_ci /* TES is special because it has only 1 shader part if NGG shader culling is disabled, 952bf215546Sopenharmony_ci * and therefore it doesn't use the wrapper function. 953bf215546Sopenharmony_ci */ 954bf215546Sopenharmony_ci bool no_wrapper_func = ctx->stage == MESA_SHADER_TESS_EVAL && !shader->key.ge.as_es && 955bf215546Sopenharmony_ci !shader->key.ge.opt.ngg_culling; 956bf215546Sopenharmony_ci 957bf215546Sopenharmony_ci /* Set EXEC = ~0 before the first shader. If the prolog is present, EXEC is set there 958bf215546Sopenharmony_ci * instead. For monolithic shaders, the wrapper function does this. 959bf215546Sopenharmony_ci */ 960bf215546Sopenharmony_ci if ((!shader->is_monolithic || no_wrapper_func) && 961bf215546Sopenharmony_ci (ctx->stage == MESA_SHADER_TESS_EVAL || 962bf215546Sopenharmony_ci (ctx->stage == MESA_SHADER_VERTEX && 963bf215546Sopenharmony_ci !si_vs_needs_prolog(sel, &shader->key.ge.part.vs.prolog, &shader->key, ngg_cull_shader, 964bf215546Sopenharmony_ci false)))) 965bf215546Sopenharmony_ci ac_init_exec_full_mask(&ctx->ac); 966bf215546Sopenharmony_ci 967bf215546Sopenharmony_ci /* NGG VS and NGG TES: Send gs_alloc_req and the prim export at the beginning to decrease 968bf215546Sopenharmony_ci * register usage. 969bf215546Sopenharmony_ci */ 970bf215546Sopenharmony_ci if ((ctx->stage == MESA_SHADER_VERTEX || ctx->stage == MESA_SHADER_TESS_EVAL) && 971bf215546Sopenharmony_ci shader->key.ge.as_ngg && !shader->key.ge.as_es && !shader->key.ge.opt.ngg_culling) { 972bf215546Sopenharmony_ci /* GFX10 requires a barrier before gs_alloc_req due to a hw bug. */ 973bf215546Sopenharmony_ci if (ctx->screen->info.gfx_level == GFX10) 974bf215546Sopenharmony_ci ac_build_s_barrier(&ctx->ac, ctx->stage); 975bf215546Sopenharmony_ci 976bf215546Sopenharmony_ci gfx10_ngg_build_sendmsg_gs_alloc_req(ctx); 977bf215546Sopenharmony_ci 978bf215546Sopenharmony_ci /* Build the primitive export at the beginning 979bf215546Sopenharmony_ci * of the shader if possible. 980bf215546Sopenharmony_ci */ 981bf215546Sopenharmony_ci if (gfx10_ngg_export_prim_early(shader)) 982bf215546Sopenharmony_ci gfx10_ngg_build_export_prim(ctx, NULL, NULL); 983bf215546Sopenharmony_ci } 984bf215546Sopenharmony_ci 985bf215546Sopenharmony_ci /* NGG GS: Initialize LDS and insert s_barrier, which must not be inside the if statement. */ 986bf215546Sopenharmony_ci if (ctx->stage == MESA_SHADER_GEOMETRY && shader->key.ge.as_ngg) 987bf215546Sopenharmony_ci gfx10_ngg_gs_emit_begin(ctx); 988bf215546Sopenharmony_ci 989bf215546Sopenharmony_ci LLVMValueRef thread_enabled = NULL; 990bf215546Sopenharmony_ci 991bf215546Sopenharmony_ci if (ctx->stage == MESA_SHADER_GEOMETRY || 992bf215546Sopenharmony_ci (ctx->stage == MESA_SHADER_TESS_CTRL && !shader->is_monolithic)) { 993bf215546Sopenharmony_ci /* Wrap both shaders in an if statement according to the number of enabled threads 994bf215546Sopenharmony_ci * there. For monolithic TCS, the if statement is inserted by the wrapper function, 995bf215546Sopenharmony_ci * not here. 996bf215546Sopenharmony_ci */ 997bf215546Sopenharmony_ci thread_enabled = si_is_gs_thread(ctx); /* 2nd shader: thread enabled bool */ 998bf215546Sopenharmony_ci } else if (((shader->key.ge.as_ls || shader->key.ge.as_es) && !shader->is_monolithic) || 999bf215546Sopenharmony_ci (shader->key.ge.as_ngg && !shader->key.ge.as_es)) { 1000bf215546Sopenharmony_ci /* This is NGG VS or NGG TES or VS before GS or TES before GS or VS before TCS. 1001bf215546Sopenharmony_ci * For monolithic LS (VS before TCS) and ES (VS before GS and TES before GS), 1002bf215546Sopenharmony_ci * the if statement is inserted by the wrapper function. 1003bf215546Sopenharmony_ci */ 1004bf215546Sopenharmony_ci thread_enabled = si_is_es_thread(ctx); /* 1st shader: thread enabled bool */ 1005bf215546Sopenharmony_ci } 1006bf215546Sopenharmony_ci 1007bf215546Sopenharmony_ci if (thread_enabled) { 1008bf215546Sopenharmony_ci ctx->merged_wrap_if_entry_block = LLVMGetInsertBlock(ctx->ac.builder); 1009bf215546Sopenharmony_ci ctx->merged_wrap_if_label = 11500; 1010bf215546Sopenharmony_ci ac_build_ifcc(&ctx->ac, thread_enabled, ctx->merged_wrap_if_label); 1011bf215546Sopenharmony_ci } 1012bf215546Sopenharmony_ci 1013bf215546Sopenharmony_ci /* Execute a barrier before the second shader in 1014bf215546Sopenharmony_ci * a merged shader. 1015bf215546Sopenharmony_ci * 1016bf215546Sopenharmony_ci * Execute the barrier inside the conditional block, 1017bf215546Sopenharmony_ci * so that empty waves can jump directly to s_endpgm, 1018bf215546Sopenharmony_ci * which will also signal the barrier. 1019bf215546Sopenharmony_ci * 1020bf215546Sopenharmony_ci * This is possible in gfx9, because an empty wave for the second shader does not insert 1021bf215546Sopenharmony_ci * any ending. With NGG, empty waves may still be required to export data (e.g. GS output 1022bf215546Sopenharmony_ci * vertices), so we cannot let them exit early. 1023bf215546Sopenharmony_ci * 1024bf215546Sopenharmony_ci * If the shader is TCS and the TCS epilog is present 1025bf215546Sopenharmony_ci * and contains a barrier, it will wait there and then 1026bf215546Sopenharmony_ci * reach s_endpgm. 1027bf215546Sopenharmony_ci */ 1028bf215546Sopenharmony_ci if (ctx->stage == MESA_SHADER_TESS_CTRL) { 1029bf215546Sopenharmony_ci /* We need the barrier only if TCS inputs are read from LDS. */ 1030bf215546Sopenharmony_ci if (!shader->key.ge.opt.same_patch_vertices || 1031bf215546Sopenharmony_ci shader->selector->info.base.inputs_read & 1032bf215546Sopenharmony_ci ~shader->selector->info.tcs_vgpr_only_inputs) { 1033bf215546Sopenharmony_ci ac_build_waitcnt(&ctx->ac, AC_WAIT_LGKM); 1034bf215546Sopenharmony_ci 1035bf215546Sopenharmony_ci /* If both input and output patches are wholly in one wave, we don't need a barrier. 1036bf215546Sopenharmony_ci * That's true when both VS and TCS have the same number of patch vertices and 1037bf215546Sopenharmony_ci * the wave size is a multiple of the number of patch vertices. 1038bf215546Sopenharmony_ci */ 1039bf215546Sopenharmony_ci if (!shader->key.ge.opt.same_patch_vertices || 1040bf215546Sopenharmony_ci ctx->ac.wave_size % sel->info.base.tess.tcs_vertices_out != 0) 1041bf215546Sopenharmony_ci ac_build_s_barrier(&ctx->ac, ctx->stage); 1042bf215546Sopenharmony_ci } 1043bf215546Sopenharmony_ci } else if (ctx->stage == MESA_SHADER_GEOMETRY && !shader->key.ge.as_ngg) { 1044bf215546Sopenharmony_ci /* gfx10_ngg_gs_emit_begin inserts the barrier for NGG. */ 1045bf215546Sopenharmony_ci ac_build_waitcnt(&ctx->ac, AC_WAIT_LGKM); 1046bf215546Sopenharmony_ci ac_build_s_barrier(&ctx->ac, ctx->stage); 1047bf215546Sopenharmony_ci } 1048bf215546Sopenharmony_ci } 1049bf215546Sopenharmony_ci 1050bf215546Sopenharmony_ci ctx->abi.clamp_shadow_reference = true; 1051bf215546Sopenharmony_ci ctx->abi.robust_buffer_access = true; 1052bf215546Sopenharmony_ci ctx->abi.convert_undef_to_zero = true; 1053bf215546Sopenharmony_ci ctx->abi.load_grid_size_from_user_sgpr = true; 1054bf215546Sopenharmony_ci ctx->abi.clamp_div_by_zero = ctx->screen->options.clamp_div_by_zero || 1055bf215546Sopenharmony_ci info->options & SI_PROFILE_CLAMP_DIV_BY_ZERO; 1056bf215546Sopenharmony_ci ctx->abi.use_waterfall_for_divergent_tex_samplers = true; 1057bf215546Sopenharmony_ci 1058bf215546Sopenharmony_ci for (unsigned i = 0; i < info->num_outputs; i++) { 1059bf215546Sopenharmony_ci LLVMTypeRef type = ctx->ac.f32; 1060bf215546Sopenharmony_ci 1061bf215546Sopenharmony_ci /* Only FS uses unpacked f16. Other stages pack 16-bit outputs into low and high bits of f32. */ 1062bf215546Sopenharmony_ci if (nir->info.stage == MESA_SHADER_FRAGMENT && 1063bf215546Sopenharmony_ci nir_alu_type_get_type_size(ctx->shader->selector->info.output_type[i]) == 16) 1064bf215546Sopenharmony_ci type = ctx->ac.f16; 1065bf215546Sopenharmony_ci 1066bf215546Sopenharmony_ci for (unsigned j = 0; j < 4; j++) { 1067bf215546Sopenharmony_ci ctx->abi.outputs[i * 4 + j] = ac_build_alloca_undef(&ctx->ac, type, ""); 1068bf215546Sopenharmony_ci ctx->abi.is_16bit[i * 4 + j] = type == ctx->ac.f16; 1069bf215546Sopenharmony_ci } 1070bf215546Sopenharmony_ci } 1071bf215546Sopenharmony_ci 1072bf215546Sopenharmony_ci ac_nir_translate(&ctx->ac, &ctx->abi, &ctx->args, nir); 1073bf215546Sopenharmony_ci 1074bf215546Sopenharmony_ci switch (sel->stage) { 1075bf215546Sopenharmony_ci case MESA_SHADER_VERTEX: 1076bf215546Sopenharmony_ci if (shader->key.ge.as_ls) 1077bf215546Sopenharmony_ci si_llvm_ls_build_end(ctx); 1078bf215546Sopenharmony_ci else if (shader->key.ge.as_es) 1079bf215546Sopenharmony_ci si_llvm_es_build_end(ctx); 1080bf215546Sopenharmony_ci else if (ngg_cull_shader) 1081bf215546Sopenharmony_ci gfx10_ngg_culling_build_end(ctx); 1082bf215546Sopenharmony_ci else if (shader->key.ge.as_ngg) 1083bf215546Sopenharmony_ci gfx10_ngg_build_end(ctx); 1084bf215546Sopenharmony_ci else 1085bf215546Sopenharmony_ci si_llvm_vs_build_end(ctx); 1086bf215546Sopenharmony_ci break; 1087bf215546Sopenharmony_ci 1088bf215546Sopenharmony_ci case MESA_SHADER_TESS_CTRL: 1089bf215546Sopenharmony_ci si_llvm_tcs_build_end(ctx); 1090bf215546Sopenharmony_ci break; 1091bf215546Sopenharmony_ci 1092bf215546Sopenharmony_ci case MESA_SHADER_TESS_EVAL: 1093bf215546Sopenharmony_ci if (ctx->shader->key.ge.as_es) 1094bf215546Sopenharmony_ci si_llvm_es_build_end(ctx); 1095bf215546Sopenharmony_ci else if (ngg_cull_shader) 1096bf215546Sopenharmony_ci gfx10_ngg_culling_build_end(ctx); 1097bf215546Sopenharmony_ci else if (ctx->shader->key.ge.as_ngg) 1098bf215546Sopenharmony_ci gfx10_ngg_build_end(ctx); 1099bf215546Sopenharmony_ci else 1100bf215546Sopenharmony_ci si_llvm_vs_build_end(ctx); 1101bf215546Sopenharmony_ci break; 1102bf215546Sopenharmony_ci 1103bf215546Sopenharmony_ci case MESA_SHADER_GEOMETRY: 1104bf215546Sopenharmony_ci if (ctx->shader->key.ge.as_ngg) 1105bf215546Sopenharmony_ci gfx10_ngg_gs_build_end(ctx); 1106bf215546Sopenharmony_ci else 1107bf215546Sopenharmony_ci si_llvm_gs_build_end(ctx); 1108bf215546Sopenharmony_ci break; 1109bf215546Sopenharmony_ci 1110bf215546Sopenharmony_ci case MESA_SHADER_FRAGMENT: 1111bf215546Sopenharmony_ci si_llvm_ps_build_end(ctx); 1112bf215546Sopenharmony_ci break; 1113bf215546Sopenharmony_ci 1114bf215546Sopenharmony_ci default: 1115bf215546Sopenharmony_ci break; 1116bf215546Sopenharmony_ci } 1117bf215546Sopenharmony_ci 1118bf215546Sopenharmony_ci si_llvm_build_ret(ctx, ctx->return_value); 1119bf215546Sopenharmony_ci 1120bf215546Sopenharmony_ci if (free_nir) 1121bf215546Sopenharmony_ci ralloc_free(nir); 1122bf215546Sopenharmony_ci return true; 1123bf215546Sopenharmony_ci} 1124bf215546Sopenharmony_ci 1125bf215546Sopenharmony_cistatic bool si_should_optimize_less(struct ac_llvm_compiler *compiler, 1126bf215546Sopenharmony_ci struct si_shader_selector *sel) 1127bf215546Sopenharmony_ci{ 1128bf215546Sopenharmony_ci if (!compiler->low_opt_passes) 1129bf215546Sopenharmony_ci return false; 1130bf215546Sopenharmony_ci 1131bf215546Sopenharmony_ci /* Assume a slow CPU. */ 1132bf215546Sopenharmony_ci assert(!sel->screen->info.has_dedicated_vram && sel->screen->info.gfx_level <= GFX8); 1133bf215546Sopenharmony_ci 1134bf215546Sopenharmony_ci /* For a crazy dEQP test containing 2597 memory opcodes, mostly 1135bf215546Sopenharmony_ci * buffer stores. */ 1136bf215546Sopenharmony_ci return sel->stage == MESA_SHADER_COMPUTE && sel->info.num_memory_stores > 1000; 1137bf215546Sopenharmony_ci} 1138bf215546Sopenharmony_ci 1139bf215546Sopenharmony_cibool si_llvm_compile_shader(struct si_screen *sscreen, struct ac_llvm_compiler *compiler, 1140bf215546Sopenharmony_ci struct si_shader *shader, const struct pipe_stream_output_info *so, 1141bf215546Sopenharmony_ci struct util_debug_callback *debug, struct nir_shader *nir, 1142bf215546Sopenharmony_ci bool free_nir) 1143bf215546Sopenharmony_ci{ 1144bf215546Sopenharmony_ci struct si_shader_selector *sel = shader->selector; 1145bf215546Sopenharmony_ci struct si_shader_context ctx; 1146bf215546Sopenharmony_ci 1147bf215546Sopenharmony_ci si_llvm_context_init(&ctx, sscreen, compiler, shader->wave_size); 1148bf215546Sopenharmony_ci ctx.so = *so; 1149bf215546Sopenharmony_ci 1150bf215546Sopenharmony_ci LLVMValueRef ngg_cull_main_fn = NULL; 1151bf215546Sopenharmony_ci if (sel->stage <= MESA_SHADER_TESS_EVAL && shader->key.ge.opt.ngg_culling) { 1152bf215546Sopenharmony_ci if (!si_llvm_translate_nir(&ctx, shader, nir, false, true)) { 1153bf215546Sopenharmony_ci si_llvm_dispose(&ctx); 1154bf215546Sopenharmony_ci return false; 1155bf215546Sopenharmony_ci } 1156bf215546Sopenharmony_ci ngg_cull_main_fn = ctx.main_fn; 1157bf215546Sopenharmony_ci ctx.main_fn = NULL; 1158bf215546Sopenharmony_ci } 1159bf215546Sopenharmony_ci 1160bf215546Sopenharmony_ci if (!si_llvm_translate_nir(&ctx, shader, nir, free_nir, false)) { 1161bf215546Sopenharmony_ci si_llvm_dispose(&ctx); 1162bf215546Sopenharmony_ci return false; 1163bf215546Sopenharmony_ci } 1164bf215546Sopenharmony_ci 1165bf215546Sopenharmony_ci if (shader->is_monolithic && sel->stage == MESA_SHADER_VERTEX) { 1166bf215546Sopenharmony_ci LLVMValueRef parts[4]; 1167bf215546Sopenharmony_ci unsigned num_parts = 0; 1168bf215546Sopenharmony_ci bool first_is_prolog = false; 1169bf215546Sopenharmony_ci LLVMValueRef main_fn = ctx.main_fn; 1170bf215546Sopenharmony_ci 1171bf215546Sopenharmony_ci if (ngg_cull_main_fn) { 1172bf215546Sopenharmony_ci if (si_vs_needs_prolog(sel, &shader->key.ge.part.vs.prolog, &shader->key, true, false)) { 1173bf215546Sopenharmony_ci union si_shader_part_key prolog_key; 1174bf215546Sopenharmony_ci si_get_vs_prolog_key(&sel->info, shader->info.num_input_sgprs, true, 1175bf215546Sopenharmony_ci &shader->key.ge.part.vs.prolog, shader, &prolog_key); 1176bf215546Sopenharmony_ci prolog_key.vs_prolog.is_monolithic = true; 1177bf215546Sopenharmony_ci si_llvm_build_vs_prolog(&ctx, &prolog_key); 1178bf215546Sopenharmony_ci parts[num_parts++] = ctx.main_fn; 1179bf215546Sopenharmony_ci first_is_prolog = true; 1180bf215546Sopenharmony_ci } 1181bf215546Sopenharmony_ci parts[num_parts++] = ngg_cull_main_fn; 1182bf215546Sopenharmony_ci } 1183bf215546Sopenharmony_ci 1184bf215546Sopenharmony_ci if (si_vs_needs_prolog(sel, &shader->key.ge.part.vs.prolog, &shader->key, false, false)) { 1185bf215546Sopenharmony_ci union si_shader_part_key prolog_key; 1186bf215546Sopenharmony_ci si_get_vs_prolog_key(&sel->info, shader->info.num_input_sgprs, false, 1187bf215546Sopenharmony_ci &shader->key.ge.part.vs.prolog, shader, &prolog_key); 1188bf215546Sopenharmony_ci prolog_key.vs_prolog.is_monolithic = true; 1189bf215546Sopenharmony_ci si_llvm_build_vs_prolog(&ctx, &prolog_key); 1190bf215546Sopenharmony_ci parts[num_parts++] = ctx.main_fn; 1191bf215546Sopenharmony_ci if (num_parts == 1) 1192bf215546Sopenharmony_ci first_is_prolog = true; 1193bf215546Sopenharmony_ci } 1194bf215546Sopenharmony_ci parts[num_parts++] = main_fn; 1195bf215546Sopenharmony_ci 1196bf215546Sopenharmony_ci si_build_wrapper_function(&ctx, parts, num_parts, first_is_prolog ? 1 : 0, 0, false); 1197bf215546Sopenharmony_ci } else if (shader->is_monolithic && sel->stage == MESA_SHADER_TESS_EVAL && ngg_cull_main_fn) { 1198bf215546Sopenharmony_ci LLVMValueRef parts[3], prolog, main_fn = ctx.main_fn; 1199bf215546Sopenharmony_ci 1200bf215546Sopenharmony_ci /* We reuse the VS prolog code for TES just to load the input VGPRs from LDS. */ 1201bf215546Sopenharmony_ci union si_shader_part_key prolog_key; 1202bf215546Sopenharmony_ci memset(&prolog_key, 0, sizeof(prolog_key)); 1203bf215546Sopenharmony_ci prolog_key.vs_prolog.num_input_sgprs = shader->info.num_input_sgprs; 1204bf215546Sopenharmony_ci prolog_key.vs_prolog.num_merged_next_stage_vgprs = 5; 1205bf215546Sopenharmony_ci prolog_key.vs_prolog.as_ngg = 1; 1206bf215546Sopenharmony_ci prolog_key.vs_prolog.load_vgprs_after_culling = 1; 1207bf215546Sopenharmony_ci prolog_key.vs_prolog.is_monolithic = true; 1208bf215546Sopenharmony_ci si_llvm_build_vs_prolog(&ctx, &prolog_key); 1209bf215546Sopenharmony_ci prolog = ctx.main_fn; 1210bf215546Sopenharmony_ci 1211bf215546Sopenharmony_ci parts[0] = ngg_cull_main_fn; 1212bf215546Sopenharmony_ci parts[1] = prolog; 1213bf215546Sopenharmony_ci parts[2] = main_fn; 1214bf215546Sopenharmony_ci 1215bf215546Sopenharmony_ci si_build_wrapper_function(&ctx, parts, 3, 0, 0, false); 1216bf215546Sopenharmony_ci } else if (shader->is_monolithic && sel->stage == MESA_SHADER_TESS_CTRL) { 1217bf215546Sopenharmony_ci if (sscreen->info.gfx_level >= GFX9) { 1218bf215546Sopenharmony_ci struct si_shader_selector *ls = shader->key.ge.part.tcs.ls; 1219bf215546Sopenharmony_ci LLVMValueRef parts[4]; 1220bf215546Sopenharmony_ci bool vs_needs_prolog = 1221bf215546Sopenharmony_ci si_vs_needs_prolog(ls, &shader->key.ge.part.tcs.ls_prolog, &shader->key, false, false); 1222bf215546Sopenharmony_ci 1223bf215546Sopenharmony_ci /* TCS main part */ 1224bf215546Sopenharmony_ci parts[2] = ctx.main_fn; 1225bf215546Sopenharmony_ci 1226bf215546Sopenharmony_ci /* TCS epilog */ 1227bf215546Sopenharmony_ci union si_shader_part_key tcs_epilog_key; 1228bf215546Sopenharmony_ci si_get_tcs_epilog_key(shader, &tcs_epilog_key); 1229bf215546Sopenharmony_ci si_llvm_build_tcs_epilog(&ctx, &tcs_epilog_key); 1230bf215546Sopenharmony_ci parts[3] = ctx.main_fn; 1231bf215546Sopenharmony_ci 1232bf215546Sopenharmony_ci struct si_shader shader_ls = {}; 1233bf215546Sopenharmony_ci shader_ls.selector = ls; 1234bf215546Sopenharmony_ci shader_ls.key.ge.part.vs.prolog = shader->key.ge.part.tcs.ls_prolog; 1235bf215546Sopenharmony_ci shader_ls.key.ge.as_ls = 1; 1236bf215546Sopenharmony_ci shader_ls.key.ge.mono = shader->key.ge.mono; 1237bf215546Sopenharmony_ci shader_ls.key.ge.opt = shader->key.ge.opt; 1238bf215546Sopenharmony_ci shader_ls.key.ge.opt.inline_uniforms = false; /* only TCS can inline uniforms */ 1239bf215546Sopenharmony_ci shader_ls.is_monolithic = true; 1240bf215546Sopenharmony_ci 1241bf215546Sopenharmony_ci nir = si_get_nir_shader(&shader_ls, &free_nir, sel->info.tcs_vgpr_only_inputs); 1242bf215546Sopenharmony_ci si_update_shader_binary_info(shader, nir); 1243bf215546Sopenharmony_ci 1244bf215546Sopenharmony_ci if (!si_llvm_translate_nir(&ctx, &shader_ls, nir, free_nir, false)) { 1245bf215546Sopenharmony_ci si_llvm_dispose(&ctx); 1246bf215546Sopenharmony_ci return false; 1247bf215546Sopenharmony_ci } 1248bf215546Sopenharmony_ci shader->info.uses_instanceid |= ls->info.uses_instanceid; 1249bf215546Sopenharmony_ci parts[1] = ctx.main_fn; 1250bf215546Sopenharmony_ci 1251bf215546Sopenharmony_ci /* LS prolog */ 1252bf215546Sopenharmony_ci if (vs_needs_prolog) { 1253bf215546Sopenharmony_ci union si_shader_part_key vs_prolog_key; 1254bf215546Sopenharmony_ci si_get_vs_prolog_key(&ls->info, shader_ls.info.num_input_sgprs, false, 1255bf215546Sopenharmony_ci &shader->key.ge.part.tcs.ls_prolog, shader, &vs_prolog_key); 1256bf215546Sopenharmony_ci vs_prolog_key.vs_prolog.is_monolithic = true; 1257bf215546Sopenharmony_ci si_llvm_build_vs_prolog(&ctx, &vs_prolog_key); 1258bf215546Sopenharmony_ci parts[0] = ctx.main_fn; 1259bf215546Sopenharmony_ci } 1260bf215546Sopenharmony_ci 1261bf215546Sopenharmony_ci /* Reset the shader context. */ 1262bf215546Sopenharmony_ci ctx.shader = shader; 1263bf215546Sopenharmony_ci ctx.stage = MESA_SHADER_TESS_CTRL; 1264bf215546Sopenharmony_ci 1265bf215546Sopenharmony_ci si_build_wrapper_function(&ctx, parts + !vs_needs_prolog, 4 - !vs_needs_prolog, 1266bf215546Sopenharmony_ci vs_needs_prolog, vs_needs_prolog ? 2 : 1, 1267bf215546Sopenharmony_ci shader->key.ge.opt.same_patch_vertices); 1268bf215546Sopenharmony_ci } else { 1269bf215546Sopenharmony_ci LLVMValueRef parts[2]; 1270bf215546Sopenharmony_ci union si_shader_part_key epilog_key; 1271bf215546Sopenharmony_ci 1272bf215546Sopenharmony_ci parts[0] = ctx.main_fn; 1273bf215546Sopenharmony_ci 1274bf215546Sopenharmony_ci memset(&epilog_key, 0, sizeof(epilog_key)); 1275bf215546Sopenharmony_ci epilog_key.tcs_epilog.states = shader->key.ge.part.tcs.epilog; 1276bf215546Sopenharmony_ci si_llvm_build_tcs_epilog(&ctx, &epilog_key); 1277bf215546Sopenharmony_ci parts[1] = ctx.main_fn; 1278bf215546Sopenharmony_ci 1279bf215546Sopenharmony_ci si_build_wrapper_function(&ctx, parts, 2, 0, 0, false); 1280bf215546Sopenharmony_ci } 1281bf215546Sopenharmony_ci } else if (shader->is_monolithic && sel->stage == MESA_SHADER_GEOMETRY) { 1282bf215546Sopenharmony_ci if (ctx.screen->info.gfx_level >= GFX9) { 1283bf215546Sopenharmony_ci struct si_shader_selector *es = shader->key.ge.part.gs.es; 1284bf215546Sopenharmony_ci LLVMValueRef es_prolog = NULL; 1285bf215546Sopenharmony_ci LLVMValueRef es_main = NULL; 1286bf215546Sopenharmony_ci LLVMValueRef gs_main = ctx.main_fn; 1287bf215546Sopenharmony_ci 1288bf215546Sopenharmony_ci /* ES main part */ 1289bf215546Sopenharmony_ci struct si_shader shader_es = {}; 1290bf215546Sopenharmony_ci shader_es.selector = es; 1291bf215546Sopenharmony_ci shader_es.key.ge.part.vs.prolog = shader->key.ge.part.gs.vs_prolog; 1292bf215546Sopenharmony_ci shader_es.key.ge.as_es = 1; 1293bf215546Sopenharmony_ci shader_es.key.ge.as_ngg = shader->key.ge.as_ngg; 1294bf215546Sopenharmony_ci shader_es.key.ge.mono = shader->key.ge.mono; 1295bf215546Sopenharmony_ci shader_es.key.ge.opt = shader->key.ge.opt; 1296bf215546Sopenharmony_ci shader_es.key.ge.opt.inline_uniforms = false; /* only GS can inline uniforms */ 1297bf215546Sopenharmony_ci /* kill_outputs was computed based on GS outputs so we can't use it to kill VS outputs */ 1298bf215546Sopenharmony_ci shader_es.key.ge.opt.kill_outputs = 0; 1299bf215546Sopenharmony_ci shader_es.is_monolithic = true; 1300bf215546Sopenharmony_ci 1301bf215546Sopenharmony_ci nir = si_get_nir_shader(&shader_es, &free_nir, 0); 1302bf215546Sopenharmony_ci si_update_shader_binary_info(shader, nir); 1303bf215546Sopenharmony_ci 1304bf215546Sopenharmony_ci if (!si_llvm_translate_nir(&ctx, &shader_es, nir, free_nir, false)) { 1305bf215546Sopenharmony_ci si_llvm_dispose(&ctx); 1306bf215546Sopenharmony_ci return false; 1307bf215546Sopenharmony_ci } 1308bf215546Sopenharmony_ci shader->info.uses_instanceid |= es->info.uses_instanceid; 1309bf215546Sopenharmony_ci es_main = ctx.main_fn; 1310bf215546Sopenharmony_ci 1311bf215546Sopenharmony_ci /* ES prolog */ 1312bf215546Sopenharmony_ci if (es->stage == MESA_SHADER_VERTEX && 1313bf215546Sopenharmony_ci si_vs_needs_prolog(es, &shader->key.ge.part.gs.vs_prolog, &shader->key, false, true)) { 1314bf215546Sopenharmony_ci union si_shader_part_key vs_prolog_key; 1315bf215546Sopenharmony_ci si_get_vs_prolog_key(&es->info, shader_es.info.num_input_sgprs, false, 1316bf215546Sopenharmony_ci &shader->key.ge.part.gs.vs_prolog, shader, &vs_prolog_key); 1317bf215546Sopenharmony_ci vs_prolog_key.vs_prolog.is_monolithic = true; 1318bf215546Sopenharmony_ci si_llvm_build_vs_prolog(&ctx, &vs_prolog_key); 1319bf215546Sopenharmony_ci es_prolog = ctx.main_fn; 1320bf215546Sopenharmony_ci } 1321bf215546Sopenharmony_ci 1322bf215546Sopenharmony_ci /* Reset the shader context. */ 1323bf215546Sopenharmony_ci ctx.shader = shader; 1324bf215546Sopenharmony_ci ctx.stage = MESA_SHADER_GEOMETRY; 1325bf215546Sopenharmony_ci 1326bf215546Sopenharmony_ci /* Prepare the array of shader parts. */ 1327bf215546Sopenharmony_ci LLVMValueRef parts[4]; 1328bf215546Sopenharmony_ci unsigned num_parts = 0, main_part; 1329bf215546Sopenharmony_ci 1330bf215546Sopenharmony_ci if (es_prolog) 1331bf215546Sopenharmony_ci parts[num_parts++] = es_prolog; 1332bf215546Sopenharmony_ci 1333bf215546Sopenharmony_ci parts[main_part = num_parts++] = es_main; 1334bf215546Sopenharmony_ci parts[num_parts++] = gs_main; 1335bf215546Sopenharmony_ci 1336bf215546Sopenharmony_ci si_build_wrapper_function(&ctx, parts, num_parts, main_part, main_part + 1, false); 1337bf215546Sopenharmony_ci } else { 1338bf215546Sopenharmony_ci /* Nothing to do for gfx6-8. The shader has only 1 part and it's ctx.main_fn. */ 1339bf215546Sopenharmony_ci } 1340bf215546Sopenharmony_ci } else if (shader->is_monolithic && sel->stage == MESA_SHADER_FRAGMENT) { 1341bf215546Sopenharmony_ci si_llvm_build_monolithic_ps(&ctx, shader); 1342bf215546Sopenharmony_ci } 1343bf215546Sopenharmony_ci 1344bf215546Sopenharmony_ci si_llvm_optimize_module(&ctx); 1345bf215546Sopenharmony_ci 1346bf215546Sopenharmony_ci /* Make sure the input is a pointer and not integer followed by inttoptr. */ 1347bf215546Sopenharmony_ci assert(LLVMGetTypeKind(LLVMTypeOf(LLVMGetParam(ctx.main_fn, 0))) == LLVMPointerTypeKind); 1348bf215546Sopenharmony_ci 1349bf215546Sopenharmony_ci /* Compile to bytecode. */ 1350bf215546Sopenharmony_ci if (!si_compile_llvm(sscreen, &shader->binary, &shader->config, compiler, &ctx.ac, debug, 1351bf215546Sopenharmony_ci sel->stage, si_get_shader_name(shader), 1352bf215546Sopenharmony_ci si_should_optimize_less(compiler, shader->selector))) { 1353bf215546Sopenharmony_ci si_llvm_dispose(&ctx); 1354bf215546Sopenharmony_ci fprintf(stderr, "LLVM failed to compile shader\n"); 1355bf215546Sopenharmony_ci return false; 1356bf215546Sopenharmony_ci } 1357bf215546Sopenharmony_ci 1358bf215546Sopenharmony_ci si_llvm_dispose(&ctx); 1359bf215546Sopenharmony_ci return true; 1360bf215546Sopenharmony_ci} 1361