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