Skip to content

Commit

Permalink
Add descriptions for GX_LOAD_INDX_A/B/C/D
Browse files Browse the repository at this point in the history
  • Loading branch information
Pokechu22 committed Mar 7, 2021
1 parent 8f584b0 commit 2a16eaa
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 15 deletions.
72 changes: 64 additions & 8 deletions Source/Core/DolphinQt/FIFO/FIFOAnalyzer.cpp
Expand Up @@ -290,21 +290,37 @@ void FIFOAnalyzer::UpdateDetails()
break;

case OpcodeDecoder::GX_LOAD_INDX_A:
new_label = QStringLiteral("LOAD INDX A");
{
const auto [desc, written] =
GetXFIndexedLoadInfo(ARRAY_XF_A, Common::swap32(&object[object_offset]));
object_offset += 4;
break;
new_label = QStringLiteral("LOAD INDX A %1").arg(QString::fromStdString(desc));
}
break;
case OpcodeDecoder::GX_LOAD_INDX_B:
new_label = QStringLiteral("LOAD INDX B");
{
const auto [desc, written] =
GetXFIndexedLoadInfo(ARRAY_XF_B, Common::swap32(&object[object_offset]));
object_offset += 4;
break;
new_label = QStringLiteral("LOAD INDX B %1").arg(QString::fromStdString(desc));
}
break;
case OpcodeDecoder::GX_LOAD_INDX_C:
new_label = QStringLiteral("LOAD INDX C");
{
const auto [desc, written] =
GetXFIndexedLoadInfo(ARRAY_XF_C, Common::swap32(&object[object_offset]));
object_offset += 4;
break;
new_label = QStringLiteral("LOAD INDX C %1").arg(QString::fromStdString(desc));
}
break;
case OpcodeDecoder::GX_LOAD_INDX_D:
new_label = QStringLiteral("LOAD INDX D");
{
const auto [desc, written] =
GetXFIndexedLoadInfo(ARRAY_XF_D, Common::swap32(&object[object_offset]));
object_offset += 4;
break;
new_label = QStringLiteral("LOAD INDX D %1").arg(QString::fromStdString(desc));
}
break;

case OpcodeDecoder::GX_CMD_CALL_DL:
// The recorder should have expanded display lists into the fifo stream and skipped the
Expand Down Expand Up @@ -611,6 +627,46 @@ void FIFOAnalyzer::UpdateDescription()
else
text += QString::fromStdString(desc);
}
else if (*cmddata == OpcodeDecoder::GX_LOAD_INDX_A)
{
const auto [desc, written] = GetXFIndexedLoadInfo(ARRAY_XF_A, Common::swap32(cmddata + 1));

text = QString::fromStdString(desc);
text += QLatin1Char{'\n'};
text += tr("Usually used for position matrices");
text += QLatin1Char{'\n'};
text += QString::fromStdString(written);
}
else if (*cmddata == OpcodeDecoder::GX_LOAD_INDX_B)
{
const auto [desc, written] = GetXFIndexedLoadInfo(ARRAY_XF_B, Common::swap32(cmddata + 1));

text = QString::fromStdString(desc);
text += QLatin1Char{'\n'};
text += tr("Usually used for normal matrices");
text += QLatin1Char{'\n'};
text += QString::fromStdString(written);
}
else if (*cmddata == OpcodeDecoder::GX_LOAD_INDX_C)
{
const auto [desc, written] = GetXFIndexedLoadInfo(ARRAY_XF_C, Common::swap32(cmddata + 1));

text = QString::fromStdString(desc);
text += QLatin1Char{'\n'};
text += tr("Usually used for tex coord matrices");
text += QLatin1Char{'\n'};
text += QString::fromStdString(written);
}
else if (*cmddata == OpcodeDecoder::GX_LOAD_INDX_D)
{
const auto [desc, written] = GetXFIndexedLoadInfo(ARRAY_XF_D, Common::swap32(cmddata + 1));

text = QString::fromStdString(desc);
text += QLatin1Char{'\n'};
text += tr("Usually used for light objects");
text += QLatin1Char{'\n'};
text += QString::fromStdString(written);
}
else if ((*cmddata & 0xC0) == 0x80)
{
const auto name = GetPrimitiveName(*cmddata);
Expand Down
4 changes: 4 additions & 0 deletions Source/Core/VideoCommon/CPMemory.h
Expand Up @@ -54,6 +54,10 @@ enum
ARRAY_COLOR = 2,
ARRAY_COLOR2 = 3,
ARRAY_TEXCOORD0 = 4,
ARRAY_XF_A = 12, // Usually used for position matrices
ARRAY_XF_B = 13, // Usually used for normal matrices
ARRAY_XF_C = 14, // Usually used for tex coord matrices
ARRAY_XF_D = 15, // Usually used for light objects
};

// Vertex components
Expand Down
35 changes: 28 additions & 7 deletions Source/Core/VideoCommon/XFStructs.cpp
Expand Up @@ -256,12 +256,19 @@ void LoadXFReg(u32 transferSize, u32 baseAddress, DataReader src)
}
}

constexpr std::tuple<u32, u32, u32> ExtractIndexedXF(u32 val)
{
u32 index = val >> 16;
u32 address = val & 0xFFF; // check mask
u32 size = ((val >> 12) & 0xF) + 1;

return {index, address, size};
}

// TODO - verify that it is correct. Seems to work, though.
void LoadIndexedXF(u32 val, int refarray)
{
int index = val >> 16;
int address = val & 0xFFF; // check mask
int size = ((val >> 12) & 0xF) + 1;
const auto [index, address, size] = ExtractIndexedXF(val);
// load stuff from array to address in xf mem

u32* currData = (u32*)(&xfmem) + address;
Expand All @@ -276,7 +283,7 @@ void LoadIndexedXF(u32 val, int refarray)
g_main_cp_state.array_strides[refarray] * index);
}
bool changed = false;
for (int i = 0; i < size; ++i)
for (u32 i = 0; i < size; ++i)
{
if (currData[i] != Common::swap32(newData[i]))
{
Expand All @@ -287,15 +294,14 @@ void LoadIndexedXF(u32 val, int refarray)
}
if (changed)
{
for (int i = 0; i < size; ++i)
for (u32 i = 0; i < size; ++i)
currData[i] = Common::swap32(newData[i]);
}
}

void PreprocessIndexedXF(u32 val, int refarray)
{
const u32 index = val >> 16;
const u32 size = ((val >> 12) & 0xF) + 1;
const auto [index, address, size] = ExtractIndexedXF(val);

const u8* new_data = Memory::GetPointer(g_preprocess_cp_state.array_bases[refarray] +
g_preprocess_cp_state.array_strides[refarray] * index);
Expand Down Expand Up @@ -640,3 +646,18 @@ std::pair<std::string, std::string> GetXFTransferInfo(const u8* data)

return std::make_pair(fmt::to_string(name), fmt::to_string(desc));
}

std::pair<std::string, std::string> GetXFIndexedLoadInfo(u8 array, u32 value)
{
const auto [index, address, size] = ExtractIndexedXF(value);

const auto desc = fmt::format("Load {} bytes to XF address {:03x} from CP array {} row {}", size,
address, array, index);
fmt::memory_buffer written;
for (u32 i = 0; i < size; i++)
{
fmt::format_to(written, "{}\n", GetXFMemName(address + i));
}

return std::make_pair(desc, fmt::to_string(written));
}
1 change: 1 addition & 0 deletions Source/Core/VideoCommon/XFStructs.h
Expand Up @@ -13,3 +13,4 @@ std::pair<std::string, std::string> GetXFRegInfo(u32 address, u32 value);
std::string GetXFMemName(u32 address);
std::string GetXFMemDescription(u32 address, u32 value);
std::pair<std::string, std::string> GetXFTransferInfo(const u8* data);
std::pair<std::string, std::string> GetXFIndexedLoadInfo(u8 array, u32 value);

0 comments on commit 2a16eaa

Please sign in to comment.