From 02b95befed8daa320a2b22d09823ad3ef9070537 Mon Sep 17 00:00:00 2001 From: Iago Toral Quiroga Date: Wed, 14 Dec 2022 10:03:38 +0100 Subject: [PATCH] v3dv: always store/restore attachment state during meta operations MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit attachment state is only relevant during render passes, however, there is a corner case: if we can't resolve an attachment in a subpass using the hardware, we emit a manual image resolve in the driver which can trigger a meta operation via blit. In this case, we pretend we are not in a render pass (since vulkan disallows blits/resolves in a render pass) but we really want to keep the attachment state after the meta operation. Fixes some of the issues we have with CTS 1.3.4 in: dEQP-VK.pipeline.monolithic.multisample.misc.* Reviewed-by: Alejandro Piñeiro Part-of: (cherry picked from commit 6117f855ee700e7addc14be64b8370f9b91a2120) --- .pick_status.json | 2 +- src/broadcom/vulkan/v3dv_cmd_buffer.c | 70 ++++++++++++++++++++--------------- 2 files changed, 42 insertions(+), 30 deletions(-) diff --git a/.pick_status.json b/.pick_status.json index 31959ef..79e9189 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -2569,7 +2569,7 @@ "description": "v3dv: always store/restore attachment state during meta operations", "nominated": false, "nomination_type": null, - "resolution": 4, + "resolution": 1, "main_sha": null, "because_sha": null }, diff --git a/src/broadcom/vulkan/v3dv_cmd_buffer.c b/src/broadcom/vulkan/v3dv_cmd_buffer.c index 0bba41e..d3d344c 100644 --- a/src/broadcom/vulkan/v3dv_cmd_buffer.c +++ b/src/broadcom/vulkan/v3dv_cmd_buffer.c @@ -2400,32 +2400,43 @@ v3dv_cmd_buffer_meta_state_push(struct v3dv_cmd_buffer *cmd_buffer, { struct v3dv_cmd_buffer_state *state = &cmd_buffer->state; + /* Attachment state. + * + * We store this state even if we are not currently in a subpass + * (subpass_idx != -1) because we may get here to implement subpass + * resolves via vkCmdResolveImage from + * cmd_buffer_subpass_handle_pending_resolves. In that scenario we pretend + * we are no longer in a subpass because Vulkan disallows image resolves + * via vkCmdResolveImage during subpasses, but we still need to preserve + * attachment state because we may have more subpasses to go through + * after processing resolves in the current subass. + */ + const uint32_t attachment_state_item_size = + sizeof(struct v3dv_cmd_buffer_attachment_state); + const uint32_t attachment_state_total_size = + attachment_state_item_size * state->attachment_alloc_count; + if (state->meta.attachment_alloc_count < state->attachment_alloc_count) { + if (state->meta.attachment_alloc_count > 0) + vk_free(&cmd_buffer->device->vk.alloc, state->meta.attachments); + + state->meta.attachments = vk_zalloc(&cmd_buffer->device->vk.alloc, + attachment_state_total_size, 8, + VK_SYSTEM_ALLOCATION_SCOPE_COMMAND); + if (!state->meta.attachments) { + v3dv_flag_oom(cmd_buffer, NULL); + return; + } + state->meta.attachment_alloc_count = state->attachment_alloc_count; + } + state->meta.attachment_count = state->attachment_alloc_count; + memcpy(state->meta.attachments, state->attachments, + attachment_state_total_size); + if (state->subpass_idx != -1) { state->meta.subpass_idx = state->subpass_idx; state->meta.framebuffer = v3dv_framebuffer_to_handle(state->framebuffer); state->meta.pass = v3dv_render_pass_to_handle(state->pass); - const uint32_t attachment_state_item_size = - sizeof(struct v3dv_cmd_buffer_attachment_state); - const uint32_t attachment_state_total_size = - attachment_state_item_size * state->attachment_alloc_count; - if (state->meta.attachment_alloc_count < state->attachment_alloc_count) { - if (state->meta.attachment_alloc_count > 0) - vk_free(&cmd_buffer->device->vk.alloc, state->meta.attachments); - - state->meta.attachments = vk_zalloc(&cmd_buffer->device->vk.alloc, - attachment_state_total_size, 8, - VK_SYSTEM_ALLOCATION_SCOPE_COMMAND); - if (!state->meta.attachments) { - v3dv_flag_oom(cmd_buffer, NULL); - return; - } - state->meta.attachment_alloc_count = state->attachment_alloc_count; - } - state->meta.attachment_count = state->attachment_alloc_count; - memcpy(state->meta.attachments, state->attachments, - attachment_state_total_size); - state->meta.tile_aligned_render_area = state->tile_aligned_render_area; memcpy(&state->meta.render_area, &state->render_area, sizeof(VkRect2D)); } @@ -2466,18 +2477,19 @@ v3dv_cmd_buffer_meta_state_pop(struct v3dv_cmd_buffer *cmd_buffer, { struct v3dv_cmd_buffer_state *state = &cmd_buffer->state; + /* Attachment state */ + assert(state->meta.attachment_count <= state->attachment_alloc_count); + const uint32_t attachment_state_item_size = + sizeof(struct v3dv_cmd_buffer_attachment_state); + const uint32_t attachment_state_total_size = + attachment_state_item_size * state->meta.attachment_count; + memcpy(state->attachments, state->meta.attachments, + attachment_state_total_size); + if (state->meta.subpass_idx != -1) { state->pass = v3dv_render_pass_from_handle(state->meta.pass); state->framebuffer = v3dv_framebuffer_from_handle(state->meta.framebuffer); - assert(state->meta.attachment_count <= state->attachment_alloc_count); - const uint32_t attachment_state_item_size = - sizeof(struct v3dv_cmd_buffer_attachment_state); - const uint32_t attachment_state_total_size = - attachment_state_item_size * state->meta.attachment_count; - memcpy(state->attachments, state->meta.attachments, - attachment_state_total_size); - state->tile_aligned_render_area = state->meta.tile_aligned_render_area; memcpy(&state->render_area, &state->meta.render_area, sizeof(VkRect2D)); -- 2.7.4