mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-21 05:09:34 -06:00
VideoCommon: move xf state management to its own class, so changes can be detected in places other than VertexShaderManager
This commit is contained in:
279
Source/Core/VideoCommon/XFStateManager.cpp
Normal file
279
Source/Core/VideoCommon/XFStateManager.cpp
Normal file
@ -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);
|
||||
}
|
Reference in New Issue
Block a user