mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Merge pull request #9500 from unknownbrackets/texcache
Texcache: Rehash textures after mem invalidation
This commit is contained in:
commit
43d0a2bcf0
6 changed files with 32 additions and 20 deletions
|
@ -219,7 +219,6 @@ void TextureCacheCommon::SetTexture(bool force) {
|
|||
if (!Memory::IsValidAddress(texaddr)) {
|
||||
// Bind a null texture and return.
|
||||
Unbind();
|
||||
InvalidateLastTexture();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -482,7 +481,7 @@ bool TextureCacheCommon::HandleTextureChange(TexCacheEntry *const entry, const c
|
|||
// Instead, let's use glTexSubImage to replace the images.
|
||||
replaceImages = true;
|
||||
} else {
|
||||
InvalidateLastTexture(entry);
|
||||
InvalidateLastTexture();
|
||||
ReleaseTexture(entry, true);
|
||||
entry->status &= ~TexCacheEntry::STATUS_IS_SCALED;
|
||||
}
|
||||
|
@ -1498,16 +1497,28 @@ bool TextureCacheCommon::CheckFullHash(TexCacheEntry *entry, bool &doDelete) {
|
|||
}
|
||||
|
||||
void TextureCacheCommon::Invalidate(u32 addr, int size, GPUInvalidationType type) {
|
||||
// They could invalidate inside the texture, let's just give a bit of leeway.
|
||||
const int LARGEST_TEXTURE_SIZE = 512 * 512 * 4;
|
||||
|
||||
addr &= 0x3FFFFFFF;
|
||||
const u32 addr_end = addr + size;
|
||||
|
||||
if (type == GPU_INVALIDATE_ALL) {
|
||||
// This is an active signal from the game that something in the texture cache may have changed.
|
||||
gstate_c.Dirty(DIRTY_TEXTURE_IMAGE);
|
||||
} else {
|
||||
// Do a quick check to see if the current texture is in range.
|
||||
const u32 currentAddr = gstate.getTextureAddress(0);
|
||||
if (addr_end >= currentAddr && addr < currentAddr + LARGEST_TEXTURE_SIZE) {
|
||||
gstate_c.Dirty(DIRTY_TEXTURE_IMAGE);
|
||||
}
|
||||
}
|
||||
|
||||
// If we're hashing every use, without backoff, then this isn't needed.
|
||||
if (!g_Config.bTextureBackoffCache) {
|
||||
return;
|
||||
}
|
||||
|
||||
addr &= 0x3FFFFFFF;
|
||||
const u32 addr_end = addr + size;
|
||||
|
||||
// They could invalidate inside the texture, let's just give a bit of leeway.
|
||||
const int LARGEST_TEXTURE_SIZE = 512 * 512 * 4;
|
||||
const u64 startKey = (u64)(addr - LARGEST_TEXTURE_SIZE) << 32;
|
||||
u64 endKey = (u64)(addr + size + LARGEST_TEXTURE_SIZE) << 32;
|
||||
if (endKey < startKey) {
|
||||
|
|
|
@ -143,7 +143,7 @@ void TextureCacheD3D11::ReleaseTexture(TexCacheEntry *entry, bool delete_them) {
|
|||
}
|
||||
|
||||
void TextureCacheD3D11::ForgetLastTexture() {
|
||||
lastBoundTexture = INVALID_TEX;
|
||||
InvalidateLastTexture();
|
||||
gstate_c.Dirty(DIRTY_TEXTURE_PARAMS);
|
||||
ID3D11ShaderResourceView *nullTex = nullptr;
|
||||
context_->PSSetShaderResources(0, 1, &nullTex);
|
||||
|
@ -201,7 +201,7 @@ void TextureCacheD3D11::SetFramebufferSamplingParams(u16 bufferWidth, u16 buffer
|
|||
}
|
||||
|
||||
void TextureCacheD3D11::StartFrame() {
|
||||
lastBoundTexture = INVALID_TEX;
|
||||
InvalidateLastTexture();
|
||||
timesInvalidatedAllThisFrame_ = 0;
|
||||
|
||||
if (texelsScaledThisFrame_) {
|
||||
|
@ -264,6 +264,7 @@ void TextureCacheD3D11::BindTexture(TexCacheEntry *entry) {
|
|||
void TextureCacheD3D11::Unbind() {
|
||||
ID3D11ShaderResourceView *nullView = nullptr;
|
||||
context_->PSSetShaderResources(0, 1, &nullView);
|
||||
InvalidateLastTexture();
|
||||
}
|
||||
|
||||
class TextureShaderApplierD3D11 {
|
||||
|
@ -438,7 +439,7 @@ void TextureCacheD3D11::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFra
|
|||
SetFramebufferSamplingParams(framebuffer->bufferWidth, framebuffer->bufferHeight, samplerKey);
|
||||
ID3D11SamplerState *state = samplerCache_.GetOrCreateSampler(device_, samplerKey);
|
||||
context_->PSSetSamplers(0, 1, &state);
|
||||
lastBoundTexture = INVALID_TEX;
|
||||
InvalidateLastTexture();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -96,7 +96,7 @@ void TextureCacheDX9::ReleaseTexture(TexCacheEntry *entry, bool delete_them) {
|
|||
}
|
||||
|
||||
void TextureCacheDX9::ForgetLastTexture() {
|
||||
lastBoundTexture = INVALID_TEX;
|
||||
InvalidateLastTexture();
|
||||
gstate_c.Dirty(DIRTY_TEXTURE_PARAMS);
|
||||
}
|
||||
|
||||
|
@ -213,7 +213,7 @@ void TextureCacheDX9::SetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHe
|
|||
}
|
||||
|
||||
void TextureCacheDX9::StartFrame() {
|
||||
lastBoundTexture = INVALID_TEX;
|
||||
InvalidateLastTexture();
|
||||
timesInvalidatedAllThisFrame_ = 0;
|
||||
|
||||
if (texelsScaledThisFrame_) {
|
||||
|
@ -279,6 +279,7 @@ void TextureCacheDX9::BindTexture(TexCacheEntry *entry) {
|
|||
|
||||
void TextureCacheDX9::Unbind() {
|
||||
device_->SetTexture(0, NULL);
|
||||
InvalidateLastTexture();
|
||||
}
|
||||
|
||||
class TextureShaderApplierDX9 {
|
||||
|
@ -458,7 +459,7 @@ void TextureCacheDX9::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFrame
|
|||
framebufferManagerDX9_->RebindFramebuffer();
|
||||
SetFramebufferSamplingParams(framebuffer->bufferWidth, framebuffer->bufferHeight);
|
||||
|
||||
lastBoundTexture = INVALID_TEX;
|
||||
InvalidateLastTexture();
|
||||
}
|
||||
|
||||
void TextureCacheDX9::BuildTexture(TexCacheEntry *const entry, bool replaceImages) {
|
||||
|
|
|
@ -340,6 +340,7 @@ void TextureCacheGLES::BindTexture(TexCacheEntry *entry) {
|
|||
|
||||
void TextureCacheGLES::Unbind() {
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
InvalidateLastTexture();
|
||||
}
|
||||
|
||||
class TextureShaderApplier {
|
||||
|
@ -522,7 +523,7 @@ void TextureCacheGLES::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFram
|
|||
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
|
||||
lastBoundTexture = INVALID_TEX;
|
||||
InvalidateLastTexture();
|
||||
}
|
||||
|
||||
ReplacedTextureFormat FromGLESFormat(GLenum fmt, bool useBGRA = false) {
|
||||
|
|
|
@ -1542,13 +1542,9 @@ void GPUCommon::Execute_BoundingBox(u32 op, u32 diff) {
|
|||
}
|
||||
|
||||
void GPUCommon::Execute_BlockTransferStart(u32 op, u32 diff) {
|
||||
// TODO: Here we should check if the transfer overlaps a framebuffer or any textures,
|
||||
// and take appropriate action. This is a block transfer between RAM and VRAM, or vice versa.
|
||||
// Can we skip this on SkipDraw?
|
||||
DoBlockTransfer(gstate_c.skipDrawReason);
|
||||
|
||||
// Fixes Gran Turismo's funky text issue, since it overwrites the current texture.
|
||||
gstate_c.Dirty(DIRTY_TEXTURE_IMAGE);
|
||||
}
|
||||
|
||||
void GPUCommon::Execute_WorldMtxNum(u32 op, u32 diff) {
|
||||
|
@ -2285,6 +2281,7 @@ void GPUCommon::DoBlockTransfer(u32 skipDrawReason) {
|
|||
}
|
||||
}
|
||||
|
||||
// Fixes Gran Turismo's funky text issue, since it overwrites the current texture.
|
||||
textureCache_->Invalidate(dstBasePtr + (dstY * dstStride + dstX) * bpp, height * dstStride * bpp, GPU_INVALIDATE_HINT);
|
||||
framebufferManager_->NotifyBlockTransferAfter(dstBasePtr, dstStride, dstX, dstY, srcBasePtr, srcStride, srcX, srcY, width, height, bpp, skipDrawReason);
|
||||
}
|
||||
|
|
|
@ -271,7 +271,7 @@ void TextureCacheVulkan::SetFramebufferSamplingParams(u16 bufferWidth, u16 buffe
|
|||
}
|
||||
|
||||
void TextureCacheVulkan::StartFrame() {
|
||||
lastBoundTexture = nullptr;
|
||||
InvalidateLastTexture();
|
||||
timesInvalidatedAllThisFrame_ = 0;
|
||||
texelsScaledThisFrame_ = 0;
|
||||
|
||||
|
@ -342,6 +342,7 @@ void TextureCacheVulkan::BindTexture(TexCacheEntry *entry) {
|
|||
void TextureCacheVulkan::Unbind() {
|
||||
imageView_ = VK_NULL_HANDLE;
|
||||
sampler_ = VK_NULL_HANDLE;
|
||||
InvalidateLastTexture();
|
||||
}
|
||||
|
||||
void TextureCacheVulkan::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFramebuffer *framebuffer) {
|
||||
|
@ -452,7 +453,7 @@ void TextureCacheVulkan::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFr
|
|||
key.mipEnable = false;
|
||||
sampler_ = samplerCache_.GetOrCreateSampler(key);
|
||||
|
||||
lastBoundTexture = nullptr;
|
||||
InvalidateLastTexture();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue