gpu: dependency-inject scaling/antialiasing filter state for capture layers

This commit is contained in:
Liam 2024-01-27 19:10:22 -05:00
parent 0cb413c3d3
commit 78aac6b403
12 changed files with 93 additions and 31 deletions

View file

@ -102,6 +102,7 @@ add_library(video_core STATIC
memory_manager.cpp memory_manager.cpp
memory_manager.h memory_manager.h
precompiled_headers.h precompiled_headers.h
present.h
pte_kind.h pte_kind.h
query_cache/bank_base.h query_cache/bank_base.h
query_cache/query_base.h query_cache/query_base.h

37
src/video_core/present.h Normal file
View file

@ -0,0 +1,37 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "common/settings.h"
static inline Settings::ScalingFilter GetScalingFilter() {
return Settings::values.scaling_filter.GetValue();
}
static inline Settings::AntiAliasing GetAntiAliasing() {
return Settings::values.anti_aliasing.GetValue();
}
static inline Settings::ScalingFilter GetScalingFilterForAppletCapture() {
return Settings::ScalingFilter::Bilinear;
}
static inline Settings::AntiAliasing GetAntiAliasingForAppletCapture() {
return Settings::AntiAliasing::None;
}
struct PresentFilters {
Settings::ScalingFilter (*get_scaling_filter)();
Settings::AntiAliasing (*get_anti_aliasing)();
};
constexpr PresentFilters PresentFiltersForDisplay{
.get_scaling_filter = &GetScalingFilter,
.get_anti_aliasing = &GetAntiAliasing,
};
constexpr PresentFilters PresentFiltersForAppletCapture{
.get_scaling_filter = &GetScalingFilterForAppletCapture,
.get_anti_aliasing = &GetAntiAliasingForAppletCapture,
};

View file

@ -2,6 +2,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#include "common/settings.h" #include "common/settings.h"
#include "video_core/present.h"
#include "video_core/renderer_opengl/gl_blit_screen.h" #include "video_core/renderer_opengl/gl_blit_screen.h"
#include "video_core/renderer_opengl/gl_state_tracker.h" #include "video_core/renderer_opengl/gl_state_tracker.h"
#include "video_core/renderer_opengl/present/filters.h" #include "video_core/renderer_opengl/present/filters.h"
@ -13,9 +14,9 @@ namespace OpenGL {
BlitScreen::BlitScreen(RasterizerOpenGL& rasterizer_, BlitScreen::BlitScreen(RasterizerOpenGL& rasterizer_,
Tegra::MaxwellDeviceMemoryManager& device_memory_, Tegra::MaxwellDeviceMemoryManager& device_memory_,
StateTracker& state_tracker_, ProgramManager& program_manager_, StateTracker& state_tracker_, ProgramManager& program_manager_,
Device& device_) Device& device_, const PresentFilters& filters_)
: rasterizer(rasterizer_), device_memory(device_memory_), state_tracker(state_tracker_), : rasterizer(rasterizer_), device_memory(device_memory_), state_tracker(state_tracker_),
program_manager(program_manager_), device(device_) {} program_manager(program_manager_), device(device_), filters(filters_) {}
BlitScreen::~BlitScreen() = default; BlitScreen::~BlitScreen() = default;
@ -56,7 +57,7 @@ void BlitScreen::DrawScreen(std::span<const Tegra::FramebufferConfig> framebuffe
glDepthRangeIndexed(0, 0.0, 0.0); glDepthRangeIndexed(0, 0.0, 0.0);
while (layers.size() < framebuffers.size()) { while (layers.size() < framebuffers.size()) {
layers.emplace_back(rasterizer, device_memory); layers.emplace_back(rasterizer, device_memory, filters);
} }
CreateWindowAdapt(); CreateWindowAdapt();
@ -67,11 +68,11 @@ void BlitScreen::DrawScreen(std::span<const Tegra::FramebufferConfig> framebuffe
} }
void BlitScreen::CreateWindowAdapt() { void BlitScreen::CreateWindowAdapt() {
if (window_adapt && Settings::values.scaling_filter.GetValue() == current_window_adapt) { if (window_adapt && filters.get_scaling_filter() == current_window_adapt) {
return; return;
} }
current_window_adapt = Settings::values.scaling_filter.GetValue(); current_window_adapt = filters.get_scaling_filter();
switch (current_window_adapt) { switch (current_window_adapt) {
case Settings::ScalingFilter::NearestNeighbor: case Settings::ScalingFilter::NearestNeighbor:
window_adapt = MakeNearestNeighbor(device); window_adapt = MakeNearestNeighbor(device);

View file

@ -15,6 +15,8 @@ namespace Layout {
struct FramebufferLayout; struct FramebufferLayout;
} }
struct PresentFilters;
namespace Tegra { namespace Tegra {
struct FramebufferConfig; struct FramebufferConfig;
} }
@ -46,7 +48,7 @@ public:
explicit BlitScreen(RasterizerOpenGL& rasterizer, explicit BlitScreen(RasterizerOpenGL& rasterizer,
Tegra::MaxwellDeviceMemoryManager& device_memory, Tegra::MaxwellDeviceMemoryManager& device_memory,
StateTracker& state_tracker, ProgramManager& program_manager, StateTracker& state_tracker, ProgramManager& program_manager,
Device& device); Device& device, const PresentFilters& filters);
~BlitScreen(); ~BlitScreen();
/// Draws the emulated screens to the emulator window. /// Draws the emulated screens to the emulator window.
@ -61,6 +63,7 @@ private:
StateTracker& state_tracker; StateTracker& state_tracker;
ProgramManager& program_manager; ProgramManager& program_manager;
Device& device; Device& device;
const PresentFilters& filters;
Settings::ScalingFilter current_window_adapt{}; Settings::ScalingFilter current_window_adapt{};
std::unique_ptr<WindowAdaptPass> window_adapt; std::unique_ptr<WindowAdaptPass> window_adapt;

View file

@ -2,6 +2,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#include "video_core/framebuffer_config.h" #include "video_core/framebuffer_config.h"
#include "video_core/present.h"
#include "video_core/renderer_opengl/gl_blit_screen.h" #include "video_core/renderer_opengl/gl_blit_screen.h"
#include "video_core/renderer_opengl/gl_rasterizer.h" #include "video_core/renderer_opengl/gl_rasterizer.h"
#include "video_core/renderer_opengl/present/fsr.h" #include "video_core/renderer_opengl/present/fsr.h"
@ -14,8 +15,9 @@
namespace OpenGL { namespace OpenGL {
Layer::Layer(RasterizerOpenGL& rasterizer_, Tegra::MaxwellDeviceMemoryManager& device_memory_) Layer::Layer(RasterizerOpenGL& rasterizer_, Tegra::MaxwellDeviceMemoryManager& device_memory_,
: rasterizer(rasterizer_), device_memory(device_memory_) { const PresentFilters& filters_)
: rasterizer(rasterizer_), device_memory(device_memory_), filters(filters_) {
// Allocate textures for the screen // Allocate textures for the screen
framebuffer_texture.resource.Create(GL_TEXTURE_2D); framebuffer_texture.resource.Create(GL_TEXTURE_2D);
@ -39,7 +41,7 @@ GLuint Layer::ConfigureDraw(std::array<GLfloat, 3 * 2>& out_matrix,
auto crop = Tegra::NormalizeCrop(framebuffer, info.width, info.height); auto crop = Tegra::NormalizeCrop(framebuffer, info.width, info.height);
GLuint texture = info.display_texture; GLuint texture = info.display_texture;
auto anti_aliasing = Settings::values.anti_aliasing.GetValue(); auto anti_aliasing = filters.get_anti_aliasing();
if (anti_aliasing != Settings::AntiAliasing::None) { if (anti_aliasing != Settings::AntiAliasing::None) {
glEnablei(GL_SCISSOR_TEST, 0); glEnablei(GL_SCISSOR_TEST, 0);
auto viewport_width = Settings::values.resolution_info.ScaleUp(framebuffer_texture.width); auto viewport_width = Settings::values.resolution_info.ScaleUp(framebuffer_texture.width);
@ -64,7 +66,7 @@ GLuint Layer::ConfigureDraw(std::array<GLfloat, 3 * 2>& out_matrix,
glDisablei(GL_SCISSOR_TEST, 0); glDisablei(GL_SCISSOR_TEST, 0);
if (Settings::values.scaling_filter.GetValue() == Settings::ScalingFilter::Fsr) { if (filters.get_scaling_filter() == Settings::ScalingFilter::Fsr) {
if (!fsr || fsr->NeedsRecreation(layout.screen)) { if (!fsr || fsr->NeedsRecreation(layout.screen)) {
fsr = std::make_unique<FSR>(layout.screen.GetWidth(), layout.screen.GetHeight()); fsr = std::make_unique<FSR>(layout.screen.GetWidth(), layout.screen.GetHeight());
} }

View file

@ -13,6 +13,8 @@ namespace Layout {
struct FramebufferLayout; struct FramebufferLayout;
} }
struct PresentFilters;
namespace Service::android { namespace Service::android {
enum class PixelFormat : u32; enum class PixelFormat : u32;
}; };
@ -44,7 +46,8 @@ struct ScreenRectVertex;
class Layer { class Layer {
public: public:
explicit Layer(RasterizerOpenGL& rasterizer, Tegra::MaxwellDeviceMemoryManager& device_memory); explicit Layer(RasterizerOpenGL& rasterizer, Tegra::MaxwellDeviceMemoryManager& device_memory,
const PresentFilters& filters);
~Layer(); ~Layer();
GLuint ConfigureDraw(std::array<GLfloat, 3 * 2>& out_matrix, GLuint ConfigureDraw(std::array<GLfloat, 3 * 2>& out_matrix,
@ -65,6 +68,7 @@ private:
private: private:
RasterizerOpenGL& rasterizer; RasterizerOpenGL& rasterizer;
Tegra::MaxwellDeviceMemoryManager& device_memory; Tegra::MaxwellDeviceMemoryManager& device_memory;
const PresentFilters& filters;
/// OpenGL framebuffer data /// OpenGL framebuffer data
std::vector<u8> gl_framebuffer_data; std::vector<u8> gl_framebuffer_data;

View file

@ -17,6 +17,7 @@
#include "core/frontend/emu_window.h" #include "core/frontend/emu_window.h"
#include "core/telemetry_session.h" #include "core/telemetry_session.h"
#include "video_core/capture.h" #include "video_core/capture.h"
#include "video_core/present.h"
#include "video_core/renderer_opengl/gl_blit_screen.h" #include "video_core/renderer_opengl/gl_blit_screen.h"
#include "video_core/renderer_opengl/gl_rasterizer.h" #include "video_core/renderer_opengl/gl_rasterizer.h"
#include "video_core/renderer_opengl/gl_shader_manager.h" #include "video_core/renderer_opengl/gl_shader_manager.h"
@ -121,9 +122,10 @@ RendererOpenGL::RendererOpenGL(Core::TelemetrySession& telemetry_session_,
glEnableClientState(GL_ELEMENT_ARRAY_UNIFIED_NV); glEnableClientState(GL_ELEMENT_ARRAY_UNIFIED_NV);
} }
blit_screen = std::make_unique<BlitScreen>(rasterizer, device_memory, state_tracker, blit_screen = std::make_unique<BlitScreen>(rasterizer, device_memory, state_tracker,
program_manager, device); program_manager, device, PresentFiltersForDisplay);
blit_applet = std::make_unique<BlitScreen>(rasterizer, device_memory, state_tracker, blit_applet =
program_manager, device); std::make_unique<BlitScreen>(rasterizer, device_memory, state_tracker, program_manager,
device, PresentFiltersForAppletCapture);
capture_framebuffer.Create(); capture_framebuffer.Create();
capture_renderbuffer.Create(); capture_renderbuffer.Create();
glBindRenderbuffer(GL_RENDERBUFFER, capture_renderbuffer.handle); glBindRenderbuffer(GL_RENDERBUFFER, capture_renderbuffer.handle);

View file

@ -1,6 +1,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 "video_core/present.h"
#include "video_core/renderer_vulkan/vk_rasterizer.h" #include "video_core/renderer_vulkan/vk_rasterizer.h"
#include "common/settings.h" #include "common/settings.h"
@ -48,12 +49,12 @@ VkFormat GetFormat(const Tegra::FramebufferConfig& framebuffer) {
Layer::Layer(const Device& device_, MemoryAllocator& memory_allocator_, Scheduler& scheduler_, Layer::Layer(const Device& device_, MemoryAllocator& memory_allocator_, Scheduler& scheduler_,
Tegra::MaxwellDeviceMemoryManager& device_memory_, size_t image_count_, Tegra::MaxwellDeviceMemoryManager& device_memory_, size_t image_count_,
VkExtent2D output_size, VkDescriptorSetLayout layout) VkExtent2D output_size, VkDescriptorSetLayout layout, const PresentFilters& filters_)
: device(device_), memory_allocator(memory_allocator_), scheduler(scheduler_), : device(device_), memory_allocator(memory_allocator_), scheduler(scheduler_),
device_memory(device_memory_), image_count(image_count_) { device_memory(device_memory_), filters(filters_), image_count(image_count_) {
CreateDescriptorPool(); CreateDescriptorPool();
CreateDescriptorSets(layout); CreateDescriptorSets(layout);
if (Settings::values.scaling_filter.GetValue() == Settings::ScalingFilter::Fsr) { if (filters.get_scaling_filter() == Settings::ScalingFilter::Fsr) {
CreateFSR(output_size); CreateFSR(output_size);
} }
} }
@ -171,11 +172,11 @@ void Layer::RefreshResources(const Tegra::FramebufferConfig& framebuffer) {
} }
void Layer::SetAntiAliasPass() { void Layer::SetAntiAliasPass() {
if (anti_alias && anti_alias_setting == Settings::values.anti_aliasing.GetValue()) { if (anti_alias && anti_alias_setting == filters.get_anti_aliasing()) {
return; return;
} }
anti_alias_setting = Settings::values.anti_aliasing.GetValue(); anti_alias_setting = filters.get_anti_aliasing();
const VkExtent2D render_area{ const VkExtent2D render_area{
.width = Settings::values.resolution_info.ScaleUp(raw_width), .width = Settings::values.resolution_info.ScaleUp(raw_width),

View file

@ -11,6 +11,8 @@ namespace Layout {
struct FramebufferLayout; struct FramebufferLayout;
} }
struct PresentFilters;
namespace Tegra { namespace Tegra {
struct FramebufferConfig; struct FramebufferConfig;
} }
@ -37,7 +39,8 @@ class Layer final {
public: public:
explicit Layer(const Device& device, MemoryAllocator& memory_allocator, Scheduler& scheduler, explicit Layer(const Device& device, MemoryAllocator& memory_allocator, Scheduler& scheduler,
Tegra::MaxwellDeviceMemoryManager& device_memory, size_t image_count, Tegra::MaxwellDeviceMemoryManager& device_memory, size_t image_count,
VkExtent2D output_size, VkDescriptorSetLayout layout); VkExtent2D output_size, VkDescriptorSetLayout layout,
const PresentFilters& filters);
~Layer(); ~Layer();
void ConfigureDraw(PresentPushConstants* out_push_constants, void ConfigureDraw(PresentPushConstants* out_push_constants,
@ -71,6 +74,7 @@ private:
MemoryAllocator& memory_allocator; MemoryAllocator& memory_allocator;
Scheduler& scheduler; Scheduler& scheduler;
Tegra::MaxwellDeviceMemoryManager& device_memory; Tegra::MaxwellDeviceMemoryManager& device_memory;
const PresentFilters& filters;
const size_t image_count{}; const size_t image_count{};
vk::DescriptorPool descriptor_pool{}; vk::DescriptorPool descriptor_pool{};
vk::DescriptorSets descriptor_sets{}; vk::DescriptorSets descriptor_sets{};

View file

@ -21,6 +21,7 @@
#include "core/telemetry_session.h" #include "core/telemetry_session.h"
#include "video_core/capture.h" #include "video_core/capture.h"
#include "video_core/gpu.h" #include "video_core/gpu.h"
#include "video_core/present.h"
#include "video_core/renderer_vulkan/present/util.h" #include "video_core/renderer_vulkan/present/util.h"
#include "video_core/renderer_vulkan/renderer_vulkan.h" #include "video_core/renderer_vulkan/renderer_vulkan.h"
#include "video_core/renderer_vulkan/vk_blit_screen.h" #include "video_core/renderer_vulkan/vk_blit_screen.h"
@ -114,9 +115,12 @@ RendererVulkan::RendererVulkan(Core::TelemetrySession& telemetry_session_,
render_window.GetFramebufferLayout().height), render_window.GetFramebufferLayout().height),
present_manager(instance, render_window, device, memory_allocator, scheduler, swapchain, present_manager(instance, render_window, device, memory_allocator, scheduler, swapchain,
surface), surface),
blit_swapchain(device_memory, device, memory_allocator, present_manager, scheduler), blit_swapchain(device_memory, device, memory_allocator, present_manager, scheduler,
blit_capture(device_memory, device, memory_allocator, present_manager, scheduler), PresentFiltersForDisplay),
blit_applet(device_memory, device, memory_allocator, present_manager, scheduler), blit_capture(device_memory, device, memory_allocator, present_manager, scheduler,
PresentFiltersForDisplay),
blit_applet(device_memory, device, memory_allocator, present_manager, scheduler,
PresentFiltersForAppletCapture),
rasterizer(render_window, gpu, device_memory, device, memory_allocator, state_tracker, rasterizer(render_window, gpu, device_memory, device, memory_allocator, state_tracker,
scheduler), scheduler),
applet_frame() { applet_frame() {

View file

@ -2,6 +2,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#include "video_core/framebuffer_config.h" #include "video_core/framebuffer_config.h"
#include "video_core/present.h"
#include "video_core/renderer_vulkan/present/filters.h" #include "video_core/renderer_vulkan/present/filters.h"
#include "video_core/renderer_vulkan/present/layer.h" #include "video_core/renderer_vulkan/present/layer.h"
#include "video_core/renderer_vulkan/vk_blit_screen.h" #include "video_core/renderer_vulkan/vk_blit_screen.h"
@ -12,9 +13,9 @@ namespace Vulkan {
BlitScreen::BlitScreen(Tegra::MaxwellDeviceMemoryManager& device_memory_, const Device& device_, BlitScreen::BlitScreen(Tegra::MaxwellDeviceMemoryManager& device_memory_, const Device& device_,
MemoryAllocator& memory_allocator_, PresentManager& present_manager_, MemoryAllocator& memory_allocator_, PresentManager& present_manager_,
Scheduler& scheduler_) Scheduler& scheduler_, const PresentFilters& filters_)
: device_memory{device_memory_}, device{device_}, memory_allocator{memory_allocator_}, : device_memory{device_memory_}, device{device_}, memory_allocator{memory_allocator_},
present_manager{present_manager_}, scheduler{scheduler_}, image_count{1}, present_manager{present_manager_}, scheduler{scheduler_}, filters{filters_}, image_count{1},
swapchain_view_format{VK_FORMAT_B8G8R8A8_UNORM} {} swapchain_view_format{VK_FORMAT_B8G8R8A8_UNORM} {}
BlitScreen::~BlitScreen() = default; BlitScreen::~BlitScreen() = default;
@ -27,7 +28,7 @@ void BlitScreen::WaitIdle() {
void BlitScreen::SetWindowAdaptPass() { void BlitScreen::SetWindowAdaptPass() {
layers.clear(); layers.clear();
scaling_filter = Settings::values.scaling_filter.GetValue(); scaling_filter = filters.get_scaling_filter();
switch (scaling_filter) { switch (scaling_filter) {
case Settings::ScalingFilter::NearestNeighbor: case Settings::ScalingFilter::NearestNeighbor:
@ -59,7 +60,7 @@ void BlitScreen::DrawToFrame(RasterizerVulkan& rasterizer, Frame* frame,
bool presentation_recreate_required = false; bool presentation_recreate_required = false;
// Recreate dynamic resources if the adapting filter changed // Recreate dynamic resources if the adapting filter changed
if (!window_adapt || scaling_filter != Settings::values.scaling_filter.GetValue()) { if (!window_adapt || scaling_filter != filters.get_scaling_filter()) {
resource_update_required = true; resource_update_required = true;
} }
@ -102,7 +103,7 @@ void BlitScreen::DrawToFrame(RasterizerVulkan& rasterizer, Frame* frame,
while (layers.size() < framebuffers.size()) { while (layers.size() < framebuffers.size()) {
layers.emplace_back(device, memory_allocator, scheduler, device_memory, image_count, layers.emplace_back(device, memory_allocator, scheduler, device_memory, image_count,
window_size, window_adapt->GetDescriptorSetLayout()); window_size, window_adapt->GetDescriptorSetLayout(), filters);
} }
// Perform the draw // Perform the draw
@ -119,8 +120,7 @@ vk::Framebuffer BlitScreen::CreateFramebuffer(const Layout::FramebufferLayout& l
VkFormat current_view_format) { VkFormat current_view_format) {
const bool format_updated = const bool format_updated =
std::exchange(swapchain_view_format, current_view_format) != current_view_format; std::exchange(swapchain_view_format, current_view_format) != current_view_format;
if (!window_adapt || scaling_filter != Settings::values.scaling_filter.GetValue() || if (!window_adapt || scaling_filter != filters.get_scaling_filter() || format_updated) {
format_updated) {
WaitIdle(); WaitIdle();
SetWindowAdaptPass(); SetWindowAdaptPass();
} }

View file

@ -16,6 +16,8 @@ namespace Core {
class System; class System;
} }
struct PresentFilters;
namespace Tegra { namespace Tegra {
struct FramebufferConfig; struct FramebufferConfig;
} }
@ -47,7 +49,7 @@ class BlitScreen {
public: public:
explicit BlitScreen(Tegra::MaxwellDeviceMemoryManager& device_memory, const Device& device, explicit BlitScreen(Tegra::MaxwellDeviceMemoryManager& device_memory, const Device& device,
MemoryAllocator& memory_allocator, PresentManager& present_manager, MemoryAllocator& memory_allocator, PresentManager& present_manager,
Scheduler& scheduler); Scheduler& scheduler, const PresentFilters& filters);
~BlitScreen(); ~BlitScreen();
void DrawToFrame(RasterizerVulkan& rasterizer, Frame* frame, void DrawToFrame(RasterizerVulkan& rasterizer, Frame* frame,
@ -70,6 +72,7 @@ private:
MemoryAllocator& memory_allocator; MemoryAllocator& memory_allocator;
PresentManager& present_manager; PresentManager& present_manager;
Scheduler& scheduler; Scheduler& scheduler;
const PresentFilters& filters;
std::size_t image_count{}; std::size_t image_count{};
std::size_t image_index{}; std::size_t image_index{};
VkFormat swapchain_view_format{}; VkFormat swapchain_view_format{};