summaryrefslogtreecommitdiff
path: root/Source/Core/VideoCommon/XFStateManager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Core/VideoCommon/XFStateManager.cpp')
-rw-r--r--Source/Core/VideoCommon/XFStateManager.cpp279
1 files changed, 279 insertions, 0 deletions
diff --git a/Source/Core/VideoCommon/XFStateManager.cpp b/Source/Core/VideoCommon/XFStateManager.cpp
new file mode 100644
index 0000000000..98bf98482d
--- /dev/null
+++ b/Source/Core/VideoCommon/XFStateManager.cpp
@@ -0,0 +1,279 @@
+// Copyright 2023 Dolphin Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "VideoCommon/XFStateManager.h"
+
+#include "Common/ChunkFile.h"
+
+#include "VideoCommon/FramebufferManager.h"
+#include "VideoCommon/VertexManagerBase.h"
+#include "VideoCommon/XFMemory.h"
+
+void XFStateManager::Init()
+{
+ // Initialize state tracking variables
+ ResetTexMatrixAChange();
+ ResetTexMatrixBChange();
+ ResetPosNormalChange();
+ ResetProjection();
+ ResetViewportChange();
+ ResetTexMatrixInfoChange();
+ ResetLightingConfigChange();
+ ResetLightsChanged();
+ ResetMaterialChanges();
+ ResetPerVertexTransformMatrixChanges();
+ ResetPerVertexNormalMatrixChanges();
+ ResetPostTransformMatrixChanges();
+
+ std::memset(static_cast<void*>(&xfmem), 0, sizeof(xfmem));
+}
+
+void XFStateManager::DoState(PointerWrap& p)
+{
+ p.DoArray(m_minmax_transform_matrices_changed);
+ p.DoArray(m_minmax_normal_matrices_changed);
+ p.DoArray(m_minmax_post_transform_matrices_changed);
+ p.DoArray(m_minmax_lights_changed);
+
+ p.Do(m_materials_changed);
+ p.DoArray(m_tex_matrices_changed);
+ p.Do(m_pos_normal_matrix_changed);
+ p.Do(m_projection_changed);
+ p.Do(m_viewport_changed);
+ p.Do(m_tex_mtx_info_changed);
+ p.Do(m_lighting_config_changed);
+
+ if (p.IsReadMode())
+ {
+ // This is called after a savestate is loaded.
+ // Any constants that can changed based on settings should be re-calculated
+ m_projection_changed = true;
+ }
+}
+
+void XFStateManager::InvalidateXFRange(int start, int end)
+{
+ if (((u32)start >= (u32)g_main_cp_state.matrix_index_a.PosNormalMtxIdx * 4 &&
+ (u32)start < (u32)g_main_cp_state.matrix_index_a.PosNormalMtxIdx * 4 + 12) ||
+ ((u32)start >=
+ XFMEM_NORMALMATRICES + ((u32)g_main_cp_state.matrix_index_a.PosNormalMtxIdx & 31) * 3 &&
+ (u32)start < XFMEM_NORMALMATRICES +
+ ((u32)g_main_cp_state.matrix_index_a.PosNormalMtxIdx & 31) * 3 + 9))
+ {
+ m_pos_normal_matrix_changed = true;
+ }
+
+ if (((u32)start >= (u32)g_main_cp_state.matrix_index_a.Tex0MtxIdx * 4 &&
+ (u32)start < (u32)g_main_cp_state.matrix_index_a.Tex0MtxIdx * 4 + 12) ||
+ ((u32)start >= (u32)g_main_cp_state.matrix_index_a.Tex1MtxIdx * 4 &&
+ (u32)start < (u32)g_main_cp_state.matrix_index_a.Tex1MtxIdx * 4 + 12) ||
+ ((u32)start >= (u32)g_main_cp_state.matrix_index_a.Tex2MtxIdx * 4 &&
+ (u32)start < (u32)g_main_cp_state.matrix_index_a.Tex2MtxIdx * 4 + 12) ||
+ ((u32)start >= (u32)g_main_cp_state.matrix_index_a.Tex3MtxIdx * 4 &&
+ (u32)start < (u32)g_main_cp_state.matrix_index_a.Tex3MtxIdx * 4 + 12))
+ {
+ m_tex_matrices_changed[0] = true;
+ }
+
+ if (((u32)start >= (u32)g_main_cp_state.matrix_index_b.Tex4MtxIdx * 4 &&
+ (u32)start < (u32)g_main_cp_state.matrix_index_b.Tex4MtxIdx * 4 + 12) ||
+ ((u32)start >= (u32)g_main_cp_state.matrix_index_b.Tex5MtxIdx * 4 &&
+ (u32)start < (u32)g_main_cp_state.matrix_index_b.Tex5MtxIdx * 4 + 12) ||
+ ((u32)start >= (u32)g_main_cp_state.matrix_index_b.Tex6MtxIdx * 4 &&
+ (u32)start < (u32)g_main_cp_state.matrix_index_b.Tex6MtxIdx * 4 + 12) ||
+ ((u32)start >= (u32)g_main_cp_state.matrix_index_b.Tex7MtxIdx * 4 &&
+ (u32)start < (u32)g_main_cp_state.matrix_index_b.Tex7MtxIdx * 4 + 12))
+ {
+ m_tex_matrices_changed[1] = true;
+ }
+
+ if (start < XFMEM_POSMATRICES_END)
+ {
+ if (m_minmax_transform_matrices_changed[0] == -1)
+ {
+ m_minmax_transform_matrices_changed[0] = start;
+ m_minmax_transform_matrices_changed[1] =
+ end > XFMEM_POSMATRICES_END ? XFMEM_POSMATRICES_END : end;
+ }
+ else
+ {
+ if (m_minmax_transform_matrices_changed[0] > start)
+ m_minmax_transform_matrices_changed[0] = start;
+
+ if (m_minmax_transform_matrices_changed[1] < end)
+ m_minmax_transform_matrices_changed[1] =
+ end > XFMEM_POSMATRICES_END ? XFMEM_POSMATRICES_END : end;
+ }
+ }
+
+ if (start < XFMEM_NORMALMATRICES_END && end > XFMEM_NORMALMATRICES)
+ {
+ int _start = start < XFMEM_NORMALMATRICES ? 0 : start - XFMEM_NORMALMATRICES;
+ int _end = end < XFMEM_NORMALMATRICES_END ? end - XFMEM_NORMALMATRICES :
+ XFMEM_NORMALMATRICES_END - XFMEM_NORMALMATRICES;
+
+ if (m_minmax_normal_matrices_changed[0] == -1)
+ {
+ m_minmax_normal_matrices_changed[0] = _start;
+ m_minmax_normal_matrices_changed[1] = _end;
+ }
+ else
+ {
+ if (m_minmax_normal_matrices_changed[0] > _start)
+ m_minmax_normal_matrices_changed[0] = _start;
+
+ if (m_minmax_normal_matrices_changed[1] < _end)
+ m_minmax_normal_matrices_changed[1] = _end;
+ }
+ }
+
+ if (start < XFMEM_POSTMATRICES_END && end > XFMEM_POSTMATRICES)
+ {
+ int _start = start < XFMEM_POSTMATRICES ? XFMEM_POSTMATRICES : start - XFMEM_POSTMATRICES;
+ int _end = end < XFMEM_POSTMATRICES_END ? end - XFMEM_POSTMATRICES :
+ XFMEM_POSTMATRICES_END - XFMEM_POSTMATRICES;
+
+ if (m_minmax_post_transform_matrices_changed[0] == -1)
+ {
+ m_minmax_post_transform_matrices_changed[0] = _start;
+ m_minmax_post_transform_matrices_changed[1] = _end;
+ }
+ else
+ {
+ if (m_minmax_post_transform_matrices_changed[0] > _start)
+ m_minmax_post_transform_matrices_changed[0] = _start;
+
+ if (m_minmax_post_transform_matrices_changed[1] < _end)
+ m_minmax_post_transform_matrices_changed[1] = _end;
+ }
+ }
+
+ if (start < XFMEM_LIGHTS_END && end > XFMEM_LIGHTS)
+ {
+ int _start = start < XFMEM_LIGHTS ? XFMEM_LIGHTS : start - XFMEM_LIGHTS;
+ int _end = end < XFMEM_LIGHTS_END ? end - XFMEM_LIGHTS : XFMEM_LIGHTS_END - XFMEM_LIGHTS;
+
+ if (m_minmax_lights_changed[0] == -1)
+ {
+ m_minmax_lights_changed[0] = _start;
+ m_minmax_lights_changed[1] = _end;
+ }
+ else
+ {
+ if (m_minmax_lights_changed[0] > _start)
+ m_minmax_lights_changed[0] = _start;
+
+ if (m_minmax_lights_changed[1] < _end)
+ m_minmax_lights_changed[1] = _end;
+ }
+ }
+}
+
+void XFStateManager::SetTexMatrixChangedA(u32 Value)
+{
+ if (g_main_cp_state.matrix_index_a.Hex != Value)
+ {
+ g_vertex_manager->Flush();
+ if (g_main_cp_state.matrix_index_a.PosNormalMtxIdx != (Value & 0x3f))
+ m_pos_normal_matrix_changed = true;
+ m_tex_matrices_changed[0] = true;
+ g_main_cp_state.matrix_index_a.Hex = Value;
+ }
+}
+
+void XFStateManager::ResetTexMatrixAChange()
+{
+ m_tex_matrices_changed[0] = false;
+}
+
+void XFStateManager::SetTexMatrixChangedB(u32 Value)
+{
+ if (g_main_cp_state.matrix_index_b.Hex != Value)
+ {
+ g_vertex_manager->Flush();
+ m_tex_matrices_changed[1] = true;
+ g_main_cp_state.matrix_index_b.Hex = Value;
+ }
+}
+
+void XFStateManager::ResetTexMatrixBChange()
+{
+ m_tex_matrices_changed[1] = false;
+}
+
+void XFStateManager::ResetPosNormalChange()
+{
+ m_pos_normal_matrix_changed = false;
+}
+
+void XFStateManager::SetProjectionChanged()
+{
+ m_projection_changed = true;
+}
+
+void XFStateManager::ResetProjection()
+{
+ m_projection_changed = false;
+}
+
+void XFStateManager::SetViewportChanged()
+{
+ m_viewport_changed = true;
+}
+
+void XFStateManager::ResetViewportChange()
+{
+ m_viewport_changed = false;
+}
+
+void XFStateManager::SetTexMatrixInfoChanged(int index)
+{
+ // TODO: Should we track this with more precision, like which indices changed?
+ // The whole vertex constants are probably going to be uploaded regardless.
+ m_tex_mtx_info_changed = true;
+}
+
+void XFStateManager::ResetTexMatrixInfoChange()
+{
+ m_tex_mtx_info_changed = false;
+}
+
+void XFStateManager::SetLightingConfigChanged()
+{
+ m_lighting_config_changed = true;
+}
+
+void XFStateManager::ResetLightingConfigChange()
+{
+ m_lighting_config_changed = false;
+}
+
+void XFStateManager::ResetLightsChanged()
+{
+ m_minmax_lights_changed.fill(-1);
+}
+
+void XFStateManager::SetMaterialColorChanged(int index)
+{
+ m_materials_changed[index] = true;
+}
+
+void XFStateManager::ResetMaterialChanges()
+{
+ m_materials_changed = BitSet32(0);
+}
+
+void XFStateManager::ResetPerVertexTransformMatrixChanges()
+{
+ m_minmax_transform_matrices_changed.fill(-1);
+}
+
+void XFStateManager::ResetPerVertexNormalMatrixChanges()
+{
+ m_minmax_normal_matrices_changed.fill(-1);
+}
+
+void XFStateManager::ResetPostTransformMatrixChanges()
+{
+ m_minmax_post_transform_matrices_changed.fill(-1);
+}