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;
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;
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);
// decoded values
s32 texture_page_x;
s32 texture_page_y;
s32 texture_palette_x;
s32 texture_palette_y;
u32 texture_page_x;
u32 texture_page_y;
u32 texture_palette_x;
u32 texture_palette_y;
TextureColorMode texture_color_mode;
TransparencyMode transparency_mode;
u8 texture_window_mask_x; // in 8 pixel steps

View File

@ -361,71 +361,64 @@ void GPU_HW::DispatchRenderCommand(RenderCommand rc, u32 num_vertices)
default:
break;
}
if (m_render_state.IsChanged())
{
if (m_render_state.IsTextureChanged())
{
if (!IsFlushed())
{
// 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();
}
// 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_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_batch.transparency_mode = m_render_state.transparency_mode;
}
}
// extract state
// 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();
// flush when the command changes
if (!m_batch.vertices.empty())
// update state
if (rc_changed)
{
// including the degenerate triangles for strips
const u32 max_added_vertices = num_vertices + 2;
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.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())
{
// 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_color_mode = m_render_state.texture_color_mode;
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.ClearTextureChangedFlag();
}
if (m_render_state.IsTransparencyModeChanged())
{
m_batch.transparency_mode = m_render_state.transparency_mode;
m_render_state.ClearTransparencyModeChangedFlag();
}
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);
}

View File

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