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