From 1405ba8a6b58548a4213dec99a99a0ce9e66094a Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Sat, 10 Jul 2021 14:28:27 +1000 Subject: [PATCH] GPU/SW: Specialize rasterizing functions further --- scripts/gen_sw_functions.py | 73 ++ src/core/gpu_sw_backend.cpp | 1316 ++++++++++++++++++++++++++++++++--- src/core/gpu_sw_backend.h | 39 +- 3 files changed, 1317 insertions(+), 111 deletions(-) create mode 100644 scripts/gen_sw_functions.py diff --git a/scripts/gen_sw_functions.py b/scripts/gen_sw_functions.py new file mode 100644 index 000000000..d28bcb9b6 --- /dev/null +++ b/scripts/gen_sw_functions.py @@ -0,0 +1,73 @@ +texmode = [ + "GPUTextureMode::Palette4Bit", + "GPUTextureMode::Palette8Bit", + "GPUTextureMode::Direct16Bit", + "GPUTextureMode::Direct16Bit", + + "GPUTextureMode::RawPalette4Bit", + "GPUTextureMode::RawPalette8Bit", + "GPUTextureMode::RawDirect16Bit", + "GPUTextureMode::RawDirect16Bit", + + "GPUTextureMode::Disabled" +] + +transparentmode = [ + "GPUTransparencyMode::HalfBackgroundPlusHalfForeground", + "GPUTransparencyMode::BackgroundPlusForeground", + "GPUTransparencyMode::BackgroundMinusForeground", + "GPUTransparencyMode::BackgroundPlusQuarterForeground", + "GPUTransparencyMode::Disabled" +] + +bools = ["false", "true"] + + +""" +print("const GPU_SW_Backend::DrawRectangleFunction GPU_SW_Backend::s_rectangle_draw_functions[%d][%d][2] = {" % (len(texmode), len(transparentmode))) +for texture in range(len(texmode)): + print(" { // %s" % texmode[texture]) + for transparency in range(len(transparentmode)): + print(" { // %s" % transparentmode[transparency]) + for check_mask in range(2): + line = "&GPU_SW_Backend::DrawRectangle<%s, %s, %s>" % (texmode[texture], transparentmode[transparency], bools[check_mask]) + print(" %s%s" % (line, "," if check_mask == 0 else "")) + print(" }%s" % ("," if transparency < (len(transparentmode) - 1) else "")) + print(" }%s" % ("," if texture < (len(texmode) - 1) else "")) +print("};") +""" + +""" +print("const GPU_SW_Backend::DrawTriangleFunction GPU_SW_Backend::s_triangle_draw_functions[2][%d][%d][2][2] = {" % (len(texmode), len(transparentmode))) +for shading in range(2): + print(" { // shading %s" % bools[shading]) + for texture in range(len(texmode)): + print(" { // %s" % texmode[texture]) + for transparency in range(len(transparentmode)): + print(" { // %s" % transparentmode[transparency]) + for dither in range(2): + print(" { // dither %s" % bools[dither]) + for check_mask in range(2): + line = "&GPU_SW_Backend::DrawTriangle<%s, %s, %s, %s, %s>" % (bools[shading], texmode[texture], transparentmode[transparency], bools[dither], bools[check_mask]) + print(" %s%s" % (line, "," if check_mask == 0 else "")) + print(" }%s" % ("," if dither == 0 else "")) + print(" }%s" % ("," if transparency < (len(transparentmode) - 1) else "")) + print(" }%s" % ("," if texture < (len(texmode) - 1) else "")) + print(" }%s" % ("," if shading == 0 else "")) +print("};") +""" + +print("const GPU_SW_Backend::DrawLineFunction GPU_SW_Backend::s_line_draw_functions[2][%d][2][2] = {" % (len(transparentmode))) +for shading in range(2): + print(" { // shading %s" % bools[shading]) + for transparency in range(len(transparentmode)): + print(" { // %s" % transparentmode[transparency]) + for dither in range(2): + print(" { // dither %s" % bools[dither]) + for check_mask in range(2): + line = "&GPU_SW_Backend::DrawLine<%s, %s, %s, %s>" % (bools[shading], transparentmode[transparency], bools[dither], bools[check_mask]) + print(" %s%s" % (line, "," if check_mask == 0 else "")) + print(" }%s" % ("," if dither == 0 else "")) + print(" }%s" % ("," if transparency < (len(transparentmode) - 1) else "")) + print(" }%s" % ("," if shading == 0 else "")) +print("};") diff --git a/src/core/gpu_sw_backend.cpp b/src/core/gpu_sw_backend.cpp index 0f3dd0f58..b40e75120 100644 --- a/src/core/gpu_sw_backend.cpp +++ b/src/core/gpu_sw_backend.cpp @@ -9,8 +9,8 @@ Log_SetChannel(GPU_SW_Backend); GPU_SW_Backend::GPU_SW_Backend() : GPUBackend() { - m_vram.fill(0); - m_vram_ptr = m_vram.data(); + std::memset(&m_vram[0], 0, sizeof(u16) * VRAM_WIDTH * VRAM_HEIGHT); + m_vram_ptr = &m_vram[0]; } GPU_SW_Backend::~GPU_SW_Backend() = default; @@ -25,16 +25,23 @@ void GPU_SW_Backend::Reset(bool clear_vram) GPUBackend::Reset(clear_vram); if (clear_vram) - m_vram.fill(0); + std::memset(&m_vram[0], 0, sizeof(u16) * VRAM_WIDTH * VRAM_HEIGHT); } void GPU_SW_Backend::DrawPolygon(const GPUBackendDrawPolygonCommand* cmd) { const GPURenderCommand rc{cmd->rc.bits}; const bool dithering_enable = rc.IsDitheringEnabled() && cmd->draw_mode.dither_enable; + const GPUTransparencyMode transparency_mode = + rc.transparency_enable ? cmd->draw_mode.transparency_mode : GPUTransparencyMode::Disabled; + const GPUTextureMode texture_mode = + rc.texture_enable ? (cmd->draw_mode.texture_mode | + (rc.raw_texture_enable ? GPUTextureMode::RawTextureBit : static_cast(0))) : + GPUTextureMode::Disabled; - const DrawTriangleFunction DrawFunction = GetDrawTriangleFunction( - rc.shading_enable, rc.texture_enable, rc.raw_texture_enable, rc.transparency_enable, dithering_enable); + const DrawTriangleFunction DrawFunction = + s_triangle_draw_functions[BoolToUInt8(rc.shading_enable)][static_cast(texture_mode)][static_cast( + transparency_mode)][BoolToUInt8(dithering_enable)][BoolToUInt8(cmd->params.check_mask_before_draw)]; (this->*DrawFunction)(cmd, &cmd->vertices[0], &cmd->vertices[1], &cmd->vertices[2]); if (rc.quad_polygon) @@ -44,17 +51,28 @@ void GPU_SW_Backend::DrawPolygon(const GPUBackendDrawPolygonCommand* cmd) void GPU_SW_Backend::DrawRectangle(const GPUBackendDrawRectangleCommand* cmd) { const GPURenderCommand rc{cmd->rc.bits}; + const GPUTransparencyMode transparency_mode = + rc.transparency_enable ? cmd->draw_mode.transparency_mode : GPUTransparencyMode::Disabled; + const GPUTextureMode texture_mode = + rc.texture_enable ? (cmd->draw_mode.texture_mode | + (rc.raw_texture_enable ? GPUTextureMode::RawTextureBit : static_cast(0))) : + GPUTextureMode::Disabled; const DrawRectangleFunction DrawFunction = - GetDrawRectangleFunction(rc.texture_enable, rc.raw_texture_enable, rc.transparency_enable); + s_rectangle_draw_functions[static_cast(texture_mode)][static_cast(transparency_mode)] + [BoolToUInt8(cmd->params.check_mask_before_draw)]; (this->*DrawFunction)(cmd); } void GPU_SW_Backend::DrawLine(const GPUBackendDrawLineCommand* cmd) { + const GPUTransparencyMode transparency_mode = + cmd->rc.transparency_enable ? cmd->draw_mode.transparency_mode : GPUTransparencyMode::Disabled; + const DrawLineFunction DrawFunction = - GetDrawLineFunction(cmd->rc.shading_enable, cmd->rc.transparency_enable, cmd->IsDitheringEnabled()); + s_line_draw_functions[BoolToUInt8(cmd->rc.shading_enable)][static_cast(transparency_mode)] + [BoolToUInt8(cmd->IsDitheringEnabled())][BoolToUInt8(cmd->params.check_mask_before_draw)]; for (u16 i = 1; i < cmd->num_vertices; i++) (this->*DrawFunction)(cmd, &cmd->vertices[i - 1], &cmd->vertices[i]); @@ -79,19 +97,19 @@ constexpr GPU_SW_Backend::DitherLUT GPU_SW_Backend::ComputeDitherLUT() static constexpr GPU_SW_Backend::DitherLUT s_dither_lut = GPU_SW_Backend::ComputeDitherLUT(); -template +template void ALWAYS_INLINE_RELEASE GPU_SW_Backend::ShadePixel(const GPUBackendDrawCommand* cmd, u32 x, u32 y, u8 color_r, u8 color_g, u8 color_b, u8 texcoord_x, u8 texcoord_y) { VRAMPixel color; - if constexpr (texture_enable) + if constexpr (texture_mode != GPUTextureMode::Disabled) { // Apply texture window texcoord_x = (texcoord_x & cmd->window.and_x) | cmd->window.or_x; texcoord_y = (texcoord_y & cmd->window.and_y) | cmd->window.or_y; VRAMPixel texture_color; - switch (cmd->draw_mode.texture_mode) + switch (texture_mode & ~GPUTextureMode::RawTextureBit) { case GPUTextureMode::Palette4Bit: { @@ -127,7 +145,7 @@ void ALWAYS_INLINE_RELEASE GPU_SW_Backend::ShadePixel(const GPUBackendDrawComman if (texture_color.bits == 0) return; - if constexpr (raw_texture_enable) + if constexpr ((texture_mode & GPUTextureMode::RawTextureBit) == GPUTextureMode::RawTextureBit) { color.bits = texture_color.bits; } @@ -150,13 +168,19 @@ void ALWAYS_INLINE_RELEASE GPU_SW_Backend::ShadePixel(const GPUBackendDrawComman // Non-textured transparent polygons don't set bit 15, but are treated as transparent. color.bits = (ZeroExtend16(s_dither_lut[dither_y][dither_x][color_r]) << 0) | (ZeroExtend16(s_dither_lut[dither_y][dither_x][color_g]) << 5) | - (ZeroExtend16(s_dither_lut[dither_y][dither_x][color_b]) << 10) | (transparency_enable ? 0x8000u : 0); + (ZeroExtend16(s_dither_lut[dither_y][dither_x][color_b]) << 10) | + ((transparency_mode != GPUTransparencyMode::Disabled) ? 0x8000u : 0); } - const VRAMPixel bg_color{GetPixel(static_cast(x), static_cast(y))}; - if constexpr (transparency_enable) + VRAMPixel bg_color; + if constexpr (transparency_mode != GPUTransparencyMode::Disabled || check_mask) + bg_color.bits = GetPixel(static_cast(x), static_cast(y)); + else + bg_color.bits = 0; + + if constexpr (transparency_mode != GPUTransparencyMode::Disabled) { - if (color.bits & 0x8000u || !texture_enable) + if (color.bits & 0x8000u || texture_mode == GPUTextureMode::Disabled) { // Based on blargg's efficient 15bpp pixel math. u32 bg_bits = ZeroExtend32(bg_color.bits); @@ -207,19 +231,22 @@ void ALWAYS_INLINE_RELEASE GPU_SW_Backend::ShadePixel(const GPUBackendDrawComman } // See above. - if constexpr (!texture_enable) + if constexpr (texture_mode == GPUTextureMode::Disabled) color.bits &= ~0x8000u; } } - const u16 mask_and = cmd->params.GetMaskAND(); - if ((bg_color.bits & mask_and) != 0) - return; + if constexpr (check_mask) + { + const u16 mask_and = cmd->params.GetMaskAND(); + if ((bg_color.bits & mask_and) != 0) + return; + } SetPixel(static_cast(x), static_cast(y), color.bits | cmd->params.GetMaskOR()); } -template +template void GPU_SW_Backend::DrawRectangle(const GPUBackendDrawRectangleCommand* cmd) { const s32 origin_x = cmd->x; @@ -246,8 +273,8 @@ void GPU_SW_Backend::DrawRectangle(const GPUBackendDrawRectangleCommand* cmd) const u8 texcoord_x = Truncate8(ZeroExtend32(origin_texcoord_x) + offset_x); - ShadePixel( - cmd, static_cast(x), static_cast(y), r, g, b, texcoord_x, texcoord_y); + ShadePixel(cmd, static_cast(x), static_cast(y), r, g, b, + texcoord_x, texcoord_y); } } } @@ -358,8 +385,8 @@ void ALWAYS_INLINE_RELEASE GPU_SW_Backend::AddIDeltas_DY(i_group& ig, const i_de } } -template +template void GPU_SW_Backend::DrawSpan(const GPUBackendDrawPolygonCommand* cmd, s32 y, s32 x_start, s32 x_bound, i_group ig, const i_deltas& idl) { @@ -384,6 +411,7 @@ void GPU_SW_Backend::DrawSpan(const GPUBackendDrawPolygonCommand* cmd, s32 y, s3 if (w <= 0) return; + constexpr bool texture_enable = (texture_mode != GPUTextureMode::Disabled); AddIDeltas_DX(ig, idl, x_ig_adjust); AddIDeltas_DY(ig, idl, y); @@ -395,7 +423,7 @@ void GPU_SW_Backend::DrawSpan(const GPUBackendDrawPolygonCommand* cmd, s32 y, s3 const u32 u = ig.u >> (COORD_FBS + COORD_POST_PADDING); const u32 v = ig.v >> (COORD_FBS + COORD_POST_PADDING); - ShadePixel( + ShadePixel( cmd, static_cast(x), static_cast(y), Truncate8(r), Truncate8(g), Truncate8(b), Truncate8(u), Truncate8(v)); @@ -404,13 +432,15 @@ void GPU_SW_Backend::DrawSpan(const GPUBackendDrawPolygonCommand* cmd, s32 y, s3 } while (--w > 0); } -template +template void GPU_SW_Backend::DrawTriangle(const GPUBackendDrawPolygonCommand* cmd, const GPUBackendDrawPolygonCommand::Vertex* v0, const GPUBackendDrawPolygonCommand::Vertex* v1, const GPUBackendDrawPolygonCommand::Vertex* v2) { + constexpr bool texture_enable = (texture_mode != GPUTextureMode::Disabled); + u32 core_vertex; { u32 cvtemp = 0; @@ -570,7 +600,7 @@ void GPU_SW_Backend::DrawTriangle(const GPUBackendDrawPolygonCommand* cmd, if (y > static_cast(m_drawing_area.bottom)) continue; - DrawSpan( + DrawSpan( cmd, yi, GetPolyXFP_Int(lc), GetPolyXFP_Int(rc), ig, idl); } } @@ -586,7 +616,7 @@ void GPU_SW_Backend::DrawTriangle(const GPUBackendDrawPolygonCommand* cmd, if (y >= static_cast(m_drawing_area.top)) { - DrawSpan( + DrawSpan( cmd, yi, GetPolyXFP_Int(lc), GetPolyXFP_Int(rc), ig, idl); } @@ -598,38 +628,6 @@ void GPU_SW_Backend::DrawTriangle(const GPUBackendDrawPolygonCommand* cmd, } } -GPU_SW_Backend::DrawTriangleFunction GPU_SW_Backend::GetDrawTriangleFunction(bool shading_enable, bool texture_enable, - bool raw_texture_enable, - bool transparency_enable, - bool dithering_enable) -{ -#define F(SHADING, TEXTURE, RAW_TEXTURE, TRANSPARENCY, DITHERING) \ - &GPU_SW_Backend::DrawTriangle - - static constexpr DrawTriangleFunction funcs[2][2][2][2][2] = { - {{{{F(false, false, false, false, false), F(false, false, false, false, true)}, - {F(false, false, false, true, false), F(false, false, false, true, true)}}, - {{F(false, false, true, false, false), F(false, false, true, false, true)}, - {F(false, false, true, true, false), F(false, false, true, true, true)}}}, - {{{F(false, true, false, false, false), F(false, true, false, false, true)}, - {F(false, true, false, true, false), F(false, true, false, true, true)}}, - {{F(false, true, true, false, false), F(false, true, true, false, true)}, - {F(false, true, true, true, false), F(false, true, true, true, true)}}}}, - {{{{F(true, false, false, false, false), F(true, false, false, false, true)}, - {F(true, false, false, true, false), F(true, false, false, true, true)}}, - {{F(true, false, true, false, false), F(true, false, true, false, true)}, - {F(true, false, true, true, false), F(true, false, true, true, true)}}}, - {{{F(true, true, false, false, false), F(true, true, false, false, true)}, - {F(true, true, false, true, false), F(true, true, false, true, true)}}, - {{F(true, true, true, false, false), F(true, true, true, false, true)}, - {F(true, true, true, true, false), F(true, true, true, true, true)}}}}}; - -#undef F - - return funcs[u8(shading_enable)][u8(texture_enable)][u8(raw_texture_enable)][u8(transparency_enable)] - [u8(dithering_enable)]; -} - enum { Line_XY_FractBits = 32 @@ -663,7 +661,7 @@ static ALWAYS_INLINE_RELEASE s64 LineDivide(s64 delta, s32 dk) return (delta / dk); } -template +template void GPU_SW_Backend::DrawLine(const GPUBackendDrawLineCommand* cmd, const GPUBackendDrawLineCommand::Vertex* p0, const GPUBackendDrawLineCommand::Vertex* p1) { @@ -732,8 +730,8 @@ void GPU_SW_Backend::DrawLine(const GPUBackendDrawLineCommand* cmd, const GPUBac const u8 g = shading_enable ? static_cast(cur_point.g >> Line_RGB_FractBits) : p0->g; const u8 b = shading_enable ? static_cast(cur_point.b >> Line_RGB_FractBits) : p0->b; - ShadePixel(cmd, static_cast(x), static_cast(y), r, - g, b, 0, 0); + ShadePixel( + cmd, static_cast(x), static_cast(y), r, g, b, 0, 0); } cur_point.x += step.dx_dk; @@ -748,34 +746,6 @@ void GPU_SW_Backend::DrawLine(const GPUBackendDrawLineCommand* cmd, const GPUBac } } -GPU_SW_Backend::DrawLineFunction GPU_SW_Backend::GetDrawLineFunction(bool shading_enable, bool transparency_enable, - bool dithering_enable) -{ -#define F(SHADING, TRANSPARENCY, DITHERING) &GPU_SW_Backend::DrawLine - - static constexpr DrawLineFunction funcs[2][2][2] = { - {{F(false, false, false), F(false, false, true)}, {F(false, true, false), F(false, true, true)}}, - {{F(true, false, false), F(true, false, true)}, {F(true, true, false), F(true, true, true)}}}; - -#undef F - - return funcs[u8(shading_enable)][u8(transparency_enable)][u8(dithering_enable)]; -} - -GPU_SW_Backend::DrawRectangleFunction -GPU_SW_Backend::GetDrawRectangleFunction(bool texture_enable, bool raw_texture_enable, bool transparency_enable) -{ -#define F(TEXTURE, RAW_TEXTURE, TRANSPARENCY) &GPU_SW_Backend::DrawRectangle - - static constexpr DrawRectangleFunction funcs[2][2][2] = { - {{F(false, false, false), F(false, false, true)}, {F(false, true, false), F(false, true, true)}}, - {{F(true, false, false), F(true, false, true)}, {F(true, true, false), F(true, true, true)}}}; - -#undef F - - return funcs[u8(texture_enable)][u8(raw_texture_enable)][u8(transparency_enable)]; -} - void GPU_SW_Backend::FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color, GPUBackendCommandParameters params) { const u16 color16 = VRAMRGBA8888ToRGBA5551(color); @@ -933,3 +903,1165 @@ void GPU_SW_Backend::CopyVRAM(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 wi void GPU_SW_Backend::FlushRender() {} void GPU_SW_Backend::DrawingAreaChanged() {} + +const GPU_SW_Backend::DrawRectangleFunction GPU_SW_Backend::s_rectangle_draw_functions[9][5][2] = { + {{&GPU_SW_Backend::DrawRectangle, + &GPU_SW_Backend::DrawRectangle}, + {&GPU_SW_Backend::DrawRectangle, + &GPU_SW_Backend::DrawRectangle}, + {&GPU_SW_Backend::DrawRectangle, + &GPU_SW_Backend::DrawRectangle}, + {&GPU_SW_Backend::DrawRectangle, + &GPU_SW_Backend::DrawRectangle}, + {&GPU_SW_Backend::DrawRectangle, + &GPU_SW_Backend::DrawRectangle}}, + {{&GPU_SW_Backend::DrawRectangle, + &GPU_SW_Backend::DrawRectangle}, + {&GPU_SW_Backend::DrawRectangle, + &GPU_SW_Backend::DrawRectangle}, + {&GPU_SW_Backend::DrawRectangle, + &GPU_SW_Backend::DrawRectangle}, + {&GPU_SW_Backend::DrawRectangle, + &GPU_SW_Backend::DrawRectangle}, + {&GPU_SW_Backend::DrawRectangle, + &GPU_SW_Backend::DrawRectangle}}, + {{&GPU_SW_Backend::DrawRectangle, + &GPU_SW_Backend::DrawRectangle}, + {&GPU_SW_Backend::DrawRectangle, + &GPU_SW_Backend::DrawRectangle}, + {&GPU_SW_Backend::DrawRectangle, + &GPU_SW_Backend::DrawRectangle}, + {&GPU_SW_Backend::DrawRectangle, + &GPU_SW_Backend::DrawRectangle}, + {&GPU_SW_Backend::DrawRectangle, + &GPU_SW_Backend::DrawRectangle}}, + {{&GPU_SW_Backend::DrawRectangle, + &GPU_SW_Backend::DrawRectangle}, + {&GPU_SW_Backend::DrawRectangle, + &GPU_SW_Backend::DrawRectangle}, + {&GPU_SW_Backend::DrawRectangle, + &GPU_SW_Backend::DrawRectangle}, + {&GPU_SW_Backend::DrawRectangle, + &GPU_SW_Backend::DrawRectangle}, + {&GPU_SW_Backend::DrawRectangle, + &GPU_SW_Backend::DrawRectangle}}, + {{&GPU_SW_Backend::DrawRectangle, + &GPU_SW_Backend::DrawRectangle}, + {&GPU_SW_Backend::DrawRectangle, + &GPU_SW_Backend::DrawRectangle}, + {&GPU_SW_Backend::DrawRectangle, + &GPU_SW_Backend::DrawRectangle}, + {&GPU_SW_Backend::DrawRectangle, + &GPU_SW_Backend::DrawRectangle}, + {&GPU_SW_Backend::DrawRectangle, + &GPU_SW_Backend::DrawRectangle}}, + {{&GPU_SW_Backend::DrawRectangle, + &GPU_SW_Backend::DrawRectangle}, + {&GPU_SW_Backend::DrawRectangle, + &GPU_SW_Backend::DrawRectangle}, + {&GPU_SW_Backend::DrawRectangle, + &GPU_SW_Backend::DrawRectangle}, + {&GPU_SW_Backend::DrawRectangle, + &GPU_SW_Backend::DrawRectangle}, + {&GPU_SW_Backend::DrawRectangle, + &GPU_SW_Backend::DrawRectangle}}, + {{&GPU_SW_Backend::DrawRectangle, + &GPU_SW_Backend::DrawRectangle}, + {&GPU_SW_Backend::DrawRectangle, + &GPU_SW_Backend::DrawRectangle}, + {&GPU_SW_Backend::DrawRectangle, + &GPU_SW_Backend::DrawRectangle}, + {&GPU_SW_Backend::DrawRectangle, + &GPU_SW_Backend::DrawRectangle}, + {&GPU_SW_Backend::DrawRectangle, + &GPU_SW_Backend::DrawRectangle}}, + {{&GPU_SW_Backend::DrawRectangle, + &GPU_SW_Backend::DrawRectangle}, + {&GPU_SW_Backend::DrawRectangle, + &GPU_SW_Backend::DrawRectangle}, + {&GPU_SW_Backend::DrawRectangle, + &GPU_SW_Backend::DrawRectangle}, + {&GPU_SW_Backend::DrawRectangle, + &GPU_SW_Backend::DrawRectangle}, + {&GPU_SW_Backend::DrawRectangle, + &GPU_SW_Backend::DrawRectangle}}, + {{&GPU_SW_Backend::DrawRectangle, + &GPU_SW_Backend::DrawRectangle}, + {&GPU_SW_Backend::DrawRectangle, + &GPU_SW_Backend::DrawRectangle}, + {&GPU_SW_Backend::DrawRectangle, + &GPU_SW_Backend::DrawRectangle}, + {&GPU_SW_Backend::DrawRectangle, + &GPU_SW_Backend::DrawRectangle}, + {&GPU_SW_Backend::DrawRectangle, + &GPU_SW_Backend::DrawRectangle}}}; + +const GPU_SW_Backend::DrawTriangleFunction GPU_SW_Backend::s_triangle_draw_functions[2][9][5][2][2] = { + { // shading false + { // GPUTextureMode::Palette4Bit + { // GPUTransparencyMode::HalfBackgroundPlusHalfForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::BackgroundPlusForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::BackgroundMinusForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::BackgroundPlusQuarterForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::Disabled + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}}, + { // GPUTextureMode::Palette8Bit + { // GPUTransparencyMode::HalfBackgroundPlusHalfForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::BackgroundPlusForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::BackgroundMinusForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::BackgroundPlusQuarterForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::Disabled + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}}, + { // GPUTextureMode::Direct16Bit + { // GPUTransparencyMode::HalfBackgroundPlusHalfForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::BackgroundPlusForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::BackgroundMinusForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::BackgroundPlusQuarterForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::Disabled + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}}, + { // GPUTextureMode::Direct16Bit + { // GPUTransparencyMode::HalfBackgroundPlusHalfForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::BackgroundPlusForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::BackgroundMinusForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::BackgroundPlusQuarterForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::Disabled + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}}, + { // GPUTextureMode::RawPalette4Bit + { // GPUTransparencyMode::HalfBackgroundPlusHalfForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::BackgroundPlusForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::BackgroundMinusForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::BackgroundPlusQuarterForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::Disabled + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}}, + { // GPUTextureMode::RawPalette8Bit + { // GPUTransparencyMode::HalfBackgroundPlusHalfForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::BackgroundPlusForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::BackgroundMinusForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::BackgroundPlusQuarterForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::Disabled + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}}, + { // GPUTextureMode::RawDirect16Bit + { // GPUTransparencyMode::HalfBackgroundPlusHalfForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::BackgroundPlusForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::BackgroundMinusForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::BackgroundPlusQuarterForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::Disabled + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}}, + { // GPUTextureMode::RawDirect16Bit + { // GPUTransparencyMode::HalfBackgroundPlusHalfForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::BackgroundPlusForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::BackgroundMinusForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::BackgroundPlusQuarterForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::Disabled + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}}, + { // GPUTextureMode::Disabled + { // GPUTransparencyMode::HalfBackgroundPlusHalfForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::BackgroundPlusForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::BackgroundMinusForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::BackgroundPlusQuarterForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::Disabled + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}}}, + { // shading true + { // GPUTextureMode::Palette4Bit + { // GPUTransparencyMode::HalfBackgroundPlusHalfForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::BackgroundPlusForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::BackgroundMinusForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::BackgroundPlusQuarterForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::Disabled + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}}, + { // GPUTextureMode::Palette8Bit + { // GPUTransparencyMode::HalfBackgroundPlusHalfForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::BackgroundPlusForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::BackgroundMinusForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::BackgroundPlusQuarterForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::Disabled + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}}, + { // GPUTextureMode::Direct16Bit + { // GPUTransparencyMode::HalfBackgroundPlusHalfForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::BackgroundPlusForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::BackgroundMinusForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::BackgroundPlusQuarterForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::Disabled + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}}, + { // GPUTextureMode::Direct16Bit + { // GPUTransparencyMode::HalfBackgroundPlusHalfForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::BackgroundPlusForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::BackgroundMinusForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::BackgroundPlusQuarterForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::Disabled + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}}, + { // GPUTextureMode::RawPalette4Bit + { // GPUTransparencyMode::HalfBackgroundPlusHalfForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::BackgroundPlusForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::BackgroundMinusForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::BackgroundPlusQuarterForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::Disabled + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}}, + { // GPUTextureMode::RawPalette8Bit + { // GPUTransparencyMode::HalfBackgroundPlusHalfForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::BackgroundPlusForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::BackgroundMinusForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::BackgroundPlusQuarterForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::Disabled + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}}, + { // GPUTextureMode::RawDirect16Bit + { // GPUTransparencyMode::HalfBackgroundPlusHalfForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::BackgroundPlusForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::BackgroundMinusForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::BackgroundPlusQuarterForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::Disabled + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}}, + { // GPUTextureMode::RawDirect16Bit + { // GPUTransparencyMode::HalfBackgroundPlusHalfForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::BackgroundPlusForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::BackgroundMinusForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::BackgroundPlusQuarterForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::Disabled + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}}, + { // GPUTextureMode::Disabled + { // GPUTransparencyMode::HalfBackgroundPlusHalfForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::BackgroundPlusForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::BackgroundMinusForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::BackgroundPlusQuarterForeground + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + { // GPUTransparencyMode::Disabled + {// dither false + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {// dither true + &GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}}}}; + +const GPU_SW_Backend::DrawLineFunction GPU_SW_Backend::s_line_draw_functions[2][5][2][2] = { + { // shading false + { // GPUTransparencyMode::HalfBackgroundPlusHalfForeground + {// dither false + &GPU_SW_Backend::DrawLine, + &GPU_SW_Backend::DrawLine}, + {// dither true + &GPU_SW_Backend::DrawLine, + &GPU_SW_Backend::DrawLine}}, + { // GPUTransparencyMode::BackgroundPlusForeground + {// dither false + &GPU_SW_Backend::DrawLine, + &GPU_SW_Backend::DrawLine}, + {// dither true + &GPU_SW_Backend::DrawLine, + &GPU_SW_Backend::DrawLine}}, + { // GPUTransparencyMode::BackgroundMinusForeground + {// dither false + &GPU_SW_Backend::DrawLine, + &GPU_SW_Backend::DrawLine}, + {// dither true + &GPU_SW_Backend::DrawLine, + &GPU_SW_Backend::DrawLine}}, + { // GPUTransparencyMode::BackgroundPlusQuarterForeground + {// dither false + &GPU_SW_Backend::DrawLine, + &GPU_SW_Backend::DrawLine}, + {// dither true + &GPU_SW_Backend::DrawLine, + &GPU_SW_Backend::DrawLine}}, + { // GPUTransparencyMode::Disabled + {// dither false + &GPU_SW_Backend::DrawLine, + &GPU_SW_Backend::DrawLine}, + {// dither true + &GPU_SW_Backend::DrawLine, + &GPU_SW_Backend::DrawLine}}}, + { // shading true + { // GPUTransparencyMode::HalfBackgroundPlusHalfForeground + {// dither false + &GPU_SW_Backend::DrawLine, + &GPU_SW_Backend::DrawLine}, + {// dither true + &GPU_SW_Backend::DrawLine, + &GPU_SW_Backend::DrawLine}}, + { // GPUTransparencyMode::BackgroundPlusForeground + {// dither false + &GPU_SW_Backend::DrawLine, + &GPU_SW_Backend::DrawLine}, + {// dither true + &GPU_SW_Backend::DrawLine, + &GPU_SW_Backend::DrawLine}}, + { // GPUTransparencyMode::BackgroundMinusForeground + {// dither false + &GPU_SW_Backend::DrawLine, + &GPU_SW_Backend::DrawLine}, + {// dither true + &GPU_SW_Backend::DrawLine, + &GPU_SW_Backend::DrawLine}}, + { // GPUTransparencyMode::BackgroundPlusQuarterForeground + {// dither false + &GPU_SW_Backend::DrawLine, + &GPU_SW_Backend::DrawLine}, + {// dither true + &GPU_SW_Backend::DrawLine, + &GPU_SW_Backend::DrawLine}}, + { // GPUTransparencyMode::Disabled + {// dither false + &GPU_SW_Backend::DrawLine, + &GPU_SW_Backend::DrawLine}, + {// dither true + &GPU_SW_Backend::DrawLine, + &GPU_SW_Backend::DrawLine}}}}; \ No newline at end of file diff --git a/src/core/gpu_sw_backend.h b/src/core/gpu_sw_backend.h index 5a7be6ffe..af93daabe 100644 --- a/src/core/gpu_sw_backend.h +++ b/src/core/gpu_sw_backend.h @@ -98,17 +98,13 @@ protected: ////////////////////////////////////////////////////////////////////////// // Rasterization ////////////////////////////////////////////////////////////////////////// - template + template void ShadePixel(const GPUBackendDrawCommand* cmd, u32 x, u32 y, u8 color_r, u8 color_g, u8 color_b, u8 texcoord_x, u8 texcoord_y); - template + template void DrawRectangle(const GPUBackendDrawRectangleCommand* cmd); - using DrawRectangleFunction = void (GPU_SW_Backend::*)(const GPUBackendDrawRectangleCommand* cmd); - DrawRectangleFunction GetDrawRectangleFunction(bool texture_enable, bool raw_texture_enable, - bool transparency_enable); - ////////////////////////////////////////////////////////////////////////// // Polygon and line rasterization ported from Mednafen ////////////////////////////////////////////////////////////////////////// @@ -137,31 +133,36 @@ protected: template void AddIDeltas_DY(i_group& ig, const i_deltas& idl, u32 count = 1); - template + template void DrawSpan(const GPUBackendDrawPolygonCommand* cmd, s32 y, s32 x_start, s32 x_bound, i_group ig, const i_deltas& idl); - template + template void DrawTriangle(const GPUBackendDrawPolygonCommand* cmd, const GPUBackendDrawPolygonCommand::Vertex* v0, const GPUBackendDrawPolygonCommand::Vertex* v1, const GPUBackendDrawPolygonCommand::Vertex* v2); + template + void DrawLine(const GPUBackendDrawLineCommand* cmd, const GPUBackendDrawLineCommand::Vertex* p0, + const GPUBackendDrawLineCommand::Vertex* p1); + +#if 0 + std::array m_vram; +#else + u16 m_vram[VRAM_WIDTH * VRAM_HEIGHT]; +#endif + + using DrawRectangleFunction = void (GPU_SW_Backend::*)(const GPUBackendDrawRectangleCommand* cmd); using DrawTriangleFunction = void (GPU_SW_Backend::*)(const GPUBackendDrawPolygonCommand* cmd, const GPUBackendDrawPolygonCommand::Vertex* v0, const GPUBackendDrawPolygonCommand::Vertex* v1, const GPUBackendDrawPolygonCommand::Vertex* v2); - DrawTriangleFunction GetDrawTriangleFunction(bool shading_enable, bool texture_enable, bool raw_texture_enable, - bool transparency_enable, bool dithering_enable); - - template - void DrawLine(const GPUBackendDrawLineCommand* cmd, const GPUBackendDrawLineCommand::Vertex* p0, - const GPUBackendDrawLineCommand::Vertex* p1); - using DrawLineFunction = void (GPU_SW_Backend::*)(const GPUBackendDrawLineCommand* cmd, const GPUBackendDrawLineCommand::Vertex* p0, const GPUBackendDrawLineCommand::Vertex* p1); - DrawLineFunction GetDrawLineFunction(bool shading_enable, bool transparency_enable, bool dithering_enable); - std::array m_vram; + static const DrawRectangleFunction s_rectangle_draw_functions[9][5][2]; + static const DrawTriangleFunction s_triangle_draw_functions[2][9][5][2][2]; + static const DrawLineFunction s_line_draw_functions[2][5][2][2]; };