diff --git a/src/amd/vulkan/radv_cmd_buffer.c b/src/amd/vulkan/radv_cmd_buffer.c index d25c1525cc8..149ad9f23a7 100644 --- a/src/amd/vulkan/radv_cmd_buffer.c +++ b/src/amd/vulkan/radv_cmd_buffer.c @@ -1648,7 +1648,7 @@ radv_emit_fb_color_state(struct radv_cmd_buffer *cmd_buffer, int index, struct radv_image *image = iview->image; if (!radv_layout_dcc_compressed( - cmd_buffer->device, image, layout, in_render_loop, + cmd_buffer->device, image, iview->base_mip, layout, in_render_loop, radv_image_queue_family_mask(image, cmd_buffer->queue_family_index, cmd_buffer->queue_family_index)) || disable_dcc) { @@ -6345,7 +6345,7 @@ radv_init_color_image_metadata(struct radv_cmd_buffer *cmd_buffer, struct radv_i /* TODO: Fix clearing CMASK layers on GFX9. */ if (radv_image_is_tc_compat_cmask(image) || (radv_image_has_fmask(image) && - radv_layout_can_fast_clear(cmd_buffer->device, image, dst_layout, + radv_layout_can_fast_clear(cmd_buffer->device, image, range->baseMipLevel, dst_layout, dst_render_loop, dst_queue_mask))) { value = 0xccccccccu; } else { @@ -6368,8 +6368,8 @@ radv_init_color_image_metadata(struct radv_cmd_buffer *cmd_buffer, struct radv_i if (radv_dcc_enabled(image, range->baseMipLevel)) { uint32_t value = 0xffffffffu; /* Fully expanded mode. */ - if (radv_layout_dcc_compressed(cmd_buffer->device, image, dst_layout, dst_render_loop, - dst_queue_mask)) { + if (radv_layout_dcc_compressed(cmd_buffer->device, image, range->baseMipLevel, + dst_layout, dst_render_loop, dst_queue_mask)) { value = 0u; } @@ -6431,16 +6431,16 @@ radv_handle_color_image_transition(struct radv_cmd_buffer *cmd_buffer, struct ra if (radv_dcc_enabled(image, range->baseMipLevel)) { if (src_layout == VK_IMAGE_LAYOUT_PREINITIALIZED) { cmd_buffer->state.flush_bits |= radv_init_dcc(cmd_buffer, image, range, 0xffffffffu); - } else if (radv_layout_dcc_compressed(cmd_buffer->device, image, src_layout, src_render_loop, - src_queue_mask) && - !radv_layout_dcc_compressed(cmd_buffer->device, image, dst_layout, dst_render_loop, - dst_queue_mask)) { + } else if (radv_layout_dcc_compressed(cmd_buffer->device, image, range->baseMipLevel, + src_layout, src_render_loop, src_queue_mask) && + !radv_layout_dcc_compressed(cmd_buffer->device, image, range->baseMipLevel, + dst_layout, dst_render_loop, dst_queue_mask)) { radv_decompress_dcc(cmd_buffer, image, range); dcc_decompressed = true; - } else if (radv_layout_can_fast_clear(cmd_buffer->device, image, src_layout, src_render_loop, - src_queue_mask) && - !radv_layout_can_fast_clear(cmd_buffer->device, image, dst_layout, dst_render_loop, - dst_queue_mask)) { + } else if (radv_layout_can_fast_clear(cmd_buffer->device, image, range->baseMipLevel, + src_layout, src_render_loop, src_queue_mask) && + !radv_layout_can_fast_clear(cmd_buffer->device, image, range->baseMipLevel, + dst_layout, dst_render_loop, dst_queue_mask)) { radv_fast_clear_flush_image_inplace(cmd_buffer, image, range); fast_clear_flushed = true; } @@ -6448,10 +6448,10 @@ radv_handle_color_image_transition(struct radv_cmd_buffer *cmd_buffer, struct ra if (radv_image_need_retile(image)) radv_retile_transition(cmd_buffer, image, src_layout, dst_layout, dst_queue_mask); } else if (radv_image_has_cmask(image) || radv_image_has_fmask(image)) { - if (radv_layout_can_fast_clear(cmd_buffer->device, image, src_layout, src_render_loop, - src_queue_mask) && - !radv_layout_can_fast_clear(cmd_buffer->device, image, dst_layout, dst_render_loop, - dst_queue_mask)) { + if (radv_layout_can_fast_clear(cmd_buffer->device, image, range->baseMipLevel, + src_layout, src_render_loop, src_queue_mask) && + !radv_layout_can_fast_clear(cmd_buffer->device, image, range->baseMipLevel, + dst_layout, dst_render_loop, dst_queue_mask)) { radv_fast_clear_flush_image_inplace(cmd_buffer, image, range); fast_clear_flushed = true; } diff --git a/src/amd/vulkan/radv_image.c b/src/amd/vulkan/radv_image.c index 01658895817..efd7d454072 100644 --- a/src/amd/vulkan/radv_image.c +++ b/src/amd/vulkan/radv_image.c @@ -1954,10 +1954,11 @@ radv_layout_is_htile_compressed(const struct radv_device *device, const struct r bool radv_layout_can_fast_clear(const struct radv_device *device, const struct radv_image *image, - VkImageLayout layout, bool in_render_loop, unsigned queue_mask) + unsigned level, VkImageLayout layout, bool in_render_loop, + unsigned queue_mask) { - if (radv_image_has_dcc(image) && - !radv_layout_dcc_compressed(device, image, layout, in_render_loop, queue_mask)) + if (radv_dcc_enabled(image, level) && + !radv_layout_dcc_compressed(device, image, level, layout, in_render_loop, queue_mask)) return false; if (!(image->usage & RADV_IMAGE_USAGE_WRITE_BITS)) @@ -1969,10 +1970,14 @@ radv_layout_can_fast_clear(const struct radv_device *device, const struct radv_i bool radv_layout_dcc_compressed(const struct radv_device *device, const struct radv_image *image, - VkImageLayout layout, bool in_render_loop, unsigned queue_mask) + unsigned level, VkImageLayout layout, bool in_render_loop, + unsigned queue_mask) { + if (!radv_dcc_enabled(image, level)) + return false; + /* If the image is read-only, we can always just keep it compressed */ - if (!(image->usage & RADV_IMAGE_USAGE_WRITE_BITS) && radv_image_has_dcc(image)) + if (!(image->usage & RADV_IMAGE_USAGE_WRITE_BITS)) return false; /* Don't compress compute transfer dst when image stores are not supported. */ @@ -1980,8 +1985,7 @@ radv_layout_dcc_compressed(const struct radv_device *device, const struct radv_i (queue_mask & (1u << RADV_QUEUE_COMPUTE)) && !radv_image_use_dcc_image_stores(device, image)) return false; - return radv_image_has_dcc(image) && (device->physical_device->rad_info.chip_class >= GFX10 || - layout != VK_IMAGE_LAYOUT_GENERAL); + return device->physical_device->rad_info.chip_class >= GFX10 || layout != VK_IMAGE_LAYOUT_GENERAL; } bool diff --git a/src/amd/vulkan/radv_meta_clear.c b/src/amd/vulkan/radv_meta_clear.c index b2f2864ebe9..13a7afee955 100644 --- a/src/amd/vulkan/radv_meta_clear.c +++ b/src/amd/vulkan/radv_meta_clear.c @@ -1477,7 +1477,7 @@ radv_can_fast_clear_color(struct radv_cmd_buffer *cmd_buffer, const struct radv_ return false; if (!radv_layout_can_fast_clear( - cmd_buffer->device, iview->image, image_layout, in_render_loop, + cmd_buffer->device, iview->image, iview->base_mip, image_layout, in_render_loop, radv_image_queue_family_mask(iview->image, cmd_buffer->queue_family_index, cmd_buffer->queue_family_index))) return false; @@ -2041,9 +2041,16 @@ radv_cmd_clear_image(struct radv_cmd_buffer *cmd_buffer, struct radv_image *imag uint32_t queue_mask = radv_image_queue_family_mask(image, cmd_buffer->queue_family_index, cmd_buffer->queue_family_index); - /* Don't use compressed image stores because they will use an incompatible format. */ - if (radv_layout_dcc_compressed(cmd_buffer->device, image, image_layout, false, queue_mask)) - disable_compression = cs; + for (uint32_t r = 0; r < range_count; r++) { + const VkImageSubresourceRange *range = &ranges[r]; + + /* Don't use compressed image stores because they will use an incompatible format. */ + if (radv_layout_dcc_compressed(cmd_buffer->device, image, range->baseMipLevel, + image_layout, false, queue_mask)) { + disable_compression = cs; + break; + } + } } } diff --git a/src/amd/vulkan/radv_meta_copy.c b/src/amd/vulkan/radv_meta_copy.c index 224419de139..168ccfc074c 100644 --- a/src/amd/vulkan/radv_meta_copy.c +++ b/src/amd/vulkan/radv_meta_copy.c @@ -181,7 +181,8 @@ copy_buffer_to_image(struct radv_cmd_buffer *cmd_buffer, struct radv_buffer *buf uint32_t queue_mask = radv_image_queue_family_mask(image, cmd_buffer->queue_family_index, cmd_buffer->queue_family_index); bool compressed = - radv_layout_dcc_compressed(cmd_buffer->device, image, layout, false, queue_mask); + radv_layout_dcc_compressed(cmd_buffer->device, image, region->imageSubresource.mipLevel, + layout, false, queue_mask); if (compressed) { radv_decompress_dcc(cmd_buffer, image, &(VkImageSubresourceRange){ @@ -307,7 +308,8 @@ copy_image_to_buffer(struct radv_cmd_buffer *cmd_buffer, struct radv_buffer *buf uint32_t queue_mask = radv_image_queue_family_mask(image, cmd_buffer->queue_family_index, cmd_buffer->queue_family_index); bool compressed = - radv_layout_dcc_compressed(cmd_buffer->device, image, layout, false, queue_mask); + radv_layout_dcc_compressed(cmd_buffer->device, image, region->imageSubresource.mipLevel, + layout, false, queue_mask); if (compressed) { radv_decompress_dcc(cmd_buffer, image, &(VkImageSubresourceRange){ @@ -425,10 +427,12 @@ copy_image(struct radv_cmd_buffer *cmd_buffer, struct radv_image *src_image, uint32_t dst_queue_mask = radv_image_queue_family_mask( dst_image, cmd_buffer->queue_family_index, cmd_buffer->queue_family_index); bool dst_compressed = radv_layout_dcc_compressed(cmd_buffer->device, dst_image, + region->dstSubresource.mipLevel, dst_image_layout, false, dst_queue_mask); uint32_t src_queue_mask = radv_image_queue_family_mask( src_image, cmd_buffer->queue_family_index, cmd_buffer->queue_family_index); bool src_compressed = radv_layout_dcc_compressed(cmd_buffer->device, src_image, + region->srcSubresource.mipLevel, src_image_layout, false, src_queue_mask); if (!src_compressed || radv_dcc_formats_compatible(b_src.format, b_dst.format)) { diff --git a/src/amd/vulkan/radv_meta_resolve.c b/src/amd/vulkan/radv_meta_resolve.c index eda31bbedb5..4214992b26b 100644 --- a/src/amd/vulkan/radv_meta_resolve.c +++ b/src/amd/vulkan/radv_meta_resolve.c @@ -369,8 +369,8 @@ image_hw_resolve_compat(const struct radv_device *device, struct radv_image *src static void radv_pick_resolve_method_images(struct radv_device *device, struct radv_image *src_image, VkFormat src_format, struct radv_image *dest_image, - VkImageLayout dest_image_layout, bool dest_render_loop, - struct radv_cmd_buffer *cmd_buffer, + unsigned dest_level, VkImageLayout dest_image_layout, + bool dest_render_loop, struct radv_cmd_buffer *cmd_buffer, enum radv_resolve_method *method) { @@ -383,8 +383,8 @@ radv_pick_resolve_method_images(struct radv_device *device, struct radv_image *s * re-initialize it after resolving using compute. * TODO: Add support for layered and int to the fragment path. */ - if (radv_layout_dcc_compressed(device, dest_image, dest_image_layout, dest_render_loop, - queue_mask)) { + if (radv_layout_dcc_compressed(device, dest_image, dest_level, dest_image_layout, + dest_render_loop, queue_mask)) { *method = RESOLVE_FRAGMENT; } else if (!image_hw_resolve_compat(device, src_image, dest_image)) { /* The micro tile mode only needs to match for the HW @@ -659,12 +659,15 @@ radv_CmdResolveImage2KHR(VkCommandBuffer commandBuffer, } else resolve_method = RESOLVE_COMPUTE; - radv_pick_resolve_method_images(cmd_buffer->device, src_image, src_image->vk_format, dst_image, - dst_image_layout, false, cmd_buffer, &resolve_method); - for (uint32_t r = 0; r < pResolveImageInfo->regionCount; r++) { - resolve_image(cmd_buffer, src_image, src_image_layout, dst_image, dst_image_layout, - &pResolveImageInfo->pRegions[r], resolve_method); + const VkImageResolve2KHR *region = &pResolveImageInfo->pRegions[r]; + + radv_pick_resolve_method_images(cmd_buffer->device, src_image, src_image->vk_format, dst_image, + region->dstSubresource.mipLevel, dst_image_layout, false, + cmd_buffer, &resolve_method); + + resolve_image(cmd_buffer, src_image, src_image_layout, dst_image, dst_image_layout, region, + resolve_method); } } @@ -752,8 +755,8 @@ radv_cmd_buffer_resolve_subpass(struct radv_cmd_buffer *cmd_buffer) cmd_buffer->state.attachments[dst_att.attachment].pending_clear_aspects = 0; radv_pick_resolve_method_images(cmd_buffer->device, src_iview->image, src_iview->vk_format, - dst_iview->image, dst_att.layout, dst_att.in_render_loop, - cmd_buffer, &resolve_method); + dst_iview->image, dst_iview->base_mip, dst_att.layout, + dst_att.in_render_loop, cmd_buffer, &resolve_method); if ((src_iview->aspect_mask & VK_IMAGE_ASPECT_DEPTH_BIT) && subpass->depth_resolve_mode != VK_RESOLVE_MODE_NONE_KHR) { @@ -811,15 +814,16 @@ radv_cmd_buffer_resolve_subpass(struct radv_cmd_buffer *cmd_buffer) /* Make sure to not clear color attachments after resolves. */ cmd_buffer->state.attachments[dest_att.attachment].pending_clear_aspects = 0; - struct radv_image *dst_img = - cmd_buffer->state.attachments[dest_att.attachment].iview->image; + struct radv_image_view *dst_iview = + cmd_buffer->state.attachments[dest_att.attachment].iview; + struct radv_image *dst_img = dst_iview->image; struct radv_image_view *src_iview = cmd_buffer->state.attachments[src_att.attachment].iview; struct radv_image *src_img = src_iview->image; radv_pick_resolve_method_images(cmd_buffer->device, src_img, src_iview->vk_format, dst_img, - dest_att.layout, dest_att.in_render_loop, cmd_buffer, - &resolve_method); + dst_iview->base_mip, dest_att.layout, + dest_att.in_render_loop, cmd_buffer, &resolve_method); if (resolve_method == RESOLVE_FRAGMENT) { break; diff --git a/src/amd/vulkan/radv_meta_resolve_cs.c b/src/amd/vulkan/radv_meta_resolve_cs.c index 9dc2c2b0ce5..2d1b86b841a 100644 --- a/src/amd/vulkan/radv_meta_resolve_cs.c +++ b/src/amd/vulkan/radv_meta_resolve_cs.c @@ -679,8 +679,8 @@ radv_meta_resolve_compute_image(struct radv_cmd_buffer *cmd_buffer, struct radv_ cmd_buffer->queue_family_index); if (radv_dcc_enabled(dest_image, region->dstSubresource.mipLevel) && - radv_layout_dcc_compressed(cmd_buffer->device, dest_image, dest_image_layout, false, - queue_mask) && + radv_layout_dcc_compressed(cmd_buffer->device, dest_image, region->dstSubresource.mipLevel, + dest_image_layout, false, queue_mask) && (region->dstOffset.x || region->dstOffset.y || region->dstOffset.z || region->extent.width != dest_image->info.width || region->extent.height != dest_image->info.height || @@ -762,8 +762,8 @@ radv_meta_resolve_compute_image(struct radv_cmd_buffer *cmd_buffer, struct radv_ if (!radv_image_use_dcc_image_stores(cmd_buffer->device, dest_image) && radv_dcc_enabled(dest_image, region->dstSubresource.mipLevel) && - radv_layout_dcc_compressed(cmd_buffer->device, dest_image, dest_image_layout, false, - queue_mask)) { + radv_layout_dcc_compressed(cmd_buffer->device, dest_image, region->dstSubresource.mipLevel, + dest_image_layout, false, queue_mask)) { cmd_buffer->state.flush_bits |= RADV_CMD_FLAG_CS_PARTIAL_FLUSH | RADV_CMD_FLAG_INV_VCACHE; diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h index ba744a22e34..a6b8d5e027e 100644 --- a/src/amd/vulkan/radv_private.h +++ b/src/amd/vulkan/radv_private.h @@ -1888,10 +1888,12 @@ bool radv_layout_is_htile_compressed(const struct radv_device *device, bool in_render_loop, unsigned queue_mask); bool radv_layout_can_fast_clear(const struct radv_device *device, const struct radv_image *image, - VkImageLayout layout, bool in_render_loop, unsigned queue_mask); + unsigned level, VkImageLayout layout, bool in_render_loop, + unsigned queue_mask); bool radv_layout_dcc_compressed(const struct radv_device *device, const struct radv_image *image, - VkImageLayout layout, bool in_render_loop, unsigned queue_mask); + unsigned level, VkImageLayout layout, bool in_render_loop, + unsigned queue_mask); bool radv_layout_fmask_compressed(const struct radv_device *device, const struct radv_image *image, VkImageLayout layout, unsigned queue_mask);