diff --git a/Source/Core/VideoCommon/Src/BPFunctions.cpp b/Source/Core/VideoCommon/Src/BPFunctions.cpp index 4f7315e832..dc0d0723a6 100644 --- a/Source/Core/VideoCommon/Src/BPFunctions.cpp +++ b/Source/Core/VideoCommon/Src/BPFunctions.cpp @@ -39,7 +39,7 @@ void FlushPipeline() VertexManager::Flush(); } -void SetGenerationMode(const BPCmd &bp) +void SetGenerationMode() { g_renderer->SetGenerationMode(); } @@ -64,30 +64,30 @@ void SetScissor() g_renderer->SetScissorRect(trc); } -void SetLineWidth(const BPCmd &bp) +void SetLineWidth() { g_renderer->SetLineWidth(); } -void SetDepthMode(const BPCmd &bp) +void SetDepthMode() { g_renderer->SetDepthMode(); } -void SetBlendMode(const BPCmd &bp) +void SetBlendMode() { g_renderer->SetBlendMode(false); } -void SetDitherMode(const BPCmd &bp) +void SetDitherMode() { g_renderer->SetDitherMode(); } -void SetLogicOpMode(const BPCmd &bp) +void SetLogicOpMode() { g_renderer->SetLogicOpMode(); } -void SetColorMask(const BPCmd &bp) +void SetColorMask() { g_renderer->SetColorMask(); } @@ -119,7 +119,7 @@ void CopyEFB(u32 dstAddr, unsigned int dstFormat, unsigned int srcFormat, - convert the RGBA8 color to RGBA6/RGB8/RGB565 and convert it to RGBA8 again - convert the Z24 depth value to Z16 and back to Z24 */ -void ClearScreen(const BPCmd &bp, const EFBRectangle &rc) +void ClearScreen(const EFBRectangle &rc) { bool colorEnable = bpmem.blendmode.colorupdate; bool alphaEnable = bpmem.blendmode.alphaupdate; @@ -152,7 +152,7 @@ void ClearScreen(const BPCmd &bp, const EFBRectangle &rc) } } -void OnPixelFormatChange(const BPCmd &bp) +void OnPixelFormatChange() { int convtype = -1; diff --git a/Source/Core/VideoCommon/Src/BPFunctions.h b/Source/Core/VideoCommon/Src/BPFunctions.h index 2b86523687..e7a8b0aeb4 100644 --- a/Source/Core/VideoCommon/Src/BPFunctions.h +++ b/Source/Core/VideoCommon/Src/BPFunctions.h @@ -37,18 +37,18 @@ enum }; void FlushPipeline(); -void SetGenerationMode(const BPCmd &bp); +void SetGenerationMode(); void SetScissor(); -void SetLineWidth(const BPCmd &bp); -void SetDepthMode(const BPCmd &bp); -void SetBlendMode(const BPCmd &bp); -void SetDitherMode(const BPCmd &bp); -void SetLogicOpMode(const BPCmd &bp); -void SetColorMask(const BPCmd &bp); +void SetLineWidth(); +void SetDepthMode(); +void SetBlendMode(); +void SetDitherMode(); +void SetLogicOpMode(); +void SetColorMask(); void CopyEFB(u32 dstAddr, unsigned int dstFormat, unsigned int srcFormat, const EFBRectangle& srcRect, bool isIntensity, bool scaleByHalf); -void ClearScreen(const BPCmd &bp, const EFBRectangle &rc); -void OnPixelFormatChange(const BPCmd &bp); +void ClearScreen(const EFBRectangle &rc); +void OnPixelFormatChange(); u8 *GetPointer(const u32 &address); bool GetConfig(const int &type); void SetTextureMode(const BPCmd &bp); diff --git a/Source/Core/VideoCommon/Src/BPMemory.cpp b/Source/Core/VideoCommon/Src/BPMemory.cpp index d5b762c1a4..c452b238b6 100644 --- a/Source/Core/VideoCommon/Src/BPMemory.cpp +++ b/Source/Core/VideoCommon/Src/BPMemory.cpp @@ -43,31 +43,6 @@ void LoadBPReg(u32 value0) BPWritten(bp); } -// Called when loading a saved state. -// Needs more testing though. -void BPReload() -{ - for (int i = 0; i < 254; i++) - { - switch (i) - { - case BPMEM_BLENDMODE: - case BPMEM_SETDRAWDONE: - case BPMEM_TRIGGER_EFB_COPY: - case BPMEM_LOADTLUT1: - case BPMEM_PERF1: - case BPMEM_PE_TOKEN_ID: - case BPMEM_PE_TOKEN_INT_ID: - // Cases in which we DON'T want to reload the BP - continue; - default: - BPCmd bp = {i, 0xFFFFFF, static_cast(((u32*)&bpmem)[i])}; - BPWritten(bp); - } - } -} - - void GetBPRegInfo(const u8* data, char* name, size_t name_size, char* desc, size_t desc_size) { const char* no_yes[2] = { "No", "Yes" }; diff --git a/Source/Core/VideoCommon/Src/BPStructs.cpp b/Source/Core/VideoCommon/Src/BPStructs.cpp index 160ee1a61b..fb22975631 100644 --- a/Source/Core/VideoCommon/Src/BPStructs.cpp +++ b/Source/Core/VideoCommon/Src/BPStructs.cpp @@ -160,7 +160,7 @@ void BPWritten(const BPCmd& bp) bpmem.genMode.numtexgens, bpmem.genMode.numcolchans, bpmem.genMode.ms_en, bpmem.genMode.numtevstages+1, bpmem.genMode.cullmode, bpmem.genMode.numindstages, bpmem.genMode.zfreeze); - SetGenerationMode(bp); + SetGenerationMode(); break; } case BPMEM_IND_MTXA: // Index Matrix Changed @@ -188,12 +188,12 @@ void BPWritten(const BPCmd& bp) SetScissor(); break; case BPMEM_LINEPTWIDTH: // Line Width - SetLineWidth(bp); + SetLineWidth(); break; case BPMEM_ZMODE: // Depth Control PRIM_LOG("zmode: test=%d, func=%d, upd=%d", bpmem.zmode.testenable, bpmem.zmode.func, bpmem.zmode.updateenable); - SetDepthMode(bp); + SetDepthMode(); break; case BPMEM_BLENDMODE: // Blending Control { @@ -204,16 +204,16 @@ void BPWritten(const BPCmd& bp) bpmem.blendmode.dstfactor, bpmem.blendmode.srcfactor, bpmem.blendmode.subtract, bpmem.blendmode.logicmode); // Set LogicOp Blending Mode if (bp.changes & 2) - SetLogicOpMode(bp); + SetLogicOpMode(); // Set Dithering Mode if (bp.changes & 4) - SetDitherMode(bp); + SetDitherMode(); // Set Blending Mode if (bp.changes & 0xFE1) - SetBlendMode(bp); + SetBlendMode(); // Set Color Mask if (bp.changes & 0x18) - SetColorMask(bp); + SetColorMask(); } break; } @@ -306,7 +306,7 @@ void BPWritten(const BPCmd& bp) // Clear the rectangular region after copying it. if (PE_copy.clear) { - ClearScreen(bp, rc); + ClearScreen(rc); } break; @@ -455,7 +455,7 @@ void BPWritten(const BPCmd& bp) case BPMEM_ZCOMPARE: // Set the Z-Compare and EFB pixel format g_renderer->SetColorMask(); // alpha writing needs to be disabled if the new pixel format doesn't have an alpha channel - OnPixelFormatChange(bp); + OnPixelFormatChange(); break; case BPMEM_MIPMAP_STRIDE: // MipMap Stride Channel @@ -680,3 +680,35 @@ void BPWritten(const BPCmd& bp) } } +// Called when loading a saved state. +void BPReload() +{ + // restore anything that goes straight to the renderer. + // let's not risk actually replaying any writes. + // note that PixelShaderManager is already covered since it has its own DoState. + SetGenerationMode(); + SetScissor(); + SetLineWidth(); + SetDepthMode(); + SetLogicOpMode(); + SetDitherMode(); + SetBlendMode(); + SetColorMask(); + OnPixelFormatChange(); + { + BPCmd bp = {BPMEM_TX_SETMODE0, 0xFFFFFF, ((u32*)&bpmem)[BPMEM_TX_SETMODE0]}; + SetTextureMode(bp); + } + { + BPCmd bp = {BPMEM_TX_SETMODE0_4, 0xFFFFFF, ((u32*)&bpmem)[BPMEM_TX_SETMODE0_4]}; + SetTextureMode(bp); + } + { + BPCmd bp = {BPMEM_FIELDMASK, 0xFFFFFF, ((u32*)&bpmem)[BPMEM_FIELDMASK]}; + SetInterlacingMode(bp); + } + { + BPCmd bp = {BPMEM_FIELDMODE, 0xFFFFFF, ((u32*)&bpmem)[BPMEM_FIELDMODE]}; + SetInterlacingMode(bp); + } +} diff --git a/Source/Core/VideoCommon/Src/MainBase.cpp b/Source/Core/VideoCommon/Src/MainBase.cpp index 85fbc3d8e9..4df2361ea9 100644 --- a/Source/Core/VideoCommon/Src/MainBase.cpp +++ b/Source/Core/VideoCommon/Src/MainBase.cpp @@ -185,10 +185,6 @@ void VideoBackendHardware::InitializeShared() // Run from the CPU thread void VideoBackendHardware::DoState(PointerWrap& p) { - // Clear all caches that touch RAM - TextureCache::Invalidate(false); - VertexLoaderManager::MarkAllDirty(); - VideoCommon_DoState(p); // Refresh state. @@ -196,6 +192,11 @@ void VideoBackendHardware::DoState(PointerWrap& p) { BPReload(); RecomputeCachedArraybases(); + + // Clear all caches that touch RAM + // (? these don't appear to touch any emulation state that gets saved. moved to on load only.) + TextureCache::Invalidate(false); + VertexLoaderManager::MarkAllDirty(); } } diff --git a/Source/Core/VideoCommon/Src/PixelShaderManager.cpp b/Source/Core/VideoCommon/Src/PixelShaderManager.cpp index 2521f80500..1533f9348e 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderManager.cpp +++ b/Source/Core/VideoCommon/Src/PixelShaderManager.cpp @@ -465,3 +465,16 @@ void PixelShaderManager::SetMaterialColorChanged(int index) { nMaterialsChanged |= (1 << index); } + +void PixelShaderManager::DoState(PointerWrap &p) +{ + p.Do(lastRGBAfull); + p.Do(lastAlpha); + p.Do(lastTexDims); + p.Do(lastZBias); + + if (p.GetMode() == PointerWrap::MODE_READ) + { + Dirty(); + } +} diff --git a/Source/Core/VideoCommon/Src/PixelShaderManager.h b/Source/Core/VideoCommon/Src/PixelShaderManager.h index 2d1c01cad6..a336287a6f 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderManager.h +++ b/Source/Core/VideoCommon/Src/PixelShaderManager.h @@ -22,6 +22,8 @@ #include "XFMemory.h" #include "PixelShaderGen.h" +class PointerWrap; + // The non-API dependent parts. class PixelShaderManager { @@ -30,6 +32,7 @@ public: static void Init(); static void Dirty(); static void Shutdown(); + static void DoState(PointerWrap &p); static void SetConstants(); // sets pixel shader constants diff --git a/Source/Core/VideoCommon/Src/VertexShaderManager.cpp b/Source/Core/VideoCommon/Src/VertexShaderManager.cpp index b6afbc61c6..6c5f59fc48 100644 --- a/Source/Core/VideoCommon/Src/VertexShaderManager.cpp +++ b/Source/Core/VideoCommon/Src/VertexShaderManager.cpp @@ -616,3 +616,18 @@ void VertexShaderManager::ResetView() bProjectionChanged = true; } + +void VertexShaderManager::DoState(PointerWrap &p) +{ + p.Do(g_fProjectionMatrix); + p.Do(s_viewportCorrection); + p.Do(s_viewRotationMatrix); + p.Do(s_viewInvRotationMatrix); + p.Do(s_fViewTranslationVector); + p.Do(s_fViewRotation); + + if (p.GetMode() == PointerWrap::MODE_READ) + { + Dirty(); + } +} diff --git a/Source/Core/VideoCommon/Src/VertexShaderManager.h b/Source/Core/VideoCommon/Src/VertexShaderManager.h index ddbde1c0dd..1252304389 100644 --- a/Source/Core/VideoCommon/Src/VertexShaderManager.h +++ b/Source/Core/VideoCommon/Src/VertexShaderManager.h @@ -20,6 +20,8 @@ #include "VertexShaderGen.h" +class PointerWrap; + struct ProjectionHack { float sign; @@ -38,7 +40,8 @@ public: static void Init(); static void Dirty(); static void Shutdown(); - + static void DoState(PointerWrap &p); +; // constant management static void SetConstants(); diff --git a/Source/Core/VideoCommon/Src/VideoState.cpp b/Source/Core/VideoCommon/Src/VideoState.cpp index b1c1ed0889..5a677a2460 100644 --- a/Source/Core/VideoCommon/Src/VideoState.cpp +++ b/Source/Core/VideoCommon/Src/VideoState.cpp @@ -24,6 +24,8 @@ #include "Fifo.h" #include "CommandProcessor.h" #include "PixelEngine.h" +#include "PixelShaderManager.h" +#include "VertexShaderManager.h" static void DoState(PointerWrap &p) { @@ -48,12 +50,17 @@ static void DoState(PointerWrap &p) CommandProcessor::DoState(p); PixelEngine::DoState(p); + + // the old way of replaying current bpmem as writes to push side effects to pixel shader manager doesn't really work. + PixelShaderManager::DoState(p); + VertexShaderManager::DoState(p); + + // TODO: search for more data that should be saved and add it here } void VideoCommon_DoState(PointerWrap &p) { DoState(p); - //TODO: search for more data that should be saved and add it here } void VideoCommon_RunLoop(bool enable)