mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-23 06:15:38 +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_page_y);
|
||||||
sw.Do(&m_render_state.texture_palette_x);
|
sw.Do(&m_render_state.texture_palette_x);
|
||||||
sw.Do(&m_render_state.texture_palette_y);
|
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.transparency_mode);
|
||||||
sw.Do(&m_render_state.texture_window_mask_x);
|
sw.Do(&m_render_state.texture_window_mask_x);
|
||||||
sw.Do(&m_render_state.texture_window_mask_y);
|
sw.Do(&m_render_state.texture_window_mask_y);
|
||||||
|
@ -701,7 +701,7 @@ void GPU::RenderState::SetFromPageAttribute(u16 value)
|
||||||
texture_page_changed |=
|
texture_page_changed |=
|
||||||
(old_page_attribute & PAGE_ATTRIBUTE_TEXTURE_PAGE_MASK) != (value & PAGE_ATTRIBUTE_TEXTURE_PAGE_MASK);
|
(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)));
|
transparency_mode = (static_cast<TransparencyMode>((value >> 5) & UINT16_C(0x03)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -337,7 +337,7 @@ protected:
|
||||||
u32 texture_page_y;
|
u32 texture_page_y;
|
||||||
u32 texture_palette_x;
|
u32 texture_palette_x;
|
||||||
u32 texture_palette_y;
|
u32 texture_palette_y;
|
||||||
TextureMode texture_color_mode;
|
TextureMode texture_mode;
|
||||||
TransparencyMode transparency_mode;
|
TransparencyMode transparency_mode;
|
||||||
u8 texture_window_mask_x; // in 8 pixel steps
|
u8 texture_window_mask_x; // in 8 pixel steps
|
||||||
u8 texture_window_mask_y; // 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_page_changed = false;
|
||||||
bool texture_window_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; }
|
bool IsTexturePageChanged() const { return texture_page_changed; }
|
||||||
void ClearTexturePageChangedFlag() { texture_page_changed = false; }
|
void ClearTexturePageChangedFlag() { texture_page_changed = false; }
|
||||||
|
|
||||||
|
|
|
@ -620,7 +620,7 @@ void GPU_HW::DispatchRenderCommand(RenderCommand rc, u32 num_vertices, const u32
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
texture_mode = m_render_state.texture_color_mode;
|
texture_mode = m_render_state.texture_mode;
|
||||||
if (rc.raw_texture_enable)
|
if (rc.raw_texture_enable)
|
||||||
{
|
{
|
||||||
texture_mode =
|
texture_mode =
|
||||||
|
@ -633,6 +633,35 @@ void GPU_HW::DispatchRenderCommand(RenderCommand rc, u32 num_vertices, const u32
|
||||||
texture_mode = TextureMode::Disabled;
|
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?
|
// has any state changed which requires a new batch?
|
||||||
const TransparencyMode transparency_mode =
|
const TransparencyMode transparency_mode =
|
||||||
rc.transparency_enable ? m_render_state.transparency_mode : TransparencyMode::Disabled;
|
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;
|
const bool buffer_overflow = GetBatchVertexSpace() < max_added_vertices;
|
||||||
if (buffer_overflow || rc_primitive == HWPrimitive::LineStrip || m_batch.texture_mode != texture_mode ||
|
if (buffer_overflow || rc_primitive == HWPrimitive::LineStrip || m_batch.texture_mode != texture_mode ||
|
||||||
m_batch.transparency_mode != transparency_mode || m_batch.primitive != rc_primitive ||
|
m_batch.transparency_mode != transparency_mode || m_batch.primitive != rc_primitive ||
|
||||||
dithering_enable != m_batch.dithering || m_render_state.IsTexturePageChanged() ||
|
dithering_enable != m_batch.dithering || m_render_state.IsTextureWindowChanged())
|
||||||
m_render_state.IsTextureWindowChanged())
|
|
||||||
{
|
{
|
||||||
FlushRender();
|
FlushRender();
|
||||||
}
|
}
|
||||||
|
@ -661,31 +689,6 @@ void GPU_HW::DispatchRenderCommand(RenderCommand rc, u32 num_vertices, const u32
|
||||||
m_batch.transparency_mode = transparency_mode;
|
m_batch.transparency_mode = transparency_mode;
|
||||||
m_batch.dithering = dithering_enable;
|
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())
|
if (m_render_state.IsTextureWindowChanged())
|
||||||
{
|
{
|
||||||
m_batch.texture_window_values[0] = m_render_state.texture_window_mask_x;
|
m_batch.texture_window_values[0] = m_render_state.texture_window_mask_x;
|
||||||
|
|
|
@ -57,10 +57,6 @@ protected:
|
||||||
|
|
||||||
struct HWBatchConfig
|
struct HWBatchConfig
|
||||||
{
|
{
|
||||||
u32 texture_page_x;
|
|
||||||
u32 texture_page_y;
|
|
||||||
u32 texture_palette_x;
|
|
||||||
u32 texture_palette_y;
|
|
||||||
HWPrimitive primitive;
|
HWPrimitive primitive;
|
||||||
TextureMode texture_mode;
|
TextureMode texture_mode;
|
||||||
TransparencyMode transparency_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);
|
((m_render_state.texture_window_offset_y & m_render_state.texture_window_mask_y) * 8u);
|
||||||
|
|
||||||
VRAMPixel texture_color;
|
VRAMPixel texture_color;
|
||||||
switch (m_render_state.texture_color_mode)
|
switch (m_render_state.texture_mode)
|
||||||
{
|
{
|
||||||
case GPU::TextureMode::Palette4Bit:
|
case GPU::TextureMode::Palette4Bit:
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue