From b13d0eea127e390f083dac13ae33d6d1e3de0531 Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Tue, 4 May 2021 10:40:55 -0500 Subject: [PATCH] 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 Reviewed-by: Lionel Landwerlin Part-of: --- 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 db23a14..a0e7d5f 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 e47e525..b6d34ea 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 1d1a08c..84eaf85 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; -- 2.7.4