From f2673c8f7bc41bd351a490196e45566edc9c83a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 12 Mar 2023 10:17:46 +0100 Subject: [PATCH] Change BGRA to be a texture-specific flag. Fixes R/B swap in DDS textures in D3D11. --- GPU/Common/ReplacedTexture.cpp | 2 +- GPU/Common/TextureCacheCommon.cpp | 11 +++++++---- GPU/Common/TextureCacheCommon.h | 3 +-- GPU/D3D11/TextureCacheD3D11.cpp | 7 ++++++- GPU/Directx9/TextureCacheDX9.cpp | 8 ++++++-- 5 files changed, 21 insertions(+), 10 deletions(-) diff --git a/GPU/Common/ReplacedTexture.cpp b/GPU/Common/ReplacedTexture.cpp index 9340ec4ed8..c6cd617fb5 100644 --- a/GPU/Common/ReplacedTexture.cpp +++ b/GPU/Common/ReplacedTexture.cpp @@ -254,7 +254,7 @@ bool ReplacedTexture::LoadLevelData(ReplacedTextureLevel &level, int mipLevel, D u32 format; if (good && (header.ddspf.dwFlags & DDPF_FOURCC)) { char *fcc = (char *)&header.ddspf.dwFourCC; - INFO_LOG(G3D, "DDS fourcc: %c%c%c%c", fcc[0], fcc[1], fcc[2], fcc[3]); + // INFO_LOG(G3D, "DDS fourcc: %c%c%c%c", fcc[0], fcc[1], fcc[2], fcc[3]); if (header.ddspf.dwFourCC == MK_FOURCC("DX10")) { ddsDX10 = true; good = good && vfs_->Read(openFile, &header10, sizeof(header10)) == sizeof(header10); diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index 3a7d149cba..9410fdb813 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -447,11 +447,9 @@ TexCacheEntry *TextureCacheCommon::SetTexture() { gstate_c.SetNeedShaderTexclamp(false); gstate_c.skipDrawReason &= ~SKIPDRAW_BAD_FB_TEXTURE; - bool isBgraTexture = isBgraBackend_ && !hasClutGPU; - gstate_c.SetTextureIsBGRA(isBgraTexture); - if (entryIter != cache_.end()) { entry = entryIter->second.get(); + // Validate the texture still matches the cache entry. bool match = entry->Matches(dim, texFormat, maxLevel); const char *reason = "different params"; @@ -540,7 +538,7 @@ TexCacheEntry *TextureCacheCommon::SetTexture() { switch (replaced->State()) { case ReplacementState::NOT_FOUND: // Didn't find a replacement, so stop looking. - WARN_LOG(G3D, "No replacement for texture %dx%d", w0, h0); + // DEBUG_LOG(G3D, "No replacement for texture %dx%d", w0, h0); entry->status &= ~TexCacheEntry::STATUS_TO_REPLACE; if (g_Config.bSaveNewTextures) { // Load it once more to actually save it. Since we don't set STATUS_TO_REPLACE, we won't end up looping. @@ -567,6 +565,8 @@ TexCacheEntry *TextureCacheCommon::SetTexture() { gstate_c.curTextureHeight = h; gstate_c.SetTextureIs3D((entry->status & TexCacheEntry::STATUS_3D) != 0); gstate_c.SetTextureIsArray(false); + gstate_c.SetTextureIsBGRA((entry->status & TexCacheEntry::STATUS_BGRA) != 0); + if (rehash) { // Update in case any of these changed. entry->sizeInRAM = (textureBitsPerPixel[texFormat] * bufw * h / 2) / 8; @@ -661,6 +661,7 @@ TexCacheEntry *TextureCacheCommon::SetTexture() { entry->dim = dim; entry->format = texFormat; entry->maxLevel = maxLevel; + entry->status &= ~TexCacheEntry::STATUS_BGRA; // This would overestimate the size in many case so we underestimate instead // to avoid excessive clearing caused by cache invalidations. @@ -2119,12 +2120,14 @@ void TextureCacheCommon::ApplyTexture() { gstate_c.SetTextureFullAlpha(false); gstate_c.SetTextureIs3D(false); gstate_c.SetTextureIsArray(false); + gstate_c.SetTextureIsBGRA(false); } else { entry->lastFrame = gpuStats.numFlips; BindTexture(entry); gstate_c.SetTextureFullAlpha(entry->GetAlphaStatus() == TexCacheEntry::STATUS_ALPHA_FULL); gstate_c.SetTextureIs3D((entry->status & TexCacheEntry::STATUS_3D) != 0); gstate_c.SetTextureIsArray(false); + gstate_c.SetTextureIsBGRA((entry->status & TexCacheEntry::STATUS_BGRA) != 0); } } diff --git a/GPU/Common/TextureCacheCommon.h b/GPU/Common/TextureCacheCommon.h index ff44e35664..f50b042d89 100644 --- a/GPU/Common/TextureCacheCommon.h +++ b/GPU/Common/TextureCacheCommon.h @@ -151,6 +151,7 @@ struct TexCacheEntry { STATUS_CLUT_GPU = 0x8000, STATUS_VIDEO = 0x10000, + STATUS_BGRA = 0x20000, }; // TexStatus enum flag combination. @@ -511,8 +512,6 @@ protected: bool nextNeedsChange_; bool nextNeedsRebuild_; - bool isBgraBackend_ = false; - u32 *expandClut_; }; diff --git a/GPU/D3D11/TextureCacheD3D11.cpp b/GPU/D3D11/TextureCacheD3D11.cpp index 2c73ab0054..487e4337ac 100644 --- a/GPU/D3D11/TextureCacheD3D11.cpp +++ b/GPU/D3D11/TextureCacheD3D11.cpp @@ -148,7 +148,6 @@ TextureCacheD3D11::TextureCacheD3D11(Draw::DrawContext *draw, Draw2D *draw2D) device_ = (ID3D11Device *)draw->GetNativeObject(Draw::NativeObject::DEVICE); context_ = (ID3D11DeviceContext *)draw->GetNativeObject(Draw::NativeObject::CONTEXT); - isBgraBackend_ = true; lastBoundTexture = INVALID_TEX; D3D11_BUFFER_DESC desc{ sizeof(DepthPushConstants), D3D11_USAGE_DYNAMIC, D3D11_BIND_CONSTANT_BUFFER, D3D11_CPU_ACCESS_WRITE }; @@ -414,6 +413,12 @@ void TextureCacheD3D11::BuildTexture(TexCacheEntry *const entry) { if (plan.replaceValid) { entry->SetAlphaStatus(TexCacheEntry::TexStatus(plan.replaced->AlphaStatus())); + + if (!Draw::DataFormatIsBlockCompressed(plan.replaced->Format(), nullptr)) { + entry->status |= TexCacheEntry::STATUS_BGRA; + } + } else { + entry->status |= TexCacheEntry::STATUS_BGRA; } } diff --git a/GPU/Directx9/TextureCacheDX9.cpp b/GPU/Directx9/TextureCacheDX9.cpp index dc1ed423d6..7ded196c82 100644 --- a/GPU/Directx9/TextureCacheDX9.cpp +++ b/GPU/Directx9/TextureCacheDX9.cpp @@ -71,8 +71,6 @@ static const D3DVERTEXELEMENT9 g_FramebufferVertexElements[] = { TextureCacheDX9::TextureCacheDX9(Draw::DrawContext *draw, Draw2D *draw2D) : TextureCacheCommon(draw, draw2D) { lastBoundTexture = INVALID_TEX; - isBgraBackend_ = true; - device_ = (LPDIRECT3DDEVICE9)draw->GetNativeObject(Draw::NativeObject::DEVICE); deviceEx_ = (LPDIRECT3DDEVICE9EX)draw->GetNativeObject(Draw::NativeObject::DEVICE_EX); D3DCAPS9 pCaps; @@ -322,6 +320,12 @@ void TextureCacheDX9::BuildTexture(TexCacheEntry *const entry) { if (plan.replaceValid) { entry->SetAlphaStatus(TexCacheEntry::TexStatus(plan.replaced->AlphaStatus())); + + if (!Draw::DataFormatIsBlockCompressed(plan.replaced->Format(), nullptr)) { + entry->status |= TexCacheEntry::STATUS_BGRA; + } + } else { + entry->status |= TexCacheEntry::STATUS_BGRA; } }