300 changes: 141 additions & 159 deletions Source/Core/VideoCommon/VertexShaderManager.cpp

Large diffs are not rendered by default.

58 changes: 40 additions & 18 deletions Source/Core/VideoCommon/VertexShaderManager.h
Expand Up @@ -3,43 +3,65 @@

#pragma once

#include <array>
#include <string>
#include <vector>

#include "Common/BitSet.h"
#include "Common/CommonTypes.h"
#include "Common/Matrix.h"
#include "VideoCommon/ConstantManager.h"

class PointerWrap;
struct PortableVertexDeclaration;

// The non-API dependent parts.
class VertexShaderManager
class alignas(16) VertexShaderManager
{
public:
static void Init();
static void Dirty();
static void DoState(PointerWrap& p);
void Init();
void Dirty();
void DoState(PointerWrap& p);

// constant management
static void SetConstants(const std::vector<std::string>& textures);
void SetConstants(const std::vector<std::string>& textures);

static void InvalidateXFRange(int start, int end);
static void SetTexMatrixChangedA(u32 value);
static void SetTexMatrixChangedB(u32 value);
static void SetViewportChanged();
static void SetProjectionChanged();
static void SetMaterialColorChanged(int index);
void InvalidateXFRange(int start, int end);
void SetTexMatrixChangedA(u32 value);
void SetTexMatrixChangedB(u32 value);
void SetViewportChanged();
void SetProjectionChanged();
void SetMaterialColorChanged(int index);

static void SetVertexFormat(u32 components, const PortableVertexDeclaration& format);
static void SetTexMatrixInfoChanged(int index);
static void SetLightingConfigChanged();
void SetVertexFormat(u32 components, const PortableVertexDeclaration& format);
void SetTexMatrixInfoChanged(int index);
void SetLightingConfigChanged();

// 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
// NOTE: g_fProjectionMatrix must be up to date when this is called
// NOTE: m_projection_matrix must be up to date when this is called
// (i.e. VertexShaderManager::SetConstants needs to be called before using this!)
static void TransformToClipSpace(const float* data, float* out, u32 mtxIdx);
void TransformToClipSpace(const float* data, float* out, u32 mtxIdx);

static VertexShaderConstants constants;
static bool dirty;
VertexShaderConstants constants{};
bool dirty = false;

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{};
};
2 changes: 1 addition & 1 deletion Source/Core/VideoCommon/VideoBackendBase.cpp
Expand Up @@ -328,7 +328,7 @@ void VideoBackendBase::InitializeShared()
system.GetPixelEngine().Init(system);
BPInit();
VertexLoaderManager::Init();
VertexShaderManager::Init();
system.GetVertexShaderManager().Init();
GeometryShaderManager::Init();
system.GetPixelShaderManager().Init();
TMEM::Init();
Expand Down
2 changes: 1 addition & 1 deletion Source/Core/VideoCommon/VideoState.cpp
Expand Up @@ -76,7 +76,7 @@ void VideoCommon_DoState(PointerWrap& p)
system.GetPixelShaderManager().DoState(p);
p.DoMarker("PixelShaderManager");

VertexShaderManager::DoState(p);
system.GetVertexShaderManager().DoState(p);
p.DoMarker("VertexShaderManager");

GeometryShaderManager::DoState(p);
Expand Down
40 changes: 23 additions & 17 deletions Source/Core/VideoCommon/XFStructs.cpp
Expand Up @@ -21,13 +21,14 @@
#include "VideoCommon/VertexShaderManager.h"
#include "VideoCommon/XFMemory.h"

static void XFMemWritten(u32 transferSize, u32 baseAddress)
static void XFMemWritten(VertexShaderManager& vertex_shader_manager, u32 transferSize,
u32 baseAddress)
{
g_vertex_manager->Flush();
VertexShaderManager::InvalidateXFRange(baseAddress, baseAddress + transferSize);
vertex_shader_manager.InvalidateXFRange(baseAddress, baseAddress + transferSize);
}

static void XFRegWritten(u32 address, u32 value)
static void XFRegWritten(VertexShaderManager& vertex_shader_manager, u32 address, u32 value)
{
if (address >= XFMEM_REGISTERS_START && address < XFMEM_REGISTERS_END)
{
Expand Down Expand Up @@ -61,7 +62,7 @@ static void XFRegWritten(u32 address, u32 value)
case XFMEM_SETNUMCHAN:
if (xfmem.numChan.numColorChans != (value & 3))
g_vertex_manager->Flush();
VertexShaderManager::SetLightingConfigChanged();
vertex_shader_manager.SetLightingConfigChanged();
break;

case XFMEM_SETCHAN0_AMBCOLOR: // Channel Ambient Color
Expand All @@ -71,7 +72,7 @@ static void XFRegWritten(u32 address, u32 value)
if (xfmem.ambColor[chan] != value)
{
g_vertex_manager->Flush();
VertexShaderManager::SetMaterialColorChanged(chan);
vertex_shader_manager.SetMaterialColorChanged(chan);
}
break;
}
Expand All @@ -83,7 +84,7 @@ static void XFRegWritten(u32 address, u32 value)
if (xfmem.matColor[chan] != value)
{
g_vertex_manager->Flush();
VertexShaderManager::SetMaterialColorChanged(chan + 2);
vertex_shader_manager.SetMaterialColorChanged(chan + 2);
}
break;
}
Expand All @@ -94,21 +95,21 @@ static void XFRegWritten(u32 address, u32 value)
case XFMEM_SETCHAN1_ALPHA:
if (((u32*)&xfmem)[address] != (value & 0x7fff))
g_vertex_manager->Flush();
VertexShaderManager::SetLightingConfigChanged();
vertex_shader_manager.SetLightingConfigChanged();
break;

case XFMEM_DUALTEX:
if (xfmem.dualTexTrans.enabled != bool(value & 1))
g_vertex_manager->Flush();
VertexShaderManager::SetTexMatrixInfoChanged(-1);
vertex_shader_manager.SetTexMatrixInfoChanged(-1);
break;

case XFMEM_SETMATRIXINDA:
VertexShaderManager::SetTexMatrixChangedA(value);
vertex_shader_manager.SetTexMatrixChangedA(value);
VertexLoaderManager::g_needs_cp_xf_consistency_check = true;
break;
case XFMEM_SETMATRIXINDB:
VertexShaderManager::SetTexMatrixChangedB(value);
vertex_shader_manager.SetTexMatrixChangedB(value);
VertexLoaderManager::g_needs_cp_xf_consistency_check = true;
break;

Expand All @@ -121,7 +122,7 @@ static void XFRegWritten(u32 address, u32 value)
{
auto& system = Core::System::GetInstance();
g_vertex_manager->Flush();
VertexShaderManager::SetViewportChanged();
vertex_shader_manager.SetViewportChanged();
system.GetPixelShaderManager().SetViewportChanged();
GeometryShaderManager::SetViewportChanged();
break;
Expand All @@ -135,7 +136,7 @@ static void XFRegWritten(u32 address, u32 value)
case XFMEM_SETPROJECTION + 5:
case XFMEM_SETPROJECTION + 6:
g_vertex_manager->Flush();
VertexShaderManager::SetProjectionChanged();
vertex_shader_manager.SetProjectionChanged();
GeometryShaderManager::SetProjectionChanged();
break;

Expand All @@ -153,7 +154,7 @@ static void XFRegWritten(u32 address, u32 value)
case XFMEM_SETTEXMTXINFO + 6:
case XFMEM_SETTEXMTXINFO + 7:
g_vertex_manager->Flush();
VertexShaderManager::SetTexMatrixInfoChanged(address - XFMEM_SETTEXMTXINFO);
vertex_shader_manager.SetTexMatrixInfoChanged(address - XFMEM_SETTEXMTXINFO);
break;

case XFMEM_SETPOSTMTXINFO:
Expand All @@ -165,7 +166,7 @@ static void XFRegWritten(u32 address, u32 value)
case XFMEM_SETPOSTMTXINFO + 6:
case XFMEM_SETPOSTMTXINFO + 7:
g_vertex_manager->Flush();
VertexShaderManager::SetTexMatrixInfoChanged(address - XFMEM_SETPOSTMTXINFO);
vertex_shader_manager.SetTexMatrixInfoChanged(address - XFMEM_SETPOSTMTXINFO);
break;

// --------------
Expand Down Expand Up @@ -218,6 +219,9 @@ void LoadXFReg(u16 base_address, u8 transfer_size, const u8* data)
end_address = XFMEM_REGISTERS_END;
}

auto& system = Core::System::GetInstance();
auto& vertex_shader_manager = system.GetVertexShaderManager();

// write to XF mem
if (base_address < XFMEM_REGISTERS_START)
{
Expand All @@ -230,7 +234,7 @@ void LoadXFReg(u16 base_address, u8 transfer_size, const u8* data)
base_address = XFMEM_REGISTERS_START;
}

XFMemWritten(xf_mem_transfer_size, xf_mem_base);
XFMemWritten(vertex_shader_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);
Expand All @@ -245,7 +249,7 @@ void LoadXFReg(u16 base_address, u8 transfer_size, const u8* data)
{
const u32 value = Common::swap32(data);

XFRegWritten(address, value);
XFRegWritten(vertex_shader_manager, address, value);
((u32*)&xfmem)[address] = value;

data += 4;
Expand All @@ -272,13 +276,15 @@ void LoadIndexedXF(CPArray array, u32 index, u16 address, u8 size)
newData = (u32*)memory.GetPointer(g_main_cp_state.array_bases[array] +
g_main_cp_state.array_strides[array] * index);
}

auto& vertex_shader_manager = system.GetVertexShaderManager();
bool changed = false;
for (u32 i = 0; i < size; ++i)
{
if (currData[i] != Common::swap32(newData[i]))
{
changed = true;
XFMemWritten(size, address);
XFMemWritten(vertex_shader_manager, size, address);
break;
}
}
Expand Down