radv: pass an image range to radv_layout_dcc_compressed()

With DCC and mipmaps, some mips can't be compressed and it makes
sense to check this here.

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10667>
This commit is contained in:
Samuel Pitoiset 2021-05-06 12:20:37 +02:00 committed by Marge Bot
parent 9cb06fca73
commit bdb9634151
7 changed files with 71 additions and 50 deletions

View file

@ -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;
}

View file

@ -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

View file

@ -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;
}
}
}
}

View file

@ -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)) {

View file

@ -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;

View file

@ -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;

View file

@ -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);