GPU: Refactor draw mode setting

This commit is contained in:
Connor McLaughlin 2019-12-11 16:35:14 +10:00
parent cda2394287
commit ffe90083d3
6 changed files with 142 additions and 146 deletions

View File

@ -57,8 +57,9 @@ void GPU::SoftReset()
m_command_total_words = 0; m_command_total_words = 0;
m_vram_transfer = {}; m_vram_transfer = {};
m_GP0_buffer.clear(); m_GP0_buffer.clear();
m_render_state = {}; SetDrawMode(0);
m_render_state.texture_page_changed = true; SetTexturePalette(0);
m_draw_mode.SetTextureWindow(0);
UpdateGPUSTAT(); UpdateGPUSTAT();
UpdateCRTCConfig(); UpdateCRTCConfig();
} }
@ -73,21 +74,19 @@ bool GPU::DoState(StateWrapper& sw)
sw.Do(&m_GPUSTAT.bits); sw.Do(&m_GPUSTAT.bits);
sw.Do(&m_render_state.texture_page_x); sw.Do(&m_draw_mode.texture_page_x);
sw.Do(&m_render_state.texture_page_y); sw.Do(&m_draw_mode.texture_page_y);
sw.Do(&m_render_state.texture_palette_x); sw.Do(&m_draw_mode.texture_palette_x);
sw.Do(&m_render_state.texture_palette_y); sw.Do(&m_draw_mode.texture_palette_y);
sw.Do(&m_render_state.texture_mode); sw.Do(&m_draw_mode.texture_window_mask_x);
sw.Do(&m_render_state.transparency_mode); sw.Do(&m_draw_mode.texture_window_mask_y);
sw.Do(&m_render_state.texture_window_mask_x); sw.Do(&m_draw_mode.texture_window_offset_x);
sw.Do(&m_render_state.texture_window_mask_y); sw.Do(&m_draw_mode.texture_window_offset_y);
sw.Do(&m_render_state.texture_window_offset_x); sw.Do(&m_draw_mode.texture_x_flip);
sw.Do(&m_render_state.texture_window_offset_y); sw.Do(&m_draw_mode.texture_y_flip);
sw.Do(&m_render_state.texture_x_flip); sw.Do(&m_draw_mode.mode_reg.bits);
sw.Do(&m_render_state.texture_y_flip); sw.Do(&m_draw_mode.palette_reg);
sw.Do(&m_render_state.texpage_attribute); sw.Do(&m_draw_mode.texture_window_value);
sw.Do(&m_render_state.texlut_attribute);
sw.Do(&m_render_state.texture_window_value);
sw.Do(&m_drawing_area.left); sw.Do(&m_drawing_area.left);
sw.Do(&m_drawing_area.top); sw.Do(&m_drawing_area.top);
@ -129,8 +128,8 @@ bool GPU::DoState(StateWrapper& sw)
if (sw.IsReading()) if (sw.IsReading())
{ {
m_render_state.texture_page_changed = true; m_draw_mode.texture_page_changed = true;
m_render_state.texture_window_changed = true; m_draw_mode.texture_window_changed = true;
m_drawing_area_changed = true; m_drawing_area_changed = true;
m_drawing_offset_changed = true; m_drawing_offset_changed = true;
UpdateGPUSTAT(); UpdateGPUSTAT();
@ -643,7 +642,7 @@ void GPU::HandleGetGPUInfoCommand(u32 value)
case 0x02: // Get Texture Window case 0x02: // Get Texture Window
{ {
Log_DebugPrintf("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; break;
@ -724,47 +723,40 @@ void GPU::DispatchRenderCommand(RenderCommand rc, u32 num_vertices, const u32* c
void GPU::FlushRender() {} void GPU::FlushRender() {}
void GPU::RenderState::SetFromPolygonTexcoord(u32 texcoord0, u32 texcoord1) void GPU::SetDrawMode(u16 value)
{ {
SetFromPaletteAttribute(Truncate16(texcoord0 >> 16)); const DrawMode::Reg reg{static_cast<u16>(value & DrawMode::Reg::MASK)};
SetFromPageAttribute(Truncate16(texcoord1 >> 16)); if (reg.bits == m_draw_mode.mode_reg.bits)
}
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)
return; return;
texpage_attribute = value; if ((reg.bits & DrawMode::Reg::TEXTURE_PAGE_MASK) != (m_draw_mode.mode_reg.bits & DrawMode::Reg::TEXTURE_PAGE_MASK))
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)); m_draw_mode.texture_page_x = reg.GetTexturePageXBase();
texture_page_changed |= m_draw_mode.texture_page_y = reg.GetTexturePageYBase();
(old_page_attribute & PAGE_ATTRIBUTE_TEXTURE_PAGE_MASK) != (value & PAGE_ATTRIBUTE_TEXTURE_PAGE_MASK); m_draw_mode.texture_page_changed = true;
}
texture_mode = (static_cast<TextureMode>((value >> 7) & UINT16_C(0x03))); m_draw_mode.mode_reg.bits = reg.bits;
transparency_mode = (static_cast<TransparencyMode>((value >> 5) & UINT16_C(0x03)));
// 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; value &= DrawMode::PALETTE_MASK;
if (texlut_attribute == value) if (m_draw_mode.palette_reg == value)
return; return;
texture_palette_x = static_cast<s32>(ZeroExtend32(value & UINT16_C(0x3F)) * UINT32_C(16)); m_draw_mode.texture_palette_x = ZeroExtend32(value & 0x3F) * 16;
texture_palette_y = static_cast<s32>(ZeroExtend32((value >> 6) & UINT16_C(0x1FF))); m_draw_mode.texture_palette_y = ZeroExtend32(value >> 6);
texlut_attribute = value; m_draw_mode.palette_reg = value;
texture_page_changed = true; m_draw_mode.texture_page_changed = true;
} }
void GPU::RenderState::SetTextureWindow(u32 value) void GPU::DrawMode::SetTextureWindow(u32 value)
{ {
value &= TEXTURE_WINDOW_MASK; value &= TEXTURE_WINDOW_MASK;
if (texture_window_value == value) if (texture_window_value == value)

View File

@ -299,6 +299,12 @@ protected:
/// Returns true if scanout should be interlaced. /// Returns true if scanout should be interlaced.
bool IsDisplayInterlaced() const { return !m_force_progressive_scan && m_GPUSTAT.In480iMode(); } 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(); u32 ReadGPUREAD();
void WriteGP0(u32 value); void WriteGP0(u32 value);
void WriteGP1(u32 value); void WriteGP1(u32 value);
@ -362,20 +368,44 @@ protected:
u16 GetMaskOR() const { return set_mask_while_drawing ? 0x8000 : 0x0000; } u16 GetMaskOR() const { return set_mask_while_drawing ? 0x8000 : 0x0000; }
} m_GPUSTAT = {}; } m_GPUSTAT = {};
struct RenderState struct DrawMode
{ {
static constexpr u16 PAGE_ATTRIBUTE_TEXTURE_PAGE_MASK = UINT16_C(0b0000000000011111); static constexpr u16 PALETTE_MASK = UINT16_C(0b0111111111111111);
static constexpr u16 PAGE_ATTRIBUTE_MASK = UINT16_C(0b0000000111111111);
static constexpr u16 PALETTE_ATTRIBUTE_MASK = UINT16_C(0b0111111111111111);
static constexpr u32 TEXTURE_WINDOW_MASK = UINT16_C(0b11111111111111111111); 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 // decoded values
u32 texture_page_x; u32 texture_page_x;
u32 texture_page_y; u32 texture_page_y;
u32 texture_palette_x; u32 texture_palette_x;
u32 texture_palette_y; u32 texture_palette_y;
TextureMode texture_mode;
TransparencyMode transparency_mode;
u8 texture_window_mask_x; // in 8 pixel steps u8 texture_window_mask_x; // in 8 pixel steps
u8 texture_window_mask_y; // in 8 pixel steps u8 texture_window_mask_y; // in 8 pixel steps
u8 texture_window_offset_x; // in 8 pixel steps u8 texture_window_offset_x; // in 8 pixel steps
@ -384,17 +414,23 @@ protected:
bool texture_y_flip; bool texture_y_flip;
// original values // original values
u16 texpage_attribute; // from register in rectangle modes/vertex in polygon modes Reg mode_reg;
u16 texlut_attribute; // from vertex u16 palette_reg; // from vertex
u32 texture_window_value; u32 texture_window_value;
bool texture_page_changed = false; bool texture_page_changed;
bool texture_window_changed = false; 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. /// Returns true if the texture mode requires a palette.
bool IsUsingPalette() const 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; (static_cast<u8>(TextureMode::Palette4Bit) | static_cast<u8>(TextureMode::Palette8Bit))) != 0;
} }
@ -409,8 +445,8 @@ protected:
Common::Rectangle<u32> GetTexturePaletteRectangle() const Common::Rectangle<u32> GetTexturePaletteRectangle() const
{ {
static constexpr std::array<u32, 4> palette_widths = {{16, 256, 0, 0}}; static constexpr std::array<u32, 4> palette_widths = {{16, 256, 0, 0}};
return Common::Rectangle<u32>::FromExtents(texture_palette_x, texture_palette_y, return Common::Rectangle<u32>::FromExtents(
palette_widths[static_cast<u8>(texture_mode) & 3], 1); 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; } bool IsTexturePageChanged() const { return texture_page_changed; }
@ -421,13 +457,9 @@ protected:
void SetTextureWindowChanged() { texture_window_changed = true; } void SetTextureWindowChanged() { texture_window_changed = true; }
void ClearTextureWindowChangedFlag() { texture_window_changed = false; } 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); void SetTextureWindow(u32 value);
} m_render_state = {};
} m_draw_mode = {};
Common::Rectangle<u32> m_drawing_area; Common::Rectangle<u32> m_drawing_area;

View File

@ -125,16 +125,8 @@ bool GPU::HandleInterruptRequestCommand(const u32*& command_ptr, u32 command_siz
bool GPU::HandleSetDrawModeCommand(const u32*& command_ptr, u32 command_size) bool GPU::HandleSetDrawModeCommand(const u32*& command_ptr, u32 command_size)
{ {
const u32 param = *(command_ptr++) & 0x00FFFFFF; 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); Log_DebugPrintf("Set draw mode %08X", param);
SetDrawMode(Truncate16(param));
EndCommand(); EndCommand();
return true; 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) bool GPU::HandleSetTextureWindowCommand(const u32*& command_ptr, u32 command_size)
{ {
const u32 param = *(command_ptr++) & 0x00FFFFFF; const u32 param = *(command_ptr++) & 0x00FFFFFF;
m_render_state.SetTextureWindow(param); m_draw_mode.SetTextureWindow(param);
Log_DebugPrintf("Set texture window %02X %02X %02X %02X", m_render_state.texture_window_mask_x, Log_DebugPrintf("Set texture window %02X %02X %02X %02X", m_draw_mode.texture_window_mask_x,
m_render_state.texture_window_mask_y, m_render_state.texture_window_offset_x, m_draw_mode.texture_window_mask_y, m_draw_mode.texture_window_offset_x,
m_render_state.texture_window_offset_y); m_draw_mode.texture_window_offset_y);
EndCommand(); EndCommand();
return true; 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); words_per_vertex = 1 + BoolToUInt8(rc.texture_enable) + BoolToUInt8(rc.shading_enable);
num_vertices = rc.quad_polygon ? 4 : 3; num_vertices = rc.quad_polygon ? 4 : 3;
total_words = words_per_vertex * num_vertices + BoolToUInt8(!rc.shading_enable); 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; 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); 2 + BoolToUInt8(rc.texture_enable) + BoolToUInt8(rc.rectangle_size == DrawRectangleSize::Variable);
num_vertices = 1; num_vertices = 1;
total_words = words_per_vertex; total_words = words_per_vertex;
if (rc.texture_enable)
SetTexturePalette(Truncate16(command_ptr[2] >> 16));
} }
break; break;

View File

@ -64,8 +64,7 @@ void GPU_HW::UpdateSettings()
void GPU_HW::LoadVertices(RenderCommand rc, u32 num_vertices, const u32* command_ptr) void GPU_HW::LoadVertices(RenderCommand rc, u32 num_vertices, const u32* command_ptr)
{ {
const u32 texpage = const u32 texpage = ZeroExtend32(m_draw_mode.mode_reg.bits) | (ZeroExtend32(m_draw_mode.palette_reg) << 16);
ZeroExtend32(m_render_state.texpage_attribute) | (ZeroExtend32(m_render_state.texlut_attribute) << 16);
// TODO: Move this to the GPU.. // TODO: Move this to the GPU..
switch (rc.primitive) switch (rc.primitive)
@ -271,34 +270,12 @@ void GPU_HW::DispatchRenderCommand(RenderCommand rc, u32 num_vertices, const u32
TextureMode texture_mode; TextureMode texture_mode;
if (rc.texture_enable) 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 // 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(); m_draw_mode.ClearTexturePageChangedFlag();
if (m_vram_dirty_rect.Valid() && (m_render_state.GetTexturePageRectangle().Intersects(m_vram_dirty_rect) || if (m_vram_dirty_rect.Valid() && (m_draw_mode.GetTexturePageRectangle().Intersects(m_vram_dirty_rect) ||
m_render_state.GetTexturePaletteRectangle().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"); Log_DevPrintf("Invalidating VRAM read cache due to drawing area overlap");
if (!IsFlushed()) 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) if (rc.raw_texture_enable)
{ {
texture_mode = 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? // has any state changed which requires a new batch?
const TransparencyMode transparency_mode = 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 BatchPrimitive rc_primitive = GetPrimitiveForCommand(rc);
const bool dithering_enable = (!m_true_color && rc.IsDitheringEnabled()) ? m_GPUSTAT.dither_enable : false; const bool dithering_enable = (!m_true_color && rc.IsDitheringEnabled()) ? m_GPUSTAT.dither_enable : false;
const u32 max_added_vertices = num_vertices + 5; 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 || if (buffer_overflow || rc_primitive == BatchPrimitive::LineStrip || m_batch.texture_mode != texture_mode ||
m_batch.transparency_mode != transparency_mode || m_batch.primitive != rc_primitive || m_batch.transparency_mode != transparency_mode || m_batch.primitive != rc_primitive ||
dithering_enable != m_batch.dithering || m_drawing_area_changed || m_drawing_offset_changed || dithering_enable != m_batch.dithering || m_drawing_area_changed || m_drawing_offset_changed ||
m_render_state.IsTextureWindowChanged()) m_draw_mode.IsTextureWindowChanged())
{ {
FlushRender(); FlushRender();
} }
@ -374,14 +351,14 @@ void GPU_HW::DispatchRenderCommand(RenderCommand rc, u32 num_vertices, const u32
m_batch.transparency_mode = transparency_mode; m_batch.transparency_mode = transparency_mode;
m_batch.dithering = dithering_enable; 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[0] = ZeroExtend32(m_draw_mode.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_mask[1] = ZeroExtend32(m_draw_mode.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[0] = ZeroExtend32(m_draw_mode.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_offset[1] = ZeroExtend32(m_draw_mode.texture_window_offset_y);
m_batch_ubo_dirty = true; m_batch_ubo_dirty = true;
} }

View File

@ -122,7 +122,7 @@ protected:
void SetFullVRAMDirtyRectangle() void SetFullVRAMDirtyRectangle()
{ {
m_vram_dirty_rect.Set(0, 0, VRAM_WIDTH, VRAM_HEIGHT); 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(); } void ClearVRAMDirtyRectangle() { m_vram_dirty_rect.SetInvalid(); }

View File

@ -164,14 +164,6 @@ void GPU_SW::DispatchRenderCommand(RenderCommand rc, u32 num_vertices, const u32
const bool shaded = rc.shading_enable; const bool shaded = rc.shading_enable;
const bool textured = rc.texture_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; u32 buffer_pos = 1;
for (u32 i = 0; i < num_vertices; i++) 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 u32 texcoord_and_palette = rc.texture_enable ? command_ptr[buffer_pos++] : 0;
const auto [texcoord_x, texcoord_y] = UnpackTexcoord(Truncate16(texcoord_and_palette)); const auto [texcoord_x, texcoord_y] = UnpackTexcoord(Truncate16(texcoord_and_palette));
m_render_state.SetFromPaletteAttribute(Truncate16(texcoord_and_palette >> 16));
s32 width; s32 width;
s32 height; s32 height;
switch (rc.rectangle_size) 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 // Apply texture window
// TODO: Precompute the second half // TODO: Precompute the second half
texcoord_x = (texcoord_x & ~(m_render_state.texture_window_mask_x * 8u)) | texcoord_x = (texcoord_x & ~(m_draw_mode.texture_window_mask_x * 8u)) |
((m_render_state.texture_window_offset_x & m_render_state.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_render_state.texture_window_mask_y * 8u)) | texcoord_y = (texcoord_y & ~(m_draw_mode.texture_window_mask_y * 8u)) |
((m_render_state.texture_window_offset_y & m_render_state.texture_window_mask_y) * 8u); ((m_draw_mode.texture_window_offset_y & m_draw_mode.texture_window_mask_y) * 8u);
VRAMPixel texture_color; VRAMPixel texture_color;
switch (m_render_state.texture_mode) switch (m_draw_mode.GetTextureMode())
{ {
case GPU::TextureMode::Palette4Bit: case GPU::TextureMode::Palette4Bit:
{ {
const u16 palette_value = const u16 palette_value =
GetPixel(std::min<u32>(m_render_state.texture_page_x + ZeroExtend32(texcoord_x / 4), VRAM_WIDTH - 1), GetPixel(std::min<u32>(m_draw_mode.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)); 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; const u16 palette_index = (palette_value >> ((texcoord_x % 4) * 4)) & 0x0Fu;
texture_color.bits = texture_color.bits =
GetPixel(std::min<u32>(m_render_state.texture_palette_x + ZeroExtend32(palette_index), VRAM_WIDTH - 1), GetPixel(std::min<u32>(m_draw_mode.texture_palette_x + ZeroExtend32(palette_index), VRAM_WIDTH - 1),
m_render_state.texture_palette_y); m_draw_mode.texture_palette_y);
} }
break; break;
case GPU::TextureMode::Palette8Bit: case GPU::TextureMode::Palette8Bit:
{ {
const u16 palette_value = const u16 palette_value =
GetPixel(std::min<u32>(m_render_state.texture_page_x + ZeroExtend32(texcoord_x / 2), VRAM_WIDTH - 1), GetPixel(std::min<u32>(m_draw_mode.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)); 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; const u16 palette_index = (palette_value >> ((texcoord_x % 2) * 8)) & 0xFFu;
texture_color.bits = texture_color.bits =
GetPixel(std::min<u32>(m_render_state.texture_palette_x + ZeroExtend32(palette_index), VRAM_WIDTH - 1), GetPixel(std::min<u32>(m_draw_mode.texture_palette_x + ZeroExtend32(palette_index), VRAM_WIDTH - 1),
m_render_state.texture_palette_y); m_draw_mode.texture_palette_y);
} }
break; break;
default: default:
{ {
texture_color.bits = texture_color.bits =
GetPixel(std::min<u32>(m_render_state.texture_page_x + ZeroExtend32(texcoord_x), VRAM_WIDTH - 1), GetPixel(std::min<u32>(m_draw_mode.texture_page_x + ZeroExtend32(texcoord_x), VRAM_WIDTH - 1),
std::min<u32>(m_render_state.texture_page_y + ZeroExtend32(texcoord_y), VRAM_HEIGHT - 1)); std::min<u32>(m_draw_mode.texture_page_y + ZeroExtend32(texcoord_y), VRAM_HEIGHT - 1));
} }
break; 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()), \ 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()) 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: case GPU::TransparencyMode::HalfBackgroundPlusHalfForeground:
BLEND_RGB(BLEND_AVERAGE); BLEND_RGB(BLEND_AVERAGE);