GPU: Fix incorrect palette used on some polygons

This commit is contained in:
Connor McLaughlin 2019-09-27 16:17:09 +10:00
parent 7ec3343ee6
commit 40d2497087
4 changed files with 55 additions and 61 deletions

View file

@ -792,7 +792,7 @@ void GPU::RenderState::SetFromPageAttribute(u16 value)
texture_color_mode = TextureColorMode::Direct16Bit; texture_color_mode = TextureColorMode::Direct16Bit;
texpage_attribute = value; texpage_attribute = value;
texture_changed = (old_page_attribute & PAGE_ATTRIBUTE_TEXTURE_MASK) != (value & PAGE_ATTRIBUTE_TEXTURE_MASK); texture_changed |= (old_page_attribute & PAGE_ATTRIBUTE_TEXTURE_MASK) != (value & PAGE_ATTRIBUTE_TEXTURE_MASK);
const TransparencyMode old_transparency_mode = transparency_mode; const TransparencyMode old_transparency_mode = transparency_mode;
transparency_mode = (static_cast<TransparencyMode>((value >> 5) & UINT16_C(0x03))); transparency_mode = (static_cast<TransparencyMode>((value >> 5) & UINT16_C(0x03)));

View file

@ -228,10 +228,10 @@ protected:
static constexpr u16 PALETTE_ATTRIBUTE_MASK = UINT16_C(0b0111111111111111); static constexpr u16 PALETTE_ATTRIBUTE_MASK = UINT16_C(0b0111111111111111);
// decoded values // decoded values
s32 texture_page_x; u32 texture_page_x;
s32 texture_page_y; u32 texture_page_y;
s32 texture_palette_x; u32 texture_palette_x;
s32 texture_palette_y; u32 texture_palette_y;
TextureColorMode texture_color_mode; TextureColorMode texture_color_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

View file

@ -361,12 +361,34 @@ void GPU_HW::DispatchRenderCommand(RenderCommand rc, u32 num_vertices)
default: default:
break; break;
} }
}
// has any state changed which requires a new batch?
const bool rc_transparency_enable = rc.transparency_enable;
const bool rc_texture_enable = rc.texture_enable;
const bool rc_texture_blend_enable = !rc.texture_blend_disable;
const HWRenderBatch::Primitive rc_primitive = GetPrimitiveForCommand(rc);
const u32 max_added_vertices = num_vertices + 2;
const bool buffer_overflow = (m_batch.vertices.size() + max_added_vertices) >= MAX_BATCH_VERTEX_COUNT;
const bool rc_changed =
m_batch.render_command_bits != rc.bits && m_batch.transparency_enable != rc_transparency_enable ||
m_batch.texture_enable != rc_texture_enable || m_batch.texture_blending_enable != rc_texture_blend_enable ||
m_batch.primitive != rc_primitive;
const bool needs_flush = !IsFlushed() && (m_render_state.IsChanged() || buffer_overflow || rc_changed);
if (needs_flush)
FlushRender();
if (m_render_state.IsChanged()) // update state
if (rc_changed)
{ {
m_batch.render_command_bits = rc.bits;
m_batch.primitive = rc_primitive;
m_batch.transparency_enable = rc_transparency_enable;
m_batch.texture_enable = rc_texture_enable;
m_batch.texture_blending_enable = rc_texture_blend_enable;
}
if (m_render_state.IsTextureChanged()) if (m_render_state.IsTextureChanged())
{
if (!IsFlushed())
{ {
// we only need to update the copy texture if the render area intersects with the texture page // 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_left = m_render_state.texture_page_x;
@ -384,48 +406,19 @@ void GPU_HW::DispatchRenderCommand(RenderCommand rc, u32 num_vertices)
InvalidateVRAMReadCache(); InvalidateVRAMReadCache();
} }
// texture page changed?
// TODO: Move this to the shader...
FlushRender();
}
m_render_state.ClearTextureChangedFlag();
}
if (m_batch.transparency_enable && m_render_state.IsTransparencyModeChanged() && !IsFlushed())
FlushRender();
m_render_state.ClearTransparencyModeChangedFlag();
m_batch.texture_color_mode = m_render_state.texture_color_mode; m_batch.texture_color_mode = m_render_state.texture_color_mode;
m_batch.texture_page_x = m_render_state.texture_page_x; 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_page_y = m_render_state.texture_page_y;
m_batch.texture_palette_x = m_render_state.texture_palette_x; m_batch.texture_palette_x = m_render_state.texture_palette_x;
m_batch.texture_palette_y = m_render_state.texture_palette_y; m_batch.texture_palette_y = m_render_state.texture_palette_y;
m_batch.transparency_mode = m_render_state.transparency_mode; m_render_state.ClearTextureChangedFlag();
}
} }
// extract state if (m_render_state.IsTransparencyModeChanged())
const bool rc_transparency_enable = rc.transparency_enable;
const bool rc_texture_enable = rc.texture_enable;
const bool rc_texture_blend_enable = !rc.texture_blend_disable;
const HWRenderBatch::Primitive rc_primitive = GetPrimitiveForCommand(rc);
// flush when the command changes
if (!m_batch.vertices.empty())
{ {
// including the degenerate triangles for strips m_batch.transparency_mode = m_render_state.transparency_mode;
const u32 max_added_vertices = num_vertices + 2; m_render_state.ClearTransparencyModeChangedFlag();
const bool params_changed =
(m_batch.transparency_enable != rc_transparency_enable || m_batch.texture_enable != rc_texture_enable ||
m_batch.texture_blending_enable != rc_texture_blend_enable || m_batch.primitive != rc_primitive);
if ((m_batch.vertices.size() + max_added_vertices) >= MAX_BATCH_VERTEX_COUNT || params_changed)
FlushRender();
} }
m_batch.primitive = rc_primitive;
m_batch.transparency_enable = rc_transparency_enable;
m_batch.texture_enable = rc_texture_enable;
m_batch.texture_blending_enable = rc_texture_blend_enable;
LoadVertices(rc, num_vertices); LoadVertices(rc, num_vertices);
} }

View file

@ -35,6 +35,7 @@ protected:
TriangleStrip = 2 TriangleStrip = 2
}; };
u32 render_command_bits;
Primitive primitive; Primitive primitive;
bool transparency_enable; bool transparency_enable;
bool texture_enable; bool texture_enable;