diff --git a/gui/game_run.pas b/gui/game_run.pas index 852ddb6d..b7d6e029 100644 --- a/gui/game_run.pas +++ b/gui/game_run.pas @@ -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); diff --git a/sys/dev/dev_gc.pas b/sys/dev/dev_gc.pas index c2806a6d..308a8bc5 100644 --- a/sys/dev/dev_gc.pas +++ b/sys/dev/dev_gc.pas @@ -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); diff --git a/sys/dev/display_interface.pas b/sys/dev/display_interface.pas index eddefe22..4a65f785 100644 --- a/sys/dev/display_interface.pas +++ b/sys/dev/display_interface.pas @@ -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; diff --git a/sys/dev/display_soft.pas b/sys/dev/display_soft.pas index 1a694922..16a4c523 100644 --- a/sys/dev/display_soft.pas +++ b/sys/dev/display_soft.pas @@ -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 (y0) 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^)-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; diff --git a/sys/jit/kern_jit.pas b/sys/jit/kern_jit.pas index b436a71a..75325323 100644 --- a/sys/jit/kern_jit.pas +++ b/sys/jit/kern_jit.pas @@ -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 diff --git a/sys/kern/kern_proc.pas b/sys/kern/kern_proc.pas index b5bb3e02..62a6cae1 100644 --- a/sys/kern/kern_proc.pas +++ b/sys/kern/kern_proc.pas @@ -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. diff --git a/sys/kern/kern_sysctl.pas b/sys/kern/kern_sysctl.pas index 7ab3ba2f..452756f0 100644 --- a/sys/kern/kern_sysctl.pas +++ b/sys/kern/kern_sysctl.pas @@ -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