diff --git a/src/pse/gpu.cpp b/src/pse/gpu.cpp index 721f68d71..5861a897f 100644 --- a/src/pse/gpu.cpp +++ b/src/pse/gpu.cpp @@ -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((value >> 5) & UINT16_C(0x03))); diff --git a/src/pse/gpu.h b/src/pse/gpu.h index 1c03d2295..10636e29f 100644 --- a/src/pse/gpu.h +++ b/src/pse/gpu.h @@ -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 diff --git a/src/pse/gpu_hw.cpp b/src/pse/gpu_hw.cpp index c2d92fdb4..a029914b6 100644 --- a/src/pse/gpu_hw.cpp +++ b/src/pse/gpu_hw.cpp @@ -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); } diff --git a/src/pse/gpu_hw.h b/src/pse/gpu_hw.h index d0f197c89..54a8d52f7 100644 --- a/src/pse/gpu_hw.h +++ b/src/pse/gpu_hw.h @@ -35,6 +35,7 @@ protected: TriangleStrip = 2 }; + u32 render_command_bits; Primitive primitive; bool transparency_enable; bool texture_enable;