From 595d362d4bc739837eae560e07ad585cd7e2cb8a Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Fri, 15 Dec 2023 14:39:18 +0100 Subject: [PATCH] panvk: Implement dynamic rendering entry points Implement dynamic rendering entry points so we can get rid of the render pass logic. Signed-off-by: Boris Brezillon Reviewed-by: Erik Faye-Lund Part-of: --- src/panfrost/vulkan/meson.build | 1 - src/panfrost/vulkan/panvk_cmd_buffer.c | 134 ------------- src/panfrost/vulkan/panvk_pass.c | 224 ---------------------- src/panfrost/vulkan/panvk_private.h | 77 +------- src/panfrost/vulkan/panvk_vX_cmd_buffer.c | 198 +++++++++++++------ src/panfrost/vulkan/panvk_vX_device.c | 25 +-- src/panfrost/vulkan/panvk_vX_meta_clear.c | 26 ++- src/panfrost/vulkan/panvk_vX_pipeline.c | 15 +- 8 files changed, 178 insertions(+), 522 deletions(-) delete mode 100644 src/panfrost/vulkan/panvk_pass.c diff --git a/src/panfrost/vulkan/meson.build b/src/panfrost/vulkan/meson.build index b8aef3ace3f..7ea27333740 100644 --- a/src/panfrost/vulkan/meson.build +++ b/src/panfrost/vulkan/meson.build @@ -42,7 +42,6 @@ libpanvk_files = files( 'panvk_formats.c', 'panvk_image.c', 'panvk_mempool.c', - 'panvk_pass.c', 'panvk_pipeline.c', 'panvk_private.h', 'panvk_query.c', diff --git a/src/panfrost/vulkan/panvk_cmd_buffer.c b/src/panfrost/vulkan/panvk_cmd_buffer.c index 84c6e82783f..61987c30eaa 100644 --- a/src/panfrost/vulkan/panvk_cmd_buffer.c +++ b/src/panfrost/vulkan/panvk_cmd_buffer.c @@ -388,140 +388,6 @@ panvk_CreateCommandPool(VkDevice _device, return VK_SUCCESS; } -static void -panvk_cmd_prepare_clear_values(struct panvk_cmd_buffer *cmdbuf, - const VkClearValue *in) -{ - for (unsigned i = 0; i < cmdbuf->state.pass->attachment_count; i++) { - const struct panvk_render_pass_attachment *attachment = - &cmdbuf->state.pass->attachments[i]; - enum pipe_format fmt = attachment->format; - - if (util_format_is_depth_or_stencil(fmt)) { - if (attachment->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR || - attachment->stencil_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) { - cmdbuf->state.clear[i].depth = in[i].depthStencil.depth; - cmdbuf->state.clear[i].stencil = in[i].depthStencil.stencil; - } else { - cmdbuf->state.clear[i].depth = 0; - cmdbuf->state.clear[i].stencil = 0; - } - } else { - if (attachment->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) { - union pipe_color_union *col = - (union pipe_color_union *)&in[i].color; - pan_pack_color(panfrost_blendable_formats_v7, - cmdbuf->state.clear[i].color, col, fmt, false); - } else { - memset(cmdbuf->state.clear[i].color, 0, - sizeof(cmdbuf->state.clear[0].color)); - } - } - } -} - -void -panvk_cmd_fb_info_set_subpass(struct panvk_cmd_buffer *cmdbuf) -{ - const struct panvk_subpass *subpass = cmdbuf->state.subpass; - struct pan_fb_info *fbinfo = &cmdbuf->state.fb.info; - const struct vk_framebuffer *fb = cmdbuf->state.framebuffer; - const struct panvk_clear_value *clears = cmdbuf->state.clear; - - fbinfo->nr_samples = 1; - fbinfo->rt_count = subpass->color_count; - memset(&fbinfo->bifrost.pre_post.dcds, 0, - sizeof(fbinfo->bifrost.pre_post.dcds)); - - for (unsigned cb = 0; cb < subpass->color_count; cb++) { - int idx = subpass->color_attachments[cb].idx; - - if (idx == VK_ATTACHMENT_UNUSED) - continue; - - VK_FROM_HANDLE(panvk_image_view, view, fb->attachments[idx]); - - fbinfo->rts[cb].view = &view->pview; - fbinfo->rts[cb].clear = subpass->color_attachments[cb].clear; - fbinfo->rts[cb].preload = subpass->color_attachments[cb].preload; - fbinfo->rts[cb].crc_valid = &cmdbuf->state.fb.crc_valid[cb]; - - memcpy(fbinfo->rts[cb].clear_value, clears[idx].color, - sizeof(fbinfo->rts[cb].clear_value)); - fbinfo->nr_samples = - MAX2(fbinfo->nr_samples, pan_image_view_get_nr_samples(&view->pview)); - } - - if (subpass->zs_attachment.idx != VK_ATTACHMENT_UNUSED) { - VK_FROM_HANDLE(panvk_image_view, view, - fb->attachments[subpass->zs_attachment.idx]); - const struct util_format_description *fdesc = - util_format_description(view->pview.format); - - fbinfo->nr_samples = - MAX2(fbinfo->nr_samples, pan_image_view_get_nr_samples(&view->pview)); - - if (util_format_has_depth(fdesc)) { - fbinfo->zs.clear.z = subpass->zs_attachment.clear; - fbinfo->zs.clear_value.depth = - clears[subpass->zs_attachment.idx].depth; - fbinfo->zs.view.zs = &view->pview; - } - - if (util_format_has_stencil(fdesc)) { - fbinfo->zs.clear.s = subpass->zs_attachment.clear; - fbinfo->zs.clear_value.stencil = - clears[subpass->zs_attachment.idx].stencil; - if (!fbinfo->zs.view.zs) - fbinfo->zs.view.s = &view->pview; - } - } -} - -void -panvk_cmd_fb_info_init(struct panvk_cmd_buffer *cmdbuf) -{ - struct panvk_device *dev = to_panvk_device(cmdbuf->vk.base.device); - struct panvk_physical_device *phys_dev = - to_panvk_physical_device(dev->vk.physical); - struct pan_fb_info *fbinfo = &cmdbuf->state.fb.info; - const struct vk_framebuffer *fb = cmdbuf->state.framebuffer; - - memset(cmdbuf->state.fb.crc_valid, 0, sizeof(cmdbuf->state.fb.crc_valid)); - - *fbinfo = (struct pan_fb_info){ - .tile_buf_budget = panfrost_query_optimal_tib_size(phys_dev->model), - .width = fb->width, - .height = fb->height, - .extent.maxx = fb->width - 1, - .extent.maxy = fb->height - 1, - }; -} - -VKAPI_ATTR void VKAPI_CALL -panvk_CmdBeginRenderPass2(VkCommandBuffer commandBuffer, - const VkRenderPassBeginInfo *pRenderPassBegin, - const VkSubpassBeginInfo *pSubpassBeginInfo) -{ - VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer); - VK_FROM_HANDLE(panvk_render_pass, pass, pRenderPassBegin->renderPass); - VK_FROM_HANDLE(vk_framebuffer, fb, pRenderPassBegin->framebuffer); - - cmdbuf->state.pass = pass; - cmdbuf->state.subpass = pass->subpasses; - cmdbuf->state.framebuffer = fb; - cmdbuf->state.render_area = pRenderPassBegin->renderArea; - panvk_cmd_open_batch(cmdbuf); - assert(pRenderPassBegin->clearValueCount <= pass->attachment_count); - cmdbuf->state.clear = - vk_zalloc(&cmdbuf->vk.pool->alloc, - sizeof(*cmdbuf->state.clear) * pass->attachment_count, 8, - VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); - panvk_cmd_prepare_clear_values(cmdbuf, pRenderPassBegin->pClearValues); - panvk_cmd_fb_info_init(cmdbuf); - panvk_cmd_fb_info_set_subpass(cmdbuf); -} - void panvk_cmd_preload_fb_after_batch_split(struct panvk_cmd_buffer *cmdbuf) { diff --git a/src/panfrost/vulkan/panvk_pass.c b/src/panfrost/vulkan/panvk_pass.c deleted file mode 100644 index d9f24de1239..00000000000 --- a/src/panfrost/vulkan/panvk_pass.c +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Copyright © 2021 Collabora Ltd. - * - * Derived from tu_pass.c which is: - * Copyright © 2016 Red Hat. - * Copyright © 2016 Bas Nieuwenhuizen - * Copyright © 2015 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ -#include "panvk_private.h" - -#include "vk_format.h" -#include "vk_util.h" - -VKAPI_ATTR VkResult VKAPI_CALL -panvk_CreateRenderPass2(VkDevice _device, - const VkRenderPassCreateInfo2 *pCreateInfo, - const VkAllocationCallbacks *pAllocator, - VkRenderPass *pRenderPass) -{ - VK_FROM_HANDLE(panvk_device, device, _device); - struct panvk_render_pass *pass; - size_t size; - size_t attachments_offset; - VkRenderPassMultiviewCreateInfo *multiview_info = NULL; - - assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2); - - size = sizeof(*pass); - size += pCreateInfo->subpassCount * sizeof(pass->subpasses[0]); - attachments_offset = size; - size += pCreateInfo->attachmentCount * sizeof(pass->attachments[0]); - - pass = vk_object_zalloc(&device->vk, pAllocator, size, - VK_OBJECT_TYPE_RENDER_PASS); - if (pass == NULL) - return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); - - pass->attachment_count = pCreateInfo->attachmentCount; - pass->subpass_count = pCreateInfo->subpassCount; - pass->attachments = (void *)pass + attachments_offset; - - vk_foreach_struct_const(ext, pCreateInfo->pNext) { - switch (ext->sType) { - case VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO: - multiview_info = (VkRenderPassMultiviewCreateInfo *)ext; - break; - default: - break; - } - } - - for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) { - struct panvk_render_pass_attachment *att = &pass->attachments[i]; - - att->format = - vk_format_to_pipe_format(pCreateInfo->pAttachments[i].format); - att->samples = pCreateInfo->pAttachments[i].samples; - att->load_op = pCreateInfo->pAttachments[i].loadOp; - att->stencil_load_op = pCreateInfo->pAttachments[i].stencilLoadOp; - att->initial_layout = pCreateInfo->pAttachments[i].initialLayout; - att->final_layout = pCreateInfo->pAttachments[i].finalLayout; - att->store_op = pCreateInfo->pAttachments[i].storeOp; - att->stencil_store_op = pCreateInfo->pAttachments[i].stencilStoreOp; - att->first_used_in_subpass = ~0; - } - - uint32_t subpass_attachment_count = 0; - struct panvk_subpass_attachment *p; - for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) { - const VkSubpassDescription2 *desc = &pCreateInfo->pSubpasses[i]; - - subpass_attachment_count += - desc->inputAttachmentCount + desc->colorAttachmentCount + - (desc->pResolveAttachments ? desc->colorAttachmentCount : 0) + - (desc->pDepthStencilAttachment != NULL); - } - - if (subpass_attachment_count) { - pass->subpass_attachments = vk_alloc2( - &device->vk.alloc, pAllocator, - subpass_attachment_count * sizeof(struct panvk_subpass_attachment), 8, - VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); - if (pass->subpass_attachments == NULL) { - vk_object_free(&device->vk, pAllocator, pass); - return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); - } - } - - p = pass->subpass_attachments; - for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) { - const VkSubpassDescription2 *desc = &pCreateInfo->pSubpasses[i]; - struct panvk_subpass *subpass = &pass->subpasses[i]; - - subpass->input_count = desc->inputAttachmentCount; - subpass->color_count = desc->colorAttachmentCount; - if (multiview_info) - subpass->view_mask = multiview_info->pViewMasks[i]; - - if (desc->inputAttachmentCount > 0) { - subpass->input_attachments = p; - p += desc->inputAttachmentCount; - - for (uint32_t j = 0; j < desc->inputAttachmentCount; j++) { - subpass->input_attachments[j] = (struct panvk_subpass_attachment){ - .idx = desc->pInputAttachments[j].attachment, - .layout = desc->pInputAttachments[j].layout, - }; - if (desc->pInputAttachments[j].attachment != VK_ATTACHMENT_UNUSED) - pass->attachments[desc->pInputAttachments[j].attachment] - .view_mask |= subpass->view_mask; - } - } - - if (desc->colorAttachmentCount > 0) { - subpass->color_attachments = p; - p += desc->colorAttachmentCount; - - for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) { - uint32_t idx = desc->pColorAttachments[j].attachment; - - subpass->color_attachments[j] = (struct panvk_subpass_attachment){ - .idx = idx, - .layout = desc->pColorAttachments[j].layout, - }; - - if (idx != VK_ATTACHMENT_UNUSED) { - pass->attachments[idx].view_mask |= subpass->view_mask; - if (pass->attachments[idx].first_used_in_subpass == ~0) { - pass->attachments[idx].first_used_in_subpass = i; - if (pass->attachments[idx].load_op == - VK_ATTACHMENT_LOAD_OP_CLEAR) - subpass->color_attachments[j].clear = true; - else if (pass->attachments[idx].load_op == - VK_ATTACHMENT_LOAD_OP_LOAD) - subpass->color_attachments[j].preload = true; - } else { - subpass->color_attachments[j].preload = true; - } - } - } - } - - if (desc->pResolveAttachments) { - subpass->resolve_attachments = p; - p += desc->colorAttachmentCount; - - for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) { - uint32_t idx = desc->pResolveAttachments[j].attachment; - - subpass->resolve_attachments[j] = (struct panvk_subpass_attachment){ - .idx = idx, - .layout = desc->pResolveAttachments[j].layout, - }; - - if (idx != VK_ATTACHMENT_UNUSED) - pass->attachments[idx].view_mask |= subpass->view_mask; - } - } - - unsigned idx = desc->pDepthStencilAttachment - ? desc->pDepthStencilAttachment->attachment - : VK_ATTACHMENT_UNUSED; - subpass->zs_attachment.idx = idx; - if (idx != VK_ATTACHMENT_UNUSED) { - subpass->zs_attachment.layout = desc->pDepthStencilAttachment->layout; - pass->attachments[idx].view_mask |= subpass->view_mask; - - if (pass->attachments[idx].first_used_in_subpass == ~0) { - pass->attachments[idx].first_used_in_subpass = i; - if (pass->attachments[idx].load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) - subpass->zs_attachment.clear = true; - else if (pass->attachments[idx].load_op == - VK_ATTACHMENT_LOAD_OP_LOAD) - subpass->zs_attachment.preload = true; - } else { - subpass->zs_attachment.preload = true; - } - } - } - - *pRenderPass = panvk_render_pass_to_handle(pass); - return VK_SUCCESS; -} - -VKAPI_ATTR void VKAPI_CALL -panvk_DestroyRenderPass(VkDevice _device, VkRenderPass _pass, - const VkAllocationCallbacks *pAllocator) -{ - VK_FROM_HANDLE(panvk_device, device, _device); - VK_FROM_HANDLE(panvk_render_pass, pass, _pass); - - if (!pass) - return; - - vk_free2(&device->vk.alloc, pAllocator, pass->subpass_attachments); - vk_object_free(&device->vk, pAllocator, pass); -} - -VKAPI_ATTR void VKAPI_CALL -panvk_GetRenderAreaGranularity(VkDevice _device, VkRenderPass renderPass, - VkExtent2D *pGranularity) -{ - /* TODO: Return the actual tile size for the render pass? */ - *pGranularity = (VkExtent2D){1, 1}; -} diff --git a/src/panfrost/vulkan/panvk_private.h b/src/panfrost/vulkan/panvk_private.h index 55aee3cb2ca..a014828f0da 100644 --- a/src/panfrost/vulkan/panvk_private.h +++ b/src/panfrost/vulkan/panvk_private.h @@ -312,8 +312,11 @@ struct panvk_batch { struct util_dynarray event_ops; struct pan_jc jc; struct { - const struct vk_framebuffer *info; struct panfrost_ptr desc; + uint32_t bo_count; + + /* One slot per color, two more slots for the depth/stencil buffers. */ + struct pan_kmod_bo *bos[MAX_RTS + 2]; } fb; struct { struct pan_kmod_bo *src, *dst; @@ -757,15 +760,10 @@ struct panvk_cmd_state { struct { struct pan_fb_info info; bool crc_valid[MAX_RTS]; + uint32_t bo_count; + struct pan_kmod_bo *bos[MAX_RTS + 2]; } fb; - const struct panvk_render_pass *pass; - const struct panvk_subpass *subpass; - const struct vk_framebuffer *framebuffer; - VkRect2D render_area; - - struct panvk_clear_value *clear; - mali_ptr vpd; VkViewport viewport; VkRect2D scissor; @@ -811,10 +809,6 @@ struct panvk_cmd_buffer { struct panvk_batch *panvk_cmd_open_batch(struct panvk_cmd_buffer *cmdbuf); -void panvk_cmd_fb_info_set_subpass(struct panvk_cmd_buffer *cmdbuf); - -void panvk_cmd_fb_info_init(struct panvk_cmd_buffer *cmdbuf); - void panvk_cmd_preload_fb_after_batch_split(struct panvk_cmd_buffer *cmdbuf); struct panvk_event { @@ -992,63 +986,6 @@ struct panvk_buffer_view { } descs; }; -struct panvk_attachment_info { - struct panvk_image_view *iview; -}; - -struct panvk_clear_value { - union { - uint32_t color[4]; - struct { - float depth; - uint8_t stencil; - }; - }; -}; - -struct panvk_subpass_attachment { - uint32_t idx; - VkImageLayout layout; - bool clear; - bool preload; -}; - -struct panvk_subpass { - uint32_t input_count; - uint32_t color_count; - struct panvk_subpass_attachment *input_attachments; - uint8_t active_color_attachments; - struct panvk_subpass_attachment *color_attachments; - struct panvk_subpass_attachment *resolve_attachments; - struct panvk_subpass_attachment zs_attachment; - - uint32_t view_mask; -}; - -struct panvk_render_pass_attachment { - VkAttachmentDescriptionFlags flags; - enum pipe_format format; - unsigned samples; - VkAttachmentLoadOp load_op; - VkAttachmentStoreOp store_op; - VkAttachmentLoadOp stencil_load_op; - VkAttachmentStoreOp stencil_store_op; - VkImageLayout initial_layout; - VkImageLayout final_layout; - unsigned view_mask; - unsigned first_used_in_subpass; -}; - -struct panvk_render_pass { - struct vk_object_base base; - - uint32_t attachment_count; - uint32_t subpass_count; - struct panvk_subpass_attachment *subpass_attachments; - struct panvk_render_pass_attachment *attachments; - struct panvk_subpass subpasses[0]; -}; - VK_DEFINE_HANDLE_CASTS(panvk_cmd_buffer, vk.base, VkCommandBuffer, VK_OBJECT_TYPE_COMMAND_BUFFER) VK_DEFINE_HANDLE_CASTS(panvk_device, vk.base, VkDevice, VK_OBJECT_TYPE_DEVICE) @@ -1082,8 +1019,6 @@ VK_DEFINE_NONDISP_HANDLE_CASTS(panvk_pipeline, base, VkPipeline, VK_OBJECT_TYPE_PIPELINE) VK_DEFINE_NONDISP_HANDLE_CASTS(panvk_pipeline_layout, vk.base, VkPipelineLayout, VK_OBJECT_TYPE_PIPELINE_LAYOUT) -VK_DEFINE_NONDISP_HANDLE_CASTS(panvk_render_pass, base, VkRenderPass, - VK_OBJECT_TYPE_RENDER_PASS) VK_DEFINE_NONDISP_HANDLE_CASTS(panvk_sampler, vk.base, VkSampler, VK_OBJECT_TYPE_SAMPLER) diff --git a/src/panfrost/vulkan/panvk_vX_cmd_buffer.c b/src/panfrost/vulkan/panvk_vX_cmd_buffer.c index d7823b5b3b3..b5fddbb4377 100644 --- a/src/panfrost/vulkan/panvk_vX_cmd_buffer.c +++ b/src/panfrost/vulkan/panvk_vX_cmd_buffer.c @@ -158,32 +158,6 @@ panvk_per_arch(cmd_close_batch)(struct panvk_cmd_buffer *cmdbuf) cmdbuf->state.batch = NULL; } -VKAPI_ATTR void VKAPI_CALL -panvk_per_arch(CmdNextSubpass2)(VkCommandBuffer commandBuffer, - const VkSubpassBeginInfo *pSubpassBeginInfo, - const VkSubpassEndInfo *pSubpassEndInfo) -{ - VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer); - - panvk_per_arch(cmd_close_batch)(cmdbuf); - - cmdbuf->state.subpass++; - panvk_cmd_fb_info_set_subpass(cmdbuf); - panvk_cmd_open_batch(cmdbuf); -} - -VKAPI_ATTR void VKAPI_CALL -panvk_per_arch(CmdNextSubpass)(VkCommandBuffer cmd, VkSubpassContents contents) -{ - VkSubpassBeginInfo binfo = {.sType = VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO, - .contents = contents}; - VkSubpassEndInfo einfo = { - .sType = VK_STRUCTURE_TYPE_SUBPASS_END_INFO, - }; - - panvk_per_arch(CmdNextSubpass2)(cmd, &binfo, &einfo); -} - void panvk_per_arch(cmd_alloc_fb_desc)(struct panvk_cmd_buffer *cmdbuf) { @@ -195,7 +169,9 @@ panvk_per_arch(cmd_alloc_fb_desc)(struct panvk_cmd_buffer *cmdbuf) const struct pan_fb_info *fbinfo = &cmdbuf->state.fb.info; bool has_zs_ext = fbinfo->zs.view.zs || fbinfo->zs.view.s; - batch->fb.info = cmdbuf->state.framebuffer; + batch->fb.bo_count = cmdbuf->state.fb.bo_count; + memcpy(batch->fb.bos, cmdbuf->state.fb.bos, + batch->fb.bo_count * sizeof(batch->fb.bos[0])); batch->fb.desc = pan_pool_alloc_desc_aggregate( &cmdbuf->desc_pool.base, PAN_DESC(FRAMEBUFFER), PAN_DESC_ARRAY(has_zs_ext ? 1 : 0, ZS_CRC_EXTENSION), @@ -909,31 +885,6 @@ panvk_per_arch(EndCommandBuffer)(VkCommandBuffer commandBuffer) return vk_command_buffer_end(&cmdbuf->vk); } -VKAPI_ATTR void VKAPI_CALL -panvk_per_arch(CmdEndRenderPass2)(VkCommandBuffer commandBuffer, - const VkSubpassEndInfo *pSubpassEndInfo) -{ - VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer); - - panvk_per_arch(cmd_close_batch)(cmdbuf); - vk_free(&cmdbuf->vk.pool->alloc, cmdbuf->state.clear); - cmdbuf->state.batch = NULL; - cmdbuf->state.pass = NULL; - cmdbuf->state.subpass = NULL; - cmdbuf->state.framebuffer = NULL; - cmdbuf->state.clear = NULL; -} - -VKAPI_ATTR void VKAPI_CALL -panvk_per_arch(CmdEndRenderPass)(VkCommandBuffer cmd) -{ - VkSubpassEndInfo einfo = { - .sType = VK_STRUCTURE_TYPE_SUBPASS_END_INFO, - }; - - panvk_per_arch(CmdEndRenderPass2)(cmd, &einfo); -} - VKAPI_ATTR void VKAPI_CALL panvk_per_arch(CmdPipelineBarrier2)(VkCommandBuffer commandBuffer, const VkDependencyInfo *pDependencyInfo) @@ -1020,7 +971,7 @@ panvk_per_arch(CmdSetEvent2)(VkCommandBuffer commandBuffer, VkEvent _event, VK_FROM_HANDLE(panvk_event, event, _event); /* vkCmdSetEvent cannot be called inside a render pass */ - assert(cmdbuf->state.pass == NULL); + assert(cmdbuf->vk.render_pass == NULL); panvk_add_set_event_operation(cmdbuf, event, PANVK_EVENT_OP_SET); } @@ -1033,7 +984,7 @@ panvk_per_arch(CmdResetEvent2)(VkCommandBuffer commandBuffer, VkEvent _event, VK_FROM_HANDLE(panvk_event, event, _event); /* vkCmdResetEvent cannot be called inside a render pass */ - assert(cmdbuf->state.pass == NULL); + assert(cmdbuf->vk.render_pass == NULL); panvk_add_set_event_operation(cmdbuf, event, PANVK_EVENT_OP_RESET); } @@ -1238,3 +1189,142 @@ panvk_per_arch(CmdDispatch)(VkCommandBuffer commandBuffer, uint32_t x, panvk_per_arch(cmd_close_batch)(cmdbuf); desc_state->dirty = 0; } + +static void +panvk_cmd_begin_rendering_init_fbinfo(struct panvk_cmd_buffer *cmdbuf, + const VkRenderingInfo *pRenderingInfo) +{ + struct panvk_device *dev = to_panvk_device(cmdbuf->vk.base.device); + struct panvk_physical_device *phys_dev = + to_panvk_physical_device(dev->vk.physical); + struct pan_fb_info *fbinfo = &cmdbuf->state.fb.info; + + cmdbuf->state.fb.bo_count = 0; + memset(cmdbuf->state.fb.bos, 0, sizeof(cmdbuf->state.fb.bos)); + memset(cmdbuf->state.fb.crc_valid, 0, sizeof(cmdbuf->state.fb.crc_valid)); + + *fbinfo = (struct pan_fb_info){ + .tile_buf_budget = panfrost_query_optimal_tib_size(phys_dev->model), + .nr_samples = 1, + .rt_count = pRenderingInfo->colorAttachmentCount, + }; + + assert(pRenderingInfo->colorAttachmentCount < ARRAY_SIZE(fbinfo->rts)); + + for (uint32_t i = 0; i < pRenderingInfo->colorAttachmentCount; i++) { + const VkRenderingAttachmentInfo *att = + &pRenderingInfo->pColorAttachments[i]; + VK_FROM_HANDLE(panvk_image_view, iview, att->imageView); + + if (!iview) + continue; + + struct panvk_image *img = + container_of(iview->vk.image, struct panvk_image, vk); + const VkExtent3D iview_size = + vk_image_mip_level_extent(&img->vk, iview->vk.base_mip_level); + + fbinfo->width = MAX2(iview_size.width, fbinfo->width); + fbinfo->height = MAX2(iview_size.height, fbinfo->height); + + cmdbuf->state.fb.bos[cmdbuf->state.fb.bo_count++] = img->bo; + fbinfo->rts[i].view = &iview->pview; + fbinfo->rts[i].crc_valid = &cmdbuf->state.fb.crc_valid[i]; + fbinfo->nr_samples = + MAX2(fbinfo->nr_samples, pan_image_view_get_nr_samples(&iview->pview)); + + if (att->loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR) { + enum pipe_format fmt = vk_format_to_pipe_format(iview->vk.format); + union pipe_color_union *col = + (union pipe_color_union *)&att->clearValue.color; + + fbinfo->rts[i].clear = true; + pan_pack_color(phys_dev->formats.blendable, fbinfo->rts[i].clear_value, + col, fmt, false); + } else if (att->loadOp == VK_ATTACHMENT_LOAD_OP_LOAD) { + fbinfo->rts[i].preload = true; + } + } + + if (pRenderingInfo->pDepthAttachment && + pRenderingInfo->pDepthAttachment->imageView != VK_NULL_HANDLE) { + const VkRenderingAttachmentInfo *att = pRenderingInfo->pDepthAttachment; + VK_FROM_HANDLE(panvk_image_view, iview, att->imageView); + struct panvk_image *img = + container_of(iview->vk.image, struct panvk_image, vk); + const VkExtent3D iview_size = + vk_image_mip_level_extent(&img->vk, iview->vk.base_mip_level); + + fbinfo->width = MAX2(iview_size.width, fbinfo->width); + fbinfo->height = MAX2(iview_size.height, fbinfo->height); + + cmdbuf->state.fb.bos[cmdbuf->state.fb.bo_count++] = img->bo; + fbinfo->zs.view.zs = &iview->pview; + + if (att->loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR) { + fbinfo->zs.clear.z = true; + fbinfo->zs.clear_value.depth = att->clearValue.depthStencil.depth; + } else if (att->loadOp == VK_ATTACHMENT_LOAD_OP_LOAD) { + fbinfo->zs.preload.z = true; + } + } + + if (pRenderingInfo->pStencilAttachment && + pRenderingInfo->pStencilAttachment->imageView != VK_NULL_HANDLE) { + const VkRenderingAttachmentInfo *att = pRenderingInfo->pStencilAttachment; + VK_FROM_HANDLE(panvk_image_view, iview, att->imageView); + struct panvk_image *img = + container_of(iview->vk.image, struct panvk_image, vk); + const VkExtent3D iview_size = + vk_image_mip_level_extent(&img->vk, iview->vk.base_mip_level); + + fbinfo->width = MAX2(iview_size.width, fbinfo->width); + fbinfo->height = MAX2(iview_size.height, fbinfo->height); + + cmdbuf->state.fb.bos[cmdbuf->state.fb.bo_count++] = img->bo; + fbinfo->zs.view.s = + iview && &iview->pview != fbinfo->zs.view.zs ? &iview->pview : NULL; + + if (iview && att->loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR) { + fbinfo->zs.clear.s = true; + fbinfo->zs.clear_value.stencil = att->clearValue.depthStencil.stencil; + } else if (att->loadOp == VK_ATTACHMENT_LOAD_OP_LOAD) { + fbinfo->zs.preload.s = true; + } + } + + /* We need the rendering area to be aligned on 32x32 section for tile buffer + * preloading to work correctly. + */ + fbinfo->width = + MIN2(fbinfo->width, ALIGN_POT(pRenderingInfo->renderArea.offset.x + + pRenderingInfo->renderArea.extent.width, + 32)); + fbinfo->height = MIN2(fbinfo->height, + ALIGN_POT(pRenderingInfo->renderArea.offset.y + + pRenderingInfo->renderArea.extent.height, + 32)); + assert(fbinfo->width && fbinfo->height); + + fbinfo->extent.maxx = fbinfo->width - 1; + fbinfo->extent.maxy = fbinfo->height - 1; +} + +VKAPI_ATTR void VKAPI_CALL +panvk_per_arch(CmdBeginRendering)(VkCommandBuffer commandBuffer, + const VkRenderingInfo *pRenderingInfo) +{ + VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer); + + panvk_cmd_begin_rendering_init_fbinfo(cmdbuf, pRenderingInfo); + panvk_cmd_open_batch(cmdbuf); +} + +VKAPI_ATTR void VKAPI_CALL +panvk_per_arch(CmdEndRendering)(VkCommandBuffer commandBuffer) +{ + VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer); + + panvk_per_arch(cmd_close_batch)(cmdbuf); + cmdbuf->state.batch = NULL; +} diff --git a/src/panfrost/vulkan/panvk_vX_device.c b/src/panfrost/vulkan/panvk_vX_device.c index bfd2c0fc462..85487db1c32 100644 --- a/src/panfrost/vulkan/panvk_vX_device.c +++ b/src/panfrost/vulkan/panvk_vX_device.c @@ -229,13 +229,12 @@ panvk_per_arch(queue_submit)(struct vk_queue *vk_queue, list_for_each_entry(struct panvk_batch, batch, &cmdbuf->batches, node) { /* FIXME: should be done at the batch level */ - unsigned nr_bos = - panvk_pool_num_bos(&cmdbuf->desc_pool) + - panvk_pool_num_bos(&cmdbuf->varying_pool) + - panvk_pool_num_bos(&cmdbuf->tls_pool) + - (batch->fb.info ? batch->fb.info->attachment_count : 0) + - (batch->blit.src ? 1 : 0) + (batch->blit.dst ? 1 : 0) + - (batch->jc.first_tiler ? 1 : 0) + 1; + unsigned nr_bos = panvk_pool_num_bos(&cmdbuf->desc_pool) + + panvk_pool_num_bos(&cmdbuf->varying_pool) + + panvk_pool_num_bos(&cmdbuf->tls_pool) + + batch->fb.bo_count + (batch->blit.src ? 1 : 0) + + (batch->blit.dst ? 1 : 0) + + (batch->jc.first_tiler ? 1 : 0) + 1; unsigned bo_idx = 0; uint32_t bos[nr_bos]; @@ -248,16 +247,8 @@ panvk_per_arch(queue_submit)(struct vk_queue *vk_queue, panvk_pool_get_bo_handles(&cmdbuf->tls_pool, &bos[bo_idx]); bo_idx += panvk_pool_num_bos(&cmdbuf->tls_pool); - if (batch->fb.info) { - for (unsigned i = 0; i < batch->fb.info->attachment_count; i++) { - VK_FROM_HANDLE(panvk_image_view, iview, - batch->fb.info->attachments[i]); - struct panvk_image *img = - container_of(iview->vk.image, struct panvk_image, vk); - - bos[bo_idx++] = pan_kmod_bo_handle(img->bo); - } - } + for (unsigned i = 0; i < batch->fb.bo_count; i++) + bos[bo_idx++] = pan_kmod_bo_handle(batch->fb.bos[i]); if (batch->blit.src) bos[bo_idx++] = pan_kmod_bo_handle(batch->blit.src); diff --git a/src/panfrost/vulkan/panvk_vX_meta_clear.c b/src/panfrost/vulkan/panvk_vX_meta_clear.c index 544483e6ad5..9f010190935 100644 --- a/src/panfrost/vulkan/panvk_vX_meta_clear.c +++ b/src/panfrost/vulkan/panvk_vX_meta_clear.c @@ -31,6 +31,7 @@ #include "panvk_vX_meta.h" #include "vk_format.h" +#include "vk_render_pass.h" static mali_ptr panvk_meta_clear_color_attachment_shader(struct panvk_device *dev, @@ -251,8 +252,7 @@ panvk_meta_get_format_type(enum pipe_format format) } static void -panvk_meta_clear_attachment(struct panvk_cmd_buffer *cmdbuf, - unsigned attachment, unsigned rt, +panvk_meta_clear_attachment(struct panvk_cmd_buffer *cmdbuf, unsigned rt, VkImageAspectFlags mask, const VkClearValue *clear_value, const VkClearRect *clear_rect) @@ -260,9 +260,7 @@ panvk_meta_clear_attachment(struct panvk_cmd_buffer *cmdbuf, struct panvk_device *dev = to_panvk_device(cmdbuf->vk.base.device); struct panvk_meta *meta = &dev->meta; struct panvk_batch *batch = cmdbuf->state.batch; - const struct panvk_render_pass *pass = cmdbuf->state.pass; - const struct panvk_render_pass_attachment *att = - &pass->attachments[attachment]; + enum pipe_format pfmt = cmdbuf->state.fb.info.rts[rt].view->format; unsigned minx = MAX2(clear_rect->rect.offset.x, 0); unsigned miny = MAX2(clear_rect->rect.offset.y, 0); unsigned maxx = @@ -284,7 +282,7 @@ panvk_meta_clear_attachment(struct panvk_cmd_buffer *cmdbuf, mali_ptr coordinates = pan_pool_upload_aligned(&cmdbuf->desc_pool.base, rect, sizeof(rect), 64); - enum glsl_base_type base_type = panvk_meta_get_format_type(att->format); + enum glsl_base_type base_type = panvk_meta_get_format_type(pfmt); mali_ptr tiler = batch->tiler.descs.gpu; mali_ptr tsd = batch->tls.gpu; @@ -300,7 +298,7 @@ panvk_meta_clear_attachment(struct panvk_cmd_buffer *cmdbuf, sizeof(*clear_value), 16); rsd = panvk_meta_clear_color_attachment_emit_rsd( - &cmdbuf->desc_pool.base, att->format, rt, shader_info, shader); + &cmdbuf->desc_pool.base, pfmt, rt, shader_info, shader); } else { rsd = panvk_meta_clear_zs_attachment_emit_rsd( &cmdbuf->desc_pool.base, mask, clear_value->depthStencil); @@ -476,24 +474,24 @@ panvk_per_arch(CmdClearAttachments)(VkCommandBuffer commandBuffer, const VkClearRect *pRects) { VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer); - const struct panvk_subpass *subpass = cmdbuf->state.subpass; + const struct vk_subpass *subpass = + &cmdbuf->vk.render_pass->subpasses[cmdbuf->vk.subpass_idx]; for (unsigned i = 0; i < attachmentCount; i++) { for (unsigned j = 0; j < rectCount; j++) { - uint32_t attachment, rt = 0; + uint32_t attachment = VK_ATTACHMENT_UNUSED, rt = 0; if (pAttachments[i].aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) { rt = pAttachments[i].colorAttachment; - attachment = subpass->color_attachments[rt].idx; - } else { - attachment = subpass->zs_attachment.idx; + attachment = subpass->color_attachments[rt].attachment; + } else if (subpass->depth_stencil_attachment) { + attachment = subpass->depth_stencil_attachment->attachment; } if (attachment == VK_ATTACHMENT_UNUSED) continue; - panvk_meta_clear_attachment(cmdbuf, attachment, rt, - pAttachments[i].aspectMask, + panvk_meta_clear_attachment(cmdbuf, rt, pAttachments[i].aspectMask, &pAttachments[i].clearValue, &pRects[j]); } } diff --git a/src/panfrost/vulkan/panvk_vX_pipeline.c b/src/panfrost/vulkan/panvk_vX_pipeline.c index a416c0d48d2..2e89e084a2f 100644 --- a/src/panfrost/vulkan/panvk_vX_pipeline.c +++ b/src/panfrost/vulkan/panvk_vX_pipeline.c @@ -39,6 +39,7 @@ #include "vk_blend.h" #include "vk_format.h" #include "vk_pipeline_cache.h" +#include "vk_render_pass.h" #include "vk_util.h" #include "panfrost/util/pan_lower_framebuffer.h" @@ -874,24 +875,24 @@ panvk_pipeline_builder_init_graphics( } else { builder->samples = create_info->pMultisampleState->rasterizationSamples; - const struct panvk_render_pass *pass = - panvk_render_pass_from_handle(create_info->renderPass); - const struct panvk_subpass *subpass = - &pass->subpasses[create_info->subpass]; + VK_FROM_HANDLE(vk_render_pass, pass, create_info->renderPass); + const struct vk_subpass *subpass = &pass->subpasses[create_info->subpass]; builder->use_depth_stencil_attachment = - subpass->zs_attachment.idx != VK_ATTACHMENT_UNUSED; + subpass->depth_stencil_attachment && + subpass->depth_stencil_attachment->attachment != VK_ATTACHMENT_UNUSED; assert(subpass->color_count <= create_info->pColorBlendState->attachmentCount); builder->active_color_attachments = 0; for (uint32_t i = 0; i < subpass->color_count; i++) { - uint32_t idx = subpass->color_attachments[i].idx; + uint32_t idx = subpass->color_attachments[i].attachment; if (idx == VK_ATTACHMENT_UNUSED) continue; builder->active_color_attachments |= 1 << i; - builder->color_attachment_formats[i] = pass->attachments[idx].format; + builder->color_attachment_formats[i] = + vk_format_to_pipe_format(pass->attachments[idx].format); } } }