diff --git a/.pick_status.json b/.pick_status.json index 845451c2623..a35f09b8d4b 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -3010,7 +3010,7 @@ "description": "radv: fix multiple resolves in the same subpass", "nominated": true, "nomination_type": 0, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": null }, diff --git a/src/amd/vulkan/radv_meta_resolve.c b/src/amd/vulkan/radv_meta_resolve.c index 6d3727d2f19..947afdef83f 100644 --- a/src/amd/vulkan/radv_meta_resolve.c +++ b/src/amd/vulkan/radv_meta_resolve.c @@ -510,10 +510,14 @@ resolve_image(struct radv_cmd_buffer *cmd_buffer, struct radv_image *src_image, dst_image_layout, region); break; case RESOLVE_FRAGMENT: + radv_decompress_resolve_src(cmd_buffer, src_image, src_image_layout, region); + radv_meta_resolve_fragment_image(cmd_buffer, src_image, src_image_layout, dst_image, dst_image_layout, region); break; case RESOLVE_COMPUTE: + radv_decompress_resolve_src(cmd_buffer, src_image, src_image_layout, region); + radv_meta_resolve_compute_image(cmd_buffer, src_image, src_image->vk.format, src_image_layout, dst_image, dst_image->vk.format, dst_image_layout, region); break; @@ -732,11 +736,28 @@ radv_cmd_buffer_resolve_rendering(struct radv_cmd_buffer *cmd_buffer) } if (has_color_resolve) { + uint32_t layer_count = render->layer_count; + VkRect2D resolve_area = render->area; + struct radv_resolve_barrier barrier; + + if (render->view_mask) + layer_count = util_last_bit(render->view_mask); + + /* Resolves happen before the end-of-subpass barriers get executed, so we have to make the + * attachment shader-readable. + */ + barrier.src_stage_mask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT; + barrier.dst_stage_mask = VK_PIPELINE_STAGE_2_RESOLVE_BIT; + barrier.src_access_mask = VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT; + barrier.dst_access_mask = VK_ACCESS_2_SHADER_READ_BIT | VK_ACCESS_2_SHADER_WRITE_BIT; + radv_emit_resolve_barrier(cmd_buffer, &barrier); + for (uint32_t i = 0; i < render->color_att_count; ++i) { if (render->color_att[i].resolve_iview == NULL) continue; struct radv_image_view *src_iview = render->color_att[i].iview; + VkImageLayout src_layout = render->color_att[i].layout; struct radv_image *src_img = src_iview->image; struct radv_image_view *dst_iview = render->color_att[i].resolve_iview; VkImageLayout dst_layout = render->color_att[i].resolve_layout; @@ -745,24 +766,50 @@ radv_cmd_buffer_resolve_rendering(struct radv_cmd_buffer *cmd_buffer) radv_pick_resolve_method_images(cmd_buffer->device, src_img, src_iview->vk.format, dst_img, dst_iview->vk.base_mip_level, dst_layout, cmd_buffer, &resolve_method); + VkImageResolve2 region = { + .sType = VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2, + .extent = { + .width = resolve_area.extent.width, + .height = resolve_area.extent.height, + .depth = 1, + }, + .srcSubresource = + (VkImageSubresourceLayers){ + .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, + .mipLevel = src_iview->vk.base_mip_level, + .baseArrayLayer = src_iview->vk.base_array_layer, + .layerCount = layer_count, + }, + .dstSubresource = + (VkImageSubresourceLayers){ + .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, + .mipLevel = dst_iview->vk.base_mip_level, + .baseArrayLayer = dst_iview->vk.base_array_layer, + .layerCount = layer_count, + }, + .srcOffset = { resolve_area.offset.x, resolve_area.offset.y, 0 }, + .dstOffset = { resolve_area.offset.x, resolve_area.offset.y, 0 }, + }; - if (resolve_method == RESOLVE_FRAGMENT) { + switch (resolve_method) { + case RESOLVE_HW: + radv_cmd_buffer_resolve_rendering_hw(cmd_buffer); break; - } - } + case RESOLVE_COMPUTE: + radv_decompress_resolve_src(cmd_buffer, src_iview->image, src_layout, ®ion); - switch (resolve_method) { - case RESOLVE_HW: - radv_cmd_buffer_resolve_rendering_hw(cmd_buffer); - break; - case RESOLVE_COMPUTE: - radv_cmd_buffer_resolve_rendering_cs(cmd_buffer); - break; - case RESOLVE_FRAGMENT: - radv_cmd_buffer_resolve_rendering_fs(cmd_buffer); - break; - default: - unreachable("Invalid resolve method"); + radv_cmd_buffer_resolve_rendering_cs(cmd_buffer, src_iview, src_layout, dst_iview, + dst_layout, ®ion); + break; + case RESOLVE_FRAGMENT: + radv_decompress_resolve_src(cmd_buffer, src_iview->image, src_layout, ®ion); + + radv_cmd_buffer_resolve_rendering_fs(cmd_buffer, src_iview, src_layout, dst_iview, + dst_layout); + break; + default: + unreachable("Invalid resolve method"); + } } } diff --git a/src/amd/vulkan/radv_meta_resolve_cs.c b/src/amd/vulkan/radv_meta_resolve_cs.c index 5ca75e03977..019e841d8f4 100644 --- a/src/amd/vulkan/radv_meta_resolve_cs.c +++ b/src/amd/vulkan/radv_meta_resolve_cs.c @@ -671,8 +671,6 @@ radv_meta_resolve_compute_image(struct radv_cmd_buffer *cmd_buffer, struct radv_ { struct radv_meta_saved_state saved_state; - radv_decompress_resolve_src(cmd_buffer, src_image, src_image_layout, region); - /* For partial resolves, DCC should be decompressed before resolving * because the metadata is re-initialized to the uncompressed after. */ @@ -780,68 +778,16 @@ radv_meta_resolve_compute_image(struct radv_cmd_buffer *cmd_buffer, struct radv_ } } -/** - * Emit any needed resolves for the current subpass. - */ void -radv_cmd_buffer_resolve_rendering_cs(struct radv_cmd_buffer *cmd_buffer) +radv_cmd_buffer_resolve_rendering_cs(struct radv_cmd_buffer *cmd_buffer, + struct radv_image_view *src_iview, VkImageLayout src_layout, + struct radv_image_view *dst_iview, VkImageLayout dst_layout, + const VkImageResolve2 *region) { - const struct radv_rendering_state *render = &cmd_buffer->state.render; - VkRect2D resolve_area = render->area; - struct radv_resolve_barrier barrier; - - uint32_t layer_count = render->layer_count; - if (render->view_mask) - layer_count = util_last_bit(render->view_mask); - - /* Resolves happen before the end-of-subpass barriers get executed, so - * we have to make the attachment shader-readable. - */ - barrier.src_stage_mask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT; - barrier.dst_stage_mask = VK_PIPELINE_STAGE_2_RESOLVE_BIT; - barrier.src_access_mask = VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT; - barrier.dst_access_mask = VK_ACCESS_2_SHADER_READ_BIT | VK_ACCESS_2_SHADER_WRITE_BIT; - radv_emit_resolve_barrier(cmd_buffer, &barrier); - - for (uint32_t i = 0; i < render->color_att_count; ++i) { - if (render->color_att[i].resolve_iview == NULL) - continue; - - struct radv_image_view *src_iview = render->color_att[i].iview; - struct radv_image_view *dst_iview = render->color_att[i].resolve_iview; - VkImageLayout src_layout = render->color_att[i].layout; - VkImageLayout dst_layout = render->color_att[i].resolve_layout; - - VkImageResolve2 region = { - .sType = VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2, - .extent = { - .width = resolve_area.extent.width, - .height = resolve_area.extent.height, - .depth = 1, - }, - .srcSubresource = - (VkImageSubresourceLayers){ - .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, - .mipLevel = src_iview->vk.base_mip_level, - .baseArrayLayer = src_iview->vk.base_array_layer, - .layerCount = layer_count, - }, - .dstSubresource = - (VkImageSubresourceLayers){ - .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, - .mipLevel = dst_iview->vk.base_mip_level, - .baseArrayLayer = dst_iview->vk.base_array_layer, - .layerCount = layer_count, - }, - .srcOffset = { resolve_area.offset.x, resolve_area.offset.y, 0 }, - .dstOffset = { resolve_area.offset.x, resolve_area.offset.y, 0 }, - }; - - radv_meta_resolve_compute_image(cmd_buffer, - src_iview->image, src_iview->vk.format, src_layout, - dst_iview->image, dst_iview->vk.format, dst_layout, - ®ion); - } + radv_meta_resolve_compute_image(cmd_buffer, + src_iview->image, src_iview->vk.format, src_layout, + dst_iview->image, dst_iview->vk.format, dst_layout, + region); cmd_buffer->state.flush_bits |= RADV_CMD_FLAG_CS_PARTIAL_FLUSH | RADV_CMD_FLAG_INV_VCACHE | diff --git a/src/amd/vulkan/radv_meta_resolve_fs.c b/src/amd/vulkan/radv_meta_resolve_fs.c index 1c050934019..da57ab86abb 100644 --- a/src/amd/vulkan/radv_meta_resolve_fs.c +++ b/src/amd/vulkan/radv_meta_resolve_fs.c @@ -781,8 +781,6 @@ radv_meta_resolve_fragment_image(struct radv_cmd_buffer *cmd_buffer, struct radv unsigned dst_layout = radv_meta_dst_layout_from_layout(dest_image_layout); VkImageLayout layout = radv_meta_dst_layout_to_layout(dst_layout); - radv_decompress_resolve_src(cmd_buffer, src_image, src_image_layout, region); - radv_meta_save( &saved_state, cmd_buffer, RADV_META_SAVE_GRAPHICS_PIPELINE | RADV_META_SAVE_CONSTANTS | RADV_META_SAVE_DESCRIPTORS); @@ -884,72 +882,52 @@ radv_meta_resolve_fragment_image(struct radv_cmd_buffer *cmd_buffer, struct radv radv_meta_restore(&saved_state, cmd_buffer); } -/** - * Emit any needed resolves for the current rendering. - */ void -radv_cmd_buffer_resolve_rendering_fs(struct radv_cmd_buffer *cmd_buffer) +radv_cmd_buffer_resolve_rendering_fs(struct radv_cmd_buffer *cmd_buffer, + struct radv_image_view *src_iview, VkImageLayout src_layout, + struct radv_image_view *dst_iview, VkImageLayout dst_layout) { + const struct radv_rendering_state *render = &cmd_buffer->state.render; struct radv_meta_saved_state saved_state; - struct radv_resolve_barrier barrier; - - /* Resolves happen before rendering ends, so we have to make the attachment shader-readable */ - barrier.src_stage_mask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT; - barrier.dst_stage_mask = VK_PIPELINE_STAGE_2_RESOLVE_BIT; - barrier.src_access_mask = VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT; - barrier.dst_access_mask = VK_ACCESS_2_INPUT_ATTACHMENT_READ_BIT; - radv_emit_resolve_barrier(cmd_buffer, &barrier); - - radv_decompress_resolve_rendering_src(cmd_buffer); + VkRect2D resolve_area = render->area; radv_meta_save( &saved_state, cmd_buffer, RADV_META_SAVE_GRAPHICS_PIPELINE | RADV_META_SAVE_CONSTANTS | RADV_META_SAVE_DESCRIPTORS | RADV_META_SAVE_RENDER); - VkRect2D *resolve_area = &saved_state.render.area; - radv_CmdSetViewport(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1, - &(VkViewport){.x = resolve_area->offset.x, - .y = resolve_area->offset.y, - .width = resolve_area->extent.width, - .height = resolve_area->extent.height, + &(VkViewport){.x = resolve_area.offset.x, + .y = resolve_area.offset.y, + .width = resolve_area.extent.width, + .height = resolve_area.extent.height, .minDepth = 0.0f, .maxDepth = 1.0f}); - radv_CmdSetScissor(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1, resolve_area); + radv_CmdSetScissor(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1, &resolve_area); - for (uint32_t i = 0; i < saved_state.render.color_att_count; ++i) { - if (saved_state.render.color_att[i].resolve_iview == NULL) - continue; + const VkRenderingAttachmentInfo color_att = { + .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, + .imageView = radv_image_view_to_handle(dst_iview), + .imageLayout = dst_layout, + .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD, + .storeOp = VK_ATTACHMENT_STORE_OP_STORE, + }; - struct radv_image_view *src_iview = saved_state.render.color_att[i].iview; - struct radv_image_view *dst_iview = saved_state.render.color_att[i].resolve_iview; + const VkRenderingInfo rendering_info = { + .sType = VK_STRUCTURE_TYPE_RENDERING_INFO, + .renderArea = saved_state.render.area, + .layerCount = saved_state.render.layer_count, + .viewMask = saved_state.render.view_mask, + .colorAttachmentCount = 1, + .pColorAttachments = &color_att, + }; - const VkRenderingAttachmentInfo color_att = { - .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, - .imageView = radv_image_view_to_handle(dst_iview), - .imageLayout = saved_state.render.color_att[i].resolve_layout, - .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD, - .storeOp = VK_ATTACHMENT_STORE_OP_STORE, - }; + radv_CmdBeginRendering(radv_cmd_buffer_to_handle(cmd_buffer), &rendering_info); - const VkRenderingInfo rendering_info = { - .sType = VK_STRUCTURE_TYPE_RENDERING_INFO, - .renderArea = saved_state.render.area, - .layerCount = saved_state.render.layer_count, - .viewMask = saved_state.render.view_mask, - .colorAttachmentCount = 1, - .pColorAttachments = &color_att, - }; + emit_resolve(cmd_buffer, src_iview, dst_iview, &resolve_area.offset, &resolve_area.offset); - radv_CmdBeginRendering(radv_cmd_buffer_to_handle(cmd_buffer), &rendering_info); - - emit_resolve(cmd_buffer, src_iview, dst_iview, &saved_state.render.area.offset, - &saved_state.render.area.offset); - - radv_CmdEndRendering(radv_cmd_buffer_to_handle(cmd_buffer)); - } + radv_CmdEndRendering(radv_cmd_buffer_to_handle(cmd_buffer)); radv_meta_restore(&saved_state, cmd_buffer); } diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h index 87c573218f4..a1bf6f0ef25 100644 --- a/src/amd/vulkan/radv_private.h +++ b/src/amd/vulkan/radv_private.h @@ -1786,11 +1786,20 @@ void radv_cmd_buffer_clear_attachment(struct radv_cmd_buffer *cmd_buffer, void radv_cmd_buffer_clear_rendering(struct radv_cmd_buffer *cmd_buffer, const VkRenderingInfo *render_info); void radv_cmd_buffer_resolve_rendering(struct radv_cmd_buffer *cmd_buffer); -void radv_cmd_buffer_resolve_rendering_cs(struct radv_cmd_buffer *cmd_buffer); +void radv_cmd_buffer_resolve_rendering_cs(struct radv_cmd_buffer *cmd_buffer, + struct radv_image_view *src_iview, + VkImageLayout src_layout, + struct radv_image_view *dst_iview, + VkImageLayout dst_layout, + const VkImageResolve2 *region); void radv_depth_stencil_resolve_rendering_cs(struct radv_cmd_buffer *cmd_buffer, VkImageAspectFlags aspects, VkResolveModeFlagBits resolve_mode); -void radv_cmd_buffer_resolve_rendering_fs(struct radv_cmd_buffer *cmd_buffer); +void radv_cmd_buffer_resolve_rendering_fs(struct radv_cmd_buffer *cmd_buffer, + struct radv_image_view *src_iview, + VkImageLayout src_layout, + struct radv_image_view *dst_iview, + VkImageLayout dst_layout); void radv_depth_stencil_resolve_rendering_fs(struct radv_cmd_buffer *cmd_buffer, VkImageAspectFlags aspects, VkResolveModeFlagBits resolve_mode);