MCPcopy Create free account
hub / github.com/PCSX2/pcsx2 / CheckWriteOverlap

Method CheckWriteOverlap

pcsx2/GS/GSState.cpp:2719–2880  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

2717}
2718
2719void GSState::CheckWriteOverlap(bool req_write, bool req_read)
2720{
2721 const int w = m_env.TRXREG.RRW;
2722 const int h = m_env.TRXREG.RRH;
2723 const GIFRegBITBLTBUF& blit = m_env.BITBLTBUF;
2724
2725 const GSVector4i write_rect = GSVector4i(m_env.TRXPOS.DSAX, m_env.TRXPOS.DSAY, m_env.TRXPOS.DSAX + w, m_env.TRXPOS.DSAY + h);
2726 const u32 write_start_bp = GSLocalMemory::GetStartBlockAddress(blit.DBP, blit.DBW, blit.DPSM, write_rect);
2727 const u32 write_end_bp = ((GSLocalMemory::GetEndBlockAddress(blit.DBP, blit.DBW, blit.DPSM, write_rect) + 1) + (GS_BLOCKS_PER_PAGE - 1)) & ~(GS_BLOCKS_PER_PAGE - 1);
2728
2729 for (int i = 0; i < m_used_buffers_idx; i++)
2730 {
2731 GSIndexBuff* cur_index_buff = &m_index_buffers[i];
2732 GSVertexBuff* cur_vertex_buff = &m_vertex_buffers[i];
2733 const GSDrawingContext& prev_ctx = m_env_buffers[i].m_env.CTXT[m_env_buffers[i].m_backed_up_ctx];
2734 const GSDrawingEnvironment& prev_env = m_env_buffers[i].m_env;
2735 GSVector4i tex_rect = prev_env.PRIM.TME ? GetTEX0Rect(prev_ctx) : GSVector4i::zero();
2736
2737 if (cur_index_buff->tail > 0)
2738 {
2739 // Only flush on a NEW transfer if a pending one is using the same address or overlap.
2740 // Check Fast & Furious (Hardare mode) and Assault Suits Valken (either renderer) and Tomb Raider - Angel of Darkness menu (TBP != DBP but overlaps).
2741 // Cartoon Network overwrites its own Z buffer in the middle of a draw.
2742 // Alias wraps its transfers, so be careful
2743 const GSVector4i read_rect = GSVector4i(m_env.TRXPOS.SSAX, m_env.TRXPOS.SSAY, m_env.TRXPOS.SSAX + w, m_env.TRXPOS.SSAY + h);
2744
2745 if (req_write && prev_env.PRIM.TME)
2746 {
2747 // Tex rect could be invalid showing 1024x1024 when it isn't. If the frame is only 1 page wide, it's either a big strip or a single page draw.
2748 // This large texture causes misdetection of overlapping writes, causing our heuristics in the hardware renderer for future draws to be missing.
2749 // Either way if we check the queued up coordinates, it should give us a fair idea. (Cabela's Trophy Bucks)
2750 if (prev_ctx.FRAME.FBW == 1 && static_cast<u32>(tex_rect.width()) > (prev_ctx.TEX0.TBW * 64))
2751 {
2752 GSVector4i tex_draw_rect = GSVector4i::zero();
2753 for (u32 i = 0; i < cur_index_buff->tail; i++)
2754 {
2755 const GSVertex* v = &cur_vertex_buff->buff[cur_index_buff->buff[i]];
2756 GSVector2i tex_coord;
2757 if (PRIM->FST)
2758 {
2759 tex_coord.x = v->U >> 4;
2760 tex_coord.y = v->V >> 4;
2761 }
2762 else
2763 {
2764 const float s = std::min((v->ST.S / v->RGBAQ.Q), 1.0f);
2765 const float t = std::min((v->ST.T / v->RGBAQ.Q), 1.0f);
2766
2767 tex_coord.x = static_cast<int>(std::round((1 << prev_ctx.TEX0.TW) * s));
2768 tex_coord.y = static_cast<int>(std::round((1 << prev_ctx.TEX0.TH) * t));
2769 }
2770
2771 if (i == 0)
2772 {
2773 tex_draw_rect.x = tex_coord.x;
2774 tex_draw_rect.y = tex_coord.y;
2775 tex_draw_rect.z = tex_coord.x;
2776 tex_draw_rect.w = tex_coord.y;

Callers

nothing calls this directly

Calls 8

InvalidateRangeMethod · 0.80
GSVector4iClass · 0.70
zeroFunction · 0.70
minFunction · 0.70
roundFunction · 0.70
maxFunction · 0.70
FlushFunction · 0.50
BlockMethod · 0.45

Tested by

no test coverage detected