From 5ba7f64b454b78c71be0827c74f37497fd135822 Mon Sep 17 00:00:00 2001 From: Iago Toral Quiroga Date: Thu, 8 Jul 2021 13:13:17 +0200 Subject: [PATCH] v3dv: remove fallback path for vkCmdClearAttachments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now that we support layered clears this code is dead. Reviewed-by: Alejandro PiƱeiro Part-of: --- src/broadcom/vulkan/v3dv_meta_clear.c | 354 -------------------------- 1 file changed, 354 deletions(-) diff --git a/src/broadcom/vulkan/v3dv_meta_clear.c b/src/broadcom/vulkan/v3dv_meta_clear.c index 7bbb4aa50a6..9d6a39e074c 100644 --- a/src/broadcom/vulkan/v3dv_meta_clear.c +++ b/src/broadcom/vulkan/v3dv_meta_clear.c @@ -827,261 +827,6 @@ fail: return result; } -static VkFormat -get_color_format_for_depth_stencil_format(VkFormat format) -{ - /* For single depth/stencil aspect formats, we just choose a compatible - * 1 channel format, but for combined depth/stencil we want an RGBA format - * so we can specify the channels we want to write. - */ - switch (format) { - case VK_FORMAT_D16_UNORM: - return VK_FORMAT_R16_UINT; - case VK_FORMAT_D32_SFLOAT: - return VK_FORMAT_R32_SFLOAT; - case VK_FORMAT_X8_D24_UNORM_PACK32: - case VK_FORMAT_D24_UNORM_S8_UINT: - return VK_FORMAT_R8G8B8A8_UINT; - default: - unreachable("Unsupported depth/stencil format"); - }; -} - -/** - * Emits a scissored quad in the clear color, however, unlike the subpass - * versions, this creates its own framebuffer setup with a single color - * attachment, and therefore spanws new jobs, making it much slower than the - * subpass version. - * - * This path is only used when we have clears on layers other than the - * base layer in a framebuffer attachment, since we don't currently - * support any form of layered rendering that would allow us to implement - * this in the subpass version. - * - * Notice this can also handle depth/stencil formats by rendering to the - * depth/stencil target using a compatible color format. - */ -static void -emit_color_clear_rect(struct v3dv_cmd_buffer *cmd_buffer, - uint32_t attachment_idx, - VkFormat rt_format, - uint32_t rt_samples, - uint32_t rt_components, - VkClearColorValue clear_color, - const VkClearRect *rect) -{ - assert(cmd_buffer->state.pass); - struct v3dv_device *device = cmd_buffer->device; - struct v3dv_render_pass *pass = cmd_buffer->state.pass; - - assert(attachment_idx != VK_ATTACHMENT_UNUSED && - attachment_idx < pass->attachment_count); - - struct v3dv_meta_color_clear_pipeline *pipeline = NULL; - VkResult result = - get_color_clear_pipeline(device, - NULL, 0, /* Not using current subpass */ - 0, attachment_idx, - rt_format, rt_samples, rt_components, false, - &pipeline); - if (result != VK_SUCCESS) { - if (result == VK_ERROR_OUT_OF_HOST_MEMORY) - v3dv_flag_oom(cmd_buffer, NULL); - return; - } - assert(pipeline && pipeline->pipeline && pipeline->pass); - - /* Since we are not emitting the draw call in the current subpass we should - * be caching the clear pipeline and we don't have to take care of destorying - * it below. - */ - assert(pipeline->cached); - - /* Store command buffer state for the current subpass before we interrupt - * it to emit the color clear pass and then finish the job for the - * interrupted subpass. - */ - v3dv_cmd_buffer_meta_state_push(cmd_buffer, false); - v3dv_cmd_buffer_finish_job(cmd_buffer); - - struct v3dv_framebuffer *subpass_fb = - v3dv_framebuffer_from_handle(cmd_buffer->state.meta.framebuffer); - VkCommandBuffer cmd_buffer_handle = v3dv_cmd_buffer_to_handle(cmd_buffer); - VkDevice device_handle = v3dv_device_to_handle(cmd_buffer->device); - - /* If we are clearing a depth/stencil attachment as a color attachment - * then we need to configure the framebuffer to the compatible color - * format. - */ - const struct v3dv_image_view *att_iview = - subpass_fb->attachments[attachment_idx]; - const bool is_depth_or_stencil = - vk_format_is_depth_or_stencil(att_iview->vk_format); - - /* Emit the pass for each attachment layer, which creates a framebuffer - * for each selected layer of the attachment and then renders a scissored - * quad in the clear color. - */ - uint32_t dirty_dynamic_state = 0; - for (uint32_t i = 0; i < rect->layerCount; i++) { - VkImageViewCreateInfo fb_layer_view_info = { - .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, - .image = v3dv_image_to_handle((struct v3dv_image *)att_iview->image), - .viewType = - v3dv_image_type_to_view_type(att_iview->image->type), - .format = is_depth_or_stencil ? rt_format : att_iview->vk_format, - .subresourceRange = { - .aspectMask = is_depth_or_stencil ? VK_IMAGE_ASPECT_COLOR_BIT : - att_iview->aspects, - .baseMipLevel = att_iview->base_level, - .levelCount = att_iview->max_level - att_iview->base_level + 1, - .baseArrayLayer = att_iview->first_layer + rect->baseArrayLayer + i, - .layerCount = 1, - }, - }; - VkImageView fb_attachment; - result = v3dv_CreateImageView(v3dv_device_to_handle(device), - &fb_layer_view_info, - &device->vk.alloc, &fb_attachment); - if (result != VK_SUCCESS) - goto fail; - - v3dv_cmd_buffer_add_private_obj( - cmd_buffer, (uintptr_t)fb_attachment, - (v3dv_cmd_buffer_private_obj_destroy_cb)v3dv_DestroyImageView); - - VkFramebufferCreateInfo fb_info = { - .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, - .renderPass = v3dv_render_pass_to_handle(pass), - .attachmentCount = 1, - .pAttachments = &fb_attachment, - .width = subpass_fb->width, - .height = subpass_fb->height, - .layers = 1, - }; - - VkFramebuffer fb; - result = v3dv_CreateFramebuffer(device_handle, &fb_info, - &cmd_buffer->device->vk.alloc, &fb); - if (result != VK_SUCCESS) - goto fail; - - v3dv_cmd_buffer_add_private_obj( - cmd_buffer, (uintptr_t)fb, - (v3dv_cmd_buffer_private_obj_destroy_cb)v3dv_DestroyFramebuffer); - - VkRenderPassBeginInfo rp_info = { - .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, - .renderPass = pipeline->pass, - .framebuffer = fb, - .renderArea = { - .offset = { rect->rect.offset.x, rect->rect.offset.y }, - .extent = { rect->rect.extent.width, rect->rect.extent.height } }, - .clearValueCount = 0, - }; - - v3dv_CmdBeginRenderPass(cmd_buffer_handle, &rp_info, - VK_SUBPASS_CONTENTS_INLINE); - - struct v3dv_job *job = cmd_buffer->state.job; - if (!job) - goto fail; - job->is_subpass_continue = true; - - v3dv_CmdPushConstants(cmd_buffer_handle, - device->meta.color_clear.p_layout, - VK_SHADER_STAGE_FRAGMENT_BIT, 0, 16, - &clear_color); - - v3dv_CmdBindPipeline(cmd_buffer_handle, - VK_PIPELINE_BIND_POINT_GRAPHICS, - pipeline->pipeline); - - const VkViewport viewport = { - .x = rect->rect.offset.x, - .y = rect->rect.offset.y, - .width = rect->rect.extent.width, - .height = rect->rect.extent.height, - .minDepth = 0.0f, - .maxDepth = 1.0f - }; - v3dv_CmdSetViewport(cmd_buffer_handle, 0, 1, &viewport); - v3dv_CmdSetScissor(cmd_buffer_handle, 0, 1, &rect->rect); - - v3dv_CmdDraw(cmd_buffer_handle, 4, 1, 0, 0); - - v3dv_CmdEndRenderPass(cmd_buffer_handle); - } - - /* The clear pipeline sets viewport and scissor state, so we need - * to restore it - */ - dirty_dynamic_state = V3DV_CMD_DIRTY_VIEWPORT | V3DV_CMD_DIRTY_SCISSOR; - -fail: - v3dv_cmd_buffer_meta_state_pop(cmd_buffer, dirty_dynamic_state, true); -} - -static void -emit_ds_clear_rect(struct v3dv_cmd_buffer *cmd_buffer, - VkImageAspectFlags aspects, - uint32_t attachment_idx, - VkClearDepthStencilValue clear_ds, - const VkClearRect *rect) -{ - assert(cmd_buffer->state.pass); - assert(attachment_idx != VK_ATTACHMENT_UNUSED); - assert(attachment_idx < cmd_buffer->state.pass->attachment_count); - - VkFormat format = - cmd_buffer->state.pass->attachments[attachment_idx].desc.format; - assert ((aspects & ~vk_format_aspects(format)) == 0); - - uint32_t samples = - cmd_buffer->state.pass->attachments[attachment_idx].desc.samples; - - enum pipe_format pformat = vk_format_to_pipe_format(format); - VkClearColorValue clear_color; - uint32_t clear_zs = - util_pack_z_stencil(pformat, clear_ds.depth, clear_ds.stencil); - - /* We implement depth/stencil clears by turning them into color clears - * with a compatible color format. - */ - VkFormat color_format = get_color_format_for_depth_stencil_format(format); - - uint32_t comps; - if (color_format == VK_FORMAT_R8G8B8A8_UINT) { - /* We are clearing a D24 format so we need to select the channels that we - * are being asked to clear to avoid clearing aspects that should be - * preserved. Also, the hardware uses the MSB channels to store the D24 - * component, so we need to shift the components in the clear value to - * match that. - */ - comps = 0; - if (aspects & VK_IMAGE_ASPECT_STENCIL_BIT) { - comps |= VK_COLOR_COMPONENT_R_BIT; - clear_color.uint32[0] = clear_zs >> 24; - } - if (aspects & VK_IMAGE_ASPECT_DEPTH_BIT) { - comps |= VK_COLOR_COMPONENT_G_BIT | - VK_COLOR_COMPONENT_B_BIT | - VK_COLOR_COMPONENT_A_BIT; - clear_color.uint32[1] = (clear_zs >> 0) & 0xff; - clear_color.uint32[2] = (clear_zs >> 8) & 0xff; - clear_color.uint32[3] = (clear_zs >> 16) & 0xff; - } - } else { - /* For anything else we use a single component format */ - comps = VK_COLOR_COMPONENT_R_BIT; - clear_color.uint32[0] = clear_zs; - } - - emit_color_clear_rect(cmd_buffer, attachment_idx, - color_format, samples, comps, - clear_color, rect); -} - /* Emits a scissored quad in the clear color */ static void emit_subpass_color_clear_rects(struct v3dv_cmd_buffer *cmd_buffer, @@ -1274,44 +1019,6 @@ emit_subpass_ds_clear_rects(struct v3dv_cmd_buffer *cmd_buffer, v3dv_cmd_buffer_meta_state_pop(cmd_buffer, dynamic_states, false); } -static bool -is_subrect(const VkRect2D *r0, const VkRect2D *r1) -{ - return r0->offset.x <= r1->offset.x && - r0->offset.y <= r1->offset.y && - r0->offset.x + r0->extent.width >= r1->offset.x + r1->extent.width && - r0->offset.y + r0->extent.height >= r1->offset.y + r1->extent.height; -} - -static bool -can_use_tlb_clear(struct v3dv_cmd_buffer *cmd_buffer, - uint32_t rect_count, - const VkClearRect* rects) -{ - const struct v3dv_framebuffer *framebuffer = cmd_buffer->state.framebuffer; - - const VkRect2D *render_area = &cmd_buffer->state.render_area; - - /* Check if we are clearing a single region covering the entire framebuffer - * and that we are not constrained by the current render area. - * - * From the Vulkan 1.0 spec: - * - * "The vkCmdClearAttachments command is not affected by the bound - * pipeline state." - * - * So we can ignore scissor and viewport state for this check. - */ - const VkRect2D fb_rect = { - { 0, 0 }, - { framebuffer->width, framebuffer->height } - }; - - return rect_count == 1 && - is_subrect(&rects[0].rect, &fb_rect) && - is_subrect(render_area, &fb_rect); -} - static void handle_deferred_clear_attachments(struct v3dv_cmd_buffer *cmd_buffer, uint32_t attachmentCount, @@ -1438,65 +1145,4 @@ v3dv_CmdClearAttachments(VkCommandBuffer commandBuffer, rectCount, pRects); } } - return; - - perf_debug("Falling back to slow path for vkCmdClearAttachments due to " - "clearing layers other than the base array layer.\n"); - - /* If we can't handle this as a draw call inside the current job then we - * will have to spawn jobs for the clears, which will be slow. In that case, - * try to use the TLB to clear if possible. - */ - if (can_use_tlb_clear(cmd_buffer, rectCount, pRects)) { - v3dv_X(cmd_buffer->device, cmd_buffer_emit_tlb_clear) - (cmd_buffer, attachmentCount, pAttachments, - pRects[0].baseArrayLayer, pRects[0].layerCount); - return; - } - - /* Otherwise, fall back to drawing rects with the clear value using a - * separate job. This is the slowest path. - */ - for (uint32_t i = 0; i < attachmentCount; i++) { - uint32_t attachment_idx = VK_ATTACHMENT_UNUSED; - - if (pAttachments[i].aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) { - uint32_t rt_idx = pAttachments[i].colorAttachment; - attachment_idx = subpass->color_attachments[rt_idx].attachment; - } else if (pAttachments[i].aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | - VK_IMAGE_ASPECT_STENCIL_BIT)) { - attachment_idx = subpass->ds_attachment.attachment; - } - - if (attachment_idx == VK_ATTACHMENT_UNUSED) - continue; - - if (pAttachments[i].aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) { - const uint32_t components = VK_COLOR_COMPONENT_R_BIT | - VK_COLOR_COMPONENT_G_BIT | - VK_COLOR_COMPONENT_B_BIT | - VK_COLOR_COMPONENT_A_BIT; - const uint32_t samples = - cmd_buffer->state.pass->attachments[attachment_idx].desc.samples; - const VkFormat format = - cmd_buffer->state.pass->attachments[attachment_idx].desc.format; - for (uint32_t j = 0; j < rectCount; j++) { - emit_color_clear_rect(cmd_buffer, - attachment_idx, - format, - samples, - components, - pAttachments[i].clearValue.color, - &pRects[j]); - } - } else { - for (uint32_t j = 0; j < rectCount; j++) { - emit_ds_clear_rect(cmd_buffer, - pAttachments[i].aspectMask, - attachment_idx, - pAttachments[i].clearValue.depthStencil, - &pRects[j]); - } - } - } }