diff options
-rw-r--r-- | src/amd/vulkan/radv_meta_resolve.c | 58 |
1 files changed, 50 insertions, 8 deletions
diff --git a/src/amd/vulkan/radv_meta_resolve.c b/src/amd/vulkan/radv_meta_resolve.c index 3e6633dec03..565909ac3c6 100644 --- a/src/amd/vulkan/radv_meta_resolve.c +++ b/src/amd/vulkan/radv_meta_resolve.c @@ -303,6 +303,25 @@ emit_resolve(struct radv_cmd_buffer *cmd_buffer, cmd_buffer->state.flush_bits |= RADV_CMD_FLAG_FLUSH_AND_INV_CB; } +enum radv_resolve_method { + RESOLVE_HW, + RESOLVE_COMPUTE, + RESOLVE_FRAGMENT, +}; + +static void radv_pick_resolve_method_images(struct radv_image *src_image, + struct radv_image *dest_image, + enum radv_resolve_method *method) + +{ + if (dest_image->surface.micro_tile_mode != src_image->surface.micro_tile_mode) { + if (dest_image->surface.level[0].dcc_enabled) + *method = RESOLVE_FRAGMENT; + else + *method = RESOLVE_COMPUTE; + } +} + void radv_CmdResolveImage( VkCommandBuffer cmd_buffer_h, VkImage src_image_h, @@ -318,27 +337,29 @@ void radv_CmdResolveImage( struct radv_device *device = cmd_buffer->device; struct radv_meta_saved_state saved_state; VkDevice device_h = radv_device_to_handle(device); - bool use_compute_resolve = false; - bool use_fragment_resolve = false; + enum radv_resolve_method resolve_method = RESOLVE_HW; /* we can use the hw resolve only for single full resolves */ if (region_count == 1) { if (regions[0].srcOffset.x || regions[0].srcOffset.y || regions[0].srcOffset.z) - use_compute_resolve = true; + resolve_method = RESOLVE_COMPUTE; if (regions[0].dstOffset.x || regions[0].dstOffset.y || regions[0].dstOffset.z) - use_compute_resolve = true; + resolve_method = RESOLVE_COMPUTE; if (regions[0].extent.width != src_image->info.width || regions[0].extent.height != src_image->info.height || regions[0].extent.depth != src_image->info.depth) - use_compute_resolve = true; + resolve_method = RESOLVE_COMPUTE; } else - use_compute_resolve = true; + resolve_method = RESOLVE_COMPUTE; + + radv_pick_resolve_method_images(src_image, dest_image, + &resolve_method); - if (use_fragment_resolve) { + if (resolve_method == RESOLVE_FRAGMENT) { radv_meta_resolve_fragment_image(cmd_buffer, src_image, src_image_layout, @@ -348,7 +369,7 @@ void radv_CmdResolveImage( return; } - if (use_compute_resolve) { + if (resolve_method == RESOLVE_COMPUTE) { radv_meta_resolve_compute_image(cmd_buffer, src_image, src_image_layout, @@ -524,6 +545,7 @@ radv_cmd_buffer_resolve_subpass(struct radv_cmd_buffer *cmd_buffer) struct radv_framebuffer *fb = cmd_buffer->state.framebuffer; const struct radv_subpass *subpass = cmd_buffer->state.subpass; struct radv_meta_saved_state saved_state; + enum radv_resolve_method resolve_method = RESOLVE_HW; /* FINISHME(perf): Skip clears for resolve attachments. * @@ -537,6 +559,26 @@ radv_cmd_buffer_resolve_subpass(struct radv_cmd_buffer *cmd_buffer) if (!subpass->has_resolve) return; + for (uint32_t i = 0; i < subpass->color_count; ++i) { + VkAttachmentReference src_att = subpass->color_attachments[i]; + VkAttachmentReference dest_att = subpass->resolve_attachments[i]; + struct radv_image *dst_img = cmd_buffer->state.framebuffer->attachments[dest_att.attachment].attachment->image; + struct radv_image *src_img = cmd_buffer->state.framebuffer->attachments[src_att.attachment].attachment->image; + + radv_pick_resolve_method_images(dst_img, src_img, &resolve_method); + if (resolve_method == RESOLVE_FRAGMENT) { + break; + } + } + + if (resolve_method == RESOLVE_COMPUTE) { + radv_cmd_buffer_resolve_subpass_cs(cmd_buffer); + return; + } else if (resolve_method == RESOLVE_FRAGMENT) { + radv_cmd_buffer_resolve_subpass_fs(cmd_buffer); + return; + } + radv_meta_save_graphics_reset_vport_scissor(&saved_state, cmd_buffer); for (uint32_t i = 0; i < subpass->color_count; ++i) { |