From 1a83279da57f2e2702d9b13437eed6bfb958af52 Mon Sep 17 00:00:00 2001 From: Jonathan Marek Date: Fri, 10 Apr 2020 12:48:31 -0400 Subject: [PATCH] turnip: enable 420_UNORM formats Signed-off-by: Jonathan Marek Part-of: --- src/freedreno/vulkan/tu_clear_blit.c | 4 +++ src/freedreno/vulkan/tu_formats.c | 9 +++-- src/freedreno/vulkan/tu_image.c | 54 ++++++++++++++++++++++++++++ src/freedreno/vulkan/vk_format.h | 2 ++ 4 files changed, 67 insertions(+), 2 deletions(-) diff --git a/src/freedreno/vulkan/tu_clear_blit.c b/src/freedreno/vulkan/tu_clear_blit.c index 260dfe5d56f..07edfa04bce 100644 --- a/src/freedreno/vulkan/tu_clear_blit.c +++ b/src/freedreno/vulkan/tu_clear_blit.c @@ -1152,6 +1152,10 @@ tu_copy_buffer_to_image(struct tu_cmd_buffer *cmd, ops = &r3d_ops; } + /* TODO: G8_B8R8_2PLANE_420_UNORM Y plane has different hardware format, + * which matters for UBWC. buffer_to_image/etc can fail because of this + */ + VkOffset3D offset = info->imageOffset; VkExtent3D extent = info->imageExtent; uint32_t src_width = info->bufferRowLength ?: extent.width; diff --git a/src/freedreno/vulkan/tu_formats.c b/src/freedreno/vulkan/tu_formats.c index a312560f116..819a6902982 100644 --- a/src/freedreno/vulkan/tu_formats.c +++ b/src/freedreno/vulkan/tu_formats.c @@ -293,6 +293,8 @@ static const struct tu_native_format tu6_format_table[] = { static const struct tu_native_format tu6_format_table_ext[] = { TU6_xTx(G8B8G8R8_422_UNORM, R8G8R8B8_422_UNORM, WZYX), /* 0 */ TU6_xTx(B8G8R8G8_422_UNORM, G8R8B8R8_422_UNORM, WZYX), /* 1 */ + TU6_xTx(G8_B8_R8_3PLANE_420_UNORM, R8_G8_B8_3PLANE_420_UNORM, WZYX), /* 2 */ + TU6_xTx(G8_B8R8_2PLANE_420_UNORM, R8_G8B8_2PLANE_420_UNORM, WZYX), /* 3 */ }; static struct tu_native_format @@ -376,8 +378,7 @@ tu_physical_device_get_format_properties( buffer |= VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT; if (native_fmt.supported & FMT_TEXTURE) { - optimal |= VK_FORMAT_FEATURE_BLIT_SRC_BIT | - VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | + optimal |= VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | @@ -387,6 +388,10 @@ tu_physical_device_get_format_properties( buffer |= VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT; + /* no blit src bit for extended (YUYV/NV12/I420) formats */ + if (format < FMT_EXT_BASE) + optimal |= VK_FORMAT_FEATURE_BLIT_SRC_BIT; + if (desc->layout != UTIL_FORMAT_LAYOUT_SUBSAMPLED) optimal |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT; diff --git a/src/freedreno/vulkan/tu_image.c b/src/freedreno/vulkan/tu_image.c index 2b8273b28bf..4641c8ea34b 100644 --- a/src/freedreno/vulkan/tu_image.c +++ b/src/freedreno/vulkan/tu_image.c @@ -149,6 +149,16 @@ tu_image_create(VkDevice _device, ubwc_enabled = false; } + /* UBWC is supported for these formats, but NV12 has a special UBWC + * format for accessing the Y plane aspect, which isn't implemented + * For IYUV, the blob doesn't use UBWC, but it seems to work, but + * disable it since we don't know if a special UBWC format is needed + * like NV12 + */ + if (image->vk_format == VK_FORMAT_G8_B8R8_2PLANE_420_UNORM || + image->vk_format == VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM) + ubwc_enabled = false; + /* don't use UBWC with compressed formats */ if (vk_format_is_compressed(image->vk_format)) ubwc_enabled = false; @@ -293,6 +303,8 @@ tu6_texswiz(const VkComponentMapping *comps, switch (format) { case VK_FORMAT_G8B8G8R8_422_UNORM: case VK_FORMAT_B8G8R8G8_422_UNORM: + case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM: + case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM: swiz[0] = A6XX_TEX_Z; swiz[1] = A6XX_TEX_X; swiz[2] = A6XX_TEX_Y; @@ -438,6 +450,48 @@ tu_image_view_init(struct tu_image_view *iview, iview->descriptor[4] = base_addr; iview->descriptor[5] = (base_addr >> 32) | A6XX_TEX_CONST_5_DEPTH(depth); + if (format == VK_FORMAT_G8_B8R8_2PLANE_420_UNORM || + format == VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM) { + /* chroma offset re-uses MIPLVLS bits */ + assert(tu_get_levelCount(image, range) == 1); + if (conversion) { + if (conversion->chroma_offsets[0] == VK_CHROMA_LOCATION_MIDPOINT) + iview->descriptor[0] |= A6XX_TEX_CONST_0_CHROMA_MIDPOINT_X; + if (conversion->chroma_offsets[1] == VK_CHROMA_LOCATION_MIDPOINT) + iview->descriptor[0] |= A6XX_TEX_CONST_0_CHROMA_MIDPOINT_Y; + } + + uint64_t base_addr[3]; + + iview->descriptor[3] |= A6XX_TEX_CONST_3_TILE_ALL; + if (ubwc_enabled) { + iview->descriptor[3] |= A6XX_TEX_CONST_3_FLAG; + /* no separate ubwc base, image must have the expected layout */ + for (uint32_t i = 0; i < 3; i++) { + base_addr[i] = image->bo->iova + image->bo_offset + + fdl_ubwc_offset(&image->layout[i], range->baseMipLevel, range->baseArrayLayer); + } + } else { + for (uint32_t i = 0; i < 3; i++) { + base_addr[i] = image->bo->iova + image->bo_offset + + fdl_surface_offset(&image->layout[i], range->baseMipLevel, range->baseArrayLayer); + } + } + + iview->descriptor[4] = base_addr[0]; + iview->descriptor[5] |= base_addr[0] >> 32; + iview->descriptor[6] = + A6XX_TEX_CONST_6_PLANE_PITCH(image->layout[1].slices[range->baseMipLevel].pitch); + iview->descriptor[7] = base_addr[1]; + iview->descriptor[8] = base_addr[1] >> 32; + iview->descriptor[9] = base_addr[2]; + iview->descriptor[10] = base_addr[2] >> 32; + + assert(pCreateInfo->viewType != VK_IMAGE_VIEW_TYPE_3D); + assert(!(image->usage & VK_IMAGE_USAGE_STORAGE_BIT)); + return; + } + if (ubwc_enabled) { uint32_t block_width, block_height; fdl6_get_ubwc_blockwidth(layout, &block_width, &block_height); diff --git a/src/freedreno/vulkan/vk_format.h b/src/freedreno/vulkan/vk_format.h index 5755ed0de52..890e453c218 100644 --- a/src/freedreno/vulkan/vk_format.h +++ b/src/freedreno/vulkan/vk_format.h @@ -132,6 +132,8 @@ vk_format_get_component_bits(VkFormat format, switch (format) { case VK_FORMAT_G8B8G8R8_422_UNORM: case VK_FORMAT_B8G8R8G8_422_UNORM: + case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM: + case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM: /* util_format_get_component_bits doesn't return what we want */ return 8; default: -- 2.30.2