diff --git a/src/dynarmic/src/dynarmic/ir/opt_passes.cpp b/src/dynarmic/src/dynarmic/ir/opt_passes.cpp index 18323936d9..844e29023c 100644 --- a/src/dynarmic/src/dynarmic/ir/opt_passes.cpp +++ b/src/dynarmic/src/dynarmic/ir/opt_passes.cpp @@ -1226,28 +1226,32 @@ static void DeadCodeElimination(IR::Block& block) { } static void IdentityRemovalPass(IR::Block& block) { - boost::container::small_vector to_invalidate; - for (auto it = block.begin(); it != block.end();) { - const size_t num_args = it->NumArgs(); - for (size_t i = 0; i < num_args; ++i) { - IR::Value arg = it->GetArg(i); - if (arg.IsIdentity()) { - do { - arg = arg.GetInst()->GetArg(0); - } while (arg.IsIdentity()); - it->SetArg(i, arg); + boost::container::small_vector to_invalidate; + + auto iter = block.begin(); + while (iter != block.end()) { + IR::Inst& inst = *iter; + + const size_t num_args = inst.NumArgs(); + for (size_t i = 0; i < num_args; i++) { + while (true) { + IR::Value arg = inst.GetArg(i); + if (!arg.IsIdentity()) + break; + inst.SetArg(i, arg.GetInst()->GetArg(0)); } } - if (it->GetOpcode() == IR::Opcode::Identity || it->GetOpcode() == IR::Opcode::Void) { - to_invalidate.push_back(&*it); - it = block.Instructions().erase(it); + if (inst.GetOpcode() == IR::Opcode::Identity || inst.GetOpcode() == IR::Opcode::Void) { + iter = block.Instructions().erase(inst); + to_invalidate.push_back(&inst); } else { - ++it; + ++iter; } } - for (IR::Inst* const inst : to_invalidate) + for (IR::Inst* inst : to_invalidate) { inst->Invalidate(); + } } static void NamingPass(IR::Block& block) { diff --git a/src/shader_recompiler/ir_opt/identity_removal_pass.cpp b/src/shader_recompiler/ir_opt/identity_removal_pass.cpp index 68f8a9ec44..951534bbf2 100644 --- a/src/shader_recompiler/ir_opt/identity_removal_pass.cpp +++ b/src/shader_recompiler/ir_opt/identity_removal_pass.cpp @@ -1,11 +1,7 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project -// SPDX-License-Identifier: GPL-3.0-or-later - // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #include -#include #include "shader_recompiler/frontend/ir/basic_block.h" #include "shader_recompiler/frontend/ir/value.h" @@ -14,30 +10,28 @@ namespace Shader::Optimization { void IdentityRemovalPass(IR::Program& program) { - boost::container::small_vector to_invalidate; + std::vector to_invalidate; for (IR::Block* const block : program.blocks) { - for (auto it = block->begin(); it != block->end();) { - const size_t num_args{it->NumArgs()}; + for (auto inst = block->begin(); inst != block->end();) { + const size_t num_args{inst->NumArgs()}; for (size_t i = 0; i < num_args; ++i) { - IR::Value arg = it->Arg(i); - if (arg.IsIdentity()) { - do { // Pointer chasing (3-derefs) - arg = arg.Inst()->Arg(0); - } while (arg.IsIdentity()); - it->SetArg(i, arg); + IR::Value arg; + while ((arg = inst->Arg(i)).IsIdentity()) { + inst->SetArg(i, arg.Inst()->Arg(0)); } } - - if (it->GetOpcode() == IR::Opcode::Identity || it->GetOpcode() == IR::Opcode::Void) { - to_invalidate.push_back(&*it); - it = block->Instructions().erase(it); + if (inst->GetOpcode() == IR::Opcode::Identity || + inst->GetOpcode() == IR::Opcode::Void) { + to_invalidate.push_back(&*inst); + inst = block->Instructions().erase(inst); } else { - ++it; + ++inst; } } } - for (IR::Inst* const inst : to_invalidate) + for (IR::Inst* const inst : to_invalidate) { inst->Invalidate(); + } } } // namespace Shader::Optimization diff --git a/src/video_core/renderer_opengl/present/layer.cpp b/src/video_core/renderer_opengl/present/layer.cpp index f18600e692..6c7092d229 100644 --- a/src/video_core/renderer_opengl/present/layer.cpp +++ b/src/video_core/renderer_opengl/present/layer.cpp @@ -1,6 +1,3 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project -// SPDX-License-Identifier: GPL-3.0-or-later - // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -57,12 +54,12 @@ GLuint Layer::ConfigureDraw(std::array& out_matrix, switch (anti_aliasing) { case Settings::AntiAliasing::Fxaa: CreateFXAA(); - texture = std::get(anti_alias).Draw(program_manager, info.display_texture); + texture = fxaa->Draw(program_manager, info.display_texture); break; case Settings::AntiAliasing::Smaa: default: CreateSMAA(); - texture = std::get(anti_alias).Draw(program_manager, info.display_texture); + texture = smaa->Draw(program_manager, info.display_texture); break; } } @@ -71,7 +68,7 @@ GLuint Layer::ConfigureDraw(std::array& out_matrix, if (filters.get_scaling_filter() == Settings::ScalingFilter::Fsr) { if (!fsr || fsr->NeedsRecreation(layout.screen)) { - fsr.emplace(layout.screen.GetWidth(), layout.screen.GetHeight()); + fsr = std::make_unique(layout.screen.GetWidth(), layout.screen.GetHeight()); } texture = fsr->Draw(program_manager, texture, info.scaled_width, info.scaled_height, crop); @@ -202,20 +199,23 @@ void Layer::ConfigureFramebufferTexture(const Tegra::FramebufferConfig& framebuf glTextureStorage2D(framebuffer_texture.resource.handle, 1, internal_format, framebuffer_texture.width, framebuffer_texture.height); - anti_alias.emplace(); + fxaa.reset(); + smaa.reset(); } void Layer::CreateFXAA() { - if (!std::holds_alternative(anti_alias)) { - anti_alias.emplace( + smaa.reset(); + if (!fxaa) { + fxaa = std::make_unique( Settings::values.resolution_info.ScaleUp(framebuffer_texture.width), Settings::values.resolution_info.ScaleUp(framebuffer_texture.height)); } } void Layer::CreateSMAA() { - if (!std::holds_alternative(anti_alias)) { - anti_alias.emplace( + fxaa.reset(); + if (!smaa) { + smaa = std::make_unique( Settings::values.resolution_info.ScaleUp(framebuffer_texture.width), Settings::values.resolution_info.ScaleUp(framebuffer_texture.height)); } diff --git a/src/video_core/renderer_opengl/present/layer.h b/src/video_core/renderer_opengl/present/layer.h index e09fd6f696..5b15b730fc 100644 --- a/src/video_core/renderer_opengl/present/layer.h +++ b/src/video_core/renderer_opengl/present/layer.h @@ -1,20 +1,13 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project -// SPDX-License-Identifier: GPL-3.0-or-later - // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #pragma once -#include -#include +#include #include #include "video_core/host1x/gpu_device_memory_manager.h" #include "video_core/renderer_opengl/gl_resource_manager.h" -#include "video_core/renderer_opengl/present/smaa.h" -#include "video_core/renderer_opengl/present/fxaa.h" -#include "video_core/renderer_opengl/present/fsr.h" namespace Layout { struct FramebufferLayout; @@ -33,8 +26,11 @@ struct FramebufferConfig; namespace OpenGL { struct FramebufferTextureInfo; +class FSR; +class FXAA; class ProgramManager; class RasterizerOpenGL; +class SMAA; /// Structure used for storing information about the textures for the Switch screen struct TextureInfo { @@ -80,8 +76,9 @@ private: /// Display information for Switch screen TextureInfo framebuffer_texture; - std::optional fsr; - std::variant anti_alias; + std::unique_ptr fsr; + std::unique_ptr fxaa; + std::unique_ptr smaa; }; } // namespace OpenGL diff --git a/src/video_core/renderer_vulkan/present/anti_alias_pass.h b/src/video_core/renderer_vulkan/present/anti_alias_pass.h index b7d3e2de15..1f20fbd7f0 100644 --- a/src/video_core/renderer_vulkan/present/anti_alias_pass.h +++ b/src/video_core/renderer_vulkan/present/anti_alias_pass.h @@ -1,6 +1,3 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project -// SPDX-License-Identifier: GPL-3.0-or-later - // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -19,4 +16,10 @@ public: VkImageView* inout_image_view) = 0; }; +class NoAA final : public AntiAliasPass { +public: + void Draw(Scheduler& scheduler, size_t image_index, VkImage* inout_image, + VkImageView* inout_image_view) override {} +}; + } // namespace Vulkan diff --git a/src/video_core/renderer_vulkan/present/filters.cpp b/src/video_core/renderer_vulkan/present/filters.cpp index 381031fe6e..e0f2b26f84 100644 --- a/src/video_core/renderer_vulkan/present/filters.cpp +++ b/src/video_core/renderer_vulkan/present/filters.cpp @@ -24,52 +24,61 @@ namespace Vulkan { +namespace { + +vk::ShaderModule SelectScaleForceShader(const Device& device) { + if (device.IsFloat16Supported()) { + return BuildShader(device, VULKAN_PRESENT_SCALEFORCE_FP16_FRAG_SPV); + } else { + return BuildShader(device, VULKAN_PRESENT_SCALEFORCE_FP32_FRAG_SPV); + } +} + +} // Anonymous namespace + std::unique_ptr MakeNearestNeighbor(const Device& device, VkFormat frame_format) { - return std::make_unique(device, frame_format, CreateNearestNeighborSampler(device), - BuildShader(device, VULKAN_PRESENT_FRAG_SPV)); + return std::make_unique(device, frame_format, + CreateNearestNeighborSampler(device), + BuildShader(device, VULKAN_PRESENT_FRAG_SPV)); } std::unique_ptr MakeBilinear(const Device& device, VkFormat frame_format) { return std::make_unique(device, frame_format, CreateBilinearSampler(device), - BuildShader(device, VULKAN_PRESENT_FRAG_SPV)); + BuildShader(device, VULKAN_PRESENT_FRAG_SPV)); } std::unique_ptr MakeSpline1(const Device& device, VkFormat frame_format) { return std::make_unique(device, frame_format, CreateBilinearSampler(device), - BuildShader(device, PRESENT_SPLINE1_FRAG_SPV)); + BuildShader(device, PRESENT_SPLINE1_FRAG_SPV)); } std::unique_ptr MakeBicubic(const Device& device, VkFormat frame_format) { // No need for handrolled shader -- if the VK impl can do it for us ;) if (device.IsExtFilterCubicSupported()) return std::make_unique(device, frame_format, CreateCubicSampler(device), - BuildShader(device, VULKAN_PRESENT_FRAG_SPV)); + BuildShader(device, VULKAN_PRESENT_FRAG_SPV)); return std::make_unique(device, frame_format, CreateBilinearSampler(device), - BuildShader(device, PRESENT_BICUBIC_FRAG_SPV)); + BuildShader(device, PRESENT_BICUBIC_FRAG_SPV)); } std::unique_ptr MakeGaussian(const Device& device, VkFormat frame_format) { return std::make_unique(device, frame_format, CreateBilinearSampler(device), - BuildShader(device, PRESENT_GAUSSIAN_FRAG_SPV)); + BuildShader(device, PRESENT_GAUSSIAN_FRAG_SPV)); } std::unique_ptr MakeLanczos(const Device& device, VkFormat frame_format) { return std::make_unique(device, frame_format, CreateBilinearSampler(device), - BuildShader(device, PRESENT_LANCZOS_FRAG_SPV)); + BuildShader(device, PRESENT_LANCZOS_FRAG_SPV)); } std::unique_ptr MakeScaleForce(const Device& device, VkFormat frame_format) { - auto const select_fn = [&]() { - return device.IsFloat16Supported() - ? BuildShader(device, VULKAN_PRESENT_SCALEFORCE_FP16_FRAG_SPV) - : BuildShader(device, VULKAN_PRESENT_SCALEFORCE_FP32_FRAG_SPV); - }; - return std::make_unique(device, frame_format, CreateBilinearSampler(device), select_fn()); + return std::make_unique(device, frame_format, CreateBilinearSampler(device), + SelectScaleForceShader(device)); } std::unique_ptr MakeArea(const Device& device, VkFormat frame_format) { return std::make_unique(device, frame_format, CreateBilinearSampler(device), - BuildShader(device, PRESENT_AREA_FRAG_SPV)); + BuildShader(device, PRESENT_AREA_FRAG_SPV)); } } // namespace Vulkan diff --git a/src/video_core/renderer_vulkan/present/fsr.cpp b/src/video_core/renderer_vulkan/present/fsr.cpp index 24fc61e813..3f708be704 100644 --- a/src/video_core/renderer_vulkan/present/fsr.cpp +++ b/src/video_core/renderer_vulkan/present/fsr.cpp @@ -1,6 +1,3 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project -// SPDX-License-Identifier: GPL-3.0-or-later - // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -44,18 +41,25 @@ FSR::FSR(const Device& device, MemoryAllocator& memory_allocator, size_t image_c void FSR::CreateImages() { m_dynamic_images.resize(m_image_count); for (auto& images : m_dynamic_images) { - images.images[Easu] = CreateWrappedImage(m_memory_allocator, m_extent, VK_FORMAT_R16G16B16A16_SFLOAT); - images.images[Rcas] = CreateWrappedImage(m_memory_allocator, m_extent, VK_FORMAT_R16G16B16A16_SFLOAT); - images.image_views[Easu] = CreateWrappedImageView(m_device, images.images[Easu], VK_FORMAT_R16G16B16A16_SFLOAT); - images.image_views[Rcas] = CreateWrappedImageView(m_device, images.images[Rcas], VK_FORMAT_R16G16B16A16_SFLOAT); + images.images[Easu] = + CreateWrappedImage(m_memory_allocator, m_extent, VK_FORMAT_R16G16B16A16_SFLOAT); + images.images[Rcas] = + CreateWrappedImage(m_memory_allocator, m_extent, VK_FORMAT_R16G16B16A16_SFLOAT); + images.image_views[Easu] = + CreateWrappedImageView(m_device, images.images[Easu], VK_FORMAT_R16G16B16A16_SFLOAT); + images.image_views[Rcas] = + CreateWrappedImageView(m_device, images.images[Rcas], VK_FORMAT_R16G16B16A16_SFLOAT); } } void FSR::CreateRenderPasses() { m_renderpass = CreateWrappedRenderPass(m_device, VK_FORMAT_R16G16B16A16_SFLOAT); + for (auto& images : m_dynamic_images) { - images.framebuffers[Easu] = CreateWrappedFramebuffer(m_device, m_renderpass, images.image_views[Easu], m_extent); - images.framebuffers[Rcas] = CreateWrappedFramebuffer(m_device, m_renderpass, images.image_views[Rcas], m_extent); + images.framebuffers[Easu] = + CreateWrappedFramebuffer(m_device, m_renderpass, images.image_views[Easu], m_extent); + images.framebuffers[Rcas] = + CreateWrappedFramebuffer(m_device, m_renderpass, images.image_views[Rcas], m_extent); } } @@ -83,13 +87,16 @@ void FSR::CreateDescriptorPool() { } void FSR::CreateDescriptorSetLayout() { - m_descriptor_set_layout = CreateWrappedDescriptorSetLayout(m_device, {VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER}); + m_descriptor_set_layout = + CreateWrappedDescriptorSetLayout(m_device, {VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER}); } void FSR::CreateDescriptorSets() { std::vector layouts(MaxFsrStage, *m_descriptor_set_layout); - for (auto& images : m_dynamic_images) + + for (auto& images : m_dynamic_images) { images.descriptor_sets = CreateWrappedDescriptorSets(m_descriptor_pool, layouts); + } } void FSR::CreatePipelineLayouts() { @@ -121,24 +128,31 @@ void FSR::CreatePipelines() { void FSR::UpdateDescriptorSets(VkImageView image_view, size_t image_index) { Images& images = m_dynamic_images[image_index]; std::vector image_infos; - std::vector updates{ - CreateWriteDescriptorSet(image_infos, *m_sampler, image_view, images.descriptor_sets[Easu], 0), - CreateWriteDescriptorSet(image_infos, *m_sampler, *images.image_views[Easu], images.descriptor_sets[Rcas], 0) - }; + std::vector updates; + image_infos.reserve(2); + + updates.push_back(CreateWriteDescriptorSet(image_infos, *m_sampler, image_view, + images.descriptor_sets[Easu], 0)); + updates.push_back(CreateWriteDescriptorSet(image_infos, *m_sampler, *images.image_views[Easu], + images.descriptor_sets[Rcas], 0)); + m_device.GetLogical().UpdateDescriptorSets(updates, {}); } void FSR::UploadImages(Scheduler& scheduler) { - if (!m_images_ready) { - m_images_ready = true; - scheduler.Record([&](vk::CommandBuffer cmdbuf) { - for (auto& image : m_dynamic_images) { - ClearColorImage(cmdbuf, *image.images[Easu]); - ClearColorImage(cmdbuf, *image.images[Rcas]); - } - }); - scheduler.Finish(); + if (m_images_ready) { + return; } + + scheduler.Record([&](vk::CommandBuffer cmdbuf) { + for (auto& image : m_dynamic_images) { + ClearColorImage(cmdbuf, *image.images[Easu]); + ClearColorImage(cmdbuf, *image.images[Rcas]); + } + }); + scheduler.Finish(); + + m_images_ready = true; } VkImageView FSR::Draw(Scheduler& scheduler, size_t image_index, VkImage source_image, diff --git a/src/video_core/renderer_vulkan/present/layer.cpp b/src/video_core/renderer_vulkan/present/layer.cpp index 9946335fa3..fa7c457573 100644 --- a/src/video_core/renderer_vulkan/present/layer.cpp +++ b/src/video_core/renderer_vulkan/present/layer.cpp @@ -4,12 +4,7 @@ // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -#include #include "video_core/present.h" -#include "video_core/renderer_vulkan/present/anti_alias_pass.h" -/* X11 defines */ -#undef Success -#undef BadValue #include "video_core/renderer_vulkan/vk_rasterizer.h" #include "common/settings.h" @@ -63,7 +58,7 @@ Layer::Layer(const Device& device_, MemoryAllocator& memory_allocator_, Schedule CreateDescriptorPool(); CreateDescriptorSets(layout); if (filters.get_scaling_filter() == Settings::ScalingFilter::Fsr) { - fsr.emplace(device, memory_allocator, image_count, output_size); + CreateFSR(output_size); } } @@ -102,11 +97,7 @@ void Layer::ConfigureDraw(PresentPushConstants* out_push_constants, VkImageView source_image_view = texture_info ? texture_info->image_view : *raw_image_views[image_index]; - if (std::holds_alternative(anti_alias)) { - std::get(anti_alias).Draw(scheduler, image_index, &source_image, &source_image_view); - } else if (std::holds_alternative(anti_alias)) { - std::get(anti_alias).Draw(scheduler, image_index, &source_image, &source_image_view); - } + anti_alias->Draw(scheduler, image_index, &source_image, &source_image_view); auto crop_rect = Tegra::NormalizeCrop(framebuffer, texture_width, texture_height); const VkExtent2D render_extent{ @@ -165,6 +156,10 @@ void Layer::CreateRawImages(const Tegra::FramebufferConfig& framebuffer) { } } +void Layer::CreateFSR(VkExtent2D output_size) { + fsr = std::make_unique(device, memory_allocator, image_count, output_size); +} + void Layer::RefreshResources(const Tegra::FramebufferConfig& framebuffer) { if (framebuffer.width == raw_width && framebuffer.height == raw_height && framebuffer.pixel_format == pixel_format && !raw_images.empty()) { @@ -174,7 +169,7 @@ void Layer::RefreshResources(const Tegra::FramebufferConfig& framebuffer) { raw_width = framebuffer.width; raw_height = framebuffer.height; pixel_format = framebuffer.pixel_format; - anti_alias.emplace(); + anti_alias.reset(); ReleaseRawImages(); CreateStagingBuffer(framebuffer); @@ -182,8 +177,9 @@ void Layer::RefreshResources(const Tegra::FramebufferConfig& framebuffer) { } void Layer::SetAntiAliasPass() { - if (!std::holds_alternative(anti_alias) && anti_alias_setting == filters.get_anti_aliasing()) + if (anti_alias && anti_alias_setting == filters.get_anti_aliasing()) { return; + } anti_alias_setting = filters.get_anti_aliasing(); @@ -194,13 +190,13 @@ void Layer::SetAntiAliasPass() { switch (anti_alias_setting) { case Settings::AntiAliasing::Fxaa: - anti_alias.emplace(device, memory_allocator, image_count, render_area); + anti_alias = std::make_unique(device, memory_allocator, image_count, render_area); break; case Settings::AntiAliasing::Smaa: - anti_alias.emplace(device, memory_allocator, image_count, render_area); + anti_alias = std::make_unique(device, memory_allocator, image_count, render_area); break; default: - anti_alias.emplace(); + anti_alias = std::make_unique(); break; } } diff --git a/src/video_core/renderer_vulkan/present/layer.h b/src/video_core/renderer_vulkan/present/layer.h index 062b7792c4..f5effdcd7f 100644 --- a/src/video_core/renderer_vulkan/present/layer.h +++ b/src/video_core/renderer_vulkan/present/layer.h @@ -1,20 +1,11 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project -// SPDX-License-Identifier: GPL-3.0-or-later - // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #pragma once -#include -#include - #include "common/math_util.h" #include "video_core/host1x/gpu_device_memory_manager.h" #include "video_core/vulkan_common/vulkan_wrapper.h" -#include "video_core/renderer_vulkan/present/fsr.h" -#include "video_core/renderer_vulkan/present/fxaa.h" -#include "video_core/renderer_vulkan/present/smaa.h" namespace Layout { struct FramebufferLayout; @@ -38,6 +29,7 @@ namespace Vulkan { class AntiAliasPass; class Device; +class FSR; class MemoryAllocator; struct PresentPushConstants; class RasterizerVulkan; @@ -62,6 +54,7 @@ private: void CreateDescriptorSets(VkDescriptorSetLayout layout); void CreateStagingBuffer(const Tegra::FramebufferConfig& framebuffer); void CreateRawImages(const Tegra::FramebufferConfig& framebuffer); + void CreateFSR(VkExtent2D output_size); void RefreshResources(const Tegra::FramebufferConfig& framebuffer); void SetAntiAliasPass(); @@ -94,8 +87,9 @@ private: Service::android::PixelFormat pixel_format{}; Settings::AntiAliasing anti_alias_setting{}; - std::variant anti_alias{}; - std::optional fsr{}; + std::unique_ptr anti_alias{}; + + std::unique_ptr fsr{}; std::vector resource_ticks{}; };