mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-22 22:05:38 +00:00
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, bool, 31, 1> display_line_lsb;
|
||||
|
||||
bool IsMaskingEnabled() const
|
||||
ALWAYS_INLINE bool IsMaskingEnabled() const
|
||||
{
|
||||
static constexpr u32 MASK = ((1 << 11) | (1 << 12));
|
||||
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 ACTIVE = (1 << 19) | (1 << 22);
|
||||
return ((bits & MASK) == ACTIVE);
|
||||
}
|
||||
bool InInterleaved480iMode() const
|
||||
ALWAYS_INLINE bool InInterleaved480iMode() const
|
||||
{
|
||||
static constexpr u32 ACTIVE = (1 << 19) | (1 << 22);
|
||||
return ((bits & ACTIVE) == ACTIVE);
|
||||
}
|
||||
|
||||
// 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 Truncate16((bits << 3) & 0x8000);
|
||||
}
|
||||
u16 GetMaskOR() const
|
||||
ALWAYS_INLINE u16 GetMaskOR() const
|
||||
{
|
||||
// return set_mask_while_drawing ? 0x8000 : 0x0000;
|
||||
return Truncate16((bits << 4) & 0x8000);
|
||||
|
@ -409,13 +409,21 @@ protected:
|
|||
bool texture_page_changed;
|
||||
bool texture_window_changed;
|
||||
|
||||
bool IsTexturePageChanged() const { return texture_page_changed; }
|
||||
void SetTexturePageChanged() { texture_page_changed = true; }
|
||||
void ClearTexturePageChangedFlag() { texture_page_changed = false; }
|
||||
/// Returns a rectangle comprising the texture palette area.
|
||||
ALWAYS_INLINE_RELEASE Common::Rectangle<u32> GetTexturePaletteRectangle() const
|
||||
{
|
||||
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; }
|
||||
void SetTextureWindowChanged() { texture_window_changed = true; }
|
||||
void ClearTextureWindowChangedFlag() { texture_window_changed = false; }
|
||||
ALWAYS_INLINE bool IsTexturePageChanged() const { return texture_page_changed; }
|
||||
ALWAYS_INLINE void SetTexturePageChanged() { texture_page_changed = true; }
|
||||
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 = {};
|
||||
|
||||
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
|
||||
if (!m_draw_mode.IsTexturePageChanged() &&
|
||||
(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();
|
||||
}
|
||||
|
@ -932,10 +932,9 @@ void GPU_HW::DispatchRenderCommand()
|
|||
if (m_draw_mode.IsTexturePageChanged())
|
||||
{
|
||||
m_draw_mode.ClearTexturePageChangedFlag();
|
||||
if (m_vram_dirty_rect.Valid() &&
|
||||
(m_draw_mode.mode_reg.GetTexturePageRectangle().Intersects(m_vram_dirty_rect) ||
|
||||
(m_draw_mode.mode_reg.IsUsingPalette() &&
|
||||
m_draw_mode.mode_reg.GetTexturePaletteRectangle().Intersects(m_vram_dirty_rect))))
|
||||
if (m_vram_dirty_rect.Valid() && (m_draw_mode.mode_reg.GetTexturePageRectangle().Intersects(m_vram_dirty_rect) ||
|
||||
(m_draw_mode.mode_reg.IsUsingPalette() &&
|
||||
m_draw_mode.GetTexturePaletteRectangle().Intersects(m_vram_dirty_rect))))
|
||||
{
|
||||
// Log_DevPrintf("Invalidating VRAM read cache due to drawing area overlap");
|
||||
if (!IsFlushed())
|
||||
|
|
|
@ -93,15 +93,15 @@ union GPURenderCommand
|
|||
{
|
||||
switch (primitive)
|
||||
{
|
||||
case GPUPrimitive::Polygon:
|
||||
return shading_enable || (texture_enable && !raw_texture_enable);
|
||||
case GPUPrimitive::Polygon:
|
||||
return shading_enable || (texture_enable && !raw_texture_enable);
|
||||
|
||||
case GPUPrimitive::Line:
|
||||
return true;
|
||||
case GPUPrimitive::Line:
|
||||
return true;
|
||||
|
||||
case GPUPrimitive::Rectangle:
|
||||
default:
|
||||
return false;
|
||||
case GPUPrimitive::Rectangle:
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -175,24 +175,16 @@ union GPUDrawModeReg
|
|||
ALWAYS_INLINE u16 GetTexturePageBaseY() const { return ZeroExtend16(texture_page_y_base.GetValue()) * 256; }
|
||||
|
||||
/// 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.
|
||||
Common::Rectangle<u32> GetTexturePageRectangle() const
|
||||
ALWAYS_INLINE_RELEASE Common::Rectangle<u32> GetTexturePageRectangle() const
|
||||
{
|
||||
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(),
|
||||
texture_page_widths[static_cast<u8>(texture_mode.GetValue())],
|
||||
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);
|
||||
texture_page_widths[static_cast<u8>(texture_mode.GetValue())],
|
||||
TEXTURE_PAGE_HEIGHT);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -218,14 +210,14 @@ struct GPUTextureWindow
|
|||
};
|
||||
|
||||
// 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
|
||||
{-3, +1, -4, +0}, // row 2
|
||||
{+4, -1, +2, -2} }; // row 3
|
||||
{+4, -1, +2, -2}}; // row 3
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#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
|
||||
|
||||
enum class GPUBackendCommandType : u8
|
||||
|
|
Loading…
Reference in a new issue