From 8a6e8066bfe3ef2b961bdd2fc1174bc75e5df48d Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 11 Sep 2022 18:41:06 -0700 Subject: [PATCH] softgpu: Store vertex colors as packed RGBA8. No need to keep it expanded at 4x the space for both colors. --- GPU/Software/Lighting.cpp | 8 +++--- GPU/Software/Rasterizer.cpp | 42 ++++++++++++++++++---------- GPU/Software/RasterizerRectangle.cpp | 17 +++++------ GPU/Software/TransformUnit.cpp | 18 ++---------- GPU/Software/TransformUnit.h | 10 +++---- 5 files changed, 48 insertions(+), 47 deletions(-) diff --git a/GPU/Software/Lighting.cpp b/GPU/Software/Lighting.cpp index 262811318f..32596989fe 100644 --- a/GPU/Software/Lighting.cpp +++ b/GPU/Software/Lighting.cpp @@ -276,12 +276,12 @@ void Process(VertexData &vertex, const WorldCoords &worldpos, const WorldCoords } if (state.setColor1) { - vertex.color0 = final_color.Clamp(0, 255); - vertex.color1 = specular_color.Clamp(0, 255).rgb(); + vertex.color0 = final_color.Clamp(0, 255).ToRGBA(); + vertex.color1 = specular_color.Clamp(0, 255).rgb().ToRGB(); } else if (state.addColor1) { - vertex.color0 = (final_color + specular_color).Clamp(0, 255); + vertex.color0 = (final_color + specular_color).Clamp(0, 255).ToRGBA(); } else { - vertex.color0 = final_color.Clamp(0, 255); + vertex.color0 = final_color.Clamp(0, 255).ToRGBA(); } } diff --git a/GPU/Software/Rasterizer.cpp b/GPU/Software/Rasterizer.cpp index 0348f6d57a..a47ed9b0da 100644 --- a/GPU/Software/Rasterizer.cpp +++ b/GPU/Software/Rasterizer.cpp @@ -721,6 +721,13 @@ void DrawTriangleSlice( std::string ztag = StringFromFormat("DisplayListTZ_%08x", state.listPC); #endif + const Vec4 v0_c0 = Vec4::FromRGBA(v0.color0); + const Vec4 v1_c0 = Vec4::FromRGBA(v1.color0); + const Vec4 v2_c0 = Vec4::FromRGBA(v2.color0); + const Vec3 v0_c1 = Vec3::FromRGB(v0.color1); + const Vec3 v1_c1 = Vec3::FromRGB(v1.color1); + const Vec3 v2_c1 = Vec3::FromRGB(v2.color1); + for (int64_t curY = minY; curY <= maxY; curY += SCREEN_SCALE_FACTOR * 2, w0_base = e0.StepY(w0_base), w1_base = e1.StepY(w1_base), @@ -790,22 +797,22 @@ void DrawTriangleSlice( if (!flatColor0) { for (int i = 0; i < 4; ++i) { if (mask[i] >= 0) - prim_color[i] = Interpolate(v0.color0, v1.color0, v2.color0, w0[i], w1[i], w2[i], wsum_recip[i]); + prim_color[i] = Interpolate(v0_c0, v1_c0, v2_c0, w0[i], w1[i], w2[i], wsum_recip[i]); } } else { for (int i = 0; i < 4; ++i) { - prim_color[i] = v2.color0; + prim_color[i] = v2_c0; } } Vec3 sec_color[4]; if (!flatColor1) { for (int i = 0; i < 4; ++i) { if (mask[i] >= 0) - sec_color[i] = Interpolate(v0.color1, v1.color1, v2.color1, w0[i], w1[i], w2[i], wsum_recip[i]); + sec_color[i] = Interpolate(v0_c1, v1_c1, v2_c1, w0[i], w1[i], w2[i], wsum_recip[i]); } } else { for (int i = 0; i < 4; ++i) { - sec_color[i] = v2.color1; + sec_color[i] = v2_c1; } } @@ -965,9 +972,10 @@ void DrawRectangle(const VertexData &v0, const VertexData &v1, const BinCoords & const Vec4f tto4(0.0f, 0.5f * stx.t(), 0.5f * sty.t(), 0.5f * stx.t() + 0.5f * sty.t()); ScreenCoords pprime(minX, minY, 0); - Vec4 fog = Vec4::AssignToAll(ClampFogDepth(v1.fogdepth)); - Vec4 z = Vec4::AssignToAll(v1.screenpos.z); - Vec3 sec_color = v1.color1; + const Vec4 fog = Vec4::AssignToAll(ClampFogDepth(v1.fogdepth)); + const Vec4 z = Vec4::AssignToAll(v1.screenpos.z); + const Vec4 c0 = Vec4::FromRGBA(v1.color0); + const Vec3 sec_color = Vec3::FromRGB(v1.color1); if (state.pixelID.applyDepthRange) { // We can bail early since the Z is flat. @@ -997,7 +1005,7 @@ void DrawRectangle(const VertexData &v0, const VertexData &v1, const BinCoords & Vec4 prim_color[4]; for (int i = 0; i < 4; ++i) { - prim_color[i] = v1.color0; + prim_color[i] = c0; } if (state.pixelID.earlyZChecks) { @@ -1073,8 +1081,8 @@ void DrawRectangle(const VertexData &v0, const VertexData &v1, const BinCoords & void DrawPoint(const VertexData &v0, const BinCoords &range, const RasterizerState &state) { ScreenCoords pos = v0.screenpos; - Vec4 prim_color = v0.color0; - Vec3 sec_color = v0.color1; + Vec4 prim_color = Vec4::FromRGBA(v0.color0); + Vec3 sec_color = Vec3::FromRGB(v0.color1); auto &pixelID = state.pixelID; auto &samplerID = state.samplerID; @@ -1218,7 +1226,7 @@ void ClearRectangle(const VertexData &v0, const VertexData &v1, const BinCoords keepOldMask |= pixelID.cached.colorWriteMask; } - const u32 new_color = v1.color0.ToRGBA(); + const u32 new_color = v1.color0; u16 new_color16; switch (pixelID.FBFormat()) { case GE_FORMAT_565: @@ -1343,6 +1351,10 @@ void DrawLine(const VertexData &v0, const VertexData &v1, const BinCoords &range auto &samplerID = state.samplerID; const bool interpolateColor = !state.shadeGouraud || (v0.color0 == v1.color0 && v0.color1 == v1.color1); + const Vec4 v0_c0 = Vec4::FromRGBA(v0.color0); + const Vec4 v1_c0 = Vec4::FromRGBA(v1.color0); + const Vec3 v0_c1 = Vec3::FromRGB(v0.color1); + const Vec3 v1_c1 = Vec3::FromRGB(v1.color1); #if defined(SOFTGPU_MEMORY_TAGGING_DETAILED) || defined(SOFTGPU_MEMORY_TAGGING_BASIC) std::string tag = StringFromFormat("DisplayListL_%08x", state.listPC); @@ -1375,11 +1387,11 @@ void DrawLine(const VertexData &v0, const VertexData &v1, const BinCoords &range Vec4 prim_color; Vec3 sec_color; if (interpolateColor) { - prim_color = (v0.color0 * (steps - i) + v1.color0 * i) / steps1; - sec_color = (v0.color1 * (steps - i) + v1.color1 * i) / steps1; + prim_color = (v0_c0 * (steps - i) + v1_c0 * i) / steps1; + sec_color = (v0_c1 * (steps - i) + v1_c1 * i) / steps1; } else { - prim_color = v1.color0; - sec_color = v1.color1; + prim_color = v1_c0; + sec_color = v1_c1; } u8 fog = 255; diff --git a/GPU/Software/RasterizerRectangle.cpp b/GPU/Software/RasterizerRectangle.cpp index c94e23beb6..6d3d490ae4 100644 --- a/GPU/Software/RasterizerRectangle.cpp +++ b/GPU/Software/RasterizerRectangle.cpp @@ -119,7 +119,7 @@ void DrawSprite(const VertexData &v0, const VertexData &v1, const BinCoords &ran int z = v1.screenpos.z; int fog = 255; - bool isWhite = v1.color0 == Vec4(255, 255, 255, 255); + bool isWhite = v1.color0 == 0xFFFFFFFF; if (state.enableTextures) { // 1:1 (but with mirror support) texture mapping! @@ -176,11 +176,12 @@ void DrawSprite(const VertexData &v0, const VertexData &v1, const BinCoords &ran } } else { int t = t_start; + const Vec4 c0 = Vec4::FromRGBA(v1.color0); for (int y = pos0.y; y < pos1.y; y++) { int s = s_start; u16 *pixel = fb.Get16Ptr(pos0.x, y, pixelID.cached.framebufStride); for (int x = pos0.x; x < pos1.x; x++) { - Vec4 prim_color = v1.color0; + Vec4 prim_color = c0; Vec4 tex_color = fetchFunc(s, t, texptr, texbufw, 0, state.samplerID); prim_color = Vec4(ModulateRGBA(ToVec4IntArg(prim_color), ToVec4IntArg(tex_color), state.samplerID)); if (prim_color.a() > 0) { @@ -202,11 +203,12 @@ void DrawSprite(const VertexData &v0, const VertexData &v1, const BinCoords &ran float tf_start = t_start * (1.0f / (float)(1 << state.samplerID.height0Shift)); float t = tf_start; + const Vec4 c0 = Vec4::FromRGBA(v1.color0); for (int y = pos0.y; y < pos1.y; y++) { float s = sf_start; // Not really that fast but faster than triangle. for (int x = pos0.x; x < pos1.x; x++) { - Vec4 prim_color = state.nearest(s, t, xoff, yoff, ToVec4IntArg(v1.color0), &texptr, &texbufw, 0, 0, state.samplerID); + Vec4 prim_color = state.nearest(s, t, xoff, yoff, ToVec4IntArg(c0), &texptr, &texbufw, 0, 0, state.samplerID); state.drawPixel(x, y, z, 255, ToVec4IntArg(prim_color), pixelID); s += dsf; } @@ -227,21 +229,20 @@ void DrawSprite(const VertexData &v0, const VertexData &v1, const BinCoords &ran AlphaTestIsNeedless(pixelID) && !pixelID.applyColorWriteMask && pixelID.FBFormat() == GE_FORMAT_5551) { - if (v1.color0.a() == 0) + if (Vec4::FromRGBA(v1.color0).a() == 0) return; for (int y = pos0.y; y < pos1.y; y++) { u16 *pixel = fb.Get16Ptr(pos0.x, y, pixelID.cached.framebufStride); for (int x = pos0.x; x < pos1.x; x++) { - Vec4 prim_color = v1.color0; - DrawSinglePixel5551(pixel, prim_color.ToRGBA(), pixelID); + DrawSinglePixel5551(pixel, v1.color0, pixelID); pixel++; } } } else { + const Vec4 prim_color = Vec4::FromRGBA(v1.color0); for (int y = pos0.y; y < pos1.y; y++) { for (int x = pos0.x; x < pos1.x; x++) { - Vec4 prim_color = v1.color0; state.drawPixel(x, y, z, fog, ToVec4IntArg(prim_color), pixelID); } } @@ -311,7 +312,7 @@ bool RectangleFastPath(const VertexData &v0, const VertexData &v1, BinManager &b // Afterwards, we also need to clear the actual destination. Can do a fast rectfill. gstate.textureMapEnable &= ~1; VertexData newV1 = v1; - newV1.color0 = Vec4(0, 0, 0, 255); + newV1.color0 = 0xFF000000; binner.AddSprite(v0, newV1); gstate.textureMapEnable |= 1; } diff --git a/GPU/Software/TransformUnit.cpp b/GPU/Software/TransformUnit.cpp index 28a91a7a8c..2c9a96221d 100644 --- a/GPU/Software/TransformUnit.cpp +++ b/GPU/Software/TransformUnit.cpp @@ -317,24 +317,12 @@ VertexData TransformUnit::ReadVertex(VertexReader &vreader, const TransformState } if (vreader.hasColor0()) { -#ifdef _M_SSE - vreader.ReadColor0_8888((u8 *)vertex.color0.AsArray()); - vertex.color0.ivec = _mm_unpacklo_epi8(vertex.color0.ivec, _mm_setzero_si128()); - vertex.color0.ivec = _mm_unpacklo_epi16(vertex.color0.ivec, _mm_setzero_si128()); -#else - float col[4]; - vreader.ReadColor0(col); - vertex.color0 = Vec4(col[0]*255, col[1]*255, col[2]*255, col[3]*255); -#endif + vreader.ReadColor0_8888((u8 *)&vertex.color0); } else { - vertex.color0 = Vec4::FromRGBA(gstate.getMaterialAmbientRGBA()); + vertex.color0 = gstate.getMaterialAmbientRGBA(); } -#ifdef _M_SSE - vertex.color1 = _mm_setzero_si128(); -#else - vertex.color1 = Vec3(0, 0, 0); -#endif + vertex.color1 = 0; if (state.enableTransform) { WorldCoords worldpos; diff --git a/GPU/Software/TransformUnit.h b/GPU/Software/TransformUnit.h index faa761639c..283273b2c2 100644 --- a/GPU/Software/TransformUnit.h +++ b/GPU/Software/TransformUnit.h @@ -79,15 +79,15 @@ struct VertexData { texturecoords = ::Lerp(a.texturecoords, b.texturecoords, t); fogdepth = ::Lerp(a.fogdepth, b.fogdepth, t); - u16 t_int = (u16)(t*256); - color0 = LerpInt,256>(a.color0, b.color0, t_int); - color1 = LerpInt,256>(a.color1, b.color1, t_int); + u16 t_int = (u16)(t * 256); + color0 = LerpInt, 256>(Vec4::FromRGBA(a.color0), Vec4::FromRGBA(b.color0), t_int).ToRGBA(); + color1 = LerpInt, 256>(Vec3::FromRGB(a.color1), Vec3::FromRGB(b.color1), t_int).ToRGB(); } ClipCoords clippos; Vec2 texturecoords; - Vec4 color0; - Vec3 color1; + uint32_t color0; + uint32_t color1; ScreenCoords screenpos; // TODO: Shouldn't store this ? float fogdepth; };