emit_spirv: Workaround VK_KHR_shader_float_controls on fp16 Nvidia
Fix regression on Fire Emblem: Three Houses when using native fp16.
This commit is contained in:
		| @@ -319,7 +319,7 @@ void SetupDenormControl(const Profile& profile, const IR::Program& program, Emit | ||||
|                         Id main_func) { | ||||
|     const Info& info{program.info}; | ||||
|     if (info.uses_fp32_denorms_flush && info.uses_fp32_denorms_preserve) { | ||||
|         LOG_WARNING(Shader_SPIRV, "Fp32 denorm flush and preserve on the same shader"); | ||||
|         LOG_DEBUG(Shader_SPIRV, "Fp32 denorm flush and preserve on the same shader"); | ||||
|     } else if (info.uses_fp32_denorms_flush) { | ||||
|         if (profile.support_fp32_denorm_flush) { | ||||
|             ctx.AddCapability(spv::Capability::DenormFlushToZero); | ||||
| @@ -332,15 +332,15 @@ void SetupDenormControl(const Profile& profile, const IR::Program& program, Emit | ||||
|             ctx.AddCapability(spv::Capability::DenormPreserve); | ||||
|             ctx.AddExecutionMode(main_func, spv::ExecutionMode::DenormPreserve, 32U); | ||||
|         } else { | ||||
|             LOG_WARNING(Shader_SPIRV, "Fp32 denorm preserve used in shader without host support"); | ||||
|             LOG_DEBUG(Shader_SPIRV, "Fp32 denorm preserve used in shader without host support"); | ||||
|         } | ||||
|     } | ||||
|     if (!profile.support_separate_denorm_behavior) { | ||||
|     if (!profile.support_separate_denorm_behavior || profile.has_broken_fp16_float_controls) { | ||||
|         // No separate denorm behavior | ||||
|         return; | ||||
|     } | ||||
|     if (info.uses_fp16_denorms_flush && info.uses_fp16_denorms_preserve) { | ||||
|         LOG_WARNING(Shader_SPIRV, "Fp16 denorm flush and preserve on the same shader"); | ||||
|         LOG_DEBUG(Shader_SPIRV, "Fp16 denorm flush and preserve on the same shader"); | ||||
|     } else if (info.uses_fp16_denorms_flush) { | ||||
|         if (profile.support_fp16_denorm_flush) { | ||||
|             ctx.AddCapability(spv::Capability::DenormFlushToZero); | ||||
| @@ -353,13 +353,16 @@ void SetupDenormControl(const Profile& profile, const IR::Program& program, Emit | ||||
|             ctx.AddCapability(spv::Capability::DenormPreserve); | ||||
|             ctx.AddExecutionMode(main_func, spv::ExecutionMode::DenormPreserve, 16U); | ||||
|         } else { | ||||
|             LOG_WARNING(Shader_SPIRV, "Fp16 denorm preserve used in shader without host support"); | ||||
|             LOG_DEBUG(Shader_SPIRV, "Fp16 denorm preserve used in shader without host support"); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| void SetupSignedNanCapabilities(const Profile& profile, const IR::Program& program, | ||||
|                                 EmitContext& ctx, Id main_func) { | ||||
|     if (profile.has_broken_fp16_float_controls && program.info.uses_fp16) { | ||||
|         return; | ||||
|     } | ||||
|     if (program.info.uses_fp16 && profile.support_fp16_signed_zero_nan_preserve) { | ||||
|         ctx.AddCapability(spv::Capability::SignedZeroInfNanPreserve); | ||||
|         ctx.AddExecutionMode(main_func, spv::ExecutionMode::SignedZeroInfNanPreserve, 16U); | ||||
|   | ||||
| @@ -58,6 +58,8 @@ struct Profile { | ||||
|     bool has_broken_unsigned_image_offsets{}; | ||||
|     /// Signed instructions with unsigned data types are misinterpreted | ||||
|     bool has_broken_signed_operations{}; | ||||
|     /// Float controls break when fp16 is enabled | ||||
|     bool has_broken_fp16_float_controls{}; | ||||
|     /// Dynamic vec4 indexing is broken on some OpenGL drivers | ||||
|     bool has_gl_component_indexing_bug{}; | ||||
|     /// The precise type qualifier is broken in the fragment stage of some drivers | ||||
|   | ||||
| @@ -206,6 +206,7 @@ ShaderCache::ShaderCache(RasterizerOpenGL& rasterizer_, Core::Frontend::EmuWindo | ||||
|           .has_broken_spirv_clamp = true, | ||||
|           .has_broken_unsigned_image_offsets = true, | ||||
|           .has_broken_signed_operations = true, | ||||
|           .has_broken_fp16_float_controls = false, | ||||
|           .has_gl_component_indexing_bug = device.HasComponentIndexingBug(), | ||||
|           .has_gl_precise_bug = device.HasPreciseBug(), | ||||
|           .ignore_nan_fp_comparisons = true, | ||||
|   | ||||
| @@ -315,6 +315,7 @@ PipelineCache::PipelineCache(RasterizerVulkan& rasterizer_, Tegra::Engines::Maxw | ||||
|         .has_broken_spirv_clamp = driver_id == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS_KHR, | ||||
|         .has_broken_unsigned_image_offsets = false, | ||||
|         .has_broken_signed_operations = false, | ||||
|         .has_broken_fp16_float_controls = driver_id == VK_DRIVER_ID_NVIDIA_PROPRIETARY_KHR, | ||||
|         .ignore_nan_fp_comparisons = false, | ||||
|     }; | ||||
|     host_info = Shader::HostTranslateInfo{ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user