From fc03723bcd9ff88f17673c6a8e2b40d601f00287 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Kristian=20H=C3=B8gsberg=20Kristensen?= Date: Mon, 21 Dec 2015 00:03:28 -0800 Subject: [PATCH] vk: Fill out buffer surface state when updating descriptor set We can do this when we update the descriptor set instead of on the fly. --- src/vulkan/anv_cmd_buffer.c | 57 ++++++++----------------- src/vulkan/anv_descriptor_set.c | 73 +++++++++++++++++++++++++++------ src/vulkan/anv_private.h | 16 +++++--- 3 files changed, 87 insertions(+), 59 deletions(-) diff --git a/src/vulkan/anv_cmd_buffer.c b/src/vulkan/anv_cmd_buffer.c index 9b54dee96bc..1eaa3df633c 100644 --- a/src/vulkan/anv_cmd_buffer.c +++ b/src/vulkan/anv_cmd_buffer.c @@ -536,8 +536,12 @@ void anv_CmdBindDescriptorSets( unsigned array_size = set_layout->binding[b].array_size; for (unsigned j = 0; j < array_size; j++) { + uint32_t range = 0; + if (desc->buffer_view) + range = desc->buffer_view; push->dynamic[d].offset = *(offsets++); - push->dynamic[d].range = (desc++)->range; + push->dynamic[d].range = range; + desc++; d++; } } @@ -582,31 +586,21 @@ add_surface_state_reloc(struct anv_cmd_buffer *cmd_buffer, state.offset + dword * 4, bo, offset); } -static void -fill_descriptor_buffer_surface_state(struct anv_device *device, void *state, - gl_shader_stage stage, - VkDescriptorType type, - uint32_t offset, uint32_t range) +const struct anv_format * +anv_format_for_descriptor_type(VkDescriptorType type) { - VkFormat format; switch (type) { case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: - format = VK_FORMAT_R32G32B32A32_SFLOAT; - break; + return anv_format_for_vk_format(VK_FORMAT_R32G32B32A32_SFLOAT); case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: - format = VK_FORMAT_UNDEFINED; - break; + return anv_format_for_vk_format(VK_FORMAT_UNDEFINED); default: unreachable("Invalid descriptor type"); } - - anv_fill_buffer_surface_state(device, state, - anv_format_for_vk_format(format)->surface_format, - offset, range, 1); } VkResult @@ -671,10 +665,10 @@ anv_cmd_buffer_emit_binding_table(struct anv_cmd_buffer *cmd_buffer, surface_state = anv_cmd_buffer_alloc_surface_state(cmd_buffer); - fill_descriptor_buffer_surface_state(cmd_buffer->device, - surface_state.map, stage, - VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, - bo_offset, 12); + const struct anv_format *format = + anv_format_for_descriptor_type(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER); + anv_fill_buffer_surface_state(cmd_buffer->device, surface_state.map, + format->surface_format, bo_offset, 12, 1); if (!cmd_buffer->device->info.has_llc) anv_state_clflush(surface_state); @@ -712,27 +706,6 @@ anv_cmd_buffer_emit_binding_table(struct anv_cmd_buffer *cmd_buffer, /* Nothing for us to do here */ continue; - 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: { - bo = desc->buffer->bo; - bo_offset = desc->buffer->offset + desc->offset; - - surface_state = - anv_cmd_buffer_alloc_surface_state(cmd_buffer); - - fill_descriptor_buffer_surface_state(cmd_buffer->device, - surface_state.map, - stage, desc->type, - bo_offset, desc->range); - - if (!cmd_buffer->device->info.has_llc) - anv_state_clflush(surface_state); - - break; - } - case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: @@ -755,6 +728,10 @@ anv_cmd_buffer_emit_binding_table(struct anv_cmd_buffer *cmd_buffer, 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: case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: surface_state = desc->buffer_view->surface_state; bo = desc->buffer_view->bo; diff --git a/src/vulkan/anv_descriptor_set.c b/src/vulkan/anv_descriptor_set.c index df53edd902c..6d38d114f96 100644 --- a/src/vulkan/anv_descriptor_set.c +++ b/src/vulkan/anv_descriptor_set.c @@ -82,6 +82,7 @@ VkResult anv_CreateDescriptorSetLayout( uint32_t sampler_count[MESA_SHADER_STAGES] = { 0, }; uint32_t surface_count[MESA_SHADER_STAGES] = { 0, }; uint32_t image_count[MESA_SHADER_STAGES] = { 0, }; + uint32_t buffer_count = 0; uint32_t dynamic_offset_count = 0; for (uint32_t j = 0; j < pCreateInfo->bindingCount; j++) { @@ -106,15 +107,19 @@ VkResult anv_CreateDescriptorSetLayout( } switch (binding->descriptorType) { + 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: + set_layout->binding[b].buffer_index = buffer_count; + buffer_count += binding->descriptorCount; + /* fall through */ + case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: - 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: case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: anv_foreach_stage(s, binding->stageFlags) { set_layout->binding[b].stage[s].surface_index = surface_count[s]; @@ -161,6 +166,7 @@ VkResult anv_CreateDescriptorSetLayout( set_layout->shader_stages |= binding->stageFlags; } + set_layout->buffer_count = buffer_count; set_layout->dynamic_offset_count = dynamic_offset_count; *pSetLayout = anv_descriptor_set_layout_to_handle(set_layout); @@ -371,6 +377,21 @@ anv_descriptor_set_create(struct anv_device *device, desc += layout->binding[b].array_size; } + /* XXX: Use the pool */ + set->buffer_views = + anv_alloc(&device->alloc, + sizeof(set->buffer_views[0]) * layout->buffer_count, 8, + VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); + if (!set->buffer_views) { + anv_free(&device->alloc, set); + return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); + } + + for (uint32_t b = 0; b < layout->buffer_count; b++) { + set->buffer_views[b].surface_state = + anv_state_pool_alloc(&device->surface_state_pool, 64, 64); + } + *out_set = set; return VK_SUCCESS; @@ -380,7 +401,13 @@ void anv_descriptor_set_destroy(struct anv_device *device, struct anv_descriptor_set *set) { - anv_free(&device->alloc /* XXX: Use the pool */, set); + /* XXX: Use the pool */ + for (uint32_t b = 0; b < set->layout->buffer_count; b++) + anv_state_pool_free(&device->surface_state_pool, + set->buffer_views[b].surface_state); + + anv_free(&device->alloc, set->buffer_views); + anv_free(&device->alloc, set); } VkResult anv_AllocateDescriptorSets( @@ -430,12 +457,14 @@ VkResult anv_FreeDescriptorSets( } void anv_UpdateDescriptorSets( - VkDevice device, + VkDevice _device, uint32_t descriptorWriteCount, const VkWriteDescriptorSet* pDescriptorWrites, uint32_t descriptorCopyCount, const VkCopyDescriptorSet* pDescriptorCopies) { + ANV_FROM_HANDLE(anv_device, device, _device); + for (uint32_t i = 0; i < descriptorWriteCount; i++) { const VkWriteDescriptorSet *write = &pDescriptorWrites[i]; ANV_FROM_HANDLE(anv_descriptor_set, set, write->dstSet); @@ -514,19 +543,37 @@ void anv_UpdateDescriptorSets( ANV_FROM_HANDLE(anv_buffer, buffer, write->pBufferInfo[j].buffer); assert(buffer); - desc[j] = (struct anv_descriptor) { - .type = write->descriptorType, - .buffer = buffer, - .offset = write->pBufferInfo[j].offset, - .range = write->pBufferInfo[j].range, - }; + struct anv_buffer_view *view = + &set->buffer_views[bind_layout->descriptor_index + j]; + + const struct anv_format *format = + anv_format_for_descriptor_type(write->descriptorType); + + view->format = format->surface_format; + view->bo = buffer->bo; + view->offset = buffer->offset + write->pBufferInfo[j].offset; /* For buffers with dynamic offsets, we use the full possible * range in the surface state and do the actual range-checking * in the shader. */ if (bind_layout->dynamic_offset_index >= 0) - desc[j].range = buffer->size - desc[j].offset; + view->range = buffer->size - write->pBufferInfo[j].offset; + else + view->range = write->pBufferInfo[j].range; + + anv_fill_buffer_surface_state(device, view->surface_state.map, + view->format, + view->offset, view->range, 1); + + if (!device->info.has_llc) + anv_state_clflush(view->surface_state); + + desc[j] = (struct anv_descriptor) { + .type = write->descriptorType, + .buffer_view = view, + }; + } default: diff --git a/src/vulkan/anv_private.h b/src/vulkan/anv_private.h index 6bd18952492..48992d99a71 100644 --- a/src/vulkan/anv_private.h +++ b/src/vulkan/anv_private.h @@ -808,6 +808,9 @@ struct anv_descriptor_set_binding_layout { /* Index into the dynamic state array for a dynamic buffer */ int16_t dynamic_offset_index; + /* Index into the descriptor set buffer views */ + int16_t buffer_index; + struct { /* Index into the binding table for the associated surface */ int16_t surface_index; @@ -833,6 +836,9 @@ struct anv_descriptor_set_layout { /* Shader stages affected by this descriptor set */ uint16_t shader_stages; + /* Number of buffers in this descriptor set */ + uint16_t buffer_count; + /* Number of dynamic offsets used by this descriptor set */ uint16_t dynamic_offset_count; @@ -852,17 +858,12 @@ struct anv_descriptor { }; struct anv_buffer_view *buffer_view; - - struct { - struct anv_buffer *buffer; - uint64_t offset; - uint64_t range; - }; }; }; struct anv_descriptor_set { const struct anv_descriptor_set_layout *layout; + struct anv_buffer_view *buffer_views; struct anv_descriptor descriptors[0]; }; @@ -1538,6 +1539,9 @@ struct anv_buffer_view { struct anv_state storage_surface_state; }; +const struct anv_format * +anv_format_for_descriptor_type(VkDescriptorType type); + void anv_fill_buffer_surface_state(struct anv_device *device, void *state, enum isl_format format, uint32_t offset, uint32_t range, -- 2.30.2