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>
This commit is contained in:
Jason Ekstrand 2021-05-04 10:40:55 -05:00 committed by Marge Bot
parent df0580312a
commit b13d0eea12
3 changed files with 39 additions and 12 deletions

View file

@ -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 ||

View file

@ -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);
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,
ISL_AUX_USAGE_NONE, NULL,
0,
&iview->planes[vplane].storage_surface_state,
&iview->planes[vplane].storage_image_param);
anv_image_fill_surface_state(device, image, 1ULL << iaspect_bit,
&iview->planes[vplane].isl,
ISL_SURF_USAGE_STORAGE_BIT,

View file

@ -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;