diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c index d1381ef8..9720a678 100644 --- a/libs/vkd3d/device.c +++ b/libs/vkd3d/device.c @@ -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) diff --git a/libs/vkd3d/resource.c b/libs/vkd3d/resource.c index f2dbf305..90bceec7 100644 --- a/libs/vkd3d/resource.c +++ b/libs/vkd3d/resource.c @@ -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); diff --git a/libs/vkd3d/state.c b/libs/vkd3d/state.c index a232ff6c..c3785ebe 100644 --- a/libs/vkd3d/state.c +++ b/libs/vkd3d/state.c @@ -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 { diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index 2adc4be1..e959c8d0 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -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) {