diff options
Diffstat (limited to 'Source/Core/VideoCommon/XFStructs.cpp')
| -rw-r--r-- | Source/Core/VideoCommon/XFStructs.cpp | 148 |
1 files changed, 56 insertions, 92 deletions
diff --git a/Source/Core/VideoCommon/XFStructs.cpp b/Source/Core/VideoCommon/XFStructs.cpp index ebf9e8efab..665e2ac22d 100644 --- a/Source/Core/VideoCommon/XFStructs.cpp +++ b/Source/Core/VideoCommon/XFStructs.cpp @@ -12,7 +12,6 @@ #include "Core/HW/Memmap.h" #include "VideoCommon/CPMemory.h" -#include "VideoCommon/DataReader.h" #include "VideoCommon/Fifo.h" #include "VideoCommon/GeometryShaderManager.h" #include "VideoCommon/PixelShaderManager.h" @@ -26,16 +25,10 @@ static void XFMemWritten(u32 transferSize, u32 baseAddress) VertexShaderManager::InvalidateXFRange(baseAddress, baseAddress + transferSize); } -static void XFRegWritten(int transferSize, u32 baseAddress, DataReader src) +static void XFRegWritten(u32 address, u32 value) { - u32 address = baseAddress; - u32 dataIndex = 0; - - while (transferSize > 0 && address < XFMEM_REGISTERS_END) + if (address >= XFMEM_REGISTERS_START && address < XFMEM_REGISTERS_END) { - u32 newValue = src.Peek<u32>(dataIndex * sizeof(u32)); - u32 nextAddress = address + 1; - switch (address) { case XFMEM_ERROR: @@ -44,12 +37,12 @@ static void XFRegWritten(int transferSize, u32 baseAddress, DataReader src) case XFMEM_STATE1: // internal state 1 case XFMEM_CLOCK: case XFMEM_SETGPMETRIC: - nextAddress = 0x1007; + // Not implemented break; case XFMEM_CLIPDISABLE: { - ClipDisable setting{.hex = newValue}; + ClipDisable setting{.hex = value}; if (setting.disable_clipping_detection) DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::SETS_XF_CLIPDISABLE_BIT_0); if (setting.disable_trivial_rejection) @@ -63,7 +56,7 @@ static void XFRegWritten(int transferSize, u32 baseAddress, DataReader src) break; case XFMEM_SETNUMCHAN: - if (xfmem.numChan.numColorChans != (newValue & 3)) + if (xfmem.numChan.numColorChans != (value & 3)) g_vertex_manager->Flush(); VertexShaderManager::SetLightingConfigChanged(); break; @@ -72,7 +65,7 @@ static void XFRegWritten(int transferSize, u32 baseAddress, DataReader src) case XFMEM_SETCHAN1_AMBCOLOR: { u8 chan = address - XFMEM_SETCHAN0_AMBCOLOR; - if (xfmem.ambColor[chan] != newValue) + if (xfmem.ambColor[chan] != value) { g_vertex_manager->Flush(); VertexShaderManager::SetMaterialColorChanged(chan); @@ -84,7 +77,7 @@ static void XFRegWritten(int transferSize, u32 baseAddress, DataReader src) case XFMEM_SETCHAN1_MATCOLOR: { u8 chan = address - XFMEM_SETCHAN0_MATCOLOR; - if (xfmem.matColor[chan] != newValue) + if (xfmem.matColor[chan] != value) { g_vertex_manager->Flush(); VertexShaderManager::SetMaterialColorChanged(chan + 2); @@ -96,22 +89,22 @@ static void XFRegWritten(int transferSize, u32 baseAddress, DataReader src) case XFMEM_SETCHAN1_COLOR: case XFMEM_SETCHAN0_ALPHA: // Channel Alpha case XFMEM_SETCHAN1_ALPHA: - if (((u32*)&xfmem)[address] != (newValue & 0x7fff)) + if (((u32*)&xfmem)[address] != (value & 0x7fff)) g_vertex_manager->Flush(); VertexShaderManager::SetLightingConfigChanged(); break; case XFMEM_DUALTEX: - if (xfmem.dualTexTrans.enabled != bool(newValue & 1)) + if (xfmem.dualTexTrans.enabled != bool(value & 1)) g_vertex_manager->Flush(); VertexShaderManager::SetTexMatrixInfoChanged(-1); break; case XFMEM_SETMATRIXINDA: - VertexShaderManager::SetTexMatrixChangedA(newValue); + VertexShaderManager::SetTexMatrixChangedA(value); break; case XFMEM_SETMATRIXINDB: - VertexShaderManager::SetTexMatrixChangedB(newValue); + VertexShaderManager::SetTexMatrixChangedB(value); break; case XFMEM_SETVIEWPORT: @@ -124,8 +117,6 @@ static void XFRegWritten(int transferSize, u32 baseAddress, DataReader src) VertexShaderManager::SetViewportChanged(); PixelShaderManager::SetViewportChanged(); GeometryShaderManager::SetViewportChanged(); - - nextAddress = XFMEM_SETVIEWPORT + 6; break; case XFMEM_SETPROJECTION: @@ -138,12 +129,10 @@ static void XFRegWritten(int transferSize, u32 baseAddress, DataReader src) g_vertex_manager->Flush(); VertexShaderManager::SetProjectionChanged(); GeometryShaderManager::SetProjectionChanged(); - - nextAddress = XFMEM_SETPROJECTION + 7; break; case XFMEM_SETNUMTEXGENS: // GXSetNumTexGens - if (xfmem.numTexGen.numTexGens != (newValue & 15)) + if (xfmem.numTexGen.numTexGens != (value & 15)) g_vertex_manager->Flush(); break; @@ -157,8 +146,6 @@ static void XFRegWritten(int transferSize, u32 baseAddress, DataReader src) case XFMEM_SETTEXMTXINFO + 7: g_vertex_manager->Flush(); VertexShaderManager::SetTexMatrixInfoChanged(address - XFMEM_SETTEXMTXINFO); - - nextAddress = XFMEM_SETTEXMTXINFO + 8; break; case XFMEM_SETPOSTMTXINFO: @@ -171,8 +158,6 @@ static void XFRegWritten(int transferSize, u32 baseAddress, DataReader src) case XFMEM_SETPOSTMTXINFO + 7: g_vertex_manager->Flush(); VertexShaderManager::SetTexMatrixInfoChanged(address - XFMEM_SETPOSTMTXINFO); - - nextAddress = XFMEM_SETPOSTMTXINFO + 8; break; // -------------- @@ -189,7 +174,7 @@ static void XFRegWritten(int transferSize, u32 baseAddress, DataReader src) case 0x104e: case 0x104f: DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::USES_UNKNOWN_XF_COMMAND); - DEBUG_LOG_FMT(VIDEO, "Possible Normal Mtx XF reg?: {:x}={:x}", address, newValue); + DEBUG_LOG_FMT(VIDEO, "Possible Normal Mtx XF reg?: {:x}={:x}", address, value); break; case 0x1013: @@ -200,83 +185,69 @@ static void XFRegWritten(int transferSize, u32 baseAddress, DataReader src) default: DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::USES_UNKNOWN_XF_COMMAND); - WARN_LOG_FMT(VIDEO, "Unknown XF Reg: {:x}={:x}", address, newValue); + WARN_LOG_FMT(VIDEO, "Unknown XF Reg: {:x}={:x}", address, value); break; } - - int transferred = nextAddress - address; - address = nextAddress; - - transferSize -= transferred; - dataIndex += transferred; } } -void LoadXFReg(u32 transferSize, u32 baseAddress, DataReader src) +void LoadXFReg(u16 base_address, u8 transfer_size, const u8* data) { - // do not allow writes past registers - if (baseAddress + transferSize > XFMEM_REGISTERS_END) + if (base_address > XFMEM_REGISTERS_END) { - WARN_LOG_FMT(VIDEO, "XF load exceeds address space: {:x} {} bytes", baseAddress, transferSize); - DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::USES_UNKNOWN_XF_COMMAND); + WARN_LOG_FMT(VIDEO, "XF load base address past end of address space: {:x} {} bytes", + base_address, transfer_size); + return; + } - if (baseAddress >= XFMEM_REGISTERS_END) - transferSize = 0; - else - transferSize = XFMEM_REGISTERS_END - baseAddress; + u32 end_address = base_address + transfer_size; // exclusive + + // do not allow writes past registers + if (end_address > XFMEM_REGISTERS_END) + { + WARN_LOG_FMT(VIDEO, "XF load ends past end of address space: {:x} {} bytes", base_address, + transfer_size); + end_address = XFMEM_REGISTERS_END; } // write to XF mem - if (baseAddress < XFMEM_REGISTERS_START && transferSize > 0) + if (base_address < XFMEM_REGISTERS_START) { - u32 end = baseAddress + transferSize; - - u32 xfMemBase = baseAddress; - u32 xfMemTransferSize = transferSize; - - if (end >= XFMEM_REGISTERS_START) - { - xfMemTransferSize = XFMEM_REGISTERS_START - baseAddress; + const u32 xf_mem_base = base_address; + u32 xf_mem_transfer_size = transfer_size; - baseAddress = XFMEM_REGISTERS_START; - transferSize = end - XFMEM_REGISTERS_START; - } - else + if (end_address > XFMEM_REGISTERS_START) { - transferSize = 0; + xf_mem_transfer_size = XFMEM_REGISTERS_START - base_address; + base_address = XFMEM_REGISTERS_START; } - XFMemWritten(xfMemTransferSize, xfMemBase); - for (u32 i = 0; i < xfMemTransferSize; i++) + XFMemWritten(xf_mem_transfer_size, xf_mem_base); + for (u32 i = 0; i < xf_mem_transfer_size; i++) { - ((u32*)&xfmem)[xfMemBase + i] = src.Read<u32>(); + ((u32*)&xfmem)[xf_mem_base + i] = Common::swap32(data); + data += 4; } } // write to XF regs - if (transferSize > 0) + if (base_address >= XFMEM_REGISTERS_START) { - XFRegWritten(transferSize, baseAddress, src); - for (u32 i = 0; i < transferSize; i++) + for (u32 address = base_address; address < end_address; address++) { - ((u32*)&xfmem)[baseAddress + i] = src.Read<u32>(); - } - } -} + const u32 value = Common::swap32(data); -constexpr std::tuple<u32, u32, u32> ExtractIndexedXF(u32 val) -{ - const u32 index = val >> 16; - const u32 address = val & 0xFFF; // check mask - const u32 size = ((val >> 12) & 0xF) + 1; + XFRegWritten(address, value); + ((u32*)&xfmem)[address] = value; - return {index, address, size}; + data += 4; + } + } } // TODO - verify that it is correct. Seems to work, though. -void LoadIndexedXF(u32 val, int refarray) +void LoadIndexedXF(CPArray array, u32 index, u16 address, u8 size) { - const auto [index, address, size] = ExtractIndexedXF(val); // load stuff from array to address in xf mem u32* currData = (u32*)(&xfmem) + address; @@ -287,8 +258,8 @@ void LoadIndexedXF(u32 val, int refarray) } else { - newData = (u32*)Memory::GetPointer(g_main_cp_state.array_bases[refarray] + - g_main_cp_state.array_strides[refarray] * index); + newData = (u32*)Memory::GetPointer(g_main_cp_state.array_bases[array] + + g_main_cp_state.array_strides[array] * index); } bool changed = false; for (u32 i = 0; i < size; ++i) @@ -307,12 +278,10 @@ void LoadIndexedXF(u32 val, int refarray) } } -void PreprocessIndexedXF(u32 val, int refarray) +void PreprocessIndexedXF(CPArray array, u32 index, u16 address, u8 size) { - 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); + const u8* new_data = Memory::GetPointer(g_preprocess_cp_state.array_bases[array] + + g_preprocess_cp_state.array_strides[array] * index); const size_t buf_size = size * sizeof(u32); Fifo::PushFifoAuxBuffer(new_data, buf_size); @@ -581,13 +550,9 @@ std::string GetXFMemDescription(u32 address, u32 value) } } -std::pair<std::string, std::string> GetXFTransferInfo(const u8* data) +std::pair<std::string, std::string> GetXFTransferInfo(u16 base_address, u8 transfer_size, + 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"); @@ -655,10 +620,9 @@ 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) +std::pair<std::string, std::string> GetXFIndexedLoadInfo(CPArray array, u32 index, u16 address, + u8 size) { - 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; |
