diff --git a/src/Cafe/CafeSystem.cpp b/src/Cafe/CafeSystem.cpp index 09020130..66b0969f 100644 --- a/src/Cafe/CafeSystem.cpp +++ b/src/Cafe/CafeSystem.cpp @@ -258,6 +258,7 @@ void InfoLog_PrintActiveSettings() else if (ActiveSettings::GetGraphicsAPI() == GraphicAPI::kMetal) { cemuLog_log(LogType::Force, "Async compile: {}", GetConfig().async_compile.GetValue() ? "true" : "false"); + cemuLog_log(LogType::Force, "Force mesh shaders: {}", GetConfig().force_mesh_shaders.GetValue() ? "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, "Position invariance: {}", g_current_game_profile->GetPositionInvariance()); diff --git a/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp b/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp index 0982c8a4..90b852d7 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp +++ b/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp @@ -170,7 +170,7 @@ MetalRenderer::MetalRenderer() m_supportsFramebufferFetch = GetConfig().framebuffer_fetch.GetValue() ? m_device->supportsFamily(MTL::GPUFamilyApple2) : false; m_hasUnifiedMemory = m_device->hasUnifiedMemory(); m_supportsMetal3 = m_device->supportsFamily(MTL::GPUFamilyMetal3); - m_supportsMeshShaders = (m_supportsMetal3 && m_vendor != GfxVendor::Intel); // Intel GPUs have issues with mesh shaders + m_supportsMeshShaders = (m_supportsMetal3 && (m_vendor != GfxVendor::Intel || GetConfig().force_mesh_shaders.GetValue())); // Intel GPUs have issues with mesh shaders m_recommendedMaxVRAMUsage = m_device->recommendedMaxWorkingSetSize(); m_pixelFormatSupport = MetalPixelFormatSupport(m_device); diff --git a/src/config/CemuConfig.cpp b/src/config/CemuConfig.cpp index 7542dc31..3878cb80 100644 --- a/src/config/CemuConfig.cpp +++ b/src/config/CemuConfig.cpp @@ -222,6 +222,7 @@ void CemuConfig::Load(XMLConfigParser& parser) fullscreen_scaling = graphic.get("FullscreenScaling", kKeepAspectRatio); async_compile = graphic.get("AsyncCompile", async_compile); vk_accurate_barriers = graphic.get("vkAccurateBarriers", true); // this used to be "VulkanAccurateBarriers" but because we changed the default to true in 1.27.1 the option name had to be changed + force_mesh_shaders = graphic.get("ForceMeshShaders", false); auto overlay_node = graphic.get("Overlay"); if(overlay_node.valid()) @@ -477,6 +478,7 @@ void CemuConfig::Save(XMLConfigParser& parser) graphic.set("mtlDevice", mtl_graphic_device_uuid); graphic.set("VSync", vsync); graphic.set("GX2DrawdoneSync", gx2drawdone_sync); + graphic.set("ForceMeshShaders", force_mesh_shaders); //graphic.set("PrecompiledShaders", precompiled_shaders.GetValue()); graphic.set("UpscaleFilter", upscale_filter); graphic.set("DownscaleFilter", downscale_filter); diff --git a/src/config/CemuConfig.h b/src/config/CemuConfig.h index e9fb225c..a931403d 100644 --- a/src/config/CemuConfig.h +++ b/src/config/CemuConfig.h @@ -494,6 +494,7 @@ struct CemuConfig ConfigValue gx2drawdone_sync { true }; ConfigValue render_upside_down{ false }; ConfigValue async_compile{ true }; + ConfigValue force_mesh_shaders{ false }; ConfigValue vk_accurate_barriers{ true }; diff --git a/src/gui/GeneralSettings2.cpp b/src/gui/GeneralSettings2.cpp index 31d16481..3d8e4c6a 100644 --- a/src/gui/GeneralSettings2.cpp +++ b/src/gui/GeneralSettings2.cpp @@ -367,6 +367,10 @@ wxPanel* GeneralSettings2::AddGraphicsPage(wxNotebook* notebook) m_gx2drawdone_sync->SetToolTip(_("If synchronization is requested by the game, the emulated CPU will wait for the GPU to finish all operations.\nThis is more accurate behavior, but may cause lower performance")); graphic_misc_row->Add(m_gx2drawdone_sync, 0, wxALL, 5); + m_force_mesh_shaders = new wxCheckBox(box, wxID_ANY, _("Force mesh shaders")); + m_force_mesh_shaders->SetToolTip(_("Force mesh shaders on all GPUs that support them. Mesh shaders are disabled by default on Intel GPUs due to potential stability issues")); + graphic_misc_row->Add(m_force_mesh_shaders, 0, wxALL, 5); + box_sizer->Add(graphic_misc_row, 1, wxEXPAND, 5); graphics_panel_sizer->Add(box_sizer, 0, wxEXPAND | wxALL, 5); } @@ -1100,6 +1104,7 @@ void GeneralSettings2::StoreConfig() config.vsync = m_vsync->GetSelection(); config.gx2drawdone_sync = m_gx2drawdone_sync->IsChecked(); + config.force_mesh_shaders = m_force_mesh_shaders->IsChecked(); config.async_compile = m_async_compile->IsChecked(); config.upscale_filter = m_upscale_filter->GetSelection(); @@ -1580,12 +1585,14 @@ void GeneralSettings2::HandleGraphicsApiSelection() m_gx2drawdone_sync->Enable(); m_async_compile->Disable(); + m_force_mesh_shaders->Disable(); } else if (m_graphic_api->GetSelection() == 1) { // Vulkan m_gx2drawdone_sync->Disable(); m_async_compile->Enable(); + m_force_mesh_shaders->Disable(); m_vsync->AppendString(_("Off")); m_vsync->AppendString(_("Double buffering")); @@ -1623,11 +1630,10 @@ void GeneralSettings2::HandleGraphicsApiSelection() // Metal m_gx2drawdone_sync->Disable(); m_async_compile->Enable(); + m_force_mesh_shaders->Enable(); - // TODO: vsync options m_vsync->AppendString(_("Off")); - m_vsync->AppendString(_("Double buffering")); - m_vsync->AppendString(_("Triple buffering")); + m_vsync->AppendString(_("On")); m_vsync->Select(selection); @@ -1708,6 +1714,7 @@ void GeneralSettings2::ApplyConfig() m_vsync->SetSelection(config.vsync); m_async_compile->SetValue(config.async_compile); m_gx2drawdone_sync->SetValue(config.gx2drawdone_sync); + m_force_mesh_shaders->SetValue(config.force_mesh_shaders); m_upscale_filter->SetSelection(config.upscale_filter); m_downscale_filter->SetSelection(config.downscale_filter); m_fullscreen_scaling->SetSelection(config.fullscreen_scaling); diff --git a/src/gui/GeneralSettings2.h b/src/gui/GeneralSettings2.h index 58459e95..0118359a 100644 --- a/src/gui/GeneralSettings2.h +++ b/src/gui/GeneralSettings2.h @@ -53,7 +53,7 @@ private: // Graphics wxChoice* m_graphic_api, * m_graphic_device; wxChoice* m_vsync; - wxCheckBox *m_async_compile, *m_gx2drawdone_sync; + wxCheckBox *m_async_compile, *m_gx2drawdone_sync, *m_force_mesh_shaders; wxRadioBox* m_upscale_filter, *m_downscale_filter, *m_fullscreen_scaling; wxChoice* m_overlay_position, *m_notification_position, *m_overlay_scale, *m_notification_scale; wxCheckBox* m_controller_profile_name, *m_controller_low_battery, *m_shader_compiling, *m_friends_data;