From 3de2557ecb50aba2ea59e61c4900918a5d99b725 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 6 Nov 2022 08:55:07 -0800 Subject: [PATCH] GPU: Always skin in decode for software transform. --- GPU/Common/SoftwareTransformCommon.cpp | 81 +++++--------------------- GPU/D3D11/DrawEngineD3D11.cpp | 2 + GPU/Directx9/DrawEngineDX9.cpp | 2 + GPU/GLES/DrawEngineGLES.cpp | 3 + GPU/Vulkan/DrawEngineVulkan.cpp | 3 + 5 files changed, 24 insertions(+), 67 deletions(-) diff --git a/GPU/Common/SoftwareTransformCommon.cpp b/GPU/Common/SoftwareTransformCommon.cpp index dc86e9ec13..67ba97af4c 100644 --- a/GPU/Common/SoftwareTransformCommon.cpp +++ b/GPU/Common/SoftwareTransformCommon.cpp @@ -168,29 +168,6 @@ void SoftwareTransform::SetProjMatrix(float mtx[14], bool invertedX, bool invert projMatrix_.translateAndScale(trans, scale); } -static void ReadWeightedNormal(Vec3f &source, VertexReader &reader, u32 vertType, bool skinningEnabled) { - if (reader.hasNormal()) - reader.ReadNrm(source.AsArray()); - if (skinningEnabled) { - float weights[8]; - reader.ReadWeights(weights); - - // Have to recalculate this, unfortunately. Please use software skinning... - Vec3f nsum(0, 0, 0); - for (int i = 0; i < vertTypeGetNumBoneWeights(vertType); i++) { - if (weights[i] != 0.0f) { - Vec3f norm; - Norm3ByMatrix43(norm.AsArray(), source.AsArray(), gstate.boneMatrix + i * 12); - nsum += norm * weights[i]; - } - } - - source = nsum; - } - if (gstate.areNormalsReversed()) - source = -source; -} - void SoftwareTransform::Decode(int prim, u32 vertType, const DecVtxFormat &decVtxFormat, int maxIndex, SoftwareTransformResult *result) { u8 *decoded = params_.decoded; TransformedVertex *transformed = params_.transformed; @@ -204,8 +181,6 @@ void SoftwareTransform::Decode(int prim, u32 vertType, const DecVtxFormat &decVt vscale /= gstate_c.curTextureHeight; } - bool skinningEnabled = vertTypeIsSkinningEnabled(vertType) && !g_Config.bSoftwareSkinning; - const int w = gstate.getTextureWidth(0); const int h = gstate.getTextureHeight(0); float widthFactor = (float) w / (float) gstate_c.curTextureWidth; @@ -296,47 +271,13 @@ void SoftwareTransform::Decode(int prim, u32 vertType, const DecVtxFormat &decVt if (reader.hasNormal()) reader.ReadNrm(normal.AsArray()); - if (!skinningEnabled) { - Vec3ByMatrix43(out, pos, gstate.worldMatrix); - if (reader.hasNormal()) { - if (gstate.areNormalsReversed()) { - normal = -normal; - } - Norm3ByMatrix43(worldnormal.AsArray(), normal.AsArray(), gstate.worldMatrix); - worldnormal = worldnormal.NormalizedOr001(cpu_info.bSSE4_1); - } - } else { - float weights[8]; - // For flat, we need the vertex weights. - reader.Goto(index); - reader.ReadWeights(weights); - - // Skinning - Vec3f psum(0, 0, 0); - Vec3f nsum(0, 0, 0); - for (int i = 0; i < vertTypeGetNumBoneWeights(vertType); i++) { - if (weights[i] != 0.0f) { - Vec3ByMatrix43(out, pos, gstate.boneMatrix+i*12); - Vec3f tpos(out); - psum += tpos * weights[i]; - if (reader.hasNormal()) { - Vec3f norm; - Norm3ByMatrix43(norm.AsArray(), normal.AsArray(), gstate.boneMatrix+i*12); - nsum += norm * weights[i]; - } - } - } - - // Yes, we really must multiply by the world matrix too. - Vec3ByMatrix43(out, psum.AsArray(), gstate.worldMatrix); - if (reader.hasNormal()) { - normal = nsum; - if (gstate.areNormalsReversed()) { - normal = -normal; - } - Norm3ByMatrix43(worldnormal.AsArray(), normal.AsArray(), gstate.worldMatrix); - worldnormal = worldnormal.NormalizedOr001(cpu_info.bSSE4_1); + Vec3ByMatrix43(out, pos, gstate.worldMatrix); + if (reader.hasNormal()) { + if (gstate.areNormalsReversed()) { + normal = -normal; } + Norm3ByMatrix43(worldnormal.AsArray(), normal.AsArray(), gstate.worldMatrix); + worldnormal = worldnormal.NormalizedOr001(cpu_info.bSSE4_1); } // Perform lighting here if enabled. @@ -398,7 +339,10 @@ void SoftwareTransform::Decode(int prim, u32 vertType, const DecVtxFormat &decVt source = normal.Normalized(cpu_info.bSSE4_1); } else { reader.Goto(index); - ReadWeightedNormal(source, reader, vertType, skinningEnabled); + if (reader.hasNormal()) + reader.ReadNrm(source.AsArray()); + if (gstate.areNormalsReversed()) + source = -source; source.Normalize(); } if (!reader.hasNormal()) { @@ -413,7 +357,10 @@ void SoftwareTransform::Decode(int prim, u32 vertType, const DecVtxFormat &decVt } else { // Need to read the normal for this vertex and weight it again.. reader.Goto(index); - ReadWeightedNormal(source, reader, vertType, skinningEnabled); + if (reader.hasNormal()) + reader.ReadNrm(source.AsArray()); + if (gstate.areNormalsReversed()) + source = -source; } if (!reader.hasNormal()) { ERROR_LOG_REPORT(G3D, "Normal projection mapping without normal?"); diff --git a/GPU/D3D11/DrawEngineD3D11.cpp b/GPU/D3D11/DrawEngineD3D11.cpp index 2a537a83a3..e0c33e5d76 100644 --- a/GPU/D3D11/DrawEngineD3D11.cpp +++ b/GPU/D3D11/DrawEngineD3D11.cpp @@ -581,6 +581,7 @@ rotateVBO: } } else { PROFILE_THIS_SCOPE("soft"); + decOptions_.applySkinInDecode = true; DecodeVerts(decoded); bool hasColor = (lastVType_ & GE_VTYPE_COL_MASK) != GE_VTYPE_COL_NONE; if (gstate.isModeThrough()) { @@ -709,6 +710,7 @@ rotateVBO: framebufferManager_->ApplyClearToMemory(scissorX1, scissorY1, scissorX2, scissorY2, clearColor); } } + decOptions_.applySkinInDecode = g_Config.bSoftwareSkinning; } gpuStats.numDrawCalls += numDrawCalls; diff --git a/GPU/Directx9/DrawEngineDX9.cpp b/GPU/Directx9/DrawEngineDX9.cpp index 40790c1648..33117be1c9 100644 --- a/GPU/Directx9/DrawEngineDX9.cpp +++ b/GPU/Directx9/DrawEngineDX9.cpp @@ -546,6 +546,7 @@ rotateVBO: } } } else { + decOptions_.applySkinInDecode = true; DecodeVerts(decoded); bool hasColor = (lastVType_ & GE_VTYPE_COL_MASK) != GE_VTYPE_COL_NONE; if (gstate.isModeThrough()) { @@ -653,6 +654,7 @@ rotateVBO: framebufferManager_->ApplyClearToMemory(scissorX1, scissorY1, scissorX2, scissorY2, clearColor); } } + decOptions_.applySkinInDecode = g_Config.bSoftwareSkinning; } gpuStats.numDrawCalls += numDrawCalls; diff --git a/GPU/GLES/DrawEngineGLES.cpp b/GPU/GLES/DrawEngineGLES.cpp index 318cb19a02..e95afe57ed 100644 --- a/GPU/GLES/DrawEngineGLES.cpp +++ b/GPU/GLES/DrawEngineGLES.cpp @@ -331,7 +331,9 @@ void DrawEngineGLES::DoFlush() { } } else { PROFILE_THIS_SCOPE("soft"); + decOptions_.applySkinInDecode = true; DecodeVerts(decoded); + bool hasColor = (lastVType_ & GE_VTYPE_COL_MASK) != GE_VTYPE_COL_NONE; if (gstate.isModeThrough()) { gstate_c.vertexFullAlpha = gstate_c.vertexFullAlpha && (hasColor || gstate.getMaterialAmbientA() == 255); @@ -446,6 +448,7 @@ void DrawEngineGLES::DoFlush() { } gstate_c.Dirty(DIRTY_BLEND_STATE); // Make sure the color mask gets re-applied. } + decOptions_.applySkinInDecode = g_Config.bSoftwareSkinning; } gpuStats.numDrawCalls += numDrawCalls; diff --git a/GPU/Vulkan/DrawEngineVulkan.cpp b/GPU/Vulkan/DrawEngineVulkan.cpp index 01c356f34d..d8c8b740e5 100644 --- a/GPU/Vulkan/DrawEngineVulkan.cpp +++ b/GPU/Vulkan/DrawEngineVulkan.cpp @@ -841,6 +841,7 @@ void DrawEngineVulkan::DoFlush() { } } else { PROFILE_THIS_SCOPE("soft"); + decOptions_.applySkinInDecode = true; DecodeVerts(decoded); bool hasColor = (lastVType_ & GE_VTYPE_COL_MASK) != GE_VTYPE_COL_NONE; if (gstate.isModeThrough()) { @@ -927,6 +928,7 @@ void DrawEngineVulkan::DoFlush() { decodedVerts_ = 0; numDrawCalls = 0; decodeCounter_ = 0; + decOptions_.applySkinInDecode = g_Config.bSoftwareSkinning; return; } BindShaderBlendTex(); // This might cause copies so super important to do before BindPipeline. @@ -994,6 +996,7 @@ void DrawEngineVulkan::DoFlush() { framebufferManager_->ApplyClearToMemory(scissorX1, scissorY1, scissorX2, scissorY2, result.color); } } + decOptions_.applySkinInDecode = g_Config.bSoftwareSkinning; } gpuStats.numDrawCalls += numDrawCalls;