vkd3d: Add workaround to ignore mismatch driver/device in PSO library.

Elden Ring does not detect the proper error code and create a new
pipeline library. Instead, create a fresh new library, which works
around the issue.

The game has a pattern of LoadPipeline -> if fail -> CreatePSO ->
StorePipeline. Sometimes, in the same process it will LoadLibrary from
its own cache (could explain some stutters),
so it's very useful to have this either way.

Signed-off-by: Hans-Kristian Arntzen <post@arntzen-software.no>
This commit is contained in:
Hans-Kristian Arntzen 2022-02-25 14:29:04 +01:00
parent a8229390f9
commit 9817c52d24
3 changed files with 16 additions and 2 deletions

View File

@ -85,6 +85,7 @@ enum vkd3d_config_flags
VKD3D_CONFIG_FLAG_MUTABLE_SINGLE_SET = 0x00400000,
VKD3D_CONFIG_FLAG_MEMORY_ALLOCATOR_SKIP_CLEAR = 0x00800000,
VKD3D_CONFIG_FLAG_RECYCLE_COMMAND_POOLS = 0x01000000,
VKD3D_CONFIG_FLAG_PIPELINE_LIBRARY_IGNORE_MISMATCH_DRIVER = 0x02000000,
};
typedef HRESULT (*PFN_vkd3d_signal_event)(HANDLE event);

View File

@ -1696,7 +1696,19 @@ static HRESULT d3d12_pipeline_library_init(struct d3d12_pipeline_library *pipeli
if (blob_length)
{
if (FAILED(hr = d3d12_pipeline_library_read_blob(pipeline_library, device, blob, blob_length)))
hr = d3d12_pipeline_library_read_blob(pipeline_library, device, blob, blob_length);
if ((vkd3d_config_flags & VKD3D_CONFIG_FLAG_PIPELINE_LIBRARY_IGNORE_MISMATCH_DRIVER) &&
(hr == D3D12_ERROR_ADAPTER_NOT_FOUND || hr == D3D12_ERROR_DRIVER_VERSION_MISMATCH))
{
/* Sigh ... Otherwise, certain games might never create a replacement
* pipeline library and never serialize out pipeline libraries. */
INFO("Application provided a pipeline library which does not match with what we expect.\n"
"Creating an empty pipeline library instead as a workaround.\n");
hr = S_OK;
}
if (FAILED(hr))
goto cleanup_hash_map;
}
else if (vkd3d_config_flags & VKD3D_CONFIG_FLAG_PIPELINE_LIBRARY_LOG)

View File

@ -494,7 +494,7 @@ static const struct vkd3d_instance_application_meta application_override[] = {
* Game is really churny on committed memory allocations, and does not use NOT_ZEROED. Clearing works causes bubbles.
* It seems to work just fine however to skip the clears. */
{ VKD3D_STRING_COMPARE_EXACT, "eldenring.exe",
VKD3D_CONFIG_FLAG_MEMORY_ALLOCATOR_SKIP_CLEAR, 0 },
VKD3D_CONFIG_FLAG_MEMORY_ALLOCATOR_SKIP_CLEAR | VKD3D_CONFIG_FLAG_PIPELINE_LIBRARY_IGNORE_MISMATCH_DRIVER, 0 },
{ VKD3D_STRING_COMPARE_NEVER, NULL, 0, 0 }
};
@ -617,6 +617,7 @@ static const struct vkd3d_debug_option vkd3d_config_options[] =
{"mutable_single_set", VKD3D_CONFIG_FLAG_MUTABLE_SINGLE_SET},
{"memory_allocator_skip_clear", VKD3D_CONFIG_FLAG_MEMORY_ALLOCATOR_SKIP_CLEAR},
{"recycle_command_pools", VKD3D_CONFIG_FLAG_RECYCLE_COMMAND_POOLS},
{"pipeline_library_ignore_mismatch_driver", VKD3D_CONFIG_FLAG_PIPELINE_LIBRARY_IGNORE_MISMATCH_DRIVER},
};
static void vkd3d_config_flags_init_once(void)