| 2880 | } |
| 2881 | |
| 2882 | void GSState::Write(const u8* mem, int len) |
| 2883 | { |
| 2884 | if (m_env.TRXDIR.XDIR == 3) |
| 2885 | return; |
| 2886 | |
| 2887 | CheckWriteOverlap(true, false); |
| 2888 | |
| 2889 | if (!m_tr.Update(m_tr.w, m_tr.h, GSLocalMemory::m_psm[m_tr.m_blit.DPSM].trbpp, len)) |
| 2890 | { |
| 2891 | m_env.TRXDIR.XDIR = 3; |
| 2892 | return; |
| 2893 | } |
| 2894 | |
| 2895 | GIFRegBITBLTBUF& blit = m_tr.m_blit; |
| 2896 | const GSLocalMemory::psm_t& psm = GSLocalMemory::m_psm[blit.DPSM]; |
| 2897 | |
| 2898 | if (m_tr.end == 0) |
| 2899 | { |
| 2900 | GSVector4i r; |
| 2901 | |
| 2902 | r = m_tr.rect; |
| 2903 | |
| 2904 | s_last_transfer_draw_n = s_n; |
| 2905 | // Store the transfer for preloading new RT's. |
| 2906 | if ((m_draw_transfers.size() > 0 && blit.DBP == m_draw_transfers.back().blit.DBP && m_draw_transfers.back().transfer_type == EEGS_TransferType::EE_to_GS)) |
| 2907 | { |
| 2908 | // Same BP, let's update the rect. |
| 2909 | GSUploadQueue transfer = m_draw_transfers.back(); |
| 2910 | m_draw_transfers.pop_back(); |
| 2911 | transfer.rect = transfer.rect.runion(r); |
| 2912 | transfer.draw = s_n; |
| 2913 | m_draw_transfers.push_back(transfer); |
| 2914 | } |
| 2915 | else |
| 2916 | { |
| 2917 | const GSUploadQueue new_transfer = {blit, s_n, r, EEGS_TransferType::EE_to_GS}; |
| 2918 | m_draw_transfers.push_back(new_transfer); |
| 2919 | } |
| 2920 | |
| 2921 | GL_CACHE("Write! %u ... => 0x%x W:%d F:%s (DIR %d%d), dPos(%d %d) size(%d %d) draw %lld", s_transfer_n, |
| 2922 | blit.DBP, blit.DBW, GSUtil::GetPSMName(blit.DPSM), |
| 2923 | m_tr.m_pos.DIRX, m_tr.m_pos.DIRY, |
| 2924 | m_tr.x, m_tr.y, m_tr.w, m_tr.h, s_n); |
| 2925 | |
| 2926 | if (len >= m_tr.total) |
| 2927 | { |
| 2928 | // received all data in one piece, no need to buffer it |
| 2929 | InvalidateVideoMem(blit, r); |
| 2930 | |
| 2931 | psm.wi(m_mem, m_tr.x, m_tr.y, mem, m_tr.total, blit, m_tr.m_pos, m_tr.m_reg); |
| 2932 | |
| 2933 | m_tr.start = m_tr.end = m_tr.total; |
| 2934 | |
| 2935 | g_perfmon.Put(GSPerfMon::Swizzle, len); |
| 2936 | s_transfer_n++; |
| 2937 | m_env.TRXDIR.XDIR = 3; |
| 2938 | return; |
| 2939 | } |