This commit is contained in:
Pavel 2024-02-27 17:12:57 +03:00
parent 4012e9f836
commit 7f611a45df
7 changed files with 305 additions and 36 deletions

View File

@ -125,6 +125,9 @@ begin
PROC_INIT_HOST_IPC(kern_ipc);
//p_proc.p_cpuid :=CPUID_NEO_MODE;
//p_proc.p_neomode:=1;
dev_dce.dce_interface:=display_soft.TDisplayHandleSoft;
Writeln(Item.FGameInfo.Exec);

View File

@ -99,6 +99,11 @@ begin
Writeln('gc_ioctl(0x',HexStr(cmd,8),')');
case cmd of
$C0108120: //call in neo mode (Tca)
begin
Exit(19);
end;
$C004811F: //sceGnmGetNumTcaUnits
begin
Exit(19);

View File

@ -10,6 +10,37 @@ uses
md_time;
const
//SceVideoOutPixelFormat
SCE_VIDEO_OUT_PIXEL_FORMAT_A8R8G8B8_SRGB = $80000000; // MSB first. Blue is at LSB
SCE_VIDEO_OUT_PIXEL_FORMAT_B8_G8_R8_A8_SRGB = SCE_VIDEO_OUT_PIXEL_FORMAT_A8R8G8B8_SRGB; // alias name in a gnm-friendly order (LSB first)
SCE_VIDEO_OUT_PIXEL_FORMAT_A16R16G16B16_FLOAT = $C1060000; // MSB first. Blue is at LSB
SCE_VIDEO_OUT_PIXEL_FORMAT_B16_G16_R16_A16_FLOAT = SCE_VIDEO_OUT_PIXEL_FORMAT_A16R16G16B16_FLOAT; // alias name in a gnm-friendly order (LSB first)
SCE_VIDEO_OUT_PIXEL_FORMAT_A8B8G8R8_SRGB = $80002200; // MSB first. Red is at LSB
SCE_VIDEO_OUT_PIXEL_FORMAT_R8_G8_B8_A8_SRGB = SCE_VIDEO_OUT_PIXEL_FORMAT_A8B8G8R8_SRGB; // alias name in a gnm-friendly order (LSB first)
SCE_VIDEO_OUT_PIXEL_FORMAT_A2R10G10B10 = $88060000; // MSB first. Blue is at LSB
SCE_VIDEO_OUT_PIXEL_FORMAT_B10_G10_R10_A2 = SCE_VIDEO_OUT_PIXEL_FORMAT_A2R10G10B10; // alias name in a gnm-friendly order (LSB first)
SCE_VIDEO_OUT_PIXEL_FORMAT_A2R10G10B10_SRGB = $88000000; // MSB first. Blue is at LSB
SCE_VIDEO_OUT_PIXEL_FORMAT_B10_G10_R10_A2_SRGB = SCE_VIDEO_OUT_PIXEL_FORMAT_A2R10G10B10_SRGB; // alias name in a gnm-friendly order (LSB first)
SCE_VIDEO_OUT_PIXEL_FORMAT_A2R10G10B10_BT2020_PQ = $88740000; // MSB first. Blue is at LSB
SCE_VIDEO_OUT_PIXEL_FORMAT_B10_G10_R10_A2_BT2020_PQ = SCE_VIDEO_OUT_PIXEL_FORMAT_A2R10G10B10_BT2020_PQ; // alias name in a gnm-friendly order (LSB first)
//SceVideoOutFlipMode
SCE_VIDEO_OUT_FLIP_MODE_VSYNC = 1; // on real video out vsync
SCE_VIDEO_OUT_FLIP_MODE_HSYNC = 2; // ASAP (but not immediate)
SCE_VIDEO_OUT_FLIP_MODE_WINDOW = 3; // similar to vsync but may flip on some windows at the top and the bottom of the display. N/A on Neo mode
SCE_VIDEO_OUT_FLIP_MODE_VSYNC_MULTI = 4; // vsync mode but allows multiple flips per vsync. flipRate is not valid. N/A on Neo mode
SCE_VIDEO_OUT_FLIP_MODE_VSYNC_MULTI_2 = 5; // vsync mode but allows multiple flips per vsync. flipRate is valid
SCE_VIDEO_OUT_FLIP_MODE_WINDOW_2 = 6; // Window mode but the top margin is less accurate than _MODE_WINDOW. The bottom margin must be 0.
//SceVideoOutTilingMode
SCE_VIDEO_OUT_TILING_MODE_TILE = 0; // 32bpp pixel format only if on Neo mode
SCE_VIDEO_OUT_TILING_MODE_LINEAR = 1; // 32bpp pixel format only
EVENTID_FLIP =$0006;
EVENTID_VBLANK =$0007;
EVENTID_SETMODE =$0051;

View File

@ -31,13 +31,8 @@ type
TOnParent=Procedure(node:PQNode) of object;
TQNode=object
next_ :PQNode;
Parent:TOnParent;
u:record
Case Byte of
0:(submit:t_submit_flip;
tsc :QWORD);
1:(attr :t_register_buffer_attr;);
end;
submit:t_submit_flip;
tsc :QWORD;
end;
TSubmitQueue=object
@ -58,9 +53,18 @@ type
FQueue:TSubmitQueue;
FTerminate:Boolean;
flip_rate:Integer;
vblank_count:Integer;
flipPendingNum:Integer;
m_attr:array[0.. 3] of t_attr;
m_bufs:array[0..15] of t_buffer;
m_sbat:array[0.. 3] of t_attr;
dst_cache:Pointer;
Ffps :QWORD;
Ftsc_prev:QWORD;
@ -68,7 +72,7 @@ type
Destructor Destroy; override;
//function GetFlipStatus (status:p_flip_status):Integer; virtual;
//function GetResolutionStatus (status:p_resolution_status):Integer; virtual;
//function SetFlipRate (rate:Integer):Integer; virtual;
function SetFlipRate (rate:Integer):Integer; override;
function RegisterBufferAttribute (attrid:Byte;attr:p_register_buffer_attr):Integer; override;
function SubmitBufferAttribute (attrid:Byte;attr:p_register_buffer_attr):Integer; override;
function UnregisterBufferAttribute(attrid:Byte):Integer; override;
@ -92,7 +96,8 @@ uses
LCLIntf,
}
kern_proc,
kern_thread;
kern_thread,
dev_dce;
Procedure TSubmitQueue.Init;
var
@ -151,9 +156,17 @@ begin
Ftd:=nil;
end;
RTLEventDestroy(FEvent);
FreeMem(dst_cache);
inherited;
end;
function TDisplayHandleSoft.SetFlipRate(rate:Integer):Integer;
begin
flip_rate:=rate;
Result:=0;
end;
function TDisplayHandleSoft.RegisterBufferAttribute(attrid:Byte;attr:p_register_buffer_attr):Integer;
begin
if (m_attr[attrid].init<>0) then Exit(EINVAL);
@ -166,8 +179,10 @@ end;
function TDisplayHandleSoft.SubmitBufferAttribute(attrid:Byte;attr:p_register_buffer_attr):Integer;
begin
m_attr[attrid].init:=1;
m_attr[attrid].attr:=attr^;
if (m_sbat[attrid].init<>0) then Exit(EBUSY);
m_sbat[attrid].attr:=attr^;
m_sbat[attrid].init:=1;
Result:=0;
end;
@ -208,11 +223,123 @@ begin
Result:=0;
end;
procedure SoftFlip(hWindow:THandle;buf:p_buffer;attr:p_attr);
function getTiledElementByteOffset_32(PITCH,x,y:DWORD):QWORD;
var
element_index:DWORD;
pipe,bank:QWORD;
total_offset:QWORD;
begin
//getElementIndex [0..5]
element_index:= ( (x ) and 1) shl 2;
element_index:=element_index or ( (x shr 1) and 1) shl 3;
element_index:=element_index or ( (y ) and 1) shl 4;
element_index:=element_index or ( (x shr 2) and 1) shl 5;
element_index:=element_index or ( (y shr 1) and 1) shl 6;
element_index:=element_index or ( (y shr 2) and 1) shl 7;
//getPipeIndex [6..8]
pipe:= ( ((x shr 3) xor (y shr 3) xor (x shr 4)) and 1) shl 8;
pipe:=pipe or ( ((x shr 4) xor (y shr 4)) and 1) shl 9;
pipe:=pipe or ( ((x shr 5) xor (y shr 5)) and 1) shl 10;
//getBankIndex [9..12]
bank:= ( ((x shr 6) xor (y shr 6)) and 1) shl 11;
bank:=bank or ( ((x shr 7) xor (y shr 5) xor (y shr 6)) and 1) shl 12;
bank:=bank or ( ((x shr 8) xor (y shr 4)) and 1) shl 13;
bank:=bank or ( ((x shr 9) xor (y shr 3)) and 1) shl 14;
total_offset:=((y shr 6)*PITCH + (x shr 7));
Result := element_index or pipe or bank or (total_offset shl 15)
end;
function getTiledElementByteOffset_32_NEO(PITCH,x,y:DWORD):QWORD;
var
element_index:DWORD;
pipe,bank:QWORD;
total_offset:QWORD;
begin
//getElementIndex [0..5]
element_index:= ( (x shr 0) and 1) shl 2;
element_index:=element_index or ( (x shr 1) and 1) shl 3;
element_index:=element_index or ( (y shr 0) and 1) shl 4;
element_index:=element_index or ( (x shr 2) and 1) shl 5;
element_index:=element_index or ( (y shr 1) and 1) shl 6;
element_index:=element_index or ( (y shr 2) and 1) shl 7;
//getPipeIndex [6..9]
pipe:= ( ((x shr 3) xor (y shr 3) xor (x shr 4)) and 1) shl 8;
pipe:=pipe or ( ((x shr 4) xor (y shr 4)) and 1) shl 9;
pipe:=pipe or ( ((x shr 5) xor (y shr 5)) and 1) shl 10;
pipe:=pipe or ( ((x shr 6) xor (y shr 5)) and 1) shl 11;
//getBankIndex [10..12]
bank:= ( ((x shr 7) xor (y shr 6)) and 1) shl 12;
bank:=bank or ( ((x shr 8) xor (y shr 5) xor (y shr 6)) and 1) shl 13;
bank:=bank or ( ((x shr 9) xor (y shr 4)) and 1) shl 14;
total_offset:=
( (x shr 7) shl 1)+
(((y shr 7)*PITCH) shl 1)+
( (y shr 3) and 1);
Result := element_index or pipe or bank or (total_offset shl 15);
end;
procedure detile32bppBuf_slow(attr:p_attr;src,dst:Pointer);
var
x,y:Ptrint;
tiled_offset,linear_offset:Ptrint;
linear_pitch:Ptrint;
FNeoMode:Boolean;
PITCH:Ptrint;
begin
linear_offset:=0;
FNeoMode:=p_proc.p_neomode<>0;
PITCH:=(attr^.attr.pitchPixel+127) div 128;
y:=0;
While (y<attr^.attr.height) do
begin
linear_pitch:=y*attr^.attr.width;
x:=0;
While (x<attr^.attr.width) do
begin
if FNeoMode then
begin
tiled_offset:=getTiledElementByteOffset_32_NEO(PITCH,x,y);
end else
begin
tiled_offset:=getTiledElementByteOffset_32(PITCH,x,y);
end;
linear_offset:=(x+linear_pitch)*4;
PDWORD(dst + linear_offset)^:=PDWORD(src+tiled_offset)^;
x:=x+1;
end;
y:=y+1;
end;
end;
procedure SoftFlip(hWindow:THandle;buf:p_buffer;attr:p_attr;p_dst:PPointer);
var
hdc:THandle;
bi:BITMAPINFO;
rect:TRect;
len:Ptrint;
dst:Pointer;
begin
hdc:=GetDC(hWindow);
@ -228,6 +355,27 @@ begin
bi.bmiHeader.biBitCount :=32;
bi.bmiHeader.biCompression:=BI_RGB;
if (attr^.attr.tilingMode<>0) then
begin
len:=attr^.attr.width*attr^.attr.height*4;
if (p_dst^=nil) then
begin
p_dst^:=AllocMem(len);
end else
if (MemSize(p_dst^)<len) then
begin
p_dst^:=ReAllocMem(p_dst^,len);
end;
dst:=p_dst^;
detile32bppBuf_slow(attr,buf^.left,dst);
end else
begin
dst:=buf^.left;
end;
//SetStretchBltMode(hdc, HALFTONE);
StretchDIBits(hdc,
@ -236,7 +384,7 @@ begin
0,0,
attr^.attr.width,
attr^.attr.height,
buf^.left,
dst,
bi,
DIB_RGB_COLORS,
SRCCOPY
@ -271,48 +419,85 @@ begin
Node:=FQueue.Alloc;
if (Node=nil) then Exit(EBUSY);
Node^.Parent :=@OnSubmit;
Node^.u.submit:=submit^;
Node^.u.tsc :=rdtsc;
Node^.submit:=submit^;
Node^.tsc :=rdtsc;
FQueue.FQueue.Push(Node);
//RTLEventSetEvent(FEvent);
if (submit^.bufferIndex<>-1) then
begin
dce_page^.labels[submit^.bufferIndex]:=1;
end;
last_status.flipPendingNum0:=last_status.flipPendingNum0+1;
if (submit^.flipMode=SCE_VIDEO_OUT_FLIP_MODE_HSYNC) then
begin
RTLEventSetEvent(FEvent);
end;
Result:=0;
end;
function TDisplayHandleSoft.Vblank():Integer;
begin
RTLEventSetEvent(FEvent);
vblank_count:=vblank_count+1;
if (vblank_count>flip_rate) then
begin
vblank_count:=0;
RTLEventSetEvent(FEvent);
end;
Result:=0;
end;
procedure TDisplayHandleSoft.OnSubmit(Node:PQNode);
var
i:Integer;
submit:p_submit_flip;
buf :p_buffer;
attr:p_attr;
begin
submit:=@Node^.u.submit;
//submit attr
For i:=0 to High(m_sbat) do
if (m_sbat[i].init<>0) then
begin
mtx_lock(mtx^);
if (submit^.bufferIndex=-1) then Exit;
m_attr[i].init:=1;
m_attr[i].attr:=m_sbat[i].attr;
buf:=@m_bufs[submit^.bufferIndex];
if (buf^.init=0) then Exit;
attr:=@m_attr[buf^.attr];
if (attr^.init=0) then Exit;
m_sbat[i].init:=0;
SoftFlip(hWindow,buf,attr);
mtx_unlock(mtx^);
end;
submit:=@Node^.submit;
if (submit^.bufferIndex<>-1) then
begin
buf:=@m_bufs[submit^.bufferIndex];
if (buf^.init=0) then Exit;
attr:=@m_attr[buf^.attr];
if (attr^.init=0) then Exit;
SoftFlip(hWindow,buf,attr,@dst_cache);
end;
mtx_lock(mtx^);
if (submit^.bufferIndex<>-1) then
begin
dce_page^.labels[submit^.bufferIndex]:=0;
end;
dce_page^.label_:=0;
last_status.flipPendingNum0:=last_status.flipPendingNum0-1;
last_status.flipArg :=submit^.flipArg;
last_status.flipArg2 :=submit^.flipArg2;
last_status.count :=last_status.count+1;
last_status.submitTsc :=Node^.u.tsc;
last_status.submitTsc :=Node^.tsc;
last_status.currentBuffer :=submit^.bufferIndex;
last_status.tsc :=rdtsc;
last_status.processTime :=last_status.tsc;
@ -351,10 +536,7 @@ begin
Node:=nil;
if dce.FQueue.FQueue.Pop(Node) then
begin
if (Node^.Parent<>nil) then
begin
Node^.Parent(Node);
end;
dce.OnSubmit(Node);
dce.FQueue.Free(Node);
end;

View File

@ -129,7 +129,8 @@ asm
//if ((cpu_id & 0xffffff80) == 0x740f00) then sceKernelIsAuthenticNeo
mov $0x00710f13,%eax //cpu_id
mov p_proc.p_cpuid,%eax //cpu_id
mov $0x178bfbff,%edx //cpu_feature
mov $0x36d8220b,%ecx //cpu_feature2

View File

@ -24,6 +24,10 @@ type
ar_args :AnsiChar; // Arguments.
end;
const
CPUID_BASE_MODE=$710f13;
CPUID_NEO_MODE =$740f00;
var
p_proc:record
p_mtx:mtx;
@ -67,6 +71,10 @@ var
p_dmem_aliasing:Integer;
p_system_sdk_version:Integer; //$10010001;
p_cpuid :Integer; //base mode = 0x710f13 / neo mode = 0x740f00
p_neomode :Integer; //[0..1]
p_host_ipc:THostIpcConnect;
end;
@ -152,6 +160,10 @@ begin
p_proc.p_randomized_path:='system';
p_proc.p_ptc:=rdtsc;
p_proc.p_system_sdk_version:=$10010001;
p_proc.p_cpuid :=CPUID_BASE_MODE;
p_proc.p_neomode :=0;
end;
end.

View File

@ -66,6 +66,7 @@ const
KERN_SMP =$100; //(OID_AUTO) Kernel SMP
KERN_SCHED =$101; //(OID_AUTO) Scheduler
KERN_NEOMODE =$102; //(OID_AUTO) Neo mode
//CTL_VM subtypes
KERN_VM_PS4DEV=1; //vm parameters for PS4 (DevKit only)
@ -103,7 +104,12 @@ const
HW_MAXID =13; // number of valid hw ids
//MACHDEP subtypes
MACHDEP_TSC_FREQ=$100; //(OID_AUTO) Time Stamp Counter frequency
MACHDEP_TSC_FREQ =$100; //(OID_AUTO) Time Stamp Counter frequency
MACHDEP_BOOTPARAMS=$101; //(OID_AUTO) orbis bootparams
//BOOTPARAMS subtypes
BOOTPARAMS_IS_MAIN_ON_STANDBY=$100; //(OID_AUTO) Is main on standby mode
BOOTPARAMS_BASE_PS4_MODE =$101; //(OID_AUTO) base ps4 mode
//KERN_VM_PS4DEV subtypes
KERN_VM_PS4DEV_TRCMEM_TOTAL=$100; //(OID_AUTO) trace memory total
@ -547,12 +553,25 @@ begin
oid[2]:=KERN_SCHED_CPUSETSIZE;
len^ :=3;
end;
'kern.neomode':
begin
oid[0]:=CTL_KERN;
oid[1]:=KERN_NEOMODE;
len^ :=2;
end;
'machdep.tsc_freq':
begin
oid[0]:=CTL_MACHDEP;
oid[1]:=MACHDEP_TSC_FREQ;
len^ :=2;
end;
'machdep.bootparams.base_ps4_mode':
begin
oid[0]:=CTL_MACHDEP;
oid[1]:=MACHDEP_BOOTPARAMS;
oid[2]:=BOOTPARAMS_BASE_PS4_MODE;
len^ :=3;
end;
'vm.ps4dev.trcmem_total':
begin
oid[0]:=CTL_VM;
@ -670,8 +689,6 @@ begin
end;
function sysctl_kern(name:PInteger;namelen:DWORD;noid:p_sysctl_oid;req:p_sysctl_req):Integer;
const
system_sdk_version=$10010001;
begin
if (namelen=0) then Exit(ENOTDIR);
Result:=ENOENT;
@ -681,10 +698,11 @@ begin
KERN_USRSTACK :Result:=SYSCTL_HANDLE(noid,name,$80008008,@sysctl_kern_usrstack);
KERN_ARND :Result:=SYSCTL_HANDLE(noid,name,$80048005,@sysctl_kern_arandom);
KERN_SDKVERSION:Result:=SYSCTL_HANDLE(noid,name,$80048006,system_sdk_version,@sysctl_handle_int);
KERN_SDKVERSION:Result:=SYSCTL_HANDLE(noid,name,$80048006,p_proc.p_system_sdk_version,@sysctl_handle_int);
KERN_SMP :Result:=sysctl_kern_smp (name+1,namelen-1,noid,req);
KERN_SCHED :Result:=sysctl_kern_sched(name+1,namelen-1,noid,req);
KERN_NEOMODE :Result:=SYSCTL_HANDLE(noid,name,$80040002,p_proc.p_neomode,@sysctl_handle_int);
else
begin
print_backtrace_td(stderr);
@ -777,13 +795,30 @@ begin
end;
end;
function sysctl_bootparams(name:PInteger;namelen:DWORD;noid:p_sysctl_oid;req:p_sysctl_req):Integer;
begin
if (namelen=0) then Exit(ENOTDIR);
Result:=ENOENT;
case name[0] of
BOOTPARAMS_BASE_PS4_MODE:Result:=SYSCTL_HANDLE(noid,name,$80040002,ord(p_proc.p_cpuid<>CPUID_NEO_MODE),@sysctl_handle_int);
else
begin
print_backtrace_td(stderr);
Writeln(StdErr,'Unhandled sysctl_bootparams:',name[0]);
Assert(False);
end;
end;
end;
function sysctl_machdep(name:PInteger;namelen:DWORD;noid:p_sysctl_oid;req:p_sysctl_req):Integer;
begin
if (namelen=0) then Exit(ENOTDIR);
Result:=ENOENT;
case name[0] of
MACHDEP_TSC_FREQ:Result:=SYSCTL_HANDLE(noid,name,$C0000009,@sysctl_machdep_tsc_freq);
MACHDEP_TSC_FREQ :Result:=SYSCTL_HANDLE(noid,name,$C0000009,@sysctl_machdep_tsc_freq);
MACHDEP_BOOTPARAMS:Result:=sysctl_bootparams(name+1,namelen-1,noid,req);
else
begin