xref: /aosp_15_r20/external/mesa3d/src/freedreno/ir3/ir3_shader.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker  * Copyright © 2014 Rob Clark <[email protected]>
3*61046927SAndroid Build Coastguard Worker  * SPDX-License-Identifier: MIT
4*61046927SAndroid Build Coastguard Worker  *
5*61046927SAndroid Build Coastguard Worker  * Authors:
6*61046927SAndroid Build Coastguard Worker  *    Rob Clark <[email protected]>
7*61046927SAndroid Build Coastguard Worker  */
8*61046927SAndroid Build Coastguard Worker 
9*61046927SAndroid Build Coastguard Worker #include "util/format/u_format.h"
10*61046927SAndroid Build Coastguard Worker #include "util/u_atomic.h"
11*61046927SAndroid Build Coastguard Worker #include "util/u_math.h"
12*61046927SAndroid Build Coastguard Worker #include "util/u_memory.h"
13*61046927SAndroid Build Coastguard Worker #include "util/u_string.h"
14*61046927SAndroid Build Coastguard Worker 
15*61046927SAndroid Build Coastguard Worker #include "drm/freedreno_drmif.h"
16*61046927SAndroid Build Coastguard Worker 
17*61046927SAndroid Build Coastguard Worker #include "ir3_assembler.h"
18*61046927SAndroid Build Coastguard Worker #include "ir3_compiler.h"
19*61046927SAndroid Build Coastguard Worker #include "ir3_nir.h"
20*61046927SAndroid Build Coastguard Worker #include "ir3_parser.h"
21*61046927SAndroid Build Coastguard Worker #include "ir3_shader.h"
22*61046927SAndroid Build Coastguard Worker 
23*61046927SAndroid Build Coastguard Worker #include "freedreno/isa/ir3-isa.h"
24*61046927SAndroid Build Coastguard Worker #include "isa/isa.h"
25*61046927SAndroid Build Coastguard Worker 
26*61046927SAndroid Build Coastguard Worker #include "disasm.h"
27*61046927SAndroid Build Coastguard Worker 
28*61046927SAndroid Build Coastguard Worker static uint16_t
const_imm_index_to_reg(const struct ir3_const_state * const_state,unsigned i)29*61046927SAndroid Build Coastguard Worker const_imm_index_to_reg(const struct ir3_const_state *const_state, unsigned i)
30*61046927SAndroid Build Coastguard Worker {
31*61046927SAndroid Build Coastguard Worker    return i + (4 * const_state->offsets.immediate);
32*61046927SAndroid Build Coastguard Worker }
33*61046927SAndroid Build Coastguard Worker 
34*61046927SAndroid Build Coastguard Worker uint16_t
ir3_const_find_imm(struct ir3_shader_variant * v,uint32_t imm)35*61046927SAndroid Build Coastguard Worker ir3_const_find_imm(struct ir3_shader_variant *v, uint32_t imm)
36*61046927SAndroid Build Coastguard Worker {
37*61046927SAndroid Build Coastguard Worker    const struct ir3_const_state *const_state = ir3_const_state(v);
38*61046927SAndroid Build Coastguard Worker 
39*61046927SAndroid Build Coastguard Worker    for (unsigned i = 0; i < const_state->immediates_count; i++) {
40*61046927SAndroid Build Coastguard Worker       if (const_state->immediates[i] == imm)
41*61046927SAndroid Build Coastguard Worker          return const_imm_index_to_reg(const_state, i);
42*61046927SAndroid Build Coastguard Worker    }
43*61046927SAndroid Build Coastguard Worker 
44*61046927SAndroid Build Coastguard Worker    return INVALID_CONST_REG;
45*61046927SAndroid Build Coastguard Worker }
46*61046927SAndroid Build Coastguard Worker 
47*61046927SAndroid Build Coastguard Worker uint16_t
ir3_const_add_imm(struct ir3_shader_variant * v,uint32_t imm)48*61046927SAndroid Build Coastguard Worker ir3_const_add_imm(struct ir3_shader_variant *v, uint32_t imm)
49*61046927SAndroid Build Coastguard Worker {
50*61046927SAndroid Build Coastguard Worker    struct ir3_const_state *const_state = ir3_const_state_mut(v);
51*61046927SAndroid Build Coastguard Worker 
52*61046927SAndroid Build Coastguard Worker    /* Reallocate for 4 more elements whenever it's necessary.  Note that ir3
53*61046927SAndroid Build Coastguard Worker     * printing relies on having groups of 4 dwords, so we fill the unused
54*61046927SAndroid Build Coastguard Worker     * slots with a dummy value.
55*61046927SAndroid Build Coastguard Worker     */
56*61046927SAndroid Build Coastguard Worker    if (const_state->immediates_count == const_state->immediates_size) {
57*61046927SAndroid Build Coastguard Worker       const_state->immediates = rerzalloc(
58*61046927SAndroid Build Coastguard Worker          const_state, const_state->immediates,
59*61046927SAndroid Build Coastguard Worker          __typeof__(const_state->immediates[0]), const_state->immediates_size,
60*61046927SAndroid Build Coastguard Worker          const_state->immediates_size + 4);
61*61046927SAndroid Build Coastguard Worker       const_state->immediates_size += 4;
62*61046927SAndroid Build Coastguard Worker 
63*61046927SAndroid Build Coastguard Worker       for (int i = const_state->immediates_count;
64*61046927SAndroid Build Coastguard Worker            i < const_state->immediates_size; i++) {
65*61046927SAndroid Build Coastguard Worker          const_state->immediates[i] = 0xd0d0d0d0;
66*61046927SAndroid Build Coastguard Worker       }
67*61046927SAndroid Build Coastguard Worker    }
68*61046927SAndroid Build Coastguard Worker 
69*61046927SAndroid Build Coastguard Worker    /* Add on a new immediate to be pushed, if we have space left in the
70*61046927SAndroid Build Coastguard Worker     * constbuf.
71*61046927SAndroid Build Coastguard Worker     */
72*61046927SAndroid Build Coastguard Worker    if (const_state->offsets.immediate + const_state->immediates_count / 4 >=
73*61046927SAndroid Build Coastguard Worker        ir3_max_const(v)) {
74*61046927SAndroid Build Coastguard Worker       return INVALID_CONST_REG;
75*61046927SAndroid Build Coastguard Worker    }
76*61046927SAndroid Build Coastguard Worker 
77*61046927SAndroid Build Coastguard Worker    const_state->immediates[const_state->immediates_count] = imm;
78*61046927SAndroid Build Coastguard Worker    return const_imm_index_to_reg(const_state, const_state->immediates_count++);
79*61046927SAndroid Build Coastguard Worker }
80*61046927SAndroid Build Coastguard Worker 
81*61046927SAndroid Build Coastguard Worker int
ir3_glsl_type_size(const struct glsl_type * type,bool bindless)82*61046927SAndroid Build Coastguard Worker ir3_glsl_type_size(const struct glsl_type *type, bool bindless)
83*61046927SAndroid Build Coastguard Worker {
84*61046927SAndroid Build Coastguard Worker    return glsl_count_attribute_slots(type, false);
85*61046927SAndroid Build Coastguard Worker }
86*61046927SAndroid Build Coastguard Worker 
87*61046927SAndroid Build Coastguard Worker /* wrapper for ir3_assemble() which does some info fixup based on
88*61046927SAndroid Build Coastguard Worker  * shader state.  Non-static since used by ir3_cmdline too.
89*61046927SAndroid Build Coastguard Worker  */
90*61046927SAndroid Build Coastguard Worker void *
ir3_shader_assemble(struct ir3_shader_variant * v)91*61046927SAndroid Build Coastguard Worker ir3_shader_assemble(struct ir3_shader_variant *v)
92*61046927SAndroid Build Coastguard Worker {
93*61046927SAndroid Build Coastguard Worker    const struct ir3_compiler *compiler = v->compiler;
94*61046927SAndroid Build Coastguard Worker    struct ir3_info *info = &v->info;
95*61046927SAndroid Build Coastguard Worker    uint32_t *bin;
96*61046927SAndroid Build Coastguard Worker 
97*61046927SAndroid Build Coastguard Worker    ir3_collect_info(v);
98*61046927SAndroid Build Coastguard Worker 
99*61046927SAndroid Build Coastguard Worker    if (v->constant_data_size) {
100*61046927SAndroid Build Coastguard Worker       /* Make sure that where we're about to place the constant_data is safe
101*61046927SAndroid Build Coastguard Worker        * to indirectly upload from.
102*61046927SAndroid Build Coastguard Worker        */
103*61046927SAndroid Build Coastguard Worker       info->constant_data_offset =
104*61046927SAndroid Build Coastguard Worker          align(info->size, v->compiler->const_upload_unit * 16);
105*61046927SAndroid Build Coastguard Worker       info->size = info->constant_data_offset + v->constant_data_size;
106*61046927SAndroid Build Coastguard Worker    }
107*61046927SAndroid Build Coastguard Worker 
108*61046927SAndroid Build Coastguard Worker    /* Pad out the size so that when turnip uploads the shaders in
109*61046927SAndroid Build Coastguard Worker     * sequence, the starting offset of the next one is properly aligned.
110*61046927SAndroid Build Coastguard Worker     */
111*61046927SAndroid Build Coastguard Worker    info->size = align(info->size, compiler->instr_align * sizeof(uint64_t));
112*61046927SAndroid Build Coastguard Worker 
113*61046927SAndroid Build Coastguard Worker    bin = isa_assemble(v);
114*61046927SAndroid Build Coastguard Worker    if (!bin)
115*61046927SAndroid Build Coastguard Worker       return NULL;
116*61046927SAndroid Build Coastguard Worker 
117*61046927SAndroid Build Coastguard Worker    /* Append the immediates after the end of the program.  This lets us emit
118*61046927SAndroid Build Coastguard Worker     * the immediates as an indirect load, while avoiding creating another BO.
119*61046927SAndroid Build Coastguard Worker     */
120*61046927SAndroid Build Coastguard Worker    if (v->constant_data_size)
121*61046927SAndroid Build Coastguard Worker       memcpy(&bin[info->constant_data_offset / 4], v->constant_data,
122*61046927SAndroid Build Coastguard Worker              v->constant_data_size);
123*61046927SAndroid Build Coastguard Worker    ralloc_free(v->constant_data);
124*61046927SAndroid Build Coastguard Worker    v->constant_data = NULL;
125*61046927SAndroid Build Coastguard Worker 
126*61046927SAndroid Build Coastguard Worker    /* NOTE: if relative addressing is used, we set constlen in
127*61046927SAndroid Build Coastguard Worker     * the compiler (to worst-case value) since we don't know in
128*61046927SAndroid Build Coastguard Worker     * the assembler what the max addr reg value can be:
129*61046927SAndroid Build Coastguard Worker     */
130*61046927SAndroid Build Coastguard Worker    v->constlen = MAX2(v->constlen, info->max_const + 1);
131*61046927SAndroid Build Coastguard Worker 
132*61046927SAndroid Build Coastguard Worker    if (v->constlen > ir3_const_state(v)->offsets.driver_param)
133*61046927SAndroid Build Coastguard Worker       v->need_driver_params = true;
134*61046927SAndroid Build Coastguard Worker 
135*61046927SAndroid Build Coastguard Worker    /* On a4xx and newer, constlen must be a multiple of 16 dwords even though
136*61046927SAndroid Build Coastguard Worker     * uploads are in units of 4 dwords. Round it up here to make calculations
137*61046927SAndroid Build Coastguard Worker     * regarding the shared constlen simpler.
138*61046927SAndroid Build Coastguard Worker     */
139*61046927SAndroid Build Coastguard Worker    if (compiler->gen >= 4)
140*61046927SAndroid Build Coastguard Worker       v->constlen = align(v->constlen, 4);
141*61046927SAndroid Build Coastguard Worker 
142*61046927SAndroid Build Coastguard Worker    /* Use the per-wave layout by default on a6xx for compute shaders. It
143*61046927SAndroid Build Coastguard Worker     * should result in better performance when loads/stores are to a uniform
144*61046927SAndroid Build Coastguard Worker     * index.
145*61046927SAndroid Build Coastguard Worker     */
146*61046927SAndroid Build Coastguard Worker    v->pvtmem_per_wave = compiler->gen >= 6 && !info->multi_dword_ldp_stp &&
147*61046927SAndroid Build Coastguard Worker                         ((v->type == MESA_SHADER_COMPUTE) ||
148*61046927SAndroid Build Coastguard Worker                          (v->type == MESA_SHADER_KERNEL));
149*61046927SAndroid Build Coastguard Worker 
150*61046927SAndroid Build Coastguard Worker    return bin;
151*61046927SAndroid Build Coastguard Worker }
152*61046927SAndroid Build Coastguard Worker 
153*61046927SAndroid Build Coastguard Worker static bool
try_override_shader_variant(struct ir3_shader_variant * v,const char * identifier)154*61046927SAndroid Build Coastguard Worker try_override_shader_variant(struct ir3_shader_variant *v,
155*61046927SAndroid Build Coastguard Worker                             const char *identifier)
156*61046927SAndroid Build Coastguard Worker {
157*61046927SAndroid Build Coastguard Worker    assert(ir3_shader_override_path);
158*61046927SAndroid Build Coastguard Worker 
159*61046927SAndroid Build Coastguard Worker    char *name =
160*61046927SAndroid Build Coastguard Worker       ralloc_asprintf(NULL, "%s/%s.asm", ir3_shader_override_path, identifier);
161*61046927SAndroid Build Coastguard Worker 
162*61046927SAndroid Build Coastguard Worker    FILE *f = fopen(name, "r");
163*61046927SAndroid Build Coastguard Worker 
164*61046927SAndroid Build Coastguard Worker    if (!f) {
165*61046927SAndroid Build Coastguard Worker       ralloc_free(name);
166*61046927SAndroid Build Coastguard Worker       return false;
167*61046927SAndroid Build Coastguard Worker    }
168*61046927SAndroid Build Coastguard Worker 
169*61046927SAndroid Build Coastguard Worker    struct ir3_kernel_info info;
170*61046927SAndroid Build Coastguard Worker    info.numwg = INVALID_REG;
171*61046927SAndroid Build Coastguard Worker    v->ir = ir3_parse(v, &info, f);
172*61046927SAndroid Build Coastguard Worker 
173*61046927SAndroid Build Coastguard Worker    fclose(f);
174*61046927SAndroid Build Coastguard Worker 
175*61046927SAndroid Build Coastguard Worker    if (!v->ir) {
176*61046927SAndroid Build Coastguard Worker       fprintf(stderr, "Failed to parse %s\n", name);
177*61046927SAndroid Build Coastguard Worker       exit(1);
178*61046927SAndroid Build Coastguard Worker    }
179*61046927SAndroid Build Coastguard Worker 
180*61046927SAndroid Build Coastguard Worker    v->bin = ir3_shader_assemble(v);
181*61046927SAndroid Build Coastguard Worker    if (!v->bin) {
182*61046927SAndroid Build Coastguard Worker       fprintf(stderr, "Failed to assemble %s\n", name);
183*61046927SAndroid Build Coastguard Worker       exit(1);
184*61046927SAndroid Build Coastguard Worker    }
185*61046927SAndroid Build Coastguard Worker 
186*61046927SAndroid Build Coastguard Worker    ralloc_free(name);
187*61046927SAndroid Build Coastguard Worker    return true;
188*61046927SAndroid Build Coastguard Worker }
189*61046927SAndroid Build Coastguard Worker 
190*61046927SAndroid Build Coastguard Worker static void
assemble_variant(struct ir3_shader_variant * v,bool internal)191*61046927SAndroid Build Coastguard Worker assemble_variant(struct ir3_shader_variant *v, bool internal)
192*61046927SAndroid Build Coastguard Worker {
193*61046927SAndroid Build Coastguard Worker    v->bin = ir3_shader_assemble(v);
194*61046927SAndroid Build Coastguard Worker 
195*61046927SAndroid Build Coastguard Worker    bool dbg_enabled = shader_debug_enabled(v->type, internal);
196*61046927SAndroid Build Coastguard Worker    if (dbg_enabled || ir3_shader_override_path || v->disasm_info.write_disasm) {
197*61046927SAndroid Build Coastguard Worker       unsigned char sha1[21];
198*61046927SAndroid Build Coastguard Worker       char sha1buf[41];
199*61046927SAndroid Build Coastguard Worker 
200*61046927SAndroid Build Coastguard Worker       _mesa_sha1_compute(v->bin, v->info.size, sha1);
201*61046927SAndroid Build Coastguard Worker       _mesa_sha1_format(sha1buf, sha1);
202*61046927SAndroid Build Coastguard Worker 
203*61046927SAndroid Build Coastguard Worker       bool shader_overridden =
204*61046927SAndroid Build Coastguard Worker          ir3_shader_override_path && try_override_shader_variant(v, sha1buf);
205*61046927SAndroid Build Coastguard Worker 
206*61046927SAndroid Build Coastguard Worker       if (v->disasm_info.write_disasm) {
207*61046927SAndroid Build Coastguard Worker          char *stream_data = NULL;
208*61046927SAndroid Build Coastguard Worker          size_t stream_size = 0;
209*61046927SAndroid Build Coastguard Worker          FILE *stream = open_memstream(&stream_data, &stream_size);
210*61046927SAndroid Build Coastguard Worker 
211*61046927SAndroid Build Coastguard Worker          fprintf(stream,
212*61046927SAndroid Build Coastguard Worker                  "Native code%s for unnamed %s shader %s with sha1 %s:\n",
213*61046927SAndroid Build Coastguard Worker                  shader_overridden ? " (overridden)" : "", ir3_shader_stage(v),
214*61046927SAndroid Build Coastguard Worker                  v->name, sha1buf);
215*61046927SAndroid Build Coastguard Worker          ir3_shader_disasm(v, v->bin, stream);
216*61046927SAndroid Build Coastguard Worker 
217*61046927SAndroid Build Coastguard Worker          fclose(stream);
218*61046927SAndroid Build Coastguard Worker 
219*61046927SAndroid Build Coastguard Worker          v->disasm_info.disasm = ralloc_size(v, stream_size + 1);
220*61046927SAndroid Build Coastguard Worker          memcpy(v->disasm_info.disasm, stream_data, stream_size);
221*61046927SAndroid Build Coastguard Worker          v->disasm_info.disasm[stream_size] = 0;
222*61046927SAndroid Build Coastguard Worker          free(stream_data);
223*61046927SAndroid Build Coastguard Worker       }
224*61046927SAndroid Build Coastguard Worker 
225*61046927SAndroid Build Coastguard Worker       if (dbg_enabled || shader_overridden) {
226*61046927SAndroid Build Coastguard Worker          char *stream_data = NULL;
227*61046927SAndroid Build Coastguard Worker          size_t stream_size = 0;
228*61046927SAndroid Build Coastguard Worker          FILE *stream = open_memstream(&stream_data, &stream_size);
229*61046927SAndroid Build Coastguard Worker 
230*61046927SAndroid Build Coastguard Worker          fprintf(stream,
231*61046927SAndroid Build Coastguard Worker                  "Native code%s for unnamed %s shader %s with sha1 %s:\n",
232*61046927SAndroid Build Coastguard Worker                  shader_overridden ? " (overridden)" : "", ir3_shader_stage(v),
233*61046927SAndroid Build Coastguard Worker                  v->name, sha1buf);
234*61046927SAndroid Build Coastguard Worker          if (v->type == MESA_SHADER_FRAGMENT)
235*61046927SAndroid Build Coastguard Worker             fprintf(stream, "SIMD0\n");
236*61046927SAndroid Build Coastguard Worker          ir3_shader_disasm(v, v->bin, stream);
237*61046927SAndroid Build Coastguard Worker          fclose(stream);
238*61046927SAndroid Build Coastguard Worker 
239*61046927SAndroid Build Coastguard Worker          mesa_log_multiline(MESA_LOG_INFO, stream_data);
240*61046927SAndroid Build Coastguard Worker          free(stream_data);
241*61046927SAndroid Build Coastguard Worker       }
242*61046927SAndroid Build Coastguard Worker    }
243*61046927SAndroid Build Coastguard Worker 
244*61046927SAndroid Build Coastguard Worker    /* no need to keep the ir around beyond this point: */
245*61046927SAndroid Build Coastguard Worker    ir3_destroy(v->ir);
246*61046927SAndroid Build Coastguard Worker    v->ir = NULL;
247*61046927SAndroid Build Coastguard Worker }
248*61046927SAndroid Build Coastguard Worker 
249*61046927SAndroid Build Coastguard Worker static bool
compile_variant(struct ir3_shader * shader,struct ir3_shader_variant * v)250*61046927SAndroid Build Coastguard Worker compile_variant(struct ir3_shader *shader, struct ir3_shader_variant *v)
251*61046927SAndroid Build Coastguard Worker {
252*61046927SAndroid Build Coastguard Worker    int ret = ir3_compile_shader_nir(shader->compiler, shader, v);
253*61046927SAndroid Build Coastguard Worker    if (ret) {
254*61046927SAndroid Build Coastguard Worker       mesa_loge("compile failed! (%s:%s)", shader->nir->info.name,
255*61046927SAndroid Build Coastguard Worker                 shader->nir->info.label);
256*61046927SAndroid Build Coastguard Worker       return false;
257*61046927SAndroid Build Coastguard Worker    }
258*61046927SAndroid Build Coastguard Worker 
259*61046927SAndroid Build Coastguard Worker    assemble_variant(v, shader->nir->info.internal);
260*61046927SAndroid Build Coastguard Worker    if (!v->bin) {
261*61046927SAndroid Build Coastguard Worker       mesa_loge("assemble failed! (%s:%s)", shader->nir->info.name,
262*61046927SAndroid Build Coastguard Worker                 shader->nir->info.label);
263*61046927SAndroid Build Coastguard Worker       return false;
264*61046927SAndroid Build Coastguard Worker    }
265*61046927SAndroid Build Coastguard Worker 
266*61046927SAndroid Build Coastguard Worker    return true;
267*61046927SAndroid Build Coastguard Worker }
268*61046927SAndroid Build Coastguard Worker 
269*61046927SAndroid Build Coastguard Worker /*
270*61046927SAndroid Build Coastguard Worker  * For creating normal shader variants, 'nonbinning' is NULL.  For
271*61046927SAndroid Build Coastguard Worker  * creating binning pass shader, it is link to corresponding normal
272*61046927SAndroid Build Coastguard Worker  * (non-binning) variant.
273*61046927SAndroid Build Coastguard Worker  */
274*61046927SAndroid Build Coastguard Worker static struct ir3_shader_variant *
alloc_variant(struct ir3_shader * shader,const struct ir3_shader_key * key,struct ir3_shader_variant * nonbinning,void * mem_ctx)275*61046927SAndroid Build Coastguard Worker alloc_variant(struct ir3_shader *shader, const struct ir3_shader_key *key,
276*61046927SAndroid Build Coastguard Worker               struct ir3_shader_variant *nonbinning, void *mem_ctx)
277*61046927SAndroid Build Coastguard Worker {
278*61046927SAndroid Build Coastguard Worker    /* hang the binning variant off it's non-binning counterpart instead
279*61046927SAndroid Build Coastguard Worker     * of the shader, to simplify the error cleanup paths
280*61046927SAndroid Build Coastguard Worker     */
281*61046927SAndroid Build Coastguard Worker    if (nonbinning)
282*61046927SAndroid Build Coastguard Worker       mem_ctx = nonbinning;
283*61046927SAndroid Build Coastguard Worker    struct ir3_shader_variant *v = rzalloc_size(mem_ctx, sizeof(*v));
284*61046927SAndroid Build Coastguard Worker 
285*61046927SAndroid Build Coastguard Worker    if (!v)
286*61046927SAndroid Build Coastguard Worker       return NULL;
287*61046927SAndroid Build Coastguard Worker 
288*61046927SAndroid Build Coastguard Worker    v->id = ++shader->variant_count;
289*61046927SAndroid Build Coastguard Worker    v->shader_id = shader->id;
290*61046927SAndroid Build Coastguard Worker    v->binning_pass = !!nonbinning;
291*61046927SAndroid Build Coastguard Worker    v->nonbinning = nonbinning;
292*61046927SAndroid Build Coastguard Worker    v->key = *key;
293*61046927SAndroid Build Coastguard Worker    v->type = shader->type;
294*61046927SAndroid Build Coastguard Worker    v->compiler = shader->compiler;
295*61046927SAndroid Build Coastguard Worker    v->mergedregs = shader->compiler->gen >= 6;
296*61046927SAndroid Build Coastguard Worker    v->stream_output = shader->stream_output;
297*61046927SAndroid Build Coastguard Worker 
298*61046927SAndroid Build Coastguard Worker    v->name = ralloc_strdup(v, shader->nir->info.name);
299*61046927SAndroid Build Coastguard Worker 
300*61046927SAndroid Build Coastguard Worker    struct shader_info *info = &shader->nir->info;
301*61046927SAndroid Build Coastguard Worker    switch (v->type) {
302*61046927SAndroid Build Coastguard Worker    case MESA_SHADER_TESS_CTRL:
303*61046927SAndroid Build Coastguard Worker    case MESA_SHADER_TESS_EVAL:
304*61046927SAndroid Build Coastguard Worker       v->tess.primitive_mode = info->tess._primitive_mode;
305*61046927SAndroid Build Coastguard Worker       v->tess.tcs_vertices_out = info->tess.tcs_vertices_out;
306*61046927SAndroid Build Coastguard Worker       v->tess.spacing = info->tess.spacing;
307*61046927SAndroid Build Coastguard Worker       v->tess.ccw = info->tess.ccw;
308*61046927SAndroid Build Coastguard Worker       v->tess.point_mode = info->tess.point_mode;
309*61046927SAndroid Build Coastguard Worker       break;
310*61046927SAndroid Build Coastguard Worker 
311*61046927SAndroid Build Coastguard Worker    case MESA_SHADER_GEOMETRY:
312*61046927SAndroid Build Coastguard Worker       v->gs.output_primitive = info->gs.output_primitive;
313*61046927SAndroid Build Coastguard Worker       v->gs.vertices_out = info->gs.vertices_out;
314*61046927SAndroid Build Coastguard Worker       v->gs.invocations = info->gs.invocations;
315*61046927SAndroid Build Coastguard Worker       v->gs.vertices_in = info->gs.vertices_in;
316*61046927SAndroid Build Coastguard Worker       break;
317*61046927SAndroid Build Coastguard Worker 
318*61046927SAndroid Build Coastguard Worker    case MESA_SHADER_FRAGMENT:
319*61046927SAndroid Build Coastguard Worker       v->fs.early_fragment_tests = info->fs.early_fragment_tests;
320*61046927SAndroid Build Coastguard Worker       v->fs.color_is_dual_source = info->fs.color_is_dual_source;
321*61046927SAndroid Build Coastguard Worker       v->fs.uses_fbfetch_output  = info->fs.uses_fbfetch_output;
322*61046927SAndroid Build Coastguard Worker       v->fs.fbfetch_coherent     = info->fs.fbfetch_coherent;
323*61046927SAndroid Build Coastguard Worker       break;
324*61046927SAndroid Build Coastguard Worker 
325*61046927SAndroid Build Coastguard Worker    case MESA_SHADER_COMPUTE:
326*61046927SAndroid Build Coastguard Worker    case MESA_SHADER_KERNEL:
327*61046927SAndroid Build Coastguard Worker       v->cs.req_input_mem = shader->cs.req_input_mem;
328*61046927SAndroid Build Coastguard Worker       v->cs.req_local_mem = shader->cs.req_local_mem;
329*61046927SAndroid Build Coastguard Worker       break;
330*61046927SAndroid Build Coastguard Worker 
331*61046927SAndroid Build Coastguard Worker    default:
332*61046927SAndroid Build Coastguard Worker       break;
333*61046927SAndroid Build Coastguard Worker    }
334*61046927SAndroid Build Coastguard Worker 
335*61046927SAndroid Build Coastguard Worker    v->num_ssbos = info->num_ssbos;
336*61046927SAndroid Build Coastguard Worker    v->num_ibos = info->num_ssbos + info->num_images;
337*61046927SAndroid Build Coastguard Worker    v->shader_options = shader->options;
338*61046927SAndroid Build Coastguard Worker 
339*61046927SAndroid Build Coastguard Worker    if (!v->binning_pass) {
340*61046927SAndroid Build Coastguard Worker       v->const_state = rzalloc_size(v, sizeof(*v->const_state));
341*61046927SAndroid Build Coastguard Worker       v->const_state->push_consts_type = shader->options.push_consts_type;
342*61046927SAndroid Build Coastguard Worker       v->const_state->consts_ubo.idx = -1;
343*61046927SAndroid Build Coastguard Worker       v->const_state->driver_params_ubo.idx = -1;
344*61046927SAndroid Build Coastguard Worker       v->const_state->primitive_map_ubo.idx = -1;
345*61046927SAndroid Build Coastguard Worker       v->const_state->primitive_param_ubo.idx = -1;
346*61046927SAndroid Build Coastguard Worker    }
347*61046927SAndroid Build Coastguard Worker 
348*61046927SAndroid Build Coastguard Worker    return v;
349*61046927SAndroid Build Coastguard Worker }
350*61046927SAndroid Build Coastguard Worker 
351*61046927SAndroid Build Coastguard Worker static bool
needs_binning_variant(struct ir3_shader_variant * v)352*61046927SAndroid Build Coastguard Worker needs_binning_variant(struct ir3_shader_variant *v)
353*61046927SAndroid Build Coastguard Worker {
354*61046927SAndroid Build Coastguard Worker    if ((v->type == MESA_SHADER_VERTEX) && ir3_has_binning_vs(&v->key))
355*61046927SAndroid Build Coastguard Worker       return true;
356*61046927SAndroid Build Coastguard Worker    return false;
357*61046927SAndroid Build Coastguard Worker }
358*61046927SAndroid Build Coastguard Worker 
359*61046927SAndroid Build Coastguard Worker static struct ir3_shader_variant *
create_variant(struct ir3_shader * shader,const struct ir3_shader_key * key,bool write_disasm,void * mem_ctx)360*61046927SAndroid Build Coastguard Worker create_variant(struct ir3_shader *shader, const struct ir3_shader_key *key,
361*61046927SAndroid Build Coastguard Worker                bool write_disasm, void *mem_ctx)
362*61046927SAndroid Build Coastguard Worker {
363*61046927SAndroid Build Coastguard Worker    struct ir3_shader_variant *v = alloc_variant(shader, key, NULL, mem_ctx);
364*61046927SAndroid Build Coastguard Worker 
365*61046927SAndroid Build Coastguard Worker    if (!v)
366*61046927SAndroid Build Coastguard Worker       goto fail;
367*61046927SAndroid Build Coastguard Worker 
368*61046927SAndroid Build Coastguard Worker    v->disasm_info.write_disasm = write_disasm;
369*61046927SAndroid Build Coastguard Worker 
370*61046927SAndroid Build Coastguard Worker    if (needs_binning_variant(v)) {
371*61046927SAndroid Build Coastguard Worker       v->binning = alloc_variant(shader, key, v, mem_ctx);
372*61046927SAndroid Build Coastguard Worker       if (!v->binning)
373*61046927SAndroid Build Coastguard Worker          goto fail;
374*61046927SAndroid Build Coastguard Worker       v->binning->disasm_info.write_disasm = write_disasm;
375*61046927SAndroid Build Coastguard Worker    }
376*61046927SAndroid Build Coastguard Worker 
377*61046927SAndroid Build Coastguard Worker    if (ir3_disk_cache_retrieve(shader, v))
378*61046927SAndroid Build Coastguard Worker       return v;
379*61046927SAndroid Build Coastguard Worker 
380*61046927SAndroid Build Coastguard Worker    if (!shader->nir_finalized) {
381*61046927SAndroid Build Coastguard Worker       ir3_nir_post_finalize(shader);
382*61046927SAndroid Build Coastguard Worker 
383*61046927SAndroid Build Coastguard Worker       if (ir3_shader_debug & IR3_DBG_DISASM) {
384*61046927SAndroid Build Coastguard Worker          mesa_logi("dump nir%d: type=%d", shader->id, shader->type);
385*61046927SAndroid Build Coastguard Worker          nir_log_shaderi(shader->nir);
386*61046927SAndroid Build Coastguard Worker       }
387*61046927SAndroid Build Coastguard Worker 
388*61046927SAndroid Build Coastguard Worker       if (v->disasm_info.write_disasm) {
389*61046927SAndroid Build Coastguard Worker          v->disasm_info.nir = nir_shader_as_str(shader->nir, v);
390*61046927SAndroid Build Coastguard Worker       }
391*61046927SAndroid Build Coastguard Worker 
392*61046927SAndroid Build Coastguard Worker       shader->nir_finalized = true;
393*61046927SAndroid Build Coastguard Worker    }
394*61046927SAndroid Build Coastguard Worker 
395*61046927SAndroid Build Coastguard Worker    if (v->type == MESA_SHADER_COMPUTE ||
396*61046927SAndroid Build Coastguard Worker        v->type == MESA_SHADER_KERNEL) {
397*61046927SAndroid Build Coastguard Worker       v->cs.force_linear_dispatch = shader->cs.force_linear_dispatch;
398*61046927SAndroid Build Coastguard Worker    }
399*61046927SAndroid Build Coastguard Worker 
400*61046927SAndroid Build Coastguard Worker    if (!compile_variant(shader, v))
401*61046927SAndroid Build Coastguard Worker       goto fail;
402*61046927SAndroid Build Coastguard Worker 
403*61046927SAndroid Build Coastguard Worker    if (needs_binning_variant(v) && !compile_variant(shader, v->binning))
404*61046927SAndroid Build Coastguard Worker       goto fail;
405*61046927SAndroid Build Coastguard Worker 
406*61046927SAndroid Build Coastguard Worker    ir3_disk_cache_store(shader, v);
407*61046927SAndroid Build Coastguard Worker 
408*61046927SAndroid Build Coastguard Worker    return v;
409*61046927SAndroid Build Coastguard Worker 
410*61046927SAndroid Build Coastguard Worker fail:
411*61046927SAndroid Build Coastguard Worker    ralloc_free(v);
412*61046927SAndroid Build Coastguard Worker    return NULL;
413*61046927SAndroid Build Coastguard Worker }
414*61046927SAndroid Build Coastguard Worker 
415*61046927SAndroid Build Coastguard Worker struct ir3_shader_variant *
ir3_shader_create_variant(struct ir3_shader * shader,const struct ir3_shader_key * key,bool keep_ir)416*61046927SAndroid Build Coastguard Worker ir3_shader_create_variant(struct ir3_shader *shader,
417*61046927SAndroid Build Coastguard Worker                           const struct ir3_shader_key *key,
418*61046927SAndroid Build Coastguard Worker                           bool keep_ir)
419*61046927SAndroid Build Coastguard Worker {
420*61046927SAndroid Build Coastguard Worker    return create_variant(shader, key, keep_ir, NULL);
421*61046927SAndroid Build Coastguard Worker }
422*61046927SAndroid Build Coastguard Worker 
423*61046927SAndroid Build Coastguard Worker static inline struct ir3_shader_variant *
shader_variant(struct ir3_shader * shader,const struct ir3_shader_key * key)424*61046927SAndroid Build Coastguard Worker shader_variant(struct ir3_shader *shader, const struct ir3_shader_key *key)
425*61046927SAndroid Build Coastguard Worker {
426*61046927SAndroid Build Coastguard Worker    struct ir3_shader_variant *v;
427*61046927SAndroid Build Coastguard Worker 
428*61046927SAndroid Build Coastguard Worker    for (v = shader->variants; v; v = v->next)
429*61046927SAndroid Build Coastguard Worker       if (ir3_shader_key_equal(key, &v->key))
430*61046927SAndroid Build Coastguard Worker          return v;
431*61046927SAndroid Build Coastguard Worker 
432*61046927SAndroid Build Coastguard Worker    return NULL;
433*61046927SAndroid Build Coastguard Worker }
434*61046927SAndroid Build Coastguard Worker 
435*61046927SAndroid Build Coastguard Worker struct ir3_shader_variant *
ir3_shader_get_variant(struct ir3_shader * shader,const struct ir3_shader_key * key,bool binning_pass,bool write_disasm,bool * created)436*61046927SAndroid Build Coastguard Worker ir3_shader_get_variant(struct ir3_shader *shader,
437*61046927SAndroid Build Coastguard Worker                        const struct ir3_shader_key *key, bool binning_pass,
438*61046927SAndroid Build Coastguard Worker                        bool write_disasm, bool *created)
439*61046927SAndroid Build Coastguard Worker {
440*61046927SAndroid Build Coastguard Worker    MESA_TRACE_FUNC();
441*61046927SAndroid Build Coastguard Worker 
442*61046927SAndroid Build Coastguard Worker    mtx_lock(&shader->variants_lock);
443*61046927SAndroid Build Coastguard Worker    struct ir3_shader_variant *v = shader_variant(shader, key);
444*61046927SAndroid Build Coastguard Worker 
445*61046927SAndroid Build Coastguard Worker    if (!v) {
446*61046927SAndroid Build Coastguard Worker       /* compile new variant if it doesn't exist already: */
447*61046927SAndroid Build Coastguard Worker       v = create_variant(shader, key, write_disasm, shader);
448*61046927SAndroid Build Coastguard Worker       if (v) {
449*61046927SAndroid Build Coastguard Worker          v->next = shader->variants;
450*61046927SAndroid Build Coastguard Worker          shader->variants = v;
451*61046927SAndroid Build Coastguard Worker          *created = true;
452*61046927SAndroid Build Coastguard Worker       }
453*61046927SAndroid Build Coastguard Worker    }
454*61046927SAndroid Build Coastguard Worker 
455*61046927SAndroid Build Coastguard Worker    if (v && binning_pass) {
456*61046927SAndroid Build Coastguard Worker       v = v->binning;
457*61046927SAndroid Build Coastguard Worker       assert(v);
458*61046927SAndroid Build Coastguard Worker    }
459*61046927SAndroid Build Coastguard Worker 
460*61046927SAndroid Build Coastguard Worker    mtx_unlock(&shader->variants_lock);
461*61046927SAndroid Build Coastguard Worker 
462*61046927SAndroid Build Coastguard Worker    return v;
463*61046927SAndroid Build Coastguard Worker }
464*61046927SAndroid Build Coastguard Worker 
465*61046927SAndroid Build Coastguard Worker struct ir3_shader *
ir3_shader_passthrough_tcs(struct ir3_shader * vs,unsigned patch_vertices)466*61046927SAndroid Build Coastguard Worker ir3_shader_passthrough_tcs(struct ir3_shader *vs, unsigned patch_vertices)
467*61046927SAndroid Build Coastguard Worker {
468*61046927SAndroid Build Coastguard Worker    assert(vs->type == MESA_SHADER_VERTEX);
469*61046927SAndroid Build Coastguard Worker    assert(patch_vertices > 0);
470*61046927SAndroid Build Coastguard Worker    assert(patch_vertices <= 32);
471*61046927SAndroid Build Coastguard Worker 
472*61046927SAndroid Build Coastguard Worker    unsigned n = patch_vertices - 1;
473*61046927SAndroid Build Coastguard Worker    if (!vs->vs.passthrough_tcs[n]) {
474*61046927SAndroid Build Coastguard Worker       const nir_shader_compiler_options *options =
475*61046927SAndroid Build Coastguard Worker             ir3_get_compiler_options(vs->compiler);
476*61046927SAndroid Build Coastguard Worker       nir_shader *tcs =
477*61046927SAndroid Build Coastguard Worker             nir_create_passthrough_tcs(options, vs->nir, patch_vertices);
478*61046927SAndroid Build Coastguard Worker 
479*61046927SAndroid Build Coastguard Worker       /* Technically it is an internal shader but it is confusing to
480*61046927SAndroid Build Coastguard Worker        * not have it show up in debug output
481*61046927SAndroid Build Coastguard Worker        */
482*61046927SAndroid Build Coastguard Worker       tcs->info.internal = false;
483*61046927SAndroid Build Coastguard Worker 
484*61046927SAndroid Build Coastguard Worker       nir_assign_io_var_locations(tcs, nir_var_shader_in,
485*61046927SAndroid Build Coastguard Worker                                   &tcs->num_inputs,
486*61046927SAndroid Build Coastguard Worker                                   tcs->info.stage);
487*61046927SAndroid Build Coastguard Worker 
488*61046927SAndroid Build Coastguard Worker       nir_assign_io_var_locations(tcs, nir_var_shader_out,
489*61046927SAndroid Build Coastguard Worker                                   &tcs->num_outputs,
490*61046927SAndroid Build Coastguard Worker                                   tcs->info.stage);
491*61046927SAndroid Build Coastguard Worker 
492*61046927SAndroid Build Coastguard Worker       NIR_PASS_V(tcs, nir_lower_system_values);
493*61046927SAndroid Build Coastguard Worker 
494*61046927SAndroid Build Coastguard Worker       nir_shader_gather_info(tcs, nir_shader_get_entrypoint(tcs));
495*61046927SAndroid Build Coastguard Worker 
496*61046927SAndroid Build Coastguard Worker       ir3_finalize_nir(vs->compiler, tcs);
497*61046927SAndroid Build Coastguard Worker 
498*61046927SAndroid Build Coastguard Worker       struct ir3_shader_options ir3_options = {};
499*61046927SAndroid Build Coastguard Worker 
500*61046927SAndroid Build Coastguard Worker       vs->vs.passthrough_tcs[n] =
501*61046927SAndroid Build Coastguard Worker             ir3_shader_from_nir(vs->compiler, tcs, &ir3_options, NULL);
502*61046927SAndroid Build Coastguard Worker 
503*61046927SAndroid Build Coastguard Worker       vs->vs.passthrough_tcs_compiled |= BITFIELD_BIT(n);
504*61046927SAndroid Build Coastguard Worker    }
505*61046927SAndroid Build Coastguard Worker 
506*61046927SAndroid Build Coastguard Worker    return vs->vs.passthrough_tcs[n];
507*61046927SAndroid Build Coastguard Worker }
508*61046927SAndroid Build Coastguard Worker 
509*61046927SAndroid Build Coastguard Worker void
ir3_shader_destroy(struct ir3_shader * shader)510*61046927SAndroid Build Coastguard Worker ir3_shader_destroy(struct ir3_shader *shader)
511*61046927SAndroid Build Coastguard Worker {
512*61046927SAndroid Build Coastguard Worker    if (shader->type == MESA_SHADER_VERTEX) {
513*61046927SAndroid Build Coastguard Worker       u_foreach_bit (b, shader->vs.passthrough_tcs_compiled) {
514*61046927SAndroid Build Coastguard Worker          ir3_shader_destroy(shader->vs.passthrough_tcs[b]);
515*61046927SAndroid Build Coastguard Worker       }
516*61046927SAndroid Build Coastguard Worker    }
517*61046927SAndroid Build Coastguard Worker    ralloc_free(shader->nir);
518*61046927SAndroid Build Coastguard Worker    mtx_destroy(&shader->variants_lock);
519*61046927SAndroid Build Coastguard Worker    ralloc_free(shader);
520*61046927SAndroid Build Coastguard Worker }
521*61046927SAndroid Build Coastguard Worker 
522*61046927SAndroid Build Coastguard Worker /**
523*61046927SAndroid Build Coastguard Worker  * Creates a bitmask of the used bits of the shader key by this particular
524*61046927SAndroid Build Coastguard Worker  * shader.  Used by the gallium driver to skip state-dependent recompiles when
525*61046927SAndroid Build Coastguard Worker  * possible.
526*61046927SAndroid Build Coastguard Worker  */
527*61046927SAndroid Build Coastguard Worker static void
ir3_setup_used_key(struct ir3_shader * shader)528*61046927SAndroid Build Coastguard Worker ir3_setup_used_key(struct ir3_shader *shader)
529*61046927SAndroid Build Coastguard Worker {
530*61046927SAndroid Build Coastguard Worker    nir_shader *nir = shader->nir;
531*61046927SAndroid Build Coastguard Worker    struct shader_info *info = &nir->info;
532*61046927SAndroid Build Coastguard Worker    struct ir3_shader_key *key = &shader->key_mask;
533*61046927SAndroid Build Coastguard Worker 
534*61046927SAndroid Build Coastguard Worker    /* This key flag is just used to make for a cheaper ir3_shader_key_equal
535*61046927SAndroid Build Coastguard Worker     * check in the common case.
536*61046927SAndroid Build Coastguard Worker     */
537*61046927SAndroid Build Coastguard Worker    key->has_per_samp = true;
538*61046927SAndroid Build Coastguard Worker 
539*61046927SAndroid Build Coastguard Worker    key->safe_constlen = true;
540*61046927SAndroid Build Coastguard Worker 
541*61046927SAndroid Build Coastguard Worker    /* When clip/cull distances are natively supported, we only use
542*61046927SAndroid Build Coastguard Worker     * ucp_enables to determine whether to lower legacy clip planes to
543*61046927SAndroid Build Coastguard Worker     * gl_ClipDistance.
544*61046927SAndroid Build Coastguard Worker     */
545*61046927SAndroid Build Coastguard Worker    if (info->stage != MESA_SHADER_COMPUTE && (info->stage != MESA_SHADER_FRAGMENT || !shader->compiler->has_clip_cull))
546*61046927SAndroid Build Coastguard Worker       key->ucp_enables = 0xff;
547*61046927SAndroid Build Coastguard Worker 
548*61046927SAndroid Build Coastguard Worker    if (info->stage == MESA_SHADER_FRAGMENT) {
549*61046927SAndroid Build Coastguard Worker       key->fastc_srgb = ~0;
550*61046927SAndroid Build Coastguard Worker       key->fsamples = ~0;
551*61046927SAndroid Build Coastguard Worker       memset(key->fsampler_swizzles, 0xff, sizeof(key->fsampler_swizzles));
552*61046927SAndroid Build Coastguard Worker 
553*61046927SAndroid Build Coastguard Worker       if (info->inputs_read & VARYING_BITS_COLOR) {
554*61046927SAndroid Build Coastguard Worker          key->rasterflat = true;
555*61046927SAndroid Build Coastguard Worker       }
556*61046927SAndroid Build Coastguard Worker 
557*61046927SAndroid Build Coastguard Worker       /* Only used for deciding on behavior of
558*61046927SAndroid Build Coastguard Worker        * nir_intrinsic_load_barycentric_sample and the centroid demotion
559*61046927SAndroid Build Coastguard Worker        * on older HW.
560*61046927SAndroid Build Coastguard Worker        */
561*61046927SAndroid Build Coastguard Worker       key->msaa = shader->compiler->gen < 6 &&
562*61046927SAndroid Build Coastguard Worker                   (info->fs.uses_sample_qualifier ||
563*61046927SAndroid Build Coastguard Worker                    (BITSET_TEST(info->system_values_read,
564*61046927SAndroid Build Coastguard Worker                                 SYSTEM_VALUE_BARYCENTRIC_PERSP_CENTROID) ||
565*61046927SAndroid Build Coastguard Worker                     BITSET_TEST(info->system_values_read,
566*61046927SAndroid Build Coastguard Worker                                 SYSTEM_VALUE_BARYCENTRIC_LINEAR_CENTROID)));
567*61046927SAndroid Build Coastguard Worker 
568*61046927SAndroid Build Coastguard Worker       /* Only enable this shader key bit if "dual_color_blend_by_location" is
569*61046927SAndroid Build Coastguard Worker        * enabled:
570*61046927SAndroid Build Coastguard Worker        */
571*61046927SAndroid Build Coastguard Worker       key->force_dual_color_blend = shader->compiler->options.dual_color_blend_by_location;
572*61046927SAndroid Build Coastguard Worker    } else if (info->stage == MESA_SHADER_COMPUTE) {
573*61046927SAndroid Build Coastguard Worker       key->fastc_srgb = ~0;
574*61046927SAndroid Build Coastguard Worker       key->fsamples = ~0;
575*61046927SAndroid Build Coastguard Worker       memset(key->fsampler_swizzles, 0xff, sizeof(key->fsampler_swizzles));
576*61046927SAndroid Build Coastguard Worker    } else {
577*61046927SAndroid Build Coastguard Worker       key->tessellation = ~0;
578*61046927SAndroid Build Coastguard Worker       key->has_gs = true;
579*61046927SAndroid Build Coastguard Worker 
580*61046927SAndroid Build Coastguard Worker       if (info->stage == MESA_SHADER_VERTEX) {
581*61046927SAndroid Build Coastguard Worker          key->vastc_srgb = ~0;
582*61046927SAndroid Build Coastguard Worker          key->vsamples = ~0;
583*61046927SAndroid Build Coastguard Worker          memset(key->vsampler_swizzles, 0xff, sizeof(key->vsampler_swizzles));
584*61046927SAndroid Build Coastguard Worker       }
585*61046927SAndroid Build Coastguard Worker 
586*61046927SAndroid Build Coastguard Worker       if (info->stage == MESA_SHADER_TESS_CTRL)
587*61046927SAndroid Build Coastguard Worker          key->tcs_store_primid = true;
588*61046927SAndroid Build Coastguard Worker    }
589*61046927SAndroid Build Coastguard Worker }
590*61046927SAndroid Build Coastguard Worker 
591*61046927SAndroid Build Coastguard Worker /* Given an array of constlen's, decrease some of them so that the sum stays
592*61046927SAndroid Build Coastguard Worker  * within "combined_limit" while trying to fairly share the reduction. Returns
593*61046927SAndroid Build Coastguard Worker  * a bitfield of which stages should be trimmed.
594*61046927SAndroid Build Coastguard Worker  */
595*61046927SAndroid Build Coastguard Worker static uint32_t
trim_constlens(unsigned * constlens,unsigned first_stage,unsigned last_stage,unsigned combined_limit,unsigned safe_limit)596*61046927SAndroid Build Coastguard Worker trim_constlens(unsigned *constlens, unsigned first_stage, unsigned last_stage,
597*61046927SAndroid Build Coastguard Worker                unsigned combined_limit, unsigned safe_limit)
598*61046927SAndroid Build Coastguard Worker {
599*61046927SAndroid Build Coastguard Worker    unsigned cur_total = 0;
600*61046927SAndroid Build Coastguard Worker    for (unsigned i = first_stage; i <= last_stage; i++) {
601*61046927SAndroid Build Coastguard Worker       cur_total += constlens[i];
602*61046927SAndroid Build Coastguard Worker    }
603*61046927SAndroid Build Coastguard Worker 
604*61046927SAndroid Build Coastguard Worker    unsigned max_stage = 0;
605*61046927SAndroid Build Coastguard Worker    unsigned max_const = 0;
606*61046927SAndroid Build Coastguard Worker    uint32_t trimmed = 0;
607*61046927SAndroid Build Coastguard Worker 
608*61046927SAndroid Build Coastguard Worker    while (cur_total > combined_limit) {
609*61046927SAndroid Build Coastguard Worker       for (unsigned i = first_stage; i <= last_stage; i++) {
610*61046927SAndroid Build Coastguard Worker          if (constlens[i] >= max_const) {
611*61046927SAndroid Build Coastguard Worker             max_stage = i;
612*61046927SAndroid Build Coastguard Worker             max_const = constlens[i];
613*61046927SAndroid Build Coastguard Worker          }
614*61046927SAndroid Build Coastguard Worker       }
615*61046927SAndroid Build Coastguard Worker 
616*61046927SAndroid Build Coastguard Worker       assert(max_const > safe_limit);
617*61046927SAndroid Build Coastguard Worker       trimmed |= 1 << max_stage;
618*61046927SAndroid Build Coastguard Worker       cur_total = cur_total - max_const + safe_limit;
619*61046927SAndroid Build Coastguard Worker       constlens[max_stage] = safe_limit;
620*61046927SAndroid Build Coastguard Worker    }
621*61046927SAndroid Build Coastguard Worker 
622*61046927SAndroid Build Coastguard Worker    return trimmed;
623*61046927SAndroid Build Coastguard Worker }
624*61046927SAndroid Build Coastguard Worker 
625*61046927SAndroid Build Coastguard Worker /* Figures out which stages in the pipeline to use the "safe" constlen for, in
626*61046927SAndroid Build Coastguard Worker  * order to satisfy all shared constlen limits.
627*61046927SAndroid Build Coastguard Worker  */
628*61046927SAndroid Build Coastguard Worker uint32_t
ir3_trim_constlen(const struct ir3_shader_variant ** variants,const struct ir3_compiler * compiler)629*61046927SAndroid Build Coastguard Worker ir3_trim_constlen(const struct ir3_shader_variant **variants,
630*61046927SAndroid Build Coastguard Worker                   const struct ir3_compiler *compiler)
631*61046927SAndroid Build Coastguard Worker {
632*61046927SAndroid Build Coastguard Worker    unsigned constlens[MESA_SHADER_STAGES] = {};
633*61046927SAndroid Build Coastguard Worker 
634*61046927SAndroid Build Coastguard Worker    bool shared_consts_enable = false;
635*61046927SAndroid Build Coastguard Worker 
636*61046927SAndroid Build Coastguard Worker    for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
637*61046927SAndroid Build Coastguard Worker       if (variants[i]) {
638*61046927SAndroid Build Coastguard Worker          constlens[i] = variants[i]->constlen;
639*61046927SAndroid Build Coastguard Worker          shared_consts_enable =
640*61046927SAndroid Build Coastguard Worker             ir3_const_state(variants[i])->push_consts_type == IR3_PUSH_CONSTS_SHARED;
641*61046927SAndroid Build Coastguard Worker       }
642*61046927SAndroid Build Coastguard Worker    }
643*61046927SAndroid Build Coastguard Worker 
644*61046927SAndroid Build Coastguard Worker    uint32_t trimmed = 0;
645*61046927SAndroid Build Coastguard Worker    STATIC_ASSERT(MESA_SHADER_STAGES <= 8 * sizeof(trimmed));
646*61046927SAndroid Build Coastguard Worker 
647*61046927SAndroid Build Coastguard Worker    /* Use a hw quirk for geometry shared consts, not matched with actual
648*61046927SAndroid Build Coastguard Worker     * shared consts size (on a6xx).
649*61046927SAndroid Build Coastguard Worker     */
650*61046927SAndroid Build Coastguard Worker    uint32_t shared_consts_size_geom = shared_consts_enable ?
651*61046927SAndroid Build Coastguard Worker       compiler->geom_shared_consts_size_quirk : 0;
652*61046927SAndroid Build Coastguard Worker 
653*61046927SAndroid Build Coastguard Worker    uint32_t shared_consts_size = shared_consts_enable ?
654*61046927SAndroid Build Coastguard Worker       compiler->shared_consts_size : 0;
655*61046927SAndroid Build Coastguard Worker 
656*61046927SAndroid Build Coastguard Worker    uint32_t safe_shared_consts_size = shared_consts_enable  ?
657*61046927SAndroid Build Coastguard Worker       ALIGN_POT(MAX2(DIV_ROUND_UP(shared_consts_size_geom, 4),
658*61046927SAndroid Build Coastguard Worker                      DIV_ROUND_UP(shared_consts_size, 5)), 4) : 0;
659*61046927SAndroid Build Coastguard Worker 
660*61046927SAndroid Build Coastguard Worker    /* There are two shared limits to take into account, the geometry limit on
661*61046927SAndroid Build Coastguard Worker     * a6xx and the total limit. The frag limit on a6xx only matters for a
662*61046927SAndroid Build Coastguard Worker     * single stage, so it's always satisfied with the first variant.
663*61046927SAndroid Build Coastguard Worker     */
664*61046927SAndroid Build Coastguard Worker    if (compiler->gen >= 6) {
665*61046927SAndroid Build Coastguard Worker       trimmed |=
666*61046927SAndroid Build Coastguard Worker          trim_constlens(constlens, MESA_SHADER_VERTEX, MESA_SHADER_GEOMETRY,
667*61046927SAndroid Build Coastguard Worker                         compiler->max_const_geom - shared_consts_size_geom,
668*61046927SAndroid Build Coastguard Worker                         compiler->max_const_safe - safe_shared_consts_size);
669*61046927SAndroid Build Coastguard Worker    }
670*61046927SAndroid Build Coastguard Worker    trimmed |=
671*61046927SAndroid Build Coastguard Worker       trim_constlens(constlens, MESA_SHADER_VERTEX, MESA_SHADER_FRAGMENT,
672*61046927SAndroid Build Coastguard Worker                      compiler->max_const_pipeline - shared_consts_size,
673*61046927SAndroid Build Coastguard Worker                      compiler->max_const_safe - safe_shared_consts_size);
674*61046927SAndroid Build Coastguard Worker 
675*61046927SAndroid Build Coastguard Worker    return trimmed;
676*61046927SAndroid Build Coastguard Worker }
677*61046927SAndroid Build Coastguard Worker 
678*61046927SAndroid Build Coastguard Worker struct ir3_shader *
ir3_shader_from_nir(struct ir3_compiler * compiler,nir_shader * nir,const struct ir3_shader_options * options,struct ir3_stream_output_info * stream_output)679*61046927SAndroid Build Coastguard Worker ir3_shader_from_nir(struct ir3_compiler *compiler, nir_shader *nir,
680*61046927SAndroid Build Coastguard Worker                     const struct ir3_shader_options *options,
681*61046927SAndroid Build Coastguard Worker                     struct ir3_stream_output_info *stream_output)
682*61046927SAndroid Build Coastguard Worker {
683*61046927SAndroid Build Coastguard Worker    struct ir3_shader *shader = rzalloc_size(NULL, sizeof(*shader));
684*61046927SAndroid Build Coastguard Worker 
685*61046927SAndroid Build Coastguard Worker    mtx_init(&shader->variants_lock, mtx_plain);
686*61046927SAndroid Build Coastguard Worker    shader->compiler = compiler;
687*61046927SAndroid Build Coastguard Worker    shader->id = p_atomic_inc_return(&shader->compiler->shader_count);
688*61046927SAndroid Build Coastguard Worker    shader->type = nir->info.stage;
689*61046927SAndroid Build Coastguard Worker    if (stream_output)
690*61046927SAndroid Build Coastguard Worker       memcpy(&shader->stream_output, stream_output,
691*61046927SAndroid Build Coastguard Worker              sizeof(shader->stream_output));
692*61046927SAndroid Build Coastguard Worker    shader->options = *options;
693*61046927SAndroid Build Coastguard Worker    shader->nir = nir;
694*61046927SAndroid Build Coastguard Worker 
695*61046927SAndroid Build Coastguard Worker    ir3_disk_cache_init_shader_key(compiler, shader);
696*61046927SAndroid Build Coastguard Worker 
697*61046927SAndroid Build Coastguard Worker    ir3_setup_used_key(shader);
698*61046927SAndroid Build Coastguard Worker 
699*61046927SAndroid Build Coastguard Worker    return shader;
700*61046927SAndroid Build Coastguard Worker }
701*61046927SAndroid Build Coastguard Worker 
702*61046927SAndroid Build Coastguard Worker static void
dump_reg(FILE * out,const char * name,uint32_t r)703*61046927SAndroid Build Coastguard Worker dump_reg(FILE *out, const char *name, uint32_t r)
704*61046927SAndroid Build Coastguard Worker {
705*61046927SAndroid Build Coastguard Worker    if (r != regid(63, 0)) {
706*61046927SAndroid Build Coastguard Worker       const char *reg_type = (r & HALF_REG_ID) ? "hr" : "r";
707*61046927SAndroid Build Coastguard Worker       fprintf(out, "; %s: %s%d.%c\n", name, reg_type, (r & ~HALF_REG_ID) >> 2,
708*61046927SAndroid Build Coastguard Worker               "xyzw"[r & 0x3]);
709*61046927SAndroid Build Coastguard Worker    }
710*61046927SAndroid Build Coastguard Worker }
711*61046927SAndroid Build Coastguard Worker 
712*61046927SAndroid Build Coastguard Worker static void
dump_output(FILE * out,struct ir3_shader_variant * so,unsigned slot,const char * name)713*61046927SAndroid Build Coastguard Worker dump_output(FILE *out, struct ir3_shader_variant *so, unsigned slot,
714*61046927SAndroid Build Coastguard Worker             const char *name)
715*61046927SAndroid Build Coastguard Worker {
716*61046927SAndroid Build Coastguard Worker    uint32_t regid;
717*61046927SAndroid Build Coastguard Worker    regid = ir3_find_output_regid(so, slot);
718*61046927SAndroid Build Coastguard Worker    dump_reg(out, name, regid);
719*61046927SAndroid Build Coastguard Worker }
720*61046927SAndroid Build Coastguard Worker 
721*61046927SAndroid Build Coastguard Worker static const char *
input_name(struct ir3_shader_variant * so,int i)722*61046927SAndroid Build Coastguard Worker input_name(struct ir3_shader_variant *so, int i)
723*61046927SAndroid Build Coastguard Worker {
724*61046927SAndroid Build Coastguard Worker    if (so->inputs[i].sysval) {
725*61046927SAndroid Build Coastguard Worker       return gl_system_value_name(so->inputs[i].slot);
726*61046927SAndroid Build Coastguard Worker    } else if (so->type == MESA_SHADER_VERTEX) {
727*61046927SAndroid Build Coastguard Worker       return gl_vert_attrib_name(so->inputs[i].slot);
728*61046927SAndroid Build Coastguard Worker    } else {
729*61046927SAndroid Build Coastguard Worker       return gl_varying_slot_name_for_stage(so->inputs[i].slot, so->type);
730*61046927SAndroid Build Coastguard Worker    }
731*61046927SAndroid Build Coastguard Worker }
732*61046927SAndroid Build Coastguard Worker 
733*61046927SAndroid Build Coastguard Worker static const char *
output_name(struct ir3_shader_variant * so,int i)734*61046927SAndroid Build Coastguard Worker output_name(struct ir3_shader_variant *so, int i)
735*61046927SAndroid Build Coastguard Worker {
736*61046927SAndroid Build Coastguard Worker    if (so->type == MESA_SHADER_FRAGMENT) {
737*61046927SAndroid Build Coastguard Worker       return gl_frag_result_name(so->outputs[i].slot);
738*61046927SAndroid Build Coastguard Worker    } else {
739*61046927SAndroid Build Coastguard Worker       switch (so->outputs[i].slot) {
740*61046927SAndroid Build Coastguard Worker       case VARYING_SLOT_GS_HEADER_IR3:
741*61046927SAndroid Build Coastguard Worker          return "GS_HEADER";
742*61046927SAndroid Build Coastguard Worker       case VARYING_SLOT_GS_VERTEX_FLAGS_IR3:
743*61046927SAndroid Build Coastguard Worker          return "GS_VERTEX_FLAGS";
744*61046927SAndroid Build Coastguard Worker       case VARYING_SLOT_TCS_HEADER_IR3:
745*61046927SAndroid Build Coastguard Worker          return "TCS_HEADER";
746*61046927SAndroid Build Coastguard Worker       default:
747*61046927SAndroid Build Coastguard Worker          return gl_varying_slot_name_for_stage(so->outputs[i].slot, so->type);
748*61046927SAndroid Build Coastguard Worker       }
749*61046927SAndroid Build Coastguard Worker    }
750*61046927SAndroid Build Coastguard Worker }
751*61046927SAndroid Build Coastguard Worker 
752*61046927SAndroid Build Coastguard Worker static void
dump_const_state(struct ir3_shader_variant * so,FILE * out)753*61046927SAndroid Build Coastguard Worker dump_const_state(struct ir3_shader_variant *so, FILE *out)
754*61046927SAndroid Build Coastguard Worker {
755*61046927SAndroid Build Coastguard Worker    const struct ir3_const_state *cs = ir3_const_state(so);
756*61046927SAndroid Build Coastguard Worker    const struct ir3_ubo_analysis_state *us = &cs->ubo_state;
757*61046927SAndroid Build Coastguard Worker 
758*61046927SAndroid Build Coastguard Worker    fprintf(out, "; num_ubos:           %u\n", cs->num_ubos);
759*61046927SAndroid Build Coastguard Worker    fprintf(out, "; num_driver_params:  %u\n", cs->num_driver_params);
760*61046927SAndroid Build Coastguard Worker    fprintf(out, "; offsets:\n");
761*61046927SAndroid Build Coastguard Worker    if (cs->offsets.ubo != ~0)
762*61046927SAndroid Build Coastguard Worker       fprintf(out, ";   ubo:              c%u.x\n", cs->offsets.ubo);
763*61046927SAndroid Build Coastguard Worker    if (cs->offsets.image_dims != ~0)
764*61046927SAndroid Build Coastguard Worker       fprintf(out, ";   image_dims:       c%u.x\n", cs->offsets.image_dims);
765*61046927SAndroid Build Coastguard Worker    if (cs->offsets.kernel_params != ~0)
766*61046927SAndroid Build Coastguard Worker       fprintf(out, ";   kernel_params:    c%u.x\n", cs->offsets.kernel_params);
767*61046927SAndroid Build Coastguard Worker    if (cs->offsets.driver_param != ~0)
768*61046927SAndroid Build Coastguard Worker       fprintf(out, ";   driver_param:     c%u.x\n", cs->offsets.driver_param);
769*61046927SAndroid Build Coastguard Worker    if (cs->offsets.tfbo != ~0)
770*61046927SAndroid Build Coastguard Worker       fprintf(out, ";   tfbo:             c%u.x\n", cs->offsets.tfbo);
771*61046927SAndroid Build Coastguard Worker    if (cs->offsets.primitive_param != ~0)
772*61046927SAndroid Build Coastguard Worker       fprintf(out, ";   primitive_params: c%u.x\n", cs->offsets.primitive_param);
773*61046927SAndroid Build Coastguard Worker    if (cs->offsets.primitive_map != ~0)
774*61046927SAndroid Build Coastguard Worker       fprintf(out, ";   primitive_map:    c%u.x\n", cs->offsets.primitive_map);
775*61046927SAndroid Build Coastguard Worker    fprintf(out, "; ubo_state:\n");
776*61046927SAndroid Build Coastguard Worker    fprintf(out, ";   num_enabled:      %u\n", us->num_enabled);
777*61046927SAndroid Build Coastguard Worker    for (unsigned i = 0; i < us->num_enabled; i++) {
778*61046927SAndroid Build Coastguard Worker       const struct ir3_ubo_range *r = &us->range[i];
779*61046927SAndroid Build Coastguard Worker 
780*61046927SAndroid Build Coastguard Worker       assert((r->offset % 16) == 0);
781*61046927SAndroid Build Coastguard Worker 
782*61046927SAndroid Build Coastguard Worker       fprintf(out, ";   range[%u]:\n", i);
783*61046927SAndroid Build Coastguard Worker       fprintf(out, ";     block:          %u\n", r->ubo.block);
784*61046927SAndroid Build Coastguard Worker       if (r->ubo.bindless)
785*61046927SAndroid Build Coastguard Worker          fprintf(out, ";     bindless_base:  %u\n", r->ubo.bindless_base);
786*61046927SAndroid Build Coastguard Worker       fprintf(out, ";     offset:         c%u.x\n", r->offset/16);
787*61046927SAndroid Build Coastguard Worker 
788*61046927SAndroid Build Coastguard Worker       unsigned size = r->end - r->start;
789*61046927SAndroid Build Coastguard Worker       assert((size % 16) == 0);
790*61046927SAndroid Build Coastguard Worker 
791*61046927SAndroid Build Coastguard Worker       fprintf(out, ";     size:           %u vec4 (%ub -> %ub)\n", (size/16), r->start, r->end);
792*61046927SAndroid Build Coastguard Worker    }
793*61046927SAndroid Build Coastguard Worker }
794*61046927SAndroid Build Coastguard Worker 
795*61046927SAndroid Build Coastguard Worker static uint8_t
find_input_reg_id(struct ir3_shader_variant * so,uint32_t input_idx)796*61046927SAndroid Build Coastguard Worker find_input_reg_id(struct ir3_shader_variant *so, uint32_t input_idx)
797*61046927SAndroid Build Coastguard Worker {
798*61046927SAndroid Build Coastguard Worker    uint8_t reg = so->inputs[input_idx].regid;
799*61046927SAndroid Build Coastguard Worker    if (so->type != MESA_SHADER_FRAGMENT || !so->ir || VALIDREG(reg))
800*61046927SAndroid Build Coastguard Worker       return reg;
801*61046927SAndroid Build Coastguard Worker 
802*61046927SAndroid Build Coastguard Worker    reg = INVALID_REG;
803*61046927SAndroid Build Coastguard Worker 
804*61046927SAndroid Build Coastguard Worker    /* In FS we don't know into which register the input is loaded
805*61046927SAndroid Build Coastguard Worker     * until the shader is scanned for the input load instructions.
806*61046927SAndroid Build Coastguard Worker     */
807*61046927SAndroid Build Coastguard Worker    foreach_block (block, &so->ir->block_list) {
808*61046927SAndroid Build Coastguard Worker       foreach_instr_safe (instr, &block->instr_list) {
809*61046927SAndroid Build Coastguard Worker          if (instr->opc == OPC_FLAT_B || instr->opc == OPC_BARY_F ||
810*61046927SAndroid Build Coastguard Worker              instr->opc == OPC_LDLV) {
811*61046927SAndroid Build Coastguard Worker             if (instr->srcs[0]->flags & IR3_REG_IMMED) {
812*61046927SAndroid Build Coastguard Worker                unsigned inloc = so->inputs[input_idx].inloc;
813*61046927SAndroid Build Coastguard Worker                unsigned instr_inloc = instr->srcs[0]->uim_val;
814*61046927SAndroid Build Coastguard Worker                unsigned size = util_bitcount(so->inputs[input_idx].compmask);
815*61046927SAndroid Build Coastguard Worker 
816*61046927SAndroid Build Coastguard Worker                if (instr_inloc == inloc) {
817*61046927SAndroid Build Coastguard Worker                   return instr->dsts[0]->num;
818*61046927SAndroid Build Coastguard Worker                }
819*61046927SAndroid Build Coastguard Worker 
820*61046927SAndroid Build Coastguard Worker                if (instr_inloc > inloc && instr_inloc < (inloc + size)) {
821*61046927SAndroid Build Coastguard Worker                   reg = MIN2(reg, instr->dsts[0]->num);
822*61046927SAndroid Build Coastguard Worker                }
823*61046927SAndroid Build Coastguard Worker 
824*61046927SAndroid Build Coastguard Worker                if (instr->dsts[0]->flags & IR3_REG_EI) {
825*61046927SAndroid Build Coastguard Worker                   return reg;
826*61046927SAndroid Build Coastguard Worker                }
827*61046927SAndroid Build Coastguard Worker             }
828*61046927SAndroid Build Coastguard Worker          }
829*61046927SAndroid Build Coastguard Worker       }
830*61046927SAndroid Build Coastguard Worker    }
831*61046927SAndroid Build Coastguard Worker 
832*61046927SAndroid Build Coastguard Worker    return reg;
833*61046927SAndroid Build Coastguard Worker }
834*61046927SAndroid Build Coastguard Worker 
835*61046927SAndroid Build Coastguard Worker void
print_raw(FILE * out,const BITSET_WORD * data,size_t size)836*61046927SAndroid Build Coastguard Worker print_raw(FILE *out, const BITSET_WORD *data, size_t size) {
837*61046927SAndroid Build Coastguard Worker    fprintf(out, "raw 0x%X%X\n", data[0], data[1]);
838*61046927SAndroid Build Coastguard Worker }
839*61046927SAndroid Build Coastguard Worker 
840*61046927SAndroid Build Coastguard Worker void
ir3_shader_disasm(struct ir3_shader_variant * so,uint32_t * bin,FILE * out)841*61046927SAndroid Build Coastguard Worker ir3_shader_disasm(struct ir3_shader_variant *so, uint32_t *bin, FILE *out)
842*61046927SAndroid Build Coastguard Worker {
843*61046927SAndroid Build Coastguard Worker    struct ir3 *ir = so->ir;
844*61046927SAndroid Build Coastguard Worker    struct ir3_register *reg;
845*61046927SAndroid Build Coastguard Worker    const char *type = ir3_shader_stage(so);
846*61046927SAndroid Build Coastguard Worker    uint8_t regid;
847*61046927SAndroid Build Coastguard Worker    unsigned i;
848*61046927SAndroid Build Coastguard Worker 
849*61046927SAndroid Build Coastguard Worker    dump_const_state(so, out);
850*61046927SAndroid Build Coastguard Worker 
851*61046927SAndroid Build Coastguard Worker    foreach_input_n (instr, i, ir) {
852*61046927SAndroid Build Coastguard Worker       reg = instr->dsts[0];
853*61046927SAndroid Build Coastguard Worker       regid = reg->num;
854*61046927SAndroid Build Coastguard Worker       fprintf(out, "@in(%sr%d.%c)\tin%d",
855*61046927SAndroid Build Coastguard Worker               (reg->flags & IR3_REG_HALF) ? "h" : "", (regid >> 2),
856*61046927SAndroid Build Coastguard Worker               "xyzw"[regid & 0x3], i);
857*61046927SAndroid Build Coastguard Worker 
858*61046927SAndroid Build Coastguard Worker       if (reg->wrmask > 0x1)
859*61046927SAndroid Build Coastguard Worker          fprintf(out, " (wrmask=0x%x)", reg->wrmask);
860*61046927SAndroid Build Coastguard Worker       fprintf(out, "\n");
861*61046927SAndroid Build Coastguard Worker    }
862*61046927SAndroid Build Coastguard Worker 
863*61046927SAndroid Build Coastguard Worker    /* print pre-dispatch texture fetches: */
864*61046927SAndroid Build Coastguard Worker    for (i = 0; i < so->num_sampler_prefetch; i++) {
865*61046927SAndroid Build Coastguard Worker       const struct ir3_sampler_prefetch *fetch = &so->sampler_prefetch[i];
866*61046927SAndroid Build Coastguard Worker       fprintf(out,
867*61046927SAndroid Build Coastguard Worker               "@tex(%sr%d.%c)\tsrc=%u, bindless=%u, samp=%u, tex=%u, wrmask=0x%x, opc=%s\n",
868*61046927SAndroid Build Coastguard Worker               fetch->half_precision ? "h" : "", fetch->dst >> 2,
869*61046927SAndroid Build Coastguard Worker               "xyzw"[fetch->dst & 0x3], fetch->src, fetch->bindless,
870*61046927SAndroid Build Coastguard Worker               fetch->bindless ? fetch->samp_bindless_id : fetch->samp_id,
871*61046927SAndroid Build Coastguard Worker               fetch->bindless ? fetch->tex_bindless_id : fetch->tex_id,
872*61046927SAndroid Build Coastguard Worker               fetch->wrmask, disasm_a3xx_instr_name(fetch->tex_opc));
873*61046927SAndroid Build Coastguard Worker    }
874*61046927SAndroid Build Coastguard Worker 
875*61046927SAndroid Build Coastguard Worker    const struct ir3_const_state *const_state = ir3_const_state(so);
876*61046927SAndroid Build Coastguard Worker    for (i = 0; i < DIV_ROUND_UP(const_state->immediates_count, 4); i++) {
877*61046927SAndroid Build Coastguard Worker       fprintf(out, "@const(c%d.x)\t", const_state->offsets.immediate + i);
878*61046927SAndroid Build Coastguard Worker       fprintf(out, "0x%08x, 0x%08x, 0x%08x, 0x%08x\n",
879*61046927SAndroid Build Coastguard Worker               const_state->immediates[i * 4 + 0],
880*61046927SAndroid Build Coastguard Worker               const_state->immediates[i * 4 + 1],
881*61046927SAndroid Build Coastguard Worker               const_state->immediates[i * 4 + 2],
882*61046927SAndroid Build Coastguard Worker               const_state->immediates[i * 4 + 3]);
883*61046927SAndroid Build Coastguard Worker    }
884*61046927SAndroid Build Coastguard Worker 
885*61046927SAndroid Build Coastguard Worker    ir3_isa_disasm(bin, so->info.sizedwords * 4, out,
886*61046927SAndroid Build Coastguard Worker                   &(struct isa_decode_options){
887*61046927SAndroid Build Coastguard Worker                      .gpu_id = ir->compiler->gen * 100,
888*61046927SAndroid Build Coastguard Worker                      .show_errors = true,
889*61046927SAndroid Build Coastguard Worker                      .branch_labels = true,
890*61046927SAndroid Build Coastguard Worker                      .no_match_cb = print_raw,
891*61046927SAndroid Build Coastguard Worker                   });
892*61046927SAndroid Build Coastguard Worker 
893*61046927SAndroid Build Coastguard Worker    fprintf(out, "; %s: outputs:", type);
894*61046927SAndroid Build Coastguard Worker    for (i = 0; i < so->outputs_count; i++) {
895*61046927SAndroid Build Coastguard Worker       uint8_t regid = so->outputs[i].regid;
896*61046927SAndroid Build Coastguard Worker       const char *reg_type = so->outputs[i].half ? "hr" : "r";
897*61046927SAndroid Build Coastguard Worker       fprintf(out, " %s%d.%c (%s)", reg_type, (regid >> 2), "xyzw"[regid & 0x3],
898*61046927SAndroid Build Coastguard Worker               output_name(so, i));
899*61046927SAndroid Build Coastguard Worker    }
900*61046927SAndroid Build Coastguard Worker    fprintf(out, "\n");
901*61046927SAndroid Build Coastguard Worker 
902*61046927SAndroid Build Coastguard Worker    fprintf(out, "; %s: inputs:", type);
903*61046927SAndroid Build Coastguard Worker    for (i = 0; i < so->inputs_count; i++) {
904*61046927SAndroid Build Coastguard Worker       uint8_t regid = find_input_reg_id(so, i);
905*61046927SAndroid Build Coastguard Worker 
906*61046927SAndroid Build Coastguard Worker       fprintf(out, " r%d.%c (%s slot=%d cm=%x,il=%u,b=%u)", (regid >> 2),
907*61046927SAndroid Build Coastguard Worker               "xyzw"[regid & 0x3], input_name(so, i), so -> inputs[i].slot,
908*61046927SAndroid Build Coastguard Worker               so->inputs[i].compmask, so->inputs[i].inloc, so->inputs[i].bary);
909*61046927SAndroid Build Coastguard Worker    }
910*61046927SAndroid Build Coastguard Worker    fprintf(out, "\n");
911*61046927SAndroid Build Coastguard Worker 
912*61046927SAndroid Build Coastguard Worker    /* print generic shader info: */
913*61046927SAndroid Build Coastguard Worker    fprintf(
914*61046927SAndroid Build Coastguard Worker       out,
915*61046927SAndroid Build Coastguard Worker       "; %s prog %d/%d: %u instr, %u nops, %u non-nops, %u mov, %u cov, %u dwords\n",
916*61046927SAndroid Build Coastguard Worker       type, so->shader_id, so->id, so->info.instrs_count, so->info.nops_count,
917*61046927SAndroid Build Coastguard Worker       so->info.instrs_count - so->info.nops_count, so->info.mov_count,
918*61046927SAndroid Build Coastguard Worker       so->info.cov_count, so->info.sizedwords);
919*61046927SAndroid Build Coastguard Worker 
920*61046927SAndroid Build Coastguard Worker    fprintf(out,
921*61046927SAndroid Build Coastguard Worker            "; %s prog %d/%d: %u last-baryf, %u last-helper, %d half, %d full, %u constlen\n",
922*61046927SAndroid Build Coastguard Worker            type, so->shader_id, so->id, so->info.last_baryf,
923*61046927SAndroid Build Coastguard Worker            so->info.last_helper, so->info.max_half_reg + 1,
924*61046927SAndroid Build Coastguard Worker            so->info.max_reg + 1, so->constlen);
925*61046927SAndroid Build Coastguard Worker 
926*61046927SAndroid Build Coastguard Worker    fprintf(
927*61046927SAndroid Build Coastguard Worker       out,
928*61046927SAndroid Build Coastguard Worker       "; %s prog %d/%d: %u cat0, %u cat1, %u cat2, %u cat3, %u cat4, %u cat5, %u cat6, %u cat7, \n",
929*61046927SAndroid Build Coastguard Worker       type, so->shader_id, so->id, so->info.instrs_per_cat[0],
930*61046927SAndroid Build Coastguard Worker       so->info.instrs_per_cat[1], so->info.instrs_per_cat[2],
931*61046927SAndroid Build Coastguard Worker       so->info.instrs_per_cat[3], so->info.instrs_per_cat[4],
932*61046927SAndroid Build Coastguard Worker       so->info.instrs_per_cat[5], so->info.instrs_per_cat[6],
933*61046927SAndroid Build Coastguard Worker       so->info.instrs_per_cat[7]);
934*61046927SAndroid Build Coastguard Worker 
935*61046927SAndroid Build Coastguard Worker    fprintf(
936*61046927SAndroid Build Coastguard Worker       out,
937*61046927SAndroid Build Coastguard Worker       "; %s prog %d/%d: %u sstall, %u (ss), %u systall, %u (sy), %d loops\n",
938*61046927SAndroid Build Coastguard Worker       type, so->shader_id, so->id, so->info.sstall, so->info.ss,
939*61046927SAndroid Build Coastguard Worker       so->info.systall, so->info.sy, so->loops);
940*61046927SAndroid Build Coastguard Worker 
941*61046927SAndroid Build Coastguard Worker    /* print shader type specific info: */
942*61046927SAndroid Build Coastguard Worker    switch (so->type) {
943*61046927SAndroid Build Coastguard Worker    case MESA_SHADER_VERTEX:
944*61046927SAndroid Build Coastguard Worker       dump_output(out, so, VARYING_SLOT_POS, "pos");
945*61046927SAndroid Build Coastguard Worker       dump_output(out, so, VARYING_SLOT_PSIZ, "psize");
946*61046927SAndroid Build Coastguard Worker       break;
947*61046927SAndroid Build Coastguard Worker    case MESA_SHADER_FRAGMENT:
948*61046927SAndroid Build Coastguard Worker       dump_reg(out, "pos (ij_pixel)",
949*61046927SAndroid Build Coastguard Worker                ir3_find_sysval_regid(so, SYSTEM_VALUE_BARYCENTRIC_PERSP_PIXEL));
950*61046927SAndroid Build Coastguard Worker       dump_reg(
951*61046927SAndroid Build Coastguard Worker          out, "pos (ij_centroid)",
952*61046927SAndroid Build Coastguard Worker          ir3_find_sysval_regid(so, SYSTEM_VALUE_BARYCENTRIC_PERSP_CENTROID));
953*61046927SAndroid Build Coastguard Worker       dump_reg(out, "pos (center_rhw)",
954*61046927SAndroid Build Coastguard Worker                ir3_find_sysval_regid(so, SYSTEM_VALUE_BARYCENTRIC_PERSP_CENTER_RHW));
955*61046927SAndroid Build Coastguard Worker       dump_output(out, so, FRAG_RESULT_DEPTH, "posz");
956*61046927SAndroid Build Coastguard Worker       if (so->color0_mrt) {
957*61046927SAndroid Build Coastguard Worker          dump_output(out, so, FRAG_RESULT_COLOR, "color");
958*61046927SAndroid Build Coastguard Worker       } else {
959*61046927SAndroid Build Coastguard Worker          dump_output(out, so, FRAG_RESULT_DATA0, "data0");
960*61046927SAndroid Build Coastguard Worker          dump_output(out, so, FRAG_RESULT_DATA1, "data1");
961*61046927SAndroid Build Coastguard Worker          dump_output(out, so, FRAG_RESULT_DATA2, "data2");
962*61046927SAndroid Build Coastguard Worker          dump_output(out, so, FRAG_RESULT_DATA3, "data3");
963*61046927SAndroid Build Coastguard Worker          dump_output(out, so, FRAG_RESULT_DATA4, "data4");
964*61046927SAndroid Build Coastguard Worker          dump_output(out, so, FRAG_RESULT_DATA5, "data5");
965*61046927SAndroid Build Coastguard Worker          dump_output(out, so, FRAG_RESULT_DATA6, "data6");
966*61046927SAndroid Build Coastguard Worker          dump_output(out, so, FRAG_RESULT_DATA7, "data7");
967*61046927SAndroid Build Coastguard Worker       }
968*61046927SAndroid Build Coastguard Worker       dump_reg(out, "fragcoord",
969*61046927SAndroid Build Coastguard Worker                ir3_find_sysval_regid(so, SYSTEM_VALUE_FRAG_COORD));
970*61046927SAndroid Build Coastguard Worker       dump_reg(out, "fragface",
971*61046927SAndroid Build Coastguard Worker                ir3_find_sysval_regid(so, SYSTEM_VALUE_FRONT_FACE));
972*61046927SAndroid Build Coastguard Worker       break;
973*61046927SAndroid Build Coastguard Worker    default:
974*61046927SAndroid Build Coastguard Worker       /* TODO */
975*61046927SAndroid Build Coastguard Worker       break;
976*61046927SAndroid Build Coastguard Worker    }
977*61046927SAndroid Build Coastguard Worker 
978*61046927SAndroid Build Coastguard Worker    fprintf(out, "\n");
979*61046927SAndroid Build Coastguard Worker }
980*61046927SAndroid Build Coastguard Worker 
981*61046927SAndroid Build Coastguard Worker uint64_t
ir3_shader_outputs(const struct ir3_shader * so)982*61046927SAndroid Build Coastguard Worker ir3_shader_outputs(const struct ir3_shader *so)
983*61046927SAndroid Build Coastguard Worker {
984*61046927SAndroid Build Coastguard Worker    return so->nir->info.outputs_written;
985*61046927SAndroid Build Coastguard Worker }
986*61046927SAndroid Build Coastguard Worker 
987*61046927SAndroid Build Coastguard Worker /* Add any missing varyings needed for stream-out.  Otherwise varyings not
988*61046927SAndroid Build Coastguard Worker  * used by fragment shader will be stripped out.
989*61046927SAndroid Build Coastguard Worker  */
990*61046927SAndroid Build Coastguard Worker void
ir3_link_stream_out(struct ir3_shader_linkage * l,const struct ir3_shader_variant * v)991*61046927SAndroid Build Coastguard Worker ir3_link_stream_out(struct ir3_shader_linkage *l,
992*61046927SAndroid Build Coastguard Worker                     const struct ir3_shader_variant *v)
993*61046927SAndroid Build Coastguard Worker {
994*61046927SAndroid Build Coastguard Worker    const struct ir3_stream_output_info *strmout = &v->stream_output;
995*61046927SAndroid Build Coastguard Worker 
996*61046927SAndroid Build Coastguard Worker    /*
997*61046927SAndroid Build Coastguard Worker     * First, any stream-out varyings not already in linkage map (ie. also
998*61046927SAndroid Build Coastguard Worker     * consumed by frag shader) need to be added:
999*61046927SAndroid Build Coastguard Worker     */
1000*61046927SAndroid Build Coastguard Worker    for (unsigned i = 0; i < strmout->num_outputs; i++) {
1001*61046927SAndroid Build Coastguard Worker       const struct ir3_stream_output *out = &strmout->output[i];
1002*61046927SAndroid Build Coastguard Worker       unsigned k = out->register_index;
1003*61046927SAndroid Build Coastguard Worker       unsigned compmask =
1004*61046927SAndroid Build Coastguard Worker          (1 << (out->num_components + out->start_component)) - 1;
1005*61046927SAndroid Build Coastguard Worker       unsigned idx, nextloc = 0;
1006*61046927SAndroid Build Coastguard Worker 
1007*61046927SAndroid Build Coastguard Worker       /* psize/pos need to be the last entries in linkage map, and will
1008*61046927SAndroid Build Coastguard Worker        * get added link_stream_out, so skip over them:
1009*61046927SAndroid Build Coastguard Worker        */
1010*61046927SAndroid Build Coastguard Worker       if ((v->outputs[k].slot == VARYING_SLOT_PSIZ) ||
1011*61046927SAndroid Build Coastguard Worker           (v->outputs[k].slot == VARYING_SLOT_POS))
1012*61046927SAndroid Build Coastguard Worker          continue;
1013*61046927SAndroid Build Coastguard Worker 
1014*61046927SAndroid Build Coastguard Worker       for (idx = 0; idx < l->cnt; idx++) {
1015*61046927SAndroid Build Coastguard Worker          if (l->var[idx].slot == v->outputs[k].slot)
1016*61046927SAndroid Build Coastguard Worker             break;
1017*61046927SAndroid Build Coastguard Worker          nextloc = MAX2(nextloc, l->var[idx].loc + 4);
1018*61046927SAndroid Build Coastguard Worker       }
1019*61046927SAndroid Build Coastguard Worker 
1020*61046927SAndroid Build Coastguard Worker       /* add if not already in linkage map: */
1021*61046927SAndroid Build Coastguard Worker       if (idx == l->cnt) {
1022*61046927SAndroid Build Coastguard Worker          ir3_link_add(l, v->outputs[k].slot, v->outputs[k].regid,
1023*61046927SAndroid Build Coastguard Worker                       compmask, nextloc);
1024*61046927SAndroid Build Coastguard Worker       }
1025*61046927SAndroid Build Coastguard Worker 
1026*61046927SAndroid Build Coastguard Worker       /* expand component-mask if needed, ie streaming out all components
1027*61046927SAndroid Build Coastguard Worker        * but frag shader doesn't consume all components:
1028*61046927SAndroid Build Coastguard Worker        */
1029*61046927SAndroid Build Coastguard Worker       if (compmask & ~l->var[idx].compmask) {
1030*61046927SAndroid Build Coastguard Worker          l->var[idx].compmask |= compmask;
1031*61046927SAndroid Build Coastguard Worker          l->max_loc = MAX2(
1032*61046927SAndroid Build Coastguard Worker             l->max_loc, l->var[idx].loc + util_last_bit(l->var[idx].compmask));
1033*61046927SAndroid Build Coastguard Worker       }
1034*61046927SAndroid Build Coastguard Worker    }
1035*61046927SAndroid Build Coastguard Worker }
1036