vkd3d: Support splitting mutable descriptor type into different subsets.

Signed-off-by: Hans-Kristian Arntzen <post@arntzen-software.no>
This commit is contained in:
Hans-Kristian Arntzen 2021-02-10 09:52:28 +01:00
parent fccbd3b5e2
commit c6b1cdfe78
4 changed files with 82 additions and 26 deletions

View File

@ -412,6 +412,7 @@ static const struct vkd3d_debug_option vkd3d_config_options[] =
/* Enable Vulkan debug extensions. */
{"vk_debug", VKD3D_CONFIG_FLAG_VULKAN_DEBUG},
{"skip_application_workarounds", VKD3D_CONFIG_FLAG_SKIP_APPLICATION_WORKAROUNDS},
{"split_mutable_types", VKD3D_CONFIG_SPLIT_MUTABLE_TYPES},
};
static uint64_t vkd3d_init_config_flags(void)

View File

@ -5536,26 +5536,46 @@ struct d3d12_descriptor_heap *unsafe_impl_from_ID3D12DescriptorHeap(ID3D12Descri
static HRESULT d3d12_descriptor_heap_create_descriptor_pool(struct d3d12_descriptor_heap *descriptor_heap,
VkDescriptorPool *vk_descriptor_pool)
{
VkDescriptorType mutable_descriptor_types[VKD3D_MAX_BINDLESS_DESCRIPTOR_SETS][VKD3D_MAX_MUTABLE_DESCRIPTOR_TYPES];
VkMutableDescriptorTypeListVALVE mutable_descriptor_list[VKD3D_MAX_BINDLESS_DESCRIPTOR_SETS];
const struct vkd3d_vk_device_procs *vk_procs = &descriptor_heap->device->vk_procs;
VkDescriptorPoolSize vk_pool_sizes[VKD3D_MAX_BINDLESS_DESCRIPTOR_SETS];
const struct d3d12_device *device = descriptor_heap->device;
VkMutableDescriptorTypeCreateInfoVALVE mutable_info;
unsigned int i, pool_count = 0, ssbo_count = 0;
VkDescriptorPoolCreateInfo vk_pool_info;
VkDescriptorPoolSize *ssbo_pool = NULL;
VkResult vr;
memset(mutable_descriptor_list, 0, sizeof(mutable_descriptor_list));
for (i = 0; i < device->bindless_state.set_count; i++)
{
const struct vkd3d_bindless_set_info *set_info = &device->bindless_state.set_info[i];
if (set_info->heap_type == descriptor_heap->desc.Type)
{
VkDescriptorPoolSize *vk_pool_size = &vk_pool_sizes[pool_count++];
VkDescriptorPoolSize *vk_pool_size = &vk_pool_sizes[pool_count];
vk_pool_size->type = set_info->vk_descriptor_type;
vk_pool_size->descriptorCount = descriptor_heap->desc.NumDescriptors;
if (set_info->vk_descriptor_type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
if (set_info->vk_descriptor_type == VK_DESCRIPTOR_TYPE_MUTABLE_VALVE)
{
mutable_descriptor_list[pool_count].descriptorTypeCount =
vkd3d_bindless_build_mutable_type_list(mutable_descriptor_types[pool_count], set_info->flags,
device->bindless_state.flags);
mutable_descriptor_list[pool_count].pDescriptorTypes = mutable_descriptor_types[pool_count];
mutable_info.sType = VK_STRUCTURE_TYPE_MUTABLE_DESCRIPTOR_TYPE_CREATE_INFO_VALVE;
mutable_info.pNext = NULL;
mutable_info.pMutableDescriptorTypeLists = mutable_descriptor_list;
mutable_info.mutableDescriptorTypeListCount = pool_count + 1;
vk_pool_info.pNext = &mutable_info;
}
else if (set_info->vk_descriptor_type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
ssbo_pool = vk_pool_size;
pool_count++;
}
ssbo_count += vkd3d_popcount(set_info->flags & VKD3D_BINDLESS_SET_EXTRA_MASK);

View File

@ -3645,27 +3645,33 @@ static uint32_t d3d12_max_host_descriptor_count_from_heap_type(struct d3d12_devi
}
}
static uint32_t vkd3d_bindless_build_mutable_type_list(VkDescriptorType *list, uint32_t flags)
uint32_t vkd3d_bindless_build_mutable_type_list(VkDescriptorType *list, uint32_t flags,
uint32_t device_flags)
{
uint32_t count = 0;
if (flags & VKD3D_BINDLESS_CBV)
if (flags & VKD3D_BINDLESS_SET_BUFFER)
{
list[count++] = flags & VKD3D_BINDLESS_CBV_AS_SSBO ?
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER : VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
if (flags & VKD3D_BINDLESS_SET_CBV)
{
list[count++] = device_flags & VKD3D_BINDLESS_CBV_AS_SSBO ?
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER : VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
}
/* SSBO for untyped UAV is deliberately left out since it has its own descriptor set. */
if (flags & VKD3D_BINDLESS_SET_UAV)
list[count++] = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
if (flags & VKD3D_BINDLESS_SET_SRV)
list[count++] = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
}
/* SSBO for untyped UAV is deliberately left out since it has its own descriptor set. */
if (flags & VKD3D_BINDLESS_UAV)
if (flags & VKD3D_BINDLESS_SET_IMAGE)
{
list[count++] = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
list[count++] = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
}
if (flags & VKD3D_BINDLESS_SRV)
{
list[count++] = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
list[count++] = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
if (flags & VKD3D_BINDLESS_SET_UAV)
list[count++] = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
if (flags & VKD3D_BINDLESS_SET_SRV)
list[count++] = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
}
return count;
@ -3745,7 +3751,8 @@ static HRESULT vkd3d_bindless_state_add_binding(struct vkd3d_bindless_state *bin
memset(mutable_descriptor_list, 0, sizeof(mutable_descriptor_list));
mutable_descriptor_list[set_info->binding_index].descriptorTypeCount =
vkd3d_bindless_build_mutable_type_list(mutable_descriptor_types, device->bindless_state.flags);
vkd3d_bindless_build_mutable_type_list(mutable_descriptor_types, flags,
device->bindless_state.flags);
mutable_descriptor_list[set_info->binding_index].pDescriptorTypes = mutable_descriptor_types;
}
@ -3770,7 +3777,7 @@ static HRESULT vkd3d_bindless_state_add_binding(struct vkd3d_bindless_state *bin
return hresult_from_vk_result(vr);
}
static bool vkd3d_bindless_supports_mutable_type(struct d3d12_device *device, uint32_t flags)
static bool vkd3d_bindless_supports_mutable_type(struct d3d12_device *device, uint32_t device_flags)
{
VkDescriptorType descriptor_types[VKD3D_MAX_MUTABLE_DESCRIPTOR_TYPES];
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
@ -3795,7 +3802,10 @@ static bool vkd3d_bindless_supports_mutable_type(struct d3d12_device *device, ui
mutable_info.pMutableDescriptorTypeLists = &mutable_list;
mutable_info.mutableDescriptorTypeListCount = 1;
mutable_list.descriptorTypeCount = vkd3d_bindless_build_mutable_type_list(descriptor_types, flags);
mutable_list.descriptorTypeCount = vkd3d_bindless_build_mutable_type_list(descriptor_types,
VKD3D_BINDLESS_SET_BUFFER | VKD3D_BINDLESS_SET_IMAGE |
VKD3D_BINDLESS_SET_CBV | VKD3D_BINDLESS_SET_UAV | VKD3D_BINDLESS_SET_SRV,
device_flags);
mutable_list.pDescriptorTypes = descriptor_types;
binding.binding = 0;
@ -3938,12 +3948,34 @@ HRESULT vkd3d_bindless_state_init(struct vkd3d_bindless_state *bindless_state,
/* If we can, prefer to use one universal descriptor type which works for any descriptor.
* The exception is SSBOs since we need to workaround buggy applications which create typed buffers,
* but assume they can be read as untyped buffers. */
if (FAILED(hr = vkd3d_bindless_state_add_binding(bindless_state, device,
VKD3D_BINDLESS_SET_CBV | VKD3D_BINDLESS_SET_UAV | VKD3D_BINDLESS_SET_SRV |
VKD3D_BINDLESS_SET_BUFFER | VKD3D_BINDLESS_SET_IMAGE |
VKD3D_BINDLESS_SET_MUTABLE | extra_bindings,
VK_DESCRIPTOR_TYPE_MUTABLE_VALVE)))
goto fail;
if (device->vkd3d_instance->config_flags & VKD3D_CONFIG_SPLIT_MUTABLE_TYPES)
{
INFO("Splitting mutable types.\n");
/* For testing purposes, attempt to split descriptors into images and buffers
* for theoretically better packing in some cases. */
if (FAILED(hr = vkd3d_bindless_state_add_binding(bindless_state, device,
VKD3D_BINDLESS_SET_CBV | VKD3D_BINDLESS_SET_UAV | VKD3D_BINDLESS_SET_SRV |
VKD3D_BINDLESS_SET_BUFFER |
VKD3D_BINDLESS_SET_MUTABLE | extra_bindings,
VK_DESCRIPTOR_TYPE_MUTABLE_VALVE)))
goto fail;
if (FAILED(hr = vkd3d_bindless_state_add_binding(bindless_state, device,
VKD3D_BINDLESS_SET_UAV | VKD3D_BINDLESS_SET_SRV |
VKD3D_BINDLESS_SET_IMAGE | VKD3D_BINDLESS_SET_MUTABLE,
VK_DESCRIPTOR_TYPE_MUTABLE_VALVE)))
goto fail;
}
else
{
INFO("Single mutable descriptor type.\n");
if (FAILED(hr = vkd3d_bindless_state_add_binding(bindless_state, device,
VKD3D_BINDLESS_SET_CBV | VKD3D_BINDLESS_SET_UAV | VKD3D_BINDLESS_SET_SRV |
VKD3D_BINDLESS_SET_BUFFER | VKD3D_BINDLESS_SET_IMAGE |
VKD3D_BINDLESS_SET_MUTABLE | extra_bindings,
VK_DESCRIPTOR_TYPE_MUTABLE_VALVE)))
goto fail;
}
}
else
{

View File

@ -165,6 +165,7 @@ enum vkd3d_config_flags
{
VKD3D_CONFIG_FLAG_VULKAN_DEBUG = 0x00000001,
VKD3D_CONFIG_FLAG_SKIP_APPLICATION_WORKAROUNDS = 0x00000002,
VKD3D_CONFIG_SPLIT_MUTABLE_TYPES = 0x00000004,
};
struct vkd3d_instance
@ -1703,6 +1704,8 @@ struct vkd3d_descriptor_binding vkd3d_bindless_state_binding_from_info_index(
const struct vkd3d_bindless_state *bindless_state, uint32_t index);
uint32_t vkd3d_bindless_state_find_set_info_index(const struct vkd3d_bindless_state *bindless_state,
uint32_t flags);
uint32_t vkd3d_bindless_build_mutable_type_list(VkDescriptorType *list, uint32_t flags,
uint32_t device_flags);
static inline VkDescriptorType vkd3d_bindless_state_get_cbv_descriptor_type(const struct vkd3d_bindless_state *bindless_state)
{