Browse Source

EDS Experiment

pull/3274/head
MaranBr 4 weeks ago
parent
commit
e83974ec45
  1. 6
      src/common/settings.h
  2. 197
      src/video_core/vulkan_common/vulkan_device.cpp

6
src/common/settings.h

@ -514,11 +514,7 @@ struct Values {
Category::RendererHacks}; Category::RendererHacks};
SwitchableSetting<ExtendedDynamicState> dyna_state{linkage, SwitchableSetting<ExtendedDynamicState> dyna_state{linkage,
#if defined (_WIN32)
ExtendedDynamicState::EDS3,
#elif defined (__FreeBSD__)
ExtendedDynamicState::EDS3,
#elif defined (ANDROID)
#if defined (ANDROID)
ExtendedDynamicState::Disabled, ExtendedDynamicState::Disabled,
#elif defined (__APPLE__) #elif defined (__APPLE__)
ExtendedDynamicState::Disabled, ExtendedDynamicState::Disabled,

197
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 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_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_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_nvidia = driver_id == VK_DRIVER_ID_NVIDIA_PROPRIETARY;
const bool is_mvk = driver_id == VK_DRIVER_ID_MOLTENVK; const bool is_mvk = driver_id == VK_DRIVER_ID_MOLTENVK;
const bool is_qualcomm = driver_id == VK_DRIVER_ID_QUALCOMM_PROPRIETARY; 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_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"); LOG_WARNING(Render_Vulkan, "Unsuitable driver - continuing anyways");
}
if (is_nvidia) { if (is_nvidia) {
nvidia_arch = GetNvidiaArchitecture(physical, supported_extensions); 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_depth24_stencil8_supported = TestDepthStencilBlits(VK_FORMAT_D24_UNORM_S8_UINT);
is_blit_depth32_stencil8_supported = TestDepthStencilBlits(VK_FORMAT_D32_SFLOAT_S8_UINT); is_blit_depth32_stencil8_supported = TestDepthStencilBlits(VK_FORMAT_D32_SFLOAT_S8_UINT);
is_optimal_astc_supported = ComputeIsOptimalAstcSupported(); 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_integrated = properties.properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU;
is_virtual = properties.properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_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); 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); supports_conditional_barriers = !(is_intel_anv || is_intel_windows);
@ -499,11 +484,9 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
CollectToolingInfo(); CollectToolingInfo();
if (is_qualcomm) { 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); 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.shaderBufferInt64Atomics = false;
features.shader_atomic_int64.shaderSharedInt64Atomics = false; features.shader_atomic_int64.shaderSharedInt64Atomics = false;
features.features.shaderInt64 = false; features.features.shaderInt64 = false;
@ -519,181 +502,85 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
bool should_patch_bcn = api_level >= 28; bool should_patch_bcn = api_level >= 28;
const bool bcn_debug_override = Settings::values.patch_old_qcom_drivers.GetValue(); const bool bcn_debug_override = Settings::values.patch_old_qcom_drivers.GetValue();
if (bcn_debug_override != should_patch_bcn) { 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; should_patch_bcn = bcn_debug_override;
} }
if (patch_status == ADRENOTOOLS_BCN_PATCH) { if (patch_status == ADRENOTOOLS_BCN_PATCH) {
if (should_patch_bcn) { 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<void*>(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<void*>(dld.vkGetPhysicalDeviceFormatProperties))) {
OverrideBcnFormats(format_properties); OverrideBcnFormats(format_properties);
} else { } else {
LOG_ERROR(Render_Vulkan, "BCn patch failed! Driver code may now crash"); LOG_ERROR(Render_Vulkan, "BCn patch failed! Driver code may now crash");
} }
} else { } 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) { } else if (patch_status == ADRENOTOOLS_BCN_BLOB) {
LOG_INFO(Render_Vulkan, "Adreno driver supports BCn textures natively (no patch needed)"); LOG_INFO(Render_Vulkan, "Adreno driver supports BCn textures natively (no patch needed)");
} else { } 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 #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; const u32 version = (properties.properties.driverVersion << 3) >> 3;
if (version < VK_MAKE_API_VERSION(0, 255, 615, 512)) { if (version < VK_MAKE_API_VERSION(0, 255, 615, 512)) {
has_broken_parallel_compiling = true; 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) { if (is_turnip) {
LOG_WARNING(Render_Vulkan, "Turnip requires higher-than-reported binding limits"); LOG_WARNING(Render_Vulkan, "Turnip requires higher-than-reported binding limits");
properties.properties.limits.maxVertexInputBindings = 32; 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;
const auto dyna_state = u32(Settings::values.dyna_state.GetValue());
has_broken_compute = CheckBrokenCompute(properties.driver.driverID, properties.properties.driverVersion) && !Settings::values.enable_compute_pipelines.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 // 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 // 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? // 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 // 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) { 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.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]]; [[fallthrough]];
case 1:
case Settings::ExtendedDynamicState::EDS1:
RemoveExtensionFeature(extensions.extended_dynamic_state2, features.extended_dynamic_state2, VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME); 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]]; [[fallthrough]];
case 2:
case Settings::ExtendedDynamicState::EDS2:
RemoveExtensionFeature(extensions.extended_dynamic_state3, features.extended_dynamic_state3, VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME); 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_blending = false;
dynamic_state3_enables = false; dynamic_state3_enables = false;
[[fallthrough]];
case Settings::ExtendedDynamicState::EDS3:
break; 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); RemoveExtensionFeature(extensions.vertex_input_dynamic_state, features.vertex_input_dynamic_state, VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME);
} }

Loading…
Cancel
Save