mirror of https://github.com/RPCS3/rpcs3.git
gl/wcb: Use temporary scaled image to implement bilinear filter
This commit is contained in:
parent
12ab03b0b5
commit
7bee4064a6
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
namespace gl
|
namespace gl
|
||||||
{
|
{
|
||||||
|
blitter *g_hw_blitter = nullptr;
|
||||||
capabilities g_driver_caps;
|
capabilities g_driver_caps;
|
||||||
const fbo screen{};
|
const fbo screen{};
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,7 @@ namespace gl
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class capabilities;
|
class capabilities;
|
||||||
|
class blitter;
|
||||||
|
|
||||||
void enable_debugging();
|
void enable_debugging();
|
||||||
capabilities& get_driver_caps();
|
capabilities& get_driver_caps();
|
||||||
|
|
|
@ -23,7 +23,61 @@ class GLGSRender;
|
||||||
|
|
||||||
namespace gl
|
namespace gl
|
||||||
{
|
{
|
||||||
|
class blitter;
|
||||||
|
|
||||||
extern GLenum get_sized_internal_format(u32);
|
extern GLenum get_sized_internal_format(u32);
|
||||||
|
extern blitter *g_hw_blitter;
|
||||||
|
|
||||||
|
class blitter
|
||||||
|
{
|
||||||
|
fbo blit_src;
|
||||||
|
fbo blit_dst;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
void init()
|
||||||
|
{
|
||||||
|
blit_src.create();
|
||||||
|
blit_dst.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
void destroy()
|
||||||
|
{
|
||||||
|
blit_dst.remove();
|
||||||
|
blit_src.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 scale_image(u32 src, u32 dst, const areai src_rect, const areai dst_rect, bool linear_interpolation, bool is_depth_copy)
|
||||||
|
{
|
||||||
|
s32 old_fbo = 0;
|
||||||
|
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &old_fbo);
|
||||||
|
|
||||||
|
u32 dst_tex = dst;
|
||||||
|
filter interp = linear_interpolation ? filter::linear : filter::nearest;
|
||||||
|
|
||||||
|
GLenum attachment = is_depth_copy ? GL_DEPTH_ATTACHMENT : GL_COLOR_ATTACHMENT0;
|
||||||
|
|
||||||
|
blit_src.bind();
|
||||||
|
glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, src, 0);
|
||||||
|
blit_src.check();
|
||||||
|
|
||||||
|
blit_dst.bind();
|
||||||
|
glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, dst_tex, 0);
|
||||||
|
blit_dst.check();
|
||||||
|
|
||||||
|
GLboolean scissor_test_enabled = glIsEnabled(GL_SCISSOR_TEST);
|
||||||
|
if (scissor_test_enabled)
|
||||||
|
glDisable(GL_SCISSOR_TEST);
|
||||||
|
|
||||||
|
blit_src.blit(blit_dst, src_rect, dst_rect, is_depth_copy ? buffers::depth : buffers::color, interp);
|
||||||
|
|
||||||
|
if (scissor_test_enabled)
|
||||||
|
glEnable(GL_SCISSOR_TEST);
|
||||||
|
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, old_fbo);
|
||||||
|
return dst_tex;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class cached_texture_section : public rsx::cached_texture_section
|
class cached_texture_section : public rsx::cached_texture_section
|
||||||
{
|
{
|
||||||
|
@ -33,6 +87,7 @@ namespace gl
|
||||||
u32 pbo_size = 0;
|
u32 pbo_size = 0;
|
||||||
|
|
||||||
u32 vram_texture = 0;
|
u32 vram_texture = 0;
|
||||||
|
u32 scaled_texture = 0;
|
||||||
|
|
||||||
bool copied = false;
|
bool copied = false;
|
||||||
bool flushed = false;
|
bool flushed = false;
|
||||||
|
@ -211,13 +266,40 @@ namespace gl
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (real_pitch != rsx_pitch || rsx::get_resolution_scale_percent() != 100)
|
||||||
|
{
|
||||||
|
const u32 real_width = (rsx_pitch * width) / real_pitch;
|
||||||
|
if (scaled_texture == 0)
|
||||||
|
{
|
||||||
|
GLenum ifmt = 0;
|
||||||
|
glBindTexture(GL_TEXTURE_2D, vram_texture);
|
||||||
|
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, (GLint*)&ifmt);
|
||||||
|
|
||||||
|
//Get expected texture dimensions..
|
||||||
|
glGenTextures(1, &scaled_texture);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, scaled_texture);
|
||||||
|
glTexStorage2D(GL_TEXTURE_2D, 1, ifmt, real_width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
areai src_area = { 0, 0, 0, 0 };
|
||||||
|
const areai dst_area = {0, 0, static_cast<s32>(real_width), height};
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, vram_texture);
|
||||||
|
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &src_area.x2);
|
||||||
|
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &src_area.y2);
|
||||||
|
|
||||||
|
g_hw_blitter->scale_image(vram_texture, scaled_texture, src_area, dst_area, true, is_depth);
|
||||||
|
}
|
||||||
|
|
||||||
glPixelStorei(GL_PACK_SWAP_BYTES, pack_unpack_swap_bytes);
|
glPixelStorei(GL_PACK_SWAP_BYTES, pack_unpack_swap_bytes);
|
||||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo_id);
|
glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo_id);
|
||||||
|
|
||||||
|
const GLuint target_texture = (scaled_texture == 0) ? vram_texture : scaled_texture;
|
||||||
|
|
||||||
if (get_driver_caps().EXT_dsa_supported)
|
if (get_driver_caps().EXT_dsa_supported)
|
||||||
glGetTextureImageEXT(vram_texture, GL_TEXTURE_2D, 0, (GLenum)format, (GLenum)type, nullptr);
|
glGetTextureImageEXT(target_texture, GL_TEXTURE_2D, 0, (GLenum)format, (GLenum)type, nullptr);
|
||||||
else
|
else
|
||||||
glGetTextureImage(vram_texture, 0, (GLenum)format, (GLenum)type, pbo_size, nullptr);
|
glGetTextureImage(target_texture, 0, (GLenum)format, (GLenum)type, pbo_size, nullptr);
|
||||||
|
|
||||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
|
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
|
||||||
|
|
||||||
|
@ -269,7 +351,7 @@ namespace gl
|
||||||
//throw if map failed since we'll segfault anyway
|
//throw if map failed since we'll segfault anyway
|
||||||
verify(HERE), data != nullptr;
|
verify(HERE), data != nullptr;
|
||||||
|
|
||||||
if (real_pitch >= rsx_pitch)
|
if (real_pitch >= rsx_pitch || scaled_texture != 0)
|
||||||
{
|
{
|
||||||
memcpy(dst, data, cpu_address_range);
|
memcpy(dst, data, cpu_address_range);
|
||||||
}
|
}
|
||||||
|
@ -310,6 +392,12 @@ namespace gl
|
||||||
glDeleteBuffers(1, &pbo_id);
|
glDeleteBuffers(1, &pbo_id);
|
||||||
pbo_id = 0;
|
pbo_id = 0;
|
||||||
pbo_size = 0;
|
pbo_size = 0;
|
||||||
|
|
||||||
|
if (scaled_texture)
|
||||||
|
{
|
||||||
|
glDeleteTextures(1, &scaled_texture);
|
||||||
|
scaled_texture = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_fence.is_empty())
|
if (!m_fence.is_empty())
|
||||||
|
@ -383,59 +471,6 @@ namespace gl
|
||||||
|
|
||||||
class texture_cache : public rsx::texture_cache<void*, cached_texture_section, u32, u32, gl::texture, gl::texture::format>
|
class texture_cache : public rsx::texture_cache<void*, cached_texture_section, u32, u32, gl::texture, gl::texture::format>
|
||||||
{
|
{
|
||||||
private:
|
|
||||||
|
|
||||||
class blitter
|
|
||||||
{
|
|
||||||
fbo blit_src;
|
|
||||||
fbo blit_dst;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
void init()
|
|
||||||
{
|
|
||||||
blit_src.create();
|
|
||||||
blit_dst.create();
|
|
||||||
}
|
|
||||||
|
|
||||||
void destroy()
|
|
||||||
{
|
|
||||||
blit_dst.remove();
|
|
||||||
blit_src.remove();
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 scale_image(u32 src, u32 dst, const areai src_rect, const areai dst_rect, bool linear_interpolation, bool is_depth_copy)
|
|
||||||
{
|
|
||||||
s32 old_fbo = 0;
|
|
||||||
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &old_fbo);
|
|
||||||
|
|
||||||
u32 dst_tex = dst;
|
|
||||||
filter interp = linear_interpolation ? filter::linear : filter::nearest;
|
|
||||||
|
|
||||||
GLenum attachment = is_depth_copy ? GL_DEPTH_ATTACHMENT : GL_COLOR_ATTACHMENT0;
|
|
||||||
|
|
||||||
blit_src.bind();
|
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, src, 0);
|
|
||||||
blit_src.check();
|
|
||||||
|
|
||||||
blit_dst.bind();
|
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, dst_tex, 0);
|
|
||||||
blit_dst.check();
|
|
||||||
|
|
||||||
GLboolean scissor_test_enabled = glIsEnabled(GL_SCISSOR_TEST);
|
|
||||||
if (scissor_test_enabled)
|
|
||||||
glDisable(GL_SCISSOR_TEST);
|
|
||||||
|
|
||||||
blit_src.blit(blit_dst, src_rect, dst_rect, is_depth_copy ? buffers::depth : buffers::color, interp);
|
|
||||||
|
|
||||||
if (scissor_test_enabled)
|
|
||||||
glEnable(GL_SCISSOR_TEST);
|
|
||||||
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, old_fbo);
|
|
||||||
return dst_tex;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
blitter m_hw_blitter;
|
blitter m_hw_blitter;
|
||||||
|
@ -633,14 +668,16 @@ namespace gl
|
||||||
void initialize()
|
void initialize()
|
||||||
{
|
{
|
||||||
m_hw_blitter.init();
|
m_hw_blitter.init();
|
||||||
|
g_hw_blitter = &m_hw_blitter;
|
||||||
}
|
}
|
||||||
|
|
||||||
void destroy() override
|
void destroy() override
|
||||||
{
|
{
|
||||||
clear();
|
clear();
|
||||||
|
g_hw_blitter = nullptr;
|
||||||
m_hw_blitter.destroy();
|
m_hw_blitter.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_depth_texture(const u32 rsx_address, const u32 rsx_size) override
|
bool is_depth_texture(const u32 rsx_address, const u32 rsx_size) override
|
||||||
{
|
{
|
||||||
reader_lock lock(m_cache_mutex);
|
reader_lock lock(m_cache_mutex);
|
||||||
|
|
Loading…
Reference in New Issue