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_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;
}
m_draw_mode.mode_reg.bits = reg.bits;
texture_mode = (static_cast<TextureMode>((value >> 7) & UINT16_C(0x03)));
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;
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)

View file

@ -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;

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)
{
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;

View file

@ -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;
}

View file

@ -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(); }

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 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);