add auto option for position invariance

This commit is contained in:
Samuliak 2025-01-23 14:50:14 +01:00
parent 7ad4d480cb
commit bc6fb816da
No known key found for this signature in database
8 changed files with 103 additions and 14 deletions

View file

@ -260,7 +260,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"); cemuLog_log(LogType::Force, "Position invariance: {}", g_current_game_profile->GetPositionInvariance());
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,7 +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); gameProfile_loadEnumOption(iniParser, "positionInvariance2", m_positionInvariance);
// legacy support // legacy support
auto option_precompiledShaders = iniParser.FindOption("precompiledShaders"); auto option_precompiledShaders = iniParser.FindOption("precompiledShaders");
@ -345,7 +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; m_positionInvariance = PositionInvariance::Auto;
// cpu settings // cpu settings
m_threadQuantum = kThreadQuantumDefault; m_threadQuantum = kThreadQuantumDefault;
m_cpuMode.reset(); // CPUModeOption::kSingleCoreRecompiler; m_cpuMode.reset(); // CPUModeOption::kSingleCoreRecompiler;
@ -368,7 +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_positionInvariance = PositionInvariance::Auto;
m_precompiledShaders = PrecompiledShaderOption::Auto; m_precompiledShaders = PrecompiledShaderOption::Auto;
// cpu settings // cpu settings
m_threadQuantum = kThreadQuantumDefault; m_threadQuantum = kThreadQuantumDefault;

View file

@ -33,7 +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]] PositionInvariance 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; }
@ -59,7 +59,7 @@ private:
AccurateShaderMulOption m_accurateShaderMul = AccurateShaderMulOption::True; AccurateShaderMulOption m_accurateShaderMul = AccurateShaderMulOption::True;
bool m_fastMath = true; bool m_fastMath = true;
BufferCacheMode m_bufferCacheMode = BufferCacheMode::DevicePrivate; BufferCacheMode m_bufferCacheMode = BufferCacheMode::DevicePrivate;
bool m_positionInvariance = false; PositionInvariance m_positionInvariance = PositionInvariance::Auto;
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

@ -17,6 +17,7 @@
#include "Cafe/HW/Latte/Core/LatteShader.h" #include "Cafe/HW/Latte/Core/LatteShader.h"
#include "Cafe/HW/Latte/Core/LatteIndices.h" #include "Cafe/HW/Latte/Core/LatteIndices.h"
#include "Cafe/HW/Latte/Core/LatteBufferCache.h" #include "Cafe/HW/Latte/Core/LatteBufferCache.h"
#include "CafeSystem.h"
#include "Cemu/Logging/CemuLogging.h" #include "Cemu/Logging/CemuLogging.h"
#include "Cafe/HW/Latte/Core/FetchShader.h" #include "Cafe/HW/Latte/Core/FetchShader.h"
#include "Cafe/HW/Latte/Core/LatteConst.h" #include "Cafe/HW/Latte/Core/LatteConst.h"
@ -54,6 +55,59 @@ std::vector<MetalRenderer::DeviceInfo> MetalRenderer::GetDevices()
MetalRenderer::MetalRenderer() MetalRenderer::MetalRenderer()
{ {
// Options
// Position invariance
switch (g_current_game_profile->GetPositionInvariance())
{
case PositionInvariance::Auto:
switch (CafeSystem::GetForegroundTitleId())
{
// Minecraft: Story Mode
case 0x000500001020A300: // EUR
case 0x00050000101E0100: // USA
//case 0x000500001020a200: // USA
// Resident Evil: Revelations
case 0x000500001012B400: // EUR
case 0x000500001012CF00: // USA
// The Legend of Zelda: Breath of the Wild
case 0x00050000101C9500: // EUR
case 0x00050000101C9400: // USA
case 0x00050000101C9300: // JPN
// Ninja Gaiden 3: Razor's Edge
case 0x0005000010110B00: // EUR
case 0x0005000010110A00: // USA
case 0x0005000010110900: // JPN
case 0x0005000010139B00: // EUR (TODO: check)
// Bayonetta 2
case 0x0005000010172700: // EUR
case 0x0005000010172600: // USA
// LEGO STAR WARS: The Force Awakens
case 0x00050000101DAA00: // EUR
case 0x00050000101DAB00: // USA
// Bayonetta
case 0x0005000010157F00: // EUR
case 0x0005000010157E00: // USA
case 0x000500001014DB00: // JPN
// Disney Planes
case 0x0005000010136900: // EUR
case 0x0005000010136A00: // EUR
case 0x0005000010136B00: // EUR
case 0x000500001011C500: // USA (TODO: check)
m_positionInvariance = true;
break;
default:
m_positionInvariance = false;
break;
}
case PositionInvariance::False:
m_positionInvariance = false;
break;
case PositionInvariance::True:
m_positionInvariance = true;
break;
}
// Pick a device // Pick a device
auto& config = GetConfig(); auto& config = GetConfig();
const bool hasDeviceSet = config.mtl_graphic_device_uuid != 0; const bool hasDeviceSet = config.mtl_graphic_device_uuid != 0;

View file

@ -358,6 +358,11 @@ public:
void CopyBufferToBuffer(MTL::Buffer* src, uint32 srcOffset, MTL::Buffer* dst, uint32 dstOffset, uint32 size, MTL::RenderStages after, MTL::RenderStages before); void CopyBufferToBuffer(MTL::Buffer* src, uint32 srcOffset, MTL::Buffer* dst, uint32 dstOffset, uint32 size, MTL::RenderStages after, MTL::RenderStages before);
// Getters // Getters
bool GetPositionInvariance() const
{
return m_positionInvariance;
}
bool IsAppleGPU() const bool IsAppleGPU() const
{ {
return m_isAppleGPU; return m_isAppleGPU;
@ -464,6 +469,9 @@ private:
MetalPerformanceMonitor m_performanceMonitor; MetalPerformanceMonitor m_performanceMonitor;
// Options
bool m_positionInvariance;
// Metal objects // Metal objects
MTL::Device* m_device = nullptr; MTL::Device* m_device = nullptr;
MTL::CommandQueue* m_commandQueue; MTL::CommandQueue* m_commandQueue;

View file

@ -2,8 +2,8 @@
#include "Cafe/HW/Latte/Renderer/Metal/MetalRenderer.h" #include "Cafe/HW/Latte/Renderer/Metal/MetalRenderer.h"
#include "Cafe/HW/Latte/Renderer/Metal/MetalCommon.h" #include "Cafe/HW/Latte/Renderer/Metal/MetalCommon.h"
#include "Cemu/FileCache/FileCache.h" //#include "Cemu/FileCache/FileCache.h"
#include "config/ActiveSettings.h" //#include "config/ActiveSettings.h"
#include "Cemu/Logging/CemuLogging.h" #include "Cemu/Logging/CemuLogging.h"
#include "Common/precompiled.h" #include "Common/precompiled.h"
#include "GameProfile/GameProfile.h" #include "GameProfile/GameProfile.h"
@ -279,8 +279,12 @@ MTL::Library* RendererShaderMtl::LibraryFromSource()
MTL::CompileOptions* options = MTL::CompileOptions::alloc()->init(); MTL::CompileOptions* options = MTL::CompileOptions::alloc()->init();
if (g_current_game_profile->GetFastMath()) if (g_current_game_profile->GetFastMath())
options->setFastMathEnabled(true); options->setFastMathEnabled(true);
if (g_current_game_profile->GetPositionInvariance())
if (m_mtlr->GetPositionInvariance())
{
// TODO: filter out based on GPU state
options->setPreserveInvariance(true); 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

@ -132,6 +132,14 @@ enum class BufferCacheMode
}; };
ENABLE_ENUM_ITERATORS(BufferCacheMode, BufferCacheMode::DevicePrivate, BufferCacheMode::Host); ENABLE_ENUM_ITERATORS(BufferCacheMode, BufferCacheMode::DevicePrivate, BufferCacheMode::Host);
enum class PositionInvariance
{
Auto,
False,
True,
};
ENABLE_ENUM_ITERATORS(PositionInvariance, PositionInvariance::False, PositionInvariance::True);
enum class CPUMode enum class CPUMode
{ {
SinglecoreInterpreter = 0, SinglecoreInterpreter = 0,
@ -245,6 +253,21 @@ struct fmt::formatter<BufferCacheMode> : formatter<string_view> {
} }
}; };
template <> template <>
struct fmt::formatter<PositionInvariance> : formatter<string_view> {
template <typename FormatContext>
auto format(const PositionInvariance c, FormatContext &ctx) const {
string_view name;
switch (c)
{
case PositionInvariance::Auto: name = "auto"; break;
case PositionInvariance::False: name = "false"; break;
case PositionInvariance::True: name = "true"; break;
default: name = "unknown"; break;
}
return formatter<string_view>::format(name, ctx);
}
};
template <>
struct fmt::formatter<CPUMode> : formatter<string_view> { struct fmt::formatter<CPUMode> : formatter<string_view> {
template <typename FormatContext> template <typename FormatContext>
auto format(const CPUMode c, FormatContext &ctx) const { auto format(const CPUMode c, FormatContext &ctx) const {

View file

@ -144,9 +144,9 @@ GameProfileWindow::GameProfileWindow(wxWindow* parent, uint64_t title_id)
first_row->Add(new wxStaticText(panel, wxID_ANY, _("Position invariance")), 0, wxALIGN_CENTER_VERTICAL | wxALL, 5); first_row->Add(new wxStaticText(panel, wxID_ANY, _("Position invariance")), 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
wxString pos_values[] = { _("false"), _("true") }; wxString pos_values[] = { _("auto"), _("false"), _("true") };
m_position_invariance = new wxChoice(panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, (int)std::size(pos_values), pos_values); 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")); m_position_invariance->SetToolTip(_("Disables most optimizations for vertex positions. May fix polygon cutouts or flickering in some games.\n\nMetal only\n\nRecommended: auto"));
first_row->Add(m_position_invariance, 0, wxALL, 5); 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);
@ -357,11 +357,11 @@ 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();
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_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
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_positionInvariance = (PositionInvariance)m_position_invariance->GetSelection();
if (m_graphic_api->GetSelection() == 0) if (m_graphic_api->GetSelection() == 0)
m_game_profile.m_graphics_api = {}; m_game_profile.m_graphics_api = {};