diff --git a/src/common/settings.h b/src/common/settings.h index b523fb673b..39bf98765b 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -514,11 +514,7 @@ struct Values { Category::RendererHacks}; SwitchableSetting dyna_state{linkage, -#if defined (_WIN32) - ExtendedDynamicState::EDS3, -#elif defined (__FreeBSD__) - ExtendedDynamicState::EDS3, -#elif defined (ANDROID) +#if defined (ANDROID) ExtendedDynamicState::Disabled, #elif defined (__APPLE__) ExtendedDynamicState::Disabled, diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index 3fc56d35d6..08265ffcf1 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -410,33 +410,22 @@ void Device::RemoveExtensionFeatureIfUnsuitable(bool is_suitable, Feature& featu } } -Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR surface, - const vk::InstanceDispatch& dld_) - : instance{instance_}, dld{dld_}, physical{physical_}, - format_properties(GetFormatProperties(physical)) { - // Get suitability and device properties. - const bool is_suitable = GetSuitability(surface != nullptr); - +Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR surface, const vk::InstanceDispatch& dld_) + : instance{instance_}, dld{dld_}, physical{physical_}, format_properties(GetFormatProperties(physical)) { const VkDriverId driver_id = properties.driver.driverID; - const auto device_id = properties.properties.deviceID; - - const bool is_radv = driver_id == VK_DRIVER_ID_MESA_RADV; - const bool is_amd_driver = - driver_id == VK_DRIVER_ID_AMD_PROPRIETARY || driver_id == VK_DRIVER_ID_AMD_OPEN_SOURCE; - const bool is_amd = is_amd_driver || is_radv; - + const bool is_suitable = GetSuitability(surface != nullptr); + const bool is_amd_driver = driver_id == VK_DRIVER_ID_AMD_PROPRIETARY || driver_id == VK_DRIVER_ID_AMD_OPEN_SOURCE; const bool is_intel_windows = driver_id == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS; const bool is_intel_anv = driver_id == VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA; - const bool is_nvidia = driver_id == VK_DRIVER_ID_NVIDIA_PROPRIETARY; const bool is_mvk = driver_id == VK_DRIVER_ID_MOLTENVK; const bool is_qualcomm = driver_id == VK_DRIVER_ID_QUALCOMM_PROPRIETARY; const bool is_turnip = driver_id == VK_DRIVER_ID_MESA_TURNIP; - const bool is_s8gen2 = device_id == 0x43050a01; - //const bool is_arm = driver_id == VK_DRIVER_ID_ARM_PROPRIETARY; + const bool is_arm = driver_id == VK_DRIVER_ID_ARM_PROPRIETARY; - if (!is_suitable) + if (!is_suitable) { LOG_WARNING(Render_Vulkan, "Unsuitable driver - continuing anyways"); + } if (is_nvidia) { nvidia_arch = GetNvidiaArchitecture(physical, supported_extensions); @@ -479,19 +468,15 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR is_blit_depth24_stencil8_supported = TestDepthStencilBlits(VK_FORMAT_D24_UNORM_S8_UINT); is_blit_depth32_stencil8_supported = TestDepthStencilBlits(VK_FORMAT_D32_SFLOAT_S8_UINT); is_optimal_astc_supported = ComputeIsOptimalAstcSupported(); - is_warp_potentially_bigger = !extensions.subgroup_size_control || - properties.subgroup_size_control.maxSubgroupSize > GuestWarpSize; + is_warp_potentially_bigger = !extensions.subgroup_size_control || properties.subgroup_size_control.maxSubgroupSize > GuestWarpSize; is_integrated = properties.properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU; is_virtual = properties.properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU; - is_non_gpu = properties.properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_OTHER || - properties.properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_CPU; + is_non_gpu = properties.properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_OTHER || properties.properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_CPU; const bool is_intel_igpu = is_integrated && (is_intel_anv || is_intel_windows); - supports_d24_depth = - IsFormatSupported(VK_FORMAT_D24_UNORM_S8_UINT, - VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT, FormatType::Optimal); + supports_d24_depth = IsFormatSupported(VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT, FormatType::Optimal); supports_conditional_barriers = !(is_intel_anv || is_intel_windows); @@ -499,11 +484,9 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR CollectToolingInfo(); if (is_qualcomm) { - LOG_WARNING(Render_Vulkan, - "Disabling shader float controls and 64-bit integer features on Qualcomm proprietary drivers"); + LOG_WARNING(Render_Vulkan, "Disabling shader float controls and 64-bit integer features on Qualcomm proprietary drivers"); RemoveExtension(extensions.shader_float_controls, VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME); - RemoveExtensionFeature(extensions.shader_atomic_int64, features.shader_atomic_int64, - VK_KHR_SHADER_ATOMIC_INT64_EXTENSION_NAME); + RemoveExtensionFeature(extensions.shader_atomic_int64, features.shader_atomic_int64, VK_KHR_SHADER_ATOMIC_INT64_EXTENSION_NAME); features.shader_atomic_int64.shaderBufferInt64Atomics = false; features.shader_atomic_int64.shaderSharedInt64Atomics = false; features.features.shaderInt64 = false; @@ -519,181 +502,85 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR bool should_patch_bcn = api_level >= 28; const bool bcn_debug_override = Settings::values.patch_old_qcom_drivers.GetValue(); if (bcn_debug_override != should_patch_bcn) { - LOG_WARNING(Render_Vulkan, - "BCn patch debug override active: {} (auto-detected: {})", - bcn_debug_override, should_patch_bcn); + LOG_WARNING(Render_Vulkan, "BCn patch debug override active: {} (auto-detected: {})", bcn_debug_override, should_patch_bcn); should_patch_bcn = bcn_debug_override; } if (patch_status == ADRENOTOOLS_BCN_PATCH) { if (should_patch_bcn) { - LOG_INFO(Render_Vulkan, - "Patching Adreno driver to support BCn texture formats " - "(Android API {}, Driver {}.{})", api_level, major, minor); - if (adrenotools_patch_bcn( - reinterpret_cast(dld.vkGetPhysicalDeviceFormatProperties))) { + LOG_INFO(Render_Vulkan, "Patching Adreno driver to support BCn texture formats (Android API {}, Driver {}.{})", api_level, major, minor); + if (adrenotools_patch_bcn(reinterpret_cast(dld.vkGetPhysicalDeviceFormatProperties))) { OverrideBcnFormats(format_properties); } else { LOG_ERROR(Render_Vulkan, "BCn patch failed! Driver code may now crash"); } } else { - LOG_WARNING(Render_Vulkan, - "BCn texture patching skipped for stability (Android API {} < 28). " - "Driver version {}.{} would support patching, but may crash on older Android.", - api_level, major, minor); + LOG_WARNING(Render_Vulkan, "BCn texture patching skipped for stability (Android API {} < 28). Driver version {}.{} would support patching, but may crash on older Android.", api_level, major, minor); } } else if (patch_status == ADRENOTOOLS_BCN_BLOB) { LOG_INFO(Render_Vulkan, "Adreno driver supports BCn textures natively (no patch needed)"); } else { - LOG_INFO(Render_Vulkan, - "Adreno driver does not support BCn texture patching (Android API {}, Driver {}.{})", - api_level, major, minor); + LOG_INFO(Render_Vulkan, "Adreno driver does not support BCn texture patching (Android API {}, Driver {}.{})", api_level, major, minor); } #endif - } - - if (is_nvidia) { - const u32 nv_major_version = (properties.properties.driverVersion >> 22) & 0x3ff; - const auto arch = GetNvidiaArch(); - if (arch >= NvidiaArchitecture::Arch_AmpereOrNewer) { - LOG_WARNING(Render_Vulkan, "Ampere and newer have broken float16 math"); - features.shader_float16_int8.shaderFloat16 = false; - } - - if (nv_major_version >= 510) { - LOG_WARNING(Render_Vulkan, "NVIDIA Drivers >= 510 do not support MSAA image blits"); - cant_blit_msaa = true; - } - } - - if (extensions.extended_dynamic_state3 && is_radv) { - LOG_WARNING(Render_Vulkan, "RADV has broken extendedDynamicState3ColorBlendEquation"); - features.extended_dynamic_state3.extendedDynamicState3ColorBlendEnable = false; - features.extended_dynamic_state3.extendedDynamicState3ColorBlendEquation = false; - dynamic_state3_blending = false; - - const u32 version = (properties.properties.driverVersion << 3) >> 3; - if (version < VK_MAKE_API_VERSION(0, 23, 1, 0)) { - LOG_WARNING(Render_Vulkan, - "RADV versions older than 23.1.0 have broken depth clamp dynamic state"); - features.extended_dynamic_state3.extendedDynamicState3DepthClampEnable = false; - dynamic_state3_enables = false; - } - } - - if (extensions.extended_dynamic_state3 && (is_amd_driver || driver_id == VK_DRIVER_ID_SAMSUNG_PROPRIETARY)) { - // AMD and Samsung drivers have broken extendedDynamicState3ColorBlendEquation - LOG_WARNING(Render_Vulkan, - "AMD and Samsung drivers have broken extendedDynamicState3ColorBlendEquation"); - features.extended_dynamic_state3.extendedDynamicState3ColorBlendEnable = false; - features.extended_dynamic_state3.extendedDynamicState3ColorBlendEquation = false; - dynamic_state3_blending = false; - } - - sets_per_pool = 64; - if (is_amd_driver) { - // AMD drivers need a higher amount of Sets per Pool in certain circumstances like in XC2. - sets_per_pool = 96; - // Disable VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT on AMD GCN4 and lower as it is broken. - if (!features.shader_float16_int8.shaderFloat16) { - LOG_WARNING(Render_Vulkan, - "AMD GCN4 and earlier have broken VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT"); - has_broken_cube_compatibility = true; - } - } - if (is_qualcomm) { const u32 version = (properties.properties.driverVersion << 3) >> 3; if (version < VK_MAKE_API_VERSION(0, 255, 615, 512)) { has_broken_parallel_compiling = true; } } - if (extensions.sampler_filter_minmax && is_amd) { - // Disable ext_sampler_filter_minmax on AMD GCN4 and lower as it is broken. - if (!features.shader_float16_int8.shaderFloat16) { - LOG_WARNING(Render_Vulkan, - "AMD GCN4 and earlier have broken VK_EXT_sampler_filter_minmax"); - RemoveExtension(extensions.sampler_filter_minmax, - VK_EXT_SAMPLER_FILTER_MINMAX_EXTENSION_NAME); - } - } - - if (features.shader_float16_int8.shaderFloat16 && is_intel_windows) { - // Intel's compiler crashes when using fp16 on Astral Chain, disable it for the time being. - LOG_WARNING(Render_Vulkan, "Intel has broken float16 math"); - features.shader_float16_int8.shaderFloat16 = false; - } - - if (is_intel_windows) { - LOG_WARNING(Render_Vulkan, "Intel proprietary drivers do not support MSAA image blits"); - cant_blit_msaa = true; - } - - has_broken_compute = - CheckBrokenCompute(properties.driver.driverID, properties.properties.driverVersion) && - !Settings::values.enable_compute_pipelines.GetValue(); - if (is_intel_anv || (is_qualcomm && !is_s8gen2)) { - LOG_WARNING(Render_Vulkan, "Driver does not support native BGR format"); - must_emulate_bgr565 = true; - } - - if (is_mvk) { - LOG_WARNING(Render_Vulkan, - "MVK driver breaks when using more than 16 vertex attributes/bindings"); - properties.properties.limits.maxVertexInputAttributes = - (std::min)(properties.properties.limits.maxVertexInputAttributes, 16U); - properties.properties.limits.maxVertexInputBindings = - (std::min)(properties.properties.limits.maxVertexInputBindings, 16U); - } - if (is_turnip) { LOG_WARNING(Render_Vulkan, "Turnip requires higher-than-reported binding limits"); properties.properties.limits.maxVertexInputBindings = 32; } - if (!extensions.extended_dynamic_state && extensions.extended_dynamic_state2) { - LOG_INFO(Render_Vulkan, - "Removing extendedDynamicState2 due to missing extendedDynamicState"); - RemoveExtensionFeature(extensions.extended_dynamic_state2, features.extended_dynamic_state2, - VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME); + if (is_mvk) { + LOG_WARNING(Render_Vulkan, "MVK driver breaks when using more than 16 vertex attributes/bindings"); + properties.properties.limits.maxVertexInputAttributes = std::min(properties.properties.limits.maxVertexInputAttributes, 16U); + properties.properties.limits.maxVertexInputBindings = std::min(properties.properties.limits.maxVertexInputBindings, 16U); } - if (!extensions.extended_dynamic_state2 && extensions.extended_dynamic_state3) { - LOG_INFO(Render_Vulkan, - "Removing extendedDynamicState3 due to missing extendedDynamicState2"); - RemoveExtensionFeature(extensions.extended_dynamic_state3, features.extended_dynamic_state3, - VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME); - dynamic_state3_blending = false; - dynamic_state3_enables = false; - } + sets_per_pool = is_amd_driver ? 96 : 64; + + has_broken_compute = CheckBrokenCompute(properties.driver.driverID, properties.properties.driverVersion) && !Settings::values.enable_compute_pipelines.GetValue(); - const auto dyna_state = u32(Settings::values.dyna_state.GetValue()); + auto dyna_state = Settings::values.dyna_state.GetValue(); // Mesa Intel drivers on UHD 620 have broken EDS causing extreme flickering - unknown if it affects other iGPUs // ALSO affects ALL versions of UHD drivers on Windows 10+, seems to cause even worse issues like straight up crashing // So... Yeah, UHD drivers fucking suck -- maybe one day we can work past this, maybe; some driver hacking? // And then we can rest in peace by doing `< VK_MAKE_API_VERSION(26, 0, 0)` for our beloved mesa drivers... one day - if ((is_mvk || is_intel_igpu) && dyna_state != 0) { - LOG_WARNING(Render_Vulkan, "Driver has broken dynamic state, forcing to 0 to prevent graphical issues"); - Settings::values.dyna_state.SetValue(Settings::ExtendedDynamicState::Disabled); + if ((is_mvk || is_intel_igpu) && dyna_state != Settings::ExtendedDynamicState::Disabled) { + LOG_WARNING(Render_Vulkan, "Driver has broken EDS1+, forcing to Disabled to prevent graphical issues"); + dyna_state = Settings::ExtendedDynamicState::Disabled; } switch (dyna_state) { - case 0: + case Settings::ExtendedDynamicState::Disabled: RemoveExtensionFeature(extensions.extended_dynamic_state, features.extended_dynamic_state, VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME); + RemoveExtensionFeature(extensions.custom_border_color, features.custom_border_color, VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME); + RemoveExtension(extensions.push_descriptor, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME); [[fallthrough]]; - case 1: + case Settings::ExtendedDynamicState::EDS1: RemoveExtensionFeature(extensions.extended_dynamic_state2, features.extended_dynamic_state2, VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME); + has_broken_cube_compatibility = true; + must_emulate_scaled_formats = true; + cant_blit_msaa = true; [[fallthrough]]; - case 2: + case Settings::ExtendedDynamicState::EDS2: RemoveExtensionFeature(extensions.extended_dynamic_state3, features.extended_dynamic_state3, VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME); + RemoveExtension(extensions.sampler_filter_minmax, VK_EXT_SAMPLER_FILTER_MINMAX_EXTENSION_NAME); + features.shader_float16_int8.shaderFloat16 = false; + features.shader_float16_int8.shaderInt8 = false; dynamic_state3_blending = false; dynamic_state3_enables = false; + [[fallthrough]]; + case Settings::ExtendedDynamicState::EDS3: break; } - if (!Settings::values.vertex_input_dynamic_state.GetValue() || !extensions.extended_dynamic_state) { + if (!Settings::values.vertex_input_dynamic_state.GetValue() || !extensions.extended_dynamic_state2) { RemoveExtensionFeature(extensions.vertex_input_dynamic_state, features.vertex_input_dynamic_state, VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME); }