diff --git a/plugins/GSdx/GSTextureCache.cpp b/plugins/GSdx/GSTextureCache.cpp index 81d4406a8d..f17a313f51 100644 --- a/plugins/GSdx/GSTextureCache.cpp +++ b/plugins/GSdx/GSTextureCache.cpp @@ -128,7 +128,16 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const GIFRegTEX0& TEX0, con Target* t = *i; if(t->m_used && t->m_dirty.empty()) { - if (GSUtil::HasSharedBits(bp, psm, t->m_TEX0.TBP0, t->m_TEX0.PSM)) { + // Typical bug (MGS3 blue cloud): + // 1/ RT used as 32 bits => alpha channel written + // 2/ RT used as 24 bits => no update of alpha channel + // 3/ Lookup of texture that used alpha channel as index, HasSharedBits will return false + // because of the previous draw call format + // + // Solution: consider the RT as 32 bits if the alpha was used in the past + uint32 t_psm = (t->m_dirty_alpha) ? t->m_TEX0.PSM & ~0x1 : t->m_TEX0.PSM; + + if (GSUtil::HasSharedBits(bp, psm, t->m_TEX0.TBP0, t_psm)) { if (psm == PSM_PSMT8) { // It is a complex to convert the code in shader. As a reference, let's do it on the CPU, it will // be slow but @@ -243,6 +252,9 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(const GIFRegTEX0& TEX0, int GL_CACHE("TC: Lookup Target(%s) %dx%d, hit: %d (0x%x, F:0x%x)", to_string(type), w, h, dst->m_texture->GetID(), bp, TEX0.PSM); dst->Update(); + + dst->m_dirty_alpha |= (TEX0.PSM != PSM_PSMCT24) && (TEX0.PSM != PSM_PSMZ24); + } else if (CanConvertDepth()) { int rev_type = (type == DepthStencil) ? RenderTarget : DepthStencil; @@ -1303,6 +1315,7 @@ GSTextureCache::Target::Target(GSRenderer* r, const GIFRegTEX0& TEX0, uint8* tem { m_TEX0 = TEX0; m_32_bits_fmt |= !(TEX0.PSM & 2); + m_dirty_alpha = (TEX0.PSM != PSM_PSMCT24) && (TEX0.PSM != PSM_PSMZ24); m_valid = GSVector4i::zero(); } diff --git a/plugins/GSdx/GSTextureCache.h b/plugins/GSdx/GSTextureCache.h index dc679bf345..d3e2ff68f3 100644 --- a/plugins/GSdx/GSTextureCache.h +++ b/plugins/GSdx/GSTextureCache.h @@ -82,6 +82,7 @@ public: GSDirtyRectList m_dirty; GSVector4i m_valid; bool m_depth_supported; + bool m_dirty_alpha; public: Target(GSRenderer* r, const GIFRegTEX0& TEX0, uint8* temp, bool depth_supported);