Mechanical changes to move most CP state to a struct rather than separate globals.

The next commit will add a separate copy of the struct and the ability
for LoadCPReg to work on it.
This commit is contained in:
comex 2014-08-27 13:26:06 -04:00
parent 90638c6806
commit f0131c2e09
16 changed files with 146 additions and 148 deletions

View File

@ -13,46 +13,46 @@ void SWLoadCPReg(u32 sub_cmd, u32 value)
switch (sub_cmd & 0xF0) switch (sub_cmd & 0xF0)
{ {
case 0x30: case 0x30:
MatrixIndexA.Hex = value; g_main_cp_state.matrix_index_a.Hex = value;
break; break;
case 0x40: case 0x40:
MatrixIndexB.Hex = value; g_main_cp_state.matrix_index_b.Hex = value;
break; break;
case 0x50: case 0x50:
g_VtxDesc.Hex &= ~0x1FFFF; // keep the Upper bits g_main_cp_state.vtx_desc.Hex &= ~0x1FFFF; // keep the Upper bits
g_VtxDesc.Hex |= value; g_main_cp_state.vtx_desc.Hex |= value;
break; break;
case 0x60: case 0x60:
g_VtxDesc.Hex &= 0x1FFFF; // keep the lower 17Bits g_main_cp_state.vtx_desc.Hex &= 0x1FFFF; // keep the lower 17Bits
g_VtxDesc.Hex |= (u64)value << 17; g_main_cp_state.vtx_desc.Hex |= (u64)value << 17;
break; break;
case 0x70: case 0x70:
_assert_((sub_cmd & 0x0F) < 8); _assert_((sub_cmd & 0x0F) < 8);
g_VtxAttr[sub_cmd & 7].g0.Hex = value; g_main_cp_state.vtx_attr[sub_cmd & 7].g0.Hex = value;
break; break;
case 0x80: case 0x80:
_assert_((sub_cmd & 0x0F) < 8); _assert_((sub_cmd & 0x0F) < 8);
g_VtxAttr[sub_cmd & 7].g1.Hex = value; g_main_cp_state.vtx_attr[sub_cmd & 7].g1.Hex = value;
break; break;
case 0x90: case 0x90:
_assert_((sub_cmd & 0x0F) < 8); _assert_((sub_cmd & 0x0F) < 8);
g_VtxAttr[sub_cmd & 7].g2.Hex = value; g_main_cp_state.vtx_attr[sub_cmd & 7].g2.Hex = value;
break; break;
// Pointers to vertex arrays in GC RAM // Pointers to vertex arrays in GC RAM
case 0xA0: case 0xA0:
arraybases[sub_cmd & 0xF] = value; g_main_cp_state.array_bases[sub_cmd & 0xF] = value;
cached_arraybases[sub_cmd & 0xF] = Memory::GetPointer(value); cached_arraybases[sub_cmd & 0xF] = Memory::GetPointer(value);
break; break;
case 0xB0: case 0xB0:
arraystrides[sub_cmd & 0xF] = value & 0xFF; g_main_cp_state.array_strides[sub_cmd & 0xF] = value & 0xFF;
break; break;
} }
} }

View File

@ -39,7 +39,7 @@ SWVertexLoader::~SWVertexLoader()
void SWVertexLoader::SetFormat(u8 attributeIndex, u8 primitiveType) void SWVertexLoader::SetFormat(u8 attributeIndex, u8 primitiveType)
{ {
m_CurrentVat = &g_VtxAttr[attributeIndex]; m_CurrentVat = &g_main_cp_state.vtx_attr[attributeIndex];
posScale = 1.0f / float(1 << m_CurrentVat->g0.PosFrac); posScale = 1.0f / float(1 << m_CurrentVat->g0.PosFrac);
tcScale[0] = 1.0f / float(1 << m_CurrentVat->g0.Tex0Frac); tcScale[0] = 1.0f / float(1 << m_CurrentVat->g0.Tex0Frac);
@ -53,20 +53,20 @@ void SWVertexLoader::SetFormat(u8 attributeIndex, u8 primitiveType)
//TexMtx //TexMtx
const u64 tmDesc[8] = { const u64 tmDesc[8] = {
g_VtxDesc.Tex0MatIdx, g_VtxDesc.Tex1MatIdx, g_VtxDesc.Tex2MatIdx, g_VtxDesc.Tex3MatIdx, g_main_cp_state.vtx_desc.Tex0MatIdx, g_main_cp_state.vtx_desc.Tex1MatIdx, g_main_cp_state.vtx_desc.Tex2MatIdx, g_main_cp_state.vtx_desc.Tex3MatIdx,
g_VtxDesc.Tex4MatIdx, g_VtxDesc.Tex5MatIdx, g_VtxDesc.Tex6MatIdx, g_VtxDesc.Tex7MatIdx g_main_cp_state.vtx_desc.Tex4MatIdx, g_main_cp_state.vtx_desc.Tex5MatIdx, g_main_cp_state.vtx_desc.Tex6MatIdx, g_main_cp_state.vtx_desc.Tex7MatIdx
}; };
// Colors // Colors
const u64 colDesc[2] = {g_VtxDesc.Color0, g_VtxDesc.Color1}; const u64 colDesc[2] = {g_main_cp_state.vtx_desc.Color0, g_main_cp_state.vtx_desc.Color1};
colElements[0] = m_CurrentVat->g0.Color0Elements; colElements[0] = m_CurrentVat->g0.Color0Elements;
colElements[1] = m_CurrentVat->g0.Color1Elements; colElements[1] = m_CurrentVat->g0.Color1Elements;
const u32 colComp[2] = {m_CurrentVat->g0.Color0Comp, m_CurrentVat->g0.Color1Comp}; const u32 colComp[2] = {m_CurrentVat->g0.Color0Comp, m_CurrentVat->g0.Color1Comp};
// TextureCoord // TextureCoord
const u64 tcDesc[8] = { const u64 tcDesc[8] = {
g_VtxDesc.Tex0Coord, g_VtxDesc.Tex1Coord, g_VtxDesc.Tex2Coord, g_VtxDesc.Tex3Coord, g_main_cp_state.vtx_desc.Tex0Coord, g_main_cp_state.vtx_desc.Tex1Coord, g_main_cp_state.vtx_desc.Tex2Coord, g_main_cp_state.vtx_desc.Tex3Coord,
g_VtxDesc.Tex4Coord, g_VtxDesc.Tex5Coord, g_VtxDesc.Tex6Coord, g_VtxDesc.Tex7Coord g_main_cp_state.vtx_desc.Tex4Coord, g_main_cp_state.vtx_desc.Tex5Coord, g_main_cp_state.vtx_desc.Tex6Coord, g_main_cp_state.vtx_desc.Tex7Coord
}; };
const u32 tcElements[8] = { const u32 tcElements[8] = {
m_CurrentVat->g0.Tex0CoordElements, m_CurrentVat->g1.Tex1CoordElements, m_CurrentVat->g1.Tex2CoordElements, m_CurrentVat->g0.Tex0CoordElements, m_CurrentVat->g1.Tex1CoordElements, m_CurrentVat->g1.Tex2CoordElements,
@ -89,15 +89,15 @@ void SWVertexLoader::SetFormat(u8 attributeIndex, u8 primitiveType)
// Reset vertex // Reset vertex
// matrix index from xf regs or cp memory? // matrix index from xf regs or cp memory?
if (xfmem.MatrixIndexA.PosNormalMtxIdx != MatrixIndexA.PosNormalMtxIdx || if (xfmem.MatrixIndexA.PosNormalMtxIdx != g_main_cp_state.matrix_index_a.PosNormalMtxIdx ||
xfmem.MatrixIndexA.Tex0MtxIdx != MatrixIndexA.Tex0MtxIdx || xfmem.MatrixIndexA.Tex0MtxIdx != g_main_cp_state.matrix_index_a.Tex0MtxIdx ||
xfmem.MatrixIndexA.Tex1MtxIdx != MatrixIndexA.Tex1MtxIdx || xfmem.MatrixIndexA.Tex1MtxIdx != g_main_cp_state.matrix_index_a.Tex1MtxIdx ||
xfmem.MatrixIndexA.Tex2MtxIdx != MatrixIndexA.Tex2MtxIdx || xfmem.MatrixIndexA.Tex2MtxIdx != g_main_cp_state.matrix_index_a.Tex2MtxIdx ||
xfmem.MatrixIndexA.Tex3MtxIdx != MatrixIndexA.Tex3MtxIdx || xfmem.MatrixIndexA.Tex3MtxIdx != g_main_cp_state.matrix_index_a.Tex3MtxIdx ||
xfmem.MatrixIndexB.Tex4MtxIdx != MatrixIndexB.Tex4MtxIdx || xfmem.MatrixIndexB.Tex4MtxIdx != g_main_cp_state.matrix_index_b.Tex4MtxIdx ||
xfmem.MatrixIndexB.Tex5MtxIdx != MatrixIndexB.Tex5MtxIdx || xfmem.MatrixIndexB.Tex5MtxIdx != g_main_cp_state.matrix_index_b.Tex5MtxIdx ||
xfmem.MatrixIndexB.Tex6MtxIdx != MatrixIndexB.Tex6MtxIdx || xfmem.MatrixIndexB.Tex6MtxIdx != g_main_cp_state.matrix_index_b.Tex6MtxIdx ||
xfmem.MatrixIndexB.Tex7MtxIdx != MatrixIndexB.Tex7MtxIdx) xfmem.MatrixIndexB.Tex7MtxIdx != g_main_cp_state.matrix_index_b.Tex7MtxIdx)
{ {
WARN_LOG(VIDEO, "Matrix indices don't match"); WARN_LOG(VIDEO, "Matrix indices don't match");
@ -118,18 +118,18 @@ void SWVertexLoader::SetFormat(u8 attributeIndex, u8 primitiveType)
m_Vertex.texMtx[6] = xfmem.MatrixIndexB.Tex6MtxIdx; m_Vertex.texMtx[6] = xfmem.MatrixIndexB.Tex6MtxIdx;
m_Vertex.texMtx[7] = xfmem.MatrixIndexB.Tex7MtxIdx; m_Vertex.texMtx[7] = xfmem.MatrixIndexB.Tex7MtxIdx;
#else #else
m_Vertex.posMtx = MatrixIndexA.PosNormalMtxIdx; m_Vertex.posMtx = g_main_cp_state.matrix_index_a.PosNormalMtxIdx;
m_Vertex.texMtx[0] = MatrixIndexA.Tex0MtxIdx; m_Vertex.texMtx[0] = g_main_cp_state.matrix_index_a.Tex0MtxIdx;
m_Vertex.texMtx[1] = MatrixIndexA.Tex1MtxIdx; m_Vertex.texMtx[1] = g_main_cp_state.matrix_index_a.Tex1MtxIdx;
m_Vertex.texMtx[2] = MatrixIndexA.Tex2MtxIdx; m_Vertex.texMtx[2] = g_main_cp_state.matrix_index_a.Tex2MtxIdx;
m_Vertex.texMtx[3] = MatrixIndexA.Tex3MtxIdx; m_Vertex.texMtx[3] = g_main_cp_state.matrix_index_a.Tex3MtxIdx;
m_Vertex.texMtx[4] = MatrixIndexB.Tex4MtxIdx; m_Vertex.texMtx[4] = g_main_cp_state.matrix_index_b.Tex4MtxIdx;
m_Vertex.texMtx[5] = MatrixIndexB.Tex5MtxIdx; m_Vertex.texMtx[5] = g_main_cp_state.matrix_index_b.Tex5MtxIdx;
m_Vertex.texMtx[6] = MatrixIndexB.Tex6MtxIdx; m_Vertex.texMtx[6] = g_main_cp_state.matrix_index_b.Tex6MtxIdx;
m_Vertex.texMtx[7] = MatrixIndexB.Tex7MtxIdx; m_Vertex.texMtx[7] = g_main_cp_state.matrix_index_b.Tex7MtxIdx;
#endif #endif
if (g_VtxDesc.PosMatIdx != NOT_PRESENT) if (g_main_cp_state.vtx_desc.PosMatIdx != NOT_PRESENT)
{ {
AddAttributeLoader(LoadPosMtx); AddAttributeLoader(LoadPosMtx);
m_VertexSize++; m_VertexSize++;
@ -145,17 +145,17 @@ void SWVertexLoader::SetFormat(u8 attributeIndex, u8 primitiveType)
} }
// Write vertex position loader // Write vertex position loader
m_positionLoader = VertexLoader_Position::GetFunction(g_VtxDesc.Position, m_CurrentVat->g0.PosFormat, m_CurrentVat->g0.PosElements); m_positionLoader = VertexLoader_Position::GetFunction(g_main_cp_state.vtx_desc.Position, m_CurrentVat->g0.PosFormat, m_CurrentVat->g0.PosElements);
m_VertexSize += VertexLoader_Position::GetSize(g_VtxDesc.Position, m_CurrentVat->g0.PosFormat, m_CurrentVat->g0.PosElements); m_VertexSize += VertexLoader_Position::GetSize(g_main_cp_state.vtx_desc.Position, m_CurrentVat->g0.PosFormat, m_CurrentVat->g0.PosElements);
AddAttributeLoader(LoadPosition); AddAttributeLoader(LoadPosition);
// Normals // Normals
if (g_VtxDesc.Normal != NOT_PRESENT) if (g_main_cp_state.vtx_desc.Normal != NOT_PRESENT)
{ {
m_VertexSize += VertexLoader_Normal::GetSize(g_VtxDesc.Normal, m_VertexSize += VertexLoader_Normal::GetSize(g_main_cp_state.vtx_desc.Normal,
m_CurrentVat->g0.NormalFormat, m_CurrentVat->g0.NormalElements, m_CurrentVat->g0.NormalIndex3); m_CurrentVat->g0.NormalFormat, m_CurrentVat->g0.NormalElements, m_CurrentVat->g0.NormalIndex3);
m_normalLoader = VertexLoader_Normal::GetFunction(g_VtxDesc.Normal, m_normalLoader = VertexLoader_Normal::GetFunction(g_main_cp_state.vtx_desc.Normal,
m_CurrentVat->g0.NormalFormat, m_CurrentVat->g0.NormalElements, m_CurrentVat->g0.NormalIndex3); m_CurrentVat->g0.NormalFormat, m_CurrentVat->g0.NormalElements, m_CurrentVat->g0.NormalIndex3);
if (m_normalLoader == nullptr) if (m_normalLoader == nullptr)
@ -234,8 +234,8 @@ void SWVertexLoader::SetFormat(u8 attributeIndex, u8 primitiveType)
// special case if only pos and tex coord 0 and tex coord input is AB11 // special case if only pos and tex coord 0 and tex coord input is AB11
m_TexGenSpecialCase = m_TexGenSpecialCase =
((g_VtxDesc.Hex & 0x60600L) == g_VtxDesc.Hex) && // only pos and tex coord 0 ((g_main_cp_state.vtx_desc.Hex & 0x60600L) == g_main_cp_state.vtx_desc.Hex) && // only pos and tex coord 0
(g_VtxDesc.Tex0Coord != NOT_PRESENT) && (g_main_cp_state.vtx_desc.Tex0Coord != NOT_PRESENT) &&
(xfmem.texMtxInfo[0].projection == XF_TEXPROJ_ST); (xfmem.texMtxInfo[0].projection == XF_TEXPROJ_ST);
m_SetupUnit->Init(primitiveType); m_SetupUnit->Init(primitiveType);
@ -252,7 +252,7 @@ void SWVertexLoader::LoadVertex()
// transform input data // transform input data
TransformUnit::TransformPosition(&m_Vertex, outVertex); TransformUnit::TransformPosition(&m_Vertex, outVertex);
if (g_VtxDesc.Normal != NOT_PRESENT) if (g_main_cp_state.vtx_desc.Normal != NOT_PRESENT)
{ {
TransformUnit::TransformNormal(&m_Vertex, m_CurrentVat->g0.NormalElements, outVertex); TransformUnit::TransformNormal(&m_Vertex, m_CurrentVat->g0.NormalElements, outVertex);
} }

View File

@ -116,14 +116,7 @@ void VideoSoftware::DoState(PointerWrap& p)
p.DoPOD(swstats); p.DoPOD(swstats);
// CP Memory // CP Memory
p.DoArray(arraybases, 16); DoCPState(p);
p.DoArray(arraystrides, 16);
p.Do(MatrixIndexA);
p.Do(MatrixIndexB);
p.Do(g_VtxDesc.Hex);
p.DoArray(g_VtxAttr, 8);
p.DoMarker("CP Memory");
} }
void VideoSoftware::CheckInvalidState() void VideoSoftware::CheckInvalidState()

View File

@ -74,7 +74,7 @@ void SWLoadIndexedXF(u32 val, int array)
int size = ((val >> 12) & 0xF) + 1; int size = ((val >> 12) & 0xF) + 1;
//load stuff from array to address in xf mem //load stuff from array to address in xf mem
u32 *pData = (u32*)Memory::GetPointer(arraybases[array] + arraystrides[array]*index); u32 *pData = (u32*)Memory::GetPointer(g_main_cp_state.array_bases[array] + g_main_cp_state.array_strides[array]*index);
// byteswap data // byteswap data
u32 buffer[16]; u32 buffer[16];

View File

@ -2,17 +2,22 @@
// Licensed under GPLv2 // Licensed under GPLv2
// Refer to the license.txt file included. // Refer to the license.txt file included.
#include "Common/ChunkFile.h"
#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
#include "VideoCommon/CPMemory.h" #include "VideoCommon/CPMemory.h"
// CP state // CP state
u8 *cached_arraybases[16]; u8 *cached_arraybases[16];
// STATE_TO_SAVE CPState g_main_cp_state;
u32 arraybases[16];
u32 arraystrides[16]; void DoCPState(PointerWrap& p)
TMatrixIndexA MatrixIndexA; {
TMatrixIndexB MatrixIndexB; p.DoArray(g_main_cp_state.array_bases, 16);
TVtxDesc g_VtxDesc; p.DoArray(g_main_cp_state.array_strides, 16);
// Most games only use the first VtxAttr and simply reconfigure it all the time as needed. p.Do(g_main_cp_state.matrix_index_a);
VAT g_VtxAttr[8]; p.Do(g_main_cp_state.matrix_index_b);
p.Do(g_main_cp_state.vtx_desc.Hex);
p.DoArray(g_main_cp_state.vtx_attr, 8);
p.DoMarker("CP Memory");
}

View File

@ -231,12 +231,6 @@ union TMatrixIndexB
#pragma pack() #pragma pack()
extern u32 arraybases[16];
extern u8 *cached_arraybases[16];
extern u32 arraystrides[16];
extern TMatrixIndexA MatrixIndexA;
extern TMatrixIndexB MatrixIndexB;
struct VAT struct VAT
{ {
UVAT_group0 g0; UVAT_group0 g0;
@ -244,8 +238,25 @@ struct VAT
UVAT_group2 g2; UVAT_group2 g2;
}; };
extern TVtxDesc g_VtxDesc; // STATE_TO_SAVE
extern VAT g_VtxAttr[8]; struct CPState final
{
u32 array_bases[16];
u32 array_strides[16];
TMatrixIndexA matrix_index_a;
TMatrixIndexB matrix_index_b;
TVtxDesc vtx_desc;
// Most games only use the first VtxAttr and simply reconfigure it all the time as needed.
VAT vtx_attr[8];
};
class PointerWrap;
extern void DoCPState(PointerWrap& p);
extern CPState g_main_cp_state;
extern u8 *cached_arraybases[16];
// Might move this into its own file later. // Might move this into its own file later.
void LoadCPReg(u32 SubCmd, u32 Value); void LoadCPReg(u32 SubCmd, u32 Value);

View File

@ -33,7 +33,7 @@
// Matrix components are first in GC format but later in PC format - we need to store it temporarily // Matrix components are first in GC format but later in PC format - we need to store it temporarily
// when decoding each vertex. // when decoding each vertex.
static u8 s_curposmtx = MatrixIndexA.PosNormalMtxIdx; static u8 s_curposmtx = g_main_cp_state.matrix_index_a.PosNormalMtxIdx;
static u8 s_curtexmtx[8]; static u8 s_curtexmtx[8];
static int s_texmtxwrite = 0; static int s_texmtxwrite = 0;
static int s_texmtxread = 0; static int s_texmtxread = 0;
@ -87,7 +87,7 @@ static void LOADERDECL PosMtx_Write()
DataWrite<u8>(0); DataWrite<u8>(0);
// Resetting current position matrix to default is needed for bbox to behave // Resetting current position matrix to default is needed for bbox to behave
s_curposmtx = (u8) MatrixIndexA.PosNormalMtxIdx; s_curposmtx = (u8) g_main_cp_state.matrix_index_a.PosNormalMtxIdx;
} }
static void LOADERDECL UpdateBoundingBoxPrepare() static void LOADERDECL UpdateBoundingBoxPrepare()

View File

@ -112,7 +112,7 @@ static VertexLoader* RefreshLoader(int vtx_attr_group)
VertexLoader* loader; VertexLoader* loader;
if ((s_attr_dirty >> vtx_attr_group) & 1) if ((s_attr_dirty >> vtx_attr_group) & 1)
{ {
VertexLoaderUID uid(g_VtxDesc, g_VtxAttr[vtx_attr_group]); VertexLoaderUID uid(g_main_cp_state.vtx_desc, g_main_cp_state.vtx_attr[vtx_attr_group]);
std::lock_guard<std::mutex> lk(s_vertex_loader_map_lock); std::lock_guard<std::mutex> lk(s_vertex_loader_map_lock);
VertexLoaderMap::iterator iter = s_vertex_loader_map.find(uid); VertexLoaderMap::iterator iter = s_vertex_loader_map.find(uid);
if (iter != s_vertex_loader_map.end()) if (iter != s_vertex_loader_map.end())
@ -121,7 +121,7 @@ static VertexLoader* RefreshLoader(int vtx_attr_group)
} }
else else
{ {
loader = new VertexLoader(g_VtxDesc, g_VtxAttr[vtx_attr_group]); loader = new VertexLoader(g_main_cp_state.vtx_desc, g_main_cp_state.vtx_attr[vtx_attr_group]);
s_vertex_loader_map[uid] = std::unique_ptr<VertexLoader>(loader); s_vertex_loader_map[uid] = std::unique_ptr<VertexLoader>(loader);
INCSTAT(stats.numVertexLoaders); INCSTAT(stats.numVertexLoaders);
} }
@ -161,7 +161,7 @@ bool RunVertices(int vtx_attr_group, int primitive, int count, size_t buf_size,
VertexManager::PrepareForAdditionalData(primitive, count, VertexManager::PrepareForAdditionalData(primitive, count,
loader->GetNativeVertexDeclaration().stride); loader->GetNativeVertexDeclaration().stride);
loader->RunVertices(g_VtxAttr[vtx_attr_group], primitive, count); loader->RunVertices(g_main_cp_state.vtx_attr[vtx_attr_group], primitive, count);
IndexGenerator::AddIndices(primitive, count); IndexGenerator::AddIndices(primitive, count);
@ -195,65 +195,65 @@ void LoadCPReg(u32 sub_cmd, u32 value)
break; break;
case 0x50: case 0x50:
g_VtxDesc.Hex &= ~0x1FFFF; // keep the Upper bits g_main_cp_state.vtx_desc.Hex &= ~0x1FFFF; // keep the Upper bits
g_VtxDesc.Hex |= value; g_main_cp_state.vtx_desc.Hex |= value;
s_attr_dirty = 0xFF; s_attr_dirty = 0xFF;
break; break;
case 0x60: case 0x60:
g_VtxDesc.Hex &= 0x1FFFF; // keep the lower 17Bits g_main_cp_state.vtx_desc.Hex &= 0x1FFFF; // keep the lower 17Bits
g_VtxDesc.Hex |= (u64)value << 17; g_main_cp_state.vtx_desc.Hex |= (u64)value << 17;
s_attr_dirty = 0xFF; s_attr_dirty = 0xFF;
break; break;
case 0x70: case 0x70:
_assert_((sub_cmd & 0x0F) < 8); _assert_((sub_cmd & 0x0F) < 8);
g_VtxAttr[sub_cmd & 7].g0.Hex = value; g_main_cp_state.vtx_attr[sub_cmd & 7].g0.Hex = value;
s_attr_dirty |= 1 << (sub_cmd & 7); s_attr_dirty |= 1 << (sub_cmd & 7);
break; break;
case 0x80: case 0x80:
_assert_((sub_cmd & 0x0F) < 8); _assert_((sub_cmd & 0x0F) < 8);
g_VtxAttr[sub_cmd & 7].g1.Hex = value; g_main_cp_state.vtx_attr[sub_cmd & 7].g1.Hex = value;
s_attr_dirty |= 1 << (sub_cmd & 7); s_attr_dirty |= 1 << (sub_cmd & 7);
break; break;
case 0x90: case 0x90:
_assert_((sub_cmd & 0x0F) < 8); _assert_((sub_cmd & 0x0F) < 8);
g_VtxAttr[sub_cmd & 7].g2.Hex = value; g_main_cp_state.vtx_attr[sub_cmd & 7].g2.Hex = value;
s_attr_dirty |= 1 << (sub_cmd & 7); s_attr_dirty |= 1 << (sub_cmd & 7);
break; break;
// Pointers to vertex arrays in GC RAM // Pointers to vertex arrays in GC RAM
case 0xA0: case 0xA0:
arraybases[sub_cmd & 0xF] = value; g_main_cp_state.array_bases[sub_cmd & 0xF] = value;
cached_arraybases[sub_cmd & 0xF] = Memory::GetPointer(value); cached_arraybases[sub_cmd & 0xF] = Memory::GetPointer(value);
break; break;
case 0xB0: case 0xB0:
arraystrides[sub_cmd & 0xF] = value & 0xFF; g_main_cp_state.array_strides[sub_cmd & 0xF] = value & 0xFF;
break; break;
} }
} }
void FillCPMemoryArray(u32 *memory) void FillCPMemoryArray(u32 *memory)
{ {
memory[0x30] = MatrixIndexA.Hex; memory[0x30] = g_main_cp_state.matrix_index_a.Hex;
memory[0x40] = MatrixIndexB.Hex; memory[0x40] = g_main_cp_state.matrix_index_b.Hex;
memory[0x50] = (u32)g_VtxDesc.Hex; memory[0x50] = (u32)g_main_cp_state.vtx_desc.Hex;
memory[0x60] = (u32)(g_VtxDesc.Hex >> 17); memory[0x60] = (u32)(g_main_cp_state.vtx_desc.Hex >> 17);
for (int i = 0; i < 8; ++i) for (int i = 0; i < 8; ++i)
{ {
memory[0x70 + i] = g_VtxAttr[i].g0.Hex; memory[0x70 + i] = g_main_cp_state.vtx_attr[i].g0.Hex;
memory[0x80 + i] = g_VtxAttr[i].g1.Hex; memory[0x80 + i] = g_main_cp_state.vtx_attr[i].g1.Hex;
memory[0x90 + i] = g_VtxAttr[i].g2.Hex; memory[0x90 + i] = g_main_cp_state.vtx_attr[i].g2.Hex;
} }
for (int i = 0; i < 16; ++i) for (int i = 0; i < 16; ++i)
{ {
memory[0xA0 + i] = arraybases[i]; memory[0xA0 + i] = g_main_cp_state.array_bases[i];
memory[0xB0 + i] = arraystrides[i]; memory[0xB0 + i] = g_main_cp_state.array_strides[i];
} }
} }
@ -261,6 +261,6 @@ void RecomputeCachedArraybases()
{ {
for (int i = 0; i < 16; i++) for (int i = 0; i < 16; i++)
{ {
cached_arraybases[i] = Memory::GetPointer(arraybases[i]); cached_arraybases[i] = Memory::GetPointer(g_main_cp_state.array_bases[i]);
} }
} }

View File

@ -117,7 +117,7 @@ template <typename I>
void Color_ReadIndex_16b_565() void Color_ReadIndex_16b_565()
{ {
auto const Index = DataRead<I>(); auto const Index = DataRead<I>();
u16 val = Common::swap16(*(const u16 *)(cached_arraybases[ARRAY_COLOR+colIndex] + (Index * arraystrides[ARRAY_COLOR+colIndex]))); u16 val = Common::swap16(*(const u16 *)(cached_arraybases[ARRAY_COLOR+colIndex] + (Index * g_main_cp_state.array_strides[ARRAY_COLOR+colIndex])));
_SetCol565(val); _SetCol565(val);
} }
@ -125,7 +125,7 @@ template <typename I>
void Color_ReadIndex_24b_888() void Color_ReadIndex_24b_888()
{ {
auto const Index = DataRead<I>(); auto const Index = DataRead<I>();
const u8 *iAddress = cached_arraybases[ARRAY_COLOR+colIndex] + (Index * arraystrides[ARRAY_COLOR+colIndex]); const u8 *iAddress = cached_arraybases[ARRAY_COLOR+colIndex] + (Index * g_main_cp_state.array_strides[ARRAY_COLOR+colIndex]);
_SetCol(_Read24(iAddress)); _SetCol(_Read24(iAddress));
} }
@ -133,7 +133,7 @@ template <typename I>
void Color_ReadIndex_32b_888x() void Color_ReadIndex_32b_888x()
{ {
auto const Index = DataRead<I>(); auto const Index = DataRead<I>();
const u8 *iAddress = cached_arraybases[ARRAY_COLOR+colIndex] + (Index * arraystrides[ARRAY_COLOR+colIndex]); const u8 *iAddress = cached_arraybases[ARRAY_COLOR+colIndex] + (Index * g_main_cp_state.array_strides[ARRAY_COLOR+colIndex]);
_SetCol(_Read24(iAddress)); _SetCol(_Read24(iAddress));
} }
@ -141,7 +141,7 @@ template <typename I>
void Color_ReadIndex_16b_4444() void Color_ReadIndex_16b_4444()
{ {
auto const Index = DataRead<I>(); auto const Index = DataRead<I>();
u16 val = *(const u16 *)(cached_arraybases[ARRAY_COLOR+colIndex] + (Index * arraystrides[ARRAY_COLOR+colIndex])); u16 val = *(const u16 *)(cached_arraybases[ARRAY_COLOR+colIndex] + (Index * g_main_cp_state.array_strides[ARRAY_COLOR+colIndex]));
_SetCol4444(val); _SetCol4444(val);
} }
@ -149,7 +149,7 @@ template <typename I>
void Color_ReadIndex_24b_6666() void Color_ReadIndex_24b_6666()
{ {
auto const Index = DataRead<I>(); auto const Index = DataRead<I>();
const u8* pData = cached_arraybases[ARRAY_COLOR+colIndex] + (Index * arraystrides[ARRAY_COLOR+colIndex]) - 1; const u8* pData = cached_arraybases[ARRAY_COLOR+colIndex] + (Index * g_main_cp_state.array_strides[ARRAY_COLOR+colIndex]) - 1;
u32 val = Common::swap32(pData); u32 val = Common::swap32(pData);
_SetCol6666(val); _SetCol6666(val);
} }
@ -158,7 +158,7 @@ template <typename I>
void Color_ReadIndex_32b_8888() void Color_ReadIndex_32b_8888()
{ {
auto const Index = DataRead<I>(); auto const Index = DataRead<I>();
const u8 *iAddress = cached_arraybases[ARRAY_COLOR+colIndex] + (Index * arraystrides[ARRAY_COLOR+colIndex]); const u8 *iAddress = cached_arraybases[ARRAY_COLOR+colIndex] + (Index * g_main_cp_state.array_strides[ARRAY_COLOR+colIndex]);
_SetCol(_Read32(iAddress)); _SetCol(_Read32(iAddress));
} }

View File

@ -80,7 +80,7 @@ __forceinline void Normal_Index_Offset()
auto const index = DataRead<I>(); auto const index = DataRead<I>();
auto const data = reinterpret_cast<const T*>(cached_arraybases[ARRAY_NORMAL] auto const data = reinterpret_cast<const T*>(cached_arraybases[ARRAY_NORMAL]
+ (index * arraystrides[ARRAY_NORMAL]) + sizeof(T) * 3 * Offset); + (index * g_main_cp_state.array_strides[ARRAY_NORMAL]) + sizeof(T) * 3 * Offset);
ReadIndirect<T, N * 3>(data); ReadIndirect<T, N * 3>(data);
} }

View File

@ -91,7 +91,7 @@ void LOADERDECL Pos_ReadIndex()
static_assert(N <= 3, "N > 3 is not sane!"); static_assert(N <= 3, "N > 3 is not sane!");
auto const index = DataRead<I>(); auto const index = DataRead<I>();
auto const data = reinterpret_cast<const T*>(cached_arraybases[ARRAY_POSITION] + (index * arraystrides[ARRAY_POSITION])); auto const data = reinterpret_cast<const T*>(cached_arraybases[ARRAY_POSITION] + (index * g_main_cp_state.array_strides[ARRAY_POSITION]));
auto const scale = posScale; auto const scale = posScale;
DataWriter dst; DataWriter dst;
@ -109,7 +109,7 @@ template <typename I, bool three>
void LOADERDECL Pos_ReadIndex_Float_SSSE3() void LOADERDECL Pos_ReadIndex_Float_SSSE3()
{ {
auto const index = DataRead<I>(); auto const index = DataRead<I>();
const u32* pData = (const u32 *)(cached_arraybases[ARRAY_POSITION] + (index * arraystrides[ARRAY_POSITION])); const u32* pData = (const u32 *)(cached_arraybases[ARRAY_POSITION] + (index * g_main_cp_state.array_strides[ARRAY_POSITION]));
GC_ALIGNED128(const __m128i a = _mm_loadu_si128((__m128i*)pData)); GC_ALIGNED128(const __m128i a = _mm_loadu_si128((__m128i*)pData));
GC_ALIGNED128(__m128i b = _mm_shuffle_epi8(a, three ? kMaskSwap32_3 : kMaskSwap32_2)); GC_ALIGNED128(__m128i b = _mm_shuffle_epi8(a, three ? kMaskSwap32_3 : kMaskSwap32_2));
_mm_storeu_si128((__m128i*)VertexManager::s_pCurBufferPointer, b); _mm_storeu_si128((__m128i*)VertexManager::s_pCurBufferPointer, b);

View File

@ -73,7 +73,7 @@ void LOADERDECL TexCoord_ReadIndex()
auto const index = DataRead<I>(); auto const index = DataRead<I>();
auto const data = reinterpret_cast<const T*>(cached_arraybases[ARRAY_TEXCOORD0 + tcIndex] auto const data = reinterpret_cast<const T*>(cached_arraybases[ARRAY_TEXCOORD0 + tcIndex]
+ (index * arraystrides[ARRAY_TEXCOORD0 + tcIndex])); + (index * g_main_cp_state.array_strides[ARRAY_TEXCOORD0 + tcIndex]));
auto const scale = tcScale[tcIndex]; auto const scale = tcScale[tcIndex];
DataWriter dst; DataWriter dst;
@ -94,7 +94,7 @@ void LOADERDECL TexCoord_ReadIndex_Short2_SSE4()
// Heavy in ZWW // Heavy in ZWW
auto const index = DataRead<I>(); auto const index = DataRead<I>();
const s32 *pData = (const s32*)(cached_arraybases[ARRAY_TEXCOORD0+tcIndex] + (index * arraystrides[ARRAY_TEXCOORD0+tcIndex])); const s32 *pData = (const s32*)(cached_arraybases[ARRAY_TEXCOORD0+tcIndex] + (index * g_main_cp_state.array_strides[ARRAY_TEXCOORD0+tcIndex]));
const __m128i a = _mm_cvtsi32_si128(*pData); const __m128i a = _mm_cvtsi32_si128(*pData);
const __m128i b = _mm_shuffle_epi8(a, kMaskSwap16_2); const __m128i b = _mm_shuffle_epi8(a, kMaskSwap16_2);
const __m128i c = _mm_cvtepi16_epi32(b); const __m128i c = _mm_cvtepi16_epi32(b);
@ -117,7 +117,7 @@ void LOADERDECL TexCoord_ReadIndex_Float2_SSSE3()
static_assert(!std::numeric_limits<I>::is_signed, "Only unsigned I is sane!"); static_assert(!std::numeric_limits<I>::is_signed, "Only unsigned I is sane!");
auto const index = DataRead<I>(); auto const index = DataRead<I>();
const u32 *pData = (const u32 *)(cached_arraybases[ARRAY_TEXCOORD0+tcIndex] + (index * arraystrides[ARRAY_TEXCOORD0+tcIndex])); const u32 *pData = (const u32 *)(cached_arraybases[ARRAY_TEXCOORD0+tcIndex] + (index * g_main_cp_state.array_strides[ARRAY_TEXCOORD0+tcIndex]));
GC_ALIGNED128(const __m128i a = _mm_loadl_epi64((__m128i*)pData)); GC_ALIGNED128(const __m128i a = _mm_loadl_epi64((__m128i*)pData));
GC_ALIGNED128(const __m128i b = _mm_shuffle_epi8(a, kMaskSwap32)); GC_ALIGNED128(const __m128i b = _mm_shuffle_epi8(a, kMaskSwap32));
_mm_storel_epi64((__m128i*)VertexManager::s_pCurBufferPointer, b); _mm_storel_epi64((__m128i*)VertexManager::s_pCurBufferPointer, b);

View File

@ -245,8 +245,8 @@ static inline void GenerateVertexShader(T& out, u32 components, API_TYPE api_typ
// donko - this has caused problems in some games. removed for now. // donko - this has caused problems in some games. removed for now.
bool texGenSpecialCase = false; bool texGenSpecialCase = false;
/*bool texGenSpecialCase = /*bool texGenSpecialCase =
((g_VtxDesc.Hex & 0x60600L) == g_VtxDesc.Hex) && // only pos and tex coord 0 ((g_main_cp_state.vtx_desc.Hex & 0x60600L) == g_main_cp_state.vtx_desc.Hex) && // only pos and tex coord 0
(g_VtxDesc.Tex0Coord != NOT_PRESENT) && (g_main_cp_state.vtx_desc.Tex0Coord != NOT_PRESENT) &&
(xfmem.texcoords[0].texmtxinfo.inputform == XF_TEXINPUT_AB11); (xfmem.texcoords[0].texmtxinfo.inputform == XF_TEXINPUT_AB11);
*/ */

View File

@ -329,8 +329,8 @@ void VertexShaderManager::SetConstants()
{ {
bPosNormalMatrixChanged = false; bPosNormalMatrixChanged = false;
const float *pos = (const float *)xfmem.posMatrices + MatrixIndexA.PosNormalMtxIdx * 4; const float *pos = (const float *)xfmem.posMatrices + g_main_cp_state.matrix_index_a.PosNormalMtxIdx * 4;
const float *norm = (const float *)xfmem.normalMatrices + 3 * (MatrixIndexA.PosNormalMtxIdx & 31); const float *norm = (const float *)xfmem.normalMatrices + 3 * (g_main_cp_state.matrix_index_a.PosNormalMtxIdx & 31);
memcpy(constants.posnormalmatrix, pos, 3*16); memcpy(constants.posnormalmatrix, pos, 3*16);
memcpy(constants.posnormalmatrix[3], norm, 12); memcpy(constants.posnormalmatrix[3], norm, 12);
@ -344,10 +344,10 @@ void VertexShaderManager::SetConstants()
bTexMatricesChanged[0] = false; bTexMatricesChanged[0] = false;
const float *fptrs[] = const float *fptrs[] =
{ {
(const float *)&xfmem.posMatrices[MatrixIndexA.Tex0MtxIdx * 4], (const float *)&xfmem.posMatrices[g_main_cp_state.matrix_index_a.Tex0MtxIdx * 4],
(const float *)&xfmem.posMatrices[MatrixIndexA.Tex1MtxIdx * 4], (const float *)&xfmem.posMatrices[g_main_cp_state.matrix_index_a.Tex1MtxIdx * 4],
(const float *)&xfmem.posMatrices[MatrixIndexA.Tex2MtxIdx * 4], (const float *)&xfmem.posMatrices[g_main_cp_state.matrix_index_a.Tex2MtxIdx * 4],
(const float *)&xfmem.posMatrices[MatrixIndexA.Tex3MtxIdx * 4] (const float *)&xfmem.posMatrices[g_main_cp_state.matrix_index_a.Tex3MtxIdx * 4]
}; };
for (int i = 0; i < 4; ++i) for (int i = 0; i < 4; ++i)
@ -361,10 +361,10 @@ void VertexShaderManager::SetConstants()
{ {
bTexMatricesChanged[1] = false; bTexMatricesChanged[1] = false;
const float *fptrs[] = { const float *fptrs[] = {
(const float *)&xfmem.posMatrices[MatrixIndexB.Tex4MtxIdx * 4], (const float *)&xfmem.posMatrices[g_main_cp_state.matrix_index_b.Tex4MtxIdx * 4],
(const float *)&xfmem.posMatrices[MatrixIndexB.Tex5MtxIdx * 4], (const float *)&xfmem.posMatrices[g_main_cp_state.matrix_index_b.Tex5MtxIdx * 4],
(const float *)&xfmem.posMatrices[MatrixIndexB.Tex6MtxIdx * 4], (const float *)&xfmem.posMatrices[g_main_cp_state.matrix_index_b.Tex6MtxIdx * 4],
(const float *)&xfmem.posMatrices[MatrixIndexB.Tex7MtxIdx * 4] (const float *)&xfmem.posMatrices[g_main_cp_state.matrix_index_b.Tex7MtxIdx * 4]
}; };
for (int i = 0; i < 4; ++i) for (int i = 0; i < 4; ++i)
@ -536,26 +536,26 @@ void VertexShaderManager::SetConstants()
void VertexShaderManager::InvalidateXFRange(int start, int end) void VertexShaderManager::InvalidateXFRange(int start, int end)
{ {
if (((u32)start >= (u32)MatrixIndexA.PosNormalMtxIdx * 4 && if (((u32)start >= (u32)g_main_cp_state.matrix_index_a.PosNormalMtxIdx * 4 &&
(u32)start < (u32)MatrixIndexA.PosNormalMtxIdx * 4 + 12) || (u32)start < (u32)g_main_cp_state.matrix_index_a.PosNormalMtxIdx * 4 + 12) ||
((u32)start >= XFMEM_NORMALMATRICES + ((u32)MatrixIndexA.PosNormalMtxIdx & 31) * 3 && ((u32)start >= XFMEM_NORMALMATRICES + ((u32)g_main_cp_state.matrix_index_a.PosNormalMtxIdx & 31) * 3 &&
(u32)start < XFMEM_NORMALMATRICES + ((u32)MatrixIndexA.PosNormalMtxIdx & 31) * 3 + 9)) (u32)start < XFMEM_NORMALMATRICES + ((u32)g_main_cp_state.matrix_index_a.PosNormalMtxIdx & 31) * 3 + 9))
{ {
bPosNormalMatrixChanged = true; bPosNormalMatrixChanged = true;
} }
if (((u32)start >= (u32)MatrixIndexA.Tex0MtxIdx*4 && (u32)start < (u32)MatrixIndexA.Tex0MtxIdx*4+12) || 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)MatrixIndexA.Tex1MtxIdx*4 && (u32)start < (u32)MatrixIndexA.Tex1MtxIdx*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)MatrixIndexA.Tex2MtxIdx*4 && (u32)start < (u32)MatrixIndexA.Tex2MtxIdx*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)MatrixIndexA.Tex3MtxIdx*4 && (u32)start < (u32)MatrixIndexA.Tex3MtxIdx*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))
{ {
bTexMatricesChanged[0] = true; bTexMatricesChanged[0] = true;
} }
if (((u32)start >= (u32)MatrixIndexB.Tex4MtxIdx*4 && (u32)start < (u32)MatrixIndexB.Tex4MtxIdx*4+12) || 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)MatrixIndexB.Tex5MtxIdx*4 && (u32)start < (u32)MatrixIndexB.Tex5MtxIdx*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)MatrixIndexB.Tex6MtxIdx*4 && (u32)start < (u32)MatrixIndexB.Tex6MtxIdx*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)MatrixIndexB.Tex7MtxIdx*4 && (u32)start < (u32)MatrixIndexB.Tex7MtxIdx*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))
{ {
bTexMatricesChanged[1] = true; bTexMatricesChanged[1] = true;
} }
@ -628,23 +628,23 @@ void VertexShaderManager::InvalidateXFRange(int start, int end)
void VertexShaderManager::SetTexMatrixChangedA(u32 Value) void VertexShaderManager::SetTexMatrixChangedA(u32 Value)
{ {
if (MatrixIndexA.Hex != Value) if (g_main_cp_state.matrix_index_a.Hex != Value)
{ {
VertexManager::Flush(); VertexManager::Flush();
if (MatrixIndexA.PosNormalMtxIdx != (Value&0x3f)) if (g_main_cp_state.matrix_index_a.PosNormalMtxIdx != (Value&0x3f))
bPosNormalMatrixChanged = true; bPosNormalMatrixChanged = true;
bTexMatricesChanged[0] = true; bTexMatricesChanged[0] = true;
MatrixIndexA.Hex = Value; g_main_cp_state.matrix_index_a.Hex = Value;
} }
} }
void VertexShaderManager::SetTexMatrixChangedB(u32 Value) void VertexShaderManager::SetTexMatrixChangedB(u32 Value)
{ {
if (MatrixIndexB.Hex != Value) if (g_main_cp_state.matrix_index_b.Hex != Value)
{ {
VertexManager::Flush(); VertexManager::Flush();
bTexMatricesChanged[1] = true; bTexMatricesChanged[1] = true;
MatrixIndexB.Hex = Value; g_main_cp_state.matrix_index_b.Hex = Value;
} }
} }

View File

@ -22,13 +22,7 @@ static void DoState(PointerWrap &p)
p.DoMarker("BP Memory"); p.DoMarker("BP Memory");
// CP Memory // CP Memory
p.DoArray(arraybases, 16); DoCPState(p);
p.DoArray(arraystrides, 16);
p.Do(MatrixIndexA);
p.Do(MatrixIndexB);
p.Do(g_VtxDesc.Hex);
p.DoArray(g_VtxAttr, 8);
p.DoMarker("CP Memory");
// XF Memory // XF Memory
p.Do(xfmem); p.Do(xfmem);
@ -73,11 +67,6 @@ void VideoCommon_RunLoop(bool enable)
void VideoCommon_Init() void VideoCommon_Init()
{ {
memset(arraybases, 0, sizeof(arraybases)); memset(&g_main_cp_state, 0, sizeof(g_main_cp_state));
memset(arraystrides, 0, sizeof(arraystrides));
memset(&MatrixIndexA, 0, sizeof(MatrixIndexA));
memset(&MatrixIndexB, 0, sizeof(MatrixIndexB));
memset(&g_VtxDesc, 0, sizeof(g_VtxDesc));
memset(g_VtxAttr, 0, sizeof(g_VtxAttr));
memset(texMem, 0, TMEM_SIZE); memset(texMem, 0, TMEM_SIZE);
} }

View File

@ -252,7 +252,7 @@ void LoadIndexedXF(u32 val, int refarray)
//load stuff from array to address in xf mem //load stuff from array to address in xf mem
u32* currData = (u32*)(&xfmem) + address; u32* currData = (u32*)(&xfmem) + address;
u32* newData = (u32*)Memory::GetPointer(arraybases[refarray] + arraystrides[refarray] * index); u32* newData = (u32*)Memory::GetPointer(g_main_cp_state.array_bases[refarray] + g_main_cp_state.array_strides[refarray] * index);
bool changed = false; bool changed = false;
for (int i = 0; i < size; ++i) for (int i = 0; i < size; ++i)
{ {