Compare commits

..

1 commit

Author SHA1 Message Date
dba05cbcab
[dist, docs] Clearer wording for settings, guidelines for new settings
All checks were successful
eden-license / license-header (pull_request) Successful in 19s
Signed-off-by: lizzie <lizzie@eden-emu.dev>
2025-09-25 00:24:41 +00:00
9 changed files with 135 additions and 124 deletions

View file

@ -1226,28 +1226,32 @@ static void DeadCodeElimination(IR::Block& block) {
} }
static void IdentityRemovalPass(IR::Block& block) { static void IdentityRemovalPass(IR::Block& block) {
boost::container::small_vector<IR::Inst*, 16> to_invalidate; boost::container::small_vector<IR::Inst*, 128> to_invalidate;
for (auto it = block.begin(); it != block.end();) {
const size_t num_args = it->NumArgs(); auto iter = block.begin();
for (size_t i = 0; i < num_args; ++i) { while (iter != block.end()) {
IR::Value arg = it->GetArg(i); IR::Inst& inst = *iter;
if (arg.IsIdentity()) {
do { const size_t num_args = inst.NumArgs();
arg = arg.GetInst()->GetArg(0); for (size_t i = 0; i < num_args; i++) {
} while (arg.IsIdentity()); while (true) {
it->SetArg(i, arg); 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) { if (inst.GetOpcode() == IR::Opcode::Identity || inst.GetOpcode() == IR::Opcode::Void) {
to_invalidate.push_back(&*it); iter = block.Instructions().erase(inst);
it = block.Instructions().erase(it); to_invalidate.push_back(&inst);
} else { } else {
++it; ++iter;
} }
} }
for (IR::Inst* const inst : to_invalidate) for (IR::Inst* inst : to_invalidate) {
inst->Invalidate(); inst->Invalidate();
}
} }
static void NamingPass(IR::Block& block) { static void NamingPass(IR::Block& block) {

View file

@ -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-FileCopyrightText: Copyright 2021 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#include <vector> #include <vector>
#include <boost/container/small_vector.hpp>
#include "shader_recompiler/frontend/ir/basic_block.h" #include "shader_recompiler/frontend/ir/basic_block.h"
#include "shader_recompiler/frontend/ir/value.h" #include "shader_recompiler/frontend/ir/value.h"
@ -14,30 +10,28 @@
namespace Shader::Optimization { namespace Shader::Optimization {
void IdentityRemovalPass(IR::Program& program) { void IdentityRemovalPass(IR::Program& program) {
boost::container::small_vector<IR::Inst*, 16> to_invalidate; std::vector<IR::Inst*> to_invalidate;
for (IR::Block* const block : program.blocks) { for (IR::Block* const block : program.blocks) {
for (auto it = block->begin(); it != block->end();) { for (auto inst = block->begin(); inst != block->end();) {
const size_t num_args{it->NumArgs()}; const size_t num_args{inst->NumArgs()};
for (size_t i = 0; i < num_args; ++i) { for (size_t i = 0; i < num_args; ++i) {
IR::Value arg = it->Arg(i); IR::Value arg;
if (arg.IsIdentity()) { while ((arg = inst->Arg(i)).IsIdentity()) {
do { // Pointer chasing (3-derefs) inst->SetArg(i, arg.Inst()->Arg(0));
arg = arg.Inst()->Arg(0);
} while (arg.IsIdentity());
it->SetArg(i, arg);
} }
} }
if (inst->GetOpcode() == IR::Opcode::Identity ||
if (it->GetOpcode() == IR::Opcode::Identity || it->GetOpcode() == IR::Opcode::Void) { inst->GetOpcode() == IR::Opcode::Void) {
to_invalidate.push_back(&*it); to_invalidate.push_back(&*inst);
it = block->Instructions().erase(it); inst = block->Instructions().erase(inst);
} else { } else {
++it; ++inst;
} }
} }
} }
for (IR::Inst* const inst : to_invalidate) for (IR::Inst* const inst : to_invalidate) {
inst->Invalidate(); inst->Invalidate();
}
} }
} // namespace Shader::Optimization } // namespace Shader::Optimization

View file

@ -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-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@ -57,12 +54,12 @@ GLuint Layer::ConfigureDraw(std::array<GLfloat, 3 * 2>& out_matrix,
switch (anti_aliasing) { switch (anti_aliasing) {
case Settings::AntiAliasing::Fxaa: case Settings::AntiAliasing::Fxaa:
CreateFXAA(); CreateFXAA();
texture = std::get<FXAA>(anti_alias).Draw(program_manager, info.display_texture); texture = fxaa->Draw(program_manager, info.display_texture);
break; break;
case Settings::AntiAliasing::Smaa: case Settings::AntiAliasing::Smaa:
default: default:
CreateSMAA(); CreateSMAA();
texture = std::get<SMAA>(anti_alias).Draw(program_manager, info.display_texture); texture = smaa->Draw(program_manager, info.display_texture);
break; break;
} }
} }
@ -71,7 +68,7 @@ GLuint Layer::ConfigureDraw(std::array<GLfloat, 3 * 2>& out_matrix,
if (filters.get_scaling_filter() == Settings::ScalingFilter::Fsr) { if (filters.get_scaling_filter() == Settings::ScalingFilter::Fsr) {
if (!fsr || fsr->NeedsRecreation(layout.screen)) { if (!fsr || fsr->NeedsRecreation(layout.screen)) {
fsr.emplace(layout.screen.GetWidth(), layout.screen.GetHeight()); fsr = std::make_unique<FSR>(layout.screen.GetWidth(), layout.screen.GetHeight());
} }
texture = fsr->Draw(program_manager, texture, info.scaled_width, info.scaled_height, crop); 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, glTextureStorage2D(framebuffer_texture.resource.handle, 1, internal_format,
framebuffer_texture.width, framebuffer_texture.height); framebuffer_texture.width, framebuffer_texture.height);
anti_alias.emplace<std::monostate>(); fxaa.reset();
smaa.reset();
} }
void Layer::CreateFXAA() { void Layer::CreateFXAA() {
if (!std::holds_alternative<FXAA>(anti_alias)) { smaa.reset();
anti_alias.emplace<FXAA>( if (!fxaa) {
fxaa = std::make_unique<FXAA>(
Settings::values.resolution_info.ScaleUp(framebuffer_texture.width), Settings::values.resolution_info.ScaleUp(framebuffer_texture.width),
Settings::values.resolution_info.ScaleUp(framebuffer_texture.height)); Settings::values.resolution_info.ScaleUp(framebuffer_texture.height));
} }
} }
void Layer::CreateSMAA() { void Layer::CreateSMAA() {
if (!std::holds_alternative<SMAA>(anti_alias)) { fxaa.reset();
anti_alias.emplace<SMAA>( if (!smaa) {
smaa = std::make_unique<SMAA>(
Settings::values.resolution_info.ScaleUp(framebuffer_texture.width), Settings::values.resolution_info.ScaleUp(framebuffer_texture.width),
Settings::values.resolution_info.ScaleUp(framebuffer_texture.height)); Settings::values.resolution_info.ScaleUp(framebuffer_texture.height));
} }

View file

@ -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-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#pragma once #pragma once
#include <optional> #include <memory>
#include <variant>
#include <vector> #include <vector>
#include "video_core/host1x/gpu_device_memory_manager.h" #include "video_core/host1x/gpu_device_memory_manager.h"
#include "video_core/renderer_opengl/gl_resource_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 { namespace Layout {
struct FramebufferLayout; struct FramebufferLayout;
@ -33,8 +26,11 @@ struct FramebufferConfig;
namespace OpenGL { namespace OpenGL {
struct FramebufferTextureInfo; struct FramebufferTextureInfo;
class FSR;
class FXAA;
class ProgramManager; class ProgramManager;
class RasterizerOpenGL; class RasterizerOpenGL;
class SMAA;
/// Structure used for storing information about the textures for the Switch screen /// Structure used for storing information about the textures for the Switch screen
struct TextureInfo { struct TextureInfo {
@ -80,8 +76,9 @@ private:
/// Display information for Switch screen /// Display information for Switch screen
TextureInfo framebuffer_texture; TextureInfo framebuffer_texture;
std::optional<FSR> fsr; std::unique_ptr<FSR> fsr;
std::variant<std::monostate, FXAA, SMAA> anti_alias; std::unique_ptr<FXAA> fxaa;
std::unique_ptr<SMAA> smaa;
}; };
} // namespace OpenGL } // namespace OpenGL

View file

@ -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-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@ -19,4 +16,10 @@ public:
VkImageView* inout_image_view) = 0; 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 } // namespace Vulkan

View file

@ -24,52 +24,61 @@
namespace Vulkan { 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<WindowAdaptPass> MakeNearestNeighbor(const Device& device, VkFormat frame_format) { std::unique_ptr<WindowAdaptPass> MakeNearestNeighbor(const Device& device, VkFormat frame_format) {
return std::make_unique<WindowAdaptPass>(device, frame_format, CreateNearestNeighborSampler(device), return std::make_unique<WindowAdaptPass>(device, frame_format,
BuildShader(device, VULKAN_PRESENT_FRAG_SPV)); CreateNearestNeighborSampler(device),
BuildShader(device, VULKAN_PRESENT_FRAG_SPV));
} }
std::unique_ptr<WindowAdaptPass> MakeBilinear(const Device& device, VkFormat frame_format) { std::unique_ptr<WindowAdaptPass> MakeBilinear(const Device& device, VkFormat frame_format) {
return std::make_unique<WindowAdaptPass>(device, frame_format, CreateBilinearSampler(device), return std::make_unique<WindowAdaptPass>(device, frame_format, CreateBilinearSampler(device),
BuildShader(device, VULKAN_PRESENT_FRAG_SPV)); BuildShader(device, VULKAN_PRESENT_FRAG_SPV));
} }
std::unique_ptr<WindowAdaptPass> MakeSpline1(const Device& device, VkFormat frame_format) { std::unique_ptr<WindowAdaptPass> MakeSpline1(const Device& device, VkFormat frame_format) {
return std::make_unique<WindowAdaptPass>(device, frame_format, CreateBilinearSampler(device), return std::make_unique<WindowAdaptPass>(device, frame_format, CreateBilinearSampler(device),
BuildShader(device, PRESENT_SPLINE1_FRAG_SPV)); BuildShader(device, PRESENT_SPLINE1_FRAG_SPV));
} }
std::unique_ptr<WindowAdaptPass> MakeBicubic(const Device& device, VkFormat frame_format) { std::unique_ptr<WindowAdaptPass> MakeBicubic(const Device& device, VkFormat frame_format) {
// No need for handrolled shader -- if the VK impl can do it for us ;) // No need for handrolled shader -- if the VK impl can do it for us ;)
if (device.IsExtFilterCubicSupported()) if (device.IsExtFilterCubicSupported())
return std::make_unique<WindowAdaptPass>(device, frame_format, CreateCubicSampler(device), return std::make_unique<WindowAdaptPass>(device, frame_format, CreateCubicSampler(device),
BuildShader(device, VULKAN_PRESENT_FRAG_SPV)); BuildShader(device, VULKAN_PRESENT_FRAG_SPV));
return std::make_unique<WindowAdaptPass>(device, frame_format, CreateBilinearSampler(device), return std::make_unique<WindowAdaptPass>(device, frame_format, CreateBilinearSampler(device),
BuildShader(device, PRESENT_BICUBIC_FRAG_SPV)); BuildShader(device, PRESENT_BICUBIC_FRAG_SPV));
} }
std::unique_ptr<WindowAdaptPass> MakeGaussian(const Device& device, VkFormat frame_format) { std::unique_ptr<WindowAdaptPass> MakeGaussian(const Device& device, VkFormat frame_format) {
return std::make_unique<WindowAdaptPass>(device, frame_format, CreateBilinearSampler(device), return std::make_unique<WindowAdaptPass>(device, frame_format, CreateBilinearSampler(device),
BuildShader(device, PRESENT_GAUSSIAN_FRAG_SPV)); BuildShader(device, PRESENT_GAUSSIAN_FRAG_SPV));
} }
std::unique_ptr<WindowAdaptPass> MakeLanczos(const Device& device, VkFormat frame_format) { std::unique_ptr<WindowAdaptPass> MakeLanczos(const Device& device, VkFormat frame_format) {
return std::make_unique<WindowAdaptPass>(device, frame_format, CreateBilinearSampler(device), return std::make_unique<WindowAdaptPass>(device, frame_format, CreateBilinearSampler(device),
BuildShader(device, PRESENT_LANCZOS_FRAG_SPV)); BuildShader(device, PRESENT_LANCZOS_FRAG_SPV));
} }
std::unique_ptr<WindowAdaptPass> MakeScaleForce(const Device& device, VkFormat frame_format) { std::unique_ptr<WindowAdaptPass> MakeScaleForce(const Device& device, VkFormat frame_format) {
auto const select_fn = [&]() { return std::make_unique<WindowAdaptPass>(device, frame_format, CreateBilinearSampler(device),
return device.IsFloat16Supported() SelectScaleForceShader(device));
? BuildShader(device, VULKAN_PRESENT_SCALEFORCE_FP16_FRAG_SPV)
: BuildShader(device, VULKAN_PRESENT_SCALEFORCE_FP32_FRAG_SPV);
};
return std::make_unique<WindowAdaptPass>(device, frame_format, CreateBilinearSampler(device), select_fn());
} }
std::unique_ptr<WindowAdaptPass> MakeArea(const Device& device, VkFormat frame_format) { std::unique_ptr<WindowAdaptPass> MakeArea(const Device& device, VkFormat frame_format) {
return std::make_unique<WindowAdaptPass>(device, frame_format, CreateBilinearSampler(device), return std::make_unique<WindowAdaptPass>(device, frame_format, CreateBilinearSampler(device),
BuildShader(device, PRESENT_AREA_FRAG_SPV)); BuildShader(device, PRESENT_AREA_FRAG_SPV));
} }
} // namespace Vulkan } // namespace Vulkan

View file

@ -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-FileCopyrightText: Copyright 2021 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // 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() { void FSR::CreateImages() {
m_dynamic_images.resize(m_image_count); m_dynamic_images.resize(m_image_count);
for (auto& images : m_dynamic_images) { for (auto& images : m_dynamic_images) {
images.images[Easu] = CreateWrappedImage(m_memory_allocator, m_extent, VK_FORMAT_R16G16B16A16_SFLOAT); images.images[Easu] =
images.images[Rcas] = CreateWrappedImage(m_memory_allocator, m_extent, VK_FORMAT_R16G16B16A16_SFLOAT); 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.images[Rcas] =
images.image_views[Rcas] = CreateWrappedImageView(m_device, images.images[Rcas], VK_FORMAT_R16G16B16A16_SFLOAT); 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() { void FSR::CreateRenderPasses() {
m_renderpass = CreateWrappedRenderPass(m_device, VK_FORMAT_R16G16B16A16_SFLOAT); m_renderpass = CreateWrappedRenderPass(m_device, VK_FORMAT_R16G16B16A16_SFLOAT);
for (auto& images : m_dynamic_images) { for (auto& images : m_dynamic_images) {
images.framebuffers[Easu] = CreateWrappedFramebuffer(m_device, m_renderpass, images.image_views[Easu], m_extent); images.framebuffers[Easu] =
images.framebuffers[Rcas] = CreateWrappedFramebuffer(m_device, m_renderpass, images.image_views[Rcas], m_extent); 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() { 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() { void FSR::CreateDescriptorSets() {
std::vector<VkDescriptorSetLayout> layouts(MaxFsrStage, *m_descriptor_set_layout); std::vector<VkDescriptorSetLayout> 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); images.descriptor_sets = CreateWrappedDescriptorSets(m_descriptor_pool, layouts);
}
} }
void FSR::CreatePipelineLayouts() { void FSR::CreatePipelineLayouts() {
@ -121,24 +128,31 @@ void FSR::CreatePipelines() {
void FSR::UpdateDescriptorSets(VkImageView image_view, size_t image_index) { void FSR::UpdateDescriptorSets(VkImageView image_view, size_t image_index) {
Images& images = m_dynamic_images[image_index]; Images& images = m_dynamic_images[image_index];
std::vector<VkDescriptorImageInfo> image_infos; std::vector<VkDescriptorImageInfo> image_infos;
std::vector<VkWriteDescriptorSet> updates{ std::vector<VkWriteDescriptorSet> updates;
CreateWriteDescriptorSet(image_infos, *m_sampler, image_view, images.descriptor_sets[Easu], 0), image_infos.reserve(2);
CreateWriteDescriptorSet(image_infos, *m_sampler, *images.image_views[Easu], images.descriptor_sets[Rcas], 0)
}; 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, {}); m_device.GetLogical().UpdateDescriptorSets(updates, {});
} }
void FSR::UploadImages(Scheduler& scheduler) { void FSR::UploadImages(Scheduler& scheduler) {
if (!m_images_ready) { if (m_images_ready) {
m_images_ready = true; return;
scheduler.Record([&](vk::CommandBuffer cmdbuf) {
for (auto& image : m_dynamic_images) {
ClearColorImage(cmdbuf, *image.images[Easu]);
ClearColorImage(cmdbuf, *image.images[Rcas]);
}
});
scheduler.Finish();
} }
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, VkImageView FSR::Draw(Scheduler& scheduler, size_t image_index, VkImage source_image,

View file

@ -4,12 +4,7 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#include <variant>
#include "video_core/present.h" #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 "video_core/renderer_vulkan/vk_rasterizer.h"
#include "common/settings.h" #include "common/settings.h"
@ -63,7 +58,7 @@ Layer::Layer(const Device& device_, MemoryAllocator& memory_allocator_, Schedule
CreateDescriptorPool(); CreateDescriptorPool();
CreateDescriptorSets(layout); CreateDescriptorSets(layout);
if (filters.get_scaling_filter() == Settings::ScalingFilter::Fsr) { 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 = VkImageView source_image_view =
texture_info ? texture_info->image_view : *raw_image_views[image_index]; texture_info ? texture_info->image_view : *raw_image_views[image_index];
if (std::holds_alternative<FXAA>(anti_alias)) { anti_alias->Draw(scheduler, image_index, &source_image, &source_image_view);
std::get<FXAA>(anti_alias).Draw(scheduler, image_index, &source_image, &source_image_view);
} else if (std::holds_alternative<SMAA>(anti_alias)) {
std::get<SMAA>(anti_alias).Draw(scheduler, image_index, &source_image, &source_image_view);
}
auto crop_rect = Tegra::NormalizeCrop(framebuffer, texture_width, texture_height); auto crop_rect = Tegra::NormalizeCrop(framebuffer, texture_width, texture_height);
const VkExtent2D render_extent{ 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<FSR>(device, memory_allocator, image_count, output_size);
}
void Layer::RefreshResources(const Tegra::FramebufferConfig& framebuffer) { void Layer::RefreshResources(const Tegra::FramebufferConfig& framebuffer) {
if (framebuffer.width == raw_width && framebuffer.height == raw_height && if (framebuffer.width == raw_width && framebuffer.height == raw_height &&
framebuffer.pixel_format == pixel_format && !raw_images.empty()) { framebuffer.pixel_format == pixel_format && !raw_images.empty()) {
@ -174,7 +169,7 @@ void Layer::RefreshResources(const Tegra::FramebufferConfig& framebuffer) {
raw_width = framebuffer.width; raw_width = framebuffer.width;
raw_height = framebuffer.height; raw_height = framebuffer.height;
pixel_format = framebuffer.pixel_format; pixel_format = framebuffer.pixel_format;
anti_alias.emplace<std::monostate>(); anti_alias.reset();
ReleaseRawImages(); ReleaseRawImages();
CreateStagingBuffer(framebuffer); CreateStagingBuffer(framebuffer);
@ -182,8 +177,9 @@ void Layer::RefreshResources(const Tegra::FramebufferConfig& framebuffer) {
} }
void Layer::SetAntiAliasPass() { void Layer::SetAntiAliasPass() {
if (!std::holds_alternative<std::monostate>(anti_alias) && anti_alias_setting == filters.get_anti_aliasing()) if (anti_alias && anti_alias_setting == filters.get_anti_aliasing()) {
return; return;
}
anti_alias_setting = filters.get_anti_aliasing(); anti_alias_setting = filters.get_anti_aliasing();
@ -194,13 +190,13 @@ void Layer::SetAntiAliasPass() {
switch (anti_alias_setting) { switch (anti_alias_setting) {
case Settings::AntiAliasing::Fxaa: case Settings::AntiAliasing::Fxaa:
anti_alias.emplace<FXAA>(device, memory_allocator, image_count, render_area); anti_alias = std::make_unique<FXAA>(device, memory_allocator, image_count, render_area);
break; break;
case Settings::AntiAliasing::Smaa: case Settings::AntiAliasing::Smaa:
anti_alias.emplace<SMAA>(device, memory_allocator, image_count, render_area); anti_alias = std::make_unique<SMAA>(device, memory_allocator, image_count, render_area);
break; break;
default: default:
anti_alias.emplace<std::monostate>(); anti_alias = std::make_unique<NoAA>();
break; break;
} }
} }

View file

@ -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-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#pragma once #pragma once
#include <optional>
#include <variant>
#include "common/math_util.h" #include "common/math_util.h"
#include "video_core/host1x/gpu_device_memory_manager.h" #include "video_core/host1x/gpu_device_memory_manager.h"
#include "video_core/vulkan_common/vulkan_wrapper.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 { namespace Layout {
struct FramebufferLayout; struct FramebufferLayout;
@ -38,6 +29,7 @@ namespace Vulkan {
class AntiAliasPass; class AntiAliasPass;
class Device; class Device;
class FSR;
class MemoryAllocator; class MemoryAllocator;
struct PresentPushConstants; struct PresentPushConstants;
class RasterizerVulkan; class RasterizerVulkan;
@ -62,6 +54,7 @@ private:
void CreateDescriptorSets(VkDescriptorSetLayout layout); void CreateDescriptorSets(VkDescriptorSetLayout layout);
void CreateStagingBuffer(const Tegra::FramebufferConfig& framebuffer); void CreateStagingBuffer(const Tegra::FramebufferConfig& framebuffer);
void CreateRawImages(const Tegra::FramebufferConfig& framebuffer); void CreateRawImages(const Tegra::FramebufferConfig& framebuffer);
void CreateFSR(VkExtent2D output_size);
void RefreshResources(const Tegra::FramebufferConfig& framebuffer); void RefreshResources(const Tegra::FramebufferConfig& framebuffer);
void SetAntiAliasPass(); void SetAntiAliasPass();
@ -94,8 +87,9 @@ private:
Service::android::PixelFormat pixel_format{}; Service::android::PixelFormat pixel_format{};
Settings::AntiAliasing anti_alias_setting{}; Settings::AntiAliasing anti_alias_setting{};
std::variant<std::monostate, FXAA, SMAA> anti_alias{}; std::unique_ptr<AntiAliasPass> anti_alias{};
std::optional<FSR> fsr{};
std::unique_ptr<FSR> fsr{};
std::vector<u64> resource_ticks{}; std::vector<u64> resource_ticks{};
}; };