Remove shaderMulAccuracy "min" option

It's less accurate and it doesn't actually perform better on most hardware.
This commit is contained in:
Exzap 2023-03-12 10:30:53 +01:00
parent 040cc27a40
commit 504e0488a8
5 changed files with 16 additions and 22 deletions

View File

@ -11,6 +11,7 @@
#include "Cafe/GraphicPack/GraphicPack2.h" #include "Cafe/GraphicPack/GraphicPack2.h"
#include "util/helpers/StringParser.h" #include "util/helpers/StringParser.h"
#include "config/ActiveSettings.h" #include "config/ActiveSettings.h"
#include "Cafe/GameProfile/GameProfile.h"
#include "util/containers/flat_hash_map.hpp" #include "util/containers/flat_hash_map.hpp"
#include <cinttypes> #include <cinttypes>
@ -686,6 +687,7 @@ void LatteShader_GetDecompilerOptions(LatteDecompilerOptions& options, LatteCons
options.useTFViaSSBO = VulkanRenderer::GetInstance()->UseTFViaSSBO(); options.useTFViaSSBO = VulkanRenderer::GetInstance()->UseTFViaSSBO();
options.spirvInstrinsics.hasRoundingModeRTEFloat32 = VulkanRenderer::GetInstance()->HasSPRIVRoundingModeRTE32(); options.spirvInstrinsics.hasRoundingModeRTEFloat32 = VulkanRenderer::GetInstance()->HasSPRIVRoundingModeRTE32();
} }
options.strictMul = g_current_game_profile->GetAccurateShaderMul() != AccurateShaderMulOption::False;
} }
LatteDecompilerShader* LatteShader_CompileSeparableVertexShader2(uint64 baseHash, uint64& vsAuxHash, uint8* vertexShaderPtr, uint32 vertexShaderSize, bool usesGeometryShader, LatteFetchShader* fetchShader) LatteDecompilerShader* LatteShader_CompileSeparableVertexShader2(uint64 baseHash, uint64& vsAuxHash, uint8* vertexShaderPtr, uint32 vertexShaderSize, bool usesGeometryShader, LatteFetchShader* fetchShader)

View File

@ -255,6 +255,8 @@ struct LatteDecompilerOutputUniformOffsets
struct LatteDecompilerOptions struct LatteDecompilerOptions
{ {
bool usesGeometryShader{ false }; bool usesGeometryShader{ false };
// floating point math
bool strictMul{}; // if true, 0*anything=0 rule is emulated
// Vulkan-specific // Vulkan-specific
bool useTFViaSSBO{ false }; bool useTFViaSSBO{ false };
struct struct

View File

@ -9,9 +9,6 @@
#include "Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerInternal.h" #include "Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerInternal.h"
#include "Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerInstructions.h" #include "Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerInstructions.h"
#include "Cafe/HW/Latte/Core/FetchShader.h" #include "Cafe/HW/Latte/Core/FetchShader.h"
#include "Cafe/GameProfile/GameProfile.h"
#include "Cafe/HW/Latte/Renderer/Renderer.h" #include "Cafe/HW/Latte/Renderer/Renderer.h"
#include "config/ActiveSettings.h" #include "config/ActiveSettings.h"
#include "util/helpers/StringBuf.h" #include "util/helpers/StringBuf.h"
@ -1122,7 +1119,7 @@ void _emitALUOP2InstructionCode(LatteDecompilerShaderContext* shaderContext, Lat
{ {
useDefaultMul = true; useDefaultMul = true;
} }
if (g_current_game_profile->GetAccurateShaderMul() != AccurateShaderMulOption::False && useDefaultMul == false) if (shaderContext->options->strictMul && useDefaultMul == false)
{ {
src->add("mul_nonIEEE("); src->add("mul_nonIEEE(");
_emitOperandInputCode(shaderContext, aluInstruction, 0, LATTE_DECOMPILER_DTYPE_FLOAT); _emitOperandInputCode(shaderContext, aluInstruction, 0, LATTE_DECOMPILER_DTYPE_FLOAT);
@ -1652,7 +1649,7 @@ void _emitALUOP3InstructionCode(LatteDecompilerShaderContext* shaderContext, Lat
if (aluInstruction->opcode == ALU_OP3_INST_MULADD_IEEE) if (aluInstruction->opcode == ALU_OP3_INST_MULADD_IEEE)
useDefaultMul = true; useDefaultMul = true;
if (g_current_game_profile->GetAccurateShaderMul() != AccurateShaderMulOption::False && useDefaultMul == false) if (shaderContext->options->strictMul && useDefaultMul == false)
{ {
src->add("mul_nonIEEE("); src->add("mul_nonIEEE(");
_emitOperandInputCode(shaderContext, aluInstruction, 0, LATTE_DECOMPILER_DTYPE_FLOAT); _emitOperandInputCode(shaderContext, aluInstruction, 0, LATTE_DECOMPILER_DTYPE_FLOAT);
@ -3843,8 +3840,6 @@ void LatteDecompiler_emitGLSLHelperFunctions(LatteDecompilerShaderContext* shade
"v.z = -1.0;\r\n" "v.z = -1.0;\r\n"
"}\r\n" "}\r\n"
"return v;\r\n" "return v;\r\n"
"}\r\n"); "}\r\n");
} }
@ -3860,7 +3855,7 @@ void LatteDecompiler_emitGLSLHelperFunctions(LatteDecompilerShaderContext* shade
"return floatBitsToInt(clamp(intBitsToFloat(v), 0.0, 1.0));\r\n" "return floatBitsToInt(clamp(intBitsToFloat(v), 0.0, 1.0));\r\n"
"}\r\n"); "}\r\n");
// mul non-ieee way (0*NaN/INF => 0.0) // mul non-ieee way (0*NaN/INF => 0.0)
if (g_current_game_profile->GetAccurateShaderMul() == AccurateShaderMulOption::True) if (shaderContext->options->strictMul)
{ {
// things we tried: // things we tried:
//fCStr_shaderSource->add("float mul_nonIEEE(float a, float b){ return mix(a*b,0.0,a==0.0||b==0.0); }" STR_LINEBREAK); //fCStr_shaderSource->add("float mul_nonIEEE(float a, float b){ return mix(a*b,0.0,a==0.0||b==0.0); }" STR_LINEBREAK);
@ -3868,17 +3863,14 @@ void LatteDecompiler_emitGLSLHelperFunctions(LatteDecompilerShaderContext* shade
//fCStr_shaderSource->add("float mul_nonIEEE(float a, float b){ if( a == 0.0 || b == 0.0 ) return 0.0; return a*b; }" STR_LINEBREAK); //fCStr_shaderSource->add("float mul_nonIEEE(float a, float b){ if( a == 0.0 || b == 0.0 ) return 0.0; return a*b; }" STR_LINEBREAK);
//fCStr_shaderSource->add("float mul_nonIEEE(float a, float b){float r = a*b;r = intBitsToFloat(floatBitsToInt(r)&(((floatBitsToInt(a) != 0) && (floatBitsToInt(b) != 0))?0xFFFFFFFF:0));return r;}" STR_LINEBREAK); works //fCStr_shaderSource->add("float mul_nonIEEE(float a, float b){float r = a*b;r = intBitsToFloat(floatBitsToInt(r)&(((floatBitsToInt(a) != 0) && (floatBitsToInt(b) != 0))?0xFFFFFFFF:0));return r;}" STR_LINEBREAK); works
// for "min" it used to be: float mul_nonIEEE(float a, float b){ return min(a*b,min(abs(a)*3.40282347E+38F,abs(b)*3.40282347E+38F)); }
if( LatteGPUState.glVendor == GLVENDOR_NVIDIA && !ActiveSettings::DumpShadersEnabled()) if( LatteGPUState.glVendor == GLVENDOR_NVIDIA && !ActiveSettings::DumpShadersEnabled())
fCStr_shaderSource->add("float mul_nonIEEE(float a, float b){return mix(0.0, a*b, (a != 0.0) && (b != 0.0));}" _CRLF); // compiles faster on Nvidia and also results in lower RAM usage (OpenGL) fCStr_shaderSource->add("float mul_nonIEEE(float a, float b){return mix(0.0, a*b, (a != 0.0) && (b != 0.0));}" _CRLF); // compiles faster on Nvidia and also results in lower RAM usage (OpenGL)
else else
fCStr_shaderSource->add("float mul_nonIEEE(float a, float b){ if( a == 0.0 || b == 0.0 ) return 0.0; return a*b; }" _CRLF); fCStr_shaderSource->add("float mul_nonIEEE(float a, float b){ if( a == 0.0 || b == 0.0 ) return 0.0; return a*b; }" _CRLF);
// DXKV-like: fCStr_shaderSource->add("float mul_nonIEEE(float a, float b){ return (b==0.0 ? 0.0 : a) * (a==0.0 ? 0.0 : b); }" _CRLF); // DXKV-like: fCStr_shaderSource->add("float mul_nonIEEE(float a, float b){ return (b==0.0 ? 0.0 : a) * (a==0.0 ? 0.0 : b); }" _CRLF);
}
else
{
fCStr_shaderSource->add("float mul_nonIEEE(float a, float b){ return min(a*b,min(abs(a)*3.40282347E+38F,abs(b)*3.40282347E+38F)); }" _CRLF);
} }
} }

View File

@ -115,11 +115,10 @@ ENABLE_ENUM_ITERATORS(PrecompiledShaderOption, PrecompiledShaderOption::Auto, Pr
enum class AccurateShaderMulOption enum class AccurateShaderMulOption
{ {
False = 0, // ignore non-ieee MUL special cases False = 0, // always use standard multiplication
True = 1, // fully emulate non-ieee MUL special cases True = 1 // fully emulate non-ieee MUL special cases (0*anything = 0)
Min = 2, // similar to true, but avoids conditionals (instead relies on min() and abs())
}; };
ENABLE_ENUM_ITERATORS(AccurateShaderMulOption, AccurateShaderMulOption::False, AccurateShaderMulOption::Min); ENABLE_ENUM_ITERATORS(AccurateShaderMulOption, AccurateShaderMulOption::False, AccurateShaderMulOption::True);
enum class CPUMode enum class CPUMode
{ {
@ -213,7 +212,6 @@ struct fmt::formatter<AccurateShaderMulOption> : formatter<string_view> {
{ {
case AccurateShaderMulOption::True: name = "true"; break; case AccurateShaderMulOption::True: name = "true"; break;
case AccurateShaderMulOption::False: name = "false"; break; case AccurateShaderMulOption::False: name = "false"; break;
case AccurateShaderMulOption::Min: name = "min"; break;
default: name = "unknown"; break; default: name = "unknown"; break;
} }
return formatter<string_view>::format(name, ctx); return formatter<string_view>::format(name, ctx);

View File

@ -118,7 +118,7 @@ GameProfileWindow::GameProfileWindow(wxWindow* parent, uint64_t title_id)
first_row->Add(new wxStaticText(panel, wxID_ANY, _("Shader multiplication accuracy")), 0, wxALIGN_CENTER_VERTICAL | wxALL, 5); first_row->Add(new wxStaticText(panel, wxID_ANY, _("Shader multiplication accuracy")), 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
wxString mul_values[] = { _("false"), _("true"), _("minimal") }; wxString mul_values[] = { _("false"), _("true")};
m_shader_mul_accuracy = new wxChoice(panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, (int)std::size(mul_values), mul_values); m_shader_mul_accuracy = new wxChoice(panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, (int)std::size(mul_values), mul_values);
m_shader_mul_accuracy->SetToolTip(_("EXPERT OPTION\nControls the accuracy of floating point multiplication in shaders.\n\nRecommended: true")); m_shader_mul_accuracy->SetToolTip(_("EXPERT OPTION\nControls the accuracy of floating point multiplication in shaders.\n\nRecommended: true"));
first_row->Add(m_shader_mul_accuracy, 0, wxALL, 5); first_row->Add(m_shader_mul_accuracy, 0, wxALL, 5);
@ -268,10 +268,7 @@ void GameProfileWindow::ApplyProfile()
m_graphic_api->SetSelection(0); // selecting "" m_graphic_api->SetSelection(0); // selecting ""
else else
m_graphic_api->SetSelection(1 + m_game_profile.m_graphics_api.value()); // "", OpenGL, Vulkan m_graphic_api->SetSelection(1 + m_game_profile.m_graphics_api.value()); // "", OpenGL, Vulkan
//m_extended_texture_readback->SetValue(m_game_profile.m_extendedTextureReadback);
//m_precompiled->SetSelection((int)m_game_profile.m_precompiledShaders.value());
m_shader_mul_accuracy->SetSelection((int)m_game_profile.m_accurateShaderMul); m_shader_mul_accuracy->SetSelection((int)m_game_profile.m_accurateShaderMul);
//m_cache_accuracy->SetSelection((int)m_game_profile.m_gpuBufferCacheAccuracy.value());
//// audio //// audio
//m_disable_audio->Set3StateValue(GetCheckboxState(m_game_profile.disableAudio)); //m_disable_audio->Set3StateValue(GetCheckboxState(m_game_profile.disableAudio));
@ -331,6 +328,9 @@ void GameProfileWindow::SaveProfile()
// gpu // gpu
m_game_profile.m_accurateShaderMul = (AccurateShaderMulOption)m_shader_mul_accuracy->GetSelection(); m_game_profile.m_accurateShaderMul = (AccurateShaderMulOption)m_shader_mul_accuracy->GetSelection();
if (m_game_profile.m_accurateShaderMul != AccurateShaderMulOption::False && m_game_profile.m_accurateShaderMul != AccurateShaderMulOption::True)
m_game_profile.m_accurateShaderMul = AccurateShaderMulOption::True; // force a legal value
if (m_graphic_api->GetSelection() == 0) if (m_graphic_api->GetSelection() == 0)
m_game_profile.m_graphics_api = {}; m_game_profile.m_graphics_api = {};
else else