From 783a21192c7cc35113ec089354369e1ad34a7df9 Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Mon, 14 Dec 2015 16:51:12 -0800 Subject: [PATCH] anv: Add support for storage texel buffers --- src/vulkan/anv_cmd_buffer.c | 11 +++++- src/vulkan/anv_descriptor_set.c | 7 +++- src/vulkan/anv_device.c | 1 + src/vulkan/anv_image.c | 64 +++++++++++++++++++++++++++------ src/vulkan/anv_private.h | 8 +++++ 5 files changed, 78 insertions(+), 13 deletions(-) diff --git a/src/vulkan/anv_cmd_buffer.c b/src/vulkan/anv_cmd_buffer.c index 984b885a4b6..759c4677a74 100644 --- a/src/vulkan/anv_cmd_buffer.c +++ b/src/vulkan/anv_cmd_buffer.c @@ -736,7 +736,16 @@ anv_cmd_buffer_emit_binding_table(struct anv_cmd_buffer *cmd_buffer, break; case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: - assert(!"Unsupported descriptor type"); + surface_state = desc->buffer_view->storage_surface_state; + bo = desc->buffer_view->bo; + bo_offset = desc->buffer_view->offset; + + struct brw_image_param *image_param = + &cmd_buffer->state.push_constants[stage]->images[image++]; + + anv_buffer_view_fill_image_param(cmd_buffer->device, desc->buffer_view, + image_param); + image_param->surface_idx = bias + s; break; default: diff --git a/src/vulkan/anv_descriptor_set.c b/src/vulkan/anv_descriptor_set.c index 52d2ffecdd6..a7b6b773012 100644 --- a/src/vulkan/anv_descriptor_set.c +++ b/src/vulkan/anv_descriptor_set.c @@ -133,11 +133,16 @@ VkResult anv_CreateDescriptorSetLayout( break; } - if (binding->descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) { + switch (binding->descriptorType) { + case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: + case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: for_each_bit(s, binding->stageFlags) { set_layout->binding[b].stage[s].image_index = image_count[s]; image_count[s] += binding->descriptorCount; } + break; + default: + break; } if (binding->pImmutableSamplers) { diff --git a/src/vulkan/anv_device.c b/src/vulkan/anv_device.c index ff224907854..df6472edfde 100644 --- a/src/vulkan/anv_device.c +++ b/src/vulkan/anv_device.c @@ -1472,6 +1472,7 @@ VkResult anv_CreateBuffer( return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); buffer->size = pCreateInfo->size; + buffer->usage = pCreateInfo->usage; buffer->bo = NULL; buffer->offset = 0; diff --git a/src/vulkan/anv_image.c b/src/vulkan/anv_image.c index 659fe80b320..159af6d19b0 100644 --- a/src/vulkan/anv_image.c +++ b/src/vulkan/anv_image.c @@ -505,26 +505,45 @@ anv_CreateBufferView(VkDevice _device, ANV_FROM_HANDLE(anv_buffer, buffer, pCreateInfo->buffer); struct anv_buffer_view *view; - /* TODO: Storage texel buffers */ - view = anv_alloc2(&device->alloc, pAllocator, sizeof(*view), 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); if (!view) return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); + const struct anv_format *format = + anv_format_for_vk_format(pCreateInfo->format); + + view->format = format->surface_format; view->bo = buffer->bo; view->offset = buffer->offset + pCreateInfo->offset; + view->range = pCreateInfo->range; - view->surface_state = - anv_state_pool_alloc(&device->surface_state_pool, 64, 64); + if (buffer->usage & VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT) { + view->surface_state = + anv_state_pool_alloc(&device->surface_state_pool, 64, 64); - const struct anv_format *format = - anv_format_for_vk_format(pCreateInfo->format); + anv_fill_buffer_surface_state(device, view->surface_state.map, + view->format, + view->offset, pCreateInfo->range, + format->isl_layout->bpb / 8); + } else { + view->surface_state = (struct anv_state){ 0 }; + } + + if (buffer->usage & VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT) { + view->storage_surface_state = + anv_state_pool_alloc(&device->surface_state_pool, 64, 64); - anv_fill_buffer_surface_state(device, view->surface_state.map, - format->surface_format, - view->offset, pCreateInfo->range, - format->isl_layout->bpb / 8); + enum isl_format storage_format = + isl_lower_storage_image_format(&device->isl_dev, view->format); + + anv_fill_buffer_surface_state(device, view->storage_surface_state.map, + storage_format, + view->offset, pCreateInfo->range, + format->isl_layout->bpb / 8); + } else { + view->storage_surface_state = (struct anv_state){ 0 }; + } *pView = anv_buffer_view_to_handle(view); @@ -538,7 +557,14 @@ anv_DestroyBufferView(VkDevice _device, VkBufferView bufferView, ANV_FROM_HANDLE(anv_device, device, _device); ANV_FROM_HANDLE(anv_buffer_view, view, bufferView); - anv_state_pool_free(&device->surface_state_pool, view->surface_state); + if (view->surface_state.alloc_size > 0) + anv_state_pool_free(&device->surface_state_pool, + view->surface_state); + + if (view->storage_surface_state.alloc_size > 0) + anv_state_pool_free(&device->surface_state_pool, + view->storage_surface_state); + anv_free2(&device->alloc, pAllocator, view); } @@ -599,3 +625,19 @@ anv_image_view_fill_image_param(struct anv_device *device, memset(param, 0, sizeof *param); anv_finishme("Actually fill out brw_image_param"); } + +void +anv_buffer_view_fill_image_param(struct anv_device *device, + struct anv_buffer_view *view, + struct brw_image_param *param) +{ + /* Set the swizzling shifts to all-ones to effectively disable swizzling -- + * See emit_address_calculation() in brw_fs_surface_builder.cpp for a more + * detailed explanation of these parameters. + */ + param->swizzling[0] = 0xff; + param->swizzling[1] = 0xff; + + param->stride[0] = isl_format_layouts[view->format].bpb / 8; + param->size[0] = view->range / param->stride[0]; +} diff --git a/src/vulkan/anv_private.h b/src/vulkan/anv_private.h index c5ab92c5438..8aaa2811fc7 100644 --- a/src/vulkan/anv_private.h +++ b/src/vulkan/anv_private.h @@ -921,6 +921,8 @@ struct anv_buffer { struct anv_device * device; VkDeviceSize size; + VkBufferUsageFlags usage; + /* Set when bound */ struct anv_bo * bo; VkDeviceSize offset; @@ -1517,10 +1519,13 @@ gen9_image_view_init(struct anv_image_view *iview, struct anv_cmd_buffer *cmd_buffer); struct anv_buffer_view { + enum isl_format format; /**< VkBufferViewCreateInfo::format */ struct anv_bo *bo; uint32_t offset; /**< Offset into bo. */ + uint64_t range; /**< VkBufferViewCreateInfo::range */ struct anv_state surface_state; + struct anv_state storage_surface_state; }; void anv_fill_buffer_surface_state(struct anv_device *device, void *state, @@ -1544,6 +1549,9 @@ void gen9_fill_buffer_surface_state(void *state, enum isl_format format, void anv_image_view_fill_image_param(struct anv_device *device, struct anv_image_view *view, struct brw_image_param *param); +void anv_buffer_view_fill_image_param(struct anv_device *device, + struct anv_buffer_view *view, + struct brw_image_param *param); struct anv_sampler { uint32_t state[4]; -- 2.30.2