diff --git a/CMakeLists.txt b/CMakeLists.txt index 46f3d2dad4..2c840491f2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -81,6 +81,9 @@ cmake_dependent_option(YUZU_USE_BUNDLED_QT "Download bundled Qt binaries" "${MSV option(ENABLE_DEBUG_TOOLS "Enable debugging tools (maxwell disassembler, SPIRV translator, etc)" OFF) 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) + # non-linux bundled qt are static if (YUZU_USE_BUNDLED_QT AND (APPLE OR NOT UNIX)) set(YUZU_STATIC_BUILD ON) diff --git a/src/android/app/src/main/jni/native.cpp b/src/android/app/src/main/jni/native.cpp index 7173ccddd0..db808f2e80 100644 --- a/src/android/app/src/main/jni/native.cpp +++ b/src/android/app/src/main/jni/native.cpp @@ -1429,20 +1429,36 @@ jint Java_org_yuzu_yuzu_1emu_NativeLibrary_installKeys(JNIEnv* env, jclass clazz } jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getLosslessDllPath(JNIEnv* env, jclass clazz) { +#ifdef HAS_LSFG const auto path = VideoCore::FrameGen::GetLosslessDllPath(); return Common::Android::ToJString(env, Common::FS::PathToUTF8String(path)); +#else + return Common::Android::ToJString(env, ""); +#endif } jint Java_org_yuzu_yuzu_1emu_NativeLibrary_validateLosslessDll(JNIEnv* env, jclass clazz) { +#ifdef HAS_LSFG return static_cast(VideoCore::FrameGen::GetInstalledLosslessStatus()); +#else + return static_cast(VideoCore::FrameGen::LosslessStatus::NotInstalled); +#endif } jint Java_org_yuzu_yuzu_1emu_NativeLibrary_prepareLosslessDll(JNIEnv* env, jclass clazz) { +#ifdef HAS_LSFG return static_cast(VideoCore::FrameGen::BuildShaderCache()); +#else + return static_cast(VideoCore::FrameGen::LosslessStatus::NotInstalled); +#endif } jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_removeLosslessDll(JNIEnv* env, jclass clazz) { +#ifdef HAS_LSFG return static_cast(VideoCore::FrameGen::RemoveInstalledLosslessDll()); +#else + return static_cast(false); +#endif } jobjectArray Java_org_yuzu_yuzu_1emu_NativeLibrary_getPatchesForFile(JNIEnv* env, jobject jobj, diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt index db397aa272..c86849837b 100644 --- a/src/video_core/CMakeLists.txt +++ b/src/video_core/CMakeLists.txt @@ -59,10 +59,6 @@ add_library(video_core STATIC engines/maxwell_dma.h engines/puller.cpp engines/puller.h - frame_gen/lossless_dll.cpp - frame_gen/lossless_dll.h - frame_gen/lsfg_translate.cpp - frame_gen/lsfg_translate.h framebuffer_config.cpp framebuffer_config.h fsr.cpp @@ -125,28 +121,6 @@ add_library(video_core STATIC renderer_vulkan/present/anti_alias_pass.h renderer_vulkan/present/filters.cpp renderer_vulkan/present/filters.h - renderer_vulkan/present/frame_gen.cpp - renderer_vulkan/present/frame_gen.h - renderer_vulkan/present/frame_gen_pacer.cpp - renderer_vulkan/present/frame_gen_pacer.h - renderer_vulkan/present/lsfg_alpha.cpp - renderer_vulkan/present/lsfg_alpha.h - renderer_vulkan/present/lsfg_beta.cpp - renderer_vulkan/present/lsfg_beta.h - renderer_vulkan/present/lsfg_chain.cpp - renderer_vulkan/present/lsfg_chain.h - renderer_vulkan/present/lsfg_common.cpp - renderer_vulkan/present/lsfg_common.h - renderer_vulkan/present/lsfg_delta.cpp - renderer_vulkan/present/lsfg_delta.h - renderer_vulkan/present/lsfg_gamma.cpp - renderer_vulkan/present/lsfg_gamma.h - renderer_vulkan/present/lsfg_generate.cpp - renderer_vulkan/present/lsfg_generate.h - renderer_vulkan/present/lsfg_mipmaps.cpp - renderer_vulkan/present/lsfg_mipmaps.h - renderer_vulkan/present/lsfg_shaders.cpp - renderer_vulkan/present/lsfg_shaders.h renderer_vulkan/present/fsr.cpp renderer_vulkan/present/fsr.h renderer_vulkan/present/fxaa.cpp @@ -293,6 +267,38 @@ add_library(video_core STATIC video_core.h ) +if (ENABLE_LSFG) + target_sources(video_core PRIVATE + frame_gen/lossless_dll.cpp + frame_gen/lossless_dll.h + frame_gen/lsfg_translate.cpp + frame_gen/lsfg_translate.h + renderer_vulkan/present/frame_gen.cpp + renderer_vulkan/present/frame_gen.h + renderer_vulkan/present/frame_gen_pacer.cpp + renderer_vulkan/present/frame_gen_pacer.h + renderer_vulkan/present/lsfg_alpha.cpp + renderer_vulkan/present/lsfg_alpha.h + renderer_vulkan/present/lsfg_beta.cpp + renderer_vulkan/present/lsfg_beta.h + renderer_vulkan/present/lsfg_chain.cpp + renderer_vulkan/present/lsfg_chain.h + renderer_vulkan/present/lsfg_common.cpp + renderer_vulkan/present/lsfg_common.h + renderer_vulkan/present/lsfg_delta.cpp + renderer_vulkan/present/lsfg_delta.h + renderer_vulkan/present/lsfg_gamma.cpp + renderer_vulkan/present/lsfg_gamma.h + renderer_vulkan/present/lsfg_generate.cpp + renderer_vulkan/present/lsfg_generate.h + renderer_vulkan/present/lsfg_mipmaps.cpp + renderer_vulkan/present/lsfg_mipmaps.h + renderer_vulkan/present/lsfg_shaders.cpp + renderer_vulkan/present/lsfg_shaders.h + ) + target_compile_definitions(video_core PUBLIC HAS_LSFG) +endif() + if (ENABLE_OPENGL) target_sources(video_core PRIVATE renderer_opengl/present/filters.cpp diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp index 411a9c5fe2..d815278c85 100644 --- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp +++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp @@ -49,6 +49,7 @@ constexpr VkExtent2D CaptureImageSize{ .height = VideoCore::Capture::LinearHeight, }; +#ifdef HAS_LSFG [[nodiscard]] VkExtent2D GuestExtent(std::span framebuffers) { if (framebuffers.empty()) { return VkExtent2D{}; @@ -63,6 +64,7 @@ constexpr VkExtent2D CaptureImageSize{ .height = static_cast(framebuffer.crop_rect.GetHeight()), }; } +#endif constexpr VkExtent3D CaptureImageExtent{ .width = VideoCore::Capture::LinearWidth, @@ -171,7 +173,10 @@ try scheduler, PresentFiltersForAppletCapture) , rasterizer(render_window, gpu, device_memory, device, memory_allocator, state_tracker, scheduler) - , frame_gen(memory_allocator, scheduler) { +#ifdef HAS_LSFG + , frame_gen(memory_allocator, scheduler) +#endif +{ if (Settings::values.renderer_force_max_clock.GetValue() && device.ShouldBoostClocks()) { turbo_mode.emplace(instance, dld); @@ -208,6 +213,7 @@ void RendererVulkan::Composite(std::span framebu render_window.GetFramebufferLayout(), swapchain.GetImageCount(), swapchain.GetImageViewFormat()); +#ifdef HAS_LSFG void(frame_gen.WantedGenerations(present_manager.MaxExtraFrames())); frame_gen.Process(device, frame, swapchain.GetImageFormat(), GuestExtent(framebuffers)); @@ -220,11 +226,14 @@ void RendererVulkan::Composite(std::span framebu scheduler.Flush(*generated->render_ready); present_manager.Present(generated); } +#endif scheduler.Flush(*frame->render_ready); present_manager.Present(frame); +#ifdef HAS_LSFG scheduler.DispatchWork(); +#endif gpu.RendererFrameEndNotify(); rasterizer.TickFrame(); diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.h b/src/video_core/renderer_vulkan/renderer_vulkan.h index 151d829aed..5125fadcd7 100644 --- a/src/video_core/renderer_vulkan/renderer_vulkan.h +++ b/src/video_core/renderer_vulkan/renderer_vulkan.h @@ -13,7 +13,9 @@ #include "common/dynamic_library.h" #include "video_core/host1x/gpu_device_memory_manager.h" #include "video_core/renderer_base.h" +#ifdef HAS_LSFG #include "video_core/renderer_vulkan/present/frame_gen.h" +#endif #include "video_core/renderer_vulkan/vk_blit_screen.h" #include "video_core/renderer_vulkan/vk_present_manager.h" #include "video_core/renderer_vulkan/vk_rasterizer.h" @@ -96,7 +98,9 @@ private: BlitScreen blit_capture; BlitScreen blit_applet; RasterizerVulkan rasterizer; +#ifdef HAS_LSFG FrameGen frame_gen; +#endif std::optional turbo_mode; Frame applet_frame; diff --git a/src/video_core/renderer_vulkan/vk_present_manager.cpp b/src/video_core/renderer_vulkan/vk_present_manager.cpp index 580d35e6d4..9035c56408 100644 --- a/src/video_core/renderer_vulkan/vk_present_manager.cpp +++ b/src/video_core/renderer_vulkan/vk_present_manager.cpp @@ -7,7 +7,9 @@ #include "common/settings.h" #include "common/thread.h" #include "core/frontend/emu_window.h" +#ifdef HAS_LSFG #include "video_core/renderer_vulkan/present/lsfg_common.h" +#endif #include "video_core/renderer_vulkan/vk_present_manager.h" #include "video_core/renderer_vulkan/vk_scheduler.h" #include "video_core/renderer_vulkan/vk_swapchain.h" @@ -21,14 +23,22 @@ namespace Vulkan { namespace { constexpr size_t MAX_FRAMES_IN_FLIGHT = 7; +#ifdef HAS_LSFG static_assert(MAX_FRAMES_IN_FLIGHT <= LSFG_MAX_TARGETS); +#endif bool CanStoreToFrame(const vk::PhysicalDevice& physical_device, VkFormat format) { +#ifdef HAS_LSFG if (!Settings::values.frame_gen.GetValue()) { return false; } const VkFormatProperties props{physical_device.GetFormatProperties(format)}; return (props.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) != 0; +#else + void(physical_device); + void(format); + return false; +#endif } bool CanBlitToSwapchain(const vk::PhysicalDevice& physical_device, VkFormat format) { @@ -350,11 +360,15 @@ void PresentManager::SetImageCount() { // We cannot have more than 7 images in flight at any given time. // FRAMES_IN_FLIGHT is 8, and the cache TICKS_TO_DESTROY is 8. // Mali drivers will give us 6. +#ifdef HAS_LSFG const size_t generations = Settings::FrameGenMaxGenerations(); const size_t queued_composites = Settings::values.frame_gen_queue_target.GetValue() + 1; image_count = std::clamp((generations + 1) * queued_composites, swapchain.GetImageCount(), MAX_FRAMES_IN_FLIGHT); +#else + image_count = std::min(swapchain.GetImageCount(), MAX_FRAMES_IN_FLIGHT); +#endif } void PresentManager::CopyToSwapchain(Frame* frame) {