From 5e16bf907bc77582d48fc6f0e3da0b428342009c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 24 Sep 2025 10:35:57 -0600 Subject: [PATCH] VertexDecoder: Improve logging for missing formats. Add missing convert function. The missing function is mainly used in D3D11, which can be used on Windows for ARM64. It's not necesssary for the other backends, which is why it used to be missing in the ARM64 vertex decoder. Also fix a minor memory leak in AtracCtx2. --- Core/HLE/AtracCtx2.cpp | 1 + GPU/Common/VertexDecoderArm.cpp | 4 +- GPU/Common/VertexDecoderArm64.cpp | 11 ++- GPU/Common/VertexDecoderCommon.cpp | 97 +++++++++++++++++++++++++ GPU/Common/VertexDecoderCommon.h | 1 + GPU/Common/VertexDecoderLoongArch64.cpp | 4 +- GPU/Common/VertexDecoderRiscV.cpp | 2 +- GPU/Common/VertexDecoderX86.cpp | 3 + 8 files changed, 116 insertions(+), 7 deletions(-) diff --git a/Core/HLE/AtracCtx2.cpp b/Core/HLE/AtracCtx2.cpp index 7610d89884..b2fc724fbb 100644 --- a/Core/HLE/AtracCtx2.cpp +++ b/Core/HLE/AtracCtx2.cpp @@ -312,6 +312,7 @@ Atrac2::Atrac2(u32 contextAddr, int codecType) { Atrac2::~Atrac2() { DumpBufferToFile(); + delete[] decodeTemp_; // Nothing else to do here, the context is freed by the HLE. } diff --git a/GPU/Common/VertexDecoderArm.cpp b/GPU/Common/VertexDecoderArm.cpp index 6dc39e2ed3..29c4368ad2 100644 --- a/GPU/Common/VertexDecoderArm.cpp +++ b/GPU/Common/VertexDecoderArm.cpp @@ -256,9 +256,9 @@ JittedVertexDecoder VertexDecoderJitCache::Compile(const VertexDecoder &dec, int EndWrite(); // Reset the code ptr and return zero to indicate that we failed. ResetCodePtr(GetOffset(start)); - char temp[1024] = {0}; + char temp[1024]{}; dec.ToString(temp, true); - INFO_LOG(Log::G3D, "Could not compile vertex decoder: %s", temp); + WARN_LOG(Log::G3D, "Could not compile vertex decoder, failed at step %s: %s", GetStepFunctionName(dec.steps_[i]), temp); return 0; } } diff --git a/GPU/Common/VertexDecoderArm64.cpp b/GPU/Common/VertexDecoderArm64.cpp index c79fb5bfcc..9c322247b8 100644 --- a/GPU/Common/VertexDecoderArm64.cpp +++ b/GPU/Common/VertexDecoderArm64.cpp @@ -106,6 +106,8 @@ static const JitLookup jitLookup[] = { {&VertexDecoder::Step_NormalS16Skin, &VertexDecoderJitCache::Jit_NormalS16Skin}, {&VertexDecoder::Step_NormalFloatSkin, &VertexDecoderJitCache::Jit_NormalFloatSkin}, + {&VertexDecoder::Step_NormalS8ToFloat, &VertexDecoderJitCache::Jit_NormalS8ToFloat}, // only used for the D3D11 backend + {&VertexDecoder::Step_Color8888, &VertexDecoderJitCache::Jit_Color8888}, {&VertexDecoder::Step_Color4444, &VertexDecoderJitCache::Jit_Color4444}, {&VertexDecoder::Step_Color565, &VertexDecoderJitCache::Jit_Color565}, @@ -252,9 +254,9 @@ JittedVertexDecoder VertexDecoderJitCache::Compile(const VertexDecoder &dec, int EndWrite(); // Reset the code ptr (effectively undoing what we generated) and return zero to indicate that we failed. ResetCodePtr(GetOffset(start)); - char temp[1024] = {0}; + char temp[1024]{}; dec.ToString(temp, true); - ERROR_LOG(Log::G3D, "Could not compile vertex decoder, failed at step %d: %s", i, temp); + WARN_LOG(Log::G3D, "Could not compile vertex decoder, failed at step %s: %s", GetStepFunctionName(dec.steps_[i]), temp); return nullptr; } } @@ -724,6 +726,11 @@ void VertexDecoderJitCache::Jit_NormalFloat() { } } +void VertexDecoderJitCache::Jit_NormalS8ToFloat() { + Jit_AnyS8ToFloat(dec_->nrmoff); + fp.STUR(128, srcQ, dstReg, dec_->decFmt.nrmoff); +} + void VertexDecoderJitCache::Jit_NormalS8Skin() { Jit_AnyS8ToFloat(dec_->nrmoff); Jit_WriteMatrixMul(dec_->decFmt.nrmoff, false); diff --git a/GPU/Common/VertexDecoderCommon.cpp b/GPU/Common/VertexDecoderCommon.cpp index a8a04defa9..0e235ea595 100644 --- a/GPU/Common/VertexDecoderCommon.cpp +++ b/GPU/Common/VertexDecoderCommon.cpp @@ -1606,3 +1606,100 @@ void VertexDecoderJitCache::Clear() { ClearCodeSpace(0); } } + +struct StepFunctionNameEntry { + StepFunction func; + const char *name; +}; + +static const StepFunctionNameEntry stepFunctionNames[] = { + {VertexDecoder::Step_WeightsU8, "WeightsU8"}, + {VertexDecoder::Step_WeightsU16, "WeightsU16"}, + {VertexDecoder::Step_WeightsU8ToFloat, "WeightsU8ToFloat"}, + {VertexDecoder::Step_WeightsU16ToFloat, "WeightsU16ToFloat"}, + {VertexDecoder::Step_WeightsFloat, "WeightsFloat"}, + + {VertexDecoder::Step_WeightsU8Skin, "WeightsU8Skin"}, + {VertexDecoder::Step_WeightsU16Skin, "WeightsU16Skin"}, + {VertexDecoder::Step_WeightsFloatSkin, "WeightsFloatSkin"}, + + {VertexDecoder::Step_TcU8ToFloat, "TcU8ToFloat"}, + {VertexDecoder::Step_TcU16ToFloat, "TcU16ToFloat"}, + {VertexDecoder::Step_TcFloat, "TcFloat"}, + + {VertexDecoder::Step_TcU8Prescale, "TcU8Prescale"}, + {VertexDecoder::Step_TcU16Prescale, "TcU16Prescale"}, + {VertexDecoder::Step_TcU16DoublePrescale, "TcU16DoublePrescale"}, + {VertexDecoder::Step_TcFloatPrescale, "TcFloatPrescale"}, + + {VertexDecoder::Step_TcU16DoubleToFloat, "TcU16DoubleToFloat"}, + {VertexDecoder::Step_TcU16ThroughToFloat, "TcU16ThroughToFloat"}, + {VertexDecoder::Step_TcU16ThroughDoubleToFloat, "TcU16ThroughDoubleToFloat"}, + {VertexDecoder::Step_TcFloatThrough, "TcFloatThrough"}, + + {VertexDecoder::Step_TcU8MorphToFloat, "TcU8MorphToFloat"}, + {VertexDecoder::Step_TcU16MorphToFloat, "TcU16MorphToFloat"}, + {VertexDecoder::Step_TcU16DoubleMorphToFloat, "TcU16DoubleMorphToFloat"}, + {VertexDecoder::Step_TcFloatMorph, "TcFloatMorph"}, + {VertexDecoder::Step_TcU8PrescaleMorph, "TcU8PrescaleMorph"}, + {VertexDecoder::Step_TcU16PrescaleMorph, "TcU16PrescaleMorph"}, + {VertexDecoder::Step_TcU16DoublePrescaleMorph, "TcU16DoublePrescaleMorph"}, + {VertexDecoder::Step_TcFloatPrescaleMorph, "TcFloatPrescaleMorph"}, + + {VertexDecoder::Step_ColorInvalid, "ColorInvalid"}, + {VertexDecoder::Step_Color4444, "Color4444"}, + {VertexDecoder::Step_Color565, "Color565"}, + {VertexDecoder::Step_Color5551, "Color5551"}, + {VertexDecoder::Step_Color8888, "Color8888"}, + + {VertexDecoder::Step_Color4444Morph, "Color4444Morph"}, + {VertexDecoder::Step_Color565Morph, "Color565Morph"}, + {VertexDecoder::Step_Color5551Morph, "Color5551Morph"}, + {VertexDecoder::Step_Color8888Morph, "Color8888Morph"}, + + {VertexDecoder::Step_NormalS8, "NormalS8"}, + {VertexDecoder::Step_NormalS8ToFloat, "NormalS8ToFloat"}, + {VertexDecoder::Step_NormalS16, "NormalS16"}, + {VertexDecoder::Step_NormalFloat, "NormalFloat"}, + + {VertexDecoder::Step_NormalS8Skin, "NormalS8Skin"}, + {VertexDecoder::Step_NormalS16Skin, "NormalS16Skin"}, + {VertexDecoder::Step_NormalFloatSkin, "NormalFloatSkin"}, + + {VertexDecoder::Step_NormalS8Morph, "NormalS8Morph"}, + {VertexDecoder::Step_NormalS16Morph, "NormalS16Morph"}, + {VertexDecoder::Step_NormalFloatMorph, "NormalFloatMorph"}, + + {VertexDecoder::Step_NormalS8MorphSkin, "NormalS8MorphSkin"}, + {VertexDecoder::Step_NormalS16MorphSkin, "NormalS16MorphSkin"}, + {VertexDecoder::Step_NormalFloatMorphSkin, "NormalFloatMorphSkin"}, + + {VertexDecoder::Step_PosS8, "PosS8"}, + {VertexDecoder::Step_PosS16, "PosS16"}, + {VertexDecoder::Step_PosFloat, "PosFloat"}, + + {VertexDecoder::Step_PosS8Skin, "PosS8Skin"}, + {VertexDecoder::Step_PosS16Skin, "PosS16Skin"}, + {VertexDecoder::Step_PosFloatSkin, "PosFloatSkin"}, + + {VertexDecoder::Step_PosS8Morph, "PosS8Morph"}, + {VertexDecoder::Step_PosS16Morph, "PosS16Morph"}, + {VertexDecoder::Step_PosFloatMorph, "PosFloatMorph"}, + + {VertexDecoder::Step_PosS8MorphSkin, "PosS8MorphSkin"}, + {VertexDecoder::Step_PosS16MorphSkin, "PosS16MorphSkin"}, + {VertexDecoder::Step_PosFloatMorphSkin, "PosFloatMorphSkin"}, + + {VertexDecoder::Step_PosInvalid, "PosInvalid"}, + {VertexDecoder::Step_PosS8Through, "PosS8Through"}, + {VertexDecoder::Step_PosS16Through, "PosS16Through"}, + {VertexDecoder::Step_PosFloatThrough, "PosFloatThrough"}, +}; + +const char *GetStepFunctionName(StepFunction func) { + for (const StepFunctionNameEntry &entry : stepFunctionNames) { + if (entry.func == func) + return entry.name; + } + return "(unknown)"; +} diff --git a/GPU/Common/VertexDecoderCommon.h b/GPU/Common/VertexDecoderCommon.h index 67e5de4960..ee66bf94b2 100644 --- a/GPU/Common/VertexDecoderCommon.h +++ b/GPU/Common/VertexDecoderCommon.h @@ -513,6 +513,7 @@ private: void CompareToJit(const u8 *startPtr, u8 *decodedptr, int count, const UVScale *uvScaleOffset) const; }; +const char *GetStepFunctionName(StepFunction func); // A compiled vertex decoder takes the following arguments (C calling convention): // u8 *src, u8 *dst, int count diff --git a/GPU/Common/VertexDecoderLoongArch64.cpp b/GPU/Common/VertexDecoderLoongArch64.cpp index acfaf55cb1..dbb1a68933 100644 --- a/GPU/Common/VertexDecoderLoongArch64.cpp +++ b/GPU/Common/VertexDecoderLoongArch64.cpp @@ -298,7 +298,7 @@ JittedVertexDecoder VertexDecoderJitCache::Compile(const VertexDecoder &dec, int ResetCodePtr(GetOffset(start)); char temp[1024]{}; dec.ToString(temp, true); - ERROR_LOG(Log::G3D, "Could not compile vertex decoder, failed at step %d: %s", i, temp); + WARN_LOG(Log::G3D, "Could not compile vertex decoder, failed at step %s: %s", GetStepFunctionName(dec.steps_[i]), temp); return nullptr; } } @@ -1294,4 +1294,4 @@ void VertexDecoderJitCache::Jit_NormalFloatMorphSkin() { Jit_AnyFloatMorph(dec_->nrmoff, -1); Jit_WriteMatrixMul(dec_->decFmt.nrmoff, false); } -#endif // PPSSPP_ARCH(LOONGARCH64) \ No newline at end of file +#endif // PPSSPP_ARCH(LOONGARCH64) diff --git a/GPU/Common/VertexDecoderRiscV.cpp b/GPU/Common/VertexDecoderRiscV.cpp index 0d232a74fb..6a1444deb4 100644 --- a/GPU/Common/VertexDecoderRiscV.cpp +++ b/GPU/Common/VertexDecoderRiscV.cpp @@ -317,7 +317,7 @@ JittedVertexDecoder VertexDecoderJitCache::Compile(const VertexDecoder &dec, int ResetCodePtr(GetOffset(start)); char temp[1024]{}; dec.ToString(temp, true); - ERROR_LOG(Log::G3D, "Could not compile vertex decoder, failed at step %d: %s", i, temp); + WARN_LOG(Log::G3D, "Could not compile vertex decoder, failed at step %s: %s", GetStepFunctionName(dec.steps_[i]), temp); return nullptr; } } diff --git a/GPU/Common/VertexDecoderX86.cpp b/GPU/Common/VertexDecoderX86.cpp index 5c29bbcab2..16935da924 100644 --- a/GPU/Common/VertexDecoderX86.cpp +++ b/GPU/Common/VertexDecoderX86.cpp @@ -280,6 +280,9 @@ JittedVertexDecoder VertexDecoderJitCache::Compile(const VertexDecoder &dec, int EndWrite(); // Reset the code ptr and return zero to indicate that we failed. ResetCodePtr(GetOffset(start)); + char temp[1024]{}; + dec.ToString(temp, true); + WARN_LOG(Log::G3D, "Could not compile vertex decoder, failed at step %s: %s", GetStepFunctionName(dec.steps_[i]), temp); return 0; } }