[Mesa-dev] [PATCH 2/2] anv: Add support for shaderStorageImageWriteWithoutFormat
Jason Ekstrand
jason at jlekstrand.net
Mon Feb 13 17:31:37 UTC 2017
On Mon, Feb 13, 2017 at 9:28 AM, Lionel Landwerlin <
lionel.g.landwerlin at intel.com> wrote:
> On 09/02/17 16:06, Alex Smith wrote:
>
>> This allows shaders to write to storage images declared with unknown
>> format if they are decorated with NonReadable ("writeonly" in GLSL).
>>
>> Previously an image view would always use a lowered format for its
>> surface state, however when a shader declares a write-only image, we
>> should use the real format. Since we don't know at view creation time
>> whether it will be used with only write-only images in shaders, create
>> two surface states using both the original format and the lowered
>> format. When emitting the binding table, choose between the states
>> based on whether the image is declared write-only in the shader.
>>
>> Tested on both Sascha Willems' computeshader sample (with the original
>> shaders and ones modified to declare images writeonly and omit their
>> format qualifiers) and on our own shaders for which we need support
>> for this.
>>
>> Signed-off-by: Alex Smith <asmith at feralinteractive.com>
>> ---
>> src/intel/vulkan/anv_device.c | 2 +-
>> src/intel/vulkan/anv_image.c | 31
>> +++++++++++++++++++++++-
>> src/intel/vulkan/anv_nir_apply_pipeline_layout.c | 10 +++++---
>> src/intel/vulkan/anv_pipeline.c | 1 +
>> src/intel/vulkan/anv_private.h | 10 +++++++-
>> src/intel/vulkan/genX_cmd_buffer.c | 4 ++-
>> 6 files changed, 50 insertions(+), 8 deletions(-)
>>
>> diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.
>> c
>> index 91ee67f..46b83a3 100644
>> --- a/src/intel/vulkan/anv_device.c
>> +++ b/src/intel/vulkan/anv_device.c
>> @@ -484,7 +484,7 @@ void anv_GetPhysicalDeviceFeatures(
>> .shaderStorageImageExtendedFormats = true,
>> .shaderStorageImageMultisample = false,
>> .shaderStorageImageReadWithoutFormat = false,
>> - .shaderStorageImageWriteWithoutFormat = false,
>> + .shaderStorageImageWriteWithoutFormat = true,
>> .shaderUniformBufferArrayDynamicIndexing = true,
>> .shaderSampledImageArrayDynamicIndexing = true,
>> .shaderStorageBufferArrayDynamicIndexing = true,
>> diff --git a/src/intel/vulkan/anv_image.c b/src/intel/vulkan/anv_image.c
>> index e59ef4d..1aeec44 100644
>> --- a/src/intel/vulkan/anv_image.c
>> +++ b/src/intel/vulkan/anv_image.c
>> @@ -583,13 +583,29 @@ anv_CreateImageView(VkDevice _device,
>> /* NOTE: This one needs to go last since it may stomp
>> isl_view.format */
>> if (image->usage & VK_IMAGE_USAGE_STORAGE_BIT) {
>> iview->storage_surface_state = alloc_surface_state(device);
>> + iview->writeonly_storage_surface_state =
>> alloc_surface_state(device);
>> if (isl_has_matching_typed_storage_image_format(&device->info,
>>
>> format.isl_format)) {
>> struct isl_view view = iview->isl;
>> view.usage |= ISL_SURF_USAGE_STORAGE_BIT;
>> +
>> + /* Write-only accesses should use the real format. */
>> + isl_surf_fill_state(&device->isl_dev,
>> + iview->writeonly_storage_surface_state.map,
>> + .surf = &surface->isl,
>> + .view = &view,
>> + .aux_surf = &image->aux_surface.isl,
>> + .aux_usage = surf_usage,
>> + .mocs = device->default_mocs);
>> +
>> + /* Typed surface reads support a very limited subset of the
>> shader
>> + * image formats. Translate it into the closest format the
>> hardware
>> + * supports.
>> + */
>> view.format = isl_lower_storage_image_format(&device->info,
>>
>> format.isl_format);
>> +
>> isl_surf_fill_state(&device->isl_dev,
>> iview->storage_surface_state.map,
>> .surf = &surface->isl,
>> @@ -602,16 +618,24 @@ anv_CreateImageView(VkDevice _device,
>> ISL_FORMAT_RAW,
>> iview->offset,
>> iview->bo->size - iview->offset,
>> 1);
>> + anv_fill_buffer_surface_state(device,
>> + iview->writeonly_storage_surf
>> ace_state,
>> + ISL_FORMAT_RAW,
>> + iview->offset,
>> + iview->bo->size - iview->offset,
>> 1);
>> }
>> isl_surf_fill_image_param(&device->isl_dev,
>> &iview->storage_image_param,
>> &surface->isl, &iview->isl);
>> - if (!device->info.has_llc)
>> + if (!device->info.has_llc) {
>> anv_state_clflush(iview->storage_surface_state);
>> + anv_state_clflush(iview->writeonly_storage_surface_state);
>> + }
>> } else {
>> iview->storage_surface_state.alloc_size = 0;
>> + iview->writeonly_storage_surface_state.alloc_size = 0;
>> }
>> *pView = anv_image_view_to_handle(iview);
>> @@ -639,6 +663,11 @@ anv_DestroyImageView(VkDevice _device, VkImageView
>> _iview,
>> iview->storage_surface_state);
>> }
>> + if (iview->writeonly_storage_surface_state.alloc_size > 0) {
>> + anv_state_pool_free(&device->surface_state_pool,
>> + iview->writeonly_storage_surface_state);
>> + }
>> +
>> vk_free2(&device->alloc, pAllocator, iview);
>> }
>> diff --git a/src/intel/vulkan/anv_nir_apply_pipeline_layout.c
>> b/src/intel/vulkan/anv_nir_apply_pipeline_layout.c
>> index 8846c2e..296fd05 100644
>> --- a/src/intel/vulkan/anv_nir_apply_pipeline_layout.c
>> +++ b/src/intel/vulkan/anv_nir_apply_pipeline_layout.c
>> @@ -351,9 +351,6 @@ anv_nir_apply_pipeline_layout(struct anv_pipeline
>> *pipeline,
>> continue;
>> enum glsl_sampler_dim dim = glsl_get_sampler_dim(var->inte
>> rface_type);
>> - if (dim != GLSL_SAMPLER_DIM_SUBPASS &&
>> - dim != GLSL_SAMPLER_DIM_SUBPASS_MS)
>> - continue;
>> const uint32_t set = var->data.descriptor_set;
>> const uint32_t binding = var->data.binding;
>> @@ -369,7 +366,12 @@ anv_nir_apply_pipeline_layout(struct anv_pipeline
>> *pipeline,
>> assert(pipe_binding[i].set == set);
>> assert(pipe_binding[i].binding == binding);
>> assert(pipe_binding[i].index == i);
>> - pipe_binding[i].input_attachment_index = var->data.index + i;
>> +
>> + if (dim != GLSL_SAMPLER_DIM_SUBPASS &&
>> + dim != GLSL_SAMPLER_DIM_SUBPASS_MS)
>>
>
> This condition is incorrect, now that you moved it here, it should be
>
> if (dim == GLSL_SAMPLER_DIM_SUBPASS ||
> dim == GLSL_SAMPLER_DIM_SUBPASS_MS)
>
Thanks for catching that. I read too fast!
> With that fixed, this patch is :
>
> Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin at intel.com>
>
>
> + pipe_binding[i].input_attachment_index = var->data.index + i;
>> +
>> + pipe_binding[i].write_only = var->data.image.write_only;
>> }
>> }
>> diff --git a/src/intel/vulkan/anv_pipeline.c
>> b/src/intel/vulkan/anv_pipeline.c
>> index ca3823c..4410103 100644
>> --- a/src/intel/vulkan/anv_pipeline.c
>> +++ b/src/intel/vulkan/anv_pipeline.c
>> @@ -128,6 +128,7 @@ anv_shader_compile_to_nir(struct anv_device *device,
>> .float64 = device->instance->physicalDevice.info.gen >= 8,
>> .tessellation = true,
>> .draw_parameters = true,
>> + .image_write_without_format = true,
>> };
>> nir_function *entry_point =
>> diff --git a/src/intel/vulkan/anv_private.h
>> b/src/intel/vulkan/anv_private.h
>> index 51e85c7..8db851a 100644
>> --- a/src/intel/vulkan/anv_private.h
>> +++ b/src/intel/vulkan/anv_private.h
>> @@ -953,6 +953,9 @@ struct anv_pipeline_binding {
>> /* Input attachment index (relative to the subpass) */
>> uint8_t input_attachment_index;
>> +
>> + /* For a storage image, whether it is write-only */
>> + bool write_only;
>> };
>> struct anv_pipeline_layout {
>> @@ -1683,8 +1686,13 @@ struct anv_image_view {
>> /** RENDER_SURFACE_STATE when using image as a sampler surface. */
>> struct anv_state sampler_surface_state;
>> - /** RENDER_SURFACE_STATE when using image as a storage image. */
>> + /**
>> + * RENDER_SURFACE_STATE when using image as a storage image. Separate
>> states
>> + * for write-only and readable, using the real format for write-only
>> and the
>> + * lowered format for readable.
>> + */
>> struct anv_state storage_surface_state;
>> + struct anv_state writeonly_storage_surface_state;
>> struct brw_image_param storage_image_param;
>> };
>> diff --git a/src/intel/vulkan/genX_cmd_buffer.c
>> b/src/intel/vulkan/genX_cmd_buffer.c
>> index 8db26e9..b80159b 100644
>> --- a/src/intel/vulkan/genX_cmd_buffer.c
>> +++ b/src/intel/vulkan/genX_cmd_buffer.c
>> @@ -1211,7 +1211,9 @@ emit_binding_table(struct anv_cmd_buffer
>> *cmd_buffer,
>> break;
>> case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: {
>> - surface_state = desc->image_view->storage_surface_state;
>> + surface_state = (binding->write_only)
>> + ? desc->image_view->writeonly_storage_surface_state
>> + : desc->image_view->storage_surface_state;
>> assert(surface_state.alloc_size);
>> add_image_view_relocs(cmd_buffer, desc->image_view,
>> desc->image_view->image->aux_usage,
>>
>
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/mesa-dev/attachments/20170213/870488dd/attachment-0001.html>
More information about the mesa-dev
mailing list