diff --git a/libs/vkd3d/command.c b/libs/vkd3d/command.c index ecdf6dbf..1ff58f97 100644 --- a/libs/vkd3d/command.c +++ b/libs/vkd3d/command.c @@ -1499,7 +1499,7 @@ static VkDescriptorPool d3d12_command_allocator_allocate_descriptor_pool( const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; struct VkDescriptorPoolCreateInfo pool_desc; VkDevice vk_device = device->vk_device; - VkDescriptorPoolSize vk_pool_sizes[2]; + VkDescriptorPoolSize vk_pool_sizes[4]; unsigned int pool_size, pool_limit; VkDescriptorPool vk_pool; VkResult vr; @@ -1530,21 +1530,43 @@ static VkDescriptorPool d3d12_command_allocator_allocate_descriptor_pool( } descriptor_count = pool_size; - vk_pool_sizes[0].type = vk_descriptor_type_from_vkd3d_descriptor_type(descriptor_type, true); - vk_pool_sizes[0].descriptorCount = descriptor_count; - - vk_pool_sizes[1].type = vk_descriptor_type_from_vkd3d_descriptor_type(descriptor_type, false); - vk_pool_sizes[1].descriptorCount = descriptor_count; - pool_desc.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; pool_desc.pNext = NULL; pool_desc.flags = 0; pool_desc.maxSets = 512; - pool_desc.poolSizeCount = 1; - if (vk_pool_sizes[1].type != vk_pool_sizes[0].type) - ++pool_desc.poolSizeCount; pool_desc.pPoolSizes = vk_pool_sizes; + if (allocator->device->use_vk_heaps) + { + /* SRV root descriptors. */ + vk_pool_sizes[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER; + vk_pool_sizes[0].descriptorCount = descriptor_count; + + /* UAV root descriptors and UAV counters. */ + vk_pool_sizes[1].type = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; + vk_pool_sizes[1].descriptorCount = descriptor_count; + + /* CBV root descriptors. */ + vk_pool_sizes[2].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + vk_pool_sizes[2].descriptorCount = descriptor_count; + + /* Static samplers. */ + vk_pool_sizes[3].type = VK_DESCRIPTOR_TYPE_SAMPLER; + vk_pool_sizes[3].descriptorCount = descriptor_count; + + pool_desc.poolSizeCount = 4; + } + else + { + vk_pool_sizes[0].type = vk_descriptor_type_from_vkd3d_descriptor_type(descriptor_type, true); + vk_pool_sizes[0].descriptorCount = descriptor_count; + + vk_pool_sizes[1].type = vk_descriptor_type_from_vkd3d_descriptor_type(descriptor_type, false); + vk_pool_sizes[1].descriptorCount = descriptor_count; + + pool_desc.poolSizeCount = 1 + (vk_pool_sizes[0].type != vk_pool_sizes[1].type); + } + if ((vr = VK_CALL(vkCreateDescriptorPool(vk_device, &pool_desc, NULL, &vk_pool))) < 0) { ERR("Failed to create descriptor pool, vr %d.\n", vr); @@ -1578,6 +1600,10 @@ static VkDescriptorSet d3d12_command_allocator_allocate_descriptor_set(struct d3 VkDescriptorSet vk_descriptor_set; VkResult vr; + /* With Vulkan heaps we use just one descriptor pool. */ + if (device->use_vk_heaps) + descriptor_type = 0; + if (!allocator->vk_descriptor_pools[descriptor_type]) allocator->vk_descriptor_pools[descriptor_type] = d3d12_command_allocator_allocate_descriptor_pool(allocator, descriptor_type, descriptor_count, unbounded); diff --git a/libs/vkd3d/state.c b/libs/vkd3d/state.c index 86541b5d..2246f49b 100644 --- a/libs/vkd3d/state.c +++ b/libs/vkd3d/state.c @@ -755,7 +755,10 @@ struct vkd3d_descriptor_set_context unsigned int push_constant_index; struct vk_binding_array *root_descriptor_set; + struct vk_binding_array *static_samplers_descriptor_set; bool push_descriptor; + bool static_samplers; + bool use_vk_heaps; }; static void descriptor_set_context_cleanup(struct vkd3d_descriptor_set_context *context) @@ -806,15 +809,61 @@ static struct vk_binding_array *d3d12_root_signature_vk_binding_array_for_type( { struct vk_binding_array *array, **current; + /* There are a few different ways we can reach this point: + * * If we are using virtual heaps we want to allocate descriptors to sets + * depending on their descriptor type, in order to minimize waste when + * recycling descriptor pools. + * + With the exception of root descriptors when we are using push + * descriptors: the push descriptors must be in a separate set, so we + * keep one specifically for them. + * * If we are using Vulkan heaps then all the root table descriptors don't + * even reach here, because they are managed by the D3D12 descriptor + * heap. Thus we only have to deal with root descriptors and static + * samplers. + * + If we're using push descriptors then again we have to dedicate a set + * for them, so static samplers will and up in their own set too. + * + If we're not using push descriptors then we can use the same set and + * save one. In this case we don't care too much about minimizing + * wasted descriptors, because few descriptors can end up here anyway. + */ + if (context->push_descriptor) { + /* The descriptor type is irrelevant here, it will never be used. */ if (!context->root_descriptor_set) context->root_descriptor_set = d3d12_root_signature_append_vk_binding_array(root_signature, - descriptor_type, VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR, context); + 0, VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR, context); return context->root_descriptor_set; } + if (context->use_vk_heaps) + { + if (context->static_samplers) + { + if (!context->static_samplers_descriptor_set) + { + if (!context->push_descriptor && context->root_descriptor_set) + context->static_samplers_descriptor_set = context->root_descriptor_set; + else + /* The descriptor type is irrelevant here, it will never be used. */ + context->static_samplers_descriptor_set = d3d12_root_signature_append_vk_binding_array( + root_signature, 0, 0, context); + } + + return context->static_samplers_descriptor_set; + } + else + { + /* The descriptor type is irrelevant here, it will never be used. */ + if (!context->root_descriptor_set) + context->root_descriptor_set = d3d12_root_signature_append_vk_binding_array( + root_signature, 0, 0, context); + + return context->root_descriptor_set; + } + } + current = context->current_binding_array; if (!(array = current[descriptor_type])) { @@ -1638,17 +1687,22 @@ static HRESULT d3d12_root_signature_init(struct d3d12_root_signature *root_signa sizeof(*root_signature->static_samplers)))) goto fail; + context.use_vk_heaps = use_vk_heaps; context.push_descriptor = vk_info->KHR_push_descriptor; if (FAILED(hr = d3d12_root_signature_init_root_descriptors(root_signature, desc, &context))) goto fail; - root_signature->main_set = !!context.root_descriptor_set; + root_signature->main_set = context.root_descriptor_set && context.push_descriptor; context.push_descriptor = false; if (FAILED(hr = d3d12_root_signature_init_push_constants(root_signature, desc, root_signature->push_constant_ranges, &root_signature->push_constant_range_count))) goto fail; + + context.static_samplers = true; if (FAILED(hr = d3d12_root_signature_init_static_samplers(root_signature, device, desc, &context))) goto fail; + context.static_samplers = false; + context.push_constant_index = 0; if (FAILED(hr = d3d12_root_signature_init_root_descriptor_tables(root_signature, desc, &info, &context))) goto fail;