1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Copyright © 2021 Collabora Ltd.
3bf215546Sopenharmony_ci *
4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation
7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
10bf215546Sopenharmony_ci *
11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next
12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the
13bf215546Sopenharmony_ci * Software.
14bf215546Sopenharmony_ci *
15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21bf215546Sopenharmony_ci * DEALINGS IN THE SOFTWARE.
22bf215546Sopenharmony_ci */
23bf215546Sopenharmony_ci
24bf215546Sopenharmony_ci#include "nir/nir_builder.h"
25bf215546Sopenharmony_ci#include "pan_blitter.h"
26bf215546Sopenharmony_ci#include "pan_encoder.h"
27bf215546Sopenharmony_ci#include "pan_shader.h"
28bf215546Sopenharmony_ci
29bf215546Sopenharmony_ci#include "panvk_private.h"
30bf215546Sopenharmony_ci#include "panvk_vX_meta.h"
31bf215546Sopenharmony_ci
32bf215546Sopenharmony_ci#include "vk_format.h"
33bf215546Sopenharmony_ci
34bf215546Sopenharmony_cistatic mali_ptr
35bf215546Sopenharmony_cipanvk_meta_clear_color_attachment_shader(struct panfrost_device *pdev,
36bf215546Sopenharmony_ci                                         struct pan_pool *bin_pool,
37bf215546Sopenharmony_ci                                         enum glsl_base_type base_type,
38bf215546Sopenharmony_ci                                         struct pan_shader_info *shader_info)
39bf215546Sopenharmony_ci{
40bf215546Sopenharmony_ci   nir_builder b = nir_builder_init_simple_shader(MESA_SHADER_FRAGMENT,
41bf215546Sopenharmony_ci                                     GENX(pan_shader_get_compiler_options)(),
42bf215546Sopenharmony_ci                                     "panvk_meta_clear_attachment(base_type=%d)",
43bf215546Sopenharmony_ci                                     base_type);
44bf215546Sopenharmony_ci
45bf215546Sopenharmony_ci   const struct glsl_type *out_type = glsl_vector_type(base_type, 4);
46bf215546Sopenharmony_ci   nir_variable *out =
47bf215546Sopenharmony_ci      nir_variable_create(b.shader, nir_var_shader_out, out_type, "out");
48bf215546Sopenharmony_ci   out->data.location = FRAG_RESULT_DATA0;
49bf215546Sopenharmony_ci
50bf215546Sopenharmony_ci   nir_ssa_def *clear_values = nir_load_push_constant(&b, 4, 32,
51bf215546Sopenharmony_ci                                                      nir_imm_int(&b, 0),
52bf215546Sopenharmony_ci                                                     .range = ~0);
53bf215546Sopenharmony_ci   nir_store_var(&b, out, clear_values, 0xff);
54bf215546Sopenharmony_ci
55bf215546Sopenharmony_ci   struct panfrost_compile_inputs inputs = {
56bf215546Sopenharmony_ci      .gpu_id = pdev->gpu_id,
57bf215546Sopenharmony_ci      .is_blit = true,
58bf215546Sopenharmony_ci      .no_ubo_to_push = true,
59bf215546Sopenharmony_ci   };
60bf215546Sopenharmony_ci
61bf215546Sopenharmony_ci   struct util_dynarray binary;
62bf215546Sopenharmony_ci
63bf215546Sopenharmony_ci   util_dynarray_init(&binary, NULL);
64bf215546Sopenharmony_ci   GENX(pan_shader_compile)(b.shader, &inputs, &binary, shader_info);
65bf215546Sopenharmony_ci
66bf215546Sopenharmony_ci   shader_info->push.count = 4;
67bf215546Sopenharmony_ci
68bf215546Sopenharmony_ci   mali_ptr shader =
69bf215546Sopenharmony_ci      pan_pool_upload_aligned(bin_pool, binary.data, binary.size, 128);
70bf215546Sopenharmony_ci
71bf215546Sopenharmony_ci   util_dynarray_fini(&binary);
72bf215546Sopenharmony_ci   ralloc_free(b.shader);
73bf215546Sopenharmony_ci
74bf215546Sopenharmony_ci   return shader;
75bf215546Sopenharmony_ci}
76bf215546Sopenharmony_ci
77bf215546Sopenharmony_cistatic mali_ptr
78bf215546Sopenharmony_cipanvk_meta_clear_color_attachment_emit_rsd(struct panfrost_device *pdev,
79bf215546Sopenharmony_ci                                           struct pan_pool *desc_pool,
80bf215546Sopenharmony_ci                                           enum pipe_format format,
81bf215546Sopenharmony_ci                                           unsigned rt,
82bf215546Sopenharmony_ci                                           struct pan_shader_info *shader_info,
83bf215546Sopenharmony_ci                                           mali_ptr shader)
84bf215546Sopenharmony_ci{
85bf215546Sopenharmony_ci   struct panfrost_ptr rsd_ptr =
86bf215546Sopenharmony_ci      pan_pool_alloc_desc_aggregate(desc_pool,
87bf215546Sopenharmony_ci                                    PAN_DESC(RENDERER_STATE),
88bf215546Sopenharmony_ci                                    PAN_DESC_ARRAY(rt + 1, BLEND));
89bf215546Sopenharmony_ci
90bf215546Sopenharmony_ci   pan_pack(rsd_ptr.cpu, RENDERER_STATE, cfg) {
91bf215546Sopenharmony_ci      pan_shader_prepare_rsd(shader_info, shader, &cfg);
92bf215546Sopenharmony_ci
93bf215546Sopenharmony_ci      cfg.properties.depth_source = MALI_DEPTH_SOURCE_FIXED_FUNCTION;
94bf215546Sopenharmony_ci      cfg.multisample_misc.sample_mask = UINT16_MAX;
95bf215546Sopenharmony_ci      cfg.multisample_misc.depth_function = MALI_FUNC_ALWAYS;
96bf215546Sopenharmony_ci      cfg.properties.allow_forward_pixel_to_be_killed = true;
97bf215546Sopenharmony_ci      cfg.properties.allow_forward_pixel_to_kill = true;
98bf215546Sopenharmony_ci      cfg.properties.zs_update_operation = MALI_PIXEL_KILL_WEAK_EARLY;
99bf215546Sopenharmony_ci      cfg.properties.pixel_kill_operation = MALI_PIXEL_KILL_WEAK_EARLY;
100bf215546Sopenharmony_ci   }
101bf215546Sopenharmony_ci
102bf215546Sopenharmony_ci   void *bd = rsd_ptr.cpu + pan_size(RENDERER_STATE);
103bf215546Sopenharmony_ci
104bf215546Sopenharmony_ci   pan_pack(bd, BLEND, cfg) {
105bf215546Sopenharmony_ci      cfg.round_to_fb_precision = true;
106bf215546Sopenharmony_ci      cfg.load_destination = false;
107bf215546Sopenharmony_ci      cfg.equation.rgb.a = MALI_BLEND_OPERAND_A_SRC;
108bf215546Sopenharmony_ci      cfg.equation.rgb.b = MALI_BLEND_OPERAND_B_SRC;
109bf215546Sopenharmony_ci      cfg.equation.rgb.c = MALI_BLEND_OPERAND_C_ZERO;
110bf215546Sopenharmony_ci      cfg.equation.alpha.a = MALI_BLEND_OPERAND_A_SRC;
111bf215546Sopenharmony_ci      cfg.equation.alpha.b = MALI_BLEND_OPERAND_B_SRC;
112bf215546Sopenharmony_ci      cfg.equation.alpha.c = MALI_BLEND_OPERAND_C_ZERO;
113bf215546Sopenharmony_ci      cfg.internal.mode = MALI_BLEND_MODE_OPAQUE;
114bf215546Sopenharmony_ci      cfg.equation.color_mask = 0xf;
115bf215546Sopenharmony_ci      cfg.internal.fixed_function.num_comps = 4;
116bf215546Sopenharmony_ci      cfg.internal.fixed_function.rt = rt;
117bf215546Sopenharmony_ci      cfg.internal.fixed_function.conversion.memory_format =
118bf215546Sopenharmony_ci         panfrost_format_to_bifrost_blend(pdev, format, false);
119bf215546Sopenharmony_ci      cfg.internal.fixed_function.conversion.register_format =
120bf215546Sopenharmony_ci         shader_info->bifrost.blend[0].format;
121bf215546Sopenharmony_ci   }
122bf215546Sopenharmony_ci
123bf215546Sopenharmony_ci   return rsd_ptr.gpu;
124bf215546Sopenharmony_ci}
125bf215546Sopenharmony_ci
126bf215546Sopenharmony_cistatic mali_ptr
127bf215546Sopenharmony_cipanvk_meta_clear_zs_attachment_emit_rsd(struct panfrost_device *pdev,
128bf215546Sopenharmony_ci                                        struct pan_pool *desc_pool,
129bf215546Sopenharmony_ci                                        VkImageAspectFlags mask,
130bf215546Sopenharmony_ci                                        VkClearDepthStencilValue value)
131bf215546Sopenharmony_ci{
132bf215546Sopenharmony_ci   struct panfrost_ptr rsd_ptr = pan_pool_alloc_desc(desc_pool, RENDERER_STATE);
133bf215546Sopenharmony_ci
134bf215546Sopenharmony_ci   pan_pack(rsd_ptr.cpu, RENDERER_STATE, cfg) {
135bf215546Sopenharmony_ci      cfg.properties.depth_source = MALI_DEPTH_SOURCE_FIXED_FUNCTION;
136bf215546Sopenharmony_ci      cfg.multisample_misc.sample_mask = UINT16_MAX;
137bf215546Sopenharmony_ci
138bf215546Sopenharmony_ci      if (mask & VK_IMAGE_ASPECT_DEPTH_BIT) {
139bf215546Sopenharmony_ci         cfg.multisample_misc.depth_write_mask = true;
140bf215546Sopenharmony_ci         cfg.multisample_misc.depth_function = MALI_FUNC_NOT_EQUAL;
141bf215546Sopenharmony_ci
142bf215546Sopenharmony_ci         if (value.depth != 0.0) {
143bf215546Sopenharmony_ci            cfg.stencil_mask_misc.front_facing_depth_bias = true;
144bf215546Sopenharmony_ci            cfg.stencil_mask_misc.back_facing_depth_bias = true;
145bf215546Sopenharmony_ci            cfg.depth_units = INFINITY;
146bf215546Sopenharmony_ci            cfg.depth_bias_clamp = value.depth;
147bf215546Sopenharmony_ci         }
148bf215546Sopenharmony_ci      }
149bf215546Sopenharmony_ci
150bf215546Sopenharmony_ci      if (mask & VK_IMAGE_ASPECT_STENCIL_BIT) {
151bf215546Sopenharmony_ci         cfg.stencil_mask_misc.stencil_enable = true;
152bf215546Sopenharmony_ci         cfg.stencil_mask_misc.stencil_mask_front = 0xFF;
153bf215546Sopenharmony_ci         cfg.stencil_mask_misc.stencil_mask_back = 0xFF;
154bf215546Sopenharmony_ci
155bf215546Sopenharmony_ci         cfg.stencil_front.compare_function =
156bf215546Sopenharmony_ci            (mask & VK_IMAGE_ASPECT_DEPTH_BIT) ?
157bf215546Sopenharmony_ci            MALI_FUNC_ALWAYS : MALI_FUNC_NOT_EQUAL;
158bf215546Sopenharmony_ci
159bf215546Sopenharmony_ci         cfg.stencil_front.stencil_fail = MALI_STENCIL_OP_KEEP;
160bf215546Sopenharmony_ci         cfg.stencil_front.depth_fail = MALI_STENCIL_OP_REPLACE;
161bf215546Sopenharmony_ci         cfg.stencil_front.depth_pass = MALI_STENCIL_OP_REPLACE;
162bf215546Sopenharmony_ci         cfg.stencil_front.reference_value = value.stencil;
163bf215546Sopenharmony_ci         cfg.stencil_front.mask = 0xFF;
164bf215546Sopenharmony_ci         cfg.stencil_back = cfg.stencil_front;
165bf215546Sopenharmony_ci      }
166bf215546Sopenharmony_ci
167bf215546Sopenharmony_ci      cfg.properties.allow_forward_pixel_to_be_killed = true;
168bf215546Sopenharmony_ci      cfg.properties.zs_update_operation = MALI_PIXEL_KILL_WEAK_EARLY;
169bf215546Sopenharmony_ci      cfg.properties.pixel_kill_operation = MALI_PIXEL_KILL_WEAK_EARLY;
170bf215546Sopenharmony_ci   }
171bf215546Sopenharmony_ci
172bf215546Sopenharmony_ci   return rsd_ptr.gpu;
173bf215546Sopenharmony_ci}
174bf215546Sopenharmony_ci
175bf215546Sopenharmony_cistatic void
176bf215546Sopenharmony_cipanvk_meta_clear_attachment_emit_dcd(struct pan_pool *pool,
177bf215546Sopenharmony_ci                                     mali_ptr coords, mali_ptr push_constants,
178bf215546Sopenharmony_ci                                     mali_ptr vpd, mali_ptr tsd, mali_ptr rsd,
179bf215546Sopenharmony_ci                                     void *out)
180bf215546Sopenharmony_ci{
181bf215546Sopenharmony_ci   pan_pack(out, DRAW, cfg) {
182bf215546Sopenharmony_ci      cfg.thread_storage = tsd;
183bf215546Sopenharmony_ci      cfg.state = rsd;
184bf215546Sopenharmony_ci      cfg.push_uniforms = push_constants;
185bf215546Sopenharmony_ci      cfg.position = coords;
186bf215546Sopenharmony_ci      cfg.viewport = vpd;
187bf215546Sopenharmony_ci   }
188bf215546Sopenharmony_ci}
189bf215546Sopenharmony_ci
190bf215546Sopenharmony_cistatic struct panfrost_ptr
191bf215546Sopenharmony_cipanvk_meta_clear_attachment_emit_tiler_job(struct pan_pool *desc_pool,
192bf215546Sopenharmony_ci                                           struct pan_scoreboard *scoreboard,
193bf215546Sopenharmony_ci                                           mali_ptr coords,
194bf215546Sopenharmony_ci                                           mali_ptr push_constants,
195bf215546Sopenharmony_ci                                           mali_ptr vpd, mali_ptr rsd,
196bf215546Sopenharmony_ci                                           mali_ptr tsd, mali_ptr tiler)
197bf215546Sopenharmony_ci{
198bf215546Sopenharmony_ci   struct panfrost_ptr job =
199bf215546Sopenharmony_ci      pan_pool_alloc_desc(desc_pool, TILER_JOB);
200bf215546Sopenharmony_ci
201bf215546Sopenharmony_ci   panvk_meta_clear_attachment_emit_dcd(desc_pool,
202bf215546Sopenharmony_ci                                        coords,
203bf215546Sopenharmony_ci                                        push_constants,
204bf215546Sopenharmony_ci                                        vpd, tsd, rsd,
205bf215546Sopenharmony_ci                                        pan_section_ptr(job.cpu, TILER_JOB, DRAW));
206bf215546Sopenharmony_ci
207bf215546Sopenharmony_ci   pan_section_pack(job.cpu, TILER_JOB, PRIMITIVE, cfg) {
208bf215546Sopenharmony_ci      cfg.draw_mode = MALI_DRAW_MODE_TRIANGLE_STRIP;
209bf215546Sopenharmony_ci      cfg.index_count = 4;
210bf215546Sopenharmony_ci      cfg.job_task_split = 6;
211bf215546Sopenharmony_ci   }
212bf215546Sopenharmony_ci
213bf215546Sopenharmony_ci   pan_section_pack(job.cpu, TILER_JOB, PRIMITIVE_SIZE, cfg) {
214bf215546Sopenharmony_ci      cfg.constant = 1.0f;
215bf215546Sopenharmony_ci   }
216bf215546Sopenharmony_ci
217bf215546Sopenharmony_ci   void *invoc = pan_section_ptr(job.cpu,
218bf215546Sopenharmony_ci                                 TILER_JOB,
219bf215546Sopenharmony_ci                                 INVOCATION);
220bf215546Sopenharmony_ci   panfrost_pack_work_groups_compute(invoc, 1, 4,
221bf215546Sopenharmony_ci                                     1, 1, 1, 1, true, false);
222bf215546Sopenharmony_ci
223bf215546Sopenharmony_ci   pan_section_pack(job.cpu, TILER_JOB, PADDING, cfg);
224bf215546Sopenharmony_ci   pan_section_pack(job.cpu, TILER_JOB, TILER, cfg) {
225bf215546Sopenharmony_ci      cfg.address = tiler;
226bf215546Sopenharmony_ci   }
227bf215546Sopenharmony_ci
228bf215546Sopenharmony_ci   panfrost_add_job(desc_pool, scoreboard, MALI_JOB_TYPE_TILER,
229bf215546Sopenharmony_ci                    false, false, 0, 0, &job, false);
230bf215546Sopenharmony_ci   return job;
231bf215546Sopenharmony_ci}
232bf215546Sopenharmony_ci
233bf215546Sopenharmony_cistatic enum glsl_base_type
234bf215546Sopenharmony_cipanvk_meta_get_format_type(enum pipe_format format)
235bf215546Sopenharmony_ci{
236bf215546Sopenharmony_ci   const struct util_format_description *desc = util_format_description(format);
237bf215546Sopenharmony_ci   int i;
238bf215546Sopenharmony_ci
239bf215546Sopenharmony_ci   i = util_format_get_first_non_void_channel(format);
240bf215546Sopenharmony_ci   assert(i >= 0);
241bf215546Sopenharmony_ci
242bf215546Sopenharmony_ci   if (desc->channel[i].normalized)
243bf215546Sopenharmony_ci      return GLSL_TYPE_FLOAT;
244bf215546Sopenharmony_ci
245bf215546Sopenharmony_ci   switch(desc->channel[i].type) {
246bf215546Sopenharmony_ci
247bf215546Sopenharmony_ci   case UTIL_FORMAT_TYPE_UNSIGNED:
248bf215546Sopenharmony_ci      return GLSL_TYPE_UINT;
249bf215546Sopenharmony_ci
250bf215546Sopenharmony_ci   case UTIL_FORMAT_TYPE_SIGNED:
251bf215546Sopenharmony_ci      return GLSL_TYPE_INT;
252bf215546Sopenharmony_ci
253bf215546Sopenharmony_ci   case UTIL_FORMAT_TYPE_FLOAT:
254bf215546Sopenharmony_ci      return GLSL_TYPE_FLOAT;
255bf215546Sopenharmony_ci
256bf215546Sopenharmony_ci   default:
257bf215546Sopenharmony_ci      unreachable("Unhandled format");
258bf215546Sopenharmony_ci      return GLSL_TYPE_FLOAT;
259bf215546Sopenharmony_ci   }
260bf215546Sopenharmony_ci}
261bf215546Sopenharmony_ci
262bf215546Sopenharmony_cistatic void
263bf215546Sopenharmony_cipanvk_meta_clear_attachment(struct panvk_cmd_buffer *cmdbuf,
264bf215546Sopenharmony_ci                            unsigned attachment, unsigned rt,
265bf215546Sopenharmony_ci                            VkImageAspectFlags mask,
266bf215546Sopenharmony_ci                            const VkClearValue *clear_value,
267bf215546Sopenharmony_ci                            const VkClearRect *clear_rect)
268bf215546Sopenharmony_ci{
269bf215546Sopenharmony_ci   struct panvk_physical_device *dev = cmdbuf->device->physical_device;
270bf215546Sopenharmony_ci   struct panfrost_device *pdev = &dev->pdev;
271bf215546Sopenharmony_ci   struct panvk_meta *meta = &cmdbuf->device->physical_device->meta;
272bf215546Sopenharmony_ci   struct panvk_batch *batch = cmdbuf->state.batch;
273bf215546Sopenharmony_ci   const struct panvk_render_pass *pass = cmdbuf->state.pass;
274bf215546Sopenharmony_ci   const struct panvk_render_pass_attachment *att = &pass->attachments[attachment];
275bf215546Sopenharmony_ci   unsigned minx = MAX2(clear_rect->rect.offset.x, 0);
276bf215546Sopenharmony_ci   unsigned miny = MAX2(clear_rect->rect.offset.y, 0);
277bf215546Sopenharmony_ci   unsigned maxx = MAX2(clear_rect->rect.offset.x + clear_rect->rect.extent.width - 1, 0);
278bf215546Sopenharmony_ci   unsigned maxy = MAX2(clear_rect->rect.offset.y + clear_rect->rect.extent.height - 1, 0);
279bf215546Sopenharmony_ci
280bf215546Sopenharmony_ci   panvk_per_arch(cmd_alloc_fb_desc)(cmdbuf);
281bf215546Sopenharmony_ci   panvk_per_arch(cmd_alloc_tls_desc)(cmdbuf, true);
282bf215546Sopenharmony_ci   panvk_per_arch(cmd_prepare_tiler_context)(cmdbuf);
283bf215546Sopenharmony_ci
284bf215546Sopenharmony_ci   mali_ptr vpd =
285bf215546Sopenharmony_ci      panvk_per_arch(meta_emit_viewport)(&cmdbuf->desc_pool.base,
286bf215546Sopenharmony_ci                                         minx, miny, maxx, maxy);
287bf215546Sopenharmony_ci
288bf215546Sopenharmony_ci   float rect[] = {
289bf215546Sopenharmony_ci      minx, miny, 0.0, 1.0,
290bf215546Sopenharmony_ci      maxx + 1, miny, 0.0, 1.0,
291bf215546Sopenharmony_ci      minx, maxy + 1, 0.0, 1.0,
292bf215546Sopenharmony_ci      maxx + 1, maxy + 1, 0.0, 1.0,
293bf215546Sopenharmony_ci   };
294bf215546Sopenharmony_ci   mali_ptr coordinates = pan_pool_upload_aligned(&cmdbuf->desc_pool.base,
295bf215546Sopenharmony_ci                                                  rect, sizeof(rect), 64);
296bf215546Sopenharmony_ci
297bf215546Sopenharmony_ci   enum glsl_base_type base_type = panvk_meta_get_format_type(att->format);
298bf215546Sopenharmony_ci
299bf215546Sopenharmony_ci   mali_ptr tiler = batch->tiler.descs.gpu;
300bf215546Sopenharmony_ci   mali_ptr tsd = batch->tls.gpu;
301bf215546Sopenharmony_ci
302bf215546Sopenharmony_ci   mali_ptr pushconsts = 0, rsd = 0;
303bf215546Sopenharmony_ci
304bf215546Sopenharmony_ci   if (mask & VK_IMAGE_ASPECT_COLOR_BIT) {
305bf215546Sopenharmony_ci      mali_ptr shader = meta->clear_attachment.color[base_type].shader;
306bf215546Sopenharmony_ci      struct pan_shader_info *shader_info = &meta->clear_attachment.color[base_type].shader_info;
307bf215546Sopenharmony_ci
308bf215546Sopenharmony_ci      pushconsts = pan_pool_upload_aligned(&cmdbuf->desc_pool.base,
309bf215546Sopenharmony_ci                              clear_value, sizeof(*clear_value), 16);
310bf215546Sopenharmony_ci
311bf215546Sopenharmony_ci      rsd = panvk_meta_clear_color_attachment_emit_rsd(pdev,
312bf215546Sopenharmony_ci                                                       &cmdbuf->desc_pool.base,
313bf215546Sopenharmony_ci                                                       att->format, rt,
314bf215546Sopenharmony_ci                                                       shader_info,
315bf215546Sopenharmony_ci                                                       shader);
316bf215546Sopenharmony_ci   } else {
317bf215546Sopenharmony_ci      rsd = panvk_meta_clear_zs_attachment_emit_rsd(pdev,
318bf215546Sopenharmony_ci                                                    &cmdbuf->desc_pool.base,
319bf215546Sopenharmony_ci                                                    mask,
320bf215546Sopenharmony_ci                                                    clear_value->depthStencil);
321bf215546Sopenharmony_ci   }
322bf215546Sopenharmony_ci
323bf215546Sopenharmony_ci   struct panfrost_ptr job;
324bf215546Sopenharmony_ci
325bf215546Sopenharmony_ci   job = panvk_meta_clear_attachment_emit_tiler_job(&cmdbuf->desc_pool.base,
326bf215546Sopenharmony_ci                                                    &batch->scoreboard,
327bf215546Sopenharmony_ci                                                    coordinates, pushconsts,
328bf215546Sopenharmony_ci                                                    vpd, rsd, tsd, tiler);
329bf215546Sopenharmony_ci
330bf215546Sopenharmony_ci   util_dynarray_append(&batch->jobs, void *, job.cpu);
331bf215546Sopenharmony_ci}
332bf215546Sopenharmony_ci
333bf215546Sopenharmony_cistatic void
334bf215546Sopenharmony_cipanvk_meta_clear_color_img(struct panvk_cmd_buffer *cmdbuf,
335bf215546Sopenharmony_ci                           struct panvk_image *img,
336bf215546Sopenharmony_ci                           const VkClearColorValue *color,
337bf215546Sopenharmony_ci                           const VkImageSubresourceRange *range)
338bf215546Sopenharmony_ci{
339bf215546Sopenharmony_ci   struct pan_fb_info *fbinfo = &cmdbuf->state.fb.info;
340bf215546Sopenharmony_ci   struct pan_image_view view = {
341bf215546Sopenharmony_ci      .format = img->pimage.layout.format,
342bf215546Sopenharmony_ci      .dim = MALI_TEXTURE_DIMENSION_2D,
343bf215546Sopenharmony_ci      .image = &img->pimage,
344bf215546Sopenharmony_ci      .nr_samples = img->pimage.layout.nr_samples,
345bf215546Sopenharmony_ci      .swizzle = { PIPE_SWIZZLE_X, PIPE_SWIZZLE_Y, PIPE_SWIZZLE_Z, PIPE_SWIZZLE_W },
346bf215546Sopenharmony_ci   };
347bf215546Sopenharmony_ci
348bf215546Sopenharmony_ci   cmdbuf->state.fb.crc_valid[0] = false;
349bf215546Sopenharmony_ci   *fbinfo = (struct pan_fb_info){
350bf215546Sopenharmony_ci      .nr_samples = img->pimage.layout.nr_samples,
351bf215546Sopenharmony_ci      .rt_count = 1,
352bf215546Sopenharmony_ci      .rts[0].view = &view,
353bf215546Sopenharmony_ci      .rts[0].clear = true,
354bf215546Sopenharmony_ci      .rts[0].crc_valid = &cmdbuf->state.fb.crc_valid[0],
355bf215546Sopenharmony_ci   };
356bf215546Sopenharmony_ci
357bf215546Sopenharmony_ci   uint32_t clearval[4];
358bf215546Sopenharmony_ci   pan_pack_color(clearval, (union pipe_color_union *)color,
359bf215546Sopenharmony_ci                  img->pimage.layout.format, false);
360bf215546Sopenharmony_ci   memcpy(fbinfo->rts[0].clear_value, clearval, sizeof(fbinfo->rts[0].clear_value));
361bf215546Sopenharmony_ci
362bf215546Sopenharmony_ci   unsigned level_count = vk_image_subresource_level_count(&img->vk, range);
363bf215546Sopenharmony_ci   unsigned layer_count = vk_image_subresource_layer_count(&img->vk, range);
364bf215546Sopenharmony_ci
365bf215546Sopenharmony_ci   for (unsigned level = range->baseMipLevel;
366bf215546Sopenharmony_ci        level < range->baseMipLevel + level_count; level++) {
367bf215546Sopenharmony_ci      view.first_level = view.last_level = level;
368bf215546Sopenharmony_ci      fbinfo->width = u_minify(img->pimage.layout.width, level);
369bf215546Sopenharmony_ci      fbinfo->height = u_minify(img->pimage.layout.height, level);
370bf215546Sopenharmony_ci      fbinfo->extent.maxx = fbinfo->width - 1;
371bf215546Sopenharmony_ci      fbinfo->extent.maxy = fbinfo->height - 1;
372bf215546Sopenharmony_ci
373bf215546Sopenharmony_ci      for (unsigned layer = range->baseArrayLayer;
374bf215546Sopenharmony_ci           layer < range->baseArrayLayer + layer_count; layer++) {
375bf215546Sopenharmony_ci         view.first_layer = view.last_layer = layer;
376bf215546Sopenharmony_ci         panvk_cmd_open_batch(cmdbuf);
377bf215546Sopenharmony_ci         panvk_per_arch(cmd_alloc_fb_desc)(cmdbuf);
378bf215546Sopenharmony_ci         panvk_per_arch(cmd_close_batch)(cmdbuf);
379bf215546Sopenharmony_ci      }
380bf215546Sopenharmony_ci   }
381bf215546Sopenharmony_ci}
382bf215546Sopenharmony_ci
383bf215546Sopenharmony_civoid
384bf215546Sopenharmony_cipanvk_per_arch(CmdClearColorImage)(VkCommandBuffer commandBuffer,
385bf215546Sopenharmony_ci                                   VkImage image,
386bf215546Sopenharmony_ci                                   VkImageLayout imageLayout,
387bf215546Sopenharmony_ci                                   const VkClearColorValue *pColor,
388bf215546Sopenharmony_ci                                   uint32_t rangeCount,
389bf215546Sopenharmony_ci                                   const VkImageSubresourceRange *pRanges)
390bf215546Sopenharmony_ci{
391bf215546Sopenharmony_ci   VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
392bf215546Sopenharmony_ci   VK_FROM_HANDLE(panvk_image, img, image);
393bf215546Sopenharmony_ci
394bf215546Sopenharmony_ci   panvk_per_arch(cmd_close_batch)(cmdbuf);
395bf215546Sopenharmony_ci
396bf215546Sopenharmony_ci   for (unsigned i = 0; i < rangeCount; i++)
397bf215546Sopenharmony_ci      panvk_meta_clear_color_img(cmdbuf, img, pColor, &pRanges[i]);
398bf215546Sopenharmony_ci}
399bf215546Sopenharmony_ci
400bf215546Sopenharmony_cistatic void
401bf215546Sopenharmony_cipanvk_meta_clear_zs_img(struct panvk_cmd_buffer *cmdbuf,
402bf215546Sopenharmony_ci                        struct panvk_image *img,
403bf215546Sopenharmony_ci                        const VkClearDepthStencilValue *value,
404bf215546Sopenharmony_ci                        const VkImageSubresourceRange *range)
405bf215546Sopenharmony_ci{
406bf215546Sopenharmony_ci   struct pan_fb_info *fbinfo = &cmdbuf->state.fb.info;
407bf215546Sopenharmony_ci   struct pan_image_view view = {
408bf215546Sopenharmony_ci      .format = img->pimage.layout.format,
409bf215546Sopenharmony_ci      .dim = MALI_TEXTURE_DIMENSION_2D,
410bf215546Sopenharmony_ci      .image = &img->pimage,
411bf215546Sopenharmony_ci      .nr_samples = img->pimage.layout.nr_samples,
412bf215546Sopenharmony_ci      .swizzle = { PIPE_SWIZZLE_X, PIPE_SWIZZLE_Y, PIPE_SWIZZLE_Z, PIPE_SWIZZLE_W },
413bf215546Sopenharmony_ci   };
414bf215546Sopenharmony_ci
415bf215546Sopenharmony_ci   cmdbuf->state.fb.crc_valid[0] = false;
416bf215546Sopenharmony_ci   *fbinfo = (struct pan_fb_info){
417bf215546Sopenharmony_ci      .nr_samples = img->pimage.layout.nr_samples,
418bf215546Sopenharmony_ci      .rt_count = 1,
419bf215546Sopenharmony_ci      .zs.clear_value.depth = value->depth,
420bf215546Sopenharmony_ci      .zs.clear_value.stencil = value->stencil,
421bf215546Sopenharmony_ci      .zs.clear.z = range->aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT,
422bf215546Sopenharmony_ci      .zs.clear.s = range->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT
423bf215546Sopenharmony_ci   };
424bf215546Sopenharmony_ci
425bf215546Sopenharmony_ci   const struct util_format_description *fdesc =
426bf215546Sopenharmony_ci      util_format_description(view.format);
427bf215546Sopenharmony_ci
428bf215546Sopenharmony_ci   if (util_format_has_depth(fdesc)) {
429bf215546Sopenharmony_ci      fbinfo->zs.view.zs = &view;
430bf215546Sopenharmony_ci      if (util_format_has_stencil(fdesc)) {
431bf215546Sopenharmony_ci         fbinfo->zs.preload.z = !fbinfo->zs.clear.z;
432bf215546Sopenharmony_ci         fbinfo->zs.preload.s = !fbinfo->zs.clear.s;
433bf215546Sopenharmony_ci      }
434bf215546Sopenharmony_ci   } else {
435bf215546Sopenharmony_ci      fbinfo->zs.view.s = &view;
436bf215546Sopenharmony_ci   }
437bf215546Sopenharmony_ci
438bf215546Sopenharmony_ci   unsigned level_count = vk_image_subresource_level_count(&img->vk, range);
439bf215546Sopenharmony_ci   unsigned layer_count = vk_image_subresource_layer_count(&img->vk, range);
440bf215546Sopenharmony_ci
441bf215546Sopenharmony_ci   for (unsigned level = range->baseMipLevel;
442bf215546Sopenharmony_ci        level < range->baseMipLevel + level_count; level++) {
443bf215546Sopenharmony_ci      view.first_level = view.last_level = level;
444bf215546Sopenharmony_ci      fbinfo->width = u_minify(img->pimage.layout.width, level);
445bf215546Sopenharmony_ci      fbinfo->height = u_minify(img->pimage.layout.height, level);
446bf215546Sopenharmony_ci      fbinfo->extent.maxx = fbinfo->width - 1;
447bf215546Sopenharmony_ci      fbinfo->extent.maxy = fbinfo->height - 1;
448bf215546Sopenharmony_ci
449bf215546Sopenharmony_ci      for (unsigned layer = range->baseArrayLayer;
450bf215546Sopenharmony_ci           layer < range->baseArrayLayer + layer_count; layer++) {
451bf215546Sopenharmony_ci         view.first_layer = view.last_layer = layer;
452bf215546Sopenharmony_ci         panvk_cmd_open_batch(cmdbuf);
453bf215546Sopenharmony_ci         panvk_per_arch(cmd_alloc_fb_desc)(cmdbuf);
454bf215546Sopenharmony_ci         panvk_per_arch(cmd_close_batch)(cmdbuf);
455bf215546Sopenharmony_ci      }
456bf215546Sopenharmony_ci   }
457bf215546Sopenharmony_ci}
458bf215546Sopenharmony_ci
459bf215546Sopenharmony_civoid
460bf215546Sopenharmony_cipanvk_per_arch(CmdClearDepthStencilImage)(VkCommandBuffer commandBuffer,
461bf215546Sopenharmony_ci                                          VkImage image,
462bf215546Sopenharmony_ci                                          VkImageLayout imageLayout,
463bf215546Sopenharmony_ci                                          const VkClearDepthStencilValue *pDepthStencil,
464bf215546Sopenharmony_ci                                          uint32_t rangeCount,
465bf215546Sopenharmony_ci                                          const VkImageSubresourceRange *pRanges)
466bf215546Sopenharmony_ci{
467bf215546Sopenharmony_ci   VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
468bf215546Sopenharmony_ci   VK_FROM_HANDLE(panvk_image, img, image);
469bf215546Sopenharmony_ci
470bf215546Sopenharmony_ci   panvk_per_arch(cmd_close_batch)(cmdbuf);
471bf215546Sopenharmony_ci
472bf215546Sopenharmony_ci   for (unsigned i = 0; i < rangeCount; i++)
473bf215546Sopenharmony_ci      panvk_meta_clear_zs_img(cmdbuf, img, pDepthStencil, &pRanges[i]);
474bf215546Sopenharmony_ci}
475bf215546Sopenharmony_ci
476bf215546Sopenharmony_civoid
477bf215546Sopenharmony_cipanvk_per_arch(CmdClearAttachments)(VkCommandBuffer commandBuffer,
478bf215546Sopenharmony_ci                                    uint32_t attachmentCount,
479bf215546Sopenharmony_ci                                    const VkClearAttachment *pAttachments,
480bf215546Sopenharmony_ci                                    uint32_t rectCount,
481bf215546Sopenharmony_ci                                    const VkClearRect *pRects)
482bf215546Sopenharmony_ci{
483bf215546Sopenharmony_ci   VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
484bf215546Sopenharmony_ci   const struct panvk_subpass *subpass = cmdbuf->state.subpass;
485bf215546Sopenharmony_ci
486bf215546Sopenharmony_ci   for (unsigned i = 0; i < attachmentCount; i++) {
487bf215546Sopenharmony_ci      for (unsigned j = 0; j < rectCount; j++) {
488bf215546Sopenharmony_ci
489bf215546Sopenharmony_ci         uint32_t attachment, rt = 0;
490bf215546Sopenharmony_ci         if (pAttachments[i].aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) {
491bf215546Sopenharmony_ci            rt = pAttachments[i].colorAttachment;
492bf215546Sopenharmony_ci            attachment = subpass->color_attachments[rt].idx;
493bf215546Sopenharmony_ci         } else {
494bf215546Sopenharmony_ci            attachment = subpass->zs_attachment.idx;
495bf215546Sopenharmony_ci         }
496bf215546Sopenharmony_ci
497bf215546Sopenharmony_ci         if (attachment == VK_ATTACHMENT_UNUSED)
498bf215546Sopenharmony_ci               continue;
499bf215546Sopenharmony_ci
500bf215546Sopenharmony_ci         panvk_meta_clear_attachment(cmdbuf, attachment, rt,
501bf215546Sopenharmony_ci                                     pAttachments[i].aspectMask,
502bf215546Sopenharmony_ci                                     &pAttachments[i].clearValue,
503bf215546Sopenharmony_ci                                     &pRects[j]);
504bf215546Sopenharmony_ci      }
505bf215546Sopenharmony_ci   }
506bf215546Sopenharmony_ci}
507bf215546Sopenharmony_ci
508bf215546Sopenharmony_cistatic void
509bf215546Sopenharmony_cipanvk_meta_clear_attachment_init(struct panvk_physical_device *dev)
510bf215546Sopenharmony_ci{
511bf215546Sopenharmony_ci   dev->meta.clear_attachment.color[GLSL_TYPE_UINT].shader =
512bf215546Sopenharmony_ci      panvk_meta_clear_color_attachment_shader(
513bf215546Sopenharmony_ci            &dev->pdev,
514bf215546Sopenharmony_ci            &dev->meta.bin_pool.base,
515bf215546Sopenharmony_ci            GLSL_TYPE_UINT,
516bf215546Sopenharmony_ci            &dev->meta.clear_attachment.color[GLSL_TYPE_UINT].shader_info);
517bf215546Sopenharmony_ci
518bf215546Sopenharmony_ci   dev->meta.clear_attachment.color[GLSL_TYPE_INT].shader =
519bf215546Sopenharmony_ci      panvk_meta_clear_color_attachment_shader(
520bf215546Sopenharmony_ci            &dev->pdev,
521bf215546Sopenharmony_ci            &dev->meta.bin_pool.base,
522bf215546Sopenharmony_ci            GLSL_TYPE_INT,
523bf215546Sopenharmony_ci            &dev->meta.clear_attachment.color[GLSL_TYPE_INT].shader_info);
524bf215546Sopenharmony_ci
525bf215546Sopenharmony_ci   dev->meta.clear_attachment.color[GLSL_TYPE_FLOAT].shader =
526bf215546Sopenharmony_ci      panvk_meta_clear_color_attachment_shader(
527bf215546Sopenharmony_ci            &dev->pdev,
528bf215546Sopenharmony_ci            &dev->meta.bin_pool.base,
529bf215546Sopenharmony_ci            GLSL_TYPE_FLOAT,
530bf215546Sopenharmony_ci            &dev->meta.clear_attachment.color[GLSL_TYPE_FLOAT].shader_info);
531bf215546Sopenharmony_ci}
532bf215546Sopenharmony_ci
533bf215546Sopenharmony_civoid
534bf215546Sopenharmony_cipanvk_per_arch(meta_clear_init)(struct panvk_physical_device *dev)
535bf215546Sopenharmony_ci{
536bf215546Sopenharmony_ci   panvk_meta_clear_attachment_init(dev);
537bf215546Sopenharmony_ci}
538