From 2b16b5b79b8b0dabb2df079185c1ca45b0babb3d Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 26 Oct 2014 17:49:24 -0700 Subject: [PATCH] Use XXH64 on 64-bit systems. I'm not able to reproduce any real performance difference, but I know there are some games which do more hashing and it may help there. --- Core/Debugger/DisassemblyManager.cpp | 10 +++++++--- Core/Debugger/DisassemblyManager.h | 10 ++++++++-- GPU/Common/TextureDecoder.cpp | 5 +++-- GPU/Common/TextureDecoder.h | 19 +++++++++++++++++-- GPU/Common/TextureDecoderNEON.cpp | 2 +- GPU/Common/TextureDecoderNEON.h | 2 +- GPU/Directx9/TextureCacheDX9.cpp | 2 +- GPU/Directx9/TransformPipelineDX9.cpp | 10 +++++----- GPU/Directx9/TransformPipelineDX9.h | 15 ++++++++------- GPU/GLES/TextureCache.cpp | 2 +- GPU/GLES/TransformPipeline.cpp | 10 +++++----- GPU/GLES/TransformPipeline.h | 11 +++++++++-- 12 files changed, 66 insertions(+), 32 deletions(-) diff --git a/Core/Debugger/DisassemblyManager.cpp b/Core/Debugger/DisassemblyManager.cpp index fa0203878d..84a51b76b0 100644 --- a/Core/Debugger/DisassemblyManager.cpp +++ b/Core/Debugger/DisassemblyManager.cpp @@ -42,7 +42,11 @@ bool isInInterval(u32 start, u32 size, u32 value) static u32 computeHash(u32 address, u32 size) { - return XXH32(Memory::GetPointer(address),size,0xBACD7814); +#ifdef _M_X64 + return XXH64(Memory::GetPointer(address), size, 0xBACD7814BACD7814LL); +#else + return XXH32(Memory::GetPointer(address), size, 0xBACD7814); +#endif } @@ -356,7 +360,7 @@ void DisassemblyFunction::recheck() if (!PSP_IsInited()) return; - u32 newHash = computeHash(address,size); + HashType newHash = computeHash(address,size); if (hash != newHash) { hash = newHash; @@ -819,7 +823,7 @@ void DisassemblyData::recheck() if (!PSP_IsInited()) return; - u32 newHash = computeHash(address,size); + HashType newHash = computeHash(address,size); if (newHash != hash) { hash = newHash; diff --git a/Core/Debugger/DisassemblyManager.h b/Core/Debugger/DisassemblyManager.h index 350752250b..d4448543f9 100644 --- a/Core/Debugger/DisassemblyManager.h +++ b/Core/Debugger/DisassemblyManager.h @@ -21,6 +21,12 @@ #include "Core/Debugger/SymbolMap.h" #include "Core/MIPS/MIPSAnalyst.h" +#ifdef _M_X64 +typedef u64 HashType; +#else +typedef u32 HashType; +#endif + enum DisassemblyLineType { DISTYPE_OPCODE, DISTYPE_MACRO, DISTYPE_DATA, DISTYPE_OTHER }; struct DisassemblyLineInfo @@ -79,7 +85,7 @@ private: u32 address; u32 size; - u32 hash; + HashType hash; std::vector lines; std::map entries; std::vector lineAddresses; @@ -155,7 +161,7 @@ private: u32 address; u32 size; - u32 hash; + HashType hash; DataType type; std::map lines; std::vector lineAddresses; diff --git a/GPU/Common/TextureDecoder.cpp b/GPU/Common/TextureDecoder.cpp index c4bfe9fe36..2ffee02b5e 100644 --- a/GPU/Common/TextureDecoder.cpp +++ b/GPU/Common/TextureDecoder.cpp @@ -157,7 +157,8 @@ void DoUnswizzleTex16Basic(const u8 *texptr, u32 *ydestp, int bxc, int byc, u32 #ifndef _M_SSE QuickTexHashFunc DoQuickTexHash = &QuickTexHashBasic; UnswizzleTex16Func DoUnswizzleTex16 = &DoUnswizzleTex16Basic; -ReliableHashFunc DoReliableHash = &XXH32; +ReliableHash32Func DoReliableHash32 = &XXH32; +ReliableHash64Func DoReliableHash64 = &XXH64; #endif // This has to be done after CPUDetect has done its magic. @@ -168,7 +169,7 @@ void SetupTextureDecoder() { DoUnswizzleTex16 = &DoUnswizzleTex16NEON; #ifndef IOS // Not sure if this is safe on iOS, it's had issues with xxhash. - DoReliableHash = &ReliableHashNEON; + DoReliableHash32 = &ReliableHash32NEON; #endif } #endif diff --git a/GPU/Common/TextureDecoder.h b/GPU/Common/TextureDecoder.h index 9f1ba46675..f99129e2f0 100644 --- a/GPU/Common/TextureDecoder.h +++ b/GPU/Common/TextureDecoder.h @@ -32,7 +32,16 @@ void DoUnswizzleTex16Basic(const u8 *texptr, u32 *ydestp, int bxc, int byc, u32 #define DoUnswizzleTex16 DoUnswizzleTex16Basic #include "ext/xxhash.h" +#define DoReliableHash32 XXH32 +#define DoReliableHash64 XXH64 + +#ifdef _M_X64 +#define DoReliableHash XXH64 +typedef u64 ReliableHashType; +#else #define DoReliableHash XXH32 +typedef u32 ReliableHashType; +#endif #else typedef u32 (*QuickTexHashFunc)(const void *checkp, u32 size); extern QuickTexHashFunc DoQuickTexHash; @@ -40,8 +49,14 @@ extern QuickTexHashFunc DoQuickTexHash; typedef void (*UnswizzleTex16Func)(const u8 *texptr, u32 *ydestp, int bxc, int byc, u32 pitch, u32 rowWidth); extern UnswizzleTex16Func DoUnswizzleTex16; -typedef u32 (*ReliableHashFunc)(const void *input, int len, u32 seed); -extern ReliableHashFunc DoReliableHash; +typedef u32 (*ReliableHash32Func)(const void *input, size_t len, u32 seed); +extern ReliableHash32Func DoReliableHash32; + +typedef u64 (*ReliableHash64Func)(const void *input, size_t len, u64 seed); +extern ReliableHash64Func DoReliableHash64; + +#define DoReliableHash DoReliableHash32 +typedef u32 ReliableHashType; #endif // All these DXT structs are in the reverse order, as compared to PC. diff --git a/GPU/Common/TextureDecoderNEON.cpp b/GPU/Common/TextureDecoderNEON.cpp index 6c6bbf7101..39c015fea2 100644 --- a/GPU/Common/TextureDecoderNEON.cpp +++ b/GPU/Common/TextureDecoderNEON.cpp @@ -177,7 +177,7 @@ void DoUnswizzleTex16NEON(const u8 *texptr, u32 *ydestp, int bxc, int byc, u32 p # define XXH_rotl32(x,r) ((x << r) | (x >> (32 - r))) #endif -u32 ReliableHashNEON(const void *input, int len, u32 seed) { +u32 ReliableHash32NEON(const void *input, size_t len, u32 seed) { const u8 *p = (const u8 *)input; const u8 *const bEnd = p + len; U32 h32; diff --git a/GPU/Common/TextureDecoderNEON.h b/GPU/Common/TextureDecoderNEON.h index 3cef806ac7..1003dc54ff 100644 --- a/GPU/Common/TextureDecoderNEON.h +++ b/GPU/Common/TextureDecoderNEON.h @@ -19,4 +19,4 @@ u32 QuickTexHashNEON(const void *checkp, u32 size); void DoUnswizzleTex16NEON(const u8 *texptr, u32 *ydestp, int bxc, int byc, u32 pitch, u32 rowWidth); -u32 ReliableHashNEON(const void *input, int len, u32 seed); +u32 ReliableHash32NEON(const void *input, size_t len, u32 seed); diff --git a/GPU/Directx9/TextureCacheDX9.cpp b/GPU/Directx9/TextureCacheDX9.cpp index edc17e01d4..a02fdad2eb 100644 --- a/GPU/Directx9/TextureCacheDX9.cpp +++ b/GPU/Directx9/TextureCacheDX9.cpp @@ -798,7 +798,7 @@ void TextureCacheDX9::UpdateCurrentClut() { // If not, we're going to hash random data, which hopefully doesn't cause a performance issue. const u32 clutExtendedBytes = clutTotalBytes_ + clutBaseBytes; - clutHash_ = DoReliableHash((const char *)clutBufRaw_, clutExtendedBytes, 0xC0108888); + clutHash_ = DoReliableHash32((const char *)clutBufRaw_, clutExtendedBytes, 0xC0108888); clutBuf_ = clutBufRaw_; // Special optimization: fonts typically draw clut4 with just alpha values in a single color. diff --git a/GPU/Directx9/TransformPipelineDX9.cpp b/GPU/Directx9/TransformPipelineDX9.cpp index dfa03faba4..af4a6463c9 100644 --- a/GPU/Directx9/TransformPipelineDX9.cpp +++ b/GPU/Directx9/TransformPipelineDX9.cpp @@ -462,7 +462,7 @@ inline u32 ComputeMiniHashRange(const void *ptr, size_t sz) { size_t step = sz / 4; u32 hash = 0; for (size_t i = 0; i < sz; i += step) { - hash += DoReliableHash(p + i, 100, 0x3A44B9C4); + hash += DoReliableHash32(p + i, 100, 0x3A44B9C4); } return hash; } else { @@ -509,8 +509,8 @@ void TransformDrawEngineDX9::MarkUnreliable(VertexArrayInfoDX9 *vai) { } } -u32 TransformDrawEngineDX9::ComputeHash() { - u32 fullhash = 0; +ReliableHashType TransformDrawEngineDX9::ComputeHash() { + ReliableHashType fullhash = 0; const int vertexSize = dec_->GetDecVtxFmt().stride; const int indexSize = (dec_->VertexType() & GE_VTYPE_IDX_MASK) == GE_VTYPE_IDX_16BIT ? 2 : 1; @@ -645,7 +645,7 @@ void TransformDrawEngineDX9::DoFlush() { case VertexArrayInfoDX9::VAI_NEW: { // Haven't seen this one before. - u32 dataHash = ComputeHash(); + ReliableHashType dataHash = ComputeHash(); vai->hash = dataHash; vai->minihash = ComputeMiniHash(); vai->status = VertexArrayInfoDX9::VAI_HASHING; @@ -670,7 +670,7 @@ void TransformDrawEngineDX9::DoFlush() { if (vai->drawsUntilNextFullHash == 0) { // Let's try to skip a full hash if mini would fail. const u32 newMiniHash = ComputeMiniHash(); - u32 newHash = vai->hash; + ReliableHashType newHash = vai->hash; if (newMiniHash == vai->minihash) { newHash = ComputeHash(); } diff --git a/GPU/Directx9/TransformPipelineDX9.h b/GPU/Directx9/TransformPipelineDX9.h index 82c09b755d..0689b1db33 100644 --- a/GPU/Directx9/TransformPipelineDX9.h +++ b/GPU/Directx9/TransformPipelineDX9.h @@ -51,11 +51,12 @@ enum { VAI_FLAG_VERTEXFULLALPHA = 1, }; - -// Don't bother storing information about draws smaller than this. -enum { - VERTEX_CACHE_THRESHOLD = 20, -}; +// Avoiding the full include of TextureDecoder.h. +#ifdef _M_X64 +typedef u64 ReliableHashType; +#else +typedef u32 ReliableHashType; +#endif // Try to keep this POD. class VertexArrayInfoDX9 { @@ -81,7 +82,7 @@ public: VAI_UNRELIABLE, // never cache }; - u32 hash; + ReliableHashType hash; u32 minihash; Status status; @@ -191,7 +192,7 @@ private: IDirect3DVertexDeclaration9 *SetupDecFmtForDraw(VSShader *vshader, const DecVtxFormat &decFmt, u32 pspFmt); u32 ComputeMiniHash(); - u32 ComputeHash(); // Reads deferred vertex data. + ReliableHashType ComputeHash(); // Reads deferred vertex data. void MarkUnreliable(VertexArrayInfoDX9 *vai); VertexDecoder *GetVertexDecoder(u32 vtype); diff --git a/GPU/GLES/TextureCache.cpp b/GPU/GLES/TextureCache.cpp index 5bcc96e8b9..3636cdffa5 100644 --- a/GPU/GLES/TextureCache.cpp +++ b/GPU/GLES/TextureCache.cpp @@ -921,7 +921,7 @@ void TextureCache::UpdateCurrentClut() { // If not, we're going to hash random data, which hopefully doesn't cause a performance issue. const u32 clutExtendedBytes = clutTotalBytes_ + clutBaseBytes; - clutHash_ = DoReliableHash((const char *)clutBufRaw_, clutExtendedBytes, 0xC0108888); + clutHash_ = DoReliableHash32((const char *)clutBufRaw_, clutExtendedBytes, 0xC0108888); // Avoid a copy when we don't need to convert colors. if (UseBGRA8888() || clutFormat != GE_CMODE_32BIT_ABGR8888) { diff --git a/GPU/GLES/TransformPipeline.cpp b/GPU/GLES/TransformPipeline.cpp index ffed06e0a5..32930746d5 100644 --- a/GPU/GLES/TransformPipeline.cpp +++ b/GPU/GLES/TransformPipeline.cpp @@ -444,7 +444,7 @@ inline u32 ComputeMiniHashRange(const void *ptr, size_t sz) { size_t step = sz / 4; u32 hash = 0; for (size_t i = 0; i < sz; i += step) { - hash += DoReliableHash(p + i, 100, 0x3A44B9C4); + hash += DoReliableHash32(p + i, 100, 0x3A44B9C4); } return hash; } else { @@ -491,8 +491,8 @@ void TransformDrawEngine::MarkUnreliable(VertexArrayInfo *vai) { } } -u32 TransformDrawEngine::ComputeHash() { - u32 fullhash = 0; +ReliableHashType TransformDrawEngine::ComputeHash() { + ReliableHashType fullhash = 0; const int vertexSize = dec_->GetDecVtxFmt().stride; const int indexSize = (dec_->VertexType() & GE_VTYPE_IDX_MASK) == GE_VTYPE_IDX_16BIT ? 2 : 1; @@ -633,7 +633,7 @@ void TransformDrawEngine::DoFlush() { case VertexArrayInfo::VAI_NEW: { // Haven't seen this one before. - u32 dataHash = ComputeHash(); + ReliableHashType dataHash = ComputeHash(); vai->hash = dataHash; vai->minihash = ComputeMiniHash(); vai->status = VertexArrayInfo::VAI_HASHING; @@ -658,7 +658,7 @@ void TransformDrawEngine::DoFlush() { if (vai->drawsUntilNextFullHash == 0) { // Let's try to skip a full hash if mini would fail. const u32 newMiniHash = ComputeMiniHash(); - u32 newHash = vai->hash; + ReliableHashType newHash = vai->hash; if (newMiniHash == vai->minihash) { newHash = ComputeHash(); } diff --git a/GPU/GLES/TransformPipeline.h b/GPU/GLES/TransformPipeline.h index 331865b597..75c2545188 100644 --- a/GPU/GLES/TransformPipeline.h +++ b/GPU/GLES/TransformPipeline.h @@ -53,6 +53,13 @@ enum { VAI_FLAG_VERTEXFULLALPHA = 1, }; +// Avoiding the full include of TextureDecoder.h. +#ifdef _M_X64 +typedef u64 ReliableHashType; +#else +typedef u32 ReliableHashType; +#endif + // Try to keep this POD. class VertexArrayInfo { public: @@ -77,7 +84,7 @@ public: VAI_UNRELIABLE, // never cache }; - u32 hash; + ReliableHashType hash; u32 minihash; Status status; @@ -188,7 +195,7 @@ private: void FreeBuffer(GLuint buf); u32 ComputeMiniHash(); - u32 ComputeHash(); // Reads deferred vertex data. + ReliableHashType ComputeHash(); // Reads deferred vertex data. void MarkUnreliable(VertexArrayInfo *vai); VertexDecoder *GetVertexDecoder(u32 vtype);