summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Ekstrand <jason@jlekstrand.net>2021-05-04 10:40:55 -0500
committerMarge Bot <eric+marge@anholt.net>2021-05-05 12:20:09 +0000
commitb13d0eea127e390f083dac13ae33d6d1e3de0531 (patch)
tree13cb787192a3dbc85c2e3ea3620327fe55865fb0
parentdf0580312a1f94f2347fea14e0e7b1585b96de71 (diff)
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@emersion.fr> Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10624>
-rw-r--r--src/intel/vulkan/anv_formats.c2
-rw-r--r--src/intel/vulkan/anv_image.c33
-rw-r--r--src/intel/vulkan/genX_cmd_buffer.c16
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;