From 425ff3d78fe979c0c328c33bd6a5db1951e885e7 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 16 May 2015 21:49:25 -0700 Subject: [PATCH] Track bone matrix updates for future morph usage. This makes them upload later, if/when they're needed. Fixes #7746, Shadow of Destiny artifacts when software skinning is enabled. --- GPU/GLES/GLES_GPU.cpp | 28 ++++++++++++++++++++++------ GPU/GPUState.h | 1 + 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/GPU/GLES/GLES_GPU.cpp b/GPU/GLES/GLES_GPU.cpp index e5a39ddba0..bef26c0b30 100644 --- a/GPU/GLES/GLES_GPU.cpp +++ b/GPU/GLES/GLES_GPU.cpp @@ -868,6 +868,12 @@ void GLES_GPU::Execute_VertexTypeSkinning(u32 op, u32 diff) { gstate.vertType ^= diff; if (diff & (GE_VTYPE_TC_MASK | GE_VTYPE_THROUGH_MASK)) shaderManager_->DirtyUniform(DIRTY_UVSCALEOFFSET); + // In this case, we may be doing weights and morphs. + // Update any bone matrix uniforms so it uses them correctly. + if ((op & GE_VTYPE_MORPHCOUNT_MASK) != 0) { + shaderManager_->DirtyUniform(gstate_c.deferredVertTypeDirty); + gstate_c.deferredVertTypeDirty = 0; + } } } @@ -1346,6 +1352,11 @@ void GLES_GPU::Execute_BoneMtxNum(u32 op, u32 diff) { break; } } + + const int numPlusCount = (op & 0x7F) + i; + for (int num = op & 0x7F; num < numPlusCount; num += 12) { + gstate_c.deferredVertTypeDirty |= DIRTY_BONEMATRIX0 << (num / 12); + } } const int count = i; @@ -1365,6 +1376,8 @@ void GLES_GPU::Execute_BoneMtxData(u32 op, u32 diff) { if (!g_Config.bSoftwareSkinning || (gstate.vertType & GE_VTYPE_MORPHCOUNT_MASK) != 0) { Flush(); shaderManager_->DirtyUniform(DIRTY_BONEMATRIX0 << (num / 12)); + } else { + gstate_c.deferredVertTypeDirty |= DIRTY_BONEMATRIX0 << (num / 12); } ((u32 *)gstate.boneMatrix)[num] = newVal; } @@ -1915,15 +1928,18 @@ void GLES_GPU::Execute_Generic(u32 op, u32 diff) { } void GLES_GPU::FastLoadBoneMatrix(u32 target) { + const int num = gstate.boneMatrixNumber & 0x7F; + const int mtxNum = num / 12; + uint32_t uniformsToDirty = DIRTY_BONEMATRIX0 << mtxNum; + if ((num - 12 * mtxNum) != 0) { + uniformsToDirty |= DIRTY_BONEMATRIX0 << ((mtxNum + 1) & 7); + } + if (!g_Config.bSoftwareSkinning || (gstate.vertType & GE_VTYPE_MORPHCOUNT_MASK) != 0) { Flush(); - const int num = gstate.boneMatrixNumber & 0x7F; - int mtxNum = num / 12; - uint32_t uniformsToDirty = DIRTY_BONEMATRIX0 << mtxNum; - if ((num - 12 * mtxNum) != 0) { - uniformsToDirty |= DIRTY_BONEMATRIX0 << ((mtxNum + 1) & 7); - } shaderManager_->DirtyUniform(uniformsToDirty); + } else { + gstate_c.deferredVertTypeDirty |= uniformsToDirty; } gstate.FastLoadBoneMatrix(target); } diff --git a/GPU/GPUState.h b/GPU/GPUState.h index 81c367c370..a23d4e615b 100644 --- a/GPU/GPUState.h +++ b/GPU/GPUState.h @@ -469,6 +469,7 @@ struct GPUStateCache bool allowShaderBlend; float morphWeights[8]; + u32 deferredVertTypeDirty; u32 curTextureWidth; u32 curTextureHeight;