turnip: enable UBWC for NV12
authorJonathan Marek <jonathan@marek.ca>
Sun, 20 Sep 2020 00:24:07 +0000 (20:24 -0400)
committerMarge Bot <eric+marge@anholt.net>
Fri, 22 Oct 2021 11:25:30 +0000 (11:25 +0000)
Use the special format for accessing the Y plane of UBWC-enabled NV12, and
enable UBWC for NV12.

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

src/freedreno/fdl/fd6_format_table.c
src/freedreno/vulkan/tu_clear_blit.c
src/freedreno/vulkan/tu_formats.c
src/freedreno/vulkan/tu_image.c

index 8f200db..d99d029 100644 (file)
@@ -67,6 +67,7 @@ static const struct fd6_format formats[PIPE_FORMAT_COUNT] = {
    V__(R8_USCALED, 8_UINT,                      WZYX),
    V__(R8_SSCALED, 8_SINT,                      WZYX),
    _TC(R8_SRGB,    8_UNORM,                     WZYX),
+   _TC(Y8_UNORM,   NV12_Y,                      WZYX),
 
    FMT(A8_UNORM,   NONE, 8_UNORM, A8_UNORM,     WZYX),
    _TC(L8_UNORM,   8_UNORM,                     WZYX),
@@ -389,14 +390,19 @@ fd6_texture_format(enum pipe_format format, enum a6xx_tile_mode tile_mode)
    if (!formats[format].present)
       return FMT6_NONE;
 
-   /* Linear ARGB/ABGR1555 has a special format for sampling (tiled 1555/5551
-    * formats always have the same swizzle and layout).
-    */
    if (!tile_mode) {
       switch (format) {
+      /* Linear ARGB/ABGR1555 has a special format for sampling (tiled
+       * 1555/5551 formats always have the same swizzle and layout).
+       */
       case PIPE_FORMAT_A1R5G5B5_UNORM:
       case PIPE_FORMAT_A1B5G5R5_UNORM:
          return FMT6_1_5_5_5_UNORM;
+      /* note: this may be more about UBWC than tiling, but we don't support
+       * tiled non-UBWC NV12
+       */
+      case PIPE_FORMAT_Y8_UNORM:
+         return FMT6_8_UNORM;
       default:
          break;
       }
@@ -428,6 +434,10 @@ fd6_color_format(enum pipe_format format, enum a6xx_tile_mode tile_mode)
 {
    if (!formats[format].present)
       return FMT6_NONE;
+
+   if (!tile_mode && format == PIPE_FORMAT_Y8_UNORM)
+      return FMT6_8_UNORM;
+
    return formats[format].rb;
 }
 
index e4afb6d..2e1f10a 100644 (file)
@@ -1188,7 +1188,7 @@ copy_format(VkFormat vk_format, VkImageAspectFlags aspect_mask, bool copy_buffer
       if (aspect_mask == VK_IMAGE_ASPECT_PLANE_1_BIT)
          return PIPE_FORMAT_R8G8_UNORM;
       else
-         return PIPE_FORMAT_R8_UNORM;
+         return PIPE_FORMAT_Y8_UNORM;
    case PIPE_FORMAT_R8_G8_B8_420_UNORM:
       return PIPE_FORMAT_R8_UNORM;
 
@@ -1502,9 +1502,9 @@ 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
-    */
+   /* note: could use "R8_UNORM" when no UBWC */
+   if (src_format == PIPE_FORMAT_Y8_UNORM)
+      ops = &r3d_ops;
 
    VkOffset3D offset = info->imageOffset;
    VkExtent3D extent = info->imageExtent;
@@ -1575,14 +1575,19 @@ tu_copy_image_to_buffer(struct tu_cmd_buffer *cmd,
       copy_format(src_image->vk_format, info->imageSubresource.aspectMask, true);
    enum pipe_format src_format =
       copy_format(src_image->vk_format, info->imageSubresource.aspectMask, false);
+   const struct blit_ops *ops = &r2d_ops;
    bool stencil_read = false;
 
    if (src_image->vk_format == VK_FORMAT_D24_UNORM_S8_UINT &&
        info->imageSubresource.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT) {
+      ops = &r3d_ops;
       stencil_read = true;
    }
 
-   const struct blit_ops *ops = stencil_read ? &r3d_ops : &r2d_ops;
+   /* note: could use "R8_UNORM" when no UBWC */
+   if (dst_format == PIPE_FORMAT_Y8_UNORM)
+      ops = &r3d_ops;
+
    VkOffset3D offset = info->imageOffset;
    VkExtent3D extent = info->imageExtent;
    uint32_t dst_width = info->bufferRowLength ?: extent.width;
@@ -1707,6 +1712,11 @@ tu_copy_image_to_image(struct tu_cmd_buffer *cmd,
    enum pipe_format dst_format = copy_format(dst_image->vk_format, info->dstSubresource.aspectMask, false);
    enum pipe_format src_format = copy_format(src_image->vk_format, info->srcSubresource.aspectMask, false);
 
+   /* note: could use "R8_UNORM" when no UBWC */
+   if (dst_format == PIPE_FORMAT_Y8_UNORM ||
+       src_format == PIPE_FORMAT_Y8_UNORM)
+      ops = &r3d_ops;
+
    bool use_staging_blit = false;
 
    if (src_format == dst_format) {
index e783e9b..0eaf284 100644 (file)
@@ -254,14 +254,15 @@ tu_physical_device_get_format_properties(
 
    if (vk_format == VK_FORMAT_G8B8G8R8_422_UNORM ||
        vk_format == VK_FORMAT_B8G8R8G8_422_UNORM ||
-       vk_format == VK_FORMAT_G8_B8R8_2PLANE_420_UNORM ||
        vk_format == VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM) {
-      /* no tiling for special UBWC formats
-       * TODO: NV12 can be UBWC but has a special UBWC format for accessing the Y plane aspect
-       * for 3plane, tiling/UBWC might be supported, but the blob doesn't use tiling
-       */
+      /* these formats don't support UBWC or tiling */
       optimal = 0;
+   }
 
+   if (vk_format == VK_FORMAT_G8B8G8R8_422_UNORM ||
+       vk_format == VK_FORMAT_B8G8R8G8_422_UNORM ||
+       vk_format == VK_FORMAT_G8_B8R8_2PLANE_420_UNORM ||
+       vk_format == VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM) {
       /* Disable buffer texturing of subsampled (422) and planar YUV textures.
        * The subsampling requirement comes from "If format is a block-compressed
        * format, then bufferFeatures must not support any features for the
index 4d9b2e9..8beb843 100644 (file)
@@ -56,8 +56,7 @@ tu6_plane_format(VkFormat format, uint32_t plane)
 {
    switch (format) {
    case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
-      /* note: with UBWC, and Y plane UBWC is different from R8_UNORM */
-      return plane ? PIPE_FORMAT_R8G8_UNORM : PIPE_FORMAT_R8_UNORM;
+      return plane ? PIPE_FORMAT_R8G8_UNORM : PIPE_FORMAT_Y8_UNORM;
    case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
       return PIPE_FORMAT_R8_UNORM;
    case VK_FORMAT_D32_SFLOAT_S8_UINT:
@@ -249,6 +248,19 @@ tu_image_view_init(struct tu_image_view *iview,
    else
       format = tu_vk_format_to_pipe_format(vk_format);
 
+   if (image->vk_format == VK_FORMAT_G8_B8R8_2PLANE_420_UNORM &&
+       aspect_mask == VK_IMAGE_ASPECT_PLANE_0_BIT) {
+      if (vk_format == VK_FORMAT_R8_UNORM) {
+         /* The 0'th plane of this format has a different UBWC compression. */
+         format = PIPE_FORMAT_Y8_UNORM;
+      } else {
+         /* If the user wants to reinterpret this plane, then they should've
+          * set MUTABLE_FORMAT_BIT which should disable UBWC and tiling.
+          */
+         assert(!layouts[0]->ubwc);
+      }
+   }
+
    if (aspect_mask == VK_IMAGE_ASPECT_COLOR_BIT &&
        (vk_format == VK_FORMAT_G8_B8R8_2PLANE_420_UNORM ||
         vk_format == VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM)) {