diff --git a/README.md b/README.md index 15545bcf..c4206630 100644 --- a/README.md +++ b/README.md @@ -144,6 +144,8 @@ commas or semicolons. - `VKD3D_CONFIG` - a list of options that change the behavior of vkd3d-proton. - `vk_debug` - enables Vulkan debug extensions and loads validation layer. + - `skip_application_workarounds` - Skips all application workarounds. + For debugging purposes. - `force_bindless_texel_buffer` - Forces use of texel buffers for bindless Raw/Structured buffers. For game workarounds only! - `VKD3D_DEBUG` - controls the debug level for log messages produced by diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c index b030fc10..ebe0137d 100644 --- a/libs/vkd3d/device.c +++ b/libs/vkd3d/device.c @@ -402,6 +402,7 @@ static const struct vkd3d_debug_option vkd3d_config_options[] = /* Never use VKD3D_BINDLESS_RAW_SSBO. * Works around buggy games which mix typed and raw buffer types. */ {"force_bindless_texel_buffer", VKD3D_CONFIG_FLAG_FORCE_BINDLESS_TEXEL_BUFFER}, + {"skip_application_workarounds", VKD3D_CONFIG_FLAG_SKIP_APPLICATION_WORKAROUNDS}, }; static uint64_t vkd3d_init_config_flags(void) @@ -418,6 +419,37 @@ static uint64_t vkd3d_init_config_flags(void) return config_flags; } +struct vkd3d_instance_application_meta +{ + const char *name; + uint64_t global_flags_add; + uint64_t global_flags_remove; +}; +static const struct vkd3d_instance_application_meta application_override[] = { + /* Application uses R32_UINT and misses raw buffer type. + * Fixes map rendering. */ + { "ds.exe", VKD3D_CONFIG_FLAG_FORCE_BINDLESS_TEXEL_BUFFER, 0 }, +}; + +static void vkd3d_instance_apply_application_workarounds(const char *app, uint64_t *flags) +{ + size_t i; + if (!app) + return; + + for (i = 0; i < ARRAY_SIZE(application_override); i++) + { + if (!strcmp(app, application_override[i].name)) + { + *flags |= application_override[i].global_flags_add; + *flags &= ~application_override[i].global_flags_remove; + INFO("Detected game %s, adding config 0x%"PRIx64", removing masks 0x%"PRIx64".\n", + app, application_override[i].global_flags_add, application_override[i].global_flags_remove); + break; + } + } +} + static HRESULT vkd3d_instance_init(struct vkd3d_instance *instance, const struct vkd3d_instance_create_info *create_info) { @@ -519,6 +551,9 @@ static HRESULT vkd3d_instance_init(struct vkd3d_instance *instance, application_info.pApplicationName = application_name; } + if (!(instance->config_flags & VKD3D_CONFIG_FLAG_SKIP_APPLICATION_WORKAROUNDS)) + vkd3d_instance_apply_application_workarounds(application_info.pApplicationName, &instance->config_flags); + TRACE("Application: %s.\n", debugstr_a(application_info.pApplicationName)); if (!(extensions = vkd3d_calloc(extension_count, sizeof(*extensions)))) diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index 6fac8395..2164de13 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -156,6 +156,7 @@ enum vkd3d_config_flags { VKD3D_CONFIG_FLAG_VULKAN_DEBUG = 0x00000001, VKD3D_CONFIG_FLAG_FORCE_BINDLESS_TEXEL_BUFFER = 0x00000002, + VKD3D_CONFIG_FLAG_SKIP_APPLICATION_WORKAROUNDS = 0x00000004, }; struct vkd3d_instance