diff --git a/src/panfrost/vulkan/csf/panvk_vX_cmd_draw.c b/src/panfrost/vulkan/csf/panvk_vX_cmd_draw.c index 7c2ac47b2b2..e262cfed191 100644 --- a/src/panfrost/vulkan/csf/panvk_vX_cmd_draw.c +++ b/src/panfrost/vulkan/csf/panvk_vX_cmd_draw.c @@ -434,116 +434,6 @@ translate_prim_topology(VkPrimitiveTopology in) } } -static void -force_fb_preload(struct panvk_cmd_buffer *cmdbuf, - const VkRenderingInfo *render_info) -{ - /* We force preloading for all active attachments when the render area is - * unaligned or when a barrier flushes prior draw calls in the middle of a - * render pass. The two cases can be distinguished by whether a - * render_info is provided. - * - * When the render area is unaligned, we force preloading to preserve - * contents falling outside of the render area. We also make sure the - * initial attachment clears are performed. - */ - struct pan_fb_info *fbinfo = &cmdbuf->state.gfx.render.fb.info; - VkClearAttachment clear_atts[MAX_RTS + 2]; - uint32_t clear_att_count = 0; - - if (!cmdbuf->state.gfx.render.bound_attachments) - return; - - for (unsigned i = 0; i < fbinfo->rt_count; i++) { - if (!fbinfo->rts[i].view) - continue; - - fbinfo->rts[i].preload = true; - - if (fbinfo->rts[i].clear) { - if (render_info) { - const VkRenderingAttachmentInfo *att = - &render_info->pColorAttachments[i]; - - clear_atts[clear_att_count++] = (VkClearAttachment){ - .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, - .colorAttachment = i, - .clearValue = att->clearValue, - }; - } - fbinfo->rts[i].clear = false; - } - } - - if (fbinfo->zs.view.zs) { - fbinfo->zs.preload.z = true; - - if (fbinfo->zs.clear.z) { - if (render_info) { - const VkRenderingAttachmentInfo *att = - render_info->pDepthAttachment; - - clear_atts[clear_att_count++] = (VkClearAttachment){ - .aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT, - .clearValue = att->clearValue, - }; - } - fbinfo->zs.clear.z = false; - } - } - - if (fbinfo->zs.view.s || - (fbinfo->zs.view.zs && - util_format_is_depth_and_stencil(fbinfo->zs.view.zs->format))) { - fbinfo->zs.preload.s = true; - - if (fbinfo->zs.clear.s) { - if (render_info) { - const VkRenderingAttachmentInfo *att = - render_info->pStencilAttachment; - - clear_atts[clear_att_count++] = (VkClearAttachment){ - .aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT, - .clearValue = att->clearValue, - }; - } - - fbinfo->zs.clear.s = false; - } - } - - /* insert a barrier for preload */ - const VkMemoryBarrier2 mem_barrier = { - .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2, - .srcStageMask = VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT | - VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT | - VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, - .srcAccessMask = VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT | - VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, - .dstStageMask = VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT, - .dstAccessMask = VK_ACCESS_2_SHADER_SAMPLED_READ_BIT, - }; - const VkDependencyInfo dep_info = { - .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO, - .memoryBarrierCount = 1, - .pMemoryBarriers = &mem_barrier, - }; - panvk_per_arch(CmdPipelineBarrier2)(panvk_cmd_buffer_to_handle(cmdbuf), - &dep_info); - - if (clear_att_count && render_info) { - VkClearRect clear_rect = { - .rect = render_info->renderArea, - .baseArrayLayer = 0, - .layerCount = render_info->layerCount, - }; - - panvk_per_arch(CmdClearAttachments)(panvk_cmd_buffer_to_handle(cmdbuf), - clear_att_count, clear_atts, 1, - &clear_rect); - } -} - static VkResult update_tls(struct panvk_cmd_buffer *cmdbuf) { @@ -1704,242 +1594,6 @@ panvk_per_arch(CmdDrawIndexedIndirect)(VkCommandBuffer commandBuffer, panvk_cmd_draw_indirect(cmdbuf, &draw); } -static void -panvk_cmd_init_render_state(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.gfx.render.fb.info; - uint32_t att_width = 0, att_height = 0; - - cmdbuf->state.gfx.render.flags = pRenderingInfo->flags; - - gfx_state_set_dirty(cmdbuf, RENDER_STATE); - memset(cmdbuf->state.gfx.render.fb.crc_valid, 0, - sizeof(cmdbuf->state.gfx.render.fb.crc_valid)); - memset(&cmdbuf->state.gfx.render.color_attachments, 0, - sizeof(cmdbuf->state.gfx.render.color_attachments)); - memset(&cmdbuf->state.gfx.render.z_attachment, 0, - sizeof(cmdbuf->state.gfx.render.z_attachment)); - memset(&cmdbuf->state.gfx.render.s_attachment, 0, - sizeof(cmdbuf->state.gfx.render.s_attachment)); - cmdbuf->state.gfx.render.bound_attachments = 0; - - cmdbuf->state.gfx.render.layer_count = pRenderingInfo->layerCount; - *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 = iview->vk.extent; - - cmdbuf->state.gfx.render.bound_attachments |= - MESA_VK_RP_ATTACHMENT_COLOR_BIT(i); - cmdbuf->state.gfx.render.color_attachments.iviews[i] = iview; - cmdbuf->state.gfx.render.color_attachments.fmts[i] = iview->vk.format; - cmdbuf->state.gfx.render.color_attachments.samples[i] = img->vk.samples; - att_width = MAX2(iview_size.width, att_width); - att_height = MAX2(iview_size.height, att_height); - - fbinfo->rts[i].view = &iview->pview; - fbinfo->rts[i].crc_valid = &cmdbuf->state.gfx.render.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 (att->resolveMode != VK_RESOLVE_MODE_NONE) { - struct panvk_resolve_attachment *resolve_info = - &cmdbuf->state.gfx.render.color_attachments.resolve[i]; - VK_FROM_HANDLE(panvk_image_view, resolve_iview, att->resolveImageView); - - resolve_info->mode = att->resolveMode; - resolve_info->dst_iview = resolve_iview; - } - } - - 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 = iview->vk.extent; - cmdbuf->state.gfx.render.z_attachment.fmt = iview->vk.format; - - if (iview->vk.aspects & VK_IMAGE_ASPECT_DEPTH_BIT) { - cmdbuf->state.gfx.render.bound_attachments |= - MESA_VK_RP_ATTACHMENT_DEPTH_BIT; - att_width = MAX2(iview_size.width, att_width); - att_height = MAX2(iview_size.height, att_height); - - fbinfo->zs.view.zs = &iview->pview; - fbinfo->nr_samples = MAX2( - fbinfo->nr_samples, pan_image_view_get_nr_samples(&iview->pview)); - cmdbuf->state.gfx.render.z_attachment.iview = iview; - - if (vk_format_has_stencil(img->vk.format)) - fbinfo->zs.preload.s = true; - - 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 (att->resolveMode != VK_RESOLVE_MODE_NONE) { - struct panvk_resolve_attachment *resolve_info = - &cmdbuf->state.gfx.render.z_attachment.resolve; - VK_FROM_HANDLE(panvk_image_view, resolve_iview, - att->resolveImageView); - - resolve_info->mode = att->resolveMode; - resolve_info->dst_iview = resolve_iview; - } - } - } - - 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 = iview->vk.extent; - cmdbuf->state.gfx.render.s_attachment.fmt = iview->vk.format; - - if (iview->vk.aspects & VK_IMAGE_ASPECT_STENCIL_BIT) { - cmdbuf->state.gfx.render.bound_attachments |= - MESA_VK_RP_ATTACHMENT_STENCIL_BIT; - att_width = MAX2(iview_size.width, att_width); - att_height = MAX2(iview_size.height, att_height); - - if (drm_is_afbc(img->pimage.layout.modifier)) { - assert(fbinfo->zs.view.zs == &iview->pview || !fbinfo->zs.view.zs); - fbinfo->zs.view.zs = &iview->pview; - } else { - fbinfo->zs.view.s = - &iview->pview != fbinfo->zs.view.zs ? &iview->pview : NULL; - } - - fbinfo->zs.view.s = - &iview->pview != fbinfo->zs.view.zs ? &iview->pview : NULL; - fbinfo->nr_samples = MAX2( - fbinfo->nr_samples, pan_image_view_get_nr_samples(&iview->pview)); - cmdbuf->state.gfx.render.s_attachment.iview = iview; - - if (vk_format_has_depth(img->vk.format)) { - assert(fbinfo->zs.view.zs == NULL || - &iview->pview == fbinfo->zs.view.zs); - fbinfo->zs.view.zs = &iview->pview; - - fbinfo->zs.preload.s = false; - fbinfo->zs.clear.s = false; - if (!fbinfo->zs.clear.z) - fbinfo->zs.preload.z = true; - } - - if (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; - } - - if (att->resolveMode != VK_RESOLVE_MODE_NONE) { - struct panvk_resolve_attachment *resolve_info = - &cmdbuf->state.gfx.render.s_attachment.resolve; - VK_FROM_HANDLE(panvk_image_view, resolve_iview, - att->resolveImageView); - - resolve_info->mode = att->resolveMode; - resolve_info->dst_iview = resolve_iview; - } - } - } - - if (fbinfo->zs.view.zs) { - const struct util_format_description *fdesc = - util_format_description(fbinfo->zs.view.zs->format); - bool needs_depth = fbinfo->zs.clear.z | fbinfo->zs.preload.z | - util_format_has_depth(fdesc); - bool needs_stencil = fbinfo->zs.clear.s | fbinfo->zs.preload.s | - util_format_has_stencil(fdesc); - enum pipe_format new_fmt = - util_format_get_blocksize(fbinfo->zs.view.zs->format) == 4 - ? PIPE_FORMAT_Z24_UNORM_S8_UINT - : PIPE_FORMAT_Z32_FLOAT_S8X24_UINT; - - if (needs_depth && needs_stencil && - fbinfo->zs.view.zs->format != new_fmt) { - cmdbuf->state.gfx.render.zs_pview = *fbinfo->zs.view.zs; - cmdbuf->state.gfx.render.zs_pview.format = new_fmt; - fbinfo->zs.view.zs = &cmdbuf->state.gfx.render.zs_pview; - } - } - - fbinfo->extent.minx = pRenderingInfo->renderArea.offset.x; - fbinfo->extent.maxx = pRenderingInfo->renderArea.offset.x + - pRenderingInfo->renderArea.extent.width - 1; - fbinfo->extent.miny = pRenderingInfo->renderArea.offset.y; - fbinfo->extent.maxy = pRenderingInfo->renderArea.offset.y + - pRenderingInfo->renderArea.extent.height - 1; - - if (cmdbuf->state.gfx.render.bound_attachments) { - fbinfo->width = att_width; - fbinfo->height = att_height; - } else { - fbinfo->width = fbinfo->extent.maxx + 1; - fbinfo->height = fbinfo->extent.maxy + 1; - } - - assert(fbinfo->width && fbinfo->height); -} - -static void -preload_render_area_border(struct panvk_cmd_buffer *cmdbuf, - const VkRenderingInfo *render_info) -{ - struct pan_fb_info *fbinfo = &cmdbuf->state.gfx.render.fb.info; - bool render_area_is_32x32_aligned = - ((fbinfo->extent.minx | fbinfo->extent.miny) % 32) == 0 && - (fbinfo->extent.maxx + 1 == fbinfo->width || - (fbinfo->extent.maxx % 32) == 31) && - (fbinfo->extent.maxy + 1 == fbinfo->height || - (fbinfo->extent.maxy % 32) == 31); - - /* If the render area is aligned on a 32x32 section, we're good. */ - if (!render_area_is_32x32_aligned) - force_fb_preload(cmdbuf, render_info); -} - void panvk_per_arch(cmd_inherit_render_state)( struct panvk_cmd_buffer *cmdbuf, @@ -1956,7 +1610,7 @@ panvk_per_arch(cmd_inherit_render_state)( pBeginInfo, gcbiar_data); if (resume_info) { - panvk_cmd_init_render_state(cmdbuf, resume_info); + panvk_per_arch(cmd_init_render_state)(cmdbuf, resume_info); return; } @@ -2033,128 +1687,19 @@ panvk_per_arch(CmdBeginRendering)(VkCommandBuffer commandBuffer, { VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer); struct panvk_cmd_graphics_state *state = &cmdbuf->state.gfx; - bool resuming = pRenderingInfo->flags & VK_RENDERING_RESUMING_BIT; /* When resuming from a suspended pass, the state should be unchanged. */ if (resuming) state->render.flags = pRenderingInfo->flags; else - panvk_cmd_init_render_state(cmdbuf, pRenderingInfo); + panvk_per_arch(cmd_init_render_state)(cmdbuf, pRenderingInfo); /* If we're not resuming, the FBD should be NULL. */ assert(!state->render.fbds.gpu || resuming); if (!resuming) - preload_render_area_border(cmdbuf, pRenderingInfo); -} - -static void -resolve_attachments(struct panvk_cmd_buffer *cmdbuf) -{ - struct pan_fb_info *fbinfo = &cmdbuf->state.gfx.render.fb.info; - bool needs_resolve = false; - - unsigned bound_atts = cmdbuf->state.gfx.render.bound_attachments; - unsigned color_att_count = - util_last_bit(bound_atts & MESA_VK_RP_ATTACHMENT_ANY_COLOR_BITS); - VkRenderingAttachmentInfo color_atts[MAX_RTS]; - for (uint32_t i = 0; i < color_att_count; i++) { - const struct panvk_resolve_attachment *resolve_info = - &cmdbuf->state.gfx.render.color_attachments.resolve[i]; - struct panvk_image_view *src_iview = - cmdbuf->state.gfx.render.color_attachments.iviews[i]; - - color_atts[i] = (VkRenderingAttachmentInfo){ - .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, - .imageView = panvk_image_view_to_handle(src_iview), - .imageLayout = VK_IMAGE_LAYOUT_GENERAL, - .resolveMode = resolve_info->mode, - .resolveImageView = - panvk_image_view_to_handle(resolve_info->dst_iview), - .resolveImageLayout = VK_IMAGE_LAYOUT_GENERAL, - }; - - if (resolve_info->mode != VK_RESOLVE_MODE_NONE) - needs_resolve = true; - } - - const struct panvk_resolve_attachment *resolve_info = - &cmdbuf->state.gfx.render.z_attachment.resolve; - struct panvk_image_view *src_iview = - cmdbuf->state.gfx.render.z_attachment.iview; - VkRenderingAttachmentInfo z_att = { - .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, - .imageView = panvk_image_view_to_handle(src_iview), - .imageLayout = VK_IMAGE_LAYOUT_GENERAL, - .resolveMode = resolve_info->mode, - .resolveImageView = panvk_image_view_to_handle(resolve_info->dst_iview), - .resolveImageLayout = VK_IMAGE_LAYOUT_GENERAL, - }; - - if (resolve_info->mode != VK_RESOLVE_MODE_NONE) - needs_resolve = true; - - resolve_info = &cmdbuf->state.gfx.render.s_attachment.resolve; - src_iview = cmdbuf->state.gfx.render.s_attachment.iview; - - VkRenderingAttachmentInfo s_att = { - .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, - .imageView = panvk_image_view_to_handle(src_iview), - .imageLayout = VK_IMAGE_LAYOUT_GENERAL, - .resolveMode = resolve_info->mode, - .resolveImageView = panvk_image_view_to_handle(resolve_info->dst_iview), - .resolveImageLayout = VK_IMAGE_LAYOUT_GENERAL, - }; - - if (resolve_info->mode != VK_RESOLVE_MODE_NONE) - needs_resolve = true; - - if (!needs_resolve) - return; - - /* insert a barrier for resolve */ - const VkMemoryBarrier2 mem_barrier = { - .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2, - .srcStageMask = VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT | - VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT | - VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, - .srcAccessMask = VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT | - VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, - .dstStageMask = VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT, - .dstAccessMask = VK_ACCESS_2_SHADER_SAMPLED_READ_BIT, - }; - const VkDependencyInfo dep_info = { - .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO, - .memoryBarrierCount = 1, - .pMemoryBarriers = &mem_barrier, - }; - panvk_per_arch(CmdPipelineBarrier2)(panvk_cmd_buffer_to_handle(cmdbuf), - &dep_info); - - const VkRenderingInfo render_info = { - .sType = VK_STRUCTURE_TYPE_RENDERING_INFO, - .renderArea = - { - .offset.x = fbinfo->extent.minx, - .offset.y = fbinfo->extent.miny, - .extent.width = fbinfo->extent.maxx - fbinfo->extent.minx + 1, - .extent.height = fbinfo->extent.maxy - fbinfo->extent.miny + 1, - }, - .layerCount = cmdbuf->state.gfx.render.layer_count, - .viewMask = 0, - .colorAttachmentCount = color_att_count, - .pColorAttachments = color_atts, - .pDepthAttachment = &z_att, - .pStencilAttachment = &s_att, - }; - - struct panvk_device *dev = to_panvk_device(cmdbuf->vk.base.device); - struct panvk_cmd_meta_graphics_save_ctx save = {0}; - - panvk_per_arch(cmd_meta_gfx_start)(cmdbuf, &save); - vk_meta_resolve_rendering(&cmdbuf->vk, &dev->meta, &render_info); - panvk_per_arch(cmd_meta_gfx_end)(cmdbuf, &save); + panvk_per_arch(cmd_preload_render_area_border)(cmdbuf, pRenderingInfo); } static uint8_t @@ -2473,7 +2018,7 @@ panvk_per_arch(cmd_flush_draws)(struct panvk_cmd_buffer *cmdbuf) sizeof(cmdbuf->state.gfx.render.fbds)); cmdbuf->state.gfx.render.tiler = 0; - force_fb_preload(cmdbuf, NULL); + panvk_per_arch(cmd_force_fb_preload)(cmdbuf, NULL); } VKAPI_ATTR void VKAPI_CALL @@ -2495,45 +2040,6 @@ panvk_per_arch(CmdEndRendering)(VkCommandBuffer commandBuffer) flush_tiling(cmdbuf); issue_fragment_jobs(cmdbuf); - resolve_attachments(cmdbuf); + panvk_per_arch(cmd_resolve_attachments)(cmdbuf); } } - -VKAPI_ATTR void VKAPI_CALL -panvk_per_arch(CmdBindVertexBuffers)(VkCommandBuffer commandBuffer, - uint32_t firstBinding, - uint32_t bindingCount, - const VkBuffer *pBuffers, - const VkDeviceSize *pOffsets) -{ - VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer); - - assert(firstBinding + bindingCount <= MAX_VBS); - - for (uint32_t i = 0; i < bindingCount; i++) { - VK_FROM_HANDLE(panvk_buffer, buffer, pBuffers[i]); - - cmdbuf->state.gfx.vb.bufs[firstBinding + i].address = - panvk_buffer_gpu_ptr(buffer, pOffsets[i]); - cmdbuf->state.gfx.vb.bufs[firstBinding + i].size = - panvk_buffer_range(buffer, pOffsets[i], VK_WHOLE_SIZE); - } - - cmdbuf->state.gfx.vb.count = - MAX2(cmdbuf->state.gfx.vb.count, firstBinding + bindingCount); - gfx_state_set_dirty(cmdbuf, VB); -} - -VKAPI_ATTR void VKAPI_CALL -panvk_per_arch(CmdBindIndexBuffer)(VkCommandBuffer commandBuffer, - VkBuffer buffer, VkDeviceSize offset, - VkIndexType indexType) -{ - VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer); - VK_FROM_HANDLE(panvk_buffer, buf, buffer); - - cmdbuf->state.gfx.ib.buffer = buf; - cmdbuf->state.gfx.ib.offset = offset; - cmdbuf->state.gfx.ib.index_size = vk_index_type_to_bytes(indexType); - gfx_state_set_dirty(cmdbuf, IB); -} diff --git a/src/panfrost/vulkan/jm/panvk_vX_cmd_draw.c b/src/panfrost/vulkan/jm/panvk_vX_cmd_draw.c index 17eefedf174..1d51db15192 100644 --- a/src/panfrost/vulkan/jm/panvk_vX_cmd_draw.c +++ b/src/panfrost/vulkan/jm/panvk_vX_cmd_draw.c @@ -1493,332 +1493,20 @@ panvk_per_arch(CmdDrawIndexedIndirect)(VkCommandBuffer commandBuffer, panvk_stub(); } -static void -panvk_cmd_begin_rendering_init_state(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.gfx.render.fb.info; - uint32_t att_width = 0, att_height = 0; - - cmdbuf->state.gfx.render.flags = pRenderingInfo->flags; - - /* Resuming from a suspended pass, the state should be unchanged. */ - if (cmdbuf->state.gfx.render.flags & VK_RENDERING_RESUMING_BIT) - return; - - gfx_state_set_dirty(cmdbuf, RENDER_STATE); - cmdbuf->state.gfx.render.fb.bo_count = 0; - memset(cmdbuf->state.gfx.render.fb.bos, 0, - sizeof(cmdbuf->state.gfx.render.fb.bos)); - memset(cmdbuf->state.gfx.render.fb.crc_valid, 0, - sizeof(cmdbuf->state.gfx.render.fb.crc_valid)); - memset(&cmdbuf->state.gfx.render.color_attachments, 0, - sizeof(cmdbuf->state.gfx.render.color_attachments)); - memset(&cmdbuf->state.gfx.render.z_attachment, 0, - sizeof(cmdbuf->state.gfx.render.z_attachment)); - memset(&cmdbuf->state.gfx.render.s_attachment, 0, - sizeof(cmdbuf->state.gfx.render.s_attachment)); - cmdbuf->state.gfx.render.bound_attachments = 0; - - cmdbuf->state.gfx.render.layer_count = pRenderingInfo->layerCount; - *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 = iview->vk.extent; - - cmdbuf->state.gfx.render.bound_attachments |= - MESA_VK_RP_ATTACHMENT_COLOR_BIT(i); - cmdbuf->state.gfx.render.color_attachments.iviews[i] = iview; - cmdbuf->state.gfx.render.color_attachments.fmts[i] = iview->vk.format; - cmdbuf->state.gfx.render.color_attachments.samples[i] = img->vk.samples; - att_width = MAX2(iview_size.width, att_width); - att_height = MAX2(iview_size.height, att_height); - - cmdbuf->state.gfx.render.fb.bos[cmdbuf->state.gfx.render.fb.bo_count++] = - img->bo; - fbinfo->rts[i].view = &iview->pview; - fbinfo->rts[i].crc_valid = &cmdbuf->state.gfx.render.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 (att->resolveMode != VK_RESOLVE_MODE_NONE) { - struct panvk_resolve_attachment *resolve_info = - &cmdbuf->state.gfx.render.color_attachments.resolve[i]; - VK_FROM_HANDLE(panvk_image_view, resolve_iview, att->resolveImageView); - - resolve_info->mode = att->resolveMode; - resolve_info->dst_iview = resolve_iview; - } - } - - 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 = iview->vk.extent; - cmdbuf->state.gfx.render.z_attachment.fmt = iview->vk.format; - - if (iview->vk.aspects & VK_IMAGE_ASPECT_DEPTH_BIT) { - cmdbuf->state.gfx.render.bound_attachments |= - MESA_VK_RP_ATTACHMENT_DEPTH_BIT; - att_width = MAX2(iview_size.width, att_width); - att_height = MAX2(iview_size.height, att_height); - - cmdbuf->state.gfx.render.fb - .bos[cmdbuf->state.gfx.render.fb.bo_count++] = img->bo; - fbinfo->zs.view.zs = &iview->pview; - fbinfo->nr_samples = MAX2( - fbinfo->nr_samples, pan_image_view_get_nr_samples(&iview->pview)); - cmdbuf->state.gfx.render.z_attachment.iview = iview; - - if (vk_format_has_stencil(img->vk.format)) - fbinfo->zs.preload.s = true; - - 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 (att->resolveMode != VK_RESOLVE_MODE_NONE) { - struct panvk_resolve_attachment *resolve_info = - &cmdbuf->state.gfx.render.z_attachment.resolve; - VK_FROM_HANDLE(panvk_image_view, resolve_iview, - att->resolveImageView); - - resolve_info->mode = att->resolveMode; - resolve_info->dst_iview = resolve_iview; - } - } - } - - 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 = iview->vk.extent; - cmdbuf->state.gfx.render.s_attachment.fmt = iview->vk.format; - - if (iview->vk.aspects & VK_IMAGE_ASPECT_STENCIL_BIT) { - cmdbuf->state.gfx.render.bound_attachments |= - MESA_VK_RP_ATTACHMENT_STENCIL_BIT; - att_width = MAX2(iview_size.width, att_width); - att_height = MAX2(iview_size.height, att_height); - - cmdbuf->state.gfx.render.fb - .bos[cmdbuf->state.gfx.render.fb.bo_count++] = img->bo; - - if (drm_is_afbc(img->pimage.layout.modifier)) { - assert(fbinfo->zs.view.zs == &iview->pview || !fbinfo->zs.view.zs); - fbinfo->zs.view.zs = &iview->pview; - } else { - fbinfo->zs.view.s = - &iview->pview != fbinfo->zs.view.zs ? &iview->pview : NULL; - } - - fbinfo->zs.view.s = - &iview->pview != fbinfo->zs.view.zs ? &iview->pview : NULL; - fbinfo->nr_samples = MAX2( - fbinfo->nr_samples, pan_image_view_get_nr_samples(&iview->pview)); - cmdbuf->state.gfx.render.s_attachment.iview = iview; - - if (vk_format_has_depth(img->vk.format)) { - assert(fbinfo->zs.view.zs == NULL || - &iview->pview == fbinfo->zs.view.zs); - fbinfo->zs.view.zs = &iview->pview; - - fbinfo->zs.preload.s = false; - fbinfo->zs.clear.s = false; - if (!fbinfo->zs.clear.z) - fbinfo->zs.preload.z = true; - } - - if (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; - } - - if (att->resolveMode != VK_RESOLVE_MODE_NONE) { - struct panvk_resolve_attachment *resolve_info = - &cmdbuf->state.gfx.render.s_attachment.resolve; - VK_FROM_HANDLE(panvk_image_view, resolve_iview, - att->resolveImageView); - - resolve_info->mode = att->resolveMode; - resolve_info->dst_iview = resolve_iview; - } - } - } - - if (fbinfo->zs.view.zs) { - const struct util_format_description *fdesc = - util_format_description(fbinfo->zs.view.zs->format); - bool needs_depth = fbinfo->zs.clear.z | fbinfo->zs.preload.z | - util_format_has_depth(fdesc); - bool needs_stencil = fbinfo->zs.clear.s | fbinfo->zs.preload.s | - util_format_has_stencil(fdesc); - enum pipe_format new_fmt = - util_format_get_blocksize(fbinfo->zs.view.zs->format) == 4 - ? PIPE_FORMAT_Z24_UNORM_S8_UINT - : PIPE_FORMAT_Z32_FLOAT_S8X24_UINT; - - if (needs_depth && needs_stencil && - fbinfo->zs.view.zs->format != new_fmt) { - cmdbuf->state.gfx.render.zs_pview = *fbinfo->zs.view.zs; - cmdbuf->state.gfx.render.zs_pview.format = new_fmt; - fbinfo->zs.view.zs = &cmdbuf->state.gfx.render.zs_pview; - } - } - - fbinfo->extent.minx = pRenderingInfo->renderArea.offset.x; - fbinfo->extent.maxx = pRenderingInfo->renderArea.offset.x + - pRenderingInfo->renderArea.extent.width - 1; - fbinfo->extent.miny = pRenderingInfo->renderArea.offset.y; - fbinfo->extent.maxy = pRenderingInfo->renderArea.offset.y + - pRenderingInfo->renderArea.extent.height - 1; - - if (cmdbuf->state.gfx.render.bound_attachments) { - fbinfo->width = att_width; - fbinfo->height = att_height; - } else { - fbinfo->width = fbinfo->extent.maxx + 1; - fbinfo->height = fbinfo->extent.maxy + 1; - } - - assert(fbinfo->width && fbinfo->height); -} - -static void -preload_render_area_border(struct panvk_cmd_buffer *cmdbuf, - const VkRenderingInfo *render_info) -{ - struct pan_fb_info *fbinfo = &cmdbuf->state.gfx.render.fb.info; - bool render_area_is_32x32_aligned = - ((fbinfo->extent.minx | fbinfo->extent.miny) % 32) == 0 && - (fbinfo->extent.maxx + 1 == fbinfo->width || - (fbinfo->extent.maxx % 32) == 31) && - (fbinfo->extent.maxy + 1 == fbinfo->height || - (fbinfo->extent.maxy % 32) == 31); - - /* If the render area is aligned on a 32x32 section, we're good. */ - if (render_area_is_32x32_aligned) - return; - - /* We force preloading for all active attachments to preverse content falling - * outside the render area, but we need to compensate with attachment clears - * for attachments that were initially cleared. - */ - uint32_t bound_atts = cmdbuf->state.gfx.render.bound_attachments; - VkClearAttachment clear_atts[MAX_RTS + 2]; - uint32_t clear_att_count = 0; - - for (uint32_t i = 0; i < render_info->colorAttachmentCount; i++) { - if (bound_atts & MESA_VK_RP_ATTACHMENT_COLOR_BIT(i)) { - if (fbinfo->rts[i].clear) { - const VkRenderingAttachmentInfo *att = - &render_info->pColorAttachments[i]; - - clear_atts[clear_att_count++] = (VkClearAttachment){ - .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, - .colorAttachment = i, - .clearValue = att->clearValue, - }; - } - - fbinfo->rts[i].preload = true; - fbinfo->rts[i].clear = false; - } - } - - if (bound_atts & MESA_VK_RP_ATTACHMENT_DEPTH_BIT) { - if (fbinfo->zs.clear.z) { - const VkRenderingAttachmentInfo *att = render_info->pDepthAttachment; - - clear_atts[clear_att_count++] = (VkClearAttachment){ - .aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT, - .clearValue = att->clearValue, - }; - } - - fbinfo->zs.preload.z = true; - fbinfo->zs.clear.z = false; - } - - if (bound_atts & MESA_VK_RP_ATTACHMENT_STENCIL_BIT) { - if (fbinfo->zs.clear.s) { - const VkRenderingAttachmentInfo *att = render_info->pStencilAttachment; - - clear_atts[clear_att_count++] = (VkClearAttachment){ - .aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT, - .clearValue = att->clearValue, - }; - } - - fbinfo->zs.preload.s = true; - fbinfo->zs.clear.s = false; - } - - if (clear_att_count) { - VkClearRect clear_rect = { - .rect = render_info->renderArea, - .baseArrayLayer = 0, - .layerCount = render_info->layerCount, - }; - - panvk_per_arch(CmdClearAttachments)(panvk_cmd_buffer_to_handle(cmdbuf), - clear_att_count, clear_atts, 1, - &clear_rect); - } -} - 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_state(cmdbuf, pRenderingInfo); - + struct panvk_cmd_graphics_state *state = &cmdbuf->state.gfx; bool resuming = cmdbuf->state.gfx.render.flags & VK_RENDERING_RESUMING_BIT; + /* When resuming from a suspended pass, the state should be unchanged. */ + if (resuming) + state->render.flags = pRenderingInfo->flags; + else + panvk_per_arch(cmd_init_render_state)(cmdbuf, pRenderingInfo); + /* If we're not resuming, cur_batch should be NULL. * However, this currently isn't true because of how events are implemented. * XXX: Rewrite events to not close and open batch and add an assert here. @@ -1835,95 +1523,7 @@ panvk_per_arch(CmdBeginRendering)(VkCommandBuffer commandBuffer, panvk_per_arch(cmd_open_batch)(cmdbuf); if (!resuming) - preload_render_area_border(cmdbuf, pRenderingInfo); -} - -static void -resolve_attachments(struct panvk_cmd_buffer *cmdbuf) -{ - struct pan_fb_info *fbinfo = &cmdbuf->state.gfx.render.fb.info; - bool needs_resolve = false; - - unsigned bound_atts = cmdbuf->state.gfx.render.bound_attachments; - unsigned color_att_count = - util_last_bit(bound_atts & MESA_VK_RP_ATTACHMENT_ANY_COLOR_BITS); - VkRenderingAttachmentInfo color_atts[MAX_RTS]; - for (uint32_t i = 0; i < color_att_count; i++) { - const struct panvk_resolve_attachment *resolve_info = - &cmdbuf->state.gfx.render.color_attachments.resolve[i]; - struct panvk_image_view *src_iview = - cmdbuf->state.gfx.render.color_attachments.iviews[i]; - - color_atts[i] = (VkRenderingAttachmentInfo){ - .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, - .imageView = panvk_image_view_to_handle(src_iview), - .imageLayout = VK_IMAGE_LAYOUT_GENERAL, - .resolveMode = resolve_info->mode, - .resolveImageView = - panvk_image_view_to_handle(resolve_info->dst_iview), - .resolveImageLayout = VK_IMAGE_LAYOUT_GENERAL, - }; - - if (resolve_info->mode != VK_RESOLVE_MODE_NONE) - needs_resolve = true; - } - - const struct panvk_resolve_attachment *resolve_info = - &cmdbuf->state.gfx.render.z_attachment.resolve; - struct panvk_image_view *src_iview = - cmdbuf->state.gfx.render.z_attachment.iview; - VkRenderingAttachmentInfo z_att = { - .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, - .imageView = panvk_image_view_to_handle(src_iview), - .imageLayout = VK_IMAGE_LAYOUT_GENERAL, - .resolveMode = resolve_info->mode, - .resolveImageView = panvk_image_view_to_handle(resolve_info->dst_iview), - .resolveImageLayout = VK_IMAGE_LAYOUT_GENERAL, - }; - - if (resolve_info->mode != VK_RESOLVE_MODE_NONE) - needs_resolve = true; - - resolve_info = &cmdbuf->state.gfx.render.s_attachment.resolve; - src_iview = cmdbuf->state.gfx.render.s_attachment.iview; - - VkRenderingAttachmentInfo s_att = { - .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, - .imageView = panvk_image_view_to_handle(src_iview), - .imageLayout = VK_IMAGE_LAYOUT_GENERAL, - .resolveMode = resolve_info->mode, - .resolveImageView = panvk_image_view_to_handle(resolve_info->dst_iview), - .resolveImageLayout = VK_IMAGE_LAYOUT_GENERAL, - }; - - if (resolve_info->mode != VK_RESOLVE_MODE_NONE) - needs_resolve = true; - - if (!needs_resolve) - return; - - const VkRenderingInfo render_info = { - .sType = VK_STRUCTURE_TYPE_RENDERING_INFO, - .renderArea = { - .offset.x = fbinfo->extent.minx, - .offset.y = fbinfo->extent.miny, - .extent.width = fbinfo->extent.maxx - fbinfo->extent.minx + 1, - .extent.height = fbinfo->extent.maxy - fbinfo->extent.miny + 1, - }, - .layerCount = cmdbuf->state.gfx.render.layer_count, - .viewMask = 0, - .colorAttachmentCount = color_att_count, - .pColorAttachments = color_atts, - .pDepthAttachment = &z_att, - .pStencilAttachment = &s_att, - }; - - struct panvk_device *dev = to_panvk_device(cmdbuf->vk.base.device); - struct panvk_cmd_meta_graphics_save_ctx save = {0}; - - panvk_per_arch(cmd_meta_gfx_start)(cmdbuf, &save); - vk_meta_resolve_rendering(&cmdbuf->vk, &dev->meta, &render_info); - panvk_per_arch(cmd_meta_gfx_end)(cmdbuf, &save); + panvk_per_arch(cmd_preload_render_area_border)(cmdbuf, pRenderingInfo); } VKAPI_ATTR void VKAPI_CALL @@ -1942,45 +1542,6 @@ panvk_per_arch(CmdEndRendering)(VkCommandBuffer commandBuffer) panvk_per_arch(cmd_close_batch)(cmdbuf); cmdbuf->cur_batch = NULL; - resolve_attachments(cmdbuf); + panvk_per_arch(cmd_resolve_attachments)(cmdbuf); } } - -VKAPI_ATTR void VKAPI_CALL -panvk_per_arch(CmdBindVertexBuffers)(VkCommandBuffer commandBuffer, - uint32_t firstBinding, - uint32_t bindingCount, - const VkBuffer *pBuffers, - const VkDeviceSize *pOffsets) -{ - VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer); - - assert(firstBinding + bindingCount <= MAX_VBS); - - for (uint32_t i = 0; i < bindingCount; i++) { - VK_FROM_HANDLE(panvk_buffer, buffer, pBuffers[i]); - - cmdbuf->state.gfx.vb.bufs[firstBinding + i].address = - panvk_buffer_gpu_ptr(buffer, pOffsets[i]); - cmdbuf->state.gfx.vb.bufs[firstBinding + i].size = - panvk_buffer_range(buffer, pOffsets[i], VK_WHOLE_SIZE); - } - - cmdbuf->state.gfx.vb.count = - MAX2(cmdbuf->state.gfx.vb.count, firstBinding + bindingCount); - gfx_state_set_dirty(cmdbuf, VB); -} - -VKAPI_ATTR void VKAPI_CALL -panvk_per_arch(CmdBindIndexBuffer)(VkCommandBuffer commandBuffer, - VkBuffer buffer, VkDeviceSize offset, - VkIndexType indexType) -{ - VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer); - VK_FROM_HANDLE(panvk_buffer, buf, buffer); - - cmdbuf->state.gfx.ib.buffer = buf; - cmdbuf->state.gfx.ib.offset = offset; - cmdbuf->state.gfx.ib.index_size = vk_index_type_to_bytes(indexType); - gfx_state_set_dirty(cmdbuf, IB); -} diff --git a/src/panfrost/vulkan/meson.build b/src/panfrost/vulkan/meson.build index dd2932c9c6a..20a33ea5530 100644 --- a/src/panfrost/vulkan/meson.build +++ b/src/panfrost/vulkan/meson.build @@ -74,6 +74,7 @@ common_per_arch_files = [ 'panvk_vX_buffer_view.c', 'panvk_vX_cmd_fb_preload.c', 'panvk_vX_cmd_desc_state.c', + 'panvk_vX_cmd_draw.c', 'panvk_vX_cmd_meta.c', 'panvk_vX_cmd_push_constant.c', 'panvk_vX_descriptor_set.c', diff --git a/src/panfrost/vulkan/panvk_cmd_draw.h b/src/panfrost/vulkan/panvk_cmd_draw.h index 873496ea1bd..18364c97fec 100644 --- a/src/panfrost/vulkan/panvk_cmd_draw.h +++ b/src/panfrost/vulkan/panvk_cmd_draw.h @@ -11,13 +11,21 @@ #endif #include "panvk_blend.h" +#include "panvk_entrypoints.h" +#include "panvk_image.h" +#include "panvk_image_view.h" #include "panvk_physical_device.h" +#include "vk_command_buffer.h" +#include "vk_format.h" + #include "pan_props.h" #define MAX_VBS 16 #define MAX_RTS 8 +struct panvk_cmd_buffer; + struct panvk_attrib_buf { mali_ptr address; unsigned size; @@ -247,4 +255,18 @@ fs_required(const struct panvk_cmd_graphics_state *state, gfx_state_set_dirty(__cmdbuf, FS); \ } while (0) +void +panvk_per_arch(cmd_init_render_state)(struct panvk_cmd_buffer *cmdbuf, + const VkRenderingInfo *pRenderingInfo); + +void +panvk_per_arch(cmd_force_fb_preload)(struct panvk_cmd_buffer *cmdbuf, + const VkRenderingInfo *render_info); + +void +panvk_per_arch(cmd_preload_render_area_border)(struct panvk_cmd_buffer *cmdbuf, + const VkRenderingInfo *render_info); + +void panvk_per_arch(cmd_resolve_attachments)(struct panvk_cmd_buffer *cmdbuf); + #endif diff --git a/src/panfrost/vulkan/panvk_vX_cmd_draw.c b/src/panfrost/vulkan/panvk_vX_cmd_draw.c new file mode 100644 index 00000000000..953b5b1b98a --- /dev/null +++ b/src/panfrost/vulkan/panvk_vX_cmd_draw.c @@ -0,0 +1,549 @@ +/* + * Copyright © 2024 Collabora Ltd. + * Copyright © 2024 Arm Ltd. + * + * SPDX-License-Identifier: MIT + */ + +#include "panvk_buffer.h" +#include "panvk_cmd_buffer.h" +#include "panvk_cmd_meta.h" +#include "panvk_entrypoints.h" + +static void +render_state_set_color_attachment(struct panvk_cmd_buffer *cmdbuf, + const VkRenderingAttachmentInfo *att, + uint32_t index) +{ + struct panvk_physical_device *phys_dev = + to_panvk_physical_device(cmdbuf->vk.base.device->physical); + struct panvk_cmd_graphics_state *state = &cmdbuf->state.gfx; + struct pan_fb_info *fbinfo = &state->render.fb.info; + VK_FROM_HANDLE(panvk_image_view, iview, att->imageView); + struct panvk_image *img = + container_of(iview->vk.image, struct panvk_image, vk); + + state->render.bound_attachments |= MESA_VK_RP_ATTACHMENT_COLOR_BIT(index); + state->render.color_attachments.iviews[index] = iview; + state->render.color_attachments.fmts[index] = iview->vk.format; + state->render.color_attachments.samples[index] = img->vk.samples; + +#if PAN_ARCH <= 7 + state->render.fb.bos[state->render.fb.bo_count++] = img->bo; +#endif + + fbinfo->rts[index].view = &iview->pview; + fbinfo->rts[index].crc_valid = &state->render.fb.crc_valid[index]; + 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[index].clear = true; + pan_pack_color(phys_dev->formats.blendable, + fbinfo->rts[index].clear_value, col, fmt, false); + } else if (att->loadOp == VK_ATTACHMENT_LOAD_OP_LOAD) { + fbinfo->rts[index].preload = true; + } + + if (att->resolveMode != VK_RESOLVE_MODE_NONE) { + struct panvk_resolve_attachment *resolve_info = + &state->render.color_attachments.resolve[index]; + VK_FROM_HANDLE(panvk_image_view, resolve_iview, att->resolveImageView); + + resolve_info->mode = att->resolveMode; + resolve_info->dst_iview = resolve_iview; + } +} + +static void +render_state_set_z_attachment(struct panvk_cmd_buffer *cmdbuf, + const VkRenderingAttachmentInfo *att) +{ + struct panvk_cmd_graphics_state *state = &cmdbuf->state.gfx; + struct pan_fb_info *fbinfo = &state->render.fb.info; + VK_FROM_HANDLE(panvk_image_view, iview, att->imageView); + struct panvk_image *img = + container_of(iview->vk.image, struct panvk_image, vk); + +#if PAN_ARCH <= 7 + state->render.fb.bos[state->render.fb.bo_count++] = img->bo; +#endif + + state->render.z_attachment.fmt = iview->vk.format; + state->render.bound_attachments |= MESA_VK_RP_ATTACHMENT_DEPTH_BIT; + fbinfo->zs.view.zs = &iview->pview; + fbinfo->nr_samples = + MAX2(fbinfo->nr_samples, pan_image_view_get_nr_samples(&iview->pview)); + state->render.z_attachment.iview = iview; + + if (vk_format_has_stencil(img->vk.format)) + fbinfo->zs.preload.s = true; + + 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 (att->resolveMode != VK_RESOLVE_MODE_NONE) { + struct panvk_resolve_attachment *resolve_info = + &state->render.z_attachment.resolve; + VK_FROM_HANDLE(panvk_image_view, resolve_iview, att->resolveImageView); + + resolve_info->mode = att->resolveMode; + resolve_info->dst_iview = resolve_iview; + } +} + +static void +render_state_set_s_attachment(struct panvk_cmd_buffer *cmdbuf, + const VkRenderingAttachmentInfo *att) +{ + struct panvk_cmd_graphics_state *state = &cmdbuf->state.gfx; + struct pan_fb_info *fbinfo = &state->render.fb.info; + VK_FROM_HANDLE(panvk_image_view, iview, att->imageView); + struct panvk_image *img = + container_of(iview->vk.image, struct panvk_image, vk); + +#if PAN_ARCH <= 7 + state->render.fb.bos[state->render.fb.bo_count++] = img->bo; +#endif + + state->render.s_attachment.fmt = iview->vk.format; + state->render.bound_attachments |= MESA_VK_RP_ATTACHMENT_STENCIL_BIT; + + if (drm_is_afbc(img->pimage.layout.modifier)) { + assert(fbinfo->zs.view.zs == &iview->pview || !fbinfo->zs.view.zs); + fbinfo->zs.view.zs = &iview->pview; + } else { + fbinfo->zs.view.s = + &iview->pview != fbinfo->zs.view.zs ? &iview->pview : NULL; + } + + fbinfo->zs.view.s = + &iview->pview != fbinfo->zs.view.zs ? &iview->pview : NULL; + fbinfo->nr_samples = + MAX2(fbinfo->nr_samples, pan_image_view_get_nr_samples(&iview->pview)); + state->render.s_attachment.iview = iview; + + if (vk_format_has_depth(img->vk.format)) { + assert(fbinfo->zs.view.zs == NULL || &iview->pview == fbinfo->zs.view.zs); + fbinfo->zs.view.zs = &iview->pview; + + fbinfo->zs.preload.s = false; + fbinfo->zs.clear.s = false; + if (!fbinfo->zs.clear.z) + fbinfo->zs.preload.z = true; + } + + if (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; + } + + if (att->resolveMode != VK_RESOLVE_MODE_NONE) { + struct panvk_resolve_attachment *resolve_info = + &state->render.s_attachment.resolve; + VK_FROM_HANDLE(panvk_image_view, resolve_iview, att->resolveImageView); + + resolve_info->mode = att->resolveMode; + resolve_info->dst_iview = resolve_iview; + } +} + +void +panvk_per_arch(cmd_init_render_state)(struct panvk_cmd_buffer *cmdbuf, + const VkRenderingInfo *pRenderingInfo) +{ + struct panvk_physical_device *phys_dev = + to_panvk_physical_device(cmdbuf->vk.base.device->physical); + struct panvk_cmd_graphics_state *state = &cmdbuf->state.gfx; + struct pan_fb_info *fbinfo = &state->render.fb.info; + uint32_t att_width = 0, att_height = 0; + + state->render.flags = pRenderingInfo->flags; + + BITSET_SET(state->dirty, PANVK_CMD_GRAPHICS_DIRTY_RENDER_STATE); + +#if PAN_ARCH <= 7 + state->render.fb.bo_count = 0; + memset(state->render.fb.bos, 0, sizeof(state->render.fb.bos)); +#endif + + memset(state->render.fb.crc_valid, 0, sizeof(state->render.fb.crc_valid)); + memset(&state->render.color_attachments, 0, + sizeof(state->render.color_attachments)); + memset(&state->render.z_attachment, 0, sizeof(state->render.z_attachment)); + memset(&state->render.s_attachment, 0, sizeof(state->render.s_attachment)); + state->render.bound_attachments = 0; + + state->render.layer_count = pRenderingInfo->layerCount; + *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; + + render_state_set_color_attachment(cmdbuf, att, i); + att_width = MAX2(iview->vk.extent.width, att_width); + att_height = MAX2(iview->vk.extent.height, att_height); + } + + if (pRenderingInfo->pDepthAttachment && + pRenderingInfo->pDepthAttachment->imageView != VK_NULL_HANDLE) { + const VkRenderingAttachmentInfo *att = pRenderingInfo->pDepthAttachment; + VK_FROM_HANDLE(panvk_image_view, iview, att->imageView); + + if (iview && (iview->vk.aspects & VK_IMAGE_ASPECT_DEPTH_BIT)) { + render_state_set_z_attachment(cmdbuf, att); + att_width = MAX2(iview->vk.extent.width, att_width); + att_height = MAX2(iview->vk.extent.height, att_height); + } + } + + if (pRenderingInfo->pStencilAttachment && + pRenderingInfo->pStencilAttachment->imageView != VK_NULL_HANDLE) { + const VkRenderingAttachmentInfo *att = pRenderingInfo->pStencilAttachment; + VK_FROM_HANDLE(panvk_image_view, iview, att->imageView); + + if (iview && (iview->vk.aspects & VK_IMAGE_ASPECT_STENCIL_BIT)) { + render_state_set_s_attachment(cmdbuf, att); + att_width = MAX2(iview->vk.extent.width, att_width); + att_height = MAX2(iview->vk.extent.height, att_height); + } + } + + if (fbinfo->zs.view.zs) { + const struct util_format_description *fdesc = + util_format_description(fbinfo->zs.view.zs->format); + bool needs_depth = fbinfo->zs.clear.z | fbinfo->zs.preload.z | + util_format_has_depth(fdesc); + bool needs_stencil = fbinfo->zs.clear.s | fbinfo->zs.preload.s | + util_format_has_stencil(fdesc); + enum pipe_format new_fmt = + util_format_get_blocksize(fbinfo->zs.view.zs->format) == 4 + ? PIPE_FORMAT_Z24_UNORM_S8_UINT + : PIPE_FORMAT_Z32_FLOAT_S8X24_UINT; + + if (needs_depth && needs_stencil && + fbinfo->zs.view.zs->format != new_fmt) { + state->render.zs_pview = *fbinfo->zs.view.zs; + state->render.zs_pview.format = new_fmt; + fbinfo->zs.view.zs = &state->render.zs_pview; + } + } + + fbinfo->extent.minx = pRenderingInfo->renderArea.offset.x; + fbinfo->extent.maxx = pRenderingInfo->renderArea.offset.x + + pRenderingInfo->renderArea.extent.width - 1; + fbinfo->extent.miny = pRenderingInfo->renderArea.offset.y; + fbinfo->extent.maxy = pRenderingInfo->renderArea.offset.y + + pRenderingInfo->renderArea.extent.height - 1; + + if (state->render.bound_attachments) { + fbinfo->width = att_width; + fbinfo->height = att_height; + } else { + fbinfo->width = fbinfo->extent.maxx + 1; + fbinfo->height = fbinfo->extent.maxy + 1; + } + + assert(fbinfo->width && fbinfo->height); +} + +void +panvk_per_arch(cmd_resolve_attachments)(struct panvk_cmd_buffer *cmdbuf) +{ + struct pan_fb_info *fbinfo = &cmdbuf->state.gfx.render.fb.info; + bool needs_resolve = false; + + unsigned bound_atts = cmdbuf->state.gfx.render.bound_attachments; + unsigned color_att_count = + util_last_bit(bound_atts & MESA_VK_RP_ATTACHMENT_ANY_COLOR_BITS); + VkRenderingAttachmentInfo color_atts[MAX_RTS]; + for (uint32_t i = 0; i < color_att_count; i++) { + const struct panvk_resolve_attachment *resolve_info = + &cmdbuf->state.gfx.render.color_attachments.resolve[i]; + struct panvk_image_view *src_iview = + cmdbuf->state.gfx.render.color_attachments.iviews[i]; + + color_atts[i] = (VkRenderingAttachmentInfo){ + .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, + .imageView = panvk_image_view_to_handle(src_iview), + .imageLayout = VK_IMAGE_LAYOUT_GENERAL, + .resolveMode = resolve_info->mode, + .resolveImageView = + panvk_image_view_to_handle(resolve_info->dst_iview), + .resolveImageLayout = VK_IMAGE_LAYOUT_GENERAL, + }; + + if (resolve_info->mode != VK_RESOLVE_MODE_NONE) + needs_resolve = true; + } + + const struct panvk_resolve_attachment *resolve_info = + &cmdbuf->state.gfx.render.z_attachment.resolve; + struct panvk_image_view *src_iview = + cmdbuf->state.gfx.render.z_attachment.iview; + VkRenderingAttachmentInfo z_att = { + .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, + .imageView = panvk_image_view_to_handle(src_iview), + .imageLayout = VK_IMAGE_LAYOUT_GENERAL, + .resolveMode = resolve_info->mode, + .resolveImageView = panvk_image_view_to_handle(resolve_info->dst_iview), + .resolveImageLayout = VK_IMAGE_LAYOUT_GENERAL, + }; + + if (resolve_info->mode != VK_RESOLVE_MODE_NONE) + needs_resolve = true; + + resolve_info = &cmdbuf->state.gfx.render.s_attachment.resolve; + src_iview = cmdbuf->state.gfx.render.s_attachment.iview; + + VkRenderingAttachmentInfo s_att = { + .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, + .imageView = panvk_image_view_to_handle(src_iview), + .imageLayout = VK_IMAGE_LAYOUT_GENERAL, + .resolveMode = resolve_info->mode, + .resolveImageView = panvk_image_view_to_handle(resolve_info->dst_iview), + .resolveImageLayout = VK_IMAGE_LAYOUT_GENERAL, + }; + + if (resolve_info->mode != VK_RESOLVE_MODE_NONE) + needs_resolve = true; + + if (!needs_resolve) + return; + +#if PAN_ARCH >= 10 + /* insert a barrier for resolve */ + const VkMemoryBarrier2 mem_barrier = { + .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2, + .srcStageMask = VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT | + VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT | + VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, + .srcAccessMask = VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT | + VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, + .dstStageMask = VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT, + .dstAccessMask = VK_ACCESS_2_SHADER_SAMPLED_READ_BIT + }; + const VkDependencyInfo dep_info = { + .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO, + .memoryBarrierCount = 1, + .pMemoryBarriers = &mem_barrier, + }; + panvk_per_arch(CmdPipelineBarrier2)(panvk_cmd_buffer_to_handle(cmdbuf), + &dep_info); +#endif + + const VkRenderingInfo render_info = { + .sType = VK_STRUCTURE_TYPE_RENDERING_INFO, + .renderArea = + { + .offset.x = fbinfo->extent.minx, + .offset.y = fbinfo->extent.miny, + .extent.width = fbinfo->extent.maxx - fbinfo->extent.minx + 1, + .extent.height = fbinfo->extent.maxy - fbinfo->extent.miny + 1, + }, + .layerCount = cmdbuf->state.gfx.render.layer_count, + .viewMask = 0, + .colorAttachmentCount = color_att_count, + .pColorAttachments = color_atts, + .pDepthAttachment = &z_att, + .pStencilAttachment = &s_att, + }; + + struct panvk_device *dev = to_panvk_device(cmdbuf->vk.base.device); + struct panvk_cmd_meta_graphics_save_ctx save = {0}; + + panvk_per_arch(cmd_meta_gfx_start)(cmdbuf, &save); + vk_meta_resolve_rendering(&cmdbuf->vk, &dev->meta, &render_info); + panvk_per_arch(cmd_meta_gfx_end)(cmdbuf, &save); +} + +void +panvk_per_arch(cmd_force_fb_preload)(struct panvk_cmd_buffer *cmdbuf, + const VkRenderingInfo *render_info) +{ + /* We force preloading for all active attachments when the render area is + * unaligned or when a barrier flushes prior draw calls in the middle of a + * render pass. The two cases can be distinguished by whether a + * render_info is provided. + * + * When the render area is unaligned, we force preloading to preserve + * contents falling outside of the render area. We also make sure the + * initial attachment clears are performed. + */ + struct panvk_cmd_graphics_state *state = &cmdbuf->state.gfx; + struct pan_fb_info *fbinfo = &state->render.fb.info; + VkClearAttachment clear_atts[MAX_RTS + 2]; + uint32_t clear_att_count = 0; + + if (!state->render.bound_attachments) + return; + + for (unsigned i = 0; i < fbinfo->rt_count; i++) { + if (!fbinfo->rts[i].view) + continue; + + fbinfo->rts[i].preload = true; + + if (fbinfo->rts[i].clear) { + if (render_info) { + const VkRenderingAttachmentInfo *att = + &render_info->pColorAttachments[i]; + + clear_atts[clear_att_count++] = (VkClearAttachment){ + .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, + .colorAttachment = i, + .clearValue = att->clearValue, + }; + } + fbinfo->rts[i].clear = false; + } + } + + if (fbinfo->zs.view.zs) { + fbinfo->zs.preload.z = true; + + if (fbinfo->zs.clear.z) { + if (render_info) { + const VkRenderingAttachmentInfo *att = + render_info->pDepthAttachment; + + clear_atts[clear_att_count++] = (VkClearAttachment){ + .aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT, + .clearValue = att->clearValue, + }; + } + fbinfo->zs.clear.z = false; + } + } + + if (fbinfo->zs.view.s || + (fbinfo->zs.view.zs && + util_format_is_depth_and_stencil(fbinfo->zs.view.zs->format))) { + fbinfo->zs.preload.s = true; + + if (fbinfo->zs.clear.s) { + if (render_info) { + const VkRenderingAttachmentInfo *att = + render_info->pStencilAttachment; + + clear_atts[clear_att_count++] = (VkClearAttachment){ + .aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT, + .clearValue = att->clearValue, + }; + } + + fbinfo->zs.clear.s = false; + } + } + +#if PAN_ARCH >= 10 + /* insert a barrier for preload */ + const VkMemoryBarrier2 mem_barrier = { + .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2, + .srcStageMask = VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT | + VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT | + VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, + .srcAccessMask = VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT | + VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, + .dstStageMask = VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT, + .dstAccessMask = VK_ACCESS_2_SHADER_SAMPLED_READ_BIT, + }; + const VkDependencyInfo dep_info = { + .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO, + .memoryBarrierCount = 1, + .pMemoryBarriers = &mem_barrier, + }; + panvk_per_arch(CmdPipelineBarrier2)(panvk_cmd_buffer_to_handle(cmdbuf), + &dep_info); +#endif + + if (clear_att_count && render_info) { + VkClearRect clear_rect = { + .rect = render_info->renderArea, + .baseArrayLayer = 0, + .layerCount = render_info->layerCount, + }; + + panvk_per_arch(CmdClearAttachments)(panvk_cmd_buffer_to_handle(cmdbuf), + clear_att_count, clear_atts, 1, + &clear_rect); + } +} + +void +panvk_per_arch(cmd_preload_render_area_border)( + struct panvk_cmd_buffer *cmdbuf, const VkRenderingInfo *render_info) +{ + struct panvk_cmd_graphics_state *state = &cmdbuf->state.gfx; + struct pan_fb_info *fbinfo = &state->render.fb.info; + bool render_area_is_32x32_aligned = + ((fbinfo->extent.minx | fbinfo->extent.miny) % 32) == 0 && + (fbinfo->extent.maxx + 1 == fbinfo->width || + (fbinfo->extent.maxx % 32) == 31) && + (fbinfo->extent.maxy + 1 == fbinfo->height || + (fbinfo->extent.maxy % 32) == 31); + + /* If the render area is aligned on a 32x32 section, we're good. */ + if (!render_area_is_32x32_aligned) + panvk_per_arch(cmd_force_fb_preload)(cmdbuf, render_info); +} + +VKAPI_ATTR void VKAPI_CALL +panvk_per_arch(CmdBindVertexBuffers)(VkCommandBuffer commandBuffer, + uint32_t firstBinding, + uint32_t bindingCount, + const VkBuffer *pBuffers, + const VkDeviceSize *pOffsets) +{ + VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer); + + assert(firstBinding + bindingCount <= MAX_VBS); + + for (uint32_t i = 0; i < bindingCount; i++) { + VK_FROM_HANDLE(panvk_buffer, buffer, pBuffers[i]); + + cmdbuf->state.gfx.vb.bufs[firstBinding + i].address = + panvk_buffer_gpu_ptr(buffer, pOffsets[i]); + cmdbuf->state.gfx.vb.bufs[firstBinding + i].size = + panvk_buffer_range(buffer, pOffsets[i], VK_WHOLE_SIZE); + } + + cmdbuf->state.gfx.vb.count = + MAX2(cmdbuf->state.gfx.vb.count, firstBinding + bindingCount); + gfx_state_set_dirty(cmdbuf, VB); +} + +VKAPI_ATTR void VKAPI_CALL +panvk_per_arch(CmdBindIndexBuffer)(VkCommandBuffer commandBuffer, + VkBuffer buffer, VkDeviceSize offset, + VkIndexType indexType) +{ + VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer); + VK_FROM_HANDLE(panvk_buffer, buf, buffer); + + cmdbuf->state.gfx.ib.buffer = buf; + cmdbuf->state.gfx.ib.offset = offset; + cmdbuf->state.gfx.ib.index_size = vk_index_type_to_bytes(indexType); + gfx_state_set_dirty(cmdbuf, IB); +}