diff --git a/include/vkd3d.h b/include/vkd3d.h index 4eebff43..db573125 100644 --- a/include/vkd3d.h +++ b/include/vkd3d.h @@ -89,6 +89,7 @@ extern "C" { #define VKD3D_CONFIG_FLAG_SHADER_CACHE_SYNC (1ull << 27) #define VKD3D_CONFIG_FLAG_FORCE_RAW_VA_CBV (1ull << 28) #define VKD3D_CONFIG_FLAG_ZERO_MEMORY_WORKAROUNDS_COMMITTED_BUFFER_UAV (1ull << 29) +#define VKD3D_CONFIG_FLAG_FORCE_ROBUST_PHYSICAL_CBV (1ull << 30) typedef HRESULT (*PFN_vkd3d_signal_event)(HANDLE event); diff --git a/include/vkd3d_shader.h b/include/vkd3d_shader.h index 7f7e893c..0ac0195a 100644 --- a/include/vkd3d_shader.h +++ b/include/vkd3d_shader.h @@ -333,6 +333,9 @@ enum vkd3d_shader_quirk /* For Position builtins in Output storage class, emit Invariant decoration. * Normally, games have to emit Precise math for position, but if they forget ... */ VKD3D_SHADER_QUIRK_INVARIANT_POSITION = (1 << 2), + + /* For raw VA CBVs, range check every access. */ + VKD3D_SHADER_QUIRK_FORCE_ROBUST_PHYSICAL_CBV = (1 << 3), }; struct vkd3d_shader_quirk_hash diff --git a/libs/vkd3d-shader/dxil.c b/libs/vkd3d-shader/dxil.c index 0a3ed2cd..96f426d1 100644 --- a/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d-shader/dxil.c @@ -846,6 +846,18 @@ int vkd3d_shader_compile_dxil(const struct vkd3d_shader_code *dxbc, } } + if (quirks & VKD3D_SHADER_QUIRK_FORCE_ROBUST_PHYSICAL_CBV) + { + const dxil_spv_option_robust_physical_cbv_load robust_cbv = + { { DXIL_SPV_OPTION_ROBUST_PHYSICAL_CBV_LOAD }, DXIL_SPV_TRUE }; + if (dxil_spv_converter_add_option(converter, &robust_cbv.base) != DXIL_SPV_SUCCESS) + { + ERR("dxil-spirv does not support ROBUST_PHYSICAL_CBV_LOAD.\n"); + ret = VKD3D_ERROR_NOT_IMPLEMENTED; + goto end; + } + } + remap_userdata.shader_interface_info = shader_interface_info; remap_userdata.shader_interface_local_info = NULL; remap_userdata.num_root_descriptors = num_root_descriptors; @@ -925,6 +937,7 @@ int vkd3d_shader_compile_dxil_export(const struct vkd3d_shader_code *dxil, vkd3d_shader_hash_t hash; char *demangled_export; int ret = VKD3D_OK; + uint32_t quirks; void *code; dxil_spv_set_thread_log_callback(vkd3d_dxil_log_callback, NULL); @@ -943,6 +956,8 @@ int vkd3d_shader_compile_dxil_export(const struct vkd3d_shader_code *dxil, } } + quirks = vkd3d_shader_compile_arguments_select_quirks(compiler_args, hash); + dxil_spv_begin_thread_allocator_context(); vkd3d_shader_dump_shader(hash, dxil, "lib.dxil"); @@ -1213,6 +1228,18 @@ int vkd3d_shader_compile_dxil_export(const struct vkd3d_shader_code *dxil, WARN("dxil-spirv does not support SHADER_SOURCE_FILE.\n"); } + if (quirks & VKD3D_SHADER_QUIRK_FORCE_ROBUST_PHYSICAL_CBV) + { + const dxil_spv_option_robust_physical_cbv_load robust_cbv = + { { DXIL_SPV_OPTION_ROBUST_PHYSICAL_CBV_LOAD }, DXIL_SPV_TRUE }; + if (dxil_spv_converter_add_option(converter, &robust_cbv.base) != DXIL_SPV_SUCCESS) + { + ERR("dxil-spirv does not support ROBUST_PHYSICAL_CBV_LOAD.\n"); + ret = VKD3D_ERROR_NOT_IMPLEMENTED; + goto end; + } + } + if (compiler_args) { for (i = 0; i < compiler_args->target_extension_count; i++) diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c index 4a994f63..cbbf8ac3 100644 --- a/libs/vkd3d/device.c +++ b/libs/vkd3d/device.c @@ -617,6 +617,7 @@ static void vkd3d_instance_apply_global_shader_quirks(void) static const struct override overrides[] = { { VKD3D_CONFIG_FLAG_FORCE_NO_INVARIANT_POSITION, VKD3D_SHADER_QUIRK_INVARIANT_POSITION, true }, + { VKD3D_CONFIG_FLAG_FORCE_ROBUST_PHYSICAL_CBV, VKD3D_SHADER_QUIRK_FORCE_ROBUST_PHYSICAL_CBV, false }, }; uint64_t eq_test; unsigned int i; @@ -660,6 +661,7 @@ static const struct vkd3d_debug_option vkd3d_config_options[] = {"pipeline_library_app_cache", VKD3D_CONFIG_FLAG_PIPELINE_LIBRARY_APP_CACHE_ONLY}, {"shader_cache_sync", VKD3D_CONFIG_FLAG_SHADER_CACHE_SYNC}, {"force_raw_va_cbv", VKD3D_CONFIG_FLAG_FORCE_RAW_VA_CBV}, + {"force_robust_physical_cbv", VKD3D_CONFIG_FLAG_FORCE_ROBUST_PHYSICAL_CBV}, }; static void vkd3d_config_flags_init_once(void)