xref: /aosp_15_r20/external/mesa3d/src/freedreno/ir3/ir3_context.h (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker  * Copyright © 2015-2018 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 #ifndef IR3_CONTEXT_H_
10*61046927SAndroid Build Coastguard Worker #define IR3_CONTEXT_H_
11*61046927SAndroid Build Coastguard Worker 
12*61046927SAndroid Build Coastguard Worker #include "ir3.h"
13*61046927SAndroid Build Coastguard Worker #include "ir3_compiler.h"
14*61046927SAndroid Build Coastguard Worker #include "ir3_nir.h"
15*61046927SAndroid Build Coastguard Worker 
16*61046927SAndroid Build Coastguard Worker /* for conditionally setting boolean flag(s): */
17*61046927SAndroid Build Coastguard Worker #define COND(bool, val) ((bool) ? (val) : 0)
18*61046927SAndroid Build Coastguard Worker 
19*61046927SAndroid Build Coastguard Worker #define DBG(fmt, ...)                                                          \
20*61046927SAndroid Build Coastguard Worker    do {                                                                        \
21*61046927SAndroid Build Coastguard Worker       mesa_logd("%s:%d: " fmt, __func__, __LINE__, ##__VA_ARGS__);             \
22*61046927SAndroid Build Coastguard Worker    } while (0)
23*61046927SAndroid Build Coastguard Worker 
24*61046927SAndroid Build Coastguard Worker /**
25*61046927SAndroid Build Coastguard Worker  * The context for compilation of a single shader.
26*61046927SAndroid Build Coastguard Worker  */
27*61046927SAndroid Build Coastguard Worker struct ir3_context {
28*61046927SAndroid Build Coastguard Worker    struct ir3_compiler *compiler;
29*61046927SAndroid Build Coastguard Worker    const struct ir3_context_funcs *funcs;
30*61046927SAndroid Build Coastguard Worker 
31*61046927SAndroid Build Coastguard Worker    struct nir_shader *s;
32*61046927SAndroid Build Coastguard Worker 
33*61046927SAndroid Build Coastguard Worker    struct nir_instr *cur_instr; /* current instruction, just for debug */
34*61046927SAndroid Build Coastguard Worker 
35*61046927SAndroid Build Coastguard Worker    struct ir3 *ir;
36*61046927SAndroid Build Coastguard Worker    struct ir3_shader_variant *so;
37*61046927SAndroid Build Coastguard Worker 
38*61046927SAndroid Build Coastguard Worker    /* Tables of scalar inputs/outputs.  Because of the way varying packing
39*61046927SAndroid Build Coastguard Worker     * works, we could have inputs w/ fractional location, which is a bit
40*61046927SAndroid Build Coastguard Worker     * awkward to deal with unless we keep track of the split scalar in/
41*61046927SAndroid Build Coastguard Worker     * out components.
42*61046927SAndroid Build Coastguard Worker     *
43*61046927SAndroid Build Coastguard Worker     * These *only* have inputs/outputs that are touched by load_*input and
44*61046927SAndroid Build Coastguard Worker     * store_output.
45*61046927SAndroid Build Coastguard Worker     */
46*61046927SAndroid Build Coastguard Worker    unsigned ninputs, noutputs;
47*61046927SAndroid Build Coastguard Worker    struct ir3_instruction **inputs;
48*61046927SAndroid Build Coastguard Worker    struct ir3_instruction **outputs;
49*61046927SAndroid Build Coastguard Worker 
50*61046927SAndroid Build Coastguard Worker    struct ir3_block *block;    /* the current block */
51*61046927SAndroid Build Coastguard Worker    struct ir3_block *in_block; /* block created for shader inputs */
52*61046927SAndroid Build Coastguard Worker 
53*61046927SAndroid Build Coastguard Worker    nir_function_impl *impl;
54*61046927SAndroid Build Coastguard Worker 
55*61046927SAndroid Build Coastguard Worker    /* For fragment shaders, varyings are not actual shader inputs,
56*61046927SAndroid Build Coastguard Worker     * instead the hw passes a ij coord which is used with
57*61046927SAndroid Build Coastguard Worker     * bary.f.
58*61046927SAndroid Build Coastguard Worker     *
59*61046927SAndroid Build Coastguard Worker     * But NIR doesn't know that, it still declares varyings as
60*61046927SAndroid Build Coastguard Worker     * inputs.  So we do all the input tracking normally and fix
61*61046927SAndroid Build Coastguard Worker     * things up after compile_instructions()
62*61046927SAndroid Build Coastguard Worker     */
63*61046927SAndroid Build Coastguard Worker    struct ir3_instruction *ij[IJ_COUNT];
64*61046927SAndroid Build Coastguard Worker 
65*61046927SAndroid Build Coastguard Worker    /* for fragment shaders, for gl_FrontFacing and gl_FragCoord: */
66*61046927SAndroid Build Coastguard Worker    struct ir3_instruction *frag_face, *frag_coord;
67*61046927SAndroid Build Coastguard Worker 
68*61046927SAndroid Build Coastguard Worker    /* For vertex shaders, keep track of the system values sources */
69*61046927SAndroid Build Coastguard Worker    struct ir3_instruction *vertex_id, *basevertex, *instance_id, *base_instance,
70*61046927SAndroid Build Coastguard Worker       *draw_id, *view_index, *is_indexed_draw;
71*61046927SAndroid Build Coastguard Worker 
72*61046927SAndroid Build Coastguard Worker    /* For fragment shaders: */
73*61046927SAndroid Build Coastguard Worker    struct ir3_instruction *samp_id, *samp_mask_in;
74*61046927SAndroid Build Coastguard Worker 
75*61046927SAndroid Build Coastguard Worker    /* For geometry shaders: */
76*61046927SAndroid Build Coastguard Worker    struct ir3_instruction *primitive_id;
77*61046927SAndroid Build Coastguard Worker    struct ir3_instruction *gs_header;
78*61046927SAndroid Build Coastguard Worker 
79*61046927SAndroid Build Coastguard Worker    /* For tessellation shaders: */
80*61046927SAndroid Build Coastguard Worker    struct ir3_instruction *tcs_header;
81*61046927SAndroid Build Coastguard Worker    struct ir3_instruction *tess_coord;
82*61046927SAndroid Build Coastguard Worker    struct ir3_instruction *rel_patch_id;
83*61046927SAndroid Build Coastguard Worker 
84*61046927SAndroid Build Coastguard Worker    /* Compute shader inputs: */
85*61046927SAndroid Build Coastguard Worker    struct ir3_instruction *local_invocation_id, *work_group_id;
86*61046927SAndroid Build Coastguard Worker 
87*61046927SAndroid Build Coastguard Worker    /* mapping from nir_register to defining instruction: */
88*61046927SAndroid Build Coastguard Worker    struct hash_table *def_ht;
89*61046927SAndroid Build Coastguard Worker 
90*61046927SAndroid Build Coastguard Worker    unsigned num_arrays;
91*61046927SAndroid Build Coastguard Worker 
92*61046927SAndroid Build Coastguard Worker    unsigned loop_depth;
93*61046927SAndroid Build Coastguard Worker 
94*61046927SAndroid Build Coastguard Worker    /* a common pattern for indirect addressing is to request the
95*61046927SAndroid Build Coastguard Worker     * same address register multiple times.  To avoid generating
96*61046927SAndroid Build Coastguard Worker     * duplicate instruction sequences (which our backend does not
97*61046927SAndroid Build Coastguard Worker     * try to clean up, since that should be done as the NIR stage)
98*61046927SAndroid Build Coastguard Worker     * we cache the address value generated for a given src value:
99*61046927SAndroid Build Coastguard Worker     *
100*61046927SAndroid Build Coastguard Worker     * Note that we have to cache these per alignment, since same
101*61046927SAndroid Build Coastguard Worker     * src used for an array of vec1 cannot be also used for an
102*61046927SAndroid Build Coastguard Worker     * array of vec4.
103*61046927SAndroid Build Coastguard Worker     */
104*61046927SAndroid Build Coastguard Worker    struct hash_table *addr0_ht[4];
105*61046927SAndroid Build Coastguard Worker 
106*61046927SAndroid Build Coastguard Worker    /* The same for a1.x. We only support immediate values for a1.x, as this
107*61046927SAndroid Build Coastguard Worker     * is the only use so far.
108*61046927SAndroid Build Coastguard Worker     */
109*61046927SAndroid Build Coastguard Worker    struct hash_table_u64 *addr1_ht;
110*61046927SAndroid Build Coastguard Worker 
111*61046927SAndroid Build Coastguard Worker    struct hash_table *sel_cond_conversions;
112*61046927SAndroid Build Coastguard Worker    struct hash_table *predicate_conversions;
113*61046927SAndroid Build Coastguard Worker 
114*61046927SAndroid Build Coastguard Worker    /* last dst array, for indirect we need to insert a var-store.
115*61046927SAndroid Build Coastguard Worker     */
116*61046927SAndroid Build Coastguard Worker    struct ir3_instruction **last_dst;
117*61046927SAndroid Build Coastguard Worker    unsigned last_dst_n;
118*61046927SAndroid Build Coastguard Worker 
119*61046927SAndroid Build Coastguard Worker    /* maps nir_block to ir3_block, mostly for the purposes of
120*61046927SAndroid Build Coastguard Worker     * figuring out the blocks successors
121*61046927SAndroid Build Coastguard Worker     */
122*61046927SAndroid Build Coastguard Worker    struct hash_table *block_ht;
123*61046927SAndroid Build Coastguard Worker 
124*61046927SAndroid Build Coastguard Worker    /* maps nir_block at the top of a loop to ir3_block collecting continue
125*61046927SAndroid Build Coastguard Worker     * edges.
126*61046927SAndroid Build Coastguard Worker     */
127*61046927SAndroid Build Coastguard Worker    struct hash_table *continue_block_ht;
128*61046927SAndroid Build Coastguard Worker 
129*61046927SAndroid Build Coastguard Worker    /* on a4xx, bitmask of samplers which need astc+srgb workaround: */
130*61046927SAndroid Build Coastguard Worker    unsigned astc_srgb;
131*61046927SAndroid Build Coastguard Worker 
132*61046927SAndroid Build Coastguard Worker    /* on a4xx, per-sampler per-component swizzles, for tg4: */
133*61046927SAndroid Build Coastguard Worker    uint16_t sampler_swizzles[16];
134*61046927SAndroid Build Coastguard Worker 
135*61046927SAndroid Build Coastguard Worker    unsigned samples; /* bitmask of x,y sample shifts */
136*61046927SAndroid Build Coastguard Worker 
137*61046927SAndroid Build Coastguard Worker    unsigned max_texture_index;
138*61046927SAndroid Build Coastguard Worker 
139*61046927SAndroid Build Coastguard Worker    unsigned prefetch_limit;
140*61046927SAndroid Build Coastguard Worker 
141*61046927SAndroid Build Coastguard Worker    /* set if we encounter something we can't handle yet, so we
142*61046927SAndroid Build Coastguard Worker     * can bail cleanly and fallback to TGSI compiler f/e
143*61046927SAndroid Build Coastguard Worker     */
144*61046927SAndroid Build Coastguard Worker    bool error;
145*61046927SAndroid Build Coastguard Worker };
146*61046927SAndroid Build Coastguard Worker 
147*61046927SAndroid Build Coastguard Worker struct ir3_context_funcs {
148*61046927SAndroid Build Coastguard Worker    void (*emit_intrinsic_load_ssbo)(struct ir3_context *ctx,
149*61046927SAndroid Build Coastguard Worker                                     nir_intrinsic_instr *intr,
150*61046927SAndroid Build Coastguard Worker                                     struct ir3_instruction **dst);
151*61046927SAndroid Build Coastguard Worker    void (*emit_intrinsic_store_ssbo)(struct ir3_context *ctx,
152*61046927SAndroid Build Coastguard Worker                                      nir_intrinsic_instr *intr);
153*61046927SAndroid Build Coastguard Worker    struct ir3_instruction *(*emit_intrinsic_atomic_ssbo)(
154*61046927SAndroid Build Coastguard Worker       struct ir3_context *ctx, nir_intrinsic_instr *intr);
155*61046927SAndroid Build Coastguard Worker    void (*emit_intrinsic_load_image)(struct ir3_context *ctx,
156*61046927SAndroid Build Coastguard Worker                                      nir_intrinsic_instr *intr,
157*61046927SAndroid Build Coastguard Worker                                      struct ir3_instruction **dst);
158*61046927SAndroid Build Coastguard Worker    void (*emit_intrinsic_store_image)(struct ir3_context *ctx,
159*61046927SAndroid Build Coastguard Worker                                       nir_intrinsic_instr *intr);
160*61046927SAndroid Build Coastguard Worker    struct ir3_instruction *(*emit_intrinsic_atomic_image)(
161*61046927SAndroid Build Coastguard Worker       struct ir3_context *ctx, nir_intrinsic_instr *intr);
162*61046927SAndroid Build Coastguard Worker    void (*emit_intrinsic_image_size)(struct ir3_context *ctx,
163*61046927SAndroid Build Coastguard Worker                                      nir_intrinsic_instr *intr,
164*61046927SAndroid Build Coastguard Worker                                      struct ir3_instruction **dst);
165*61046927SAndroid Build Coastguard Worker    void (*emit_intrinsic_load_global_ir3)(struct ir3_context *ctx,
166*61046927SAndroid Build Coastguard Worker                                           nir_intrinsic_instr *intr,
167*61046927SAndroid Build Coastguard Worker                                           struct ir3_instruction **dst);
168*61046927SAndroid Build Coastguard Worker    void (*emit_intrinsic_store_global_ir3)(struct ir3_context *ctx,
169*61046927SAndroid Build Coastguard Worker                                            nir_intrinsic_instr *intr);
170*61046927SAndroid Build Coastguard Worker    struct ir3_instruction *(*emit_intrinsic_atomic_global)(
171*61046927SAndroid Build Coastguard Worker       struct ir3_context *ctx, nir_intrinsic_instr *intr);
172*61046927SAndroid Build Coastguard Worker };
173*61046927SAndroid Build Coastguard Worker 
174*61046927SAndroid Build Coastguard Worker extern const struct ir3_context_funcs ir3_a4xx_funcs;
175*61046927SAndroid Build Coastguard Worker extern const struct ir3_context_funcs ir3_a6xx_funcs;
176*61046927SAndroid Build Coastguard Worker 
177*61046927SAndroid Build Coastguard Worker struct ir3_context *ir3_context_init(struct ir3_compiler *compiler,
178*61046927SAndroid Build Coastguard Worker                                      struct ir3_shader *shader,
179*61046927SAndroid Build Coastguard Worker                                      struct ir3_shader_variant *so);
180*61046927SAndroid Build Coastguard Worker void ir3_context_free(struct ir3_context *ctx);
181*61046927SAndroid Build Coastguard Worker 
182*61046927SAndroid Build Coastguard Worker struct ir3_instruction **ir3_get_dst_ssa(struct ir3_context *ctx,
183*61046927SAndroid Build Coastguard Worker                                          nir_def *dst, unsigned n);
184*61046927SAndroid Build Coastguard Worker struct ir3_instruction **ir3_get_def(struct ir3_context *ctx, nir_def *def,
185*61046927SAndroid Build Coastguard Worker                                      unsigned n);
186*61046927SAndroid Build Coastguard Worker struct ir3_instruction *const *ir3_get_src_maybe_shared(struct ir3_context *ctx,
187*61046927SAndroid Build Coastguard Worker                                                         nir_src *src);
188*61046927SAndroid Build Coastguard Worker struct ir3_instruction *const *ir3_get_src_shared(struct ir3_context *ctx,
189*61046927SAndroid Build Coastguard Worker                                                   nir_src *src, bool shared);
190*61046927SAndroid Build Coastguard Worker 
191*61046927SAndroid Build Coastguard Worker static inline struct ir3_instruction *const *
ir3_get_src(struct ir3_context * ctx,nir_src * src)192*61046927SAndroid Build Coastguard Worker ir3_get_src(struct ir3_context *ctx, nir_src *src)
193*61046927SAndroid Build Coastguard Worker {
194*61046927SAndroid Build Coastguard Worker    return ir3_get_src_shared(ctx, src, false);
195*61046927SAndroid Build Coastguard Worker }
196*61046927SAndroid Build Coastguard Worker 
197*61046927SAndroid Build Coastguard Worker void ir3_put_def(struct ir3_context *ctx, nir_def *def);
198*61046927SAndroid Build Coastguard Worker struct ir3_instruction *ir3_create_collect(struct ir3_block *block,
199*61046927SAndroid Build Coastguard Worker                                            struct ir3_instruction *const *arr,
200*61046927SAndroid Build Coastguard Worker                                            unsigned arrsz);
201*61046927SAndroid Build Coastguard Worker void ir3_split_dest(struct ir3_block *block, struct ir3_instruction **dst,
202*61046927SAndroid Build Coastguard Worker                     struct ir3_instruction *src, unsigned base, unsigned n);
203*61046927SAndroid Build Coastguard Worker void ir3_handle_bindless_cat6(struct ir3_instruction *instr, nir_src rsrc);
204*61046927SAndroid Build Coastguard Worker void ir3_handle_nonuniform(struct ir3_instruction *instr,
205*61046927SAndroid Build Coastguard Worker                            nir_intrinsic_instr *intrin);
206*61046927SAndroid Build Coastguard Worker void emit_intrinsic_image_size_tex(struct ir3_context *ctx,
207*61046927SAndroid Build Coastguard Worker                                    nir_intrinsic_instr *intr,
208*61046927SAndroid Build Coastguard Worker                                    struct ir3_instruction **dst);
209*61046927SAndroid Build Coastguard Worker 
210*61046927SAndroid Build Coastguard Worker #define ir3_collect(block, ...)                                                \
211*61046927SAndroid Build Coastguard Worker    ({                                                                          \
212*61046927SAndroid Build Coastguard Worker       struct ir3_instruction *__arr[] = {__VA_ARGS__};                         \
213*61046927SAndroid Build Coastguard Worker       ir3_create_collect(block, __arr, ARRAY_SIZE(__arr));                     \
214*61046927SAndroid Build Coastguard Worker    })
215*61046927SAndroid Build Coastguard Worker 
216*61046927SAndroid Build Coastguard Worker NORETURN void ir3_context_error(struct ir3_context *ctx, const char *format,
217*61046927SAndroid Build Coastguard Worker                                 ...);
218*61046927SAndroid Build Coastguard Worker 
219*61046927SAndroid Build Coastguard Worker #define compile_assert(ctx, cond)                                              \
220*61046927SAndroid Build Coastguard Worker    do {                                                                        \
221*61046927SAndroid Build Coastguard Worker       if (!(cond))                                                             \
222*61046927SAndroid Build Coastguard Worker          ir3_context_error((ctx), "failed assert: " #cond "\n");               \
223*61046927SAndroid Build Coastguard Worker    } while (0)
224*61046927SAndroid Build Coastguard Worker 
225*61046927SAndroid Build Coastguard Worker struct ir3_instruction *ir3_get_addr0(struct ir3_context *ctx,
226*61046927SAndroid Build Coastguard Worker                                       struct ir3_instruction *src, int align);
227*61046927SAndroid Build Coastguard Worker struct ir3_instruction *ir3_get_addr1(struct ir3_context *ctx,
228*61046927SAndroid Build Coastguard Worker                                       unsigned const_val);
229*61046927SAndroid Build Coastguard Worker struct ir3_instruction *ir3_get_predicate(struct ir3_context *ctx,
230*61046927SAndroid Build Coastguard Worker                                           struct ir3_instruction *src);
231*61046927SAndroid Build Coastguard Worker 
232*61046927SAndroid Build Coastguard Worker void ir3_declare_array(struct ir3_context *ctx, nir_intrinsic_instr *decl);
233*61046927SAndroid Build Coastguard Worker struct ir3_array *ir3_get_array(struct ir3_context *ctx, nir_def *reg);
234*61046927SAndroid Build Coastguard Worker struct ir3_instruction *ir3_create_array_load(struct ir3_context *ctx,
235*61046927SAndroid Build Coastguard Worker                                               struct ir3_array *arr, int n,
236*61046927SAndroid Build Coastguard Worker                                               struct ir3_instruction *address);
237*61046927SAndroid Build Coastguard Worker void ir3_create_array_store(struct ir3_context *ctx, struct ir3_array *arr,
238*61046927SAndroid Build Coastguard Worker                             int n, struct ir3_instruction *src,
239*61046927SAndroid Build Coastguard Worker                             struct ir3_instruction *address);
240*61046927SAndroid Build Coastguard Worker void ir3_lower_imm_offset(struct ir3_context *ctx, nir_intrinsic_instr *intr,
241*61046927SAndroid Build Coastguard Worker                           nir_src *offset_src, unsigned imm_offset_bits,
242*61046927SAndroid Build Coastguard Worker                           struct ir3_instruction **offset,
243*61046927SAndroid Build Coastguard Worker                           unsigned *imm_offset);
244*61046927SAndroid Build Coastguard Worker 
245*61046927SAndroid Build Coastguard Worker static inline type_t
utype_for_size(unsigned bit_size)246*61046927SAndroid Build Coastguard Worker utype_for_size(unsigned bit_size)
247*61046927SAndroid Build Coastguard Worker {
248*61046927SAndroid Build Coastguard Worker    switch (bit_size) {
249*61046927SAndroid Build Coastguard Worker    case 32:
250*61046927SAndroid Build Coastguard Worker       return TYPE_U32;
251*61046927SAndroid Build Coastguard Worker    case 16:
252*61046927SAndroid Build Coastguard Worker       return TYPE_U16;
253*61046927SAndroid Build Coastguard Worker    case 8:
254*61046927SAndroid Build Coastguard Worker       return TYPE_U8;
255*61046927SAndroid Build Coastguard Worker    default:
256*61046927SAndroid Build Coastguard Worker       unreachable("bad bitsize");
257*61046927SAndroid Build Coastguard Worker       return ~0;
258*61046927SAndroid Build Coastguard Worker    }
259*61046927SAndroid Build Coastguard Worker }
260*61046927SAndroid Build Coastguard Worker 
261*61046927SAndroid Build Coastguard Worker static inline type_t
utype_src(nir_src src)262*61046927SAndroid Build Coastguard Worker utype_src(nir_src src)
263*61046927SAndroid Build Coastguard Worker {
264*61046927SAndroid Build Coastguard Worker    return utype_for_size(nir_src_bit_size(src));
265*61046927SAndroid Build Coastguard Worker }
266*61046927SAndroid Build Coastguard Worker 
267*61046927SAndroid Build Coastguard Worker static inline type_t
utype_def(nir_def * def)268*61046927SAndroid Build Coastguard Worker utype_def(nir_def *def)
269*61046927SAndroid Build Coastguard Worker {
270*61046927SAndroid Build Coastguard Worker    return utype_for_size(def->bit_size);
271*61046927SAndroid Build Coastguard Worker }
272*61046927SAndroid Build Coastguard Worker 
273*61046927SAndroid Build Coastguard Worker /**
274*61046927SAndroid Build Coastguard Worker  * Convert nir bitsize to ir3 bitsize, handling the special case of 1b bools
275*61046927SAndroid Build Coastguard Worker  * which can be 16b or 32b depending on gen.
276*61046927SAndroid Build Coastguard Worker  */
277*61046927SAndroid Build Coastguard Worker static inline unsigned
ir3_bitsize(struct ir3_context * ctx,unsigned nir_bitsize)278*61046927SAndroid Build Coastguard Worker ir3_bitsize(struct ir3_context *ctx, unsigned nir_bitsize)
279*61046927SAndroid Build Coastguard Worker {
280*61046927SAndroid Build Coastguard Worker    if (nir_bitsize == 1)
281*61046927SAndroid Build Coastguard Worker       return type_size(ctx->compiler->bool_type);
282*61046927SAndroid Build Coastguard Worker    return nir_bitsize;
283*61046927SAndroid Build Coastguard Worker }
284*61046927SAndroid Build Coastguard Worker 
285*61046927SAndroid Build Coastguard Worker #endif /* IR3_CONTEXT_H_ */
286