diff --git a/plugins/GSdx/GSClut.cpp b/plugins/GSdx/GSClut.cpp index 423957760d..582aff7af6 100644 --- a/plugins/GSdx/GSClut.cpp +++ b/plugins/GSdx/GSClut.cpp @@ -318,6 +318,73 @@ void GSClut::Read32(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) } } +void GSClut::GetAlphaMinMax32(int& amin, int& amax) +{ + // call only after Read32 + + ASSERT(!m_read.dirty); + + if(m_read.adirty) + { + m_read.adirty = false; + + if(GSLocalMemory::m_psm[m_read.TEX0.CPSM].trbpp == 24 && m_read.TEXA.AEM == 0) + { + m_read.amin = m_read.TEXA.TA0; + m_read.amax = m_read.TEXA.TA0; + } + else + { + const GSVector4i* p = (const GSVector4i*)m_buff32; + + GSVector4i amin, amax; + + if(GSLocalMemory::m_psm[m_read.TEX0.PSM].pal == 256) + { + amin = GSVector4i::xffffffff(); + amax = GSVector4i::zero(); + + for(int i = 0; i < 16; i++) + { + GSVector4i v0 = (p[i * 4 + 0] >> 24).ps32(p[i * 4 + 1] >> 24); + GSVector4i v1 = (p[i * 4 + 2] >> 24).ps32(p[i * 4 + 3] >> 24); + GSVector4i v2 = v0.pu16(v1); + + amin = amin.min_u8(v2); + amax = amax.max_u8(v2); + } + } + else + { + ASSERT(GSLocalMemory::m_psm[m_read.TEX0.PSM].pal == 16); + + GSVector4i v0 = (p[0] >> 24).ps32(p[1] >> 24); + GSVector4i v1 = (p[2] >> 24).ps32(p[3] >> 24); + GSVector4i v2 = v0.pu16(v1); + + amin = v2; + amax = v2; + } + + amin = amin.min_u8(amin.zwxy()); + amax = amax.max_u8(amax.zwxy()); + amin = amin.min_u8(amin.zwxyl()); + amax = amax.max_u8(amax.zwxyl()); + amin = amin.min_u8(amin.yxwzl()); + amax = amax.max_u8(amax.yxwzl()); + + GSVector4i v0 = amin.upl8(amax).u8to16(); + GSVector4i v1 = v0.yxwz(); + + m_read.amin = v0.min_i16(v1).extract16<0>(); + m_read.amax = v0.max_i16(v1).extract16<1>(); + } + } + + amin = m_read.amin; + amax = m_read.amax; +} + // void GSClut::WriteCLUT_T32_I8_CSM1(const uint32* RESTRICT src, uint16* RESTRICT clut) diff --git a/plugins/GSdx/GSClut.h b/plugins/GSdx/GSClut.h index 7ffde33c8e..081af13f54 100644 --- a/plugins/GSdx/GSClut.h +++ b/plugins/GSdx/GSClut.h @@ -101,6 +101,7 @@ public: void Write(const GIFRegTEX0& TEX0, const GIFRegTEXCLUT& TEXCLUT); void Read(const GIFRegTEX0& TEX0); void Read32(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA); + void GetAlphaMinMax32(int& amin, int& amax); uint32 operator [] (size_t i) const {return m_buff32[i];} diff --git a/plugins/GSdx/GSState.cpp b/plugins/GSdx/GSState.cpp index 08ea94425c..eac4dff1e8 100644 --- a/plugins/GSdx/GSState.cpp +++ b/plugins/GSdx/GSState.cpp @@ -2654,10 +2654,7 @@ void GSState::GetAlphaMinMax() if(PRIM->TME && context->TEX0.TCC) { - const GSLocalMemory::psm_t& psm = GSLocalMemory::m_psm[context->TEX0.PSM]; - const GSLocalMemory::psm_t& cpsm = psm.pal > 0 ? GSLocalMemory::m_psm[context->TEX0.CPSM] : psm; - - switch(cpsm.fmt) + switch(GSLocalMemory::m_psm[context->TEX0.PSM].fmt) { case 0: a.y = 0; @@ -2671,6 +2668,10 @@ void GSState::GetAlphaMinMax() a.y = env.TEXA.AEM ? 0 : min(env.TEXA.TA0, env.TEXA.TA1); a.w = max(env.TEXA.TA0, env.TEXA.TA1); break; + case 3: + m_mem.m_clut.Read32(context->TEX0, env.TEXA); + m_mem.m_clut.GetAlphaMinMax32(a.y, a.w); + break; default: __assume(0); }