mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-11-13 01:29:41 +01:00
d3d9: Move texture hashing after vertex decode.
This commit is contained in:
1 parent
4ce02e0920
commit
f1dda6a53d
2 files changed
+206
-135
No files matched your search
+197
-135
@@ -697,22 +697,61 @@ void TextureCacheDX9::SetTextureFramebuffer(TexCacheEntry *entry, VirtualFramebu
|
||||
}
|
||||
|
||||
void TextureCacheDX9::ApplyTexture() {
|
||||
if (nextTexture_ == nullptr) {
|
||||
TexCacheEntry *entry = nextTexture_;
|
||||
if (entry == nullptr) {
|
||||
return;
|
||||
}
|
||||
nextTexture_ = nullptr;
|
||||
|
||||
if (nextTexture_->framebuffer) {
|
||||
ApplyTextureFramebuffer(nextTexture_, nextTexture_->framebuffer);
|
||||
} else {
|
||||
UpdateMaxSeenV(nextTexture_, gstate.isModeThrough());
|
||||
UpdateMaxSeenV(entry, gstate.isModeThrough());
|
||||
|
||||
LPDIRECT3DTEXTURE9 texture = DxTex(nextTexture_);
|
||||
pD3Ddevice->SetTexture(0, texture);
|
||||
lastBoundTexture = texture;
|
||||
UpdateSamplingParams(*nextTexture_, false);
|
||||
bool replaceImages = false;
|
||||
if (nextNeedsRebuild_) {
|
||||
if (nextNeedsRehash_) {
|
||||
// Update the hash on the texture.
|
||||
int w = gstate.getTextureWidth(0);
|
||||
int h = gstate.getTextureHeight(0);
|
||||
entry->fullhash = QuickTexHash(replacer, entry->addr, entry->bufw, w, h, GETextureFormat(entry->format), entry);
|
||||
}
|
||||
if (nextNeedsChange_) {
|
||||
// This texture existed previously, let's handle the change.
|
||||
replaceImages = HandleTextureChange(entry, nextChangeReason_, false, true);
|
||||
}
|
||||
|
||||
// We actually build afterward (shared with rehash rebuild.)
|
||||
} else if (nextNeedsRehash_) {
|
||||
// Okay, this matched and didn't change - but let's check the hash. Maybe it will change.
|
||||
bool doDelete = true;
|
||||
if (!CheckFullHash(entry, doDelete)) {
|
||||
replaceImages = HandleTextureChange(entry, "hash fail", true, doDelete);
|
||||
nextNeedsRebuild_ = true;
|
||||
} else if (nextTexture_ != nullptr) {
|
||||
// Secondary cache picked a different texture, use it.
|
||||
entry = nextTexture_;
|
||||
nextTexture_ = nullptr;
|
||||
UpdateMaxSeenV(entry, gstate.isModeThrough());
|
||||
}
|
||||
}
|
||||
|
||||
nextTexture_ = nullptr;
|
||||
// Okay, now actually rebuild the texture if needed.
|
||||
if (nextNeedsRebuild_) {
|
||||
BuildTexture(entry, replaceImages);
|
||||
}
|
||||
|
||||
entry->lastFrame = gpuStats.numFlips;
|
||||
if (entry->framebuffer) {
|
||||
ApplyTextureFramebuffer(entry, entry->framebuffer);
|
||||
} else {
|
||||
LPDIRECT3DTEXTURE9 texture = DxTex(entry);
|
||||
if (texture != lastBoundTexture) {
|
||||
pD3Ddevice->SetTexture(0, texture);
|
||||
lastBoundTexture = texture;
|
||||
}
|
||||
UpdateSamplingParams(*entry, false);
|
||||
|
||||
gstate_c.textureFullAlpha = entry->GetAlphaStatus() == TexCacheEntry::STATUS_ALPHA_FULL;
|
||||
gstate_c.textureSimpleAlpha = entry->GetAlphaStatus() != TexCacheEntry::STATUS_ALPHA_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
void TextureCacheDX9::DownloadFramebufferForClut(u32 clutAddr, u32 bytes) {
|
||||
@@ -909,7 +948,6 @@ bool TextureCacheDX9::SetOffsetTexture(u32 offset) {
|
||||
|
||||
if (success && entry->framebuffer) {
|
||||
SetTextureFramebuffer(entry, entry->framebuffer);
|
||||
entry->lastFrame = gpuStats.numFlips;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -966,7 +1004,6 @@ void TextureCacheDX9::SetTexture(bool force) {
|
||||
u8 maxLevel = gstate.getTextureMaxLevel();
|
||||
|
||||
u32 texhash = MiniHash((const u32 *)Memory::GetPointer(texaddr));
|
||||
u32 fullhash = 0;
|
||||
|
||||
TexCache::iterator iter = cache.find(cachekey);
|
||||
TexCacheEntry *entry = NULL;
|
||||
@@ -974,7 +1011,6 @@ void TextureCacheDX9::SetTexture(bool force) {
|
||||
gstate_c.bgraTexture = true;
|
||||
gstate_c.skipDrawReason &= ~SKIPDRAW_BAD_FB_TEXTURE;
|
||||
bool useBufferedRendering = g_Config.iRenderingMode != FB_NON_BUFFERED_MODE;
|
||||
bool replaceImages = false;
|
||||
|
||||
if (iter != cache.end()) {
|
||||
entry = &iter->second;
|
||||
@@ -990,7 +1026,6 @@ void TextureCacheDX9::SetTexture(bool force) {
|
||||
}
|
||||
|
||||
SetTextureFramebuffer(entry, entry->framebuffer);
|
||||
entry->lastFrame = gpuStats.numFlips;
|
||||
return;
|
||||
} else {
|
||||
// Make sure we re-evaluate framebuffers.
|
||||
@@ -1001,7 +1036,6 @@ void TextureCacheDX9::SetTexture(bool force) {
|
||||
}
|
||||
|
||||
bool rehash = entry->GetHashStatus() == TexCacheEntry::STATUS_UNRELIABLE;
|
||||
bool doDelete = true;
|
||||
|
||||
// First let's see if another texture with the same address had a hashfail.
|
||||
if (entry->status & TexCacheEntry::STATUS_CLUT_RECHECK) {
|
||||
@@ -1038,67 +1072,10 @@ void TextureCacheDX9::SetTexture(bool force) {
|
||||
rehash = true;
|
||||
}
|
||||
|
||||
bool hashFail = false;
|
||||
if (texhash != entry->hash) {
|
||||
fullhash = QuickTexHash(replacer, texaddr, bufw, w, h, format, entry);
|
||||
hashFail = true;
|
||||
rehash = false;
|
||||
}
|
||||
|
||||
if (rehash && entry->GetHashStatus() != TexCacheEntry::STATUS_RELIABLE) {
|
||||
fullhash = QuickTexHash(replacer, texaddr, bufw, w, h, format, entry);
|
||||
if (fullhash != entry->fullhash) {
|
||||
hashFail = true;
|
||||
} else {
|
||||
if (g_Config.bTextureBackoffCache) {
|
||||
if (entry->GetHashStatus() != TexCacheEntry::STATUS_HASHING && entry->numFrames > TexCacheEntry::FRAMES_REGAIN_TRUST) {
|
||||
// Reset to STATUS_HASHING.
|
||||
entry->SetHashStatus(TexCacheEntry::STATUS_HASHING);
|
||||
entry->status &= ~TexCacheEntry::STATUS_CHANGE_FREQUENT;
|
||||
}
|
||||
} else if (entry->numFrames > TEXCACHE_FRAME_CHANGE_FREQUENT_REGAIN_TRUST) {
|
||||
entry->status &= ~TexCacheEntry::STATUS_CHANGE_FREQUENT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hashFail) {
|
||||
match = false;
|
||||
reason = "hash fail";
|
||||
entry->status |= TexCacheEntry::STATUS_UNRELIABLE;
|
||||
if (entry->numFrames < TEXCACHE_FRAME_CHANGE_FREQUENT) {
|
||||
if (entry->status & TexCacheEntry::STATUS_FREE_CHANGE) {
|
||||
entry->status &= ~TexCacheEntry::STATUS_FREE_CHANGE;
|
||||
} else {
|
||||
entry->status |= TexCacheEntry::STATUS_CHANGE_FREQUENT;
|
||||
}
|
||||
}
|
||||
entry->numFrames = 0;
|
||||
|
||||
// Don't give up just yet. Let's try the secondary cache if it's been invalidated before.
|
||||
// If it's failed a bunch of times, then the second cache is just wasting time and VRAM.
|
||||
if (g_Config.bTextureSecondaryCache) {
|
||||
if (entry->numInvalidated > 2 && entry->numInvalidated < 128 && !lowMemoryMode_) {
|
||||
u64 secondKey = fullhash | (u64)cluthash << 32;
|
||||
TexCache::iterator secondIter = secondCache.find(secondKey);
|
||||
if (secondIter != secondCache.end()) {
|
||||
TexCacheEntry *secondEntry = &secondIter->second;
|
||||
if (secondEntry->Matches(dim, format, maxLevel)) {
|
||||
// Reset the numInvalidated value lower, we got a match.
|
||||
if (entry->numInvalidated > 8) {
|
||||
--entry->numInvalidated;
|
||||
}
|
||||
entry = secondEntry;
|
||||
match = true;
|
||||
}
|
||||
} else {
|
||||
secondKey = entry->fullhash | ((u64)entry->cluthash << 32);
|
||||
secondCacheSizeEstimate_ += EstimateTexMemoryUsage(entry);
|
||||
secondCache[secondKey] = *entry;
|
||||
doDelete = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (entry->GetHashStatus() == TexCacheEntry::STATUS_RELIABLE) {
|
||||
rehash = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1113,48 +1090,27 @@ void TextureCacheDX9::SetTexture(bool force) {
|
||||
if (match) {
|
||||
// TODO: Mark the entry reliable if it's been safe for long enough?
|
||||
//got one!
|
||||
entry->lastFrame = gpuStats.numFlips;
|
||||
LPDIRECT3DTEXTURE9 texture = DxTex(entry);
|
||||
if (texture != lastBoundTexture) {
|
||||
nextTexture_ = entry;
|
||||
gstate_c.textureFullAlpha = entry->GetAlphaStatus() == TexCacheEntry::STATUS_ALPHA_FULL;
|
||||
gstate_c.textureSimpleAlpha = entry->GetAlphaStatus() != TexCacheEntry::STATUS_ALPHA_UNKNOWN;
|
||||
if (entry->texturePtr != lastBoundTexture) {
|
||||
gstate_c.curTextureWidth = w;
|
||||
gstate_c.curTextureHeight = h;
|
||||
}
|
||||
UpdateSamplingParams(*entry, false);
|
||||
if (rehash) {
|
||||
// Update in case any of these changed.
|
||||
entry->sizeInRAM = (textureBitsPerPixel[format] * bufw * h / 2) / 8;
|
||||
entry->bufw = bufw;
|
||||
entry->cluthash = cluthash;
|
||||
}
|
||||
|
||||
nextTexture_ = entry;
|
||||
nextNeedsRehash_ = rehash;
|
||||
nextNeedsChange_ = false;
|
||||
// Might need a rebuild if the hash fails.
|
||||
nextNeedsRebuild_= false;
|
||||
VERBOSE_LOG(G3D, "Texture at %08x Found in Cache, applying", texaddr);
|
||||
return; //Done!
|
||||
} else {
|
||||
cacheSizeEstimate_ -= EstimateTexMemoryUsage(entry);
|
||||
entry->numInvalidated++;
|
||||
gpuStats.numTextureInvalidations++;
|
||||
DEBUG_LOG(G3D, "Texture different or overwritten, reloading at %08x: %s", texaddr, reason);
|
||||
if (doDelete) {
|
||||
if (entry->maxLevel == maxLevel && entry->dim == gstate.getTextureDimension(0) && entry->format == format && standardScaleFactor_ == 1) {
|
||||
// Actually, if size and number of levels match, let's try to avoid deleting and recreating.
|
||||
// Instead, let's use glTexSubImage to replace the images.
|
||||
replaceImages = true;
|
||||
} else {
|
||||
if (entry->texturePtr == lastBoundTexture) {
|
||||
lastBoundTexture = INVALID_TEX;
|
||||
}
|
||||
ReleaseTexture(entry);
|
||||
}
|
||||
}
|
||||
// Clear the reliable bit if set.
|
||||
if (entry->GetHashStatus() == TexCacheEntry::STATUS_RELIABLE) {
|
||||
entry->SetHashStatus(TexCacheEntry::STATUS_HASHING);
|
||||
}
|
||||
|
||||
// Also, mark any textures with the same address but different clut. They need rechecking.
|
||||
if (cluthash != 0) {
|
||||
const u64 cachekeyMin = (u64)(texaddr & 0x3FFFFFFF) << 32;
|
||||
const u64 cachekeyMax = cachekeyMin + (1ULL << 32);
|
||||
for (auto it = cache.lower_bound(cachekeyMin), end = cache.upper_bound(cachekeyMax); it != end; ++it) {
|
||||
if (it->second.cluthash != cluthash) {
|
||||
it->second.status |= TexCacheEntry::STATUS_CLUT_RECHECK;
|
||||
}
|
||||
}
|
||||
}
|
||||
nextChangeReason_ = reason;
|
||||
nextNeedsChange_ = true;
|
||||
}
|
||||
} else {
|
||||
VERBOSE_LOG(G3D, "No texture in cache, decoding...");
|
||||
@@ -1171,36 +1127,136 @@ void TextureCacheDX9::SetTexture(bool force) {
|
||||
} else {
|
||||
entry->status = TexCacheEntry::STATUS_UNRELIABLE;
|
||||
}
|
||||
}
|
||||
|
||||
if ((bufw == 0 || (gstate.texbufwidth[0] & 0xf800) != 0) && texaddr >= PSP_GetKernelMemoryEnd()) {
|
||||
ERROR_LOG_REPORT(G3D, "Texture with unexpected bufw (full=%d)", gstate.texbufwidth[0] & 0xffff);
|
||||
nextNeedsChange_ = false;
|
||||
}
|
||||
|
||||
// We have to decode it, let's setup the cache entry first.
|
||||
entry->addr = texaddr;
|
||||
entry->hash = texhash;
|
||||
entry->format = format;
|
||||
entry->lastFrame = gpuStats.numFlips;
|
||||
entry->framebuffer = 0;
|
||||
entry->maxLevel = maxLevel;
|
||||
entry->lodBias = 0.0f;
|
||||
|
||||
entry->dim = dim;
|
||||
entry->bufw = bufw;
|
||||
entry->format = format;
|
||||
entry->maxLevel = maxLevel;
|
||||
|
||||
// This would overestimate the size in many case so we underestimate instead
|
||||
// to avoid excessive clearing caused by cache invalidations.
|
||||
entry->sizeInRAM = (textureBitsPerPixel[format] * bufw * h / 2) / 8;
|
||||
entry->bufw = bufw;
|
||||
|
||||
entry->fullhash = fullhash == 0 ? QuickTexHash(replacer, texaddr, bufw, w, h, format, entry) : fullhash;
|
||||
entry->cluthash = cluthash;
|
||||
|
||||
entry->status &= ~TexCacheEntry::STATUS_ALPHA_MASK;
|
||||
|
||||
gstate_c.curTextureWidth = w;
|
||||
gstate_c.curTextureHeight = h;
|
||||
|
||||
nextTexture_ = entry;
|
||||
nextNeedsRehash_ = true;
|
||||
nextNeedsRebuild_= true;
|
||||
}
|
||||
|
||||
bool TextureCacheDX9::CheckFullHash(TexCacheEntry *const entry, bool &doDelete) {
|
||||
bool hashFail = false;
|
||||
int w = gstate.getTextureWidth(0);
|
||||
int h = gstate.getTextureHeight(0);
|
||||
u32 fullhash = QuickTexHash(replacer, entry->addr, entry->bufw, w, h, GETextureFormat(entry->format), entry);
|
||||
if (fullhash != entry->fullhash) {
|
||||
hashFail = true;
|
||||
} else {
|
||||
if (g_Config.bTextureBackoffCache) {
|
||||
if (entry->GetHashStatus() != TexCacheEntry::STATUS_HASHING && entry->numFrames > TexCacheEntry::FRAMES_REGAIN_TRUST) {
|
||||
// Reset to STATUS_HASHING.
|
||||
entry->SetHashStatus(TexCacheEntry::STATUS_HASHING);
|
||||
entry->status &= ~TexCacheEntry::STATUS_CHANGE_FREQUENT;
|
||||
}
|
||||
} else if (entry->numFrames > TEXCACHE_FRAME_CHANGE_FREQUENT_REGAIN_TRUST) {
|
||||
entry->status &= ~TexCacheEntry::STATUS_CHANGE_FREQUENT;
|
||||
}
|
||||
}
|
||||
|
||||
if (hashFail) {
|
||||
entry->status |= TexCacheEntry::STATUS_UNRELIABLE;
|
||||
if (entry->numFrames < TEXCACHE_FRAME_CHANGE_FREQUENT) {
|
||||
if (entry->status & TexCacheEntry::STATUS_FREE_CHANGE) {
|
||||
entry->status &= ~TexCacheEntry::STATUS_FREE_CHANGE;
|
||||
} else {
|
||||
entry->status |= TexCacheEntry::STATUS_CHANGE_FREQUENT;
|
||||
}
|
||||
}
|
||||
entry->numFrames = 0;
|
||||
|
||||
// Don't give up just yet. Let's try the secondary cache if it's been invalidated before.
|
||||
// If it's failed a bunch of times, then the second cache is just wasting time and VRAM.
|
||||
if (g_Config.bTextureSecondaryCache) {
|
||||
if (entry->numInvalidated > 2 && entry->numInvalidated < 128 && !lowMemoryMode_) {
|
||||
u64 secondKey = fullhash | (u64)entry->cluthash << 32;
|
||||
TexCache::iterator secondIter = secondCache.find(secondKey);
|
||||
if (secondIter != secondCache.end()) {
|
||||
TexCacheEntry *secondEntry = &secondIter->second;
|
||||
if (secondEntry->Matches(entry->dim, entry->format, entry->maxLevel)) {
|
||||
// Reset the numInvalidated value lower, we got a match.
|
||||
if (entry->numInvalidated > 8) {
|
||||
--entry->numInvalidated;
|
||||
}
|
||||
nextTexture_ = secondEntry;
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
secondKey = entry->fullhash | ((u64)entry->cluthash << 32);
|
||||
secondCacheSizeEstimate_ += EstimateTexMemoryUsage(entry);
|
||||
secondCache[secondKey] = *entry;
|
||||
doDelete = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We know it failed, so update the full hash right away.
|
||||
entry->fullhash = fullhash;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TextureCacheDX9::HandleTextureChange(TexCacheEntry *const entry, const char *reason, bool initialMatch, bool doDelete) {
|
||||
bool replaceImages = false;
|
||||
|
||||
cacheSizeEstimate_ -= EstimateTexMemoryUsage(entry);
|
||||
entry->numInvalidated++;
|
||||
gpuStats.numTextureInvalidations++;
|
||||
DEBUG_LOG(G3D, "Texture different or overwritten, reloading at %08x: %s", entry->addr, reason);
|
||||
if (doDelete) {
|
||||
if (initialMatch && standardScaleFactor_ == 1) {
|
||||
// Actually, if size and number of levels match, let's try to avoid deleting and recreating.
|
||||
// Instead, let's use glTexSubImage to replace the images.
|
||||
replaceImages = true;
|
||||
} else {
|
||||
if (entry->texturePtr == lastBoundTexture) {
|
||||
lastBoundTexture = INVALID_TEX;
|
||||
}
|
||||
ReleaseTexture(entry);
|
||||
}
|
||||
}
|
||||
// Clear the reliable bit if set.
|
||||
if (entry->GetHashStatus() == TexCacheEntry::STATUS_RELIABLE) {
|
||||
entry->SetHashStatus(TexCacheEntry::STATUS_HASHING);
|
||||
}
|
||||
|
||||
// Also, mark any textures with the same address but different clut. They need rechecking.
|
||||
if (entry->cluthash != 0) {
|
||||
const u64 cachekeyMin = (u64)(entry->addr & 0x3FFFFFFF) << 32;
|
||||
const u64 cachekeyMax = cachekeyMin + (1ULL << 32);
|
||||
for (auto it = cache.lower_bound(cachekeyMin), end = cache.upper_bound(cachekeyMax); it != end; ++it) {
|
||||
if (it->second.cluthash != entry->cluthash) {
|
||||
it->second.status |= TexCacheEntry::STATUS_CLUT_RECHECK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return replaceImages;
|
||||
}
|
||||
|
||||
void TextureCacheDX9::BuildTexture(TexCacheEntry *const entry, bool replaceImages) {
|
||||
entry->status &= ~TexCacheEntry::STATUS_ALPHA_MASK;
|
||||
|
||||
// For the estimate, we assume cluts always point to 8888 for simplicity.
|
||||
cacheSizeEstimate_ += EstimateTexMemoryUsage(entry);
|
||||
|
||||
@@ -1208,6 +1264,7 @@ void TextureCacheDX9::SetTexture(bool force) {
|
||||
// Should just always create one here or something (like GLES.)
|
||||
|
||||
// Before we go reading the texture from memory, let's check for render-to-texture.
|
||||
entry->framebuffer = 0;
|
||||
for (size_t i = 0, n = fbCache_.size(); i < n; ++i) {
|
||||
auto framebuffer = fbCache_[i];
|
||||
AttachFramebuffer(entry, framebuffer->fb_address, framebuffer);
|
||||
@@ -1216,13 +1273,19 @@ void TextureCacheDX9::SetTexture(bool force) {
|
||||
// If we ended up with a framebuffer, attach it - no texture decoding needed.
|
||||
if (entry->framebuffer) {
|
||||
SetTextureFramebuffer(entry, entry->framebuffer);
|
||||
entry->lastFrame = gpuStats.numFlips;
|
||||
return;
|
||||
}
|
||||
|
||||
if ((entry->bufw == 0 || (gstate.texbufwidth[0] & 0xf800) != 0) && entry->addr >= PSP_GetKernelMemoryEnd()) {
|
||||
ERROR_LOG_REPORT(G3D, "Texture with unexpected bufw (full=%d)", gstate.texbufwidth[0] & 0xffff);
|
||||
// Proceeding here can cause a crash.
|
||||
return;
|
||||
}
|
||||
|
||||
// Adjust maxLevel to actually present levels..
|
||||
bool badMipSizes = false;
|
||||
for (u32 i = 0; i <= maxLevel; i++) {
|
||||
int maxLevel = entry->maxLevel;
|
||||
for (int i = 0; i <= maxLevel; i++) {
|
||||
// If encountering levels pointing to nothing, adjust max level.
|
||||
u32 levelTexaddr = gstate.getTextureAddress(i);
|
||||
if (!Memory::IsValidAddress(levelTexaddr)) {
|
||||
@@ -1230,7 +1293,7 @@ void TextureCacheDX9::SetTexture(bool force) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (i > 0) {
|
||||
if (i > 0 && gstate_c.Supports(GPU_SUPPORTS_TEXTURE_LOD_CONTROL)) {
|
||||
int tw = gstate.getTextureWidth(i);
|
||||
int th = gstate.getTextureHeight(i);
|
||||
if (tw != 1 && tw != (gstate.getTextureWidth(i - 1) >> 1))
|
||||
@@ -1246,7 +1309,7 @@ void TextureCacheDX9::SetTexture(bool force) {
|
||||
}
|
||||
|
||||
// If GLES3 is available, we can preallocate the storage, which makes texture loading more efficient.
|
||||
D3DFORMAT dstFmt = GetDestFormat(format, gstate.getClutPaletteFormat());
|
||||
D3DFORMAT dstFmt = GetDestFormat(GETextureFormat(entry->format), gstate.getClutPaletteFormat());
|
||||
|
||||
int scaleFactor = standardScaleFactor_;
|
||||
|
||||
@@ -1256,6 +1319,9 @@ void TextureCacheDX9::SetTexture(bool force) {
|
||||
scaleFactor = scaleFactor > 4 ? 4 : (scaleFactor > 2 ? 2 : 1);
|
||||
}
|
||||
|
||||
u64 cachekey = replacer.Enabled() ? entry->CacheKey() : 0;
|
||||
int w = gstate.getTextureWidth(0);
|
||||
int h = gstate.getTextureHeight(0);
|
||||
ReplacedTexture &replaced = replacer.FindReplacement(cachekey, entry->fullhash, w, h);
|
||||
if (replaced.GetSize(0, w, h)) {
|
||||
// We're replacing, so we won't scale.
|
||||
@@ -1302,7 +1368,7 @@ void TextureCacheDX9::SetTexture(bool force) {
|
||||
|
||||
// Mipmapping is only enabled when texture scaling is disabled.
|
||||
if (maxLevel > 0 && scaleFactor == 1) {
|
||||
for (u32 i = 1; i <= maxLevel; i++) {
|
||||
for (int i = 1; i <= maxLevel; i++) {
|
||||
LoadTextureLevel(*entry, replaced, i, maxLevel, replaceImages, scaleFactor, dstFmt);
|
||||
}
|
||||
}
|
||||
@@ -1311,11 +1377,7 @@ void TextureCacheDX9::SetTexture(bool force) {
|
||||
entry->SetAlphaStatus(TexCacheEntry::Status(replaced.AlphaStatus()));
|
||||
}
|
||||
|
||||
gstate_c.textureFullAlpha = entry->GetAlphaStatus() == TexCacheEntry::STATUS_ALPHA_FULL;
|
||||
gstate_c.textureSimpleAlpha = entry->GetAlphaStatus() != TexCacheEntry::STATUS_ALPHA_UNKNOWN;
|
||||
|
||||
nextTexture_ = entry;
|
||||
UpdateSamplingParams(*nextTexture_, true);
|
||||
UpdateSamplingParams(*entry, true);
|
||||
}
|
||||
|
||||
D3DFORMAT TextureCacheDX9::GetDestFormat(GETextureFormat format, GEPaletteFormat clutFormat) const {
|
||||
|
||||
Reference in new issue
Block a user