GPU: Refactor draw mode setting
This commit is contained in:
parent
cda2394287
commit
ffe90083d3
|
@ -57,8 +57,9 @@ void GPU::SoftReset()
|
|||
m_command_total_words = 0;
|
||||
m_vram_transfer = {};
|
||||
m_GP0_buffer.clear();
|
||||
m_render_state = {};
|
||||
m_render_state.texture_page_changed = true;
|
||||
SetDrawMode(0);
|
||||
SetTexturePalette(0);
|
||||
m_draw_mode.SetTextureWindow(0);
|
||||
UpdateGPUSTAT();
|
||||
UpdateCRTCConfig();
|
||||
}
|
||||
|
@ -73,21 +74,19 @@ bool GPU::DoState(StateWrapper& sw)
|
|||
|
||||
sw.Do(&m_GPUSTAT.bits);
|
||||
|
||||
sw.Do(&m_render_state.texture_page_x);
|
||||
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_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);
|
||||
sw.Do(&m_render_state.texture_window_offset_x);
|
||||
sw.Do(&m_render_state.texture_window_offset_y);
|
||||
sw.Do(&m_render_state.texture_x_flip);
|
||||
sw.Do(&m_render_state.texture_y_flip);
|
||||
sw.Do(&m_render_state.texpage_attribute);
|
||||
sw.Do(&m_render_state.texlut_attribute);
|
||||
sw.Do(&m_render_state.texture_window_value);
|
||||
sw.Do(&m_draw_mode.texture_page_x);
|
||||
sw.Do(&m_draw_mode.texture_page_y);
|
||||
sw.Do(&m_draw_mode.texture_palette_x);
|
||||
sw.Do(&m_draw_mode.texture_palette_y);
|
||||
sw.Do(&m_draw_mode.texture_window_mask_x);
|
||||
sw.Do(&m_draw_mode.texture_window_mask_y);
|
||||
sw.Do(&m_draw_mode.texture_window_offset_x);
|
||||
sw.Do(&m_draw_mode.texture_window_offset_y);
|
||||
sw.Do(&m_draw_mode.texture_x_flip);
|
||||
sw.Do(&m_draw_mode.texture_y_flip);
|
||||
sw.Do(&m_draw_mode.mode_reg.bits);
|
||||
sw.Do(&m_draw_mode.palette_reg);
|
||||
sw.Do(&m_draw_mode.texture_window_value);
|
||||
|
||||
sw.Do(&m_drawing_area.left);
|
||||
sw.Do(&m_drawing_area.top);
|
||||
|
@ -129,8 +128,8 @@ bool GPU::DoState(StateWrapper& sw)
|
|||
|
||||
if (sw.IsReading())
|
||||
{
|
||||
m_render_state.texture_page_changed = true;
|
||||
m_render_state.texture_window_changed = true;
|
||||
m_draw_mode.texture_page_changed = true;
|
||||
m_draw_mode.texture_window_changed = true;
|
||||
m_drawing_area_changed = true;
|
||||
m_drawing_offset_changed = true;
|
||||
UpdateGPUSTAT();
|
||||
|
@ -643,7 +642,7 @@ void GPU::HandleGetGPUInfoCommand(u32 value)
|
|||
case 0x02: // Get Texture Window
|
||||
{
|
||||
Log_DebugPrintf("Get texture window");
|
||||
m_GPUREAD_latch = m_render_state.texture_window_value;
|
||||
m_GPUREAD_latch = m_draw_mode.texture_window_value;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -724,47 +723,40 @@ void GPU::DispatchRenderCommand(RenderCommand rc, u32 num_vertices, const u32* c
|
|||
|
||||
void GPU::FlushRender() {}
|
||||
|
||||
void GPU::RenderState::SetFromPolygonTexcoord(u32 texcoord0, u32 texcoord1)
|
||||
void GPU::SetDrawMode(u16 value)
|
||||
{
|
||||
SetFromPaletteAttribute(Truncate16(texcoord0 >> 16));
|
||||
SetFromPageAttribute(Truncate16(texcoord1 >> 16));
|
||||
}
|
||||
|
||||
void GPU::RenderState::SetFromRectangleTexcoord(u32 texcoord)
|
||||
{
|
||||
SetFromPaletteAttribute(Truncate16(texcoord >> 16));
|
||||
}
|
||||
|
||||
void GPU::RenderState::SetFromPageAttribute(u16 value)
|
||||
{
|
||||
const u16 old_page_attribute = texpage_attribute;
|
||||
value &= PAGE_ATTRIBUTE_MASK;
|
||||
if (texpage_attribute == value)
|
||||
const DrawMode::Reg reg{static_cast<u16>(value & DrawMode::Reg::MASK)};
|
||||
if (reg.bits == m_draw_mode.mode_reg.bits)
|
||||
return;
|
||||
|
||||
texpage_attribute = value;
|
||||
texture_page_x = static_cast<s32>(ZeroExtend32(value & UINT16_C(0x0F)) * UINT32_C(64));
|
||||
texture_page_y = static_cast<s32>(ZeroExtend32((value >> 4) & UINT16_C(1)) * UINT32_C(256));
|
||||
texture_page_changed |=
|
||||
(old_page_attribute & PAGE_ATTRIBUTE_TEXTURE_PAGE_MASK) != (value & PAGE_ATTRIBUTE_TEXTURE_PAGE_MASK);
|
||||
if ((reg.bits & DrawMode::Reg::TEXTURE_PAGE_MASK) != (m_draw_mode.mode_reg.bits & DrawMode::Reg::TEXTURE_PAGE_MASK))
|
||||
{
|
||||
m_draw_mode.texture_page_x = reg.GetTexturePageXBase();
|
||||
m_draw_mode.texture_page_y = reg.GetTexturePageYBase();
|
||||
m_draw_mode.texture_page_changed = true;
|
||||
}
|
||||
|
||||
texture_mode = (static_cast<TextureMode>((value >> 7) & UINT16_C(0x03)));
|
||||
transparency_mode = (static_cast<TransparencyMode>((value >> 5) & UINT16_C(0x03)));
|
||||
m_draw_mode.mode_reg.bits = reg.bits;
|
||||
|
||||
// Bits 0..10 are returned in the GPU status register.
|
||||
m_GPUSTAT.bits =
|
||||
m_GPUSTAT.bits & ~(DrawMode::Reg::GPUSTAT_MASK) | (ZeroExtend32(reg.bits) & DrawMode::Reg::GPUSTAT_MASK);
|
||||
m_GPUSTAT.texture_disable = m_draw_mode.mode_reg.texture_disable;
|
||||
}
|
||||
|
||||
void GPU::RenderState::SetFromPaletteAttribute(u16 value)
|
||||
void GPU::SetTexturePalette(u16 value)
|
||||
{
|
||||
value &= PALETTE_ATTRIBUTE_MASK;
|
||||
if (texlut_attribute == value)
|
||||
value &= DrawMode::PALETTE_MASK;
|
||||
if (m_draw_mode.palette_reg == value)
|
||||
return;
|
||||
|
||||
texture_palette_x = static_cast<s32>(ZeroExtend32(value & UINT16_C(0x3F)) * UINT32_C(16));
|
||||
texture_palette_y = static_cast<s32>(ZeroExtend32((value >> 6) & UINT16_C(0x1FF)));
|
||||
texlut_attribute = value;
|
||||
texture_page_changed = true;
|
||||
m_draw_mode.texture_palette_x = ZeroExtend32(value & 0x3F) * 16;
|
||||
m_draw_mode.texture_palette_y = ZeroExtend32(value >> 6);
|
||||
m_draw_mode.palette_reg = value;
|
||||
m_draw_mode.texture_page_changed = true;
|
||||
}
|
||||
|
||||
void GPU::RenderState::SetTextureWindow(u32 value)
|
||||
void GPU::DrawMode::SetTextureWindow(u32 value)
|
||||
{
|
||||
value &= TEXTURE_WINDOW_MASK;
|
||||
if (texture_window_value == value)
|
||||
|
|
|
@ -299,6 +299,12 @@ protected:
|
|||
/// Returns true if scanout should be interlaced.
|
||||
bool IsDisplayInterlaced() const { return !m_force_progressive_scan && m_GPUSTAT.In480iMode(); }
|
||||
|
||||
/// Sets/decodes GP0(E1h) (set draw mode).
|
||||
void SetDrawMode(u16 bits);
|
||||
|
||||
/// Sets/decodes polygon/rectangle texture palette value.
|
||||
void SetTexturePalette(u16 bits);
|
||||
|
||||
u32 ReadGPUREAD();
|
||||
void WriteGP0(u32 value);
|
||||
void WriteGP1(u32 value);
|
||||
|
@ -362,20 +368,44 @@ protected:
|
|||
u16 GetMaskOR() const { return set_mask_while_drawing ? 0x8000 : 0x0000; }
|
||||
} m_GPUSTAT = {};
|
||||
|
||||
struct RenderState
|
||||
struct DrawMode
|
||||
{
|
||||
static constexpr u16 PAGE_ATTRIBUTE_TEXTURE_PAGE_MASK = UINT16_C(0b0000000000011111);
|
||||
static constexpr u16 PAGE_ATTRIBUTE_MASK = UINT16_C(0b0000000111111111);
|
||||
static constexpr u16 PALETTE_ATTRIBUTE_MASK = UINT16_C(0b0111111111111111);
|
||||
static constexpr u16 PALETTE_MASK = UINT16_C(0b0111111111111111);
|
||||
static constexpr u32 TEXTURE_WINDOW_MASK = UINT16_C(0b11111111111111111111);
|
||||
|
||||
// bits in GP0(E1h) or texpage part of polygon
|
||||
union Reg
|
||||
{
|
||||
static constexpr u16 MASK = 0b1111111111111;
|
||||
static constexpr u16 TEXTURE_PAGE_MASK = UINT16_C(0b0000000000011111);
|
||||
|
||||
// Polygon texpage commands only affect bits 0-8, 11
|
||||
static constexpr u16 POLYGON_TEXPAGE_MASK = 0b0000100111111111;
|
||||
|
||||
// Bits 0..5 are returned in the GPU status register, latched at E1h/polygon draw time.
|
||||
static constexpr u32 GPUSTAT_MASK = 0b111111111111;
|
||||
|
||||
u16 bits;
|
||||
|
||||
BitField<u16, u8, 0, 4> texture_page_x_base;
|
||||
BitField<u16, u8, 4, 1> texture_page_y_base;
|
||||
BitField<u16, TransparencyMode, 5, 2> transparency_mode;
|
||||
BitField<u16, TextureMode, 7, 2> texture_mode;
|
||||
BitField<u16, bool, 9, 1> dither_enable;
|
||||
BitField<u16, bool, 10, 1> draw_to_display_area;
|
||||
BitField<u16, bool, 11, 1> texture_disable;
|
||||
BitField<u16, bool, 12, 1> texture_x_flip;
|
||||
BitField<u16, bool, 13, 1> texture_y_flip;
|
||||
|
||||
u32 GetTexturePageXBase() const { return ZeroExtend32(texture_page_x_base.GetValue()) * 64; }
|
||||
u32 GetTexturePageYBase() const { return ZeroExtend32(texture_page_y_base.GetValue()) * 256; }
|
||||
};
|
||||
|
||||
// decoded values
|
||||
u32 texture_page_x;
|
||||
u32 texture_page_y;
|
||||
u32 texture_palette_x;
|
||||
u32 texture_palette_y;
|
||||
TextureMode texture_mode;
|
||||
TransparencyMode transparency_mode;
|
||||
u8 texture_window_mask_x; // in 8 pixel steps
|
||||
u8 texture_window_mask_y; // in 8 pixel steps
|
||||
u8 texture_window_offset_x; // in 8 pixel steps
|
||||
|
@ -384,17 +414,23 @@ protected:
|
|||
bool texture_y_flip;
|
||||
|
||||
// original values
|
||||
u16 texpage_attribute; // from register in rectangle modes/vertex in polygon modes
|
||||
u16 texlut_attribute; // from vertex
|
||||
Reg mode_reg;
|
||||
u16 palette_reg; // from vertex
|
||||
u32 texture_window_value;
|
||||
|
||||
bool texture_page_changed = false;
|
||||
bool texture_window_changed = false;
|
||||
bool texture_page_changed;
|
||||
bool texture_window_changed;
|
||||
|
||||
/// Returns the texture/palette rendering mode.
|
||||
TextureMode GetTextureMode() const { return mode_reg.texture_mode; }
|
||||
|
||||
/// Returns the semi-transparency mode when enabled.
|
||||
TransparencyMode GetTransparencyMode() const { return mode_reg.transparency_mode; }
|
||||
|
||||
/// Returns true if the texture mode requires a palette.
|
||||
bool IsUsingPalette() const
|
||||
{
|
||||
return (static_cast<u8>(texture_mode) &
|
||||
return (static_cast<u8>(mode_reg.texture_mode.GetValue()) &
|
||||
(static_cast<u8>(TextureMode::Palette4Bit) | static_cast<u8>(TextureMode::Palette8Bit))) != 0;
|
||||
}
|
||||
|
||||
|
@ -409,8 +445,8 @@ protected:
|
|||
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>(texture_mode) & 3], 1);
|
||||
return Common::Rectangle<u32>::FromExtents(
|
||||
texture_palette_x, texture_palette_y, palette_widths[static_cast<u8>(mode_reg.texture_mode.GetValue()) & 3], 1);
|
||||
}
|
||||
|
||||
bool IsTexturePageChanged() const { return texture_page_changed; }
|
||||
|
@ -421,13 +457,9 @@ protected:
|
|||
void SetTextureWindowChanged() { texture_window_changed = true; }
|
||||
void ClearTextureWindowChangedFlag() { texture_window_changed = false; }
|
||||
|
||||
void SetFromPolygonTexcoord(u32 texcoord0, u32 texcoord1);
|
||||
void SetFromRectangleTexcoord(u32 texcoord);
|
||||
|
||||
void SetFromPageAttribute(u16 value);
|
||||
void SetFromPaletteAttribute(u16 value);
|
||||
void SetTextureWindow(u32 value);
|
||||
} m_render_state = {};
|
||||
|
||||
} m_draw_mode = {};
|
||||
|
||||
Common::Rectangle<u32> m_drawing_area;
|
||||
|
||||
|
|
|
@ -125,16 +125,8 @@ bool GPU::HandleInterruptRequestCommand(const u32*& command_ptr, u32 command_siz
|
|||
bool GPU::HandleSetDrawModeCommand(const u32*& command_ptr, u32 command_size)
|
||||
{
|
||||
const u32 param = *(command_ptr++) & 0x00FFFFFF;
|
||||
|
||||
// 0..10 bits match GPUSTAT
|
||||
const u32 MASK = ((1 << 11) - 1);
|
||||
m_render_state.SetFromPageAttribute(param & MASK);
|
||||
m_GPUSTAT.bits = (m_GPUSTAT.bits & ~MASK) | (param & MASK);
|
||||
m_GPUSTAT.texture_disable = (param & (1 << 11)) != 0;
|
||||
m_render_state.texture_x_flip = (param & (1 << 12)) != 0;
|
||||
m_render_state.texture_y_flip = (param & (1 << 13)) != 0;
|
||||
Log_DebugPrintf("Set draw mode %08X", param);
|
||||
|
||||
SetDrawMode(Truncate16(param));
|
||||
EndCommand();
|
||||
return true;
|
||||
}
|
||||
|
@ -142,10 +134,10 @@ bool GPU::HandleSetDrawModeCommand(const u32*& command_ptr, u32 command_size)
|
|||
bool GPU::HandleSetTextureWindowCommand(const u32*& command_ptr, u32 command_size)
|
||||
{
|
||||
const u32 param = *(command_ptr++) & 0x00FFFFFF;
|
||||
m_render_state.SetTextureWindow(param);
|
||||
Log_DebugPrintf("Set texture window %02X %02X %02X %02X", m_render_state.texture_window_mask_x,
|
||||
m_render_state.texture_window_mask_y, m_render_state.texture_window_offset_x,
|
||||
m_render_state.texture_window_offset_y);
|
||||
m_draw_mode.SetTextureWindow(param);
|
||||
Log_DebugPrintf("Set texture window %02X %02X %02X %02X", m_draw_mode.texture_window_mask_x,
|
||||
m_draw_mode.texture_window_mask_y, m_draw_mode.texture_window_offset_x,
|
||||
m_draw_mode.texture_window_offset_y);
|
||||
|
||||
EndCommand();
|
||||
return true;
|
||||
|
@ -241,6 +233,16 @@ bool GPU::HandleRenderCommand(const u32*& command_ptr, u32 command_size)
|
|||
words_per_vertex = 1 + BoolToUInt8(rc.texture_enable) + BoolToUInt8(rc.shading_enable);
|
||||
num_vertices = rc.quad_polygon ? 4 : 3;
|
||||
total_words = words_per_vertex * num_vertices + BoolToUInt8(!rc.shading_enable);
|
||||
CHECK_COMMAND_SIZE(total_words);
|
||||
|
||||
// set draw state up
|
||||
if (rc.texture_enable)
|
||||
{
|
||||
const u16 texpage_attribute = Truncate16((rc.shading_enable ? command_ptr[5] : command_ptr[4]) >> 16);
|
||||
SetDrawMode((texpage_attribute & DrawMode::Reg::POLYGON_TEXPAGE_MASK) |
|
||||
(m_draw_mode.mode_reg.bits & ~DrawMode::Reg::POLYGON_TEXPAGE_MASK));
|
||||
SetTexturePalette(Truncate16(command_ptr[2] >> 16));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -281,6 +283,9 @@ bool GPU::HandleRenderCommand(const u32*& command_ptr, u32 command_size)
|
|||
2 + BoolToUInt8(rc.texture_enable) + BoolToUInt8(rc.rectangle_size == DrawRectangleSize::Variable);
|
||||
num_vertices = 1;
|
||||
total_words = words_per_vertex;
|
||||
|
||||
if (rc.texture_enable)
|
||||
SetTexturePalette(Truncate16(command_ptr[2] >> 16));
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -64,8 +64,7 @@ void GPU_HW::UpdateSettings()
|
|||
|
||||
void GPU_HW::LoadVertices(RenderCommand rc, u32 num_vertices, const u32* command_ptr)
|
||||
{
|
||||
const u32 texpage =
|
||||
ZeroExtend32(m_render_state.texpage_attribute) | (ZeroExtend32(m_render_state.texlut_attribute) << 16);
|
||||
const u32 texpage = ZeroExtend32(m_draw_mode.mode_reg.bits) | (ZeroExtend32(m_draw_mode.palette_reg) << 16);
|
||||
|
||||
// TODO: Move this to the GPU..
|
||||
switch (rc.primitive)
|
||||
|
@ -271,34 +270,12 @@ void GPU_HW::DispatchRenderCommand(RenderCommand rc, u32 num_vertices, const u32
|
|||
TextureMode texture_mode;
|
||||
if (rc.texture_enable)
|
||||
{
|
||||
// extract texture lut/page
|
||||
switch (rc.primitive)
|
||||
{
|
||||
case Primitive::Polygon:
|
||||
{
|
||||
if (rc.shading_enable)
|
||||
m_render_state.SetFromPolygonTexcoord(command_ptr[2], command_ptr[5]);
|
||||
else
|
||||
m_render_state.SetFromPolygonTexcoord(command_ptr[2], command_ptr[4]);
|
||||
}
|
||||
break;
|
||||
|
||||
case Primitive::Rectangle:
|
||||
{
|
||||
m_render_state.SetFromRectangleTexcoord(command_ptr[2]);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// texture page changed - check that the new page doesn't intersect the drawing area
|
||||
if (m_render_state.IsTexturePageChanged())
|
||||
if (m_draw_mode.IsTexturePageChanged())
|
||||
{
|
||||
m_render_state.ClearTexturePageChangedFlag();
|
||||
if (m_vram_dirty_rect.Valid() && (m_render_state.GetTexturePageRectangle().Intersects(m_vram_dirty_rect) ||
|
||||
m_render_state.GetTexturePaletteRectangle().Intersects(m_vram_dirty_rect)))
|
||||
m_draw_mode.ClearTexturePageChangedFlag();
|
||||
if (m_vram_dirty_rect.Valid() && (m_draw_mode.GetTexturePageRectangle().Intersects(m_vram_dirty_rect) ||
|
||||
m_draw_mode.GetTexturePaletteRectangle().Intersects(m_vram_dirty_rect)))
|
||||
{
|
||||
Log_DevPrintf("Invalidating VRAM read cache due to drawing area overlap");
|
||||
if (!IsFlushed())
|
||||
|
@ -308,7 +285,7 @@ void GPU_HW::DispatchRenderCommand(RenderCommand rc, u32 num_vertices, const u32
|
|||
}
|
||||
}
|
||||
|
||||
texture_mode = m_render_state.texture_mode;
|
||||
texture_mode = m_draw_mode.GetTextureMode();
|
||||
if (rc.raw_texture_enable)
|
||||
{
|
||||
texture_mode =
|
||||
|
@ -322,7 +299,7 @@ void GPU_HW::DispatchRenderCommand(RenderCommand rc, u32 num_vertices, const u32
|
|||
|
||||
// has any state changed which requires a new batch?
|
||||
const TransparencyMode transparency_mode =
|
||||
rc.transparency_enable ? m_render_state.transparency_mode : TransparencyMode::Disabled;
|
||||
rc.transparency_enable ? m_draw_mode.GetTransparencyMode() : TransparencyMode::Disabled;
|
||||
const BatchPrimitive rc_primitive = GetPrimitiveForCommand(rc);
|
||||
const bool dithering_enable = (!m_true_color && rc.IsDitheringEnabled()) ? m_GPUSTAT.dither_enable : false;
|
||||
const u32 max_added_vertices = num_vertices + 5;
|
||||
|
@ -332,7 +309,7 @@ void GPU_HW::DispatchRenderCommand(RenderCommand rc, u32 num_vertices, const u32
|
|||
if (buffer_overflow || rc_primitive == BatchPrimitive::LineStrip || m_batch.texture_mode != texture_mode ||
|
||||
m_batch.transparency_mode != transparency_mode || m_batch.primitive != rc_primitive ||
|
||||
dithering_enable != m_batch.dithering || m_drawing_area_changed || m_drawing_offset_changed ||
|
||||
m_render_state.IsTextureWindowChanged())
|
||||
m_draw_mode.IsTextureWindowChanged())
|
||||
{
|
||||
FlushRender();
|
||||
}
|
||||
|
@ -374,14 +351,14 @@ 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.IsTextureWindowChanged())
|
||||
if (m_draw_mode.IsTextureWindowChanged())
|
||||
{
|
||||
m_render_state.ClearTextureWindowChangedFlag();
|
||||
m_draw_mode.ClearTextureWindowChangedFlag();
|
||||
|
||||
m_batch_ubo_data.u_texture_window_mask[0] = ZeroExtend32(m_render_state.texture_window_mask_x);
|
||||
m_batch_ubo_data.u_texture_window_mask[1] = ZeroExtend32(m_render_state.texture_window_mask_y);
|
||||
m_batch_ubo_data.u_texture_window_offset[0] = ZeroExtend32(m_render_state.texture_window_offset_x);
|
||||
m_batch_ubo_data.u_texture_window_offset[1] = ZeroExtend32(m_render_state.texture_window_offset_y);
|
||||
m_batch_ubo_data.u_texture_window_mask[0] = ZeroExtend32(m_draw_mode.texture_window_mask_x);
|
||||
m_batch_ubo_data.u_texture_window_mask[1] = ZeroExtend32(m_draw_mode.texture_window_mask_y);
|
||||
m_batch_ubo_data.u_texture_window_offset[0] = ZeroExtend32(m_draw_mode.texture_window_offset_x);
|
||||
m_batch_ubo_data.u_texture_window_offset[1] = ZeroExtend32(m_draw_mode.texture_window_offset_y);
|
||||
m_batch_ubo_dirty = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -122,7 +122,7 @@ protected:
|
|||
void SetFullVRAMDirtyRectangle()
|
||||
{
|
||||
m_vram_dirty_rect.Set(0, 0, VRAM_WIDTH, VRAM_HEIGHT);
|
||||
m_render_state.SetTexturePageChanged();
|
||||
m_draw_mode.SetTexturePageChanged();
|
||||
}
|
||||
void ClearVRAMDirtyRectangle() { m_vram_dirty_rect.SetInvalid(); }
|
||||
|
||||
|
|
|
@ -164,14 +164,6 @@ void GPU_SW::DispatchRenderCommand(RenderCommand rc, u32 num_vertices, const u32
|
|||
const bool shaded = rc.shading_enable;
|
||||
const bool textured = rc.texture_enable;
|
||||
|
||||
if (textured)
|
||||
{
|
||||
if (shaded)
|
||||
m_render_state.SetFromPolygonTexcoord(command_ptr[2], command_ptr[5]);
|
||||
else
|
||||
m_render_state.SetFromPolygonTexcoord(command_ptr[2], command_ptr[4]);
|
||||
}
|
||||
|
||||
u32 buffer_pos = 1;
|
||||
for (u32 i = 0; i < num_vertices; i++)
|
||||
{
|
||||
|
@ -210,8 +202,6 @@ void GPU_SW::DispatchRenderCommand(RenderCommand rc, u32 num_vertices, const u32
|
|||
const u32 texcoord_and_palette = rc.texture_enable ? command_ptr[buffer_pos++] : 0;
|
||||
const auto [texcoord_x, texcoord_y] = UnpackTexcoord(Truncate16(texcoord_and_palette));
|
||||
|
||||
m_render_state.SetFromPaletteAttribute(Truncate16(texcoord_and_palette >> 16));
|
||||
|
||||
s32 width;
|
||||
s32 height;
|
||||
switch (rc.rectangle_size)
|
||||
|
@ -400,43 +390,43 @@ void GPU_SW::ShadePixel(RenderCommand rc, u32 x, u32 y, u8 color_r, u8 color_g,
|
|||
{
|
||||
// Apply texture window
|
||||
// TODO: Precompute the second half
|
||||
texcoord_x = (texcoord_x & ~(m_render_state.texture_window_mask_x * 8u)) |
|
||||
((m_render_state.texture_window_offset_x & m_render_state.texture_window_mask_x) * 8u);
|
||||
texcoord_y = (texcoord_y & ~(m_render_state.texture_window_mask_y * 8u)) |
|
||||
((m_render_state.texture_window_offset_y & m_render_state.texture_window_mask_y) * 8u);
|
||||
texcoord_x = (texcoord_x & ~(m_draw_mode.texture_window_mask_x * 8u)) |
|
||||
((m_draw_mode.texture_window_offset_x & m_draw_mode.texture_window_mask_x) * 8u);
|
||||
texcoord_y = (texcoord_y & ~(m_draw_mode.texture_window_mask_y * 8u)) |
|
||||
((m_draw_mode.texture_window_offset_y & m_draw_mode.texture_window_mask_y) * 8u);
|
||||
|
||||
VRAMPixel texture_color;
|
||||
switch (m_render_state.texture_mode)
|
||||
switch (m_draw_mode.GetTextureMode())
|
||||
{
|
||||
case GPU::TextureMode::Palette4Bit:
|
||||
{
|
||||
const u16 palette_value =
|
||||
GetPixel(std::min<u32>(m_render_state.texture_page_x + ZeroExtend32(texcoord_x / 4), VRAM_WIDTH - 1),
|
||||
std::min<u32>(m_render_state.texture_page_y + ZeroExtend32(texcoord_y), VRAM_HEIGHT - 1));
|
||||
GetPixel(std::min<u32>(m_draw_mode.texture_page_x + ZeroExtend32(texcoord_x / 4), VRAM_WIDTH - 1),
|
||||
std::min<u32>(m_draw_mode.texture_page_y + ZeroExtend32(texcoord_y), VRAM_HEIGHT - 1));
|
||||
const u16 palette_index = (palette_value >> ((texcoord_x % 4) * 4)) & 0x0Fu;
|
||||
texture_color.bits =
|
||||
GetPixel(std::min<u32>(m_render_state.texture_palette_x + ZeroExtend32(palette_index), VRAM_WIDTH - 1),
|
||||
m_render_state.texture_palette_y);
|
||||
GetPixel(std::min<u32>(m_draw_mode.texture_palette_x + ZeroExtend32(palette_index), VRAM_WIDTH - 1),
|
||||
m_draw_mode.texture_palette_y);
|
||||
}
|
||||
break;
|
||||
|
||||
case GPU::TextureMode::Palette8Bit:
|
||||
{
|
||||
const u16 palette_value =
|
||||
GetPixel(std::min<u32>(m_render_state.texture_page_x + ZeroExtend32(texcoord_x / 2), VRAM_WIDTH - 1),
|
||||
std::min<u32>(m_render_state.texture_page_y + ZeroExtend32(texcoord_y), VRAM_HEIGHT - 1));
|
||||
GetPixel(std::min<u32>(m_draw_mode.texture_page_x + ZeroExtend32(texcoord_x / 2), VRAM_WIDTH - 1),
|
||||
std::min<u32>(m_draw_mode.texture_page_y + ZeroExtend32(texcoord_y), VRAM_HEIGHT - 1));
|
||||
const u16 palette_index = (palette_value >> ((texcoord_x % 2) * 8)) & 0xFFu;
|
||||
texture_color.bits =
|
||||
GetPixel(std::min<u32>(m_render_state.texture_palette_x + ZeroExtend32(palette_index), VRAM_WIDTH - 1),
|
||||
m_render_state.texture_palette_y);
|
||||
GetPixel(std::min<u32>(m_draw_mode.texture_palette_x + ZeroExtend32(palette_index), VRAM_WIDTH - 1),
|
||||
m_draw_mode.texture_palette_y);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
texture_color.bits =
|
||||
GetPixel(std::min<u32>(m_render_state.texture_page_x + ZeroExtend32(texcoord_x), VRAM_WIDTH - 1),
|
||||
std::min<u32>(m_render_state.texture_page_y + ZeroExtend32(texcoord_y), VRAM_HEIGHT - 1));
|
||||
GetPixel(std::min<u32>(m_draw_mode.texture_page_x + ZeroExtend32(texcoord_x), VRAM_WIDTH - 1),
|
||||
std::min<u32>(m_draw_mode.texture_page_y + ZeroExtend32(texcoord_y), VRAM_HEIGHT - 1));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -482,7 +472,7 @@ void GPU_SW::ShadePixel(RenderCommand rc, u32 x, u32 y, u8 color_r, u8 color_g,
|
|||
color.Set(func(bg_color.r.GetValue(), color.r.GetValue()), func(bg_color.g.GetValue(), color.g.GetValue()), \
|
||||
func(bg_color.b.GetValue(), color.b.GetValue()), color.c.GetValue())
|
||||
|
||||
switch (m_render_state.transparency_mode)
|
||||
switch (m_draw_mode.GetTransparencyMode())
|
||||
{
|
||||
case GPU::TransparencyMode::HalfBackgroundPlusHalfForeground:
|
||||
BLEND_RGB(BLEND_AVERAGE);
|
||||
|
|
Loading…
Reference in New Issue