diff --git a/chip/ps4_videodrv.pas b/chip/ps4_videodrv.pas index 1a790bcc..832d4751 100644 --- a/chip/ps4_videodrv.pas +++ b/chip/ps4_videodrv.pas @@ -80,12 +80,8 @@ type TvSubmitNode=record next_:PvSubmitNode; // - dcbAddr:Pointer; - ccbAddr:Pointer; - dcbSize:DWORD; - ccbSize:DWORD; + Submit:TvSubmitInfo; Flip:TqcFlipInfo; - IsFlip:Boolean; end; TvCmdRing=object @@ -103,7 +99,6 @@ type qcInfo:TqcFlipInfo; FlipLData:DWORD; FlipLabel:PDWORD; - IsFlip:Boolean; Interrupt:Boolean; end; @@ -135,7 +130,7 @@ type Procedure Init; Function Next:Boolean; Procedure PushCmd(var Cmd:TvCmdBuffer); - Procedure PushFlip(var qcInfo:TqcFlipInfo;FlipLData:DWORD;FlipLabel:PDWORD;IsFlip,Interrupt:Boolean); + Procedure PushFlip(var qcInfo:TqcFlipInfo;FlipLData:DWORD;FlipLabel:PDWORD;Interrupt:Boolean); Procedure PushEop(adr:Pointer;data:QWORD;dataSel:Byte;Interrupt:Boolean); end; @@ -217,7 +212,7 @@ begin Cmd:=nil; end; -Procedure TvMicroEngine.PushFlip(var qcInfo:TqcFlipInfo;FlipLData:DWORD;FlipLabel:PDWORD;IsFlip,Interrupt:Boolean); +Procedure TvMicroEngine.PushFlip(var qcInfo:TqcFlipInfo;FlipLData:DWORD;FlipLabel:PDWORD;Interrupt:Boolean); var node:PvMicroEngineNode; begin @@ -228,10 +223,11 @@ begin node^.FlipInfo.qcInfo :=qcInfo; node^.FlipInfo.FlipLData:=FlipLData; node^.FlipInfo.FlipLabel:=FlipLabel; - node^.FlipInfo.IsFlip :=IsFlip; node^.FlipInfo.Interrupt:=Interrupt; Queue.Push(node); + + qcInfo:=Default(TqcFlipInfo); end; Procedure TvMicroEngine.PushEop(adr:Pointer;data:QWORD;dataSel:Byte;Interrupt:Boolean); @@ -250,7 +246,7 @@ begin Queue.Push(node); end; -procedure gfx_cp_parser(node:PvSubmitNode); forward; +procedure gfx_cp_parser(node:PvSubmitInfo); forward; function gfx_submit(CmdBuffer:TvCmdBuffer):Boolean; forward; function gfx_test(CmdBuffer:TvCmdBuffer):Boolean; forward; @@ -264,7 +260,7 @@ begin node^.FlipLabel^:=node^.FlipLData; end; - if node^.IsFlip then + if (node^.qcInfo.hVideo<>0) then begin _qc_sceVideoOutSubmitFlip(@node^.qcInfo); end; @@ -342,7 +338,7 @@ begin if GFXRing.Next then begin - gfx_cp_parser(GFXRing.Current); + gfx_cp_parser(@GFXRing.Current^.Submit); work_do:=True; end; @@ -440,6 +436,7 @@ begin end; end; +{ procedure copy_submit_addr(node:PvSubmitInfo;dcbAddr,ccbAddr:Pointer); var n:DWORD; @@ -481,14 +478,13 @@ begin Inc(n); end; end; +} function vSubmitCommandBuffers( Submit:PvSubmitInfo; Flip:PqcFlipInfo):Integer; var node:PvSubmitNode; - dcbAddr:Pointer; - ccbAddr:Pointer; dcbSize:DWORD; ccbSize:DWORD; addr:Pointer; @@ -507,37 +503,58 @@ begin Exit(SCE_KERNEL_ERROR_EINVAL); end; - size:=AlignUp(SizeOf(TvSubmitNode),4)+dcbSize+ccbSize; + //calc size + + size:=SizeOf(TvSubmitNode); + + if (Submit^.dcbGpuAddrs<>nil) and (Submit^.dcbSizesInBytes<>nil) then + begin + size:=size+Submit^.count*(SizeOf(Pointer)+SizeOf(DWORD)); + end; + + if (Submit^.ccbGpuAddrs<>nil) and (Submit^.ccbSizesInBytes<>nil) then + begin + size:=size+Submit^.count*(SizeOf(Pointer)+SizeOf(DWORD)); + end; + + //alloc + node:=AllocMem(size); if (node=nil) then begin Exit(SCE_KERNEL_ERROR_ENOMEM); end; - addr:=AlignUp(Pointer(node)+SizeOf(TvSubmitNode),4); + //distrib - if (dcbSize<>0) then + addr:=Pointer(node)+SizeOf(TvSubmitNode); + + if (Submit^.dcbGpuAddrs<>nil) and (Submit^.dcbSizesInBytes<>nil) then begin - dcbAddr:=addr; - addr:=addr+dcbSize; - end; - if (ccbSize<>0) then - begin - ccbAddr:=addr; - addr:=addr+ccbSize; + node^.Submit.dcbGpuAddrs:=addr; + addr:=addr+Submit^.count*SizeOf(Pointer); + node^.Submit.dcbSizesInBytes:=addr; + addr:=addr+Submit^.count*SizeOf(DWORD); + //copy + Move(Submit^.dcbGpuAddrs^ ,node^.Submit.dcbGpuAddrs^ ,Submit^.count*SizeOf(Pointer)); + Move(Submit^.dcbSizesInBytes^,node^.Submit.dcbSizesInBytes^,Submit^.count*SizeOf(DWORD)); end; - copy_submit_addr(Submit,dcbAddr,ccbAddr); + if (Submit^.ccbGpuAddrs<>nil) and (Submit^.ccbSizesInBytes<>nil) then + begin + node^.Submit.ccbGpuAddrs:=addr; + addr:=addr+Submit^.count*SizeOf(Pointer); + node^.Submit.ccbSizesInBytes:=addr; + addr:=addr+Submit^.count*SizeOf(DWORD); + //copy + Move(Submit^.ccbGpuAddrs^ ,node^.Submit.ccbGpuAddrs^ ,Submit^.count*SizeOf(Pointer)); + Move(Submit^.ccbSizesInBytes^,node^.Submit.ccbSizesInBytes^,Submit^.count*SizeOf(DWORD)); + end; + + node^.Submit.count:=Submit^.count; Init_gfx; - node^.dcbAddr:=dcbAddr; - node^.ccbAddr:=ccbAddr; - node^.dcbSize:=dcbSize; - node^.ccbSize:=ccbSize; - - node^.IsFlip:=(Flip<>nil); - if (Flip<>nil) then begin node^.Flip:=Flip^; @@ -556,7 +573,7 @@ end; procedure onPrepareFlip(); begin GFXMicroEngine.PushCmd(GFXRing.CmdBuffer); - GFXMicroEngine.PushFlip(GFXRing.Current^.Flip,0,nil,GFXRing.Current^.IsFlip,False); + GFXMicroEngine.PushFlip(GFXRing.Current^.Flip,0,nil,False); end; procedure onPrepareFlipLabel(pm4Hdr:PM4_TYPE_3_HEADER;Body:PPM4PrepareFlip); @@ -567,7 +584,7 @@ begin {$ifdef ww}Writeln('adr:',HexStr(adr),' data:',Body^.DATA);{$endif} GFXMicroEngine.PushCmd(GFXRing.CmdBuffer); - GFXMicroEngine.PushFlip(GFXRing.Current^.Flip,Body^.DATA,adr,GFXRing.Current^.IsFlip,False); + GFXMicroEngine.PushFlip(GFXRing.Current^.Flip,Body^.DATA,adr,False); end; procedure onPrepareFlipWithEopInterrupt(pm4Hdr:PM4_TYPE_3_HEADER;Body:PPM4PrepareFlipWithEopInterrupt); @@ -575,7 +592,7 @@ begin {$ifdef ww}writeln;{$endif} GFXMicroEngine.PushCmd(GFXRing.CmdBuffer); - GFXMicroEngine.PushFlip(GFXRing.Current^.Flip,0,nil,GFXRing.Current^.IsFlip,True); + GFXMicroEngine.PushFlip(GFXRing.Current^.Flip,0,nil,True); end; procedure onPrepareFlipWithEopInterruptLabel(pm4Hdr:PM4_TYPE_3_HEADER;Body:PPM4PrepareFlipWithEopInterrupt); @@ -586,7 +603,7 @@ begin {$ifdef ww}Writeln('adr:',HexStr(adr),' data:',Body^.DATA);{$endif} GFXMicroEngine.PushCmd(GFXRing.CmdBuffer); - GFXMicroEngine.PushFlip(GFXRing.Current^.Flip,Body^.DATA,adr,GFXRing.Current^.IsFlip,True); + GFXMicroEngine.PushFlip(GFXRing.Current^.Flip,Body^.DATA,adr,True); end; procedure onEventWriteEop(pm4Hdr:PM4_TYPE_3_HEADER;Body:PEVENTWRITEEOP); @@ -1340,12 +1357,6 @@ end; //PITCH.TILE_MAX = 159, //(PITCH.TILE_MAX+1)*8=1280 //SLICE.TILE_MAX = 15359, //(SLICE.TILE_MAX+1)/(PITCH.TILE_MAX+1)*8=768 -var - FAttrBuilder:TvAttrBuilder; - FUniformBuilder:TvUniformBuilder; - - FShaderGroup:TvShaderGroup; - type TvEvent2=class(TvEvent) Procedure Release(Sender:TObject); @@ -1356,10 +1367,14 @@ begin Free; end; -procedure UpdateGpuRegsInfo; - - var + FShaderGroup:TvShaderGroup; + +procedure UpdateGpuRegsInfo; +var + FAttrBuilder:TvAttrBuilder; + FUniformBuilder:TvUniformBuilder; + i,o,a:DWORD; pData:Pointer; @@ -1857,6 +1872,9 @@ end; procedure UpdateGpuRegsInfoCompute; var + FAttrBuilder:TvAttrBuilder; + FUniformBuilder:TvUniformBuilder; + fdump_cs:RawByteString; i,o,a:Integer; @@ -2030,156 +2048,159 @@ begin {$ifdef ww}Writeln('onNumInstances:',Body^);{$endif} end; -procedure gfx_cp_parser(node:PvSubmitNode); +procedure gfx_cp_parser(node:PvSubmitInfo); var - i,s:DWORD; + n,i,s:DWORD; token:DWORD; P:PByte; begin if (node=nil) then Exit; - if (node^.ccbAddr<>nil) and (node^.ccbSize<>0) then + if (node^.ccbGpuAddrs<>nil) and (node^.ccbSizesInBytes<>nil) then begin Assert(false,'TODO CCB'); end; - if (node^.dcbAddr=nil) or (node^.dcbSize=0) then Exit; - - i:=0; - s:=node^.dcbSize; - P:=node^.dcbAddr; - While (inil) and (Info^.sType=STT_FUN) then //trace begin - //Case Info^.lib^.strName of - // 'libc':; - // 'libkernel':; - // else - // //if (Pos('Sem',ps4libdoc.GetFunctName(Info^.Nid))<>0) or - // // (Pos('Equeue',ps4libdoc.GetFunctName(Info^.Nid))<>0) then - // begin - // Result:=TStubMemoryTrace(Stub).NewTraceStub(Info^.Nid,Info^.lib,Result,@_trace_enter,@_trace_exit); - // end; - //end; + //Case Info^.lib^.strName of + // 'libc':; + // 'libSceLibcInternal':; + // else + // Case RawByteString(ps4libdoc.GetFunctName(Info^.Nid)) of + // 'scePthreadMutexInit':; + // 'scePthreadMutexattrInit':; + // 'scePthreadMutexattrDestroy':; + // 'scePthreadMutexattrSettype':; + // 'scePthreadMutexTrylock':; + // 'scePthreadMutexLock':; + // 'scePthreadMutexUnlock':; + // 'pthread_self':; + // 'scePthreadSelf':; + // 'scePthreadEqual':; + // 'sceKernelGettimeofday':; + // 'sceKernelClockGettime':; + // 'pthread_mutex_lock':; + // 'pthread_mutex_unlock':; + // 'sceKernelPread':; + // 'sceKernelClose':; + // 'sceDiscMapIsRequestOnHDD':; + // 'Unknow':; + // 'sceFiosIOFilterPsarcDearchiver':; + // 'sceFiosFHReadSync':; + // 'sceFiosFHTell':; + // 'sceNgs2VoiceGetState':; + // 'sceNgs2SystemRender':; + // 'sceAudioOutOutputs':; + // '__tls_get_addr':; + // 'scePthreadRwlockRdlock':; + // 'scePthreadRwlockUnlock':; + // 'scePthreadCondBroadcast':; + // 'sceFiosFHCloseSync':; + // 'sceKernelStat':; + // 'sceFiosFHOpenSync':; + // 'sceFiosFHGetSize':; + // 'sceKernelOpen':; + // else + // begin + // Result:=TStubMemoryTrace(Stub).NewTraceStub(Info^.Nid,Info^.lib,Result,@_trace_enter,@_trace_exit); + // end; + // end; + //end; end; + if (Result=nil) then begin if (Info^.sType=STT_FUN) then @@ -426,6 +461,9 @@ begin //ps4_app.app_path:='G:\Games\Worms\CUSA04047\'; //ps4_app.app_file:='G:\Games\Worms\CUSA04047\eboot.bin'; + //ps4_app.app_path:='G:\Games\Super Meat Boy\'; + //ps4_app.app_file:='G:\Games\Super Meat Boy\eboot.bin'; + //elf:=Telf_file(LoadPs4ElfFromFile('libSceLibcInternal.sprx')); //elf.Prepare; //elf.SavePs4ElfToFile('libSceLibcInternal.prx'); diff --git a/ps4_libkernel/ps4_queue.pas b/ps4_libkernel/ps4_queue.pas index f27f3d3f..e49bcb1a 100644 --- a/ps4_libkernel/ps4_queue.pas +++ b/ps4_libkernel/ps4_queue.pas @@ -100,6 +100,8 @@ type SceKernelEqueue_t=record valid:DWORD; FRefs:DWORD; + lock:DWORD; + wait:DWORD; hIOCP:Thandle; name:array[0..31] of AnsiChar; end; @@ -108,6 +110,7 @@ type TKEventNode=object refs:DWORD; lock:DWORD; + wait:DWORD; eq:SceKernelEqueue; ev:SceKernelEvent; end; @@ -127,7 +130,7 @@ type function _acqure_equeue(eq:SceKernelEqueue):SceKernelEqueue; procedure _release_equeue(eq:SceKernelEqueue); -function _post_event(eq:SceKernelEqueue;node:Pointer;cb:TKFetchEvent):Boolean; +function _post_event(eq:SceKernelEqueue;node:PKEventNode;cb:TKFetchEvent):Boolean; function _alloc_kevent_node(eq:SceKernelEqueue;size:qword):Pointer; procedure _free_kevent_node(node:PKEventNode); @@ -164,7 +167,7 @@ end; procedure _free_kevent_node(node:PKEventNode); begin if (node=nil) then Exit; - _release_equeue(System.InterlockedExchange(node^.eq,nil)); + _release_equeue(XCHG(node^.eq,nil)); if System.InterlockedDecrement(node^.refs)=0 then begin SwFreeMem(node); @@ -178,11 +181,14 @@ begin Result:=false; if (node=nil) or (ev=nil) then Exit; tmp:=node^.ev; - spin_unlock(node^.lock); - if System.InterlockedDecrement(node^.refs)=0 then + if System.InterlockedDecrement(node^.wait)=0 then begin - SwFreeMem(node); - Exit; + spin_unlock(node^.lock); + if System.InterlockedDecrement(node^.refs)=0 then + begin + SwFreeMem(node); + Exit; + end; end; ev^:=tmp; Result:=True; @@ -210,6 +216,9 @@ begin Exit; end; end; + end else + begin + //Assert(false); end; end; @@ -218,7 +227,7 @@ var hIOCP:Thandle; data:SceKernelEqueue; begin - Writeln('sceKernelCreateEqueue:',name); + //Writeln('sceKernelCreateEqueue:',name); if (outEq=nil) then Exit(SCE_KERNEL_ERROR_EINVAL); data:=SwAllocMem(SizeOf(SceKernelEqueue_t)); @@ -243,13 +252,39 @@ begin Result:=0; end; -function _post_event(eq:SceKernelEqueue;node:Pointer;cb:TKFetchEvent):Boolean; +function _post_event(eq:SceKernelEqueue;node:PKEventNode;cb:TKFetchEvent):Boolean; +var + i,t,wait:DWORD; begin Result:=False; if (eq=nil) then Exit; if (eq^.valid<>LIFE_EQ) then Exit; _sig_lock; - Result:=PostQueuedCompletionStatus(eq^.hIOCP,1,ULONG_PTR(cb),node); + spin_lock(eq^.lock); + wait:=load_acq_rel(eq^.wait); + + if (wait=0) then wait:=1; + + //Writeln(GetCurrentThreadId,':>post_event:',eq^.name,' wait:',wait); + + //one shoot or all ???????? + i:=wait; + repeat + System.InterlockedIncrement(node^.wait); + Result:=PostQueuedCompletionStatus(eq^.hIOCP,1,ULONG_PTR(cb),Pointer(node)); + if (not Result) then + begin + System.InterlockedDecrement(node^.wait); + spin_unlock(eq^.lock); + _sig_unlock; + Exit; + end; + Dec(i); + t:=load_acq_rel(eq^.wait); + if (tsceKernelWaitEqueue'); + //Writeln('>sceKernelWaitEqueue:',eq^.name); if (timo<>nil) then begin @@ -327,7 +363,24 @@ begin ulNum:=0; _sig_lock; if (LTIME<>INFINITE) then QTIME:=Windows.GetTickCount; + + spin_lock(eq^.lock); + System.InterlockedIncrement(eq^.wait); + //Writeln(GetCurrentThreadId,':>sceKernelWaitEqueue:',eq^.name,':',eq^.wait); + spin_unlock(eq^.lock); + + err:=0; Q:=GetQueuedCompletionStatusEX(eq^.hIOCP,@OE,num,ulNum,LTIME,True); + + //spin_lock(eq^.lock); + System.InterlockedDecrement(eq^.wait); + //Writeln(GetCurrentThreadId,':INFINITE) then begin @@ -341,7 +394,7 @@ begin end; if not Q then begin - Case GetLastError of + Case err of ERROR_INVALID_PARAMETER, ERROR_INVALID_HANDLE :Exit(SCE_KERNEL_ERROR_EBADF); WAIT_TIMEOUT :Exit(SCE_KERNEL_ERROR_ETIMEDOUT); @@ -356,14 +409,19 @@ begin if Assigned(CTXProc) then begin if CTXProc(PKEventNode(OE[i].lpOverlapped),@ev[olNum]) then Inc(olNum); + end else + begin + Assert(false); end; end; if (olNum<>0) then begin out_num^:=olNum; - //Writeln('