From 52e0b2a0051cb5653c43d8c5a83bbe8bcecfcbf0 Mon Sep 17 00:00:00 2001 From: CamilleLaVey Date: Wed, 12 Aug 2026 23:43:34 -0400 Subject: [PATCH] Generate pass on lsfg --- src/video_core/CMakeLists.txt | 2 + .../renderer_vulkan/present/lsfg_generate.cpp | 79 +++++++++++++++++++ .../renderer_vulkan/present/lsfg_generate.h | 43 ++++++++++ 3 files changed, 124 insertions(+) create mode 100644 src/video_core/renderer_vulkan/present/lsfg_generate.cpp create mode 100644 src/video_core/renderer_vulkan/present/lsfg_generate.h diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt index d0d2f9045a..13e95bb704 100644 --- a/src/video_core/CMakeLists.txt +++ b/src/video_core/CMakeLists.txt @@ -137,6 +137,8 @@ add_library(video_core STATIC 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 diff --git a/src/video_core/renderer_vulkan/present/lsfg_generate.cpp b/src/video_core/renderer_vulkan/present/lsfg_generate.cpp new file mode 100644 index 0000000000..8498f2487d --- /dev/null +++ b/src/video_core/renderer_vulkan/present/lsfg_generate.cpp @@ -0,0 +1,79 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#include + +#include "video_core/frame_gen/lossless_dll.h" +#include "video_core/renderer_vulkan/present/lsfg_generate.h" +#include "video_core/renderer_vulkan/present/lsfg_shaders.h" +#include "video_core/renderer_vulkan/present/util.h" +#include "video_core/vulkan_common/vulkan_device.h" + +namespace Vulkan { + +namespace { + +constexpr u32 DISPATCH_TILE_SHIFT = 4; + +[[nodiscard]] u32 GroupCount(u32 size) { + return (size + (1u << DISPATCH_TILE_SHIFT) - 1) >> DISPATCH_TILE_SHIFT; +} + +} // Anonymous namespace + +LsfgGenerate::LsfgGenerate(const Device& device, MemoryAllocator& memory_allocator, + const LsfgShaders& shaders, LsfgResources& resources, + vk::DescriptorPool& descriptor_pool, LsfgImagePair& frames_, + LsfgImage& motion_, LsfgImage& detail1_, LsfgImage& detail2_, + VkFormat format) + : frames{&frames_}, motion{&motion_}, detail1{&detail1_}, detail2{&detail2_} { + using namespace VideoCore::FrameGen::PerformanceShader; + + pass = LsfgPass(device, shaders, GENERATE, + {{1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER}, + {2, VK_DESCRIPTOR_TYPE_SAMPLER}, + {5, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE}, + {1, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE}}); + + out_image = LsfgImage(device, memory_allocator, (*frames)[0].Extent(), format); + + const std::vector layouts(descriptor_sets.size(), pass.SetLayout()); + owned_sets = CreateWrappedDescriptorSets(descriptor_pool, layouts); + + const VkSampler sampler = resources.GetSampler(); + const VkSampler edge_sampler = + resources.GetSampler(VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, VK_COMPARE_OP_ALWAYS, false); + const VkBuffer buffer = resources.GetBuffer(LSFG_TIMESTAMP); + + for (size_t i = 0; i < descriptor_sets.size(); ++i) { + descriptor_sets[i] = owned_sets[i]; + LsfgDescriptorWriter(descriptor_sets[i]) + .AddUniformBuffer(buffer, LsfgResources::BufferSize()) + .AddSampler(sampler) + .AddSampler(edge_sampler) + .AddSampledImage((*frames)[1 - i]) + .AddSampledImage((*frames)[i]) + .AddSampledImage(*motion) + .AddSampledImage(*detail1) + .AddSampledImage(*detail2) + .AddStorageImage(out_image) + .Build(device); + } +} + +void LsfgGenerate::Dispatch(vk::CommandBuffer cmdbuf, u64 frame_count) { + const VkExtent2D extent = out_image.Extent(); + + LsfgBarriers(cmdbuf) + .WriteToReadAll(*frames) + .WriteToRead(*motion) + .WriteToRead(*detail1) + .WriteToRead(*detail2) + .ReadToWrite(out_image) + .Build(); + + pass.Bind(cmdbuf, descriptor_sets[frame_count % descriptor_sets.size()]); + cmdbuf.Dispatch(GroupCount(extent.width), GroupCount(extent.height), 1); +} + +} // namespace Vulkan diff --git a/src/video_core/renderer_vulkan/present/lsfg_generate.h b/src/video_core/renderer_vulkan/present/lsfg_generate.h new file mode 100644 index 0000000000..0ee90b4b71 --- /dev/null +++ b/src/video_core/renderer_vulkan/present/lsfg_generate.h @@ -0,0 +1,43 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include + +#include "common/common_types.h" +#include "video_core/renderer_vulkan/present/lsfg_common.h" + +namespace Vulkan { + +class Device; +class LsfgShaders; + +class LsfgGenerate { +public: + LsfgGenerate() = default; + LsfgGenerate(const Device& device, MemoryAllocator& memory_allocator, + const LsfgShaders& shaders, LsfgResources& resources, + vk::DescriptorPool& descriptor_pool, LsfgImagePair& frames, LsfgImage& motion, + LsfgImage& detail1, LsfgImage& detail2, VkFormat format); + + void Dispatch(vk::CommandBuffer cmdbuf, u64 frame_count); + + [[nodiscard]] LsfgImage& Output() { + return out_image; + } + +private: + LsfgImagePair* frames{}; + LsfgImage* motion{}; + LsfgImage* detail1{}; + LsfgImage* detail2{}; + + LsfgPass pass; + std::array descriptor_sets{}; + vk::DescriptorSets owned_sets; + + LsfgImage out_image; +}; + +} // namespace Vulkan