xref: /aosp_15_r20/external/mesa3d/src/panfrost/lib/pan_shader.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright (C) 2018 Alyssa Rosenzweig
3  * Copyright (C) 2019-2021 Collabora, Ltd.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the next
13  * paragraph) shall be included in all copies or substantial portions of the
14  * Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
24 
25 #include "pan_shader.h"
26 #include "pan_format.h"
27 
28 #if PAN_ARCH <= 5
29 #include "panfrost/midgard/midgard_compile.h"
30 #else
31 #include "panfrost/compiler/bifrost_compile.h"
32 #endif
33 
34 const nir_shader_compiler_options *
GENX(pan_shader_get_compiler_options)35 GENX(pan_shader_get_compiler_options)(void)
36 {
37 #if PAN_ARCH >= 9
38    return &bifrost_nir_options_v9;
39 #elif PAN_ARCH >= 6
40    return &bifrost_nir_options_v6;
41 #else
42    return &midgard_nir_options;
43 #endif
44 }
45 
46 #if PAN_ARCH >= 6
47 static enum mali_register_file_format
bifrost_blend_type_from_nir(nir_alu_type nir_type)48 bifrost_blend_type_from_nir(nir_alu_type nir_type)
49 {
50    switch (nir_type) {
51    case 0: /* Render target not in use */
52       return 0;
53    case nir_type_float16:
54       return MALI_REGISTER_FILE_FORMAT_F16;
55    case nir_type_float32:
56       return MALI_REGISTER_FILE_FORMAT_F32;
57    case nir_type_int32:
58       return MALI_REGISTER_FILE_FORMAT_I32;
59    case nir_type_uint32:
60       return MALI_REGISTER_FILE_FORMAT_U32;
61    case nir_type_int16:
62       return MALI_REGISTER_FILE_FORMAT_I16;
63    case nir_type_uint16:
64       return MALI_REGISTER_FILE_FORMAT_U16;
65    default:
66       unreachable("Unsupported blend shader type for NIR alu type");
67       return 0;
68    }
69 }
70 
71 #if PAN_ARCH <= 7
72 enum mali_register_file_format
GENX(pan_fixup_blend_type)73 GENX(pan_fixup_blend_type)(nir_alu_type T_size, enum pipe_format format)
74 {
75    const struct util_format_description *desc = util_format_description(format);
76    unsigned size = nir_alu_type_get_type_size(T_size);
77    nir_alu_type T_format = pan_unpacked_type_for_format(desc);
78    nir_alu_type T = nir_alu_type_get_base_type(T_format) | size;
79 
80    return bifrost_blend_type_from_nir(T);
81 }
82 #endif
83 #endif
84 
85 /* This is only needed on Midgard. It's the same on both v4 and v5, so only
86  * compile once to avoid the GenXML dependency for calls.
87  */
88 #if PAN_ARCH == 5
89 uint8_t
pan_raw_format_mask_midgard(enum pipe_format * formats)90 pan_raw_format_mask_midgard(enum pipe_format *formats)
91 {
92    uint8_t out = 0;
93 
94    for (unsigned i = 0; i < 8; i++) {
95       enum pipe_format fmt = formats[i];
96       unsigned wb_fmt = panfrost_blendable_formats_v6[fmt].writeback;
97 
98       if (wb_fmt < MALI_COLOR_FORMAT_R8)
99          out |= BITFIELD_BIT(i);
100    }
101 
102    return out;
103 }
104 #endif
105 
106 void
GENX(pan_shader_compile)107 GENX(pan_shader_compile)(nir_shader *s, struct panfrost_compile_inputs *inputs,
108                          struct util_dynarray *binary,
109                          struct pan_shader_info *info)
110 {
111    memset(info, 0, sizeof(*info));
112 
113 #if PAN_ARCH >= 6
114    bifrost_compile_shader_nir(s, inputs, binary, info);
115 #else
116    midgard_compile_shader_nir(s, inputs, binary, info);
117 #endif
118 
119    info->stage = s->info.stage;
120    info->contains_barrier =
121       s->info.uses_memory_barrier || s->info.uses_control_barrier;
122    info->separable = s->info.separate_shader;
123 
124    switch (info->stage) {
125    case MESA_SHADER_VERTEX:
126       info->attributes_read = s->info.inputs_read;
127       info->attributes_read_count = util_bitcount64(info->attributes_read);
128       info->attribute_count = info->attributes_read_count;
129 
130 #if PAN_ARCH <= 5
131       bool vertex_id = BITSET_TEST(s->info.system_values_read,
132                                    SYSTEM_VALUE_VERTEX_ID_ZERO_BASE);
133       if (vertex_id)
134          info->attribute_count = MAX2(info->attribute_count, PAN_VERTEX_ID + 1);
135 
136       bool instance_id =
137          BITSET_TEST(s->info.system_values_read, SYSTEM_VALUE_INSTANCE_ID);
138       if (instance_id)
139          info->attribute_count =
140             MAX2(info->attribute_count, PAN_INSTANCE_ID + 1);
141 #endif
142 
143       info->vs.writes_point_size =
144          s->info.outputs_written & (1 << VARYING_SLOT_PSIZ);
145 
146 #if PAN_ARCH >= 9
147       info->varyings.output_count =
148          util_last_bit(s->info.outputs_written >> VARYING_SLOT_VAR0);
149 #endif
150       break;
151    case MESA_SHADER_FRAGMENT:
152       if (s->info.outputs_written & BITFIELD64_BIT(FRAG_RESULT_DEPTH))
153          info->fs.writes_depth = true;
154       if (s->info.outputs_written & BITFIELD64_BIT(FRAG_RESULT_STENCIL))
155          info->fs.writes_stencil = true;
156       if (s->info.outputs_written & BITFIELD64_BIT(FRAG_RESULT_SAMPLE_MASK))
157          info->fs.writes_coverage = true;
158 
159       info->fs.outputs_read = s->info.outputs_read >> FRAG_RESULT_DATA0;
160       info->fs.outputs_written = s->info.outputs_written >> FRAG_RESULT_DATA0;
161       info->fs.sample_shading = s->info.fs.uses_sample_shading;
162       info->fs.untyped_color_outputs = s->info.fs.untyped_color_outputs;
163 
164       info->fs.can_discard = s->info.fs.uses_discard;
165       info->fs.early_fragment_tests = s->info.fs.early_fragment_tests;
166 
167       /* List of reasons we need to execute frag shaders when things
168        * are masked off */
169 
170       info->fs.sidefx = s->info.writes_memory || s->info.fs.uses_discard;
171 
172       /* With suitable ZSA/blend, is early-z possible? */
173       info->fs.can_early_z = !info->fs.sidefx && !info->fs.writes_depth &&
174                              !info->fs.writes_stencil &&
175                              !info->fs.writes_coverage;
176 
177       /* Similiarly with suitable state, is FPK possible? */
178       info->fs.can_fpk = !info->fs.writes_depth && !info->fs.writes_stencil &&
179                          !info->fs.writes_coverage && !info->fs.can_discard &&
180                          !info->fs.outputs_read;
181 
182       /* Requires the same hardware guarantees, so grouped as one bit
183        * in the hardware.
184        */
185       info->contains_barrier |= s->info.fs.needs_quad_helper_invocations;
186 
187       info->fs.reads_frag_coord =
188          (s->info.inputs_read & (1 << VARYING_SLOT_POS)) ||
189          BITSET_TEST(s->info.system_values_read, SYSTEM_VALUE_FRAG_COORD);
190       info->fs.reads_point_coord =
191          s->info.inputs_read & (1 << VARYING_SLOT_PNTC);
192       info->fs.reads_face =
193          (s->info.inputs_read & (1 << VARYING_SLOT_FACE)) ||
194          BITSET_TEST(s->info.system_values_read, SYSTEM_VALUE_FRONT_FACE);
195 #if PAN_ARCH >= 9
196       info->varyings.input_count =
197          util_last_bit(s->info.inputs_read >> VARYING_SLOT_VAR0);
198 #endif
199       break;
200    default:
201       /* Everything else treated as compute */
202       info->wls_size = s->info.shared_size;
203       break;
204    }
205 
206    info->outputs_written = s->info.outputs_written;
207    info->attribute_count += BITSET_LAST_BIT(s->info.images_used);
208    info->writes_global = s->info.writes_memory;
209    info->ubo_count = s->info.num_ubos;
210 
211    info->sampler_count = info->texture_count =
212       BITSET_LAST_BIT(s->info.textures_used);
213 
214    unsigned execution_mode = s->info.float_controls_execution_mode;
215    info->ftz_fp16 = nir_is_denorm_flush_to_zero(execution_mode, 16);
216    info->ftz_fp32 = nir_is_denorm_flush_to_zero(execution_mode, 32);
217 
218 #if PAN_ARCH >= 6
219    /* This is "redundant" information, but is needed in a draw-time hot path */
220    for (unsigned i = 0; i < ARRAY_SIZE(info->bifrost.blend); ++i) {
221       info->bifrost.blend[i].format =
222          bifrost_blend_type_from_nir(info->bifrost.blend[i].type);
223    }
224 #endif
225 }
226