diff --git a/pcsx2/GS/GSState.cpp b/pcsx2/GS/GSState.cpp index 991a34860b..f9ddcab9ae 100644 --- a/pcsx2/GS/GSState.cpp +++ b/pcsx2/GS/GSState.cpp @@ -3689,7 +3689,7 @@ void GSState::CalcAlphaMinMax(const int tex_alpha_min, const int tex_alpha_max) return; // We wanted to force an update as we now know the alpha of the non-indexed texture. - // Limit max to 255 as we send 500 when we don't know, makes calculating 16bit easier. + // Limit max to 255 as we send 500 when we don't know, makes calculating 24/16bit easier. int min = tex_alpha_min, max = std::min(tex_alpha_max, 255); if (IsCoverageAlpha()) @@ -3712,12 +3712,14 @@ void GSState::CalcAlphaMinMax(const int tex_alpha_min, const int tex_alpha_max) a.w = max; break; case 1: - a.y = env.TEXA.AEM ? 0 : env.TEXA.TA0; - a.w = env.TEXA.TA0; + // If we're using the alpha from the texture, not the whole range, we can just use tex_alpha_min/max. + // AEM and TA0 re precomputed with GSBlock::ReadAndExpandBlock24, so already worked out for tex_alpha. + a.y = (tex_alpha_max < 500) ? min : (env.TEXA.AEM ? 0 : env.TEXA.TA0); + a.w = (tex_alpha_max < 500) ? max : env.TEXA.TA0; break; case 2: // If we're using the alpha from the texture, not the whole range, we can just use tex_alpha_min/max. - // TA0/TA1 is precomputed with GSBlock::ReadAndExpandBlock16, so already worked out for tex_alpha. + // AEM, TA0 and TA1 are precomputed with GSBlock::ReadAndExpandBlock16, so already worked out for tex_alpha. a.y = (tex_alpha_max < 500) ? min : (env.TEXA.AEM ? 0 : std::min(env.TEXA.TA0, env.TEXA.TA1)); a.w = (tex_alpha_max < 500) ? max : std::max(env.TEXA.TA0, env.TEXA.TA1); break; diff --git a/pcsx2/GS/Renderers/HW/GSTextureCache.cpp b/pcsx2/GS/Renderers/HW/GSTextureCache.cpp index cce19b97f4..eecae12f65 100644 --- a/pcsx2/GS/Renderers/HW/GSTextureCache.cpp +++ b/pcsx2/GS/Renderers/HW/GSTextureCache.cpp @@ -3646,17 +3646,25 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con src->m_target = true; src->m_from_target = dst; src->m_from_target_TEX0 = dst->m_TEX0; - src->m_alpha_minmax.first = dst->m_alpha_min; - src->m_alpha_minmax.second = dst->m_alpha_max; - // This is a bit rough, since if AEM is on, without rescanning the whole texture, we don't know if anything is transparent, so just go the hard way. - if (!dst->m_32_bits_fmt) + if ((src->m_TEX0.PSM & 0xf) == PSMCT24) { - const bool using_both = (src->m_alpha_minmax.first ^ src->m_alpha_minmax.second) & 128; - const bool using_ta1 = (src->m_alpha_minmax.second & 128); + src->m_alpha_minmax.first = TEXA.AEM ? 0 : TEXA.TA0; + src->m_alpha_minmax.second = TEXA.TA0; + } + else + { + src->m_alpha_minmax.first = dst->m_alpha_min; + src->m_alpha_minmax.second = dst->m_alpha_max; - src->m_alpha_minmax.first = TEXA.AEM ? 0 : (using_both ? std::min(TEXA.TA1, TEXA.TA0) : (using_ta1 ? TEXA.TA1 : TEXA.TA0)); - src->m_alpha_minmax.second = (using_both ? std::max(TEXA.TA1, TEXA.TA0) : (using_ta1 ? TEXA.TA1 : TEXA.TA0)); + if (!dst->m_32_bits_fmt) + { + const bool using_both = (src->m_alpha_minmax.first ^ src->m_alpha_minmax.second) & 128; + const bool using_ta1 = (src->m_alpha_minmax.second & 128); + + src->m_alpha_minmax.first = TEXA.AEM ? 0 : (using_both ? std::min(TEXA.TA1, TEXA.TA0) : (using_ta1 ? TEXA.TA1 : TEXA.TA0)); + src->m_alpha_minmax.second = (using_both ? std::max(TEXA.TA1, TEXA.TA0) : (using_ta1 ? TEXA.TA1 : TEXA.TA0)); + } } if (psm.pal > 0) @@ -3698,17 +3706,25 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con src->m_from_target_TEX0 = dst->m_TEX0; src->m_valid_rect = dst->m_valid; src->m_end_block = dst->m_end_block; - src->m_alpha_minmax.first = dst->m_alpha_min; - src->m_alpha_minmax.second = dst->m_alpha_max; - // This is a bit rough, since if AEM is on, without rescanning the whole texture, we don't know if anything is transparent, so just go the hard way. - if (!dst->m_32_bits_fmt) + if ((src->m_TEX0.PSM & 0xf) == PSMCT24) { - const bool using_both = (src->m_alpha_minmax.first ^ src->m_alpha_minmax.second) & 128; - const bool using_ta1 = (src->m_alpha_minmax.second & 128); + src->m_alpha_minmax.first = TEXA.AEM ? 0 : TEXA.TA0; + src->m_alpha_minmax.second = TEXA.TA0; + } + else + { + src->m_alpha_minmax.first = dst->m_alpha_min; + src->m_alpha_minmax.second = dst->m_alpha_max; - src->m_alpha_minmax.first = TEXA.AEM ? 0 : (using_both ? std::min(TEXA.TA1, TEXA.TA0) : (using_ta1 ? TEXA.TA1 : TEXA.TA0)); - src->m_alpha_minmax.second = (using_both ? std::max(TEXA.TA1, TEXA.TA0) : (using_ta1 ? TEXA.TA1 : TEXA.TA0)); + if (!dst->m_32_bits_fmt) + { + const bool using_both = (src->m_alpha_minmax.first ^ src->m_alpha_minmax.second) & 128; + const bool using_ta1 = (src->m_alpha_minmax.second & 128); + + src->m_alpha_minmax.first = TEXA.AEM ? 0 : (using_both ? std::min(TEXA.TA1, TEXA.TA0) : (using_ta1 ? TEXA.TA1 : TEXA.TA0)); + src->m_alpha_minmax.second = (using_both ? std::max(TEXA.TA1, TEXA.TA0) : (using_ta1 ? TEXA.TA1 : TEXA.TA0)); + } } dst->Update(); @@ -5210,8 +5226,16 @@ void GSTextureCache::Target::Update() g_gs_device->DrawMultiStretchRects(drects, ndrects, m_texture, shader); } - m_alpha_min = 0; - m_alpha_max = m_32_bits_fmt ? 255 : 128; + if ((m_TEX0.PSM & 0xf) == PSMCT24) + { + m_alpha_min = 128; + m_alpha_max = 128; + } + else + { + m_alpha_min = 0; + m_alpha_max = m_32_bits_fmt ? 255 : 128; + } g_gs_device->Recycle(t); m_dirty.clear(); }