[vk, pipeline_cache] TEST: Refactor shader float controls handling for Qualcomm devices

This commit is contained in:
CamilleLaVey 2025-11-17 20:30:17 -04:00
parent ca479883ec
commit 1f5def5756
2 changed files with 31 additions and 81 deletions

View file

@ -342,18 +342,14 @@ PipelineCache::PipelineCache(Tegra::MaxwellDeviceMemoryManager& device_memory_,
.support_fp64_signed_zero_nan_preserve = .support_fp64_signed_zero_nan_preserve =
float_control.shaderSignedZeroInfNanPreserveFloat64 != VK_FALSE, float_control.shaderSignedZeroInfNanPreserveFloat64 != VK_FALSE,
#ifdef ANDROID // Switch/Maxwell native float behavior (auto-configured on Qualcomm)
// User-forced float behavior overrides (Eden Veil/Extensions) .force_fp32_denorm_flush = driver_id == VK_DRIVER_ID_QUALCOMM_PROPRIETARY &&
.force_fp32_denorm_flush = Settings::values.shader_float_ftz.GetValue(), device.IsKhrShaderFloatControlsSupported(),
.force_fp32_denorm_preserve = Settings::values.shader_float_denorm_preserve.GetValue(), .force_fp32_denorm_preserve = false, // FTZ dominates
.force_fp32_rte_rounding = Settings::values.shader_float_rte.GetValue(), .force_fp32_rte_rounding = driver_id == VK_DRIVER_ID_QUALCOMM_PROPRIETARY &&
.force_fp32_signed_zero_inf_nan = Settings::values.shader_float_signed_zero_inf_nan.GetValue(), device.IsKhrShaderFloatControlsSupported(),
#else .force_fp32_signed_zero_inf_nan = driver_id == VK_DRIVER_ID_QUALCOMM_PROPRIETARY &&
.force_fp32_denorm_flush = false, device.IsKhrShaderFloatControlsSupported(),
.force_fp32_denorm_preserve = false,
.force_fp32_rte_rounding = false,
.force_fp32_signed_zero_inf_nan = false,
#endif
.support_explicit_workgroup_layout = device.IsKhrWorkgroupMemoryExplicitLayoutSupported(), .support_explicit_workgroup_layout = device.IsKhrWorkgroupMemoryExplicitLayoutSupported(),
.support_vote = device.IsSubgroupFeatureSupported(VK_SUBGROUP_FEATURE_VOTE_BIT), .support_vote = device.IsSubgroupFeatureSupported(VK_SUBGROUP_FEATURE_VOTE_BIT),

View file

@ -542,81 +542,32 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
// Log Qualcomm-specific optimizations // Log Qualcomm-specific optimizations
if (extensions.render_pass_store_ops) { if (extensions.render_pass_store_ops) {
LOG_INFO(Render_Vulkan, "VK_QCOM_render_pass_store_ops: ENABLED (TBDR store optimization)"); LOG_INFO(Render_Vulkan, "VK_QCOM_render_pass_store_ops: ENABLED");
} }
if (extensions.tile_properties) { if (extensions.tile_properties) {
LOG_INFO(Render_Vulkan, "VK_QCOM_tile_properties: ENABLED (tile size queries available)"); LOG_INFO(Render_Vulkan, "VK_QCOM_tile_properties: ENABLED (tile size queries available)");
} }
if (extensions.render_pass_shader_resolve) { if (extensions.render_pass_shader_resolve) {
LOG_INFO(Render_Vulkan, "VK_QCOM_render_pass_shader_resolve: ENABLED (HDR+MSAA shader resolve)"); LOG_INFO(Render_Vulkan, "VK_QCOM_render_pass_shader_resolve: ENABLED");
} }
#ifdef ANDROID // Shader Float Controls for Qualcomm Adreno
// Shader Float Controls handling for Qualcomm Adreno LOG_INFO(Render_Vulkan, "Enabling Shader Float Controls with Switch/Maxwell native configuration");
// Default: DISABLED due to historical issues with binning precision causing visual glitches
const bool force_enable = Settings::values.shader_float_controls_force_enable.GetValue();
if (force_enable) { // Log driver capabilities
// User explicitly enabled float controls - log detected capabilities and user config const auto& fc = properties.float_controls;
LOG_INFO(Render_Vulkan, "Shader Float Controls FORCE ENABLED by user (Eden Veil/Extensions)"); LOG_INFO(Render_Vulkan, "Driver Capabilities:");
LOG_INFO(Render_Vulkan, " - Denorm Flush FP32: {}", fc.shaderDenormFlushToZeroFloat32 ? "YES" : "NO");
// Log driver capabilities LOG_INFO(Render_Vulkan, " - RTE Rounding FP32: {}", fc.shaderRoundingModeRTEFloat32 ? "YES" : "NO");
const auto& fc = properties.float_controls; LOG_INFO(Render_Vulkan, " - Signed Zero/Inf/Nan FP32: {}", fc.shaderSignedZeroInfNanPreserveFloat32 ? "YES" : "NO");
LOG_INFO(Render_Vulkan, "Driver Float Controls Capabilities:");
LOG_INFO(Render_Vulkan, " - Denorm Flush FP32: {}", fc.shaderDenormFlushToZeroFloat32 ? "YES" : "NO"); // Apply Switch/Maxwell native float behavior
LOG_INFO(Render_Vulkan, " - Denorm Preserve FP32: {}", fc.shaderDenormPreserveFloat32 ? "YES" : "NO"); LOG_INFO(Render_Vulkan, "Applying Switch/Maxwell native float behavior:");
LOG_INFO(Render_Vulkan, " - RTE Rounding FP32: {}", fc.shaderRoundingModeRTEFloat32 ? "YES" : "NO"); LOG_INFO(Render_Vulkan, " - FTZ (Flush-To-Zero): ON - Matches Switch hardware behavior");
LOG_INFO(Render_Vulkan, " - Signed Zero/Inf/Nan FP32: {}", fc.shaderSignedZeroInfNanPreserveFloat32 ? "YES" : "NO"); LOG_INFO(Render_Vulkan, " - RTE (Round-To-Even): ON - IEEE 754 standard precision");
LOG_INFO(Render_Vulkan, " - Independence: {}", LOG_INFO(Render_Vulkan, " - SignedZero/Inf/NaN: ON - Mathematical correctness");
fc.denormBehaviorIndependence == VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL ? "ALL" : "LIMITED");
LOG_INFO(Render_Vulkan, "VK_KHR_shader_float_controls: ENABLED (auto-configured)");
// Log user selections
bool ftz = Settings::values.shader_float_ftz.GetValue();
bool preserve = Settings::values.shader_float_denorm_preserve.GetValue();
const bool rte = Settings::values.shader_float_rte.GetValue();
const bool signed_zero = Settings::values.shader_float_signed_zero_inf_nan.GetValue();
// Validate mutually exclusive options
if (ftz && preserve) {
LOG_WARNING(Render_Vulkan,
"CONFLICT: FTZ and DenormPreserve are mutually exclusive!");
LOG_WARNING(Render_Vulkan,
" -> DenormPreserve will take precedence (accuracy over speed)");
ftz = false; // Preserve takes priority for correctness
}
LOG_INFO(Render_Vulkan, "User Float Behavior Selection:");
LOG_INFO(Render_Vulkan, " - Flush To Zero (FTZ): {}", ftz ? "ENABLED" : "disabled");
LOG_INFO(Render_Vulkan, " - Denorm Preserve: {}", preserve ? "ENABLED" : "disabled");
LOG_INFO(Render_Vulkan, " - Round To Even (RTE): {}", rte ? "ENABLED" : "disabled");
LOG_INFO(Render_Vulkan, " - Signed Zero/Inf/Nan: {}", signed_zero ? "ENABLED" : "disabled");
// Analyze configuration vs Switch native behavior
const bool matches_switch = ftz && !preserve && rte && signed_zero;
if (matches_switch) {
LOG_INFO(Render_Vulkan, "Configuration MATCHES Switch/Maxwell native behavior (FTZ+RTE+SignedZero)");
} else if (!ftz && !preserve && !rte && !signed_zero) {
LOG_WARNING(Render_Vulkan, "No float behaviors selected - using driver default (may cause glitches)");
} else {
LOG_INFO(Render_Vulkan, "Configuration is CUSTOM - testing mode active");
}
// Extension stays enabled
LOG_INFO(Render_Vulkan, "VK_KHR_shader_float_controls: ENABLED");
} else {
// Default behavior - disable float controls
LOG_WARNING(Render_Vulkan,
"Disabling shader float controls on Qualcomm (historical binning precision issues)");
LOG_INFO(Render_Vulkan,
"To enable: Eden Veil -> Extensions -> Shader Float Controls (Force Enable)");
RemoveExtension(extensions.shader_float_controls, VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME);
}
#else
// Non-Android: keep original behavior
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);
#endif
// Int64 atomics - genuinely broken, always disable // Int64 atomics - genuinely broken, always disable
RemoveExtensionFeature(extensions.shader_atomic_int64, features.shader_atomic_int64, RemoveExtensionFeature(extensions.shader_atomic_int64, features.shader_atomic_int64,
@ -854,8 +805,11 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
(std::min)(properties.properties.limits.maxVertexInputBindings, 16U); (std::min)(properties.properties.limits.maxVertexInputBindings, 16U);
} }
if (is_turnip) { if (is_turnip || is_qualcomm) {
LOG_WARNING(Render_Vulkan, "Turnip requires higher-than-reported binding limits"); // Ensure proper vertex input bindings limit for Qualcomm hardware
LOG_WARNING(Render_Vulkan,
"{}: Ensuring maxVertexInputBindings = 32",
is_turnip ? "Turnip" : "Qualcomm");
properties.properties.limits.maxVertexInputBindings = 32; properties.properties.limits.maxVertexInputBindings = 32;
} }