Mesa (master): turnip: enable 420_UNORM formats

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Sun Jul 5 15:45:27 UTC 2020


Module: Mesa
Branch: master
Commit: 1a83279da57f2e2702d9b13437eed6bfb958af52
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=1a83279da57f2e2702d9b13437eed6bfb958af52

Author: Jonathan Marek <jonathan at marek.ca>
Date:   Fri Apr 10 12:48:31 2020 -0400

turnip: enable 420_UNORM formats

Signed-off-by: Jonathan Marek <jonathan at marek.ca>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4600>

---

 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:



More information about the mesa-commit mailing list