xref: /aosp_15_r20/external/mesa3d/src/panfrost/lib/pan_blitter.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker  * Copyright (C) 2020-2021 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  * Authors:
24*61046927SAndroid Build Coastguard Worker  *   Alyssa Rosenzweig <[email protected]>
25*61046927SAndroid Build Coastguard Worker  *   Boris Brezillon <[email protected]>
26*61046927SAndroid Build Coastguard Worker  */
27*61046927SAndroid Build Coastguard Worker 
28*61046927SAndroid Build Coastguard Worker #include "pan_blitter.h"
29*61046927SAndroid Build Coastguard Worker #include <math.h>
30*61046927SAndroid Build Coastguard Worker #include <stdio.h>
31*61046927SAndroid Build Coastguard Worker #include "compiler/nir/nir_builder.h"
32*61046927SAndroid Build Coastguard Worker #include "util/u_math.h"
33*61046927SAndroid Build Coastguard Worker #include "pan_blend.h"
34*61046927SAndroid Build Coastguard Worker #include "pan_desc.h"
35*61046927SAndroid Build Coastguard Worker #include "pan_encoder.h"
36*61046927SAndroid Build Coastguard Worker #include "pan_jc.h"
37*61046927SAndroid Build Coastguard Worker #include "pan_pool.h"
38*61046927SAndroid Build Coastguard Worker #include "pan_shader.h"
39*61046927SAndroid Build Coastguard Worker #include "pan_texture.h"
40*61046927SAndroid Build Coastguard Worker 
41*61046927SAndroid Build Coastguard Worker #if PAN_ARCH >= 6
42*61046927SAndroid Build Coastguard Worker /* On Midgard, the native blit infrastructure (via MFBD preloads) is broken or
43*61046927SAndroid Build Coastguard Worker  * missing in many cases. We instead use software paths as fallbacks to
44*61046927SAndroid Build Coastguard Worker  * implement blits, which are done as TILER jobs. No vertex shader is
45*61046927SAndroid Build Coastguard Worker  * necessary since we can supply screen-space coordinates directly.
46*61046927SAndroid Build Coastguard Worker  *
47*61046927SAndroid Build Coastguard Worker  * This is primarily designed as a fallback for preloads but could be extended
48*61046927SAndroid Build Coastguard Worker  * for other clears/blits if needed in the future. */
49*61046927SAndroid Build Coastguard Worker 
50*61046927SAndroid Build Coastguard Worker static enum mali_register_file_format
blit_type_to_reg_fmt(nir_alu_type in)51*61046927SAndroid Build Coastguard Worker blit_type_to_reg_fmt(nir_alu_type in)
52*61046927SAndroid Build Coastguard Worker {
53*61046927SAndroid Build Coastguard Worker    switch (in) {
54*61046927SAndroid Build Coastguard Worker    case nir_type_float32:
55*61046927SAndroid Build Coastguard Worker       return MALI_REGISTER_FILE_FORMAT_F32;
56*61046927SAndroid Build Coastguard Worker    case nir_type_int32:
57*61046927SAndroid Build Coastguard Worker       return MALI_REGISTER_FILE_FORMAT_I32;
58*61046927SAndroid Build Coastguard Worker    case nir_type_uint32:
59*61046927SAndroid Build Coastguard Worker       return MALI_REGISTER_FILE_FORMAT_U32;
60*61046927SAndroid Build Coastguard Worker    default:
61*61046927SAndroid Build Coastguard Worker       unreachable("Invalid blit type");
62*61046927SAndroid Build Coastguard Worker    }
63*61046927SAndroid Build Coastguard Worker }
64*61046927SAndroid Build Coastguard Worker #endif
65*61046927SAndroid Build Coastguard Worker 
66*61046927SAndroid Build Coastguard Worker /* On Valhall, the driver gives the hardware a table of resource tables.
67*61046927SAndroid Build Coastguard Worker  * Resources are addressed as the index of the table together with the index of
68*61046927SAndroid Build Coastguard Worker  * the resource within the table. For simplicity, we put one type of resource
69*61046927SAndroid Build Coastguard Worker  * in each table and fix the numbering of the tables.
70*61046927SAndroid Build Coastguard Worker  *
71*61046927SAndroid Build Coastguard Worker  * This numbering is arbitrary.
72*61046927SAndroid Build Coastguard Worker  */
73*61046927SAndroid Build Coastguard Worker enum pan_blit_resource_table {
74*61046927SAndroid Build Coastguard Worker    PAN_BLIT_TABLE_ATTRIBUTE = 0,
75*61046927SAndroid Build Coastguard Worker    PAN_BLIT_TABLE_ATTRIBUTE_BUFFER,
76*61046927SAndroid Build Coastguard Worker    PAN_BLIT_TABLE_SAMPLER,
77*61046927SAndroid Build Coastguard Worker    PAN_BLIT_TABLE_TEXTURE,
78*61046927SAndroid Build Coastguard Worker 
79*61046927SAndroid Build Coastguard Worker    PAN_BLIT_NUM_RESOURCE_TABLES
80*61046927SAndroid Build Coastguard Worker };
81*61046927SAndroid Build Coastguard Worker 
82*61046927SAndroid Build Coastguard Worker struct pan_blit_surface {
83*61046927SAndroid Build Coastguard Worker    gl_frag_result loc              : 4;
84*61046927SAndroid Build Coastguard Worker    nir_alu_type type               : 8;
85*61046927SAndroid Build Coastguard Worker    enum mali_texture_dimension dim : 2;
86*61046927SAndroid Build Coastguard Worker    bool array                      : 1;
87*61046927SAndroid Build Coastguard Worker    unsigned src_samples            : 5;
88*61046927SAndroid Build Coastguard Worker    unsigned dst_samples            : 5;
89*61046927SAndroid Build Coastguard Worker };
90*61046927SAndroid Build Coastguard Worker 
91*61046927SAndroid Build Coastguard Worker struct pan_blit_shader_key {
92*61046927SAndroid Build Coastguard Worker    struct pan_blit_surface surfaces[8];
93*61046927SAndroid Build Coastguard Worker };
94*61046927SAndroid Build Coastguard Worker 
95*61046927SAndroid Build Coastguard Worker struct pan_blit_shader_data {
96*61046927SAndroid Build Coastguard Worker    struct pan_blit_shader_key key;
97*61046927SAndroid Build Coastguard Worker    struct pan_shader_info info;
98*61046927SAndroid Build Coastguard Worker    mali_ptr address;
99*61046927SAndroid Build Coastguard Worker    unsigned blend_ret_offsets[8];
100*61046927SAndroid Build Coastguard Worker    nir_alu_type blend_types[8];
101*61046927SAndroid Build Coastguard Worker };
102*61046927SAndroid Build Coastguard Worker 
103*61046927SAndroid Build Coastguard Worker struct pan_blit_blend_shader_key {
104*61046927SAndroid Build Coastguard Worker    enum pipe_format format;
105*61046927SAndroid Build Coastguard Worker    nir_alu_type type;
106*61046927SAndroid Build Coastguard Worker    unsigned rt         : 3;
107*61046927SAndroid Build Coastguard Worker    unsigned nr_samples : 5;
108*61046927SAndroid Build Coastguard Worker    unsigned pad        : 24;
109*61046927SAndroid Build Coastguard Worker };
110*61046927SAndroid Build Coastguard Worker 
111*61046927SAndroid Build Coastguard Worker struct pan_blit_blend_shader_data {
112*61046927SAndroid Build Coastguard Worker    struct pan_blit_blend_shader_key key;
113*61046927SAndroid Build Coastguard Worker    mali_ptr address;
114*61046927SAndroid Build Coastguard Worker };
115*61046927SAndroid Build Coastguard Worker 
116*61046927SAndroid Build Coastguard Worker struct pan_blit_rsd_key {
117*61046927SAndroid Build Coastguard Worker    struct {
118*61046927SAndroid Build Coastguard Worker       enum pipe_format format;
119*61046927SAndroid Build Coastguard Worker       nir_alu_type type               : 8;
120*61046927SAndroid Build Coastguard Worker       unsigned src_samples            : 5;
121*61046927SAndroid Build Coastguard Worker       unsigned dst_samples            : 5;
122*61046927SAndroid Build Coastguard Worker       enum mali_texture_dimension dim : 2;
123*61046927SAndroid Build Coastguard Worker       bool array                      : 1;
124*61046927SAndroid Build Coastguard Worker    } rts[8], z, s;
125*61046927SAndroid Build Coastguard Worker };
126*61046927SAndroid Build Coastguard Worker 
127*61046927SAndroid Build Coastguard Worker struct pan_blit_rsd_data {
128*61046927SAndroid Build Coastguard Worker    struct pan_blit_rsd_key key;
129*61046927SAndroid Build Coastguard Worker    mali_ptr address;
130*61046927SAndroid Build Coastguard Worker };
131*61046927SAndroid Build Coastguard Worker 
132*61046927SAndroid Build Coastguard Worker #if PAN_ARCH >= 5
133*61046927SAndroid Build Coastguard Worker static void
pan_blitter_emit_blend(unsigned rt,const struct pan_image_view * iview,const struct pan_blit_shader_data * blit_shader,mali_ptr blend_shader,void * out)134*61046927SAndroid Build Coastguard Worker pan_blitter_emit_blend(unsigned rt,
135*61046927SAndroid Build Coastguard Worker                        const struct pan_image_view *iview,
136*61046927SAndroid Build Coastguard Worker                        const struct pan_blit_shader_data *blit_shader,
137*61046927SAndroid Build Coastguard Worker                        mali_ptr blend_shader, void *out)
138*61046927SAndroid Build Coastguard Worker {
139*61046927SAndroid Build Coastguard Worker    assert(blend_shader == 0 || PAN_ARCH <= 5);
140*61046927SAndroid Build Coastguard Worker 
141*61046927SAndroid Build Coastguard Worker    pan_pack(out, BLEND, cfg) {
142*61046927SAndroid Build Coastguard Worker       if (!iview) {
143*61046927SAndroid Build Coastguard Worker          cfg.enable = false;
144*61046927SAndroid Build Coastguard Worker #if PAN_ARCH >= 6
145*61046927SAndroid Build Coastguard Worker          cfg.internal.mode = MALI_BLEND_MODE_OFF;
146*61046927SAndroid Build Coastguard Worker #endif
147*61046927SAndroid Build Coastguard Worker          continue;
148*61046927SAndroid Build Coastguard Worker       }
149*61046927SAndroid Build Coastguard Worker 
150*61046927SAndroid Build Coastguard Worker       cfg.round_to_fb_precision = true;
151*61046927SAndroid Build Coastguard Worker       cfg.srgb = util_format_is_srgb(iview->format);
152*61046927SAndroid Build Coastguard Worker 
153*61046927SAndroid Build Coastguard Worker #if PAN_ARCH >= 6
154*61046927SAndroid Build Coastguard Worker       cfg.internal.mode = MALI_BLEND_MODE_OPAQUE;
155*61046927SAndroid Build Coastguard Worker #endif
156*61046927SAndroid Build Coastguard Worker 
157*61046927SAndroid Build Coastguard Worker       if (!blend_shader) {
158*61046927SAndroid Build Coastguard Worker          cfg.equation.rgb.a = MALI_BLEND_OPERAND_A_SRC;
159*61046927SAndroid Build Coastguard Worker          cfg.equation.rgb.b = MALI_BLEND_OPERAND_B_SRC;
160*61046927SAndroid Build Coastguard Worker          cfg.equation.rgb.c = MALI_BLEND_OPERAND_C_ZERO;
161*61046927SAndroid Build Coastguard Worker          cfg.equation.alpha.a = MALI_BLEND_OPERAND_A_SRC;
162*61046927SAndroid Build Coastguard Worker          cfg.equation.alpha.b = MALI_BLEND_OPERAND_B_SRC;
163*61046927SAndroid Build Coastguard Worker          cfg.equation.alpha.c = MALI_BLEND_OPERAND_C_ZERO;
164*61046927SAndroid Build Coastguard Worker          cfg.equation.color_mask = 0xf;
165*61046927SAndroid Build Coastguard Worker 
166*61046927SAndroid Build Coastguard Worker #if PAN_ARCH >= 6
167*61046927SAndroid Build Coastguard Worker          nir_alu_type type = blit_shader->key.surfaces[rt].type;
168*61046927SAndroid Build Coastguard Worker 
169*61046927SAndroid Build Coastguard Worker          cfg.internal.fixed_function.num_comps = 4;
170*61046927SAndroid Build Coastguard Worker          cfg.internal.fixed_function.conversion.memory_format = GENX(
171*61046927SAndroid Build Coastguard Worker             panfrost_dithered_format_from_pipe_format)(iview->format, false);
172*61046927SAndroid Build Coastguard Worker          cfg.internal.fixed_function.conversion.register_format =
173*61046927SAndroid Build Coastguard Worker             blit_type_to_reg_fmt(type);
174*61046927SAndroid Build Coastguard Worker 
175*61046927SAndroid Build Coastguard Worker          cfg.internal.fixed_function.rt = rt;
176*61046927SAndroid Build Coastguard Worker #endif
177*61046927SAndroid Build Coastguard Worker       } else {
178*61046927SAndroid Build Coastguard Worker #if PAN_ARCH <= 5
179*61046927SAndroid Build Coastguard Worker          cfg.blend_shader = true;
180*61046927SAndroid Build Coastguard Worker          cfg.shader_pc = blend_shader;
181*61046927SAndroid Build Coastguard Worker #endif
182*61046927SAndroid Build Coastguard Worker       }
183*61046927SAndroid Build Coastguard Worker    }
184*61046927SAndroid Build Coastguard Worker }
185*61046927SAndroid Build Coastguard Worker #endif
186*61046927SAndroid Build Coastguard Worker 
187*61046927SAndroid Build Coastguard Worker struct pan_blitter_views {
188*61046927SAndroid Build Coastguard Worker    unsigned rt_count;
189*61046927SAndroid Build Coastguard Worker    const struct pan_image_view *src_rts[8];
190*61046927SAndroid Build Coastguard Worker    const struct pan_image_view *dst_rts[8];
191*61046927SAndroid Build Coastguard Worker    const struct pan_image_view *src_z;
192*61046927SAndroid Build Coastguard Worker    const struct pan_image_view *dst_z;
193*61046927SAndroid Build Coastguard Worker    const struct pan_image_view *src_s;
194*61046927SAndroid Build Coastguard Worker    const struct pan_image_view *dst_s;
195*61046927SAndroid Build Coastguard Worker };
196*61046927SAndroid Build Coastguard Worker 
197*61046927SAndroid Build Coastguard Worker static bool
pan_blitter_is_ms(struct pan_blitter_views * views)198*61046927SAndroid Build Coastguard Worker pan_blitter_is_ms(struct pan_blitter_views *views)
199*61046927SAndroid Build Coastguard Worker {
200*61046927SAndroid Build Coastguard Worker    for (unsigned i = 0; i < views->rt_count; i++) {
201*61046927SAndroid Build Coastguard Worker       if (views->dst_rts[i]) {
202*61046927SAndroid Build Coastguard Worker          if (pan_image_view_get_nr_samples(views->dst_rts[i]) > 1)
203*61046927SAndroid Build Coastguard Worker             return true;
204*61046927SAndroid Build Coastguard Worker       }
205*61046927SAndroid Build Coastguard Worker    }
206*61046927SAndroid Build Coastguard Worker 
207*61046927SAndroid Build Coastguard Worker    if (views->dst_z && pan_image_view_get_nr_samples(views->dst_z) > 1)
208*61046927SAndroid Build Coastguard Worker       return true;
209*61046927SAndroid Build Coastguard Worker 
210*61046927SAndroid Build Coastguard Worker    if (views->dst_s && pan_image_view_get_nr_samples(views->dst_s) > 1)
211*61046927SAndroid Build Coastguard Worker       return true;
212*61046927SAndroid Build Coastguard Worker 
213*61046927SAndroid Build Coastguard Worker    return false;
214*61046927SAndroid Build Coastguard Worker }
215*61046927SAndroid Build Coastguard Worker 
216*61046927SAndroid Build Coastguard Worker #if PAN_ARCH >= 5
217*61046927SAndroid Build Coastguard Worker static void
pan_blitter_emit_blends(const struct pan_blit_shader_data * blit_shader,struct pan_blitter_views * views,mali_ptr * blend_shaders,void * out)218*61046927SAndroid Build Coastguard Worker pan_blitter_emit_blends(const struct pan_blit_shader_data *blit_shader,
219*61046927SAndroid Build Coastguard Worker                         struct pan_blitter_views *views,
220*61046927SAndroid Build Coastguard Worker                         mali_ptr *blend_shaders, void *out)
221*61046927SAndroid Build Coastguard Worker {
222*61046927SAndroid Build Coastguard Worker    for (unsigned i = 0; i < MAX2(views->rt_count, 1); ++i) {
223*61046927SAndroid Build Coastguard Worker       void *dest = out + pan_size(BLEND) * i;
224*61046927SAndroid Build Coastguard Worker       const struct pan_image_view *rt_view = views->dst_rts[i];
225*61046927SAndroid Build Coastguard Worker       mali_ptr blend_shader = blend_shaders ? blend_shaders[i] : 0;
226*61046927SAndroid Build Coastguard Worker 
227*61046927SAndroid Build Coastguard Worker       pan_blitter_emit_blend(i, rt_view, blit_shader, blend_shader, dest);
228*61046927SAndroid Build Coastguard Worker    }
229*61046927SAndroid Build Coastguard Worker }
230*61046927SAndroid Build Coastguard Worker #endif
231*61046927SAndroid Build Coastguard Worker 
232*61046927SAndroid Build Coastguard Worker #if PAN_ARCH <= 7
233*61046927SAndroid Build Coastguard Worker static void
pan_blitter_emit_rsd(const struct pan_blit_shader_data * blit_shader,struct pan_blitter_views * views,mali_ptr * blend_shaders,void * out)234*61046927SAndroid Build Coastguard Worker pan_blitter_emit_rsd(const struct pan_blit_shader_data *blit_shader,
235*61046927SAndroid Build Coastguard Worker                      struct pan_blitter_views *views, mali_ptr *blend_shaders,
236*61046927SAndroid Build Coastguard Worker                      void *out)
237*61046927SAndroid Build Coastguard Worker {
238*61046927SAndroid Build Coastguard Worker    UNUSED bool zs = (views->dst_z || views->dst_s);
239*61046927SAndroid Build Coastguard Worker    bool ms = pan_blitter_is_ms(views);
240*61046927SAndroid Build Coastguard Worker 
241*61046927SAndroid Build Coastguard Worker    pan_pack(out, RENDERER_STATE, cfg) {
242*61046927SAndroid Build Coastguard Worker       assert(blit_shader->address);
243*61046927SAndroid Build Coastguard Worker       pan_shader_prepare_rsd(&blit_shader->info, blit_shader->address, &cfg);
244*61046927SAndroid Build Coastguard Worker 
245*61046927SAndroid Build Coastguard Worker       cfg.multisample_misc.sample_mask = 0xFFFF;
246*61046927SAndroid Build Coastguard Worker       cfg.multisample_misc.multisample_enable = ms;
247*61046927SAndroid Build Coastguard Worker       cfg.multisample_misc.evaluate_per_sample = ms;
248*61046927SAndroid Build Coastguard Worker       cfg.multisample_misc.depth_write_mask = views->dst_z != NULL;
249*61046927SAndroid Build Coastguard Worker       cfg.multisample_misc.depth_function = MALI_FUNC_ALWAYS;
250*61046927SAndroid Build Coastguard Worker 
251*61046927SAndroid Build Coastguard Worker       cfg.stencil_mask_misc.stencil_enable = views->dst_s != NULL;
252*61046927SAndroid Build Coastguard Worker       cfg.stencil_mask_misc.stencil_mask_front = 0xFF;
253*61046927SAndroid Build Coastguard Worker       cfg.stencil_mask_misc.stencil_mask_back = 0xFF;
254*61046927SAndroid Build Coastguard Worker       cfg.stencil_front.compare_function = MALI_FUNC_ALWAYS;
255*61046927SAndroid Build Coastguard Worker       cfg.stencil_front.stencil_fail = MALI_STENCIL_OP_REPLACE;
256*61046927SAndroid Build Coastguard Worker       cfg.stencil_front.depth_fail = MALI_STENCIL_OP_REPLACE;
257*61046927SAndroid Build Coastguard Worker       cfg.stencil_front.depth_pass = MALI_STENCIL_OP_REPLACE;
258*61046927SAndroid Build Coastguard Worker       cfg.stencil_front.mask = 0xFF;
259*61046927SAndroid Build Coastguard Worker       cfg.stencil_back = cfg.stencil_front;
260*61046927SAndroid Build Coastguard Worker 
261*61046927SAndroid Build Coastguard Worker #if PAN_ARCH >= 6
262*61046927SAndroid Build Coastguard Worker       if (zs) {
263*61046927SAndroid Build Coastguard Worker          /* Writing Z/S requires late updates */
264*61046927SAndroid Build Coastguard Worker          cfg.properties.zs_update_operation = MALI_PIXEL_KILL_FORCE_LATE;
265*61046927SAndroid Build Coastguard Worker          cfg.properties.pixel_kill_operation = MALI_PIXEL_KILL_FORCE_LATE;
266*61046927SAndroid Build Coastguard Worker       } else {
267*61046927SAndroid Build Coastguard Worker          /* Skipping ATEST requires forcing Z/S */
268*61046927SAndroid Build Coastguard Worker          cfg.properties.zs_update_operation = MALI_PIXEL_KILL_STRONG_EARLY;
269*61046927SAndroid Build Coastguard Worker          cfg.properties.pixel_kill_operation = MALI_PIXEL_KILL_FORCE_EARLY;
270*61046927SAndroid Build Coastguard Worker       }
271*61046927SAndroid Build Coastguard Worker 
272*61046927SAndroid Build Coastguard Worker       /* However, while shaders writing Z/S can normally be killed, on v6
273*61046927SAndroid Build Coastguard Worker        * for frame shaders it can cause GPU timeouts, so only allow colour
274*61046927SAndroid Build Coastguard Worker        * blit shaders to be killed. */
275*61046927SAndroid Build Coastguard Worker       cfg.properties.allow_forward_pixel_to_kill = !zs;
276*61046927SAndroid Build Coastguard Worker 
277*61046927SAndroid Build Coastguard Worker       if (PAN_ARCH == 6)
278*61046927SAndroid Build Coastguard Worker          cfg.properties.allow_forward_pixel_to_be_killed = !zs;
279*61046927SAndroid Build Coastguard Worker #else
280*61046927SAndroid Build Coastguard Worker 
281*61046927SAndroid Build Coastguard Worker       mali_ptr blend_shader =
282*61046927SAndroid Build Coastguard Worker          blend_shaders
283*61046927SAndroid Build Coastguard Worker             ? panfrost_last_nonnull(blend_shaders, MAX2(views->rt_count, 1))
284*61046927SAndroid Build Coastguard Worker             : 0;
285*61046927SAndroid Build Coastguard Worker 
286*61046927SAndroid Build Coastguard Worker       cfg.properties.work_register_count = 4;
287*61046927SAndroid Build Coastguard Worker       cfg.properties.force_early_z = !zs;
288*61046927SAndroid Build Coastguard Worker       cfg.stencil_mask_misc.alpha_test_compare_function = MALI_FUNC_ALWAYS;
289*61046927SAndroid Build Coastguard Worker 
290*61046927SAndroid Build Coastguard Worker       /* Set even on v5 for erratum workaround */
291*61046927SAndroid Build Coastguard Worker #if PAN_ARCH == 5
292*61046927SAndroid Build Coastguard Worker       cfg.legacy_blend_shader = blend_shader;
293*61046927SAndroid Build Coastguard Worker #else
294*61046927SAndroid Build Coastguard Worker       cfg.blend_shader = blend_shader;
295*61046927SAndroid Build Coastguard Worker       cfg.stencil_mask_misc.write_enable = true;
296*61046927SAndroid Build Coastguard Worker       cfg.stencil_mask_misc.dither_disable = true;
297*61046927SAndroid Build Coastguard Worker       cfg.multisample_misc.blend_shader = !!blend_shader;
298*61046927SAndroid Build Coastguard Worker       cfg.blend_shader = blend_shader;
299*61046927SAndroid Build Coastguard Worker       if (!cfg.multisample_misc.blend_shader) {
300*61046927SAndroid Build Coastguard Worker          cfg.blend_equation.rgb.a = MALI_BLEND_OPERAND_A_SRC;
301*61046927SAndroid Build Coastguard Worker          cfg.blend_equation.rgb.b = MALI_BLEND_OPERAND_B_SRC;
302*61046927SAndroid Build Coastguard Worker          cfg.blend_equation.rgb.c = MALI_BLEND_OPERAND_C_ZERO;
303*61046927SAndroid Build Coastguard Worker          cfg.blend_equation.alpha.a = MALI_BLEND_OPERAND_A_SRC;
304*61046927SAndroid Build Coastguard Worker          cfg.blend_equation.alpha.b = MALI_BLEND_OPERAND_B_SRC;
305*61046927SAndroid Build Coastguard Worker          cfg.blend_equation.alpha.c = MALI_BLEND_OPERAND_C_ZERO;
306*61046927SAndroid Build Coastguard Worker          cfg.blend_constant = 0;
307*61046927SAndroid Build Coastguard Worker 
308*61046927SAndroid Build Coastguard Worker          if (views->dst_rts[0] != NULL) {
309*61046927SAndroid Build Coastguard Worker             cfg.stencil_mask_misc.srgb =
310*61046927SAndroid Build Coastguard Worker                util_format_is_srgb(views->dst_rts[0]->format);
311*61046927SAndroid Build Coastguard Worker             cfg.blend_equation.color_mask = 0xf;
312*61046927SAndroid Build Coastguard Worker          }
313*61046927SAndroid Build Coastguard Worker       }
314*61046927SAndroid Build Coastguard Worker #endif
315*61046927SAndroid Build Coastguard Worker #endif
316*61046927SAndroid Build Coastguard Worker    }
317*61046927SAndroid Build Coastguard Worker 
318*61046927SAndroid Build Coastguard Worker #if PAN_ARCH >= 5
319*61046927SAndroid Build Coastguard Worker    pan_blitter_emit_blends(blit_shader, views, blend_shaders,
320*61046927SAndroid Build Coastguard Worker                            out + pan_size(RENDERER_STATE));
321*61046927SAndroid Build Coastguard Worker #endif
322*61046927SAndroid Build Coastguard Worker }
323*61046927SAndroid Build Coastguard Worker #endif
324*61046927SAndroid Build Coastguard Worker 
325*61046927SAndroid Build Coastguard Worker #if PAN_ARCH <= 5
326*61046927SAndroid Build Coastguard Worker static void
pan_blitter_get_blend_shaders(struct pan_blitter_cache * cache,unsigned rt_count,const struct pan_image_view ** rts,const struct pan_blit_shader_data * blit_shader,mali_ptr * blend_shaders)327*61046927SAndroid Build Coastguard Worker pan_blitter_get_blend_shaders(struct pan_blitter_cache *cache,
328*61046927SAndroid Build Coastguard Worker                               unsigned rt_count,
329*61046927SAndroid Build Coastguard Worker                               const struct pan_image_view **rts,
330*61046927SAndroid Build Coastguard Worker                               const struct pan_blit_shader_data *blit_shader,
331*61046927SAndroid Build Coastguard Worker                               mali_ptr *blend_shaders)
332*61046927SAndroid Build Coastguard Worker {
333*61046927SAndroid Build Coastguard Worker    if (!rt_count)
334*61046927SAndroid Build Coastguard Worker       return;
335*61046927SAndroid Build Coastguard Worker 
336*61046927SAndroid Build Coastguard Worker    struct pan_blend_state blend_state = {
337*61046927SAndroid Build Coastguard Worker       .rt_count = rt_count,
338*61046927SAndroid Build Coastguard Worker    };
339*61046927SAndroid Build Coastguard Worker 
340*61046927SAndroid Build Coastguard Worker    for (unsigned i = 0; i < rt_count; i++) {
341*61046927SAndroid Build Coastguard Worker       if (!rts[i] || panfrost_blendable_formats_v7[rts[i]->format].internal)
342*61046927SAndroid Build Coastguard Worker          continue;
343*61046927SAndroid Build Coastguard Worker 
344*61046927SAndroid Build Coastguard Worker       struct pan_blit_blend_shader_key key = {
345*61046927SAndroid Build Coastguard Worker          .format = rts[i]->format,
346*61046927SAndroid Build Coastguard Worker          .rt = i,
347*61046927SAndroid Build Coastguard Worker          .nr_samples = pan_image_view_get_nr_samples(rts[i]),
348*61046927SAndroid Build Coastguard Worker          .type = blit_shader->blend_types[i],
349*61046927SAndroid Build Coastguard Worker       };
350*61046927SAndroid Build Coastguard Worker 
351*61046927SAndroid Build Coastguard Worker       pthread_mutex_lock(&cache->shaders.lock);
352*61046927SAndroid Build Coastguard Worker       struct hash_entry *he =
353*61046927SAndroid Build Coastguard Worker          _mesa_hash_table_search(cache->shaders.blend, &key);
354*61046927SAndroid Build Coastguard Worker       struct pan_blit_blend_shader_data *blend_shader = he ? he->data : NULL;
355*61046927SAndroid Build Coastguard Worker       if (blend_shader) {
356*61046927SAndroid Build Coastguard Worker          blend_shaders[i] = blend_shader->address;
357*61046927SAndroid Build Coastguard Worker          pthread_mutex_unlock(&cache->shaders.lock);
358*61046927SAndroid Build Coastguard Worker          continue;
359*61046927SAndroid Build Coastguard Worker       }
360*61046927SAndroid Build Coastguard Worker 
361*61046927SAndroid Build Coastguard Worker       blend_shader =
362*61046927SAndroid Build Coastguard Worker          rzalloc(cache->shaders.blend, struct pan_blit_blend_shader_data);
363*61046927SAndroid Build Coastguard Worker       blend_shader->key = key;
364*61046927SAndroid Build Coastguard Worker 
365*61046927SAndroid Build Coastguard Worker       blend_state.rts[i] = (struct pan_blend_rt_state){
366*61046927SAndroid Build Coastguard Worker          .format = rts[i]->format,
367*61046927SAndroid Build Coastguard Worker          .nr_samples = pan_image_view_get_nr_samples(rts[i]),
368*61046927SAndroid Build Coastguard Worker          .equation =
369*61046927SAndroid Build Coastguard Worker             {
370*61046927SAndroid Build Coastguard Worker                .blend_enable = false,
371*61046927SAndroid Build Coastguard Worker                .color_mask = 0xf,
372*61046927SAndroid Build Coastguard Worker             },
373*61046927SAndroid Build Coastguard Worker       };
374*61046927SAndroid Build Coastguard Worker 
375*61046927SAndroid Build Coastguard Worker       pthread_mutex_lock(&cache->blend_shader_cache->lock);
376*61046927SAndroid Build Coastguard Worker       struct pan_blend_shader_variant *b = GENX(pan_blend_get_shader_locked)(
377*61046927SAndroid Build Coastguard Worker          cache->blend_shader_cache, &blend_state, blit_shader->blend_types[i],
378*61046927SAndroid Build Coastguard Worker          nir_type_float32, /* unused */
379*61046927SAndroid Build Coastguard Worker          i);
380*61046927SAndroid Build Coastguard Worker 
381*61046927SAndroid Build Coastguard Worker       assert(b->work_reg_count <= 4);
382*61046927SAndroid Build Coastguard Worker       struct panfrost_ptr bin =
383*61046927SAndroid Build Coastguard Worker          pan_pool_alloc_aligned(cache->shaders.pool, b->binary.size, 64);
384*61046927SAndroid Build Coastguard Worker       memcpy(bin.cpu, b->binary.data, b->binary.size);
385*61046927SAndroid Build Coastguard Worker 
386*61046927SAndroid Build Coastguard Worker       blend_shader->address = bin.gpu | b->first_tag;
387*61046927SAndroid Build Coastguard Worker       pthread_mutex_unlock(&cache->blend_shader_cache->lock);
388*61046927SAndroid Build Coastguard Worker       _mesa_hash_table_insert(cache->shaders.blend, &blend_shader->key,
389*61046927SAndroid Build Coastguard Worker                               blend_shader);
390*61046927SAndroid Build Coastguard Worker       pthread_mutex_unlock(&cache->shaders.lock);
391*61046927SAndroid Build Coastguard Worker       blend_shaders[i] = blend_shader->address;
392*61046927SAndroid Build Coastguard Worker    }
393*61046927SAndroid Build Coastguard Worker }
394*61046927SAndroid Build Coastguard Worker #endif
395*61046927SAndroid Build Coastguard Worker 
396*61046927SAndroid Build Coastguard Worker /*
397*61046927SAndroid Build Coastguard Worker  * Early Mali GPUs did not respect sampler LOD clamps or bias, so the Midgard
398*61046927SAndroid Build Coastguard Worker  * compiler inserts lowering code with a load_sampler_lod_parameters_pan sysval
399*61046927SAndroid Build Coastguard Worker  * that we need to lower. Our samplers do not use LOD clamps or bias, so we
400*61046927SAndroid Build Coastguard Worker  * lower to the identity settings and let constant folding get rid of the
401*61046927SAndroid Build Coastguard Worker  * unnecessary lowering.
402*61046927SAndroid Build Coastguard Worker  */
403*61046927SAndroid Build Coastguard Worker static bool
lower_sampler_parameters(nir_builder * b,nir_intrinsic_instr * intr,UNUSED void * data)404*61046927SAndroid Build Coastguard Worker lower_sampler_parameters(nir_builder *b, nir_intrinsic_instr *intr,
405*61046927SAndroid Build Coastguard Worker                          UNUSED void *data)
406*61046927SAndroid Build Coastguard Worker {
407*61046927SAndroid Build Coastguard Worker    if (intr->intrinsic != nir_intrinsic_load_sampler_lod_parameters_pan)
408*61046927SAndroid Build Coastguard Worker       return false;
409*61046927SAndroid Build Coastguard Worker 
410*61046927SAndroid Build Coastguard Worker    const nir_const_value constants[4] = {
411*61046927SAndroid Build Coastguard Worker       nir_const_value_for_float(0.0f, 32),     /* min_lod */
412*61046927SAndroid Build Coastguard Worker       nir_const_value_for_float(INFINITY, 32), /* max_lod */
413*61046927SAndroid Build Coastguard Worker       nir_const_value_for_float(0.0f, 32),     /* lod_bias */
414*61046927SAndroid Build Coastguard Worker    };
415*61046927SAndroid Build Coastguard Worker 
416*61046927SAndroid Build Coastguard Worker    b->cursor = nir_after_instr(&intr->instr);
417*61046927SAndroid Build Coastguard Worker    nir_def_rewrite_uses(&intr->def, nir_build_imm(b, 3, 32, constants));
418*61046927SAndroid Build Coastguard Worker    return true;
419*61046927SAndroid Build Coastguard Worker }
420*61046927SAndroid Build Coastguard Worker 
421*61046927SAndroid Build Coastguard Worker static uint32_t
sampler_hw_index(uint32_t index)422*61046927SAndroid Build Coastguard Worker sampler_hw_index(uint32_t index)
423*61046927SAndroid Build Coastguard Worker {
424*61046927SAndroid Build Coastguard Worker    return PAN_ARCH >= 9 ? pan_res_handle(PAN_BLIT_TABLE_SAMPLER, index) : index;
425*61046927SAndroid Build Coastguard Worker }
426*61046927SAndroid Build Coastguard Worker 
427*61046927SAndroid Build Coastguard Worker static uint32_t
tex_hw_index(uint32_t index)428*61046927SAndroid Build Coastguard Worker tex_hw_index(uint32_t index)
429*61046927SAndroid Build Coastguard Worker {
430*61046927SAndroid Build Coastguard Worker    return PAN_ARCH >= 9 ? pan_res_handle(PAN_BLIT_TABLE_TEXTURE, index) : index;
431*61046927SAndroid Build Coastguard Worker }
432*61046927SAndroid Build Coastguard Worker 
433*61046927SAndroid Build Coastguard Worker static uint32_t
attr_hw_index(uint32_t index)434*61046927SAndroid Build Coastguard Worker attr_hw_index(uint32_t index)
435*61046927SAndroid Build Coastguard Worker {
436*61046927SAndroid Build Coastguard Worker    return PAN_ARCH >= 9 ? pan_res_handle(PAN_BLIT_TABLE_ATTRIBUTE, index)
437*61046927SAndroid Build Coastguard Worker                         : index;
438*61046927SAndroid Build Coastguard Worker }
439*61046927SAndroid Build Coastguard Worker 
440*61046927SAndroid Build Coastguard Worker static const struct pan_blit_shader_data *
pan_blitter_get_blit_shader(struct pan_blitter_cache * cache,const struct pan_blit_shader_key * key)441*61046927SAndroid Build Coastguard Worker pan_blitter_get_blit_shader(struct pan_blitter_cache *cache,
442*61046927SAndroid Build Coastguard Worker                             const struct pan_blit_shader_key *key)
443*61046927SAndroid Build Coastguard Worker {
444*61046927SAndroid Build Coastguard Worker    pthread_mutex_lock(&cache->shaders.lock);
445*61046927SAndroid Build Coastguard Worker    struct hash_entry *he =
446*61046927SAndroid Build Coastguard Worker       _mesa_hash_table_search(cache->shaders.blit, key);
447*61046927SAndroid Build Coastguard Worker    struct pan_blit_shader_data *shader = he ? he->data : NULL;
448*61046927SAndroid Build Coastguard Worker 
449*61046927SAndroid Build Coastguard Worker    if (shader)
450*61046927SAndroid Build Coastguard Worker       goto out;
451*61046927SAndroid Build Coastguard Worker 
452*61046927SAndroid Build Coastguard Worker    unsigned coord_comps = 0;
453*61046927SAndroid Build Coastguard Worker    unsigned sig_offset = 0;
454*61046927SAndroid Build Coastguard Worker    char sig[256];
455*61046927SAndroid Build Coastguard Worker    bool first = true;
456*61046927SAndroid Build Coastguard Worker    for (unsigned i = 0; i < ARRAY_SIZE(key->surfaces); i++) {
457*61046927SAndroid Build Coastguard Worker       const char *type_str, *dim_str;
458*61046927SAndroid Build Coastguard Worker       if (key->surfaces[i].type == nir_type_invalid)
459*61046927SAndroid Build Coastguard Worker          continue;
460*61046927SAndroid Build Coastguard Worker 
461*61046927SAndroid Build Coastguard Worker       switch (key->surfaces[i].type) {
462*61046927SAndroid Build Coastguard Worker       case nir_type_float32:
463*61046927SAndroid Build Coastguard Worker          type_str = "float";
464*61046927SAndroid Build Coastguard Worker          break;
465*61046927SAndroid Build Coastguard Worker       case nir_type_uint32:
466*61046927SAndroid Build Coastguard Worker          type_str = "uint";
467*61046927SAndroid Build Coastguard Worker          break;
468*61046927SAndroid Build Coastguard Worker       case nir_type_int32:
469*61046927SAndroid Build Coastguard Worker          type_str = "int";
470*61046927SAndroid Build Coastguard Worker          break;
471*61046927SAndroid Build Coastguard Worker       default:
472*61046927SAndroid Build Coastguard Worker          unreachable("Invalid type\n");
473*61046927SAndroid Build Coastguard Worker       }
474*61046927SAndroid Build Coastguard Worker 
475*61046927SAndroid Build Coastguard Worker       switch (key->surfaces[i].dim) {
476*61046927SAndroid Build Coastguard Worker       case MALI_TEXTURE_DIMENSION_CUBE:
477*61046927SAndroid Build Coastguard Worker          dim_str = "cube";
478*61046927SAndroid Build Coastguard Worker          break;
479*61046927SAndroid Build Coastguard Worker       case MALI_TEXTURE_DIMENSION_1D:
480*61046927SAndroid Build Coastguard Worker          dim_str = "1D";
481*61046927SAndroid Build Coastguard Worker          break;
482*61046927SAndroid Build Coastguard Worker       case MALI_TEXTURE_DIMENSION_2D:
483*61046927SAndroid Build Coastguard Worker          dim_str = "2D";
484*61046927SAndroid Build Coastguard Worker          break;
485*61046927SAndroid Build Coastguard Worker       case MALI_TEXTURE_DIMENSION_3D:
486*61046927SAndroid Build Coastguard Worker          dim_str = "3D";
487*61046927SAndroid Build Coastguard Worker          break;
488*61046927SAndroid Build Coastguard Worker       default:
489*61046927SAndroid Build Coastguard Worker          unreachable("Invalid dim\n");
490*61046927SAndroid Build Coastguard Worker       }
491*61046927SAndroid Build Coastguard Worker 
492*61046927SAndroid Build Coastguard Worker       coord_comps = MAX2(coord_comps, (key->surfaces[i].dim ?: 3) +
493*61046927SAndroid Build Coastguard Worker                                          (key->surfaces[i].array ? 1 : 0));
494*61046927SAndroid Build Coastguard Worker 
495*61046927SAndroid Build Coastguard Worker       if (sig_offset >= sizeof(sig)) {
496*61046927SAndroid Build Coastguard Worker          first = false;
497*61046927SAndroid Build Coastguard Worker          continue;
498*61046927SAndroid Build Coastguard Worker       }
499*61046927SAndroid Build Coastguard Worker 
500*61046927SAndroid Build Coastguard Worker       sig_offset +=
501*61046927SAndroid Build Coastguard Worker          snprintf(sig + sig_offset, sizeof(sig) - sig_offset,
502*61046927SAndroid Build Coastguard Worker                   "%s[%s;%s;%s%s;src_samples=%d,dst_samples=%d]",
503*61046927SAndroid Build Coastguard Worker                   first ? "" : ",", gl_frag_result_name(key->surfaces[i].loc),
504*61046927SAndroid Build Coastguard Worker                   type_str, dim_str, key->surfaces[i].array ? "[]" : "",
505*61046927SAndroid Build Coastguard Worker                   key->surfaces[i].src_samples, key->surfaces[i].dst_samples);
506*61046927SAndroid Build Coastguard Worker 
507*61046927SAndroid Build Coastguard Worker       first = false;
508*61046927SAndroid Build Coastguard Worker    }
509*61046927SAndroid Build Coastguard Worker 
510*61046927SAndroid Build Coastguard Worker    nir_builder b = nir_builder_init_simple_shader(
511*61046927SAndroid Build Coastguard Worker       MESA_SHADER_FRAGMENT, GENX(pan_shader_get_compiler_options)(),
512*61046927SAndroid Build Coastguard Worker       "pan_blit(%s)", sig);
513*61046927SAndroid Build Coastguard Worker 
514*61046927SAndroid Build Coastguard Worker    nir_def *barycentric = nir_load_barycentric(
515*61046927SAndroid Build Coastguard Worker       &b, nir_intrinsic_load_barycentric_pixel, INTERP_MODE_SMOOTH);
516*61046927SAndroid Build Coastguard Worker    nir_def *coord = nir_load_interpolated_input(
517*61046927SAndroid Build Coastguard Worker       &b, coord_comps, 32, barycentric, nir_imm_int(&b, 0),
518*61046927SAndroid Build Coastguard Worker       .base = attr_hw_index(0), .dest_type = nir_type_float32,
519*61046927SAndroid Build Coastguard Worker       .io_semantics.location = VARYING_SLOT_VAR0, .io_semantics.num_slots = 1);
520*61046927SAndroid Build Coastguard Worker 
521*61046927SAndroid Build Coastguard Worker    unsigned active_count = 0;
522*61046927SAndroid Build Coastguard Worker    for (unsigned i = 0; i < ARRAY_SIZE(key->surfaces); i++) {
523*61046927SAndroid Build Coastguard Worker       if (key->surfaces[i].type == nir_type_invalid)
524*61046927SAndroid Build Coastguard Worker          continue;
525*61046927SAndroid Build Coastguard Worker 
526*61046927SAndroid Build Coastguard Worker       /* Resolve operations only work for N -> 1 samples. */
527*61046927SAndroid Build Coastguard Worker       assert(key->surfaces[i].dst_samples == 1 ||
528*61046927SAndroid Build Coastguard Worker              key->surfaces[i].src_samples == key->surfaces[i].dst_samples);
529*61046927SAndroid Build Coastguard Worker 
530*61046927SAndroid Build Coastguard Worker       bool resolve =
531*61046927SAndroid Build Coastguard Worker          key->surfaces[i].src_samples > key->surfaces[i].dst_samples;
532*61046927SAndroid Build Coastguard Worker       bool ms = key->surfaces[i].src_samples > 1;
533*61046927SAndroid Build Coastguard Worker       enum glsl_sampler_dim sampler_dim;
534*61046927SAndroid Build Coastguard Worker 
535*61046927SAndroid Build Coastguard Worker       switch (key->surfaces[i].dim) {
536*61046927SAndroid Build Coastguard Worker       case MALI_TEXTURE_DIMENSION_1D:
537*61046927SAndroid Build Coastguard Worker          sampler_dim = GLSL_SAMPLER_DIM_1D;
538*61046927SAndroid Build Coastguard Worker          break;
539*61046927SAndroid Build Coastguard Worker       case MALI_TEXTURE_DIMENSION_2D:
540*61046927SAndroid Build Coastguard Worker          sampler_dim = ms ? GLSL_SAMPLER_DIM_MS : GLSL_SAMPLER_DIM_2D;
541*61046927SAndroid Build Coastguard Worker          break;
542*61046927SAndroid Build Coastguard Worker       case MALI_TEXTURE_DIMENSION_3D:
543*61046927SAndroid Build Coastguard Worker          sampler_dim = GLSL_SAMPLER_DIM_3D;
544*61046927SAndroid Build Coastguard Worker          break;
545*61046927SAndroid Build Coastguard Worker       case MALI_TEXTURE_DIMENSION_CUBE:
546*61046927SAndroid Build Coastguard Worker          sampler_dim = GLSL_SAMPLER_DIM_CUBE;
547*61046927SAndroid Build Coastguard Worker          break;
548*61046927SAndroid Build Coastguard Worker       }
549*61046927SAndroid Build Coastguard Worker 
550*61046927SAndroid Build Coastguard Worker       nir_def *res = NULL;
551*61046927SAndroid Build Coastguard Worker 
552*61046927SAndroid Build Coastguard Worker       if (resolve) {
553*61046927SAndroid Build Coastguard Worker          /* When resolving a float type, we need to calculate
554*61046927SAndroid Build Coastguard Worker           * the average of all samples. For integer resolve, GL
555*61046927SAndroid Build Coastguard Worker           * and Vulkan say that one sample should be chosen
556*61046927SAndroid Build Coastguard Worker           * without telling which. Let's just pick the first one
557*61046927SAndroid Build Coastguard Worker           * in that case.
558*61046927SAndroid Build Coastguard Worker           */
559*61046927SAndroid Build Coastguard Worker          nir_alu_type base_type =
560*61046927SAndroid Build Coastguard Worker             nir_alu_type_get_base_type(key->surfaces[i].type);
561*61046927SAndroid Build Coastguard Worker          unsigned nsamples =
562*61046927SAndroid Build Coastguard Worker             base_type == nir_type_float ? key->surfaces[i].src_samples : 1;
563*61046927SAndroid Build Coastguard Worker 
564*61046927SAndroid Build Coastguard Worker          for (unsigned s = 0; s < nsamples; s++) {
565*61046927SAndroid Build Coastguard Worker             nir_tex_instr *tex = nir_tex_instr_create(b.shader, 3);
566*61046927SAndroid Build Coastguard Worker 
567*61046927SAndroid Build Coastguard Worker             tex->op = nir_texop_txf_ms;
568*61046927SAndroid Build Coastguard Worker             tex->dest_type = key->surfaces[i].type;
569*61046927SAndroid Build Coastguard Worker             tex->texture_index = tex_hw_index(active_count);
570*61046927SAndroid Build Coastguard Worker             tex->sampler_index = sampler_hw_index(0);
571*61046927SAndroid Build Coastguard Worker             tex->is_array = key->surfaces[i].array;
572*61046927SAndroid Build Coastguard Worker             tex->sampler_dim = sampler_dim;
573*61046927SAndroid Build Coastguard Worker 
574*61046927SAndroid Build Coastguard Worker             tex->src[0] =
575*61046927SAndroid Build Coastguard Worker                nir_tex_src_for_ssa(nir_tex_src_coord, nir_f2i32(&b, coord));
576*61046927SAndroid Build Coastguard Worker             tex->coord_components = coord_comps;
577*61046927SAndroid Build Coastguard Worker 
578*61046927SAndroid Build Coastguard Worker             tex->src[1] =
579*61046927SAndroid Build Coastguard Worker                nir_tex_src_for_ssa(nir_tex_src_ms_index, nir_imm_int(&b, s));
580*61046927SAndroid Build Coastguard Worker 
581*61046927SAndroid Build Coastguard Worker             tex->src[2] =
582*61046927SAndroid Build Coastguard Worker                nir_tex_src_for_ssa(nir_tex_src_lod, nir_imm_int(&b, 0));
583*61046927SAndroid Build Coastguard Worker             nir_def_init(&tex->instr, &tex->def, 4, 32);
584*61046927SAndroid Build Coastguard Worker             nir_builder_instr_insert(&b, &tex->instr);
585*61046927SAndroid Build Coastguard Worker 
586*61046927SAndroid Build Coastguard Worker             res = res ? nir_fadd(&b, res, &tex->def) : &tex->def;
587*61046927SAndroid Build Coastguard Worker          }
588*61046927SAndroid Build Coastguard Worker 
589*61046927SAndroid Build Coastguard Worker          if (base_type == nir_type_float)
590*61046927SAndroid Build Coastguard Worker             res = nir_fmul_imm(&b, res, 1.0f / nsamples);
591*61046927SAndroid Build Coastguard Worker       } else {
592*61046927SAndroid Build Coastguard Worker          nir_tex_instr *tex = nir_tex_instr_create(b.shader, ms ? 3 : 1);
593*61046927SAndroid Build Coastguard Worker 
594*61046927SAndroid Build Coastguard Worker          tex->dest_type = key->surfaces[i].type;
595*61046927SAndroid Build Coastguard Worker          tex->texture_index = tex_hw_index(active_count);
596*61046927SAndroid Build Coastguard Worker          tex->sampler_index = sampler_hw_index(0);
597*61046927SAndroid Build Coastguard Worker          tex->is_array = key->surfaces[i].array;
598*61046927SAndroid Build Coastguard Worker          tex->sampler_dim = sampler_dim;
599*61046927SAndroid Build Coastguard Worker 
600*61046927SAndroid Build Coastguard Worker          if (ms) {
601*61046927SAndroid Build Coastguard Worker             tex->op = nir_texop_txf_ms;
602*61046927SAndroid Build Coastguard Worker 
603*61046927SAndroid Build Coastguard Worker             tex->src[0] =
604*61046927SAndroid Build Coastguard Worker                nir_tex_src_for_ssa(nir_tex_src_coord, nir_f2i32(&b, coord));
605*61046927SAndroid Build Coastguard Worker             tex->coord_components = coord_comps;
606*61046927SAndroid Build Coastguard Worker 
607*61046927SAndroid Build Coastguard Worker             tex->src[1] = nir_tex_src_for_ssa(nir_tex_src_ms_index,
608*61046927SAndroid Build Coastguard Worker                                               nir_load_sample_id(&b));
609*61046927SAndroid Build Coastguard Worker 
610*61046927SAndroid Build Coastguard Worker             tex->src[2] =
611*61046927SAndroid Build Coastguard Worker                nir_tex_src_for_ssa(nir_tex_src_lod, nir_imm_int(&b, 0));
612*61046927SAndroid Build Coastguard Worker          } else {
613*61046927SAndroid Build Coastguard Worker             tex->op = nir_texop_txl;
614*61046927SAndroid Build Coastguard Worker 
615*61046927SAndroid Build Coastguard Worker             tex->src[0] = nir_tex_src_for_ssa(nir_tex_src_coord, coord);
616*61046927SAndroid Build Coastguard Worker             tex->coord_components = coord_comps;
617*61046927SAndroid Build Coastguard Worker          }
618*61046927SAndroid Build Coastguard Worker 
619*61046927SAndroid Build Coastguard Worker          nir_def_init(&tex->instr, &tex->def, 4, 32);
620*61046927SAndroid Build Coastguard Worker          nir_builder_instr_insert(&b, &tex->instr);
621*61046927SAndroid Build Coastguard Worker          res = &tex->def;
622*61046927SAndroid Build Coastguard Worker       }
623*61046927SAndroid Build Coastguard Worker 
624*61046927SAndroid Build Coastguard Worker       assert(res);
625*61046927SAndroid Build Coastguard Worker 
626*61046927SAndroid Build Coastguard Worker       if (key->surfaces[i].loc >= FRAG_RESULT_DATA0) {
627*61046927SAndroid Build Coastguard Worker          nir_store_output(
628*61046927SAndroid Build Coastguard Worker             &b, res, nir_imm_int(&b, 0), .base = active_count,
629*61046927SAndroid Build Coastguard Worker             .src_type = key->surfaces[i].type,
630*61046927SAndroid Build Coastguard Worker             .io_semantics.location = key->surfaces[i].loc,
631*61046927SAndroid Build Coastguard Worker             .io_semantics.num_slots = 1,
632*61046927SAndroid Build Coastguard Worker             .write_mask = nir_component_mask(res->num_components));
633*61046927SAndroid Build Coastguard Worker       } else {
634*61046927SAndroid Build Coastguard Worker          unsigned c = key->surfaces[i].loc == FRAG_RESULT_STENCIL ? 1 : 0;
635*61046927SAndroid Build Coastguard Worker          nir_store_output(
636*61046927SAndroid Build Coastguard Worker             &b, nir_channel(&b, res, c), nir_imm_int(&b, 0),
637*61046927SAndroid Build Coastguard Worker             .base = active_count, .src_type = key->surfaces[i].type,
638*61046927SAndroid Build Coastguard Worker             .io_semantics.location = key->surfaces[i].loc,
639*61046927SAndroid Build Coastguard Worker             .io_semantics.num_slots = 1, .write_mask = nir_component_mask(1));
640*61046927SAndroid Build Coastguard Worker       }
641*61046927SAndroid Build Coastguard Worker       active_count++;
642*61046927SAndroid Build Coastguard Worker    }
643*61046927SAndroid Build Coastguard Worker 
644*61046927SAndroid Build Coastguard Worker    struct panfrost_compile_inputs inputs = {
645*61046927SAndroid Build Coastguard Worker       .gpu_id = cache->gpu_id,
646*61046927SAndroid Build Coastguard Worker       .is_blit = true,
647*61046927SAndroid Build Coastguard Worker       .no_idvs = true,
648*61046927SAndroid Build Coastguard Worker    };
649*61046927SAndroid Build Coastguard Worker    struct util_dynarray binary;
650*61046927SAndroid Build Coastguard Worker 
651*61046927SAndroid Build Coastguard Worker    util_dynarray_init(&binary, NULL);
652*61046927SAndroid Build Coastguard Worker 
653*61046927SAndroid Build Coastguard Worker    shader = rzalloc(cache->shaders.blit, struct pan_blit_shader_data);
654*61046927SAndroid Build Coastguard Worker 
655*61046927SAndroid Build Coastguard Worker    nir_shader_gather_info(b.shader, nir_shader_get_entrypoint(b.shader));
656*61046927SAndroid Build Coastguard Worker 
657*61046927SAndroid Build Coastguard Worker    for (unsigned i = 0; i < active_count; ++i)
658*61046927SAndroid Build Coastguard Worker       BITSET_SET(b.shader->info.textures_used, i);
659*61046927SAndroid Build Coastguard Worker 
660*61046927SAndroid Build Coastguard Worker    pan_shader_preprocess(b.shader, inputs.gpu_id);
661*61046927SAndroid Build Coastguard Worker 
662*61046927SAndroid Build Coastguard Worker    if (PAN_ARCH == 4) {
663*61046927SAndroid Build Coastguard Worker       NIR_PASS_V(b.shader, nir_shader_intrinsics_pass, lower_sampler_parameters,
664*61046927SAndroid Build Coastguard Worker                  nir_metadata_control_flow, NULL);
665*61046927SAndroid Build Coastguard Worker    }
666*61046927SAndroid Build Coastguard Worker 
667*61046927SAndroid Build Coastguard Worker    GENX(pan_shader_compile)(b.shader, &inputs, &binary, &shader->info);
668*61046927SAndroid Build Coastguard Worker 
669*61046927SAndroid Build Coastguard Worker    shader->key = *key;
670*61046927SAndroid Build Coastguard Worker    shader->address =
671*61046927SAndroid Build Coastguard Worker       pan_pool_upload_aligned(cache->shaders.pool, binary.data,
672*61046927SAndroid Build Coastguard Worker                               binary.size, PAN_ARCH >= 6 ? 128 : 64);
673*61046927SAndroid Build Coastguard Worker 
674*61046927SAndroid Build Coastguard Worker    util_dynarray_fini(&binary);
675*61046927SAndroid Build Coastguard Worker    ralloc_free(b.shader);
676*61046927SAndroid Build Coastguard Worker 
677*61046927SAndroid Build Coastguard Worker #if PAN_ARCH >= 6
678*61046927SAndroid Build Coastguard Worker    for (unsigned i = 0; i < ARRAY_SIZE(shader->blend_ret_offsets); i++) {
679*61046927SAndroid Build Coastguard Worker       shader->blend_ret_offsets[i] =
680*61046927SAndroid Build Coastguard Worker          shader->info.bifrost.blend[i].return_offset;
681*61046927SAndroid Build Coastguard Worker       shader->blend_types[i] = shader->info.bifrost.blend[i].type;
682*61046927SAndroid Build Coastguard Worker    }
683*61046927SAndroid Build Coastguard Worker #endif
684*61046927SAndroid Build Coastguard Worker 
685*61046927SAndroid Build Coastguard Worker    _mesa_hash_table_insert(cache->shaders.blit, &shader->key, shader);
686*61046927SAndroid Build Coastguard Worker 
687*61046927SAndroid Build Coastguard Worker out:
688*61046927SAndroid Build Coastguard Worker    pthread_mutex_unlock(&cache->shaders.lock);
689*61046927SAndroid Build Coastguard Worker    return shader;
690*61046927SAndroid Build Coastguard Worker }
691*61046927SAndroid Build Coastguard Worker 
692*61046927SAndroid Build Coastguard Worker static struct pan_blit_shader_key
pan_blitter_get_key(struct pan_blitter_views * views)693*61046927SAndroid Build Coastguard Worker pan_blitter_get_key(struct pan_blitter_views *views)
694*61046927SAndroid Build Coastguard Worker {
695*61046927SAndroid Build Coastguard Worker    struct pan_blit_shader_key key = {0};
696*61046927SAndroid Build Coastguard Worker 
697*61046927SAndroid Build Coastguard Worker    if (views->src_z) {
698*61046927SAndroid Build Coastguard Worker       assert(views->dst_z);
699*61046927SAndroid Build Coastguard Worker       key.surfaces[0].loc = FRAG_RESULT_DEPTH;
700*61046927SAndroid Build Coastguard Worker       key.surfaces[0].type = nir_type_float32;
701*61046927SAndroid Build Coastguard Worker       key.surfaces[0].src_samples = pan_image_view_get_nr_samples(views->src_z);
702*61046927SAndroid Build Coastguard Worker       key.surfaces[0].dst_samples = pan_image_view_get_nr_samples(views->dst_z);
703*61046927SAndroid Build Coastguard Worker       key.surfaces[0].dim = views->src_z->dim;
704*61046927SAndroid Build Coastguard Worker       key.surfaces[0].array =
705*61046927SAndroid Build Coastguard Worker          views->src_z->first_layer != views->src_z->last_layer;
706*61046927SAndroid Build Coastguard Worker    }
707*61046927SAndroid Build Coastguard Worker 
708*61046927SAndroid Build Coastguard Worker    if (views->src_s) {
709*61046927SAndroid Build Coastguard Worker       assert(views->dst_s);
710*61046927SAndroid Build Coastguard Worker       key.surfaces[1].loc = FRAG_RESULT_STENCIL;
711*61046927SAndroid Build Coastguard Worker       key.surfaces[1].type = nir_type_uint32;
712*61046927SAndroid Build Coastguard Worker       key.surfaces[1].src_samples = pan_image_view_get_nr_samples(views->src_s);
713*61046927SAndroid Build Coastguard Worker       key.surfaces[1].dst_samples = pan_image_view_get_nr_samples(views->dst_s);
714*61046927SAndroid Build Coastguard Worker       key.surfaces[1].dim = views->src_s->dim;
715*61046927SAndroid Build Coastguard Worker       key.surfaces[1].array =
716*61046927SAndroid Build Coastguard Worker          views->src_s->first_layer != views->src_s->last_layer;
717*61046927SAndroid Build Coastguard Worker    }
718*61046927SAndroid Build Coastguard Worker 
719*61046927SAndroid Build Coastguard Worker    for (unsigned i = 0; i < views->rt_count; i++) {
720*61046927SAndroid Build Coastguard Worker       if (!views->src_rts[i])
721*61046927SAndroid Build Coastguard Worker          continue;
722*61046927SAndroid Build Coastguard Worker 
723*61046927SAndroid Build Coastguard Worker       assert(views->dst_rts[i]);
724*61046927SAndroid Build Coastguard Worker       key.surfaces[i].loc = FRAG_RESULT_DATA0 + i;
725*61046927SAndroid Build Coastguard Worker       key.surfaces[i].type =
726*61046927SAndroid Build Coastguard Worker          util_format_is_pure_uint(views->src_rts[i]->format) ? nir_type_uint32
727*61046927SAndroid Build Coastguard Worker          : util_format_is_pure_sint(views->src_rts[i]->format)
728*61046927SAndroid Build Coastguard Worker             ? nir_type_int32
729*61046927SAndroid Build Coastguard Worker             : nir_type_float32;
730*61046927SAndroid Build Coastguard Worker       key.surfaces[i].src_samples =
731*61046927SAndroid Build Coastguard Worker          pan_image_view_get_nr_samples(views->src_rts[i]);
732*61046927SAndroid Build Coastguard Worker       key.surfaces[i].dst_samples =
733*61046927SAndroid Build Coastguard Worker          pan_image_view_get_nr_samples(views->dst_rts[i]);
734*61046927SAndroid Build Coastguard Worker       key.surfaces[i].dim = views->src_rts[i]->dim;
735*61046927SAndroid Build Coastguard Worker       key.surfaces[i].array =
736*61046927SAndroid Build Coastguard Worker          views->src_rts[i]->first_layer != views->src_rts[i]->last_layer;
737*61046927SAndroid Build Coastguard Worker    }
738*61046927SAndroid Build Coastguard Worker 
739*61046927SAndroid Build Coastguard Worker    return key;
740*61046927SAndroid Build Coastguard Worker }
741*61046927SAndroid Build Coastguard Worker 
742*61046927SAndroid Build Coastguard Worker #if PAN_ARCH <= 7
743*61046927SAndroid Build Coastguard Worker static mali_ptr
pan_blitter_get_rsd(struct pan_blitter_cache * cache,struct pan_blitter_views * views)744*61046927SAndroid Build Coastguard Worker pan_blitter_get_rsd(struct pan_blitter_cache *cache,
745*61046927SAndroid Build Coastguard Worker                     struct pan_blitter_views *views)
746*61046927SAndroid Build Coastguard Worker {
747*61046927SAndroid Build Coastguard Worker    struct pan_blit_rsd_key rsd_key = {0};
748*61046927SAndroid Build Coastguard Worker 
749*61046927SAndroid Build Coastguard Worker    assert(!views->rt_count || (!views->src_z && !views->src_s));
750*61046927SAndroid Build Coastguard Worker 
751*61046927SAndroid Build Coastguard Worker    struct pan_blit_shader_key blit_key = pan_blitter_get_key(views);
752*61046927SAndroid Build Coastguard Worker 
753*61046927SAndroid Build Coastguard Worker    if (views->src_z) {
754*61046927SAndroid Build Coastguard Worker       assert(views->dst_z);
755*61046927SAndroid Build Coastguard Worker       rsd_key.z.format = views->dst_z->format;
756*61046927SAndroid Build Coastguard Worker       rsd_key.z.type = blit_key.surfaces[0].type;
757*61046927SAndroid Build Coastguard Worker       rsd_key.z.src_samples = blit_key.surfaces[0].src_samples;
758*61046927SAndroid Build Coastguard Worker       rsd_key.z.dst_samples = blit_key.surfaces[0].dst_samples;
759*61046927SAndroid Build Coastguard Worker       rsd_key.z.dim = blit_key.surfaces[0].dim;
760*61046927SAndroid Build Coastguard Worker       rsd_key.z.array = blit_key.surfaces[0].array;
761*61046927SAndroid Build Coastguard Worker    }
762*61046927SAndroid Build Coastguard Worker 
763*61046927SAndroid Build Coastguard Worker    if (views->src_s) {
764*61046927SAndroid Build Coastguard Worker       assert(views->dst_s);
765*61046927SAndroid Build Coastguard Worker       rsd_key.s.format = views->dst_s->format;
766*61046927SAndroid Build Coastguard Worker       rsd_key.s.type = blit_key.surfaces[1].type;
767*61046927SAndroid Build Coastguard Worker       rsd_key.s.src_samples = blit_key.surfaces[1].src_samples;
768*61046927SAndroid Build Coastguard Worker       rsd_key.s.dst_samples = blit_key.surfaces[1].dst_samples;
769*61046927SAndroid Build Coastguard Worker       rsd_key.s.dim = blit_key.surfaces[1].dim;
770*61046927SAndroid Build Coastguard Worker       rsd_key.s.array = blit_key.surfaces[1].array;
771*61046927SAndroid Build Coastguard Worker    }
772*61046927SAndroid Build Coastguard Worker 
773*61046927SAndroid Build Coastguard Worker    for (unsigned i = 0; i < views->rt_count; i++) {
774*61046927SAndroid Build Coastguard Worker       if (!views->src_rts[i])
775*61046927SAndroid Build Coastguard Worker          continue;
776*61046927SAndroid Build Coastguard Worker 
777*61046927SAndroid Build Coastguard Worker       assert(views->dst_rts[i]);
778*61046927SAndroid Build Coastguard Worker       rsd_key.rts[i].format = views->dst_rts[i]->format;
779*61046927SAndroid Build Coastguard Worker       rsd_key.rts[i].type = blit_key.surfaces[i].type;
780*61046927SAndroid Build Coastguard Worker       rsd_key.rts[i].src_samples = blit_key.surfaces[i].src_samples;
781*61046927SAndroid Build Coastguard Worker       rsd_key.rts[i].dst_samples = blit_key.surfaces[i].dst_samples;
782*61046927SAndroid Build Coastguard Worker       rsd_key.rts[i].dim = blit_key.surfaces[i].dim;
783*61046927SAndroid Build Coastguard Worker       rsd_key.rts[i].array = blit_key.surfaces[i].array;
784*61046927SAndroid Build Coastguard Worker    }
785*61046927SAndroid Build Coastguard Worker 
786*61046927SAndroid Build Coastguard Worker    pthread_mutex_lock(&cache->rsds.lock);
787*61046927SAndroid Build Coastguard Worker    struct hash_entry *he =
788*61046927SAndroid Build Coastguard Worker       _mesa_hash_table_search(cache->rsds.rsds, &rsd_key);
789*61046927SAndroid Build Coastguard Worker    struct pan_blit_rsd_data *rsd = he ? he->data : NULL;
790*61046927SAndroid Build Coastguard Worker    if (rsd)
791*61046927SAndroid Build Coastguard Worker       goto out;
792*61046927SAndroid Build Coastguard Worker 
793*61046927SAndroid Build Coastguard Worker    rsd = rzalloc(cache->rsds.rsds, struct pan_blit_rsd_data);
794*61046927SAndroid Build Coastguard Worker    rsd->key = rsd_key;
795*61046927SAndroid Build Coastguard Worker 
796*61046927SAndroid Build Coastguard Worker #if PAN_ARCH == 4
797*61046927SAndroid Build Coastguard Worker    struct panfrost_ptr rsd_ptr =
798*61046927SAndroid Build Coastguard Worker       pan_pool_alloc_desc(cache->rsds.pool, RENDERER_STATE);
799*61046927SAndroid Build Coastguard Worker #else
800*61046927SAndroid Build Coastguard Worker    unsigned bd_count = PAN_ARCH >= 5 ? MAX2(views->rt_count, 1) : 0;
801*61046927SAndroid Build Coastguard Worker    struct panfrost_ptr rsd_ptr = pan_pool_alloc_desc_aggregate(
802*61046927SAndroid Build Coastguard Worker       cache->rsds.pool, PAN_DESC(RENDERER_STATE),
803*61046927SAndroid Build Coastguard Worker       PAN_DESC_ARRAY(bd_count, BLEND));
804*61046927SAndroid Build Coastguard Worker #endif
805*61046927SAndroid Build Coastguard Worker 
806*61046927SAndroid Build Coastguard Worker    mali_ptr blend_shaders[8] = {0};
807*61046927SAndroid Build Coastguard Worker 
808*61046927SAndroid Build Coastguard Worker    const struct pan_blit_shader_data *blit_shader =
809*61046927SAndroid Build Coastguard Worker       pan_blitter_get_blit_shader(cache, &blit_key);
810*61046927SAndroid Build Coastguard Worker 
811*61046927SAndroid Build Coastguard Worker #if PAN_ARCH <= 5
812*61046927SAndroid Build Coastguard Worker    pan_blitter_get_blend_shaders(cache,
813*61046927SAndroid Build Coastguard Worker                                  views->rt_count, views->dst_rts, blit_shader,
814*61046927SAndroid Build Coastguard Worker                                  blend_shaders);
815*61046927SAndroid Build Coastguard Worker #endif
816*61046927SAndroid Build Coastguard Worker 
817*61046927SAndroid Build Coastguard Worker    pan_blitter_emit_rsd(blit_shader, views, blend_shaders, rsd_ptr.cpu);
818*61046927SAndroid Build Coastguard Worker    rsd->address = rsd_ptr.gpu;
819*61046927SAndroid Build Coastguard Worker    _mesa_hash_table_insert(cache->rsds.rsds, &rsd->key, rsd);
820*61046927SAndroid Build Coastguard Worker 
821*61046927SAndroid Build Coastguard Worker out:
822*61046927SAndroid Build Coastguard Worker    pthread_mutex_unlock(&cache->rsds.lock);
823*61046927SAndroid Build Coastguard Worker    return rsd->address;
824*61046927SAndroid Build Coastguard Worker }
825*61046927SAndroid Build Coastguard Worker #endif
826*61046927SAndroid Build Coastguard Worker 
827*61046927SAndroid Build Coastguard Worker static struct pan_blitter_views
pan_preload_get_views(const struct pan_fb_info * fb,bool zs,struct pan_image_view * patched_s)828*61046927SAndroid Build Coastguard Worker pan_preload_get_views(const struct pan_fb_info *fb, bool zs,
829*61046927SAndroid Build Coastguard Worker                       struct pan_image_view *patched_s)
830*61046927SAndroid Build Coastguard Worker {
831*61046927SAndroid Build Coastguard Worker    struct pan_blitter_views views = {0};
832*61046927SAndroid Build Coastguard Worker 
833*61046927SAndroid Build Coastguard Worker    if (zs) {
834*61046927SAndroid Build Coastguard Worker       if (fb->zs.preload.z)
835*61046927SAndroid Build Coastguard Worker          views.src_z = views.dst_z = fb->zs.view.zs;
836*61046927SAndroid Build Coastguard Worker 
837*61046927SAndroid Build Coastguard Worker       if (fb->zs.preload.s) {
838*61046927SAndroid Build Coastguard Worker          const struct pan_image_view *view = fb->zs.view.s ?: fb->zs.view.zs;
839*61046927SAndroid Build Coastguard Worker          enum pipe_format fmt = util_format_get_depth_only(view->format);
840*61046927SAndroid Build Coastguard Worker 
841*61046927SAndroid Build Coastguard Worker          switch (view->format) {
842*61046927SAndroid Build Coastguard Worker          case PIPE_FORMAT_Z24_UNORM_S8_UINT:
843*61046927SAndroid Build Coastguard Worker             fmt = PIPE_FORMAT_X24S8_UINT;
844*61046927SAndroid Build Coastguard Worker             break;
845*61046927SAndroid Build Coastguard Worker          case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
846*61046927SAndroid Build Coastguard Worker             fmt = PIPE_FORMAT_X32_S8X24_UINT;
847*61046927SAndroid Build Coastguard Worker             break;
848*61046927SAndroid Build Coastguard Worker          default:
849*61046927SAndroid Build Coastguard Worker             fmt = view->format;
850*61046927SAndroid Build Coastguard Worker             break;
851*61046927SAndroid Build Coastguard Worker          }
852*61046927SAndroid Build Coastguard Worker 
853*61046927SAndroid Build Coastguard Worker          if (fmt != view->format) {
854*61046927SAndroid Build Coastguard Worker             *patched_s = *view;
855*61046927SAndroid Build Coastguard Worker             patched_s->format = fmt;
856*61046927SAndroid Build Coastguard Worker             views.src_s = views.dst_s = patched_s;
857*61046927SAndroid Build Coastguard Worker          } else {
858*61046927SAndroid Build Coastguard Worker             views.src_s = views.dst_s = view;
859*61046927SAndroid Build Coastguard Worker          }
860*61046927SAndroid Build Coastguard Worker       }
861*61046927SAndroid Build Coastguard Worker    } else {
862*61046927SAndroid Build Coastguard Worker       for (unsigned i = 0; i < fb->rt_count; i++) {
863*61046927SAndroid Build Coastguard Worker          if (fb->rts[i].preload) {
864*61046927SAndroid Build Coastguard Worker             views.src_rts[i] = fb->rts[i].view;
865*61046927SAndroid Build Coastguard Worker             views.dst_rts[i] = fb->rts[i].view;
866*61046927SAndroid Build Coastguard Worker          }
867*61046927SAndroid Build Coastguard Worker       }
868*61046927SAndroid Build Coastguard Worker 
869*61046927SAndroid Build Coastguard Worker       views.rt_count = fb->rt_count;
870*61046927SAndroid Build Coastguard Worker    }
871*61046927SAndroid Build Coastguard Worker 
872*61046927SAndroid Build Coastguard Worker    return views;
873*61046927SAndroid Build Coastguard Worker }
874*61046927SAndroid Build Coastguard Worker 
875*61046927SAndroid Build Coastguard Worker static bool
pan_preload_needed(const struct pan_fb_info * fb,bool zs)876*61046927SAndroid Build Coastguard Worker pan_preload_needed(const struct pan_fb_info *fb, bool zs)
877*61046927SAndroid Build Coastguard Worker {
878*61046927SAndroid Build Coastguard Worker    if (zs) {
879*61046927SAndroid Build Coastguard Worker       if (fb->zs.preload.z || fb->zs.preload.s)
880*61046927SAndroid Build Coastguard Worker          return true;
881*61046927SAndroid Build Coastguard Worker    } else {
882*61046927SAndroid Build Coastguard Worker       for (unsigned i = 0; i < fb->rt_count; i++) {
883*61046927SAndroid Build Coastguard Worker          if (fb->rts[i].preload)
884*61046927SAndroid Build Coastguard Worker             return true;
885*61046927SAndroid Build Coastguard Worker       }
886*61046927SAndroid Build Coastguard Worker    }
887*61046927SAndroid Build Coastguard Worker 
888*61046927SAndroid Build Coastguard Worker    return false;
889*61046927SAndroid Build Coastguard Worker }
890*61046927SAndroid Build Coastguard Worker 
891*61046927SAndroid Build Coastguard Worker static mali_ptr
pan_blitter_emit_varying(struct pan_pool * pool)892*61046927SAndroid Build Coastguard Worker pan_blitter_emit_varying(struct pan_pool *pool)
893*61046927SAndroid Build Coastguard Worker {
894*61046927SAndroid Build Coastguard Worker    struct panfrost_ptr varying = pan_pool_alloc_desc(pool, ATTRIBUTE);
895*61046927SAndroid Build Coastguard Worker 
896*61046927SAndroid Build Coastguard Worker    pan_pack(varying.cpu, ATTRIBUTE, cfg) {
897*61046927SAndroid Build Coastguard Worker       cfg.buffer_index = 0;
898*61046927SAndroid Build Coastguard Worker       cfg.offset_enable = PAN_ARCH <= 5;
899*61046927SAndroid Build Coastguard Worker       cfg.format =
900*61046927SAndroid Build Coastguard Worker          GENX(panfrost_format_from_pipe_format)(PIPE_FORMAT_R32G32B32_FLOAT)->hw;
901*61046927SAndroid Build Coastguard Worker 
902*61046927SAndroid Build Coastguard Worker #if PAN_ARCH >= 9
903*61046927SAndroid Build Coastguard Worker       cfg.attribute_type = MALI_ATTRIBUTE_TYPE_1D;
904*61046927SAndroid Build Coastguard Worker       cfg.table = PAN_BLIT_TABLE_ATTRIBUTE_BUFFER;
905*61046927SAndroid Build Coastguard Worker       cfg.frequency = MALI_ATTRIBUTE_FREQUENCY_VERTEX;
906*61046927SAndroid Build Coastguard Worker       cfg.stride = 4 * sizeof(float);
907*61046927SAndroid Build Coastguard Worker #endif
908*61046927SAndroid Build Coastguard Worker    }
909*61046927SAndroid Build Coastguard Worker 
910*61046927SAndroid Build Coastguard Worker    return varying.gpu;
911*61046927SAndroid Build Coastguard Worker }
912*61046927SAndroid Build Coastguard Worker 
913*61046927SAndroid Build Coastguard Worker static mali_ptr
pan_blitter_emit_varying_buffer(struct pan_pool * pool,mali_ptr coordinates)914*61046927SAndroid Build Coastguard Worker pan_blitter_emit_varying_buffer(struct pan_pool *pool, mali_ptr coordinates)
915*61046927SAndroid Build Coastguard Worker {
916*61046927SAndroid Build Coastguard Worker #if PAN_ARCH >= 9
917*61046927SAndroid Build Coastguard Worker    struct panfrost_ptr varying_buffer = pan_pool_alloc_desc(pool, BUFFER);
918*61046927SAndroid Build Coastguard Worker 
919*61046927SAndroid Build Coastguard Worker    pan_pack(varying_buffer.cpu, BUFFER, cfg) {
920*61046927SAndroid Build Coastguard Worker       cfg.address = coordinates;
921*61046927SAndroid Build Coastguard Worker       cfg.size = 4 * sizeof(float) * 4;
922*61046927SAndroid Build Coastguard Worker    }
923*61046927SAndroid Build Coastguard Worker #else
924*61046927SAndroid Build Coastguard Worker    /* Bifrost needs an empty desc to mark end of prefetching */
925*61046927SAndroid Build Coastguard Worker    bool padding_buffer = PAN_ARCH >= 6;
926*61046927SAndroid Build Coastguard Worker 
927*61046927SAndroid Build Coastguard Worker    struct panfrost_ptr varying_buffer = pan_pool_alloc_desc_array(
928*61046927SAndroid Build Coastguard Worker       pool, (padding_buffer ? 2 : 1), ATTRIBUTE_BUFFER);
929*61046927SAndroid Build Coastguard Worker 
930*61046927SAndroid Build Coastguard Worker    pan_pack(varying_buffer.cpu, ATTRIBUTE_BUFFER, cfg) {
931*61046927SAndroid Build Coastguard Worker       cfg.pointer = coordinates;
932*61046927SAndroid Build Coastguard Worker       cfg.stride = 4 * sizeof(float);
933*61046927SAndroid Build Coastguard Worker       cfg.size = cfg.stride * 4;
934*61046927SAndroid Build Coastguard Worker    }
935*61046927SAndroid Build Coastguard Worker 
936*61046927SAndroid Build Coastguard Worker    if (padding_buffer) {
937*61046927SAndroid Build Coastguard Worker       pan_pack(varying_buffer.cpu + pan_size(ATTRIBUTE_BUFFER),
938*61046927SAndroid Build Coastguard Worker                ATTRIBUTE_BUFFER, cfg)
939*61046927SAndroid Build Coastguard Worker          ;
940*61046927SAndroid Build Coastguard Worker    }
941*61046927SAndroid Build Coastguard Worker #endif
942*61046927SAndroid Build Coastguard Worker 
943*61046927SAndroid Build Coastguard Worker    return varying_buffer.gpu;
944*61046927SAndroid Build Coastguard Worker }
945*61046927SAndroid Build Coastguard Worker 
946*61046927SAndroid Build Coastguard Worker static mali_ptr
pan_blitter_emit_sampler(struct pan_pool * pool,bool nearest_filter)947*61046927SAndroid Build Coastguard Worker pan_blitter_emit_sampler(struct pan_pool *pool, bool nearest_filter)
948*61046927SAndroid Build Coastguard Worker {
949*61046927SAndroid Build Coastguard Worker    struct panfrost_ptr sampler = pan_pool_alloc_desc(pool, SAMPLER);
950*61046927SAndroid Build Coastguard Worker 
951*61046927SAndroid Build Coastguard Worker    pan_pack(sampler.cpu, SAMPLER, cfg) {
952*61046927SAndroid Build Coastguard Worker       cfg.seamless_cube_map = false;
953*61046927SAndroid Build Coastguard Worker       cfg.normalized_coordinates = false;
954*61046927SAndroid Build Coastguard Worker       cfg.minify_nearest = nearest_filter;
955*61046927SAndroid Build Coastguard Worker       cfg.magnify_nearest = nearest_filter;
956*61046927SAndroid Build Coastguard Worker    }
957*61046927SAndroid Build Coastguard Worker 
958*61046927SAndroid Build Coastguard Worker    return sampler.gpu;
959*61046927SAndroid Build Coastguard Worker }
960*61046927SAndroid Build Coastguard Worker 
961*61046927SAndroid Build Coastguard Worker static mali_ptr
pan_blitter_emit_textures(struct pan_pool * pool,unsigned tex_count,const struct pan_image_view ** views)962*61046927SAndroid Build Coastguard Worker pan_blitter_emit_textures(struct pan_pool *pool, unsigned tex_count,
963*61046927SAndroid Build Coastguard Worker                           const struct pan_image_view **views)
964*61046927SAndroid Build Coastguard Worker {
965*61046927SAndroid Build Coastguard Worker #if PAN_ARCH >= 6
966*61046927SAndroid Build Coastguard Worker    struct panfrost_ptr textures =
967*61046927SAndroid Build Coastguard Worker       pan_pool_alloc_desc_array(pool, tex_count, TEXTURE);
968*61046927SAndroid Build Coastguard Worker 
969*61046927SAndroid Build Coastguard Worker    for (unsigned i = 0; i < tex_count; i++) {
970*61046927SAndroid Build Coastguard Worker       void *texture = textures.cpu + (pan_size(TEXTURE) * i);
971*61046927SAndroid Build Coastguard Worker       size_t payload_size =
972*61046927SAndroid Build Coastguard Worker          GENX(panfrost_estimate_texture_payload_size)(views[i]);
973*61046927SAndroid Build Coastguard Worker       struct panfrost_ptr surfaces =
974*61046927SAndroid Build Coastguard Worker          pan_pool_alloc_aligned(pool, payload_size, 64);
975*61046927SAndroid Build Coastguard Worker 
976*61046927SAndroid Build Coastguard Worker       GENX(panfrost_new_texture)(views[i], texture, &surfaces);
977*61046927SAndroid Build Coastguard Worker    }
978*61046927SAndroid Build Coastguard Worker 
979*61046927SAndroid Build Coastguard Worker    return textures.gpu;
980*61046927SAndroid Build Coastguard Worker #else
981*61046927SAndroid Build Coastguard Worker    mali_ptr textures[8] = {0};
982*61046927SAndroid Build Coastguard Worker 
983*61046927SAndroid Build Coastguard Worker    for (unsigned i = 0; i < tex_count; i++) {
984*61046927SAndroid Build Coastguard Worker       size_t sz = pan_size(TEXTURE) +
985*61046927SAndroid Build Coastguard Worker                   GENX(panfrost_estimate_texture_payload_size)(views[i]);
986*61046927SAndroid Build Coastguard Worker       struct panfrost_ptr texture =
987*61046927SAndroid Build Coastguard Worker          pan_pool_alloc_aligned(pool, sz, pan_alignment(TEXTURE));
988*61046927SAndroid Build Coastguard Worker       struct panfrost_ptr surfaces = {
989*61046927SAndroid Build Coastguard Worker          .cpu = texture.cpu + pan_size(TEXTURE),
990*61046927SAndroid Build Coastguard Worker          .gpu = texture.gpu + pan_size(TEXTURE),
991*61046927SAndroid Build Coastguard Worker       };
992*61046927SAndroid Build Coastguard Worker 
993*61046927SAndroid Build Coastguard Worker       GENX(panfrost_new_texture)(views[i], texture.cpu, &surfaces);
994*61046927SAndroid Build Coastguard Worker       textures[i] = texture.gpu;
995*61046927SAndroid Build Coastguard Worker    }
996*61046927SAndroid Build Coastguard Worker 
997*61046927SAndroid Build Coastguard Worker    return pan_pool_upload_aligned(pool, textures, tex_count * sizeof(mali_ptr),
998*61046927SAndroid Build Coastguard Worker                                   sizeof(mali_ptr));
999*61046927SAndroid Build Coastguard Worker #endif
1000*61046927SAndroid Build Coastguard Worker }
1001*61046927SAndroid Build Coastguard Worker 
1002*61046927SAndroid Build Coastguard Worker static mali_ptr
pan_preload_emit_textures(struct pan_pool * pool,const struct pan_fb_info * fb,bool zs,unsigned * tex_count_out)1003*61046927SAndroid Build Coastguard Worker pan_preload_emit_textures(struct pan_pool *pool, const struct pan_fb_info *fb,
1004*61046927SAndroid Build Coastguard Worker                           bool zs, unsigned *tex_count_out)
1005*61046927SAndroid Build Coastguard Worker {
1006*61046927SAndroid Build Coastguard Worker    const struct pan_image_view *views[8];
1007*61046927SAndroid Build Coastguard Worker    struct pan_image_view patched_s_view;
1008*61046927SAndroid Build Coastguard Worker    unsigned tex_count = 0;
1009*61046927SAndroid Build Coastguard Worker 
1010*61046927SAndroid Build Coastguard Worker    if (zs) {
1011*61046927SAndroid Build Coastguard Worker       if (fb->zs.preload.z)
1012*61046927SAndroid Build Coastguard Worker          views[tex_count++] = fb->zs.view.zs;
1013*61046927SAndroid Build Coastguard Worker 
1014*61046927SAndroid Build Coastguard Worker       if (fb->zs.preload.s) {
1015*61046927SAndroid Build Coastguard Worker          const struct pan_image_view *view = fb->zs.view.s ?: fb->zs.view.zs;
1016*61046927SAndroid Build Coastguard Worker          enum pipe_format fmt = util_format_get_depth_only(view->format);
1017*61046927SAndroid Build Coastguard Worker 
1018*61046927SAndroid Build Coastguard Worker          switch (view->format) {
1019*61046927SAndroid Build Coastguard Worker          case PIPE_FORMAT_Z24_UNORM_S8_UINT:
1020*61046927SAndroid Build Coastguard Worker             fmt = PIPE_FORMAT_X24S8_UINT;
1021*61046927SAndroid Build Coastguard Worker             break;
1022*61046927SAndroid Build Coastguard Worker          case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
1023*61046927SAndroid Build Coastguard Worker             fmt = PIPE_FORMAT_X32_S8X24_UINT;
1024*61046927SAndroid Build Coastguard Worker             break;
1025*61046927SAndroid Build Coastguard Worker          default:
1026*61046927SAndroid Build Coastguard Worker             fmt = view->format;
1027*61046927SAndroid Build Coastguard Worker             break;
1028*61046927SAndroid Build Coastguard Worker          }
1029*61046927SAndroid Build Coastguard Worker 
1030*61046927SAndroid Build Coastguard Worker          if (fmt != view->format) {
1031*61046927SAndroid Build Coastguard Worker             patched_s_view = *view;
1032*61046927SAndroid Build Coastguard Worker             patched_s_view.format = fmt;
1033*61046927SAndroid Build Coastguard Worker             view = &patched_s_view;
1034*61046927SAndroid Build Coastguard Worker          }
1035*61046927SAndroid Build Coastguard Worker          views[tex_count++] = view;
1036*61046927SAndroid Build Coastguard Worker       }
1037*61046927SAndroid Build Coastguard Worker    } else {
1038*61046927SAndroid Build Coastguard Worker       for (unsigned i = 0; i < fb->rt_count; i++) {
1039*61046927SAndroid Build Coastguard Worker          if (fb->rts[i].preload)
1040*61046927SAndroid Build Coastguard Worker             views[tex_count++] = fb->rts[i].view;
1041*61046927SAndroid Build Coastguard Worker       }
1042*61046927SAndroid Build Coastguard Worker    }
1043*61046927SAndroid Build Coastguard Worker 
1044*61046927SAndroid Build Coastguard Worker    *tex_count_out = tex_count;
1045*61046927SAndroid Build Coastguard Worker 
1046*61046927SAndroid Build Coastguard Worker    return pan_blitter_emit_textures(pool, tex_count, views);
1047*61046927SAndroid Build Coastguard Worker }
1048*61046927SAndroid Build Coastguard Worker 
1049*61046927SAndroid Build Coastguard Worker #if PAN_ARCH >= 8
1050*61046927SAndroid Build Coastguard Worker /* TODO: cache */
1051*61046927SAndroid Build Coastguard Worker static mali_ptr
pan_blitter_emit_zs(struct pan_pool * pool,bool z,bool s)1052*61046927SAndroid Build Coastguard Worker pan_blitter_emit_zs(struct pan_pool *pool, bool z, bool s)
1053*61046927SAndroid Build Coastguard Worker {
1054*61046927SAndroid Build Coastguard Worker    struct panfrost_ptr zsd = pan_pool_alloc_desc(pool, DEPTH_STENCIL);
1055*61046927SAndroid Build Coastguard Worker 
1056*61046927SAndroid Build Coastguard Worker    pan_pack(zsd.cpu, DEPTH_STENCIL, cfg) {
1057*61046927SAndroid Build Coastguard Worker       cfg.depth_function = MALI_FUNC_ALWAYS;
1058*61046927SAndroid Build Coastguard Worker       cfg.depth_write_enable = z;
1059*61046927SAndroid Build Coastguard Worker 
1060*61046927SAndroid Build Coastguard Worker       if (z)
1061*61046927SAndroid Build Coastguard Worker          cfg.depth_source = MALI_DEPTH_SOURCE_SHADER;
1062*61046927SAndroid Build Coastguard Worker 
1063*61046927SAndroid Build Coastguard Worker       cfg.stencil_test_enable = s;
1064*61046927SAndroid Build Coastguard Worker       cfg.stencil_from_shader = s;
1065*61046927SAndroid Build Coastguard Worker 
1066*61046927SAndroid Build Coastguard Worker       cfg.front_compare_function = MALI_FUNC_ALWAYS;
1067*61046927SAndroid Build Coastguard Worker       cfg.front_stencil_fail = MALI_STENCIL_OP_REPLACE;
1068*61046927SAndroid Build Coastguard Worker       cfg.front_depth_fail = MALI_STENCIL_OP_REPLACE;
1069*61046927SAndroid Build Coastguard Worker       cfg.front_depth_pass = MALI_STENCIL_OP_REPLACE;
1070*61046927SAndroid Build Coastguard Worker       cfg.front_write_mask = 0xFF;
1071*61046927SAndroid Build Coastguard Worker       cfg.front_value_mask = 0xFF;
1072*61046927SAndroid Build Coastguard Worker 
1073*61046927SAndroid Build Coastguard Worker       cfg.back_compare_function = MALI_FUNC_ALWAYS;
1074*61046927SAndroid Build Coastguard Worker       cfg.back_stencil_fail = MALI_STENCIL_OP_REPLACE;
1075*61046927SAndroid Build Coastguard Worker       cfg.back_depth_fail = MALI_STENCIL_OP_REPLACE;
1076*61046927SAndroid Build Coastguard Worker       cfg.back_depth_pass = MALI_STENCIL_OP_REPLACE;
1077*61046927SAndroid Build Coastguard Worker       cfg.back_write_mask = 0xFF;
1078*61046927SAndroid Build Coastguard Worker       cfg.back_value_mask = 0xFF;
1079*61046927SAndroid Build Coastguard Worker 
1080*61046927SAndroid Build Coastguard Worker       cfg.depth_cull_enable = false;
1081*61046927SAndroid Build Coastguard Worker    }
1082*61046927SAndroid Build Coastguard Worker 
1083*61046927SAndroid Build Coastguard Worker    return zsd.gpu;
1084*61046927SAndroid Build Coastguard Worker }
1085*61046927SAndroid Build Coastguard Worker #else
1086*61046927SAndroid Build Coastguard Worker static mali_ptr
pan_blitter_emit_viewport(struct pan_pool * pool,uint16_t minx,uint16_t miny,uint16_t maxx,uint16_t maxy)1087*61046927SAndroid Build Coastguard Worker pan_blitter_emit_viewport(struct pan_pool *pool, uint16_t minx, uint16_t miny,
1088*61046927SAndroid Build Coastguard Worker                           uint16_t maxx, uint16_t maxy)
1089*61046927SAndroid Build Coastguard Worker {
1090*61046927SAndroid Build Coastguard Worker    struct panfrost_ptr vp = pan_pool_alloc_desc(pool, VIEWPORT);
1091*61046927SAndroid Build Coastguard Worker 
1092*61046927SAndroid Build Coastguard Worker    pan_pack(vp.cpu, VIEWPORT, cfg) {
1093*61046927SAndroid Build Coastguard Worker       cfg.scissor_minimum_x = minx;
1094*61046927SAndroid Build Coastguard Worker       cfg.scissor_minimum_y = miny;
1095*61046927SAndroid Build Coastguard Worker       cfg.scissor_maximum_x = maxx;
1096*61046927SAndroid Build Coastguard Worker       cfg.scissor_maximum_y = maxy;
1097*61046927SAndroid Build Coastguard Worker    }
1098*61046927SAndroid Build Coastguard Worker 
1099*61046927SAndroid Build Coastguard Worker    return vp.gpu;
1100*61046927SAndroid Build Coastguard Worker }
1101*61046927SAndroid Build Coastguard Worker #endif
1102*61046927SAndroid Build Coastguard Worker 
1103*61046927SAndroid Build Coastguard Worker static void
pan_preload_emit_dcd(struct pan_blitter_cache * cache,struct pan_pool * pool,struct pan_fb_info * fb,bool zs,mali_ptr coordinates,mali_ptr tsd,void * out,bool always_write)1104*61046927SAndroid Build Coastguard Worker pan_preload_emit_dcd(struct pan_blitter_cache *cache,
1105*61046927SAndroid Build Coastguard Worker                      struct pan_pool *pool, struct pan_fb_info *fb, bool zs,
1106*61046927SAndroid Build Coastguard Worker                      mali_ptr coordinates, mali_ptr tsd, void *out,
1107*61046927SAndroid Build Coastguard Worker                      bool always_write)
1108*61046927SAndroid Build Coastguard Worker {
1109*61046927SAndroid Build Coastguard Worker    unsigned tex_count = 0;
1110*61046927SAndroid Build Coastguard Worker    mali_ptr textures = pan_preload_emit_textures(pool, fb, zs, &tex_count);
1111*61046927SAndroid Build Coastguard Worker    mali_ptr samplers = pan_blitter_emit_sampler(pool, true);
1112*61046927SAndroid Build Coastguard Worker    mali_ptr varyings = pan_blitter_emit_varying(pool);
1113*61046927SAndroid Build Coastguard Worker    mali_ptr varying_buffers =
1114*61046927SAndroid Build Coastguard Worker       pan_blitter_emit_varying_buffer(pool, coordinates);
1115*61046927SAndroid Build Coastguard Worker 
1116*61046927SAndroid Build Coastguard Worker    /* Tiles updated by blit shaders are still considered clean (separate
1117*61046927SAndroid Build Coastguard Worker     * for colour and Z/S), allowing us to suppress unnecessary writeback
1118*61046927SAndroid Build Coastguard Worker     */
1119*61046927SAndroid Build Coastguard Worker    UNUSED bool clean_fragment_write = !always_write;
1120*61046927SAndroid Build Coastguard Worker 
1121*61046927SAndroid Build Coastguard Worker    /* Image view used when patching stencil formats for combined
1122*61046927SAndroid Build Coastguard Worker     * depth/stencil preloads.
1123*61046927SAndroid Build Coastguard Worker     */
1124*61046927SAndroid Build Coastguard Worker    struct pan_image_view patched_s;
1125*61046927SAndroid Build Coastguard Worker 
1126*61046927SAndroid Build Coastguard Worker    struct pan_blitter_views views = pan_preload_get_views(fb, zs, &patched_s);
1127*61046927SAndroid Build Coastguard Worker 
1128*61046927SAndroid Build Coastguard Worker #if PAN_ARCH <= 7
1129*61046927SAndroid Build Coastguard Worker    pan_pack(out, DRAW, cfg) {
1130*61046927SAndroid Build Coastguard Worker       uint16_t minx = 0, miny = 0, maxx, maxy;
1131*61046927SAndroid Build Coastguard Worker 
1132*61046927SAndroid Build Coastguard Worker       if (PAN_ARCH == 4) {
1133*61046927SAndroid Build Coastguard Worker          maxx = fb->width - 1;
1134*61046927SAndroid Build Coastguard Worker          maxy = fb->height - 1;
1135*61046927SAndroid Build Coastguard Worker       } else {
1136*61046927SAndroid Build Coastguard Worker          /* Align on 32x32 tiles */
1137*61046927SAndroid Build Coastguard Worker          minx = fb->extent.minx & ~31;
1138*61046927SAndroid Build Coastguard Worker          miny = fb->extent.miny & ~31;
1139*61046927SAndroid Build Coastguard Worker          maxx = MIN2(ALIGN_POT(fb->extent.maxx + 1, 32), fb->width) - 1;
1140*61046927SAndroid Build Coastguard Worker          maxy = MIN2(ALIGN_POT(fb->extent.maxy + 1, 32), fb->height) - 1;
1141*61046927SAndroid Build Coastguard Worker       }
1142*61046927SAndroid Build Coastguard Worker 
1143*61046927SAndroid Build Coastguard Worker       cfg.thread_storage = tsd;
1144*61046927SAndroid Build Coastguard Worker       cfg.state = pan_blitter_get_rsd(cache, &views);
1145*61046927SAndroid Build Coastguard Worker 
1146*61046927SAndroid Build Coastguard Worker       cfg.position = coordinates;
1147*61046927SAndroid Build Coastguard Worker       cfg.viewport = pan_blitter_emit_viewport(pool, minx, miny, maxx, maxy);
1148*61046927SAndroid Build Coastguard Worker 
1149*61046927SAndroid Build Coastguard Worker       cfg.varyings = varyings;
1150*61046927SAndroid Build Coastguard Worker       cfg.varying_buffers = varying_buffers;
1151*61046927SAndroid Build Coastguard Worker       cfg.textures = textures;
1152*61046927SAndroid Build Coastguard Worker       cfg.samplers = samplers;
1153*61046927SAndroid Build Coastguard Worker 
1154*61046927SAndroid Build Coastguard Worker #if PAN_ARCH >= 6
1155*61046927SAndroid Build Coastguard Worker       cfg.clean_fragment_write = clean_fragment_write;
1156*61046927SAndroid Build Coastguard Worker #endif
1157*61046927SAndroid Build Coastguard Worker    }
1158*61046927SAndroid Build Coastguard Worker #else
1159*61046927SAndroid Build Coastguard Worker    struct panfrost_ptr T;
1160*61046927SAndroid Build Coastguard Worker    unsigned nr_tables = PAN_BLIT_NUM_RESOURCE_TABLES;
1161*61046927SAndroid Build Coastguard Worker 
1162*61046927SAndroid Build Coastguard Worker    /* Although individual resources need only 16 byte alignment, the
1163*61046927SAndroid Build Coastguard Worker     * resource table as a whole must be 64-byte aligned.
1164*61046927SAndroid Build Coastguard Worker     */
1165*61046927SAndroid Build Coastguard Worker    T = pan_pool_alloc_aligned(pool, nr_tables * pan_size(RESOURCE), 64);
1166*61046927SAndroid Build Coastguard Worker    memset(T.cpu, 0, nr_tables * pan_size(RESOURCE));
1167*61046927SAndroid Build Coastguard Worker 
1168*61046927SAndroid Build Coastguard Worker    panfrost_make_resource_table(T, PAN_BLIT_TABLE_TEXTURE, textures, tex_count);
1169*61046927SAndroid Build Coastguard Worker    panfrost_make_resource_table(T, PAN_BLIT_TABLE_SAMPLER, samplers, 1);
1170*61046927SAndroid Build Coastguard Worker    panfrost_make_resource_table(T, PAN_BLIT_TABLE_ATTRIBUTE, varyings, 1);
1171*61046927SAndroid Build Coastguard Worker    panfrost_make_resource_table(T, PAN_BLIT_TABLE_ATTRIBUTE_BUFFER,
1172*61046927SAndroid Build Coastguard Worker                                 varying_buffers, 1);
1173*61046927SAndroid Build Coastguard Worker 
1174*61046927SAndroid Build Coastguard Worker    struct pan_blit_shader_key key = pan_blitter_get_key(&views);
1175*61046927SAndroid Build Coastguard Worker    const struct pan_blit_shader_data *blit_shader =
1176*61046927SAndroid Build Coastguard Worker       pan_blitter_get_blit_shader(cache, &key);
1177*61046927SAndroid Build Coastguard Worker 
1178*61046927SAndroid Build Coastguard Worker    bool z = fb->zs.preload.z;
1179*61046927SAndroid Build Coastguard Worker    bool s = fb->zs.preload.s;
1180*61046927SAndroid Build Coastguard Worker    bool ms = pan_blitter_is_ms(&views);
1181*61046927SAndroid Build Coastguard Worker 
1182*61046927SAndroid Build Coastguard Worker    struct panfrost_ptr spd = pan_pool_alloc_desc(pool, SHADER_PROGRAM);
1183*61046927SAndroid Build Coastguard Worker    pan_pack(spd.cpu, SHADER_PROGRAM, cfg) {
1184*61046927SAndroid Build Coastguard Worker       cfg.stage = MALI_SHADER_STAGE_FRAGMENT;
1185*61046927SAndroid Build Coastguard Worker       cfg.fragment_coverage_bitmask_type = MALI_COVERAGE_BITMASK_TYPE_GL;
1186*61046927SAndroid Build Coastguard Worker       cfg.register_allocation = MALI_SHADER_REGISTER_ALLOCATION_32_PER_THREAD;
1187*61046927SAndroid Build Coastguard Worker       cfg.binary = blit_shader->address;
1188*61046927SAndroid Build Coastguard Worker       cfg.preload.r48_r63 = blit_shader->info.preload >> 48;
1189*61046927SAndroid Build Coastguard Worker    }
1190*61046927SAndroid Build Coastguard Worker 
1191*61046927SAndroid Build Coastguard Worker    unsigned bd_count = views.rt_count;
1192*61046927SAndroid Build Coastguard Worker    struct panfrost_ptr blend = pan_pool_alloc_desc_array(pool, bd_count, BLEND);
1193*61046927SAndroid Build Coastguard Worker 
1194*61046927SAndroid Build Coastguard Worker    if (!zs) {
1195*61046927SAndroid Build Coastguard Worker       pan_blitter_emit_blends(blit_shader, &views, NULL, blend.cpu);
1196*61046927SAndroid Build Coastguard Worker    }
1197*61046927SAndroid Build Coastguard Worker 
1198*61046927SAndroid Build Coastguard Worker    pan_pack(out, DRAW, cfg) {
1199*61046927SAndroid Build Coastguard Worker       if (zs) {
1200*61046927SAndroid Build Coastguard Worker          /* ZS_EMIT requires late update/kill */
1201*61046927SAndroid Build Coastguard Worker          cfg.zs_update_operation = MALI_PIXEL_KILL_FORCE_LATE;
1202*61046927SAndroid Build Coastguard Worker          cfg.pixel_kill_operation = MALI_PIXEL_KILL_FORCE_LATE;
1203*61046927SAndroid Build Coastguard Worker          cfg.blend_count = 0;
1204*61046927SAndroid Build Coastguard Worker       } else {
1205*61046927SAndroid Build Coastguard Worker          /* Skipping ATEST requires forcing Z/S */
1206*61046927SAndroid Build Coastguard Worker          cfg.zs_update_operation = MALI_PIXEL_KILL_STRONG_EARLY;
1207*61046927SAndroid Build Coastguard Worker          cfg.pixel_kill_operation = MALI_PIXEL_KILL_FORCE_EARLY;
1208*61046927SAndroid Build Coastguard Worker 
1209*61046927SAndroid Build Coastguard Worker          cfg.blend = blend.gpu;
1210*61046927SAndroid Build Coastguard Worker          cfg.blend_count = bd_count;
1211*61046927SAndroid Build Coastguard Worker          cfg.render_target_mask = 0x1;
1212*61046927SAndroid Build Coastguard Worker       }
1213*61046927SAndroid Build Coastguard Worker 
1214*61046927SAndroid Build Coastguard Worker       cfg.allow_forward_pixel_to_kill = !zs;
1215*61046927SAndroid Build Coastguard Worker       cfg.allow_forward_pixel_to_be_killed = true;
1216*61046927SAndroid Build Coastguard Worker       cfg.depth_stencil = pan_blitter_emit_zs(pool, z, s);
1217*61046927SAndroid Build Coastguard Worker       cfg.sample_mask = 0xFFFF;
1218*61046927SAndroid Build Coastguard Worker       cfg.multisample_enable = ms;
1219*61046927SAndroid Build Coastguard Worker       cfg.evaluate_per_sample = ms;
1220*61046927SAndroid Build Coastguard Worker       cfg.maximum_z = 1.0;
1221*61046927SAndroid Build Coastguard Worker       cfg.clean_fragment_write = clean_fragment_write;
1222*61046927SAndroid Build Coastguard Worker       cfg.shader.resources = T.gpu | nr_tables;
1223*61046927SAndroid Build Coastguard Worker       cfg.shader.shader = spd.gpu;
1224*61046927SAndroid Build Coastguard Worker       cfg.shader.thread_storage = tsd;
1225*61046927SAndroid Build Coastguard Worker    }
1226*61046927SAndroid Build Coastguard Worker #endif
1227*61046927SAndroid Build Coastguard Worker }
1228*61046927SAndroid Build Coastguard Worker 
1229*61046927SAndroid Build Coastguard Worker #if PAN_ARCH >= 6
1230*61046927SAndroid Build Coastguard Worker static void
pan_preload_fb_alloc_pre_post_dcds(struct pan_pool * desc_pool,struct pan_fb_info * fb)1231*61046927SAndroid Build Coastguard Worker pan_preload_fb_alloc_pre_post_dcds(struct pan_pool *desc_pool,
1232*61046927SAndroid Build Coastguard Worker                                    struct pan_fb_info *fb)
1233*61046927SAndroid Build Coastguard Worker {
1234*61046927SAndroid Build Coastguard Worker    if (fb->bifrost.pre_post.dcds.gpu)
1235*61046927SAndroid Build Coastguard Worker       return;
1236*61046927SAndroid Build Coastguard Worker 
1237*61046927SAndroid Build Coastguard Worker    fb->bifrost.pre_post.dcds = pan_pool_alloc_desc_array(desc_pool, 3, DRAW);
1238*61046927SAndroid Build Coastguard Worker }
1239*61046927SAndroid Build Coastguard Worker 
1240*61046927SAndroid Build Coastguard Worker static void
pan_preload_emit_pre_frame_dcd(struct pan_blitter_cache * cache,struct pan_pool * desc_pool,struct pan_fb_info * fb,bool zs,mali_ptr coords,mali_ptr tsd)1241*61046927SAndroid Build Coastguard Worker pan_preload_emit_pre_frame_dcd(struct pan_blitter_cache *cache,
1242*61046927SAndroid Build Coastguard Worker                                struct pan_pool *desc_pool,
1243*61046927SAndroid Build Coastguard Worker                                struct pan_fb_info *fb, bool zs, mali_ptr coords,
1244*61046927SAndroid Build Coastguard Worker                                mali_ptr tsd)
1245*61046927SAndroid Build Coastguard Worker {
1246*61046927SAndroid Build Coastguard Worker    unsigned dcd_idx = zs ? 1 : 0;
1247*61046927SAndroid Build Coastguard Worker    pan_preload_fb_alloc_pre_post_dcds(desc_pool, fb);
1248*61046927SAndroid Build Coastguard Worker    assert(fb->bifrost.pre_post.dcds.cpu);
1249*61046927SAndroid Build Coastguard Worker    void *dcd = fb->bifrost.pre_post.dcds.cpu + (dcd_idx * pan_size(DRAW));
1250*61046927SAndroid Build Coastguard Worker 
1251*61046927SAndroid Build Coastguard Worker    /* We only use crc_rt to determine whether to force writes for updating
1252*61046927SAndroid Build Coastguard Worker     * the CRCs, so use a conservative tile size (16x16).
1253*61046927SAndroid Build Coastguard Worker     */
1254*61046927SAndroid Build Coastguard Worker    int crc_rt = GENX(pan_select_crc_rt)(fb, 16 * 16);
1255*61046927SAndroid Build Coastguard Worker 
1256*61046927SAndroid Build Coastguard Worker    bool always_write = false;
1257*61046927SAndroid Build Coastguard Worker 
1258*61046927SAndroid Build Coastguard Worker    /* If CRC data is currently invalid and this batch will make it valid,
1259*61046927SAndroid Build Coastguard Worker     * write even clean tiles to make sure CRC data is updated. */
1260*61046927SAndroid Build Coastguard Worker    if (crc_rt >= 0) {
1261*61046927SAndroid Build Coastguard Worker       bool *valid = fb->rts[crc_rt].crc_valid;
1262*61046927SAndroid Build Coastguard Worker       bool full = !fb->extent.minx && !fb->extent.miny &&
1263*61046927SAndroid Build Coastguard Worker                   fb->extent.maxx == (fb->width - 1) &&
1264*61046927SAndroid Build Coastguard Worker                   fb->extent.maxy == (fb->height - 1);
1265*61046927SAndroid Build Coastguard Worker 
1266*61046927SAndroid Build Coastguard Worker       if (full && !(*valid))
1267*61046927SAndroid Build Coastguard Worker          always_write = true;
1268*61046927SAndroid Build Coastguard Worker    }
1269*61046927SAndroid Build Coastguard Worker 
1270*61046927SAndroid Build Coastguard Worker    pan_preload_emit_dcd(cache, desc_pool, fb, zs, coords, tsd, dcd,
1271*61046927SAndroid Build Coastguard Worker                         always_write);
1272*61046927SAndroid Build Coastguard Worker    if (zs) {
1273*61046927SAndroid Build Coastguard Worker       enum pipe_format fmt = fb->zs.view.zs
1274*61046927SAndroid Build Coastguard Worker                                 ? fb->zs.view.zs->planes[0]->layout.format
1275*61046927SAndroid Build Coastguard Worker                                 : fb->zs.view.s->planes[0]->layout.format;
1276*61046927SAndroid Build Coastguard Worker       bool always = false;
1277*61046927SAndroid Build Coastguard Worker 
1278*61046927SAndroid Build Coastguard Worker       /* If we're dealing with a combined ZS resource and only one
1279*61046927SAndroid Build Coastguard Worker        * component is cleared, we need to reload the whole surface
1280*61046927SAndroid Build Coastguard Worker        * because the zs_clean_pixel_write_enable flag is set in that
1281*61046927SAndroid Build Coastguard Worker        * case.
1282*61046927SAndroid Build Coastguard Worker        */
1283*61046927SAndroid Build Coastguard Worker       if (util_format_is_depth_and_stencil(fmt) &&
1284*61046927SAndroid Build Coastguard Worker           fb->zs.clear.z != fb->zs.clear.s)
1285*61046927SAndroid Build Coastguard Worker          always = true;
1286*61046927SAndroid Build Coastguard Worker 
1287*61046927SAndroid Build Coastguard Worker       /* We could use INTERSECT on Bifrost v7 too, but
1288*61046927SAndroid Build Coastguard Worker        * EARLY_ZS_ALWAYS has the advantage of reloading the ZS tile
1289*61046927SAndroid Build Coastguard Worker        * buffer one or more tiles ahead, making ZS data immediately
1290*61046927SAndroid Build Coastguard Worker        * available for any ZS tests taking place in other shaders.
1291*61046927SAndroid Build Coastguard Worker        * Thing's haven't been benchmarked to determine what's
1292*61046927SAndroid Build Coastguard Worker        * preferable (saving bandwidth vs having ZS preloaded
1293*61046927SAndroid Build Coastguard Worker        * earlier), so let's leave it like that for now.
1294*61046927SAndroid Build Coastguard Worker        */
1295*61046927SAndroid Build Coastguard Worker       fb->bifrost.pre_post.modes[dcd_idx] =
1296*61046927SAndroid Build Coastguard Worker          PAN_ARCH > 6
1297*61046927SAndroid Build Coastguard Worker             ? MALI_PRE_POST_FRAME_SHADER_MODE_EARLY_ZS_ALWAYS
1298*61046927SAndroid Build Coastguard Worker          : always ? MALI_PRE_POST_FRAME_SHADER_MODE_ALWAYS
1299*61046927SAndroid Build Coastguard Worker                   : MALI_PRE_POST_FRAME_SHADER_MODE_INTERSECT;
1300*61046927SAndroid Build Coastguard Worker    } else {
1301*61046927SAndroid Build Coastguard Worker       fb->bifrost.pre_post.modes[dcd_idx] =
1302*61046927SAndroid Build Coastguard Worker          always_write ? MALI_PRE_POST_FRAME_SHADER_MODE_ALWAYS
1303*61046927SAndroid Build Coastguard Worker                       : MALI_PRE_POST_FRAME_SHADER_MODE_INTERSECT;
1304*61046927SAndroid Build Coastguard Worker    }
1305*61046927SAndroid Build Coastguard Worker }
1306*61046927SAndroid Build Coastguard Worker #else
1307*61046927SAndroid Build Coastguard Worker static struct panfrost_ptr
pan_preload_emit_tiler_job(struct pan_blitter_cache * cache,struct pan_pool * desc_pool,struct pan_fb_info * fb,bool zs,mali_ptr coords,mali_ptr tsd)1308*61046927SAndroid Build Coastguard Worker pan_preload_emit_tiler_job(struct pan_blitter_cache *cache, struct pan_pool *desc_pool,
1309*61046927SAndroid Build Coastguard Worker                            struct pan_fb_info *fb, bool zs, mali_ptr coords,
1310*61046927SAndroid Build Coastguard Worker                            mali_ptr tsd)
1311*61046927SAndroid Build Coastguard Worker {
1312*61046927SAndroid Build Coastguard Worker    struct panfrost_ptr job = pan_pool_alloc_desc(desc_pool, TILER_JOB);
1313*61046927SAndroid Build Coastguard Worker 
1314*61046927SAndroid Build Coastguard Worker    pan_preload_emit_dcd(cache, desc_pool, fb, zs, coords, tsd,
1315*61046927SAndroid Build Coastguard Worker                         pan_section_ptr(job.cpu, TILER_JOB, DRAW), false);
1316*61046927SAndroid Build Coastguard Worker 
1317*61046927SAndroid Build Coastguard Worker    pan_section_pack(job.cpu, TILER_JOB, PRIMITIVE, cfg) {
1318*61046927SAndroid Build Coastguard Worker       cfg.draw_mode = MALI_DRAW_MODE_TRIANGLE_STRIP;
1319*61046927SAndroid Build Coastguard Worker       cfg.index_count = 4;
1320*61046927SAndroid Build Coastguard Worker       cfg.job_task_split = 6;
1321*61046927SAndroid Build Coastguard Worker    }
1322*61046927SAndroid Build Coastguard Worker 
1323*61046927SAndroid Build Coastguard Worker    pan_section_pack(job.cpu, TILER_JOB, PRIMITIVE_SIZE, cfg) {
1324*61046927SAndroid Build Coastguard Worker       cfg.constant = 1.0f;
1325*61046927SAndroid Build Coastguard Worker    }
1326*61046927SAndroid Build Coastguard Worker 
1327*61046927SAndroid Build Coastguard Worker    void *invoc = pan_section_ptr(job.cpu, TILER_JOB, INVOCATION);
1328*61046927SAndroid Build Coastguard Worker    panfrost_pack_work_groups_compute(invoc, 1, 4, 1, 1, 1, 1, true, false);
1329*61046927SAndroid Build Coastguard Worker 
1330*61046927SAndroid Build Coastguard Worker    return job;
1331*61046927SAndroid Build Coastguard Worker }
1332*61046927SAndroid Build Coastguard Worker #endif
1333*61046927SAndroid Build Coastguard Worker 
1334*61046927SAndroid Build Coastguard Worker static struct panfrost_ptr
pan_preload_fb_part(struct pan_blitter_cache * cache,struct pan_pool * pool,struct pan_fb_info * fb,bool zs,mali_ptr coords,mali_ptr tsd)1335*61046927SAndroid Build Coastguard Worker pan_preload_fb_part(struct pan_blitter_cache *cache, struct pan_pool *pool,
1336*61046927SAndroid Build Coastguard Worker                     struct pan_fb_info *fb, bool zs, mali_ptr coords,
1337*61046927SAndroid Build Coastguard Worker                     mali_ptr tsd)
1338*61046927SAndroid Build Coastguard Worker {
1339*61046927SAndroid Build Coastguard Worker    struct panfrost_ptr job = {0};
1340*61046927SAndroid Build Coastguard Worker 
1341*61046927SAndroid Build Coastguard Worker #if PAN_ARCH >= 6
1342*61046927SAndroid Build Coastguard Worker    pan_preload_emit_pre_frame_dcd(cache, pool, fb, zs, coords, tsd);
1343*61046927SAndroid Build Coastguard Worker #else
1344*61046927SAndroid Build Coastguard Worker    job = pan_preload_emit_tiler_job(cache, pool, fb, zs, coords, tsd);
1345*61046927SAndroid Build Coastguard Worker #endif
1346*61046927SAndroid Build Coastguard Worker    return job;
1347*61046927SAndroid Build Coastguard Worker }
1348*61046927SAndroid Build Coastguard Worker 
1349*61046927SAndroid Build Coastguard Worker unsigned
GENX(pan_preload_fb)1350*61046927SAndroid Build Coastguard Worker GENX(pan_preload_fb)(struct pan_blitter_cache *cache, struct pan_pool *pool,
1351*61046927SAndroid Build Coastguard Worker                      struct pan_fb_info *fb, unsigned layer_idx, mali_ptr tsd,
1352*61046927SAndroid Build Coastguard Worker                      struct panfrost_ptr *jobs)
1353*61046927SAndroid Build Coastguard Worker {
1354*61046927SAndroid Build Coastguard Worker    bool preload_zs = pan_preload_needed(fb, true);
1355*61046927SAndroid Build Coastguard Worker    bool preload_rts = pan_preload_needed(fb, false);
1356*61046927SAndroid Build Coastguard Worker    mali_ptr coords;
1357*61046927SAndroid Build Coastguard Worker 
1358*61046927SAndroid Build Coastguard Worker    if (!preload_zs && !preload_rts)
1359*61046927SAndroid Build Coastguard Worker       return 0;
1360*61046927SAndroid Build Coastguard Worker 
1361*61046927SAndroid Build Coastguard Worker    float rect[] = {
1362*61046927SAndroid Build Coastguard Worker       0.0,       0.0,        layer_idx, 1.0,
1363*61046927SAndroid Build Coastguard Worker       fb->width, 0.0,        layer_idx, 1.0,
1364*61046927SAndroid Build Coastguard Worker       0.0,       fb->height, layer_idx, 1.0,
1365*61046927SAndroid Build Coastguard Worker       fb->width, fb->height, layer_idx, 1.0,
1366*61046927SAndroid Build Coastguard Worker    };
1367*61046927SAndroid Build Coastguard Worker 
1368*61046927SAndroid Build Coastguard Worker    coords = pan_pool_upload_aligned(pool, rect, sizeof(rect), 64);
1369*61046927SAndroid Build Coastguard Worker 
1370*61046927SAndroid Build Coastguard Worker    unsigned njobs = 0;
1371*61046927SAndroid Build Coastguard Worker    if (preload_zs) {
1372*61046927SAndroid Build Coastguard Worker       struct panfrost_ptr job =
1373*61046927SAndroid Build Coastguard Worker          pan_preload_fb_part(cache, pool, fb, true, coords, tsd);
1374*61046927SAndroid Build Coastguard Worker       if (jobs && job.cpu)
1375*61046927SAndroid Build Coastguard Worker          jobs[njobs++] = job;
1376*61046927SAndroid Build Coastguard Worker    }
1377*61046927SAndroid Build Coastguard Worker 
1378*61046927SAndroid Build Coastguard Worker    if (preload_rts) {
1379*61046927SAndroid Build Coastguard Worker       struct panfrost_ptr job =
1380*61046927SAndroid Build Coastguard Worker          pan_preload_fb_part(cache, pool, fb, false, coords, tsd);
1381*61046927SAndroid Build Coastguard Worker       if (jobs && job.cpu)
1382*61046927SAndroid Build Coastguard Worker          jobs[njobs++] = job;
1383*61046927SAndroid Build Coastguard Worker    }
1384*61046927SAndroid Build Coastguard Worker 
1385*61046927SAndroid Build Coastguard Worker    return njobs;
1386*61046927SAndroid Build Coastguard Worker }
1387*61046927SAndroid Build Coastguard Worker 
1388*61046927SAndroid Build Coastguard Worker DERIVE_HASH_TABLE(pan_blit_shader_key);
1389*61046927SAndroid Build Coastguard Worker DERIVE_HASH_TABLE(pan_blit_blend_shader_key);
1390*61046927SAndroid Build Coastguard Worker DERIVE_HASH_TABLE(pan_blit_rsd_key);
1391*61046927SAndroid Build Coastguard Worker 
1392*61046927SAndroid Build Coastguard Worker static void
pan_blitter_prefill_blit_shader_cache(struct pan_blitter_cache * cache)1393*61046927SAndroid Build Coastguard Worker pan_blitter_prefill_blit_shader_cache(struct pan_blitter_cache *cache)
1394*61046927SAndroid Build Coastguard Worker {
1395*61046927SAndroid Build Coastguard Worker    static const struct pan_blit_shader_key prefill[] = {
1396*61046927SAndroid Build Coastguard Worker       {
1397*61046927SAndroid Build Coastguard Worker          .surfaces[0] =
1398*61046927SAndroid Build Coastguard Worker             {
1399*61046927SAndroid Build Coastguard Worker                .loc = FRAG_RESULT_DEPTH,
1400*61046927SAndroid Build Coastguard Worker                .type = nir_type_float32,
1401*61046927SAndroid Build Coastguard Worker                .dim = MALI_TEXTURE_DIMENSION_2D,
1402*61046927SAndroid Build Coastguard Worker                .src_samples = 1,
1403*61046927SAndroid Build Coastguard Worker                .dst_samples = 1,
1404*61046927SAndroid Build Coastguard Worker             },
1405*61046927SAndroid Build Coastguard Worker       },
1406*61046927SAndroid Build Coastguard Worker       {
1407*61046927SAndroid Build Coastguard Worker          .surfaces[1] =
1408*61046927SAndroid Build Coastguard Worker             {
1409*61046927SAndroid Build Coastguard Worker                .loc = FRAG_RESULT_STENCIL,
1410*61046927SAndroid Build Coastguard Worker                .type = nir_type_uint32,
1411*61046927SAndroid Build Coastguard Worker                .dim = MALI_TEXTURE_DIMENSION_2D,
1412*61046927SAndroid Build Coastguard Worker                .src_samples = 1,
1413*61046927SAndroid Build Coastguard Worker                .dst_samples = 1,
1414*61046927SAndroid Build Coastguard Worker             },
1415*61046927SAndroid Build Coastguard Worker       },
1416*61046927SAndroid Build Coastguard Worker       {
1417*61046927SAndroid Build Coastguard Worker          .surfaces[0] =
1418*61046927SAndroid Build Coastguard Worker             {
1419*61046927SAndroid Build Coastguard Worker                .loc = FRAG_RESULT_DATA0,
1420*61046927SAndroid Build Coastguard Worker                .type = nir_type_float32,
1421*61046927SAndroid Build Coastguard Worker                .dim = MALI_TEXTURE_DIMENSION_2D,
1422*61046927SAndroid Build Coastguard Worker                .src_samples = 1,
1423*61046927SAndroid Build Coastguard Worker                .dst_samples = 1,
1424*61046927SAndroid Build Coastguard Worker             },
1425*61046927SAndroid Build Coastguard Worker       },
1426*61046927SAndroid Build Coastguard Worker    };
1427*61046927SAndroid Build Coastguard Worker 
1428*61046927SAndroid Build Coastguard Worker    for (unsigned i = 0; i < ARRAY_SIZE(prefill); i++)
1429*61046927SAndroid Build Coastguard Worker       pan_blitter_get_blit_shader(cache, &prefill[i]);
1430*61046927SAndroid Build Coastguard Worker }
1431*61046927SAndroid Build Coastguard Worker 
1432*61046927SAndroid Build Coastguard Worker void
GENX(pan_blitter_cache_init)1433*61046927SAndroid Build Coastguard Worker GENX(pan_blitter_cache_init)(struct pan_blitter_cache *cache,
1434*61046927SAndroid Build Coastguard Worker                              unsigned gpu_id,
1435*61046927SAndroid Build Coastguard Worker                              struct pan_blend_shader_cache *blend_shader_cache,
1436*61046927SAndroid Build Coastguard Worker                              struct pan_pool *bin_pool,
1437*61046927SAndroid Build Coastguard Worker                              struct pan_pool *desc_pool)
1438*61046927SAndroid Build Coastguard Worker {
1439*61046927SAndroid Build Coastguard Worker    cache->gpu_id = gpu_id;
1440*61046927SAndroid Build Coastguard Worker    cache->shaders.blit = pan_blit_shader_key_table_create(NULL);
1441*61046927SAndroid Build Coastguard Worker    cache->shaders.blend = pan_blit_blend_shader_key_table_create(NULL);
1442*61046927SAndroid Build Coastguard Worker    cache->shaders.pool = bin_pool;
1443*61046927SAndroid Build Coastguard Worker    pthread_mutex_init(&cache->shaders.lock, NULL);
1444*61046927SAndroid Build Coastguard Worker    pan_blitter_prefill_blit_shader_cache(cache);
1445*61046927SAndroid Build Coastguard Worker 
1446*61046927SAndroid Build Coastguard Worker    cache->rsds.pool = desc_pool;
1447*61046927SAndroid Build Coastguard Worker    cache->rsds.rsds = pan_blit_rsd_key_table_create(NULL);
1448*61046927SAndroid Build Coastguard Worker    pthread_mutex_init(&cache->rsds.lock, NULL);
1449*61046927SAndroid Build Coastguard Worker    cache->blend_shader_cache = blend_shader_cache;
1450*61046927SAndroid Build Coastguard Worker }
1451*61046927SAndroid Build Coastguard Worker 
1452*61046927SAndroid Build Coastguard Worker void
GENX(pan_blitter_cache_cleanup)1453*61046927SAndroid Build Coastguard Worker GENX(pan_blitter_cache_cleanup)(struct pan_blitter_cache *cache)
1454*61046927SAndroid Build Coastguard Worker {
1455*61046927SAndroid Build Coastguard Worker    _mesa_hash_table_destroy(cache->shaders.blit, NULL);
1456*61046927SAndroid Build Coastguard Worker    _mesa_hash_table_destroy(cache->shaders.blend, NULL);
1457*61046927SAndroid Build Coastguard Worker    pthread_mutex_destroy(&cache->shaders.lock);
1458*61046927SAndroid Build Coastguard Worker    _mesa_hash_table_destroy(cache->rsds.rsds, NULL);
1459*61046927SAndroid Build Coastguard Worker    pthread_mutex_destroy(&cache->rsds.lock);
1460*61046927SAndroid Build Coastguard Worker }
1461