Mesa (staging/19.3): anv: Canonicalize buffer formats for image/buffer copies

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Jan 23 22:40:49 UTC 2020


Module: Mesa
Branch: staging/19.3
Commit: 3fc3d4d2bffd49310b1dbb49aad71728aed1f798
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=3fc3d4d2bffd49310b1dbb49aad71728aed1f798

Author: Jason Ekstrand <jason at jlekstrand.net>
Date:   Fri Jan 17 17:46:31 2020 -0600

anv: Canonicalize buffer formats for image/buffer copies

Some formats, in particular YCbCr formats and ASTC have additional
restrictions.  We already whack ASTC formats to RGBA32_UINT because the
hardware doesn't allow LINEAR with ASTC.  However, we need to fix YCbCr
formats as well because they come with alignment restrictions that we
can't guarantee are satisfied.  We're using blorp_copy to do the copies
so we may as well just stomp formats for everything.

Fixes: b24b93d5843 "anv: enable VK_KHR_sampler_ycbcr_conversion"
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin at intel.com>
Tested-by: Marge Bot <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3460>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3460>
(cherry picked from commit dd92179a72e5263b9db730d92a883e2536aa4474)

---

 .pick_status.json            |  2 +-
 src/intel/vulkan/anv_blorp.c | 62 ++++++++++++++++++++++++++++++--------------
 2 files changed, 43 insertions(+), 21 deletions(-)

diff --git a/.pick_status.json b/.pick_status.json
index 4f398a425fd..90b90c5da26 100644
--- a/.pick_status.json
+++ b/.pick_status.json
@@ -1867,7 +1867,7 @@
         "description": "anv: Canonicalize buffer formats for image/buffer copies",
         "nominated": true,
         "nomination_type": 1,
-        "resolution": 0,
+        "resolution": 1,
         "master_sha": null,
         "because_sha": "b24b93d58431a4349eecddb07304f6eda648e997"
     },
diff --git a/src/intel/vulkan/anv_blorp.c b/src/intel/vulkan/anv_blorp.c
index bb831ceb069..0ad1f77f87a 100644
--- a/src/intel/vulkan/anv_blorp.c
+++ b/src/intel/vulkan/anv_blorp.c
@@ -403,6 +403,24 @@ void anv_CmdCopyImage(
    blorp_batch_finish(&batch);
 }
 
+static enum isl_format
+isl_format_for_size(unsigned size_B)
+{
+   /* Prefer 32-bit per component formats for CmdFillBuffer */
+   switch (size_B) {
+   case 1:  return ISL_FORMAT_R8_UINT;
+   case 2:  return ISL_FORMAT_R16_UINT;
+   case 3:  return ISL_FORMAT_R8G8B8_UINT;
+   case 4:  return ISL_FORMAT_R32_UINT;
+   case 6:  return ISL_FORMAT_R16G16B16_UINT;
+   case 8:  return ISL_FORMAT_R32G32_UINT;
+   case 12: return ISL_FORMAT_R32G32B32_UINT;
+   case 16: return ISL_FORMAT_R32G32B32A32_UINT;
+   default:
+      unreachable("Unknown format size");
+   }
+}
+
 static void
 copy_buffer_to_image(struct anv_cmd_buffer *cmd_buffer,
                      struct anv_buffer *anv_buffer,
@@ -450,12 +468,11 @@ copy_buffer_to_image(struct anv_cmd_buffer *cmd_buffer,
             anv_get_layerCount(anv_image, &pRegions[r].imageSubresource);
       }
 
-      const enum isl_format buffer_format =
+      const enum isl_format linear_format =
          anv_get_isl_format(&cmd_buffer->device->info, anv_image->vk_format,
                             aspect, VK_IMAGE_TILING_LINEAR);
-
-      const struct isl_format_layout *buffer_fmtl =
-         isl_format_get_layout(buffer_format);
+      const struct isl_format_layout *linear_fmtl =
+         isl_format_get_layout(linear_format);
 
       const uint32_t buffer_row_length =
          pRegions[r].bufferRowLength ?
@@ -466,17 +483,34 @@ copy_buffer_to_image(struct anv_cmd_buffer *cmd_buffer,
          pRegions[r].bufferImageHeight : extent.height;
 
       const uint32_t buffer_row_pitch =
-         DIV_ROUND_UP(buffer_row_length, buffer_fmtl->bw) *
-         (buffer_fmtl->bpb / 8);
+         DIV_ROUND_UP(buffer_row_length, linear_fmtl->bw) *
+         (linear_fmtl->bpb / 8);
 
       const uint32_t buffer_layer_stride =
-         DIV_ROUND_UP(buffer_image_height, buffer_fmtl->bh) *
+         DIV_ROUND_UP(buffer_image_height, linear_fmtl->bh) *
          buffer_row_pitch;
 
+      /* Some formats have additional restrictions which may cause ISL to
+       * fail to create a surface for us.  Some examples include:
+       *
+       *    1. ASTC formats are not allowed to be LINEAR and must be tiled
+       *    2. YCbCr formats have to have 2-pixel aligned strides
+       *
+       * To avoid these issues, we always bind the buffer as if it's a
+       * "normal" format like RGBA32_UINT.  Since we're using blorp_copy,
+       * the format doesn't matter as long as it has the right bpb.
+       */
+      const VkExtent2D buffer_extent = {
+         .width = DIV_ROUND_UP(extent.width, linear_fmtl->bw),
+         .height = DIV_ROUND_UP(extent.height, linear_fmtl->bh),
+      };
+      const enum isl_format buffer_format =
+         isl_format_for_size(linear_fmtl->bpb / 8);
+
       struct isl_surf buffer_isl_surf;
       get_blorp_surf_for_anv_buffer(cmd_buffer->device,
                                     anv_buffer, pRegions[r].bufferOffset,
-                                    extent.width, extent.height,
+                                    buffer_extent.width, buffer_extent.height,
                                     buffer_row_pitch, buffer_format,
                                     &buffer.surf, &buffer_isl_surf);
 
@@ -692,18 +726,6 @@ void anv_CmdBlitImage(
    blorp_batch_finish(&batch);
 }
 
-static enum isl_format
-isl_format_for_size(unsigned size_B)
-{
-   switch (size_B) {
-   case 4:  return ISL_FORMAT_R32_UINT;
-   case 8:  return ISL_FORMAT_R32G32_UINT;
-   case 16: return ISL_FORMAT_R32G32B32A32_UINT;
-   default:
-      unreachable("Not a power-of-two format size");
-   }
-}
-
 /**
  * Returns the greatest common divisor of a and b that is a power of two.
  */



More information about the mesa-commit mailing list