diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index ce35a7be1d..e96c88d3aa 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -357,6 +357,7 @@ PipelineCache::PipelineCache(Tegra::MaxwellDeviceMemoryManager& device_memory_, "VkPipelineBuilder"), serialization_thread(1, "VkPipelineSerialization") { const auto& float_control{device.FloatControlProperties()}; + const bool float_controls_supported{device.IsKhrShaderFloatControlsSupported()}; const VkDriverId driver_id{device.GetDriverID()}; profile = Shader::Profile{ .supported_spirv = device.SupportedSpirvVersion(), @@ -366,20 +367,24 @@ PipelineCache::PipelineCache(Tegra::MaxwellDeviceMemoryManager& device_memory_, .support_int16 = device.IsShaderInt16Supported(), .support_int64 = device.IsShaderInt64Supported(), .support_vertex_instance_id = false, - .support_float_controls = device.IsKhrShaderFloatControlsSupported(), - .support_separate_denorm_behavior = + .support_float_controls = float_controls_supported, + .support_separate_denorm_behavior = float_controls_supported && float_control.denormBehaviorIndependence == VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL, - .support_separate_rounding_mode = + .support_separate_rounding_mode = float_controls_supported && float_control.roundingModeIndependence == VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL, - .support_fp16_denorm_preserve = float_control.shaderDenormPreserveFloat16 != VK_FALSE, - .support_fp32_denorm_preserve = float_control.shaderDenormPreserveFloat32 != VK_FALSE, - .support_fp16_denorm_flush = float_control.shaderDenormFlushToZeroFloat16 != VK_FALSE, - .support_fp32_denorm_flush = float_control.shaderDenormFlushToZeroFloat32 != VK_FALSE, - .support_fp16_signed_zero_nan_preserve = + .support_fp16_denorm_preserve = float_controls_supported && + float_control.shaderDenormPreserveFloat16 != VK_FALSE, + .support_fp32_denorm_preserve = float_controls_supported && + float_control.shaderDenormPreserveFloat32 != VK_FALSE, + .support_fp16_denorm_flush = float_controls_supported && + float_control.shaderDenormFlushToZeroFloat16 != VK_FALSE, + .support_fp32_denorm_flush = float_controls_supported && + float_control.shaderDenormFlushToZeroFloat32 != VK_FALSE, + .support_fp16_signed_zero_nan_preserve = float_controls_supported && float_control.shaderSignedZeroInfNanPreserveFloat16 != VK_FALSE, - .support_fp32_signed_zero_nan_preserve = + .support_fp32_signed_zero_nan_preserve = float_controls_supported && float_control.shaderSignedZeroInfNanPreserveFloat32 != VK_FALSE, - .support_fp64_signed_zero_nan_preserve = + .support_fp64_signed_zero_nan_preserve = float_controls_supported && float_control.shaderSignedZeroInfNanPreserveFloat64 != VK_FALSE, .support_explicit_workgroup_layout = device.IsKhrWorkgroupMemoryExplicitLayoutSupported(), .support_vote = device.IsSubgroupFeatureSupported(VK_SUBGROUP_FEATURE_VOTE_BIT), diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index b5299bf51c..e3b2395335 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -506,13 +506,9 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR "Qualcomm drivers require scaled vertex format emulation; forcing fallback"); 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); - if (extensions.spirv_1_4) { - LOG_WARNING(Render_Vulkan, - "VK_KHR_spirv_1_4 depends on VK_KHR_shader_float_controls; disabling both on Qualcomm"); - RemoveExtension(extensions.spirv_1_4, VK_KHR_SPIRV_1_4_EXTENSION_NAME); - } + "Qualcomm proprietary drivers report VK_KHR_shader_float_controls but remain unreliable;" + " disabling usage while keeping the extension enabled"); + disable_shader_float_controls_usage = true; RemoveExtensionFeature(extensions.shader_atomic_int64, features.shader_atomic_int64, VK_KHR_SHADER_ATOMIC_INT64_EXTENSION_NAME); features.shader_atomic_int64.shaderBufferInt64Atomics = false; diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h index a0342b55ea..aa3a4707d7 100644 --- a/src/video_core/vulkan_common/vulkan_device.h +++ b/src/video_core/vulkan_common/vulkan_device.h @@ -503,7 +503,7 @@ public: /// Returns true if VK_KHR_shader_float_controls is enabled. bool IsKhrShaderFloatControlsSupported() const { - return extensions.shader_float_controls; + return extensions.shader_float_controls && !disable_shader_float_controls_usage; } /// Returns true if the device supports VK_KHR_workgroup_memory_explicit_layout. @@ -1090,6 +1090,7 @@ private: bool cant_blit_msaa{}; ///< Does not support MSAA<->MSAA blitting. bool must_emulate_scaled_formats{}; ///< Requires scaled vertex format emulation bool must_emulate_bgr565{}; ///< Emulates BGR565 by swizzling RGB565 format. + bool disable_shader_float_controls_usage{}; ///< True when VK_KHR_shader_float_controls cannot be safely used. bool use_mobile_megabuffer{}; ///< Use the Android mega buffer path. bool dynamic_state3_blending{}; ///< Has blending features of dynamic_state3. bool dynamic_state3_enables{}; ///< Has at least one enable feature of dynamic_state3.