mirror of
https://github.com/libretro/pcsx2.git
synced 2024-11-24 01:39:55 +00:00
GS/HW: Skip draws on reset until scissor is set
This commit is contained in:
parent
7531080e51
commit
c045feae50
@ -159,6 +159,23 @@ void GSState::Reset(bool hardware_reset)
|
|||||||
{
|
{
|
||||||
m_env.CTXT[i].UpdateScissor();
|
m_env.CTXT[i].UpdateScissor();
|
||||||
|
|
||||||
|
// What is this nonsense? Basically, GOW does a 32x448 draw after resetting the GS, thinking the PSM for the framebuffer is going
|
||||||
|
// to be set to C24, therefore the alpha bits get left alone. Because of the reset, in PCSX2, it ends up as C32, and the TC gets
|
||||||
|
// confused, leading to a later texture load using this render target instead of local memory. It's a problem because the game
|
||||||
|
// uploads texture data on startup to the beginning of VRAM, and never overwrites it.
|
||||||
|
//
|
||||||
|
// In the software renderer, if we let the draw happen, it gets scissored to 1x1 (because the scissor is inclusive of the
|
||||||
|
// upper bounds). This doesn't seem to destroy the chest texture, presumably it's further out in memory.
|
||||||
|
//
|
||||||
|
// Hardware test show that VRAM gets corrupted on CSR reset, but the first page remains intact. We're guessing this has something
|
||||||
|
// to do with DRAM refresh, and perhaps the internal counters used for refresh also getting reset. We're obviously not going
|
||||||
|
// to emulate this, but to work around the aforementioned issue, in the hardware renderers, we set the scissor to an out of
|
||||||
|
// bounds value. This means that draws get skipped until the game sets a proper scissor up, which is definitely going to happen
|
||||||
|
// after reset (otherwise it'd only ever render 1x1).
|
||||||
|
//
|
||||||
|
if (!hardware_reset && GSConfig.UseHardwareRenderer())
|
||||||
|
m_env.CTXT[i].scissor.ex = GSVector4i::xffffffff();
|
||||||
|
|
||||||
m_env.CTXT[i].offset.fb = m_mem.GetOffset(m_env.CTXT[i].FRAME.Block(), m_env.CTXT[i].FRAME.FBW, m_env.CTXT[i].FRAME.PSM);
|
m_env.CTXT[i].offset.fb = m_mem.GetOffset(m_env.CTXT[i].FRAME.Block(), m_env.CTXT[i].FRAME.FBW, m_env.CTXT[i].FRAME.PSM);
|
||||||
m_env.CTXT[i].offset.zb = m_mem.GetOffset(m_env.CTXT[i].ZBUF.Block(), m_env.CTXT[i].FRAME.FBW, m_env.CTXT[i].ZBUF.PSM);
|
m_env.CTXT[i].offset.zb = m_mem.GetOffset(m_env.CTXT[i].ZBUF.Block(), m_env.CTXT[i].FRAME.FBW, m_env.CTXT[i].ZBUF.PSM);
|
||||||
m_env.CTXT[i].offset.fzb4 = m_mem.GetPixelOffset4(m_env.CTXT[i].FRAME, m_env.CTXT[i].ZBUF);
|
m_env.CTXT[i].offset.fzb4 = m_mem.GetPixelOffset4(m_env.CTXT[i].FRAME, m_env.CTXT[i].ZBUF);
|
||||||
@ -1025,18 +1042,21 @@ void GSState::GIFRegHandlerXYOFFSET(const GIFReg* RESTRICT r)
|
|||||||
{
|
{
|
||||||
GL_REG("XYOFFSET_%d = 0x%x_%x", i, r->U32[1], r->U32[0]);
|
GL_REG("XYOFFSET_%d = 0x%x_%x", i, r->U32[1], r->U32[0]);
|
||||||
|
|
||||||
const GSVector4i o = (GSVector4i)r->XYOFFSET & GSVector4i::x0000ffff();
|
const u64 r_masked = r->U64 & 0x0000FFFF0000FFFFu;
|
||||||
|
|
||||||
m_env.CTXT[i].XYOFFSET = o;
|
|
||||||
|
|
||||||
if (i == m_prev_env.PRIM.CTXT)
|
if (i == m_prev_env.PRIM.CTXT)
|
||||||
{
|
{
|
||||||
if (m_prev_env.CTXT[i].XYOFFSET.U64 ^ m_env.CTXT[i].XYOFFSET.U64)
|
if (m_prev_env.CTXT[i].XYOFFSET.U64 != r_masked)
|
||||||
m_dirty_gs_regs |= (1 << DIRTY_REG_XYOFFSET);
|
m_dirty_gs_regs |= (1 << DIRTY_REG_XYOFFSET);
|
||||||
else
|
else
|
||||||
m_dirty_gs_regs &= ~(1 << DIRTY_REG_XYOFFSET);
|
m_dirty_gs_regs &= ~(1 << DIRTY_REG_XYOFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_env.CTXT[i].XYOFFSET.U64 == r_masked)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_env.CTXT[i].XYOFFSET.U64 = r_masked;
|
||||||
|
|
||||||
m_env.CTXT[i].UpdateScissor();
|
m_env.CTXT[i].UpdateScissor();
|
||||||
|
|
||||||
UpdateScissor();
|
UpdateScissor();
|
||||||
@ -1159,16 +1179,18 @@ void GSState::GIFRegHandlerTEXFLUSH(const GIFReg* RESTRICT r)
|
|||||||
template <int i>
|
template <int i>
|
||||||
void GSState::GIFRegHandlerSCISSOR(const GIFReg* RESTRICT r)
|
void GSState::GIFRegHandlerSCISSOR(const GIFReg* RESTRICT r)
|
||||||
{
|
{
|
||||||
m_env.CTXT[i].SCISSOR = r->SCISSOR;
|
|
||||||
|
|
||||||
if (i == m_prev_env.PRIM.CTXT)
|
if (i == m_prev_env.PRIM.CTXT)
|
||||||
{
|
{
|
||||||
if (m_prev_env.CTXT[i].SCISSOR.U64 != m_env.CTXT[i].SCISSOR.U64)
|
if (m_prev_env.CTXT[i].SCISSOR.U64 != r->SCISSOR.U64)
|
||||||
m_dirty_gs_regs |= (1 << DIRTY_REG_SCISSOR);
|
m_dirty_gs_regs |= (1 << DIRTY_REG_SCISSOR);
|
||||||
else
|
else
|
||||||
m_dirty_gs_regs &= ~(1 << DIRTY_REG_SCISSOR);
|
m_dirty_gs_regs &= ~(1 << DIRTY_REG_SCISSOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_env.CTXT[i].SCISSOR.U64 == r->SCISSOR.U64)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_env.CTXT[i].SCISSOR = r->SCISSOR;
|
||||||
m_env.CTXT[i].UpdateScissor();
|
m_env.CTXT[i].UpdateScissor();
|
||||||
|
|
||||||
UpdateScissor();
|
UpdateScissor();
|
||||||
|
Loading…
Reference in New Issue
Block a user