| 1642 | |
| 1643 | template <int i> |
| 1644 | void GSState::ApplyTEX0(GIFRegTEX0& TEX0) |
| 1645 | { |
| 1646 | // TODO: Paletted Formats |
| 1647 | // 8-bit and 4 bit formats need to be addressed with a buffer width divisible 2. |
| 1648 | // However, not doing so is possible and does have a behavior on the GS. |
| 1649 | // When implementing such code care must be taken not to apply it unless it is |
| 1650 | // used for a draw. Galaxy Angel will send TEX0 with a PSM of T8 and a TBW of 7 |
| 1651 | // only to immediately update it to CT32 with TEX2. The old code used to apply a |
| 1652 | // correction on the TEX0 setting which caused the game to draw the CT32 texture |
| 1653 | // with an incorrect buffer width. |
| 1654 | // |
| 1655 | // Bouken Jidai Katsugeki Goemon apparently uses a TBW of 1 but this game is currently |
| 1656 | // extremely broken for the same reasons as MLB Power Pros in that it spams TEX0 with |
| 1657 | // complete garbage making for a nice 1G heap of GSOffset. |
| 1658 | |
| 1659 | GL_REG("Apply TEX0_%d = 0x%x_%x", i, TEX0.U32[1], TEX0.U32[0]); |
| 1660 | |
| 1661 | if ((TEX0.PSM & 0x7) >= 3 && m_mem.m_clut.CanLoadCLUT(TEX0)) |
| 1662 | { |
| 1663 | m_mem.m_clut.ClearDrawInvalidity(); |
| 1664 | m_mem.m_clut.SetNextCLUTTEX0(TEX0.U64); |
| 1665 | CheckCLUTValidity(m_prev_env.PRIM.PRIM); |
| 1666 | } |
| 1667 | |
| 1668 | // Even if TEX0 did not change, a new palette may have been uploaded and will overwrite the currently queued for drawing. |
| 1669 | const bool wt = m_mem.m_clut.WriteTest(TEX0, m_env.TEXCLUT); |
| 1670 | |
| 1671 | // No need to flush on CLUT if we aren't texture mapping. |
| 1672 | if (wt) |
| 1673 | { |
| 1674 | for (int b = 0; b < m_used_buffers_idx; b++) |
| 1675 | { |
| 1676 | GSDrawingEnvironment& buffered_env = m_env_buffers[b].m_env; |
| 1677 | if ((buffered_env.PRIM.TME && (buffered_env.CTXT[buffered_env.PRIM.CTXT].TEX0.PSM & 0x7) >= 3) || (m_mem.m_clut.IsInvalid() & 2)) |
| 1678 | Flush(GSFlushReason::CLUTCHANGE); |
| 1679 | } |
| 1680 | FlushWrite(); |
| 1681 | // Abort any channel shuffle skipping, since this is likely part of a new shuffle. |
| 1682 | // Test case: Tomb Raider series. This is gated by the CBP actually changing, because |
| 1683 | // Urban Chaos writes to the memory backing the CLUT in the middle of a shuffle, and |
| 1684 | // it's unclear whether the CLUT would actually get reloaded in that case. |
| 1685 | if (TEX0.CBP != m_mem.m_clut.GetCLUTCBP()) |
| 1686 | m_channel_shuffle_finish = true; |
| 1687 | } |
| 1688 | |
| 1689 | TEX0.CPSM &= 0xa; // 1010b |
| 1690 | |
| 1691 | m_env.CTXT[i].TEX0 = TEX0; |
| 1692 | |
| 1693 | if (wt) |
| 1694 | { |
| 1695 | GIFRegBITBLTBUF BITBLTBUF = {}; |
| 1696 | GSVector4i r; |
| 1697 | |
| 1698 | if (TEX0.CSM == 0) |
| 1699 | { |
| 1700 | BITBLTBUF.SBP = TEX0.CBP; |
| 1701 | BITBLTBUF.SBW = 1; |
nothing calls this directly
no test coverage detected