mirror of
https://github.com/PabloMK7/citra.git
synced 2025-09-12 05:40:04 +00:00
rasterizer_cache: Introduce TextureRuntime and separate CachedSurface
* This commit aims to both continue the rasterizer cache cleanup by separating CachedSurface into a dedicated header and to start weeding out the raw OpenGL code from the cache. * The latter is achieved by abstracting most texture operations in a new class called TextureRuntime. This has many benefits such as making it easier to port the functionality to other graphics APIs and the removal of the need to pass (read/draw) framebuffer handles everywhere. The filterer and reinterpreter get their own sets of FBOs due to this, something that might be a performance win since it reduces the state switching overhead on the runtime FBOs.
This commit is contained in:
parent
199671301d
commit
17ad594a62
23 changed files with 1176 additions and 1012 deletions
|
@ -1,14 +1,12 @@
|
|||
// Copyright 2020 Citra Emulator Project
|
||||
// Copyright 2022 Citra Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "common/scope_exit.h"
|
||||
#include "video_core/renderer_opengl/gl_format_reinterpreter.h"
|
||||
#include "video_core/rasterizer_cache/rasterizer_cache.h"
|
||||
#include "video_core/renderer_opengl/gl_state.h"
|
||||
#include "video_core/renderer_opengl/gl_vars.h"
|
||||
#include "video_core/renderer_opengl/texture_filters/texture_filterer.h"
|
||||
|
||||
namespace OpenGL {
|
||||
|
||||
|
@ -64,15 +62,18 @@ void main() {
|
|||
vao.Create();
|
||||
}
|
||||
|
||||
void Reinterpret(GLuint src_tex, const Common::Rectangle<u32>& src_rect, GLuint read_fb_handle,
|
||||
GLuint dst_tex, const Common::Rectangle<u32>& dst_rect,
|
||||
GLuint draw_fb_handle) override {
|
||||
PixelFormat GetSourceFormat() const override {
|
||||
return PixelFormat::RGBA4;
|
||||
}
|
||||
|
||||
void Reinterpret(const OGLTexture& src_tex, Common::Rectangle<u32> src_rect,
|
||||
const OGLTexture& dst_tex, Common::Rectangle<u32> dst_rect) override {
|
||||
OpenGLState prev_state = OpenGLState::GetCurState();
|
||||
SCOPE_EXIT({ prev_state.Apply(); });
|
||||
|
||||
OpenGLState state;
|
||||
state.texture_units[0].texture_2d = src_tex;
|
||||
state.draw.draw_framebuffer = draw_fb_handle;
|
||||
state.texture_units[0].texture_2d = src_tex.handle;
|
||||
state.draw.draw_framebuffer = draw_fbo.handle;
|
||||
state.draw.shader_program = program.handle;
|
||||
state.draw.vertex_array = vao.handle;
|
||||
state.viewport = {static_cast<GLint>(dst_rect.left), static_cast<GLint>(dst_rect.bottom),
|
||||
|
@ -80,10 +81,10 @@ void main() {
|
|||
static_cast<GLsizei>(dst_rect.GetHeight())};
|
||||
state.Apply();
|
||||
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, dst_tex,
|
||||
0);
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0,
|
||||
0);
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
|
||||
dst_tex.handle, 0);
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
|
||||
0, 0);
|
||||
|
||||
glUniform2i(dst_size_loc, dst_rect.GetWidth(), dst_rect.GetHeight());
|
||||
glUniform2i(src_size_loc, src_rect.GetWidth(), src_rect.GetHeight());
|
||||
|
@ -148,15 +149,18 @@ void main() {
|
|||
|
||||
~PixelBufferD24S8toABGR() {}
|
||||
|
||||
void Reinterpret(GLuint src_tex, const Common::Rectangle<u32>& src_rect, GLuint read_fb_handle,
|
||||
GLuint dst_tex, const Common::Rectangle<u32>& dst_rect,
|
||||
GLuint draw_fb_handle) override {
|
||||
PixelFormat GetSourceFormat() const override {
|
||||
return PixelFormat::D24S8;
|
||||
}
|
||||
|
||||
void Reinterpret(const OGLTexture& src_tex, Common::Rectangle<u32> src_rect,
|
||||
const OGLTexture& dst_tex, Common::Rectangle<u32> dst_rect) override {
|
||||
OpenGLState prev_state = OpenGLState::GetCurState();
|
||||
SCOPE_EXIT({ prev_state.Apply(); });
|
||||
|
||||
OpenGLState state;
|
||||
state.draw.read_framebuffer = read_fb_handle;
|
||||
state.draw.draw_framebuffer = draw_fb_handle;
|
||||
state.draw.read_framebuffer = read_fbo.handle;
|
||||
state.draw.draw_framebuffer = draw_fbo.handle;
|
||||
state.Apply();
|
||||
|
||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, d24s8_abgr_buffer.handle);
|
||||
|
@ -170,7 +174,8 @@ void main() {
|
|||
|
||||
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
|
||||
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
|
||||
src_tex, 0);
|
||||
src_tex.handle, 0);
|
||||
|
||||
glReadPixels(static_cast<GLint>(src_rect.left), static_cast<GLint>(src_rect.bottom),
|
||||
static_cast<GLsizei>(src_rect.GetWidth()),
|
||||
static_cast<GLsizei>(src_rect.GetHeight()), GL_DEPTH_STENCIL,
|
||||
|
@ -200,12 +205,11 @@ void main() {
|
|||
static_cast<GLfloat>(state.viewport.width),
|
||||
static_cast<GLfloat>(state.viewport.height));
|
||||
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, dst_tex,
|
||||
0);
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0,
|
||||
0);
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
|
||||
dst_tex.handle, 0);
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
|
||||
0, 0);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
|
||||
glBindTexture(GL_TEXTURE_BUFFER, 0);
|
||||
}
|
||||
|
||||
|
@ -292,19 +296,22 @@ void main() {
|
|||
}
|
||||
}
|
||||
|
||||
void Reinterpret(GLuint src_tex, const Common::Rectangle<u32>& src_rect, GLuint read_fb_handle,
|
||||
GLuint dst_tex, const Common::Rectangle<u32>& dst_rect,
|
||||
GLuint draw_fb_handle) override {
|
||||
PixelFormat GetSourceFormat() const override {
|
||||
return PixelFormat::D24S8;
|
||||
}
|
||||
|
||||
void Reinterpret(const OGLTexture& src_tex, Common::Rectangle<u32> src_rect,
|
||||
const OGLTexture& dst_tex, Common::Rectangle<u32> dst_rect) override {
|
||||
OpenGLState prev_state = OpenGLState::GetCurState();
|
||||
SCOPE_EXIT({ prev_state.Apply(); });
|
||||
|
||||
OpenGLState state;
|
||||
state.texture_units[0].texture_2d = src_tex;
|
||||
state.texture_units[0].texture_2d = src_tex.handle;
|
||||
|
||||
if (use_texture_view) {
|
||||
temp_tex.Create();
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glTextureView(temp_tex.handle, GL_TEXTURE_2D, src_tex, GL_DEPTH24_STENCIL8, 0, 1, 0, 1);
|
||||
glTextureView(temp_tex.handle, GL_TEXTURE_2D, src_tex.handle, GL_DEPTH24_STENCIL8, 0, 1, 0, 1);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
} else if (src_rect.top > temp_rect.top || src_rect.right > temp_rect.right) {
|
||||
|
@ -320,7 +327,7 @@ void main() {
|
|||
}
|
||||
|
||||
state.texture_units[1].texture_2d = temp_tex.handle;
|
||||
state.draw.draw_framebuffer = draw_fb_handle;
|
||||
state.draw.draw_framebuffer = draw_fbo.handle;
|
||||
state.draw.shader_program = program.handle;
|
||||
state.draw.vertex_array = vao.handle;
|
||||
state.viewport = {static_cast<GLint>(dst_rect.left), static_cast<GLint>(dst_rect.bottom),
|
||||
|
@ -330,16 +337,16 @@ void main() {
|
|||
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
if (!use_texture_view) {
|
||||
glCopyImageSubData(src_tex, GL_TEXTURE_2D, 0, src_rect.left, src_rect.bottom, 0,
|
||||
glCopyImageSubData(src_tex.handle, GL_TEXTURE_2D, 0, src_rect.left, src_rect.bottom, 0,
|
||||
temp_tex.handle, GL_TEXTURE_2D, 0, src_rect.left, src_rect.bottom, 0,
|
||||
src_rect.GetWidth(), src_rect.GetHeight(), 1);
|
||||
}
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_STENCIL_INDEX);
|
||||
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, dst_tex,
|
||||
0);
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0,
|
||||
0);
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
|
||||
dst_tex.handle, 0);
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
|
||||
0, 0);
|
||||
|
||||
glUniform2i(dst_size_loc, dst_rect.GetWidth(), dst_rect.GetHeight());
|
||||
glUniform2i(src_size_loc, src_rect.GetWidth(), src_rect.GetHeight());
|
||||
|
@ -363,32 +370,32 @@ private:
|
|||
FormatReinterpreterOpenGL::FormatReinterpreterOpenGL() {
|
||||
const std::string_view vendor{reinterpret_cast<const char*>(glGetString(GL_VENDOR))};
|
||||
const std::string_view version{reinterpret_cast<const char*>(glGetString(GL_VERSION))};
|
||||
|
||||
// Fallback to PBO path on obsolete intel drivers
|
||||
// intel`s GL_VERSION string - `3.3.0 - Build 25.20.100.6373`
|
||||
const bool intel_broken_drivers =
|
||||
vendor.find("Intel") != vendor.npos && (std::atoi(version.substr(14, 2).data()) < 30);
|
||||
|
||||
if ((!intel_broken_drivers && GLAD_GL_ARB_stencil_texturing && GLAD_GL_ARB_texture_storage &&
|
||||
GLAD_GL_ARB_copy_image) ||
|
||||
GLES) {
|
||||
reinterpreters.emplace(PixelFormatPair{PixelFormat::RGBA8, PixelFormat::D24S8},
|
||||
std::make_unique<ShaderD24S8toRGBA8>());
|
||||
auto Register = [this](PixelFormat dest, std::unique_ptr<FormatReinterpreterBase>&& obj) {
|
||||
const u32 dst_index = static_cast<u32>(dest);
|
||||
return reinterpreters[dst_index].push_back(std::move(obj));
|
||||
};
|
||||
|
||||
if ((!intel_broken_drivers && GLAD_GL_ARB_stencil_texturing &&
|
||||
GLAD_GL_ARB_texture_storage && GLAD_GL_ARB_copy_image) || GLES) {
|
||||
Register(PixelFormat::RGBA8, std::make_unique<ShaderD24S8toRGBA8>());
|
||||
LOG_INFO(Render_OpenGL, "Using shader for D24S8 to RGBA8 reinterpretation");
|
||||
} else {
|
||||
reinterpreters.emplace(PixelFormatPair{PixelFormat::RGBA8, PixelFormat::D24S8},
|
||||
std::make_unique<PixelBufferD24S8toABGR>());
|
||||
LOG_INFO(Render_OpenGL, "Using pbo for D24S8 to RGBA8 reinterpretation");
|
||||
Register(PixelFormat::RGBA8, std::make_unique<PixelBufferD24S8toABGR>());
|
||||
LOG_INFO(Render_OpenGL, "Using PBO for D24S8 to RGBA8 reinterpretation");
|
||||
}
|
||||
reinterpreters.emplace(PixelFormatPair{PixelFormat::RGB5A1, PixelFormat::RGBA4},
|
||||
std::make_unique<RGBA4toRGB5A1>());
|
||||
|
||||
Register(PixelFormat::RGB5A1, std::make_unique<RGBA4toRGB5A1>());
|
||||
}
|
||||
|
||||
FormatReinterpreterOpenGL::~FormatReinterpreterOpenGL() = default;
|
||||
|
||||
std::pair<FormatReinterpreterOpenGL::ReinterpreterMap::iterator,
|
||||
FormatReinterpreterOpenGL::ReinterpreterMap::iterator>
|
||||
FormatReinterpreterOpenGL::GetPossibleReinterpretations(PixelFormat dst_format) {
|
||||
return reinterpreters.equal_range(dst_format);
|
||||
auto FormatReinterpreterOpenGL::GetPossibleReinterpretations(PixelFormat dst_format)
|
||||
-> const ReinterpreterList& {
|
||||
return reinterpreters[static_cast<u32>(dst_format)];
|
||||
}
|
||||
|
||||
} // namespace OpenGL
|
||||
|
|
|
@ -1,62 +1,46 @@
|
|||
// Copyright 2020 Citra Emulator Project
|
||||
// Copyright 2022 Citra Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <type_traits>
|
||||
#include <glad/glad.h>
|
||||
#include "common/common_types.h"
|
||||
#include <unordered_map>
|
||||
#include "common/math_util.h"
|
||||
#include "video_core/rasterizer_cache/pixel_format.h"
|
||||
#include "video_core/renderer_opengl/gl_resource_manager.h"
|
||||
|
||||
namespace OpenGL {
|
||||
|
||||
class RasterizerCacheOpenGL;
|
||||
|
||||
struct PixelFormatPair {
|
||||
const PixelFormat dst_format, src_format;
|
||||
|
||||
struct less {
|
||||
using is_transparent = void;
|
||||
constexpr bool operator()(PixelFormatPair lhs, PixelFormatPair rhs) const {
|
||||
return std::tie(lhs.dst_format, lhs.src_format) <
|
||||
std::tie(rhs.dst_format, rhs.src_format);
|
||||
}
|
||||
|
||||
constexpr bool operator()(PixelFormat lhs, PixelFormatPair rhs) const {
|
||||
return lhs < rhs.dst_format;
|
||||
}
|
||||
|
||||
constexpr bool operator()(PixelFormatPair lhs, PixelFormat rhs) const {
|
||||
return lhs.dst_format < rhs;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class FormatReinterpreterBase {
|
||||
public:
|
||||
FormatReinterpreterBase() {
|
||||
read_fbo.Create();
|
||||
draw_fbo.Create();
|
||||
}
|
||||
|
||||
virtual ~FormatReinterpreterBase() = default;
|
||||
|
||||
virtual void Reinterpret(GLuint src_tex, const Common::Rectangle<u32>& src_rect,
|
||||
GLuint read_fb_handle, GLuint dst_tex,
|
||||
const Common::Rectangle<u32>& dst_rect, GLuint draw_fb_handle) = 0;
|
||||
virtual PixelFormat GetSourceFormat() const = 0;
|
||||
virtual void Reinterpret(const OGLTexture& src_tex, Common::Rectangle<u32> src_rect,
|
||||
const OGLTexture& dst_tex, Common::Rectangle<u32> dst_rect) = 0;
|
||||
|
||||
protected:
|
||||
OGLFramebuffer read_fbo, draw_fbo;
|
||||
};
|
||||
|
||||
using ReinterpreterList = std::vector<std::unique_ptr<FormatReinterpreterBase>>;
|
||||
|
||||
class FormatReinterpreterOpenGL : NonCopyable {
|
||||
using ReinterpreterMap =
|
||||
std::map<PixelFormatPair, std::unique_ptr<FormatReinterpreterBase>, PixelFormatPair::less>;
|
||||
|
||||
public:
|
||||
explicit FormatReinterpreterOpenGL();
|
||||
~FormatReinterpreterOpenGL();
|
||||
FormatReinterpreterOpenGL();
|
||||
~FormatReinterpreterOpenGL() = default;
|
||||
|
||||
auto GetPossibleReinterpretations(PixelFormat dst_format) ->
|
||||
std::pair<ReinterpreterMap::iterator, ReinterpreterMap::iterator>;
|
||||
const ReinterpreterList& GetPossibleReinterpretations(PixelFormat dst_format);
|
||||
|
||||
private:
|
||||
ReinterpreterMap reinterpreters;
|
||||
std::array<ReinterpreterList, PIXEL_FORMAT_COUNT> reinterpreters;
|
||||
};
|
||||
|
||||
} // namespace OpenGL
|
||||
|
|
|
@ -30,7 +30,6 @@
|
|||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#include "video_core/rasterizer_cache/rasterizer_cache.h"
|
||||
#include "video_core/renderer_opengl/texture_filters/anime4k/anime4k_ultrafast.h"
|
||||
|
||||
#include "shaders/refine.frag"
|
||||
|
@ -72,9 +71,8 @@ Anime4kUltrafast::Anime4kUltrafast(u16 scale_factor) : TextureFilterBase(scale_f
|
|||
cur_state.Apply();
|
||||
}
|
||||
|
||||
void Anime4kUltrafast::Filter(GLuint src_tex, const Common::Rectangle<u32>& src_rect,
|
||||
GLuint dst_tex, const Common::Rectangle<u32>& dst_rect,
|
||||
GLuint read_fb_handle, GLuint draw_fb_handle) {
|
||||
void Anime4kUltrafast::Filter(const OGLTexture& src_tex, Common::Rectangle<u32> src_rect,
|
||||
const OGLTexture& dst_tex, Common::Rectangle<u32> dst_rect) {
|
||||
const OpenGLState cur_state = OpenGLState::GetCurState();
|
||||
|
||||
// These will have handles from the previous texture that was filtered, reset them to avoid
|
||||
|
@ -112,7 +110,7 @@ void Anime4kUltrafast::Filter(GLuint src_tex, const Common::Rectangle<u32>& src_
|
|||
static_cast<GLint>(src_rect.bottom * internal_scale_factor),
|
||||
static_cast<GLsizei>(src_rect.GetWidth() * internal_scale_factor),
|
||||
static_cast<GLsizei>(src_rect.GetHeight() * internal_scale_factor)};
|
||||
state.texture_units[0].texture_2d = src_tex;
|
||||
state.texture_units[0].texture_2d = src_tex.handle;
|
||||
state.texture_units[1].texture_2d = LUMAD.tex.handle;
|
||||
state.texture_units[2].texture_2d = XY.tex.handle;
|
||||
state.draw.draw_framebuffer = XY.fbo.handle;
|
||||
|
@ -131,11 +129,12 @@ void Anime4kUltrafast::Filter(GLuint src_tex, const Common::Rectangle<u32>& src_
|
|||
state.viewport = {static_cast<GLint>(dst_rect.left), static_cast<GLint>(dst_rect.bottom),
|
||||
static_cast<GLsizei>(dst_rect.GetWidth()),
|
||||
static_cast<GLsizei>(dst_rect.GetHeight())};
|
||||
state.draw.draw_framebuffer = draw_fb_handle;
|
||||
state.draw.draw_framebuffer = draw_fbo.handle;
|
||||
state.draw.shader_program = refine_program.handle;
|
||||
state.Apply();
|
||||
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, dst_tex, 0);
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
|
||||
dst_tex.handle, 0);
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
|
||||
|
|
|
@ -15,9 +15,8 @@ public:
|
|||
static constexpr std::string_view NAME = "Anime4K Ultrafast";
|
||||
|
||||
explicit Anime4kUltrafast(u16 scale_factor);
|
||||
void Filter(GLuint src_tex, const Common::Rectangle<u32>& src_rect, GLuint dst_tex,
|
||||
const Common::Rectangle<u32>& dst_rect, GLuint read_fb_handle,
|
||||
GLuint draw_fb_handle) override;
|
||||
void Filter(const OGLTexture& src_tex, Common::Rectangle<u32> src_rect,
|
||||
const OGLTexture& dst_tex, Common::Rectangle<u32> dst_rect) override;
|
||||
|
||||
private:
|
||||
static constexpr u8 internal_scale_factor = 2;
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "video_core/rasterizer_cache/rasterizer_cache.h"
|
||||
#include "video_core/renderer_opengl/texture_filters/bicubic/bicubic.h"
|
||||
|
||||
#include "shaders/bicubic.frag"
|
||||
|
@ -26,18 +25,18 @@ Bicubic::Bicubic(u16 scale_factor) : TextureFilterBase(scale_factor) {
|
|||
glSamplerParameteri(src_sampler.handle, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
} // namespace OpenGL
|
||||
|
||||
void Bicubic::Filter(GLuint src_tex, const Common::Rectangle<u32>& src_rect, GLuint dst_tex,
|
||||
const Common::Rectangle<u32>& dst_rect, GLuint read_fb_handle,
|
||||
GLuint draw_fb_handle) {
|
||||
void Bicubic::Filter(const OGLTexture& src_tex, Common::Rectangle<u32> src_rect,
|
||||
const OGLTexture& dst_tex, Common::Rectangle<u32> dst_rect) {
|
||||
const OpenGLState cur_state = OpenGLState::GetCurState();
|
||||
state.texture_units[0].texture_2d = src_tex;
|
||||
state.draw.draw_framebuffer = draw_fb_handle;
|
||||
state.texture_units[0].texture_2d = src_tex.handle;
|
||||
state.draw.draw_framebuffer = draw_fbo.handle;
|
||||
state.viewport = {static_cast<GLint>(dst_rect.left), static_cast<GLint>(dst_rect.bottom),
|
||||
static_cast<GLsizei>(dst_rect.GetWidth()),
|
||||
static_cast<GLsizei>(dst_rect.GetHeight())};
|
||||
state.Apply();
|
||||
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, dst_tex, 0);
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
|
||||
dst_tex.handle, 0);
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
|
||||
|
|
|
@ -15,9 +15,8 @@ public:
|
|||
static constexpr std::string_view NAME = "Bicubic";
|
||||
|
||||
explicit Bicubic(u16 scale_factor);
|
||||
void Filter(GLuint src_tex, const Common::Rectangle<u32>& src_rect, GLuint dst_tex,
|
||||
const Common::Rectangle<u32>& dst_rect, GLuint read_fb_handle,
|
||||
GLuint draw_fb_handle) override;
|
||||
void Filter(const OGLTexture& src_tex, Common::Rectangle<u32> src_rect,
|
||||
const OGLTexture& dst_tex, Common::Rectangle<u32> dst_rect) override;
|
||||
|
||||
private:
|
||||
OpenGLState state{};
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "video_core/rasterizer_cache/rasterizer_cache.h"
|
||||
#include "video_core/renderer_opengl/texture_filters/scale_force/scale_force.h"
|
||||
|
||||
#include "shaders/scale_force.frag"
|
||||
|
@ -26,18 +25,18 @@ ScaleForce::ScaleForce(u16 scale_factor) : TextureFilterBase(scale_factor) {
|
|||
glSamplerParameteri(src_sampler.handle, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
}
|
||||
|
||||
void ScaleForce::Filter(GLuint src_tex, const Common::Rectangle<u32>& src_rect, GLuint dst_tex,
|
||||
const Common::Rectangle<u32>& dst_rect, GLuint read_fb_handle,
|
||||
GLuint draw_fb_handle) {
|
||||
void ScaleForce::Filter(const OGLTexture& src_tex, Common::Rectangle<u32> src_rect,
|
||||
const OGLTexture& dst_tex, Common::Rectangle<u32> dst_rect) {
|
||||
const OpenGLState cur_state = OpenGLState::GetCurState();
|
||||
state.texture_units[0].texture_2d = src_tex;
|
||||
state.draw.draw_framebuffer = draw_fb_handle;
|
||||
state.texture_units[0].texture_2d = src_tex.handle;
|
||||
state.draw.draw_framebuffer = draw_fbo.handle;
|
||||
state.viewport = {static_cast<GLint>(dst_rect.left), static_cast<GLint>(dst_rect.bottom),
|
||||
static_cast<GLsizei>(dst_rect.GetWidth()),
|
||||
static_cast<GLsizei>(dst_rect.GetHeight())};
|
||||
state.Apply();
|
||||
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, dst_tex, 0);
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
|
||||
dst_tex.handle, 0);
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
|
||||
|
|
|
@ -15,9 +15,8 @@ public:
|
|||
static constexpr std::string_view NAME = "ScaleForce";
|
||||
|
||||
explicit ScaleForce(u16 scale_factor);
|
||||
void Filter(GLuint src_tex, const Common::Rectangle<u32>& src_rect, GLuint dst_tex,
|
||||
const Common::Rectangle<u32>& dst_rect, GLuint read_fb_handle,
|
||||
GLuint draw_fb_handle) override;
|
||||
void Filter(const OGLTexture& src_tex, Common::Rectangle<u32> src_rect,
|
||||
const OGLTexture& dst_tex, Common::Rectangle<u32> dst_rect) override;
|
||||
|
||||
private:
|
||||
OpenGLState state{};
|
||||
|
|
|
@ -3,23 +3,31 @@
|
|||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <glad/glad.h>
|
||||
#include <string_view>
|
||||
#include "common/common_types.h"
|
||||
#include "common/math_util.h"
|
||||
#include "video_core/renderer_opengl/gl_resource_manager.h"
|
||||
|
||||
namespace OpenGL {
|
||||
|
||||
class TextureRuntime;
|
||||
class OGLTexture;
|
||||
|
||||
class TextureFilterBase {
|
||||
friend class TextureFilterer;
|
||||
virtual void Filter(GLuint src_tex, const Common::Rectangle<u32>& src_rect, GLuint dst_tex,
|
||||
const Common::Rectangle<u32>& dst_rect, GLuint read_fb_handle,
|
||||
GLuint draw_fb_handle) = 0;
|
||||
|
||||
public:
|
||||
explicit TextureFilterBase(u16 scale_factor) : scale_factor{scale_factor} {};
|
||||
explicit TextureFilterBase(u16 scale_factor) : scale_factor(scale_factor) {
|
||||
draw_fbo.Create();
|
||||
};
|
||||
|
||||
virtual ~TextureFilterBase() = default;
|
||||
|
||||
private:
|
||||
virtual void Filter(const OGLTexture& src_tex, Common::Rectangle<u32> src_rect,
|
||||
const OGLTexture& dst_tex, Common::Rectangle<u32> dst_rect) = 0;
|
||||
|
||||
protected:
|
||||
OGLFramebuffer draw_fbo;
|
||||
const u16 scale_factor{};
|
||||
};
|
||||
|
||||
|
|
|
@ -58,16 +58,16 @@ bool TextureFilterer::IsNull() const {
|
|||
return !filter;
|
||||
}
|
||||
|
||||
bool TextureFilterer::Filter(GLuint src_tex, const Common::Rectangle<u32>& src_rect, GLuint dst_tex,
|
||||
const Common::Rectangle<u32>& dst_rect,
|
||||
SurfaceType type, GLuint read_fb_handle,
|
||||
GLuint draw_fb_handle) {
|
||||
// depth / stencil texture filtering is not supported for now
|
||||
bool TextureFilterer::Filter(const OGLTexture& src_tex, Common::Rectangle<u32> src_rect,
|
||||
const OGLTexture& dst_tex, Common::Rectangle<u32> dst_rect,
|
||||
SurfaceType type) {
|
||||
|
||||
// Depth/Stencil texture filtering is not supported for now
|
||||
if (IsNull() || (type != SurfaceType::Color && type != SurfaceType::Texture)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
filter->Filter(src_tex, src_rect, dst_tex, dst_rect, read_fb_handle, draw_fb_handle);
|
||||
filter->Filter(src_tex, src_rect, dst_tex, dst_rect);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -83,6 +83,7 @@ std::vector<std::string_view> TextureFilterer::GetFilterNames() {
|
|||
return lhs_is_none && !rhs_is_none;
|
||||
return lhs < rhs;
|
||||
});
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,15 +16,19 @@ class TextureFilterer {
|
|||
public:
|
||||
static constexpr std::string_view NONE = "none";
|
||||
|
||||
public:
|
||||
explicit TextureFilterer(std::string_view filter_name, u16 scale_factor);
|
||||
// returns true if the filter actually changed
|
||||
|
||||
// Returns true if the filter actually changed
|
||||
bool Reset(std::string_view new_filter_name, u16 new_scale_factor);
|
||||
// returns true if there is no active filter
|
||||
|
||||
// Returns true if there is no active filter
|
||||
bool IsNull() const;
|
||||
// returns true if the texture was able to be filtered
|
||||
bool Filter(GLuint src_tex, const Common::Rectangle<u32>& src_rect, GLuint dst_tex,
|
||||
const Common::Rectangle<u32>& dst_rect, SurfaceType type,
|
||||
GLuint read_fb_handle, GLuint draw_fb_handle);
|
||||
|
||||
// Returns true if the texture was able to be filtered
|
||||
bool Filter(const OGLTexture& src_tex, Common::Rectangle<u32> src_rect,
|
||||
const OGLTexture& dst_tex, Common::Rectangle<u32> dst_rect,
|
||||
SurfaceType type);
|
||||
|
||||
static std::vector<std::string_view> GetFilterNames();
|
||||
|
||||
|
|
|
@ -40,7 +40,6 @@
|
|||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include "video_core/rasterizer_cache/rasterizer_cache.h"
|
||||
#include "video_core/renderer_opengl/texture_filters/xbrz/xbrz_freescale.h"
|
||||
|
||||
#include "shaders/xbrz_freescale.frag"
|
||||
|
@ -48,7 +47,9 @@
|
|||
|
||||
namespace OpenGL {
|
||||
|
||||
XbrzFreescale::XbrzFreescale(u16 scale_factor) : TextureFilterBase(scale_factor) {
|
||||
XbrzFreescale::XbrzFreescale(u16 scale_factor) :
|
||||
TextureFilterBase(scale_factor) {
|
||||
|
||||
const OpenGLState cur_state = OpenGLState::GetCurState();
|
||||
|
||||
program.Create(xbrz_freescale_vert.data(), xbrz_freescale_frag.data());
|
||||
|
@ -62,7 +63,9 @@ XbrzFreescale::XbrzFreescale(u16 scale_factor) : TextureFilterBase(scale_factor)
|
|||
glSamplerParameteri(src_sampler.handle, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glSamplerParameteri(src_sampler.handle, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glSamplerParameteri(src_sampler.handle, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glUniform1f(glGetUniformLocation(program.handle, "scale"), static_cast<GLfloat>(scale_factor));
|
||||
|
||||
const GLint scale_loc = glGetUniformLocation(program.handle, "scale");
|
||||
glUniform1f(scale_loc, static_cast<GLfloat>(scale_factor));
|
||||
|
||||
cur_state.Apply();
|
||||
state.draw.vertex_array = vao.handle;
|
||||
|
@ -70,19 +73,19 @@ XbrzFreescale::XbrzFreescale(u16 scale_factor) : TextureFilterBase(scale_factor)
|
|||
state.texture_units[0].sampler = src_sampler.handle;
|
||||
}
|
||||
|
||||
void XbrzFreescale::Filter(GLuint src_tex, const Common::Rectangle<u32>& src_rect, GLuint dst_tex,
|
||||
const Common::Rectangle<u32>& dst_rect, GLuint read_fb_handle,
|
||||
GLuint draw_fb_handle) {
|
||||
void XbrzFreescale::Filter(const OGLTexture& src_tex, Common::Rectangle<u32> src_rect,
|
||||
const OGLTexture& dst_tex, Common::Rectangle<u32> dst_rect) {
|
||||
const OpenGLState cur_state = OpenGLState::GetCurState();
|
||||
|
||||
state.texture_units[0].texture_2d = src_tex;
|
||||
state.draw.draw_framebuffer = draw_fb_handle;
|
||||
state.texture_units[0].texture_2d = src_tex.handle;
|
||||
state.draw.draw_framebuffer = draw_fbo.handle;
|
||||
state.viewport = {static_cast<GLint>(dst_rect.left), static_cast<GLint>(dst_rect.bottom),
|
||||
static_cast<GLsizei>(dst_rect.GetWidth()),
|
||||
static_cast<GLsizei>(dst_rect.GetHeight())};
|
||||
state.Apply();
|
||||
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, dst_tex, 0);
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
|
||||
dst_tex.handle, 0);
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "video_core/renderer_opengl/gl_resource_manager.h"
|
||||
#include "video_core/renderer_opengl/gl_state.h"
|
||||
#include "video_core/renderer_opengl/texture_filters/texture_filter_base.h"
|
||||
|
@ -15,9 +14,8 @@ public:
|
|||
static constexpr std::string_view NAME = "xBRZ freescale";
|
||||
|
||||
explicit XbrzFreescale(u16 scale_factor);
|
||||
void Filter(GLuint src_tex, const Common::Rectangle<u32>& src_rect, GLuint dst_tex,
|
||||
const Common::Rectangle<u32>& dst_rect, GLuint read_fb_handle,
|
||||
GLuint draw_fb_handle) override;
|
||||
void Filter(const OGLTexture& src_tex, Common::Rectangle<u32> src_rect,
|
||||
const OGLTexture& dst_tex, Common::Rectangle<u32> dst_rect) override;
|
||||
|
||||
private:
|
||||
OpenGLState state{};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue