From e9374646e97ecde8c75618c32d02e2e0d90c49e4 Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Sat, 17 Jul 2021 14:02:54 +1000 Subject: [PATCH] GPU/SW: Fix performance regression on 32-bit ARM --- scripts/gen_sw_functions.py | 93 +-- src/core/gpu_sw_backend.cpp | 1317 +++-------------------------------- src/core/gpu_sw_backend.h | 39 +- 3 files changed, 148 insertions(+), 1301 deletions(-) diff --git a/scripts/gen_sw_functions.py b/scripts/gen_sw_functions.py index d28bcb9b6..fc114fe54 100644 --- a/scripts/gen_sw_functions.py +++ b/scripts/gen_sw_functions.py @@ -1,73 +1,46 @@ -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("static constexpr DrawRectangleFunction funcs[2][2][2] = {") +for texture in range(2): + print(" {") + for raw_texture in range(2): + print(" {") + for transparency in range(2): + line = "&GPU_SW_Backend::DrawRectangle<%s, %s, %s>" % (bools[texture], bools[0 if texture == 0 else raw_texture], bools[transparency]) + print(" %s%s" % (line, "," if transparency == 0 else "")) + print(" }%s" % ("," if raw_texture == 0 else "")) + print(" }%s" % ("," if texture == 0 else "")) print("};") -""" -""" -print("const GPU_SW_Backend::DrawTriangleFunction GPU_SW_Backend::s_triangle_draw_functions[2][%d][%d][2][2] = {" % (len(texmode), len(transparentmode))) + +print("static constexpr DrawTriangleFunction funcs[2][2][2][2][2] = {") 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(" {") + for texture in range(2): + print(" {") + for raw_texture in range(2): + print(" {") + for transparency in range(2): + print(" {") + for dither in range(2): + line = "&GPU_SW_Backend::DrawTriangle<%s, %s, %s, %s, %s>" % (bools[shading], bools[texture], bools[0 if texture == 0 else raw_texture], bools[transparency], bools[0 if raw_texture != 0 else dither]) + print(" %s%s" % (line, "," if dither == 0 else "")) + print(" }%s" % ("," if transparency == 0 else "")) + print(" }%s" % ("," if raw_texture == 0 else "")) + print(" }%s" % ("," if texture == 0 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))) + +print("static constexpr DrawLineFunction funcs[2][2][2] = {") for shading in range(2): - print(" { // shading %s" % bools[shading]) - for transparency in range(len(transparentmode)): - print(" { // %s" % transparentmode[transparency]) + print(" {") + for transparency in range(2): + print(" {") 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 "")) + line = "&GPU_SW_Backend::DrawLine<%s, %s, %s>" % (bools[shading], bools[transparency], bools[dither]) + print(" %s%s" % (line, "," if dither == 0 else "")) + print(" }%s" % ("," if transparency == 0 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 b40e75120..c32c23b63 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() { - std::memset(&m_vram[0], 0, sizeof(u16) * VRAM_WIDTH * VRAM_HEIGHT); - m_vram_ptr = &m_vram[0]; + m_vram.fill(0); + m_vram_ptr = m_vram.data(); } GPU_SW_Backend::~GPU_SW_Backend() = default; @@ -25,23 +25,16 @@ void GPU_SW_Backend::Reset(bool clear_vram) GPUBackend::Reset(clear_vram); if (clear_vram) - std::memset(&m_vram[0], 0, sizeof(u16) * VRAM_WIDTH * VRAM_HEIGHT); + m_vram.fill(0); } 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 = - 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)]; + const DrawTriangleFunction DrawFunction = GetDrawTriangleFunction( + rc.shading_enable, rc.texture_enable, rc.raw_texture_enable, rc.transparency_enable, dithering_enable); (this->*DrawFunction)(cmd, &cmd->vertices[0], &cmd->vertices[1], &cmd->vertices[2]); if (rc.quad_polygon) @@ -51,28 +44,17 @@ 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 = - s_rectangle_draw_functions[static_cast(texture_mode)][static_cast(transparency_mode)] - [BoolToUInt8(cmd->params.check_mask_before_draw)]; + GetDrawRectangleFunction(rc.texture_enable, rc.raw_texture_enable, rc.transparency_enable); (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 = - s_line_draw_functions[BoolToUInt8(cmd->rc.shading_enable)][static_cast(transparency_mode)] - [BoolToUInt8(cmd->IsDitheringEnabled())][BoolToUInt8(cmd->params.check_mask_before_draw)]; + GetDrawLineFunction(cmd->rc.shading_enable, cmd->rc.transparency_enable, cmd->IsDitheringEnabled()); for (u16 i = 1; i < cmd->num_vertices; i++) (this->*DrawFunction)(cmd, &cmd->vertices[i - 1], &cmd->vertices[i]); @@ -97,19 +79,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_mode != GPUTextureMode::Disabled) + if constexpr (texture_enable) { // 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 (texture_mode & ~GPUTextureMode::RawTextureBit) + switch (cmd->draw_mode.texture_mode) { case GPUTextureMode::Palette4Bit: { @@ -145,7 +127,7 @@ void ALWAYS_INLINE_RELEASE GPU_SW_Backend::ShadePixel(const GPUBackendDrawComman if (texture_color.bits == 0) return; - if constexpr ((texture_mode & GPUTextureMode::RawTextureBit) == GPUTextureMode::RawTextureBit) + if constexpr (raw_texture_enable) { color.bits = texture_color.bits; } @@ -168,19 +150,13 @@ 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_mode != GPUTransparencyMode::Disabled) ? 0x8000u : 0); + (ZeroExtend16(s_dither_lut[dither_y][dither_x][color_b]) << 10) | (transparency_enable ? 0x8000u : 0); } - 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) + const VRAMPixel bg_color{GetPixel(static_cast(x), static_cast(y))}; + if constexpr (transparency_enable) { - if (color.bits & 0x8000u || texture_mode == GPUTextureMode::Disabled) + if (color.bits & 0x8000u || !texture_enable) { // Based on blargg's efficient 15bpp pixel math. u32 bg_bits = ZeroExtend32(bg_color.bits); @@ -231,22 +207,19 @@ void ALWAYS_INLINE_RELEASE GPU_SW_Backend::ShadePixel(const GPUBackendDrawComman } // See above. - if constexpr (texture_mode == GPUTextureMode::Disabled) + if constexpr (!texture_enable) color.bits &= ~0x8000u; } } - if constexpr (check_mask) - { - const u16 mask_and = cmd->params.GetMaskAND(); - if ((bg_color.bits & mask_and) != 0) - return; - } + 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; @@ -273,8 +246,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); } } } @@ -385,8 +358,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) { @@ -411,7 +384,6 @@ 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); @@ -423,7 +395,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)); @@ -432,15 +404,13 @@ 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; @@ -600,7 +570,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); } } @@ -616,7 +586,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); } @@ -661,7 +631,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) { @@ -730,8 +700,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; @@ -904,1164 +874,69 @@ 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}}}; +GPU_SW_Backend::DrawLineFunction GPU_SW_Backend::GetDrawLineFunction(bool shading_enable, bool transparency_enable, + bool dithering_enable) +{ + static constexpr DrawLineFunction funcs[2][2][2] = { + {{&GPU_SW_Backend::DrawLine, &GPU_SW_Backend::DrawLine}, + {&GPU_SW_Backend::DrawLine, &GPU_SW_Backend::DrawLine}}, + {{&GPU_SW_Backend::DrawLine, &GPU_SW_Backend::DrawLine}, + {&GPU_SW_Backend::DrawLine, &GPU_SW_Backend::DrawLine}}}; -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}}}}}; + return funcs[u8(shading_enable)][u8(transparency_enable)][u8(dithering_enable)]; +} -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 +GPU_SW_Backend::DrawRectangleFunction +GPU_SW_Backend::GetDrawRectangleFunction(bool texture_enable, bool raw_texture_enable, bool transparency_enable) +{ + static constexpr DrawRectangleFunction funcs[2][2][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}}}; + + return funcs[u8(texture_enable)][u8(raw_texture_enable)][u8(transparency_enable)]; +} + +GPU_SW_Backend::DrawTriangleFunction GPU_SW_Backend::GetDrawTriangleFunction(bool shading_enable, bool texture_enable, + bool raw_texture_enable, + bool transparency_enable, + bool dithering_enable) +{ + static constexpr DrawTriangleFunction funcs[2][2][2][2][2] = { + {{{{&GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {&GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + {{&GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {&GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}}, + {{{&GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {&GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + {{&GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {&GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}}}, + {{{{&GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {&GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + {{&GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {&GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}}, + {{{&GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {&GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}, + {{&GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}, + {&GPU_SW_Backend::DrawTriangle, + &GPU_SW_Backend::DrawTriangle}}}}}; + + return funcs[u8(shading_enable)][u8(texture_enable)][u8(raw_texture_enable)][u8(transparency_enable)] + [u8(dithering_enable)]; +} \ No newline at end of file diff --git a/src/core/gpu_sw_backend.h b/src/core/gpu_sw_backend.h index af93daabe..5a7be6ffe 100644 --- a/src/core/gpu_sw_backend.h +++ b/src/core/gpu_sw_backend.h @@ -98,13 +98,17 @@ 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 ////////////////////////////////////////////////////////////////////////// @@ -133,36 +137,31 @@ 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); - 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]; + std::array m_vram; };