diff options
author | Alex Smith <[email protected]> | 2017-02-14 10:34:49 +0000 |
---|---|---|
committer | Jason Ekstrand <[email protected]> | 2017-02-14 08:16:52 -0800 |
commit | 924a8cbb408e7dd110d172093908f99926b7970d (patch) | |
tree | 5804a5c32f959de05fbaaeeccfda2cd96e4f9fee /src/intel/vulkan/anv_image.c | |
parent | 94d48b7f9f143ff333dff4eba8069ee26acbf4e0 (diff) |
anv: Add support for shaderStorageImageWriteWithoutFormat
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 <[email protected]>
Reviewed-by: Lionel Landwerlin <[email protected]>
Reviewed-by: Jason Ekstrand <[email protected]>
Diffstat (limited to 'src/intel/vulkan/anv_image.c')
-rw-r--r-- | src/intel/vulkan/anv_image.c | 44 |
1 files changed, 41 insertions, 3 deletions
diff --git a/src/intel/vulkan/anv_image.c b/src/intel/vulkan/anv_image.c index e59ef4dbb67..cf4304a0cc3 100644 --- a/src/intel/vulkan/anv_image.c +++ b/src/intel/vulkan/anv_image.c @@ -583,13 +583,31 @@ 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); + + struct isl_view view = iview->isl; + view.usage |= ISL_SURF_USAGE_STORAGE_BIT; + + /* Write-only accesses always used a typed write instruction and should + * therefore 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); 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; + /* 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, @@ -608,10 +626,13 @@ anv_CreateImageView(VkDevice _device, &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 +660,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); } @@ -682,6 +708,7 @@ anv_CreateBufferView(VkDevice _device, if (buffer->usage & VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT) { view->storage_surface_state = alloc_surface_state(device); + view->writeonly_storage_surface_state = alloc_surface_state(device); enum isl_format storage_format = isl_has_matching_typed_storage_image_format(&device->info, @@ -695,11 +722,18 @@ anv_CreateBufferView(VkDevice _device, (storage_format == ISL_FORMAT_RAW ? 1 : isl_format_get_layout(storage_format)->bpb / 8)); + /* Write-only accesses should use the original format. */ + anv_fill_buffer_surface_state(device, view->writeonly_storage_surface_state, + view->format, + view->offset, view->range, + isl_format_get_layout(view->format)->bpb / 8); + isl_buffer_fill_image_param(&device->isl_dev, &view->storage_image_param, view->format, view->range); } else { view->storage_surface_state = (struct anv_state){ 0 }; + view->writeonly_storage_surface_state = (struct anv_state){ 0 }; } *pView = anv_buffer_view_to_handle(view); @@ -725,6 +759,10 @@ anv_DestroyBufferView(VkDevice _device, VkBufferView bufferView, anv_state_pool_free(&device->surface_state_pool, view->storage_surface_state); + if (view->writeonly_storage_surface_state.alloc_size > 0) + anv_state_pool_free(&device->surface_state_pool, + view->writeonly_storage_surface_state); + vk_free2(&device->alloc, pAllocator, view); } |