diff options
Diffstat (limited to 'Source/Core/VideoCommon/XFStateManager.cpp')
| -rw-r--r-- | Source/Core/VideoCommon/XFStateManager.cpp | 279 |
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); +} |
