mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-06-18 18:58:55 +02:00
Add names and descriptions for XF registers to the FIFO analyzer
This commit is contained in:
@ -2,6 +2,9 @@
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "VideoCommon/XFStructs.h"
|
||||
|
||||
#include "Common/BitUtils.h"
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/Logging/Log.h"
|
||||
#include "Common/Swap.h"
|
||||
@ -300,3 +303,242 @@ void PreprocessIndexedXF(u32 val, int refarray)
|
||||
const size_t buf_size = size * sizeof(u32);
|
||||
Fifo::PushFifoAuxBuffer(new_data, buf_size);
|
||||
}
|
||||
|
||||
std::pair<std::string, std::string> GetXFRegInfo(u32 address, u32 value)
|
||||
{
|
||||
// Macro to set the register name and make sure it was written correctly via compile time assertion
|
||||
#define RegName(reg) ((void)(reg), #reg)
|
||||
#define DescriptionlessReg(reg) std::make_pair(RegName(reg), "");
|
||||
|
||||
switch (address)
|
||||
{
|
||||
case XFMEM_ERROR:
|
||||
return DescriptionlessReg(XFMEM_ERROR);
|
||||
case XFMEM_DIAG:
|
||||
return DescriptionlessReg(XFMEM_DIAG);
|
||||
case XFMEM_STATE0: // internal state 0
|
||||
return std::make_pair(RegName(XFMEM_STATE0), "internal state 0");
|
||||
case XFMEM_STATE1: // internal state 1
|
||||
return std::make_pair(RegName(XFMEM_STATE1), "internal state 1");
|
||||
case XFMEM_CLOCK:
|
||||
return DescriptionlessReg(XFMEM_CLOCK);
|
||||
case XFMEM_SETGPMETRIC:
|
||||
return DescriptionlessReg(XFMEM_SETGPMETRIC);
|
||||
|
||||
case XFMEM_CLIPDISABLE:
|
||||
return std::make_pair(RegName(XFMEM_CLIPDISABLE), fmt::to_string(ClipDisable{.hex = value}));
|
||||
|
||||
case XFMEM_VTXSPECS:
|
||||
return std::make_pair(RegName(XFMEM_VTXSPECS), fmt::to_string(INVTXSPEC{.hex = value}));
|
||||
|
||||
case XFMEM_SETNUMCHAN:
|
||||
return std::make_pair(RegName(XFMEM_SETNUMCHAN),
|
||||
fmt::format("Number of color channels: {}", value & 3));
|
||||
break;
|
||||
|
||||
case XFMEM_SETCHAN0_AMBCOLOR:
|
||||
return std::make_pair(RegName(XFMEM_SETCHAN0_AMBCOLOR),
|
||||
fmt::format("Channel 0 Ambient Color: {:06x}", value));
|
||||
case XFMEM_SETCHAN1_AMBCOLOR:
|
||||
return std::make_pair(RegName(XFMEM_SETCHAN1_AMBCOLOR),
|
||||
fmt::format("Channel 1 Ambient Color: {:06x}", value));
|
||||
|
||||
case XFMEM_SETCHAN0_MATCOLOR:
|
||||
return std::make_pair(RegName(XFMEM_SETCHAN0_MATCOLOR),
|
||||
fmt::format("Channel 0 Material Color: {:06x}", value));
|
||||
case XFMEM_SETCHAN1_MATCOLOR:
|
||||
return std::make_pair(RegName(XFMEM_SETCHAN1_MATCOLOR),
|
||||
fmt::format("Channel 1 Material Color: {:06x}", value));
|
||||
|
||||
case XFMEM_SETCHAN0_COLOR: // Channel Color
|
||||
return std::make_pair(RegName(XFMEM_SETCHAN0_COLOR),
|
||||
fmt::format("Channel 0 Color config:\n{}", LitChannel{.hex = value}));
|
||||
case XFMEM_SETCHAN1_COLOR:
|
||||
return std::make_pair(RegName(XFMEM_SETCHAN1_COLOR),
|
||||
fmt::format("Channel 1 Color config:\n{}", LitChannel{.hex = value}));
|
||||
case XFMEM_SETCHAN0_ALPHA: // Channel Alpha
|
||||
return std::make_pair(RegName(XFMEM_SETCHAN0_ALPHA),
|
||||
fmt::format("Channel 0 Alpha config:\n{}", LitChannel{.hex = value}));
|
||||
case XFMEM_SETCHAN1_ALPHA:
|
||||
return std::make_pair(RegName(XFMEM_SETCHAN1_ALPHA),
|
||||
fmt::format("Channel 1 Alpha config:\n{}", LitChannel{.hex = value}));
|
||||
|
||||
case XFMEM_DUALTEX:
|
||||
return std::make_pair(RegName(XFMEM_DUALTEX),
|
||||
fmt::format("Dual Tex Trans {}", (value & 1) ? "enabled" : "disabled"));
|
||||
|
||||
case XFMEM_SETMATRIXINDA:
|
||||
return std::make_pair(RegName(XFMEM_SETMATRIXINDA),
|
||||
fmt::format("Matrix index A:\n{}", TMatrixIndexA{.Hex = value}));
|
||||
case XFMEM_SETMATRIXINDB:
|
||||
return std::make_pair(RegName(XFMEM_SETMATRIXINDB),
|
||||
fmt::format("Matrix index B:\n{}", TMatrixIndexB{.Hex = value}));
|
||||
|
||||
case XFMEM_SETVIEWPORT:
|
||||
return std::make_pair(RegName(XFMEM_SETVIEWPORT + 0),
|
||||
fmt::format("Viewport width: {}", Common::BitCast<float>(value)));
|
||||
case XFMEM_SETVIEWPORT + 1:
|
||||
return std::make_pair(RegName(XFMEM_SETVIEWPORT + 1),
|
||||
fmt::format("Viewport height: {}", Common::BitCast<float>(value)));
|
||||
case XFMEM_SETVIEWPORT + 2:
|
||||
return std::make_pair(RegName(XFMEM_SETVIEWPORT + 2),
|
||||
fmt::format("Viewport z range: {}", Common::BitCast<float>(value)));
|
||||
case XFMEM_SETVIEWPORT + 3:
|
||||
return std::make_pair(RegName(XFMEM_SETVIEWPORT + 3),
|
||||
fmt::format("Viewport x origin: {}", Common::BitCast<float>(value)));
|
||||
case XFMEM_SETVIEWPORT + 4:
|
||||
return std::make_pair(RegName(XFMEM_SETVIEWPORT + 4),
|
||||
fmt::format("Viewport y origin: {}", Common::BitCast<float>(value)));
|
||||
case XFMEM_SETVIEWPORT + 5:
|
||||
return std::make_pair(RegName(XFMEM_SETVIEWPORT + 5),
|
||||
fmt::format("Viewport far z: {}", Common::BitCast<float>(value)));
|
||||
break;
|
||||
|
||||
case XFMEM_SETPROJECTION:
|
||||
return std::make_pair(RegName(XFMEM_SETPROJECTION + 0),
|
||||
fmt::format("Projection[0]: {}", Common::BitCast<float>(value)));
|
||||
case XFMEM_SETPROJECTION + 1:
|
||||
return std::make_pair(RegName(XFMEM_SETPROJECTION + 1),
|
||||
fmt::format("Projection[1]: {}", Common::BitCast<float>(value)));
|
||||
case XFMEM_SETPROJECTION + 2:
|
||||
return std::make_pair(RegName(XFMEM_SETPROJECTION + 2),
|
||||
fmt::format("Projection[2]: {}", Common::BitCast<float>(value)));
|
||||
case XFMEM_SETPROJECTION + 3:
|
||||
return std::make_pair(RegName(XFMEM_SETPROJECTION + 3),
|
||||
fmt::format("Projection[3]: {}", Common::BitCast<float>(value)));
|
||||
case XFMEM_SETPROJECTION + 4:
|
||||
return std::make_pair(RegName(XFMEM_SETPROJECTION + 4),
|
||||
fmt::format("Projection[4]: {}", Common::BitCast<float>(value)));
|
||||
case XFMEM_SETPROJECTION + 5:
|
||||
return std::make_pair(RegName(XFMEM_SETPROJECTION + 5),
|
||||
fmt::format("Projection[5]: {}", Common::BitCast<float>(value)));
|
||||
case XFMEM_SETPROJECTION + 6:
|
||||
return std::make_pair(RegName(XFMEM_SETPROJECTION + 6),
|
||||
fmt::to_string(static_cast<ProjectionType>(value)));
|
||||
|
||||
case XFMEM_SETNUMTEXGENS:
|
||||
return std::make_pair(RegName(XFMEM_SETNUMTEXGENS),
|
||||
fmt::format("Number of tex gens: {}", value & 15));
|
||||
|
||||
case XFMEM_SETTEXMTXINFO:
|
||||
case XFMEM_SETTEXMTXINFO + 1:
|
||||
case XFMEM_SETTEXMTXINFO + 2:
|
||||
case XFMEM_SETTEXMTXINFO + 3:
|
||||
case XFMEM_SETTEXMTXINFO + 4:
|
||||
case XFMEM_SETTEXMTXINFO + 5:
|
||||
case XFMEM_SETTEXMTXINFO + 6:
|
||||
case XFMEM_SETTEXMTXINFO + 7:
|
||||
return std::make_pair(
|
||||
fmt::format("XFMEM_SETTEXMTXINFO Matrix {}", address - XFMEM_SETTEXMTXINFO),
|
||||
fmt::to_string(TexMtxInfo{.hex = value}));
|
||||
|
||||
case XFMEM_SETPOSTMTXINFO:
|
||||
case XFMEM_SETPOSTMTXINFO + 1:
|
||||
case XFMEM_SETPOSTMTXINFO + 2:
|
||||
case XFMEM_SETPOSTMTXINFO + 3:
|
||||
case XFMEM_SETPOSTMTXINFO + 4:
|
||||
case XFMEM_SETPOSTMTXINFO + 5:
|
||||
case XFMEM_SETPOSTMTXINFO + 6:
|
||||
case XFMEM_SETPOSTMTXINFO + 7:
|
||||
return std::make_pair(
|
||||
fmt::format("XFMEM_SETPOSTMTXINFO Matrix {}", address - XFMEM_SETPOSTMTXINFO),
|
||||
fmt::to_string(PostMtxInfo{.hex = value}));
|
||||
|
||||
// --------------
|
||||
// Unknown Regs
|
||||
// --------------
|
||||
|
||||
// Maybe these are for Normals?
|
||||
case 0x1048: // xfmem.texcoords[0].nrmmtxinfo.hex = data; break; ??
|
||||
case 0x1049:
|
||||
case 0x104a:
|
||||
case 0x104b:
|
||||
case 0x104c:
|
||||
case 0x104d:
|
||||
case 0x104e:
|
||||
case 0x104f:
|
||||
return std::make_pair(
|
||||
fmt::format("Possible Normal Mtx XF reg?: {:x}={:x}", address, value),
|
||||
"Maybe these are for Normals? xfmem.texcoords[0].nrmmtxinfo.hex = data; break; ??");
|
||||
break;
|
||||
|
||||
case 0x1013:
|
||||
case 0x1014:
|
||||
case 0x1015:
|
||||
case 0x1016:
|
||||
case 0x1017:
|
||||
|
||||
default:
|
||||
return std::make_pair(fmt::format("Unknown XF Reg: {:x}={:x}", address, value), "");
|
||||
}
|
||||
#undef RegName
|
||||
#undef DescriptionlessReg
|
||||
}
|
||||
|
||||
std::pair<std::string, std::string> GetXFTransferInfo(const u8* data)
|
||||
{
|
||||
const u32 cmd = Common::swap32(data);
|
||||
data += 4;
|
||||
u32 base_address = cmd & 0xFFFF;
|
||||
const u32 transfer_size = ((cmd >> 16) & 15) + 1;
|
||||
|
||||
if (base_address > XFMEM_REGISTERS_END)
|
||||
{
|
||||
return std::make_pair("Invalid XF Transfer", "Base address past end of address space");
|
||||
}
|
||||
else if (transfer_size == 1 && base_address >= XFMEM_REGISTERS_START)
|
||||
{
|
||||
// Write directly to a single register
|
||||
const u32 value = Common::swap32(data);
|
||||
return GetXFRegInfo(base_address, value);
|
||||
}
|
||||
|
||||
// More complicated cases
|
||||
fmt::memory_buffer name, desc;
|
||||
u32 end_address = base_address + transfer_size; // exclusive
|
||||
|
||||
// do not allow writes past registers
|
||||
if (end_address > XFMEM_REGISTERS_END)
|
||||
{
|
||||
fmt::format_to(name, "Invalid XF Transfer ");
|
||||
fmt::format_to(desc, "Transfer ends past end of address space\n\n");
|
||||
end_address = XFMEM_REGISTERS_END;
|
||||
}
|
||||
|
||||
// write to XF mem
|
||||
if (base_address < XFMEM_REGISTERS_START)
|
||||
{
|
||||
const u32 xf_mem_base = base_address;
|
||||
u32 xf_mem_transfer_size = transfer_size;
|
||||
|
||||
if (end_address > XFMEM_REGISTERS_START)
|
||||
{
|
||||
xf_mem_transfer_size = XFMEM_REGISTERS_START - base_address;
|
||||
base_address = XFMEM_REGISTERS_START;
|
||||
data += 4 * xf_mem_transfer_size;
|
||||
}
|
||||
|
||||
fmt::format_to(name, "Write {} XF mem words at {:04x}", xf_mem_transfer_size, xf_mem_base);
|
||||
|
||||
if (end_address > XFMEM_REGISTERS_START)
|
||||
fmt::format_to(name, "; ");
|
||||
}
|
||||
|
||||
// write to XF regs
|
||||
if (base_address >= XFMEM_REGISTERS_START)
|
||||
{
|
||||
fmt::format_to(name, "Write {} XF regs at {:04x}", end_address - base_address, base_address);
|
||||
|
||||
for (u32 address = base_address; address < end_address; address++)
|
||||
{
|
||||
const u32 value = Common::swap32(data);
|
||||
|
||||
const auto [regname, regdesc] = GetXFRegInfo(address, value);
|
||||
fmt::format_to(desc, "{}\n{}\n", regname, regdesc);
|
||||
|
||||
data += 4;
|
||||
}
|
||||
}
|
||||
|
||||
return std::make_pair(fmt::to_string(name), fmt::to_string(desc));
|
||||
}
|
||||
|
Reference in New Issue
Block a user