Mesa (main): radv: Add extra plane for decoding ETC images with emulation.
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Tue Dec 14 12:10:38 UTC 2021
Module: Mesa
Branch: main
Commit: 42a71be793f60309901af898189593a8bff7e05f
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=42a71be793f60309901af898189593a8bff7e05f
Author: Bas Nieuwenhuizen <bas at basnieuwenhuizen.nl>
Date: Thu Nov 4 00:00:59 2021 +0100
radv: Add extra plane for decoding ETC images with emulation.
Reviewed-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14071>
---
src/amd/vulkan/radv_image.c | 100 +++++++++++++++++++++++++++++++++++---------
1 file changed, 81 insertions(+), 19 deletions(-)
diff --git a/src/amd/vulkan/radv_image.c b/src/amd/vulkan/radv_image.c
index bf0a64968ca..7e09be00257 100644
--- a/src/amd/vulkan/radv_image.c
+++ b/src/amd/vulkan/radv_image.c
@@ -532,13 +532,51 @@ radv_patch_image_from_extra_info(struct radv_device *device, struct radv_image *
return VK_SUCCESS;
}
+static VkFormat
+etc2_emulation_format(VkFormat format)
+{
+ switch (format) {
+ case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
+ case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:
+ case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:
+ return VK_FORMAT_R8G8B8A8_UNORM;
+ case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
+ case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:
+ case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:
+ return VK_FORMAT_R8G8B8A8_SRGB;
+ case VK_FORMAT_EAC_R11_UNORM_BLOCK:
+ return VK_FORMAT_R16_UNORM;
+ case VK_FORMAT_EAC_R11_SNORM_BLOCK:
+ return VK_FORMAT_R16_SNORM;
+ case VK_FORMAT_EAC_R11G11_UNORM_BLOCK:
+ return VK_FORMAT_R16G16_UNORM;
+ case VK_FORMAT_EAC_R11G11_SNORM_BLOCK:
+ return VK_FORMAT_R16G16_SNORM;
+ default:
+ unreachable("Unhandled ETC format");
+ }
+}
+
+static VkFormat
+radv_image_get_plane_format(const struct radv_physical_device *pdev, const struct radv_image *image,
+ unsigned plane)
+{
+ if (pdev->emulate_etc2 &&
+ vk_format_description(image->vk_format)->layout == UTIL_FORMAT_LAYOUT_ETC) {
+ if (plane == 0)
+ return image->vk_format;
+ return etc2_emulation_format(image->vk_format);
+ }
+ return vk_format_get_plane_format(image->vk_format, plane);
+}
+
static uint64_t
radv_get_surface_flags(struct radv_device *device, struct radv_image *image, unsigned plane_id,
const VkImageCreateInfo *pCreateInfo, VkFormat image_format)
{
uint64_t flags;
unsigned array_mode = radv_choose_tiling(device, pCreateInfo, image_format);
- VkFormat format = vk_format_get_plane_format(image_format, plane_id);
+ VkFormat format = radv_image_get_plane_format(device->physical_device, image, plane_id);
const struct util_format_description *desc = vk_format_description(format);
bool is_depth, is_stencil;
@@ -1369,7 +1407,7 @@ radv_image_is_pipe_misaligned(const struct radv_device *device, const struct rad
assert(rad_info->chip_class >= GFX10);
for (unsigned i = 0; i < image->plane_count; ++i) {
- VkFormat fmt = vk_format_get_plane_format(image->vk_format, i);
+ VkFormat fmt = radv_image_get_plane_format(device->physical_device, image, i);
int log2_bpp = util_logbase2(vk_format_get_blocksize(fmt));
int log2_bpp_and_samples;
@@ -1484,8 +1522,16 @@ radv_image_use_comp_to_single(const struct radv_device *device, const struct rad
return true;
}
+static unsigned
+radv_get_internal_plane_count(const struct radv_physical_device *pdev, VkFormat fmt)
+{
+ if (pdev->emulate_etc2 && vk_format_description(fmt)->layout == UTIL_FORMAT_LAYOUT_ETC)
+ return 2;
+ return vk_format_get_plane_count(fmt);
+}
+
static void
-radv_image_reset_layout(struct radv_image *image)
+radv_image_reset_layout(const struct radv_physical_device *pdev, struct radv_image *image)
{
image->size = 0;
image->alignment = 1;
@@ -1494,8 +1540,9 @@ radv_image_reset_layout(struct radv_image *image)
image->fce_pred_offset = image->dcc_pred_offset = 0;
image->clear_value_offset = image->tc_compat_zrange_offset = 0;
- for (unsigned i = 0; i < image->plane_count; ++i) {
- VkFormat format = vk_format_get_plane_format(image->vk_format, i);
+ unsigned plane_count = radv_get_internal_plane_count(pdev, image->vk_format);
+ for (unsigned i = 0; i < plane_count; ++i) {
+ VkFormat format = radv_image_get_plane_format(pdev, image, i);
if (vk_format_has_depth(format))
format = vk_format_depth_only(format);
@@ -1532,9 +1579,10 @@ radv_image_create_layout(struct radv_device *device, struct radv_image_create_in
assert(!mod_info || mod_info->drmFormatModifierPlaneCount >= image->plane_count);
- radv_image_reset_layout(image);
+ radv_image_reset_layout(device->physical_device, image);
- for (unsigned plane = 0; plane < image->plane_count; ++plane) {
+ unsigned plane_count = radv_get_internal_plane_count(device->physical_device, image->vk_format);
+ for (unsigned plane = 0; plane < plane_count; ++plane) {
struct ac_surf_info info = image_info;
uint64_t offset;
unsigned stride;
@@ -1542,7 +1590,7 @@ radv_image_create_layout(struct radv_device *device, struct radv_image_create_in
info.width = vk_format_get_plane_width(image->vk_format, plane, info.width);
info.height = vk_format_get_plane_height(image->vk_format, plane, info.height);
- if (create_info.no_metadata_planes || image->plane_count > 1) {
+ if (create_info.no_metadata_planes || plane_count > 1) {
image->planes[plane].surface.flags |=
RADEON_SURF_DISABLE_DCC | RADEON_SURF_NO_FMASK | RADEON_SURF_NO_HTILE;
}
@@ -1561,7 +1609,7 @@ radv_image_create_layout(struct radv_device *device, struct radv_image_create_in
create_info.bo_metadata->metadata))
return VK_ERROR_INVALID_EXTERNAL_HANDLE;
- if (!create_info.no_metadata_planes && !create_info.bo_metadata && image->plane_count == 1 &&
+ if (!create_info.no_metadata_planes && !create_info.bo_metadata && plane_count == 1 &&
!mod_info)
radv_image_alloc_single_sample_cmask(device, image, &image->planes[plane].surface);
@@ -1583,7 +1631,7 @@ radv_image_create_layout(struct radv_device *device, struct radv_image_create_in
return VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT;
/* Validate DCC offsets in modifier layout. */
- if (image->plane_count == 1 && mod_info) {
+ if (plane_count == 1 && mod_info) {
unsigned mem_planes = ac_surface_get_nplanes(&image->planes[plane].surface);
if (mod_info->drmFormatModifierPlaneCount != mem_planes)
return VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT;
@@ -1599,7 +1647,8 @@ radv_image_create_layout(struct radv_device *device, struct radv_image_create_in
image->size = MAX2(image->size, offset + image->planes[plane].surface.total_size);
image->alignment = MAX2(image->alignment, 1 << image->planes[plane].surface.alignment_log2);
- image->planes[plane].format = vk_format_get_plane_format(image->vk_format, plane);
+ image->planes[plane].format =
+ radv_image_get_plane_format(device->physical_device, image, plane);
}
image->tc_compatible_cmask =
@@ -1710,7 +1759,8 @@ radv_image_create(VkDevice _device, const struct radv_image_create_info *create_
vk_find_struct_const(pCreateInfo->pNext, IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT);
assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO);
- const unsigned plane_count = vk_format_get_plane_count(format);
+ unsigned plane_count = radv_get_internal_plane_count(device->physical_device, format);
+
const size_t image_struct_size = sizeof(*image) + sizeof(struct radv_image_plane) * plane_count;
radv_assert(pCreateInfo->mipLevels > 0);
@@ -1741,7 +1791,7 @@ radv_image_create(VkDevice _device, const struct radv_image_create_info *create_
image->tiling = pCreateInfo->tiling;
image->usage = pCreateInfo->usage;
image->flags = pCreateInfo->flags;
- image->plane_count = plane_count;
+ image->plane_count = vk_format_get_plane_count(format);
image->exclusive = pCreateInfo->sharingMode == VK_SHARING_MODE_EXCLUSIVE;
if (pCreateInfo->sharingMode == VK_SHARING_MODE_CONCURRENT) {
@@ -1768,7 +1818,7 @@ radv_image_create(VkDevice _device, const struct radv_image_create_info *create_
else if (explicit_mod)
modifier = explicit_mod->drmFormatModifier;
- for (unsigned plane = 0; plane < image->plane_count; ++plane) {
+ for (unsigned plane = 0; plane < plane_count; ++plane) {
image->planes[plane].surface.flags =
radv_get_surface_flags(device, image, plane, pCreateInfo, format);
image->planes[plane].surface.modifier = modifier;
@@ -1991,6 +2041,23 @@ radv_image_view_init(struct radv_image_view *iview, struct radv_device *device,
iview->vk_format = vk_format_depth_only(iview->vk_format);
}
+ if (vk_format_get_plane_count(image->vk_format) > 1 &&
+ iview->aspect_mask == VK_IMAGE_ASPECT_COLOR_BIT) {
+ plane_count = vk_format_get_plane_count(iview->vk_format);
+ }
+
+ if (device->physical_device->emulate_etc2 &&
+ vk_format_description(image->vk_format)->layout == UTIL_FORMAT_LAYOUT_ETC) {
+ const struct util_format_description *desc = vk_format_description(iview->vk_format);
+ assert(desc);
+ if (desc->layout == UTIL_FORMAT_LAYOUT_ETC) {
+ iview->plane_id = 1;
+ iview->vk_format = etc2_emulation_format(iview->vk_format);
+ }
+
+ plane_count = 1;
+ }
+
if (device->physical_device->rad_info.chip_class >= GFX9) {
iview->extent = (VkExtent3D){
.width = image->info.width,
@@ -2068,11 +2135,6 @@ radv_image_view_init(struct radv_image_view *iview, struct radv_device *device,
iview->support_fast_clear = radv_image_view_can_fast_clear(device, iview);
- if (vk_format_get_plane_count(image->vk_format) > 1 &&
- iview->aspect_mask == VK_IMAGE_ASPECT_COLOR_BIT) {
- plane_count = vk_format_get_plane_count(iview->vk_format);
- }
-
bool disable_compression = extra_create_info ? extra_create_info->disable_compression : false;
bool enable_compression = extra_create_info ? extra_create_info->enable_compression : false;
for (unsigned i = 0; i < plane_count; ++i) {
More information about the mesa-commit
mailing list