[Mesa-dev] [PATCH 2/2] anv: Add support for shaderStorageImageWriteWithoutFormat
Jason Ekstrand
jason at jlekstrand.net
Mon Feb 13 18:09:09 UTC 2017
On Mon, Feb 13, 2017 at 9:40 AM, Alex Smith <asmith at feralinteractive.com>
wrote:
> Hi Lionel,
>
> On 13 February 2017 at 17:28, 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_surf
>>> ace_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)
>>
>> With that fixed, this patch is :
>>
>> Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin at intel.com>
>
>
> Oops, thanks for that, I'll fix that as well.
>
It would be good to run the CTS with at least dEQP-VK.image.load_store.* to
make sure you didn't break anything before you re-send. If you're not
familiar with running dEQP, it's just
./deqp-vk -n 'dEQP-VK.image.load_store.*'
The quotes matter because dEQP needs to see the "*" not your shell.
--Jason
> Alex
>
>
>>
>>
>> + 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/92c90b12/attachment-0001.html>
More information about the mesa-dev
mailing list