From c918df60d2576dde1fd51c6260628f8a9864681d Mon Sep 17 00:00:00 2001 From: cottonvibes Date: Wed, 27 Jul 2011 03:55:43 +0000 Subject: [PATCH] newGif: do what r4829 did, except only flush the gs primitives to the mtgs when theres going to be a GS download (busdir=1). this should be the only time that an explicit flushing is needed. doing it this way should be faster than flushing every incomplete gs packet like r4829 was doing... git-svn-id: http://pcsx2.googlecode.com/svn/trunk@4831 96395faa-99c1-11dd-bbfe-3dabce05a288 --- pcsx2/GS.cpp | 20 ++++++++------------ pcsx2/Gif_Unit.h | 35 +++++++++++++++++++++-------------- 2 files changed, 29 insertions(+), 26 deletions(-) diff --git a/pcsx2/GS.cpp b/pcsx2/GS.cpp index c8b6a243a8..a4637a7541 100644 --- a/pcsx2/GS.cpp +++ b/pcsx2/GS.cpp @@ -260,20 +260,16 @@ void __fastcall gsWrite64_page_01( u32 mem, const mem64_t* value ) switch( mem ) { case GS_BUSDIR: - //This is probably a complete hack, however writing to BUSDIR "should" start a transfer - //Only problem is it kills killzone :(. - // (yes it *is* a complete hack; both lines here in fact --air) - //========================================================================= - //gifRegs.stat.OPH = true; // Bleach wants it, Killzone hates it. - GUNIT_LOG("GIF - busdir"); - gifRegs.stat.DIR = value[0] & 1; - - if (gifRegs.stat.DIR) { // Assume will do local->host transfer? - gifRegs.stat.OPH = true; // Is OPH set on local->host transfers? - DevCon.WriteLn("Busdir - GS->EE Download"); + gifUnit.stat.DIR = value[0] & 1; + if (gifUnit.stat.DIR) { // Assume will do local->host transfer + gifUnit.stat.OPH = true; // Should we set OPH here? + gifUnit.FlushToMTGS(); // Send any pending GS Primitives to the GS + GUNIT_LOG("Busdir - GS->EE Download"); + } + else { + GUNIT_LOG("Busdir - EE->GS Upload"); } - else DevCon.WriteLn("Busdir - EE->GS Upload"); //========================================================================= // BUSDIR INSANITY !! MTGS FLUSH NEEDED diff --git a/pcsx2/Gif_Unit.h b/pcsx2/Gif_Unit.h index f89decc063..346ffc46cc 100644 --- a/pcsx2/Gif_Unit.h +++ b/pcsx2/Gif_Unit.h @@ -317,7 +317,7 @@ struct Gif_Unit { GIF_LOG("%s - [path=%d][size=%d]", Gif_TransferStr[(tranType>>8)&0xf], (tranType&3)+1, size); if (size == 0) { GUNIT_WARN("Gif Unit - Size == 0"); return 0; } - if(!CanDoGif()) { GUNIT_WARN("Gif Unit - PSE Set or Dir = GS to EE"); } + if(!CanDoGif()) { GUNIT_WARN("Gif Unit - Signal or PSE Set or Dir = GS to EE"); } pxAssertDev((stat.APATH==0) || checkPaths(1,1,1), "Gif Unit - APATH wasn't cleared?"); lastTranType = tranType; @@ -361,8 +361,21 @@ struct Gif_Unit { return ret; } + // Send processed GS Primitive(s) to the MTGS thread + // Note: Only does so if current path fully completed all + // of its given gs primitives (but didn't upload them yet) + void FlushToMTGS() { + if (!stat.APATH) return; + Gif_Path& path = gifPath[stat.APATH-1]; + if (path.gsPack.size && !path.gifTag.isValid) { + AddCompletedGSPacket(path.gsPack, (GIF_PATH)(stat.APATH-1)); + path.gsPack.offset = path.curOffset; + path.gsPack.size = 0; + } + } + // Processes gif packets and performs path arbitration - // according to path priority... + // on EOPs or on Path 3 Images when IMT is set. void Execute() { if (!CanDoGif()) { DevCon.Error("Gif Unit - Signal or PSE Set or Dir = GS to EE"); return; } bool didPath3 = false; @@ -377,7 +390,7 @@ struct Gif_Unit { didPath3 = true; stat.APATH = 0; stat.IP3 = 1; - //DevCon.WriteLn(Color_Magenta, "Gif Unit - Path 3 slicing arbitration"); + GUNIT_LOG(Color_Magenta, "Gif Unit - Path 3 slicing arbitration"); if (gsPack.size > 16) { // Packet had other tags which we already processed u32 subOffset = path.gifTag.isValid ? 16 : 0; // if isValid, image-primitive not finished gsPack.size -= subOffset; // Remove the image-tag (should be last thing read) @@ -388,30 +401,24 @@ struct Gif_Unit { path.gifTag.isValid = false; // Reload tag next ExecuteGSPacket() pxAssert((s32)path.curOffset >= 0); pxAssert(path.state == GIF_PATH_IMAGE); - DevCon.WriteLn(Color_Magenta, "Gif Unit - Sending path 3 sliced gs packet!"); + GUNIT_LOG(Color_Magenta, "Gif Unit - Sending path 3 sliced gs packet!"); } continue; } } - // Send complete gs primitive packet(s) - if (gsPack.size && !path.gifTag.isValid) { - AddCompletedGSPacket(gsPack, (GIF_PATH)(stat.APATH-1)); - path.gsPack.size = 0; - path.gsPack.offset = path.curOffset; - } //DevCon.WriteLn("Incomplete GS Packet for path %d, size=%d", stat.APATH, gsPack.size); break; // Not finished with GS packet } //DevCon.WriteLn("Adding GS Packet for path %d", stat.APATH); AddCompletedGSPacket(gsPack, (GIF_PATH)(stat.APATH-1)); } - if (!gsSIGNAL.queued && checkPaths(1,0,0,0)) { stat.APATH = 1; stat.P1Q = 0; } - elif (!gsSIGNAL.queued && checkPaths(0,1,0,0)) { stat.APATH = 2; stat.P2Q = 0; } - elif (!gsSIGNAL.queued && checkPaths(0,0,1,0) && !Path3Masked()) + if (!gsSIGNAL.queued && !gifPath[0].isDone()) { stat.APATH = 1; stat.P1Q = 0; } + elif (!gsSIGNAL.queued && !gifPath[1].isDone()) { stat.APATH = 2; stat.P2Q = 0; } + elif (!gsSIGNAL.queued && !gifPath[2].isDone() && !Path3Masked()) { stat.APATH = 3; stat.P3Q = 0; stat.IP3 = 0; } else { stat.APATH = 0; stat.OPH = 0; break; } } - Gif_FinishIRQ(); // hmm + Gif_FinishIRQ(); //DevCon.WriteLn("APATH = %d [%d,%d,%d]", stat.APATH, !!checkPaths(1,0,0,0),!!checkPaths(0,1,0,0),!!checkPaths(0,0,1,0)); }