From 18aaa373b701c98ea85058deeaeadac44f120bab Mon Sep 17 00:00:00 2001 From: Samuel Pitoiset Date: Tue, 17 Jan 2023 17:53:13 +0100 Subject: [PATCH] radv: fix buffer to image copies with BC views on the graphics queue The color surface descriptor needs to be adjusted, otherwise addressing is wrong. Fixes tests performed on the graphics queue from dEQP-VK.api.copy_and_blit.*.image_to_buffer.2d_images.mip_copies_*. Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/7900 Fixes: 98ba1e0d817 ("radv: Fix mipmap views on GFX10+") Signed-off-by: Samuel Pitoiset Part-of: --- src/amd/vulkan/radv_device.c | 24 +++++++++++++++++++----- src/amd/vulkan/radv_image.c | 8 ++++---- src/amd/vulkan/radv_private.h | 3 +++ 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c index 0ada5b8acf4..e3d4b540693 100644 --- a/src/amd/vulkan/radv_device.c +++ b/src/amd/vulkan/radv_device.c @@ -6921,6 +6921,7 @@ radv_initialise_color_surface(struct radv_device *device, struct radv_color_buff uint64_t va; const struct radv_image_plane *plane = &iview->image->planes[iview->plane_id]; const struct radeon_surf *surf = &plane->surface; + uint8_t tile_swizzle = plane->surface.tile_swizzle; desc = vk_format_description(iview->vk.format); @@ -6936,6 +6937,11 @@ radv_initialise_color_surface(struct radv_device *device, struct radv_color_buff va = radv_buffer_get_va(iview->image->bindings[plane_id].bo) + iview->image->bindings[plane_id].offset; + if (iview->nbc_view.valid) { + va += iview->nbc_view.base_address_offset; + tile_swizzle = iview->nbc_view.tile_swizzle; + } + cb->cb_color_base = va >> 8; if (device->physical_device->rad_info.gfx_level >= GFX9) { @@ -6964,14 +6970,14 @@ radv_initialise_color_surface(struct radv_device *device, struct radv_color_buff } cb->cb_color_base += surf->u.gfx9.surf_offset >> 8; - cb->cb_color_base |= surf->tile_swizzle; + cb->cb_color_base |= tile_swizzle; } else { const struct legacy_surf_level *level_info = &surf->u.legacy.level[iview->vk.base_mip_level]; unsigned pitch_tile_max, slice_tile_max, tile_mode_index; cb->cb_color_base += level_info->offset_256B; if (level_info->mode == RADEON_SURF_MODE_2D) - cb->cb_color_base |= surf->tile_swizzle; + cb->cb_color_base |= tile_swizzle; pitch_tile_max = level_info->nblk_x / 8 - 1; slice_tile_max = (level_info->nblk_x * level_info->nblk_y) / 64 - 1; @@ -7010,7 +7016,7 @@ radv_initialise_color_surface(struct radv_device *device, struct radv_color_buff device->physical_device->rad_info.gfx_level <= GFX8) va += plane->surface.u.legacy.color.dcc_level[iview->vk.base_mip_level].dcc_offset; - unsigned dcc_tile_swizzle = surf->tile_swizzle; + unsigned dcc_tile_swizzle = tile_swizzle; dcc_tile_swizzle &= ((1 << surf->meta_alignment_log2) - 1) >> 8; cb->cb_dcc_base = va >> 8; @@ -7129,9 +7135,17 @@ radv_initialise_color_surface(struct radv_device *device, struct radv_color_buff vk_format_get_plane_width(iview->image->vk.format, iview->plane_id, iview->extent.width); unsigned height = vk_format_get_plane_height(iview->image->vk.format, iview->plane_id, iview->extent.height); + unsigned max_mip = iview->image->info.levels - 1; if (device->physical_device->rad_info.gfx_level >= GFX10) { - cb->cb_color_view |= S_028C6C_MIP_LEVEL_GFX10(iview->vk.base_mip_level); + unsigned base_level = iview->vk.base_mip_level; + + if (iview->nbc_view.valid) { + base_level = iview->nbc_view.level; + max_mip = iview->nbc_view.max_mip - 1; + } + + cb->cb_color_view |= S_028C6C_MIP_LEVEL_GFX10(base_level); cb->cb_color_attrib3 |= S_028EE0_MIP0_DEPTH(mip0_depth) | S_028EE0_RESOURCE_TYPE(surf->u.gfx9.resource_type) | @@ -7143,7 +7157,7 @@ radv_initialise_color_surface(struct radv_device *device, struct radv_color_buff } cb->cb_color_attrib2 = S_028C68_MIP0_WIDTH(width - 1) | S_028C68_MIP0_HEIGHT(height - 1) | - S_028C68_MAX_MIP(iview->image->info.levels - 1); + S_028C68_MAX_MIP(max_mip); } } diff --git a/src/amd/vulkan/radv_image.c b/src/amd/vulkan/radv_image.c index a1238f7335f..3f8a87e5860 100644 --- a/src/amd/vulkan/radv_image.c +++ b/src/amd/vulkan/radv_image.c @@ -2107,7 +2107,6 @@ radv_image_view_init(struct radv_image_view *iview, struct radv_device *device, const VkImageSubresourceRange *range = &pCreateInfo->subresourceRange; uint32_t plane_count = 1; float min_lod = 0.0f; - struct ac_surf_nbc_view nbc_view = {0}; const struct VkImageViewMinLodCreateInfoEXT *min_lod_info = vk_find_struct_const(pCreateInfo->pNext, IMAGE_VIEW_MIN_LOD_CREATE_INFO_EXT); @@ -2133,6 +2132,7 @@ radv_image_view_init(struct radv_image_view *iview, struct radv_device *device, } iview->image = image; iview->plane_id = radv_plane_from_aspect(pCreateInfo->subresourceRange.aspectMask); + iview->nbc_view.valid = false; /* If the image has an Android external format, pCreateInfo->format will be * VK_FORMAT_UNDEFINED. */ @@ -2244,7 +2244,7 @@ radv_image_view_init(struct radv_image_view *iview, struct radv_device *device, (radv_minify(iview->extent.width, range->baseMipLevel) < lvl_width || radv_minify(iview->extent.height, range->baseMipLevel) < lvl_height) && iview->vk.layer_count == 1) { - compute_non_block_compressed_view(device, iview, &nbc_view); + compute_non_block_compressed_view(device, iview, &iview->nbc_view); } } } @@ -2259,10 +2259,10 @@ radv_image_view_init(struct radv_image_view *iview, struct radv_device *device, VkFormat format = vk_format_get_plane_format(iview->vk.view_format, i); radv_image_view_make_descriptor(iview, device, format, &pCreateInfo->components, min_lod, false, disable_compression, enable_compression, iview->plane_id + i, - i, img_create_flags, &nbc_view); + i, img_create_flags, &iview->nbc_view); radv_image_view_make_descriptor(iview, device, format, &pCreateInfo->components, min_lod, true, disable_compression, enable_compression, iview->plane_id + i, - i, img_create_flags, &nbc_view); + i, img_create_flags, &iview->nbc_view); } } diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h index beea6745d16..5ab7de9daa9 100644 --- a/src/amd/vulkan/radv_private.h +++ b/src/amd/vulkan/radv_private.h @@ -2626,6 +2626,9 @@ struct radv_image_view { * This has a few differences for cube maps (e.g. type). */ union radv_descriptor storage_descriptor; + + /* Block-compressed image views on GFX10+. */ + struct ac_surf_nbc_view nbc_view; }; struct radv_image_create_info {