Create and use CPArray enum class

This commit is contained in:
Pokechu22 2021-06-20 13:47:57 -07:00
parent 3aaeb2b9ef
commit 1914087998
22 changed files with 171 additions and 126 deletions

View File

@ -190,11 +190,11 @@ u32 AnalyzeCommand(const u8* data, DecodeMode mode)
{ {
s_DrawingObject = false; s_DrawingObject = false;
int array = 0xc + (cmd - static_cast<u8>(Opcode::GX_LOAD_INDX_A)) / 8; CPArray array = static_cast<CPArray>(0xc + (cmd - static_cast<u8>(Opcode::GX_LOAD_INDX_A)) / 8);
u32 value = ReadFifo32(data); u32 value = ReadFifo32(data);
if (mode == DecodeMode::Record) if (mode == DecodeMode::Record)
FifoRecordAnalyzer::ProcessLoadIndexedXf(value, array); FifoRecordAnalyzer::ProcessLoadIndexedXf(array, value);
break; break;
} }
@ -238,8 +238,8 @@ u32 AnalyzeCommand(const u8* data, DecodeMode mode)
{ {
for (size_t i = 0; i < offsets.size(); ++i) for (size_t i = 0; i < offsets.size(); ++i)
{ {
FifoRecordAnalyzer::WriteVertexArray(static_cast<int>(i), data + offsets[i], vertexSize, FifoRecordAnalyzer::WriteVertexArray(static_cast<CPArray>(i), data + offsets[i],
numVertices); vertexSize, numVertices);
} }
} }
@ -284,11 +284,11 @@ void LoadCPReg(u32 subCmd, u32 value, CPMemory& cpMem)
break; break;
case ARRAY_BASE: case ARRAY_BASE:
cpMem.arrayBases[subCmd & CP_ARRAY_MASK] = value; cpMem.arrayBases[static_cast<CPArray>(subCmd & CP_ARRAY_MASK)] = value;
break; break;
case ARRAY_STRIDE: case ARRAY_STRIDE:
cpMem.arrayStrides[subCmd & CP_ARRAY_MASK] = value & 0xFF; cpMem.arrayStrides[static_cast<CPArray>(subCmd & CP_ARRAY_MASK)] = value & 0xFF;
break; break;
} }
} }

View File

@ -6,6 +6,8 @@
#include <array> #include <array>
#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
#include "Common/EnumMap.h"
#include "VideoCommon/CPMemory.h" #include "VideoCommon/CPMemory.h"
namespace FifoAnalyzer namespace FifoAnalyzer
@ -22,8 +24,8 @@ struct CPMemory
{ {
TVtxDesc vtxDesc; TVtxDesc vtxDesc;
std::array<VAT, CP_NUM_VAT_REG> vtxAttr; std::array<VAT, CP_NUM_VAT_REG> vtxAttr;
std::array<u32, CP_NUM_ARRAYS> arrayBases{}; Common::EnumMap<u32, CPArray::XF_D> arrayBases{};
std::array<u32, CP_NUM_ARRAYS> arrayStrides{}; Common::EnumMap<u32, CPArray::XF_D> arrayStrides{};
}; };
void LoadCPReg(u32 subCmd, u32 value, CPMemory& cpMem); void LoadCPReg(u32 subCmd, u32 value, CPMemory& cpMem);

View File

@ -30,7 +30,7 @@ void FifoRecordAnalyzer::Initialize(const u32* cpMem)
std::copy(strides_start, strides_end, s_CpMem.arrayStrides.begin()); std::copy(strides_start, strides_end, s_CpMem.arrayStrides.begin());
} }
void FifoRecordAnalyzer::ProcessLoadIndexedXf(u32 val, int array) void FifoRecordAnalyzer::ProcessLoadIndexedXf(CPArray array, u32 val)
{ {
int index = val >> 16; int index = val >> 16;
int size = ((val >> 12) & 0xF) + 1; int size = ((val >> 12) & 0xF) + 1;
@ -40,19 +40,19 @@ void FifoRecordAnalyzer::ProcessLoadIndexedXf(u32 val, int array)
FifoRecorder::GetInstance().UseMemory(address, size * 4, MemoryUpdate::XF_DATA); FifoRecorder::GetInstance().UseMemory(address, size * 4, MemoryUpdate::XF_DATA);
} }
void FifoRecordAnalyzer::WriteVertexArray(int arrayIndex, const u8* vertexData, int vertexSize, void FifoRecordAnalyzer::WriteVertexArray(CPArray arrayIndex, const u8* vertexData, int vertexSize,
int numVertices) int numVertices)
{ {
// Skip if not indexed array // Skip if not indexed array
VertexComponentFormat arrayType; VertexComponentFormat arrayType;
if (arrayIndex == ARRAY_POSITION) if (arrayIndex == CPArray::Position)
arrayType = s_CpMem.vtxDesc.low.Position; arrayType = s_CpMem.vtxDesc.low.Position;
else if (arrayIndex == ARRAY_NORMAL) else if (arrayIndex == CPArray::Normal)
arrayType = s_CpMem.vtxDesc.low.Normal; arrayType = s_CpMem.vtxDesc.low.Normal;
else if (arrayIndex >= ARRAY_COLOR0 && arrayIndex < ARRAY_COLOR0 + NUM_COLOR_ARRAYS) else if (arrayIndex >= CPArray::Color0 && arrayIndex <= CPArray::Color1)
arrayType = s_CpMem.vtxDesc.low.Color[arrayIndex - ARRAY_COLOR0]; arrayType = s_CpMem.vtxDesc.low.Color[u8(arrayIndex) - u8(CPArray::Color0)];
else if (arrayIndex >= ARRAY_TEXCOORD0 && arrayIndex < ARRAY_TEXCOORD0 + NUM_TEXCOORD_ARRAYS) else if (arrayIndex >= CPArray::TexCoord0 && arrayIndex <= CPArray::TexCoord7)
arrayType = s_CpMem.vtxDesc.high.TexCoord[arrayIndex - ARRAY_TEXCOORD0]; arrayType = s_CpMem.vtxDesc.high.TexCoord[u8(arrayIndex) - u8(CPArray::TexCoord0)];
else else
{ {
PanicAlertFmt("Invalid arrayIndex {}", arrayIndex); PanicAlertFmt("Invalid arrayIndex {}", arrayIndex);

View File

@ -5,11 +5,13 @@
#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
enum class CPArray : u8;
namespace FifoRecordAnalyzer namespace FifoRecordAnalyzer
{ {
// Must call this before analyzing Fifo commands with FifoAnalyzer::AnalyzeCommand() // Must call this before analyzing Fifo commands with FifoAnalyzer::AnalyzeCommand()
void Initialize(const u32* cpMem); void Initialize(const u32* cpMem);
void ProcessLoadIndexedXf(u32 val, int array); void ProcessLoadIndexedXf(CPArray array, u32 val);
void WriteVertexArray(int arrayIndex, const u8* vertexData, int vertexSize, int numVertices); void WriteVertexArray(CPArray arrayIndex, const u8* vertexData, int vertexSize, int numVertices);
} // namespace FifoRecordAnalyzer } // namespace FifoRecordAnalyzer

View File

@ -287,7 +287,7 @@ void FIFOAnalyzer::UpdateDetails()
case Opcode::GX_LOAD_INDX_A: case Opcode::GX_LOAD_INDX_A:
{ {
const auto [desc, written] = const auto [desc, written] =
GetXFIndexedLoadInfo(ARRAY_XF_A, Common::swap32(&object[object_offset])); GetXFIndexedLoadInfo(CPArray::XF_A, Common::swap32(&object[object_offset]));
object_offset += 4; object_offset += 4;
new_label = QStringLiteral("LOAD INDX A %1").arg(QString::fromStdString(desc)); new_label = QStringLiteral("LOAD INDX A %1").arg(QString::fromStdString(desc));
} }
@ -295,7 +295,7 @@ void FIFOAnalyzer::UpdateDetails()
case Opcode::GX_LOAD_INDX_B: case Opcode::GX_LOAD_INDX_B:
{ {
const auto [desc, written] = const auto [desc, written] =
GetXFIndexedLoadInfo(ARRAY_XF_B, Common::swap32(&object[object_offset])); GetXFIndexedLoadInfo(CPArray::XF_B, Common::swap32(&object[object_offset]));
object_offset += 4; object_offset += 4;
new_label = QStringLiteral("LOAD INDX B %1").arg(QString::fromStdString(desc)); new_label = QStringLiteral("LOAD INDX B %1").arg(QString::fromStdString(desc));
} }
@ -303,7 +303,7 @@ void FIFOAnalyzer::UpdateDetails()
case Opcode::GX_LOAD_INDX_C: case Opcode::GX_LOAD_INDX_C:
{ {
const auto [desc, written] = const auto [desc, written] =
GetXFIndexedLoadInfo(ARRAY_XF_C, Common::swap32(&object[object_offset])); GetXFIndexedLoadInfo(CPArray::XF_C, Common::swap32(&object[object_offset]));
object_offset += 4; object_offset += 4;
new_label = QStringLiteral("LOAD INDX C %1").arg(QString::fromStdString(desc)); new_label = QStringLiteral("LOAD INDX C %1").arg(QString::fromStdString(desc));
} }
@ -311,7 +311,7 @@ void FIFOAnalyzer::UpdateDetails()
case Opcode::GX_LOAD_INDX_D: case Opcode::GX_LOAD_INDX_D:
{ {
const auto [desc, written] = const auto [desc, written] =
GetXFIndexedLoadInfo(ARRAY_XF_D, Common::swap32(&object[object_offset])); GetXFIndexedLoadInfo(CPArray::XF_D, Common::swap32(&object[object_offset]));
object_offset += 4; object_offset += 4;
new_label = QStringLiteral("LOAD INDX D %1").arg(QString::fromStdString(desc)); new_label = QStringLiteral("LOAD INDX D %1").arg(QString::fromStdString(desc));
} }
@ -619,7 +619,7 @@ void FIFOAnalyzer::UpdateDescription()
} }
else if (opcode == Opcode::GX_LOAD_INDX_A) else if (opcode == Opcode::GX_LOAD_INDX_A)
{ {
const auto [desc, written] = GetXFIndexedLoadInfo(ARRAY_XF_A, Common::swap32(cmddata + 1)); const auto [desc, written] = GetXFIndexedLoadInfo(CPArray::XF_A, Common::swap32(cmddata + 1));
text = QString::fromStdString(desc); text = QString::fromStdString(desc);
text += QLatin1Char{'\n'}; text += QLatin1Char{'\n'};
@ -629,7 +629,7 @@ void FIFOAnalyzer::UpdateDescription()
} }
else if (opcode == Opcode::GX_LOAD_INDX_B) else if (opcode == Opcode::GX_LOAD_INDX_B)
{ {
const auto [desc, written] = GetXFIndexedLoadInfo(ARRAY_XF_B, Common::swap32(cmddata + 1)); const auto [desc, written] = GetXFIndexedLoadInfo(CPArray::XF_B, Common::swap32(cmddata + 1));
text = QString::fromStdString(desc); text = QString::fromStdString(desc);
text += QLatin1Char{'\n'}; text += QLatin1Char{'\n'};
@ -641,7 +641,7 @@ void FIFOAnalyzer::UpdateDescription()
} }
else if (opcode == Opcode::GX_LOAD_INDX_C) else if (opcode == Opcode::GX_LOAD_INDX_C)
{ {
const auto [desc, written] = GetXFIndexedLoadInfo(ARRAY_XF_C, Common::swap32(cmddata + 1)); const auto [desc, written] = GetXFIndexedLoadInfo(CPArray::XF_C, Common::swap32(cmddata + 1));
text = QString::fromStdString(desc); text = QString::fromStdString(desc);
text += QLatin1Char{'\n'}; text += QLatin1Char{'\n'};
@ -652,7 +652,7 @@ void FIFOAnalyzer::UpdateDescription()
} }
else if (opcode == Opcode::GX_LOAD_INDX_D) else if (opcode == Opcode::GX_LOAD_INDX_D)
{ {
const auto [desc, written] = GetXFIndexedLoadInfo(ARRAY_XF_D, Common::swap32(cmddata + 1)); const auto [desc, written] = GetXFIndexedLoadInfo(CPArray::XF_D, Common::swap32(cmddata + 1));
text = QString::fromStdString(desc); text = QString::fromStdString(desc);
text += QLatin1Char{'\n'}; text += QLatin1Char{'\n'};

View File

@ -62,10 +62,12 @@ std::pair<std::string, std::string> GetCPRegInfo(u8 cmd, u32 value)
return std::make_pair(fmt::format("CP_VAT_REG_C - Format {}", cmd & CP_VAT_MASK), return std::make_pair(fmt::format("CP_VAT_REG_C - Format {}", cmd & CP_VAT_MASK),
fmt::to_string(UVAT_group2{.Hex = value})); fmt::to_string(UVAT_group2{.Hex = value}));
case ARRAY_BASE: case ARRAY_BASE:
return std::make_pair(fmt::format("ARRAY_BASE Array {}", cmd & CP_ARRAY_MASK), return std::make_pair(
fmt::format("ARRAY_BASE Array {}", static_cast<CPArray>(cmd & CP_ARRAY_MASK)),
fmt::format("Base address {:08x}", value)); fmt::format("Base address {:08x}", value));
case ARRAY_STRIDE: case ARRAY_STRIDE:
return std::make_pair(fmt::format("ARRAY_STRIDE Array {}", cmd - ARRAY_STRIDE), return std::make_pair(
fmt::format("ARRAY_STRIDE Array {}", static_cast<CPArray>(cmd & CP_ARRAY_MASK)),
fmt::format("Stride {:02x}", value & 0xff)); fmt::format("Stride {:02x}", value & 0xff));
default: default:
return std::make_pair(fmt::format("Invalid CP register {:02x} = {:08x}", cmd, value), ""); return std::make_pair(fmt::format("Invalid CP register {:02x} = {:08x}", cmd, value), "");

View File

@ -11,6 +11,7 @@
#include "Common/BitSet.h" #include "Common/BitSet.h"
#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
#include "Common/EnumFormatter.h" #include "Common/EnumFormatter.h"
#include "Common/EnumMap.h"
#include "Common/MsgHandler.h" #include "Common/MsgHandler.h"
enum enum
@ -53,24 +54,46 @@ enum
}; };
// Vertex array numbers // Vertex array numbers
enum enum class CPArray : u8
{ {
ARRAY_POSITION = 0, Position = 0,
ARRAY_NORMAL = 1, Normal = 1,
ARRAY_COLOR0 = 2,
NUM_COLOR_ARRAYS = 2,
ARRAY_TEXCOORD0 = 4,
NUM_TEXCOORD_ARRAYS = 8,
ARRAY_XF_A = 12, // Usually used for position matrices Color0 = 2,
ARRAY_XF_B = 13, // Usually used for normal matrices Color1 = 3,
ARRAY_XF_C = 14, // Usually used for tex coord matrices
ARRAY_XF_D = 15, // Usually used for light objects TexCoord0 = 4,
TexCoord1 = 5,
TexCoord2 = 6,
TexCoord3 = 7,
TexCoord4 = 8,
TexCoord5 = 9,
TexCoord6 = 10,
TexCoord7 = 11,
XF_A = 12, // Usually used for position matrices
XF_B = 13, // Usually used for normal matrices
XF_C = 14, // Usually used for tex coord matrices
XF_D = 15, // Usually used for light objects
};
template <>
struct fmt::formatter<CPArray> : EnumFormatter<CPArray::XF_D>
{
static constexpr array_type names = {"Position", "Normal", "Color 0", "Color 1",
"Tex Coord 0", "Tex Coord 1", "Tex Coord 2", "Tex Coord 3",
"Tex Coord 4", "Tex Coord 5", "Tex Coord 6", "Tex Coord 7",
"XF A", "XF B", "XF C", "XF D"};
formatter() : EnumFormatter(names) {}
};
// Intended for offsetting from Color0/TexCoord0
constexpr CPArray operator+(CPArray array, u8 offset)
{
return static_cast<CPArray>(static_cast<u8>(array) + offset);
}
// Number of arrays related to vertex components (position, normal, color, tex coord) // Number of arrays related to vertex components (position, normal, color, tex coord)
// Excludes the 4 arrays used for indexed XF loads // Excludes the 4 arrays used for indexed XF loads
NUM_VERTEX_COMPONENT_ARRAYS = 12, constexpr u8 NUM_VERTEX_COMPONENT_ARRAYS = 12;
};
// Vertex components // Vertex components
enum class VertexComponentFormat enum class VertexComponentFormat
@ -607,8 +630,8 @@ class VertexLoaderBase;
// STATE_TO_SAVE // STATE_TO_SAVE
struct CPState final struct CPState final
{ {
u32 array_bases[CP_NUM_ARRAYS]{}; Common::EnumMap<u32, CPArray::XF_D> array_bases;
u32 array_strides[CP_NUM_ARRAYS]{}; Common::EnumMap<u32, CPArray::XF_D> array_strides;
TMatrixIndexA matrix_index_a{}; TMatrixIndexA matrix_index_a{};
TMatrixIndexB matrix_index_b{}; TMatrixIndexB matrix_index_b{};
TVtxDesc vtx_desc; TVtxDesc vtx_desc;

View File

@ -166,12 +166,12 @@ u8* Run(DataReader src, u32* cycles, bool in_display_list)
// GX_LOAD_INDX_B (40) -> 0xD // GX_LOAD_INDX_B (40) -> 0xD
// GX_LOAD_INDX_C (48) -> 0xE // GX_LOAD_INDX_C (48) -> 0xE
// GX_LOAD_INDX_D (56) -> 0xF // GX_LOAD_INDX_D (56) -> 0xF
const int ref_array = (cmd_byte / 8) + 8; const auto array = static_cast<CPArray>((cmd_byte / 8) + 8);
if constexpr (is_preprocess) if constexpr (is_preprocess)
PreprocessIndexedXF(src.Read<u32>(), ref_array); PreprocessIndexedXF(array, src.Read<u32>());
else else
LoadIndexedXF(src.Read<u32>(), ref_array); LoadIndexedXF(array, src.Read<u32>());
} }
break; break;

View File

@ -6,6 +6,7 @@
#include <array> #include <array>
#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
#include "VideoCommon/CPMemory.h"
#include "VideoCommon/DataReader.h" #include "VideoCommon/DataReader.h"
#include "VideoCommon/VertexLoaderManager.h" #include "VideoCommon/VertexLoaderManager.h"
@ -59,7 +60,7 @@ VertexLoaderARM64::VertexLoaderARM64(const TVtxDesc& vtx_desc, const VAT& vtx_at
WriteProtect(); WriteProtect();
} }
void VertexLoaderARM64::GetVertexAddr(int array, VertexComponentFormat attribute, ARM64Reg reg) void VertexLoaderARM64::GetVertexAddr(CPArray array, VertexComponentFormat attribute, ARM64Reg reg)
{ {
if (IsIndexed(attribute)) if (IsIndexed(attribute))
{ {
@ -95,7 +96,7 @@ void VertexLoaderARM64::GetVertexAddr(int array, VertexComponentFormat attribute
REV16(scratch1_reg, scratch1_reg); REV16(scratch1_reg, scratch1_reg);
} }
if (array == ARRAY_POSITION) if (array == CPArray::Position)
{ {
EOR(scratch2_reg, scratch1_reg, EOR(scratch2_reg, scratch1_reg,
attribute == VertexComponentFormat::Index8 ? LogicalImm(0xFF, 32) : attribute == VertexComponentFormat::Index8 ? LogicalImm(0xFF, 32) :
@ -103,17 +104,18 @@ void VertexLoaderARM64::GetVertexAddr(int array, VertexComponentFormat attribute
m_skip_vertex = CBZ(scratch2_reg); m_skip_vertex = CBZ(scratch2_reg);
} }
LDR(IndexType::Unsigned, scratch2_reg, stride_reg, array * 4); LDR(IndexType::Unsigned, scratch2_reg, stride_reg, static_cast<u8>(array) * 4);
MUL(scratch1_reg, scratch1_reg, scratch2_reg); MUL(scratch1_reg, scratch1_reg, scratch2_reg);
LDR(IndexType::Unsigned, EncodeRegTo64(scratch2_reg), arraybase_reg, array * 8); LDR(IndexType::Unsigned, EncodeRegTo64(scratch2_reg), arraybase_reg,
static_cast<u8>(array) * 8);
ADD(EncodeRegTo64(reg), EncodeRegTo64(scratch1_reg), EncodeRegTo64(scratch2_reg)); ADD(EncodeRegTo64(reg), EncodeRegTo64(scratch1_reg), EncodeRegTo64(scratch2_reg));
} }
else else
ADD(reg, src_reg, m_src_ofs); ADD(reg, src_reg, m_src_ofs);
} }
s32 VertexLoaderARM64::GetAddressImm(int array, VertexComponentFormat attribute, s32 VertexLoaderARM64::GetAddressImm(CPArray array, VertexComponentFormat attribute,
Arm64Gen::ARM64Reg reg, u32 align) Arm64Gen::ARM64Reg reg, u32 align)
{ {
if (IsIndexed(attribute) || (m_src_ofs > 255 && (m_src_ofs & (align - 1)))) if (IsIndexed(attribute) || (m_src_ofs > 255 && (m_src_ofs & (align - 1))))
@ -448,8 +450,8 @@ void VertexLoaderARM64::GenerateVertexLoader()
int load_size = GetLoadSize(load_bytes); int load_size = GetLoadSize(load_bytes);
load_size <<= 3; load_size <<= 3;
s32 offset = GetAddressImm(ARRAY_POSITION, m_VtxDesc.low.Position, EncodeRegTo64(scratch1_reg), s32 offset = GetAddressImm(CPArray::Position, m_VtxDesc.low.Position,
load_size); EncodeRegTo64(scratch1_reg), load_size);
ReadVertex(m_VtxDesc.low.Position, m_VtxAttr.g0.PosFormat, pos_elements, pos_elements, ReadVertex(m_VtxDesc.low.Position, m_VtxAttr.g0.PosFormat, pos_elements, pos_elements,
m_VtxAttr.g0.ByteDequant, m_VtxAttr.g0.PosFrac, &m_native_vtx_decl.position, offset); m_VtxAttr.g0.ByteDequant, m_VtxAttr.g0.PosFrac, &m_native_vtx_decl.position, offset);
} }
@ -470,7 +472,7 @@ void VertexLoaderARM64::GenerateVertexLoader()
int load_bytes = elem_size * 3; int load_bytes = elem_size * 3;
int load_size = GetLoadSize(load_bytes); int load_size = GetLoadSize(load_bytes);
offset = GetAddressImm(ARRAY_NORMAL, m_VtxDesc.low.Normal, EncodeRegTo64(scratch1_reg), offset = GetAddressImm(CPArray::Normal, m_VtxDesc.low.Normal, EncodeRegTo64(scratch1_reg),
load_size << 3); load_size << 3);
if (offset == -1) if (offset == -1)
@ -488,7 +490,7 @@ void VertexLoaderARM64::GenerateVertexLoader()
} }
} }
for (size_t i = 0; i < m_VtxDesc.low.Color.Size(); i++) for (u8 i = 0; i < m_VtxDesc.low.Color.Size(); i++)
{ {
m_native_vtx_decl.colors[i].components = 4; m_native_vtx_decl.colors[i].components = 4;
m_native_vtx_decl.colors[i].type = VAR_UNSIGNED_BYTE; m_native_vtx_decl.colors[i].type = VAR_UNSIGNED_BYTE;
@ -501,7 +503,7 @@ void VertexLoaderARM64::GenerateVertexLoader()
m_VtxAttr.GetColorFormat(i) == ColorFormat::RGBA4444) m_VtxAttr.GetColorFormat(i) == ColorFormat::RGBA4444)
align = 2; align = 2;
s32 offset = GetAddressImm(ARRAY_COLOR0 + int(i), m_VtxDesc.low.Color[i], s32 offset = GetAddressImm(CPArray::Color0 + i, m_VtxDesc.low.Color[i],
EncodeRegTo64(scratch1_reg), align); EncodeRegTo64(scratch1_reg), align);
ReadColor(m_VtxDesc.low.Color[i], m_VtxAttr.GetColorFormat(i), offset); ReadColor(m_VtxDesc.low.Color[i], m_VtxAttr.GetColorFormat(i), offset);
m_native_vtx_decl.colors[i].components = 4; m_native_vtx_decl.colors[i].components = 4;
@ -513,7 +515,7 @@ void VertexLoaderARM64::GenerateVertexLoader()
} }
} }
for (size_t i = 0; i < m_VtxDesc.high.TexCoord.Size(); i++) for (u8 i = 0; i < m_VtxDesc.high.TexCoord.Size(); i++)
{ {
m_native_vtx_decl.texcoords[i].offset = m_dst_ofs; m_native_vtx_decl.texcoords[i].offset = m_dst_ofs;
m_native_vtx_decl.texcoords[i].type = VAR_FLOAT; m_native_vtx_decl.texcoords[i].type = VAR_FLOAT;
@ -527,7 +529,7 @@ void VertexLoaderARM64::GenerateVertexLoader()
int load_size = GetLoadSize(load_bytes); int load_size = GetLoadSize(load_bytes);
load_size <<= 3; load_size <<= 3;
s32 offset = GetAddressImm(ARRAY_TEXCOORD0 + int(i), m_VtxDesc.high.TexCoord[i], s32 offset = GetAddressImm(CPArray::TexCoord0 + i, m_VtxDesc.high.TexCoord[i],
EncodeRegTo64(scratch1_reg), load_size); EncodeRegTo64(scratch1_reg), load_size);
u8 scaling_exponent = m_VtxAttr.GetTexFrac(i); u8 scaling_exponent = m_VtxAttr.GetTexFrac(i);
ReadVertex(m_VtxDesc.high.TexCoord[i], m_VtxAttr.GetTexFormat(i), elements, ReadVertex(m_VtxDesc.high.TexCoord[i], m_VtxAttr.GetTexFormat(i), elements,

View File

@ -11,6 +11,7 @@ class DataReader;
enum class VertexComponentFormat; enum class VertexComponentFormat;
enum class ComponentFormat; enum class ComponentFormat;
enum class ColorFormat; enum class ColorFormat;
enum class CPArray : u8;
class VertexLoaderARM64 : public VertexLoaderBase, public Arm64Gen::ARM64CodeBlock class VertexLoaderARM64 : public VertexLoaderBase, public Arm64Gen::ARM64CodeBlock
{ {
@ -25,8 +26,9 @@ private:
u32 m_dst_ofs = 0; u32 m_dst_ofs = 0;
Arm64Gen::FixupBranch m_skip_vertex; Arm64Gen::FixupBranch m_skip_vertex;
Arm64Gen::ARM64FloatEmitter m_float_emit; Arm64Gen::ARM64FloatEmitter m_float_emit;
void GetVertexAddr(int array, VertexComponentFormat attribute, Arm64Gen::ARM64Reg reg); void GetVertexAddr(CPArray array, VertexComponentFormat attribute, Arm64Gen::ARM64Reg reg);
s32 GetAddressImm(int array, VertexComponentFormat attribute, Arm64Gen::ARM64Reg reg, u32 align); s32 GetAddressImm(CPArray array, VertexComponentFormat attribute, Arm64Gen::ARM64Reg reg,
u32 align);
int ReadVertex(VertexComponentFormat attribute, ComponentFormat format, int count_in, int ReadVertex(VertexComponentFormat attribute, ComponentFormat format, int count_in,
int count_out, bool dequantize, u8 scaling_exponent, int count_out, bool dequantize, u8 scaling_exponent,
AttributeFormat* native_format, s32 offset = -1); AttributeFormat* native_format, s32 offset = -1);

View File

@ -14,6 +14,7 @@
#include "Common/Assert.h" #include "Common/Assert.h"
#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
#include "Common/EnumMap.h"
#include "Common/Logging/Log.h" #include "Common/Logging/Log.h"
#include "Core/DolphinAnalytics.h" #include "Core/DolphinAnalytics.h"
@ -48,7 +49,14 @@ static std::mutex s_vertex_loader_map_lock;
static VertexLoaderMap s_vertex_loader_map; static VertexLoaderMap s_vertex_loader_map;
// TODO - change into array of pointers. Keep a map of all seen so far. // TODO - change into array of pointers. Keep a map of all seen so far.
u8* cached_arraybases[NUM_VERTEX_COMPONENT_ARRAYS]; Common::EnumMap<u8*, CPArray::TexCoord7> cached_arraybases;
BitSet8 g_main_vat_dirty;
BitSet8 g_preprocess_vat_dirty;
bool g_bases_dirty; // Main only
u8 g_current_vat; // Main only
std::array<VertexLoaderBase*, CP_NUM_VAT_REG> g_main_vertex_loaders;
std::array<VertexLoaderBase*, CP_NUM_VAT_REG> g_preprocess_vertex_loaders;
void Init() void Init()
{ {
@ -80,24 +88,25 @@ void UpdateVertexArrayPointers()
// 12 through 15 are used for loading data into xfmem. // 12 through 15 are used for loading data into xfmem.
// We also only update the array base if the vertex description states we are going to use it. // We also only update the array base if the vertex description states we are going to use it.
if (IsIndexed(g_main_cp_state.vtx_desc.low.Position)) if (IsIndexed(g_main_cp_state.vtx_desc.low.Position))
cached_arraybases[ARRAY_POSITION] = cached_arraybases[CPArray::Position] =
Memory::GetPointer(g_main_cp_state.array_bases[ARRAY_POSITION]); Memory::GetPointer(g_main_cp_state.array_bases[CPArray::Position]);
if (IsIndexed(g_main_cp_state.vtx_desc.low.Normal)) if (IsIndexed(g_main_cp_state.vtx_desc.low.Normal))
cached_arraybases[ARRAY_NORMAL] = Memory::GetPointer(g_main_cp_state.array_bases[ARRAY_NORMAL]); cached_arraybases[CPArray::Normal] =
Memory::GetPointer(g_main_cp_state.array_bases[CPArray::Normal]);
for (size_t i = 0; i < g_main_cp_state.vtx_desc.low.Color.Size(); i++) for (u8 i = 0; i < g_main_cp_state.vtx_desc.low.Color.Size(); i++)
{ {
if (IsIndexed(g_main_cp_state.vtx_desc.low.Color[i])) if (IsIndexed(g_main_cp_state.vtx_desc.low.Color[i]))
cached_arraybases[ARRAY_COLOR0 + i] = cached_arraybases[CPArray::Color0 + i] =
Memory::GetPointer(g_main_cp_state.array_bases[ARRAY_COLOR0 + i]); Memory::GetPointer(g_main_cp_state.array_bases[CPArray::Color0 + i]);
} }
for (size_t i = 0; i < g_main_cp_state.vtx_desc.high.TexCoord.Size(); i++) for (u8 i = 0; i < g_main_cp_state.vtx_desc.high.TexCoord.Size(); i++)
{ {
if (IsIndexed(g_main_cp_state.vtx_desc.high.TexCoord[i])) if (IsIndexed(g_main_cp_state.vtx_desc.high.TexCoord[i]))
cached_arraybases[ARRAY_TEXCOORD0 + i] = cached_arraybases[CPArray::TexCoord0 + i] =
Memory::GetPointer(g_main_cp_state.array_bases[ARRAY_TEXCOORD0 + i]); Memory::GetPointer(g_main_cp_state.array_bases[CPArray::TexCoord0 + i]);
} }
g_main_cp_state.bases_dirty = false; g_main_cp_state.bases_dirty = false;
@ -398,13 +407,13 @@ void LoadCPReg(u32 sub_cmd, u32 value, bool is_preprocess)
// Pointers to vertex arrays in GC RAM // Pointers to vertex arrays in GC RAM
case ARRAY_BASE: case ARRAY_BASE:
state->array_bases[sub_cmd & CP_ARRAY_MASK] = state->array_bases[static_cast<CPArray>(sub_cmd & CP_ARRAY_MASK)] =
value & CommandProcessor::GetPhysicalAddressMask(); value & CommandProcessor::GetPhysicalAddressMask();
state->bases_dirty = true; state->bases_dirty = true;
break; break;
case ARRAY_STRIDE: case ARRAY_STRIDE:
state->array_strides[sub_cmd & CP_ARRAY_MASK] = value & 0xFF; state->array_strides[static_cast<CPArray>(sub_cmd & CP_ARRAY_MASK)] = value & 0xFF;
break; break;
default: default:
@ -427,9 +436,9 @@ void FillCPMemoryArray(u32* memory)
memory[CP_VAT_REG_C + i] = g_main_cp_state.vtx_attr[i].g2.Hex; memory[CP_VAT_REG_C + i] = g_main_cp_state.vtx_attr[i].g2.Hex;
} }
for (int i = 0; i < CP_NUM_ARRAYS; ++i) for (u8 i = 0; i < CP_NUM_ARRAYS; ++i)
{ {
memory[ARRAY_BASE + i] = g_main_cp_state.array_bases[i]; memory[ARRAY_BASE + i] = g_main_cp_state.array_bases[static_cast<CPArray>(i)];
memory[ARRAY_STRIDE + i] = g_main_cp_state.array_strides[i]; memory[ARRAY_STRIDE + i] = g_main_cp_state.array_strides[static_cast<CPArray>(i)];
} }
} }

View File

@ -8,6 +8,7 @@
#include <unordered_map> #include <unordered_map>
#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
#include "Common/EnumMap.h"
#include "VideoCommon/CPMemory.h" #include "VideoCommon/CPMemory.h"
class DataReader; class DataReader;
@ -46,7 +47,7 @@ int RunVertices(int vtx_attr_group, OpcodeDecoder::Primitive primitive, int coun
NativeVertexFormat* GetCurrentVertexFormat(); NativeVertexFormat* GetCurrentVertexFormat();
// Resolved pointers to array bases. Used by vertex loaders. // Resolved pointers to array bases. Used by vertex loaders.
extern u8* cached_arraybases[NUM_VERTEX_COMPONENT_ARRAYS]; extern Common::EnumMap<u8*, CPArray::TexCoord7> cached_arraybases;
void UpdateVertexArrayPointers(); void UpdateVertexArrayPointers();
// Position cache for zfreeze (3 vertices, 4 floats each to allow SIMD overwrite). // Position cache for zfreeze (3 vertices, 4 floats each to allow SIMD overwrite).

View File

@ -15,6 +15,7 @@
#include "Common/JitRegister.h" #include "Common/JitRegister.h"
#include "Common/x64ABI.h" #include "Common/x64ABI.h"
#include "Common/x64Emitter.h" #include "Common/x64Emitter.h"
#include "VideoCommon/CPMemory.h"
#include "VideoCommon/DataReader.h" #include "VideoCommon/DataReader.h"
#include "VideoCommon/VertexLoaderManager.h" #include "VideoCommon/VertexLoaderManager.h"
@ -54,7 +55,7 @@ VertexLoaderX64::VertexLoaderX64(const TVtxDesc& vtx_desc, const VAT& vtx_att)
JitRegister::Register(region, GetCodePtr(), name.c_str()); JitRegister::Register(region, GetCodePtr(), name.c_str());
} }
OpArg VertexLoaderX64::GetVertexAddr(int array, VertexComponentFormat attribute) OpArg VertexLoaderX64::GetVertexAddr(CPArray array, VertexComponentFormat attribute)
{ {
OpArg data = MDisp(src_reg, m_src_ofs); OpArg data = MDisp(src_reg, m_src_ofs);
if (IsIndexed(attribute)) if (IsIndexed(attribute))
@ -62,7 +63,7 @@ OpArg VertexLoaderX64::GetVertexAddr(int array, VertexComponentFormat attribute)
int bits = attribute == VertexComponentFormat::Index8 ? 8 : 16; int bits = attribute == VertexComponentFormat::Index8 ? 8 : 16;
LoadAndSwap(bits, scratch1, data); LoadAndSwap(bits, scratch1, data);
m_src_ofs += bits / 8; m_src_ofs += bits / 8;
if (array == ARRAY_POSITION) if (array == CPArray::Position)
{ {
CMP(bits, R(scratch1), Imm8(-1)); CMP(bits, R(scratch1), Imm8(-1));
m_skip_vertex = J_CC(CC_E, true); m_skip_vertex = J_CC(CC_E, true);
@ -433,7 +434,7 @@ void VertexLoaderX64::GenerateVertexLoader()
texmatidx_ofs[i] = m_src_ofs++; texmatidx_ofs[i] = m_src_ofs++;
} }
OpArg data = GetVertexAddr(ARRAY_POSITION, m_VtxDesc.low.Position); OpArg data = GetVertexAddr(CPArray::Position, m_VtxDesc.low.Position);
int pos_elements = m_VtxAttr.g0.PosElements == CoordComponentCount::XY ? 2 : 3; int pos_elements = m_VtxAttr.g0.PosElements == CoordComponentCount::XY ? 2 : 3;
ReadVertex(data, m_VtxDesc.low.Position, m_VtxAttr.g0.PosFormat, pos_elements, pos_elements, ReadVertex(data, m_VtxDesc.low.Position, m_VtxAttr.g0.PosFormat, pos_elements, pos_elements,
m_VtxAttr.g0.ByteDequant, m_VtxAttr.g0.PosFrac, &m_native_vtx_decl.position); m_VtxAttr.g0.ByteDequant, m_VtxAttr.g0.PosFrac, &m_native_vtx_decl.position);
@ -448,7 +449,7 @@ void VertexLoaderX64::GenerateVertexLoader()
{ {
if (!i || m_VtxAttr.g0.NormalIndex3) if (!i || m_VtxAttr.g0.NormalIndex3)
{ {
data = GetVertexAddr(ARRAY_NORMAL, m_VtxDesc.low.Normal); data = GetVertexAddr(CPArray::Normal, m_VtxDesc.low.Normal);
int elem_size = GetElementSize(m_VtxAttr.g0.NormalFormat); int elem_size = GetElementSize(m_VtxAttr.g0.NormalFormat);
data.AddMemOffset(i * elem_size * 3); data.AddMemOffset(i * elem_size * 3);
} }
@ -457,11 +458,11 @@ void VertexLoaderX64::GenerateVertexLoader()
} }
} }
for (size_t i = 0; i < m_VtxDesc.low.Color.Size(); i++) for (u8 i = 0; i < m_VtxDesc.low.Color.Size(); i++)
{ {
if (m_VtxDesc.low.Color[i] != VertexComponentFormat::NotPresent) if (m_VtxDesc.low.Color[i] != VertexComponentFormat::NotPresent)
{ {
data = GetVertexAddr(ARRAY_COLOR0 + int(i), m_VtxDesc.low.Color[i]); data = GetVertexAddr(CPArray::Color0 + i, m_VtxDesc.low.Color[i]);
ReadColor(data, m_VtxDesc.low.Color[i], m_VtxAttr.GetColorFormat(i)); ReadColor(data, m_VtxDesc.low.Color[i], m_VtxAttr.GetColorFormat(i));
m_native_vtx_decl.colors[i].components = 4; m_native_vtx_decl.colors[i].components = 4;
m_native_vtx_decl.colors[i].enable = true; m_native_vtx_decl.colors[i].enable = true;
@ -472,12 +473,12 @@ void VertexLoaderX64::GenerateVertexLoader()
} }
} }
for (size_t i = 0; i < m_VtxDesc.high.TexCoord.Size(); i++) for (u8 i = 0; i < m_VtxDesc.high.TexCoord.Size(); i++)
{ {
int elements = m_VtxAttr.GetTexElements(i) == TexComponentCount::ST ? 2 : 1; int elements = m_VtxAttr.GetTexElements(i) == TexComponentCount::ST ? 2 : 1;
if (m_VtxDesc.high.TexCoord[i] != VertexComponentFormat::NotPresent) if (m_VtxDesc.high.TexCoord[i] != VertexComponentFormat::NotPresent)
{ {
data = GetVertexAddr(ARRAY_TEXCOORD0 + int(i), m_VtxDesc.high.TexCoord[i]); data = GetVertexAddr(CPArray::TexCoord0 + i, m_VtxDesc.high.TexCoord[i]);
u8 scaling_exponent = m_VtxAttr.GetTexFrac(i); u8 scaling_exponent = m_VtxAttr.GetTexFrac(i);
ReadVertex(data, m_VtxDesc.high.TexCoord[i], m_VtxAttr.GetTexFormat(i), elements, ReadVertex(data, m_VtxDesc.high.TexCoord[i], m_VtxAttr.GetTexFormat(i), elements,
m_VtxDesc.low.TexMatIdx[i] ? 2 : elements, m_VtxAttr.g0.ByteDequant, m_VtxDesc.low.TexMatIdx[i] ? 2 : elements, m_VtxAttr.g0.ByteDequant,

View File

@ -10,6 +10,7 @@
enum class VertexComponentFormat; enum class VertexComponentFormat;
enum class ComponentFormat; enum class ComponentFormat;
enum class ColorFormat; enum class ColorFormat;
enum class CPArray : u8;
class VertexLoaderX64 : public VertexLoaderBase, public Gen::X64CodeBlock class VertexLoaderX64 : public VertexLoaderBase, public Gen::X64CodeBlock
{ {
@ -23,7 +24,7 @@ private:
u32 m_src_ofs = 0; u32 m_src_ofs = 0;
u32 m_dst_ofs = 0; u32 m_dst_ofs = 0;
Gen::FixupBranch m_skip_vertex; Gen::FixupBranch m_skip_vertex;
Gen::OpArg GetVertexAddr(int array, VertexComponentFormat attribute); Gen::OpArg GetVertexAddr(CPArray array, VertexComponentFormat attribute);
int ReadVertex(Gen::OpArg data, VertexComponentFormat attribute, ComponentFormat format, int ReadVertex(Gen::OpArg data, VertexComponentFormat attribute, ComponentFormat format,
int count_in, int count_out, bool dequantize, u8 scaling_exponent, int count_in, int count_out, bool dequantize, u8 scaling_exponent,
AttributeFormat* native_format); AttributeFormat* native_format);

View File

@ -79,8 +79,8 @@ void Color_ReadIndex_16b_565(VertexLoader* loader)
{ {
const auto index = DataRead<I>(); const auto index = DataRead<I>();
const u8* const address = const u8* const address =
VertexLoaderManager::cached_arraybases[ARRAY_COLOR0 + loader->m_colIndex] + VertexLoaderManager::cached_arraybases[CPArray::Color0 + loader->m_colIndex] +
(index * g_main_cp_state.array_strides[ARRAY_COLOR0 + loader->m_colIndex]); (index * g_main_cp_state.array_strides[CPArray::Color0 + loader->m_colIndex]);
u16 value; u16 value;
std::memcpy(&value, address, sizeof(u16)); std::memcpy(&value, address, sizeof(u16));
@ -92,8 +92,8 @@ template <typename I>
void Color_ReadIndex_24b_888(VertexLoader* loader) void Color_ReadIndex_24b_888(VertexLoader* loader)
{ {
const auto index = DataRead<I>(); const auto index = DataRead<I>();
const u8* address = VertexLoaderManager::cached_arraybases[ARRAY_COLOR0 + loader->m_colIndex] + const u8* address = VertexLoaderManager::cached_arraybases[CPArray::Color0 + loader->m_colIndex] +
(index * g_main_cp_state.array_strides[ARRAY_COLOR0 + loader->m_colIndex]); (index * g_main_cp_state.array_strides[CPArray::Color0 + loader->m_colIndex]);
SetCol(loader, Read24(address)); SetCol(loader, Read24(address));
} }
@ -101,18 +101,18 @@ template <typename I>
void Color_ReadIndex_32b_888x(VertexLoader* loader) void Color_ReadIndex_32b_888x(VertexLoader* loader)
{ {
const auto index = DataRead<I>(); const auto index = DataRead<I>();
const u8* address = VertexLoaderManager::cached_arraybases[ARRAY_COLOR0 + loader->m_colIndex] + const u8* address = VertexLoaderManager::cached_arraybases[CPArray::Color0 + loader->m_colIndex] +
(index * g_main_cp_state.array_strides[ARRAY_COLOR0 + loader->m_colIndex]); (index * g_main_cp_state.array_strides[CPArray::Color0 + loader->m_colIndex]);
SetCol(loader, Read24(address)); SetCol(loader, Read24(address));
} }
template <typename I> template <typename I>
void Color_ReadIndex_16b_4444(VertexLoader* loader) void Color_ReadIndex_16b_4444(VertexLoader* loader)
{ {
auto const index = DataRead<I>(); const auto index = DataRead<I>();
const u8* const address = const u8* const address =
VertexLoaderManager::cached_arraybases[ARRAY_COLOR0 + loader->m_colIndex] + VertexLoaderManager::cached_arraybases[CPArray::Color0 + loader->m_colIndex] +
(index * g_main_cp_state.array_strides[ARRAY_COLOR0 + loader->m_colIndex]); (index * g_main_cp_state.array_strides[CPArray::Color0 + loader->m_colIndex]);
u16 value; u16 value;
std::memcpy(&value, address, sizeof(u16)); std::memcpy(&value, address, sizeof(u16));
@ -124,8 +124,8 @@ template <typename I>
void Color_ReadIndex_24b_6666(VertexLoader* loader) void Color_ReadIndex_24b_6666(VertexLoader* loader)
{ {
const auto index = DataRead<I>(); const auto index = DataRead<I>();
const u8* data = VertexLoaderManager::cached_arraybases[ARRAY_COLOR0 + loader->m_colIndex] + const u8* data = VertexLoaderManager::cached_arraybases[CPArray::Color0 + loader->m_colIndex] +
(index * g_main_cp_state.array_strides[ARRAY_COLOR0 + loader->m_colIndex]) - 1; (index * g_main_cp_state.array_strides[CPArray::Color0 + loader->m_colIndex]) - 1;
const u32 val = Common::swap32(data); const u32 val = Common::swap32(data);
SetCol6666(loader, val); SetCol6666(loader, val);
} }
@ -134,8 +134,8 @@ template <typename I>
void Color_ReadIndex_32b_8888(VertexLoader* loader) void Color_ReadIndex_32b_8888(VertexLoader* loader)
{ {
const auto index = DataRead<I>(); const auto index = DataRead<I>();
const u8* address = VertexLoaderManager::cached_arraybases[ARRAY_COLOR0 + loader->m_colIndex] + const u8* address = VertexLoaderManager::cached_arraybases[CPArray::Color0 + loader->m_colIndex] +
(index * g_main_cp_state.array_strides[ARRAY_COLOR0 + loader->m_colIndex]); (index * g_main_cp_state.array_strides[CPArray::Color0 + loader->m_colIndex]);
SetCol(loader, Read32(address)); SetCol(loader, Read32(address));
} }

View File

@ -59,7 +59,7 @@ struct Normal_Direct
{ {
static void function([[maybe_unused]] VertexLoader* loader) static void function([[maybe_unused]] VertexLoader* loader)
{ {
auto const source = reinterpret_cast<const T*>(DataGetPosition()); const auto source = reinterpret_cast<const T*>(DataGetPosition());
ReadIndirect<T, N * 3>(source); ReadIndirect<T, N * 3>(source);
DataSkip<N * 3 * sizeof(T)>(); DataSkip<N * 3 * sizeof(T)>();
} }
@ -72,10 +72,10 @@ void Normal_Index_Offset()
{ {
static_assert(std::is_unsigned_v<I>, "Only unsigned I is sane!"); static_assert(std::is_unsigned_v<I>, "Only unsigned I is sane!");
auto const index = DataRead<I>(); const auto index = DataRead<I>();
auto const data = reinterpret_cast<const T*>( const auto data = reinterpret_cast<const T*>(
VertexLoaderManager::cached_arraybases[ARRAY_NORMAL] + VertexLoaderManager::cached_arraybases[CPArray::Normal] +
(index * g_main_cp_state.array_strides[ARRAY_NORMAL]) + sizeof(T) * 3 * Offset); (index * g_main_cp_state.array_strides[CPArray::Normal]) + sizeof(T) * 3 * Offset);
ReadIndirect<T, N * 3>(data); ReadIndirect<T, N * 3>(data);
} }

View File

@ -60,8 +60,8 @@ void Pos_ReadIndex(VertexLoader* loader)
const auto index = DataRead<I>(); const auto index = DataRead<I>();
loader->m_vertexSkip = index == std::numeric_limits<I>::max(); loader->m_vertexSkip = index == std::numeric_limits<I>::max();
const auto data = const auto data =
reinterpret_cast<const T*>(VertexLoaderManager::cached_arraybases[ARRAY_POSITION] + reinterpret_cast<const T*>(VertexLoaderManager::cached_arraybases[CPArray::Position] +
(index * g_main_cp_state.array_strides[ARRAY_POSITION])); (index * g_main_cp_state.array_strides[CPArray::Position]));
const auto scale = loader->m_posScale; const auto scale = loader->m_posScale;
DataReader dst(g_vertex_manager_write_ptr, nullptr); DataReader dst(g_vertex_manager_write_ptr, nullptr);

View File

@ -55,8 +55,8 @@ void TexCoord_ReadIndex(VertexLoader* loader)
const auto index = DataRead<I>(); const auto index = DataRead<I>();
const auto data = reinterpret_cast<const T*>( const auto data = reinterpret_cast<const T*>(
VertexLoaderManager::cached_arraybases[ARRAY_TEXCOORD0 + loader->m_tcIndex] + VertexLoaderManager::cached_arraybases[CPArray::TexCoord0 + loader->m_tcIndex] +
(index * g_main_cp_state.array_strides[ARRAY_TEXCOORD0 + loader->m_tcIndex])); (index * g_main_cp_state.array_strides[CPArray::TexCoord0 + loader->m_tcIndex]));
const auto scale = loader->m_tcScale[loader->m_tcIndex]; const auto scale = loader->m_tcScale[loader->m_tcIndex];
DataReader dst(g_vertex_manager_write_ptr, nullptr); DataReader dst(g_vertex_manager_write_ptr, nullptr);

View File

@ -459,5 +459,5 @@ static_assert(sizeof(XFMemory) == sizeof(u32) * 0x1058);
extern XFMemory xfmem; extern XFMemory xfmem;
void LoadXFReg(u32 transferSize, u32 address, DataReader src); void LoadXFReg(u32 transferSize, u32 address, DataReader src);
void LoadIndexedXF(u32 val, int array); void LoadIndexedXF(CPArray array, u32 val);
void PreprocessIndexedXF(u32 val, int refarray); void PreprocessIndexedXF(CPArray array, u32 val);

View File

@ -274,7 +274,7 @@ constexpr std::tuple<u32, u32, u32> ExtractIndexedXF(u32 val)
} }
// TODO - verify that it is correct. Seems to work, though. // TODO - verify that it is correct. Seems to work, though.
void LoadIndexedXF(u32 val, int refarray) void LoadIndexedXF(CPArray array, u32 val)
{ {
const auto [index, address, size] = ExtractIndexedXF(val); const auto [index, address, size] = ExtractIndexedXF(val);
// load stuff from array to address in xf mem // load stuff from array to address in xf mem
@ -287,8 +287,8 @@ void LoadIndexedXF(u32 val, int refarray)
} }
else else
{ {
newData = (u32*)Memory::GetPointer(g_main_cp_state.array_bases[refarray] + newData = (u32*)Memory::GetPointer(g_main_cp_state.array_bases[array] +
g_main_cp_state.array_strides[refarray] * index); g_main_cp_state.array_strides[array] * index);
} }
bool changed = false; bool changed = false;
for (u32 i = 0; i < size; ++i) for (u32 i = 0; i < size; ++i)
@ -307,12 +307,12 @@ void LoadIndexedXF(u32 val, int refarray)
} }
} }
void PreprocessIndexedXF(u32 val, int refarray) void PreprocessIndexedXF(CPArray array, u32 val)
{ {
const auto [index, address, size] = ExtractIndexedXF(val); const auto [index, address, size] = ExtractIndexedXF(val);
const u8* new_data = Memory::GetPointer(g_preprocess_cp_state.array_bases[refarray] + const u8* new_data = Memory::GetPointer(g_preprocess_cp_state.array_bases[array] +
g_preprocess_cp_state.array_strides[refarray] * index); g_preprocess_cp_state.array_strides[array] * index);
const size_t buf_size = size * sizeof(u32); const size_t buf_size = size * sizeof(u32);
Fifo::PushFifoAuxBuffer(new_data, buf_size); Fifo::PushFifoAuxBuffer(new_data, buf_size);
@ -655,7 +655,7 @@ std::pair<std::string, std::string> GetXFTransferInfo(const u8* data)
return std::make_pair(fmt::to_string(name), fmt::to_string(desc)); return std::make_pair(fmt::to_string(name), fmt::to_string(desc));
} }
std::pair<std::string, std::string> GetXFIndexedLoadInfo(u8 array, u32 value) std::pair<std::string, std::string> GetXFIndexedLoadInfo(CPArray array, u32 value)
{ {
const auto [index, address, size] = ExtractIndexedXF(value); const auto [index, address, size] = ExtractIndexedXF(value);

View File

@ -12,4 +12,4 @@ std::pair<std::string, std::string> GetXFRegInfo(u32 address, u32 value);
std::string GetXFMemName(u32 address); std::string GetXFMemName(u32 address);
std::string GetXFMemDescription(u32 address, u32 value); std::string GetXFMemDescription(u32 address, u32 value);
std::pair<std::string, std::string> GetXFTransferInfo(const u8* data); std::pair<std::string, std::string> GetXFTransferInfo(const u8* data);
std::pair<std::string, std::string> GetXFIndexedLoadInfo(u8 array, u32 value); std::pair<std::string, std::string> GetXFIndexedLoadInfo(CPArray array, u32 value);

View File

@ -174,8 +174,8 @@ TEST_P(VertexLoaderParamTest, PositionAll)
Input<u8>(i); Input<u8>(i);
else else
Input<u16>(i); Input<u16>(i);
VertexLoaderManager::cached_arraybases[ARRAY_POSITION] = m_src.GetPointer(); VertexLoaderManager::cached_arraybases[CPArray::Position] = m_src.GetPointer();
g_main_cp_state.array_strides[ARRAY_POSITION] = elem_count * elem_size; g_main_cp_state.array_strides[CPArray::Position] = elem_count * elem_size;
} }
CreateAndCheckSizes(input_size, elem_count * sizeof(float)); CreateAndCheckSizes(input_size, elem_count * sizeof(float));
for (float value : values) for (float value : values)
@ -243,8 +243,8 @@ TEST_F(VertexLoaderTest, PositionIndex16FloatXY)
CreateAndCheckSizes(sizeof(u16), 2 * sizeof(float)); CreateAndCheckSizes(sizeof(u16), 2 * sizeof(float));
Input<u16>(1); Input<u16>(1);
Input<u16>(0); Input<u16>(0);
VertexLoaderManager::cached_arraybases[ARRAY_POSITION] = m_src.GetPointer(); VertexLoaderManager::cached_arraybases[CPArray::Position] = m_src.GetPointer();
g_main_cp_state.array_strides[ARRAY_POSITION] = sizeof(float); // ;) g_main_cp_state.array_strides[CPArray::Position] = sizeof(float); // ;)
Input(1.f); Input(1.f);
Input(2.f); Input(2.f);
Input(3.f); Input(3.f);
@ -357,8 +357,8 @@ TEST_F(VertexLoaderTest, LargeFloatVertexSpeed)
for (int i = 0; i < NUM_VERTEX_COMPONENT_ARRAYS; i++) for (int i = 0; i < NUM_VERTEX_COMPONENT_ARRAYS; i++)
{ {
VertexLoaderManager::cached_arraybases[i] = m_src.GetPointer(); VertexLoaderManager::cached_arraybases[static_cast<CPArray>(i)] = m_src.GetPointer();
g_main_cp_state.array_strides[i] = 129; g_main_cp_state.array_strides[static_cast<CPArray>(i)] = 129;
} }
// This test is only done 100x in a row since it's ~20x slower using the // This test is only done 100x in a row since it's ~20x slower using the