GPU: Implement skip-drawing-to-active-field for interlaced mode

Currently only in the software renderer.
This commit is contained in:
Connor McLaughlin 2020-04-04 00:10:41 +10:00
parent ba98bf345a
commit 48fba47ee6
4 changed files with 13 additions and 1 deletions

View file

@ -240,7 +240,7 @@ u32 GPU::ReadRegister(u32 offset)
// code can be dependent on the odd/even bit, so update the GPU state when reading.
// we can mitigate this slightly by only updating when the raster is actually hitting a new line
if (IsRasterScanlinePending())
m_tick_event->InvokeEarly(true);
Synchronize();
return m_GPUSTAT.bits;
}

View file

@ -400,6 +400,12 @@ protected:
static constexpr u32 MASK = (1 << 19) | (1 << 22);
return ((bits & MASK) == MASK);
}
bool SkipDrawingToActiveField() const
{
static constexpr u32 MASK = (1 << 19) | (1 << 22) | (1 << 10);
static constexpr u32 ACTIVE = (1 << 19) | (1 << 22);
return ((bits & MASK) == ACTIVE);
}
// During transfer/render operations, if ((dst_pixel & mask_and) == 0) { pixel = src_pixel | mask_or }
u16 GetMaskAND() const

View file

@ -306,6 +306,9 @@ bool GPU::HandleRenderCommand(const u32*& command_ptr, u32 command_size)
primitive_names[static_cast<u8>(rc.primitive.GetValue())], ZeroExtend32(num_vertices),
ZeroExtend32(words_per_vertex));
if (m_GPUSTAT.SkipDrawingToActiveField() && IsRasterScanlinePending())
Synchronize();
DispatchRenderCommand(rc, num_vertices, command_ptr);
command_ptr += total_words;
m_stats.num_vertices += num_vertices;

View file

@ -574,6 +574,9 @@ void GPU_SW::ShadePixel(u32 x, u32 y, u8 color_r, u8 color_g, u8 color_b, u8 tex
if ((bg_color.bits & mask_and) != 0)
return;
if (m_GPUSTAT.SkipDrawingToActiveField() && BoolToUInt32(m_GPUSTAT.drawing_even_line) != (static_cast<u32>(y) & 1u))
return;
SetPixel(static_cast<u32>(x), static_cast<u32>(y), color.bits | m_GPUSTAT.GetMaskOR());
}