From d6a8cb2a0ed72ee82247d0b66d58c38024db07f4 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Fri, 14 Jan 2022 20:26:05 -0800 Subject: [PATCH] softgpu: Stop storing normal/worldnormal/worldpos. This is only needed for lighting, which is applied right away. This improves perf just simply from less data being copied. --- GPU/Software/Lighting.cpp | 18 +++++++++--------- GPU/Software/Lighting.h | 4 ++-- GPU/Software/TransformUnit.cpp | 28 +++++++++++++++------------- GPU/Software/TransformUnit.h | 12 ++---------- 4 files changed, 28 insertions(+), 34 deletions(-) diff --git a/GPU/Software/Lighting.cpp b/GPU/Software/Lighting.cpp index 67e21b4028..3b1a078768 100644 --- a/GPU/Software/Lighting.cpp +++ b/GPU/Software/Lighting.cpp @@ -44,23 +44,23 @@ static inline float pspLightPow(float v, float e) { return v; } -static inline float GenerateLightCoord(VertexData &vertex, int light) { +static inline float GenerateLightCoord(VertexData &vertex, const WorldCoords &worldnormal, int light) { // TODO: Should specular lighting should affect this, too? Doesn't in GLES. Vec3 L = GetLightVec(gstate.lpos, light); // In other words, L.Length2() == 0.0f means Dot({0, 0, 1}, worldnormal). - float diffuse_factor = Dot(L.NormalizedOr001(cpu_info.bSSE4_1), vertex.worldnormal); + float diffuse_factor = Dot(L.NormalizedOr001(cpu_info.bSSE4_1), worldnormal); return (diffuse_factor + 1.0f) / 2.0f; } -void GenerateLightST(VertexData &vertex) { +void GenerateLightST(VertexData &vertex, const WorldCoords &worldnormal) { // Always calculate texture coords from lighting results if environment mapping is active // This should be done even if lighting is disabled altogether. - vertex.texturecoords.s() = GenerateLightCoord(vertex, gstate.getUVLS0()); - vertex.texturecoords.t() = GenerateLightCoord(vertex, gstate.getUVLS1()); + vertex.texturecoords.s() = GenerateLightCoord(vertex, worldnormal, gstate.getUVLS0()); + vertex.texturecoords.t() = GenerateLightCoord(vertex, worldnormal, gstate.getUVLS1()); } -void Process(VertexData& vertex, bool hasColor) { +void Process(VertexData& vertex, const WorldCoords &worldpos, const WorldCoords &worldnormal, bool hasColor) { const int materialupdate = gstate.materialupdate & (hasColor ? 7 : 0); Vec4 mec = Vec4::FromRGBA(gstate.getMaterialEmissive()); @@ -82,7 +82,7 @@ void Process(VertexData& vertex, bool hasColor) { // TODO: Should transfer the light positions to world/view space for these calculations? Vec3 L = GetLightVec(gstate.lpos, light); if (!gstate.isDirectionalLight(light)) { - L -= vertex.worldpos; + L -= worldpos; } // TODO: Should this normalize (0, 0, 0) to (0, 0, 1)? float d = L.NormalizeOr001(); @@ -124,7 +124,7 @@ void Process(VertexData& vertex, bool hasColor) { final_color += lambient; // diffuse lighting - float diffuse_factor = Dot(L, vertex.worldnormal); + float diffuse_factor = Dot(L, worldnormal); if (gstate.isUsingPoweredDiffuseLight(light)) { float k = gstate.getMaterialSpecularCoef(); diffuse_factor = pspLightPow(diffuse_factor, k); @@ -143,7 +143,7 @@ void Process(VertexData& vertex, bool hasColor) { if (gstate.isUsingSpecularLight(light) && diffuse_factor >= 0.0f) { Vec3 H = L + Vec3(0.f, 0.f, 1.f); - float specular_factor = Dot(H.NormalizedOr001(cpu_info.bSSE4_1), vertex.worldnormal); + float specular_factor = Dot(H.NormalizedOr001(cpu_info.bSSE4_1), worldnormal); float k = gstate.getMaterialSpecularCoef(); specular_factor = pspLightPow(specular_factor, k); diff --git a/GPU/Software/Lighting.h b/GPU/Software/Lighting.h index e5915e6aac..483133b313 100644 --- a/GPU/Software/Lighting.h +++ b/GPU/Software/Lighting.h @@ -21,7 +21,7 @@ namespace Lighting { -void GenerateLightST(VertexData &vertex); -void Process(VertexData& vertex, bool hasColor); +void GenerateLightST(VertexData &vertex, const WorldCoords &worldnormal); +void Process(VertexData &vertex, const WorldCoords &worldpos, const WorldCoords &worldnormal, bool hasColor); } diff --git a/GPU/Software/TransformUnit.cpp b/GPU/Software/TransformUnit.cpp index f018446ede..aba57d7ebb 100644 --- a/GPU/Software/TransformUnit.cpp +++ b/GPU/Software/TransformUnit.cpp @@ -164,11 +164,12 @@ VertexData TransformUnit::ReadVertex(VertexReader &vreader, bool &outside_range_ vreader.ReadUV(vertex.texturecoords.AsArray()); } + Vec3 normal; if (vreader.hasNormal()) { - vreader.ReadNrm(vertex.normal.AsArray()); + vreader.ReadNrm(normal.AsArray()); if (gstate.areNormalsReversed()) - vertex.normal = -vertex.normal; + normal = -normal; } if (vertTypeIsSkinningEnabled(gstate.vertType) && !gstate.isModeThrough()) { @@ -182,14 +183,14 @@ VertexData TransformUnit::ReadVertex(VertexReader &vreader, bool &outside_range_ Vec3 step = Vec3ByMatrix43(pos, gstate.boneMatrix + i * 12); tmppos += step * W[i]; if (vreader.hasNormal()) { - step = Norm3ByMatrix43(vertex.normal, gstate.boneMatrix + i * 12); + step = Norm3ByMatrix43(normal, gstate.boneMatrix + i * 12); tmpnrm += step * W[i]; } } pos = tmppos; if (vreader.hasNormal()) - vertex.normal = tmpnrm; + normal = tmpnrm; } if (vreader.hasColor0()) { @@ -210,8 +211,8 @@ VertexData TransformUnit::ReadVertex(VertexReader &vreader, bool &outside_range_ if (!gstate.isModeThrough()) { vertex.modelpos = pos; - vertex.worldpos = WorldCoords(TransformUnit::ModelToWorld(vertex.modelpos)); - ModelCoords viewpos = TransformUnit::WorldToView(vertex.worldpos); + WorldCoords worldpos = WorldCoords(TransformUnit::ModelToWorld(vertex.modelpos)); + ModelCoords viewpos = TransformUnit::WorldToView(worldpos); vertex.clippos = ClipCoords(TransformUnit::ViewToClip(viewpos)); if (gstate.isFogEnabled()) { float fog_end = getFloat24(gstate.fog1); @@ -230,11 +231,12 @@ VertexData TransformUnit::ReadVertex(VertexReader &vreader, bool &outside_range_ } vertex.screenpos = ClipToScreenInternal(vertex.clippos, &outside_range_flag); + Vec3 worldnormal; if (vreader.hasNormal()) { - vertex.worldnormal = TransformUnit::ModelToWorldNormal(vertex.normal); - vertex.worldnormal.NormalizeOr001(); + worldnormal = TransformUnit::ModelToWorldNormal(normal); + worldnormal.NormalizeOr001(); } else { - vertex.worldnormal = Vec3(0.0f, 0.0f, 1.0f); + worldnormal = Vec3(0.0f, 0.0f, 1.0f); } // Time to generate some texture coords. Lighting will handle shade mapping. @@ -250,11 +252,11 @@ VertexData TransformUnit::ReadVertex(VertexReader &vreader, bool &outside_range_ break; case GE_PROJMAP_NORMALIZED_NORMAL: - source = vertex.normal.NormalizedOr001(cpu_info.bSSE4_1); + source = normal.NormalizedOr001(cpu_info.bSSE4_1); break; case GE_PROJMAP_NORMAL: - source = vertex.normal; + source = normal; break; default: @@ -268,12 +270,12 @@ VertexData TransformUnit::ReadVertex(VertexReader &vreader, bool &outside_range_ float z_recip = 1.0f / stq.z; vertex.texturecoords = Vec2f(stq.x * z_recip, stq.y * z_recip); } else if (gstate.getUVGenMode() == GE_TEXMAP_ENVIRONMENT_MAP) { - Lighting::GenerateLightST(vertex); + Lighting::GenerateLightST(vertex, worldnormal); } PROFILE_THIS_SCOPE("light"); if (gstate.isLightingEnabled()) - Lighting::Process(vertex, vreader.hasColor0()); + Lighting::Process(vertex, worldpos, worldnormal, vreader.hasColor0()); } else { vertex.screenpos.x = (int)(pos[0] * 16) + gstate.getOffsetX16(); vertex.screenpos.y = (int)(pos[1] * 16) + gstate.getOffsetY16(); diff --git a/GPU/Software/TransformUnit.h b/GPU/Software/TransformUnit.h index 0726ec25f0..b78967cf56 100644 --- a/GPU/Software/TransformUnit.h +++ b/GPU/Software/TransformUnit.h @@ -82,17 +82,12 @@ struct DrawingCoords } }; -struct VertexData -{ - void Lerp(float t, const VertexData& a, const VertexData& b) - { - // World coords only needed for lighting, so we don't Lerp those - +struct VertexData { + void Lerp(float t, const VertexData &a, const VertexData &b) { modelpos = ::Lerp(a.modelpos, b.modelpos, t); clippos = ::Lerp(a.clippos, b.clippos, t); screenpos = ::Lerp(a.screenpos, b.screenpos, t); // TODO: Should use a LerpInt (?) texturecoords = ::Lerp(a.texturecoords, b.texturecoords, t); - normal = ::Lerp(a.normal, b.normal, t); fogdepth = ::Lerp(a.fogdepth, b.fogdepth, t); u16 t_int = (u16)(t*256); @@ -101,12 +96,9 @@ struct VertexData } ModelCoords modelpos; - WorldCoords worldpos; // TODO: Storing this is dumb, should transform the light to clip space instead ClipCoords clippos; ScreenCoords screenpos; // TODO: Shouldn't store this ? Vec2 texturecoords; - Vec3 normal; - WorldCoords worldnormal; Vec4 color0; Vec3 color1; float fogdepth;