summaryrefslogtreecommitdiff
path: root/Source/Core/VideoCommon/XFStructs.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Core/VideoCommon/XFStructs.cpp')
-rw-r--r--Source/Core/VideoCommon/XFStructs.cpp148
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;