diff --git a/plugins/GSdx/GSDrawingContext.h b/plugins/GSdx/GSDrawingContext.h index 85b6542fbd..44d6f589b9 100644 --- a/plugins/GSdx/GSDrawingContext.h +++ b/plugins/GSdx/GSDrawingContext.h @@ -124,4 +124,95 @@ public: return ZBUF.ZMSK == 0 && TEST.ZTE != 0; // ZTE == 0 is bug on the real hardware, write is blocked then } + + void Dump(const std::string& filename) + { + // Append on purpose so env + context are merged into a single file + FILE* fp = fopen(filename.c_str(), "at"); + if (!fp) return; + + fprintf(fp, "XYOFFSET\n" + "\tX:%d\n" + "\tY:%d\n\n" + , XYOFFSET.OFX, XYOFFSET.OFY); + fprintf(fp, "TEX0\n" + "\tTBP0:%d\n" + "\tTBW:%d\n" + "\tPSM:%d\n" + "\tTW:%d\n" + "\tTCC:%d\n" + "\tTFX:%d\n" + "\tCBP:%d\n" + "\tCPSM:%d\n" + "\tCSM:%d\n" + "\tCSA:%d\n" + "\tCLD:%d\n" + "\tTH:%lld\n\n" + , TEX0.TBP0, TEX0.TBW, TEX0.PSM, TEX0.TW, TEX0.TCC, TEX0.TFX, TEX0.CBP, TEX0.CPSM, TEX0.CSM, TEX0.CSA, TEX0.CLD, TEX0.TH); + fprintf(fp, "TEX1\n" + "\tLCM:%d\n" + "\tMXL:%d\n" + "\tMMAG:%d\n" + "\tMMIN:%d\n" + "\tMTBA:%d\n" + "\tL:%d\n" + "\tK:%d\n\n" + , TEX1.LCM, TEX1.MXL, TEX1.MMAG, TEX1.MMIN, TEX1.MTBA, TEX1.L, TEX1.K); + fprintf(fp, "TEX2\n" + "\tPSM:%d\n" + "\tCBP:%d\n" + "\tCPSM:%d\n" + "\tCSM:%d\n" + "\tCSA:%d\n" + "\tCLD:%d\n\n" + , TEX2.PSM, TEX2.CBP, TEX2.CPSM, TEX2.CSM, TEX2.CSA, TEX2.CLD); + fprintf(fp, "CLAMP\n" + "\tWMS:%d\n" + "\tWMT:%d\n" + "\tMINU:%d\n" + "\tMAXU:%d\n" + "\tMAXV:%d\n" + "\tMINV:%lld\n\n" + , CLAMP.WMS, CLAMP.WMT, CLAMP.MINU, CLAMP.MAXU, CLAMP.MAXV, CLAMP.MINV); + // TODO mimmap? (yes I'm lazy) + fprintf(fp, "SCISSOR\n" + "\tX0:%d\n" + "\tX1:%d\n" + "\tY0:%d\n" + "\tY1:%d\n\n" + , SCISSOR.SCAX0, SCISSOR.SCAX1, SCISSOR.SCAY0, SCISSOR.SCAY1); + fprintf(fp, "ALPHA\n" + "\tA:%d\n" + "\tB:%d\n" + "\tC:%d\n" + "\tD:%d\n" + "\tFIX:%d\n\n" + , ALPHA.A, ALPHA.B, ALPHA.C, ALPHA.D, ALPHA.FIX); + fprintf(fp, "TEST\n" + "\tATE:%d\n" + "\tATST:%d\n" + "\tAREF:%d\n" + "\tAFAIL:%d\n" + "\tDATE:%d\n" + "\tDATM:%d\n" + "\tZTE:%d\n" + "\tZTST:%d\n\n" + , TEST.ATE, TEST.ATST, TEST.AREF, TEST.AFAIL, TEST.DATE, TEST.DATM, TEST.ZTE, TEST.ZTST); + fprintf(fp, "FBA\n" + "\tFBA:%d\n\n" + , FBA.FBA); + fprintf(fp, "FRAME\n" + "\tFBP:%d\n" + "\tFBW:%d\n" + "\tPSM:%d\n" + "\tFBMSK:%d\n\n" + , FRAME.FBP, FRAME.FBW, FRAME.PSM, FRAME.FBMSK); + fprintf(fp, "ZBUF\n" + "\tZBP:%d\n" + "\tPSM:%d\n" + "\tZMSK:%d\n\n" + , ZBUF.ZBP, ZBUF.PSM, ZBUF.ZMSK); + + fclose(fp); + } }; diff --git a/plugins/GSdx/GSDrawingEnvironment.h b/plugins/GSdx/GSDrawingEnvironment.h index e9c21b0d7f..94627f484d 100644 --- a/plugins/GSdx/GSDrawingEnvironment.h +++ b/plugins/GSdx/GSDrawingEnvironment.h @@ -84,4 +84,43 @@ public: dimx[7] = GSVector4i(DIMX.DM30, 0, DIMX.DM31, 0, DIMX.DM32, 0, DIMX.DM33, 0), dimx[6] = dimx[7].xxzzlh(); } + + void Dump(const std::string& filename) + { + FILE* fp = fopen(filename.c_str(), "wt"); + if (!fp) return; + + fprintf(fp, "PRIM\n" + "\tPRIM:%d\n" + "\tIIP:%d\n" + "\tTME:%d\n" + "\tFGE:%d\n" + "\tABE:%d\n" + "\tAA1:%d\n" + "\tFST:%d\n" + "\tCTXT:%d\n" + "\tFIX:%d\n\n" + , PRIM.PRIM, PRIM.IIP, PRIM.TME, PRIM.FGE, PRIM.ABE, PRIM.AA1, PRIM.FST, PRIM.CTXT, PRIM.FIX); + + fprintf(fp, "PRMODE (when AC=0)\n" + "\t_PRIM:%d\n" + "\tIIP:%d\n" + "\tTME:%d\n" + "\tFGE:%d\n" + "\tABE:%d\n" + "\tAA1:%d\n" + "\tFST:%d\n" + "\tCTXT:%d\n" + "\tFIX:%d\n\n" + , PRMODE._PRIM, PRMODE.IIP, PRMODE.TME, PRMODE.FGE, PRMODE.ABE, PRMODE.AA1, PRMODE.FST, PRMODE.CTXT, PRMODE.FIX); + + fprintf(fp, "PRMODECONT\n" + "\tAC:%d\n\n" + , PRMODECONT.AC); + + // Lots of register TODO but later + + fclose(fp); + } + }; diff --git a/plugins/GSdx/GSRendererHW.cpp b/plugins/GSdx/GSRendererHW.cpp index 7192077168..6af8558f39 100644 --- a/plugins/GSdx/GSRendererHW.cpp +++ b/plugins/GSdx/GSRendererHW.cpp @@ -332,9 +332,13 @@ void GSRendererHW::RoundSpriteOffset() void GSRendererHW::Draw() { - if(m_dev->IsLost()) return; - - if(GSRenderer::IsBadFrame(m_skip, m_userhacks_skipdraw)) return; + if(m_dev->IsLost() || GSRenderer::IsBadFrame(m_skip, m_userhacks_skipdraw)) { + if (s_dump) { + fprintf(stderr, "Warning skipping a draw call\n"); + s_n += 3; // Keep it sync with SW renderer + } + return; + } GSDrawingEnvironment& env = m_env; GSDrawingContext* context = m_context; @@ -430,9 +434,15 @@ void GSRendererHW::Draw() s_n++; - if ((s_n - s_saven) > s_savel) { - s_dump = 0; + static uint64 draw_call = 0; // Redundant with s_n but easier to map in GL debug tool + if (s_n >= s_saven) { + // Dump Register state + s = format("%05d_context_d%lld.txt", s_n, draw_call); + + m_env.Dump(root_hw+s); + m_context->Dump(root_hw+s); } + draw_call++; } if(m_hacks.m_oi && !(this->*m_hacks.m_oi)(rt->m_texture, ds->m_texture, tex)) @@ -554,6 +564,10 @@ void GSRendererHW::Draw() } s_n++; + + if ((s_n - s_saven) > s_savel) { + s_dump = 0; + } } #ifdef DISABLE_HW_TEXTURE_CACHE diff --git a/plugins/GSdx/GSRendererSW.cpp b/plugins/GSdx/GSRendererSW.cpp index ffeb17c373..5b1f0e92ee 100644 --- a/plugins/GSdx/GSRendererSW.cpp +++ b/plugins/GSdx/GSRendererSW.cpp @@ -541,6 +541,17 @@ void GSRendererSW::Draw() s_n++; + static uint64 draw_call = 0; // Redundant with s_n but easier to map in GL debug tool + if (s_n >= s_saven) { + // Dump Register state + s = format("%05d_context_d%lld.txt", s_n, draw_call); + + m_env.Dump(root_sw+s); + m_context->Dump(root_sw+s); + } + draw_call++; + + Queue(data); Sync(3);