Merge pull request #9668 from LunaMoo/featureTR

Add "ignoreAddress" to texture replacement.
This commit is contained in:
Henrik Rydgård 2017-06-04 12:01:23 +02:00 committed by GitHub
commit af1801af54
2 changed files with 57 additions and 7 deletions

View file

@ -35,7 +35,7 @@ static const std::string NEW_TEXTURE_DIR = "new/";
static const int VERSION = 1;
static const int MAX_MIP_LEVELS = 64;
TextureReplacer::TextureReplacer() : enabled_(false), allowVideo_(false), hash_(ReplacedTextureHash::QUICK) {
TextureReplacer::TextureReplacer() : enabled_(false), allowVideo_(false), ignoreAddress_(false), hash_(ReplacedTextureHash::QUICK) {
none_.alphaStatus_ = ReplacedTextureAlpha::UNKNOWN;
}
@ -85,12 +85,27 @@ bool TextureReplacer::LoadIni() {
// TODO: crc32c.
if (strcasecmp(hash.c_str(), "quick") == 0) {
hash_ = ReplacedTextureHash::QUICK;
} else if (strcasecmp(hash.c_str(), "xxh32") == 0) {
hash_ = ReplacedTextureHash::XXH32;
} else if (strcasecmp(hash.c_str(), "xxh64") == 0) {
hash_ = ReplacedTextureHash::XXH64;
} else {
ERROR_LOG(G3D, "Unsupported hash type: %s", hash.c_str());
return false;
}
options->Get("video", &allowVideo_, false);
options->Get("ignoreAddress", &ignoreAddress_, false);
options->Get("reduceHash", &reduceHash_, false); // Multiplies sizeInRAM/bytesPerLine in XXHASH by 0.5
if (reduceHash_ && hash_ == ReplacedTextureHash::QUICK) {
reduceHash_ = false;
ERROR_LOG(G3D, "Texture Replacement: reduceHash option requires safer hash, use xxh32 or xxh64 instead.");
}
if (ignoreAddress_ && hash_ == ReplacedTextureHash::QUICK) {
ignoreAddress_ = false;
ERROR_LOG(G3D, "Texture Replacement: ignoreAddress option requires safer hash, use xxh32 or xxh64 instead.");
}
int version = 0;
if (options->Get("version", &version, 0) && version > VERSION) {
@ -174,20 +189,27 @@ u32 TextureReplacer::ComputeHash(u32 addr, int bufw, int w, int h, GETextureForm
}
const u8 *checkp = Memory::GetPointer(addr);
float reduceHashSize = 1.0;
if (reduceHash_)
reduceHashSize = 0.5;
if (bufw <= w) {
// We can assume the data is contiguous. These are the total used pixels.
const u32 totalPixels = bufw * h + (w - bufw);
const u32 sizeInRAM = (textureBitsPerPixel[fmt] * totalPixels) / 8;
const u32 sizeInRAM = (textureBitsPerPixel[fmt] * totalPixels) / 8 * reduceHashSize;
switch (hash_) {
case ReplacedTextureHash::QUICK:
return StableQuickTexHash(checkp, sizeInRAM);
case ReplacedTextureHash::XXH32:
return DoReliableHash32(checkp, sizeInRAM, 0xBACD7814);
case ReplacedTextureHash::XXH64:
return DoReliableHash64(checkp, sizeInRAM, 0xBACD7814);
default:
return 0;
}
} else {
// We have gaps. Let's hash each row and sum.
const u32 bytesPerLine = (textureBitsPerPixel[fmt] * w) / 8;
const u32 bytesPerLine = (textureBitsPerPixel[fmt] * w) / 8 * reduceHashSize;
const u32 stride = (textureBitsPerPixel[fmt] * bufw) / 8;
u32 result = 0;
@ -200,6 +222,22 @@ u32 TextureReplacer::ComputeHash(u32 addr, int bufw, int w, int h, GETextureForm
}
break;
case ReplacedTextureHash::XXH32:
for (int y = 0; y < h; ++y) {
u32 rowHash = DoReliableHash32(checkp, bytesPerLine, 0xBACD7814);
result = (result * 11) ^ rowHash;
checkp += stride;
}
break;
case ReplacedTextureHash::XXH64:
for (int y = 0; y < h; ++y) {
u32 rowHash = DoReliableHash64(checkp, bytesPerLine, 0xBACD7814);
result = (result * 11) ^ rowHash;
checkp += stride;
}
break;
default:
break;
}
@ -232,6 +270,10 @@ void TextureReplacer::PopulateReplacement(ReplacedTexture *result, u64 cachekey,
int newH = h;
LookupHashRange(cachekey >> 32, newW, newH);
if (ignoreAddress_) {
cachekey = cachekey & 0xFFFFFFFFULL;
}
for (int i = 0; i < MAX_MIP_LEVELS; ++i) {
const std::string hashfile = LookupHashFile(cachekey, hash, i);
const std::string filename = basePath_ + hashfile;
@ -304,8 +346,12 @@ void TextureReplacer::NotifyTextureDecoded(const ReplacedTextureDecodeInfo &repl
if (replacedInfo.isVideo && !allowVideo_) {
return;
}
u64 cachekey = replacedInfo.cachekey;
if (ignoreAddress_) {
cachekey = cachekey & 0xFFFFFFFFULL;
}
std::string hashfile = LookupHashFile(replacedInfo.cachekey, replacedInfo.hash, level);
std::string hashfile = LookupHashFile(cachekey, replacedInfo.hash, level);
const std::string filename = basePath_ + hashfile;
const std::string saveFilename = basePath_ + NEW_TEXTURE_DIR + hashfile;
@ -315,7 +361,7 @@ void TextureReplacer::NotifyTextureDecoded(const ReplacedTextureDecodeInfo &repl
return;
}
ReplacementCacheKey replacementKey(replacedInfo.cachekey, replacedInfo.hash);
ReplacementCacheKey replacementKey(cachekey, replacedInfo.hash);
auto it = savedCache_.find(replacementKey);
if (it != savedCache_.end() && File::Exists(saveFilename)) {
// We've already saved this texture. Let's only save if it's bigger (e.g. scaled now.)
@ -419,7 +465,7 @@ std::string TextureReplacer::LookupHashFile(u64 cachekey, u32 hash, int level) {
key.hash = 0;
alias = aliases_.find(key);
if (alias == aliases_.end()) {
if (!ignoreAddress_ && alias == aliases_.end()) {
// No data hash.
key.cachekey = cachekey;
key.hash = 0;
@ -433,7 +479,7 @@ std::string TextureReplacer::LookupHashFile(u64 cachekey, u32 hash, int level) {
alias = aliases_.find(key);
}
if (alias == aliases_.end()) {
if (!ignoreAddress_ && alias == aliases_.end()) {
// Address, but not clut hash (in case of garbage clut data.)
key.cachekey = cachekey & ~0xFFFFFFFFULL;
key.hash = hash;

View file

@ -50,6 +50,8 @@ enum class ReplacedTextureAlpha {
enum class ReplacedTextureHash {
// TODO: Maybe only support crc32c for now?
QUICK,
XXH32,
XXH64,
};
struct ReplacedTextureLevel {
@ -196,6 +198,8 @@ protected:
SimpleBuf<u32> saveBuf;
bool enabled_;
bool allowVideo_;
bool ignoreAddress_;
bool reduceHash_;
std::string gameID_;
std::string basePath_;
ReplacedTextureHash hash_;