mirror of
https://github.com/par274/sharpemu.git
synced 2026-07-31 23:19:44 +08:00
fix(agc): implement sceAgcDcbSetUcRegisterDirect (#558)
Emit the 3-dword SET_UCONFIG_REG packet from the packed {offset,value}
in RSI. Unresolved calls left GPU config registers unset during
RenderThread/Main bring-up.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1431,6 +1431,26 @@ public static partial class AgcExports
|
|||||||
public static int DcbSetUcRegistersIndirect(CpuContext ctx) =>
|
public static int DcbSetUcRegistersIndirect(CpuContext ctx) =>
|
||||||
DcbSetRegistersIndirect(ctx, RUcRegsIndirect, "uc");
|
DcbSetRegistersIndirect(ctx, RUcRegsIndirect, "uc");
|
||||||
|
|
||||||
|
[SysAbiExport(
|
||||||
|
Nid = "w4-d0n60hdo",
|
||||||
|
ExportName = "sceAgcDcbSetUcRegisterDirect",
|
||||||
|
Target = Generation.Gen5,
|
||||||
|
LibraryName = "libSceAgc")]
|
||||||
|
public static int DcbSetUcRegisterDirect(CpuContext ctx) =>
|
||||||
|
DcbSetRegisterDirect(ctx, ItSetUconfigReg, "uc");
|
||||||
|
|
||||||
|
[SysAbiExport(
|
||||||
|
Nid = "aP1Ki9G3++4",
|
||||||
|
ExportName = "sceAgcDcbSetUcRegisterDirectGetSize",
|
||||||
|
Target = Generation.Gen5,
|
||||||
|
LibraryName = "libSceAgc")]
|
||||||
|
public static int DcbSetUcRegisterDirectGetSize(CpuContext ctx)
|
||||||
|
{
|
||||||
|
// SET_UCONFIG_REG header + offset + value.
|
||||||
|
ctx[CpuRegister.Rax] = 3u * sizeof(uint);
|
||||||
|
return (int)ctx[CpuRegister.Rax];
|
||||||
|
}
|
||||||
|
|
||||||
[SysAbiExport(
|
[SysAbiExport(
|
||||||
Nid = "GIIW2J37e70",
|
Nid = "GIIW2J37e70",
|
||||||
ExportName = "sceAgcDcbSetIndexSize",
|
ExportName = "sceAgcDcbSetIndexSize",
|
||||||
@@ -10814,6 +10834,33 @@ public static partial class AgcExports
|
|||||||
return ReturnPointer(ctx, commandAddress);
|
return ReturnPointer(ctx, commandAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static int DcbSetRegisterDirect(CpuContext ctx, uint op, string registerSpace)
|
||||||
|
{
|
||||||
|
var commandBufferAddress = ctx[CpuRegister.Rdi];
|
||||||
|
// Uc/Cx/Sh register is passed by value as {u32 offset, u32 value} in RSI.
|
||||||
|
var packedRegister = ctx[CpuRegister.Rsi];
|
||||||
|
var registerOffset = (uint)(packedRegister & 0xFFFF_FFFFUL);
|
||||||
|
var registerValue = (uint)(packedRegister >> 32);
|
||||||
|
if (commandBufferAddress == 0)
|
||||||
|
{
|
||||||
|
return ReturnPointer(ctx, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint packetDwords = 3;
|
||||||
|
if (!TryAllocateCommandDwords(ctx, commandBufferAddress, packetDwords, out var commandAddress) ||
|
||||||
|
!TryWriteUInt32(ctx, commandAddress, Pm4(packetDwords, op, 0)) ||
|
||||||
|
!TryWriteUInt32(ctx, commandAddress + 4, registerOffset & 0xFFFFu) ||
|
||||||
|
!TryWriteUInt32(ctx, commandAddress + 8, registerValue))
|
||||||
|
{
|
||||||
|
return ReturnPointer(ctx, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TraceAgc(
|
||||||
|
$"agc.dcb_set_{registerSpace}_direct buf=0x{commandBufferAddress:X16} " +
|
||||||
|
$"cmd=0x{commandAddress:X16} offset=0x{registerOffset:X4} value=0x{registerValue:X8}");
|
||||||
|
return ReturnPointer(ctx, commandAddress);
|
||||||
|
}
|
||||||
|
|
||||||
private static bool TryAllocateCommandDwords(CpuContext ctx, ulong commandBufferAddress, uint sizeDwords, out ulong commandAddress)
|
private static bool TryAllocateCommandDwords(CpuContext ctx, ulong commandBufferAddress, uint sizeDwords, out ulong commandAddress)
|
||||||
{
|
{
|
||||||
commandAddress = 0;
|
commandAddress = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user