VideoCommon: move xf state management to its own class, so changes can be detected in places other than VertexShaderManager
This commit is contained in:
parent
1a2d0882d0
commit
849a0c13b5
|
@ -39,8 +39,8 @@
|
|||
#include "DiscIO/VolumeDisc.h"
|
||||
|
||||
#include "VideoCommon/VertexManagerBase.h"
|
||||
#include "VideoCommon/VertexShaderManager.h"
|
||||
#include "VideoCommon/XFMemory.h"
|
||||
#include "VideoCommon/XFStateManager.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
|
@ -285,8 +285,8 @@ bool CBoot::EmulatedBS2_GC(Core::System& system, const Core::CPUThreadGuard& gua
|
|||
xfmem.postMatrices[0x3e * 4 + 1] = 1.0f;
|
||||
xfmem.postMatrices[0x3f * 4 + 2] = 1.0f;
|
||||
g_vertex_manager->Flush();
|
||||
auto& vertex_shader_manager = system.GetVertexShaderManager();
|
||||
vertex_shader_manager.InvalidateXFRange(XFMEM_POSTMATRICES + 0x3d * 4, XFMEM_POSTMATRICES_END);
|
||||
auto& xf_state_manager = system.GetXFStateManager();
|
||||
xf_state_manager.InvalidateXFRange(XFMEM_POSTMATRICES + 0x3d * 4, XFMEM_POSTMATRICES_END);
|
||||
|
||||
DVDReadDiscID(system, volume, 0x00000000);
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "VideoCommon/PixelEngine.h"
|
||||
#include "VideoCommon/PixelShaderManager.h"
|
||||
#include "VideoCommon/VertexShaderManager.h"
|
||||
#include "VideoCommon/XFStateManager.h"
|
||||
|
||||
namespace Core
|
||||
{
|
||||
|
@ -77,6 +78,7 @@ struct System::Impl
|
|||
SerialInterface::SerialInterfaceManager m_serial_interface;
|
||||
Sram m_sram;
|
||||
VertexShaderManager m_vertex_shader_manager;
|
||||
XFStateManager m_xf_state_manager;
|
||||
VideoInterface::VideoInterfaceManager m_video_interface;
|
||||
Interpreter m_interpreter;
|
||||
JitInterface m_jit_interface;
|
||||
|
@ -261,6 +263,11 @@ VertexShaderManager& System::GetVertexShaderManager() const
|
|||
return m_impl->m_vertex_shader_manager;
|
||||
}
|
||||
|
||||
XFStateManager& System::GetXFStateManager() const
|
||||
{
|
||||
return m_impl->m_xf_state_manager;
|
||||
}
|
||||
|
||||
VideoInterface::VideoInterfaceManager& System::GetVideoInterface() const
|
||||
{
|
||||
return m_impl->m_video_interface;
|
||||
|
|
|
@ -12,6 +12,7 @@ class PixelShaderManager;
|
|||
class SoundStream;
|
||||
struct Sram;
|
||||
class VertexShaderManager;
|
||||
class XFStateManager;
|
||||
|
||||
namespace AudioInterface
|
||||
{
|
||||
|
@ -155,6 +156,7 @@ public:
|
|||
SerialInterface::SerialInterfaceManager& GetSerialInterface() const;
|
||||
Sram& GetSRAM() const;
|
||||
VertexShaderManager& GetVertexShaderManager() const;
|
||||
XFStateManager& GetXFStateManager() const;
|
||||
VideoInterface::VideoInterfaceManager& GetVideoInterface() const;
|
||||
VideoCommon::CustomAssetLoader& GetCustomAssetLoader() const;
|
||||
|
||||
|
|
|
@ -746,6 +746,7 @@
|
|||
<ClInclude Include="VideoCommon\VideoState.h" />
|
||||
<ClInclude Include="VideoCommon\Widescreen.h" />
|
||||
<ClInclude Include="VideoCommon\XFMemory.h" />
|
||||
<ClInclude Include="VideoCommon\XFStateManager.h" />
|
||||
<ClInclude Include="VideoCommon\XFStructs.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -1356,6 +1357,7 @@
|
|||
<ClCompile Include="VideoCommon\VideoState.cpp" />
|
||||
<ClCompile Include="VideoCommon\Widescreen.cpp" />
|
||||
<ClCompile Include="VideoCommon\XFMemory.cpp" />
|
||||
<ClCompile Include="VideoCommon\XFStateManager.cpp" />
|
||||
<ClCompile Include="VideoCommon\XFStructs.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
|
|
@ -38,11 +38,11 @@
|
|||
#include "VideoCommon/TMEM.h"
|
||||
#include "VideoCommon/TextureCacheBase.h"
|
||||
#include "VideoCommon/TextureDecoder.h"
|
||||
#include "VideoCommon/VertexShaderManager.h"
|
||||
#include "VideoCommon/VideoBackendBase.h"
|
||||
#include "VideoCommon/VideoCommon.h"
|
||||
#include "VideoCommon/VideoConfig.h"
|
||||
#include "VideoCommon/VideoEvents.h"
|
||||
#include "VideoCommon/XFStateManager.h"
|
||||
|
||||
using namespace BPFunctions;
|
||||
|
||||
|
@ -55,8 +55,7 @@ void BPInit()
|
|||
bpmem.bpMask = 0xFFFFFF;
|
||||
}
|
||||
|
||||
static void BPWritten(PixelShaderManager& pixel_shader_manager,
|
||||
VertexShaderManager& vertex_shader_manager,
|
||||
static void BPWritten(PixelShaderManager& pixel_shader_manager, XFStateManager& xf_state_manager,
|
||||
GeometryShaderManager& geometry_shader_manager, const BPCmd& bp,
|
||||
int cycles_into_future)
|
||||
{
|
||||
|
@ -139,7 +138,7 @@ static void BPWritten(PixelShaderManager& pixel_shader_manager,
|
|||
case BPMEM_SCISSORTL: // Scissor Rectable Top, Left
|
||||
case BPMEM_SCISSORBR: // Scissor Rectable Bottom, Right
|
||||
case BPMEM_SCISSOROFFSET: // Scissor Offset
|
||||
vertex_shader_manager.SetViewportChanged();
|
||||
xf_state_manager.SetViewportChanged();
|
||||
geometry_shader_manager.SetViewportChanged();
|
||||
return;
|
||||
case BPMEM_LINEPTWIDTH: // Line Width
|
||||
|
@ -790,7 +789,7 @@ void LoadBPReg(u8 reg, u32 value, int cycles_into_future)
|
|||
if (reg != BPMEM_BP_MASK)
|
||||
bpmem.bpMask = 0xFFFFFF;
|
||||
|
||||
BPWritten(system.GetPixelShaderManager(), system.GetVertexShaderManager(),
|
||||
BPWritten(system.GetPixelShaderManager(), system.GetXFStateManager(),
|
||||
system.GetGeometryShaderManager(), bp, cycles_into_future);
|
||||
}
|
||||
|
||||
|
|
|
@ -196,6 +196,8 @@ add_library(videocommon
|
|||
Widescreen.h
|
||||
XFMemory.cpp
|
||||
XFMemory.h
|
||||
XFStateManager.cpp
|
||||
XFStateManager.h
|
||||
XFStructs.cpp
|
||||
XFStructs.h
|
||||
)
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "VideoCommon/VertexShaderManager.h"
|
||||
#include "VideoCommon/VideoConfig.h"
|
||||
#include "VideoCommon/XFMemory.h"
|
||||
#include "VideoCommon/XFStateManager.h"
|
||||
|
||||
// We really want things like c.w * a.x - a.w * c.x to stay symmetric, so they cancel to zero on
|
||||
// degenerate triangles. Make sure the compiler doesn't optimize in fmas where not requested.
|
||||
|
@ -153,7 +154,8 @@ bool CPUCull::AreAllVerticesCulled(VertexLoaderBase* loader, OpcodeDecoder::Prim
|
|||
}
|
||||
|
||||
// transform functions need the projection matrix to tranform to clip space
|
||||
Core::System::GetInstance().GetVertexShaderManager().SetProjectionMatrix();
|
||||
auto& system = Core::System::GetInstance();
|
||||
system.GetVertexShaderManager().SetProjectionMatrix(system.GetXFStateManager());
|
||||
|
||||
static constexpr Common::EnumMap<CullMode, CullMode::All> cullmode_invert = {
|
||||
CullMode::None, CullMode::Front, CullMode::Back, CullMode::All};
|
||||
|
|
|
@ -27,8 +27,8 @@
|
|||
#include "VideoCommon/Statistics.h"
|
||||
#include "VideoCommon/VertexLoaderBase.h"
|
||||
#include "VideoCommon/VertexLoaderManager.h"
|
||||
#include "VideoCommon/VertexShaderManager.h"
|
||||
#include "VideoCommon/XFMemory.h"
|
||||
#include "VideoCommon/XFStateManager.h"
|
||||
#include "VideoCommon/XFStructs.h"
|
||||
|
||||
namespace OpcodeDecoder
|
||||
|
@ -60,13 +60,13 @@ public:
|
|||
{
|
||||
VertexLoaderManager::g_needs_cp_xf_consistency_check = true;
|
||||
auto& system = Core::System::GetInstance();
|
||||
system.GetVertexShaderManager().SetTexMatrixChangedA(value);
|
||||
system.GetXFStateManager().SetTexMatrixChangedA(value);
|
||||
}
|
||||
else if (sub_command == MATINDEX_B)
|
||||
{
|
||||
VertexLoaderManager::g_needs_cp_xf_consistency_check = true;
|
||||
auto& system = Core::System::GetInstance();
|
||||
system.GetVertexShaderManager().SetTexMatrixChangedB(value);
|
||||
system.GetXFStateManager().SetTexMatrixChangedB(value);
|
||||
}
|
||||
else if (sub_command == VCD_LO || sub_command == VCD_HI)
|
||||
{
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include "VideoCommon/VideoCommon.h"
|
||||
#include "VideoCommon/VideoConfig.h"
|
||||
#include "VideoCommon/XFMemory.h"
|
||||
#include "VideoCommon/XFStateManager.h"
|
||||
|
||||
std::unique_ptr<VertexManagerBase> g_vertex_manager;
|
||||
|
||||
|
@ -539,6 +540,7 @@ void VertexManagerBase::Flush()
|
|||
auto& pixel_shader_manager = system.GetPixelShaderManager();
|
||||
auto& geometry_shader_manager = system.GetGeometryShaderManager();
|
||||
auto& vertex_shader_manager = system.GetVertexShaderManager();
|
||||
auto& xf_state_manager = system.GetXFStateManager();
|
||||
|
||||
if (g_ActiveConfig.bGraphicMods)
|
||||
{
|
||||
|
@ -578,7 +580,7 @@ void VertexManagerBase::Flush()
|
|||
}
|
||||
}
|
||||
}
|
||||
vertex_shader_manager.SetConstants(texture_names);
|
||||
vertex_shader_manager.SetConstants(texture_names, xf_state_manager);
|
||||
if (!bpmem.genMode.zfreeze)
|
||||
{
|
||||
// Must be done after VertexShaderManager::SetConstants()
|
||||
|
|
|
@ -30,24 +30,13 @@
|
|||
#include "VideoCommon/VideoCommon.h"
|
||||
#include "VideoCommon/VideoConfig.h"
|
||||
#include "VideoCommon/XFMemory.h"
|
||||
#include "VideoCommon/XFStateManager.h"
|
||||
|
||||
void VertexShaderManager::Init()
|
||||
{
|
||||
// Initialize state tracking variables
|
||||
m_minmax_transform_matrices_changed.fill(-1);
|
||||
m_minmax_normal_matrices_changed.fill(-1);
|
||||
m_minmax_post_transform_matrices_changed.fill(-1);
|
||||
m_minmax_lights_changed.fill(-1);
|
||||
m_materials_changed = BitSet32(0);
|
||||
m_tex_matrices_changed.fill(false);
|
||||
m_pos_normal_matrix_changed = false;
|
||||
m_projection_changed = true;
|
||||
m_viewport_changed = false;
|
||||
m_tex_mtx_info_changed = false;
|
||||
m_lighting_config_changed = false;
|
||||
m_projection_graphics_mod_change = false;
|
||||
|
||||
std::memset(static_cast<void*>(&xfmem), 0, sizeof(xfmem));
|
||||
constants = {};
|
||||
|
||||
// TODO: should these go inside ResetView()?
|
||||
|
@ -57,15 +46,6 @@ void VertexShaderManager::Init()
|
|||
dirty = true;
|
||||
}
|
||||
|
||||
void VertexShaderManager::Dirty()
|
||||
{
|
||||
// This function is called after a savestate is loaded.
|
||||
// Any constants that can changed based on settings should be re-calculated
|
||||
m_projection_changed = true;
|
||||
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
Common::Matrix44 VertexShaderManager::LoadProjectionMatrix()
|
||||
{
|
||||
const auto& rawProjection = xfmem.projection.rawProjection;
|
||||
|
@ -147,11 +127,11 @@ Common::Matrix44 VertexShaderManager::LoadProjectionMatrix()
|
|||
return corrected_matrix;
|
||||
}
|
||||
|
||||
void VertexShaderManager::SetProjectionMatrix()
|
||||
void VertexShaderManager::SetProjectionMatrix(XFStateManager& xf_state_manager)
|
||||
{
|
||||
if (m_projection_changed || g_freelook_camera.GetController()->IsDirty())
|
||||
if (xf_state_manager.DidProjectionChange() || g_freelook_camera.GetController()->IsDirty())
|
||||
{
|
||||
m_projection_changed = false;
|
||||
xf_state_manager.ResetProjection();
|
||||
auto corrected_matrix = LoadProjectionMatrix();
|
||||
memcpy(constants.projection.data(), corrected_matrix.data.data(), 4 * sizeof(float4));
|
||||
}
|
||||
|
@ -178,7 +158,8 @@ bool VertexShaderManager::UseVertexDepthRange()
|
|||
|
||||
// Syncs the shader constant buffers with xfmem
|
||||
// TODO: A cleaner way to control the matrices without making a mess in the parameters field
|
||||
void VertexShaderManager::SetConstants(const std::vector<std::string>& textures)
|
||||
void VertexShaderManager::SetConstants(const std::vector<std::string>& textures,
|
||||
XFStateManager& xf_state_manager)
|
||||
{
|
||||
if (constants.missing_color_hex != g_ActiveConfig.iMissingColorValue)
|
||||
{
|
||||
|
@ -192,44 +173,50 @@ void VertexShaderManager::SetConstants(const std::vector<std::string>& textures)
|
|||
dirty = true;
|
||||
}
|
||||
|
||||
if (m_minmax_transform_matrices_changed[0] >= 0)
|
||||
const auto per_vertex_transform_matrix_changes =
|
||||
xf_state_manager.GetPerVertexTransformMatrixChanges();
|
||||
if (per_vertex_transform_matrix_changes[0] >= 0)
|
||||
{
|
||||
int startn = m_minmax_transform_matrices_changed[0] / 4;
|
||||
int endn = (m_minmax_transform_matrices_changed[1] + 3) / 4;
|
||||
int startn = per_vertex_transform_matrix_changes[0] / 4;
|
||||
int endn = (per_vertex_transform_matrix_changes[1] + 3) / 4;
|
||||
memcpy(constants.transformmatrices[startn].data(), &xfmem.posMatrices[startn * 4],
|
||||
(endn - startn) * sizeof(float4));
|
||||
dirty = true;
|
||||
m_minmax_transform_matrices_changed[0] = m_minmax_transform_matrices_changed[1] = -1;
|
||||
xf_state_manager.ResetPerVertexTransformMatrixChanges();
|
||||
}
|
||||
|
||||
if (m_minmax_normal_matrices_changed[0] >= 0)
|
||||
const auto per_vertex_normal_matrices_changed =
|
||||
xf_state_manager.GetPerVertexNormalMatrixChanges();
|
||||
if (per_vertex_normal_matrices_changed[0] >= 0)
|
||||
{
|
||||
int startn = m_minmax_normal_matrices_changed[0] / 3;
|
||||
int endn = (m_minmax_normal_matrices_changed[1] + 2) / 3;
|
||||
int startn = per_vertex_normal_matrices_changed[0] / 3;
|
||||
int endn = (per_vertex_normal_matrices_changed[1] + 2) / 3;
|
||||
for (int i = startn; i < endn; i++)
|
||||
{
|
||||
memcpy(constants.normalmatrices[i].data(), &xfmem.normalMatrices[3 * i], 12);
|
||||
}
|
||||
dirty = true;
|
||||
m_minmax_normal_matrices_changed[0] = m_minmax_normal_matrices_changed[1] = -1;
|
||||
xf_state_manager.ResetPerVertexNormalMatrixChanges();
|
||||
}
|
||||
|
||||
if (m_minmax_post_transform_matrices_changed[0] >= 0)
|
||||
const auto post_transform_matrices_changed = xf_state_manager.GetPostTransformMatrixChanges();
|
||||
if (post_transform_matrices_changed[0] >= 0)
|
||||
{
|
||||
int startn = m_minmax_post_transform_matrices_changed[0] / 4;
|
||||
int endn = (m_minmax_post_transform_matrices_changed[1] + 3) / 4;
|
||||
int startn = post_transform_matrices_changed[0] / 4;
|
||||
int endn = (post_transform_matrices_changed[1] + 3) / 4;
|
||||
memcpy(constants.posttransformmatrices[startn].data(), &xfmem.postMatrices[startn * 4],
|
||||
(endn - startn) * sizeof(float4));
|
||||
dirty = true;
|
||||
m_minmax_post_transform_matrices_changed[0] = m_minmax_post_transform_matrices_changed[1] = -1;
|
||||
xf_state_manager.ResetPostTransformMatrixChanges();
|
||||
}
|
||||
|
||||
if (m_minmax_lights_changed[0] >= 0)
|
||||
const auto light_changes = xf_state_manager.GetLightsChanged();
|
||||
if (light_changes[0] >= 0)
|
||||
{
|
||||
// TODO: Outdated comment
|
||||
// lights don't have a 1 to 1 mapping, the color component needs to be converted to 4 floats
|
||||
int istart = m_minmax_lights_changed[0] / 0x10;
|
||||
int iend = (m_minmax_lights_changed[1] + 15) / 0x10;
|
||||
const int istart = light_changes[0] / 0x10;
|
||||
const int iend = (light_changes[1] + 15) / 0x10;
|
||||
|
||||
for (int i = istart; i < iend; ++i)
|
||||
{
|
||||
|
@ -282,10 +269,10 @@ void VertexShaderManager::SetConstants(const std::vector<std::string>& textures)
|
|||
}
|
||||
dirty = true;
|
||||
|
||||
m_minmax_lights_changed[0] = m_minmax_lights_changed[1] = -1;
|
||||
xf_state_manager.ResetLightsChanged();
|
||||
}
|
||||
|
||||
for (int i : m_materials_changed)
|
||||
for (int i : xf_state_manager.GetMaterialChanges())
|
||||
{
|
||||
u32 data = i >= 2 ? xfmem.matColor[i - 2] : xfmem.ambColor[i];
|
||||
constants.materials[i][0] = (data >> 24) & 0xFF;
|
||||
|
@ -294,12 +281,11 @@ void VertexShaderManager::SetConstants(const std::vector<std::string>& textures)
|
|||
constants.materials[i][3] = data & 0xFF;
|
||||
dirty = true;
|
||||
}
|
||||
m_materials_changed = BitSet32(0);
|
||||
xf_state_manager.ResetMaterialChanges();
|
||||
|
||||
if (m_pos_normal_matrix_changed)
|
||||
if (xf_state_manager.DidPosNormalChange())
|
||||
{
|
||||
m_pos_normal_matrix_changed = false;
|
||||
|
||||
xf_state_manager.ResetPosNormalChange();
|
||||
const float* pos = &xfmem.posMatrices[g_main_cp_state.matrix_index_a.PosNormalMtxIdx * 4];
|
||||
const float* norm =
|
||||
&xfmem.normalMatrices[3 * (g_main_cp_state.matrix_index_a.PosNormalMtxIdx & 31)];
|
||||
|
@ -311,9 +297,9 @@ void VertexShaderManager::SetConstants(const std::vector<std::string>& textures)
|
|||
dirty = true;
|
||||
}
|
||||
|
||||
if (m_tex_matrices_changed[0])
|
||||
if (xf_state_manager.DidTexMatrixAChange())
|
||||
{
|
||||
m_tex_matrices_changed[0] = false;
|
||||
xf_state_manager.ResetTexMatrixAChange();
|
||||
const std::array<const float*, 4> pos_matrix_ptrs{
|
||||
&xfmem.posMatrices[g_main_cp_state.matrix_index_a.Tex0MtxIdx * 4],
|
||||
&xfmem.posMatrices[g_main_cp_state.matrix_index_a.Tex1MtxIdx * 4],
|
||||
|
@ -328,9 +314,9 @@ void VertexShaderManager::SetConstants(const std::vector<std::string>& textures)
|
|||
dirty = true;
|
||||
}
|
||||
|
||||
if (m_tex_matrices_changed[1])
|
||||
if (xf_state_manager.DidTexMatrixBChange())
|
||||
{
|
||||
m_tex_matrices_changed[1] = false;
|
||||
xf_state_manager.ResetTexMatrixBChange();
|
||||
const std::array<const float*, 4> pos_matrix_ptrs{
|
||||
&xfmem.posMatrices[g_main_cp_state.matrix_index_b.Tex4MtxIdx * 4],
|
||||
&xfmem.posMatrices[g_main_cp_state.matrix_index_b.Tex5MtxIdx * 4],
|
||||
|
@ -345,9 +331,9 @@ void VertexShaderManager::SetConstants(const std::vector<std::string>& textures)
|
|||
dirty = true;
|
||||
}
|
||||
|
||||
if (m_viewport_changed)
|
||||
if (xf_state_manager.DidViewportChange())
|
||||
{
|
||||
m_viewport_changed = false;
|
||||
xf_state_manager.ResetViewportChange();
|
||||
|
||||
// The console GPU places the pixel center at 7/12 unless antialiasing
|
||||
// is enabled, while D3D and OpenGL place it at 0.5. See the comment
|
||||
|
@ -421,10 +407,10 @@ void VertexShaderManager::SetConstants(const std::vector<std::string>& textures)
|
|||
}
|
||||
}
|
||||
|
||||
if (m_projection_changed || g_freelook_camera.GetController()->IsDirty() ||
|
||||
if (xf_state_manager.DidProjectionChange() || g_freelook_camera.GetController()->IsDirty() ||
|
||||
!projection_actions.empty() || m_projection_graphics_mod_change)
|
||||
{
|
||||
m_projection_changed = false;
|
||||
xf_state_manager.ResetProjection();
|
||||
m_projection_graphics_mod_change = !projection_actions.empty();
|
||||
|
||||
auto corrected_matrix = LoadProjectionMatrix();
|
||||
|
@ -436,13 +422,12 @@ void VertexShaderManager::SetConstants(const std::vector<std::string>& textures)
|
|||
}
|
||||
|
||||
memcpy(constants.projection.data(), corrected_matrix.data.data(), 4 * sizeof(float4));
|
||||
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
if (m_tex_mtx_info_changed)
|
||||
if (xf_state_manager.DidTexMatrixInfoChange())
|
||||
{
|
||||
m_tex_mtx_info_changed = false;
|
||||
xf_state_manager.ResetTexMatrixInfoChange();
|
||||
constants.xfmem_dualTexInfo = xfmem.dualTexTrans.enabled;
|
||||
for (size_t i = 0; i < std::size(xfmem.texMtxInfo); i++)
|
||||
constants.xfmem_pack1[i][0] = xfmem.texMtxInfo[i].hex;
|
||||
|
@ -452,9 +437,9 @@ void VertexShaderManager::SetConstants(const std::vector<std::string>& textures)
|
|||
dirty = true;
|
||||
}
|
||||
|
||||
if (m_lighting_config_changed)
|
||||
if (xf_state_manager.DidLightingConfigChange())
|
||||
{
|
||||
m_lighting_config_changed = false;
|
||||
xf_state_manager.ResetLightingConfigChange();
|
||||
|
||||
for (size_t i = 0; i < 2; i++)
|
||||
{
|
||||
|
@ -466,173 +451,6 @@ void VertexShaderManager::SetConstants(const std::vector<std::string>& textures)
|
|||
}
|
||||
}
|
||||
|
||||
void VertexShaderManager::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 VertexShaderManager::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 VertexShaderManager::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 VertexShaderManager::SetViewportChanged()
|
||||
{
|
||||
m_viewport_changed = true;
|
||||
}
|
||||
|
||||
void VertexShaderManager::SetProjectionChanged()
|
||||
{
|
||||
m_projection_changed = true;
|
||||
}
|
||||
|
||||
void VertexShaderManager::SetMaterialColorChanged(int index)
|
||||
{
|
||||
m_materials_changed[index] = true;
|
||||
}
|
||||
|
||||
void VertexShaderManager::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 VertexShaderManager::SetLightingConfigChanged()
|
||||
{
|
||||
m_lighting_config_changed = true;
|
||||
}
|
||||
|
||||
void VertexShaderManager::TransformToClipSpace(const float* data, float* out, u32 MtxIdx)
|
||||
{
|
||||
const float* world_matrix = &xfmem.posMatrices[(MtxIdx & 0x3f) * 4];
|
||||
|
@ -662,23 +480,10 @@ void VertexShaderManager::DoState(PointerWrap& p)
|
|||
p.Do(m_viewport_correction);
|
||||
g_freelook_camera.DoState(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);
|
||||
|
||||
p.Do(constants);
|
||||
|
||||
if (p.IsReadMode())
|
||||
{
|
||||
Dirty();
|
||||
dirty = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,28 +15,18 @@
|
|||
|
||||
class PointerWrap;
|
||||
struct PortableVertexDeclaration;
|
||||
class XFStateManager;
|
||||
|
||||
// The non-API dependent parts.
|
||||
class alignas(16) VertexShaderManager
|
||||
{
|
||||
public:
|
||||
void Init();
|
||||
void Dirty();
|
||||
void DoState(PointerWrap& p);
|
||||
|
||||
// constant management
|
||||
void SetProjectionMatrix();
|
||||
void SetConstants(const std::vector<std::string>& textures);
|
||||
|
||||
void InvalidateXFRange(int start, int end);
|
||||
void SetTexMatrixChangedA(u32 value);
|
||||
void SetTexMatrixChangedB(u32 value);
|
||||
void SetViewportChanged();
|
||||
void SetProjectionChanged();
|
||||
void SetMaterialColorChanged(int index);
|
||||
|
||||
void SetTexMatrixInfoChanged(int index);
|
||||
void SetLightingConfigChanged();
|
||||
void SetProjectionMatrix(XFStateManager& xf_state_manager);
|
||||
void SetConstants(const std::vector<std::string>& textures, XFStateManager& xf_state_manager);
|
||||
|
||||
// data: 3 floats representing the X, Y and Z vertex model coordinates and the posmatrix index.
|
||||
// out: 4 floats which will be initialized with the corresponding clip space coordinates
|
||||
|
@ -92,18 +82,7 @@ private:
|
|||
alignas(16) std::array<float, 16> m_projection_matrix;
|
||||
|
||||
// track changes
|
||||
std::array<bool, 2> m_tex_matrices_changed{};
|
||||
bool m_pos_normal_matrix_changed = false;
|
||||
bool m_projection_changed = false;
|
||||
bool m_viewport_changed = false;
|
||||
bool m_tex_mtx_info_changed = false;
|
||||
bool m_lighting_config_changed = false;
|
||||
bool m_projection_graphics_mod_change = false;
|
||||
BitSet32 m_materials_changed;
|
||||
std::array<int, 2> m_minmax_transform_matrices_changed{};
|
||||
std::array<int, 2> m_minmax_normal_matrices_changed{};
|
||||
std::array<int, 2> m_minmax_post_transform_matrices_changed{};
|
||||
std::array<int, 2> m_minmax_lights_changed{};
|
||||
|
||||
Common::Matrix44 m_viewport_correction{};
|
||||
|
||||
|
|
|
@ -66,6 +66,7 @@
|
|||
#include "VideoCommon/VideoConfig.h"
|
||||
#include "VideoCommon/VideoState.h"
|
||||
#include "VideoCommon/Widescreen.h"
|
||||
#include "VideoCommon/XFStateManager.h"
|
||||
|
||||
VideoBackendBase* g_video_backend = nullptr;
|
||||
|
||||
|
@ -385,6 +386,7 @@ bool VideoBackendBase::InitializeShared(std::unique_ptr<AbstractGfx> gfx,
|
|||
system.GetVertexShaderManager().Init();
|
||||
system.GetGeometryShaderManager().Init();
|
||||
system.GetPixelShaderManager().Init();
|
||||
system.GetXFStateManager().Init();
|
||||
TMEM::Init();
|
||||
|
||||
g_Config.VerifyValidity();
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "VideoCommon/VertexShaderManager.h"
|
||||
#include "VideoCommon/Widescreen.h"
|
||||
#include "VideoCommon/XFMemory.h"
|
||||
#include "VideoCommon/XFStateManager.h"
|
||||
|
||||
void VideoCommon_DoState(PointerWrap& p)
|
||||
{
|
||||
|
@ -105,6 +106,9 @@ void VideoCommon_DoState(PointerWrap& p)
|
|||
g_widescreen->DoState(p);
|
||||
p.DoMarker("Widescreen");
|
||||
|
||||
system.GetXFStateManager().DoState(p);
|
||||
p.DoMarker("XFStateManager");
|
||||
|
||||
// Refresh state.
|
||||
if (p.IsReadMode())
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
// Copyright 2023 Dolphin Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
|
||||
#include "Common/BitSet.h"
|
||||
|
||||
class PointerWrap;
|
||||
|
||||
// This class manages how XF state changes over
|
||||
// a period of time (typically a single draw call)
|
||||
class XFStateManager
|
||||
{
|
||||
public:
|
||||
void Init();
|
||||
void DoState(PointerWrap& p);
|
||||
|
||||
void InvalidateXFRange(int start, int end);
|
||||
|
||||
void SetTexMatrixChangedA(u32 value);
|
||||
bool DidTexMatrixAChange() const { return m_tex_matrices_changed[0]; }
|
||||
void ResetTexMatrixAChange();
|
||||
|
||||
void SetTexMatrixChangedB(u32 value);
|
||||
bool DidTexMatrixBChange() const { return m_tex_matrices_changed[1]; }
|
||||
void ResetTexMatrixBChange();
|
||||
|
||||
bool DidPosNormalChange() const { return m_pos_normal_matrix_changed; }
|
||||
void ResetPosNormalChange();
|
||||
|
||||
void SetProjectionChanged();
|
||||
bool DidProjectionChange() const { return m_projection_changed; }
|
||||
void ResetProjection();
|
||||
|
||||
void SetViewportChanged();
|
||||
bool DidViewportChange() const { return m_viewport_changed; }
|
||||
void ResetViewportChange();
|
||||
|
||||
void SetTexMatrixInfoChanged(int index);
|
||||
bool DidTexMatrixInfoChange() const { return m_tex_mtx_info_changed; }
|
||||
void ResetTexMatrixInfoChange();
|
||||
|
||||
void SetLightingConfigChanged();
|
||||
bool DidLightingConfigChange() const { return m_lighting_config_changed; }
|
||||
void ResetLightingConfigChange();
|
||||
|
||||
const std::array<int, 2>& GetLightsChanged() const { return m_minmax_lights_changed; }
|
||||
void ResetLightsChanged();
|
||||
|
||||
void SetMaterialColorChanged(int index);
|
||||
const BitSet32& GetMaterialChanges() const { return m_materials_changed; }
|
||||
void ResetMaterialChanges();
|
||||
|
||||
const std::array<int, 2>& GetPerVertexTransformMatrixChanges() const
|
||||
{
|
||||
return m_minmax_transform_matrices_changed;
|
||||
}
|
||||
void ResetPerVertexTransformMatrixChanges();
|
||||
|
||||
const std::array<int, 2>& GetPerVertexNormalMatrixChanges() const
|
||||
{
|
||||
return m_minmax_normal_matrices_changed;
|
||||
}
|
||||
void ResetPerVertexNormalMatrixChanges();
|
||||
|
||||
const std::array<int, 2>& GetPostTransformMatrixChanges() const
|
||||
{
|
||||
return m_minmax_post_transform_matrices_changed;
|
||||
}
|
||||
void ResetPostTransformMatrixChanges();
|
||||
|
||||
private:
|
||||
// track changes
|
||||
std::array<bool, 2> m_tex_matrices_changed{};
|
||||
bool m_pos_normal_matrix_changed = false;
|
||||
bool m_projection_changed = false;
|
||||
bool m_viewport_changed = false;
|
||||
bool m_tex_mtx_info_changed = false;
|
||||
bool m_lighting_config_changed = false;
|
||||
BitSet32 m_materials_changed;
|
||||
std::array<int, 2> m_minmax_transform_matrices_changed{};
|
||||
std::array<int, 2> m_minmax_normal_matrices_changed{};
|
||||
std::array<int, 2> m_minmax_post_transform_matrices_changed{};
|
||||
std::array<int, 2> m_minmax_lights_changed{};
|
||||
};
|
|
@ -18,18 +18,17 @@
|
|||
#include "VideoCommon/PixelShaderManager.h"
|
||||
#include "VideoCommon/VertexLoaderManager.h"
|
||||
#include "VideoCommon/VertexManagerBase.h"
|
||||
#include "VideoCommon/VertexShaderManager.h"
|
||||
#include "VideoCommon/XFMemory.h"
|
||||
#include "VideoCommon/XFStateManager.h"
|
||||
|
||||
static void XFMemWritten(VertexShaderManager& vertex_shader_manager, u32 transferSize,
|
||||
u32 baseAddress)
|
||||
static void XFMemWritten(XFStateManager& xf_state_manager, u32 transferSize, u32 baseAddress)
|
||||
{
|
||||
g_vertex_manager->Flush();
|
||||
vertex_shader_manager.InvalidateXFRange(baseAddress, baseAddress + transferSize);
|
||||
xf_state_manager.InvalidateXFRange(baseAddress, baseAddress + transferSize);
|
||||
}
|
||||
|
||||
static void XFRegWritten(Core::System& system, VertexShaderManager& vertex_shader_manager,
|
||||
u32 address, u32 value)
|
||||
static void XFRegWritten(Core::System& system, XFStateManager& xf_state_manager, u32 address,
|
||||
u32 value)
|
||||
{
|
||||
if (address >= XFMEM_REGISTERS_START && address < XFMEM_REGISTERS_END)
|
||||
{
|
||||
|
@ -63,7 +62,7 @@ static void XFRegWritten(Core::System& system, VertexShaderManager& vertex_shade
|
|||
case XFMEM_SETNUMCHAN:
|
||||
if (xfmem.numChan.numColorChans != (value & 3))
|
||||
g_vertex_manager->Flush();
|
||||
vertex_shader_manager.SetLightingConfigChanged();
|
||||
xf_state_manager.SetLightingConfigChanged();
|
||||
break;
|
||||
|
||||
case XFMEM_SETCHAN0_AMBCOLOR: // Channel Ambient Color
|
||||
|
@ -73,7 +72,7 @@ static void XFRegWritten(Core::System& system, VertexShaderManager& vertex_shade
|
|||
if (xfmem.ambColor[chan] != value)
|
||||
{
|
||||
g_vertex_manager->Flush();
|
||||
vertex_shader_manager.SetMaterialColorChanged(chan);
|
||||
xf_state_manager.SetMaterialColorChanged(chan);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -85,7 +84,7 @@ static void XFRegWritten(Core::System& system, VertexShaderManager& vertex_shade
|
|||
if (xfmem.matColor[chan] != value)
|
||||
{
|
||||
g_vertex_manager->Flush();
|
||||
vertex_shader_manager.SetMaterialColorChanged(chan + 2);
|
||||
xf_state_manager.SetMaterialColorChanged(chan + 2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -96,21 +95,21 @@ static void XFRegWritten(Core::System& system, VertexShaderManager& vertex_shade
|
|||
case XFMEM_SETCHAN1_ALPHA:
|
||||
if (((u32*)&xfmem)[address] != (value & 0x7fff))
|
||||
g_vertex_manager->Flush();
|
||||
vertex_shader_manager.SetLightingConfigChanged();
|
||||
xf_state_manager.SetLightingConfigChanged();
|
||||
break;
|
||||
|
||||
case XFMEM_DUALTEX:
|
||||
if (xfmem.dualTexTrans.enabled != bool(value & 1))
|
||||
g_vertex_manager->Flush();
|
||||
vertex_shader_manager.SetTexMatrixInfoChanged(-1);
|
||||
xf_state_manager.SetTexMatrixInfoChanged(-1);
|
||||
break;
|
||||
|
||||
case XFMEM_SETMATRIXINDA:
|
||||
vertex_shader_manager.SetTexMatrixChangedA(value);
|
||||
xf_state_manager.SetTexMatrixChangedA(value);
|
||||
VertexLoaderManager::g_needs_cp_xf_consistency_check = true;
|
||||
break;
|
||||
case XFMEM_SETMATRIXINDB:
|
||||
vertex_shader_manager.SetTexMatrixChangedB(value);
|
||||
xf_state_manager.SetTexMatrixChangedB(value);
|
||||
VertexLoaderManager::g_needs_cp_xf_consistency_check = true;
|
||||
break;
|
||||
|
||||
|
@ -121,7 +120,7 @@ static void XFRegWritten(Core::System& system, VertexShaderManager& vertex_shade
|
|||
case XFMEM_SETVIEWPORT + 4:
|
||||
case XFMEM_SETVIEWPORT + 5:
|
||||
g_vertex_manager->Flush();
|
||||
vertex_shader_manager.SetViewportChanged();
|
||||
xf_state_manager.SetViewportChanged();
|
||||
system.GetPixelShaderManager().SetViewportChanged();
|
||||
system.GetGeometryShaderManager().SetViewportChanged();
|
||||
break;
|
||||
|
@ -134,7 +133,7 @@ static void XFRegWritten(Core::System& system, VertexShaderManager& vertex_shade
|
|||
case XFMEM_SETPROJECTION + 5:
|
||||
case XFMEM_SETPROJECTION + 6:
|
||||
g_vertex_manager->Flush();
|
||||
vertex_shader_manager.SetProjectionChanged();
|
||||
xf_state_manager.SetProjectionChanged();
|
||||
system.GetGeometryShaderManager().SetProjectionChanged();
|
||||
break;
|
||||
|
||||
|
@ -152,7 +151,7 @@ static void XFRegWritten(Core::System& system, VertexShaderManager& vertex_shade
|
|||
case XFMEM_SETTEXMTXINFO + 6:
|
||||
case XFMEM_SETTEXMTXINFO + 7:
|
||||
g_vertex_manager->Flush();
|
||||
vertex_shader_manager.SetTexMatrixInfoChanged(address - XFMEM_SETTEXMTXINFO);
|
||||
xf_state_manager.SetTexMatrixInfoChanged(address - XFMEM_SETTEXMTXINFO);
|
||||
break;
|
||||
|
||||
case XFMEM_SETPOSTMTXINFO:
|
||||
|
@ -164,7 +163,7 @@ static void XFRegWritten(Core::System& system, VertexShaderManager& vertex_shade
|
|||
case XFMEM_SETPOSTMTXINFO + 6:
|
||||
case XFMEM_SETPOSTMTXINFO + 7:
|
||||
g_vertex_manager->Flush();
|
||||
vertex_shader_manager.SetTexMatrixInfoChanged(address - XFMEM_SETPOSTMTXINFO);
|
||||
xf_state_manager.SetTexMatrixInfoChanged(address - XFMEM_SETPOSTMTXINFO);
|
||||
break;
|
||||
|
||||
// --------------
|
||||
|
@ -218,7 +217,7 @@ void LoadXFReg(u16 base_address, u8 transfer_size, const u8* data)
|
|||
}
|
||||
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& vertex_shader_manager = system.GetVertexShaderManager();
|
||||
auto& xf_state_manager = system.GetXFStateManager();
|
||||
|
||||
// write to XF mem
|
||||
if (base_address < XFMEM_REGISTERS_START)
|
||||
|
@ -232,7 +231,7 @@ void LoadXFReg(u16 base_address, u8 transfer_size, const u8* data)
|
|||
base_address = XFMEM_REGISTERS_START;
|
||||
}
|
||||
|
||||
XFMemWritten(vertex_shader_manager, xf_mem_transfer_size, xf_mem_base);
|
||||
XFMemWritten(xf_state_manager, xf_mem_transfer_size, xf_mem_base);
|
||||
for (u32 i = 0; i < xf_mem_transfer_size; i++)
|
||||
{
|
||||
((u32*)&xfmem)[xf_mem_base + i] = Common::swap32(data);
|
||||
|
@ -247,7 +246,7 @@ void LoadXFReg(u16 base_address, u8 transfer_size, const u8* data)
|
|||
{
|
||||
const u32 value = Common::swap32(data);
|
||||
|
||||
XFRegWritten(system, vertex_shader_manager, address, value);
|
||||
XFRegWritten(system, xf_state_manager, address, value);
|
||||
((u32*)&xfmem)[address] = value;
|
||||
|
||||
data += 4;
|
||||
|
@ -275,14 +274,14 @@ void LoadIndexedXF(CPArray array, u32 index, u16 address, u8 size)
|
|||
g_main_cp_state.array_strides[array] * index);
|
||||
}
|
||||
|
||||
auto& vertex_shader_manager = system.GetVertexShaderManager();
|
||||
auto& xf_state_manager = system.GetXFStateManager();
|
||||
bool changed = false;
|
||||
for (u32 i = 0; i < size; ++i)
|
||||
{
|
||||
if (currData[i] != Common::swap32(newData[i]))
|
||||
{
|
||||
changed = true;
|
||||
XFMemWritten(vertex_shader_manager, size, address);
|
||||
XFMemWritten(xf_state_manager, size, address);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue