mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-21 03:55:32 +00:00
gl: Introduce the concept of scaling passes to the backend
This commit is contained in:
parent
e7d8ef924f
commit
12694dcf69
11 changed files with 148 additions and 14 deletions
|
@ -518,6 +518,7 @@ target_sources(rpcs3_emu PRIVATE
|
|||
RSX/GL/glutils/program.cpp
|
||||
RSX/GL/glutils/ring_buffer.cpp
|
||||
RSX/GL/glutils/sampler.cpp
|
||||
RSX/GL/upscalers/fsr1/fsr_pass.cpp
|
||||
RSX/GL/GLCommonDecompiler.cpp
|
||||
RSX/GL/GLCompute.cpp
|
||||
RSX/GL/GLDraw.cpp
|
||||
|
|
|
@ -411,10 +411,7 @@ void GLGSRender::on_exit()
|
|||
|
||||
m_framebuffer_cache.clear();
|
||||
|
||||
if (m_flip_fbo)
|
||||
{
|
||||
m_flip_fbo.remove();
|
||||
}
|
||||
m_upscaler.reset();
|
||||
|
||||
for (auto& flip_tex_image : m_flip_tex_color)
|
||||
{
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <unordered_map>
|
||||
|
||||
#include "glutils/ring_buffer.h"
|
||||
#include "upscalers/upscaling.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma comment(lib, "opengl32.lib")
|
||||
|
@ -125,9 +126,12 @@ class GLGSRender : public GSRender, public ::rsx::reports::ZCULL_control
|
|||
//buffer
|
||||
gl::fbo* m_draw_fbo = nullptr;
|
||||
std::list<gl::framebuffer_holder> m_framebuffer_cache;
|
||||
gl::fbo m_flip_fbo;
|
||||
std::unique_ptr<gl::texture> m_flip_tex_color[2];
|
||||
|
||||
// Present
|
||||
std::unique_ptr<gl::upscaler> m_upscaler;
|
||||
output_scaling_mode m_output_scaling = output_scaling_mode::bilinear;
|
||||
|
||||
//vaos are mandatory for core profile
|
||||
gl::vao m_vao;
|
||||
|
||||
|
|
|
@ -482,6 +482,7 @@ namespace gl
|
|||
m_sampler.set_parameteri(GL_TEXTURE_MIN_FILTER, static_cast<GLenum>(m_input_filter));
|
||||
m_sampler.set_parameteri(GL_TEXTURE_MAG_FILTER, static_cast<GLenum>(m_input_filter));
|
||||
}
|
||||
|
||||
program_handle.uniforms["gamma"] = gamma;
|
||||
program_handle.uniforms["limit_range"] = limited_rgb + 0;
|
||||
program_handle.uniforms["stereo_display_mode"] = static_cast<u8>(stereo_mode);
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
#include "stdafx.h"
|
||||
#include "GLGSRender.h"
|
||||
#include "upscalers/bilinear_pass.hpp"
|
||||
#include "upscalers/nearest_pass.hpp"
|
||||
|
||||
#include "Emu/Cell/Modules/cellVideoOut.h"
|
||||
#include "Emu/RSX/Overlays/overlay_manager.h"
|
||||
#include "Emu/RSX/Overlays/overlay_debug_overlay.h"
|
||||
|
||||
#include "util/video_provider.h"
|
||||
|
||||
LOG_CHANNEL(screenshot_log, "SCREENSHOT");
|
||||
|
@ -298,27 +302,40 @@ void GLGSRender::flip(const rsx::display_flip_info_t& info)
|
|||
}
|
||||
|
||||
const areai screen_area = coordi({}, { static_cast<int>(buffer_width), static_cast<int>(buffer_height) });
|
||||
|
||||
const bool use_full_rgb_range_output = g_cfg.video.full_rgb_range_output.get();
|
||||
// TODO: Implement FSR for OpenGL and remove this fallback to bilinear
|
||||
const gl::filter filter = g_cfg.video.output_scaling == output_scaling_mode::nearest ? gl::filter::nearest : gl::filter::linear;
|
||||
|
||||
if (!m_upscaler || m_output_scaling != g_cfg.video.output_scaling)
|
||||
{
|
||||
m_output_scaling = g_cfg.video.output_scaling;
|
||||
|
||||
switch (m_output_scaling)
|
||||
{
|
||||
case output_scaling_mode::nearest:
|
||||
m_upscaler = std::make_unique<gl::nearest_upscale_pass>();
|
||||
break;
|
||||
case output_scaling_mode::fsr:
|
||||
// Unimplemented
|
||||
[[ fallthrough ]];
|
||||
case output_scaling_mode::bilinear:
|
||||
default:
|
||||
m_upscaler = std::make_unique<gl::bilinear_upscale_pass>();
|
||||
}
|
||||
}
|
||||
|
||||
if (use_full_rgb_range_output && rsx::fcmp(avconfig.gamma, 1.f) && avconfig.stereo_mode == stereo_render_mode_options::disabled)
|
||||
{
|
||||
// Blit source image to the screen
|
||||
m_flip_fbo.recreate();
|
||||
m_flip_fbo.bind();
|
||||
m_flip_fbo.color = image_to_flip;
|
||||
m_flip_fbo.read_buffer(m_flip_fbo.color);
|
||||
m_flip_fbo.draw_buffer(m_flip_fbo.color);
|
||||
m_flip_fbo.blit(gl::screen, screen_area, aspect_ratio.flipped_vertical(), gl::buffers::color, filter);
|
||||
m_upscaler->scale_output(cmd, image_to_flip, gl::screen, screen_area, aspect_ratio.flipped_vertical(), gl::UPSCALE_AND_COMMIT);
|
||||
}
|
||||
else
|
||||
{
|
||||
const f32 gamma = avconfig.gamma;
|
||||
const bool limited_range = !use_full_rgb_range_output;
|
||||
const rsx::simple_array<GLuint> images{ image_to_flip, image_to_flip2 };
|
||||
const auto filter = m_output_scaling == output_scaling_mode::nearest ? gl::filter::nearest : gl::filter::linear;
|
||||
|
||||
// FIXME: Upscaling should optionally happen before this step.
|
||||
// With linear and nearest scaling, it really doesn't matter here, but for FSR we cannot just bind the images and use a hardware filter.
|
||||
gl::screen.bind();
|
||||
m_video_output_pass.run(cmd, areau(aspect_ratio), images, gamma, limited_range, avconfig.stereo_mode, filter);
|
||||
}
|
||||
|
|
|
@ -49,6 +49,9 @@
|
|||
|
||||
namespace gl
|
||||
{
|
||||
using flags32_t = u32;
|
||||
using handle32_t = u32;
|
||||
|
||||
template<typename Type, uint BindId, uint GetStateId>
|
||||
class save_binding_state_base
|
||||
{
|
||||
|
|
8
rpcs3/Emu/RSX/GL/upscalers/bilinear_pass.hpp
Normal file
8
rpcs3/Emu/RSX/GL/upscalers/bilinear_pass.hpp
Normal file
|
@ -0,0 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
#include "static_pass.hpp"
|
||||
|
||||
namespace gl
|
||||
{
|
||||
using bilinear_upscale_pass = static_upscale_pass<gl::filter::linear>;
|
||||
}
|
9
rpcs3/Emu/RSX/GL/upscalers/fsr1/fsr_pass.cpp
Normal file
9
rpcs3/Emu/RSX/GL/upscalers/fsr1/fsr_pass.cpp
Normal file
|
@ -0,0 +1,9 @@
|
|||
#include "stdafx.h"
|
||||
|
||||
namespace gl
|
||||
{
|
||||
namespace FidelityFX
|
||||
{
|
||||
|
||||
}
|
||||
}
|
8
rpcs3/Emu/RSX/GL/upscalers/nearest_pass.hpp
Normal file
8
rpcs3/Emu/RSX/GL/upscalers/nearest_pass.hpp
Normal file
|
@ -0,0 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
#include "static_pass.hpp"
|
||||
|
||||
namespace gl
|
||||
{
|
||||
using nearest_upscale_pass = static_upscale_pass<gl::filter::nearest>;
|
||||
}
|
49
rpcs3/Emu/RSX/GL/upscalers/static_pass.hpp
Normal file
49
rpcs3/Emu/RSX/GL/upscalers/static_pass.hpp
Normal file
|
@ -0,0 +1,49 @@
|
|||
#pragma once
|
||||
|
||||
#include "../glutils/fbo.h"
|
||||
|
||||
#include "upscaling.h"
|
||||
|
||||
namespace gl
|
||||
{
|
||||
template<gl::filter Filter>
|
||||
class static_upscale_pass : public upscaler
|
||||
{
|
||||
public:
|
||||
static_upscale_pass() = default;
|
||||
~static_upscale_pass()
|
||||
{
|
||||
if (m_flip_fbo)
|
||||
{
|
||||
m_flip_fbo.remove();
|
||||
}
|
||||
}
|
||||
|
||||
gl::handle32_t scale_output(
|
||||
const gl::command_context& /*cmd*/, // State
|
||||
gl::handle32_t src, // Source input
|
||||
const gl::fbo& screen, // Present target. May be VK_NULL_HANDLE for some passes
|
||||
const areai& src_region, // Scaling request information
|
||||
const areai& dst_region, // Ditto
|
||||
gl::flags32_t mode // Mode
|
||||
) override
|
||||
{
|
||||
if (mode & UPSCALE_AND_COMMIT)
|
||||
{
|
||||
m_flip_fbo.recreate();
|
||||
m_flip_fbo.bind();
|
||||
m_flip_fbo.color = src;
|
||||
m_flip_fbo.read_buffer(m_flip_fbo.color);
|
||||
m_flip_fbo.draw_buffer(m_flip_fbo.color);
|
||||
m_flip_fbo.blit(screen, src_region, dst_region, gl::buffers::color, Filter);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Upscaling source only is unsupported
|
||||
return src;
|
||||
}
|
||||
|
||||
private:
|
||||
gl::fbo m_flip_fbo;
|
||||
};
|
||||
}
|
37
rpcs3/Emu/RSX/GL/upscalers/upscaling.h
Normal file
37
rpcs3/Emu/RSX/GL/upscalers/upscaling.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
#pragma once
|
||||
|
||||
#include "util/types.hpp"
|
||||
|
||||
#include "../glutils/fbo.h"
|
||||
#include "../glutils/image.h"
|
||||
#include "../glutils/state_tracker.hpp"
|
||||
|
||||
namespace gl
|
||||
{
|
||||
namespace upscaling_flags_
|
||||
{
|
||||
enum upscaling_flags
|
||||
{
|
||||
UPSCALE_DEFAULT_VIEW = (1 << 0),
|
||||
UPSCALE_LEFT_VIEW = (1 << 0),
|
||||
UPSCALE_RIGHT_VIEW = (1 << 1),
|
||||
UPSCALE_AND_COMMIT = (1 << 2)
|
||||
};
|
||||
}
|
||||
|
||||
using namespace upscaling_flags_;
|
||||
|
||||
struct upscaler
|
||||
{
|
||||
virtual ~upscaler() {}
|
||||
|
||||
virtual gl::handle32_t scale_output(
|
||||
const gl::command_context& cmd, // State
|
||||
gl::handle32_t src, // Source input
|
||||
const gl::fbo& screen, // Present target. May be VK_NULL_HANDLE for some passes
|
||||
const areai& src_region, // Scaling request information
|
||||
const areai& dst_region, // Ditto
|
||||
gl::flags32_t mode // Mode
|
||||
) = 0;
|
||||
};
|
||||
}
|
Loading…
Add table
Reference in a new issue