diff --git a/include/vkd3d.h b/include/vkd3d.h index 175a278c3f..a7e2ce40ea 100644 --- a/include/vkd3d.h +++ b/include/vkd3d.h @@ -111,6 +111,7 @@ extern "C" { #define VKD3D_CONFIG_FLAG_INSTRUCTION_QA_CHECKS (1ull << 53) #define VKD3D_CONFIG_FLAG_TRANSFER_QUEUE (1ull << 54) #define VKD3D_CONFIG_FLAG_NO_GPU_UPLOAD_HEAP (1ull << 55) +#define VKD3D_CONFIG_FLAG_NO_SUBALLOCATION (1ull << 56) struct vkd3d_instance; diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c index 2f68fecb41..5f90e96195 100644 --- a/libs/vkd3d/device.c +++ b/libs/vkd3d/device.c @@ -982,6 +982,7 @@ static const struct vkd3d_debug_option vkd3d_config_options[] = {"instruction_qa_checks", VKD3D_CONFIG_FLAG_INSTRUCTION_QA_CHECKS}, {"transfer_queue", VKD3D_CONFIG_FLAG_TRANSFER_QUEUE}, {"no_gpu_upload_heap", VKD3D_CONFIG_FLAG_NO_GPU_UPLOAD_HEAP}, + {"no_suballocation", VKD3D_CONFIG_FLAG_NO_SUBALLOCATION}, }; static void vkd3d_config_flags_init_once(void) diff --git a/libs/vkd3d/memory.c b/libs/vkd3d/memory.c index 1d62fc2fac..52166023a7 100644 --- a/libs/vkd3d/memory.c +++ b/libs/vkd3d/memory.c @@ -1839,6 +1839,9 @@ bool vkd3d_allocate_image_memory_prefers_dedicated(struct d3d12_device *device, static bool vkd3d_memory_info_allow_suballocate(struct d3d12_device *device, const struct vkd3d_allocate_memory_info *info) { + if (vkd3d_config_flags & VKD3D_CONFIG_FLAG_NO_SUBALLOCATION) + return true; + /* pNext implies dedicated allocation or similar. Host pointer implies external memory import. */ if (info->pNext || info->host_ptr) return false; @@ -1912,6 +1915,19 @@ HRESULT vkd3d_allocate_memory(struct d3d12_device *device, struct vkd3d_memory_a info = &tmp_info; } + /* To avoid a potential collapse in CPU performance, force larger allocations + * when using NO_SUBALLOCATION. */ + if ((vkd3d_config_flags & VKD3D_CONFIG_FLAG_NO_SUBALLOCATION) && + !info->host_ptr && + (info->flags & VKD3D_ALLOCATION_FLAG_GLOBAL_BUFFER) && + info->memory_requirements.size < VKD3D_VA_BLOCK_SIZE) + { + if (&tmp_info != info) + tmp_info = *info; + info = &tmp_info; + tmp_info.memory_requirements.size = max(VKD3D_VA_BLOCK_SIZE, tmp_info.memory_requirements.size); + } + if (suballocate) hr = vkd3d_suballocate_memory(device, allocator, info, allocation); else