vkd3d: Create separate descriptor pools for each vkd3d descriptor type.

Now that our Vulkan descriptor sets contain only a single vkd3d
descriptor type, we're able to create descriptor pools containing only a
single vkd3d descriptor type as well. This avoids wasting unallocated
descriptors of one type when we run out of descriptors of another type.
This commit is contained in:
Conor McCarthy 2024-10-25 12:57:25 +10:00 committed by Henri Verbeet
parent a97c7c1fda
commit e729ceeb1a
Notes: Henri Verbeet 2024-12-05 21:35:35 +01:00
Approved-by: Giovanni Mascellani (@giomasce)
Approved-by: Henri Verbeet (@hverbeet)
Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/1088
4 changed files with 115 additions and 97 deletions

View File

@ -1463,23 +1463,33 @@ static bool d3d12_command_allocator_add_transfer_buffer(struct d3d12_command_all
} }
static VkDescriptorPool d3d12_command_allocator_allocate_descriptor_pool( static VkDescriptorPool d3d12_command_allocator_allocate_descriptor_pool(
struct d3d12_command_allocator *allocator) struct d3d12_command_allocator *allocator, enum vkd3d_shader_descriptor_type descriptor_type)
{ {
struct d3d12_device *device = allocator->device; struct d3d12_device *device = allocator->device;
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
struct VkDescriptorPoolCreateInfo pool_desc; struct VkDescriptorPoolCreateInfo pool_desc;
VkDevice vk_device = device->vk_device; VkDevice vk_device = device->vk_device;
VkDescriptorPoolSize vk_pool_sizes[2];
VkDescriptorPool vk_pool; VkDescriptorPool vk_pool;
VkResult vr; VkResult vr;
if (!(vk_pool = vkd3d_vk_descriptor_pool_array_pop(&allocator->free_descriptor_pools))) if (!(vk_pool = vkd3d_vk_descriptor_pool_array_pop(&allocator->free_descriptor_pools[descriptor_type])))
{ {
vk_pool_sizes[0].type = vk_descriptor_type_from_vkd3d_descriptor_type(descriptor_type, true);
vk_pool_sizes[0].descriptorCount = device->vk_pool_sizes[descriptor_type];
vk_pool_sizes[1].type = vk_descriptor_type_from_vkd3d_descriptor_type(descriptor_type, false);
vk_pool_sizes[1].descriptorCount = vk_pool_sizes[0].descriptorCount;
pool_desc.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; pool_desc.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
pool_desc.pNext = NULL; pool_desc.pNext = NULL;
pool_desc.flags = 0; pool_desc.flags = 0;
pool_desc.maxSets = 512; pool_desc.maxSets = 512;
pool_desc.poolSizeCount = device->vk_pool_count; pool_desc.poolSizeCount = 1;
pool_desc.pPoolSizes = device->vk_pool_sizes; if (vk_pool_sizes[1].type != vk_pool_sizes[0].type)
++pool_desc.poolSizeCount;
pool_desc.pPoolSizes = vk_pool_sizes;
if ((vr = VK_CALL(vkCreateDescriptorPool(vk_device, &pool_desc, NULL, &vk_pool))) < 0) if ((vr = VK_CALL(vkCreateDescriptorPool(vk_device, &pool_desc, NULL, &vk_pool))) < 0)
{ {
ERR("Failed to create descriptor pool, vr %d.\n", vr); ERR("Failed to create descriptor pool, vr %d.\n", vr);
@ -1487,7 +1497,7 @@ static VkDescriptorPool d3d12_command_allocator_allocate_descriptor_pool(
} }
} }
if (!(vkd3d_vk_descriptor_pool_array_push(&allocator->descriptor_pools, vk_pool))) if (!(vkd3d_vk_descriptor_pool_array_push(&allocator->descriptor_pools[descriptor_type], vk_pool)))
{ {
ERR("Failed to add descriptor pool.\n"); ERR("Failed to add descriptor pool.\n");
VK_CALL(vkDestroyDescriptorPool(vk_device, vk_pool, NULL)); VK_CALL(vkDestroyDescriptorPool(vk_device, vk_pool, NULL));
@ -1497,8 +1507,8 @@ static VkDescriptorPool d3d12_command_allocator_allocate_descriptor_pool(
return vk_pool; return vk_pool;
} }
static VkDescriptorSet d3d12_command_allocator_allocate_descriptor_set( static VkDescriptorSet d3d12_command_allocator_allocate_descriptor_set(struct d3d12_command_allocator *allocator,
struct d3d12_command_allocator *allocator, VkDescriptorSetLayout vk_set_layout, enum vkd3d_shader_descriptor_type descriptor_type, VkDescriptorSetLayout vk_set_layout,
unsigned int variable_binding_size, bool unbounded) unsigned int variable_binding_size, bool unbounded)
{ {
struct d3d12_device *device = allocator->device; struct d3d12_device *device = allocator->device;
@ -1509,14 +1519,15 @@ static VkDescriptorSet d3d12_command_allocator_allocate_descriptor_set(
VkDescriptorSet vk_descriptor_set; VkDescriptorSet vk_descriptor_set;
VkResult vr; VkResult vr;
if (!allocator->vk_descriptor_pool) if (!allocator->vk_descriptor_pools[descriptor_type])
allocator->vk_descriptor_pool = d3d12_command_allocator_allocate_descriptor_pool(allocator); allocator->vk_descriptor_pools[descriptor_type] = d3d12_command_allocator_allocate_descriptor_pool(allocator,
if (!allocator->vk_descriptor_pool) descriptor_type);
if (!allocator->vk_descriptor_pools[descriptor_type])
return VK_NULL_HANDLE; return VK_NULL_HANDLE;
set_desc.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; set_desc.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
set_desc.pNext = NULL; set_desc.pNext = NULL;
set_desc.descriptorPool = allocator->vk_descriptor_pool; set_desc.descriptorPool = allocator->vk_descriptor_pools[descriptor_type];
set_desc.descriptorSetCount = 1; set_desc.descriptorSetCount = 1;
set_desc.pSetLayouts = &vk_set_layout; set_desc.pSetLayouts = &vk_set_layout;
if (unbounded) if (unbounded)
@ -1530,16 +1541,17 @@ static VkDescriptorSet d3d12_command_allocator_allocate_descriptor_set(
if ((vr = VK_CALL(vkAllocateDescriptorSets(vk_device, &set_desc, &vk_descriptor_set))) >= 0) if ((vr = VK_CALL(vkAllocateDescriptorSets(vk_device, &set_desc, &vk_descriptor_set))) >= 0)
return vk_descriptor_set; return vk_descriptor_set;
allocator->vk_descriptor_pool = VK_NULL_HANDLE; allocator->vk_descriptor_pools[descriptor_type] = VK_NULL_HANDLE;
if (vr == VK_ERROR_FRAGMENTED_POOL || vr == VK_ERROR_OUT_OF_POOL_MEMORY_KHR) if (vr == VK_ERROR_FRAGMENTED_POOL || vr == VK_ERROR_OUT_OF_POOL_MEMORY_KHR)
allocator->vk_descriptor_pool = d3d12_command_allocator_allocate_descriptor_pool(allocator); allocator->vk_descriptor_pools[descriptor_type] = d3d12_command_allocator_allocate_descriptor_pool(allocator,
if (!allocator->vk_descriptor_pool) descriptor_type);
if (!allocator->vk_descriptor_pools[descriptor_type])
{ {
ERR("Failed to allocate descriptor set, vr %d.\n", vr); ERR("Failed to allocate descriptor set, vr %d.\n", vr);
return VK_NULL_HANDLE; return VK_NULL_HANDLE;
} }
set_desc.descriptorPool = allocator->vk_descriptor_pool; set_desc.descriptorPool = allocator->vk_descriptor_pools[descriptor_type];
if ((vr = VK_CALL(vkAllocateDescriptorSets(vk_device, &set_desc, &vk_descriptor_set))) < 0) if ((vr = VK_CALL(vkAllocateDescriptorSets(vk_device, &set_desc, &vk_descriptor_set))) < 0)
{ {
FIXME("Failed to allocate descriptor set from a new pool, vr %d.\n", vr); FIXME("Failed to allocate descriptor set from a new pool, vr %d.\n", vr);
@ -1565,6 +1577,26 @@ static void vkd3d_buffer_destroy(struct vkd3d_buffer *buffer, struct d3d12_devic
VK_CALL(vkDestroyBuffer(device->vk_device, buffer->vk_buffer, NULL)); VK_CALL(vkDestroyBuffer(device->vk_device, buffer->vk_buffer, NULL));
} }
static void d3d12_command_allocator_reset_descriptor_pool_array(struct d3d12_command_allocator *allocator,
enum vkd3d_shader_descriptor_type type)
{
struct vkd3d_vk_descriptor_pool_array *array = &allocator->descriptor_pools[type];
struct d3d12_device *device = allocator->device;
const struct vkd3d_vk_device_procs *vk_procs;
size_t i;
if (!vkd3d_vk_descriptor_pool_array_push_array(&allocator->free_descriptor_pools[type],
array->pools, array->count))
return;
vk_procs = &device->vk_procs;
for (i = 0; i < array->count; ++i)
{
VK_CALL(vkResetDescriptorPool(device->vk_device, array->pools[i], 0));
}
array->count = 0;
}
static void d3d12_command_allocator_free_resources(struct d3d12_command_allocator *allocator, static void d3d12_command_allocator_free_resources(struct d3d12_command_allocator *allocator,
bool keep_reusable_resources) bool keep_reusable_resources)
{ {
@ -1572,24 +1604,21 @@ static void d3d12_command_allocator_free_resources(struct d3d12_command_allocato
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
unsigned int i; unsigned int i;
allocator->vk_descriptor_pool = VK_NULL_HANDLE; memset(allocator->vk_descriptor_pools, 0, sizeof(allocator->vk_descriptor_pools));
if (keep_reusable_resources) if (keep_reusable_resources)
{ {
struct vkd3d_vk_descriptor_pool_array *array = &allocator->descriptor_pools; for (i = 0; i < ARRAY_SIZE(allocator->descriptor_pools); ++i)
if (vkd3d_vk_descriptor_pool_array_push_array(&allocator->free_descriptor_pools, array->pools, array->count))
{ {
for (i = 0; i < array->count; ++i) d3d12_command_allocator_reset_descriptor_pool_array(allocator, i);
{
VK_CALL(vkResetDescriptorPool(device->vk_device, array->pools[i], 0));
}
array->count = 0;
} }
} }
else else
{ {
vkd3d_vk_descriptor_pool_array_destroy_pools(&allocator->free_descriptor_pools, device); for (i = 0; i < ARRAY_SIZE(allocator->free_descriptor_pools); ++i)
{
vkd3d_vk_descriptor_pool_array_destroy_pools(&allocator->free_descriptor_pools[i], device);
}
} }
for (i = 0; i < allocator->transfer_buffer_count; ++i) for (i = 0; i < allocator->transfer_buffer_count; ++i)
@ -1610,7 +1639,10 @@ static void d3d12_command_allocator_free_resources(struct d3d12_command_allocato
} }
allocator->view_count = 0; allocator->view_count = 0;
vkd3d_vk_descriptor_pool_array_destroy_pools(&allocator->descriptor_pools, device); for (i = 0; i < ARRAY_SIZE(allocator->descriptor_pools); ++i)
{
vkd3d_vk_descriptor_pool_array_destroy_pools(&allocator->descriptor_pools[i], device);
}
for (i = 0; i < allocator->framebuffer_count; ++i) for (i = 0; i < allocator->framebuffer_count; ++i)
{ {
@ -1667,6 +1699,7 @@ static ULONG STDMETHODCALLTYPE d3d12_command_allocator_Release(ID3D12CommandAllo
{ {
struct d3d12_command_allocator *allocator = impl_from_ID3D12CommandAllocator(iface); struct d3d12_command_allocator *allocator = impl_from_ID3D12CommandAllocator(iface);
unsigned int refcount = vkd3d_atomic_decrement_u32(&allocator->refcount); unsigned int refcount = vkd3d_atomic_decrement_u32(&allocator->refcount);
size_t i;
TRACE("%p decreasing refcount to %u.\n", allocator, refcount); TRACE("%p decreasing refcount to %u.\n", allocator, refcount);
@ -1684,8 +1717,11 @@ static ULONG STDMETHODCALLTYPE d3d12_command_allocator_Release(ID3D12CommandAllo
vkd3d_free(allocator->transfer_buffers); vkd3d_free(allocator->transfer_buffers);
vkd3d_free(allocator->buffer_views); vkd3d_free(allocator->buffer_views);
vkd3d_free(allocator->views); vkd3d_free(allocator->views);
vkd3d_vk_descriptor_pool_array_cleanup(&allocator->descriptor_pools); for (i = 0; i < ARRAY_SIZE(allocator->free_descriptor_pools); ++i)
vkd3d_vk_descriptor_pool_array_cleanup(&allocator->free_descriptor_pools); {
vkd3d_vk_descriptor_pool_array_cleanup(&allocator->descriptor_pools[i]);
vkd3d_vk_descriptor_pool_array_cleanup(&allocator->free_descriptor_pools[i]);
}
vkd3d_free(allocator->framebuffers); vkd3d_free(allocator->framebuffers);
vkd3d_free(allocator->passes); vkd3d_free(allocator->passes);
@ -1842,6 +1878,7 @@ static HRESULT d3d12_command_allocator_init(struct d3d12_command_allocator *allo
struct vkd3d_queue *queue; struct vkd3d_queue *queue;
VkResult vr; VkResult vr;
HRESULT hr; HRESULT hr;
size_t i;
if (FAILED(hr = vkd3d_private_store_init(&allocator->private_store))) if (FAILED(hr = vkd3d_private_store_init(&allocator->private_store)))
return hr; return hr;
@ -1871,9 +1908,12 @@ static HRESULT d3d12_command_allocator_init(struct d3d12_command_allocator *allo
return hresult_from_vk_result(vr); return hresult_from_vk_result(vr);
} }
allocator->vk_descriptor_pool = VK_NULL_HANDLE; memset(allocator->vk_descriptor_pools, 0, sizeof(allocator->vk_descriptor_pools));
vkd3d_vk_descriptor_pool_array_init(&allocator->free_descriptor_pools); for (i = 0; i < ARRAY_SIZE(allocator->free_descriptor_pools); ++i)
{
vkd3d_vk_descriptor_pool_array_init(&allocator->free_descriptor_pools[i]);
}
allocator->passes = NULL; allocator->passes = NULL;
allocator->passes_size = 0; allocator->passes_size = 0;
@ -1883,7 +1923,10 @@ static HRESULT d3d12_command_allocator_init(struct d3d12_command_allocator *allo
allocator->framebuffers_size = 0; allocator->framebuffers_size = 0;
allocator->framebuffer_count = 0; allocator->framebuffer_count = 0;
vkd3d_vk_descriptor_pool_array_init(&allocator->descriptor_pools); for (i = 0; i < ARRAY_SIZE(allocator->descriptor_pools); ++i)
{
vkd3d_vk_descriptor_pool_array_init(&allocator->descriptor_pools[i]);
}
allocator->views = NULL; allocator->views = NULL;
allocator->views_size = 0; allocator->views_size = 0;
@ -2765,7 +2808,7 @@ static void d3d12_command_list_prepare_descriptors(struct d3d12_command_list *li
} }
vk_descriptor_set = d3d12_command_allocator_allocate_descriptor_set(list->allocator, vk_descriptor_set = d3d12_command_allocator_allocate_descriptor_set(list->allocator,
layout->vk_layout, variable_binding_size, unbounded_offset != UINT_MAX); layout->descriptor_type, layout->vk_layout, variable_binding_size, unbounded_offset != UINT_MAX);
bindings->descriptor_sets[bindings->descriptor_set_count++] = vk_descriptor_set; bindings->descriptor_sets[bindings->descriptor_set_count++] = vk_descriptor_set;
} }
@ -3050,8 +3093,8 @@ static void d3d12_command_list_update_uav_counter_descriptors(struct d3d12_comma
uav_counter_count = state->uav_counters.binding_count; uav_counter_count = state->uav_counters.binding_count;
if (!(vk_descriptor_writes = vkd3d_calloc(uav_counter_count, sizeof(*vk_descriptor_writes)))) if (!(vk_descriptor_writes = vkd3d_calloc(uav_counter_count, sizeof(*vk_descriptor_writes))))
return; return;
if (!(vk_descriptor_set = d3d12_command_allocator_allocate_descriptor_set( if (!(vk_descriptor_set = d3d12_command_allocator_allocate_descriptor_set(list->allocator,
list->allocator, state->uav_counters.vk_set_layout, 0, false))) VKD3D_SHADER_DESCRIPTOR_TYPE_UAV, state->uav_counters.vk_set_layout, 0, false)))
goto done; goto done;
for (i = 0; i < uav_counter_count; ++i) for (i = 0; i < uav_counter_count; ++i)
@ -5380,8 +5423,8 @@ static void d3d12_command_list_clear_uav(struct d3d12_command_list *list,
view->info.texture.vk_view_type, view->format->type, &pipeline); view->info.texture.vk_view_type, view->format->type, &pipeline);
} }
if (!(write_set.dstSet = d3d12_command_allocator_allocate_descriptor_set( if (!(write_set.dstSet = d3d12_command_allocator_allocate_descriptor_set(list->allocator,
list->allocator, pipeline.vk_set_layout, 0, false))) VKD3D_SHADER_DESCRIPTOR_TYPE_UAV, pipeline.vk_set_layout, 0, false)))
{ {
ERR("Failed to allocate descriptor set.\n"); ERR("Failed to allocate descriptor set.\n");
return; return;

View File

@ -2677,39 +2677,16 @@ static void vkd3d_time_domains_init(struct d3d12_device *device)
static void device_init_descriptor_pool_sizes(struct d3d12_device *device) static void device_init_descriptor_pool_sizes(struct d3d12_device *device)
{ {
const struct vkd3d_device_descriptor_limits *limits = &device->vk_info.descriptor_limits; const struct vkd3d_device_descriptor_limits *limits = &device->vk_info.descriptor_limits;
VkDescriptorPoolSize *pool_sizes = device->vk_pool_sizes; unsigned int *pool_sizes = device->vk_pool_sizes;
if (device->use_vk_heaps) pool_sizes[VKD3D_SHADER_DESCRIPTOR_TYPE_CBV] = min(limits->uniform_buffer_max_descriptors,
{
pool_sizes[0].type = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
pool_sizes[0].descriptorCount = min(limits->storage_image_max_descriptors,
VKD3D_MAX_UAV_CLEAR_DESCRIPTORS_PER_TYPE);
pool_sizes[1].type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
pool_sizes[1].descriptorCount = pool_sizes[0].descriptorCount;
pool_sizes[2].type = VK_DESCRIPTOR_TYPE_SAMPLER;
pool_sizes[2].descriptorCount = min(limits->sampler_max_descriptors, D3D12_MAX_LIVE_STATIC_SAMPLERS);
device->vk_pool_count = 3;
return;
}
VKD3D_ASSERT(ARRAY_SIZE(device->vk_pool_sizes) >= 6);
pool_sizes[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
pool_sizes[0].descriptorCount = min(limits->uniform_buffer_max_descriptors,
VKD3D_MAX_VIRTUAL_HEAP_DESCRIPTORS_PER_TYPE); VKD3D_MAX_VIRTUAL_HEAP_DESCRIPTORS_PER_TYPE);
pool_sizes[1].type = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER; pool_sizes[VKD3D_SHADER_DESCRIPTOR_TYPE_SRV] = min(limits->sampled_image_max_descriptors,
pool_sizes[1].descriptorCount = min(limits->sampled_image_max_descriptors,
VKD3D_MAX_VIRTUAL_HEAP_DESCRIPTORS_PER_TYPE); VKD3D_MAX_VIRTUAL_HEAP_DESCRIPTORS_PER_TYPE);
pool_sizes[2].type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; pool_sizes[VKD3D_SHADER_DESCRIPTOR_TYPE_UAV] = min(limits->storage_image_max_descriptors,
pool_sizes[2].descriptorCount = pool_sizes[1].descriptorCount;
pool_sizes[3].type = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
pool_sizes[3].descriptorCount = min(limits->storage_image_max_descriptors,
VKD3D_MAX_VIRTUAL_HEAP_DESCRIPTORS_PER_TYPE); VKD3D_MAX_VIRTUAL_HEAP_DESCRIPTORS_PER_TYPE);
pool_sizes[4].type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; pool_sizes[VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER] = min(limits->sampler_max_descriptors,
pool_sizes[4].descriptorCount = pool_sizes[3].descriptorCount;
pool_sizes[5].type = VK_DESCRIPTOR_TYPE_SAMPLER;
pool_sizes[5].descriptorCount = min(limits->sampler_max_descriptors,
VKD3D_MAX_VIRTUAL_HEAP_DESCRIPTORS_PER_TYPE); VKD3D_MAX_VIRTUAL_HEAP_DESCRIPTORS_PER_TYPE);
device->vk_pool_count = 6;
}; };
static void vkd3d_desc_object_cache_init(struct vkd3d_desc_object_cache *cache, size_t size) static void vkd3d_desc_object_cache_init(struct vkd3d_desc_object_cache *cache, size_t size)

View File

@ -265,25 +265,6 @@ static enum vkd3d_shader_visibility vkd3d_shader_visibility_from_d3d12(D3D12_SHA
} }
} }
static VkDescriptorType vk_descriptor_type_from_vkd3d_descriptor_type(enum vkd3d_shader_descriptor_type type,
bool is_buffer)
{
switch (type)
{
case VKD3D_SHADER_DESCRIPTOR_TYPE_SRV:
return is_buffer ? VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER : VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
case VKD3D_SHADER_DESCRIPTOR_TYPE_UAV:
return is_buffer ? VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER : VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
case VKD3D_SHADER_DESCRIPTOR_TYPE_CBV:
return VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
case VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER:
return VK_DESCRIPTOR_TYPE_SAMPLER;
default:
FIXME("Unhandled descriptor range type type %#x.\n", type);
return VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
}
}
static enum vkd3d_shader_descriptor_type vkd3d_descriptor_type_from_d3d12_range_type( static enum vkd3d_shader_descriptor_type vkd3d_descriptor_type_from_d3d12_range_type(
D3D12_DESCRIPTOR_RANGE_TYPE type) D3D12_DESCRIPTOR_RANGE_TYPE type)
{ {
@ -717,6 +698,7 @@ struct vk_binding_array
VkDescriptorSetLayoutBinding *bindings; VkDescriptorSetLayoutBinding *bindings;
size_t capacity, count; size_t capacity, count;
enum vkd3d_shader_descriptor_type descriptor_type;
unsigned int descriptor_set; unsigned int descriptor_set;
unsigned int table_index; unsigned int table_index;
unsigned int unbounded_offset; unsigned int unbounded_offset;
@ -798,8 +780,8 @@ static bool vkd3d_validate_descriptor_set_count(struct d3d12_device *device, uns
} }
static struct vk_binding_array *d3d12_root_signature_append_vk_binding_array( static struct vk_binding_array *d3d12_root_signature_append_vk_binding_array(
struct d3d12_root_signature *root_signature, VkDescriptorSetLayoutCreateFlags flags, struct d3d12_root_signature *root_signature, enum vkd3d_shader_descriptor_type descriptor_type,
struct vkd3d_descriptor_set_context *context) VkDescriptorSetLayoutCreateFlags flags, struct vkd3d_descriptor_set_context *context)
{ {
struct vk_binding_array *array; struct vk_binding_array *array;
unsigned int set; unsigned int set;
@ -809,6 +791,7 @@ static struct vk_binding_array *d3d12_root_signature_append_vk_binding_array(
set = root_signature->vk_set_count++; set = root_signature->vk_set_count++;
array = &context->vk_bindings[set]; array = &context->vk_bindings[set];
array->descriptor_type = descriptor_type;
array->descriptor_set = set; array->descriptor_set = set;
array->unbounded_offset = UINT_MAX; array->unbounded_offset = UINT_MAX;
array->flags = flags; array->flags = flags;
@ -826,7 +809,7 @@ static struct vk_binding_array *d3d12_root_signature_vk_binding_array_for_type(
{ {
if (!context->push_descriptor_set) if (!context->push_descriptor_set)
context->push_descriptor_set = d3d12_root_signature_append_vk_binding_array(root_signature, context->push_descriptor_set = d3d12_root_signature_append_vk_binding_array(root_signature,
VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR, context); descriptor_type, VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR, context);
return context->push_descriptor_set; return context->push_descriptor_set;
} }
@ -834,7 +817,7 @@ static struct vk_binding_array *d3d12_root_signature_vk_binding_array_for_type(
current = context->current_binding_array; current = context->current_binding_array;
if (!(array = current[descriptor_type])) if (!(array = current[descriptor_type]))
{ {
array = d3d12_root_signature_append_vk_binding_array(root_signature, 0, context); array = d3d12_root_signature_append_vk_binding_array(root_signature, descriptor_type, 0, context);
current[descriptor_type] = array; current[descriptor_type] = array;
} }
@ -1510,6 +1493,7 @@ static HRESULT d3d12_descriptor_set_layout_init(struct d3d12_descriptor_set_layo
if (FAILED(hr = vkd3d_create_descriptor_set_layout(device, array->flags, array->count, if (FAILED(hr = vkd3d_create_descriptor_set_layout(device, array->flags, array->count,
array->unbounded_offset != UINT_MAX, array->bindings, &layout->vk_layout))) array->unbounded_offset != UINT_MAX, array->bindings, &layout->vk_layout)))
return hr; return hr;
layout->descriptor_type = array->descriptor_type;
layout->unbounded_offset = array->unbounded_offset; layout->unbounded_offset = array->unbounded_offset;
layout->table_index = array->table_index; layout->table_index = array->table_index;

View File

@ -60,9 +60,6 @@
#define VKD3D_MAX_DESCRIPTOR_SETS 64u #define VKD3D_MAX_DESCRIPTOR_SETS 64u
/* D3D12 binding tier 3 has a limit of 2048 samplers. */ /* D3D12 binding tier 3 has a limit of 2048 samplers. */
#define VKD3D_MAX_DESCRIPTOR_SET_SAMPLERS 2048u #define VKD3D_MAX_DESCRIPTOR_SET_SAMPLERS 2048u
/* The main limitation here is the simple descriptor pool recycling scheme
* requiring each pool to contain all descriptor types used by vkd3d. Limit
* this number to prevent excessive pool memory use. */
#define VKD3D_MAX_VIRTUAL_HEAP_DESCRIPTORS_PER_TYPE (16 * 1024u) #define VKD3D_MAX_VIRTUAL_HEAP_DESCRIPTORS_PER_TYPE (16 * 1024u)
#define VKD3D_SHADER_DESCRIPTOR_TYPE_COUNT (VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER + 1) #define VKD3D_SHADER_DESCRIPTOR_TYPE_COUNT (VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER + 1)
@ -772,6 +769,25 @@ static inline struct d3d12_dsv_desc *d3d12_dsv_desc_from_cpu_handle(D3D12_CPU_DE
void d3d12_dsv_desc_create_dsv(struct d3d12_dsv_desc *dsv_desc, struct d3d12_device *device, void d3d12_dsv_desc_create_dsv(struct d3d12_dsv_desc *dsv_desc, struct d3d12_device *device,
struct d3d12_resource *resource, const D3D12_DEPTH_STENCIL_VIEW_DESC *desc); struct d3d12_resource *resource, const D3D12_DEPTH_STENCIL_VIEW_DESC *desc);
static inline VkDescriptorType vk_descriptor_type_from_vkd3d_descriptor_type(enum vkd3d_shader_descriptor_type type,
bool is_buffer)
{
switch (type)
{
case VKD3D_SHADER_DESCRIPTOR_TYPE_SRV:
return is_buffer ? VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER : VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
case VKD3D_SHADER_DESCRIPTOR_TYPE_UAV:
return is_buffer ? VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER : VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
case VKD3D_SHADER_DESCRIPTOR_TYPE_CBV:
return VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
case VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER:
return VK_DESCRIPTOR_TYPE_SAMPLER;
default:
FIXME("Unhandled descriptor range type type %#x.\n", type);
return VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
}
}
enum vkd3d_vk_descriptor_set_index enum vkd3d_vk_descriptor_set_index
{ {
VKD3D_SET_INDEX_SAMPLER, VKD3D_SET_INDEX_SAMPLER,
@ -941,6 +957,7 @@ struct d3d12_root_parameter
struct d3d12_descriptor_set_layout struct d3d12_descriptor_set_layout
{ {
enum vkd3d_shader_descriptor_type descriptor_type;
VkDescriptorSetLayout vk_layout; VkDescriptorSetLayout vk_layout;
unsigned int unbounded_offset; unsigned int unbounded_offset;
unsigned int table_index; unsigned int table_index;
@ -1157,9 +1174,9 @@ struct d3d12_command_allocator
VkCommandPool vk_command_pool; VkCommandPool vk_command_pool;
VkDescriptorPool vk_descriptor_pool; VkDescriptorPool vk_descriptor_pools[VKD3D_SHADER_DESCRIPTOR_TYPE_COUNT];
struct vkd3d_vk_descriptor_pool_array free_descriptor_pools; struct vkd3d_vk_descriptor_pool_array free_descriptor_pools[VKD3D_SHADER_DESCRIPTOR_TYPE_COUNT];
VkRenderPass *passes; VkRenderPass *passes;
size_t passes_size; size_t passes_size;
@ -1169,7 +1186,7 @@ struct d3d12_command_allocator
size_t framebuffers_size; size_t framebuffers_size;
size_t framebuffer_count; size_t framebuffer_count;
struct vkd3d_vk_descriptor_pool_array descriptor_pools; struct vkd3d_vk_descriptor_pool_array descriptor_pools[VKD3D_SHADER_DESCRIPTOR_TYPE_COUNT];
struct vkd3d_view **views; struct vkd3d_view **views;
size_t views_size; size_t views_size;
@ -1523,8 +1540,6 @@ struct vkd3d_desc_object_cache
size_t size; size_t size;
}; };
#define VKD3D_DESCRIPTOR_POOL_COUNT 6
/* ID3D12Device */ /* ID3D12Device */
struct d3d12_device struct d3d12_device
{ {
@ -1543,8 +1558,7 @@ struct d3d12_device
struct vkd3d_desc_object_cache view_desc_cache; struct vkd3d_desc_object_cache view_desc_cache;
struct vkd3d_desc_object_cache cbuffer_desc_cache; struct vkd3d_desc_object_cache cbuffer_desc_cache;
VkDescriptorPoolSize vk_pool_sizes[VKD3D_DESCRIPTOR_POOL_COUNT]; unsigned int vk_pool_sizes[VKD3D_SHADER_DESCRIPTOR_TYPE_COUNT];
unsigned int vk_pool_count;
struct vkd3d_vk_descriptor_heap_layout vk_descriptor_heap_layouts[VKD3D_SET_INDEX_COUNT]; struct vkd3d_vk_descriptor_heap_layout vk_descriptor_heap_layouts[VKD3D_SET_INDEX_COUNT];
bool use_vk_heaps; bool use_vk_heaps;