mirror of https://github.com/PCSX2/pcsx2.git
GS-hw: rework surface fetching.
Factorized code. Always clear render targets and depth stencils when being fetched. "force_texture_clear" OGL only config removed.
This commit is contained in:
parent
0f2768dca4
commit
2e6c5cde29
|
@ -1134,7 +1134,6 @@ void GSApp::Init()
|
|||
m_default_configuration["extrathreads"] = "2";
|
||||
m_default_configuration["extrathreads_height"] = "4";
|
||||
m_default_configuration["filter"] = std::to_string(static_cast<s8>(BiFiltering::PS2));
|
||||
m_default_configuration["force_texture_clear"] = "0";
|
||||
m_default_configuration["fxaa"] = "0";
|
||||
m_default_configuration["interlace"] = "7";
|
||||
m_default_configuration["conservative_framebuffer"] = "1";
|
||||
|
|
|
@ -66,9 +66,7 @@ GSDevice::GSDevice()
|
|||
|
||||
GSDevice::~GSDevice()
|
||||
{
|
||||
for (auto t : m_pool)
|
||||
delete t;
|
||||
|
||||
PurgePool();
|
||||
delete m_backbuffer;
|
||||
delete m_merge;
|
||||
delete m_weavebob;
|
||||
|
@ -83,10 +81,7 @@ bool GSDevice::Create(const WindowInfo& wi)
|
|||
|
||||
bool GSDevice::Reset(int w, int h)
|
||||
{
|
||||
for (auto t : m_pool)
|
||||
delete t;
|
||||
|
||||
m_pool.clear();
|
||||
PurgePool();
|
||||
|
||||
delete m_backbuffer;
|
||||
delete m_merge;
|
||||
|
@ -94,13 +89,13 @@ bool GSDevice::Reset(int w, int h)
|
|||
delete m_blend;
|
||||
delete m_target_tmp;
|
||||
|
||||
m_backbuffer = NULL;
|
||||
m_merge = NULL;
|
||||
m_weavebob = NULL;
|
||||
m_blend = NULL;
|
||||
m_target_tmp = NULL;
|
||||
m_backbuffer = nullptr;
|
||||
m_merge = nullptr;
|
||||
m_weavebob = nullptr;
|
||||
m_blend = nullptr;
|
||||
m_target_tmp = nullptr;
|
||||
|
||||
m_current = NULL; // current is special, points to other textures, no need to delete
|
||||
m_current = nullptr; // current is special, points to other textures, no need to delete
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -139,19 +134,44 @@ GSTexture* GSDevice::FetchSurface(GSTexture::Type type, int w, int h, GSTexture:
|
|||
{
|
||||
const GSVector2i size(w, h);
|
||||
|
||||
GSTexture* t = nullptr;
|
||||
|
||||
for (auto i = m_pool.begin(); i != m_pool.end(); ++i)
|
||||
{
|
||||
GSTexture* t = *i;
|
||||
t = *i;
|
||||
|
||||
assert(t);
|
||||
|
||||
if (t->GetType() == type && t->GetFormat() == format && t->GetSize() == size)
|
||||
{
|
||||
m_pool.erase(i);
|
||||
|
||||
return t;
|
||||
break;
|
||||
}
|
||||
|
||||
t = nullptr;
|
||||
}
|
||||
|
||||
return CreateSurface(type, w, h, format);
|
||||
if (!t)
|
||||
t = CreateSurface(type, w, h, format);
|
||||
|
||||
if (!t)
|
||||
throw std::bad_alloc();
|
||||
|
||||
t->Commit(); // Clear won't be done if the texture isn't committed.
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case GSTexture::Type::RenderTarget:
|
||||
ClearRenderTarget(t, 0);
|
||||
break;
|
||||
case GSTexture::Type::DepthStencil:
|
||||
ClearDepth(t);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
void GSDevice::PrintMemoryUsage()
|
||||
|
@ -214,13 +234,9 @@ void GSDevice::AgePool()
|
|||
|
||||
void GSDevice::PurgePool()
|
||||
{
|
||||
// OOM emergency. Let's free this useless pool
|
||||
while (!m_pool.empty())
|
||||
{
|
||||
delete m_pool.back();
|
||||
|
||||
m_pool.pop_back();
|
||||
}
|
||||
for (auto t : m_pool)
|
||||
delete t;
|
||||
m_pool.clear();
|
||||
}
|
||||
|
||||
GSTexture* GSDevice::CreateSparseRenderTarget(int w, int h, GSTexture::Format format)
|
||||
|
|
|
@ -629,7 +629,7 @@ GSTexture* GSDevice11::CreateSurface(GSTexture::Type type, int w, int h, GSTextu
|
|||
break;
|
||||
}
|
||||
|
||||
GSTexture11* t = NULL;
|
||||
GSTexture11* t = nullptr;
|
||||
|
||||
wil::com_ptr_nothrow<ID3D11Texture2D> texture;
|
||||
HRESULT hr = m_dev->CreateTexture2D(&desc, nullptr, texture.put());
|
||||
|
@ -637,16 +637,7 @@ GSTexture* GSDevice11::CreateSurface(GSTexture::Type type, int w, int h, GSTextu
|
|||
if (SUCCEEDED(hr))
|
||||
{
|
||||
t = new GSTexture11(std::move(texture), format);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case GSTexture::Type::RenderTarget:
|
||||
ClearRenderTarget(t, 0);
|
||||
break;
|
||||
case GSTexture::Type::DepthStencil:
|
||||
ClearDepth(t);
|
||||
break;
|
||||
}
|
||||
assert(type == t->GetType());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -656,11 +647,6 @@ GSTexture* GSDevice11::CreateSurface(GSTexture::Type type, int w, int h, GSTextu
|
|||
return t;
|
||||
}
|
||||
|
||||
GSTexture* GSDevice11::FetchSurface(GSTexture::Type type, int w, int h, GSTexture::Format format)
|
||||
{
|
||||
return __super::FetchSurface(type, w, h, format);
|
||||
}
|
||||
|
||||
bool GSDevice11::DownloadTexture(GSTexture* src, const GSVector4i& rect, GSTexture::GSMap& out_map)
|
||||
{
|
||||
ASSERT(src);
|
||||
|
|
|
@ -397,7 +397,6 @@ private:
|
|||
int m_d3d_texsize;
|
||||
|
||||
GSTexture* CreateSurface(GSTexture::Type type, int w, int h, GSTexture::Format format) final;
|
||||
GSTexture* FetchSurface(GSTexture::Type type, int w, int h, GSTexture::Format format) final;
|
||||
|
||||
void DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex, GSVector4* dRect, const GSRegPMODE& PMODE, const GSRegEXTBUF& EXTBUF, const GSVector4& c) final;
|
||||
void DoInterlace(GSTexture* sTex, GSTexture* dTex, int shader, bool linear, float yoffset = 0) final;
|
||||
|
|
|
@ -49,8 +49,7 @@ int GSDeviceOGL::m_shader_reg = 0;
|
|||
FILE* GSDeviceOGL::m_debug_gl_file = NULL;
|
||||
|
||||
GSDeviceOGL::GSDeviceOGL()
|
||||
: m_force_texture_clear(0)
|
||||
, m_fbo(0)
|
||||
: m_fbo(0)
|
||||
, m_fbo_read(0)
|
||||
, m_apitrace(0)
|
||||
, m_palette_ss(0)
|
||||
|
@ -238,68 +237,9 @@ GSTexture* GSDeviceOGL::CreateSurface(GSTexture::Type type, int w, int h, GSText
|
|||
{
|
||||
GL_PUSH("Create surface");
|
||||
|
||||
// A wrapper to call GSTextureOGL, with the different kind of parameter
|
||||
// A wrapper to call GSTextureOGL, with the different kind of parameters.
|
||||
GSTextureOGL* t = new GSTextureOGL(type, w, h, fmt, m_fbo_read, m_mipmap > 1 || m_filter != TriFiltering::None);
|
||||
|
||||
// NOTE: I'm not sure RenderTarget always need to be cleared. It could be costly for big upscale.
|
||||
// FIXME: it will be more logical to do it in FetchSurface. This code is only called at first creation
|
||||
// of the texture. However we could reuse a deleted texture.
|
||||
if (m_force_texture_clear == 0)
|
||||
{
|
||||
// Clear won't be done if the texture isn't committed. Commit the full texture to ensure
|
||||
// correct behavior of force clear option (debug option)
|
||||
t->Commit();
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case GSTexture::Type::RenderTarget:
|
||||
ClearRenderTarget(t, 0);
|
||||
break;
|
||||
case GSTexture::Type::DepthStencil:
|
||||
ClearDepth(t);
|
||||
// No need to clear the stencil now.
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
GSTexture* GSDeviceOGL::FetchSurface(GSTexture::Type type, int w, int h, GSTexture::Format format)
|
||||
{
|
||||
GSTexture* t = GSDevice::FetchSurface(type, w, h, format);
|
||||
|
||||
|
||||
if (m_force_texture_clear)
|
||||
{
|
||||
// Clear won't be done if the texture isn't committed. Commit the full texture to ensure
|
||||
// correct behavior of force clear option (debug option)
|
||||
t->Commit();
|
||||
|
||||
const GSVector4 red(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
switch (type)
|
||||
{
|
||||
case GSTexture::Type::RenderTarget:
|
||||
ClearRenderTarget(t, 0);
|
||||
break;
|
||||
case GSTexture::Type::DepthStencil:
|
||||
ClearDepth(t);
|
||||
// No need to clear the stencil now.
|
||||
break;
|
||||
case GSTexture::Type::Texture:
|
||||
if (m_force_texture_clear > 1)
|
||||
static_cast<GSTextureOGL*>(t)->Clear((void*)&red);
|
||||
else if (m_force_texture_clear)
|
||||
static_cast<GSTextureOGL*>(t)->Clear(NULL);
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
|
@ -346,8 +286,6 @@ bool GSDeviceOGL::Create(const WindowInfo& wi)
|
|||
}
|
||||
#endif
|
||||
|
||||
m_force_texture_clear = theApp.GetConfigI("force_texture_clear");
|
||||
|
||||
// WARNING it must be done after the control setup (at least on MESA)
|
||||
GL_PUSH("GSDeviceOGL::Create");
|
||||
|
||||
|
|
|
@ -462,7 +462,6 @@ public:
|
|||
|
||||
private:
|
||||
std::unique_ptr<GL::Context> m_gl_context;
|
||||
int m_force_texture_clear;
|
||||
int m_mipmap;
|
||||
TriFiltering m_filter;
|
||||
|
||||
|
@ -559,7 +558,6 @@ private:
|
|||
AlignedBuffer<u8, 32> m_download_buffer;
|
||||
|
||||
GSTexture* CreateSurface(GSTexture::Type type, int w, int h, GSTexture::Format format) final;
|
||||
GSTexture* FetchSurface(GSTexture::Type type, int w, int h, GSTexture::Format format) final;
|
||||
|
||||
void DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex, GSVector4* dRect, const GSRegPMODE& PMODE, const GSRegEXTBUF& EXTBUF, const GSVector4& c) final;
|
||||
void DoInterlace(GSTexture* sTex, GSTexture* dTex, int shader, bool linear, float yoffset = 0) final;
|
||||
|
|
Loading…
Reference in New Issue