xref: /aosp_15_r20/external/mesa3d/src/asahi/lib/agx_linker.h (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker  * Copyright 2024 Alyssa Rosenzweig
3*61046927SAndroid Build Coastguard Worker  * SPDX-License-Identifier: MIT
4*61046927SAndroid Build Coastguard Worker  */
5*61046927SAndroid Build Coastguard Worker 
6*61046927SAndroid Build Coastguard Worker #pragma once
7*61046927SAndroid Build Coastguard Worker 
8*61046927SAndroid Build Coastguard Worker #include "agx_bo.h"
9*61046927SAndroid Build Coastguard Worker #include "agx_compile.h"
10*61046927SAndroid Build Coastguard Worker #include "agx_nir_lower_vbo.h"
11*61046927SAndroid Build Coastguard Worker #include "agx_pack.h"
12*61046927SAndroid Build Coastguard Worker #include "nir_lower_blend.h"
13*61046927SAndroid Build Coastguard Worker 
14*61046927SAndroid Build Coastguard Worker struct agx_linked_shader {
15*61046927SAndroid Build Coastguard Worker    /* Mapped executable memory */
16*61046927SAndroid Build Coastguard Worker    struct agx_bo *bo;
17*61046927SAndroid Build Coastguard Worker 
18*61046927SAndroid Build Coastguard Worker    /* Set if the linked SW vertex shader reads base vertex/instance. The VS
19*61046927SAndroid Build Coastguard Worker     * prolog can read base instance even when the API VS does not, which is why
20*61046927SAndroid Build Coastguard Worker     * this needs to be aggregated in the linker.
21*61046927SAndroid Build Coastguard Worker     */
22*61046927SAndroid Build Coastguard Worker    bool uses_base_param;
23*61046927SAndroid Build Coastguard Worker 
24*61046927SAndroid Build Coastguard Worker    /* Set if the linked shader uses txf. The epilog may even if the main shader
25*61046927SAndroid Build Coastguard Worker     * does not, in the case of spilled render targets.
26*61046927SAndroid Build Coastguard Worker     */
27*61046927SAndroid Build Coastguard Worker    bool uses_txf;
28*61046927SAndroid Build Coastguard Worker 
29*61046927SAndroid Build Coastguard Worker    /* Coefficient register bindings */
30*61046927SAndroid Build Coastguard Worker    struct agx_varyings_fs cf;
31*61046927SAndroid Build Coastguard Worker 
32*61046927SAndroid Build Coastguard Worker    /* Data structures packed for the linked program */
33*61046927SAndroid Build Coastguard Worker    struct agx_usc_shader_packed shader;
34*61046927SAndroid Build Coastguard Worker    struct agx_usc_registers_packed regs;
35*61046927SAndroid Build Coastguard Worker    struct agx_usc_fragment_properties_packed fragment_props;
36*61046927SAndroid Build Coastguard Worker    struct agx_output_select_packed osel;
37*61046927SAndroid Build Coastguard Worker    struct agx_fragment_control_packed fragment_control;
38*61046927SAndroid Build Coastguard Worker };
39*61046927SAndroid Build Coastguard Worker 
40*61046927SAndroid Build Coastguard Worker void agx_fast_link(struct agx_linked_shader *linked, struct agx_device *dev,
41*61046927SAndroid Build Coastguard Worker                    bool fragment, struct agx_shader_part *main,
42*61046927SAndroid Build Coastguard Worker                    struct agx_shader_part *prolog,
43*61046927SAndroid Build Coastguard Worker                    struct agx_shader_part *epilog, unsigned nr_samples_shaded);
44*61046927SAndroid Build Coastguard Worker 
45*61046927SAndroid Build Coastguard Worker /* These parts of the vertex element affect the generated code */
46*61046927SAndroid Build Coastguard Worker struct agx_velem_key {
47*61046927SAndroid Build Coastguard Worker    uint32_t divisor;
48*61046927SAndroid Build Coastguard Worker    uint16_t stride;
49*61046927SAndroid Build Coastguard Worker    uint8_t format;
50*61046927SAndroid Build Coastguard Worker    bool instanced;
51*61046927SAndroid Build Coastguard Worker };
52*61046927SAndroid Build Coastguard Worker 
53*61046927SAndroid Build Coastguard Worker struct agx_vs_prolog_key {
54*61046927SAndroid Build Coastguard Worker    struct agx_velem_key attribs[AGX_MAX_VBUFS];
55*61046927SAndroid Build Coastguard Worker 
56*61046927SAndroid Build Coastguard Worker    /* Bit mask of attribute components to load */
57*61046927SAndroid Build Coastguard Worker    BITSET_DECLARE(component_mask, AGX_MAX_ATTRIBS * 4);
58*61046927SAndroid Build Coastguard Worker 
59*61046927SAndroid Build Coastguard Worker    /* Whether running as a hardware vertex shader (versus compute) */
60*61046927SAndroid Build Coastguard Worker    bool hw;
61*61046927SAndroid Build Coastguard Worker 
62*61046927SAndroid Build Coastguard Worker    /* If !hw and the draw call is indexed, the index size */
63*61046927SAndroid Build Coastguard Worker    uint8_t sw_index_size_B;
64*61046927SAndroid Build Coastguard Worker 
65*61046927SAndroid Build Coastguard Worker    /* Robustness settings for the vertex fetch */
66*61046927SAndroid Build Coastguard Worker    struct agx_robustness robustness;
67*61046927SAndroid Build Coastguard Worker };
68*61046927SAndroid Build Coastguard Worker 
69*61046927SAndroid Build Coastguard Worker struct agx_fs_prolog_key {
70*61046927SAndroid Build Coastguard Worker    /* glSampleMask() mask */
71*61046927SAndroid Build Coastguard Worker    uint8_t api_sample_mask;
72*61046927SAndroid Build Coastguard Worker 
73*61046927SAndroid Build Coastguard Worker    /* Number of cull planes requiring lowering */
74*61046927SAndroid Build Coastguard Worker    uint8_t cull_distance_size;
75*61046927SAndroid Build Coastguard Worker 
76*61046927SAndroid Build Coastguard Worker    /* Need to count FRAGMENT_SHADER_INVOCATIONS */
77*61046927SAndroid Build Coastguard Worker    bool statistics;
78*61046927SAndroid Build Coastguard Worker 
79*61046927SAndroid Build Coastguard Worker    /* Need to lower desktop OpenGL polygon stipple */
80*61046927SAndroid Build Coastguard Worker    bool polygon_stipple;
81*61046927SAndroid Build Coastguard Worker 
82*61046927SAndroid Build Coastguard Worker    /* If we discard, whether we need to run Z/S tests */
83*61046927SAndroid Build Coastguard Worker    bool run_zs_tests;
84*61046927SAndroid Build Coastguard Worker 
85*61046927SAndroid Build Coastguard Worker    /* If we emulate cull distance, the base offset for our allocated coefficient
86*61046927SAndroid Build Coastguard Worker     * registers so we don't interfere with the main shader.
87*61046927SAndroid Build Coastguard Worker     */
88*61046927SAndroid Build Coastguard Worker    unsigned cf_base;
89*61046927SAndroid Build Coastguard Worker };
90*61046927SAndroid Build Coastguard Worker 
91*61046927SAndroid Build Coastguard Worker struct agx_blend_rt_key {
92*61046927SAndroid Build Coastguard Worker    enum pipe_blend_func rgb_func          : 3;
93*61046927SAndroid Build Coastguard Worker    enum pipe_blendfactor rgb_src_factor   : 5;
94*61046927SAndroid Build Coastguard Worker    enum pipe_blendfactor rgb_dst_factor   : 5;
95*61046927SAndroid Build Coastguard Worker    enum pipe_blend_func alpha_func        : 3;
96*61046927SAndroid Build Coastguard Worker    enum pipe_blendfactor alpha_src_factor : 5;
97*61046927SAndroid Build Coastguard Worker    enum pipe_blendfactor alpha_dst_factor : 5;
98*61046927SAndroid Build Coastguard Worker    unsigned colormask                     : 4;
99*61046927SAndroid Build Coastguard Worker    unsigned pad                           : 2;
100*61046927SAndroid Build Coastguard Worker };
101*61046927SAndroid Build Coastguard Worker static_assert(sizeof(struct agx_blend_rt_key) == 4, "packed");
102*61046927SAndroid Build Coastguard Worker 
103*61046927SAndroid Build Coastguard Worker struct agx_blend_key {
104*61046927SAndroid Build Coastguard Worker    struct agx_blend_rt_key rt[8];
105*61046927SAndroid Build Coastguard Worker    uint8_t logicop_func;
106*61046927SAndroid Build Coastguard Worker    bool alpha_to_coverage, alpha_to_one;
107*61046927SAndroid Build Coastguard Worker    bool padding;
108*61046927SAndroid Build Coastguard Worker };
109*61046927SAndroid Build Coastguard Worker static_assert(sizeof(struct agx_blend_key) == 36, "packed");
110*61046927SAndroid Build Coastguard Worker 
111*61046927SAndroid Build Coastguard Worker struct agx_fs_epilog_link_info {
112*61046927SAndroid Build Coastguard Worker    /* Base index of spilled render targets in the binding table */
113*61046927SAndroid Build Coastguard Worker    uint8_t rt_spill_base;
114*61046927SAndroid Build Coastguard Worker 
115*61046927SAndroid Build Coastguard Worker    /* Bit mask of the bit size written to each render target. Bit i set if RT i
116*61046927SAndroid Build Coastguard Worker     * uses 32-bit registers, else 16-bit registers.
117*61046927SAndroid Build Coastguard Worker     */
118*61046927SAndroid Build Coastguard Worker    uint8_t size_32;
119*61046927SAndroid Build Coastguard Worker 
120*61046927SAndroid Build Coastguard Worker    /* Mask of render targets written by the main shader */
121*61046927SAndroid Build Coastguard Worker    uint8_t rt_written;
122*61046927SAndroid Build Coastguard Worker 
123*61046927SAndroid Build Coastguard Worker    /* If set, the API fragment shader uses sample shading. This means the epilog
124*61046927SAndroid Build Coastguard Worker     * will be invoked per-sample as well.
125*61046927SAndroid Build Coastguard Worker     */
126*61046927SAndroid Build Coastguard Worker    unsigned sample_shading : 1;
127*61046927SAndroid Build Coastguard Worker 
128*61046927SAndroid Build Coastguard Worker    /* If set, broadcast the render target #0 value to all render targets. This
129*61046927SAndroid Build Coastguard Worker     * implements gl_FragColor semantics.
130*61046927SAndroid Build Coastguard Worker     */
131*61046927SAndroid Build Coastguard Worker    unsigned broadcast_rt0 : 1;
132*61046927SAndroid Build Coastguard Worker 
133*61046927SAndroid Build Coastguard Worker    /* If set, force render target 0's W channel to 1.0. This optimizes blending
134*61046927SAndroid Build Coastguard Worker     * calculations in some applications.
135*61046927SAndroid Build Coastguard Worker     */
136*61046927SAndroid Build Coastguard Worker    unsigned rt0_w_1 : 1;
137*61046927SAndroid Build Coastguard Worker 
138*61046927SAndroid Build Coastguard Worker    /* If set, the API fragment shader wants to write depth/stencil respectively.
139*61046927SAndroid Build Coastguard Worker     * This happens in the epilog for correctness when the epilog discards.
140*61046927SAndroid Build Coastguard Worker     */
141*61046927SAndroid Build Coastguard Worker    unsigned write_z : 1;
142*61046927SAndroid Build Coastguard Worker    unsigned write_s : 1;
143*61046927SAndroid Build Coastguard Worker 
144*61046927SAndroid Build Coastguard Worker    /* Whether the fragment prolog or main fragment shader already ran tests due
145*61046927SAndroid Build Coastguard Worker     * to early_fragment_tests. In this case, the epilog must not run tests.
146*61046927SAndroid Build Coastguard Worker     */
147*61046927SAndroid Build Coastguard Worker    unsigned already_ran_zs : 1;
148*61046927SAndroid Build Coastguard Worker 
149*61046927SAndroid Build Coastguard Worker    /* Whether the main fragment shader ran tests before discards due to
150*61046927SAndroid Build Coastguard Worker     * early_fragment_tests. In this case, the epilog must mask the stores in
151*61046927SAndroid Build Coastguard Worker     * software instead.
152*61046927SAndroid Build Coastguard Worker     */
153*61046927SAndroid Build Coastguard Worker    bool sample_mask_after_force_early : 1;
154*61046927SAndroid Build Coastguard Worker 
155*61046927SAndroid Build Coastguard Worker    unsigned padding : 1;
156*61046927SAndroid Build Coastguard Worker };
157*61046927SAndroid Build Coastguard Worker static_assert(sizeof(struct agx_fs_epilog_link_info) == 4, "packed");
158*61046927SAndroid Build Coastguard Worker 
159*61046927SAndroid Build Coastguard Worker struct agx_fs_epilog_key {
160*61046927SAndroid Build Coastguard Worker    struct agx_fs_epilog_link_info link;
161*61046927SAndroid Build Coastguard Worker 
162*61046927SAndroid Build Coastguard Worker    /* Blend state. Blending happens in the epilog. */
163*61046927SAndroid Build Coastguard Worker    struct agx_blend_key blend;
164*61046927SAndroid Build Coastguard Worker 
165*61046927SAndroid Build Coastguard Worker    /* Tilebuffer configuration */
166*61046927SAndroid Build Coastguard Worker    enum pipe_format rt_formats[8];
167*61046927SAndroid Build Coastguard Worker    uint8_t nr_samples;
168*61046927SAndroid Build Coastguard Worker    bool force_small_tile;
169*61046927SAndroid Build Coastguard Worker };
170*61046927SAndroid Build Coastguard Worker 
171*61046927SAndroid Build Coastguard Worker void agx_nir_vs_prolog(struct nir_builder *b, const void *key_);
172*61046927SAndroid Build Coastguard Worker void agx_nir_fs_epilog(struct nir_builder *b, const void *key_);
173*61046927SAndroid Build Coastguard Worker void agx_nir_fs_prolog(struct nir_builder *b, const void *key_);
174*61046927SAndroid Build Coastguard Worker 
175*61046927SAndroid Build Coastguard Worker bool agx_nir_lower_vs_input_to_prolog(nir_shader *s,
176*61046927SAndroid Build Coastguard Worker                                       BITSET_WORD *attrib_components_read);
177*61046927SAndroid Build Coastguard Worker 
178*61046927SAndroid Build Coastguard Worker bool agx_nir_lower_fs_output_to_epilog(nir_shader *s,
179*61046927SAndroid Build Coastguard Worker                                        struct agx_fs_epilog_link_info *out);
180*61046927SAndroid Build Coastguard Worker 
181*61046927SAndroid Build Coastguard Worker bool agx_nir_lower_fs_active_samples_to_register(nir_shader *s);
182