From af5f13e58c9dfe3a54487a3b002370c1edd39cf3 Mon Sep 17 00:00:00 2001 From: Lionel Landwerlin Date: Tue, 17 Jan 2017 16:38:01 +0000 Subject: [PATCH] anv: add VK_KHR_descriptor_update_template support Signed-off-by: Lionel Landwerlin Reviewed-by: Jason Ekstrand --- src/intel/vulkan/anv_cmd_buffer.c | 33 ++++++++ src/intel/vulkan/anv_descriptor_set.c | 146 ++++++++++++++++++++++++++++++++ src/intel/vulkan/anv_device.c | 4 + src/intel/vulkan/anv_entrypoints_gen.py | 1 + src/intel/vulkan/anv_private.h | 48 +++++++++++ 5 files changed, 232 insertions(+) diff --git a/src/intel/vulkan/anv_cmd_buffer.c b/src/intel/vulkan/anv_cmd_buffer.c index 3ce8827..a6addd7 100644 --- a/src/intel/vulkan/anv_cmd_buffer.c +++ b/src/intel/vulkan/anv_cmd_buffer.c @@ -907,3 +907,36 @@ void anv_CmdPushDescriptorSetKHR( cmd_buffer->state.descriptors[_set] = set; cmd_buffer->state.descriptors_dirty |= set_layout->shader_stages; } + +void anv_CmdPushDescriptorSetWithTemplateKHR( + VkCommandBuffer commandBuffer, + VkDescriptorUpdateTemplateKHR descriptorUpdateTemplate, + VkPipelineLayout _layout, + uint32_t _set, + const void* pData) +{ + ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); + ANV_FROM_HANDLE(anv_descriptor_update_template, template, + descriptorUpdateTemplate); + ANV_FROM_HANDLE(anv_pipeline_layout, layout, _layout); + + assert(_set < MAX_PUSH_DESCRIPTORS); + + const struct anv_descriptor_set_layout *set_layout = + layout->set[_set].layout; + struct anv_descriptor_set *set = &cmd_buffer->state.push_descriptor.set; + + set->layout = set_layout; + set->size = anv_descriptor_set_layout_size(set_layout); + set->buffer_count = set_layout->buffer_count; + set->buffer_views = cmd_buffer->state.push_descriptor.buffer_views; + + anv_descriptor_set_write_template(set, + cmd_buffer->device, + &cmd_buffer->surface_state_stream, + template, + pData); + + cmd_buffer->state.descriptors[_set] = set; + cmd_buffer->state.descriptors_dirty |= set_layout->shader_stages; +} diff --git a/src/intel/vulkan/anv_descriptor_set.c b/src/intel/vulkan/anv_descriptor_set.c index e4224743..bbd3f0f 100644 --- a/src/intel/vulkan/anv_descriptor_set.c +++ b/src/intel/vulkan/anv_descriptor_set.c @@ -780,3 +780,149 @@ void anv_UpdateDescriptorSets( dst_desc[j] = src_desc[j]; } } + +/* + * Descriptor update templates. + */ + +void +anv_descriptor_set_write_template(struct anv_descriptor_set *set, + struct anv_device *device, + struct anv_state_stream *alloc_stream, + const struct anv_descriptor_update_template *template, + const void *data) +{ + const struct anv_descriptor_set_layout *layout = set->layout; + + for (uint32_t i = 0; i < template->entry_count; i++) { + const struct anv_descriptor_template_entry *entry = + &template->entries[i]; + const struct anv_descriptor_set_binding_layout *bind_layout = + &layout->binding[entry->binding]; + struct anv_descriptor *desc = &set->descriptors[bind_layout->descriptor_index]; + desc += entry->array_element; + + switch (entry->type) { + case VK_DESCRIPTOR_TYPE_SAMPLER: + case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: + case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: + case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: + case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: + for (uint32_t j = 0; j < entry->array_count; j++) { + const VkDescriptorImageInfo *info = + data + entry->offset + j * entry->stride; + anv_descriptor_set_write_image_view(set, + entry->type, + info->imageView, + info->sampler, + entry->binding, + entry->array_element + j); + } + break; + + case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: + case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: + for (uint32_t j = 0; j < entry->array_count; j++) { + const VkBufferView *_bview = + data + entry->offset + j * entry->stride; + ANV_FROM_HANDLE(anv_buffer_view, bview, *_bview); + + anv_descriptor_set_write_buffer_view(set, + entry->type, + bview, + entry->binding, + entry->array_element + j); + } + break; + + case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: + case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: + case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: + case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: + for (uint32_t j = 0; j < entry->array_count; j++) { + const VkDescriptorBufferInfo *info = + data + entry->offset + j * entry->stride; + ANV_FROM_HANDLE(anv_buffer, buffer, info->buffer); + + anv_descriptor_set_write_buffer(set, + device, + alloc_stream, + entry->type, + buffer, + entry->binding, + entry->array_element + j, + info->offset, info->range); + } + break; + + default: + break; + } + } +} + +VkResult anv_CreateDescriptorUpdateTemplateKHR( + VkDevice _device, + const VkDescriptorUpdateTemplateCreateInfoKHR* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkDescriptorUpdateTemplateKHR* pDescriptorUpdateTemplate) +{ + ANV_FROM_HANDLE(anv_device, device, _device); + struct anv_descriptor_update_template *template; + + size_t size = sizeof(*template) + + pCreateInfo->descriptorUpdateEntryCount * sizeof(template->entries[0]); + template = vk_alloc2(&device->alloc, pAllocator, size, 8, + VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); + if (template == NULL) + return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); + + if (pCreateInfo->templateType == VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR) + template->set = pCreateInfo->set; + + template->entry_count = pCreateInfo->descriptorUpdateEntryCount; + for (uint32_t i = 0; i < template->entry_count; i++) { + const VkDescriptorUpdateTemplateEntryKHR *pEntry = + &pCreateInfo->pDescriptorUpdateEntries[i]; + + template->entries[i] = (struct anv_descriptor_template_entry) { + .type = pEntry->descriptorType, + .binding = pEntry->dstBinding, + .array_element = pEntry->dstArrayElement, + .array_count = pEntry->descriptorCount, + .offset = pEntry->offset, + .stride = pEntry->stride, + }; + } + + *pDescriptorUpdateTemplate = + anv_descriptor_update_template_to_handle(template); + + return VK_SUCCESS; +} + +void anv_DestroyDescriptorUpdateTemplateKHR( + VkDevice _device, + VkDescriptorUpdateTemplateKHR descriptorUpdateTemplate, + const VkAllocationCallbacks* pAllocator) +{ + ANV_FROM_HANDLE(anv_device, device, _device); + ANV_FROM_HANDLE(anv_descriptor_update_template, template, + descriptorUpdateTemplate); + + vk_free2(&device->alloc, pAllocator, template); +} + +void anv_UpdateDescriptorSetWithTemplateKHR( + VkDevice _device, + VkDescriptorSet descriptorSet, + VkDescriptorUpdateTemplateKHR descriptorUpdateTemplate, + const void* pData) +{ + ANV_FROM_HANDLE(anv_device, device, _device); + ANV_FROM_HANDLE(anv_descriptor_set, set, descriptorSet); + ANV_FROM_HANDLE(anv_descriptor_update_template, template, + descriptorUpdateTemplate); + + anv_descriptor_set_write_template(set, device, NULL, template, pData); +} diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c index 0764db1..a5b91fd 100644 --- a/src/intel/vulkan/anv_device.c +++ b/src/intel/vulkan/anv_device.c @@ -265,6 +265,10 @@ static const VkExtensionProperties device_extensions[] = { { .extensionName = VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME, .specVersion = 1, + }, + { + .extensionName = VK_KHR_DESCRIPTOR_UPDATE_TEMPLATE_EXTENSION_NAME, + .specVersion = 1, } }; diff --git a/src/intel/vulkan/anv_entrypoints_gen.py b/src/intel/vulkan/anv_entrypoints_gen.py index b2b2b62..4e5d2ee 100644 --- a/src/intel/vulkan/anv_entrypoints_gen.py +++ b/src/intel/vulkan/anv_entrypoints_gen.py @@ -28,6 +28,7 @@ import xml.etree.ElementTree as ET max_api_version = 1.0 supported_extensions = [ + 'VK_KHR_descriptor_update_template', 'VK_KHR_get_physical_device_properties2', 'VK_KHR_maintenance1', 'VK_KHR_push_descriptor', diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index 8ac910a..b3bc1b3 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -950,6 +950,46 @@ struct anv_descriptor_pool { char data[0]; }; +enum anv_descriptor_template_entry_type { + ANV_DESCRIPTOR_TEMPLATE_ENTRY_TYPE_IMAGE, + ANV_DESCRIPTOR_TEMPLATE_ENTRY_TYPE_BUFFER, + ANV_DESCRIPTOR_TEMPLATE_ENTRY_TYPE_BUFFER_VIEW +}; + +struct anv_descriptor_template_entry { + /* The type of descriptor in this entry */ + VkDescriptorType type; + + /* Binding in the descriptor set */ + uint32_t binding; + + /* Offset at which to write into the descriptor set binding */ + uint32_t array_element; + + /* Number of elements to write into the descriptor set binding */ + uint32_t array_count; + + /* Offset into the user provided data */ + size_t offset; + + /* Stride between elements into the user provided data */ + size_t stride; +}; + +struct anv_descriptor_update_template { + /* The descriptor set this template corresponds to. This value is only + * valid if the template was created with the templateType + * VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR. + */ + uint8_t set; + + /* Number of entries in this template */ + uint32_t entry_count; + + /* Entries of the template */ + struct anv_descriptor_template_entry entries[0]; +}; + size_t anv_descriptor_set_layout_size(const struct anv_descriptor_set_layout *layout); @@ -979,6 +1019,13 @@ anv_descriptor_set_write_buffer(struct anv_descriptor_set *set, VkDeviceSize offset, VkDeviceSize range); +void +anv_descriptor_set_write_template(struct anv_descriptor_set *set, + struct anv_device *device, + struct anv_state_stream *alloc_stream, + const struct anv_descriptor_update_template *template, + const void *data); + VkResult anv_descriptor_set_create(struct anv_device *device, struct anv_descriptor_pool *pool, @@ -1981,6 +2028,7 @@ ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_buffer_view, VkBufferView) ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_descriptor_pool, VkDescriptorPool) ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_descriptor_set, VkDescriptorSet) ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_descriptor_set_layout, VkDescriptorSetLayout) +ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_descriptor_update_template, VkDescriptorUpdateTemplateKHR) ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_device_memory, VkDeviceMemory) ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_fence, VkFence) ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_event, VkEvent) -- 2.7.4