From df77a687e891efdca38223c353da0d06bc666359 Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Sat, 20 Feb 2021 13:17:42 -0800 Subject: [PATCH] Add descriptions for GX_LOAD_INDX_A/B/C/D --- Source/Core/DolphinQt/FIFO/FIFOAnalyzer.cpp | 72 ++++++++++++++++++--- Source/Core/VideoCommon/CPMemory.h | 5 ++ Source/Core/VideoCommon/XFStructs.cpp | 35 ++++++++-- Source/Core/VideoCommon/XFStructs.h | 1 + 4 files changed, 98 insertions(+), 15 deletions(-) diff --git a/Source/Core/DolphinQt/FIFO/FIFOAnalyzer.cpp b/Source/Core/DolphinQt/FIFO/FIFOAnalyzer.cpp index 5511fe0dfe..676288f442 100644 --- a/Source/Core/DolphinQt/FIFO/FIFOAnalyzer.cpp +++ b/Source/Core/DolphinQt/FIFO/FIFOAnalyzer.cpp @@ -271,21 +271,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 @@ -565,6 +581,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 { text = tr("No description available"); diff --git a/Source/Core/VideoCommon/CPMemory.h b/Source/Core/VideoCommon/CPMemory.h index c82521ebb4..488d210129 100644 --- a/Source/Core/VideoCommon/CPMemory.h +++ b/Source/Core/VideoCommon/CPMemory.h @@ -63,6 +63,11 @@ enum ARRAY_TEXCOORD0 = 4, NUM_TEXCOORD_ARRAYS = 8, + 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 + // Number of arrays related to vertex components (position, normal, color, tex coord) // Excludes the 4 arrays used for indexed XF loads NUM_VERTEX_COMPONENT_ARRAYS = 12, diff --git a/Source/Core/VideoCommon/XFStructs.cpp b/Source/Core/VideoCommon/XFStructs.cpp index 9ceaf2edc1..4da229c422 100644 --- a/Source/Core/VideoCommon/XFStructs.cpp +++ b/Source/Core/VideoCommon/XFStructs.cpp @@ -259,12 +259,19 @@ void LoadXFReg(u32 transferSize, u32 baseAddress, DataReader src) } } +constexpr std::tuple ExtractIndexedXF(u32 val) +{ + const u32 index = val >> 16; + const u32 address = val & 0xFFF; // check mask + const 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; @@ -279,7 +286,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])) { @@ -290,15 +297,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); @@ -643,3 +649,18 @@ std::pair GetXFTransferInfo(const u8* data) return std::make_pair(fmt::to_string(name), fmt::to_string(desc)); } + +std::pair 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)); +} diff --git a/Source/Core/VideoCommon/XFStructs.h b/Source/Core/VideoCommon/XFStructs.h index 5aac1f059b..d73f47c722 100644 --- a/Source/Core/VideoCommon/XFStructs.h +++ b/Source/Core/VideoCommon/XFStructs.h @@ -13,3 +13,4 @@ std::pair GetXFRegInfo(u32 address, u32 value); std::string GetXFMemName(u32 address); std::string GetXFMemDescription(u32 address, u32 value); std::pair GetXFTransferInfo(const u8* data); +std::pair GetXFIndexedLoadInfo(u8 array, u32 value);