Mesa (master): anv: Allow storage on all formats that support typed writes

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed May 5 12:26:15 UTC 2021


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

Author: Jason Ekstrand <jason at jlekstrand.net>
Date:   Tue May  4 10:40:55 2021 -0500

anv: Allow storage on all formats that support typed writes

In particular, this gives us B8G8R8A8_UNORM storage support which is
useful for writing WSI images from compute shaders.  These formats can
only be accessed in a spec-compliant way by decorating the variable
NonReadable in the SPIR-V (writeonly in GLSL).  If the client doesn't so
decorate the variable, it'll get the null surface state where reads
return 0 and writes are ignored.

Tested-by: Simon Ser <contact at emersion.fr>
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin at intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10624>

---

 src/intel/vulkan/anv_formats.c     |  2 +-
 src/intel/vulkan/anv_image.c       | 33 +++++++++++++++++++++++----------
 src/intel/vulkan/genX_cmd_buffer.c | 16 +++++++++++++++-
 3 files changed, 39 insertions(+), 12 deletions(-)

diff --git a/src/intel/vulkan/anv_formats.c b/src/intel/vulkan/anv_formats.c
index db23a14e9c5..a0e7d5f4fed 100644
--- a/src/intel/vulkan/anv_formats.c
+++ b/src/intel/vulkan/anv_formats.c
@@ -636,7 +636,7 @@ anv_get_image_format_features(const struct intel_device_info *devinfo,
    /* Load/store is determined based on base format.  This prevents RGB
     * formats from showing up as load/store capable.
     */
-   if (isl_is_storage_image_format(base_isl_format))
+   if (isl_format_supports_typed_writes(devinfo, base_isl_format))
       flags |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT;
 
    if (base_isl_format == ISL_FORMAT_R32_SINT ||
diff --git a/src/intel/vulkan/anv_image.c b/src/intel/vulkan/anv_image.c
index e47e525affa..b6d34ea66b4 100644
--- a/src/intel/vulkan/anv_image.c
+++ b/src/intel/vulkan/anv_image.c
@@ -2872,17 +2872,30 @@ anv_CreateImageView(VkDevice _device,
 
       /* NOTE: This one needs to go last since it may stomp isl_view.format */
       if (view_usage & VK_IMAGE_USAGE_STORAGE_BIT) {
-         iview->planes[vplane].storage_surface_state.state = alloc_surface_state(device);
-         iview->planes[vplane].writeonly_storage_surface_state.state = alloc_surface_state(device);
-
-         anv_image_fill_surface_state(device, image, 1ULL << iaspect_bit,
-                                      &iview->planes[vplane].isl,
-                                      ISL_SURF_USAGE_STORAGE_BIT,
-                                      ISL_AUX_USAGE_NONE, NULL,
-                                      0,
-                                      &iview->planes[vplane].storage_surface_state,
-                                      &iview->planes[vplane].storage_image_param);
+         if (isl_is_storage_image_format(format.isl_format)) {
+            iview->planes[vplane].storage_surface_state.state =
+               alloc_surface_state(device);
+
+            anv_image_fill_surface_state(device, image, 1ULL << iaspect_bit,
+                                         &iview->planes[vplane].isl,
+                                         ISL_SURF_USAGE_STORAGE_BIT,
+                                         ISL_AUX_USAGE_NONE, NULL,
+                                         0,
+                                         &iview->planes[vplane].storage_surface_state,
+                                         &iview->planes[vplane].storage_image_param);
+         } else {
+            /* In this case, we support the format but, because there's no
+             * SPIR-V format specifier corresponding to it, we only support
+             * NonReadable (writeonly in GLSL) access.  Instead of hanging in
+             * these invalid cases, we give them a NULL descriptor.
+             */
+            assert(isl_format_supports_typed_writes(&device->info,
+                                                    format.isl_format));
+            iview->planes[vplane].storage_surface_state.state =
+               device->null_surface_state;
+         }
 
+         iview->planes[vplane].writeonly_storage_surface_state.state = alloc_surface_state(device);
          anv_image_fill_surface_state(device, image, 1ULL << iaspect_bit,
                                       &iview->planes[vplane].isl,
                                       ISL_SURF_USAGE_STORAGE_BIT,
diff --git a/src/intel/vulkan/genX_cmd_buffer.c b/src/intel/vulkan/genX_cmd_buffer.c
index 1d1a08cf548..84eaf85d524 100644
--- a/src/intel/vulkan/genX_cmd_buffer.c
+++ b/src/intel/vulkan/genX_cmd_buffer.c
@@ -2721,7 +2721,21 @@ emit_binding_table(struct anv_cmd_buffer *cmd_buffer,
                   : desc->image_view->planes[binding->plane].storage_surface_state;
                surface_state = sstate.state;
                assert(surface_state.alloc_size);
-               if (need_client_mem_relocs)
+               if (surface_state.offset == 0) {
+                  mesa_loge("Bound a image to a descriptor where the "
+                            "descriptor does not have NonReadable "
+                            "set and the image does not have a "
+                            "corresponding SPIR-V format enum.");
+                  vk_debug_report(&cmd_buffer->device->physical->instance->vk,
+                                  VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                                  &desc->image_view->base,
+                                  __LINE__, 0, "anv",
+                                  "Bound a image to a descriptor where the "
+                                  "descriptor does not have NonReadable "
+                                  "set and the image does not have a "
+                                  "corresponding SPIR-V format enum.");
+               }
+               if (surface_state.offset && need_client_mem_relocs)
                   add_surface_state_relocs(cmd_buffer, sstate);
             } else {
                surface_state = cmd_buffer->device->null_surface_state;



More information about the mesa-commit mailing list