GPU: Fix VRAM palette changes not being detected in hw renderer
Fixes wall texture animation in Mega Man Legends.
This commit is contained in:
parent
b49067d165
commit
e06f85a328
|
@ -358,30 +358,30 @@ protected:
|
||||||
BitField<u32, DMADirection, 29, 2> dma_direction;
|
BitField<u32, DMADirection, 29, 2> dma_direction;
|
||||||
BitField<u32, bool, 31, 1> display_line_lsb;
|
BitField<u32, bool, 31, 1> display_line_lsb;
|
||||||
|
|
||||||
bool IsMaskingEnabled() const
|
ALWAYS_INLINE bool IsMaskingEnabled() const
|
||||||
{
|
{
|
||||||
static constexpr u32 MASK = ((1 << 11) | (1 << 12));
|
static constexpr u32 MASK = ((1 << 11) | (1 << 12));
|
||||||
return ((bits & MASK) != 0);
|
return ((bits & MASK) != 0);
|
||||||
}
|
}
|
||||||
bool SkipDrawingToActiveField() const
|
ALWAYS_INLINE bool SkipDrawingToActiveField() const
|
||||||
{
|
{
|
||||||
static constexpr u32 MASK = (1 << 19) | (1 << 22) | (1 << 10);
|
static constexpr u32 MASK = (1 << 19) | (1 << 22) | (1 << 10);
|
||||||
static constexpr u32 ACTIVE = (1 << 19) | (1 << 22);
|
static constexpr u32 ACTIVE = (1 << 19) | (1 << 22);
|
||||||
return ((bits & MASK) == ACTIVE);
|
return ((bits & MASK) == ACTIVE);
|
||||||
}
|
}
|
||||||
bool InInterleaved480iMode() const
|
ALWAYS_INLINE bool InInterleaved480iMode() const
|
||||||
{
|
{
|
||||||
static constexpr u32 ACTIVE = (1 << 19) | (1 << 22);
|
static constexpr u32 ACTIVE = (1 << 19) | (1 << 22);
|
||||||
return ((bits & ACTIVE) == ACTIVE);
|
return ((bits & ACTIVE) == ACTIVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// During transfer/render operations, if ((dst_pixel & mask_and) == 0) { pixel = src_pixel | mask_or }
|
// During transfer/render operations, if ((dst_pixel & mask_and) == 0) { pixel = src_pixel | mask_or }
|
||||||
u16 GetMaskAND() const
|
ALWAYS_INLINE u16 GetMaskAND() const
|
||||||
{
|
{
|
||||||
// return check_mask_before_draw ? 0x8000 : 0x0000;
|
// return check_mask_before_draw ? 0x8000 : 0x0000;
|
||||||
return Truncate16((bits << 3) & 0x8000);
|
return Truncate16((bits << 3) & 0x8000);
|
||||||
}
|
}
|
||||||
u16 GetMaskOR() const
|
ALWAYS_INLINE u16 GetMaskOR() const
|
||||||
{
|
{
|
||||||
// return set_mask_while_drawing ? 0x8000 : 0x0000;
|
// return set_mask_while_drawing ? 0x8000 : 0x0000;
|
||||||
return Truncate16((bits << 4) & 0x8000);
|
return Truncate16((bits << 4) & 0x8000);
|
||||||
|
@ -409,13 +409,21 @@ protected:
|
||||||
bool texture_page_changed;
|
bool texture_page_changed;
|
||||||
bool texture_window_changed;
|
bool texture_window_changed;
|
||||||
|
|
||||||
bool IsTexturePageChanged() const { return texture_page_changed; }
|
/// Returns a rectangle comprising the texture palette area.
|
||||||
void SetTexturePageChanged() { texture_page_changed = true; }
|
ALWAYS_INLINE_RELEASE Common::Rectangle<u32> GetTexturePaletteRectangle() const
|
||||||
void ClearTexturePageChangedFlag() { texture_page_changed = false; }
|
{
|
||||||
|
static constexpr std::array<u32, 4> palette_widths = {{16, 256, 0, 0}};
|
||||||
|
return Common::Rectangle<u32>::FromExtents(texture_palette_x, texture_palette_y,
|
||||||
|
palette_widths[static_cast<u8>(mode_reg.texture_mode.GetValue())], 1);
|
||||||
|
}
|
||||||
|
|
||||||
bool IsTextureWindowChanged() const { return texture_window_changed; }
|
ALWAYS_INLINE bool IsTexturePageChanged() const { return texture_page_changed; }
|
||||||
void SetTextureWindowChanged() { texture_window_changed = true; }
|
ALWAYS_INLINE void SetTexturePageChanged() { texture_page_changed = true; }
|
||||||
void ClearTextureWindowChangedFlag() { texture_window_changed = false; }
|
ALWAYS_INLINE void ClearTexturePageChangedFlag() { texture_page_changed = false; }
|
||||||
|
|
||||||
|
ALWAYS_INLINE bool IsTextureWindowChanged() const { return texture_window_changed; }
|
||||||
|
ALWAYS_INLINE void SetTextureWindowChanged() { texture_window_changed = true; }
|
||||||
|
ALWAYS_INLINE void ClearTextureWindowChangedFlag() { texture_window_changed = false; }
|
||||||
} m_draw_mode = {};
|
} m_draw_mode = {};
|
||||||
|
|
||||||
Common::Rectangle<u32> m_drawing_area{0, 0, VRAM_WIDTH, VRAM_HEIGHT};
|
Common::Rectangle<u32> m_drawing_area{0, 0, VRAM_WIDTH, VRAM_HEIGHT};
|
||||||
|
|
|
@ -829,7 +829,7 @@ void GPU_HW::IncludeVRAMDityRectangle(const Common::Rectangle<u32>& rect)
|
||||||
// shadow texture is updated
|
// shadow texture is updated
|
||||||
if (!m_draw_mode.IsTexturePageChanged() &&
|
if (!m_draw_mode.IsTexturePageChanged() &&
|
||||||
(m_draw_mode.mode_reg.GetTexturePageRectangle().Intersects(rect) ||
|
(m_draw_mode.mode_reg.GetTexturePageRectangle().Intersects(rect) ||
|
||||||
(m_draw_mode.mode_reg.IsUsingPalette() && m_draw_mode.mode_reg.GetTexturePaletteRectangle().Intersects(rect))))
|
(m_draw_mode.mode_reg.IsUsingPalette() && m_draw_mode.GetTexturePaletteRectangle().Intersects(rect))))
|
||||||
{
|
{
|
||||||
m_draw_mode.SetTexturePageChanged();
|
m_draw_mode.SetTexturePageChanged();
|
||||||
}
|
}
|
||||||
|
@ -932,10 +932,9 @@ void GPU_HW::DispatchRenderCommand()
|
||||||
if (m_draw_mode.IsTexturePageChanged())
|
if (m_draw_mode.IsTexturePageChanged())
|
||||||
{
|
{
|
||||||
m_draw_mode.ClearTexturePageChangedFlag();
|
m_draw_mode.ClearTexturePageChangedFlag();
|
||||||
if (m_vram_dirty_rect.Valid() &&
|
if (m_vram_dirty_rect.Valid() && (m_draw_mode.mode_reg.GetTexturePageRectangle().Intersects(m_vram_dirty_rect) ||
|
||||||
(m_draw_mode.mode_reg.GetTexturePageRectangle().Intersects(m_vram_dirty_rect) ||
|
(m_draw_mode.mode_reg.IsUsingPalette() &&
|
||||||
(m_draw_mode.mode_reg.IsUsingPalette() &&
|
m_draw_mode.GetTexturePaletteRectangle().Intersects(m_vram_dirty_rect))))
|
||||||
m_draw_mode.mode_reg.GetTexturePaletteRectangle().Intersects(m_vram_dirty_rect))))
|
|
||||||
{
|
{
|
||||||
// Log_DevPrintf("Invalidating VRAM read cache due to drawing area overlap");
|
// Log_DevPrintf("Invalidating VRAM read cache due to drawing area overlap");
|
||||||
if (!IsFlushed())
|
if (!IsFlushed())
|
||||||
|
|
|
@ -93,15 +93,15 @@ union GPURenderCommand
|
||||||
{
|
{
|
||||||
switch (primitive)
|
switch (primitive)
|
||||||
{
|
{
|
||||||
case GPUPrimitive::Polygon:
|
case GPUPrimitive::Polygon:
|
||||||
return shading_enable || (texture_enable && !raw_texture_enable);
|
return shading_enable || (texture_enable && !raw_texture_enable);
|
||||||
|
|
||||||
case GPUPrimitive::Line:
|
case GPUPrimitive::Line:
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case GPUPrimitive::Rectangle:
|
case GPUPrimitive::Rectangle:
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -175,24 +175,16 @@ union GPUDrawModeReg
|
||||||
ALWAYS_INLINE u16 GetTexturePageBaseY() const { return ZeroExtend16(texture_page_y_base.GetValue()) * 256; }
|
ALWAYS_INLINE u16 GetTexturePageBaseY() const { return ZeroExtend16(texture_page_y_base.GetValue()) * 256; }
|
||||||
|
|
||||||
/// Returns true if the texture mode requires a palette.
|
/// Returns true if the texture mode requires a palette.
|
||||||
bool IsUsingPalette() const { return (bits & (2 << 7)) == 0; }
|
ALWAYS_INLINE bool IsUsingPalette() const { return (bits & (2 << 7)) == 0; }
|
||||||
|
|
||||||
/// Returns a rectangle comprising the texture page area.
|
/// Returns a rectangle comprising the texture page area.
|
||||||
Common::Rectangle<u32> GetTexturePageRectangle() const
|
ALWAYS_INLINE_RELEASE Common::Rectangle<u32> GetTexturePageRectangle() const
|
||||||
{
|
{
|
||||||
static constexpr std::array<u32, 4> texture_page_widths = {
|
static constexpr std::array<u32, 4> texture_page_widths = {
|
||||||
{TEXTURE_PAGE_WIDTH / 4, TEXTURE_PAGE_WIDTH / 2, TEXTURE_PAGE_WIDTH, TEXTURE_PAGE_WIDTH} };
|
{TEXTURE_PAGE_WIDTH / 4, TEXTURE_PAGE_WIDTH / 2, TEXTURE_PAGE_WIDTH, TEXTURE_PAGE_WIDTH}};
|
||||||
return Common::Rectangle<u32>::FromExtents(GetTexturePageBaseX(), GetTexturePageBaseY(),
|
return Common::Rectangle<u32>::FromExtents(GetTexturePageBaseX(), GetTexturePageBaseY(),
|
||||||
texture_page_widths[static_cast<u8>(texture_mode.GetValue())],
|
texture_page_widths[static_cast<u8>(texture_mode.GetValue())],
|
||||||
TEXTURE_PAGE_HEIGHT);
|
TEXTURE_PAGE_HEIGHT);
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns a rectangle comprising the texture palette area.
|
|
||||||
Common::Rectangle<u32> GetTexturePaletteRectangle() const
|
|
||||||
{
|
|
||||||
static constexpr std::array<u32, 4> palette_widths = { {16, 256, 0, 0} };
|
|
||||||
return Common::Rectangle<u32>::FromExtents(GetTexturePageBaseX(), GetTexturePageBaseY(),
|
|
||||||
palette_widths[static_cast<u8>(texture_mode.GetValue())], 1);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -218,14 +210,14 @@ struct GPUTextureWindow
|
||||||
};
|
};
|
||||||
|
|
||||||
// 4x4 dither matrix.
|
// 4x4 dither matrix.
|
||||||
static constexpr s32 DITHER_MATRIX[DITHER_MATRIX_SIZE][DITHER_MATRIX_SIZE] = { {-4, +0, -3, +1}, // row 0
|
static constexpr s32 DITHER_MATRIX[DITHER_MATRIX_SIZE][DITHER_MATRIX_SIZE] = {{-4, +0, -3, +1}, // row 0
|
||||||
{+2, -2, +3, -1}, // row 1
|
{+2, -2, +3, -1}, // row 1
|
||||||
{-3, +1, -4, +0}, // row 2
|
{-3, +1, -4, +0}, // row 2
|
||||||
{+4, -1, +2, -2} }; // row 3
|
{+4, -1, +2, -2}}; // row 3
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
#pragma warning(disable:4200) // warning C4200: nonstandard extension used: zero-sized array in struct/union
|
#pragma warning(disable : 4200) // warning C4200: nonstandard extension used: zero-sized array in struct/union
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
enum class GPUBackendCommandType : u8
|
enum class GPUBackendCommandType : u8
|
||||||
|
|
Loading…
Reference in New Issue