mirror of https://github.com/PCSX2/pcsx2.git
GS-hw: resize rt and ds before draw if necessary.
This commit is contained in:
parent
6b51462fa0
commit
b315625a94
|
@ -1295,8 +1295,8 @@ void GSRendererHW::Draw()
|
||||||
TEX0.TBW = context->FRAME.FBW;
|
TEX0.TBW = context->FRAME.FBW;
|
||||||
TEX0.PSM = context->FRAME.PSM;
|
TEX0.PSM = context->FRAME.PSM;
|
||||||
|
|
||||||
GSTextureCache::Target* rt = NULL;
|
GSTextureCache::Target* rt = nullptr;
|
||||||
GSTexture* rt_tex = NULL;
|
GSTexture* rt_tex = nullptr;
|
||||||
if (!no_rt)
|
if (!no_rt)
|
||||||
{
|
{
|
||||||
rt = m_tc->LookupTarget(TEX0, m_width, m_height, GSTextureCache::RenderTarget, true, fm);
|
rt = m_tc->LookupTarget(TEX0, m_width, m_height, GSTextureCache::RenderTarget, true, fm);
|
||||||
|
@ -1307,8 +1307,8 @@ void GSRendererHW::Draw()
|
||||||
TEX0.TBW = context->FRAME.FBW;
|
TEX0.TBW = context->FRAME.FBW;
|
||||||
TEX0.PSM = context->ZBUF.PSM;
|
TEX0.PSM = context->ZBUF.PSM;
|
||||||
|
|
||||||
GSTextureCache::Target* ds = NULL;
|
GSTextureCache::Target* ds = nullptr;
|
||||||
GSTexture* ds_tex = NULL;
|
GSTexture* ds_tex = nullptr;
|
||||||
if (!no_ds)
|
if (!no_ds)
|
||||||
{
|
{
|
||||||
ds = m_tc->LookupTarget(TEX0, m_width, m_height, GSTextureCache::DepthStencil, context->DepthWrite());
|
ds = m_tc->LookupTarget(TEX0, m_width, m_height, GSTextureCache::DepthStencil, context->DepthWrite());
|
||||||
|
@ -1491,6 +1491,41 @@ void GSRendererHW::Draw()
|
||||||
rt->m_32_bits_fmt = m_texture_shuffle || (GSLocalMemory::m_psm[context->FRAME.PSM].bpp != 16);
|
rt->m_32_bits_fmt = m_texture_shuffle || (GSLocalMemory::m_psm[context->FRAME.PSM].bpp != 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The rectangle of the draw
|
||||||
|
m_r = GSVector4i(m_vt.m_min.p.xyxy(m_vt.m_max.p)).rintersect(GSVector4i(context->scissor.in));
|
||||||
|
|
||||||
|
{
|
||||||
|
const GSVector2 up_s = GetTextureScaleFactor();
|
||||||
|
const int up_w = static_cast<int>(std::ceil(static_cast<float>(m_r.z) * up_s.x));
|
||||||
|
const int up_h = static_cast<int>(std::ceil(static_cast<float>(m_r.w) * up_s.y));
|
||||||
|
const int new_w = std::max(up_w, std::max(rt_tex ? rt_tex->GetWidth() : 0, ds_tex ? ds_tex->GetWidth() : 0));
|
||||||
|
const int new_h = std::max(up_h, std::max(rt_tex ? rt_tex->GetHeight() : 0, ds_tex ? ds_tex->GetHeight() : 0));
|
||||||
|
std::array<GSTextureCache::Target*, 2> ts{ rt, ds };
|
||||||
|
for (GSTextureCache::Target* t : ts)
|
||||||
|
{
|
||||||
|
if (t)
|
||||||
|
{
|
||||||
|
// Adjust texture size to fit current draw if necessary.
|
||||||
|
GSTexture* tex = t->m_texture;
|
||||||
|
assert(up_s == tex->GetScale());
|
||||||
|
const int w = tex->GetWidth();
|
||||||
|
const int h = tex->GetHeight();
|
||||||
|
if (w != new_w || h != new_h)
|
||||||
|
{
|
||||||
|
const bool is_rt = t == rt;
|
||||||
|
t->m_texture = is_rt ?
|
||||||
|
m_dev->CreateSparseRenderTarget(new_w, new_h, tex->GetFormat()) :
|
||||||
|
m_dev->CreateSparseDepthStencil(new_w, new_h, tex->GetFormat());
|
||||||
|
const GSVector4i r{ 0, 0, w, h };
|
||||||
|
m_dev->CopyRect(tex, t->m_texture, r);
|
||||||
|
m_dev->Recycle(tex);
|
||||||
|
t->m_texture->SetScale(up_s);
|
||||||
|
(is_rt ? rt_tex : ds_tex) = t->m_texture;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (s_dump)
|
if (s_dump)
|
||||||
{
|
{
|
||||||
const u64 frame = m_perfmon.GetFrame();
|
const u64 frame = m_perfmon.GetFrame();
|
||||||
|
@ -1528,8 +1563,8 @@ void GSRendererHW::Draw()
|
||||||
{
|
{
|
||||||
s = format("%05d_f%lld_rt0_%05x_%s.bmp", s_n, frame, context->FRAME.Block(), psm_str(context->FRAME.PSM));
|
s = format("%05d_f%lld_rt0_%05x_%s.bmp", s_n, frame, context->FRAME.Block(), psm_str(context->FRAME.PSM));
|
||||||
|
|
||||||
if (rt)
|
if (rt_tex)
|
||||||
rt->m_texture->Save(m_dump_root + s);
|
rt_tex->Save(m_dump_root + s);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s_savez && s_n >= s_saven)
|
if (s_savez && s_n >= s_saven)
|
||||||
|
@ -1541,9 +1576,6 @@ void GSRendererHW::Draw()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The rectangle of the draw
|
|
||||||
m_r = GSVector4i(m_vt.m_min.p.xyxy(m_vt.m_max.p)).rintersect(GSVector4i(context->scissor.in));
|
|
||||||
|
|
||||||
if (m_hacks.m_oi && !(this->*m_hacks.m_oi)(rt_tex, ds_tex, m_src))
|
if (m_hacks.m_oi && !(this->*m_hacks.m_oi)(rt_tex, ds_tex, m_src))
|
||||||
{
|
{
|
||||||
GL_INS("Warning skipping a draw call (%d)", s_n);
|
GL_INS("Warning skipping a draw call (%d)", s_n);
|
||||||
|
@ -1634,18 +1666,6 @@ void GSRendererHW::Draw()
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
// Help to detect rendering outside of the framebuffer
|
|
||||||
#if _DEBUG
|
|
||||||
if (m_upscale_multiplier * m_r.z > m_width)
|
|
||||||
{
|
|
||||||
GL_INS("ERROR: RT width is too small only %d but require %d", m_width, m_upscale_multiplier * m_r.z);
|
|
||||||
}
|
|
||||||
if (m_upscale_multiplier * m_r.w > m_height)
|
|
||||||
{
|
|
||||||
GL_INS("ERROR: RT height is too small only %d but require %d", m_height, m_upscale_multiplier * m_r.w);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (fm != 0xffffffff && rt)
|
if (fm != 0xffffffff && rt)
|
||||||
{
|
{
|
||||||
//rt->m_valid = rt->m_valid.runion(r);
|
//rt->m_valid = rt->m_valid.runion(r);
|
||||||
|
@ -1683,8 +1703,8 @@ void GSRendererHW::Draw()
|
||||||
{
|
{
|
||||||
s = format("%05d_f%lld_rt1_%05x_%s.bmp", s_n, frame, context->FRAME.Block(), psm_str(context->FRAME.PSM));
|
s = format("%05d_f%lld_rt1_%05x_%s.bmp", s_n, frame, context->FRAME.Block(), psm_str(context->FRAME.PSM));
|
||||||
|
|
||||||
if (rt)
|
if (rt_tex)
|
||||||
rt->m_texture->Save(m_dump_root + s);
|
rt_tex->Save(m_dump_root + s);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s_savez && s_n >= s_saven)
|
if (s_savez && s_n >= s_saven)
|
||||||
|
|
Loading…
Reference in New Issue