mirror of https://github.com/PCSX2/pcsx2.git
GS: Use textures instead of render targets for target copies
Saves the clear.
This commit is contained in:
parent
4c3df1a963
commit
5976be55f4
|
@ -103,7 +103,7 @@ void GSDevice::RestoreAPIState()
|
|||
{
|
||||
}
|
||||
|
||||
GSTexture* GSDevice::FetchSurface(GSTexture::Type type, int w, int h, GSTexture::Format format)
|
||||
GSTexture* GSDevice::FetchSurface(GSTexture::Type type, int w, int h, GSTexture::Format format, bool clear)
|
||||
{
|
||||
const GSVector2i size(w, h);
|
||||
|
||||
|
@ -135,10 +135,20 @@ GSTexture* GSDevice::FetchSurface(GSTexture::Type type, int w, int h, GSTexture:
|
|||
switch (type)
|
||||
{
|
||||
case GSTexture::Type::RenderTarget:
|
||||
ClearRenderTarget(t, 0);
|
||||
{
|
||||
if (clear)
|
||||
ClearRenderTarget(t, 0);
|
||||
else
|
||||
InvalidateRenderTarget(t);
|
||||
}
|
||||
break;
|
||||
case GSTexture::Type::DepthStencil:
|
||||
ClearDepth(t);
|
||||
{
|
||||
if (clear)
|
||||
ClearDepth(t);
|
||||
else
|
||||
InvalidateRenderTarget(t);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -212,34 +222,34 @@ void GSDevice::PurgePool()
|
|||
m_pool.clear();
|
||||
}
|
||||
|
||||
GSTexture* GSDevice::CreateSparseRenderTarget(int w, int h, GSTexture::Format format)
|
||||
GSTexture* GSDevice::CreateSparseRenderTarget(int w, int h, GSTexture::Format format, bool clear)
|
||||
{
|
||||
return FetchSurface(HasColorSparse() ? GSTexture::Type::SparseRenderTarget : GSTexture::Type::RenderTarget, w, h, format);
|
||||
return FetchSurface(HasColorSparse() ? GSTexture::Type::SparseRenderTarget : GSTexture::Type::RenderTarget, w, h, format, clear);
|
||||
}
|
||||
|
||||
GSTexture* GSDevice::CreateSparseDepthStencil(int w, int h, GSTexture::Format format)
|
||||
GSTexture* GSDevice::CreateSparseDepthStencil(int w, int h, GSTexture::Format format, bool clear)
|
||||
{
|
||||
return FetchSurface(HasDepthSparse() ? GSTexture::Type::SparseDepthStencil : GSTexture::Type::DepthStencil, w, h, format);
|
||||
return FetchSurface(HasDepthSparse() ? GSTexture::Type::SparseDepthStencil : GSTexture::Type::DepthStencil, w, h, format, clear);
|
||||
}
|
||||
|
||||
GSTexture* GSDevice::CreateRenderTarget(int w, int h, GSTexture::Format format)
|
||||
GSTexture* GSDevice::CreateRenderTarget(int w, int h, GSTexture::Format format, bool clear)
|
||||
{
|
||||
return FetchSurface(GSTexture::Type::RenderTarget, w, h, format);
|
||||
return FetchSurface(GSTexture::Type::RenderTarget, w, h, format, clear);
|
||||
}
|
||||
|
||||
GSTexture* GSDevice::CreateDepthStencil(int w, int h, GSTexture::Format format)
|
||||
GSTexture* GSDevice::CreateDepthStencil(int w, int h, GSTexture::Format format, bool clear)
|
||||
{
|
||||
return FetchSurface(GSTexture::Type::DepthStencil, w, h, format);
|
||||
return FetchSurface(GSTexture::Type::DepthStencil, w, h, format, clear);
|
||||
}
|
||||
|
||||
GSTexture* GSDevice::CreateTexture(int w, int h, GSTexture::Format format)
|
||||
{
|
||||
return FetchSurface(GSTexture::Type::Texture, w, h, format);
|
||||
return FetchSurface(GSTexture::Type::Texture, w, h, format, false);
|
||||
}
|
||||
|
||||
GSTexture* GSDevice::CreateOffscreen(int w, int h, GSTexture::Format format)
|
||||
{
|
||||
return FetchSurface(GSTexture::Type::Offscreen, w, h, format);
|
||||
return FetchSurface(GSTexture::Type::Offscreen, w, h, format, false);
|
||||
}
|
||||
|
||||
GSTexture::Format GSDevice::GetDefaultTextureFormat(GSTexture::Type type)
|
||||
|
@ -387,7 +397,7 @@ void GSDevice::ShadeBoost()
|
|||
}
|
||||
}
|
||||
|
||||
bool GSDevice::ResizeTexture(GSTexture** t, GSTexture::Type type, int w, int h)
|
||||
bool GSDevice::ResizeTexture(GSTexture** t, GSTexture::Type type, int w, int h, bool clear)
|
||||
{
|
||||
if (t == NULL)
|
||||
{
|
||||
|
@ -402,7 +412,7 @@ bool GSDevice::ResizeTexture(GSTexture** t, GSTexture::Type type, int w, int h)
|
|||
GSTexture::Format fmt = t2 ? t2->GetFormat() : GetDefaultTextureFormat(type);
|
||||
delete t2;
|
||||
|
||||
t2 = FetchSurface(type, w, h, fmt);
|
||||
t2 = FetchSurface(type, w, h, fmt, clear);
|
||||
|
||||
*t = t2;
|
||||
}
|
||||
|
@ -410,9 +420,9 @@ bool GSDevice::ResizeTexture(GSTexture** t, GSTexture::Type type, int w, int h)
|
|||
return t2 != NULL;
|
||||
}
|
||||
|
||||
bool GSDevice::ResizeTexture(GSTexture** t, int w, int h)
|
||||
bool GSDevice::ResizeTexture(GSTexture** t, int w, int h, bool clear)
|
||||
{
|
||||
return ResizeTexture(t, GSTexture::Type::Texture, w, h);
|
||||
return ResizeTexture(t, GSTexture::Type::Texture, w, h, clear);
|
||||
}
|
||||
|
||||
bool GSDevice::ResizeTarget(GSTexture** t, int w, int h)
|
||||
|
|
|
@ -546,7 +546,7 @@ protected:
|
|||
FeatureSupport m_features;
|
||||
|
||||
virtual GSTexture* CreateSurface(GSTexture::Type type, int w, int h, GSTexture::Format format) = 0;
|
||||
virtual GSTexture* FetchSurface(GSTexture::Type type, int w, int h, GSTexture::Format format);
|
||||
virtual GSTexture* FetchSurface(GSTexture::Type type, int w, int h, GSTexture::Format format, bool clear);
|
||||
|
||||
virtual void DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex, GSVector4* dRect, const GSRegPMODE& PMODE, const GSRegEXTBUF& EXTBUF, const GSVector4& c) = 0;
|
||||
virtual void DoInterlace(GSTexture* sTex, GSTexture* dTex, int shader, bool linear, float yoffset) = 0;
|
||||
|
@ -584,13 +584,14 @@ public:
|
|||
|
||||
virtual void ClearRenderTarget(GSTexture* t, const GSVector4& c) {}
|
||||
virtual void ClearRenderTarget(GSTexture* t, u32 c) {}
|
||||
virtual void InvalidateRenderTarget(GSTexture* t) {}
|
||||
virtual void ClearDepth(GSTexture* t) {}
|
||||
virtual void ClearStencil(GSTexture* t, u8 c) {}
|
||||
|
||||
GSTexture* CreateSparseRenderTarget(int w, int h, GSTexture::Format format);
|
||||
GSTexture* CreateSparseDepthStencil(int w, int h, GSTexture::Format format);
|
||||
GSTexture* CreateRenderTarget(int w, int h, GSTexture::Format format);
|
||||
GSTexture* CreateDepthStencil(int w, int h, GSTexture::Format format);
|
||||
GSTexture* CreateSparseRenderTarget(int w, int h, GSTexture::Format format, bool clear = true);
|
||||
GSTexture* CreateSparseDepthStencil(int w, int h, GSTexture::Format format, bool clear = true);
|
||||
GSTexture* CreateRenderTarget(int w, int h, GSTexture::Format format, bool clear = true);
|
||||
GSTexture* CreateDepthStencil(int w, int h, GSTexture::Format format, bool clear = true);
|
||||
GSTexture* CreateTexture(int w, int h, GSTexture::Format format);
|
||||
GSTexture* CreateOffscreen(int w, int h, GSTexture::Format format);
|
||||
GSTexture::Format GetDefaultTextureFormat(GSTexture::Type type);
|
||||
|
@ -623,8 +624,8 @@ public:
|
|||
void ShadeBoost();
|
||||
void ExternalFX();
|
||||
|
||||
bool ResizeTexture(GSTexture** t, GSTexture::Type type, int w, int h);
|
||||
bool ResizeTexture(GSTexture** t, int w, int h);
|
||||
bool ResizeTexture(GSTexture** t, GSTexture::Type type, int w, int h, bool clear = true);
|
||||
bool ResizeTexture(GSTexture** t, int w, int h, bool clear = true);
|
||||
bool ResizeTarget(GSTexture** t, int w, int h);
|
||||
bool ResizeTarget(GSTexture** t);
|
||||
|
||||
|
|
|
@ -1297,7 +1297,7 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con
|
|||
int h = (int)(scale.y * th);
|
||||
|
||||
GSTexture* sTex = dst->m_texture;
|
||||
GSTexture* dTex = g_gs_device->CreateRenderTarget(w, h, GSTexture::Format::Color);
|
||||
GSTexture* dTex = g_gs_device->CreateTexture(w, h, GSTexture::Format::Color);
|
||||
|
||||
GSVector4i area(x, y, x + w, y + h);
|
||||
g_gs_device->CopyRect(sTex, dTex, area);
|
||||
|
@ -1329,7 +1329,7 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con
|
|||
// So it could be tricky to put in the middle of the DrawPrims
|
||||
|
||||
// Texture is created to keep code compatibility
|
||||
GSTexture* dTex = g_gs_device->CreateRenderTarget(tw, th, GSTexture::Format::Color);
|
||||
GSTexture* dTex = g_gs_device->CreateTexture(tw, th, GSTexture::Format::Color);
|
||||
|
||||
// Keep a trace of origin of the texture
|
||||
src->m_texture = dTex;
|
||||
|
@ -1496,11 +1496,15 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con
|
|||
}
|
||||
|
||||
GSVector4 sRect(0, 0, w, h);
|
||||
const bool texture_completely_overwritten = ((sRect == dRect).alltrue());
|
||||
const bool use_texture = (texture_completely_overwritten && shader == ShaderConvert::COPY);
|
||||
|
||||
// Don't be fooled by the name. 'dst' is the old target (hence the input)
|
||||
// 'src' is the new texture cache entry (hence the output)
|
||||
GSTexture* sTex = dst->m_texture;
|
||||
GSTexture* dTex = g_gs_device->CreateRenderTarget(w, h, GSTexture::Format::Color);
|
||||
GSTexture* dTex = use_texture ?
|
||||
g_gs_device->CreateTexture(w, h, GSTexture::Format::Color) :
|
||||
g_gs_device->CreateRenderTarget(w, h, GSTexture::Format::Color, !texture_completely_overwritten);
|
||||
src->m_texture = dTex;
|
||||
|
||||
// GH: by default (m_paltex == 0) GS converts texture to the 32 bit format
|
||||
|
@ -1536,7 +1540,7 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con
|
|||
// copy. Likely a speed boost and memory usage reduction.
|
||||
bool linear = (TEX0.PSM == PSM_PSMCT32 || TEX0.PSM == PSM_PSMCT24);
|
||||
|
||||
if ((sRect == dRect).alltrue() && shader == ShaderConvert::COPY)
|
||||
if (use_texture)
|
||||
{
|
||||
if (half_right)
|
||||
{
|
||||
|
|
|
@ -752,6 +752,31 @@ void GSDeviceOGL::ClearRenderTarget(GSTexture* t, u32 c)
|
|||
ClearRenderTarget(t, color);
|
||||
}
|
||||
|
||||
void GSDeviceOGL::InvalidateRenderTarget(GSTexture* t)
|
||||
{
|
||||
GSTextureOGL* T = static_cast<GSTextureOGL*>(t);
|
||||
if (!T || T->HasBeenCleaned())
|
||||
return;
|
||||
|
||||
if (GLAD_GL_VERSION_4_3 || GLAD_GL_ES_VERSION_3_0)
|
||||
{
|
||||
OMSetFBO(m_fbo);
|
||||
|
||||
if (T->GetType() == GSTexture::Type::DepthStencil || T->GetType() == GSTexture::Type::SparseDepthStencil)
|
||||
{
|
||||
OMAttachDs(T);
|
||||
const GLenum attachments[] = {GL_DEPTH_STENCIL_ATTACHMENT};
|
||||
glInvalidateFramebuffer(GL_DRAW_FRAMEBUFFER, std::size(attachments), attachments);
|
||||
}
|
||||
else
|
||||
{
|
||||
OMAttachRt(T);
|
||||
const GLenum attachments[] = {GL_COLOR_ATTACHMENT0};
|
||||
glInvalidateFramebuffer(GL_DRAW_FRAMEBUFFER, std::size(attachments), attachments);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GSDeviceOGL::ClearDepth(GSTexture* t)
|
||||
{
|
||||
if (!t)
|
||||
|
|
|
@ -336,6 +336,7 @@ public:
|
|||
|
||||
void ClearRenderTarget(GSTexture* t, const GSVector4& c) final;
|
||||
void ClearRenderTarget(GSTexture* t, u32 c) final;
|
||||
void InvalidateRenderTarget(GSTexture* t) final;
|
||||
void ClearDepth(GSTexture* t) final;
|
||||
void ClearStencil(GSTexture* t, u8 c) final;
|
||||
|
||||
|
|
|
@ -146,7 +146,7 @@ GSTexture* GSRendererSW::GetOutput(int i, int& y_offset)
|
|||
|
||||
// TODO: round up bottom
|
||||
|
||||
if (g_gs_device->ResizeTexture(&m_texture[i], w, h))
|
||||
if (g_gs_device->ResizeTexture(&m_texture[i], w, h, false))
|
||||
{
|
||||
static int pitch = 1024 * 4;
|
||||
|
||||
|
|
Loading…
Reference in New Issue