From 821765189a5912980a56dacc0dd6aeec2646b00e Mon Sep 17 00:00:00 2001 From: CamilleLaVey Date: Fri, 4 Sep 2026 03:41:24 -0400 Subject: [PATCH] add reshade toggle --- CMakeLists.txt | 2 + externals/CMakeLists.txt | 48 ++++++++++--------- .../src/main/jni/native_post_processing.cpp | 36 ++++++++++++++ src/video_core/CMakeLists.txt | 26 +++++----- .../renderer_vulkan/present/layer.cpp | 8 ++++ .../renderer_vulkan/present/layer.h | 6 +++ .../renderer_vulkan/renderer_vulkan.cpp | 4 ++ src/yuzu/CMakeLists.txt | 8 +++- src/yuzu/main_window.cpp | 8 ++++ src/yuzu/main_window.h | 6 +++ 10 files changed, 116 insertions(+), 36 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 310237bc59..07bb55f9ef 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -84,6 +84,8 @@ option(ENABLE_WERROR "Enable -Werror diagnostics" ON) # Lossless Scaling frame generation. Only Android. cmake_dependent_option(ENABLE_LSFG "Enable Lossless Scaling frame generation" ON "ANDROID" OFF) +option(ENABLE_RESHADE "Enable ReShade FX post-processing effects" ON) + # non-linux bundled qt are static if (YUZU_USE_BUNDLED_QT AND (APPLE OR NOT UNIX)) set(YUZU_STATIC_BUILD ON) diff --git a/externals/CMakeLists.txt b/externals/CMakeLists.txt index 1c16db723a..b021b10fae 100644 --- a/externals/CMakeLists.txt +++ b/externals/CMakeLists.txt @@ -196,34 +196,36 @@ else() endif() # reshadefx -AddJsonPackage(reshade DOWNLOAD_ONLY) +if (ENABLE_RESHADE) + AddJsonPackage(NAME reshade DOWNLOAD_ONLY) -set(RESHADEFX_SHIM_DIR ${CMAKE_CURRENT_BINARY_DIR}/reshadefx_shim) -file(WRITE ${RESHADEFX_SHIM_DIR}/spirv.hpp "#include \n") -file(WRITE ${RESHADEFX_SHIM_DIR}/GLSL.std.450.h "#include \n") + set(RESHADEFX_SHIM_DIR ${CMAKE_CURRENT_BINARY_DIR}/reshadefx_shim) + file(WRITE ${RESHADEFX_SHIM_DIR}/spirv.hpp "#include \n") + file(WRITE ${RESHADEFX_SHIM_DIR}/GLSL.std.450.h "#include \n") -add_library(reshadefx STATIC - ${reshade_SOURCE_DIR}/source/effect_codegen_spirv.cpp - ${reshade_SOURCE_DIR}/source/effect_expression.cpp - ${reshade_SOURCE_DIR}/source/effect_lexer.cpp - ${reshade_SOURCE_DIR}/source/effect_parser_exp.cpp - ${reshade_SOURCE_DIR}/source/effect_parser_stmt.cpp - ${reshade_SOURCE_DIR}/source/effect_preprocessor.cpp - ${reshade_SOURCE_DIR}/source/effect_symbol_table.cpp -) + add_library(reshadefx STATIC + ${reshade_SOURCE_DIR}/source/effect_codegen_spirv.cpp + ${reshade_SOURCE_DIR}/source/effect_expression.cpp + ${reshade_SOURCE_DIR}/source/effect_lexer.cpp + ${reshade_SOURCE_DIR}/source/effect_parser_exp.cpp + ${reshade_SOURCE_DIR}/source/effect_parser_stmt.cpp + ${reshade_SOURCE_DIR}/source/effect_preprocessor.cpp + ${reshade_SOURCE_DIR}/source/effect_symbol_table.cpp + ) -target_include_directories(reshadefx PUBLIC ${reshade_SOURCE_DIR}/source) -target_include_directories(reshadefx PRIVATE ${RESHADEFX_SHIM_DIR}) -target_link_libraries(reshadefx PUBLIC SPIRV-Headers::SPIRV-Headers) + target_include_directories(reshadefx PUBLIC ${reshade_SOURCE_DIR}/source) + target_include_directories(reshadefx PRIVATE ${RESHADEFX_SHIM_DIR}) + target_link_libraries(reshadefx PUBLIC SPIRV-Headers::SPIRV-Headers) -if (NOT MSVC) - target_compile_options(reshadefx PRIVATE -w) -else() - target_compile_options(reshadefx PRIVATE /w) -endif() + if (NOT MSVC) + target_compile_options(reshadefx PRIVATE -w) + else() + target_compile_options(reshadefx PRIVATE /w) + endif() -if (NOT TARGET reshadefx::reshadefx) - add_library(reshadefx::reshadefx ALIAS reshadefx) + if (NOT TARGET reshadefx::reshadefx) + add_library(reshadefx::reshadefx ALIAS reshadefx) + endif() endif() # Catch2 diff --git a/src/android/app/src/main/jni/native_post_processing.cpp b/src/android/app/src/main/jni/native_post_processing.cpp index c20c039a43..e7bdad104d 100644 --- a/src/android/app/src/main/jni/native_post_processing.cpp +++ b/src/android/app/src/main/jni/native_post_processing.cpp @@ -7,11 +7,14 @@ #include #include "common/android/android_common.h" +#ifdef HAS_RESHADE #include "video_core/post_processing/fx_chain.h" #include "video_core/post_processing/fx_effect.h" +#endif namespace { +#ifdef HAS_RESHADE nlohmann::json SerializeUniform(const VideoCore::FxUniformDesc& uniform) { nlohmann::json out; out["name"] = uniform.name; @@ -34,6 +37,7 @@ nlohmann::json SerializeUniform(const VideoCore::FxUniformDesc& uniform) { return out; } +#endif } // Anonymous namespace @@ -43,6 +47,7 @@ jstring Java_org_yuzu_yuzu_1emu_utils_NativePostProcessing_getCatalogJson(JNIEnv jobject obj) { nlohmann::json out = nlohmann::json::array(); +#ifdef HAS_RESHADE for (const auto& effect : VideoCore::GetFxCatalog()) { nlohmann::json entry; entry["file"] = effect.file; @@ -58,6 +63,7 @@ jstring Java_org_yuzu_yuzu_1emu_utils_NativePostProcessing_getCatalogJson(JNIEnv out.push_back(entry); } +#endif return Common::Android::ToJString(env, out.dump()); } @@ -65,6 +71,7 @@ jstring Java_org_yuzu_yuzu_1emu_utils_NativePostProcessing_getCatalogJson(JNIEnv jstring Java_org_yuzu_yuzu_1emu_utils_NativePostProcessing_getChainJson(JNIEnv* env, jobject obj) { nlohmann::json out = nlohmann::json::array(); +#ifdef HAS_RESHADE for (const auto& entry : VideoCore::FxChain::Instance().Entries()) { nlohmann::json item; item["file"] = entry.file; @@ -78,60 +85,80 @@ jstring Java_org_yuzu_yuzu_1emu_utils_NativePostProcessing_getChainJson(JNIEnv* out.push_back(item); } +#endif return Common::Android::ToJString(env, out.dump()); } void Java_org_yuzu_yuzu_1emu_utils_NativePostProcessing_append(JNIEnv* env, jobject obj, jstring jfile, jstring jtechnique) { +#ifdef HAS_RESHADE VideoCore::FxChain::Instance().Append(Common::Android::GetJString(env, jfile), Common::Android::GetJString(env, jtechnique)); +#endif } void Java_org_yuzu_yuzu_1emu_utils_NativePostProcessing_replace(JNIEnv* env, jobject obj, jint index, jstring jfile, jstring jtechnique) { +#ifdef HAS_RESHADE VideoCore::FxChain::Instance().Replace(static_cast(index), Common::Android::GetJString(env, jfile), Common::Android::GetJString(env, jtechnique)); +#endif } void Java_org_yuzu_yuzu_1emu_utils_NativePostProcessing_remove(JNIEnv* env, jobject obj, jint index) { +#ifdef HAS_RESHADE VideoCore::FxChain::Instance().Remove(static_cast(index)); +#endif } void Java_org_yuzu_yuzu_1emu_utils_NativePostProcessing_move(JNIEnv* env, jobject obj, jint index, jint delta) { +#ifdef HAS_RESHADE VideoCore::FxChain::Instance().Move(static_cast(index), delta); +#endif } void Java_org_yuzu_yuzu_1emu_utils_NativePostProcessing_resetValues(JNIEnv* env, jobject obj, jint index) { +#ifdef HAS_RESHADE VideoCore::FxChain::Instance().ResetValues(static_cast(index)); +#endif } jfloat Java_org_yuzu_yuzu_1emu_utils_NativePostProcessing_getValue(JNIEnv* env, jobject obj, jint index, jstring juniform, jint component) { +#ifdef HAS_RESHADE if (component < 0 || component >= 4) { return 0.0f; } const auto value = VideoCore::FxChain::Instance().GetValue( static_cast(index), Common::Android::GetJString(env, juniform)); return value[static_cast(component)]; +#else + return 0.0f; +#endif } jboolean Java_org_yuzu_yuzu_1emu_utils_NativePostProcessing_hasValue(JNIEnv* env, jobject obj, jint index, jstring juniform) { +#ifdef HAS_RESHADE return static_cast(VideoCore::FxChain::Instance().HasValue( static_cast(index), Common::Android::GetJString(env, juniform))); +#else + return static_cast(false); +#endif } void Java_org_yuzu_yuzu_1emu_utils_NativePostProcessing_setValue(JNIEnv* env, jobject obj, jint index, jstring juniform, jint component, jfloat value) { +#ifdef HAS_RESHADE if (component < 0 || component >= 4) { return; } @@ -141,20 +168,29 @@ void Java_org_yuzu_yuzu_1emu_utils_NativePostProcessing_setValue(JNIEnv* env, jo auto current = chain.GetValue(static_cast(index), uniform); current[static_cast(component)] = value; chain.SetValue(static_cast(index), uniform, current); +#endif } void Java_org_yuzu_yuzu_1emu_utils_NativePostProcessing_store(JNIEnv* env, jobject obj) { +#ifdef HAS_RESHADE VideoCore::FxChain::Instance().StoreToSettings(); +#endif } void Java_org_yuzu_yuzu_1emu_utils_NativePostProcessing_reload(JNIEnv* env, jobject obj) { +#ifdef HAS_RESHADE VideoCore::ReloadFxCatalog(); VideoCore::FxChain::Instance().DropUnknownEntries(); +#endif } jstring Java_org_yuzu_yuzu_1emu_utils_NativePostProcessing_getShaderDirectory(JNIEnv* env, jobject obj) { +#ifdef HAS_RESHADE return Common::Android::ToJString(env, VideoCore::GetFxRootDirectory().string()); +#else + return Common::Android::ToJString(env, ""); +#endif } } // extern "C" diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt index c284e07a24..4e37901652 100644 --- a/src/video_core/CMakeLists.txt +++ b/src/video_core/CMakeLists.txt @@ -117,14 +117,6 @@ add_library(video_core STATIC renderer_null/renderer_null.cpp renderer_null/renderer_null.h - # Post-processing - post_processing/fx_chain.cpp - post_processing/fx_chain.h - post_processing/fx_compile.cpp - post_processing/fx_compile.h - post_processing/fx_effect.cpp - post_processing/fx_effect.h - # Vulkan renderer_vulkan/present/anti_alias_pass.h renderer_vulkan/present/filters.cpp @@ -135,8 +127,6 @@ add_library(video_core STATIC renderer_vulkan/present/fxaa.h renderer_vulkan/present/layer.cpp renderer_vulkan/present/layer.h - renderer_vulkan/present/post_process.cpp - renderer_vulkan/present/post_process.h renderer_vulkan/present/present_push_constants.h renderer_vulkan/present/smaa.cpp renderer_vulkan/present/smaa.h @@ -309,6 +299,21 @@ if (ENABLE_LSFG) target_compile_definitions(video_core PUBLIC HAS_LSFG) endif() +if (ENABLE_RESHADE) + target_sources(video_core PRIVATE + post_processing/fx_chain.cpp + post_processing/fx_chain.h + post_processing/fx_compile.cpp + post_processing/fx_compile.h + post_processing/fx_effect.cpp + post_processing/fx_effect.h + renderer_vulkan/present/post_process.cpp + renderer_vulkan/present/post_process.h + ) + target_link_libraries(video_core PRIVATE reshadefx::reshadefx) + target_compile_definitions(video_core PUBLIC HAS_RESHADE) +endif() + if (ENABLE_OPENGL) target_sources(video_core PRIVATE renderer_opengl/present/filters.cpp @@ -387,7 +392,6 @@ add_dependencies(video_core host_shaders) target_include_directories(video_core PRIVATE ${HOST_SHADERS_INCLUDE}) target_link_libraries(video_core PRIVATE sirit::sirit) -target_link_libraries(video_core PRIVATE reshadefx::reshadefx stb::headers) # Header-only stuff needed by all dependent targets target_link_libraries(video_core PUBLIC Vulkan::Headers Vulkan::UtilityHeaders GPUOpen::VulkanMemoryAllocator) diff --git a/src/video_core/renderer_vulkan/present/layer.cpp b/src/video_core/renderer_vulkan/present/layer.cpp index 88fdfe4500..6d79f07521 100644 --- a/src/video_core/renderer_vulkan/present/layer.cpp +++ b/src/video_core/renderer_vulkan/present/layer.cpp @@ -18,8 +18,10 @@ #include "video_core/renderer_vulkan/present/sgsr.h" #include "video_core/renderer_vulkan/present/fxaa.h" #include "video_core/renderer_vulkan/present/layer.h" +#ifdef HAS_RESHADE #include "video_core/post_processing/fx_chain.h" #include "video_core/renderer_vulkan/present/post_process.h" +#endif #include "video_core/renderer_vulkan/present/present_push_constants.h" #include "video_core/renderer_vulkan/present/smaa.h" #include "video_core/renderer_vulkan/present/util.h" @@ -95,7 +97,9 @@ void Layer::ConfigureDraw(const Device& device, PresentPushConstants* out_push_c RefreshResources(device, framebuffer); SetAntiAliasPass(device); +#ifdef HAS_RESHADE SetPostProcessPass(device); +#endif // Finish any pending renderpass scheduler.RequestOutsideRenderPassOperationContext(); @@ -118,9 +122,11 @@ void Layer::ConfigureDraw(const Device& device, PresentPushConstants* out_push_c smaa->Draw(device, scheduler, image_index, &source_image, &source_image_view); } +#ifdef HAS_RESHADE if (post_process.has_value()) { post_process->Draw(device, scheduler, image_index, &source_image, &source_image_view); } +#endif auto crop_rect = Tegra::NormalizeCrop(framebuffer, texture_width, texture_height); const VkExtent2D render_extent{ @@ -221,6 +227,7 @@ void Layer::SetAntiAliasPass(const Device& device) { } } +#ifdef HAS_RESHADE void Layer::SetPostProcessPass(const Device& device) { const VkExtent2D render_area{ .width = Settings::values.resolution_info.ScaleUp(raw_width), @@ -252,6 +259,7 @@ void Layer::SetPostProcessPass(const Device& device) { post_process.reset(); } } +#endif void Layer::ReleaseRawImages() { for (const u64 tick : resource_ticks) { diff --git a/src/video_core/renderer_vulkan/present/layer.h b/src/video_core/renderer_vulkan/present/layer.h index 73ada26613..4cc911713f 100644 --- a/src/video_core/renderer_vulkan/present/layer.h +++ b/src/video_core/renderer_vulkan/present/layer.h @@ -15,7 +15,9 @@ #include "video_core/renderer_vulkan/present/fsr.h" #include "video_core/renderer_vulkan/present/sgsr.h" #include "video_core/renderer_vulkan/present/fxaa.h" +#ifdef HAS_RESHADE #include "video_core/renderer_vulkan/present/post_process.h" +#endif #include "video_core/renderer_vulkan/present/smaa.h" namespace Layout { @@ -67,7 +69,9 @@ private: void RefreshResources(const Device& device, const Tegra::FramebufferConfig& framebuffer); void SetAntiAliasPass(const Device& device); +#ifdef HAS_RESHADE void SetPostProcessPass(const Device& device); +#endif void ReleaseRawImages(); u64 CalculateBufferSize(const Tegra::FramebufferConfig& framebuffer) const; @@ -97,9 +101,11 @@ private: Settings::AntiAliasing anti_alias_setting{}; std::variant anti_alias{}; std::variant sr_filter{}; +#ifdef HAS_RESHADE std::optional post_process{}; u64 post_process_generation{}; VkExtent2D post_process_extent{}; +#endif std::vector resource_ticks{}; }; diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp index 0350e09692..b05b866b4c 100644 --- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp +++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp @@ -24,8 +24,10 @@ #include "video_core/gpu.h" #include "video_core/present.h" #include "video_core/renderer_vulkan/present/util.h" +#ifdef HAS_RESHADE #include "video_core/post_processing/fx_chain.h" #include "video_core/post_processing/fx_effect.h" +#endif #include "video_core/renderer_vulkan/renderer_vulkan.h" #include "video_core/renderer_vulkan/vk_blit_screen.h" #include "video_core/renderer_vulkan/vk_rasterizer.h" @@ -185,9 +187,11 @@ try scheduler.RegisterOnSubmit([this] { turbo_mode->QueueSubmitted(); }); } +#ifdef HAS_RESHADE VideoCore::ReloadFxCatalog(); VideoCore::FxChain::Instance().LoadFromSettings(); VideoCore::FxChain::Instance().DropUnknownEntries(); +#endif Report(); } catch (const vk::Exception& exception) { diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt index 184cf7968e..b93080f2a1 100644 --- a/src/yuzu/CMakeLists.txt +++ b/src/yuzu/CMakeLists.txt @@ -74,8 +74,6 @@ add_executable(yuzu configuration/configure_general.ui configuration/configure_graphics.cpp configuration/configure_graphics.h - configuration/configure_post_processing.cpp - configuration/configure_post_processing.h configuration/configure_graphics.ui configuration/configure_graphics_advanced.cpp configuration/configure_graphics_advanced.h @@ -252,6 +250,12 @@ if (YUZU_CRASH_DUMPS) target_compile_definitions(yuzu PRIVATE YUZU_CRASH_DUMPS) endif() +if (ENABLE_RESHADE) + target_sources(yuzu PRIVATE + configuration/configure_post_processing.cpp + configuration/configure_post_processing.h) +endif() + if (CXX_CLANG) target_compile_definitions(yuzu PRIVATE $<$,15>:CANNOT_EXPLICITLY_INSTANTIATE>) diff --git a/src/yuzu/main_window.cpp b/src/yuzu/main_window.cpp index 3a5b25f400..2a0178114d 100644 --- a/src/yuzu/main_window.cpp +++ b/src/yuzu/main_window.cpp @@ -13,7 +13,9 @@ #include "common/settings_enums.h" #include "frontend_common/settings_generator.h" #include "render/performance_overlay.h" +#ifdef HAS_RESHADE #include "configuration/configure_post_processing.h" +#endif #include "updater/update_dialog.h" #include "common/fs/ryujinx_compat.h" @@ -1519,7 +1521,11 @@ void MainWindow::ConnectMenuEvents() { connect_menu(ui->action_Show_Filter_Bar, &MainWindow::OnToggleFilterBar); connect_menu(ui->action_Show_Status_Bar, &MainWindow::OnToggleStatusBar); connect_menu(ui->action_Show_Performance_Overlay, &MainWindow::OnTogglePerfOverlay); +#ifdef HAS_RESHADE connect_menu(ui->action_Post_Processing_Shaders, &MainWindow::OnPostProcessingShaders); +#else + ui->action_Post_Processing_Shaders->setVisible(false); +#endif connect_menu(ui->action_Reset_Window_Size_720, &MainWindow::ResetWindowSize720); connect_menu(ui->action_Reset_Window_Size_900, &MainWindow::ResetWindowSize900); @@ -3902,6 +3908,7 @@ void MainWindow::OnTogglePerfOverlay() { perf_overlay->setVisible(ui->action_Show_Performance_Overlay->isChecked()); } +#ifdef HAS_RESHADE void MainWindow::OnPostProcessingShaders() { if (post_processing_dialog == nullptr) { post_processing_dialog = new ConfigurePostProcessing(this); @@ -3915,6 +3922,7 @@ void MainWindow::OnPostProcessingShaders() { post_processing_dialog->raise(); post_processing_dialog->activateWindow(); } +#endif void MainWindow::OnGameListRefresh() { // Resets metadata cache and reloads diff --git a/src/yuzu/main_window.h b/src/yuzu/main_window.h index 78864f719c..ce17f7f935 100644 --- a/src/yuzu/main_window.h +++ b/src/yuzu/main_window.h @@ -56,7 +56,9 @@ class QSlider; class QHBoxLayout; class WaitTreeWidget; class PerformanceOverlay; +#ifdef HAS_RESHADE class ConfigurePostProcessing; +#endif enum class GameListOpenTarget; enum class DumpRomFSTarget; class GameListPlaceholder; @@ -393,7 +395,9 @@ private slots: void OnToggleFilterBar(); void OnToggleStatusBar(); void OnTogglePerfOverlay(); +#ifdef HAS_RESHADE void OnPostProcessingShaders(); +#endif void OnGameListRefresh(); void InitializeHotkeys(); void ToggleFullscreen(); @@ -498,7 +502,9 @@ private: QTimer shutdown_timer; OverlayDialog* shutdown_dialog{}; PerformanceOverlay* perf_overlay = nullptr; +#ifdef HAS_RESHADE ConfigurePostProcessing* post_processing_dialog = nullptr; +#endif GameListPlaceholder* game_list_placeholder = nullptr;