From e88c02dece0e5e8d3b019fd0137eab790d6d2036 Mon Sep 17 00:00:00 2001 From: Scott Mansell Date: Fri, 16 Jan 2015 05:29:39 +1300 Subject: [PATCH] Ensure that ZSlopes save/restore state correctly. Had to re-do *ShaderManager so they saved their constant arrays instead of completly rebuilding them on restore state. --- Source/Core/Core/State.cpp | 2 +- .../VideoCommon/GeometryShaderManager.cpp | 22 +++--- .../Core/VideoCommon/PixelShaderManager.cpp | 70 +++++++------------ Source/Core/VideoCommon/PixelShaderManager.h | 6 -- Source/Core/VideoCommon/VertexManagerBase.cpp | 1 + .../Core/VideoCommon/VertexShaderManager.cpp | 51 ++++++++------ 6 files changed, 72 insertions(+), 80 deletions(-) diff --git a/Source/Core/Core/State.cpp b/Source/Core/Core/State.cpp index a63fafc2a5..2b3ce95e08 100644 --- a/Source/Core/Core/State.cpp +++ b/Source/Core/Core/State.cpp @@ -64,7 +64,7 @@ static Common::Event g_compressAndDumpStateSyncEvent; static std::thread g_save_thread; // Don't forget to increase this after doing changes on the savestate system -static const u32 STATE_VERSION = 38; +static const u32 STATE_VERSION = 39; enum { diff --git a/Source/Core/VideoCommon/GeometryShaderManager.cpp b/Source/Core/VideoCommon/GeometryShaderManager.cpp index 3e96592625..0a07cf683c 100644 --- a/Source/Core/VideoCommon/GeometryShaderManager.cpp +++ b/Source/Core/VideoCommon/GeometryShaderManager.cpp @@ -26,7 +26,11 @@ void GeometryShaderManager::Init() { memset(&constants, 0, sizeof(constants)); - Dirty(); + // Init any intial constants which aren't zero when bpmem is zero. + SetViewportChanged(); + SetProjectionChanged(); + + dirty = true; } void GeometryShaderManager::Shutdown() @@ -35,12 +39,9 @@ void GeometryShaderManager::Shutdown() void GeometryShaderManager::Dirty() { - SetViewportChanged(); - SetProjectionChanged(); - SetLinePtWidthChanged(); - - for (int i = 0; i < 8; i++) - SetTexCoordChanged(i); + // This function is called after a savestate is loaded. + // Any constants that can changed based on settings should be re-calculated + s_projection_changed = true; dirty = true; } @@ -110,9 +111,14 @@ void GeometryShaderManager::SetTexCoordChanged(u8 texmapid) void GeometryShaderManager::DoState(PointerWrap &p) { + p.Do(s_projection_changed); + p.Do(s_viewport_changed); + + p.Do(constants); + if (p.GetMode() == PointerWrap::MODE_READ) { - // Reload current state from global GPU state + // Fixup the current state from global GPU state // NOTE: This requires that all GPU memory has been loaded already. Dirty(); } diff --git a/Source/Core/VideoCommon/PixelShaderManager.cpp b/Source/Core/VideoCommon/PixelShaderManager.cpp index f80fc114ce..b1a68248ee 100644 --- a/Source/Core/VideoCommon/PixelShaderManager.cpp +++ b/Source/Core/VideoCommon/PixelShaderManager.cpp @@ -14,10 +14,6 @@ bool PixelShaderManager::s_bFogRangeAdjustChanged; bool PixelShaderManager::s_bViewPortChanged; -bool PixelShaderManager::s_bEFBScaleChanged; - -std::array PixelShaderManager::s_tev_color; -std::array PixelShaderManager::s_tev_konst_color; PixelShaderConstants PixelShaderManager::constants; bool PixelShaderManager::dirty; @@ -25,34 +21,12 @@ bool PixelShaderManager::dirty; void PixelShaderManager::Init() { memset(&constants, 0, sizeof(constants)); - memset(s_tev_color.data(), 0, sizeof(s_tev_color)); - memset(s_tev_konst_color.data(), 0, sizeof(s_tev_konst_color)); - Dirty(); -} - -void PixelShaderManager::Dirty() -{ + // Init any intial constants which aren't zero when bpmem is zero. s_bFogRangeAdjustChanged = true; - s_bViewPortChanged = true; + s_bViewPortChanged = false; - for (unsigned index = 0; index < s_tev_color.size(); ++index) - { - for (int comp = 0; comp < 4; ++comp) - { - SetTevColor(index, comp, s_tev_color[index][comp]); - SetTevKonstColor(index, comp, s_tev_konst_color[index][comp]); - } - } - - SetAlpha(); - SetDestAlpha(); - SetZTextureBias(); - SetViewportChanged(); SetEfbScaleChanged(); - SetZSlope(0, 0, (float)0xFFFFFF); - SetIndTexScaleChanged(false); - SetIndTexScaleChanged(true); SetIndMatrixChanged(0); SetIndMatrixChanged(1); SetIndMatrixChanged(2); @@ -65,8 +39,20 @@ void PixelShaderManager::Dirty() SetTexCoordChanged(5); SetTexCoordChanged(6); SetTexCoordChanged(7); - SetFogColorChanged(); + + dirty = true; +} + +void PixelShaderManager::Dirty() +{ + // This function is called after a savestate is loaded. + // Any constants that can changed based on settings should be re-calculated + s_bFogRangeAdjustChanged = true; + + SetEfbScaleChanged(); SetFogParamChanged(); + + dirty = true; } void PixelShaderManager::Shutdown() @@ -115,20 +101,12 @@ void PixelShaderManager::SetConstants() dirty = true; s_bViewPortChanged = false; } - - if (s_bEFBScaleChanged) - { - constants.efbscale[0] = 1.0f / float(Renderer::EFBToScaledXf(1)); - constants.efbscale[1] = 1.0f / float(Renderer::EFBToScaledYf(1)); - dirty = true; - s_bEFBScaleChanged = false; - } } void PixelShaderManager::SetTevColor(int index, int component, s32 value) { auto& c = constants.colors[index]; - c[component] = s_tev_color[index][component] = value; + c[component] = value; dirty = true; PRIM_LOG("tev color%d: %d %d %d %d\n", index, c[0], c[1], c[2], c[3]); @@ -137,7 +115,7 @@ void PixelShaderManager::SetTevColor(int index, int component, s32 value) void PixelShaderManager::SetTevKonstColor(int index, int component, s32 value) { auto& c = constants.kcolors[index]; - c[component] = s_tev_konst_color[index][component] = value; + c[component] = value; dirty = true; PRIM_LOG("tev konst color%d: %d %d %d %d\n", index, c[0], c[1], c[2], c[3]); @@ -181,8 +159,9 @@ void PixelShaderManager::SetViewportChanged() void PixelShaderManager::SetEfbScaleChanged() { - s_bEFBScaleChanged = true; - s_bViewPortChanged = true; + constants.efbscale[0] = 1.0f / float(Renderer::EFBToScaledXf(1)); + constants.efbscale[1] = 1.0f / float(Renderer::EFBToScaledYf(1)); + dirty = true; } void PixelShaderManager::SetZSlope(float dfdx, float dfdy, float f0) @@ -190,7 +169,6 @@ void PixelShaderManager::SetZSlope(float dfdx, float dfdy, float f0) constants.zslope[0] = dfdx; constants.zslope[1] = dfdy; constants.zslope[2] = f0; - constants.zslope[3] = 0; dirty = true; } @@ -304,12 +282,14 @@ void PixelShaderManager::SetFogRangeAdjustChanged() void PixelShaderManager::DoState(PointerWrap &p) { - p.DoArray(s_tev_color); - p.DoArray(s_tev_konst_color); + p.Do(s_bFogRangeAdjustChanged); + p.Do(s_bViewPortChanged); + + p.Do(constants); if (p.GetMode() == PointerWrap::MODE_READ) { - // Reload current state from global GPU state + // Fixup the current state from global GPU state // NOTE: This requires that all GPU memory has been loaded already. Dirty(); } diff --git a/Source/Core/VideoCommon/PixelShaderManager.h b/Source/Core/VideoCommon/PixelShaderManager.h index 421fd3393c..0f3dba3699 100644 --- a/Source/Core/VideoCommon/PixelShaderManager.h +++ b/Source/Core/VideoCommon/PixelShaderManager.h @@ -52,10 +52,4 @@ public: static bool s_bFogRangeAdjustChanged; static bool s_bViewPortChanged; - static bool s_bEFBScaleChanged; - - // These colors aren't available from global BP state, - // hence we keep a copy of them around. - static std::array s_tev_color; - static std::array s_tev_konst_color; }; diff --git a/Source/Core/VideoCommon/VertexManagerBase.cpp b/Source/Core/VideoCommon/VertexManagerBase.cpp index c9f5e2c714..3f6c672c65 100644 --- a/Source/Core/VideoCommon/VertexManagerBase.cpp +++ b/Source/Core/VideoCommon/VertexManagerBase.cpp @@ -241,6 +241,7 @@ void VertexManager::Flush() void VertexManager::DoState(PointerWrap& p) { + p.Do(ZSlope); g_vertex_manager->vDoState(p); } diff --git a/Source/Core/VideoCommon/VertexShaderManager.cpp b/Source/Core/VideoCommon/VertexShaderManager.cpp index 5320e0af2e..c6cf8edce5 100644 --- a/Source/Core/VideoCommon/VertexShaderManager.cpp +++ b/Source/Core/VideoCommon/VertexShaderManager.cpp @@ -167,7 +167,21 @@ static void ViewportCorrectionMatrix(Matrix44& result) void VertexShaderManager::Init() { - Dirty(); + // Initialize state tracking variables + nTransformMatricesChanged[0] = -1; + nTransformMatricesChanged[1] = -1; + nNormalMatricesChanged[0] = -1; + nNormalMatricesChanged[1] = -1; + nPostTransformMatricesChanged[0] = -1; + nPostTransformMatricesChanged[1] = -1; + nLightsChanged[0] = -1; + nLightsChanged[1] = -1; + nMaterialsChanged = BitSet32(0); + bTexMatricesChanged[0] = false; + bTexMatricesChanged[1] = false; + bPosNormalMatrixChanged = false; + bProjectionChanged = true; + bViewportChanged = false; memset(&xfmem, 0, sizeof(xfmem)); memset(&constants, 0 , sizeof(constants)); @@ -178,6 +192,8 @@ void VertexShaderManager::Init() memset(g_fProjectionMatrix, 0, sizeof(g_fProjectionMatrix)); for (int i = 0; i < 4; ++i) g_fProjectionMatrix[i*5] = 1.0f; + + dirty = true; } void VertexShaderManager::Shutdown() @@ -186,26 +202,10 @@ void VertexShaderManager::Shutdown() void VertexShaderManager::Dirty() { - nTransformMatricesChanged[0] = 0; - nTransformMatricesChanged[1] = 256; - - nNormalMatricesChanged[0] = 0; - nNormalMatricesChanged[1] = 96; - - nPostTransformMatricesChanged[0] = 0; - nPostTransformMatricesChanged[1] = 256; - - nLightsChanged[0] = 0; - nLightsChanged[1] = 0x80; - - bPosNormalMatrixChanged = true; - bTexMatricesChanged[0] = true; - bTexMatricesChanged[1] = true; - + // This function is called after a savestate is loaded. + // Any constants that can changed based on settings should be re-calculated bProjectionChanged = true; - nMaterialsChanged = BitSet32::AllTrue(4); - dirty = true; } @@ -715,8 +715,19 @@ void VertexShaderManager::DoState(PointerWrap &p) p.Do(s_viewInvRotationMatrix); p.Do(s_fViewTranslationVector); p.Do(s_fViewRotation); + + p.Do(nTransformMatricesChanged); + p.Do(nNormalMatricesChanged); + p.Do(nPostTransformMatricesChanged); + p.Do(nLightsChanged); + + p.Do(nMaterialsChanged); + p.Do(bTexMatricesChanged); + p.Do(bPosNormalMatrixChanged); + p.Do(bProjectionChanged); + p.Do(bViewportChanged); + p.Do(constants); - p.Do(dirty); if (p.GetMode() == PointerWrap::MODE_READ) {