mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-26 02:00:12 +01:00
venus: split out vn_descriptor_set.[ch]
Move VkDescriptor{Pool,Set,SetLayout,UpdateTemplate} functions to the
new files.
Signed-off-by: Chia-I Wu <olvaffe@gmail.com>
Reviewed-by: Yiwei Zhang <zzyiwei@chromium.org>
Acked-by: Erik Faye-Lund <erik.faye-lund@collabora.com>
Reviewed-by: Ryan Neph <ryanneph@google.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10117>
This commit is contained in:
parent
c3fbe3368b
commit
e653dc7697
5 changed files with 790 additions and 755 deletions
|
|
@ -34,6 +34,7 @@ libvn_files = files(
|
|||
'vn_command_buffer.c',
|
||||
'vn_common.c',
|
||||
'vn_cs.c',
|
||||
'vn_descriptor_set.c',
|
||||
'vn_device.c',
|
||||
'vn_icd.c',
|
||||
'vn_pipeline.c',
|
||||
|
|
|
|||
712
src/virtio/vulkan/vn_descriptor_set.c
Normal file
712
src/virtio/vulkan/vn_descriptor_set.c
Normal file
|
|
@ -0,0 +1,712 @@
|
|||
/*
|
||||
* Copyright 2019 Google LLC
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* based in part on anv and radv which are:
|
||||
* Copyright © 2015 Intel Corporation
|
||||
* Copyright © 2016 Red Hat.
|
||||
* Copyright © 2016 Bas Nieuwenhuizen
|
||||
*/
|
||||
|
||||
#include "vn_descriptor_set.h"
|
||||
|
||||
#include "venus-protocol/vn_protocol_driver_descriptor_pool.h"
|
||||
#include "venus-protocol/vn_protocol_driver_descriptor_set.h"
|
||||
#include "venus-protocol/vn_protocol_driver_descriptor_set_layout.h"
|
||||
#include "venus-protocol/vn_protocol_driver_descriptor_update_template.h"
|
||||
|
||||
#include "vn_device.h"
|
||||
|
||||
/* descriptor set layout commands */
|
||||
|
||||
void
|
||||
vn_GetDescriptorSetLayoutSupport(
|
||||
VkDevice device,
|
||||
const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
|
||||
VkDescriptorSetLayoutSupport *pSupport)
|
||||
{
|
||||
struct vn_device *dev = vn_device_from_handle(device);
|
||||
|
||||
/* TODO per-device cache */
|
||||
vn_call_vkGetDescriptorSetLayoutSupport(dev->instance, device, pCreateInfo,
|
||||
pSupport);
|
||||
}
|
||||
|
||||
VkResult
|
||||
vn_CreateDescriptorSetLayout(
|
||||
VkDevice device,
|
||||
const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
|
||||
const VkAllocationCallbacks *pAllocator,
|
||||
VkDescriptorSetLayout *pSetLayout)
|
||||
{
|
||||
struct vn_device *dev = vn_device_from_handle(device);
|
||||
const VkAllocationCallbacks *alloc =
|
||||
pAllocator ? pAllocator : &dev->base.base.alloc;
|
||||
|
||||
uint32_t max_binding = 0;
|
||||
VkDescriptorSetLayoutBinding *local_bindings = NULL;
|
||||
VkDescriptorSetLayoutCreateInfo local_create_info;
|
||||
if (pCreateInfo->bindingCount) {
|
||||
/* the encoder does not ignore
|
||||
* VkDescriptorSetLayoutBinding::pImmutableSamplers when it should
|
||||
*/
|
||||
const size_t binding_size =
|
||||
sizeof(*pCreateInfo->pBindings) * pCreateInfo->bindingCount;
|
||||
local_bindings = vk_alloc(alloc, binding_size, VN_DEFAULT_ALIGN,
|
||||
VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
|
||||
if (!local_bindings)
|
||||
return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
|
||||
|
||||
memcpy(local_bindings, pCreateInfo->pBindings, binding_size);
|
||||
for (uint32_t i = 0; i < pCreateInfo->bindingCount; i++) {
|
||||
VkDescriptorSetLayoutBinding *binding = &local_bindings[i];
|
||||
|
||||
if (max_binding < binding->binding)
|
||||
max_binding = binding->binding;
|
||||
|
||||
switch (binding->descriptorType) {
|
||||
case VK_DESCRIPTOR_TYPE_SAMPLER:
|
||||
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
|
||||
break;
|
||||
default:
|
||||
binding->pImmutableSamplers = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
local_create_info = *pCreateInfo;
|
||||
local_create_info.pBindings = local_bindings;
|
||||
pCreateInfo = &local_create_info;
|
||||
}
|
||||
|
||||
const size_t layout_size =
|
||||
offsetof(struct vn_descriptor_set_layout, bindings[max_binding + 1]);
|
||||
struct vn_descriptor_set_layout *layout =
|
||||
vk_zalloc(alloc, layout_size, VN_DEFAULT_ALIGN,
|
||||
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
|
||||
if (!layout) {
|
||||
vk_free(alloc, local_bindings);
|
||||
return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
|
||||
}
|
||||
|
||||
vn_object_base_init(&layout->base, VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT,
|
||||
&dev->base);
|
||||
|
||||
for (uint32_t i = 0; i < pCreateInfo->bindingCount; i++) {
|
||||
const VkDescriptorSetLayoutBinding *binding =
|
||||
&pCreateInfo->pBindings[i];
|
||||
struct vn_descriptor_set_layout_binding *dst =
|
||||
&layout->bindings[binding->binding];
|
||||
|
||||
switch (binding->descriptorType) {
|
||||
case VK_DESCRIPTOR_TYPE_SAMPLER:
|
||||
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
|
||||
dst->has_immutable_samplers = binding->pImmutableSamplers;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
VkDescriptorSetLayout layout_handle =
|
||||
vn_descriptor_set_layout_to_handle(layout);
|
||||
vn_async_vkCreateDescriptorSetLayout(dev->instance, device, pCreateInfo,
|
||||
NULL, &layout_handle);
|
||||
|
||||
vk_free(alloc, local_bindings);
|
||||
|
||||
*pSetLayout = layout_handle;
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
vn_DestroyDescriptorSetLayout(VkDevice device,
|
||||
VkDescriptorSetLayout descriptorSetLayout,
|
||||
const VkAllocationCallbacks *pAllocator)
|
||||
{
|
||||
struct vn_device *dev = vn_device_from_handle(device);
|
||||
struct vn_descriptor_set_layout *layout =
|
||||
vn_descriptor_set_layout_from_handle(descriptorSetLayout);
|
||||
const VkAllocationCallbacks *alloc =
|
||||
pAllocator ? pAllocator : &dev->base.base.alloc;
|
||||
|
||||
if (!layout)
|
||||
return;
|
||||
|
||||
vn_async_vkDestroyDescriptorSetLayout(dev->instance, device,
|
||||
descriptorSetLayout, NULL);
|
||||
|
||||
vn_object_base_fini(&layout->base);
|
||||
vk_free(alloc, layout);
|
||||
}
|
||||
|
||||
/* descriptor pool commands */
|
||||
|
||||
VkResult
|
||||
vn_CreateDescriptorPool(VkDevice device,
|
||||
const VkDescriptorPoolCreateInfo *pCreateInfo,
|
||||
const VkAllocationCallbacks *pAllocator,
|
||||
VkDescriptorPool *pDescriptorPool)
|
||||
{
|
||||
struct vn_device *dev = vn_device_from_handle(device);
|
||||
const VkAllocationCallbacks *alloc =
|
||||
pAllocator ? pAllocator : &dev->base.base.alloc;
|
||||
|
||||
struct vn_descriptor_pool *pool =
|
||||
vk_zalloc(alloc, sizeof(*pool), VN_DEFAULT_ALIGN,
|
||||
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
|
||||
if (!pool)
|
||||
return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
|
||||
|
||||
vn_object_base_init(&pool->base, VK_OBJECT_TYPE_DESCRIPTOR_POOL,
|
||||
&dev->base);
|
||||
|
||||
pool->allocator = *alloc;
|
||||
list_inithead(&pool->descriptor_sets);
|
||||
|
||||
VkDescriptorPool pool_handle = vn_descriptor_pool_to_handle(pool);
|
||||
vn_async_vkCreateDescriptorPool(dev->instance, device, pCreateInfo, NULL,
|
||||
&pool_handle);
|
||||
|
||||
*pDescriptorPool = pool_handle;
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
vn_DestroyDescriptorPool(VkDevice device,
|
||||
VkDescriptorPool descriptorPool,
|
||||
const VkAllocationCallbacks *pAllocator)
|
||||
{
|
||||
struct vn_device *dev = vn_device_from_handle(device);
|
||||
struct vn_descriptor_pool *pool =
|
||||
vn_descriptor_pool_from_handle(descriptorPool);
|
||||
const VkAllocationCallbacks *alloc;
|
||||
|
||||
if (!pool)
|
||||
return;
|
||||
|
||||
alloc = pAllocator ? pAllocator : &pool->allocator;
|
||||
|
||||
vn_async_vkDestroyDescriptorPool(dev->instance, device, descriptorPool,
|
||||
NULL);
|
||||
|
||||
list_for_each_entry_safe (struct vn_descriptor_set, set,
|
||||
&pool->descriptor_sets, head) {
|
||||
list_del(&set->head);
|
||||
|
||||
vn_object_base_fini(&set->base);
|
||||
vk_free(alloc, set);
|
||||
}
|
||||
|
||||
vn_object_base_fini(&pool->base);
|
||||
vk_free(alloc, pool);
|
||||
}
|
||||
|
||||
VkResult
|
||||
vn_ResetDescriptorPool(VkDevice device,
|
||||
VkDescriptorPool descriptorPool,
|
||||
VkDescriptorPoolResetFlags flags)
|
||||
{
|
||||
struct vn_device *dev = vn_device_from_handle(device);
|
||||
struct vn_descriptor_pool *pool =
|
||||
vn_descriptor_pool_from_handle(descriptorPool);
|
||||
const VkAllocationCallbacks *alloc = &pool->allocator;
|
||||
|
||||
vn_async_vkResetDescriptorPool(dev->instance, device, descriptorPool,
|
||||
flags);
|
||||
|
||||
list_for_each_entry_safe (struct vn_descriptor_set, set,
|
||||
&pool->descriptor_sets, head) {
|
||||
list_del(&set->head);
|
||||
|
||||
vn_object_base_fini(&set->base);
|
||||
vk_free(alloc, set);
|
||||
}
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
/* descriptor set commands */
|
||||
|
||||
VkResult
|
||||
vn_AllocateDescriptorSets(VkDevice device,
|
||||
const VkDescriptorSetAllocateInfo *pAllocateInfo,
|
||||
VkDescriptorSet *pDescriptorSets)
|
||||
{
|
||||
struct vn_device *dev = vn_device_from_handle(device);
|
||||
struct vn_descriptor_pool *pool =
|
||||
vn_descriptor_pool_from_handle(pAllocateInfo->descriptorPool);
|
||||
const VkAllocationCallbacks *alloc = &pool->allocator;
|
||||
|
||||
for (uint32_t i = 0; i < pAllocateInfo->descriptorSetCount; i++) {
|
||||
struct vn_descriptor_set *set =
|
||||
vk_zalloc(alloc, sizeof(*set), VN_DEFAULT_ALIGN,
|
||||
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
|
||||
if (!set) {
|
||||
for (uint32_t j = 0; j < i; j++) {
|
||||
set = vn_descriptor_set_from_handle(pDescriptorSets[j]);
|
||||
list_del(&set->head);
|
||||
vk_free(alloc, set);
|
||||
}
|
||||
memset(pDescriptorSets, 0,
|
||||
sizeof(*pDescriptorSets) * pAllocateInfo->descriptorSetCount);
|
||||
return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
|
||||
}
|
||||
|
||||
vn_object_base_init(&set->base, VK_OBJECT_TYPE_DESCRIPTOR_SET,
|
||||
&dev->base);
|
||||
set->layout =
|
||||
vn_descriptor_set_layout_from_handle(pAllocateInfo->pSetLayouts[i]);
|
||||
list_addtail(&set->head, &pool->descriptor_sets);
|
||||
|
||||
VkDescriptorSet set_handle = vn_descriptor_set_to_handle(set);
|
||||
pDescriptorSets[i] = set_handle;
|
||||
}
|
||||
|
||||
VkResult result = vn_call_vkAllocateDescriptorSets(
|
||||
dev->instance, device, pAllocateInfo, pDescriptorSets);
|
||||
if (result != VK_SUCCESS) {
|
||||
for (uint32_t i = 0; i < pAllocateInfo->descriptorSetCount; i++) {
|
||||
struct vn_descriptor_set *set =
|
||||
vn_descriptor_set_from_handle(pDescriptorSets[i]);
|
||||
list_del(&set->head);
|
||||
vk_free(alloc, set);
|
||||
}
|
||||
memset(pDescriptorSets, 0,
|
||||
sizeof(*pDescriptorSets) * pAllocateInfo->descriptorSetCount);
|
||||
return vn_error(dev->instance, result);
|
||||
}
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
VkResult
|
||||
vn_FreeDescriptorSets(VkDevice device,
|
||||
VkDescriptorPool descriptorPool,
|
||||
uint32_t descriptorSetCount,
|
||||
const VkDescriptorSet *pDescriptorSets)
|
||||
{
|
||||
struct vn_device *dev = vn_device_from_handle(device);
|
||||
struct vn_descriptor_pool *pool =
|
||||
vn_descriptor_pool_from_handle(descriptorPool);
|
||||
const VkAllocationCallbacks *alloc = &pool->allocator;
|
||||
|
||||
vn_async_vkFreeDescriptorSets(dev->instance, device, descriptorPool,
|
||||
descriptorSetCount, pDescriptorSets);
|
||||
|
||||
for (uint32_t i = 0; i < descriptorSetCount; i++) {
|
||||
struct vn_descriptor_set *set =
|
||||
vn_descriptor_set_from_handle(pDescriptorSets[i]);
|
||||
|
||||
if (!set)
|
||||
continue;
|
||||
|
||||
list_del(&set->head);
|
||||
|
||||
vn_object_base_fini(&set->base);
|
||||
vk_free(alloc, set);
|
||||
}
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
static struct vn_update_descriptor_sets *
|
||||
vn_update_descriptor_sets_alloc(uint32_t write_count,
|
||||
uint32_t image_count,
|
||||
uint32_t buffer_count,
|
||||
uint32_t view_count,
|
||||
const VkAllocationCallbacks *alloc,
|
||||
VkSystemAllocationScope scope)
|
||||
{
|
||||
const size_t writes_offset = sizeof(struct vn_update_descriptor_sets);
|
||||
const size_t images_offset =
|
||||
writes_offset + sizeof(VkWriteDescriptorSet) * write_count;
|
||||
const size_t buffers_offset =
|
||||
images_offset + sizeof(VkDescriptorImageInfo) * image_count;
|
||||
const size_t views_offset =
|
||||
buffers_offset + sizeof(VkDescriptorBufferInfo) * buffer_count;
|
||||
const size_t alloc_size = views_offset + sizeof(VkBufferView) * view_count;
|
||||
|
||||
void *storage = vk_alloc(alloc, alloc_size, VN_DEFAULT_ALIGN, scope);
|
||||
if (!storage)
|
||||
return NULL;
|
||||
|
||||
struct vn_update_descriptor_sets *update = storage;
|
||||
update->write_count = write_count;
|
||||
update->writes = storage + writes_offset;
|
||||
update->images = storage + images_offset;
|
||||
update->buffers = storage + buffers_offset;
|
||||
update->views = storage + views_offset;
|
||||
|
||||
return update;
|
||||
}
|
||||
|
||||
static struct vn_update_descriptor_sets *
|
||||
vn_update_descriptor_sets_parse_writes(uint32_t write_count,
|
||||
const VkWriteDescriptorSet *writes,
|
||||
const VkAllocationCallbacks *alloc)
|
||||
{
|
||||
uint32_t img_count = 0;
|
||||
for (uint32_t i = 0; i < write_count; i++) {
|
||||
const VkWriteDescriptorSet *write = &writes[i];
|
||||
switch (write->descriptorType) {
|
||||
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:
|
||||
img_count += write->descriptorCount;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
struct vn_update_descriptor_sets *update =
|
||||
vn_update_descriptor_sets_alloc(write_count, img_count, 0, 0, alloc,
|
||||
VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
|
||||
if (!update)
|
||||
return NULL;
|
||||
|
||||
/* the encoder does not ignore
|
||||
* VkWriteDescriptorSet::{pImageInfo,pBufferInfo,pTexelBufferView} when it
|
||||
* should
|
||||
*
|
||||
* TODO make the encoder smarter
|
||||
*/
|
||||
memcpy(update->writes, writes, sizeof(*writes) * write_count);
|
||||
img_count = 0;
|
||||
for (uint32_t i = 0; i < write_count; i++) {
|
||||
const struct vn_descriptor_set *set =
|
||||
vn_descriptor_set_from_handle(writes[i].dstSet);
|
||||
const struct vn_descriptor_set_layout_binding *binding =
|
||||
&set->layout->bindings[writes[i].dstBinding];
|
||||
VkWriteDescriptorSet *write = &update->writes[i];
|
||||
VkDescriptorImageInfo *imgs = &update->images[img_count];
|
||||
|
||||
switch (write->descriptorType) {
|
||||
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:
|
||||
memcpy(imgs, write->pImageInfo,
|
||||
sizeof(*imgs) * write->descriptorCount);
|
||||
img_count += write->descriptorCount;
|
||||
|
||||
for (uint32_t j = 0; j < write->descriptorCount; j++) {
|
||||
switch (write->descriptorType) {
|
||||
case VK_DESCRIPTOR_TYPE_SAMPLER:
|
||||
imgs[j].imageView = VK_NULL_HANDLE;
|
||||
break;
|
||||
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
|
||||
if (binding->has_immutable_samplers)
|
||||
imgs[j].sampler = VK_NULL_HANDLE;
|
||||
break;
|
||||
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
|
||||
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
|
||||
case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
|
||||
imgs[j].sampler = VK_NULL_HANDLE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
write->pImageInfo = imgs;
|
||||
write->pBufferInfo = NULL;
|
||||
write->pTexelBufferView = NULL;
|
||||
break;
|
||||
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
|
||||
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
|
||||
write->pImageInfo = NULL;
|
||||
write->pBufferInfo = NULL;
|
||||
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:
|
||||
write->pImageInfo = NULL;
|
||||
write->pTexelBufferView = NULL;
|
||||
break;
|
||||
default:
|
||||
write->pImageInfo = NULL;
|
||||
write->pBufferInfo = NULL;
|
||||
write->pTexelBufferView = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return update;
|
||||
}
|
||||
|
||||
void
|
||||
vn_UpdateDescriptorSets(VkDevice device,
|
||||
uint32_t descriptorWriteCount,
|
||||
const VkWriteDescriptorSet *pDescriptorWrites,
|
||||
uint32_t descriptorCopyCount,
|
||||
const VkCopyDescriptorSet *pDescriptorCopies)
|
||||
{
|
||||
struct vn_device *dev = vn_device_from_handle(device);
|
||||
const VkAllocationCallbacks *alloc = &dev->base.base.alloc;
|
||||
|
||||
struct vn_update_descriptor_sets *update =
|
||||
vn_update_descriptor_sets_parse_writes(descriptorWriteCount,
|
||||
pDescriptorWrites, alloc);
|
||||
if (!update) {
|
||||
/* TODO update one-by-one? */
|
||||
vn_log(dev->instance, "TODO descriptor set update ignored due to OOM");
|
||||
return;
|
||||
}
|
||||
|
||||
vn_async_vkUpdateDescriptorSets(dev->instance, device, update->write_count,
|
||||
update->writes, descriptorCopyCount,
|
||||
pDescriptorCopies);
|
||||
|
||||
vk_free(alloc, update);
|
||||
}
|
||||
|
||||
/* descriptor update template commands */
|
||||
|
||||
static struct vn_update_descriptor_sets *
|
||||
vn_update_descriptor_sets_parse_template(
|
||||
const VkDescriptorUpdateTemplateCreateInfo *create_info,
|
||||
const VkAllocationCallbacks *alloc,
|
||||
struct vn_descriptor_update_template_entry *entries)
|
||||
{
|
||||
uint32_t img_count = 0;
|
||||
uint32_t buf_count = 0;
|
||||
uint32_t view_count = 0;
|
||||
for (uint32_t i = 0; i < create_info->descriptorUpdateEntryCount; i++) {
|
||||
const VkDescriptorUpdateTemplateEntry *entry =
|
||||
&create_info->pDescriptorUpdateEntries[i];
|
||||
|
||||
switch (entry->descriptorType) {
|
||||
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:
|
||||
img_count += entry->descriptorCount;
|
||||
break;
|
||||
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
|
||||
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
|
||||
view_count += entry->descriptorCount;
|
||||
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:
|
||||
buf_count += entry->descriptorCount;
|
||||
break;
|
||||
default:
|
||||
unreachable("unhandled descriptor type");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
struct vn_update_descriptor_sets *update = vn_update_descriptor_sets_alloc(
|
||||
create_info->descriptorUpdateEntryCount, img_count, buf_count,
|
||||
view_count, alloc, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
|
||||
if (!update)
|
||||
return NULL;
|
||||
|
||||
img_count = 0;
|
||||
buf_count = 0;
|
||||
view_count = 0;
|
||||
for (uint32_t i = 0; i < create_info->descriptorUpdateEntryCount; i++) {
|
||||
const VkDescriptorUpdateTemplateEntry *entry =
|
||||
&create_info->pDescriptorUpdateEntries[i];
|
||||
VkWriteDescriptorSet *write = &update->writes[i];
|
||||
|
||||
write->sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||
write->pNext = NULL;
|
||||
write->dstBinding = entry->dstBinding;
|
||||
write->dstArrayElement = entry->dstArrayElement;
|
||||
write->descriptorCount = entry->descriptorCount;
|
||||
write->descriptorType = entry->descriptorType;
|
||||
|
||||
entries[i].offset = entry->offset;
|
||||
entries[i].stride = entry->stride;
|
||||
|
||||
switch (entry->descriptorType) {
|
||||
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:
|
||||
write->pImageInfo = &update->images[img_count];
|
||||
write->pBufferInfo = NULL;
|
||||
write->pTexelBufferView = NULL;
|
||||
img_count += entry->descriptorCount;
|
||||
break;
|
||||
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
|
||||
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
|
||||
write->pImageInfo = NULL;
|
||||
write->pBufferInfo = NULL;
|
||||
write->pTexelBufferView = &update->views[view_count];
|
||||
view_count += entry->descriptorCount;
|
||||
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:
|
||||
write->pImageInfo = NULL;
|
||||
write->pBufferInfo = &update->buffers[buf_count];
|
||||
write->pTexelBufferView = NULL;
|
||||
buf_count += entry->descriptorCount;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return update;
|
||||
}
|
||||
|
||||
VkResult
|
||||
vn_CreateDescriptorUpdateTemplate(
|
||||
VkDevice device,
|
||||
const VkDescriptorUpdateTemplateCreateInfo *pCreateInfo,
|
||||
const VkAllocationCallbacks *pAllocator,
|
||||
VkDescriptorUpdateTemplate *pDescriptorUpdateTemplate)
|
||||
{
|
||||
struct vn_device *dev = vn_device_from_handle(device);
|
||||
const VkAllocationCallbacks *alloc =
|
||||
pAllocator ? pAllocator : &dev->base.base.alloc;
|
||||
|
||||
const size_t templ_size =
|
||||
offsetof(struct vn_descriptor_update_template,
|
||||
entries[pCreateInfo->descriptorUpdateEntryCount + 1]);
|
||||
struct vn_descriptor_update_template *templ = vk_zalloc(
|
||||
alloc, templ_size, VN_DEFAULT_ALIGN, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
|
||||
if (!templ)
|
||||
return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
|
||||
|
||||
vn_object_base_init(&templ->base,
|
||||
VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE, &dev->base);
|
||||
|
||||
templ->update = vn_update_descriptor_sets_parse_template(
|
||||
pCreateInfo, alloc, templ->entries);
|
||||
if (!templ->update) {
|
||||
vk_free(alloc, templ);
|
||||
return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
|
||||
}
|
||||
|
||||
mtx_init(&templ->mutex, mtx_plain);
|
||||
|
||||
/* no host object */
|
||||
VkDescriptorUpdateTemplate templ_handle =
|
||||
vn_descriptor_update_template_to_handle(templ);
|
||||
*pDescriptorUpdateTemplate = templ_handle;
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
vn_DestroyDescriptorUpdateTemplate(
|
||||
VkDevice device,
|
||||
VkDescriptorUpdateTemplate descriptorUpdateTemplate,
|
||||
const VkAllocationCallbacks *pAllocator)
|
||||
{
|
||||
struct vn_device *dev = vn_device_from_handle(device);
|
||||
struct vn_descriptor_update_template *templ =
|
||||
vn_descriptor_update_template_from_handle(descriptorUpdateTemplate);
|
||||
const VkAllocationCallbacks *alloc =
|
||||
pAllocator ? pAllocator : &dev->base.base.alloc;
|
||||
|
||||
if (!templ)
|
||||
return;
|
||||
|
||||
/* no host object */
|
||||
vk_free(alloc, templ->update);
|
||||
mtx_destroy(&templ->mutex);
|
||||
|
||||
vn_object_base_fini(&templ->base);
|
||||
vk_free(alloc, templ);
|
||||
}
|
||||
|
||||
void
|
||||
vn_UpdateDescriptorSetWithTemplate(
|
||||
VkDevice device,
|
||||
VkDescriptorSet descriptorSet,
|
||||
VkDescriptorUpdateTemplate descriptorUpdateTemplate,
|
||||
const void *pData)
|
||||
{
|
||||
struct vn_device *dev = vn_device_from_handle(device);
|
||||
struct vn_descriptor_set *set =
|
||||
vn_descriptor_set_from_handle(descriptorSet);
|
||||
struct vn_descriptor_update_template *templ =
|
||||
vn_descriptor_update_template_from_handle(descriptorUpdateTemplate);
|
||||
struct vn_update_descriptor_sets *update = templ->update;
|
||||
|
||||
/* duplicate update instead to avoid locking? */
|
||||
mtx_lock(&templ->mutex);
|
||||
|
||||
for (uint32_t i = 0; i < update->write_count; i++) {
|
||||
const struct vn_descriptor_update_template_entry *entry =
|
||||
&templ->entries[i];
|
||||
const struct vn_descriptor_set_layout_binding *binding =
|
||||
&set->layout->bindings[update->writes[i].dstBinding];
|
||||
VkWriteDescriptorSet *write = &update->writes[i];
|
||||
|
||||
write->dstSet = vn_descriptor_set_to_handle(set);
|
||||
|
||||
switch (write->descriptorType) {
|
||||
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 < write->descriptorCount; j++) {
|
||||
const bool need_sampler =
|
||||
(write->descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER ||
|
||||
write->descriptorType ==
|
||||
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) &&
|
||||
!binding->has_immutable_samplers;
|
||||
const bool need_view =
|
||||
write->descriptorType != VK_DESCRIPTOR_TYPE_SAMPLER;
|
||||
const VkDescriptorImageInfo *src =
|
||||
pData + entry->offset + entry->stride * j;
|
||||
VkDescriptorImageInfo *dst =
|
||||
(VkDescriptorImageInfo *)&write->pImageInfo[j];
|
||||
|
||||
dst->sampler = need_sampler ? src->sampler : VK_NULL_HANDLE;
|
||||
dst->imageView = need_view ? src->imageView : VK_NULL_HANDLE;
|
||||
dst->imageLayout = src->imageLayout;
|
||||
}
|
||||
break;
|
||||
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
|
||||
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
|
||||
for (uint32_t j = 0; j < write->descriptorCount; j++) {
|
||||
const VkBufferView *src =
|
||||
pData + entry->offset + entry->stride * j;
|
||||
VkBufferView *dst = (VkBufferView *)&write->pTexelBufferView[j];
|
||||
*dst = *src;
|
||||
}
|
||||
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 < write->descriptorCount; j++) {
|
||||
const VkDescriptorBufferInfo *src =
|
||||
pData + entry->offset + entry->stride * j;
|
||||
VkDescriptorBufferInfo *dst =
|
||||
(VkDescriptorBufferInfo *)&write->pBufferInfo[j];
|
||||
*dst = *src;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
unreachable("unhandled descriptor type");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
vn_async_vkUpdateDescriptorSets(dev->instance, device, update->write_count,
|
||||
update->writes, 0, NULL);
|
||||
|
||||
mtx_unlock(&templ->mutex);
|
||||
}
|
||||
77
src/virtio/vulkan/vn_descriptor_set.h
Normal file
77
src/virtio/vulkan/vn_descriptor_set.h
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* Copyright 2019 Google LLC
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* based in part on anv and radv which are:
|
||||
* Copyright © 2015 Intel Corporation
|
||||
* Copyright © 2016 Red Hat.
|
||||
* Copyright © 2016 Bas Nieuwenhuizen
|
||||
*/
|
||||
|
||||
#ifndef VN_DESCRIPTOR_SET_H
|
||||
#define VN_DESCRIPTOR_SET_H
|
||||
|
||||
#include "vn_common.h"
|
||||
|
||||
struct vn_descriptor_set_layout_binding {
|
||||
bool has_immutable_samplers;
|
||||
};
|
||||
|
||||
struct vn_descriptor_set_layout {
|
||||
struct vn_object_base base;
|
||||
struct vn_descriptor_set_layout_binding bindings[];
|
||||
};
|
||||
VK_DEFINE_NONDISP_HANDLE_CASTS(vn_descriptor_set_layout,
|
||||
base.base,
|
||||
VkDescriptorSetLayout,
|
||||
VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT)
|
||||
|
||||
struct vn_descriptor_pool {
|
||||
struct vn_object_base base;
|
||||
|
||||
VkAllocationCallbacks allocator;
|
||||
struct list_head descriptor_sets;
|
||||
};
|
||||
VK_DEFINE_NONDISP_HANDLE_CASTS(vn_descriptor_pool,
|
||||
base.base,
|
||||
VkDescriptorPool,
|
||||
VK_OBJECT_TYPE_DESCRIPTOR_POOL)
|
||||
|
||||
struct vn_update_descriptor_sets {
|
||||
uint32_t write_count;
|
||||
VkWriteDescriptorSet *writes;
|
||||
VkDescriptorImageInfo *images;
|
||||
VkDescriptorBufferInfo *buffers;
|
||||
VkBufferView *views;
|
||||
};
|
||||
|
||||
struct vn_descriptor_set {
|
||||
struct vn_object_base base;
|
||||
|
||||
const struct vn_descriptor_set_layout *layout;
|
||||
struct list_head head;
|
||||
};
|
||||
VK_DEFINE_NONDISP_HANDLE_CASTS(vn_descriptor_set,
|
||||
base.base,
|
||||
VkDescriptorSet,
|
||||
VK_OBJECT_TYPE_DESCRIPTOR_SET)
|
||||
|
||||
struct vn_descriptor_update_template_entry {
|
||||
size_t offset;
|
||||
size_t stride;
|
||||
};
|
||||
|
||||
struct vn_descriptor_update_template {
|
||||
struct vn_object_base base;
|
||||
|
||||
mtx_t mutex;
|
||||
struct vn_update_descriptor_sets *update;
|
||||
|
||||
struct vn_descriptor_update_template_entry entries[];
|
||||
};
|
||||
VK_DEFINE_NONDISP_HANDLE_CASTS(vn_descriptor_update_template,
|
||||
base.base,
|
||||
VkDescriptorUpdateTemplate,
|
||||
VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE)
|
||||
|
||||
#endif /* VN_DESCRIPTOR_SET_H */
|
||||
|
|
@ -5452,700 +5452,6 @@ vn_DestroySamplerYcbcrConversion(VkDevice device,
|
|||
vk_free(alloc, conv);
|
||||
}
|
||||
|
||||
/* descriptor set layout commands */
|
||||
|
||||
void
|
||||
vn_GetDescriptorSetLayoutSupport(
|
||||
VkDevice device,
|
||||
const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
|
||||
VkDescriptorSetLayoutSupport *pSupport)
|
||||
{
|
||||
struct vn_device *dev = vn_device_from_handle(device);
|
||||
|
||||
/* TODO per-device cache */
|
||||
vn_call_vkGetDescriptorSetLayoutSupport(dev->instance, device, pCreateInfo,
|
||||
pSupport);
|
||||
}
|
||||
|
||||
VkResult
|
||||
vn_CreateDescriptorSetLayout(
|
||||
VkDevice device,
|
||||
const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
|
||||
const VkAllocationCallbacks *pAllocator,
|
||||
VkDescriptorSetLayout *pSetLayout)
|
||||
{
|
||||
struct vn_device *dev = vn_device_from_handle(device);
|
||||
const VkAllocationCallbacks *alloc =
|
||||
pAllocator ? pAllocator : &dev->base.base.alloc;
|
||||
|
||||
uint32_t max_binding = 0;
|
||||
VkDescriptorSetLayoutBinding *local_bindings = NULL;
|
||||
VkDescriptorSetLayoutCreateInfo local_create_info;
|
||||
if (pCreateInfo->bindingCount) {
|
||||
/* the encoder does not ignore
|
||||
* VkDescriptorSetLayoutBinding::pImmutableSamplers when it should
|
||||
*/
|
||||
const size_t binding_size =
|
||||
sizeof(*pCreateInfo->pBindings) * pCreateInfo->bindingCount;
|
||||
local_bindings = vk_alloc(alloc, binding_size, VN_DEFAULT_ALIGN,
|
||||
VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
|
||||
if (!local_bindings)
|
||||
return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
|
||||
|
||||
memcpy(local_bindings, pCreateInfo->pBindings, binding_size);
|
||||
for (uint32_t i = 0; i < pCreateInfo->bindingCount; i++) {
|
||||
VkDescriptorSetLayoutBinding *binding = &local_bindings[i];
|
||||
|
||||
if (max_binding < binding->binding)
|
||||
max_binding = binding->binding;
|
||||
|
||||
switch (binding->descriptorType) {
|
||||
case VK_DESCRIPTOR_TYPE_SAMPLER:
|
||||
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
|
||||
break;
|
||||
default:
|
||||
binding->pImmutableSamplers = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
local_create_info = *pCreateInfo;
|
||||
local_create_info.pBindings = local_bindings;
|
||||
pCreateInfo = &local_create_info;
|
||||
}
|
||||
|
||||
const size_t layout_size =
|
||||
offsetof(struct vn_descriptor_set_layout, bindings[max_binding + 1]);
|
||||
struct vn_descriptor_set_layout *layout =
|
||||
vk_zalloc(alloc, layout_size, VN_DEFAULT_ALIGN,
|
||||
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
|
||||
if (!layout) {
|
||||
vk_free(alloc, local_bindings);
|
||||
return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
|
||||
}
|
||||
|
||||
vn_object_base_init(&layout->base, VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT,
|
||||
&dev->base);
|
||||
|
||||
for (uint32_t i = 0; i < pCreateInfo->bindingCount; i++) {
|
||||
const VkDescriptorSetLayoutBinding *binding =
|
||||
&pCreateInfo->pBindings[i];
|
||||
struct vn_descriptor_set_layout_binding *dst =
|
||||
&layout->bindings[binding->binding];
|
||||
|
||||
switch (binding->descriptorType) {
|
||||
case VK_DESCRIPTOR_TYPE_SAMPLER:
|
||||
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
|
||||
dst->has_immutable_samplers = binding->pImmutableSamplers;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
VkDescriptorSetLayout layout_handle =
|
||||
vn_descriptor_set_layout_to_handle(layout);
|
||||
vn_async_vkCreateDescriptorSetLayout(dev->instance, device, pCreateInfo,
|
||||
NULL, &layout_handle);
|
||||
|
||||
vk_free(alloc, local_bindings);
|
||||
|
||||
*pSetLayout = layout_handle;
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
vn_DestroyDescriptorSetLayout(VkDevice device,
|
||||
VkDescriptorSetLayout descriptorSetLayout,
|
||||
const VkAllocationCallbacks *pAllocator)
|
||||
{
|
||||
struct vn_device *dev = vn_device_from_handle(device);
|
||||
struct vn_descriptor_set_layout *layout =
|
||||
vn_descriptor_set_layout_from_handle(descriptorSetLayout);
|
||||
const VkAllocationCallbacks *alloc =
|
||||
pAllocator ? pAllocator : &dev->base.base.alloc;
|
||||
|
||||
if (!layout)
|
||||
return;
|
||||
|
||||
vn_async_vkDestroyDescriptorSetLayout(dev->instance, device,
|
||||
descriptorSetLayout, NULL);
|
||||
|
||||
vn_object_base_fini(&layout->base);
|
||||
vk_free(alloc, layout);
|
||||
}
|
||||
|
||||
/* descriptor pool commands */
|
||||
|
||||
VkResult
|
||||
vn_CreateDescriptorPool(VkDevice device,
|
||||
const VkDescriptorPoolCreateInfo *pCreateInfo,
|
||||
const VkAllocationCallbacks *pAllocator,
|
||||
VkDescriptorPool *pDescriptorPool)
|
||||
{
|
||||
struct vn_device *dev = vn_device_from_handle(device);
|
||||
const VkAllocationCallbacks *alloc =
|
||||
pAllocator ? pAllocator : &dev->base.base.alloc;
|
||||
|
||||
struct vn_descriptor_pool *pool =
|
||||
vk_zalloc(alloc, sizeof(*pool), VN_DEFAULT_ALIGN,
|
||||
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
|
||||
if (!pool)
|
||||
return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
|
||||
|
||||
vn_object_base_init(&pool->base, VK_OBJECT_TYPE_DESCRIPTOR_POOL,
|
||||
&dev->base);
|
||||
|
||||
pool->allocator = *alloc;
|
||||
list_inithead(&pool->descriptor_sets);
|
||||
|
||||
VkDescriptorPool pool_handle = vn_descriptor_pool_to_handle(pool);
|
||||
vn_async_vkCreateDescriptorPool(dev->instance, device, pCreateInfo, NULL,
|
||||
&pool_handle);
|
||||
|
||||
*pDescriptorPool = pool_handle;
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
vn_DestroyDescriptorPool(VkDevice device,
|
||||
VkDescriptorPool descriptorPool,
|
||||
const VkAllocationCallbacks *pAllocator)
|
||||
{
|
||||
struct vn_device *dev = vn_device_from_handle(device);
|
||||
struct vn_descriptor_pool *pool =
|
||||
vn_descriptor_pool_from_handle(descriptorPool);
|
||||
const VkAllocationCallbacks *alloc;
|
||||
|
||||
if (!pool)
|
||||
return;
|
||||
|
||||
alloc = pAllocator ? pAllocator : &pool->allocator;
|
||||
|
||||
vn_async_vkDestroyDescriptorPool(dev->instance, device, descriptorPool,
|
||||
NULL);
|
||||
|
||||
list_for_each_entry_safe (struct vn_descriptor_set, set,
|
||||
&pool->descriptor_sets, head) {
|
||||
list_del(&set->head);
|
||||
|
||||
vn_object_base_fini(&set->base);
|
||||
vk_free(alloc, set);
|
||||
}
|
||||
|
||||
vn_object_base_fini(&pool->base);
|
||||
vk_free(alloc, pool);
|
||||
}
|
||||
|
||||
VkResult
|
||||
vn_ResetDescriptorPool(VkDevice device,
|
||||
VkDescriptorPool descriptorPool,
|
||||
VkDescriptorPoolResetFlags flags)
|
||||
{
|
||||
struct vn_device *dev = vn_device_from_handle(device);
|
||||
struct vn_descriptor_pool *pool =
|
||||
vn_descriptor_pool_from_handle(descriptorPool);
|
||||
const VkAllocationCallbacks *alloc = &pool->allocator;
|
||||
|
||||
vn_async_vkResetDescriptorPool(dev->instance, device, descriptorPool,
|
||||
flags);
|
||||
|
||||
list_for_each_entry_safe (struct vn_descriptor_set, set,
|
||||
&pool->descriptor_sets, head) {
|
||||
list_del(&set->head);
|
||||
|
||||
vn_object_base_fini(&set->base);
|
||||
vk_free(alloc, set);
|
||||
}
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
/* descriptor set commands */
|
||||
|
||||
VkResult
|
||||
vn_AllocateDescriptorSets(VkDevice device,
|
||||
const VkDescriptorSetAllocateInfo *pAllocateInfo,
|
||||
VkDescriptorSet *pDescriptorSets)
|
||||
{
|
||||
struct vn_device *dev = vn_device_from_handle(device);
|
||||
struct vn_descriptor_pool *pool =
|
||||
vn_descriptor_pool_from_handle(pAllocateInfo->descriptorPool);
|
||||
const VkAllocationCallbacks *alloc = &pool->allocator;
|
||||
|
||||
for (uint32_t i = 0; i < pAllocateInfo->descriptorSetCount; i++) {
|
||||
struct vn_descriptor_set *set =
|
||||
vk_zalloc(alloc, sizeof(*set), VN_DEFAULT_ALIGN,
|
||||
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
|
||||
if (!set) {
|
||||
for (uint32_t j = 0; j < i; j++) {
|
||||
set = vn_descriptor_set_from_handle(pDescriptorSets[j]);
|
||||
list_del(&set->head);
|
||||
vk_free(alloc, set);
|
||||
}
|
||||
memset(pDescriptorSets, 0,
|
||||
sizeof(*pDescriptorSets) * pAllocateInfo->descriptorSetCount);
|
||||
return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
|
||||
}
|
||||
|
||||
vn_object_base_init(&set->base, VK_OBJECT_TYPE_DESCRIPTOR_SET,
|
||||
&dev->base);
|
||||
set->layout =
|
||||
vn_descriptor_set_layout_from_handle(pAllocateInfo->pSetLayouts[i]);
|
||||
list_addtail(&set->head, &pool->descriptor_sets);
|
||||
|
||||
VkDescriptorSet set_handle = vn_descriptor_set_to_handle(set);
|
||||
pDescriptorSets[i] = set_handle;
|
||||
}
|
||||
|
||||
VkResult result = vn_call_vkAllocateDescriptorSets(
|
||||
dev->instance, device, pAllocateInfo, pDescriptorSets);
|
||||
if (result != VK_SUCCESS) {
|
||||
for (uint32_t i = 0; i < pAllocateInfo->descriptorSetCount; i++) {
|
||||
struct vn_descriptor_set *set =
|
||||
vn_descriptor_set_from_handle(pDescriptorSets[i]);
|
||||
list_del(&set->head);
|
||||
vk_free(alloc, set);
|
||||
}
|
||||
memset(pDescriptorSets, 0,
|
||||
sizeof(*pDescriptorSets) * pAllocateInfo->descriptorSetCount);
|
||||
return vn_error(dev->instance, result);
|
||||
}
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
VkResult
|
||||
vn_FreeDescriptorSets(VkDevice device,
|
||||
VkDescriptorPool descriptorPool,
|
||||
uint32_t descriptorSetCount,
|
||||
const VkDescriptorSet *pDescriptorSets)
|
||||
{
|
||||
struct vn_device *dev = vn_device_from_handle(device);
|
||||
struct vn_descriptor_pool *pool =
|
||||
vn_descriptor_pool_from_handle(descriptorPool);
|
||||
const VkAllocationCallbacks *alloc = &pool->allocator;
|
||||
|
||||
vn_async_vkFreeDescriptorSets(dev->instance, device, descriptorPool,
|
||||
descriptorSetCount, pDescriptorSets);
|
||||
|
||||
for (uint32_t i = 0; i < descriptorSetCount; i++) {
|
||||
struct vn_descriptor_set *set =
|
||||
vn_descriptor_set_from_handle(pDescriptorSets[i]);
|
||||
|
||||
if (!set)
|
||||
continue;
|
||||
|
||||
list_del(&set->head);
|
||||
|
||||
vn_object_base_fini(&set->base);
|
||||
vk_free(alloc, set);
|
||||
}
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
static struct vn_update_descriptor_sets *
|
||||
vn_update_descriptor_sets_alloc(uint32_t write_count,
|
||||
uint32_t image_count,
|
||||
uint32_t buffer_count,
|
||||
uint32_t view_count,
|
||||
const VkAllocationCallbacks *alloc,
|
||||
VkSystemAllocationScope scope)
|
||||
{
|
||||
const size_t writes_offset = sizeof(struct vn_update_descriptor_sets);
|
||||
const size_t images_offset =
|
||||
writes_offset + sizeof(VkWriteDescriptorSet) * write_count;
|
||||
const size_t buffers_offset =
|
||||
images_offset + sizeof(VkDescriptorImageInfo) * image_count;
|
||||
const size_t views_offset =
|
||||
buffers_offset + sizeof(VkDescriptorBufferInfo) * buffer_count;
|
||||
const size_t alloc_size = views_offset + sizeof(VkBufferView) * view_count;
|
||||
|
||||
void *storage = vk_alloc(alloc, alloc_size, VN_DEFAULT_ALIGN, scope);
|
||||
if (!storage)
|
||||
return NULL;
|
||||
|
||||
struct vn_update_descriptor_sets *update = storage;
|
||||
update->write_count = write_count;
|
||||
update->writes = storage + writes_offset;
|
||||
update->images = storage + images_offset;
|
||||
update->buffers = storage + buffers_offset;
|
||||
update->views = storage + views_offset;
|
||||
|
||||
return update;
|
||||
}
|
||||
|
||||
static struct vn_update_descriptor_sets *
|
||||
vn_update_descriptor_sets_parse_writes(uint32_t write_count,
|
||||
const VkWriteDescriptorSet *writes,
|
||||
const VkAllocationCallbacks *alloc)
|
||||
{
|
||||
uint32_t img_count = 0;
|
||||
for (uint32_t i = 0; i < write_count; i++) {
|
||||
const VkWriteDescriptorSet *write = &writes[i];
|
||||
switch (write->descriptorType) {
|
||||
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:
|
||||
img_count += write->descriptorCount;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
struct vn_update_descriptor_sets *update =
|
||||
vn_update_descriptor_sets_alloc(write_count, img_count, 0, 0, alloc,
|
||||
VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
|
||||
if (!update)
|
||||
return NULL;
|
||||
|
||||
/* the encoder does not ignore
|
||||
* VkWriteDescriptorSet::{pImageInfo,pBufferInfo,pTexelBufferView} when it
|
||||
* should
|
||||
*
|
||||
* TODO make the encoder smarter
|
||||
*/
|
||||
memcpy(update->writes, writes, sizeof(*writes) * write_count);
|
||||
img_count = 0;
|
||||
for (uint32_t i = 0; i < write_count; i++) {
|
||||
const struct vn_descriptor_set *set =
|
||||
vn_descriptor_set_from_handle(writes[i].dstSet);
|
||||
const struct vn_descriptor_set_layout_binding *binding =
|
||||
&set->layout->bindings[writes[i].dstBinding];
|
||||
VkWriteDescriptorSet *write = &update->writes[i];
|
||||
VkDescriptorImageInfo *imgs = &update->images[img_count];
|
||||
|
||||
switch (write->descriptorType) {
|
||||
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:
|
||||
memcpy(imgs, write->pImageInfo,
|
||||
sizeof(*imgs) * write->descriptorCount);
|
||||
img_count += write->descriptorCount;
|
||||
|
||||
for (uint32_t j = 0; j < write->descriptorCount; j++) {
|
||||
switch (write->descriptorType) {
|
||||
case VK_DESCRIPTOR_TYPE_SAMPLER:
|
||||
imgs[j].imageView = VK_NULL_HANDLE;
|
||||
break;
|
||||
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
|
||||
if (binding->has_immutable_samplers)
|
||||
imgs[j].sampler = VK_NULL_HANDLE;
|
||||
break;
|
||||
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
|
||||
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
|
||||
case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
|
||||
imgs[j].sampler = VK_NULL_HANDLE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
write->pImageInfo = imgs;
|
||||
write->pBufferInfo = NULL;
|
||||
write->pTexelBufferView = NULL;
|
||||
break;
|
||||
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
|
||||
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
|
||||
write->pImageInfo = NULL;
|
||||
write->pBufferInfo = NULL;
|
||||
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:
|
||||
write->pImageInfo = NULL;
|
||||
write->pTexelBufferView = NULL;
|
||||
break;
|
||||
default:
|
||||
write->pImageInfo = NULL;
|
||||
write->pBufferInfo = NULL;
|
||||
write->pTexelBufferView = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return update;
|
||||
}
|
||||
|
||||
void
|
||||
vn_UpdateDescriptorSets(VkDevice device,
|
||||
uint32_t descriptorWriteCount,
|
||||
const VkWriteDescriptorSet *pDescriptorWrites,
|
||||
uint32_t descriptorCopyCount,
|
||||
const VkCopyDescriptorSet *pDescriptorCopies)
|
||||
{
|
||||
struct vn_device *dev = vn_device_from_handle(device);
|
||||
const VkAllocationCallbacks *alloc = &dev->base.base.alloc;
|
||||
|
||||
struct vn_update_descriptor_sets *update =
|
||||
vn_update_descriptor_sets_parse_writes(descriptorWriteCount,
|
||||
pDescriptorWrites, alloc);
|
||||
if (!update) {
|
||||
/* TODO update one-by-one? */
|
||||
vn_log(dev->instance, "TODO descriptor set update ignored due to OOM");
|
||||
return;
|
||||
}
|
||||
|
||||
vn_async_vkUpdateDescriptorSets(dev->instance, device, update->write_count,
|
||||
update->writes, descriptorCopyCount,
|
||||
pDescriptorCopies);
|
||||
|
||||
vk_free(alloc, update);
|
||||
}
|
||||
|
||||
/* descriptor update template commands */
|
||||
|
||||
static struct vn_update_descriptor_sets *
|
||||
vn_update_descriptor_sets_parse_template(
|
||||
const VkDescriptorUpdateTemplateCreateInfo *create_info,
|
||||
const VkAllocationCallbacks *alloc,
|
||||
struct vn_descriptor_update_template_entry *entries)
|
||||
{
|
||||
uint32_t img_count = 0;
|
||||
uint32_t buf_count = 0;
|
||||
uint32_t view_count = 0;
|
||||
for (uint32_t i = 0; i < create_info->descriptorUpdateEntryCount; i++) {
|
||||
const VkDescriptorUpdateTemplateEntry *entry =
|
||||
&create_info->pDescriptorUpdateEntries[i];
|
||||
|
||||
switch (entry->descriptorType) {
|
||||
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:
|
||||
img_count += entry->descriptorCount;
|
||||
break;
|
||||
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
|
||||
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
|
||||
view_count += entry->descriptorCount;
|
||||
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:
|
||||
buf_count += entry->descriptorCount;
|
||||
break;
|
||||
default:
|
||||
unreachable("unhandled descriptor type");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
struct vn_update_descriptor_sets *update = vn_update_descriptor_sets_alloc(
|
||||
create_info->descriptorUpdateEntryCount, img_count, buf_count,
|
||||
view_count, alloc, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
|
||||
if (!update)
|
||||
return NULL;
|
||||
|
||||
img_count = 0;
|
||||
buf_count = 0;
|
||||
view_count = 0;
|
||||
for (uint32_t i = 0; i < create_info->descriptorUpdateEntryCount; i++) {
|
||||
const VkDescriptorUpdateTemplateEntry *entry =
|
||||
&create_info->pDescriptorUpdateEntries[i];
|
||||
VkWriteDescriptorSet *write = &update->writes[i];
|
||||
|
||||
write->sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||
write->pNext = NULL;
|
||||
write->dstBinding = entry->dstBinding;
|
||||
write->dstArrayElement = entry->dstArrayElement;
|
||||
write->descriptorCount = entry->descriptorCount;
|
||||
write->descriptorType = entry->descriptorType;
|
||||
|
||||
entries[i].offset = entry->offset;
|
||||
entries[i].stride = entry->stride;
|
||||
|
||||
switch (entry->descriptorType) {
|
||||
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:
|
||||
write->pImageInfo = &update->images[img_count];
|
||||
write->pBufferInfo = NULL;
|
||||
write->pTexelBufferView = NULL;
|
||||
img_count += entry->descriptorCount;
|
||||
break;
|
||||
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
|
||||
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
|
||||
write->pImageInfo = NULL;
|
||||
write->pBufferInfo = NULL;
|
||||
write->pTexelBufferView = &update->views[view_count];
|
||||
view_count += entry->descriptorCount;
|
||||
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:
|
||||
write->pImageInfo = NULL;
|
||||
write->pBufferInfo = &update->buffers[buf_count];
|
||||
write->pTexelBufferView = NULL;
|
||||
buf_count += entry->descriptorCount;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return update;
|
||||
}
|
||||
|
||||
VkResult
|
||||
vn_CreateDescriptorUpdateTemplate(
|
||||
VkDevice device,
|
||||
const VkDescriptorUpdateTemplateCreateInfo *pCreateInfo,
|
||||
const VkAllocationCallbacks *pAllocator,
|
||||
VkDescriptorUpdateTemplate *pDescriptorUpdateTemplate)
|
||||
{
|
||||
struct vn_device *dev = vn_device_from_handle(device);
|
||||
const VkAllocationCallbacks *alloc =
|
||||
pAllocator ? pAllocator : &dev->base.base.alloc;
|
||||
|
||||
const size_t templ_size =
|
||||
offsetof(struct vn_descriptor_update_template,
|
||||
entries[pCreateInfo->descriptorUpdateEntryCount + 1]);
|
||||
struct vn_descriptor_update_template *templ = vk_zalloc(
|
||||
alloc, templ_size, VN_DEFAULT_ALIGN, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
|
||||
if (!templ)
|
||||
return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
|
||||
|
||||
vn_object_base_init(&templ->base,
|
||||
VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE, &dev->base);
|
||||
|
||||
templ->update = vn_update_descriptor_sets_parse_template(
|
||||
pCreateInfo, alloc, templ->entries);
|
||||
if (!templ->update) {
|
||||
vk_free(alloc, templ);
|
||||
return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
|
||||
}
|
||||
|
||||
mtx_init(&templ->mutex, mtx_plain);
|
||||
|
||||
/* no host object */
|
||||
VkDescriptorUpdateTemplate templ_handle =
|
||||
vn_descriptor_update_template_to_handle(templ);
|
||||
*pDescriptorUpdateTemplate = templ_handle;
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
vn_DestroyDescriptorUpdateTemplate(
|
||||
VkDevice device,
|
||||
VkDescriptorUpdateTemplate descriptorUpdateTemplate,
|
||||
const VkAllocationCallbacks *pAllocator)
|
||||
{
|
||||
struct vn_device *dev = vn_device_from_handle(device);
|
||||
struct vn_descriptor_update_template *templ =
|
||||
vn_descriptor_update_template_from_handle(descriptorUpdateTemplate);
|
||||
const VkAllocationCallbacks *alloc =
|
||||
pAllocator ? pAllocator : &dev->base.base.alloc;
|
||||
|
||||
if (!templ)
|
||||
return;
|
||||
|
||||
/* no host object */
|
||||
vk_free(alloc, templ->update);
|
||||
mtx_destroy(&templ->mutex);
|
||||
|
||||
vn_object_base_fini(&templ->base);
|
||||
vk_free(alloc, templ);
|
||||
}
|
||||
|
||||
void
|
||||
vn_UpdateDescriptorSetWithTemplate(
|
||||
VkDevice device,
|
||||
VkDescriptorSet descriptorSet,
|
||||
VkDescriptorUpdateTemplate descriptorUpdateTemplate,
|
||||
const void *pData)
|
||||
{
|
||||
struct vn_device *dev = vn_device_from_handle(device);
|
||||
struct vn_descriptor_set *set =
|
||||
vn_descriptor_set_from_handle(descriptorSet);
|
||||
struct vn_descriptor_update_template *templ =
|
||||
vn_descriptor_update_template_from_handle(descriptorUpdateTemplate);
|
||||
struct vn_update_descriptor_sets *update = templ->update;
|
||||
|
||||
/* duplicate update instead to avoid locking? */
|
||||
mtx_lock(&templ->mutex);
|
||||
|
||||
for (uint32_t i = 0; i < update->write_count; i++) {
|
||||
const struct vn_descriptor_update_template_entry *entry =
|
||||
&templ->entries[i];
|
||||
const struct vn_descriptor_set_layout_binding *binding =
|
||||
&set->layout->bindings[update->writes[i].dstBinding];
|
||||
VkWriteDescriptorSet *write = &update->writes[i];
|
||||
|
||||
write->dstSet = vn_descriptor_set_to_handle(set);
|
||||
|
||||
switch (write->descriptorType) {
|
||||
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 < write->descriptorCount; j++) {
|
||||
const bool need_sampler =
|
||||
(write->descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER ||
|
||||
write->descriptorType ==
|
||||
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) &&
|
||||
!binding->has_immutable_samplers;
|
||||
const bool need_view =
|
||||
write->descriptorType != VK_DESCRIPTOR_TYPE_SAMPLER;
|
||||
const VkDescriptorImageInfo *src =
|
||||
pData + entry->offset + entry->stride * j;
|
||||
VkDescriptorImageInfo *dst =
|
||||
(VkDescriptorImageInfo *)&write->pImageInfo[j];
|
||||
|
||||
dst->sampler = need_sampler ? src->sampler : VK_NULL_HANDLE;
|
||||
dst->imageView = need_view ? src->imageView : VK_NULL_HANDLE;
|
||||
dst->imageLayout = src->imageLayout;
|
||||
}
|
||||
break;
|
||||
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
|
||||
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
|
||||
for (uint32_t j = 0; j < write->descriptorCount; j++) {
|
||||
const VkBufferView *src =
|
||||
pData + entry->offset + entry->stride * j;
|
||||
VkBufferView *dst = (VkBufferView *)&write->pTexelBufferView[j];
|
||||
*dst = *src;
|
||||
}
|
||||
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 < write->descriptorCount; j++) {
|
||||
const VkDescriptorBufferInfo *src =
|
||||
pData + entry->offset + entry->stride * j;
|
||||
VkDescriptorBufferInfo *dst =
|
||||
(VkDescriptorBufferInfo *)&write->pBufferInfo[j];
|
||||
*dst = *src;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
unreachable("unhandled descriptor type");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
vn_async_vkUpdateDescriptorSets(dev->instance, device, update->write_count,
|
||||
update->writes, 0, NULL);
|
||||
|
||||
mtx_unlock(&templ->mutex);
|
||||
}
|
||||
|
||||
/* event commands */
|
||||
|
||||
VkResult
|
||||
|
|
|
|||
|
|
@ -257,67 +257,6 @@ VK_DEFINE_NONDISP_HANDLE_CASTS(vn_sampler_ycbcr_conversion,
|
|||
VkSamplerYcbcrConversion,
|
||||
VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION)
|
||||
|
||||
struct vn_descriptor_set_layout_binding {
|
||||
bool has_immutable_samplers;
|
||||
};
|
||||
|
||||
struct vn_descriptor_set_layout {
|
||||
struct vn_object_base base;
|
||||
struct vn_descriptor_set_layout_binding bindings[];
|
||||
};
|
||||
VK_DEFINE_NONDISP_HANDLE_CASTS(vn_descriptor_set_layout,
|
||||
base.base,
|
||||
VkDescriptorSetLayout,
|
||||
VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT)
|
||||
|
||||
struct vn_descriptor_pool {
|
||||
struct vn_object_base base;
|
||||
|
||||
VkAllocationCallbacks allocator;
|
||||
struct list_head descriptor_sets;
|
||||
};
|
||||
VK_DEFINE_NONDISP_HANDLE_CASTS(vn_descriptor_pool,
|
||||
base.base,
|
||||
VkDescriptorPool,
|
||||
VK_OBJECT_TYPE_DESCRIPTOR_POOL)
|
||||
|
||||
struct vn_update_descriptor_sets {
|
||||
uint32_t write_count;
|
||||
VkWriteDescriptorSet *writes;
|
||||
VkDescriptorImageInfo *images;
|
||||
VkDescriptorBufferInfo *buffers;
|
||||
VkBufferView *views;
|
||||
};
|
||||
|
||||
struct vn_descriptor_set {
|
||||
struct vn_object_base base;
|
||||
|
||||
const struct vn_descriptor_set_layout *layout;
|
||||
struct list_head head;
|
||||
};
|
||||
VK_DEFINE_NONDISP_HANDLE_CASTS(vn_descriptor_set,
|
||||
base.base,
|
||||
VkDescriptorSet,
|
||||
VK_OBJECT_TYPE_DESCRIPTOR_SET)
|
||||
|
||||
struct vn_descriptor_update_template_entry {
|
||||
size_t offset;
|
||||
size_t stride;
|
||||
};
|
||||
|
||||
struct vn_descriptor_update_template {
|
||||
struct vn_object_base base;
|
||||
|
||||
mtx_t mutex;
|
||||
struct vn_update_descriptor_sets *update;
|
||||
|
||||
struct vn_descriptor_update_template_entry entries[];
|
||||
};
|
||||
VK_DEFINE_NONDISP_HANDLE_CASTS(vn_descriptor_update_template,
|
||||
base.base,
|
||||
VkDescriptorUpdateTemplate,
|
||||
VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE)
|
||||
|
||||
struct vn_event {
|
||||
struct vn_object_base base;
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue