mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
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.
This commit is contained in:
parent
139277bc1a
commit
2b16b5b79b
12 changed files with 66 additions and 32 deletions
|
@ -42,7 +42,11 @@ bool isInInterval(u32 start, u32 size, u32 value)
|
||||||
|
|
||||||
static u32 computeHash(u32 address, u32 size)
|
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())
|
if (!PSP_IsInited())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
u32 newHash = computeHash(address,size);
|
HashType newHash = computeHash(address,size);
|
||||||
if (hash != newHash)
|
if (hash != newHash)
|
||||||
{
|
{
|
||||||
hash = newHash;
|
hash = newHash;
|
||||||
|
@ -819,7 +823,7 @@ void DisassemblyData::recheck()
|
||||||
if (!PSP_IsInited())
|
if (!PSP_IsInited())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
u32 newHash = computeHash(address,size);
|
HashType newHash = computeHash(address,size);
|
||||||
if (newHash != hash)
|
if (newHash != hash)
|
||||||
{
|
{
|
||||||
hash = newHash;
|
hash = newHash;
|
||||||
|
|
|
@ -21,6 +21,12 @@
|
||||||
#include "Core/Debugger/SymbolMap.h"
|
#include "Core/Debugger/SymbolMap.h"
|
||||||
#include "Core/MIPS/MIPSAnalyst.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 };
|
enum DisassemblyLineType { DISTYPE_OPCODE, DISTYPE_MACRO, DISTYPE_DATA, DISTYPE_OTHER };
|
||||||
|
|
||||||
struct DisassemblyLineInfo
|
struct DisassemblyLineInfo
|
||||||
|
@ -79,7 +85,7 @@ private:
|
||||||
|
|
||||||
u32 address;
|
u32 address;
|
||||||
u32 size;
|
u32 size;
|
||||||
u32 hash;
|
HashType hash;
|
||||||
std::vector<BranchLine> lines;
|
std::vector<BranchLine> lines;
|
||||||
std::map<u32,DisassemblyEntry*> entries;
|
std::map<u32,DisassemblyEntry*> entries;
|
||||||
std::vector<u32> lineAddresses;
|
std::vector<u32> lineAddresses;
|
||||||
|
@ -155,7 +161,7 @@ private:
|
||||||
|
|
||||||
u32 address;
|
u32 address;
|
||||||
u32 size;
|
u32 size;
|
||||||
u32 hash;
|
HashType hash;
|
||||||
DataType type;
|
DataType type;
|
||||||
std::map<u32,DataEntry> lines;
|
std::map<u32,DataEntry> lines;
|
||||||
std::vector<u32> lineAddresses;
|
std::vector<u32> lineAddresses;
|
||||||
|
|
|
@ -157,7 +157,8 @@ void DoUnswizzleTex16Basic(const u8 *texptr, u32 *ydestp, int bxc, int byc, u32
|
||||||
#ifndef _M_SSE
|
#ifndef _M_SSE
|
||||||
QuickTexHashFunc DoQuickTexHash = &QuickTexHashBasic;
|
QuickTexHashFunc DoQuickTexHash = &QuickTexHashBasic;
|
||||||
UnswizzleTex16Func DoUnswizzleTex16 = &DoUnswizzleTex16Basic;
|
UnswizzleTex16Func DoUnswizzleTex16 = &DoUnswizzleTex16Basic;
|
||||||
ReliableHashFunc DoReliableHash = &XXH32;
|
ReliableHash32Func DoReliableHash32 = &XXH32;
|
||||||
|
ReliableHash64Func DoReliableHash64 = &XXH64;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// This has to be done after CPUDetect has done its magic.
|
// This has to be done after CPUDetect has done its magic.
|
||||||
|
@ -168,7 +169,7 @@ void SetupTextureDecoder() {
|
||||||
DoUnswizzleTex16 = &DoUnswizzleTex16NEON;
|
DoUnswizzleTex16 = &DoUnswizzleTex16NEON;
|
||||||
#ifndef IOS
|
#ifndef IOS
|
||||||
// Not sure if this is safe on iOS, it's had issues with xxhash.
|
// Not sure if this is safe on iOS, it's had issues with xxhash.
|
||||||
DoReliableHash = &ReliableHashNEON;
|
DoReliableHash32 = &ReliableHash32NEON;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -32,7 +32,16 @@ void DoUnswizzleTex16Basic(const u8 *texptr, u32 *ydestp, int bxc, int byc, u32
|
||||||
#define DoUnswizzleTex16 DoUnswizzleTex16Basic
|
#define DoUnswizzleTex16 DoUnswizzleTex16Basic
|
||||||
|
|
||||||
#include "ext/xxhash.h"
|
#include "ext/xxhash.h"
|
||||||
|
#define DoReliableHash32 XXH32
|
||||||
|
#define DoReliableHash64 XXH64
|
||||||
|
|
||||||
|
#ifdef _M_X64
|
||||||
|
#define DoReliableHash XXH64
|
||||||
|
typedef u64 ReliableHashType;
|
||||||
|
#else
|
||||||
#define DoReliableHash XXH32
|
#define DoReliableHash XXH32
|
||||||
|
typedef u32 ReliableHashType;
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
typedef u32 (*QuickTexHashFunc)(const void *checkp, u32 size);
|
typedef u32 (*QuickTexHashFunc)(const void *checkp, u32 size);
|
||||||
extern QuickTexHashFunc DoQuickTexHash;
|
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);
|
typedef void (*UnswizzleTex16Func)(const u8 *texptr, u32 *ydestp, int bxc, int byc, u32 pitch, u32 rowWidth);
|
||||||
extern UnswizzleTex16Func DoUnswizzleTex16;
|
extern UnswizzleTex16Func DoUnswizzleTex16;
|
||||||
|
|
||||||
typedef u32 (*ReliableHashFunc)(const void *input, int len, u32 seed);
|
typedef u32 (*ReliableHash32Func)(const void *input, size_t len, u32 seed);
|
||||||
extern ReliableHashFunc DoReliableHash;
|
extern ReliableHash32Func DoReliableHash32;
|
||||||
|
|
||||||
|
typedef u64 (*ReliableHash64Func)(const void *input, size_t len, u64 seed);
|
||||||
|
extern ReliableHash64Func DoReliableHash64;
|
||||||
|
|
||||||
|
#define DoReliableHash DoReliableHash32
|
||||||
|
typedef u32 ReliableHashType;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// All these DXT structs are in the reverse order, as compared to PC.
|
// All these DXT structs are in the reverse order, as compared to PC.
|
||||||
|
|
|
@ -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)))
|
# define XXH_rotl32(x,r) ((x << r) | (x >> (32 - r)))
|
||||||
#endif
|
#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 *p = (const u8 *)input;
|
||||||
const u8 *const bEnd = p + len;
|
const u8 *const bEnd = p + len;
|
||||||
U32 h32;
|
U32 h32;
|
||||||
|
|
|
@ -19,4 +19,4 @@
|
||||||
|
|
||||||
u32 QuickTexHashNEON(const void *checkp, u32 size);
|
u32 QuickTexHashNEON(const void *checkp, u32 size);
|
||||||
void DoUnswizzleTex16NEON(const u8 *texptr, u32 *ydestp, int bxc, int byc, u32 pitch, u32 rowWidth);
|
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);
|
||||||
|
|
|
@ -798,7 +798,7 @@ void TextureCacheDX9::UpdateCurrentClut() {
|
||||||
// If not, we're going to hash random data, which hopefully doesn't cause a performance issue.
|
// If not, we're going to hash random data, which hopefully doesn't cause a performance issue.
|
||||||
const u32 clutExtendedBytes = clutTotalBytes_ + clutBaseBytes;
|
const u32 clutExtendedBytes = clutTotalBytes_ + clutBaseBytes;
|
||||||
|
|
||||||
clutHash_ = DoReliableHash((const char *)clutBufRaw_, clutExtendedBytes, 0xC0108888);
|
clutHash_ = DoReliableHash32((const char *)clutBufRaw_, clutExtendedBytes, 0xC0108888);
|
||||||
clutBuf_ = clutBufRaw_;
|
clutBuf_ = clutBufRaw_;
|
||||||
|
|
||||||
// Special optimization: fonts typically draw clut4 with just alpha values in a single color.
|
// Special optimization: fonts typically draw clut4 with just alpha values in a single color.
|
||||||
|
|
|
@ -462,7 +462,7 @@ inline u32 ComputeMiniHashRange(const void *ptr, size_t sz) {
|
||||||
size_t step = sz / 4;
|
size_t step = sz / 4;
|
||||||
u32 hash = 0;
|
u32 hash = 0;
|
||||||
for (size_t i = 0; i < sz; i += step) {
|
for (size_t i = 0; i < sz; i += step) {
|
||||||
hash += DoReliableHash(p + i, 100, 0x3A44B9C4);
|
hash += DoReliableHash32(p + i, 100, 0x3A44B9C4);
|
||||||
}
|
}
|
||||||
return hash;
|
return hash;
|
||||||
} else {
|
} else {
|
||||||
|
@ -509,8 +509,8 @@ void TransformDrawEngineDX9::MarkUnreliable(VertexArrayInfoDX9 *vai) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 TransformDrawEngineDX9::ComputeHash() {
|
ReliableHashType TransformDrawEngineDX9::ComputeHash() {
|
||||||
u32 fullhash = 0;
|
ReliableHashType fullhash = 0;
|
||||||
const int vertexSize = dec_->GetDecVtxFmt().stride;
|
const int vertexSize = dec_->GetDecVtxFmt().stride;
|
||||||
const int indexSize = (dec_->VertexType() & GE_VTYPE_IDX_MASK) == GE_VTYPE_IDX_16BIT ? 2 : 1;
|
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:
|
case VertexArrayInfoDX9::VAI_NEW:
|
||||||
{
|
{
|
||||||
// Haven't seen this one before.
|
// Haven't seen this one before.
|
||||||
u32 dataHash = ComputeHash();
|
ReliableHashType dataHash = ComputeHash();
|
||||||
vai->hash = dataHash;
|
vai->hash = dataHash;
|
||||||
vai->minihash = ComputeMiniHash();
|
vai->minihash = ComputeMiniHash();
|
||||||
vai->status = VertexArrayInfoDX9::VAI_HASHING;
|
vai->status = VertexArrayInfoDX9::VAI_HASHING;
|
||||||
|
@ -670,7 +670,7 @@ void TransformDrawEngineDX9::DoFlush() {
|
||||||
if (vai->drawsUntilNextFullHash == 0) {
|
if (vai->drawsUntilNextFullHash == 0) {
|
||||||
// Let's try to skip a full hash if mini would fail.
|
// Let's try to skip a full hash if mini would fail.
|
||||||
const u32 newMiniHash = ComputeMiniHash();
|
const u32 newMiniHash = ComputeMiniHash();
|
||||||
u32 newHash = vai->hash;
|
ReliableHashType newHash = vai->hash;
|
||||||
if (newMiniHash == vai->minihash) {
|
if (newMiniHash == vai->minihash) {
|
||||||
newHash = ComputeHash();
|
newHash = ComputeHash();
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,11 +51,12 @@ enum {
|
||||||
VAI_FLAG_VERTEXFULLALPHA = 1,
|
VAI_FLAG_VERTEXFULLALPHA = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Avoiding the full include of TextureDecoder.h.
|
||||||
// Don't bother storing information about draws smaller than this.
|
#ifdef _M_X64
|
||||||
enum {
|
typedef u64 ReliableHashType;
|
||||||
VERTEX_CACHE_THRESHOLD = 20,
|
#else
|
||||||
};
|
typedef u32 ReliableHashType;
|
||||||
|
#endif
|
||||||
|
|
||||||
// Try to keep this POD.
|
// Try to keep this POD.
|
||||||
class VertexArrayInfoDX9 {
|
class VertexArrayInfoDX9 {
|
||||||
|
@ -81,7 +82,7 @@ public:
|
||||||
VAI_UNRELIABLE, // never cache
|
VAI_UNRELIABLE, // never cache
|
||||||
};
|
};
|
||||||
|
|
||||||
u32 hash;
|
ReliableHashType hash;
|
||||||
u32 minihash;
|
u32 minihash;
|
||||||
|
|
||||||
Status status;
|
Status status;
|
||||||
|
@ -191,7 +192,7 @@ private:
|
||||||
IDirect3DVertexDeclaration9 *SetupDecFmtForDraw(VSShader *vshader, const DecVtxFormat &decFmt, u32 pspFmt);
|
IDirect3DVertexDeclaration9 *SetupDecFmtForDraw(VSShader *vshader, const DecVtxFormat &decFmt, u32 pspFmt);
|
||||||
|
|
||||||
u32 ComputeMiniHash();
|
u32 ComputeMiniHash();
|
||||||
u32 ComputeHash(); // Reads deferred vertex data.
|
ReliableHashType ComputeHash(); // Reads deferred vertex data.
|
||||||
void MarkUnreliable(VertexArrayInfoDX9 *vai);
|
void MarkUnreliable(VertexArrayInfoDX9 *vai);
|
||||||
|
|
||||||
VertexDecoder *GetVertexDecoder(u32 vtype);
|
VertexDecoder *GetVertexDecoder(u32 vtype);
|
||||||
|
|
|
@ -921,7 +921,7 @@ void TextureCache::UpdateCurrentClut() {
|
||||||
// If not, we're going to hash random data, which hopefully doesn't cause a performance issue.
|
// If not, we're going to hash random data, which hopefully doesn't cause a performance issue.
|
||||||
const u32 clutExtendedBytes = clutTotalBytes_ + clutBaseBytes;
|
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.
|
// Avoid a copy when we don't need to convert colors.
|
||||||
if (UseBGRA8888() || clutFormat != GE_CMODE_32BIT_ABGR8888) {
|
if (UseBGRA8888() || clutFormat != GE_CMODE_32BIT_ABGR8888) {
|
||||||
|
|
|
@ -444,7 +444,7 @@ inline u32 ComputeMiniHashRange(const void *ptr, size_t sz) {
|
||||||
size_t step = sz / 4;
|
size_t step = sz / 4;
|
||||||
u32 hash = 0;
|
u32 hash = 0;
|
||||||
for (size_t i = 0; i < sz; i += step) {
|
for (size_t i = 0; i < sz; i += step) {
|
||||||
hash += DoReliableHash(p + i, 100, 0x3A44B9C4);
|
hash += DoReliableHash32(p + i, 100, 0x3A44B9C4);
|
||||||
}
|
}
|
||||||
return hash;
|
return hash;
|
||||||
} else {
|
} else {
|
||||||
|
@ -491,8 +491,8 @@ void TransformDrawEngine::MarkUnreliable(VertexArrayInfo *vai) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 TransformDrawEngine::ComputeHash() {
|
ReliableHashType TransformDrawEngine::ComputeHash() {
|
||||||
u32 fullhash = 0;
|
ReliableHashType fullhash = 0;
|
||||||
const int vertexSize = dec_->GetDecVtxFmt().stride;
|
const int vertexSize = dec_->GetDecVtxFmt().stride;
|
||||||
const int indexSize = (dec_->VertexType() & GE_VTYPE_IDX_MASK) == GE_VTYPE_IDX_16BIT ? 2 : 1;
|
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:
|
case VertexArrayInfo::VAI_NEW:
|
||||||
{
|
{
|
||||||
// Haven't seen this one before.
|
// Haven't seen this one before.
|
||||||
u32 dataHash = ComputeHash();
|
ReliableHashType dataHash = ComputeHash();
|
||||||
vai->hash = dataHash;
|
vai->hash = dataHash;
|
||||||
vai->minihash = ComputeMiniHash();
|
vai->minihash = ComputeMiniHash();
|
||||||
vai->status = VertexArrayInfo::VAI_HASHING;
|
vai->status = VertexArrayInfo::VAI_HASHING;
|
||||||
|
@ -658,7 +658,7 @@ void TransformDrawEngine::DoFlush() {
|
||||||
if (vai->drawsUntilNextFullHash == 0) {
|
if (vai->drawsUntilNextFullHash == 0) {
|
||||||
// Let's try to skip a full hash if mini would fail.
|
// Let's try to skip a full hash if mini would fail.
|
||||||
const u32 newMiniHash = ComputeMiniHash();
|
const u32 newMiniHash = ComputeMiniHash();
|
||||||
u32 newHash = vai->hash;
|
ReliableHashType newHash = vai->hash;
|
||||||
if (newMiniHash == vai->minihash) {
|
if (newMiniHash == vai->minihash) {
|
||||||
newHash = ComputeHash();
|
newHash = ComputeHash();
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,6 +53,13 @@ enum {
|
||||||
VAI_FLAG_VERTEXFULLALPHA = 1,
|
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.
|
// Try to keep this POD.
|
||||||
class VertexArrayInfo {
|
class VertexArrayInfo {
|
||||||
public:
|
public:
|
||||||
|
@ -77,7 +84,7 @@ public:
|
||||||
VAI_UNRELIABLE, // never cache
|
VAI_UNRELIABLE, // never cache
|
||||||
};
|
};
|
||||||
|
|
||||||
u32 hash;
|
ReliableHashType hash;
|
||||||
u32 minihash;
|
u32 minihash;
|
||||||
|
|
||||||
Status status;
|
Status status;
|
||||||
|
@ -188,7 +195,7 @@ private:
|
||||||
void FreeBuffer(GLuint buf);
|
void FreeBuffer(GLuint buf);
|
||||||
|
|
||||||
u32 ComputeMiniHash();
|
u32 ComputeMiniHash();
|
||||||
u32 ComputeHash(); // Reads deferred vertex data.
|
ReliableHashType ComputeHash(); // Reads deferred vertex data.
|
||||||
void MarkUnreliable(VertexArrayInfo *vai);
|
void MarkUnreliable(VertexArrayInfo *vai);
|
||||||
|
|
||||||
VertexDecoder *GetVertexDecoder(u32 vtype);
|
VertexDecoder *GetVertexDecoder(u32 vtype);
|
||||||
|
|
Loading…
Add table
Reference in a new issue