VkDescriptorSetLayout* pSetLayout)
{
ANV_FROM_HANDLE(anv_device, device, _device);
- struct anv_descriptor_set_layout *set_layout;
assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO);
immutable_sampler_count += pCreateInfo->pBindings[j].descriptorCount;
}
- size_t size = sizeof(struct anv_descriptor_set_layout) +
- (max_binding + 1) * sizeof(set_layout->binding[0]) +
- immutable_sampler_count * sizeof(struct anv_sampler *);
+ struct anv_descriptor_set_layout *set_layout;
+ struct anv_descriptor_set_binding_layout *bindings;
+ struct anv_sampler **samplers;
- set_layout = vk_alloc2(&device->alloc, pAllocator, size, 8,
- VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
- if (!set_layout)
- return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+ ANV_MULTIALLOC(ma);
+ anv_multialloc_add(&ma, &set_layout, 1);
+ anv_multialloc_add(&ma, &bindings, max_binding + 1);
+ anv_multialloc_add(&ma, &samplers, immutable_sampler_count);
- /* We just allocate all the samplers at the end of the struct */
- struct anv_sampler **samplers =
- (struct anv_sampler **)&set_layout->binding[max_binding + 1];
+ if (!anv_multialloc_alloc2(&ma, &device->alloc, pAllocator,
+ VK_SYSTEM_ALLOCATION_SCOPE_OBJECT))
+ return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
memset(set_layout, 0, sizeof(*set_layout));
set_layout->binding_count = max_binding + 1;
if (binding == NULL)
continue;
- assert(binding->descriptorCount > 0);
+ if (binding->descriptorCount == 0)
+ continue;
+
#ifndef NDEBUG
set_layout->binding[b].type = binding->descriptorType;
#endif
}
}
- struct mesa_sha1 *ctx = _mesa_sha1_init();
+ struct mesa_sha1 ctx;
+ _mesa_sha1_init(&ctx);
for (unsigned s = 0; s < layout->num_sets; s++) {
- sha1_update_descriptor_set_layout(ctx, layout->set[s].layout);
- _mesa_sha1_update(ctx, &layout->set[s].dynamic_offset_start,
+ sha1_update_descriptor_set_layout(&ctx, layout->set[s].layout);
+ _mesa_sha1_update(&ctx, &layout->set[s].dynamic_offset_start,
sizeof(layout->set[s].dynamic_offset_start));
}
- _mesa_sha1_update(ctx, &layout->num_sets, sizeof(layout->num_sets));
+ _mesa_sha1_update(&ctx, &layout->num_sets, sizeof(layout->num_sets));
for (unsigned s = 0; s < MESA_SHADER_STAGES; s++) {
- _mesa_sha1_update(ctx, &layout->stage[s].has_dynamic_offsets,
+ _mesa_sha1_update(&ctx, &layout->stage[s].has_dynamic_offsets,
sizeof(layout->stage[s].has_dynamic_offsets));
}
- _mesa_sha1_final(ctx, layout->sha1);
+ _mesa_sha1_final(&ctx, layout->sha1);
*pPipelineLayout = anv_pipeline_layout_to_handle(layout);
pool->free_list = EMPTY;
anv_state_stream_init(&pool->surface_state_stream,
- &device->surface_state_block_pool);
+ &device->surface_state_pool, 4096);
pool->surface_state_free_list = NULL;
*pDescriptorPool = anv_descriptor_pool_to_handle(pool);
pool->free_list = EMPTY;
anv_state_stream_finish(&pool->surface_state_stream);
anv_state_stream_init(&pool->surface_state_stream,
- &device->surface_state_block_pool);
+ &device->surface_state_pool, 4096);
pool->surface_state_free_list = NULL;
return VK_SUCCESS;
layout->buffer_count * sizeof(struct anv_buffer_view);
}
+size_t
+anv_descriptor_set_binding_layout_get_hw_size(const struct anv_descriptor_set_binding_layout *binding)
+{
+ if (!binding->immutable_samplers)
+ return binding->array_size;
+
+ uint32_t total_plane_count = 0;
+ for (uint32_t i = 0; i < binding->array_size; i++)
+ total_plane_count += binding->immutable_samplers[i]->n_planes;
+
+ return total_plane_count;
+}
+
struct surface_state_free_list_entry {
void *next;
struct anv_state state;
void
anv_descriptor_set_write_image_view(struct anv_descriptor_set *set,
+ const struct gen_device_info * const devinfo,
+ const VkDescriptorImageInfo * const info,
VkDescriptorType type,
- VkImageView _image_view,
- VkSampler _sampler,
uint32_t binding,
uint32_t element)
{
switch (type) {
case VK_DESCRIPTOR_TYPE_SAMPLER:
- sampler = anv_sampler_from_handle(_sampler);
+ sampler = anv_sampler_from_handle(info->sampler);
break;
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
- image_view = anv_image_view_from_handle(_image_view);
- sampler = anv_sampler_from_handle(_sampler);
+ image_view = anv_image_view_from_handle(info->imageView);
+ sampler = anv_sampler_from_handle(info->sampler);
break;
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
- image_view = anv_image_view_from_handle(_image_view);
+ image_view = anv_image_view_from_handle(info->imageView);
break;
default:
*desc = (struct anv_descriptor) {
.type = type,
+ .layout = info->imageLayout,
.image_view = image_view,
.sampler = sampler,
};
void
anv_descriptor_set_write_buffer(struct anv_descriptor_set *set,
struct anv_device *device,
+ struct anv_state_stream *alloc_stream,
VkDescriptorType type,
struct anv_buffer *buffer,
uint32_t binding,
assert(type == bind_layout->type);
- struct anv_buffer_view *bview =
- &set->buffer_views[bind_layout->buffer_index + element];
-
- bview->format = anv_isl_format_for_descriptor_type(type);
- bview->bo = buffer->bo;
- bview->offset = buffer->offset + 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 || range == VK_WHOLE_SIZE)
- bview->range = buffer->size - offset;
- else
- bview->range = range;
-
- anv_fill_buffer_surface_state(device, bview->surface_state,
- bview->format,
- bview->offset, bview->range, 1);
-
- *desc = (struct anv_descriptor) {
- .type = type,
- .buffer_view = bview,
- };
+ if (type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC ||
+ type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) {
+ *desc = (struct anv_descriptor) {
+ .type = type,
+ .buffer = buffer,
+ .offset = offset,
+ .range = range,
+ };
+ } else {
+ struct anv_buffer_view *bview =
+ &set->buffer_views[bind_layout->buffer_index + element];
+
+ bview->format = anv_isl_format_for_descriptor_type(type);
+ bview->bo = buffer->bo;
+ bview->offset = buffer->offset + offset;
+ bview->range = anv_buffer_get_range(buffer, offset, range);
+
+ /* If we're writing descriptors through a push command, we need to
+ * allocate the surface state from the command buffer. Otherwise it will
+ * be allocated by the descriptor pool when calling
+ * vkAllocateDescriptorSets. */
+ if (alloc_stream)
+ bview->surface_state = anv_state_stream_alloc(alloc_stream, 64, 64);
+
+ anv_fill_buffer_surface_state(device, bview->surface_state,
+ bview->format,
+ bview->offset, bview->range, 1);
+
+ *desc = (struct anv_descriptor) {
+ .type = type,
+ .buffer_view = bview,
+ };
+ }
}
void anv_UpdateDescriptorSets(
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
for (uint32_t j = 0; j < write->descriptorCount; j++) {
- anv_descriptor_set_write_image_view(set,
+ anv_descriptor_set_write_image_view(set, &device->info,
+ write->pImageInfo + j,
write->descriptorType,
- write->pImageInfo[j].imageView,
- write->pImageInfo[j].sampler,
write->dstBinding,
write->dstArrayElement + j);
}
anv_descriptor_set_write_buffer(set,
device,
+ NULL,
write->descriptorType,
buffer,
write->dstBinding,
for (uint32_t i = 0; i < descriptorCopyCount; i++) {
const VkCopyDescriptorSet *copy = &pDescriptorCopies[i];
- ANV_FROM_HANDLE(anv_descriptor_set, src, copy->dstSet);
+ ANV_FROM_HANDLE(anv_descriptor_set, src, copy->srcSet);
ANV_FROM_HANDLE(anv_descriptor_set, dst, copy->dstSet);
const struct anv_descriptor_set_binding_layout *src_layout =
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, &device->info,
+ info, entry->type,
+ 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);
+}