mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-26 15:45:42 +00:00
GPU: Fix batching regression (draws split on texture page)
This commit is contained in:
parent
5abbdef065
commit
ba1a5a5ca9
|
@ -67,7 +67,7 @@ bool GPU::DoState(StateWrapper& sw)
|
|||
sw.Do(&m_render_state.texture_page_y);
|
||||
sw.Do(&m_render_state.texture_palette_x);
|
||||
sw.Do(&m_render_state.texture_palette_y);
|
||||
sw.Do(&m_render_state.texture_color_mode);
|
||||
sw.Do(&m_render_state.texture_mode);
|
||||
sw.Do(&m_render_state.transparency_mode);
|
||||
sw.Do(&m_render_state.texture_window_mask_x);
|
||||
sw.Do(&m_render_state.texture_window_mask_y);
|
||||
|
@ -701,7 +701,7 @@ void GPU::RenderState::SetFromPageAttribute(u16 value)
|
|||
texture_page_changed |=
|
||||
(old_page_attribute & PAGE_ATTRIBUTE_TEXTURE_PAGE_MASK) != (value & PAGE_ATTRIBUTE_TEXTURE_PAGE_MASK);
|
||||
|
||||
texture_color_mode = (static_cast<TextureMode>((value >> 7) & UINT16_C(0x03)));
|
||||
texture_mode = (static_cast<TextureMode>((value >> 7) & UINT16_C(0x03)));
|
||||
transparency_mode = (static_cast<TransparencyMode>((value >> 5) & UINT16_C(0x03)));
|
||||
}
|
||||
|
||||
|
|
|
@ -337,7 +337,7 @@ protected:
|
|||
u32 texture_page_y;
|
||||
u32 texture_palette_x;
|
||||
u32 texture_palette_y;
|
||||
TextureMode texture_color_mode;
|
||||
TextureMode texture_mode;
|
||||
TransparencyMode transparency_mode;
|
||||
u8 texture_window_mask_x; // in 8 pixel steps
|
||||
u8 texture_window_mask_y; // in 8 pixel steps
|
||||
|
@ -354,6 +354,13 @@ protected:
|
|||
bool texture_page_changed = false;
|
||||
bool texture_window_changed = false;
|
||||
|
||||
/// Returns true if the texture mode requires a palette.
|
||||
bool IsUsingPalette() const
|
||||
{
|
||||
return (static_cast<u8>(texture_mode) &
|
||||
(static_cast<u8>(TextureMode::Palette4Bit) | static_cast<u8>(TextureMode::Palette8Bit))) != 0;
|
||||
}
|
||||
|
||||
bool IsTexturePageChanged() const { return texture_page_changed; }
|
||||
void ClearTexturePageChangedFlag() { texture_page_changed = false; }
|
||||
|
||||
|
|
|
@ -620,7 +620,7 @@ void GPU_HW::DispatchRenderCommand(RenderCommand rc, u32 num_vertices, const u32
|
|||
break;
|
||||
}
|
||||
|
||||
texture_mode = m_render_state.texture_color_mode;
|
||||
texture_mode = m_render_state.texture_mode;
|
||||
if (rc.raw_texture_enable)
|
||||
{
|
||||
texture_mode =
|
||||
|
@ -633,6 +633,35 @@ void GPU_HW::DispatchRenderCommand(RenderCommand rc, u32 num_vertices, const u32
|
|||
texture_mode = TextureMode::Disabled;
|
||||
}
|
||||
|
||||
// texture page changed - check that the new page doesn't intersect the drawing area
|
||||
if (m_render_state.IsTexturePageChanged())
|
||||
{
|
||||
m_render_state.ClearTexturePageChangedFlag();
|
||||
|
||||
const u32 texture_page_left = m_render_state.texture_page_x;
|
||||
const u32 texture_page_right = m_render_state.texture_page_y + TEXTURE_PAGE_WIDTH;
|
||||
const u32 texture_page_top = m_render_state.texture_page_y;
|
||||
const u32 texture_page_bottom = texture_page_top + TEXTURE_PAGE_HEIGHT;
|
||||
const bool texture_page_overlaps =
|
||||
(texture_page_left < m_drawing_area.right && texture_page_right > m_drawing_area.left &&
|
||||
texture_page_top > m_drawing_area.bottom && texture_page_bottom < m_drawing_area.top);
|
||||
const u32 texture_palette_left = m_render_state.texture_palette_x;
|
||||
const u32 texture_palette_right = m_render_state.texture_palette_x + 256;
|
||||
const bool texture_palette_overlaps =
|
||||
m_render_state.IsUsingPalette() && texture_palette_left < m_drawing_area.right &&
|
||||
texture_palette_right > m_drawing_area.left && m_render_state.texture_palette_y < m_drawing_area.bottom &&
|
||||
m_render_state.texture_palette_y >= m_drawing_area.top;
|
||||
|
||||
// we only need to update the copy texture if the render area intersects with the texture page
|
||||
if (texture_page_overlaps || texture_palette_overlaps)
|
||||
{
|
||||
Log_WarningPrintf("Invalidating VRAM read cache due to drawing area overlap");
|
||||
if (!IsFlushed())
|
||||
FlushRender();
|
||||
InvalidateVRAMReadCache();
|
||||
}
|
||||
}
|
||||
|
||||
// has any state changed which requires a new batch?
|
||||
const TransparencyMode transparency_mode =
|
||||
rc.transparency_enable ? m_render_state.transparency_mode : TransparencyMode::Disabled;
|
||||
|
@ -644,8 +673,7 @@ void GPU_HW::DispatchRenderCommand(RenderCommand rc, u32 num_vertices, const u32
|
|||
const bool buffer_overflow = GetBatchVertexSpace() < max_added_vertices;
|
||||
if (buffer_overflow || rc_primitive == HWPrimitive::LineStrip || m_batch.texture_mode != texture_mode ||
|
||||
m_batch.transparency_mode != transparency_mode || m_batch.primitive != rc_primitive ||
|
||||
dithering_enable != m_batch.dithering || m_render_state.IsTexturePageChanged() ||
|
||||
m_render_state.IsTextureWindowChanged())
|
||||
dithering_enable != m_batch.dithering || m_render_state.IsTextureWindowChanged())
|
||||
{
|
||||
FlushRender();
|
||||
}
|
||||
|
@ -661,31 +689,6 @@ void GPU_HW::DispatchRenderCommand(RenderCommand rc, u32 num_vertices, const u32
|
|||
m_batch.transparency_mode = transparency_mode;
|
||||
m_batch.dithering = dithering_enable;
|
||||
|
||||
if (m_render_state.IsTexturePageChanged())
|
||||
{
|
||||
// we only need to update the copy texture if the render area intersects with the texture page
|
||||
const u32 texture_page_left = m_render_state.texture_page_x;
|
||||
const u32 texture_page_right = m_render_state.texture_page_y + TEXTURE_PAGE_WIDTH;
|
||||
const u32 texture_page_top = m_render_state.texture_page_y;
|
||||
const u32 texture_page_bottom = texture_page_top + TEXTURE_PAGE_HEIGHT;
|
||||
const bool texture_page_overlaps =
|
||||
(texture_page_left < m_drawing_area.right && texture_page_right > m_drawing_area.left &&
|
||||
texture_page_top > m_drawing_area.bottom && texture_page_bottom < m_drawing_area.top);
|
||||
|
||||
// TODO: Check palette too.
|
||||
if (texture_page_overlaps)
|
||||
{
|
||||
Log_DebugPrintf("Invalidating VRAM read cache due to drawing area overlap");
|
||||
InvalidateVRAMReadCache();
|
||||
}
|
||||
|
||||
m_batch.texture_page_x = m_render_state.texture_page_x;
|
||||
m_batch.texture_page_y = m_render_state.texture_page_y;
|
||||
m_batch.texture_palette_x = m_render_state.texture_palette_x;
|
||||
m_batch.texture_palette_y = m_render_state.texture_palette_y;
|
||||
m_render_state.ClearTexturePageChangedFlag();
|
||||
}
|
||||
|
||||
if (m_render_state.IsTextureWindowChanged())
|
||||
{
|
||||
m_batch.texture_window_values[0] = m_render_state.texture_window_mask_x;
|
||||
|
|
|
@ -57,10 +57,6 @@ protected:
|
|||
|
||||
struct HWBatchConfig
|
||||
{
|
||||
u32 texture_page_x;
|
||||
u32 texture_page_y;
|
||||
u32 texture_palette_x;
|
||||
u32 texture_palette_y;
|
||||
HWPrimitive primitive;
|
||||
TextureMode texture_mode;
|
||||
TransparencyMode transparency_mode;
|
||||
|
|
|
@ -416,7 +416,7 @@ void GPU_SW::ShadePixel(RenderCommand rc, u32 x, u32 y, u8 color_r, u8 color_g,
|
|||
((m_render_state.texture_window_offset_y & m_render_state.texture_window_mask_y) * 8u);
|
||||
|
||||
VRAMPixel texture_color;
|
||||
switch (m_render_state.texture_color_mode)
|
||||
switch (m_render_state.texture_mode)
|
||||
{
|
||||
case GPU::TextureMode::Palette4Bit:
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue