vkd3d: Add VKD3D_CONFIG option for command pool recycling.
Normal behaving apps should not benefit from any of this. Signed-off-by: Hans-Kristian Arntzen <post@arntzen-software.no>
This commit is contained in:
parent
54fbadcc94
commit
c19eaac376
|
@ -84,6 +84,7 @@ enum vkd3d_config_flags
|
||||||
VKD3D_CONFIG_FLAG_PIPELINE_LIBRARY_IGNORE_SPIRV = 0x00200000,
|
VKD3D_CONFIG_FLAG_PIPELINE_LIBRARY_IGNORE_SPIRV = 0x00200000,
|
||||||
VKD3D_CONFIG_FLAG_MUTABLE_SINGLE_SET = 0x00400000,
|
VKD3D_CONFIG_FLAG_MUTABLE_SINGLE_SET = 0x00400000,
|
||||||
VKD3D_CONFIG_FLAG_MEMORY_ALLOCATOR_SKIP_CLEAR = 0x00800000,
|
VKD3D_CONFIG_FLAG_MEMORY_ALLOCATOR_SKIP_CLEAR = 0x00800000,
|
||||||
|
VKD3D_CONFIG_FLAG_RECYCLE_COMMAND_POOLS = 0x01000000,
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef HRESULT (*PFN_vkd3d_signal_event)(HANDLE event);
|
typedef HRESULT (*PFN_vkd3d_signal_event)(HANDLE event);
|
||||||
|
|
|
@ -1587,28 +1587,33 @@ static ULONG STDMETHODCALLTYPE d3d12_command_allocator_Release(ID3D12CommandAllo
|
||||||
vkd3d_free(allocator->framebuffers);
|
vkd3d_free(allocator->framebuffers);
|
||||||
vkd3d_free(allocator->passes);
|
vkd3d_free(allocator->passes);
|
||||||
|
|
||||||
if (pthread_mutex_lock(&device->mutex) == 0)
|
if (vkd3d_config_flags & VKD3D_CONFIG_FLAG_RECYCLE_COMMAND_POOLS)
|
||||||
{
|
{
|
||||||
if (device->cached_command_allocator_count < ARRAY_SIZE(device->cached_command_allocators))
|
/* Don't want to do this unless we have to, so hide it behind a config.
|
||||||
|
* For well-behaving apps, we'll just bloat memory. */
|
||||||
|
if (pthread_mutex_lock(&device->mutex) == 0)
|
||||||
{
|
{
|
||||||
/* Recycle the pool. Some games spam free/allocate pools,
|
if (device->cached_command_allocator_count < ARRAY_SIZE(device->cached_command_allocators))
|
||||||
* even if it completely goes against the point of the API. */
|
{
|
||||||
|
/* Recycle the pool. Some games spam free/allocate pools,
|
||||||
|
* even if it completely goes against the point of the API. */
|
||||||
|
|
||||||
/* Have to free command buffers here if we're going to recycle,
|
/* Have to free command buffers here if we're going to recycle,
|
||||||
* otherwise DestroyCommandPool takes care of it. */
|
* otherwise DestroyCommandPool takes care of it. */
|
||||||
VK_CALL(vkFreeCommandBuffers(device->vk_device, allocator->vk_command_pool,
|
VK_CALL(vkFreeCommandBuffers(device->vk_device, allocator->vk_command_pool,
|
||||||
allocator->command_buffer_count, allocator->command_buffers));
|
allocator->command_buffer_count, allocator->command_buffers));
|
||||||
VK_CALL(vkResetCommandPool(device->vk_device, allocator->vk_command_pool, 0));
|
VK_CALL(vkResetCommandPool(device->vk_device, allocator->vk_command_pool, 0));
|
||||||
|
|
||||||
device->cached_command_allocators[device->cached_command_allocator_count].vk_command_pool =
|
device->cached_command_allocators[device->cached_command_allocator_count].vk_command_pool =
|
||||||
allocator->vk_command_pool;
|
allocator->vk_command_pool;
|
||||||
device->cached_command_allocators[device->cached_command_allocator_count].vk_family_index =
|
device->cached_command_allocators[device->cached_command_allocator_count].vk_family_index =
|
||||||
allocator->vk_family_index;
|
allocator->vk_family_index;
|
||||||
device->cached_command_allocator_count++;
|
device->cached_command_allocator_count++;
|
||||||
allocator->vk_command_pool = VK_NULL_HANDLE;
|
allocator->vk_command_pool = VK_NULL_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&device->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_unlock(&device->mutex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Command buffers are implicitly freed when destroying the pool. */
|
/* Command buffers are implicitly freed when destroying the pool. */
|
||||||
|
@ -1843,20 +1848,23 @@ static HRESULT d3d12_command_allocator_init(struct d3d12_command_allocator *allo
|
||||||
allocator->vk_command_pool = VK_NULL_HANDLE;
|
allocator->vk_command_pool = VK_NULL_HANDLE;
|
||||||
allocator->vk_family_index = queue_family->vk_family_index;
|
allocator->vk_family_index = queue_family->vk_family_index;
|
||||||
|
|
||||||
/* Try to recycle command allocators. Some games spam free/allocate pools. */
|
if (vkd3d_config_flags & VKD3D_CONFIG_FLAG_RECYCLE_COMMAND_POOLS)
|
||||||
if (pthread_mutex_lock(&device->mutex) == 0)
|
|
||||||
{
|
{
|
||||||
for (i = 0; i < device->cached_command_allocator_count; i++)
|
/* Try to recycle command allocators. Some games spam free/allocate pools. */
|
||||||
|
if (pthread_mutex_lock(&device->mutex) == 0)
|
||||||
{
|
{
|
||||||
if (device->cached_command_allocators[i].vk_family_index == queue_family->vk_family_index)
|
for (i = 0; i < device->cached_command_allocator_count; i++)
|
||||||
{
|
{
|
||||||
allocator->vk_command_pool = device->cached_command_allocators[i].vk_command_pool;
|
if (device->cached_command_allocators[i].vk_family_index == queue_family->vk_family_index)
|
||||||
device->cached_command_allocators[i] =
|
{
|
||||||
device->cached_command_allocators[--device->cached_command_allocator_count];
|
allocator->vk_command_pool = device->cached_command_allocators[i].vk_command_pool;
|
||||||
break;
|
device->cached_command_allocators[i] =
|
||||||
|
device->cached_command_allocators[--device->cached_command_allocator_count];
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
pthread_mutex_unlock(&device->mutex);
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&device->mutex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (allocator->vk_command_pool == VK_NULL_HANDLE)
|
if (allocator->vk_command_pool == VK_NULL_HANDLE)
|
||||||
|
|
|
@ -611,6 +611,7 @@ static const struct vkd3d_debug_option vkd3d_config_options[] =
|
||||||
{"pipeline_library_ignore_spirv", VKD3D_CONFIG_FLAG_PIPELINE_LIBRARY_IGNORE_SPIRV},
|
{"pipeline_library_ignore_spirv", VKD3D_CONFIG_FLAG_PIPELINE_LIBRARY_IGNORE_SPIRV},
|
||||||
{"mutable_single_set", VKD3D_CONFIG_FLAG_MUTABLE_SINGLE_SET},
|
{"mutable_single_set", VKD3D_CONFIG_FLAG_MUTABLE_SINGLE_SET},
|
||||||
{"memory_allocator_skip_clear", VKD3D_CONFIG_FLAG_MEMORY_ALLOCATOR_SKIP_CLEAR},
|
{"memory_allocator_skip_clear", VKD3D_CONFIG_FLAG_MEMORY_ALLOCATOR_SKIP_CLEAR},
|
||||||
|
{"recycle_command_pools", VKD3D_CONFIG_FLAG_RECYCLE_COMMAND_POOLS},
|
||||||
};
|
};
|
||||||
|
|
||||||
static void vkd3d_config_flags_init_once(void)
|
static void vkd3d_config_flags_init_once(void)
|
||||||
|
|
Loading…
Reference in New Issue