xref: /aosp_15_r20/external/mesa3d/src/panfrost/util/pan_ir.h (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker  * Copyright (C) 2020 Collabora, Ltd.
3*61046927SAndroid Build Coastguard Worker  *
4*61046927SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a
5*61046927SAndroid Build Coastguard Worker  * copy of this software and associated documentation files (the "Software"),
6*61046927SAndroid Build Coastguard Worker  * to deal in the Software without restriction, including without limitation
7*61046927SAndroid Build Coastguard Worker  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*61046927SAndroid Build Coastguard Worker  * and/or sell copies of the Software, and to permit persons to whom the
9*61046927SAndroid Build Coastguard Worker  * Software is furnished to do so, subject to the following conditions:
10*61046927SAndroid Build Coastguard Worker  *
11*61046927SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice (including the next
12*61046927SAndroid Build Coastguard Worker  * paragraph) shall be included in all copies or substantial portions of the
13*61046927SAndroid Build Coastguard Worker  * Software.
14*61046927SAndroid Build Coastguard Worker  *
15*61046927SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*61046927SAndroid Build Coastguard Worker  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*61046927SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18*61046927SAndroid Build Coastguard Worker  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*61046927SAndroid Build Coastguard Worker  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20*61046927SAndroid Build Coastguard Worker  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21*61046927SAndroid Build Coastguard Worker  * SOFTWARE.
22*61046927SAndroid Build Coastguard Worker  */
23*61046927SAndroid Build Coastguard Worker 
24*61046927SAndroid Build Coastguard Worker #ifndef __PAN_IR_H
25*61046927SAndroid Build Coastguard Worker #define __PAN_IR_H
26*61046927SAndroid Build Coastguard Worker 
27*61046927SAndroid Build Coastguard Worker #include <stdint.h>
28*61046927SAndroid Build Coastguard Worker #include "compiler/nir/nir.h"
29*61046927SAndroid Build Coastguard Worker #include "util/hash_table.h"
30*61046927SAndroid Build Coastguard Worker #include "util/u_dynarray.h"
31*61046927SAndroid Build Coastguard Worker 
32*61046927SAndroid Build Coastguard Worker /* Indices for named (non-XFB) varyings that are present. These are packed
33*61046927SAndroid Build Coastguard Worker  * tightly so they correspond to a bitfield present (P) indexed by (1 <<
34*61046927SAndroid Build Coastguard Worker  * PAN_VARY_*). This has the nice property that you can lookup the buffer index
35*61046927SAndroid Build Coastguard Worker  * of a given special field given a shift S by:
36*61046927SAndroid Build Coastguard Worker  *
37*61046927SAndroid Build Coastguard Worker  *      idx = popcount(P & ((1 << S) - 1))
38*61046927SAndroid Build Coastguard Worker  *
39*61046927SAndroid Build Coastguard Worker  * That is... look at all of the varyings that come earlier and count them, the
40*61046927SAndroid Build Coastguard Worker  * count is the new index since plus one. Likewise, the total number of special
41*61046927SAndroid Build Coastguard Worker  * buffers required is simply popcount(P)
42*61046927SAndroid Build Coastguard Worker  */
43*61046927SAndroid Build Coastguard Worker 
44*61046927SAndroid Build Coastguard Worker enum pan_special_varying {
45*61046927SAndroid Build Coastguard Worker    PAN_VARY_GENERAL = 0,
46*61046927SAndroid Build Coastguard Worker    PAN_VARY_POSITION = 1,
47*61046927SAndroid Build Coastguard Worker    PAN_VARY_PSIZ = 2,
48*61046927SAndroid Build Coastguard Worker    PAN_VARY_PNTCOORD = 3,
49*61046927SAndroid Build Coastguard Worker    PAN_VARY_FACE = 4,
50*61046927SAndroid Build Coastguard Worker    PAN_VARY_FRAGCOORD = 5,
51*61046927SAndroid Build Coastguard Worker 
52*61046927SAndroid Build Coastguard Worker    /* Keep last */
53*61046927SAndroid Build Coastguard Worker    PAN_VARY_MAX,
54*61046927SAndroid Build Coastguard Worker };
55*61046927SAndroid Build Coastguard Worker 
56*61046927SAndroid Build Coastguard Worker /* Maximum number of attribute descriptors required for varyings. These include
57*61046927SAndroid Build Coastguard Worker  * up to MAX_VARYING source level varyings plus a descriptor each non-GENERAL
58*61046927SAndroid Build Coastguard Worker  * special varying */
59*61046927SAndroid Build Coastguard Worker #define PAN_MAX_VARYINGS (MAX_VARYING + PAN_VARY_MAX - 1)
60*61046927SAndroid Build Coastguard Worker 
61*61046927SAndroid Build Coastguard Worker /* Special attribute slots for vertex builtins. Sort of arbitrary but let's be
62*61046927SAndroid Build Coastguard Worker  * consistent with the blob so we can compare traces easier. */
63*61046927SAndroid Build Coastguard Worker 
64*61046927SAndroid Build Coastguard Worker enum { PAN_VERTEX_ID = 16, PAN_INSTANCE_ID = 17, PAN_MAX_ATTRIBUTE };
65*61046927SAndroid Build Coastguard Worker 
66*61046927SAndroid Build Coastguard Worker /* Architecturally, Bifrost/Valhall can address 128 FAU slots of 64-bits each.
67*61046927SAndroid Build Coastguard Worker  * In practice, the maximum number of FAU slots is limited by implementation.
68*61046927SAndroid Build Coastguard Worker  * All known Bifrost and Valhall devices limit to 64 FAU slots. Therefore the
69*61046927SAndroid Build Coastguard Worker  * maximum number of 32-bit words is 128, since there are 2 words per FAU slot.
70*61046927SAndroid Build Coastguard Worker  *
71*61046927SAndroid Build Coastguard Worker  * Midgard can push at most 92 words, so this bound suffices. The Midgard
72*61046927SAndroid Build Coastguard Worker  * compiler pushes less than this, as Midgard uses register-mapped uniforms
73*61046927SAndroid Build Coastguard Worker  * instead of FAU, preventing large numbers of uniforms to be pushed for
74*61046927SAndroid Build Coastguard Worker  * nontrivial programs.
75*61046927SAndroid Build Coastguard Worker  */
76*61046927SAndroid Build Coastguard Worker #define PAN_MAX_PUSH 128
77*61046927SAndroid Build Coastguard Worker 
78*61046927SAndroid Build Coastguard Worker /* Architectural invariants (Midgard and Bifrost): UBO must be <= 2^16 bytes so
79*61046927SAndroid Build Coastguard Worker  * an offset to a word must be < 2^16. There are less than 2^8 UBOs */
80*61046927SAndroid Build Coastguard Worker 
81*61046927SAndroid Build Coastguard Worker struct panfrost_ubo_word {
82*61046927SAndroid Build Coastguard Worker    uint16_t ubo;
83*61046927SAndroid Build Coastguard Worker    uint16_t offset;
84*61046927SAndroid Build Coastguard Worker };
85*61046927SAndroid Build Coastguard Worker 
86*61046927SAndroid Build Coastguard Worker struct panfrost_ubo_push {
87*61046927SAndroid Build Coastguard Worker    unsigned count;
88*61046927SAndroid Build Coastguard Worker    struct panfrost_ubo_word words[PAN_MAX_PUSH];
89*61046927SAndroid Build Coastguard Worker };
90*61046927SAndroid Build Coastguard Worker 
91*61046927SAndroid Build Coastguard Worker /* Helper for searching the above. Note this is O(N) to the number of pushed
92*61046927SAndroid Build Coastguard Worker  * constants, do not run in the draw call hot path */
93*61046927SAndroid Build Coastguard Worker 
94*61046927SAndroid Build Coastguard Worker unsigned pan_lookup_pushed_ubo(struct panfrost_ubo_push *push, unsigned ubo,
95*61046927SAndroid Build Coastguard Worker                                unsigned offs);
96*61046927SAndroid Build Coastguard Worker 
97*61046927SAndroid Build Coastguard Worker struct panfrost_compile_inputs {
98*61046927SAndroid Build Coastguard Worker    struct util_debug_callback *debug;
99*61046927SAndroid Build Coastguard Worker 
100*61046927SAndroid Build Coastguard Worker    unsigned gpu_id;
101*61046927SAndroid Build Coastguard Worker    bool is_blend, is_blit;
102*61046927SAndroid Build Coastguard Worker    struct {
103*61046927SAndroid Build Coastguard Worker       unsigned nr_samples;
104*61046927SAndroid Build Coastguard Worker       uint64_t bifrost_blend_desc;
105*61046927SAndroid Build Coastguard Worker    } blend;
106*61046927SAndroid Build Coastguard Worker    bool no_idvs;
107*61046927SAndroid Build Coastguard Worker    bool no_ubo_to_push;
108*61046927SAndroid Build Coastguard Worker 
109*61046927SAndroid Build Coastguard Worker    /* Used on Valhall.
110*61046927SAndroid Build Coastguard Worker     *
111*61046927SAndroid Build Coastguard Worker     * Bit mask of special desktop-only varyings (e.g VARYING_SLOT_TEX0)
112*61046927SAndroid Build Coastguard Worker     * written by the previous stage (fragment shader) or written by this
113*61046927SAndroid Build Coastguard Worker     * stage (vertex shader). Bits are slots from gl_varying_slot.
114*61046927SAndroid Build Coastguard Worker     *
115*61046927SAndroid Build Coastguard Worker     * For modern APIs (GLES or VK), this should be 0.
116*61046927SAndroid Build Coastguard Worker     */
117*61046927SAndroid Build Coastguard Worker    uint32_t fixed_varying_mask;
118*61046927SAndroid Build Coastguard Worker 
119*61046927SAndroid Build Coastguard Worker    union {
120*61046927SAndroid Build Coastguard Worker       struct {
121*61046927SAndroid Build Coastguard Worker          uint32_t rt_conv[8];
122*61046927SAndroid Build Coastguard Worker       } bifrost;
123*61046927SAndroid Build Coastguard Worker    };
124*61046927SAndroid Build Coastguard Worker };
125*61046927SAndroid Build Coastguard Worker 
126*61046927SAndroid Build Coastguard Worker struct pan_shader_varying {
127*61046927SAndroid Build Coastguard Worker    gl_varying_slot location;
128*61046927SAndroid Build Coastguard Worker    enum pipe_format format;
129*61046927SAndroid Build Coastguard Worker };
130*61046927SAndroid Build Coastguard Worker 
131*61046927SAndroid Build Coastguard Worker struct bifrost_shader_blend_info {
132*61046927SAndroid Build Coastguard Worker    nir_alu_type type;
133*61046927SAndroid Build Coastguard Worker    uint32_t return_offset;
134*61046927SAndroid Build Coastguard Worker 
135*61046927SAndroid Build Coastguard Worker    /* mali_bifrost_register_file_format corresponding to nir_alu_type */
136*61046927SAndroid Build Coastguard Worker    unsigned format;
137*61046927SAndroid Build Coastguard Worker };
138*61046927SAndroid Build Coastguard Worker 
139*61046927SAndroid Build Coastguard Worker /*
140*61046927SAndroid Build Coastguard Worker  * Unpacked form of a v7 message preload descriptor, produced by the compiler's
141*61046927SAndroid Build Coastguard Worker  * message preload optimization. By splitting out this struct, the compiler does
142*61046927SAndroid Build Coastguard Worker  * not need to know about data structure packing, avoiding a dependency on
143*61046927SAndroid Build Coastguard Worker  * GenXML.
144*61046927SAndroid Build Coastguard Worker  */
145*61046927SAndroid Build Coastguard Worker struct bifrost_message_preload {
146*61046927SAndroid Build Coastguard Worker    /* Whether to preload this message */
147*61046927SAndroid Build Coastguard Worker    bool enabled;
148*61046927SAndroid Build Coastguard Worker 
149*61046927SAndroid Build Coastguard Worker    /* Varying to load from */
150*61046927SAndroid Build Coastguard Worker    unsigned varying_index;
151*61046927SAndroid Build Coastguard Worker 
152*61046927SAndroid Build Coastguard Worker    /* Register type, FP32 otherwise */
153*61046927SAndroid Build Coastguard Worker    bool fp16;
154*61046927SAndroid Build Coastguard Worker 
155*61046927SAndroid Build Coastguard Worker    /* Number of components, ignored if texturing */
156*61046927SAndroid Build Coastguard Worker    unsigned num_components;
157*61046927SAndroid Build Coastguard Worker 
158*61046927SAndroid Build Coastguard Worker    /* If texture is set, performs a texture instruction according to
159*61046927SAndroid Build Coastguard Worker     * texture_index, skip, and zero_lod. If texture is unset, only the
160*61046927SAndroid Build Coastguard Worker     * varying load is performed.
161*61046927SAndroid Build Coastguard Worker     */
162*61046927SAndroid Build Coastguard Worker    bool texture, skip, zero_lod;
163*61046927SAndroid Build Coastguard Worker    unsigned texture_index;
164*61046927SAndroid Build Coastguard Worker };
165*61046927SAndroid Build Coastguard Worker 
166*61046927SAndroid Build Coastguard Worker struct bifrost_shader_info {
167*61046927SAndroid Build Coastguard Worker    struct bifrost_shader_blend_info blend[8];
168*61046927SAndroid Build Coastguard Worker    nir_alu_type blend_src1_type;
169*61046927SAndroid Build Coastguard Worker    bool wait_6, wait_7;
170*61046927SAndroid Build Coastguard Worker    struct bifrost_message_preload messages[2];
171*61046927SAndroid Build Coastguard Worker 
172*61046927SAndroid Build Coastguard Worker    /* Whether any flat varyings are loaded. This may disable optimizations
173*61046927SAndroid Build Coastguard Worker     * that change the provoking vertex, since that would load incorrect
174*61046927SAndroid Build Coastguard Worker     * values for flat varyings.
175*61046927SAndroid Build Coastguard Worker     */
176*61046927SAndroid Build Coastguard Worker    bool uses_flat_shading;
177*61046927SAndroid Build Coastguard Worker };
178*61046927SAndroid Build Coastguard Worker 
179*61046927SAndroid Build Coastguard Worker struct midgard_shader_info {
180*61046927SAndroid Build Coastguard Worker    unsigned first_tag;
181*61046927SAndroid Build Coastguard Worker };
182*61046927SAndroid Build Coastguard Worker 
183*61046927SAndroid Build Coastguard Worker struct pan_shader_info {
184*61046927SAndroid Build Coastguard Worker    gl_shader_stage stage;
185*61046927SAndroid Build Coastguard Worker    unsigned work_reg_count;
186*61046927SAndroid Build Coastguard Worker    unsigned tls_size;
187*61046927SAndroid Build Coastguard Worker    unsigned wls_size;
188*61046927SAndroid Build Coastguard Worker 
189*61046927SAndroid Build Coastguard Worker    /* Bit mask of preloaded registers */
190*61046927SAndroid Build Coastguard Worker    uint64_t preload;
191*61046927SAndroid Build Coastguard Worker 
192*61046927SAndroid Build Coastguard Worker    union {
193*61046927SAndroid Build Coastguard Worker       struct {
194*61046927SAndroid Build Coastguard Worker          bool reads_frag_coord;
195*61046927SAndroid Build Coastguard Worker          bool reads_point_coord;
196*61046927SAndroid Build Coastguard Worker          bool reads_face;
197*61046927SAndroid Build Coastguard Worker          bool can_discard;
198*61046927SAndroid Build Coastguard Worker          bool writes_depth;
199*61046927SAndroid Build Coastguard Worker          bool writes_stencil;
200*61046927SAndroid Build Coastguard Worker          bool writes_coverage;
201*61046927SAndroid Build Coastguard Worker          bool sidefx;
202*61046927SAndroid Build Coastguard Worker          bool sample_shading;
203*61046927SAndroid Build Coastguard Worker          bool early_fragment_tests;
204*61046927SAndroid Build Coastguard Worker          bool can_early_z, can_fpk;
205*61046927SAndroid Build Coastguard Worker          bool untyped_color_outputs;
206*61046927SAndroid Build Coastguard Worker          BITSET_WORD outputs_read;
207*61046927SAndroid Build Coastguard Worker          BITSET_WORD outputs_written;
208*61046927SAndroid Build Coastguard Worker       } fs;
209*61046927SAndroid Build Coastguard Worker 
210*61046927SAndroid Build Coastguard Worker       struct {
211*61046927SAndroid Build Coastguard Worker          bool writes_point_size;
212*61046927SAndroid Build Coastguard Worker 
213*61046927SAndroid Build Coastguard Worker          /* If the primary shader writes point size, the Valhall
214*61046927SAndroid Build Coastguard Worker           * driver may need a variant that does not write point
215*61046927SAndroid Build Coastguard Worker           * size. Offset to such a shader in the program binary.
216*61046927SAndroid Build Coastguard Worker           *
217*61046927SAndroid Build Coastguard Worker           * Zero if no such variant is required.
218*61046927SAndroid Build Coastguard Worker           *
219*61046927SAndroid Build Coastguard Worker           * Only used with IDVS on Valhall.
220*61046927SAndroid Build Coastguard Worker           */
221*61046927SAndroid Build Coastguard Worker          unsigned no_psiz_offset;
222*61046927SAndroid Build Coastguard Worker 
223*61046927SAndroid Build Coastguard Worker          /* Set if Index-Driven Vertex Shading is in use */
224*61046927SAndroid Build Coastguard Worker          bool idvs;
225*61046927SAndroid Build Coastguard Worker 
226*61046927SAndroid Build Coastguard Worker          /* If IDVS is used, whether a varying shader is used */
227*61046927SAndroid Build Coastguard Worker          bool secondary_enable;
228*61046927SAndroid Build Coastguard Worker 
229*61046927SAndroid Build Coastguard Worker          /* If a varying shader is used, the varying shader's
230*61046927SAndroid Build Coastguard Worker           * offset in the program binary
231*61046927SAndroid Build Coastguard Worker           */
232*61046927SAndroid Build Coastguard Worker          unsigned secondary_offset;
233*61046927SAndroid Build Coastguard Worker 
234*61046927SAndroid Build Coastguard Worker          /* If IDVS is in use, number of work registers used by
235*61046927SAndroid Build Coastguard Worker           * the varying shader
236*61046927SAndroid Build Coastguard Worker           */
237*61046927SAndroid Build Coastguard Worker          unsigned secondary_work_reg_count;
238*61046927SAndroid Build Coastguard Worker 
239*61046927SAndroid Build Coastguard Worker          /* If IDVS is in use, bit mask of preloaded registers
240*61046927SAndroid Build Coastguard Worker           * used by the varying shader
241*61046927SAndroid Build Coastguard Worker           */
242*61046927SAndroid Build Coastguard Worker          uint64_t secondary_preload;
243*61046927SAndroid Build Coastguard Worker       } vs;
244*61046927SAndroid Build Coastguard Worker 
245*61046927SAndroid Build Coastguard Worker       struct {
246*61046927SAndroid Build Coastguard Worker          /* Is it legal to merge workgroups? This is true if the
247*61046927SAndroid Build Coastguard Worker           * shader uses neither barriers nor shared memory. This
248*61046927SAndroid Build Coastguard Worker           * requires caution: if the API allows specifying shared
249*61046927SAndroid Build Coastguard Worker           * memory at launch time (instead of compile time), that
250*61046927SAndroid Build Coastguard Worker           * memory will not be accounted for by the compiler.
251*61046927SAndroid Build Coastguard Worker           *
252*61046927SAndroid Build Coastguard Worker           * Used by the Valhall hardware.
253*61046927SAndroid Build Coastguard Worker           */
254*61046927SAndroid Build Coastguard Worker          bool allow_merging_workgroups;
255*61046927SAndroid Build Coastguard Worker       } cs;
256*61046927SAndroid Build Coastguard Worker    };
257*61046927SAndroid Build Coastguard Worker 
258*61046927SAndroid Build Coastguard Worker    /* Does the shader contains a barrier? or (for fragment shaders) does it
259*61046927SAndroid Build Coastguard Worker     * require helper invocations, which demand the same ordering guarantees
260*61046927SAndroid Build Coastguard Worker     * of the hardware? These notions are unified in the hardware, so we
261*61046927SAndroid Build Coastguard Worker     * unify them here as well.
262*61046927SAndroid Build Coastguard Worker     */
263*61046927SAndroid Build Coastguard Worker    bool contains_barrier;
264*61046927SAndroid Build Coastguard Worker    bool separable;
265*61046927SAndroid Build Coastguard Worker    bool writes_global;
266*61046927SAndroid Build Coastguard Worker    uint64_t outputs_written;
267*61046927SAndroid Build Coastguard Worker 
268*61046927SAndroid Build Coastguard Worker    /* Floating point controls that the driver should try to honour */
269*61046927SAndroid Build Coastguard Worker    bool ftz_fp16, ftz_fp32;
270*61046927SAndroid Build Coastguard Worker 
271*61046927SAndroid Build Coastguard Worker    unsigned sampler_count;
272*61046927SAndroid Build Coastguard Worker    unsigned texture_count;
273*61046927SAndroid Build Coastguard Worker    unsigned ubo_count;
274*61046927SAndroid Build Coastguard Worker    unsigned attributes_read_count;
275*61046927SAndroid Build Coastguard Worker    unsigned attribute_count;
276*61046927SAndroid Build Coastguard Worker    unsigned attributes_read;
277*61046927SAndroid Build Coastguard Worker 
278*61046927SAndroid Build Coastguard Worker    struct {
279*61046927SAndroid Build Coastguard Worker       unsigned input_count;
280*61046927SAndroid Build Coastguard Worker       struct pan_shader_varying input[PAN_MAX_VARYINGS];
281*61046927SAndroid Build Coastguard Worker       unsigned output_count;
282*61046927SAndroid Build Coastguard Worker       struct pan_shader_varying output[PAN_MAX_VARYINGS];
283*61046927SAndroid Build Coastguard Worker    } varyings;
284*61046927SAndroid Build Coastguard Worker 
285*61046927SAndroid Build Coastguard Worker    /* UBOs to push to Register Mapped Uniforms (Midgard) or Fast Access
286*61046927SAndroid Build Coastguard Worker     * Uniforms (Bifrost) */
287*61046927SAndroid Build Coastguard Worker    struct panfrost_ubo_push push;
288*61046927SAndroid Build Coastguard Worker 
289*61046927SAndroid Build Coastguard Worker    uint32_t ubo_mask;
290*61046927SAndroid Build Coastguard Worker 
291*61046927SAndroid Build Coastguard Worker    /* Quirk for GPUs that does not support auto32 types. */
292*61046927SAndroid Build Coastguard Worker    bool quirk_no_auto32;
293*61046927SAndroid Build Coastguard Worker 
294*61046927SAndroid Build Coastguard Worker    union {
295*61046927SAndroid Build Coastguard Worker       struct bifrost_shader_info bifrost;
296*61046927SAndroid Build Coastguard Worker       struct midgard_shader_info midgard;
297*61046927SAndroid Build Coastguard Worker    };
298*61046927SAndroid Build Coastguard Worker };
299*61046927SAndroid Build Coastguard Worker 
300*61046927SAndroid Build Coastguard Worker typedef struct pan_block {
301*61046927SAndroid Build Coastguard Worker    /* Link to next block. Must be first for mir_get_block */
302*61046927SAndroid Build Coastguard Worker    struct list_head link;
303*61046927SAndroid Build Coastguard Worker 
304*61046927SAndroid Build Coastguard Worker    /* List of instructions emitted for the current block */
305*61046927SAndroid Build Coastguard Worker    struct list_head instructions;
306*61046927SAndroid Build Coastguard Worker 
307*61046927SAndroid Build Coastguard Worker    /* Index of the block in source order */
308*61046927SAndroid Build Coastguard Worker    unsigned name;
309*61046927SAndroid Build Coastguard Worker 
310*61046927SAndroid Build Coastguard Worker    /* Control flow graph */
311*61046927SAndroid Build Coastguard Worker    struct pan_block *successors[2];
312*61046927SAndroid Build Coastguard Worker    struct set *predecessors;
313*61046927SAndroid Build Coastguard Worker    bool unconditional_jumps;
314*61046927SAndroid Build Coastguard Worker 
315*61046927SAndroid Build Coastguard Worker    /* In liveness analysis, these are live masks (per-component) for
316*61046927SAndroid Build Coastguard Worker     * indices for the block. Scalar compilers have the luxury of using
317*61046927SAndroid Build Coastguard Worker     * simple bit fields, but for us, liveness is a vector idea. */
318*61046927SAndroid Build Coastguard Worker    uint16_t *live_in;
319*61046927SAndroid Build Coastguard Worker    uint16_t *live_out;
320*61046927SAndroid Build Coastguard Worker } pan_block;
321*61046927SAndroid Build Coastguard Worker 
322*61046927SAndroid Build Coastguard Worker struct pan_instruction {
323*61046927SAndroid Build Coastguard Worker    struct list_head link;
324*61046927SAndroid Build Coastguard Worker };
325*61046927SAndroid Build Coastguard Worker 
326*61046927SAndroid Build Coastguard Worker #define pan_foreach_instr_in_block_rev(block, v)                               \
327*61046927SAndroid Build Coastguard Worker    list_for_each_entry_rev(struct pan_instruction, v, &block->instructions,    \
328*61046927SAndroid Build Coastguard Worker                            link)
329*61046927SAndroid Build Coastguard Worker 
330*61046927SAndroid Build Coastguard Worker #define pan_foreach_successor(blk, v)                                          \
331*61046927SAndroid Build Coastguard Worker    pan_block *v;                                                               \
332*61046927SAndroid Build Coastguard Worker    pan_block **_v;                                                             \
333*61046927SAndroid Build Coastguard Worker    for (_v = (pan_block **)&blk->successors[0], v = *_v;                       \
334*61046927SAndroid Build Coastguard Worker         v != NULL && _v < (pan_block **)&blk->successors[2]; _v++, v = *_v)
335*61046927SAndroid Build Coastguard Worker 
336*61046927SAndroid Build Coastguard Worker #define pan_foreach_predecessor(blk, v)                                        \
337*61046927SAndroid Build Coastguard Worker    struct set_entry *_entry_##v;                                               \
338*61046927SAndroid Build Coastguard Worker    struct pan_block *v;                                                        \
339*61046927SAndroid Build Coastguard Worker    for (_entry_##v = _mesa_set_next_entry(blk->predecessors, NULL),            \
340*61046927SAndroid Build Coastguard Worker        v = (struct pan_block *)(_entry_##v ? _entry_##v->key : NULL);          \
341*61046927SAndroid Build Coastguard Worker         _entry_##v != NULL;                                                    \
342*61046927SAndroid Build Coastguard Worker         _entry_##v = _mesa_set_next_entry(blk->predecessors, _entry_##v),      \
343*61046927SAndroid Build Coastguard Worker        v = (struct pan_block *)(_entry_##v ? _entry_##v->key : NULL))
344*61046927SAndroid Build Coastguard Worker 
345*61046927SAndroid Build Coastguard Worker static inline pan_block *
pan_exit_block(struct list_head * blocks)346*61046927SAndroid Build Coastguard Worker pan_exit_block(struct list_head *blocks)
347*61046927SAndroid Build Coastguard Worker {
348*61046927SAndroid Build Coastguard Worker    pan_block *last = list_last_entry(blocks, pan_block, link);
349*61046927SAndroid Build Coastguard Worker    assert(!last->successors[0] && !last->successors[1]);
350*61046927SAndroid Build Coastguard Worker    return last;
351*61046927SAndroid Build Coastguard Worker }
352*61046927SAndroid Build Coastguard Worker 
353*61046927SAndroid Build Coastguard Worker typedef void (*pan_liveness_update)(uint16_t *, void *, unsigned max);
354*61046927SAndroid Build Coastguard Worker 
355*61046927SAndroid Build Coastguard Worker void pan_liveness_gen(uint16_t *live, unsigned node, unsigned max,
356*61046927SAndroid Build Coastguard Worker                       uint16_t mask);
357*61046927SAndroid Build Coastguard Worker void pan_liveness_kill(uint16_t *live, unsigned node, unsigned max,
358*61046927SAndroid Build Coastguard Worker                        uint16_t mask);
359*61046927SAndroid Build Coastguard Worker bool pan_liveness_get(uint16_t *live, unsigned node, uint16_t max);
360*61046927SAndroid Build Coastguard Worker 
361*61046927SAndroid Build Coastguard Worker void pan_compute_liveness(struct list_head *blocks, unsigned temp_count,
362*61046927SAndroid Build Coastguard Worker                           pan_liveness_update callback);
363*61046927SAndroid Build Coastguard Worker 
364*61046927SAndroid Build Coastguard Worker void pan_free_liveness(struct list_head *blocks);
365*61046927SAndroid Build Coastguard Worker 
366*61046927SAndroid Build Coastguard Worker uint16_t pan_to_bytemask(unsigned bytes, unsigned mask);
367*61046927SAndroid Build Coastguard Worker 
368*61046927SAndroid Build Coastguard Worker void pan_block_add_successor(pan_block *block, pan_block *successor);
369*61046927SAndroid Build Coastguard Worker 
370*61046927SAndroid Build Coastguard Worker /* IR indexing */
371*61046927SAndroid Build Coastguard Worker #define PAN_IS_REG (1)
372*61046927SAndroid Build Coastguard Worker 
373*61046927SAndroid Build Coastguard Worker /* IR printing helpers */
374*61046927SAndroid Build Coastguard Worker void pan_print_alu_type(nir_alu_type t, FILE *fp);
375*61046927SAndroid Build Coastguard Worker 
376*61046927SAndroid Build Coastguard Worker /* NIR passes to do some backend-specific lowering */
377*61046927SAndroid Build Coastguard Worker 
378*61046927SAndroid Build Coastguard Worker #define PAN_WRITEOUT_C 1
379*61046927SAndroid Build Coastguard Worker #define PAN_WRITEOUT_Z 2
380*61046927SAndroid Build Coastguard Worker #define PAN_WRITEOUT_S 4
381*61046927SAndroid Build Coastguard Worker #define PAN_WRITEOUT_2 8
382*61046927SAndroid Build Coastguard Worker 
383*61046927SAndroid Build Coastguard Worker bool pan_nir_lower_zs_store(nir_shader *nir);
384*61046927SAndroid Build Coastguard Worker bool pan_nir_lower_store_component(nir_shader *shader);
385*61046927SAndroid Build Coastguard Worker 
386*61046927SAndroid Build Coastguard Worker bool pan_nir_lower_image_ms(nir_shader *shader);
387*61046927SAndroid Build Coastguard Worker 
388*61046927SAndroid Build Coastguard Worker bool pan_lower_helper_invocation(nir_shader *shader);
389*61046927SAndroid Build Coastguard Worker bool pan_lower_sample_pos(nir_shader *shader);
390*61046927SAndroid Build Coastguard Worker bool pan_lower_xfb(nir_shader *nir);
391*61046927SAndroid Build Coastguard Worker 
392*61046927SAndroid Build Coastguard Worker bool pan_lower_image_index(nir_shader *shader, unsigned vs_img_attrib_offset);
393*61046927SAndroid Build Coastguard Worker 
394*61046927SAndroid Build Coastguard Worker void pan_nir_collect_varyings(nir_shader *s, struct pan_shader_info *info);
395*61046927SAndroid Build Coastguard Worker 
396*61046927SAndroid Build Coastguard Worker /*
397*61046927SAndroid Build Coastguard Worker  * Helper returning the subgroup size. Generally, this is equal to the number of
398*61046927SAndroid Build Coastguard Worker  * threads in a warp. For Midgard (including warping models), this returns 1, as
399*61046927SAndroid Build Coastguard Worker  * subgroups are not supported.
400*61046927SAndroid Build Coastguard Worker  */
401*61046927SAndroid Build Coastguard Worker static inline unsigned
pan_subgroup_size(unsigned arch)402*61046927SAndroid Build Coastguard Worker pan_subgroup_size(unsigned arch)
403*61046927SAndroid Build Coastguard Worker {
404*61046927SAndroid Build Coastguard Worker    if (arch >= 9)
405*61046927SAndroid Build Coastguard Worker       return 16;
406*61046927SAndroid Build Coastguard Worker    else if (arch >= 7)
407*61046927SAndroid Build Coastguard Worker       return 8;
408*61046927SAndroid Build Coastguard Worker    else if (arch >= 6)
409*61046927SAndroid Build Coastguard Worker       return 4;
410*61046927SAndroid Build Coastguard Worker    else
411*61046927SAndroid Build Coastguard Worker       return 1;
412*61046927SAndroid Build Coastguard Worker }
413*61046927SAndroid Build Coastguard Worker 
414*61046927SAndroid Build Coastguard Worker /*
415*61046927SAndroid Build Coastguard Worker  * Helper extracting the table from a given handle of Valhall descriptor model.
416*61046927SAndroid Build Coastguard Worker  */
417*61046927SAndroid Build Coastguard Worker static inline unsigned
pan_res_handle_get_table(unsigned handle)418*61046927SAndroid Build Coastguard Worker pan_res_handle_get_table(unsigned handle)
419*61046927SAndroid Build Coastguard Worker {
420*61046927SAndroid Build Coastguard Worker    unsigned table = handle >> 24;
421*61046927SAndroid Build Coastguard Worker 
422*61046927SAndroid Build Coastguard Worker    assert(table < 64);
423*61046927SAndroid Build Coastguard Worker    return table;
424*61046927SAndroid Build Coastguard Worker }
425*61046927SAndroid Build Coastguard Worker 
426*61046927SAndroid Build Coastguard Worker /*
427*61046927SAndroid Build Coastguard Worker  * Helper returning the index from a given handle of Valhall descriptor model.
428*61046927SAndroid Build Coastguard Worker  */
429*61046927SAndroid Build Coastguard Worker static inline unsigned
pan_res_handle_get_index(unsigned handle)430*61046927SAndroid Build Coastguard Worker pan_res_handle_get_index(unsigned handle)
431*61046927SAndroid Build Coastguard Worker {
432*61046927SAndroid Build Coastguard Worker    return handle & BITFIELD_MASK(24);
433*61046927SAndroid Build Coastguard Worker }
434*61046927SAndroid Build Coastguard Worker 
435*61046927SAndroid Build Coastguard Worker /*
436*61046927SAndroid Build Coastguard Worker  * Helper creating an handle for Valhall descriptor model.
437*61046927SAndroid Build Coastguard Worker  */
438*61046927SAndroid Build Coastguard Worker static inline unsigned
pan_res_handle(unsigned table,unsigned index)439*61046927SAndroid Build Coastguard Worker pan_res_handle(unsigned table, unsigned index)
440*61046927SAndroid Build Coastguard Worker {
441*61046927SAndroid Build Coastguard Worker    assert(table < 64);
442*61046927SAndroid Build Coastguard Worker    assert(index < (1u << 24));
443*61046927SAndroid Build Coastguard Worker 
444*61046927SAndroid Build Coastguard Worker    return (table << 24) | index;
445*61046927SAndroid Build Coastguard Worker }
446*61046927SAndroid Build Coastguard Worker 
447*61046927SAndroid Build Coastguard Worker #endif
448