1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Copyright © 2021 Collabora Ltd.
3bf215546Sopenharmony_ci *
4bf215546Sopenharmony_ci * Derived from tu_cmd_buffer.c which is:
5bf215546Sopenharmony_ci * Copyright © 2016 Red Hat.
6bf215546Sopenharmony_ci * Copyright © 2016 Bas Nieuwenhuizen
7bf215546Sopenharmony_ci * Copyright © 2015 Intel Corporation
8bf215546Sopenharmony_ci *
9bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
10bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
11bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation
12bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
14bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
15bf215546Sopenharmony_ci *
16bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next
17bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the
18bf215546Sopenharmony_ci * Software.
19bf215546Sopenharmony_ci *
20bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
23bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26bf215546Sopenharmony_ci * DEALINGS IN THE SOFTWARE.
27bf215546Sopenharmony_ci */
28bf215546Sopenharmony_ci
29bf215546Sopenharmony_ci#include "genxml/gen_macros.h"
30bf215546Sopenharmony_ci
31bf215546Sopenharmony_ci#include "panvk_cs.h"
32bf215546Sopenharmony_ci#include "panvk_private.h"
33bf215546Sopenharmony_ci
34bf215546Sopenharmony_ci#include "pan_blitter.h"
35bf215546Sopenharmony_ci#include "pan_cs.h"
36bf215546Sopenharmony_ci#include "pan_encoder.h"
37bf215546Sopenharmony_ci
38bf215546Sopenharmony_ci#include "util/rounding.h"
39bf215546Sopenharmony_ci#include "util/u_pack_color.h"
40bf215546Sopenharmony_ci#include "vk_format.h"
41bf215546Sopenharmony_ci
42bf215546Sopenharmony_cistatic uint32_t
43bf215546Sopenharmony_cipanvk_debug_adjust_bo_flags(const struct panvk_device *device,
44bf215546Sopenharmony_ci                      uint32_t bo_flags)
45bf215546Sopenharmony_ci{
46bf215546Sopenharmony_ci   uint32_t debug_flags =
47bf215546Sopenharmony_ci      device->physical_device->instance->debug_flags;
48bf215546Sopenharmony_ci
49bf215546Sopenharmony_ci   if (debug_flags & PANVK_DEBUG_DUMP)
50bf215546Sopenharmony_ci      bo_flags &= ~PAN_BO_INVISIBLE;
51bf215546Sopenharmony_ci
52bf215546Sopenharmony_ci   return bo_flags;
53bf215546Sopenharmony_ci}
54bf215546Sopenharmony_ci
55bf215546Sopenharmony_cistatic void
56bf215546Sopenharmony_cipanvk_cmd_prepare_fragment_job(struct panvk_cmd_buffer *cmdbuf)
57bf215546Sopenharmony_ci{
58bf215546Sopenharmony_ci   const struct pan_fb_info *fbinfo = &cmdbuf->state.fb.info;
59bf215546Sopenharmony_ci   struct panvk_batch *batch = cmdbuf->state.batch;
60bf215546Sopenharmony_ci   struct panfrost_ptr job_ptr =
61bf215546Sopenharmony_ci      pan_pool_alloc_desc(&cmdbuf->desc_pool.base, FRAGMENT_JOB);
62bf215546Sopenharmony_ci
63bf215546Sopenharmony_ci   GENX(pan_emit_fragment_job)(fbinfo, batch->fb.desc.gpu, job_ptr.cpu),
64bf215546Sopenharmony_ci   batch->fragment_job = job_ptr.gpu;
65bf215546Sopenharmony_ci   util_dynarray_append(&batch->jobs, void *, job_ptr.cpu);
66bf215546Sopenharmony_ci}
67bf215546Sopenharmony_ci
68bf215546Sopenharmony_civoid
69bf215546Sopenharmony_cipanvk_per_arch(cmd_close_batch)(struct panvk_cmd_buffer *cmdbuf)
70bf215546Sopenharmony_ci{
71bf215546Sopenharmony_ci   struct panvk_batch *batch = cmdbuf->state.batch;
72bf215546Sopenharmony_ci
73bf215546Sopenharmony_ci   if (!batch)
74bf215546Sopenharmony_ci      return;
75bf215546Sopenharmony_ci
76bf215546Sopenharmony_ci   const struct pan_fb_info *fbinfo = &cmdbuf->state.fb.info;
77bf215546Sopenharmony_ci
78bf215546Sopenharmony_ci   assert(batch);
79bf215546Sopenharmony_ci
80bf215546Sopenharmony_ci   bool clear = fbinfo->zs.clear.z | fbinfo->zs.clear.s;
81bf215546Sopenharmony_ci   for (unsigned i = 0; i < fbinfo->rt_count; i++)
82bf215546Sopenharmony_ci      clear |= fbinfo->rts[i].clear;
83bf215546Sopenharmony_ci
84bf215546Sopenharmony_ci   if (!clear && !batch->scoreboard.first_job) {
85bf215546Sopenharmony_ci      if (util_dynarray_num_elements(&batch->event_ops, struct panvk_event_op) == 0) {
86bf215546Sopenharmony_ci         /* Content-less batch, let's drop it */
87bf215546Sopenharmony_ci         vk_free(&cmdbuf->pool->vk.alloc, batch);
88bf215546Sopenharmony_ci      } else {
89bf215546Sopenharmony_ci         /* Batch has no jobs but is needed for synchronization, let's add a
90bf215546Sopenharmony_ci          * NULL job so the SUBMIT ioctl doesn't choke on it.
91bf215546Sopenharmony_ci          */
92bf215546Sopenharmony_ci         struct panfrost_ptr ptr = pan_pool_alloc_desc(&cmdbuf->desc_pool.base,
93bf215546Sopenharmony_ci                                                       JOB_HEADER);
94bf215546Sopenharmony_ci         util_dynarray_append(&batch->jobs, void *, ptr.cpu);
95bf215546Sopenharmony_ci         panfrost_add_job(&cmdbuf->desc_pool.base, &batch->scoreboard,
96bf215546Sopenharmony_ci                          MALI_JOB_TYPE_NULL, false, false, 0, 0,
97bf215546Sopenharmony_ci                          &ptr, false);
98bf215546Sopenharmony_ci         list_addtail(&batch->node, &cmdbuf->batches);
99bf215546Sopenharmony_ci      }
100bf215546Sopenharmony_ci      cmdbuf->state.batch = NULL;
101bf215546Sopenharmony_ci      return;
102bf215546Sopenharmony_ci   }
103bf215546Sopenharmony_ci
104bf215546Sopenharmony_ci   struct panfrost_device *pdev = &cmdbuf->device->physical_device->pdev;
105bf215546Sopenharmony_ci
106bf215546Sopenharmony_ci   list_addtail(&batch->node, &cmdbuf->batches);
107bf215546Sopenharmony_ci
108bf215546Sopenharmony_ci   if (batch->scoreboard.first_tiler) {
109bf215546Sopenharmony_ci      struct panfrost_ptr preload_jobs[2];
110bf215546Sopenharmony_ci      unsigned num_preload_jobs =
111bf215546Sopenharmony_ci         GENX(pan_preload_fb)(&cmdbuf->desc_pool.base, &batch->scoreboard,
112bf215546Sopenharmony_ci                              &cmdbuf->state.fb.info, batch->tls.gpu,
113bf215546Sopenharmony_ci                              batch->tiler.descs.gpu, preload_jobs);
114bf215546Sopenharmony_ci      for (unsigned i = 0; i < num_preload_jobs; i++)
115bf215546Sopenharmony_ci         util_dynarray_append(&batch->jobs, void *, preload_jobs[i].cpu);
116bf215546Sopenharmony_ci   }
117bf215546Sopenharmony_ci
118bf215546Sopenharmony_ci   if (batch->tlsinfo.tls.size) {
119bf215546Sopenharmony_ci      unsigned size = panfrost_get_total_stack_size(batch->tlsinfo.tls.size,
120bf215546Sopenharmony_ci                                                    pdev->thread_tls_alloc,
121bf215546Sopenharmony_ci                                                    pdev->core_id_range);
122bf215546Sopenharmony_ci      batch->tlsinfo.tls.ptr =
123bf215546Sopenharmony_ci         pan_pool_alloc_aligned(&cmdbuf->tls_pool.base, size, 4096).gpu;
124bf215546Sopenharmony_ci   }
125bf215546Sopenharmony_ci
126bf215546Sopenharmony_ci   if (batch->tlsinfo.wls.size) {
127bf215546Sopenharmony_ci      assert(batch->wls_total_size);
128bf215546Sopenharmony_ci      batch->tlsinfo.wls.ptr =
129bf215546Sopenharmony_ci         pan_pool_alloc_aligned(&cmdbuf->tls_pool.base, batch->wls_total_size, 4096).gpu;
130bf215546Sopenharmony_ci   }
131bf215546Sopenharmony_ci
132bf215546Sopenharmony_ci   if (batch->tls.cpu)
133bf215546Sopenharmony_ci      GENX(pan_emit_tls)(&batch->tlsinfo, batch->tls.cpu);
134bf215546Sopenharmony_ci
135bf215546Sopenharmony_ci   if (batch->fb.desc.cpu) {
136bf215546Sopenharmony_ci      batch->fb.desc.gpu |=
137bf215546Sopenharmony_ci         GENX(pan_emit_fbd)(pdev, &cmdbuf->state.fb.info, &batch->tlsinfo,
138bf215546Sopenharmony_ci                            &batch->tiler.ctx, batch->fb.desc.cpu);
139bf215546Sopenharmony_ci
140bf215546Sopenharmony_ci      panvk_cmd_prepare_fragment_job(cmdbuf);
141bf215546Sopenharmony_ci   }
142bf215546Sopenharmony_ci
143bf215546Sopenharmony_ci   cmdbuf->state.batch = NULL;
144bf215546Sopenharmony_ci}
145bf215546Sopenharmony_ci
146bf215546Sopenharmony_civoid
147bf215546Sopenharmony_cipanvk_per_arch(CmdNextSubpass2)(VkCommandBuffer commandBuffer,
148bf215546Sopenharmony_ci                                const VkSubpassBeginInfo *pSubpassBeginInfo,
149bf215546Sopenharmony_ci                                const VkSubpassEndInfo *pSubpassEndInfo)
150bf215546Sopenharmony_ci{
151bf215546Sopenharmony_ci   VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
152bf215546Sopenharmony_ci
153bf215546Sopenharmony_ci   panvk_per_arch(cmd_close_batch)(cmdbuf);
154bf215546Sopenharmony_ci
155bf215546Sopenharmony_ci   cmdbuf->state.subpass++;
156bf215546Sopenharmony_ci   panvk_cmd_fb_info_set_subpass(cmdbuf);
157bf215546Sopenharmony_ci   panvk_cmd_open_batch(cmdbuf);
158bf215546Sopenharmony_ci}
159bf215546Sopenharmony_ci
160bf215546Sopenharmony_civoid
161bf215546Sopenharmony_cipanvk_per_arch(CmdNextSubpass)(VkCommandBuffer cmd, VkSubpassContents contents)
162bf215546Sopenharmony_ci{
163bf215546Sopenharmony_ci   VkSubpassBeginInfo binfo = {
164bf215546Sopenharmony_ci      .sType = VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO,
165bf215546Sopenharmony_ci      .contents = contents
166bf215546Sopenharmony_ci   };
167bf215546Sopenharmony_ci   VkSubpassEndInfo einfo = {
168bf215546Sopenharmony_ci      .sType = VK_STRUCTURE_TYPE_SUBPASS_END_INFO,
169bf215546Sopenharmony_ci   };
170bf215546Sopenharmony_ci
171bf215546Sopenharmony_ci   panvk_per_arch(CmdNextSubpass2)(cmd, &binfo, &einfo);
172bf215546Sopenharmony_ci}
173bf215546Sopenharmony_ci
174bf215546Sopenharmony_civoid
175bf215546Sopenharmony_cipanvk_per_arch(cmd_alloc_fb_desc)(struct panvk_cmd_buffer *cmdbuf)
176bf215546Sopenharmony_ci{
177bf215546Sopenharmony_ci   struct panvk_batch *batch = cmdbuf->state.batch;
178bf215546Sopenharmony_ci
179bf215546Sopenharmony_ci   if (batch->fb.desc.gpu)
180bf215546Sopenharmony_ci      return;
181bf215546Sopenharmony_ci
182bf215546Sopenharmony_ci   const struct pan_fb_info *fbinfo = &cmdbuf->state.fb.info;
183bf215546Sopenharmony_ci   bool has_zs_ext = fbinfo->zs.view.zs || fbinfo->zs.view.s;
184bf215546Sopenharmony_ci   unsigned tags = MALI_FBD_TAG_IS_MFBD;
185bf215546Sopenharmony_ci
186bf215546Sopenharmony_ci   batch->fb.info = cmdbuf->state.framebuffer;
187bf215546Sopenharmony_ci   batch->fb.desc =
188bf215546Sopenharmony_ci      pan_pool_alloc_desc_aggregate(&cmdbuf->desc_pool.base,
189bf215546Sopenharmony_ci                                    PAN_DESC(FRAMEBUFFER),
190bf215546Sopenharmony_ci                                    PAN_DESC_ARRAY(has_zs_ext ? 1 : 0, ZS_CRC_EXTENSION),
191bf215546Sopenharmony_ci                                    PAN_DESC_ARRAY(MAX2(fbinfo->rt_count, 1), RENDER_TARGET));
192bf215546Sopenharmony_ci
193bf215546Sopenharmony_ci   /* Tag the pointer */
194bf215546Sopenharmony_ci   batch->fb.desc.gpu |= tags;
195bf215546Sopenharmony_ci
196bf215546Sopenharmony_ci   memset(&cmdbuf->state.fb.info.bifrost.pre_post.dcds, 0,
197bf215546Sopenharmony_ci          sizeof(cmdbuf->state.fb.info.bifrost.pre_post.dcds));
198bf215546Sopenharmony_ci}
199bf215546Sopenharmony_ci
200bf215546Sopenharmony_civoid
201bf215546Sopenharmony_cipanvk_per_arch(cmd_alloc_tls_desc)(struct panvk_cmd_buffer *cmdbuf, bool gfx)
202bf215546Sopenharmony_ci{
203bf215546Sopenharmony_ci   struct panvk_batch *batch = cmdbuf->state.batch;
204bf215546Sopenharmony_ci
205bf215546Sopenharmony_ci   assert(batch);
206bf215546Sopenharmony_ci   if (!batch->tls.gpu) {
207bf215546Sopenharmony_ci      batch->tls =
208bf215546Sopenharmony_ci         pan_pool_alloc_desc(&cmdbuf->desc_pool.base, LOCAL_STORAGE);
209bf215546Sopenharmony_ci   }
210bf215546Sopenharmony_ci}
211bf215546Sopenharmony_ci
212bf215546Sopenharmony_cistatic void
213bf215546Sopenharmony_cipanvk_cmd_prepare_draw_sysvals(struct panvk_cmd_buffer *cmdbuf,
214bf215546Sopenharmony_ci                               struct panvk_cmd_bind_point_state *bind_point_state,
215bf215546Sopenharmony_ci                               struct panvk_draw_info *draw)
216bf215546Sopenharmony_ci{
217bf215546Sopenharmony_ci   struct panvk_sysvals *sysvals = &bind_point_state->desc_state.sysvals;
218bf215546Sopenharmony_ci
219bf215546Sopenharmony_ci   unsigned base_vertex = draw->index_size ? draw->vertex_offset : 0;
220bf215546Sopenharmony_ci   if (sysvals->first_vertex != draw->offset_start ||
221bf215546Sopenharmony_ci       sysvals->base_vertex != base_vertex ||
222bf215546Sopenharmony_ci       sysvals->base_instance != draw->first_instance) {
223bf215546Sopenharmony_ci      sysvals->first_vertex = draw->offset_start;
224bf215546Sopenharmony_ci      sysvals->base_vertex = base_vertex;
225bf215546Sopenharmony_ci      sysvals->base_instance = draw->first_instance;
226bf215546Sopenharmony_ci      bind_point_state->desc_state.sysvals_ptr = 0;
227bf215546Sopenharmony_ci   }
228bf215546Sopenharmony_ci
229bf215546Sopenharmony_ci   if (cmdbuf->state.dirty & PANVK_DYNAMIC_BLEND_CONSTANTS) {
230bf215546Sopenharmony_ci      memcpy(&sysvals->blend_constants, cmdbuf->state.blend.constants,
231bf215546Sopenharmony_ci             sizeof(cmdbuf->state.blend.constants));
232bf215546Sopenharmony_ci      bind_point_state->desc_state.sysvals_ptr = 0;
233bf215546Sopenharmony_ci   }
234bf215546Sopenharmony_ci
235bf215546Sopenharmony_ci   if (cmdbuf->state.dirty & PANVK_DYNAMIC_VIEWPORT) {
236bf215546Sopenharmony_ci      panvk_sysval_upload_viewport_scale(&cmdbuf->state.viewport,
237bf215546Sopenharmony_ci                                         &sysvals->viewport_scale);
238bf215546Sopenharmony_ci      panvk_sysval_upload_viewport_offset(&cmdbuf->state.viewport,
239bf215546Sopenharmony_ci                                          &sysvals->viewport_offset);
240bf215546Sopenharmony_ci      bind_point_state->desc_state.sysvals_ptr = 0;
241bf215546Sopenharmony_ci   }
242bf215546Sopenharmony_ci}
243bf215546Sopenharmony_ci
244bf215546Sopenharmony_cistatic void
245bf215546Sopenharmony_cipanvk_cmd_prepare_sysvals(struct panvk_cmd_buffer *cmdbuf,
246bf215546Sopenharmony_ci                          struct panvk_cmd_bind_point_state *bind_point_state)
247bf215546Sopenharmony_ci{
248bf215546Sopenharmony_ci   struct panvk_descriptor_state *desc_state = &bind_point_state->desc_state;
249bf215546Sopenharmony_ci
250bf215546Sopenharmony_ci   if (desc_state->sysvals_ptr)
251bf215546Sopenharmony_ci      return;
252bf215546Sopenharmony_ci
253bf215546Sopenharmony_ci   struct panfrost_ptr sysvals =
254bf215546Sopenharmony_ci      pan_pool_alloc_aligned(&cmdbuf->desc_pool.base,
255bf215546Sopenharmony_ci                             sizeof(desc_state->sysvals), 16);
256bf215546Sopenharmony_ci   memcpy(sysvals.cpu, &desc_state->sysvals, sizeof(desc_state->sysvals));
257bf215546Sopenharmony_ci   desc_state->sysvals_ptr = sysvals.gpu;
258bf215546Sopenharmony_ci}
259bf215546Sopenharmony_ci
260bf215546Sopenharmony_cistatic void
261bf215546Sopenharmony_cipanvk_cmd_prepare_push_constants(struct panvk_cmd_buffer *cmdbuf,
262bf215546Sopenharmony_ci                                 struct panvk_cmd_bind_point_state *bind_point_state)
263bf215546Sopenharmony_ci{
264bf215546Sopenharmony_ci   struct panvk_descriptor_state *desc_state = &bind_point_state->desc_state;
265bf215546Sopenharmony_ci   const struct panvk_pipeline *pipeline = bind_point_state->pipeline;
266bf215546Sopenharmony_ci
267bf215546Sopenharmony_ci   if (!pipeline->layout->push_constants.size || desc_state->push_constants)
268bf215546Sopenharmony_ci      return;
269bf215546Sopenharmony_ci
270bf215546Sopenharmony_ci   struct panfrost_ptr push_constants =
271bf215546Sopenharmony_ci      pan_pool_alloc_aligned(&cmdbuf->desc_pool.base,
272bf215546Sopenharmony_ci                             ALIGN_POT(pipeline->layout->push_constants.size, 16),
273bf215546Sopenharmony_ci                             16);
274bf215546Sopenharmony_ci
275bf215546Sopenharmony_ci   memcpy(push_constants.cpu, cmdbuf->push_constants,
276bf215546Sopenharmony_ci          pipeline->layout->push_constants.size);
277bf215546Sopenharmony_ci   desc_state->push_constants = push_constants.gpu;
278bf215546Sopenharmony_ci}
279bf215546Sopenharmony_ci
280bf215546Sopenharmony_cistatic void
281bf215546Sopenharmony_cipanvk_cmd_prepare_ubos(struct panvk_cmd_buffer *cmdbuf,
282bf215546Sopenharmony_ci                       struct panvk_cmd_bind_point_state *bind_point_state)
283bf215546Sopenharmony_ci{
284bf215546Sopenharmony_ci   struct panvk_descriptor_state *desc_state = &bind_point_state->desc_state;
285bf215546Sopenharmony_ci   const struct panvk_pipeline *pipeline = bind_point_state->pipeline;
286bf215546Sopenharmony_ci
287bf215546Sopenharmony_ci   if (!pipeline->num_ubos || desc_state->ubos)
288bf215546Sopenharmony_ci      return;
289bf215546Sopenharmony_ci
290bf215546Sopenharmony_ci   panvk_cmd_prepare_sysvals(cmdbuf, bind_point_state);
291bf215546Sopenharmony_ci   panvk_cmd_prepare_push_constants(cmdbuf, bind_point_state);
292bf215546Sopenharmony_ci
293bf215546Sopenharmony_ci   struct panfrost_ptr ubos =
294bf215546Sopenharmony_ci      pan_pool_alloc_desc_array(&cmdbuf->desc_pool.base,
295bf215546Sopenharmony_ci                                pipeline->num_ubos,
296bf215546Sopenharmony_ci                                UNIFORM_BUFFER);
297bf215546Sopenharmony_ci
298bf215546Sopenharmony_ci   panvk_per_arch(emit_ubos)(pipeline, desc_state, ubos.cpu);
299bf215546Sopenharmony_ci
300bf215546Sopenharmony_ci   desc_state->ubos = ubos.gpu;
301bf215546Sopenharmony_ci}
302bf215546Sopenharmony_ci
303bf215546Sopenharmony_cistatic void
304bf215546Sopenharmony_cipanvk_cmd_prepare_textures(struct panvk_cmd_buffer *cmdbuf,
305bf215546Sopenharmony_ci                           struct panvk_cmd_bind_point_state *bind_point_state)
306bf215546Sopenharmony_ci{
307bf215546Sopenharmony_ci   struct panvk_descriptor_state *desc_state = &bind_point_state->desc_state;
308bf215546Sopenharmony_ci   const struct panvk_pipeline *pipeline = bind_point_state->pipeline;
309bf215546Sopenharmony_ci   unsigned num_textures = pipeline->layout->num_textures;
310bf215546Sopenharmony_ci
311bf215546Sopenharmony_ci   if (!num_textures || desc_state->textures)
312bf215546Sopenharmony_ci      return;
313bf215546Sopenharmony_ci
314bf215546Sopenharmony_ci   struct panfrost_ptr textures =
315bf215546Sopenharmony_ci      pan_pool_alloc_aligned(&cmdbuf->desc_pool.base,
316bf215546Sopenharmony_ci                             num_textures * pan_size(TEXTURE),
317bf215546Sopenharmony_ci                             pan_size(TEXTURE));
318bf215546Sopenharmony_ci
319bf215546Sopenharmony_ci   void *texture = textures.cpu;
320bf215546Sopenharmony_ci
321bf215546Sopenharmony_ci   for (unsigned i = 0; i < ARRAY_SIZE(desc_state->sets); i++) {
322bf215546Sopenharmony_ci      if (!desc_state->sets[i]) continue;
323bf215546Sopenharmony_ci
324bf215546Sopenharmony_ci      memcpy(texture,
325bf215546Sopenharmony_ci             desc_state->sets[i]->textures,
326bf215546Sopenharmony_ci             desc_state->sets[i]->layout->num_textures *
327bf215546Sopenharmony_ci             pan_size(TEXTURE));
328bf215546Sopenharmony_ci
329bf215546Sopenharmony_ci      texture += desc_state->sets[i]->layout->num_textures *
330bf215546Sopenharmony_ci                 pan_size(TEXTURE);
331bf215546Sopenharmony_ci   }
332bf215546Sopenharmony_ci
333bf215546Sopenharmony_ci   desc_state->textures = textures.gpu;
334bf215546Sopenharmony_ci}
335bf215546Sopenharmony_ci
336bf215546Sopenharmony_cistatic void
337bf215546Sopenharmony_cipanvk_cmd_prepare_samplers(struct panvk_cmd_buffer *cmdbuf,
338bf215546Sopenharmony_ci                           struct panvk_cmd_bind_point_state *bind_point_state)
339bf215546Sopenharmony_ci{
340bf215546Sopenharmony_ci   struct panvk_descriptor_state *desc_state = &bind_point_state->desc_state;
341bf215546Sopenharmony_ci   const struct panvk_pipeline *pipeline = bind_point_state->pipeline;
342bf215546Sopenharmony_ci   unsigned num_samplers = pipeline->layout->num_samplers;
343bf215546Sopenharmony_ci
344bf215546Sopenharmony_ci   if (!num_samplers || desc_state->samplers)
345bf215546Sopenharmony_ci      return;
346bf215546Sopenharmony_ci
347bf215546Sopenharmony_ci   struct panfrost_ptr samplers =
348bf215546Sopenharmony_ci      pan_pool_alloc_desc_array(&cmdbuf->desc_pool.base,
349bf215546Sopenharmony_ci                                num_samplers,
350bf215546Sopenharmony_ci                                SAMPLER);
351bf215546Sopenharmony_ci
352bf215546Sopenharmony_ci   void *sampler = samplers.cpu;
353bf215546Sopenharmony_ci
354bf215546Sopenharmony_ci   /* Prepare the dummy sampler */
355bf215546Sopenharmony_ci   pan_pack(sampler, SAMPLER, cfg) {
356bf215546Sopenharmony_ci      cfg.seamless_cube_map = false;
357bf215546Sopenharmony_ci      cfg.magnify_nearest = true;
358bf215546Sopenharmony_ci      cfg.minify_nearest = true;
359bf215546Sopenharmony_ci      cfg.normalized_coordinates = false;
360bf215546Sopenharmony_ci   }
361bf215546Sopenharmony_ci
362bf215546Sopenharmony_ci   sampler += pan_size(SAMPLER);
363bf215546Sopenharmony_ci
364bf215546Sopenharmony_ci   for (unsigned i = 0; i < ARRAY_SIZE(desc_state->sets); i++) {
365bf215546Sopenharmony_ci      if (!desc_state->sets[i]) continue;
366bf215546Sopenharmony_ci
367bf215546Sopenharmony_ci      memcpy(sampler,
368bf215546Sopenharmony_ci             desc_state->sets[i]->samplers,
369bf215546Sopenharmony_ci             desc_state->sets[i]->layout->num_samplers *
370bf215546Sopenharmony_ci             pan_size(SAMPLER));
371bf215546Sopenharmony_ci
372bf215546Sopenharmony_ci      sampler += desc_state->sets[i]->layout->num_samplers *
373bf215546Sopenharmony_ci                 pan_size(SAMPLER);
374bf215546Sopenharmony_ci   }
375bf215546Sopenharmony_ci
376bf215546Sopenharmony_ci   desc_state->samplers = samplers.gpu;
377bf215546Sopenharmony_ci}
378bf215546Sopenharmony_ci
379bf215546Sopenharmony_cistatic void
380bf215546Sopenharmony_cipanvk_draw_prepare_fs_rsd(struct panvk_cmd_buffer *cmdbuf,
381bf215546Sopenharmony_ci                          struct panvk_draw_info *draw)
382bf215546Sopenharmony_ci{
383bf215546Sopenharmony_ci   const struct panvk_pipeline *pipeline =
384bf215546Sopenharmony_ci      panvk_cmd_get_pipeline(cmdbuf, GRAPHICS);
385bf215546Sopenharmony_ci
386bf215546Sopenharmony_ci   if (!pipeline->fs.dynamic_rsd) {
387bf215546Sopenharmony_ci      draw->fs_rsd = pipeline->rsds[MESA_SHADER_FRAGMENT];
388bf215546Sopenharmony_ci      return;
389bf215546Sopenharmony_ci   }
390bf215546Sopenharmony_ci
391bf215546Sopenharmony_ci   if (!cmdbuf->state.fs_rsd) {
392bf215546Sopenharmony_ci      struct panfrost_ptr rsd =
393bf215546Sopenharmony_ci         pan_pool_alloc_desc_aggregate(&cmdbuf->desc_pool.base,
394bf215546Sopenharmony_ci                                       PAN_DESC(RENDERER_STATE),
395bf215546Sopenharmony_ci                                       PAN_DESC_ARRAY(pipeline->blend.state.rt_count,
396bf215546Sopenharmony_ci                                                      BLEND));
397bf215546Sopenharmony_ci
398bf215546Sopenharmony_ci      struct mali_renderer_state_packed rsd_dyn;
399bf215546Sopenharmony_ci      struct mali_renderer_state_packed *rsd_templ =
400bf215546Sopenharmony_ci         (struct mali_renderer_state_packed *)&pipeline->fs.rsd_template;
401bf215546Sopenharmony_ci
402bf215546Sopenharmony_ci      STATIC_ASSERT(sizeof(pipeline->fs.rsd_template) >= sizeof(*rsd_templ));
403bf215546Sopenharmony_ci
404bf215546Sopenharmony_ci      panvk_per_arch(emit_dyn_fs_rsd)(pipeline, &cmdbuf->state, &rsd_dyn);
405bf215546Sopenharmony_ci      pan_merge(rsd_dyn, (*rsd_templ), RENDERER_STATE);
406bf215546Sopenharmony_ci      memcpy(rsd.cpu, &rsd_dyn, sizeof(rsd_dyn));
407bf215546Sopenharmony_ci
408bf215546Sopenharmony_ci      void *bd = rsd.cpu + pan_size(RENDERER_STATE);
409bf215546Sopenharmony_ci      for (unsigned i = 0; i < pipeline->blend.state.rt_count; i++) {
410bf215546Sopenharmony_ci         if (pipeline->blend.constant[i].index != (uint8_t)~0) {
411bf215546Sopenharmony_ci            struct mali_blend_packed bd_dyn;
412bf215546Sopenharmony_ci            struct mali_blend_packed *bd_templ =
413bf215546Sopenharmony_ci               (struct mali_blend_packed *)&pipeline->blend.bd_template[i];
414bf215546Sopenharmony_ci
415bf215546Sopenharmony_ci            STATIC_ASSERT(sizeof(pipeline->blend.bd_template[0]) >= sizeof(*bd_templ));
416bf215546Sopenharmony_ci            panvk_per_arch(emit_blend_constant)(cmdbuf->device, pipeline, i,
417bf215546Sopenharmony_ci                                                cmdbuf->state.blend.constants,
418bf215546Sopenharmony_ci                                                &bd_dyn);
419bf215546Sopenharmony_ci            pan_merge(bd_dyn, (*bd_templ), BLEND);
420bf215546Sopenharmony_ci            memcpy(bd, &bd_dyn, sizeof(bd_dyn));
421bf215546Sopenharmony_ci         }
422bf215546Sopenharmony_ci         bd += pan_size(BLEND);
423bf215546Sopenharmony_ci      }
424bf215546Sopenharmony_ci
425bf215546Sopenharmony_ci      cmdbuf->state.fs_rsd = rsd.gpu;
426bf215546Sopenharmony_ci   }
427bf215546Sopenharmony_ci
428bf215546Sopenharmony_ci   draw->fs_rsd = cmdbuf->state.fs_rsd;
429bf215546Sopenharmony_ci}
430bf215546Sopenharmony_ci
431bf215546Sopenharmony_civoid
432bf215546Sopenharmony_cipanvk_per_arch(cmd_get_tiler_context)(struct panvk_cmd_buffer *cmdbuf,
433bf215546Sopenharmony_ci                                      unsigned width, unsigned height)
434bf215546Sopenharmony_ci{
435bf215546Sopenharmony_ci   struct panvk_batch *batch = cmdbuf->state.batch;
436bf215546Sopenharmony_ci
437bf215546Sopenharmony_ci   if (batch->tiler.descs.cpu)
438bf215546Sopenharmony_ci      return;
439bf215546Sopenharmony_ci
440bf215546Sopenharmony_ci   batch->tiler.descs =
441bf215546Sopenharmony_ci      pan_pool_alloc_desc_aggregate(&cmdbuf->desc_pool.base,
442bf215546Sopenharmony_ci                                    PAN_DESC(TILER_CONTEXT),
443bf215546Sopenharmony_ci                                    PAN_DESC(TILER_HEAP));
444bf215546Sopenharmony_ci   STATIC_ASSERT(sizeof(batch->tiler.templ) >=
445bf215546Sopenharmony_ci                 pan_size(TILER_CONTEXT) + pan_size(TILER_HEAP));
446bf215546Sopenharmony_ci
447bf215546Sopenharmony_ci   struct panfrost_ptr desc = {
448bf215546Sopenharmony_ci      .gpu = batch->tiler.descs.gpu,
449bf215546Sopenharmony_ci      .cpu = batch->tiler.templ,
450bf215546Sopenharmony_ci   };
451bf215546Sopenharmony_ci
452bf215546Sopenharmony_ci   panvk_per_arch(emit_tiler_context)(cmdbuf->device, width, height, &desc);
453bf215546Sopenharmony_ci   memcpy(batch->tiler.descs.cpu, batch->tiler.templ,
454bf215546Sopenharmony_ci          pan_size(TILER_CONTEXT) + pan_size(TILER_HEAP));
455bf215546Sopenharmony_ci   batch->tiler.ctx.bifrost = batch->tiler.descs.gpu;
456bf215546Sopenharmony_ci}
457bf215546Sopenharmony_ci
458bf215546Sopenharmony_civoid
459bf215546Sopenharmony_cipanvk_per_arch(cmd_prepare_tiler_context)(struct panvk_cmd_buffer *cmdbuf)
460bf215546Sopenharmony_ci{
461bf215546Sopenharmony_ci   const struct pan_fb_info *fbinfo = &cmdbuf->state.fb.info;
462bf215546Sopenharmony_ci
463bf215546Sopenharmony_ci   panvk_per_arch(cmd_get_tiler_context)(cmdbuf,
464bf215546Sopenharmony_ci                                         fbinfo->width,
465bf215546Sopenharmony_ci                                         fbinfo->height);
466bf215546Sopenharmony_ci}
467bf215546Sopenharmony_ci
468bf215546Sopenharmony_cistatic void
469bf215546Sopenharmony_cipanvk_draw_prepare_tiler_context(struct panvk_cmd_buffer *cmdbuf,
470bf215546Sopenharmony_ci                                 struct panvk_draw_info *draw)
471bf215546Sopenharmony_ci{
472bf215546Sopenharmony_ci   struct panvk_batch *batch = cmdbuf->state.batch;
473bf215546Sopenharmony_ci
474bf215546Sopenharmony_ci   panvk_per_arch(cmd_prepare_tiler_context)(cmdbuf);
475bf215546Sopenharmony_ci   draw->tiler_ctx = &batch->tiler.ctx;
476bf215546Sopenharmony_ci}
477bf215546Sopenharmony_ci
478bf215546Sopenharmony_cistatic void
479bf215546Sopenharmony_cipanvk_draw_prepare_varyings(struct panvk_cmd_buffer *cmdbuf,
480bf215546Sopenharmony_ci                            struct panvk_draw_info *draw)
481bf215546Sopenharmony_ci{
482bf215546Sopenharmony_ci   const struct panvk_pipeline *pipeline = panvk_cmd_get_pipeline(cmdbuf, GRAPHICS);
483bf215546Sopenharmony_ci   struct panvk_varyings_info *varyings = &cmdbuf->state.varyings;
484bf215546Sopenharmony_ci
485bf215546Sopenharmony_ci   panvk_varyings_alloc(varyings, &cmdbuf->varying_pool.base,
486bf215546Sopenharmony_ci                        draw->padded_vertex_count * draw->instance_count);
487bf215546Sopenharmony_ci
488bf215546Sopenharmony_ci   unsigned buf_count = panvk_varyings_buf_count(varyings);
489bf215546Sopenharmony_ci   struct panfrost_ptr bufs =
490bf215546Sopenharmony_ci      pan_pool_alloc_desc_array(&cmdbuf->desc_pool.base,
491bf215546Sopenharmony_ci                                buf_count + 1,
492bf215546Sopenharmony_ci                                ATTRIBUTE_BUFFER);
493bf215546Sopenharmony_ci
494bf215546Sopenharmony_ci   panvk_per_arch(emit_varying_bufs)(varyings, bufs.cpu);
495bf215546Sopenharmony_ci
496bf215546Sopenharmony_ci   /* We need an empty entry to stop prefetching on Bifrost */
497bf215546Sopenharmony_ci   memset(bufs.cpu + (pan_size(ATTRIBUTE_BUFFER) * buf_count), 0,
498bf215546Sopenharmony_ci          pan_size(ATTRIBUTE_BUFFER));
499bf215546Sopenharmony_ci
500bf215546Sopenharmony_ci   if (BITSET_TEST(varyings->active, VARYING_SLOT_POS)) {
501bf215546Sopenharmony_ci      draw->position = varyings->buf[varyings->varying[VARYING_SLOT_POS].buf].address +
502bf215546Sopenharmony_ci                       varyings->varying[VARYING_SLOT_POS].offset;
503bf215546Sopenharmony_ci   }
504bf215546Sopenharmony_ci
505bf215546Sopenharmony_ci   if (pipeline->ia.writes_point_size) {
506bf215546Sopenharmony_ci      draw->psiz = varyings->buf[varyings->varying[VARYING_SLOT_PSIZ].buf].address +
507bf215546Sopenharmony_ci                       varyings->varying[VARYING_SLOT_POS].offset;
508bf215546Sopenharmony_ci   } else if (pipeline->ia.topology == MALI_DRAW_MODE_LINES ||
509bf215546Sopenharmony_ci              pipeline->ia.topology == MALI_DRAW_MODE_LINE_STRIP ||
510bf215546Sopenharmony_ci              pipeline->ia.topology == MALI_DRAW_MODE_LINE_LOOP) {
511bf215546Sopenharmony_ci      draw->line_width = pipeline->dynamic_state_mask & PANVK_DYNAMIC_LINE_WIDTH ?
512bf215546Sopenharmony_ci                         cmdbuf->state.rast.line_width : pipeline->rast.line_width;
513bf215546Sopenharmony_ci   } else {
514bf215546Sopenharmony_ci      draw->line_width = 1.0f;
515bf215546Sopenharmony_ci   }
516bf215546Sopenharmony_ci   draw->varying_bufs = bufs.gpu;
517bf215546Sopenharmony_ci
518bf215546Sopenharmony_ci   for (unsigned s = 0; s < MESA_SHADER_STAGES; s++) {
519bf215546Sopenharmony_ci      if (!varyings->stage[s].count) continue;
520bf215546Sopenharmony_ci
521bf215546Sopenharmony_ci      struct panfrost_ptr attribs =
522bf215546Sopenharmony_ci         pan_pool_alloc_desc_array(&cmdbuf->desc_pool.base,
523bf215546Sopenharmony_ci                                   varyings->stage[s].count,
524bf215546Sopenharmony_ci                                   ATTRIBUTE);
525bf215546Sopenharmony_ci
526bf215546Sopenharmony_ci      panvk_per_arch(emit_varyings)(cmdbuf->device, varyings, s, attribs.cpu);
527bf215546Sopenharmony_ci      draw->stages[s].varyings = attribs.gpu;
528bf215546Sopenharmony_ci   }
529bf215546Sopenharmony_ci}
530bf215546Sopenharmony_ci
531bf215546Sopenharmony_cistatic void
532bf215546Sopenharmony_cipanvk_fill_non_vs_attribs(struct panvk_cmd_buffer *cmdbuf,
533bf215546Sopenharmony_ci                          struct panvk_cmd_bind_point_state *bind_point_state,
534bf215546Sopenharmony_ci                          void *attrib_bufs, void *attribs,
535bf215546Sopenharmony_ci                          unsigned first_buf)
536bf215546Sopenharmony_ci{
537bf215546Sopenharmony_ci   struct panvk_descriptor_state *desc_state = &bind_point_state->desc_state;
538bf215546Sopenharmony_ci   const struct panvk_pipeline *pipeline = bind_point_state->pipeline;
539bf215546Sopenharmony_ci
540bf215546Sopenharmony_ci   for (unsigned s = 0; s < pipeline->layout->num_sets; s++) {
541bf215546Sopenharmony_ci      const struct panvk_descriptor_set *set = desc_state->sets[s];
542bf215546Sopenharmony_ci
543bf215546Sopenharmony_ci      if (!set) continue;
544bf215546Sopenharmony_ci
545bf215546Sopenharmony_ci      const struct panvk_descriptor_set_layout *layout = set->layout;
546bf215546Sopenharmony_ci      unsigned img_idx = pipeline->layout->sets[s].img_offset;
547bf215546Sopenharmony_ci      unsigned offset = img_idx * pan_size(ATTRIBUTE_BUFFER) * 2;
548bf215546Sopenharmony_ci      unsigned size = layout->num_imgs * pan_size(ATTRIBUTE_BUFFER) * 2;
549bf215546Sopenharmony_ci
550bf215546Sopenharmony_ci      memcpy(attrib_bufs + offset, desc_state->sets[s]->img_attrib_bufs, size);
551bf215546Sopenharmony_ci
552bf215546Sopenharmony_ci      offset = img_idx * pan_size(ATTRIBUTE);
553bf215546Sopenharmony_ci      for (unsigned i = 0; i < layout->num_imgs; i++) {
554bf215546Sopenharmony_ci         pan_pack(attribs + offset, ATTRIBUTE, cfg) {
555bf215546Sopenharmony_ci            cfg.buffer_index = first_buf + (img_idx + i) * 2;
556bf215546Sopenharmony_ci            cfg.format = desc_state->sets[s]->img_fmts[i];
557bf215546Sopenharmony_ci         }
558bf215546Sopenharmony_ci         offset += pan_size(ATTRIBUTE);
559bf215546Sopenharmony_ci      }
560bf215546Sopenharmony_ci   }
561bf215546Sopenharmony_ci}
562bf215546Sopenharmony_ci
563bf215546Sopenharmony_cistatic void
564bf215546Sopenharmony_cipanvk_prepare_non_vs_attribs(struct panvk_cmd_buffer *cmdbuf,
565bf215546Sopenharmony_ci                             struct panvk_cmd_bind_point_state *bind_point_state)
566bf215546Sopenharmony_ci{
567bf215546Sopenharmony_ci   struct panvk_descriptor_state *desc_state = &bind_point_state->desc_state;
568bf215546Sopenharmony_ci   const struct panvk_pipeline *pipeline = bind_point_state->pipeline;
569bf215546Sopenharmony_ci
570bf215546Sopenharmony_ci   if (desc_state->non_vs_attribs || !pipeline->img_access_mask)
571bf215546Sopenharmony_ci      return;
572bf215546Sopenharmony_ci
573bf215546Sopenharmony_ci   unsigned attrib_count = pipeline->layout->num_imgs;
574bf215546Sopenharmony_ci   unsigned attrib_buf_count = (pipeline->layout->num_imgs * 2);
575bf215546Sopenharmony_ci   struct panfrost_ptr bufs =
576bf215546Sopenharmony_ci      pan_pool_alloc_desc_array(&cmdbuf->desc_pool.base,
577bf215546Sopenharmony_ci                                attrib_buf_count + 1,
578bf215546Sopenharmony_ci                                ATTRIBUTE_BUFFER);
579bf215546Sopenharmony_ci   struct panfrost_ptr attribs =
580bf215546Sopenharmony_ci      pan_pool_alloc_desc_array(&cmdbuf->desc_pool.base, attrib_count,
581bf215546Sopenharmony_ci                                ATTRIBUTE);
582bf215546Sopenharmony_ci
583bf215546Sopenharmony_ci   panvk_fill_non_vs_attribs(cmdbuf, bind_point_state, bufs.cpu, attribs.cpu, 0);
584bf215546Sopenharmony_ci
585bf215546Sopenharmony_ci   desc_state->non_vs_attrib_bufs = bufs.gpu;
586bf215546Sopenharmony_ci   desc_state->non_vs_attribs = attribs.gpu;
587bf215546Sopenharmony_ci}
588bf215546Sopenharmony_ci
589bf215546Sopenharmony_cistatic void
590bf215546Sopenharmony_cipanvk_draw_prepare_vs_attribs(struct panvk_cmd_buffer *cmdbuf,
591bf215546Sopenharmony_ci                              struct panvk_draw_info *draw)
592bf215546Sopenharmony_ci{
593bf215546Sopenharmony_ci   struct panvk_cmd_bind_point_state *bind_point_state =
594bf215546Sopenharmony_ci      panvk_cmd_get_bind_point_state(cmdbuf, GRAPHICS);
595bf215546Sopenharmony_ci   struct panvk_descriptor_state *desc_state = &bind_point_state->desc_state;
596bf215546Sopenharmony_ci   const struct panvk_pipeline *pipeline = bind_point_state->pipeline;
597bf215546Sopenharmony_ci   unsigned num_imgs =
598bf215546Sopenharmony_ci      pipeline->img_access_mask & BITFIELD_BIT(MESA_SHADER_VERTEX) ?
599bf215546Sopenharmony_ci      pipeline->layout->num_imgs : 0;
600bf215546Sopenharmony_ci   unsigned attrib_count = pipeline->attribs.attrib_count + num_imgs;
601bf215546Sopenharmony_ci
602bf215546Sopenharmony_ci   if (desc_state->vs_attribs || !attrib_count)
603bf215546Sopenharmony_ci      return;
604bf215546Sopenharmony_ci
605bf215546Sopenharmony_ci   if (!pipeline->attribs.buf_count) {
606bf215546Sopenharmony_ci      panvk_prepare_non_vs_attribs(cmdbuf, bind_point_state);
607bf215546Sopenharmony_ci      desc_state->vs_attrib_bufs = desc_state->non_vs_attrib_bufs;
608bf215546Sopenharmony_ci      desc_state->vs_attribs = desc_state->non_vs_attribs;
609bf215546Sopenharmony_ci      return;
610bf215546Sopenharmony_ci   }
611bf215546Sopenharmony_ci
612bf215546Sopenharmony_ci   unsigned attrib_buf_count = pipeline->attribs.buf_count * 2;
613bf215546Sopenharmony_ci   struct panfrost_ptr bufs =
614bf215546Sopenharmony_ci      pan_pool_alloc_desc_array(&cmdbuf->desc_pool.base,
615bf215546Sopenharmony_ci                                attrib_buf_count + 1,
616bf215546Sopenharmony_ci                                ATTRIBUTE_BUFFER);
617bf215546Sopenharmony_ci   struct panfrost_ptr attribs =
618bf215546Sopenharmony_ci      pan_pool_alloc_desc_array(&cmdbuf->desc_pool.base, attrib_count,
619bf215546Sopenharmony_ci                                ATTRIBUTE);
620bf215546Sopenharmony_ci
621bf215546Sopenharmony_ci   panvk_per_arch(emit_attrib_bufs)(&pipeline->attribs,
622bf215546Sopenharmony_ci                                    cmdbuf->state.vb.bufs,
623bf215546Sopenharmony_ci                                    cmdbuf->state.vb.count,
624bf215546Sopenharmony_ci                                    draw, bufs.cpu);
625bf215546Sopenharmony_ci   panvk_per_arch(emit_attribs)(cmdbuf->device, draw, &pipeline->attribs,
626bf215546Sopenharmony_ci                                cmdbuf->state.vb.bufs, cmdbuf->state.vb.count,
627bf215546Sopenharmony_ci                                attribs.cpu);
628bf215546Sopenharmony_ci
629bf215546Sopenharmony_ci   if (attrib_count > pipeline->attribs.buf_count) {
630bf215546Sopenharmony_ci      unsigned bufs_offset = pipeline->attribs.buf_count * pan_size(ATTRIBUTE_BUFFER) * 2;
631bf215546Sopenharmony_ci      unsigned attribs_offset = pipeline->attribs.buf_count * pan_size(ATTRIBUTE);
632bf215546Sopenharmony_ci
633bf215546Sopenharmony_ci      panvk_fill_non_vs_attribs(cmdbuf, bind_point_state,
634bf215546Sopenharmony_ci                                bufs.cpu + bufs_offset, attribs.cpu + attribs_offset,
635bf215546Sopenharmony_ci                                pipeline->attribs.buf_count * 2);
636bf215546Sopenharmony_ci   }
637bf215546Sopenharmony_ci
638bf215546Sopenharmony_ci   /* A NULL entry is needed to stop prefecting on Bifrost */
639bf215546Sopenharmony_ci   memset(bufs.cpu + (pan_size(ATTRIBUTE_BUFFER) * attrib_buf_count), 0,
640bf215546Sopenharmony_ci          pan_size(ATTRIBUTE_BUFFER));
641bf215546Sopenharmony_ci
642bf215546Sopenharmony_ci   desc_state->vs_attrib_bufs = bufs.gpu;
643bf215546Sopenharmony_ci   desc_state->vs_attribs = attribs.gpu;
644bf215546Sopenharmony_ci}
645bf215546Sopenharmony_ci
646bf215546Sopenharmony_cistatic void
647bf215546Sopenharmony_cipanvk_draw_prepare_attributes(struct panvk_cmd_buffer *cmdbuf,
648bf215546Sopenharmony_ci                              struct panvk_draw_info *draw)
649bf215546Sopenharmony_ci{
650bf215546Sopenharmony_ci   struct panvk_cmd_bind_point_state *bind_point_state =
651bf215546Sopenharmony_ci      panvk_cmd_get_bind_point_state(cmdbuf, GRAPHICS);
652bf215546Sopenharmony_ci   struct panvk_descriptor_state *desc_state = &bind_point_state->desc_state;
653bf215546Sopenharmony_ci   const struct panvk_pipeline *pipeline = bind_point_state->pipeline;
654bf215546Sopenharmony_ci
655bf215546Sopenharmony_ci   for (unsigned i = 0; i < ARRAY_SIZE(draw->stages); i++) {
656bf215546Sopenharmony_ci      if (i == MESA_SHADER_VERTEX) {
657bf215546Sopenharmony_ci         panvk_draw_prepare_vs_attribs(cmdbuf, draw);
658bf215546Sopenharmony_ci         draw->stages[i].attributes = desc_state->vs_attribs;
659bf215546Sopenharmony_ci         draw->stages[i].attribute_bufs = desc_state->vs_attrib_bufs;
660bf215546Sopenharmony_ci      } else if (pipeline->img_access_mask & BITFIELD_BIT(i)) {
661bf215546Sopenharmony_ci         panvk_prepare_non_vs_attribs(cmdbuf, bind_point_state);
662bf215546Sopenharmony_ci         draw->stages[i].attributes = desc_state->non_vs_attribs;
663bf215546Sopenharmony_ci         draw->stages[i].attribute_bufs = desc_state->non_vs_attrib_bufs;
664bf215546Sopenharmony_ci      }
665bf215546Sopenharmony_ci   }
666bf215546Sopenharmony_ci}
667bf215546Sopenharmony_ci
668bf215546Sopenharmony_cistatic void
669bf215546Sopenharmony_cipanvk_draw_prepare_viewport(struct panvk_cmd_buffer *cmdbuf,
670bf215546Sopenharmony_ci                            struct panvk_draw_info *draw)
671bf215546Sopenharmony_ci{
672bf215546Sopenharmony_ci   const struct panvk_pipeline *pipeline = panvk_cmd_get_pipeline(cmdbuf, GRAPHICS);
673bf215546Sopenharmony_ci
674bf215546Sopenharmony_ci   if (pipeline->vpd) {
675bf215546Sopenharmony_ci      draw->viewport = pipeline->vpd;
676bf215546Sopenharmony_ci   } else if (cmdbuf->state.vpd) {
677bf215546Sopenharmony_ci      draw->viewport = cmdbuf->state.vpd;
678bf215546Sopenharmony_ci   } else {
679bf215546Sopenharmony_ci      struct panfrost_ptr vp =
680bf215546Sopenharmony_ci         pan_pool_alloc_desc(&cmdbuf->desc_pool.base, VIEWPORT);
681bf215546Sopenharmony_ci
682bf215546Sopenharmony_ci      const VkViewport *viewport =
683bf215546Sopenharmony_ci         pipeline->dynamic_state_mask & PANVK_DYNAMIC_VIEWPORT ?
684bf215546Sopenharmony_ci         &cmdbuf->state.viewport : &pipeline->viewport;
685bf215546Sopenharmony_ci      const VkRect2D *scissor =
686bf215546Sopenharmony_ci         pipeline->dynamic_state_mask & PANVK_DYNAMIC_SCISSOR ?
687bf215546Sopenharmony_ci         &cmdbuf->state.scissor : &pipeline->scissor;
688bf215546Sopenharmony_ci
689bf215546Sopenharmony_ci      panvk_per_arch(emit_viewport)(viewport, scissor, vp.cpu);
690bf215546Sopenharmony_ci      draw->viewport = cmdbuf->state.vpd = vp.gpu;
691bf215546Sopenharmony_ci   }
692bf215546Sopenharmony_ci}
693bf215546Sopenharmony_ci
694bf215546Sopenharmony_cistatic void
695bf215546Sopenharmony_cipanvk_draw_prepare_vertex_job(struct panvk_cmd_buffer *cmdbuf,
696bf215546Sopenharmony_ci                              struct panvk_draw_info *draw)
697bf215546Sopenharmony_ci{
698bf215546Sopenharmony_ci   const struct panvk_pipeline *pipeline = panvk_cmd_get_pipeline(cmdbuf, GRAPHICS);
699bf215546Sopenharmony_ci   struct panvk_batch *batch = cmdbuf->state.batch;
700bf215546Sopenharmony_ci   struct panfrost_ptr ptr =
701bf215546Sopenharmony_ci      pan_pool_alloc_desc(&cmdbuf->desc_pool.base, COMPUTE_JOB);
702bf215546Sopenharmony_ci
703bf215546Sopenharmony_ci   util_dynarray_append(&batch->jobs, void *, ptr.cpu);
704bf215546Sopenharmony_ci   draw->jobs.vertex = ptr;
705bf215546Sopenharmony_ci   panvk_per_arch(emit_vertex_job)(pipeline, draw, ptr.cpu);
706bf215546Sopenharmony_ci}
707bf215546Sopenharmony_ci
708bf215546Sopenharmony_cistatic void
709bf215546Sopenharmony_cipanvk_draw_prepare_tiler_job(struct panvk_cmd_buffer *cmdbuf,
710bf215546Sopenharmony_ci                             struct panvk_draw_info *draw)
711bf215546Sopenharmony_ci{
712bf215546Sopenharmony_ci   const struct panvk_pipeline *pipeline = panvk_cmd_get_pipeline(cmdbuf, GRAPHICS);
713bf215546Sopenharmony_ci   struct panvk_batch *batch = cmdbuf->state.batch;
714bf215546Sopenharmony_ci   struct panfrost_ptr ptr =
715bf215546Sopenharmony_ci      pan_pool_alloc_desc(&cmdbuf->desc_pool.base, TILER_JOB);
716bf215546Sopenharmony_ci
717bf215546Sopenharmony_ci   util_dynarray_append(&batch->jobs, void *, ptr.cpu);
718bf215546Sopenharmony_ci   draw->jobs.tiler = ptr;
719bf215546Sopenharmony_ci   panvk_per_arch(emit_tiler_job)(pipeline, draw, ptr.cpu);
720bf215546Sopenharmony_ci}
721bf215546Sopenharmony_ci
722bf215546Sopenharmony_cistatic void
723bf215546Sopenharmony_cipanvk_cmd_draw(struct panvk_cmd_buffer *cmdbuf,
724bf215546Sopenharmony_ci               struct panvk_draw_info *draw)
725bf215546Sopenharmony_ci{
726bf215546Sopenharmony_ci   struct panvk_batch *batch = cmdbuf->state.batch;
727bf215546Sopenharmony_ci   struct panvk_cmd_bind_point_state *bind_point_state =
728bf215546Sopenharmony_ci      panvk_cmd_get_bind_point_state(cmdbuf, GRAPHICS);
729bf215546Sopenharmony_ci   const struct panvk_pipeline *pipeline =
730bf215546Sopenharmony_ci      panvk_cmd_get_pipeline(cmdbuf, GRAPHICS);
731bf215546Sopenharmony_ci
732bf215546Sopenharmony_ci   /* There are only 16 bits in the descriptor for the job ID, make sure all
733bf215546Sopenharmony_ci    * the 3 (2 in Bifrost) jobs in this draw are in the same batch.
734bf215546Sopenharmony_ci    */
735bf215546Sopenharmony_ci   if (batch->scoreboard.job_index >= (UINT16_MAX - 3)) {
736bf215546Sopenharmony_ci      panvk_per_arch(cmd_close_batch)(cmdbuf);
737bf215546Sopenharmony_ci      panvk_cmd_preload_fb_after_batch_split(cmdbuf);
738bf215546Sopenharmony_ci      batch = panvk_cmd_open_batch(cmdbuf);
739bf215546Sopenharmony_ci   }
740bf215546Sopenharmony_ci
741bf215546Sopenharmony_ci   if (pipeline->rast.enable)
742bf215546Sopenharmony_ci      panvk_per_arch(cmd_alloc_fb_desc)(cmdbuf);
743bf215546Sopenharmony_ci
744bf215546Sopenharmony_ci   panvk_per_arch(cmd_alloc_tls_desc)(cmdbuf, true);
745bf215546Sopenharmony_ci
746bf215546Sopenharmony_ci   panvk_cmd_prepare_draw_sysvals(cmdbuf, bind_point_state, draw);
747bf215546Sopenharmony_ci   panvk_cmd_prepare_ubos(cmdbuf, bind_point_state);
748bf215546Sopenharmony_ci   panvk_cmd_prepare_textures(cmdbuf, bind_point_state);
749bf215546Sopenharmony_ci   panvk_cmd_prepare_samplers(cmdbuf, bind_point_state);
750bf215546Sopenharmony_ci
751bf215546Sopenharmony_ci   /* TODO: indexed draws */
752bf215546Sopenharmony_ci   struct panvk_descriptor_state *desc_state =
753bf215546Sopenharmony_ci      panvk_cmd_get_desc_state(cmdbuf, GRAPHICS);
754bf215546Sopenharmony_ci
755bf215546Sopenharmony_ci   draw->tls = batch->tls.gpu;
756bf215546Sopenharmony_ci   draw->fb = batch->fb.desc.gpu;
757bf215546Sopenharmony_ci   draw->ubos = desc_state->ubos;
758bf215546Sopenharmony_ci   draw->textures = desc_state->textures;
759bf215546Sopenharmony_ci   draw->samplers = desc_state->samplers;
760bf215546Sopenharmony_ci
761bf215546Sopenharmony_ci   STATIC_ASSERT(sizeof(draw->invocation) >= sizeof(struct mali_invocation_packed));
762bf215546Sopenharmony_ci   panfrost_pack_work_groups_compute((struct mali_invocation_packed *)&draw->invocation,
763bf215546Sopenharmony_ci                                      1, draw->vertex_range, draw->instance_count,
764bf215546Sopenharmony_ci                                      1, 1, 1, true, false);
765bf215546Sopenharmony_ci
766bf215546Sopenharmony_ci   panvk_draw_prepare_fs_rsd(cmdbuf, draw);
767bf215546Sopenharmony_ci   panvk_draw_prepare_varyings(cmdbuf, draw);
768bf215546Sopenharmony_ci   panvk_draw_prepare_attributes(cmdbuf, draw);
769bf215546Sopenharmony_ci   panvk_draw_prepare_viewport(cmdbuf, draw);
770bf215546Sopenharmony_ci   panvk_draw_prepare_tiler_context(cmdbuf, draw);
771bf215546Sopenharmony_ci   panvk_draw_prepare_vertex_job(cmdbuf, draw);
772bf215546Sopenharmony_ci   panvk_draw_prepare_tiler_job(cmdbuf, draw);
773bf215546Sopenharmony_ci   batch->tlsinfo.tls.size = MAX2(pipeline->tls_size, batch->tlsinfo.tls.size);
774bf215546Sopenharmony_ci   assert(!pipeline->wls_size);
775bf215546Sopenharmony_ci
776bf215546Sopenharmony_ci   unsigned vjob_id =
777bf215546Sopenharmony_ci      panfrost_add_job(&cmdbuf->desc_pool.base, &batch->scoreboard,
778bf215546Sopenharmony_ci                       MALI_JOB_TYPE_VERTEX, false, false, 0, 0,
779bf215546Sopenharmony_ci                       &draw->jobs.vertex, false);
780bf215546Sopenharmony_ci
781bf215546Sopenharmony_ci   if (pipeline->rast.enable) {
782bf215546Sopenharmony_ci      panfrost_add_job(&cmdbuf->desc_pool.base, &batch->scoreboard,
783bf215546Sopenharmony_ci                       MALI_JOB_TYPE_TILER, false, false, vjob_id, 0,
784bf215546Sopenharmony_ci                       &draw->jobs.tiler, false);
785bf215546Sopenharmony_ci   }
786bf215546Sopenharmony_ci
787bf215546Sopenharmony_ci   /* Clear the dirty flags all at once */
788bf215546Sopenharmony_ci   desc_state->dirty = cmdbuf->state.dirty = 0;
789bf215546Sopenharmony_ci}
790bf215546Sopenharmony_ci
791bf215546Sopenharmony_civoid
792bf215546Sopenharmony_cipanvk_per_arch(CmdDraw)(VkCommandBuffer commandBuffer,
793bf215546Sopenharmony_ci                        uint32_t vertexCount,
794bf215546Sopenharmony_ci                        uint32_t instanceCount,
795bf215546Sopenharmony_ci                        uint32_t firstVertex,
796bf215546Sopenharmony_ci                        uint32_t firstInstance)
797bf215546Sopenharmony_ci{
798bf215546Sopenharmony_ci   VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
799bf215546Sopenharmony_ci
800bf215546Sopenharmony_ci   if (instanceCount == 0 || vertexCount == 0)
801bf215546Sopenharmony_ci      return;
802bf215546Sopenharmony_ci
803bf215546Sopenharmony_ci   struct panvk_draw_info draw = {
804bf215546Sopenharmony_ci      .first_vertex = firstVertex,
805bf215546Sopenharmony_ci      .vertex_count = vertexCount,
806bf215546Sopenharmony_ci      .vertex_range = vertexCount,
807bf215546Sopenharmony_ci      .first_instance = firstInstance,
808bf215546Sopenharmony_ci      .instance_count = instanceCount,
809bf215546Sopenharmony_ci      .padded_vertex_count = instanceCount > 1 ?
810bf215546Sopenharmony_ci                             panfrost_padded_vertex_count(vertexCount) :
811bf215546Sopenharmony_ci                             vertexCount,
812bf215546Sopenharmony_ci      .offset_start = firstVertex,
813bf215546Sopenharmony_ci   };
814bf215546Sopenharmony_ci
815bf215546Sopenharmony_ci   panvk_cmd_draw(cmdbuf, &draw);
816bf215546Sopenharmony_ci}
817bf215546Sopenharmony_ci
818bf215546Sopenharmony_cistatic void
819bf215546Sopenharmony_cipanvk_index_minmax_search(struct panvk_cmd_buffer *cmdbuf,
820bf215546Sopenharmony_ci                          uint32_t start, uint32_t count,
821bf215546Sopenharmony_ci                          bool restart,
822bf215546Sopenharmony_ci                          uint32_t *min, uint32_t *max)
823bf215546Sopenharmony_ci{
824bf215546Sopenharmony_ci   void *ptr = cmdbuf->state.ib.buffer->bo->ptr.cpu +
825bf215546Sopenharmony_ci               cmdbuf->state.ib.buffer->bo_offset +
826bf215546Sopenharmony_ci               cmdbuf->state.ib.offset;
827bf215546Sopenharmony_ci
828bf215546Sopenharmony_ci   fprintf(stderr, "WARNING: Crawling index buffers from the CPU isn't valid in Vulkan\n");
829bf215546Sopenharmony_ci
830bf215546Sopenharmony_ci   assert(cmdbuf->state.ib.buffer);
831bf215546Sopenharmony_ci   assert(cmdbuf->state.ib.buffer->bo);
832bf215546Sopenharmony_ci   assert(cmdbuf->state.ib.buffer->bo->ptr.cpu);
833bf215546Sopenharmony_ci
834bf215546Sopenharmony_ci   *max = 0;
835bf215546Sopenharmony_ci
836bf215546Sopenharmony_ci   /* TODO: Use panfrost_minmax_cache */
837bf215546Sopenharmony_ci   /* TODO: Read full cacheline of data to mitigate the uncached
838bf215546Sopenharmony_ci    * mapping slowness.
839bf215546Sopenharmony_ci    */
840bf215546Sopenharmony_ci   switch (cmdbuf->state.ib.index_size) {
841bf215546Sopenharmony_ci#define MINMAX_SEARCH_CASE(sz) \
842bf215546Sopenharmony_ci   case sz: { \
843bf215546Sopenharmony_ci      uint ## sz ## _t *indices = ptr; \
844bf215546Sopenharmony_ci      *min = UINT ## sz ## _MAX; \
845bf215546Sopenharmony_ci      for (uint32_t i = 0; i < count; i++) { \
846bf215546Sopenharmony_ci         if (restart && indices[i + start] == UINT ## sz ##_MAX) continue; \
847bf215546Sopenharmony_ci         *min = MIN2(indices[i + start], *min); \
848bf215546Sopenharmony_ci         *max = MAX2(indices[i + start], *max); \
849bf215546Sopenharmony_ci      } \
850bf215546Sopenharmony_ci      break; \
851bf215546Sopenharmony_ci   }
852bf215546Sopenharmony_ci   MINMAX_SEARCH_CASE(32)
853bf215546Sopenharmony_ci   MINMAX_SEARCH_CASE(16)
854bf215546Sopenharmony_ci   MINMAX_SEARCH_CASE(8)
855bf215546Sopenharmony_ci#undef MINMAX_SEARCH_CASE
856bf215546Sopenharmony_ci   default:
857bf215546Sopenharmony_ci      unreachable("Invalid index size");
858bf215546Sopenharmony_ci   }
859bf215546Sopenharmony_ci}
860bf215546Sopenharmony_ci
861bf215546Sopenharmony_civoid
862bf215546Sopenharmony_cipanvk_per_arch(CmdDrawIndexed)(VkCommandBuffer commandBuffer,
863bf215546Sopenharmony_ci                               uint32_t indexCount,
864bf215546Sopenharmony_ci                               uint32_t instanceCount,
865bf215546Sopenharmony_ci                               uint32_t firstIndex,
866bf215546Sopenharmony_ci                               int32_t vertexOffset,
867bf215546Sopenharmony_ci                               uint32_t firstInstance)
868bf215546Sopenharmony_ci{
869bf215546Sopenharmony_ci   VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
870bf215546Sopenharmony_ci   uint32_t min_vertex, max_vertex;
871bf215546Sopenharmony_ci
872bf215546Sopenharmony_ci   if (instanceCount == 0 || indexCount == 0)
873bf215546Sopenharmony_ci      return;
874bf215546Sopenharmony_ci
875bf215546Sopenharmony_ci   const struct panvk_pipeline *pipeline =
876bf215546Sopenharmony_ci      panvk_cmd_get_pipeline(cmdbuf, GRAPHICS);
877bf215546Sopenharmony_ci   bool primitive_restart = pipeline->ia.primitive_restart;
878bf215546Sopenharmony_ci
879bf215546Sopenharmony_ci   panvk_index_minmax_search(cmdbuf, firstIndex, indexCount, primitive_restart,
880bf215546Sopenharmony_ci                             &min_vertex, &max_vertex);
881bf215546Sopenharmony_ci
882bf215546Sopenharmony_ci   unsigned vertex_range = max_vertex - min_vertex + 1;
883bf215546Sopenharmony_ci   struct panvk_draw_info draw = {
884bf215546Sopenharmony_ci      .index_size = cmdbuf->state.ib.index_size,
885bf215546Sopenharmony_ci      .first_index = firstIndex,
886bf215546Sopenharmony_ci      .index_count = indexCount,
887bf215546Sopenharmony_ci      .vertex_offset = vertexOffset,
888bf215546Sopenharmony_ci      .first_instance = firstInstance,
889bf215546Sopenharmony_ci      .instance_count = instanceCount,
890bf215546Sopenharmony_ci      .vertex_range = vertex_range,
891bf215546Sopenharmony_ci      .vertex_count = indexCount + abs(vertexOffset),
892bf215546Sopenharmony_ci      .padded_vertex_count = instanceCount > 1 ?
893bf215546Sopenharmony_ci                             panfrost_padded_vertex_count(vertex_range) :
894bf215546Sopenharmony_ci                             vertex_range,
895bf215546Sopenharmony_ci      .offset_start = min_vertex + vertexOffset,
896bf215546Sopenharmony_ci      .indices = panvk_buffer_gpu_ptr(cmdbuf->state.ib.buffer,
897bf215546Sopenharmony_ci                                      cmdbuf->state.ib.offset) +
898bf215546Sopenharmony_ci                 (firstIndex * (cmdbuf->state.ib.index_size / 8)),
899bf215546Sopenharmony_ci   };
900bf215546Sopenharmony_ci
901bf215546Sopenharmony_ci   panvk_cmd_draw(cmdbuf, &draw);
902bf215546Sopenharmony_ci}
903bf215546Sopenharmony_ci
904bf215546Sopenharmony_ciVkResult
905bf215546Sopenharmony_cipanvk_per_arch(EndCommandBuffer)(VkCommandBuffer commandBuffer)
906bf215546Sopenharmony_ci{
907bf215546Sopenharmony_ci   VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
908bf215546Sopenharmony_ci   VkResult ret =
909bf215546Sopenharmony_ci      cmdbuf->vk.level == VK_COMMAND_BUFFER_LEVEL_SECONDARY ?
910bf215546Sopenharmony_ci      cmdbuf->vk.cmd_queue.error : cmdbuf->record_result;
911bf215546Sopenharmony_ci
912bf215546Sopenharmony_ci   panvk_per_arch(cmd_close_batch)(cmdbuf);
913bf215546Sopenharmony_ci   cmdbuf->status = ret == VK_SUCCESS ?
914bf215546Sopenharmony_ci                    PANVK_CMD_BUFFER_STATUS_EXECUTABLE :
915bf215546Sopenharmony_ci                    PANVK_CMD_BUFFER_STATUS_INVALID;
916bf215546Sopenharmony_ci   return ret;
917bf215546Sopenharmony_ci}
918bf215546Sopenharmony_ci
919bf215546Sopenharmony_civoid
920bf215546Sopenharmony_cipanvk_per_arch(CmdEndRenderPass2)(VkCommandBuffer commandBuffer,
921bf215546Sopenharmony_ci                                  const VkSubpassEndInfo *pSubpassEndInfo)
922bf215546Sopenharmony_ci{
923bf215546Sopenharmony_ci   VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
924bf215546Sopenharmony_ci
925bf215546Sopenharmony_ci   panvk_per_arch(cmd_close_batch)(cmdbuf);
926bf215546Sopenharmony_ci   vk_free(&cmdbuf->pool->vk.alloc, cmdbuf->state.clear);
927bf215546Sopenharmony_ci   cmdbuf->state.batch = NULL;
928bf215546Sopenharmony_ci   cmdbuf->state.pass = NULL;
929bf215546Sopenharmony_ci   cmdbuf->state.subpass = NULL;
930bf215546Sopenharmony_ci   cmdbuf->state.framebuffer = NULL;
931bf215546Sopenharmony_ci   cmdbuf->state.clear = NULL;
932bf215546Sopenharmony_ci}
933bf215546Sopenharmony_ci
934bf215546Sopenharmony_civoid
935bf215546Sopenharmony_cipanvk_per_arch(CmdEndRenderPass)(VkCommandBuffer cmd)
936bf215546Sopenharmony_ci{
937bf215546Sopenharmony_ci   VkSubpassEndInfo einfo = {
938bf215546Sopenharmony_ci      .sType = VK_STRUCTURE_TYPE_SUBPASS_END_INFO,
939bf215546Sopenharmony_ci   };
940bf215546Sopenharmony_ci
941bf215546Sopenharmony_ci   panvk_per_arch(CmdEndRenderPass2)(cmd, &einfo);
942bf215546Sopenharmony_ci}
943bf215546Sopenharmony_ci
944bf215546Sopenharmony_ci
945bf215546Sopenharmony_civoid
946bf215546Sopenharmony_cipanvk_per_arch(CmdPipelineBarrier2)(VkCommandBuffer commandBuffer,
947bf215546Sopenharmony_ci                                    const VkDependencyInfo *pDependencyInfo)
948bf215546Sopenharmony_ci{
949bf215546Sopenharmony_ci   VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
950bf215546Sopenharmony_ci
951bf215546Sopenharmony_ci   /* Caches are flushed/invalidated at batch boundaries for now, nothing to do
952bf215546Sopenharmony_ci    * for memory barriers assuming we implement barriers with the creation of a
953bf215546Sopenharmony_ci    * new batch.
954bf215546Sopenharmony_ci    * FIXME: We can probably do better with a CacheFlush job that has the
955bf215546Sopenharmony_ci    * barrier flag set to true.
956bf215546Sopenharmony_ci    */
957bf215546Sopenharmony_ci   if (cmdbuf->state.batch) {
958bf215546Sopenharmony_ci      panvk_per_arch(cmd_close_batch)(cmdbuf);
959bf215546Sopenharmony_ci      panvk_cmd_preload_fb_after_batch_split(cmdbuf);
960bf215546Sopenharmony_ci      panvk_cmd_open_batch(cmdbuf);
961bf215546Sopenharmony_ci   }
962bf215546Sopenharmony_ci}
963bf215546Sopenharmony_ci
964bf215546Sopenharmony_cistatic void
965bf215546Sopenharmony_cipanvk_add_set_event_operation(struct panvk_cmd_buffer *cmdbuf,
966bf215546Sopenharmony_ci                              struct panvk_event *event,
967bf215546Sopenharmony_ci                              enum panvk_event_op_type type)
968bf215546Sopenharmony_ci{
969bf215546Sopenharmony_ci   struct panvk_event_op op = {
970bf215546Sopenharmony_ci      .type = type,
971bf215546Sopenharmony_ci      .event = event,
972bf215546Sopenharmony_ci   };
973bf215546Sopenharmony_ci
974bf215546Sopenharmony_ci   if (cmdbuf->state.batch == NULL) {
975bf215546Sopenharmony_ci      /* No open batch, let's create a new one so this operation happens in
976bf215546Sopenharmony_ci       * the right order.
977bf215546Sopenharmony_ci       */
978bf215546Sopenharmony_ci      panvk_cmd_open_batch(cmdbuf);
979bf215546Sopenharmony_ci      util_dynarray_append(&cmdbuf->state.batch->event_ops,
980bf215546Sopenharmony_ci                           struct panvk_event_op,
981bf215546Sopenharmony_ci                           op);
982bf215546Sopenharmony_ci      panvk_per_arch(cmd_close_batch)(cmdbuf);
983bf215546Sopenharmony_ci   } else {
984bf215546Sopenharmony_ci      /* Let's close the current batch so the operation executes before any
985bf215546Sopenharmony_ci       * future commands.
986bf215546Sopenharmony_ci       */
987bf215546Sopenharmony_ci      util_dynarray_append(&cmdbuf->state.batch->event_ops,
988bf215546Sopenharmony_ci                           struct panvk_event_op,
989bf215546Sopenharmony_ci                           op);
990bf215546Sopenharmony_ci      panvk_per_arch(cmd_close_batch)(cmdbuf);
991bf215546Sopenharmony_ci      panvk_cmd_preload_fb_after_batch_split(cmdbuf);
992bf215546Sopenharmony_ci      panvk_cmd_open_batch(cmdbuf);
993bf215546Sopenharmony_ci   }
994bf215546Sopenharmony_ci}
995bf215546Sopenharmony_ci
996bf215546Sopenharmony_cistatic void
997bf215546Sopenharmony_cipanvk_add_wait_event_operation(struct panvk_cmd_buffer *cmdbuf,
998bf215546Sopenharmony_ci                               struct panvk_event *event)
999bf215546Sopenharmony_ci{
1000bf215546Sopenharmony_ci   struct panvk_event_op op = {
1001bf215546Sopenharmony_ci      .type = PANVK_EVENT_OP_WAIT,
1002bf215546Sopenharmony_ci      .event = event,
1003bf215546Sopenharmony_ci   };
1004bf215546Sopenharmony_ci
1005bf215546Sopenharmony_ci   if (cmdbuf->state.batch == NULL) {
1006bf215546Sopenharmony_ci      /* No open batch, let's create a new one and have it wait for this event. */
1007bf215546Sopenharmony_ci      panvk_cmd_open_batch(cmdbuf);
1008bf215546Sopenharmony_ci      util_dynarray_append(&cmdbuf->state.batch->event_ops,
1009bf215546Sopenharmony_ci                           struct panvk_event_op,
1010bf215546Sopenharmony_ci                           op);
1011bf215546Sopenharmony_ci   } else {
1012bf215546Sopenharmony_ci      /* Let's close the current batch so any future commands wait on the
1013bf215546Sopenharmony_ci       * event signal operation.
1014bf215546Sopenharmony_ci       */
1015bf215546Sopenharmony_ci      if (cmdbuf->state.batch->fragment_job ||
1016bf215546Sopenharmony_ci          cmdbuf->state.batch->scoreboard.first_job) {
1017bf215546Sopenharmony_ci         panvk_per_arch(cmd_close_batch)(cmdbuf);
1018bf215546Sopenharmony_ci         panvk_cmd_preload_fb_after_batch_split(cmdbuf);
1019bf215546Sopenharmony_ci         panvk_cmd_open_batch(cmdbuf);
1020bf215546Sopenharmony_ci      }
1021bf215546Sopenharmony_ci      util_dynarray_append(&cmdbuf->state.batch->event_ops,
1022bf215546Sopenharmony_ci                           struct panvk_event_op,
1023bf215546Sopenharmony_ci                           op);
1024bf215546Sopenharmony_ci   }
1025bf215546Sopenharmony_ci}
1026bf215546Sopenharmony_ci
1027bf215546Sopenharmony_civoid
1028bf215546Sopenharmony_cipanvk_per_arch(CmdSetEvent2)(VkCommandBuffer commandBuffer,
1029bf215546Sopenharmony_ci                             VkEvent _event,
1030bf215546Sopenharmony_ci                             const VkDependencyInfo *pDependencyInfo)
1031bf215546Sopenharmony_ci{
1032bf215546Sopenharmony_ci   VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
1033bf215546Sopenharmony_ci   VK_FROM_HANDLE(panvk_event, event, _event);
1034bf215546Sopenharmony_ci
1035bf215546Sopenharmony_ci   /* vkCmdSetEvent cannot be called inside a render pass */
1036bf215546Sopenharmony_ci   assert(cmdbuf->state.pass == NULL);
1037bf215546Sopenharmony_ci
1038bf215546Sopenharmony_ci   panvk_add_set_event_operation(cmdbuf, event, PANVK_EVENT_OP_SET);
1039bf215546Sopenharmony_ci}
1040bf215546Sopenharmony_ci
1041bf215546Sopenharmony_civoid
1042bf215546Sopenharmony_cipanvk_per_arch(CmdResetEvent2)(VkCommandBuffer commandBuffer,
1043bf215546Sopenharmony_ci                               VkEvent _event,
1044bf215546Sopenharmony_ci                               VkPipelineStageFlags2 stageMask)
1045bf215546Sopenharmony_ci{
1046bf215546Sopenharmony_ci   VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
1047bf215546Sopenharmony_ci   VK_FROM_HANDLE(panvk_event, event, _event);
1048bf215546Sopenharmony_ci
1049bf215546Sopenharmony_ci   /* vkCmdResetEvent cannot be called inside a render pass */
1050bf215546Sopenharmony_ci   assert(cmdbuf->state.pass == NULL);
1051bf215546Sopenharmony_ci
1052bf215546Sopenharmony_ci   panvk_add_set_event_operation(cmdbuf, event, PANVK_EVENT_OP_RESET);
1053bf215546Sopenharmony_ci}
1054bf215546Sopenharmony_ci
1055bf215546Sopenharmony_civoid
1056bf215546Sopenharmony_cipanvk_per_arch(CmdWaitEvents2)(VkCommandBuffer commandBuffer,
1057bf215546Sopenharmony_ci                               uint32_t eventCount,
1058bf215546Sopenharmony_ci                               const VkEvent *pEvents,
1059bf215546Sopenharmony_ci                               const VkDependencyInfo *pDependencyInfos)
1060bf215546Sopenharmony_ci{
1061bf215546Sopenharmony_ci   VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
1062bf215546Sopenharmony_ci
1063bf215546Sopenharmony_ci   assert(eventCount > 0);
1064bf215546Sopenharmony_ci
1065bf215546Sopenharmony_ci   for (uint32_t i = 0; i < eventCount; i++) {
1066bf215546Sopenharmony_ci      VK_FROM_HANDLE(panvk_event, event, pEvents[i]);
1067bf215546Sopenharmony_ci      panvk_add_wait_event_operation(cmdbuf, event);
1068bf215546Sopenharmony_ci   }
1069bf215546Sopenharmony_ci}
1070bf215546Sopenharmony_ci
1071bf215546Sopenharmony_cistatic VkResult
1072bf215546Sopenharmony_cipanvk_reset_cmdbuf(struct panvk_cmd_buffer *cmdbuf)
1073bf215546Sopenharmony_ci{
1074bf215546Sopenharmony_ci   vk_command_buffer_reset(&cmdbuf->vk);
1075bf215546Sopenharmony_ci
1076bf215546Sopenharmony_ci   cmdbuf->record_result = VK_SUCCESS;
1077bf215546Sopenharmony_ci
1078bf215546Sopenharmony_ci   list_for_each_entry_safe(struct panvk_batch, batch, &cmdbuf->batches, node) {
1079bf215546Sopenharmony_ci      list_del(&batch->node);
1080bf215546Sopenharmony_ci      util_dynarray_fini(&batch->jobs);
1081bf215546Sopenharmony_ci      util_dynarray_fini(&batch->event_ops);
1082bf215546Sopenharmony_ci
1083bf215546Sopenharmony_ci      vk_free(&cmdbuf->pool->vk.alloc, batch);
1084bf215546Sopenharmony_ci   }
1085bf215546Sopenharmony_ci
1086bf215546Sopenharmony_ci   panvk_pool_reset(&cmdbuf->desc_pool);
1087bf215546Sopenharmony_ci   panvk_pool_reset(&cmdbuf->tls_pool);
1088bf215546Sopenharmony_ci   panvk_pool_reset(&cmdbuf->varying_pool);
1089bf215546Sopenharmony_ci   cmdbuf->status = PANVK_CMD_BUFFER_STATUS_INITIAL;
1090bf215546Sopenharmony_ci
1091bf215546Sopenharmony_ci   for (unsigned i = 0; i < MAX_BIND_POINTS; i++)
1092bf215546Sopenharmony_ci      memset(&cmdbuf->bind_points[i].desc_state.sets, 0, sizeof(cmdbuf->bind_points[0].desc_state.sets));
1093bf215546Sopenharmony_ci
1094bf215546Sopenharmony_ci   return cmdbuf->record_result;
1095bf215546Sopenharmony_ci}
1096bf215546Sopenharmony_ci
1097bf215546Sopenharmony_cistatic void
1098bf215546Sopenharmony_cipanvk_destroy_cmdbuf(struct panvk_cmd_buffer *cmdbuf)
1099bf215546Sopenharmony_ci{
1100bf215546Sopenharmony_ci   struct panvk_device *device = cmdbuf->device;
1101bf215546Sopenharmony_ci
1102bf215546Sopenharmony_ci   list_del(&cmdbuf->pool_link);
1103bf215546Sopenharmony_ci
1104bf215546Sopenharmony_ci   list_for_each_entry_safe(struct panvk_batch, batch, &cmdbuf->batches, node) {
1105bf215546Sopenharmony_ci      list_del(&batch->node);
1106bf215546Sopenharmony_ci      util_dynarray_fini(&batch->jobs);
1107bf215546Sopenharmony_ci      util_dynarray_fini(&batch->event_ops);
1108bf215546Sopenharmony_ci
1109bf215546Sopenharmony_ci      vk_free(&cmdbuf->pool->vk.alloc, batch);
1110bf215546Sopenharmony_ci   }
1111bf215546Sopenharmony_ci
1112bf215546Sopenharmony_ci   panvk_pool_cleanup(&cmdbuf->desc_pool);
1113bf215546Sopenharmony_ci   panvk_pool_cleanup(&cmdbuf->tls_pool);
1114bf215546Sopenharmony_ci   panvk_pool_cleanup(&cmdbuf->varying_pool);
1115bf215546Sopenharmony_ci   vk_command_buffer_finish(&cmdbuf->vk);
1116bf215546Sopenharmony_ci   vk_free(&device->vk.alloc, cmdbuf);
1117bf215546Sopenharmony_ci}
1118bf215546Sopenharmony_ci
1119bf215546Sopenharmony_cistatic VkResult
1120bf215546Sopenharmony_cipanvk_create_cmdbuf(struct panvk_device *device,
1121bf215546Sopenharmony_ci                    struct panvk_cmd_pool *pool,
1122bf215546Sopenharmony_ci                    VkCommandBufferLevel level,
1123bf215546Sopenharmony_ci                    struct panvk_cmd_buffer **cmdbuf_out)
1124bf215546Sopenharmony_ci{
1125bf215546Sopenharmony_ci   struct panvk_cmd_buffer *cmdbuf;
1126bf215546Sopenharmony_ci
1127bf215546Sopenharmony_ci   cmdbuf = vk_zalloc(&device->vk.alloc, sizeof(*cmdbuf),
1128bf215546Sopenharmony_ci                      8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
1129bf215546Sopenharmony_ci   if (!cmdbuf)
1130bf215546Sopenharmony_ci      return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
1131bf215546Sopenharmony_ci
1132bf215546Sopenharmony_ci   VkResult result = vk_command_buffer_init(&cmdbuf->vk, &pool->vk, level);
1133bf215546Sopenharmony_ci   if (result != VK_SUCCESS) {
1134bf215546Sopenharmony_ci      vk_free(&device->vk.alloc, cmdbuf);
1135bf215546Sopenharmony_ci      return result;
1136bf215546Sopenharmony_ci   }
1137bf215546Sopenharmony_ci
1138bf215546Sopenharmony_ci   cmdbuf->device = device;
1139bf215546Sopenharmony_ci   cmdbuf->pool = pool;
1140bf215546Sopenharmony_ci
1141bf215546Sopenharmony_ci   if (pool) {
1142bf215546Sopenharmony_ci      list_addtail(&cmdbuf->pool_link, &pool->active_cmd_buffers);
1143bf215546Sopenharmony_ci      cmdbuf->queue_family_index = pool->vk.queue_family_index;
1144bf215546Sopenharmony_ci   } else {
1145bf215546Sopenharmony_ci      /* Init the pool_link so we can safely call list_del when we destroy
1146bf215546Sopenharmony_ci       * the command buffer
1147bf215546Sopenharmony_ci       */
1148bf215546Sopenharmony_ci      list_inithead(&cmdbuf->pool_link);
1149bf215546Sopenharmony_ci      cmdbuf->queue_family_index = PANVK_QUEUE_GENERAL;
1150bf215546Sopenharmony_ci   }
1151bf215546Sopenharmony_ci
1152bf215546Sopenharmony_ci   panvk_pool_init(&cmdbuf->desc_pool, &device->physical_device->pdev,
1153bf215546Sopenharmony_ci                   pool ? &pool->desc_bo_pool : NULL, 0, 64 * 1024,
1154bf215546Sopenharmony_ci                   "Command buffer descriptor pool", true);
1155bf215546Sopenharmony_ci   panvk_pool_init(&cmdbuf->tls_pool, &device->physical_device->pdev,
1156bf215546Sopenharmony_ci                   pool ? &pool->tls_bo_pool : NULL,
1157bf215546Sopenharmony_ci                   panvk_debug_adjust_bo_flags(device, PAN_BO_INVISIBLE),
1158bf215546Sopenharmony_ci                   64 * 1024, "TLS pool", false);
1159bf215546Sopenharmony_ci   panvk_pool_init(&cmdbuf->varying_pool, &device->physical_device->pdev,
1160bf215546Sopenharmony_ci                   pool ? &pool->varying_bo_pool : NULL,
1161bf215546Sopenharmony_ci                   panvk_debug_adjust_bo_flags(device, PAN_BO_INVISIBLE),
1162bf215546Sopenharmony_ci                   64 * 1024, "Varyings pool", false);
1163bf215546Sopenharmony_ci   list_inithead(&cmdbuf->batches);
1164bf215546Sopenharmony_ci   cmdbuf->status = PANVK_CMD_BUFFER_STATUS_INITIAL;
1165bf215546Sopenharmony_ci   *cmdbuf_out = cmdbuf;
1166bf215546Sopenharmony_ci   return VK_SUCCESS;
1167bf215546Sopenharmony_ci}
1168bf215546Sopenharmony_ci
1169bf215546Sopenharmony_ciVkResult
1170bf215546Sopenharmony_cipanvk_per_arch(AllocateCommandBuffers)(VkDevice _device,
1171bf215546Sopenharmony_ci                                       const VkCommandBufferAllocateInfo *pAllocateInfo,
1172bf215546Sopenharmony_ci                                       VkCommandBuffer *pCommandBuffers)
1173bf215546Sopenharmony_ci{
1174bf215546Sopenharmony_ci   VK_FROM_HANDLE(panvk_device, device, _device);
1175bf215546Sopenharmony_ci   VK_FROM_HANDLE(panvk_cmd_pool, pool, pAllocateInfo->commandPool);
1176bf215546Sopenharmony_ci
1177bf215546Sopenharmony_ci   VkResult result = VK_SUCCESS;
1178bf215546Sopenharmony_ci   unsigned i;
1179bf215546Sopenharmony_ci
1180bf215546Sopenharmony_ci   for (i = 0; i < pAllocateInfo->commandBufferCount; i++) {
1181bf215546Sopenharmony_ci      struct panvk_cmd_buffer *cmdbuf = NULL;
1182bf215546Sopenharmony_ci
1183bf215546Sopenharmony_ci      if (!list_is_empty(&pool->free_cmd_buffers)) {
1184bf215546Sopenharmony_ci         cmdbuf = list_first_entry(
1185bf215546Sopenharmony_ci            &pool->free_cmd_buffers, struct panvk_cmd_buffer, pool_link);
1186bf215546Sopenharmony_ci
1187bf215546Sopenharmony_ci         list_del(&cmdbuf->pool_link);
1188bf215546Sopenharmony_ci         list_addtail(&cmdbuf->pool_link, &pool->active_cmd_buffers);
1189bf215546Sopenharmony_ci
1190bf215546Sopenharmony_ci         vk_command_buffer_finish(&cmdbuf->vk);
1191bf215546Sopenharmony_ci         result = vk_command_buffer_init(&cmdbuf->vk, &pool->vk, pAllocateInfo->level);
1192bf215546Sopenharmony_ci      } else {
1193bf215546Sopenharmony_ci         result = panvk_create_cmdbuf(device, pool, pAllocateInfo->level, &cmdbuf);
1194bf215546Sopenharmony_ci      }
1195bf215546Sopenharmony_ci
1196bf215546Sopenharmony_ci      if (result != VK_SUCCESS)
1197bf215546Sopenharmony_ci         goto err_free_cmd_bufs;
1198bf215546Sopenharmony_ci
1199bf215546Sopenharmony_ci      pCommandBuffers[i] = panvk_cmd_buffer_to_handle(cmdbuf);
1200bf215546Sopenharmony_ci   }
1201bf215546Sopenharmony_ci
1202bf215546Sopenharmony_ci   return VK_SUCCESS;
1203bf215546Sopenharmony_ci
1204bf215546Sopenharmony_cierr_free_cmd_bufs:
1205bf215546Sopenharmony_ci   panvk_per_arch(FreeCommandBuffers)(_device, pAllocateInfo->commandPool, i,
1206bf215546Sopenharmony_ci                                      pCommandBuffers);
1207bf215546Sopenharmony_ci   for (unsigned j = 0; j < i; j++)
1208bf215546Sopenharmony_ci      pCommandBuffers[j] = VK_NULL_HANDLE;
1209bf215546Sopenharmony_ci
1210bf215546Sopenharmony_ci   return result;
1211bf215546Sopenharmony_ci}
1212bf215546Sopenharmony_ci
1213bf215546Sopenharmony_civoid
1214bf215546Sopenharmony_cipanvk_per_arch(FreeCommandBuffers)(VkDevice device,
1215bf215546Sopenharmony_ci                                   VkCommandPool commandPool,
1216bf215546Sopenharmony_ci                                   uint32_t commandBufferCount,
1217bf215546Sopenharmony_ci                                   const VkCommandBuffer *pCommandBuffers)
1218bf215546Sopenharmony_ci{
1219bf215546Sopenharmony_ci   for (uint32_t i = 0; i < commandBufferCount; i++) {
1220bf215546Sopenharmony_ci      VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, pCommandBuffers[i]);
1221bf215546Sopenharmony_ci
1222bf215546Sopenharmony_ci      if (cmdbuf) {
1223bf215546Sopenharmony_ci         if (cmdbuf->pool) {
1224bf215546Sopenharmony_ci            list_del(&cmdbuf->pool_link);
1225bf215546Sopenharmony_ci            panvk_reset_cmdbuf(cmdbuf);
1226bf215546Sopenharmony_ci            list_addtail(&cmdbuf->pool_link,
1227bf215546Sopenharmony_ci                         &cmdbuf->pool->free_cmd_buffers);
1228bf215546Sopenharmony_ci         } else
1229bf215546Sopenharmony_ci            panvk_destroy_cmdbuf(cmdbuf);
1230bf215546Sopenharmony_ci      }
1231bf215546Sopenharmony_ci   }
1232bf215546Sopenharmony_ci}
1233bf215546Sopenharmony_ci
1234bf215546Sopenharmony_ciVkResult
1235bf215546Sopenharmony_cipanvk_per_arch(ResetCommandBuffer)(VkCommandBuffer commandBuffer,
1236bf215546Sopenharmony_ci                                   VkCommandBufferResetFlags flags)
1237bf215546Sopenharmony_ci{
1238bf215546Sopenharmony_ci   VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
1239bf215546Sopenharmony_ci
1240bf215546Sopenharmony_ci   return panvk_reset_cmdbuf(cmdbuf);
1241bf215546Sopenharmony_ci}
1242bf215546Sopenharmony_ci
1243bf215546Sopenharmony_ciVkResult
1244bf215546Sopenharmony_cipanvk_per_arch(BeginCommandBuffer)(VkCommandBuffer commandBuffer,
1245bf215546Sopenharmony_ci                                   const VkCommandBufferBeginInfo *pBeginInfo)
1246bf215546Sopenharmony_ci{
1247bf215546Sopenharmony_ci   VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
1248bf215546Sopenharmony_ci   VkResult result = VK_SUCCESS;
1249bf215546Sopenharmony_ci
1250bf215546Sopenharmony_ci   if (cmdbuf->status != PANVK_CMD_BUFFER_STATUS_INITIAL) {
1251bf215546Sopenharmony_ci      /* If the command buffer has already been reset with
1252bf215546Sopenharmony_ci       * vkResetCommandBuffer, no need to do it again.
1253bf215546Sopenharmony_ci       */
1254bf215546Sopenharmony_ci      result = panvk_reset_cmdbuf(cmdbuf);
1255bf215546Sopenharmony_ci      if (result != VK_SUCCESS)
1256bf215546Sopenharmony_ci         return result;
1257bf215546Sopenharmony_ci   }
1258bf215546Sopenharmony_ci
1259bf215546Sopenharmony_ci   memset(&cmdbuf->state, 0, sizeof(cmdbuf->state));
1260bf215546Sopenharmony_ci
1261bf215546Sopenharmony_ci   cmdbuf->status = PANVK_CMD_BUFFER_STATUS_RECORDING;
1262bf215546Sopenharmony_ci
1263bf215546Sopenharmony_ci   return VK_SUCCESS;
1264bf215546Sopenharmony_ci}
1265bf215546Sopenharmony_ci
1266bf215546Sopenharmony_civoid
1267bf215546Sopenharmony_cipanvk_per_arch(DestroyCommandPool)(VkDevice _device,
1268bf215546Sopenharmony_ci                                   VkCommandPool commandPool,
1269bf215546Sopenharmony_ci                                   const VkAllocationCallbacks *pAllocator)
1270bf215546Sopenharmony_ci{
1271bf215546Sopenharmony_ci   VK_FROM_HANDLE(panvk_device, device, _device);
1272bf215546Sopenharmony_ci   VK_FROM_HANDLE(panvk_cmd_pool, pool, commandPool);
1273bf215546Sopenharmony_ci
1274bf215546Sopenharmony_ci   list_for_each_entry_safe(struct panvk_cmd_buffer, cmdbuf,
1275bf215546Sopenharmony_ci                            &pool->active_cmd_buffers, pool_link)
1276bf215546Sopenharmony_ci      panvk_destroy_cmdbuf(cmdbuf);
1277bf215546Sopenharmony_ci
1278bf215546Sopenharmony_ci   list_for_each_entry_safe(struct panvk_cmd_buffer, cmdbuf,
1279bf215546Sopenharmony_ci                            &pool->free_cmd_buffers, pool_link)
1280bf215546Sopenharmony_ci      panvk_destroy_cmdbuf(cmdbuf);
1281bf215546Sopenharmony_ci
1282bf215546Sopenharmony_ci   panvk_bo_pool_cleanup(&pool->desc_bo_pool);
1283bf215546Sopenharmony_ci   panvk_bo_pool_cleanup(&pool->varying_bo_pool);
1284bf215546Sopenharmony_ci   panvk_bo_pool_cleanup(&pool->tls_bo_pool);
1285bf215546Sopenharmony_ci
1286bf215546Sopenharmony_ci   vk_command_pool_finish(&pool->vk);
1287bf215546Sopenharmony_ci   vk_free2(&device->vk.alloc, pAllocator, pool);
1288bf215546Sopenharmony_ci}
1289bf215546Sopenharmony_ci
1290bf215546Sopenharmony_ciVkResult
1291bf215546Sopenharmony_cipanvk_per_arch(ResetCommandPool)(VkDevice device,
1292bf215546Sopenharmony_ci                                 VkCommandPool commandPool,
1293bf215546Sopenharmony_ci                                 VkCommandPoolResetFlags flags)
1294bf215546Sopenharmony_ci{
1295bf215546Sopenharmony_ci   VK_FROM_HANDLE(panvk_cmd_pool, pool, commandPool);
1296bf215546Sopenharmony_ci   VkResult result;
1297bf215546Sopenharmony_ci
1298bf215546Sopenharmony_ci   list_for_each_entry(struct panvk_cmd_buffer, cmdbuf, &pool->active_cmd_buffers,
1299bf215546Sopenharmony_ci                       pool_link)
1300bf215546Sopenharmony_ci   {
1301bf215546Sopenharmony_ci      result = panvk_reset_cmdbuf(cmdbuf);
1302bf215546Sopenharmony_ci      if (result != VK_SUCCESS)
1303bf215546Sopenharmony_ci         return result;
1304bf215546Sopenharmony_ci   }
1305bf215546Sopenharmony_ci
1306bf215546Sopenharmony_ci   return VK_SUCCESS;
1307bf215546Sopenharmony_ci}
1308bf215546Sopenharmony_ci
1309bf215546Sopenharmony_civoid
1310bf215546Sopenharmony_cipanvk_per_arch(TrimCommandPool)(VkDevice device,
1311bf215546Sopenharmony_ci                                VkCommandPool commandPool,
1312bf215546Sopenharmony_ci                                VkCommandPoolTrimFlags flags)
1313bf215546Sopenharmony_ci{
1314bf215546Sopenharmony_ci   VK_FROM_HANDLE(panvk_cmd_pool, pool, commandPool);
1315bf215546Sopenharmony_ci
1316bf215546Sopenharmony_ci   if (!pool)
1317bf215546Sopenharmony_ci      return;
1318bf215546Sopenharmony_ci
1319bf215546Sopenharmony_ci   list_for_each_entry_safe(struct panvk_cmd_buffer, cmdbuf,
1320bf215546Sopenharmony_ci                            &pool->free_cmd_buffers, pool_link)
1321bf215546Sopenharmony_ci      panvk_destroy_cmdbuf(cmdbuf);
1322bf215546Sopenharmony_ci}
1323bf215546Sopenharmony_ci
1324bf215546Sopenharmony_civoid
1325bf215546Sopenharmony_cipanvk_per_arch(CmdDispatch)(VkCommandBuffer commandBuffer,
1326bf215546Sopenharmony_ci                            uint32_t x,
1327bf215546Sopenharmony_ci                            uint32_t y,
1328bf215546Sopenharmony_ci                            uint32_t z)
1329bf215546Sopenharmony_ci{
1330bf215546Sopenharmony_ci   VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
1331bf215546Sopenharmony_ci   const struct panfrost_device *pdev =
1332bf215546Sopenharmony_ci      &cmdbuf->device->physical_device->pdev;
1333bf215546Sopenharmony_ci   struct panvk_dispatch_info dispatch = {
1334bf215546Sopenharmony_ci      .wg_count = { x, y, z },
1335bf215546Sopenharmony_ci   };
1336bf215546Sopenharmony_ci
1337bf215546Sopenharmony_ci   panvk_per_arch(cmd_close_batch)(cmdbuf);
1338bf215546Sopenharmony_ci   struct panvk_batch *batch = panvk_cmd_open_batch(cmdbuf);
1339bf215546Sopenharmony_ci
1340bf215546Sopenharmony_ci   struct panvk_cmd_bind_point_state *bind_point_state =
1341bf215546Sopenharmony_ci      panvk_cmd_get_bind_point_state(cmdbuf, COMPUTE);
1342bf215546Sopenharmony_ci   struct panvk_descriptor_state *desc_state = &bind_point_state->desc_state;
1343bf215546Sopenharmony_ci   const struct panvk_pipeline *pipeline = bind_point_state->pipeline;
1344bf215546Sopenharmony_ci   struct panfrost_ptr job =
1345bf215546Sopenharmony_ci      pan_pool_alloc_desc(&cmdbuf->desc_pool.base, COMPUTE_JOB);
1346bf215546Sopenharmony_ci
1347bf215546Sopenharmony_ci   struct panvk_sysvals *sysvals = &desc_state->sysvals;
1348bf215546Sopenharmony_ci   sysvals->num_work_groups.u32[0] = x;
1349bf215546Sopenharmony_ci   sysvals->num_work_groups.u32[1] = y;
1350bf215546Sopenharmony_ci   sysvals->num_work_groups.u32[2] = z;
1351bf215546Sopenharmony_ci   sysvals->local_group_size.u32[0] = pipeline->cs.local_size.x;
1352bf215546Sopenharmony_ci   sysvals->local_group_size.u32[1] = pipeline->cs.local_size.y;
1353bf215546Sopenharmony_ci   sysvals->local_group_size.u32[2] = pipeline->cs.local_size.z;
1354bf215546Sopenharmony_ci   desc_state->sysvals_ptr = 0;
1355bf215546Sopenharmony_ci
1356bf215546Sopenharmony_ci   panvk_per_arch(cmd_alloc_tls_desc)(cmdbuf, false);
1357bf215546Sopenharmony_ci   dispatch.tsd = batch->tls.gpu;
1358bf215546Sopenharmony_ci
1359bf215546Sopenharmony_ci   panvk_prepare_non_vs_attribs(cmdbuf, bind_point_state);
1360bf215546Sopenharmony_ci   dispatch.attributes = desc_state->non_vs_attribs;
1361bf215546Sopenharmony_ci   dispatch.attribute_bufs = desc_state->non_vs_attrib_bufs;
1362bf215546Sopenharmony_ci
1363bf215546Sopenharmony_ci   panvk_cmd_prepare_ubos(cmdbuf, bind_point_state);
1364bf215546Sopenharmony_ci   dispatch.ubos = desc_state->ubos;
1365bf215546Sopenharmony_ci
1366bf215546Sopenharmony_ci   panvk_cmd_prepare_textures(cmdbuf, bind_point_state);
1367bf215546Sopenharmony_ci   dispatch.textures = desc_state->textures;
1368bf215546Sopenharmony_ci
1369bf215546Sopenharmony_ci   panvk_cmd_prepare_samplers(cmdbuf, bind_point_state);
1370bf215546Sopenharmony_ci   dispatch.samplers = desc_state->samplers;
1371bf215546Sopenharmony_ci
1372bf215546Sopenharmony_ci   panvk_per_arch(emit_compute_job)(pipeline, &dispatch, job.cpu);
1373bf215546Sopenharmony_ci   panfrost_add_job(&cmdbuf->desc_pool.base, &batch->scoreboard,
1374bf215546Sopenharmony_ci                    MALI_JOB_TYPE_COMPUTE, false, false, 0, 0,
1375bf215546Sopenharmony_ci                    &job, false);
1376bf215546Sopenharmony_ci
1377bf215546Sopenharmony_ci   batch->tlsinfo.tls.size = pipeline->tls_size;
1378bf215546Sopenharmony_ci   batch->tlsinfo.wls.size = pipeline->wls_size;
1379bf215546Sopenharmony_ci   if (batch->tlsinfo.wls.size) {
1380bf215546Sopenharmony_ci      batch->wls_total_size =
1381bf215546Sopenharmony_ci         pan_wls_mem_size(pdev, &dispatch.wg_count, batch->tlsinfo.wls.size);
1382bf215546Sopenharmony_ci   }
1383bf215546Sopenharmony_ci
1384bf215546Sopenharmony_ci   panvk_per_arch(cmd_close_batch)(cmdbuf);
1385bf215546Sopenharmony_ci   desc_state->dirty = 0;
1386bf215546Sopenharmony_ci}
1387