From d5b4c98f96ab37da76f13d1214bccc9dc32a2874 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 16 Jul 2023 10:30:53 -0700 Subject: [PATCH 1/4] softgpu: Reduce some non-SIMD lighting math. Small perf improvement for vertex/lighting heavy (i.e. 3D) scenes. --- GPU/Math3D.h | 10 ++++++++++ GPU/Software/Lighting.cpp | 27 +++++++++++++++------------ 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/GPU/Math3D.h b/GPU/Math3D.h index ebf34f7823..16e8eb7629 100644 --- a/GPU/Math3D.h +++ b/GPU/Math3D.h @@ -1367,6 +1367,16 @@ inline Vec3 Vec3::operator + (const Vec3 &other) const { return Vec3(_mm_add_ps(SAFE_M128(vec), SAFE_M128(other.vec))); } +template<> +inline void Vec3::operator -= (const Vec3 &other) { + vec = _mm_sub_ps(SAFE_M128(vec), SAFE_M128(other.vec)); +} + +template<> +inline Vec3 Vec3::operator - (const Vec3 &other) const { + return Vec3(_mm_sub_ps(SAFE_M128(vec), SAFE_M128(other.vec))); +} + template<> inline Vec3 Vec3::operator * (const Vec3 &other) const { return Vec3(_mm_mul_ps(SAFE_M128(vec), SAFE_M128(other.vec))); diff --git a/GPU/Software/Lighting.cpp b/GPU/Software/Lighting.cpp index 3ba37a04dd..2f57638593 100644 --- a/GPU/Software/Lighting.cpp +++ b/GPU/Software/Lighting.cpp @@ -215,7 +215,7 @@ static inline __m128i LightColorScaleBy512SSE4(__m128i factor, __m128i color, __ __m128i result18 = _mm_madd_epi16(factor, color); // But now with 18 bits, we need a full multiply. __m128i multiplied = _mm_mullo_epi32(result18, scale); - return _mm_srai_epi32(multiplied, 19); + return _mm_srai_epi32(multiplied, 10 + 9); } #endif @@ -240,9 +240,9 @@ static Vec4 LightColorScaleBy512(const Vec4 &factor, const Vec4 & return LightColorScaleBy512SSE4(factor.ivec, color.ivec, _mm_set1_epi32(scale)); #elif PPSSPP_ARCH(ARM64_NEON) int32x4_t multiplied = vmulq_n_s32(vmulq_s32(factor.ivec, color.ivec), scale); - return vshrq_n_s32(multiplied, 19); + return vshrq_n_s32(multiplied, 10 + 19); #endif - return (factor * color * scale) / (1024 * 512); + return (factor * color * scale) >> (10 + 9); } static inline void LightColorSum(Vec4 &sum, const Vec4 &src) { @@ -296,25 +296,26 @@ static void ProcessSIMD(VertexData &vertex, const WorldCoords &worldpos, const W // L = vector from vertex to light source // TODO: Should transfer the light positions to world/view space for these calculations? Vec3 L = lstate.pos; - float att = 1.0f; + float attspot = 1.0f; if (!lstate.directional) { L -= worldpos; // TODO: Should this normalize (0, 0, 0) to (0, 0, 1)? float d = L.NormalizeOr001(); - att = 1.0f / Dot33(lstate.att, Vec3f(1.0f, d, d * d)); + float att = 1.0f / Dot33(lstate.att, Vec3f(1.0f, d, d * d)); if (!(att > 0.0f)) att = 0.0f; else if (att > 1.0f) att = 1.0f; + attspot = att; } - float spot = 1.0f; if (lstate.spot) { float rawSpot = Dot33(lstate.spotDir, L); if (std::isnan(rawSpot)) rawSpot = std::signbit(rawSpot) ? 0.0f : 1.0f; + float spot = 1.0f; if (rawSpot >= lstate.spotCutoff) { spot = pspLightPow(rawSpot, lstate.spotExp); if (std::isnan(spot)) @@ -322,14 +323,16 @@ static void ProcessSIMD(VertexData &vertex, const WorldCoords &worldpos, const W } else { spot = 0.0f; } + + attspot *= spot; } // ambient lighting if (lstate.ambient) { - int attspot = (int)LightCeil(256 * 2 * att * spot + 1); - if (attspot > 512) - attspot = 512; - Vec4 lambient = LightColorScaleBy512(lstate.ambientColorFactor, mac, attspot); + int attspot512 = (int)LightCeil(256 * 2 * attspot + 1); + if (attspot512 > 512) + attspot512 = 512; + Vec4 lambient = LightColorScaleBy512(lstate.ambientColorFactor, mac, attspot512); LightColorSum(final_color, lambient); } @@ -343,7 +346,7 @@ static void ProcessSIMD(VertexData &vertex, const WorldCoords &worldpos, const W } if (lstate.diffuse && diffuse_factor > 0.0f) { - int diffuse_attspot = (int)LightCeil(256 * 2 * att * spot * diffuse_factor + 1); + int diffuse_attspot = (int)LightCeil(256 * 2 * attspot * diffuse_factor + 1); if (diffuse_attspot > 512) diffuse_attspot = 512; Vec4 mdc = state.colorForDiffuse ? colorFactor : state.material.diffuseColorFactor; @@ -358,7 +361,7 @@ static void ProcessSIMD(VertexData &vertex, const WorldCoords &worldpos, const W specular_factor = pspLightPow(specular_factor, state.specularExp); if (specular_factor > 0.0f) { - int specular_attspot = (int)LightCeil(256 * 2 * att * spot * specular_factor + 1); + int specular_attspot = (int)LightCeil(256 * 2 * attspot * specular_factor + 1); if (specular_attspot > 512) specular_attspot = 512; From 47c29e0874943f6b0d8bf5a59644ba64a43dc675 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 16 Jul 2023 10:31:58 -0700 Subject: [PATCH 2/4] sopftgpu: Disable lights if all else disabled. Tiny gain, but seeing it happen so might as well. --- GPU/Software/Lighting.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/GPU/Software/Lighting.cpp b/GPU/Software/Lighting.cpp index 2f57638593..61599e4336 100644 --- a/GPU/Software/Lighting.cpp +++ b/GPU/Software/Lighting.cpp @@ -93,8 +93,6 @@ void ComputeState(State *state, bool hasColor0) { if (!lstate.enabled) continue; - lstate.spot = gstate.isSpotLight(light); - lstate.directional = gstate.isDirectionalLight(light); lstate.poweredDiffuse = gstate.isUsingPoweredDiffuseLight(light); lstate.specular = gstate.isUsingSpecularLight(light); @@ -112,7 +110,14 @@ void ComputeState(State *state, bool hasColor0) { anySpecular = anySpecular || lstate.specular; } + // Doesn't actually need to be on if nothing will affect it. + if (!lstate.specular && !lstate.ambient && !lstate.diffuse) { + lstate.enabled = false; + continue; + } + lstate.pos = GetLightVec(gstate.lpos, light); + lstate.directional = gstate.isDirectionalLight(light); if (lstate.directional) { lstate.pos.NormalizeOr001(); anyDirectional = true; @@ -120,6 +125,7 @@ void ComputeState(State *state, bool hasColor0) { lstate.att = GetLightVec(gstate.latt, light); } + lstate.spot = gstate.isSpotLight(light); if (lstate.spot) { lstate.spotDir = GetLightVec(gstate.ldir, light); lstate.spotDir.Normalize(); From 112d0adde9701176b94d793f0d4a5057114d9636 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 16 Jul 2023 10:47:43 -0700 Subject: [PATCH 3/4] Windows: Normalize rcheevos build settings. Gets rid of a LTCG restart warning, which in previous tests has not really helped us anyway. Better to keep projects consistent. --- ext/rcheevos-build/rcheevos.vcxproj | 67 ++++++++++++++++++++++++----- 1 file changed, 57 insertions(+), 10 deletions(-) diff --git a/ext/rcheevos-build/rcheevos.vcxproj b/ext/rcheevos-build/rcheevos.vcxproj index ac67e81de7..24a0a77d11 100644 --- a/ext/rcheevos-build/rcheevos.vcxproj +++ b/ext/rcheevos-build/rcheevos.vcxproj @@ -104,14 +104,14 @@ StaticLibrary false - true + false Unicode $(DefaultPlatformToolset) StaticLibrary false - true + false Unicode $(DefaultPlatformToolset) @@ -130,14 +130,14 @@ StaticLibrary false - true + false Unicode $(DefaultPlatformToolset) StaticLibrary false - true + false Unicode $(DefaultPlatformToolset) @@ -174,11 +174,15 @@ Level3 - true RC_DISABLE_LUA;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) true pch.h ../rcheevos/include + StreamingSIMDExtensions2 + Precise + Default + true + false MultiThreadedDebug @@ -190,11 +194,15 @@ Level3 - true RC_DISABLE_LUA;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) true pch.h ../rcheevos/include + false + NotSet + Precise + true + false MultiThreadedDebug @@ -206,13 +214,19 @@ Level3 + MaxSpeed true true - true RC_DISABLE_LUA;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) true pch.h ../rcheevos/include + StreamingSIMDExtensions2 + false + Precise + Speed + AnySuitable + true MultiThreaded @@ -226,13 +240,20 @@ Level3 + MaxSpeed true true - true RC_DISABLE_LUA;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) true pch.h ../rcheevos/include + false + AnySuitable + Speed + false + NotSet + Precise + true MultiThreaded @@ -251,6 +272,12 @@ true pch.h ../rcheevos/include + false + NotSet + Precise + Default + true + false MultiThreadedDebug @@ -267,6 +294,12 @@ true pch.h ../rcheevos/include + false + NotSet + Precise + Default + true + false MultiThreadedDebug @@ -278,13 +311,20 @@ Level3 + MaxSpeed true true - true RC_DISABLE_LUA;NDEBUG;_LIB;%(PreprocessorDefinitions) true pch.h ../rcheevos/include + false + AnySuitable + Speed + false + NotSet + Precise + true MultiThreaded @@ -298,13 +338,20 @@ Level3 + MaxSpeed true true - true RC_DISABLE_LUA;NDEBUG;_LIB;%(PreprocessorDefinitions) true pch.h ../rcheevos/include + false + AnySuitable + Speed + false + NotSet + Precise + true MultiThreaded From d6a5e84db57afbd5cb5a4114c6013935a1fee8ee Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 16 Jul 2023 10:59:44 -0700 Subject: [PATCH 4/4] softgpu: Fix worldpos skipping. Oops, was reversed. We need worldpos for non-directional lights. --- GPU/Software/Lighting.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/GPU/Software/Lighting.cpp b/GPU/Software/Lighting.cpp index 61599e4336..e4ea2ff6e7 100644 --- a/GPU/Software/Lighting.cpp +++ b/GPU/Software/Lighting.cpp @@ -86,7 +86,7 @@ void ComputeState(State *state, bool hasColor0) { bool anyAmbient = false; bool anyDiffuse = false; bool anySpecular = false; - bool anyDirectional = false; + bool anyNonDirectional = false; for (int light = 0; light < 4; ++light) { auto &lstate = state->lights[light]; lstate.enabled = gstate.isLightChanEnabled(light); @@ -120,9 +120,9 @@ void ComputeState(State *state, bool hasColor0) { lstate.directional = gstate.isDirectionalLight(light); if (lstate.directional) { lstate.pos.NormalizeOr001(); - anyDirectional = true; } else { lstate.att = GetLightVec(gstate.latt, light); + anyNonDirectional = true; } lstate.spot = gstate.isSpotLight(light); @@ -183,7 +183,7 @@ void ComputeState(State *state, bool hasColor0) { state->baseAmbientColorFactor = LightColorFactor(gstate.getAmbientRGBA(), ones); state->setColor1 = gstate.isUsingSecondaryColor() && anySpecular; state->addColor1 = !gstate.isUsingSecondaryColor() && anySpecular; - state->usesWorldPos = anyDirectional; + state->usesWorldPos = anyNonDirectional; state->usesWorldNormal = gstate.getUVGenMode() == GE_TEXMAP_ENVIRONMENT_MAP || anyDiffuse || anySpecular; }