diff --git a/Core/Config.cpp b/Core/Config.cpp index 4b75a46c54..6a209ea96d 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -879,7 +879,6 @@ static ConfigSetting graphicsSettings[] = { ConfigSetting("SoftwareRenderer", &g_Config.bSoftwareRendering, false, true, true), ConfigSetting("SoftwareRendererJit", &g_Config.bSoftwareRenderingJit, true, true, true), ReportedConfigSetting("HardwareTransform", &g_Config.bHardwareTransform, true, true, true), - ReportedConfigSetting("SoftwareSkinning", &g_Config.bSoftwareSkinning, true, true, true), ReportedConfigSetting("TextureFiltering", &g_Config.iTexFiltering, 1, true, true), ReportedConfigSetting("BufferFiltering", &g_Config.iBufFilter, SCALE_LINEAR, true, true), ReportedConfigSetting("InternalResolution", &g_Config.iInternalResolution, &DefaultInternalResolution, true, true), diff --git a/Core/Config.h b/Core/Config.h index af20f6289e..510f0a86d8 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -162,7 +162,6 @@ public: bool bSoftwareRendering; bool bSoftwareRenderingJit; bool bHardwareTransform; // only used in the GLES backend - bool bSoftwareSkinning; bool bVendorBugChecksEnabled; bool bUseGeometryShader; diff --git a/GPU/Common/DrawEngineCommon.cpp b/GPU/Common/DrawEngineCommon.cpp index 664b90823e..11092286a0 100644 --- a/GPU/Common/DrawEngineCommon.cpp +++ b/GPU/Common/DrawEngineCommon.cpp @@ -180,11 +180,10 @@ void DrawEngineCommon::NotifyConfigChanged() { useHWTransform_ = g_Config.bHardwareTransform; useHWTessellation_ = UpdateUseHWTessellation(g_Config.bHardwareTessellation); - decOptions_.applySkinInDecode = g_Config.bSoftwareSkinning; } u32 DrawEngineCommon::NormalizeVertices(u8 *outPtr, u8 *bufPtr, const u8 *inPtr, int lowerBound, int upperBound, u32 vertType, int *vertexSize) { - const u32 vertTypeID = GetVertTypeID(vertType, gstate.getUVGenMode(), decOptions_.applySkinInDecode); + const u32 vertTypeID = GetVertTypeID(vertType, gstate.getUVGenMode(), true); VertexDecoder *dec = GetVertexDecoder(vertTypeID); if (vertexSize) *vertexSize = dec->VertexSize(); @@ -232,7 +231,7 @@ void DrawEngineCommon::DispatchSubmitImm(GEPrimitiveType prim, TransformedVertex } int bytesRead; - uint32_t vertTypeID = GetVertTypeID(vtype, 0, decOptions_.applySkinInDecode); + uint32_t vertTypeID = GetVertTypeID(vtype, 0, true); SubmitPrim(&temp[0], nullptr, prim, vertexCount, vertTypeID, cullMode, &bytesRead); DispatchFlush(); @@ -281,10 +280,7 @@ bool DrawEngineCommon::TestBoundingBox(const void *control_points, const void *i } // Force software skinning. - bool wasApplyingSkinInDecode = decOptions_.applySkinInDecode; - decOptions_.applySkinInDecode = true; NormalizeVertices((u8 *)corners, temp_buffer, (const u8 *)control_points, indexLowerBound, indexUpperBound, vertType); - decOptions_.applySkinInDecode = wasApplyingSkinInDecode; IndexConverter conv(vertType, inds); for (int i = 0; i < vertexCount; i++) { @@ -499,8 +495,7 @@ u32 DrawEngineCommon::NormalizeVertices(u8 *outPtr, u8 *bufPtr, const u8 *inPtr, // implementation of the vertex decoder. dec->DecodeVerts(bufPtr, inPtr, lowerBound, upperBound); - // OK, morphing eliminated but bones still remain to be taken care of. - // Let's do a partial software transform where we only do skinning. + // Morph and skin are both removed during decode now. VertexReader reader(bufPtr, dec->GetDecVtxFmt(), vertType); @@ -513,80 +508,29 @@ u32 DrawEngineCommon::NormalizeVertices(u8 *outPtr, u8 *bufPtr, const u8 *inPtr, (u8)gstate.getMaterialAmbientA(), }; - // Let's have two separate loops, one for non skinning and one for skinning. - if (!dec->skinInDecode && (vertType & GE_VTYPE_WEIGHT_MASK) != GE_VTYPE_WEIGHT_NONE) { - int numBoneWeights = vertTypeGetNumBoneWeights(vertType); - for (int i = lowerBound; i <= upperBound; i++) { - reader.Goto(i - lowerBound); - SimpleVertex &sv = sverts[i]; - if (vertType & GE_VTYPE_TC_MASK) { - reader.ReadUV(sv.uv); - } - - if (vertType & GE_VTYPE_COL_MASK) { - reader.ReadColor0_8888(sv.color); - } else { - memcpy(sv.color, defaultColor, 4); - } - - float nrm[3], pos[3]; - float bnrm[3], bpos[3]; - - if (vertType & GE_VTYPE_NRM_MASK) { - // Normals are generated during tessellation anyway, not sure if any need to supply - reader.ReadNrm(nrm); - } else { - nrm[0] = 0; - nrm[1] = 0; - nrm[2] = 1.0f; - } - reader.ReadPos(pos); - - // Apply skinning transform directly - float weights[8]; - reader.ReadWeights(weights); - // Skinning - Vec3Packedf psum(0, 0, 0); - Vec3Packedf nsum(0, 0, 0); - for (int w = 0; w < numBoneWeights; w++) { - if (weights[w] != 0.0f) { - Vec3ByMatrix43(bpos, pos, gstate.boneMatrix + w * 12); - Vec3Packedf tpos(bpos); - psum += tpos * weights[w]; - - Norm3ByMatrix43(bnrm, nrm, gstate.boneMatrix + w * 12); - Vec3Packedf tnorm(bnrm); - nsum += tnorm * weights[w]; - } - } - sv.pos = psum; - sv.nrm = nsum; + for (int i = lowerBound; i <= upperBound; i++) { + reader.Goto(i - lowerBound); + SimpleVertex &sv = sverts[i]; + if (vertType & GE_VTYPE_TC_MASK) { + reader.ReadUV(sv.uv); + } else { + sv.uv[0] = 0.0f; // This will get filled in during tessellation + sv.uv[1] = 0.0f; } - } else { - for (int i = lowerBound; i <= upperBound; i++) { - reader.Goto(i - lowerBound); - SimpleVertex &sv = sverts[i]; - if (vertType & GE_VTYPE_TC_MASK) { - reader.ReadUV(sv.uv); - } else { - sv.uv[0] = 0.0f; // This will get filled in during tessellation - sv.uv[1] = 0.0f; - } - if (vertType & GE_VTYPE_COL_MASK) { - reader.ReadColor0_8888(sv.color); - } else { - memcpy(sv.color, defaultColor, 4); - } - if (vertType & GE_VTYPE_NRM_MASK) { - // Normals are generated during tessellation anyway, not sure if any need to supply - reader.ReadNrm((float *)&sv.nrm); - } else { - sv.nrm.x = 0.0f; - sv.nrm.y = 0.0f; - sv.nrm.z = 1.0f; - } - reader.ReadPos((float *)&sv.pos); + if (vertType & GE_VTYPE_COL_MASK) { + reader.ReadColor0_8888(sv.color); + } else { + memcpy(sv.color, defaultColor, 4); } + if (vertType & GE_VTYPE_NRM_MASK) { + // Normals are generated during tessellation anyway, not sure if any need to supply + reader.ReadNrm((float *)&sv.nrm); + } else { + sv.nrm.x = 0.0f; + sv.nrm.y = 0.0f; + sv.nrm.z = 1.0f; + } + reader.ReadPos((float *)&sv.pos); } // Okay, there we are! Return the new type (but keep the index bits) @@ -836,7 +780,7 @@ void DrawEngineCommon::SubmitPrim(const void *verts, const void *inds, GEPrimiti numDrawCalls++; vertexCountInDrawCalls_ += vertexCount; - if (decOptions_.applySkinInDecode && (vertTypeID & GE_VTYPE_WEIGHT_MASK)) { + if (vertTypeID & GE_VTYPE_WEIGHT_MASK) { DecodeVertsStep(decoded, decodeCounter_, decodedVerts_); decodeCounter_++; } diff --git a/GPU/Common/ShaderId.cpp b/GPU/Common/ShaderId.cpp index 0f034c7709..8ecced2853 100644 --- a/GPU/Common/ShaderId.cpp +++ b/GPU/Common/ShaderId.cpp @@ -118,7 +118,7 @@ void ComputeVertexShaderID(VShaderID *id_out, u32 vertType, bool useHWTransform, } // Bones. - bool enableBones = !useSkinInDecode && vertTypeIsSkinningEnabled(vertType); + bool enableBones = false; id.SetBit(VS_BIT_ENABLE_BONES, enableBones); if (enableBones) { id.SetBits(VS_BIT_BONES, 3, TranslateNumBones(vertTypeGetNumBoneWeights(vertType)) - 1); diff --git a/GPU/Common/SplineCommon.cpp b/GPU/Common/SplineCommon.cpp index 6fe6436291..5589fa8009 100644 --- a/GPU/Common/SplineCommon.cpp +++ b/GPU/Common/SplineCommon.cpp @@ -507,7 +507,7 @@ void DrawEngineCommon::SubmitCurve(const void *control_points, const void *indic if (indices) GetIndexBounds(indices, num_points, vertType, &index_lower_bound, &index_upper_bound); - VertexDecoder *origVDecoder = GetVertexDecoder(GetVertTypeID(vertType, gstate.getUVGenMode(), decOptions_.applySkinInDecode)); + VertexDecoder *origVDecoder = GetVertexDecoder(GetVertTypeID(vertType, gstate.getUVGenMode(), true)); *bytesRead = num_points * origVDecoder->VertexSize(); // Simplify away bones and morph before proceeding @@ -572,7 +572,7 @@ void DrawEngineCommon::SubmitCurve(const void *control_points, const void *indic gstate_c.uv.vOff = 0; } - uint32_t vertTypeID = GetVertTypeID(vertTypeWithIndex16, gstate.getUVGenMode(), decOptions_.applySkinInDecode); + uint32_t vertTypeID = GetVertTypeID(vertTypeWithIndex16, gstate.getUVGenMode(), true); int generatedBytesRead; if (output.count) DispatchSubmitPrim(output.vertices, output.indices, PatchPrimToPrim(surface.primType), output.count, vertTypeID, gstate.getCullMode(), &generatedBytesRead); diff --git a/GPU/Common/VertexDecoderCommon.cpp b/GPU/Common/VertexDecoderCommon.cpp index 3a77375cba..be5eb82515 100644 --- a/GPU/Common/VertexDecoderCommon.cpp +++ b/GPU/Common/VertexDecoderCommon.cpp @@ -1089,7 +1089,7 @@ void VertexDecoder::SetVertexType(u32 fmt, const VertexDecoderOptions &options, DEBUG_LOG(G3D, "VTYPE: THRU=%i TC=%i COL=%i POS=%i NRM=%i WT=%i NW=%i IDX=%i MC=%i", (int)throughmode, tc, col, pos, nrm, weighttype, nweights, idx, morphcount); } - skinInDecode = weighttype != 0 && options.applySkinInDecode; + skinInDecode = weighttype != 0; if (weighttype) { // && nweights? weightoff = size; @@ -1098,43 +1098,11 @@ void VertexDecoder::SetVertexType(u32 fmt, const VertexDecoderOptions &options, if (wtalign[weighttype] > biggest) biggest = wtalign[weighttype]; - if (skinInDecode) { - // No visible output, computes a matrix that is passed through the skinMatrix variable - // to the "nrm" and "pos" steps. - // Technically we should support morphing the weights too, but I have a hard time - // imagining that any game would use that.. but you never know. - steps_[numSteps_++] = wtstep_skin[weighttype]; - } else { - int fmtBase = DEC_FLOAT_1; - if (options.expandAllWeightsToFloat) { - steps_[numSteps_++] = wtstepToFloat[weighttype]; - fmtBase = DEC_FLOAT_1; - } else { - steps_[numSteps_++] = wtstep[weighttype]; - if (weighttype == GE_VTYPE_WEIGHT_8BIT >> GE_VTYPE_WEIGHT_SHIFT) { - fmtBase = DEC_U8_1; - } else if (weighttype == GE_VTYPE_WEIGHT_16BIT >> GE_VTYPE_WEIGHT_SHIFT) { - fmtBase = DEC_U16_1; - } else if (weighttype == GE_VTYPE_WEIGHT_FLOAT >> GE_VTYPE_WEIGHT_SHIFT) { - fmtBase = DEC_FLOAT_1; - } - } - - int numWeights = TranslateNumBones(nweights); - - if (numWeights <= 4) { - decFmt.w0off = decOff; - decFmt.w0fmt = fmtBase + numWeights - 1; - decOff += DecFmtSize(decFmt.w0fmt); - } else { - decFmt.w0off = decOff; - decFmt.w0fmt = fmtBase + 3; - decOff += DecFmtSize(decFmt.w0fmt); - decFmt.w1off = decOff; - decFmt.w1fmt = fmtBase + numWeights - 5; - decOff += DecFmtSize(decFmt.w1fmt); - } - } + // No visible output, computes a matrix that is passed through the skinMatrix variable + // to the "nrm" and "pos" steps. + // Technically we should support morphing the weights too, but I have a hard time + // imagining that any game would use that.. but you never know. + steps_[numSteps_++] = wtstep_skin[weighttype]; } if (tc) { diff --git a/GPU/Common/VertexDecoderCommon.h b/GPU/Common/VertexDecoderCommon.h index 7c2dcb2cfc..e93601e9ac 100644 --- a/GPU/Common/VertexDecoderCommon.h +++ b/GPU/Common/VertexDecoderCommon.h @@ -333,7 +333,6 @@ typedef void(*JittedVertexDecoder)(const u8 *src, u8 *dst, int count); struct VertexDecoderOptions { bool expandAllWeightsToFloat; bool expand8BitNormalsToFloat; - bool applySkinInDecode; }; class VertexDecoder { diff --git a/GPU/D3D11/DrawEngineD3D11.cpp b/GPU/D3D11/DrawEngineD3D11.cpp index e0c33e5d76..4b40bb5161 100644 --- a/GPU/D3D11/DrawEngineD3D11.cpp +++ b/GPU/D3D11/DrawEngineD3D11.cpp @@ -364,8 +364,8 @@ void DrawEngineD3D11::DoFlush() { // Cannot cache vertex data with morph enabled. bool useCache = g_Config.bVertexCache && !(lastVType_ & GE_VTYPE_MORPHCOUNT_MASK); - // Also avoid caching when software skinning. - if (decOptions_.applySkinInDecode && (lastVType_ & GE_VTYPE_WEIGHT_MASK)) + // Also avoid caching when skinning. + if (lastVType_ & GE_VTYPE_WEIGHT_MASK) useCache = false; if (useCache) { @@ -538,7 +538,7 @@ rotateVBO: D3D11VertexShader *vshader; D3D11FragmentShader *fshader; - shaderManager_->GetShaders(prim, lastVType_, &vshader, &fshader, pipelineState_, useHWTransform, useHWTessellation_, decOptions_.expandAllWeightsToFloat, decOptions_.applySkinInDecode); + shaderManager_->GetShaders(prim, lastVType_, &vshader, &fshader, pipelineState_, useHWTransform, useHWTessellation_, decOptions_.expandAllWeightsToFloat, true); ID3D11InputLayout *inputLayout = SetupDecFmtForDraw(vshader, dec_->GetDecVtxFmt(), dec_->VertexType()); context_->PSSetShader(fshader->GetShader(), nullptr, 0); context_->VSSetShader(vshader->GetShader(), nullptr, 0); @@ -581,7 +581,6 @@ 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()) { @@ -649,7 +648,7 @@ rotateVBO: if (result.action == SW_DRAW_PRIMITIVES) { D3D11VertexShader *vshader; D3D11FragmentShader *fshader; - shaderManager_->GetShaders(prim, lastVType_, &vshader, &fshader, pipelineState_, false, false, decOptions_.expandAllWeightsToFloat, decOptions_.applySkinInDecode); + shaderManager_->GetShaders(prim, lastVType_, &vshader, &fshader, pipelineState_, false, false, decOptions_.expandAllWeightsToFloat, true); context_->PSSetShader(fshader->GetShader(), nullptr, 0); context_->VSSetShader(vshader->GetShader(), nullptr, 0); shaderManager_->UpdateUniforms(framebufferManager_->UseBufferedRendering()); @@ -710,7 +709,6 @@ rotateVBO: framebufferManager_->ApplyClearToMemory(scissorX1, scissorY1, scissorX2, scissorY2, clearColor); } } - decOptions_.applySkinInDecode = g_Config.bSoftwareSkinning; } gpuStats.numDrawCalls += numDrawCalls; diff --git a/GPU/D3D11/ShaderManagerD3D11.h b/GPU/D3D11/ShaderManagerD3D11.h index d239daff8f..37997b80a1 100644 --- a/GPU/D3D11/ShaderManagerD3D11.h +++ b/GPU/D3D11/ShaderManagerD3D11.h @@ -85,8 +85,7 @@ public: ShaderManagerD3D11(Draw::DrawContext *draw, ID3D11Device *device, ID3D11DeviceContext *context, D3D_FEATURE_LEVEL featureLevel); ~ShaderManagerD3D11(); - void GetShaders(int prim, u32 vertType, D3D11VertexShader **vshader, D3D11FragmentShader **fshader, const ComputedPipelineState &pipelineState, bool useHWTransform, bool useHWTessellation, bool weightsAsFloat, bool useSkinInDecode); - void ClearShaders(); + void GetShaders(int prim, u32 vertType, D3D11VertexShader **vshader, D3D11FragmentShader **fshader, const ComputedPipelineState &pipelineState, bool useHWTransform, bool useHWTessellation, bool weightsAsFloat, bool useSkinInDecode); void ClearShaders(); void DirtyLastShader() override; int GetNumVertexShaders() const { return (int)vsCache_.size(); } diff --git a/GPU/Directx9/DrawEngineDX9.cpp b/GPU/Directx9/DrawEngineDX9.cpp index 33117be1c9..e74e0f2b55 100644 --- a/GPU/Directx9/DrawEngineDX9.cpp +++ b/GPU/Directx9/DrawEngineDX9.cpp @@ -348,8 +348,8 @@ void DrawEngineDX9::DoFlush() { // Cannot cache vertex data with morph enabled. bool useCache = g_Config.bVertexCache && !(lastVType_ & GE_VTYPE_MORPHCOUNT_MASK); - // Also avoid caching when software skinning. - if (decOptions_.applySkinInDecode && (lastVType_ & GE_VTYPE_WEIGHT_MASK)) + // Also avoid caching when skinning. + if (lastVType_ & GE_VTYPE_WEIGHT_MASK) useCache = false; if (useCache) { @@ -522,7 +522,7 @@ rotateVBO: ApplyDrawState(prim); ApplyDrawStateLate(); - VSShader *vshader = shaderManager_->ApplyShader(true, useHWTessellation_, lastVType_, decOptions_.expandAllWeightsToFloat, decOptions_.applySkinInDecode, pipelineState_); + VSShader *vshader = shaderManager_->ApplyShader(true, useHWTessellation_, lastVType_, decOptions_.expandAllWeightsToFloat, true, pipelineState_); IDirect3DVertexDeclaration9 *pHardwareVertexDecl = SetupDecFmtForDraw(vshader, dec_->GetDecVtxFmt(), dec_->VertexType()); if (pHardwareVertexDecl) { @@ -546,7 +546,6 @@ rotateVBO: } } } else { - decOptions_.applySkinInDecode = true; DecodeVerts(decoded); bool hasColor = (lastVType_ & GE_VTYPE_COL_MASK) != GE_VTYPE_COL_NONE; if (gstate.isModeThrough()) { @@ -614,7 +613,7 @@ rotateVBO: ApplyDrawStateLate(); - VSShader *vshader = shaderManager_->ApplyShader(false, false, lastVType_, decOptions_.expandAllWeightsToFloat, decOptions_.applySkinInDecode, pipelineState_); + VSShader *vshader = shaderManager_->ApplyShader(false, false, lastVType_, decOptions_.expandAllWeightsToFloat, true, pipelineState_); if (result.action == SW_DRAW_PRIMITIVES) { if (result.setStencil) { @@ -654,7 +653,6 @@ 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 e95afe57ed..7b975184f5 100644 --- a/GPU/GLES/DrawEngineGLES.cpp +++ b/GPU/GLES/DrawEngineGLES.cpp @@ -267,7 +267,7 @@ void DrawEngineGLES::DoFlush() { GEPrimitiveType prim = prevPrim_; VShaderID vsid; - Shader *vshader = shaderManager_->ApplyVertexShader(CanUseHardwareTransform(prim), useHWTessellation_, lastVType_, decOptions_.expandAllWeightsToFloat, decOptions_.applySkinInDecode, &vsid); + Shader *vshader = shaderManager_->ApplyVertexShader(CanUseHardwareTransform(prim), useHWTessellation_, lastVType_, decOptions_.expandAllWeightsToFloat, true, &vsid); GLRBuffer *vertexBuffer = nullptr; GLRBuffer *indexBuffer = nullptr; @@ -278,8 +278,8 @@ void DrawEngineGLES::DoFlush() { int vertexCount = 0; bool useElements = true; - if (decOptions_.applySkinInDecode && (lastVType_ & GE_VTYPE_WEIGHT_MASK)) { - // If software skinning, we've already predecoded into "decoded". So push that content. + if (lastVType_ & GE_VTYPE_WEIGHT_MASK) { + // Since we're software skinning, we've already predecoded into "decoded". So push that content. size_t size = decodedVerts_ * dec_->GetDecVtxFmt().stride; u8 *dest = (u8 *)frameData.pushVertex->Push(size, &vertexBufferOffset, &vertexBuffer); memcpy(dest, decoded, size); @@ -331,7 +331,6 @@ void DrawEngineGLES::DoFlush() { } } else { PROFILE_THIS_SCOPE("soft"); - decOptions_.applySkinInDecode = true; DecodeVerts(decoded); bool hasColor = (lastVType_ & GE_VTYPE_COL_MASK) != GE_VTYPE_COL_NONE; @@ -448,7 +447,6 @@ 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/GPUCommon.cpp b/GPU/GPUCommon.cpp index ddaf02bab8..930c3becab 100644 --- a/GPU/GPUCommon.cpp +++ b/GPU/GPUCommon.cpp @@ -436,13 +436,8 @@ GPUCommon::~GPUCommon() { } void GPUCommon::UpdateCmdInfo() { - if (g_Config.bSoftwareSkinning) { - cmdInfo_[GE_CMD_VERTEXTYPE].flags &= ~FLAG_FLUSHBEFOREONCHANGE; - cmdInfo_[GE_CMD_VERTEXTYPE].func = &GPUCommon::Execute_VertexTypeSkinning; - } else { - cmdInfo_[GE_CMD_VERTEXTYPE].flags |= FLAG_FLUSHBEFOREONCHANGE; - cmdInfo_[GE_CMD_VERTEXTYPE].func = &GPUCommon::Execute_VertexType; - } + cmdInfo_[GE_CMD_VERTEXTYPE].flags &= ~FLAG_FLUSHBEFOREONCHANGE; + cmdInfo_[GE_CMD_VERTEXTYPE].func = &GPUCommon::Execute_VertexTypeSkinning; if (g_Config.bFastMemory) { cmdInfo_[GE_CMD_JUMP].func = &GPUCommon::Execute_JumpFast; @@ -1834,7 +1829,7 @@ void GPUCommon::Execute_Prim(u32 op, u32 diff) { // cull mode int cullMode = gstate.getCullMode(); - uint32_t vertTypeID = GetVertTypeID(vertexType, gstate.getUVGenMode(), g_Config.bSoftwareSkinning); + uint32_t vertTypeID = GetVertTypeID(vertexType, gstate.getUVGenMode(), true); drawEngineCommon_->SubmitPrim(verts, inds, prim, count, vertTypeID, cullMode, &bytesRead); // After drawing, we advance the vertexAddr (when non indexed) or indexAddr (when indexed). // Some games rely on this, they don't bother reloading VADDR and IADDR. @@ -1853,8 +1848,6 @@ void GPUCommon::Execute_Prim(u32 op, u32 diff) { // between each prim, we just change the triangle winding right here to still be able to join draw calls. uint32_t vtypeCheckMask = ~GE_VTYPE_WEIGHTCOUNT_MASK; - if (!g_Config.bSoftwareSkinning) - vtypeCheckMask = 0xFFFFFFFF; if (debugRecording_) goto bail; @@ -1892,7 +1885,7 @@ void GPUCommon::Execute_Prim(u32 op, u32 diff) { goto bail; } else { vertexType = data; - vertTypeID = GetVertTypeID(vertexType, gstate.getUVGenMode(), g_Config.bSoftwareSkinning); + vertTypeID = GetVertTypeID(vertexType, gstate.getUVGenMode(), true); } break; } @@ -2033,10 +2026,6 @@ void GPUCommon::Execute_Bezier(u32 op, u32 diff) { indices = Memory::GetPointerUnchecked(gstate_c.indexAddr); } - if (vertTypeIsSkinningEnabled(gstate.vertType)) { - DEBUG_LOG_REPORT(G3D, "Unusual bezier/spline vtype: %08x, morph: %d, bones: %d", gstate.vertType, (gstate.vertType & GE_VTYPE_MORPHCOUNT_MASK) >> GE_VTYPE_MORPHCOUNT_SHIFT, vertTypeGetNumBoneWeights(gstate.vertType)); - } - // Can't flush after setting gstate_c.submitType below since it'll be a mess - it must be done already. if (flushOnParams_) drawEngineCommon_->DispatchFlush(); @@ -2106,10 +2095,6 @@ void GPUCommon::Execute_Spline(u32 op, u32 diff) { indices = Memory::GetPointerUnchecked(gstate_c.indexAddr); } - if (vertTypeIsSkinningEnabled(gstate.vertType)) { - DEBUG_LOG_REPORT(G3D, "Unusual bezier/spline vtype: %08x, morph: %d, bones: %d", gstate.vertType, (gstate.vertType & GE_VTYPE_MORPHCOUNT_MASK) >> GE_VTYPE_MORPHCOUNT_SHIFT, vertTypeGetNumBoneWeights(gstate.vertType)); - } - // Can't flush after setting gstate_c.submitType below since it'll be a mess - it must be done already. if (flushOnParams_) drawEngineCommon_->DispatchFlush(); @@ -2451,35 +2436,16 @@ void GPUCommon::Execute_BoneMtxNum(u32 op, u32 diff) { } if (fastLoad) { - // If we can't use software skinning, we have to flush and dirty. - if (!g_Config.bSoftwareSkinning) { - while ((src[i] >> 24) == GE_CMD_BONEMATRIXDATA) { - const u32 newVal = src[i] << 8; - if (dst[i] != newVal) { - Flush(); - dst[i] = newVal; - } - if (++i >= end) { - break; - } + while ((src[i] >> 24) == GE_CMD_BONEMATRIXDATA) { + dst[i] = src[i] << 8; + if (++i >= end) { + break; } + } - const unsigned int numPlusCount = (op & 0x7F) + i; - for (unsigned int num = op & 0x7F; num < numPlusCount; num += 12) { - gstate_c.Dirty(DIRTY_BONEMATRIX0 << (num / 12)); - } - } else { - while ((src[i] >> 24) == GE_CMD_BONEMATRIXDATA) { - dst[i] = src[i] << 8; - if (++i >= end) { - break; - } - } - - const unsigned int numPlusCount = (op & 0x7F) + i; - for (unsigned int num = op & 0x7F; num < numPlusCount; num += 12) { - gstate_c.deferredVertTypeDirty |= DIRTY_BONEMATRIX0 << (num / 12); - } + const unsigned int numPlusCount = (op & 0x7F) + i; + for (unsigned int num = op & 0x7F; num < numPlusCount; num += 12) { + gstate_c.deferredVertTypeDirty |= DIRTY_BONEMATRIX0 << (num / 12); } } @@ -2496,13 +2462,8 @@ void GPUCommon::Execute_BoneMtxData(u32 op, u32 diff) { int num = gstate.boneMatrixNumber & 0x00FFFFFF; u32 newVal = op << 8; if (num < 96 && newVal != ((const u32 *)gstate.boneMatrix)[num]) { - // Bone matrices should NOT flush when software skinning is enabled! - if (!g_Config.bSoftwareSkinning) { - Flush(); - gstate_c.Dirty(DIRTY_BONEMATRIX0 << (num / 12)); - } else { - gstate_c.deferredVertTypeDirty |= DIRTY_BONEMATRIX0 << (num / 12); - } + // Bone matrices should NOT flush since we're software skinning! + gstate_c.deferredVertTypeDirty |= DIRTY_BONEMATRIX0 << (num / 12); ((u32 *)gstate.boneMatrix)[num] = newVal; } num++; @@ -2528,7 +2489,7 @@ void GPUCommon::Execute_ImmVertexAlphaPrim(u32 op, u32 diff) { int prim = (op >> 8) & 0x7; if (prim != GE_PRIM_KEEP_PREVIOUS) { - // Flush before changing the prim type. Only continue can be used to continue a prim. + // Flush before changing the prim type. Only continue can be used to continue a prim. FlushImm(); } @@ -2692,13 +2653,7 @@ void GPUCommon::FastLoadBoneMatrix(u32 target) { uniformsToDirty |= DIRTY_BONEMATRIX0 << ((mtxNum + 1) & 7); } - if (!g_Config.bSoftwareSkinning) { - if (flushOnParams_) - Flush(); - gstate_c.Dirty(uniformsToDirty); - } else { - gstate_c.deferredVertTypeDirty |= uniformsToDirty; - } + gstate_c.deferredVertTypeDirty |= uniformsToDirty; gstate.FastLoadBoneMatrix(target); } diff --git a/GPU/GPUState.cpp b/GPU/GPUState.cpp index bae93b34b1..b54ab4cda5 100644 --- a/GPU/GPUState.cpp +++ b/GPU/GPUState.cpp @@ -260,10 +260,6 @@ void GPUgstate::Restore(u32_le *ptr) { gpu->ResetMatrices(); } -bool vertTypeIsSkinningEnabled(u32 vertType) { - return ((vertType & GE_VTYPE_WEIGHT_MASK) != GE_VTYPE_WEIGHT_NONE); -} - struct GPUStateCache_v0 { u32 vertexAddr; u32 indexAddr; diff --git a/GPU/GPUState.h b/GPU/GPUState.h index 0347371212..d1efba7fb7 100644 --- a/GPU/GPUState.h +++ b/GPU/GPUState.h @@ -448,8 +448,6 @@ struct GPUgstate { void Restore(u32_le *ptr); }; -bool vertTypeIsSkinningEnabled(u32 vertType); - inline int vertTypeGetNumBoneWeights(u32 vertType) { return 1 + ((vertType & GE_VTYPE_WEIGHTCOUNT_MASK) >> GE_VTYPE_WEIGHTCOUNT_SHIFT); } inline int vertTypeGetWeightMask(u32 vertType) { return vertType & GE_VTYPE_WEIGHT_MASK; } diff --git a/GPU/Software/SoftGpu.cpp b/GPU/Software/SoftGpu.cpp index 04e3c1d5c7..ede6d9e0bc 100644 --- a/GPU/Software/SoftGpu.cpp +++ b/GPU/Software/SoftGpu.cpp @@ -889,7 +889,7 @@ void SoftGPU::Execute_Bezier(u32 op, u32 diff) { indices = Memory::GetPointerUnchecked(gstate_c.indexAddr); } - if ((gstate.vertType & GE_VTYPE_MORPHCOUNT_MASK) || vertTypeIsSkinningEnabled(gstate.vertType)) { + if (gstate.vertType & GE_VTYPE_MORPHCOUNT_MASK) { DEBUG_LOG_REPORT(G3D, "Unusual bezier/spline vtype: %08x, morph: %d, bones: %d", gstate.vertType, (gstate.vertType & GE_VTYPE_MORPHCOUNT_MASK) >> GE_VTYPE_MORPHCOUNT_SHIFT, vertTypeGetNumBoneWeights(gstate.vertType)); } @@ -941,7 +941,7 @@ void SoftGPU::Execute_Spline(u32 op, u32 diff) { indices = Memory::GetPointerUnchecked(gstate_c.indexAddr); } - if ((gstate.vertType & GE_VTYPE_MORPHCOUNT_MASK) || vertTypeIsSkinningEnabled(gstate.vertType)) { + if (gstate.vertType & GE_VTYPE_MORPHCOUNT_MASK) { DEBUG_LOG_REPORT(G3D, "Unusual bezier/spline vtype: %08x, morph: %d, bones: %d", gstate.vertType, (gstate.vertType & GE_VTYPE_MORPHCOUNT_MASK) >> GE_VTYPE_MORPHCOUNT_SHIFT, vertTypeGetNumBoneWeights(gstate.vertType)); } diff --git a/GPU/Software/TransformUnit.cpp b/GPU/Software/TransformUnit.cpp index bc1f8679eb..0de3589419 100644 --- a/GPU/Software/TransformUnit.cpp +++ b/GPU/Software/TransformUnit.cpp @@ -64,7 +64,6 @@ SoftwareDrawEngine::~SoftwareDrawEngine() { void SoftwareDrawEngine::NotifyConfigChanged() { DrawEngineCommon::NotifyConfigChanged(); - decOptions_.applySkinInDecode = true; } void SoftwareDrawEngine::DispatchFlush() { @@ -940,7 +939,6 @@ bool TransformUnit::GetCurrentSimpleVertices(int count, std::vectorGetDecVtxFmt().stride; u8 *dest = (u8 *)frameData.pushVertex->Push(size, &vbOffset, &vbuf); @@ -784,7 +784,7 @@ void DrawEngineVulkan::DoFlush() { VulkanFragmentShader *fshader = nullptr; VulkanGeometryShader *gshader = nullptr; - shaderManager_->GetShaders(prim, lastVType_, &vshader, &fshader, &gshader, pipelineState_, true, useHWTessellation_, decOptions_.expandAllWeightsToFloat, decOptions_.applySkinInDecode); + shaderManager_->GetShaders(prim, lastVType_, &vshader, &fshader, &gshader, pipelineState_, true, useHWTessellation_, decOptions_.expandAllWeightsToFloat, true); if (!vshader) { // We're screwed. return; @@ -841,7 +841,6 @@ 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()) { @@ -920,7 +919,7 @@ void DrawEngineVulkan::DoFlush() { VulkanFragmentShader *fshader = nullptr; VulkanGeometryShader *gshader = nullptr; - shaderManager_->GetShaders(prim, lastVType_, &vshader, &fshader, &gshader, pipelineState_, false, false, decOptions_.expandAllWeightsToFloat, decOptions_.applySkinInDecode); + shaderManager_->GetShaders(prim, lastVType_, &vshader, &fshader, &gshader, pipelineState_, false, false, decOptions_.expandAllWeightsToFloat, true); _dbg_assert_msg_(!vshader->UseHWTransform(), "Bad vshader"); VulkanPipeline *pipeline = pipelineManager_->GetOrCreatePipeline(renderManager, pipelineLayout_, pipelineKey_, &dec_->decFmt, vshader, fshader, gshader, false, 0); if (!pipeline || !pipeline->pipeline) { @@ -928,7 +927,6 @@ 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. @@ -996,7 +994,6 @@ void DrawEngineVulkan::DoFlush() { framebufferManager_->ApplyClearToMemory(scissorX1, scissorY1, scissorX2, scissorY2, result.color); } } - decOptions_.applySkinInDecode = g_Config.bSoftwareSkinning; } gpuStats.numDrawCalls += numDrawCalls; diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index c551d87721..3bdf3828d4 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -540,12 +540,6 @@ void GameSettingsScreen::CreateViews() { hwTransform->SetDisabledPtr(&g_Config.bSoftwareRendering); } - CheckBox *swSkin = graphicsSettings->Add(new CheckBox(&g_Config.bSoftwareSkinning, gr->T("Software Skinning"))); - swSkin->OnClick.Add([=](EventParams &e) { - settingInfo_->Show(gr->T("SoftwareSkinning Tip", "Combine skinned model draws on the CPU, faster in most games"), e.v); - return UI::EVENT_CONTINUE; - }); - swSkin->SetDisabledPtr(&g_Config.bSoftwareRendering); CheckBox *tessellationHW = graphicsSettings->Add(new CheckBox(&g_Config.bHardwareTessellation, gr->T("Hardware Tessellation"))); tessellationHW->OnClick.Add([=](EventParams &e) { diff --git a/Windows/GEDebugger/TabVertices.cpp b/Windows/GEDebugger/TabVertices.cpp index 35ab37e498..024938a43d 100644 --- a/Windows/GEDebugger/TabVertices.cpp +++ b/Windows/GEDebugger/TabVertices.cpp @@ -306,8 +306,6 @@ int CtrlVertexList::GetRowCount() { rowCount_ = 0; } VertexDecoderOptions options{}; - // TODO: Maybe an option? - options.applySkinInDecode = true; decoder->SetVertexType(state.vertType, options); return rowCount_; } diff --git a/headless/Headless.cpp b/headless/Headless.cpp index eb29a26500..42c4696ceb 100644 --- a/headless/Headless.cpp +++ b/headless/Headless.cpp @@ -436,7 +436,6 @@ int main(int argc, const char* argv[]) g_Config.iInternalResolution = 1; g_Config.iFastForwardMode = (int)FastForwardMode::CONTINUOUS; g_Config.bEnableLogging = fullLog; - g_Config.bSoftwareSkinning = true; g_Config.bVertexDecoderJit = true; g_Config.bSoftwareRendering = coreParameter.gpuCore == GPUCORE_SOFTWARE; g_Config.bSoftwareRenderingJit = true; diff --git a/libretro/libretro.cpp b/libretro/libretro.cpp index 4213a72758..50bd44a2d3 100644 --- a/libretro/libretro.cpp +++ b/libretro/libretro.cpp @@ -823,15 +823,6 @@ static void check_variables(CoreParameter &coreParam) g_Config.bHardwareTransform = true; } - var.key = "ppsspp_software_skinning"; - if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) - { - if (!strcmp(var.value, "disabled")) - g_Config.bSoftwareSkinning = false; - else - g_Config.bSoftwareSkinning = true; - } - var.key = "ppsspp_vertex_cache"; if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) { diff --git a/unittest/TestVertexJit.cpp b/unittest/TestVertexJit.cpp index 12dad2f5aa..fa2fd6a2dd 100644 --- a/unittest/TestVertexJit.cpp +++ b/unittest/TestVertexJit.cpp @@ -546,7 +546,6 @@ static bool TestVertexColor565() { static bool TestVertex8Skin() { VertexDecoderTestHarness dec; VertexDecoderOptions opts{}; - opts.applySkinInDecode = true; dec.SetOptions(opts); for (int i = 0; i < 8 * 12; ++i) { @@ -578,7 +577,6 @@ static bool TestVertex8Skin() { static bool TestVertex16Skin() { VertexDecoderTestHarness dec; VertexDecoderOptions opts{}; - opts.applySkinInDecode = true; dec.SetOptions(opts); for (int i = 0; i < 8 * 12; ++i) { @@ -610,7 +608,6 @@ static bool TestVertex16Skin() { static bool TestVertexFloatSkin() { VertexDecoderTestHarness dec; VertexDecoderOptions opts{}; - opts.applySkinInDecode = true; dec.SetOptions(opts); for (int i = 0; i < 8 * 12; ++i) {