diff --git a/.pick_status.json b/.pick_status.json index 03fe35d6a4e..016dd722598 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -2902,7 +2902,7 @@ "description": "radv: fix buffer to image copies with BC views on the graphics queue", "nominated": true, "nomination_type": 1, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": "98ba1e0d817e0354aad5d82eb9a2dc4cce33540f" }, diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c index 90d037ade77..829a5df00b8 100644 --- a/src/amd/vulkan/radv_device.c +++ b/src/amd/vulkan/radv_device.c @@ -6538,6 +6538,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); @@ -6553,6 +6554,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) { @@ -6581,14 +6587,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; @@ -6627,7 +6633,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; @@ -6746,9 +6752,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) | @@ -6760,7 +6774,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 4f8e06bd358..42d01ec890e 100644 --- a/src/amd/vulkan/radv_image.c +++ b/src/amd/vulkan/radv_image.c @@ -2094,7 +2094,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); @@ -2120,6 +2119,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. */ @@ -2231,7 +2231,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); } } } @@ -2246,10 +2246,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 a1bf6f0ef25..f3728ab00be 100644 --- a/src/amd/vulkan/radv_private.h +++ b/src/amd/vulkan/radv_private.h @@ -2630,6 +2630,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 {