GS/OGL: Avoid framebuffer swaps when depth is being alternated

This commit is contained in:
Stenzek 2023-02-25 17:39:27 +10:00 committed by refractionpcsx2
parent 1b607a8c4d
commit b4beacfc43
5 changed files with 40 additions and 26 deletions

View File

@ -42,8 +42,8 @@ namespace GLState
GLuint ps_ss; GLuint ps_ss;
GLuint rt; GSTextureOGL* rt = nullptr;
GLuint ds; GSTextureOGL* ds = nullptr;
GLuint tex_unit[8]; GLuint tex_unit[8];
GLuint64 tex_handle[8]; GLuint64 tex_handle[8];
@ -72,8 +72,8 @@ namespace GLState
ps_ss = 0; ps_ss = 0;
rt = 0; rt = nullptr;
ds = 0; ds = nullptr;
std::fill(std::begin(tex_unit), std::end(tex_unit), 0); std::fill(std::begin(tex_unit), std::end(tex_unit), 0);
std::fill(std::begin(tex_handle), std::end(tex_handle), 0); std::fill(std::begin(tex_handle), std::end(tex_handle), 0);

View File

@ -18,6 +18,8 @@
#include "GS/Renderers/OpenGL/GLLoader.h" #include "GS/Renderers/OpenGL/GLLoader.h"
#include "GS/GSVector.h" #include "GS/GSVector.h"
class GSTextureOGL;
namespace GLState namespace GLState
{ {
extern GLuint fbo; // frame buffer object extern GLuint fbo; // frame buffer object
@ -44,8 +46,8 @@ namespace GLState
extern GLuint ps_ss; // sampler extern GLuint ps_ss; // sampler
extern GLuint rt; // render target extern GSTextureOGL* rt; // render target
extern GLuint ds; // Depth-Stencil extern GSTextureOGL* ds; // Depth-Stencil
extern GLuint tex_unit[8]; // shader input texture extern GLuint tex_unit[8]; // shader input texture
extern GLuint64 tex_handle[8]; // shader input texture extern GLuint64 tex_handle[8]; // shader input texture

View File

@ -1600,35 +1600,27 @@ bool GSDeviceOGL::DoCAS(GSTexture* sTex, GSTexture* dTex, bool sharpen_only, con
void GSDeviceOGL::OMAttachRt(GSTextureOGL* rt) void GSDeviceOGL::OMAttachRt(GSTextureOGL* rt)
{ {
GLuint id = 0;
if (rt) if (rt)
{
rt->WasAttached(); rt->WasAttached();
id = rt->GetID();
}
if (GLState::rt != id) if (GLState::rt != rt)
{ {
GLState::rt = id; GLState::rt = rt;
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, id, 0); glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt ? rt->GetID() : 0, 0);
} }
} }
void GSDeviceOGL::OMAttachDs(GSTextureOGL* ds) void GSDeviceOGL::OMAttachDs(GSTextureOGL* ds)
{ {
GLuint id = 0;
if (ds) if (ds)
{
ds->WasAttached(); ds->WasAttached();
id = ds->GetID();
}
if (GLState::ds != id) if (GLState::ds != ds)
{ {
GLState::ds = id; GLState::ds = ds;
const GLenum target = m_features.framebuffer_fetch ? GL_DEPTH_ATTACHMENT : GL_DEPTH_STENCIL_ATTACHMENT; const GLenum target = m_features.framebuffer_fetch ? GL_DEPTH_ATTACHMENT : GL_DEPTH_STENCIL_ATTACHMENT;
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, target, GL_TEXTURE_2D, id, 0); glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, target, GL_TEXTURE_2D, ds ? ds->GetID() : 0, 0);
} }
} }
@ -1657,6 +1649,14 @@ void GSDeviceOGL::OMSetColorMaskState(OMColorMaskSelector sel)
} }
} }
void GSDeviceOGL::OMUnbindTexture(GSTextureOGL* tex)
{
if (GLState::rt == tex)
OMAttachRt();
if (GLState::ds == tex)
OMAttachDs();
}
void GSDeviceOGL::OMSetBlendState(bool enable, GLenum src_factor, GLenum dst_factor, GLenum op, bool is_constant, u8 constant) void GSDeviceOGL::OMSetBlendState(bool enable, GLenum src_factor, GLenum dst_factor, GLenum op, bool is_constant, u8 constant)
{ {
if (enable) if (enable)
@ -1968,8 +1968,21 @@ void GSDeviceOGL::RenderHW(GSHWDrawConfig& config)
s_gl_blend_factors[config.blend.dst_factor], s_gl_blend_ops[config.blend.op], s_gl_blend_factors[config.blend.dst_factor], s_gl_blend_ops[config.blend.op],
config.blend.constant_enable, config.blend.constant); config.blend.constant_enable, config.blend.constant);
OMSetColorMaskState(config.colormask); OMSetColorMaskState(config.colormask);
// avoid changing framebuffer just to switch from rt+depth to rt and vice versa
GSTexture* draw_rt = hdr_rt ? hdr_rt : config.rt;
GSTexture* draw_ds = config.ds;
if (!draw_ds && GLState::ds && GLState::rt == draw_rt && config.tex != GLState::ds &&
GLState::ds->GetSize() == draw_rt->GetSize())
{
// should already be always-pass.
draw_ds = GLState::ds;
config.depth.ztst = ZTST_ALWAYS;
config.depth.zwe = false;
}
OMSetRenderTargets(draw_rt, draw_ds, &config.scissor);
SetupOM(config.depth); SetupOM(config.depth);
OMSetRenderTargets(hdr_rt ? hdr_rt : config.rt, config.ds, &config.scissor);
SendHWDraw(config, psel.ps.IsFeedbackLoop()); SendHWDraw(config, psel.ps.IsFeedbackLoop());

View File

@ -357,6 +357,7 @@ public:
void OMSetBlendState(bool enable = false, GLenum src_factor = GL_ONE, GLenum dst_factor = GL_ZERO, GLenum op = GL_FUNC_ADD, bool is_constant = false, u8 constant = 0); void OMSetBlendState(bool enable = false, GLenum src_factor = GL_ONE, GLenum dst_factor = GL_ZERO, GLenum op = GL_FUNC_ADD, bool is_constant = false, u8 constant = 0);
void OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVector4i* scissor = NULL); void OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVector4i* scissor = NULL);
void OMSetColorMaskState(OMColorMaskSelector sel = OMColorMaskSelector()); void OMSetColorMaskState(OMColorMaskSelector sel = OMColorMaskSelector());
void OMUnbindTexture(GSTextureOGL* tex);
bool CreateTextureFX(); bool CreateTextureFX();
std::string GetShaderSource(const std::string_view& entry, GLenum type, const std::string_view& common_header, const std::string_view& glsl_h_code, const std::string_view& macro_sel); std::string GetShaderSource(const std::string_view& entry, GLenum type, const std::string_view& common_header, const std::string_view& glsl_h_code, const std::string_view& macro_sel);

View File

@ -174,12 +174,10 @@ GSTextureOGL::GSTextureOGL(Type type, int width, int height, int levels, Format
GSTextureOGL::~GSTextureOGL() GSTextureOGL::~GSTextureOGL()
{ {
/* Unbind the texture from our local state */ // Textures aren't cleared from attachments on deletion.
GSDeviceOGL::GetInstance()->OMUnbindTexture(this);
if (m_texture_id == GLState::rt) // But they are unbound.
GLState::rt = 0;
if (m_texture_id == GLState::ds)
GLState::ds = 0;
for (GLuint& tex : GLState::tex_unit) for (GLuint& tex : GLState::tex_unit)
{ {
if (m_texture_id == tex) if (m_texture_id == tex)