diff --git a/src/core/gpu.cpp b/src/core/gpu.cpp index c719378b5..f3b4459c9 100644 --- a/src/core/gpu.cpp +++ b/src/core/gpu.cpp @@ -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((value >> 7) & UINT16_C(0x03))); + texture_mode = (static_cast((value >> 7) & UINT16_C(0x03))); transparency_mode = (static_cast((value >> 5) & UINT16_C(0x03))); } diff --git a/src/core/gpu.h b/src/core/gpu.h index b781169a1..367da8fd7 100644 --- a/src/core/gpu.h +++ b/src/core/gpu.h @@ -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(texture_mode) & + (static_cast(TextureMode::Palette4Bit) | static_cast(TextureMode::Palette8Bit))) != 0; + } + bool IsTexturePageChanged() const { return texture_page_changed; } void ClearTexturePageChangedFlag() { texture_page_changed = false; } diff --git a/src/core/gpu_hw.cpp b/src/core/gpu_hw.cpp index b43b48ad8..662145306 100644 --- a/src/core/gpu_hw.cpp +++ b/src/core/gpu_hw.cpp @@ -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; diff --git a/src/core/gpu_hw.h b/src/core/gpu_hw.h index 1a421bf64..212ecbfa8 100644 --- a/src/core/gpu_hw.h +++ b/src/core/gpu_hw.h @@ -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; diff --git a/src/core/gpu_sw.cpp b/src/core/gpu_sw.cpp index 1cd2e3bcf..ffcd82765 100644 --- a/src/core/gpu_sw.cpp +++ b/src/core/gpu_sw.cpp @@ -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: {