xref: /aosp_15_r20/external/mesa3d/src/nouveau/vulkan/nvk_codegen.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker  * Copyright © 2022 Collabora Ltd. and Red Hat Inc.
3*61046927SAndroid Build Coastguard Worker  * SPDX-License-Identifier: MIT
4*61046927SAndroid Build Coastguard Worker  */
5*61046927SAndroid Build Coastguard Worker #include "nvk_cmd_buffer.h"
6*61046927SAndroid Build Coastguard Worker #include "nvk_physical_device.h"
7*61046927SAndroid Build Coastguard Worker #include "nvk_shader.h"
8*61046927SAndroid Build Coastguard Worker 
9*61046927SAndroid Build Coastguard Worker #include "nir.h"
10*61046927SAndroid Build Coastguard Worker #include "nir_builder.h"
11*61046927SAndroid Build Coastguard Worker #include "nir_xfb_info.h"
12*61046927SAndroid Build Coastguard Worker 
13*61046927SAndroid Build Coastguard Worker #include "nv50_ir_driver.h"
14*61046927SAndroid Build Coastguard Worker #include "pipe/p_defines.h"
15*61046927SAndroid Build Coastguard Worker #include "pipe/p_shader_tokens.h"
16*61046927SAndroid Build Coastguard Worker #include "util/u_memory.h"
17*61046927SAndroid Build Coastguard Worker 
18*61046927SAndroid Build Coastguard Worker #include "nv_push_cl9097.h"
19*61046927SAndroid Build Coastguard Worker 
20*61046927SAndroid Build Coastguard Worker uint64_t
nvk_cg_get_prog_debug(void)21*61046927SAndroid Build Coastguard Worker nvk_cg_get_prog_debug(void)
22*61046927SAndroid Build Coastguard Worker {
23*61046927SAndroid Build Coastguard Worker    return debug_get_num_option("NV50_PROG_DEBUG", 0);
24*61046927SAndroid Build Coastguard Worker }
25*61046927SAndroid Build Coastguard Worker 
26*61046927SAndroid Build Coastguard Worker uint64_t
nvk_cg_get_prog_optimize(void)27*61046927SAndroid Build Coastguard Worker nvk_cg_get_prog_optimize(void)
28*61046927SAndroid Build Coastguard Worker {
29*61046927SAndroid Build Coastguard Worker    return debug_get_num_option("NV50_PROG_OPTIMIZE", 3);
30*61046927SAndroid Build Coastguard Worker }
31*61046927SAndroid Build Coastguard Worker 
32*61046927SAndroid Build Coastguard Worker const nir_shader_compiler_options *
nvk_cg_nir_options(const struct nvk_physical_device * pdev,gl_shader_stage stage)33*61046927SAndroid Build Coastguard Worker nvk_cg_nir_options(const struct nvk_physical_device *pdev,
34*61046927SAndroid Build Coastguard Worker                    gl_shader_stage stage)
35*61046927SAndroid Build Coastguard Worker {
36*61046927SAndroid Build Coastguard Worker    return nv50_ir_nir_shader_compiler_options(pdev->info.chipset, stage);
37*61046927SAndroid Build Coastguard Worker }
38*61046927SAndroid Build Coastguard Worker 
39*61046927SAndroid Build Coastguard Worker static nir_variable *
find_or_create_input(nir_builder * b,const struct glsl_type * type,const char * name,unsigned location)40*61046927SAndroid Build Coastguard Worker find_or_create_input(nir_builder *b, const struct glsl_type *type,
41*61046927SAndroid Build Coastguard Worker                      const char *name, unsigned location)
42*61046927SAndroid Build Coastguard Worker {
43*61046927SAndroid Build Coastguard Worker    nir_foreach_shader_in_variable(in, b->shader) {
44*61046927SAndroid Build Coastguard Worker       if (in->data.location == location)
45*61046927SAndroid Build Coastguard Worker          return in;
46*61046927SAndroid Build Coastguard Worker    }
47*61046927SAndroid Build Coastguard Worker    nir_variable *in = nir_variable_create(b->shader, nir_var_shader_in,
48*61046927SAndroid Build Coastguard Worker                                           type, name);
49*61046927SAndroid Build Coastguard Worker    in->data.location = location;
50*61046927SAndroid Build Coastguard Worker    if (glsl_type_is_integer(type))
51*61046927SAndroid Build Coastguard Worker       in->data.interpolation = INTERP_MODE_FLAT;
52*61046927SAndroid Build Coastguard Worker    else
53*61046927SAndroid Build Coastguard Worker       in->data.interpolation = INTERP_MODE_NOPERSPECTIVE;
54*61046927SAndroid Build Coastguard Worker 
55*61046927SAndroid Build Coastguard Worker    return in;
56*61046927SAndroid Build Coastguard Worker }
57*61046927SAndroid Build Coastguard Worker 
58*61046927SAndroid Build Coastguard Worker static bool
lower_fragcoord_instr(nir_builder * b,nir_instr * instr,UNUSED void * _data)59*61046927SAndroid Build Coastguard Worker lower_fragcoord_instr(nir_builder *b, nir_instr *instr, UNUSED void *_data)
60*61046927SAndroid Build Coastguard Worker {
61*61046927SAndroid Build Coastguard Worker    assert(b->shader->info.stage == MESA_SHADER_FRAGMENT);
62*61046927SAndroid Build Coastguard Worker    nir_variable *var;
63*61046927SAndroid Build Coastguard Worker 
64*61046927SAndroid Build Coastguard Worker    if (instr->type != nir_instr_type_intrinsic)
65*61046927SAndroid Build Coastguard Worker       return false;
66*61046927SAndroid Build Coastguard Worker 
67*61046927SAndroid Build Coastguard Worker    nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
68*61046927SAndroid Build Coastguard Worker    b->cursor = nir_before_instr(&intrin->instr);
69*61046927SAndroid Build Coastguard Worker 
70*61046927SAndroid Build Coastguard Worker    nir_def *val;
71*61046927SAndroid Build Coastguard Worker    switch (intrin->intrinsic) {
72*61046927SAndroid Build Coastguard Worker    case nir_intrinsic_load_frag_coord:
73*61046927SAndroid Build Coastguard Worker       var = find_or_create_input(b, glsl_vec4_type(),
74*61046927SAndroid Build Coastguard Worker                                  "gl_FragCoord",
75*61046927SAndroid Build Coastguard Worker                                  VARYING_SLOT_POS);
76*61046927SAndroid Build Coastguard Worker       val = nir_load_var(b, var);
77*61046927SAndroid Build Coastguard Worker       break;
78*61046927SAndroid Build Coastguard Worker    case nir_intrinsic_load_point_coord:
79*61046927SAndroid Build Coastguard Worker       var = find_or_create_input(b, glsl_vector_type(GLSL_TYPE_FLOAT, 2),
80*61046927SAndroid Build Coastguard Worker                                  "gl_PointCoord",
81*61046927SAndroid Build Coastguard Worker                                  VARYING_SLOT_PNTC);
82*61046927SAndroid Build Coastguard Worker       val = nir_load_var(b, var);
83*61046927SAndroid Build Coastguard Worker       break;
84*61046927SAndroid Build Coastguard Worker    case nir_intrinsic_load_sample_pos:
85*61046927SAndroid Build Coastguard Worker       var = find_or_create_input(b, glsl_vec4_type(),
86*61046927SAndroid Build Coastguard Worker                                  "gl_FragCoord",
87*61046927SAndroid Build Coastguard Worker                                  VARYING_SLOT_POS);
88*61046927SAndroid Build Coastguard Worker       val = nir_ffract(b, nir_trim_vector(b, nir_load_var(b, var), 2));
89*61046927SAndroid Build Coastguard Worker       break;
90*61046927SAndroid Build Coastguard Worker    case nir_intrinsic_load_layer_id:
91*61046927SAndroid Build Coastguard Worker       var = find_or_create_input(b, glsl_int_type(),
92*61046927SAndroid Build Coastguard Worker                                  "gl_Layer", VARYING_SLOT_LAYER);
93*61046927SAndroid Build Coastguard Worker       val = nir_load_var(b, var);
94*61046927SAndroid Build Coastguard Worker       break;
95*61046927SAndroid Build Coastguard Worker 
96*61046927SAndroid Build Coastguard Worker    default:
97*61046927SAndroid Build Coastguard Worker       return false;
98*61046927SAndroid Build Coastguard Worker    }
99*61046927SAndroid Build Coastguard Worker 
100*61046927SAndroid Build Coastguard Worker    nir_def_rewrite_uses(&intrin->def, val);
101*61046927SAndroid Build Coastguard Worker 
102*61046927SAndroid Build Coastguard Worker    return true;
103*61046927SAndroid Build Coastguard Worker }
104*61046927SAndroid Build Coastguard Worker 
105*61046927SAndroid Build Coastguard Worker void
nvk_cg_preprocess_nir(nir_shader * nir)106*61046927SAndroid Build Coastguard Worker nvk_cg_preprocess_nir(nir_shader *nir)
107*61046927SAndroid Build Coastguard Worker {
108*61046927SAndroid Build Coastguard Worker    NIR_PASS(_, nir, nir_split_struct_vars, nir_var_function_temp);
109*61046927SAndroid Build Coastguard Worker    NIR_PASS(_, nir, nir_lower_vars_to_ssa);
110*61046927SAndroid Build Coastguard Worker 
111*61046927SAndroid Build Coastguard Worker    NIR_PASS(_, nir, nir_split_var_copies);
112*61046927SAndroid Build Coastguard Worker    NIR_PASS(_, nir, nir_lower_vars_to_ssa);
113*61046927SAndroid Build Coastguard Worker 
114*61046927SAndroid Build Coastguard Worker    NIR_PASS(_, nir, nir_lower_global_vars_to_local);
115*61046927SAndroid Build Coastguard Worker    NIR_PASS(_, nir, nir_remove_dead_variables, nir_var_function_temp, NULL);
116*61046927SAndroid Build Coastguard Worker 
117*61046927SAndroid Build Coastguard Worker    NIR_PASS(_, nir, nir_lower_system_values);
118*61046927SAndroid Build Coastguard Worker 
119*61046927SAndroid Build Coastguard Worker    if (nir->info.stage == MESA_SHADER_FRAGMENT) {
120*61046927SAndroid Build Coastguard Worker       NIR_PASS(_, nir, nir_shader_instructions_pass, lower_fragcoord_instr,
121*61046927SAndroid Build Coastguard Worker                nir_metadata_control_flow, NULL);
122*61046927SAndroid Build Coastguard Worker    }
123*61046927SAndroid Build Coastguard Worker 
124*61046927SAndroid Build Coastguard Worker    nvk_cg_optimize_nir(nir);
125*61046927SAndroid Build Coastguard Worker 
126*61046927SAndroid Build Coastguard Worker    NIR_PASS(_, nir, nir_lower_var_copies);
127*61046927SAndroid Build Coastguard Worker }
128*61046927SAndroid Build Coastguard Worker 
129*61046927SAndroid Build Coastguard Worker void
nvk_cg_optimize_nir(nir_shader * nir)130*61046927SAndroid Build Coastguard Worker nvk_cg_optimize_nir(nir_shader *nir)
131*61046927SAndroid Build Coastguard Worker {
132*61046927SAndroid Build Coastguard Worker    bool progress;
133*61046927SAndroid Build Coastguard Worker 
134*61046927SAndroid Build Coastguard Worker    do {
135*61046927SAndroid Build Coastguard Worker       progress = false;
136*61046927SAndroid Build Coastguard Worker 
137*61046927SAndroid Build Coastguard Worker       NIR_PASS(progress, nir, nir_split_array_vars, nir_var_function_temp);
138*61046927SAndroid Build Coastguard Worker       NIR_PASS(progress, nir, nir_shrink_vec_array_vars, nir_var_function_temp);
139*61046927SAndroid Build Coastguard Worker 
140*61046927SAndroid Build Coastguard Worker       if (!nir->info.var_copies_lowered) {
141*61046927SAndroid Build Coastguard Worker          /* Only run this pass if nir_lower_var_copies was not called
142*61046927SAndroid Build Coastguard Worker           * yet. That would lower away any copy_deref instructions and we
143*61046927SAndroid Build Coastguard Worker           * don't want to introduce any more.
144*61046927SAndroid Build Coastguard Worker           */
145*61046927SAndroid Build Coastguard Worker          NIR_PASS(progress, nir, nir_opt_find_array_copies);
146*61046927SAndroid Build Coastguard Worker       }
147*61046927SAndroid Build Coastguard Worker       NIR_PASS(progress, nir, nir_opt_copy_prop_vars);
148*61046927SAndroid Build Coastguard Worker       NIR_PASS(progress, nir, nir_opt_dead_write_vars);
149*61046927SAndroid Build Coastguard Worker       NIR_PASS(progress, nir, nir_lower_vars_to_ssa);
150*61046927SAndroid Build Coastguard Worker       NIR_PASS(progress, nir, nir_copy_prop);
151*61046927SAndroid Build Coastguard Worker       NIR_PASS(progress, nir, nir_opt_remove_phis);
152*61046927SAndroid Build Coastguard Worker       NIR_PASS(progress, nir, nir_opt_dce);
153*61046927SAndroid Build Coastguard Worker       if (nir_opt_loop(nir)) {
154*61046927SAndroid Build Coastguard Worker          progress = true;
155*61046927SAndroid Build Coastguard Worker          NIR_PASS(progress, nir, nir_copy_prop);
156*61046927SAndroid Build Coastguard Worker          NIR_PASS(progress, nir, nir_opt_remove_phis);
157*61046927SAndroid Build Coastguard Worker          NIR_PASS(progress, nir, nir_opt_dce);
158*61046927SAndroid Build Coastguard Worker       }
159*61046927SAndroid Build Coastguard Worker       NIR_PASS(progress, nir, nir_opt_if, nir_opt_if_optimize_phi_true_false);
160*61046927SAndroid Build Coastguard Worker       NIR_PASS(progress, nir, nir_opt_dead_cf);
161*61046927SAndroid Build Coastguard Worker       NIR_PASS(progress, nir, nir_opt_cse);
162*61046927SAndroid Build Coastguard Worker       /*
163*61046927SAndroid Build Coastguard Worker        * this should be fine, likely a backend problem,
164*61046927SAndroid Build Coastguard Worker        * but a bunch of tessellation shaders blow up.
165*61046927SAndroid Build Coastguard Worker        * we should revisit this when NAK is merged.
166*61046927SAndroid Build Coastguard Worker        */
167*61046927SAndroid Build Coastguard Worker       NIR_PASS(progress, nir, nir_opt_peephole_select, 2, true, true);
168*61046927SAndroid Build Coastguard Worker       NIR_PASS(progress, nir, nir_opt_constant_folding);
169*61046927SAndroid Build Coastguard Worker       NIR_PASS(progress, nir, nir_opt_algebraic);
170*61046927SAndroid Build Coastguard Worker 
171*61046927SAndroid Build Coastguard Worker       NIR_PASS(progress, nir, nir_opt_undef);
172*61046927SAndroid Build Coastguard Worker 
173*61046927SAndroid Build Coastguard Worker       if (nir->options->max_unroll_iterations) {
174*61046927SAndroid Build Coastguard Worker          NIR_PASS(progress, nir, nir_opt_loop_unroll);
175*61046927SAndroid Build Coastguard Worker       }
176*61046927SAndroid Build Coastguard Worker    } while (progress);
177*61046927SAndroid Build Coastguard Worker 
178*61046927SAndroid Build Coastguard Worker    NIR_PASS(progress, nir, nir_opt_shrink_vectors, true);
179*61046927SAndroid Build Coastguard Worker    NIR_PASS(progress, nir, nir_remove_dead_variables,
180*61046927SAndroid Build Coastguard Worker             nir_var_function_temp | nir_var_shader_in | nir_var_shader_out, NULL);
181*61046927SAndroid Build Coastguard Worker }
182*61046927SAndroid Build Coastguard Worker 
183*61046927SAndroid Build Coastguard Worker static bool
lower_image_size_to_txs(nir_builder * b,nir_intrinsic_instr * intrin,UNUSED void * _data)184*61046927SAndroid Build Coastguard Worker lower_image_size_to_txs(nir_builder *b, nir_intrinsic_instr *intrin,
185*61046927SAndroid Build Coastguard Worker                         UNUSED void *_data)
186*61046927SAndroid Build Coastguard Worker {
187*61046927SAndroid Build Coastguard Worker    if (intrin->intrinsic != nir_intrinsic_image_deref_size)
188*61046927SAndroid Build Coastguard Worker       return false;
189*61046927SAndroid Build Coastguard Worker 
190*61046927SAndroid Build Coastguard Worker    b->cursor = nir_instr_remove(&intrin->instr);
191*61046927SAndroid Build Coastguard Worker 
192*61046927SAndroid Build Coastguard Worker    nir_deref_instr *img = nir_src_as_deref(intrin->src[0]);
193*61046927SAndroid Build Coastguard Worker    nir_def *lod = nir_tex_type_has_lod(img->type) ?
194*61046927SAndroid Build Coastguard Worker                       intrin->src[1].ssa : NULL;
195*61046927SAndroid Build Coastguard Worker    nir_def *size = nir_txs_deref(b, img, lod);
196*61046927SAndroid Build Coastguard Worker 
197*61046927SAndroid Build Coastguard Worker    if (glsl_get_sampler_dim(img->type) == GLSL_SAMPLER_DIM_CUBE) {
198*61046927SAndroid Build Coastguard Worker       /* Cube image descriptors are set up as simple arrays but SPIR-V wants
199*61046927SAndroid Build Coastguard Worker        * the number of cubes.
200*61046927SAndroid Build Coastguard Worker        */
201*61046927SAndroid Build Coastguard Worker       if (glsl_sampler_type_is_array(img->type)) {
202*61046927SAndroid Build Coastguard Worker          size = nir_vec3(b, nir_channel(b, size, 0),
203*61046927SAndroid Build Coastguard Worker                             nir_channel(b, size, 1),
204*61046927SAndroid Build Coastguard Worker                             nir_udiv_imm(b, nir_channel(b, size, 2), 6));
205*61046927SAndroid Build Coastguard Worker       } else {
206*61046927SAndroid Build Coastguard Worker          size = nir_vec3(b, nir_channel(b, size, 0),
207*61046927SAndroid Build Coastguard Worker                             nir_channel(b, size, 1),
208*61046927SAndroid Build Coastguard Worker                             nir_imm_int(b, 1));
209*61046927SAndroid Build Coastguard Worker       }
210*61046927SAndroid Build Coastguard Worker    }
211*61046927SAndroid Build Coastguard Worker 
212*61046927SAndroid Build Coastguard Worker    nir_def_rewrite_uses(&intrin->def, size);
213*61046927SAndroid Build Coastguard Worker 
214*61046927SAndroid Build Coastguard Worker    return true;
215*61046927SAndroid Build Coastguard Worker }
216*61046927SAndroid Build Coastguard Worker 
217*61046927SAndroid Build Coastguard Worker static int
count_location_slots(const struct glsl_type * type,bool bindless)218*61046927SAndroid Build Coastguard Worker count_location_slots(const struct glsl_type *type, bool bindless)
219*61046927SAndroid Build Coastguard Worker {
220*61046927SAndroid Build Coastguard Worker    return glsl_count_attribute_slots(type, false);
221*61046927SAndroid Build Coastguard Worker }
222*61046927SAndroid Build Coastguard Worker 
223*61046927SAndroid Build Coastguard Worker static void
assign_io_locations(nir_shader * nir)224*61046927SAndroid Build Coastguard Worker assign_io_locations(nir_shader *nir)
225*61046927SAndroid Build Coastguard Worker {
226*61046927SAndroid Build Coastguard Worker    if (nir->info.stage != MESA_SHADER_VERTEX) {
227*61046927SAndroid Build Coastguard Worker       unsigned location = 0;
228*61046927SAndroid Build Coastguard Worker       nir_foreach_variable_with_modes(var, nir, nir_var_shader_in) {
229*61046927SAndroid Build Coastguard Worker          var->data.driver_location = location;
230*61046927SAndroid Build Coastguard Worker          if (nir_is_arrayed_io(var, nir->info.stage)) {
231*61046927SAndroid Build Coastguard Worker             location += glsl_count_attribute_slots(glsl_get_array_element(var->type), false);
232*61046927SAndroid Build Coastguard Worker          } else {
233*61046927SAndroid Build Coastguard Worker             location += glsl_count_attribute_slots(var->type, false);
234*61046927SAndroid Build Coastguard Worker          }
235*61046927SAndroid Build Coastguard Worker       }
236*61046927SAndroid Build Coastguard Worker       nir->num_inputs = location;
237*61046927SAndroid Build Coastguard Worker    } else {
238*61046927SAndroid Build Coastguard Worker       nir_foreach_shader_in_variable(var, nir) {
239*61046927SAndroid Build Coastguard Worker          assert(var->data.location >= VERT_ATTRIB_GENERIC0);
240*61046927SAndroid Build Coastguard Worker          var->data.driver_location = var->data.location - VERT_ATTRIB_GENERIC0;
241*61046927SAndroid Build Coastguard Worker       }
242*61046927SAndroid Build Coastguard Worker    }
243*61046927SAndroid Build Coastguard Worker 
244*61046927SAndroid Build Coastguard Worker    {
245*61046927SAndroid Build Coastguard Worker       unsigned location = 0;
246*61046927SAndroid Build Coastguard Worker       nir_foreach_variable_with_modes(var, nir, nir_var_shader_out) {
247*61046927SAndroid Build Coastguard Worker          var->data.driver_location = location;
248*61046927SAndroid Build Coastguard Worker          if (nir_is_arrayed_io(var, nir->info.stage)) {
249*61046927SAndroid Build Coastguard Worker             location += glsl_count_attribute_slots(glsl_get_array_element(var->type), false);
250*61046927SAndroid Build Coastguard Worker          } else {
251*61046927SAndroid Build Coastguard Worker             location += glsl_count_attribute_slots(var->type, false);
252*61046927SAndroid Build Coastguard Worker          }
253*61046927SAndroid Build Coastguard Worker       }
254*61046927SAndroid Build Coastguard Worker       nir->num_outputs = location;
255*61046927SAndroid Build Coastguard Worker    }
256*61046927SAndroid Build Coastguard Worker }
257*61046927SAndroid Build Coastguard Worker 
258*61046927SAndroid Build Coastguard Worker static void
nak_cg_postprocess_nir(nir_shader * nir)259*61046927SAndroid Build Coastguard Worker nak_cg_postprocess_nir(nir_shader *nir)
260*61046927SAndroid Build Coastguard Worker {
261*61046927SAndroid Build Coastguard Worker    NIR_PASS(_, nir, nir_shader_intrinsics_pass, lower_image_size_to_txs,
262*61046927SAndroid Build Coastguard Worker             nir_metadata_control_flow, NULL);
263*61046927SAndroid Build Coastguard Worker 
264*61046927SAndroid Build Coastguard Worker    uint32_t indirect_mask = nir_var_function_temp;
265*61046927SAndroid Build Coastguard Worker 
266*61046927SAndroid Build Coastguard Worker    NIR_PASS(_, nir, nir_lower_indirect_derefs, indirect_mask, 16);
267*61046927SAndroid Build Coastguard Worker 
268*61046927SAndroid Build Coastguard Worker    nvk_cg_optimize_nir(nir);
269*61046927SAndroid Build Coastguard Worker    if (nir->info.stage != MESA_SHADER_COMPUTE)
270*61046927SAndroid Build Coastguard Worker       assign_io_locations(nir);
271*61046927SAndroid Build Coastguard Worker 
272*61046927SAndroid Build Coastguard Worker    NIR_PASS(_, nir, nir_lower_int64);
273*61046927SAndroid Build Coastguard Worker 
274*61046927SAndroid Build Coastguard Worker    nir_shader_gather_info(nir, nir_shader_get_entrypoint(nir));
275*61046927SAndroid Build Coastguard Worker }
276*61046927SAndroid Build Coastguard Worker 
277*61046927SAndroid Build Coastguard Worker /* NOTE: Using a[0x270] in FP may cause an error even if we're using less than
278*61046927SAndroid Build Coastguard Worker  * 124 scalar varying values.
279*61046927SAndroid Build Coastguard Worker  */
280*61046927SAndroid Build Coastguard Worker static uint32_t
nvc0_shader_input_address(unsigned sn,unsigned si)281*61046927SAndroid Build Coastguard Worker nvc0_shader_input_address(unsigned sn, unsigned si)
282*61046927SAndroid Build Coastguard Worker {
283*61046927SAndroid Build Coastguard Worker    switch (sn) {
284*61046927SAndroid Build Coastguard Worker    case TGSI_SEMANTIC_TESSOUTER:    return 0x000 + si * 0x4;
285*61046927SAndroid Build Coastguard Worker    case TGSI_SEMANTIC_TESSINNER:    return 0x010 + si * 0x4;
286*61046927SAndroid Build Coastguard Worker    case TGSI_SEMANTIC_PATCH:        return 0x020 + si * 0x10;
287*61046927SAndroid Build Coastguard Worker    case TGSI_SEMANTIC_PRIMID:       return 0x060;
288*61046927SAndroid Build Coastguard Worker    case TGSI_SEMANTIC_LAYER:        return 0x064;
289*61046927SAndroid Build Coastguard Worker    case TGSI_SEMANTIC_VIEWPORT_INDEX:return 0x068;
290*61046927SAndroid Build Coastguard Worker    case TGSI_SEMANTIC_PSIZE:        return 0x06c;
291*61046927SAndroid Build Coastguard Worker    case TGSI_SEMANTIC_POSITION:     return 0x070;
292*61046927SAndroid Build Coastguard Worker    case TGSI_SEMANTIC_GENERIC:      return 0x080 + si * 0x10;
293*61046927SAndroid Build Coastguard Worker    case TGSI_SEMANTIC_FOG:          return 0x2e8;
294*61046927SAndroid Build Coastguard Worker    case TGSI_SEMANTIC_COLOR:        return 0x280 + si * 0x10;
295*61046927SAndroid Build Coastguard Worker    case TGSI_SEMANTIC_BCOLOR:       return 0x2a0 + si * 0x10;
296*61046927SAndroid Build Coastguard Worker    case TGSI_SEMANTIC_CLIPDIST:     return 0x2c0 + si * 0x10;
297*61046927SAndroid Build Coastguard Worker    case TGSI_SEMANTIC_CLIPVERTEX:   return 0x270;
298*61046927SAndroid Build Coastguard Worker    case TGSI_SEMANTIC_PCOORD:       return 0x2e0;
299*61046927SAndroid Build Coastguard Worker    case TGSI_SEMANTIC_TESSCOORD:    return 0x2f0;
300*61046927SAndroid Build Coastguard Worker    case TGSI_SEMANTIC_INSTANCEID:   return 0x2f8;
301*61046927SAndroid Build Coastguard Worker    case TGSI_SEMANTIC_VERTEXID:     return 0x2fc;
302*61046927SAndroid Build Coastguard Worker    case TGSI_SEMANTIC_TEXCOORD:     return 0x300 + si * 0x10;
303*61046927SAndroid Build Coastguard Worker    default:
304*61046927SAndroid Build Coastguard Worker       assert(!"invalid TGSI input semantic");
305*61046927SAndroid Build Coastguard Worker       return ~0;
306*61046927SAndroid Build Coastguard Worker    }
307*61046927SAndroid Build Coastguard Worker }
308*61046927SAndroid Build Coastguard Worker 
309*61046927SAndroid Build Coastguard Worker static uint32_t
nvc0_shader_output_address(unsigned sn,unsigned si)310*61046927SAndroid Build Coastguard Worker nvc0_shader_output_address(unsigned sn, unsigned si)
311*61046927SAndroid Build Coastguard Worker {
312*61046927SAndroid Build Coastguard Worker    switch (sn) {
313*61046927SAndroid Build Coastguard Worker    case TGSI_SEMANTIC_TESSOUTER:     return 0x000 + si * 0x4;
314*61046927SAndroid Build Coastguard Worker    case TGSI_SEMANTIC_TESSINNER:     return 0x010 + si * 0x4;
315*61046927SAndroid Build Coastguard Worker    case TGSI_SEMANTIC_PATCH:         return 0x020 + si * 0x10;
316*61046927SAndroid Build Coastguard Worker    case TGSI_SEMANTIC_PRIMID:        return 0x060;
317*61046927SAndroid Build Coastguard Worker    case TGSI_SEMANTIC_LAYER:         return 0x064;
318*61046927SAndroid Build Coastguard Worker    case TGSI_SEMANTIC_VIEWPORT_INDEX:return 0x068;
319*61046927SAndroid Build Coastguard Worker    case TGSI_SEMANTIC_PSIZE:         return 0x06c;
320*61046927SAndroid Build Coastguard Worker    case TGSI_SEMANTIC_POSITION:      return 0x070;
321*61046927SAndroid Build Coastguard Worker    case TGSI_SEMANTIC_GENERIC:       return 0x080 + si * 0x10;
322*61046927SAndroid Build Coastguard Worker    case TGSI_SEMANTIC_FOG:           return 0x2e8;
323*61046927SAndroid Build Coastguard Worker    case TGSI_SEMANTIC_COLOR:         return 0x280 + si * 0x10;
324*61046927SAndroid Build Coastguard Worker    case TGSI_SEMANTIC_BCOLOR:        return 0x2a0 + si * 0x10;
325*61046927SAndroid Build Coastguard Worker    case TGSI_SEMANTIC_CLIPDIST:      return 0x2c0 + si * 0x10;
326*61046927SAndroid Build Coastguard Worker    case TGSI_SEMANTIC_CLIPVERTEX:    return 0x270;
327*61046927SAndroid Build Coastguard Worker    case TGSI_SEMANTIC_TEXCOORD:      return 0x300 + si * 0x10;
328*61046927SAndroid Build Coastguard Worker    case TGSI_SEMANTIC_VIEWPORT_MASK: return 0x3a0;
329*61046927SAndroid Build Coastguard Worker    case TGSI_SEMANTIC_EDGEFLAG:      return ~0;
330*61046927SAndroid Build Coastguard Worker    default:
331*61046927SAndroid Build Coastguard Worker       assert(!"invalid TGSI output semantic");
332*61046927SAndroid Build Coastguard Worker       return ~0;
333*61046927SAndroid Build Coastguard Worker    }
334*61046927SAndroid Build Coastguard Worker }
335*61046927SAndroid Build Coastguard Worker 
336*61046927SAndroid Build Coastguard Worker static int
nvc0_vp_assign_input_slots(struct nv50_ir_prog_info_out * info)337*61046927SAndroid Build Coastguard Worker nvc0_vp_assign_input_slots(struct nv50_ir_prog_info_out *info)
338*61046927SAndroid Build Coastguard Worker {
339*61046927SAndroid Build Coastguard Worker    unsigned i, c, n;
340*61046927SAndroid Build Coastguard Worker 
341*61046927SAndroid Build Coastguard Worker    for (n = 0, i = 0; i < info->numInputs; ++i) {
342*61046927SAndroid Build Coastguard Worker       switch (info->in[i].sn) {
343*61046927SAndroid Build Coastguard Worker       case TGSI_SEMANTIC_INSTANCEID: /* for SM4 only, in TGSI they're SVs */
344*61046927SAndroid Build Coastguard Worker       case TGSI_SEMANTIC_VERTEXID:
345*61046927SAndroid Build Coastguard Worker          info->in[i].mask = 0x1;
346*61046927SAndroid Build Coastguard Worker          info->in[i].slot[0] =
347*61046927SAndroid Build Coastguard Worker             nvc0_shader_input_address(info->in[i].sn, 0) / 4;
348*61046927SAndroid Build Coastguard Worker          continue;
349*61046927SAndroid Build Coastguard Worker       default:
350*61046927SAndroid Build Coastguard Worker          break;
351*61046927SAndroid Build Coastguard Worker       }
352*61046927SAndroid Build Coastguard Worker       for (c = 0; c < 4; ++c)
353*61046927SAndroid Build Coastguard Worker          info->in[i].slot[c] = (0x80 + n * 0x10 + c * 0x4) / 4;
354*61046927SAndroid Build Coastguard Worker       ++n;
355*61046927SAndroid Build Coastguard Worker    }
356*61046927SAndroid Build Coastguard Worker 
357*61046927SAndroid Build Coastguard Worker    return 0;
358*61046927SAndroid Build Coastguard Worker }
359*61046927SAndroid Build Coastguard Worker 
360*61046927SAndroid Build Coastguard Worker static int
nvc0_sp_assign_input_slots(struct nv50_ir_prog_info_out * info)361*61046927SAndroid Build Coastguard Worker nvc0_sp_assign_input_slots(struct nv50_ir_prog_info_out *info)
362*61046927SAndroid Build Coastguard Worker {
363*61046927SAndroid Build Coastguard Worker    unsigned offset;
364*61046927SAndroid Build Coastguard Worker    unsigned i, c;
365*61046927SAndroid Build Coastguard Worker 
366*61046927SAndroid Build Coastguard Worker    for (i = 0; i < info->numInputs; ++i) {
367*61046927SAndroid Build Coastguard Worker       offset = nvc0_shader_input_address(info->in[i].sn, info->in[i].si);
368*61046927SAndroid Build Coastguard Worker 
369*61046927SAndroid Build Coastguard Worker       for (c = 0; c < 4; ++c)
370*61046927SAndroid Build Coastguard Worker          info->in[i].slot[c] = (offset + c * 0x4) / 4;
371*61046927SAndroid Build Coastguard Worker    }
372*61046927SAndroid Build Coastguard Worker 
373*61046927SAndroid Build Coastguard Worker    return 0;
374*61046927SAndroid Build Coastguard Worker }
375*61046927SAndroid Build Coastguard Worker 
376*61046927SAndroid Build Coastguard Worker static int
nvc0_fp_assign_output_slots(struct nv50_ir_prog_info_out * info)377*61046927SAndroid Build Coastguard Worker nvc0_fp_assign_output_slots(struct nv50_ir_prog_info_out *info)
378*61046927SAndroid Build Coastguard Worker {
379*61046927SAndroid Build Coastguard Worker    unsigned count = info->prop.fp.numColourResults * 4;
380*61046927SAndroid Build Coastguard Worker    unsigned i, c;
381*61046927SAndroid Build Coastguard Worker 
382*61046927SAndroid Build Coastguard Worker    /* Compute the relative position of each color output, since skipped MRT
383*61046927SAndroid Build Coastguard Worker     * positions will not have registers allocated to them.
384*61046927SAndroid Build Coastguard Worker     */
385*61046927SAndroid Build Coastguard Worker    unsigned colors[8] = {0};
386*61046927SAndroid Build Coastguard Worker    for (i = 0; i < info->numOutputs; ++i)
387*61046927SAndroid Build Coastguard Worker       if (info->out[i].sn == TGSI_SEMANTIC_COLOR)
388*61046927SAndroid Build Coastguard Worker          colors[info->out[i].si] = 1;
389*61046927SAndroid Build Coastguard Worker    for (i = 0, c = 0; i < 8; i++)
390*61046927SAndroid Build Coastguard Worker       if (colors[i])
391*61046927SAndroid Build Coastguard Worker          colors[i] = c++;
392*61046927SAndroid Build Coastguard Worker    for (i = 0; i < info->numOutputs; ++i)
393*61046927SAndroid Build Coastguard Worker       if (info->out[i].sn == TGSI_SEMANTIC_COLOR)
394*61046927SAndroid Build Coastguard Worker          for (c = 0; c < 4; ++c)
395*61046927SAndroid Build Coastguard Worker             info->out[i].slot[c] = colors[info->out[i].si] * 4 + c;
396*61046927SAndroid Build Coastguard Worker 
397*61046927SAndroid Build Coastguard Worker    if (info->io.sampleMask < NV50_CODEGEN_MAX_VARYINGS)
398*61046927SAndroid Build Coastguard Worker       info->out[info->io.sampleMask].slot[0] = count++;
399*61046927SAndroid Build Coastguard Worker    else
400*61046927SAndroid Build Coastguard Worker    if (info->target >= 0xe0)
401*61046927SAndroid Build Coastguard Worker       count++; /* on Kepler, depth is always last colour reg + 2 */
402*61046927SAndroid Build Coastguard Worker 
403*61046927SAndroid Build Coastguard Worker    if (info->io.fragDepth < NV50_CODEGEN_MAX_VARYINGS)
404*61046927SAndroid Build Coastguard Worker       info->out[info->io.fragDepth].slot[2] = count;
405*61046927SAndroid Build Coastguard Worker 
406*61046927SAndroid Build Coastguard Worker    return 0;
407*61046927SAndroid Build Coastguard Worker }
408*61046927SAndroid Build Coastguard Worker 
409*61046927SAndroid Build Coastguard Worker static int
nvc0_sp_assign_output_slots(struct nv50_ir_prog_info_out * info)410*61046927SAndroid Build Coastguard Worker nvc0_sp_assign_output_slots(struct nv50_ir_prog_info_out *info)
411*61046927SAndroid Build Coastguard Worker {
412*61046927SAndroid Build Coastguard Worker    unsigned offset;
413*61046927SAndroid Build Coastguard Worker    unsigned i, c;
414*61046927SAndroid Build Coastguard Worker 
415*61046927SAndroid Build Coastguard Worker    for (i = 0; i < info->numOutputs; ++i) {
416*61046927SAndroid Build Coastguard Worker       offset = nvc0_shader_output_address(info->out[i].sn, info->out[i].si);
417*61046927SAndroid Build Coastguard Worker 
418*61046927SAndroid Build Coastguard Worker       for (c = 0; c < 4; ++c)
419*61046927SAndroid Build Coastguard Worker          info->out[i].slot[c] = (offset + c * 0x4) / 4;
420*61046927SAndroid Build Coastguard Worker    }
421*61046927SAndroid Build Coastguard Worker 
422*61046927SAndroid Build Coastguard Worker    return 0;
423*61046927SAndroid Build Coastguard Worker }
424*61046927SAndroid Build Coastguard Worker 
425*61046927SAndroid Build Coastguard Worker static int
nvc0_program_assign_varying_slots(struct nv50_ir_prog_info_out * info)426*61046927SAndroid Build Coastguard Worker nvc0_program_assign_varying_slots(struct nv50_ir_prog_info_out *info)
427*61046927SAndroid Build Coastguard Worker {
428*61046927SAndroid Build Coastguard Worker    int ret;
429*61046927SAndroid Build Coastguard Worker 
430*61046927SAndroid Build Coastguard Worker    if (info->type == PIPE_SHADER_VERTEX)
431*61046927SAndroid Build Coastguard Worker       ret = nvc0_vp_assign_input_slots(info);
432*61046927SAndroid Build Coastguard Worker    else
433*61046927SAndroid Build Coastguard Worker       ret = nvc0_sp_assign_input_slots(info);
434*61046927SAndroid Build Coastguard Worker    if (ret)
435*61046927SAndroid Build Coastguard Worker       return ret;
436*61046927SAndroid Build Coastguard Worker 
437*61046927SAndroid Build Coastguard Worker    if (info->type == PIPE_SHADER_FRAGMENT)
438*61046927SAndroid Build Coastguard Worker       ret = nvc0_fp_assign_output_slots(info);
439*61046927SAndroid Build Coastguard Worker    else
440*61046927SAndroid Build Coastguard Worker       ret = nvc0_sp_assign_output_slots(info);
441*61046927SAndroid Build Coastguard Worker    return ret;
442*61046927SAndroid Build Coastguard Worker }
443*61046927SAndroid Build Coastguard Worker 
444*61046927SAndroid Build Coastguard Worker static inline void
nvk_vtgs_hdr_update_oread(struct nvk_shader * vs,uint8_t slot)445*61046927SAndroid Build Coastguard Worker nvk_vtgs_hdr_update_oread(struct nvk_shader *vs, uint8_t slot)
446*61046927SAndroid Build Coastguard Worker {
447*61046927SAndroid Build Coastguard Worker    uint8_t min = (vs->info.hdr[4] >> 12) & 0xff;
448*61046927SAndroid Build Coastguard Worker    uint8_t max = (vs->info.hdr[4] >> 24);
449*61046927SAndroid Build Coastguard Worker 
450*61046927SAndroid Build Coastguard Worker    min = MIN2(min, slot);
451*61046927SAndroid Build Coastguard Worker    max = MAX2(max, slot);
452*61046927SAndroid Build Coastguard Worker 
453*61046927SAndroid Build Coastguard Worker    vs->info.hdr[4] = (max << 24) | (min << 12);
454*61046927SAndroid Build Coastguard Worker }
455*61046927SAndroid Build Coastguard Worker 
456*61046927SAndroid Build Coastguard Worker static int
nvk_vtgp_gen_header(struct nvk_shader * vs,struct nv50_ir_prog_info_out * info)457*61046927SAndroid Build Coastguard Worker nvk_vtgp_gen_header(struct nvk_shader *vs, struct nv50_ir_prog_info_out *info)
458*61046927SAndroid Build Coastguard Worker {
459*61046927SAndroid Build Coastguard Worker    unsigned i, c, a;
460*61046927SAndroid Build Coastguard Worker 
461*61046927SAndroid Build Coastguard Worker    for (i = 0; i < info->numInputs; ++i) {
462*61046927SAndroid Build Coastguard Worker       if (info->in[i].patch)
463*61046927SAndroid Build Coastguard Worker          continue;
464*61046927SAndroid Build Coastguard Worker       for (c = 0; c < 4; ++c) {
465*61046927SAndroid Build Coastguard Worker          a = info->in[i].slot[c];
466*61046927SAndroid Build Coastguard Worker          if (info->in[i].mask & (1 << c))
467*61046927SAndroid Build Coastguard Worker             vs->info.hdr[5 + a / 32] |= 1 << (a % 32);
468*61046927SAndroid Build Coastguard Worker       }
469*61046927SAndroid Build Coastguard Worker    }
470*61046927SAndroid Build Coastguard Worker 
471*61046927SAndroid Build Coastguard Worker    for (i = 0; i < info->numOutputs; ++i) {
472*61046927SAndroid Build Coastguard Worker       if (info->out[i].patch)
473*61046927SAndroid Build Coastguard Worker          continue;
474*61046927SAndroid Build Coastguard Worker       for (c = 0; c < 4; ++c) {
475*61046927SAndroid Build Coastguard Worker          if (!(info->out[i].mask & (1 << c)))
476*61046927SAndroid Build Coastguard Worker             continue;
477*61046927SAndroid Build Coastguard Worker          assert(info->out[i].slot[c] >= 0x40 / 4);
478*61046927SAndroid Build Coastguard Worker          a = info->out[i].slot[c] - 0x40 / 4;
479*61046927SAndroid Build Coastguard Worker          vs->info.hdr[13 + a / 32] |= 1 << (a % 32);
480*61046927SAndroid Build Coastguard Worker          if (info->out[i].oread)
481*61046927SAndroid Build Coastguard Worker             nvk_vtgs_hdr_update_oread(vs, info->out[i].slot[c]);
482*61046927SAndroid Build Coastguard Worker       }
483*61046927SAndroid Build Coastguard Worker    }
484*61046927SAndroid Build Coastguard Worker 
485*61046927SAndroid Build Coastguard Worker    for (i = 0; i < info->numSysVals; ++i) {
486*61046927SAndroid Build Coastguard Worker       switch (info->sv[i].sn) {
487*61046927SAndroid Build Coastguard Worker       case SYSTEM_VALUE_PRIMITIVE_ID:
488*61046927SAndroid Build Coastguard Worker          vs->info.hdr[5] |= 1 << 24;
489*61046927SAndroid Build Coastguard Worker          break;
490*61046927SAndroid Build Coastguard Worker       case SYSTEM_VALUE_INSTANCE_ID:
491*61046927SAndroid Build Coastguard Worker          vs->info.hdr[10] |= 1 << 30;
492*61046927SAndroid Build Coastguard Worker          break;
493*61046927SAndroid Build Coastguard Worker       case SYSTEM_VALUE_VERTEX_ID:
494*61046927SAndroid Build Coastguard Worker          vs->info.hdr[10] |= 1 << 31;
495*61046927SAndroid Build Coastguard Worker          break;
496*61046927SAndroid Build Coastguard Worker       case SYSTEM_VALUE_TESS_COORD:
497*61046927SAndroid Build Coastguard Worker          /* We don't have the mask, nor the slots populated. While this could
498*61046927SAndroid Build Coastguard Worker           * be achieved, the vast majority of the time if either of the coords
499*61046927SAndroid Build Coastguard Worker           * are read, then both will be read.
500*61046927SAndroid Build Coastguard Worker           */
501*61046927SAndroid Build Coastguard Worker          nvk_vtgs_hdr_update_oread(vs, 0x2f0 / 4);
502*61046927SAndroid Build Coastguard Worker          nvk_vtgs_hdr_update_oread(vs, 0x2f4 / 4);
503*61046927SAndroid Build Coastguard Worker          break;
504*61046927SAndroid Build Coastguard Worker       default:
505*61046927SAndroid Build Coastguard Worker          break;
506*61046927SAndroid Build Coastguard Worker       }
507*61046927SAndroid Build Coastguard Worker    }
508*61046927SAndroid Build Coastguard Worker 
509*61046927SAndroid Build Coastguard Worker    vs->info.vtg.writes_layer = (vs->info.hdr[13] & (1 << 9)) != 0;
510*61046927SAndroid Build Coastguard Worker    vs->info.vtg.clip_enable = (1 << info->io.clipDistances) - 1;
511*61046927SAndroid Build Coastguard Worker    vs->info.vtg.cull_enable =
512*61046927SAndroid Build Coastguard Worker       ((1 << info->io.cullDistances) - 1) << info->io.clipDistances;
513*61046927SAndroid Build Coastguard Worker 
514*61046927SAndroid Build Coastguard Worker    return 0;
515*61046927SAndroid Build Coastguard Worker }
516*61046927SAndroid Build Coastguard Worker 
517*61046927SAndroid Build Coastguard Worker static int
nvk_vs_gen_header(struct nvk_shader * vs,struct nv50_ir_prog_info_out * info)518*61046927SAndroid Build Coastguard Worker nvk_vs_gen_header(struct nvk_shader *vs, struct nv50_ir_prog_info_out *info)
519*61046927SAndroid Build Coastguard Worker {
520*61046927SAndroid Build Coastguard Worker    vs->info.hdr[0] = 0x20061 | (1 << 10);
521*61046927SAndroid Build Coastguard Worker    vs->info.hdr[4] = 0xff000;
522*61046927SAndroid Build Coastguard Worker 
523*61046927SAndroid Build Coastguard Worker    return nvk_vtgp_gen_header(vs, info);
524*61046927SAndroid Build Coastguard Worker }
525*61046927SAndroid Build Coastguard Worker 
526*61046927SAndroid Build Coastguard Worker static int
nvk_gs_gen_header(struct nvk_shader * gs,const struct nir_shader * nir,struct nv50_ir_prog_info_out * info)527*61046927SAndroid Build Coastguard Worker nvk_gs_gen_header(struct nvk_shader *gs,
528*61046927SAndroid Build Coastguard Worker                   const struct nir_shader *nir,
529*61046927SAndroid Build Coastguard Worker                   struct nv50_ir_prog_info_out *info)
530*61046927SAndroid Build Coastguard Worker {
531*61046927SAndroid Build Coastguard Worker    gs->info.hdr[0] = 0x20061 | (4 << 10);
532*61046927SAndroid Build Coastguard Worker 
533*61046927SAndroid Build Coastguard Worker    gs->info.hdr[2] = MIN2(info->prop.gp.instanceCount, 32) << 24;
534*61046927SAndroid Build Coastguard Worker 
535*61046927SAndroid Build Coastguard Worker    switch (info->prop.gp.outputPrim) {
536*61046927SAndroid Build Coastguard Worker    case MESA_PRIM_POINTS:
537*61046927SAndroid Build Coastguard Worker       gs->info.hdr[3] = 0x01000000;
538*61046927SAndroid Build Coastguard Worker       break;
539*61046927SAndroid Build Coastguard Worker    case MESA_PRIM_LINE_STRIP:
540*61046927SAndroid Build Coastguard Worker       gs->info.hdr[3] = 0x06000000;
541*61046927SAndroid Build Coastguard Worker       break;
542*61046927SAndroid Build Coastguard Worker    case MESA_PRIM_TRIANGLE_STRIP:
543*61046927SAndroid Build Coastguard Worker       gs->info.hdr[3] = 0x07000000;
544*61046927SAndroid Build Coastguard Worker       break;
545*61046927SAndroid Build Coastguard Worker    default:
546*61046927SAndroid Build Coastguard Worker       assert(0);
547*61046927SAndroid Build Coastguard Worker       break;
548*61046927SAndroid Build Coastguard Worker    }
549*61046927SAndroid Build Coastguard Worker 
550*61046927SAndroid Build Coastguard Worker    gs->info.hdr[4] = CLAMP(info->prop.gp.maxVertices, 1, 1024);
551*61046927SAndroid Build Coastguard Worker 
552*61046927SAndroid Build Coastguard Worker    gs->info.hdr[0] |= nir->info.gs.active_stream_mask << 28;
553*61046927SAndroid Build Coastguard Worker 
554*61046927SAndroid Build Coastguard Worker    return nvk_vtgp_gen_header(gs, info);
555*61046927SAndroid Build Coastguard Worker }
556*61046927SAndroid Build Coastguard Worker 
557*61046927SAndroid Build Coastguard Worker static void
nvk_generate_tessellation_parameters(const struct nv50_ir_prog_info_out * info,struct nvk_shader * shader)558*61046927SAndroid Build Coastguard Worker nvk_generate_tessellation_parameters(const struct nv50_ir_prog_info_out *info,
559*61046927SAndroid Build Coastguard Worker                                      struct nvk_shader *shader)
560*61046927SAndroid Build Coastguard Worker {
561*61046927SAndroid Build Coastguard Worker    // TODO: this is a little confusing because nouveau codegen uses
562*61046927SAndroid Build Coastguard Worker    // MESA_PRIM_POINTS for unspecified domain and
563*61046927SAndroid Build Coastguard Worker    // MESA_PRIM_POINTS = 0, the same as NV9097 ISOLINE enum
564*61046927SAndroid Build Coastguard Worker    switch (info->prop.tp.domain) {
565*61046927SAndroid Build Coastguard Worker    case MESA_PRIM_LINES:
566*61046927SAndroid Build Coastguard Worker       shader->info.ts.domain = NAK_TS_DOMAIN_ISOLINE;
567*61046927SAndroid Build Coastguard Worker       break;
568*61046927SAndroid Build Coastguard Worker    case MESA_PRIM_TRIANGLES:
569*61046927SAndroid Build Coastguard Worker       shader->info.ts.domain = NAK_TS_DOMAIN_TRIANGLE;
570*61046927SAndroid Build Coastguard Worker       break;
571*61046927SAndroid Build Coastguard Worker    case MESA_PRIM_QUADS:
572*61046927SAndroid Build Coastguard Worker       shader->info.ts.domain = NAK_TS_DOMAIN_QUAD;
573*61046927SAndroid Build Coastguard Worker       break;
574*61046927SAndroid Build Coastguard Worker    default:
575*61046927SAndroid Build Coastguard Worker       return;
576*61046927SAndroid Build Coastguard Worker    }
577*61046927SAndroid Build Coastguard Worker 
578*61046927SAndroid Build Coastguard Worker    switch (info->prop.tp.partitioning) {
579*61046927SAndroid Build Coastguard Worker    case PIPE_TESS_SPACING_EQUAL:
580*61046927SAndroid Build Coastguard Worker       shader->info.ts.spacing = NAK_TS_SPACING_INTEGER;
581*61046927SAndroid Build Coastguard Worker       break;
582*61046927SAndroid Build Coastguard Worker    case PIPE_TESS_SPACING_FRACTIONAL_ODD:
583*61046927SAndroid Build Coastguard Worker       shader->info.ts.spacing = NAK_TS_SPACING_FRACT_ODD;
584*61046927SAndroid Build Coastguard Worker       break;
585*61046927SAndroid Build Coastguard Worker    case PIPE_TESS_SPACING_FRACTIONAL_EVEN:
586*61046927SAndroid Build Coastguard Worker       shader->info.ts.spacing = NAK_TS_SPACING_FRACT_EVEN;
587*61046927SAndroid Build Coastguard Worker       break;
588*61046927SAndroid Build Coastguard Worker    default:
589*61046927SAndroid Build Coastguard Worker       assert(!"invalid tessellator partitioning");
590*61046927SAndroid Build Coastguard Worker       break;
591*61046927SAndroid Build Coastguard Worker    }
592*61046927SAndroid Build Coastguard Worker 
593*61046927SAndroid Build Coastguard Worker    if (info->prop.tp.outputPrim == MESA_PRIM_POINTS) { // point_mode
594*61046927SAndroid Build Coastguard Worker       shader->info.ts.prims = NAK_TS_PRIMS_POINTS;
595*61046927SAndroid Build Coastguard Worker    } else if (info->prop.tp.domain == MESA_PRIM_LINES) { // isoline domain
596*61046927SAndroid Build Coastguard Worker       shader->info.ts.prims = NAK_TS_PRIMS_LINES;
597*61046927SAndroid Build Coastguard Worker    } else {  // triangle/quad domain
598*61046927SAndroid Build Coastguard Worker       if (info->prop.tp.winding > 0) {
599*61046927SAndroid Build Coastguard Worker          shader->info.ts.prims = NAK_TS_PRIMS_TRIANGLES_CW;
600*61046927SAndroid Build Coastguard Worker       } else {
601*61046927SAndroid Build Coastguard Worker          shader->info.ts.prims = NAK_TS_PRIMS_TRIANGLES_CCW;
602*61046927SAndroid Build Coastguard Worker       }
603*61046927SAndroid Build Coastguard Worker    }
604*61046927SAndroid Build Coastguard Worker }
605*61046927SAndroid Build Coastguard Worker 
606*61046927SAndroid Build Coastguard Worker static int
nvk_tcs_gen_header(struct nvk_shader * tcs,struct nv50_ir_prog_info_out * info)607*61046927SAndroid Build Coastguard Worker nvk_tcs_gen_header(struct nvk_shader *tcs, struct nv50_ir_prog_info_out *info)
608*61046927SAndroid Build Coastguard Worker {
609*61046927SAndroid Build Coastguard Worker    unsigned opcs = 6; /* output patch constants (at least the TessFactors) */
610*61046927SAndroid Build Coastguard Worker 
611*61046927SAndroid Build Coastguard Worker    if (info->numPatchConstants)
612*61046927SAndroid Build Coastguard Worker       opcs = 8 + info->numPatchConstants * 4;
613*61046927SAndroid Build Coastguard Worker 
614*61046927SAndroid Build Coastguard Worker    tcs->info.hdr[0] = 0x20061 | (2 << 10);
615*61046927SAndroid Build Coastguard Worker 
616*61046927SAndroid Build Coastguard Worker    tcs->info.hdr[1] = opcs << 24;
617*61046927SAndroid Build Coastguard Worker    tcs->info.hdr[2] = info->prop.tp.outputPatchSize << 24;
618*61046927SAndroid Build Coastguard Worker 
619*61046927SAndroid Build Coastguard Worker    tcs->info.hdr[4] = 0xff000; /* initial min/max parallel output read address */
620*61046927SAndroid Build Coastguard Worker 
621*61046927SAndroid Build Coastguard Worker    nvk_vtgp_gen_header(tcs, info);
622*61046927SAndroid Build Coastguard Worker 
623*61046927SAndroid Build Coastguard Worker    if (info->target >= NVISA_GM107_CHIPSET) {
624*61046927SAndroid Build Coastguard Worker       /* On GM107+, the number of output patch components has moved in the TCP
625*61046927SAndroid Build Coastguard Worker        * header, but it seems like blob still also uses the old position.
626*61046927SAndroid Build Coastguard Worker        * Also, the high 8-bits are located in between the min/max parallel
627*61046927SAndroid Build Coastguard Worker        * field and has to be set after updating the outputs. */
628*61046927SAndroid Build Coastguard Worker       tcs->info.hdr[3] = (opcs & 0x0f) << 28;
629*61046927SAndroid Build Coastguard Worker       tcs->info.hdr[4] |= (opcs & 0xf0) << 16;
630*61046927SAndroid Build Coastguard Worker    }
631*61046927SAndroid Build Coastguard Worker 
632*61046927SAndroid Build Coastguard Worker    nvk_generate_tessellation_parameters(info, tcs);
633*61046927SAndroid Build Coastguard Worker 
634*61046927SAndroid Build Coastguard Worker    return 0;
635*61046927SAndroid Build Coastguard Worker }
636*61046927SAndroid Build Coastguard Worker 
637*61046927SAndroid Build Coastguard Worker static int
nvk_tes_gen_header(struct nvk_shader * tes,struct nv50_ir_prog_info_out * info)638*61046927SAndroid Build Coastguard Worker nvk_tes_gen_header(struct nvk_shader *tes, struct nv50_ir_prog_info_out *info)
639*61046927SAndroid Build Coastguard Worker {
640*61046927SAndroid Build Coastguard Worker    tes->info.hdr[0] = 0x20061 | (3 << 10);
641*61046927SAndroid Build Coastguard Worker    tes->info.hdr[4] = 0xff000;
642*61046927SAndroid Build Coastguard Worker 
643*61046927SAndroid Build Coastguard Worker    nvk_vtgp_gen_header(tes, info);
644*61046927SAndroid Build Coastguard Worker 
645*61046927SAndroid Build Coastguard Worker    nvk_generate_tessellation_parameters(info, tes);
646*61046927SAndroid Build Coastguard Worker 
647*61046927SAndroid Build Coastguard Worker    tes->info.hdr[18] |= 0x3 << 12; /* ? */
648*61046927SAndroid Build Coastguard Worker 
649*61046927SAndroid Build Coastguard Worker    return 0;
650*61046927SAndroid Build Coastguard Worker }
651*61046927SAndroid Build Coastguard Worker 
652*61046927SAndroid Build Coastguard Worker #define NVC0_INTERP_FLAT          (1 << 0)
653*61046927SAndroid Build Coastguard Worker #define NVC0_INTERP_PERSPECTIVE   (2 << 0)
654*61046927SAndroid Build Coastguard Worker #define NVC0_INTERP_LINEAR        (3 << 0)
655*61046927SAndroid Build Coastguard Worker #define NVC0_INTERP_CENTROID      (1 << 2)
656*61046927SAndroid Build Coastguard Worker 
657*61046927SAndroid Build Coastguard Worker static uint8_t
nvk_hdr_interp_mode(const struct nv50_ir_varying * var)658*61046927SAndroid Build Coastguard Worker nvk_hdr_interp_mode(const struct nv50_ir_varying *var)
659*61046927SAndroid Build Coastguard Worker {
660*61046927SAndroid Build Coastguard Worker    if (var->linear)
661*61046927SAndroid Build Coastguard Worker       return NVC0_INTERP_LINEAR;
662*61046927SAndroid Build Coastguard Worker    if (var->flat)
663*61046927SAndroid Build Coastguard Worker       return NVC0_INTERP_FLAT;
664*61046927SAndroid Build Coastguard Worker    return NVC0_INTERP_PERSPECTIVE;
665*61046927SAndroid Build Coastguard Worker }
666*61046927SAndroid Build Coastguard Worker 
667*61046927SAndroid Build Coastguard Worker 
668*61046927SAndroid Build Coastguard Worker static int
nvk_fs_gen_header(struct nvk_shader * fs,const struct nak_fs_key * key,struct nv50_ir_prog_info_out * info)669*61046927SAndroid Build Coastguard Worker nvk_fs_gen_header(struct nvk_shader *fs, const struct nak_fs_key *key,
670*61046927SAndroid Build Coastguard Worker                   struct nv50_ir_prog_info_out *info)
671*61046927SAndroid Build Coastguard Worker {
672*61046927SAndroid Build Coastguard Worker    unsigned i, c, a, m;
673*61046927SAndroid Build Coastguard Worker 
674*61046927SAndroid Build Coastguard Worker    /* just 00062 on Kepler */
675*61046927SAndroid Build Coastguard Worker    fs->info.hdr[0] = 0x20062 | (5 << 10);
676*61046927SAndroid Build Coastguard Worker    fs->info.hdr[5] = 0x80000000; /* getting a trap if FRAG_COORD_UMASK.w = 0 */
677*61046927SAndroid Build Coastguard Worker 
678*61046927SAndroid Build Coastguard Worker    if (info->prop.fp.usesDiscard || key->zs_self_dep)
679*61046927SAndroid Build Coastguard Worker       fs->info.hdr[0] |= 0x8000;
680*61046927SAndroid Build Coastguard Worker    if (!info->prop.fp.separateFragData)
681*61046927SAndroid Build Coastguard Worker       fs->info.hdr[0] |= 0x4000;
682*61046927SAndroid Build Coastguard Worker    if (info->io.sampleMask < 80 /* PIPE_MAX_SHADER_OUTPUTS */)
683*61046927SAndroid Build Coastguard Worker       fs->info.hdr[19] |= 0x1;
684*61046927SAndroid Build Coastguard Worker    if (info->prop.fp.writesDepth) {
685*61046927SAndroid Build Coastguard Worker       fs->info.hdr[19] |= 0x2;
686*61046927SAndroid Build Coastguard Worker       fs->info.fs.writes_depth = true;
687*61046927SAndroid Build Coastguard Worker    }
688*61046927SAndroid Build Coastguard Worker 
689*61046927SAndroid Build Coastguard Worker    for (i = 0; i < info->numInputs; ++i) {
690*61046927SAndroid Build Coastguard Worker       m = nvk_hdr_interp_mode(&info->in[i]);
691*61046927SAndroid Build Coastguard Worker       for (c = 0; c < 4; ++c) {
692*61046927SAndroid Build Coastguard Worker          if (!(info->in[i].mask & (1 << c)))
693*61046927SAndroid Build Coastguard Worker             continue;
694*61046927SAndroid Build Coastguard Worker          a = info->in[i].slot[c];
695*61046927SAndroid Build Coastguard Worker          if (info->in[i].slot[0] >= (0x060 / 4) &&
696*61046927SAndroid Build Coastguard Worker              info->in[i].slot[0] <= (0x07c / 4)) {
697*61046927SAndroid Build Coastguard Worker             fs->info.hdr[5] |= 1 << (24 + (a - 0x060 / 4));
698*61046927SAndroid Build Coastguard Worker          } else
699*61046927SAndroid Build Coastguard Worker          if (info->in[i].slot[0] >= (0x2c0 / 4) &&
700*61046927SAndroid Build Coastguard Worker              info->in[i].slot[0] <= (0x2fc / 4)) {
701*61046927SAndroid Build Coastguard Worker             fs->info.hdr[14] |= (1 << (a - 0x280 / 4)) & 0x07ff0000;
702*61046927SAndroid Build Coastguard Worker          } else {
703*61046927SAndroid Build Coastguard Worker             if (info->in[i].slot[c] < (0x040 / 4) ||
704*61046927SAndroid Build Coastguard Worker                 info->in[i].slot[c] > (0x380 / 4))
705*61046927SAndroid Build Coastguard Worker                continue;
706*61046927SAndroid Build Coastguard Worker             a *= 2;
707*61046927SAndroid Build Coastguard Worker             if (info->in[i].slot[0] >= (0x300 / 4))
708*61046927SAndroid Build Coastguard Worker                a -= 32;
709*61046927SAndroid Build Coastguard Worker             fs->info.hdr[4 + a / 32] |= m << (a % 32);
710*61046927SAndroid Build Coastguard Worker          }
711*61046927SAndroid Build Coastguard Worker       }
712*61046927SAndroid Build Coastguard Worker    }
713*61046927SAndroid Build Coastguard Worker    /* GM20x+ needs TGSI_SEMANTIC_POSITION to access sample locations */
714*61046927SAndroid Build Coastguard Worker    if (info->prop.fp.readsSampleLocations && info->target >= NVISA_GM200_CHIPSET)
715*61046927SAndroid Build Coastguard Worker       fs->info.hdr[5] |= 0x30000000;
716*61046927SAndroid Build Coastguard Worker 
717*61046927SAndroid Build Coastguard Worker    for (i = 0; i < info->numOutputs; ++i) {
718*61046927SAndroid Build Coastguard Worker       if (info->out[i].sn == TGSI_SEMANTIC_COLOR)
719*61046927SAndroid Build Coastguard Worker          fs->info.hdr[18] |= 0xf << (4 * info->out[i].si);
720*61046927SAndroid Build Coastguard Worker    }
721*61046927SAndroid Build Coastguard Worker 
722*61046927SAndroid Build Coastguard Worker    /* There are no "regular" attachments, but the shader still needs to be
723*61046927SAndroid Build Coastguard Worker     * executed. It seems like it wants to think that it has some color
724*61046927SAndroid Build Coastguard Worker     * outputs in order to actually run.
725*61046927SAndroid Build Coastguard Worker     */
726*61046927SAndroid Build Coastguard Worker    if (info->prop.fp.numColourResults == 0 &&
727*61046927SAndroid Build Coastguard Worker        !info->prop.fp.writesDepth &&
728*61046927SAndroid Build Coastguard Worker        info->io.sampleMask >= 80 /* PIPE_MAX_SHADER_OUTPUTS */)
729*61046927SAndroid Build Coastguard Worker       fs->info.hdr[18] |= 0xf;
730*61046927SAndroid Build Coastguard Worker 
731*61046927SAndroid Build Coastguard Worker    fs->info.fs.early_fragment_tests = info->prop.fp.earlyFragTests;
732*61046927SAndroid Build Coastguard Worker    fs->info.fs.reads_sample_mask = info->prop.fp.usesSampleMaskIn;
733*61046927SAndroid Build Coastguard Worker    fs->info.fs.post_depth_coverage = info->prop.fp.postDepthCoverage;
734*61046927SAndroid Build Coastguard Worker 
735*61046927SAndroid Build Coastguard Worker    return 0;
736*61046927SAndroid Build Coastguard Worker }
737*61046927SAndroid Build Coastguard Worker 
find_register_index_for_xfb_output(const struct nir_shader * nir,nir_xfb_output_info output)738*61046927SAndroid Build Coastguard Worker static uint8_t find_register_index_for_xfb_output(const struct nir_shader *nir,
739*61046927SAndroid Build Coastguard Worker                                                   nir_xfb_output_info output)
740*61046927SAndroid Build Coastguard Worker {
741*61046927SAndroid Build Coastguard Worker    nir_foreach_shader_out_variable(var, nir) {
742*61046927SAndroid Build Coastguard Worker       uint32_t slots = glsl_count_vec4_slots(var->type, false, false);
743*61046927SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < slots; ++i) {
744*61046927SAndroid Build Coastguard Worker          if (output.location == (var->data.location+i)) {
745*61046927SAndroid Build Coastguard Worker             return var->data.driver_location+i;
746*61046927SAndroid Build Coastguard Worker          }
747*61046927SAndroid Build Coastguard Worker       }
748*61046927SAndroid Build Coastguard Worker    }
749*61046927SAndroid Build Coastguard Worker    // should not be reached
750*61046927SAndroid Build Coastguard Worker    return 0;
751*61046927SAndroid Build Coastguard Worker }
752*61046927SAndroid Build Coastguard Worker 
753*61046927SAndroid Build Coastguard Worker static void
nvk_fill_transform_feedback_state(struct nak_xfb_info * xfb,struct nir_shader * nir,const struct nv50_ir_prog_info_out * info)754*61046927SAndroid Build Coastguard Worker nvk_fill_transform_feedback_state(struct nak_xfb_info *xfb,
755*61046927SAndroid Build Coastguard Worker                                   struct nir_shader *nir,
756*61046927SAndroid Build Coastguard Worker                                   const struct nv50_ir_prog_info_out *info)
757*61046927SAndroid Build Coastguard Worker {
758*61046927SAndroid Build Coastguard Worker    const uint8_t max_buffers = 4;
759*61046927SAndroid Build Coastguard Worker    const uint8_t dw_bytes = 4;
760*61046927SAndroid Build Coastguard Worker    const struct nir_xfb_info *nx = nir->xfb_info;
761*61046927SAndroid Build Coastguard Worker    //nir_print_xfb_info(nx, stdout);
762*61046927SAndroid Build Coastguard Worker 
763*61046927SAndroid Build Coastguard Worker    memset(xfb, 0, sizeof(*xfb));
764*61046927SAndroid Build Coastguard Worker 
765*61046927SAndroid Build Coastguard Worker    for (uint8_t b = 0; b < max_buffers; ++b) {
766*61046927SAndroid Build Coastguard Worker       xfb->stride[b] = b < nx->buffers_written ? nx->buffers[b].stride : 0;
767*61046927SAndroid Build Coastguard Worker       xfb->attr_count[b] = 0;
768*61046927SAndroid Build Coastguard Worker       xfb->stream[b] = nx->buffer_to_stream[b];
769*61046927SAndroid Build Coastguard Worker    }
770*61046927SAndroid Build Coastguard Worker    memset(xfb->attr_index, 0xff, sizeof(xfb->attr_index)); /* = skip */
771*61046927SAndroid Build Coastguard Worker 
772*61046927SAndroid Build Coastguard Worker    if (info->numOutputs == 0)
773*61046927SAndroid Build Coastguard Worker       return;
774*61046927SAndroid Build Coastguard Worker 
775*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < nx->output_count; ++i) {
776*61046927SAndroid Build Coastguard Worker       const nir_xfb_output_info output = nx->outputs[i];
777*61046927SAndroid Build Coastguard Worker       const uint8_t b = output.buffer;
778*61046927SAndroid Build Coastguard Worker       const uint8_t r = find_register_index_for_xfb_output(nir, output);
779*61046927SAndroid Build Coastguard Worker       uint32_t p = output.offset / dw_bytes;
780*61046927SAndroid Build Coastguard Worker 
781*61046927SAndroid Build Coastguard Worker       assert(r < info->numOutputs && p < ARRAY_SIZE(xfb->attr_index[b]));
782*61046927SAndroid Build Coastguard Worker 
783*61046927SAndroid Build Coastguard Worker       u_foreach_bit(c, nx->outputs[i].component_mask)
784*61046927SAndroid Build Coastguard Worker          xfb->attr_index[b][p++] = info->out[r].slot[c];
785*61046927SAndroid Build Coastguard Worker 
786*61046927SAndroid Build Coastguard Worker       xfb->attr_count[b] = MAX2(xfb->attr_count[b], p);
787*61046927SAndroid Build Coastguard Worker    }
788*61046927SAndroid Build Coastguard Worker 
789*61046927SAndroid Build Coastguard Worker    /* zero unused indices */
790*61046927SAndroid Build Coastguard Worker    for (uint8_t b = 0; b < 4; ++b)
791*61046927SAndroid Build Coastguard Worker       for (uint32_t c = xfb->attr_count[b]; c & 3; ++c)
792*61046927SAndroid Build Coastguard Worker          xfb->attr_index[b][c] = 0;
793*61046927SAndroid Build Coastguard Worker }
794*61046927SAndroid Build Coastguard Worker 
795*61046927SAndroid Build Coastguard Worker VkResult
nvk_cg_compile_nir(struct nvk_physical_device * pdev,nir_shader * nir,const struct nak_fs_key * fs_key,struct nvk_shader * shader)796*61046927SAndroid Build Coastguard Worker nvk_cg_compile_nir(struct nvk_physical_device *pdev, nir_shader *nir,
797*61046927SAndroid Build Coastguard Worker                    const struct nak_fs_key *fs_key,
798*61046927SAndroid Build Coastguard Worker                    struct nvk_shader *shader)
799*61046927SAndroid Build Coastguard Worker {
800*61046927SAndroid Build Coastguard Worker    struct nv50_ir_prog_info *info;
801*61046927SAndroid Build Coastguard Worker    struct nv50_ir_prog_info_out info_out = {};
802*61046927SAndroid Build Coastguard Worker    int ret;
803*61046927SAndroid Build Coastguard Worker 
804*61046927SAndroid Build Coastguard Worker    nak_cg_postprocess_nir(nir);
805*61046927SAndroid Build Coastguard Worker 
806*61046927SAndroid Build Coastguard Worker    info = CALLOC_STRUCT(nv50_ir_prog_info);
807*61046927SAndroid Build Coastguard Worker    if (!info)
808*61046927SAndroid Build Coastguard Worker       return false;
809*61046927SAndroid Build Coastguard Worker 
810*61046927SAndroid Build Coastguard Worker    info->type = nir->info.stage;
811*61046927SAndroid Build Coastguard Worker    info->target = pdev->info.chipset;
812*61046927SAndroid Build Coastguard Worker    info->bin.nir = nir;
813*61046927SAndroid Build Coastguard Worker 
814*61046927SAndroid Build Coastguard Worker    for (unsigned i = 0; i < 3; i++)
815*61046927SAndroid Build Coastguard Worker       shader->info.cs.local_size[i] = nir->info.workgroup_size[i];
816*61046927SAndroid Build Coastguard Worker 
817*61046927SAndroid Build Coastguard Worker    info->dbgFlags = nvk_cg_get_prog_debug();
818*61046927SAndroid Build Coastguard Worker    info->optLevel = nvk_cg_get_prog_optimize();
819*61046927SAndroid Build Coastguard Worker    info->io.auxCBSlot = 1;
820*61046927SAndroid Build Coastguard Worker    info->io.uboInfoBase = 0;
821*61046927SAndroid Build Coastguard Worker    info->io.drawInfoBase = nvk_root_descriptor_offset(draw.base_vertex);
822*61046927SAndroid Build Coastguard Worker    if (nir->info.stage == MESA_SHADER_COMPUTE) {
823*61046927SAndroid Build Coastguard Worker       info->prop.cp.gridInfoBase = 0;
824*61046927SAndroid Build Coastguard Worker    } else {
825*61046927SAndroid Build Coastguard Worker       info->assignSlots = nvc0_program_assign_varying_slots;
826*61046927SAndroid Build Coastguard Worker    }
827*61046927SAndroid Build Coastguard Worker    ret = nv50_ir_generate_code(info, &info_out);
828*61046927SAndroid Build Coastguard Worker    if (ret)
829*61046927SAndroid Build Coastguard Worker       return VK_ERROR_UNKNOWN;
830*61046927SAndroid Build Coastguard Worker 
831*61046927SAndroid Build Coastguard Worker    if (info_out.bin.fixupData) {
832*61046927SAndroid Build Coastguard Worker       nv50_ir_apply_fixups(info_out.bin.fixupData, info_out.bin.code,
833*61046927SAndroid Build Coastguard Worker                            fs_key && fs_key->force_sample_shading,
834*61046927SAndroid Build Coastguard Worker                            false /* flatshade */, false /* alphatest */,
835*61046927SAndroid Build Coastguard Worker                            fs_key && fs_key->force_sample_shading);
836*61046927SAndroid Build Coastguard Worker    }
837*61046927SAndroid Build Coastguard Worker 
838*61046927SAndroid Build Coastguard Worker    shader->info.stage = nir->info.stage;
839*61046927SAndroid Build Coastguard Worker    shader->code_ptr = (uint8_t *)info_out.bin.code;
840*61046927SAndroid Build Coastguard Worker    shader->code_size = info_out.bin.codeSize;
841*61046927SAndroid Build Coastguard Worker 
842*61046927SAndroid Build Coastguard Worker    if (info_out.target >= NVISA_GV100_CHIPSET)
843*61046927SAndroid Build Coastguard Worker       shader->info.num_gprs = MAX2(4, info_out.bin.maxGPR + 3);
844*61046927SAndroid Build Coastguard Worker    else
845*61046927SAndroid Build Coastguard Worker       shader->info.num_gprs = MAX2(4, info_out.bin.maxGPR + 1);
846*61046927SAndroid Build Coastguard Worker    shader->info.num_control_barriers = info_out.numBarriers;
847*61046927SAndroid Build Coastguard Worker 
848*61046927SAndroid Build Coastguard Worker    if (info_out.bin.tlsSpace) {
849*61046927SAndroid Build Coastguard Worker       assert(info_out.bin.tlsSpace < (1 << 24));
850*61046927SAndroid Build Coastguard Worker       shader->info.hdr[0] |= 1 << 26;
851*61046927SAndroid Build Coastguard Worker       shader->info.hdr[1] |= align(info_out.bin.tlsSpace, 0x10); /* l[] size */
852*61046927SAndroid Build Coastguard Worker       shader->info.slm_size = info_out.bin.tlsSpace;
853*61046927SAndroid Build Coastguard Worker    }
854*61046927SAndroid Build Coastguard Worker 
855*61046927SAndroid Build Coastguard Worker    switch (info->type) {
856*61046927SAndroid Build Coastguard Worker    case PIPE_SHADER_VERTEX:
857*61046927SAndroid Build Coastguard Worker       ret = nvk_vs_gen_header(shader, &info_out);
858*61046927SAndroid Build Coastguard Worker       break;
859*61046927SAndroid Build Coastguard Worker    case PIPE_SHADER_FRAGMENT:
860*61046927SAndroid Build Coastguard Worker       ret = nvk_fs_gen_header(shader, fs_key, &info_out);
861*61046927SAndroid Build Coastguard Worker       shader->info.fs.uses_sample_shading = nir->info.fs.uses_sample_shading;
862*61046927SAndroid Build Coastguard Worker       break;
863*61046927SAndroid Build Coastguard Worker    case PIPE_SHADER_GEOMETRY:
864*61046927SAndroid Build Coastguard Worker       ret = nvk_gs_gen_header(shader, nir, &info_out);
865*61046927SAndroid Build Coastguard Worker       break;
866*61046927SAndroid Build Coastguard Worker    case PIPE_SHADER_TESS_CTRL:
867*61046927SAndroid Build Coastguard Worker       ret = nvk_tcs_gen_header(shader, &info_out);
868*61046927SAndroid Build Coastguard Worker       break;
869*61046927SAndroid Build Coastguard Worker    case PIPE_SHADER_TESS_EVAL:
870*61046927SAndroid Build Coastguard Worker       ret = nvk_tes_gen_header(shader, &info_out);
871*61046927SAndroid Build Coastguard Worker       break;
872*61046927SAndroid Build Coastguard Worker    case PIPE_SHADER_COMPUTE:
873*61046927SAndroid Build Coastguard Worker       shader->info.cs.smem_size = info_out.bin.smemSize;
874*61046927SAndroid Build Coastguard Worker       break;
875*61046927SAndroid Build Coastguard Worker    default:
876*61046927SAndroid Build Coastguard Worker       unreachable("Invalid shader stage");
877*61046927SAndroid Build Coastguard Worker       break;
878*61046927SAndroid Build Coastguard Worker    }
879*61046927SAndroid Build Coastguard Worker    assert(ret == 0);
880*61046927SAndroid Build Coastguard Worker 
881*61046927SAndroid Build Coastguard Worker    if (info_out.io.globalAccess)
882*61046927SAndroid Build Coastguard Worker       shader->info.hdr[0] |= 1 << 26;
883*61046927SAndroid Build Coastguard Worker    if (info_out.io.globalAccess & 0x2)
884*61046927SAndroid Build Coastguard Worker       shader->info.hdr[0] |= 1 << 16;
885*61046927SAndroid Build Coastguard Worker    if (info_out.io.fp64)
886*61046927SAndroid Build Coastguard Worker       shader->info.hdr[0] |= 1 << 27;
887*61046927SAndroid Build Coastguard Worker 
888*61046927SAndroid Build Coastguard Worker    if (nir->xfb_info)
889*61046927SAndroid Build Coastguard Worker       nvk_fill_transform_feedback_state(&shader->info.vtg.xfb, nir, &info_out);
890*61046927SAndroid Build Coastguard Worker 
891*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
892*61046927SAndroid Build Coastguard Worker }
893