mirror of https://github.com/PCSX2/pcsx2.git
GS/HW: Fix possible texture leak on skipped draw
This commit is contained in:
parent
612c24e0c0
commit
fdb751ed1a
|
@ -396,6 +396,11 @@ bool GSDevice::UpdateImGuiFontTexture()
|
|||
return true;
|
||||
}
|
||||
|
||||
void GSDevice::TextureRecycleDeleter::operator()(GSTexture* const tex)
|
||||
{
|
||||
g_gs_device->Recycle(tex);
|
||||
}
|
||||
|
||||
GSTexture* GSDevice::FetchSurface(GSTexture::Type type, int width, int height, int levels, GSTexture::Format format, bool clear, bool prefer_unused_texture)
|
||||
{
|
||||
const GSVector2i size(width, height);
|
||||
|
|
|
@ -763,6 +763,12 @@ public:
|
|||
GSHWDrawConfig::ColorMaskSelector wmask; // 0xf for all channels by default
|
||||
};
|
||||
|
||||
struct TextureRecycleDeleter
|
||||
{
|
||||
void operator()(GSTexture* const tex);
|
||||
};
|
||||
using RecycledTexture = std::unique_ptr<GSTexture, TextureRecycleDeleter>;
|
||||
|
||||
enum BlendFactor : u8
|
||||
{
|
||||
// HW blend factors
|
||||
|
|
|
@ -4586,7 +4586,8 @@ __ri static constexpr u8 EffectiveClamp(u8 clamp, bool has_region)
|
|||
return (clamp >= CLAMP_REGION_CLAMP && has_region) ? (clamp ^ 3) : clamp;
|
||||
}
|
||||
|
||||
__ri void GSRendererHW::EmulateTextureSampler(const GSTextureCache::Target* rt, const GSTextureCache::Target* ds, GSTextureCache::Source* tex, const TextureMinMaxResult& tmm, GSTexture*& src_copy)
|
||||
__ri void GSRendererHW::EmulateTextureSampler(const GSTextureCache::Target* rt, const GSTextureCache::Target* ds, GSTextureCache::Source* tex,
|
||||
const TextureMinMaxResult& tmm, GSDevice::RecycledTexture& src_copy)
|
||||
{
|
||||
// don't overwrite the texture when using channel shuffle, but keep the palette
|
||||
if (!m_channel_shuffle)
|
||||
|
@ -4908,7 +4909,7 @@ __ri void GSRendererHW::EmulateTextureSampler(const GSTextureCache::Target* rt,
|
|||
|
||||
__ri void GSRendererHW::HandleTextureHazards(const GSTextureCache::Target* rt, const GSTextureCache::Target* ds,
|
||||
const GSTextureCache::Source* tex, const TextureMinMaxResult& tmm, GSTextureCache::SourceRegion& source_region,
|
||||
bool& target_region, GSVector2i& unscaled_size, float& scale, GSTexture*& src_copy)
|
||||
bool& target_region, GSVector2i& unscaled_size, float& scale, GSDevice::RecycledTexture& src_copy)
|
||||
{
|
||||
// Detect framebuffer read that will need special handling
|
||||
const GSTextureCache::Target* src_target = nullptr;
|
||||
|
@ -5051,11 +5052,11 @@ __ri void GSRendererHW::HandleTextureHazards(const GSTextureCache::Target* rt, c
|
|||
GSVector2i(static_cast<int>(std::ceil(static_cast<float>(copy_dst_offset.x) * scale)),
|
||||
static_cast<int>(std::ceil(static_cast<float>(copy_dst_offset.y) * scale)));
|
||||
|
||||
src_copy = src_target->m_texture->IsDepthStencil() ?
|
||||
src_copy.reset(src_target->m_texture->IsDepthStencil() ?
|
||||
g_gs_device->CreateDepthStencil(
|
||||
scaled_copy_size.x, scaled_copy_size.y, src_target->m_texture->GetFormat(), false) :
|
||||
g_gs_device->CreateTexture(
|
||||
scaled_copy_size.x, scaled_copy_size.y, 1, src_target->m_texture->GetFormat(), true);
|
||||
scaled_copy_size.x, scaled_copy_size.y, 1, src_target->m_texture->GetFormat(), true));
|
||||
if (!src_copy) [[unlikely]]
|
||||
{
|
||||
Console.Error("Failed to allocate %dx%d texture for hazard copy", scaled_copy_size.x, scaled_copy_size.y);
|
||||
|
@ -5065,8 +5066,8 @@ __ri void GSRendererHW::HandleTextureHazards(const GSTextureCache::Target* rt, c
|
|||
}
|
||||
|
||||
g_gs_device->CopyRect(
|
||||
src_target->m_texture, src_copy, scaled_copy_range, scaled_copy_dst_offset.x, scaled_copy_dst_offset.y);
|
||||
m_conf.tex = src_copy;
|
||||
src_target->m_texture, src_copy.get(), scaled_copy_range, scaled_copy_dst_offset.x, scaled_copy_dst_offset.y);
|
||||
m_conf.tex = src_copy.get();
|
||||
}
|
||||
|
||||
bool GSRendererHW::CanUseTexIsFB(const GSTextureCache::Target* rt, const GSTextureCache::Source* tex,
|
||||
|
@ -5761,12 +5762,12 @@ __ri void GSRendererHW::DrawPrims(GSTextureCache::Target* rt, GSTextureCache::Ta
|
|||
m_conf.datm = static_cast<SetDATM>(m_cached_ctx.TEST.DATM);
|
||||
|
||||
// If we're doing stencil DATE and we don't have a depth buffer, we need to allocate a temporary one.
|
||||
GSTexture* temp_ds = nullptr;
|
||||
GSDevice::RecycledTexture temp_ds;
|
||||
if (m_conf.destination_alpha >= GSHWDrawConfig::DestinationAlphaMode::Stencil &&
|
||||
m_conf.destination_alpha <= GSHWDrawConfig::DestinationAlphaMode::StencilOne && !m_conf.ds)
|
||||
{
|
||||
temp_ds = g_gs_device->CreateDepthStencil(m_conf.rt->GetWidth(), m_conf.rt->GetHeight(), GSTexture::Format::DepthStencil, false);
|
||||
m_conf.ds = temp_ds;
|
||||
temp_ds.reset(g_gs_device->CreateDepthStencil(m_conf.rt->GetWidth(), m_conf.rt->GetHeight(), GSTexture::Format::DepthStencil, false));
|
||||
m_conf.ds = temp_ds.get();
|
||||
}
|
||||
|
||||
// vs
|
||||
|
@ -5868,7 +5869,7 @@ __ri void GSRendererHW::DrawPrims(GSTextureCache::Target* rt, GSTextureCache::Ta
|
|||
m_conf.cb_ps.FogColor_AREF = fc.blend32<8>(m_conf.cb_ps.FogColor_AREF);
|
||||
}
|
||||
|
||||
GSTexture* tex_copy = nullptr;
|
||||
GSDevice::RecycledTexture tex_copy;
|
||||
if (tex)
|
||||
{
|
||||
EmulateTextureSampler(rt, ds, tex, tmm, tex_copy);
|
||||
|
@ -5983,10 +5984,7 @@ __ri void GSRendererHW::DrawPrims(GSTextureCache::Target* rt, GSTextureCache::Ta
|
|||
if (!ate_first_pass)
|
||||
{
|
||||
if (!m_conf.alpha_second_pass.enable)
|
||||
{
|
||||
CleanupDraw(true);
|
||||
return;
|
||||
}
|
||||
|
||||
// RenderHW always renders first pass, replace first pass with second
|
||||
std::memcpy(&m_conf.ps, &m_conf.alpha_second_pass.ps, sizeof(m_conf.ps));
|
||||
|
@ -5999,11 +5997,6 @@ __ri void GSRendererHW::DrawPrims(GSTextureCache::Target* rt, GSTextureCache::Ta
|
|||
m_conf.drawlist = (m_conf.require_full_barrier && m_vt.m_primclass == GS_SPRITE_CLASS) ? &m_drawlist : nullptr;
|
||||
|
||||
g_gs_device->RenderHW(m_conf);
|
||||
|
||||
if (tex_copy)
|
||||
g_gs_device->Recycle(tex_copy);
|
||||
if (temp_ds)
|
||||
g_gs_device->Recycle(temp_ds);
|
||||
}
|
||||
|
||||
// If the EE uploaded a new CLUT since the last draw, use that.
|
||||
|
|
|
@ -92,10 +92,10 @@ private:
|
|||
void CleanupDraw(bool invalidate_temp_src);
|
||||
|
||||
void EmulateTextureSampler(const GSTextureCache::Target* rt, const GSTextureCache::Target* ds,
|
||||
GSTextureCache::Source* tex, const TextureMinMaxResult& tmm, GSTexture*& src_copy);
|
||||
GSTextureCache::Source* tex, const TextureMinMaxResult& tmm, GSDevice::RecycledTexture& src_copy);
|
||||
void HandleTextureHazards(const GSTextureCache::Target* rt, const GSTextureCache::Target* ds,
|
||||
const GSTextureCache::Source* tex, const TextureMinMaxResult& tmm, GSTextureCache::SourceRegion& source_region,
|
||||
bool& target_region, GSVector2i& unscaled_size, float& scale, GSTexture*& src_copy);
|
||||
bool& target_region, GSVector2i& unscaled_size, float& scale, GSDevice::RecycledTexture& src_copy);
|
||||
bool CanUseTexIsFB(const GSTextureCache::Target* rt, const GSTextureCache::Source* tex,
|
||||
const TextureMinMaxResult& tmm);
|
||||
|
||||
|
|
Loading…
Reference in New Issue