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