GPU: Always skin in decode for software transform.

This commit is contained in:
Unknown W. Brackets 2022-11-06 08:55:07 -08:00
parent 7880eb15c1
commit 3de2557ecb
5 changed files with 24 additions and 67 deletions

View File

@ -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?");

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;