add an option to preserve position invariance

This commit is contained in:
Samuliak 2024-12-18 16:38:55 +01:00
parent 4281f6e0c8
commit fa004a33c6
No known key found for this signature in database
7 changed files with 21 additions and 2 deletions

View file

@ -259,6 +259,7 @@ void InfoLog_PrintActiveSettings()
cemuLog_log(LogType::Force, "Async compile: {}", GetConfig().async_compile.GetValue() ? "true" : "false"); cemuLog_log(LogType::Force, "Async compile: {}", GetConfig().async_compile.GetValue() ? "true" : "false");
cemuLog_log(LogType::Force, "Fast math: {}", g_current_game_profile->GetFastMath() ? "true" : "false"); cemuLog_log(LogType::Force, "Fast math: {}", g_current_game_profile->GetFastMath() ? "true" : "false");
cemuLog_log(LogType::Force, "Buffer cache type: {}", g_current_game_profile->GetBufferCacheMode()); cemuLog_log(LogType::Force, "Buffer cache type: {}", g_current_game_profile->GetBufferCacheMode());
cemuLog_log(LogType::Force, "Position invariance: {}", g_current_game_profile->GetPositionInvariance() ? "true" : "false");
if (!GetConfig().vk_accurate_barriers.GetValue()) if (!GetConfig().vk_accurate_barriers.GetValue())
cemuLog_log(LogType::Force, "Accurate barriers are disabled!"); cemuLog_log(LogType::Force, "Accurate barriers are disabled!");
} }

View file

@ -228,6 +228,7 @@ bool GameProfile::Load(uint64_t title_id)
gameProfile_loadEnumOption(iniParser, "accurateShaderMul", m_accurateShaderMul); gameProfile_loadEnumOption(iniParser, "accurateShaderMul", m_accurateShaderMul);
gameProfile_loadBooleanOption2(iniParser, "fastMath", m_fastMath); gameProfile_loadBooleanOption2(iniParser, "fastMath", m_fastMath);
gameProfile_loadEnumOption(iniParser, "bufferCacheMode", m_bufferCacheMode); gameProfile_loadEnumOption(iniParser, "bufferCacheMode", m_bufferCacheMode);
gameProfile_loadBooleanOption2(iniParser, "positionInvariance", m_positionInvariance);
// legacy support // legacy support
auto option_precompiledShaders = iniParser.FindOption("precompiledShaders"); auto option_precompiledShaders = iniParser.FindOption("precompiledShaders");
@ -312,6 +313,7 @@ void GameProfile::Save(uint64_t title_id)
WRITE_ENTRY(accurateShaderMul); WRITE_ENTRY(accurateShaderMul);
WRITE_ENTRY(fastMath); WRITE_ENTRY(fastMath);
WRITE_ENTRY(bufferCacheMode); WRITE_ENTRY(bufferCacheMode);
WRITE_ENTRY(positionInvariance);
WRITE_OPTIONAL_ENTRY(precompiledShaders); WRITE_OPTIONAL_ENTRY(precompiledShaders);
WRITE_OPTIONAL_ENTRY(graphics_api); WRITE_OPTIONAL_ENTRY(graphics_api);
fs->writeLine(""); fs->writeLine("");
@ -343,6 +345,7 @@ void GameProfile::ResetOptional()
m_accurateShaderMul = AccurateShaderMulOption::True; m_accurateShaderMul = AccurateShaderMulOption::True;
m_fastMath = true; m_fastMath = true;
m_bufferCacheMode = BufferCacheMode::DevicePrivate; m_bufferCacheMode = BufferCacheMode::DevicePrivate;
m_positionInvariance = false;
// cpu settings // cpu settings
m_threadQuantum = kThreadQuantumDefault; m_threadQuantum = kThreadQuantumDefault;
m_cpuMode.reset(); // CPUModeOption::kSingleCoreRecompiler; m_cpuMode.reset(); // CPUModeOption::kSingleCoreRecompiler;
@ -365,6 +368,7 @@ void GameProfile::Reset()
m_accurateShaderMul = AccurateShaderMulOption::True; m_accurateShaderMul = AccurateShaderMulOption::True;
m_fastMath = true; m_fastMath = true;
m_bufferCacheMode = BufferCacheMode::DevicePrivate; m_bufferCacheMode = BufferCacheMode::DevicePrivate;
m_positionInvariance = false;
m_precompiledShaders = PrecompiledShaderOption::Auto; m_precompiledShaders = PrecompiledShaderOption::Auto;
// cpu settings // cpu settings
m_threadQuantum = kThreadQuantumDefault; m_threadQuantum = kThreadQuantumDefault;

View file

@ -33,6 +33,7 @@ public:
[[nodiscard]] const AccurateShaderMulOption& GetAccurateShaderMul() const { return m_accurateShaderMul; } [[nodiscard]] const AccurateShaderMulOption& GetAccurateShaderMul() const { return m_accurateShaderMul; }
[[nodiscard]] bool GetFastMath() const { return m_fastMath; } [[nodiscard]] bool GetFastMath() const { return m_fastMath; }
[[nodiscard]] BufferCacheMode GetBufferCacheMode() const { return m_bufferCacheMode; } [[nodiscard]] BufferCacheMode GetBufferCacheMode() const { return m_bufferCacheMode; }
[[nodiscard]] bool GetPositionInvariance() const { return m_positionInvariance; }
[[nodiscard]] const std::optional<PrecompiledShaderOption>& GetPrecompiledShadersState() const { return m_precompiledShaders; } [[nodiscard]] const std::optional<PrecompiledShaderOption>& GetPrecompiledShadersState() const { return m_precompiledShaders; }
[[nodiscard]] uint32 GetThreadQuantum() const { return m_threadQuantum; } [[nodiscard]] uint32 GetThreadQuantum() const { return m_threadQuantum; }
@ -56,8 +57,9 @@ private:
// graphic settings // graphic settings
std::optional<GraphicAPI> m_graphics_api{}; std::optional<GraphicAPI> m_graphics_api{};
AccurateShaderMulOption m_accurateShaderMul = AccurateShaderMulOption::True; AccurateShaderMulOption m_accurateShaderMul = AccurateShaderMulOption::True;
bool m_fastMath = false; bool m_fastMath = true;
BufferCacheMode m_bufferCacheMode = BufferCacheMode::DevicePrivate; BufferCacheMode m_bufferCacheMode = BufferCacheMode::DevicePrivate;
bool m_positionInvariance = false;
std::optional<PrecompiledShaderOption> m_precompiledShaders{}; std::optional<PrecompiledShaderOption> m_precompiledShaders{};
// cpu settings // cpu settings
uint32 m_threadQuantum = kThreadQuantumDefault; // values: 20000 45000 60000 80000 100000 uint32 m_threadQuantum = kThreadQuantumDefault; // values: 20000 45000 60000 80000 100000

View file

@ -180,7 +180,7 @@ namespace LatteDecompiler
auto* src = shaderContext->shaderSource; auto* src = shaderContext->shaderSource;
src->add("struct VertexOut {" _CRLF); src->add("struct VertexOut {" _CRLF);
src->add("float4 position [[position]];" _CRLF); src->add("float4 position [[position]] [[invariant]];" _CRLF);
if (shaderContext->analyzer.outputPointSize) if (shaderContext->analyzer.outputPointSize)
src->add("float pointSize [[point_size]];" _CRLF); src->add("float pointSize [[point_size]];" _CRLF);

View file

@ -178,6 +178,8 @@ void RendererShaderMtl::CompileInternal()
// TODO: always disable fast math for problematic shaders // TODO: always disable fast math for problematic shaders
if (g_current_game_profile->GetFastMath()) if (g_current_game_profile->GetFastMath())
options->setFastMathEnabled(true); options->setFastMathEnabled(true);
if (g_current_game_profile->GetPositionInvariance())
options->setPreserveInvariance(true);
NS::Error* error = nullptr; NS::Error* error = nullptr;
MTL::Library* library = m_mtlr->GetDevice()->newLibrary(ToNSString(m_mslCode), options, &error); MTL::Library* library = m_mtlr->GetDevice()->newLibrary(ToNSString(m_mslCode), options, &error);

View file

@ -142,6 +142,13 @@ GameProfileWindow::GameProfileWindow(wxWindow* parent, uint64_t title_id)
m_buffer_cache_mode->SetToolTip(_("EXPERT OPTION\nDecides how the buffer cache memory will be managed.\n\nMetal only\n\nRecommended: device private")); m_buffer_cache_mode->SetToolTip(_("EXPERT OPTION\nDecides how the buffer cache memory will be managed.\n\nMetal only\n\nRecommended: device private"));
first_row->Add(m_buffer_cache_mode, 0, wxALL, 5); first_row->Add(m_buffer_cache_mode, 0, wxALL, 5);
first_row->Add(new wxStaticText(panel, wxID_ANY, _("Position invariance")), 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
wxString pos_values[] = { _("false"), _("true") };
m_position_invariance = new wxChoice(panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, (int)std::size(pos_values), pos_values);
m_position_invariance->SetToolTip(_("Disables most optimizations for vertex positions. May fix polygon cutouts in some games.\n\nMetal only\n\nRecommended: false"));
first_row->Add(m_position_invariance, 0, wxALL, 5);
/*first_row->Add(new wxStaticText(panel, wxID_ANY, _("GPU buffer cache accuracy")), 0, wxALIGN_CENTER_VERTICAL | wxALL, 5); /*first_row->Add(new wxStaticText(panel, wxID_ANY, _("GPU buffer cache accuracy")), 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
wxString accuarcy_values[] = { _("high"), _("medium"), _("low") }; wxString accuarcy_values[] = { _("high"), _("medium"), _("low") };
m_cache_accuracy = new wxChoice(panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, (int)std::size(accuarcy_values), accuarcy_values); m_cache_accuracy = new wxChoice(panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, (int)std::size(accuarcy_values), accuarcy_values);
@ -290,6 +297,7 @@ void GameProfileWindow::ApplyProfile()
m_shader_mul_accuracy->SetSelection((int)m_game_profile.m_accurateShaderMul); m_shader_mul_accuracy->SetSelection((int)m_game_profile.m_accurateShaderMul);
m_fast_math->SetSelection((int)m_game_profile.m_fastMath); m_fast_math->SetSelection((int)m_game_profile.m_fastMath);
m_buffer_cache_mode->SetSelection((int)m_game_profile.m_bufferCacheMode); m_buffer_cache_mode->SetSelection((int)m_game_profile.m_bufferCacheMode);
m_position_invariance->SetSelection((int)m_game_profile.m_positionInvariance);
//// audio //// audio
//m_disable_audio->Set3StateValue(GetCheckboxState(m_game_profile.disableAudio)); //m_disable_audio->Set3StateValue(GetCheckboxState(m_game_profile.disableAudio));
@ -351,6 +359,7 @@ void GameProfileWindow::SaveProfile()
m_game_profile.m_accurateShaderMul = (AccurateShaderMulOption)m_shader_mul_accuracy->GetSelection(); m_game_profile.m_accurateShaderMul = (AccurateShaderMulOption)m_shader_mul_accuracy->GetSelection();
m_game_profile.m_fastMath = (bool)m_fast_math->GetSelection(); m_game_profile.m_fastMath = (bool)m_fast_math->GetSelection();
m_game_profile.m_bufferCacheMode = (BufferCacheMode)m_buffer_cache_mode->GetSelection(); m_game_profile.m_bufferCacheMode = (BufferCacheMode)m_buffer_cache_mode->GetSelection();
m_game_profile.m_positionInvariance = (bool)m_position_invariance->GetSelection();
if (m_game_profile.m_accurateShaderMul != AccurateShaderMulOption::False && m_game_profile.m_accurateShaderMul != AccurateShaderMulOption::True) 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 m_game_profile.m_accurateShaderMul = AccurateShaderMulOption::True; // force a legal value

View file

@ -42,6 +42,7 @@ private:
wxChoice* m_shader_mul_accuracy; wxChoice* m_shader_mul_accuracy;
wxChoice* m_fast_math; wxChoice* m_fast_math;
wxChoice* m_buffer_cache_mode; wxChoice* m_buffer_cache_mode;
wxChoice* m_position_invariance;
//wxChoice* m_cache_accuracy; //wxChoice* m_cache_accuracy;
// audio // audio