mirror of https://github.com/red-prig/fpPS4.git
This commit is contained in:
parent
9e2f88ee97
commit
7f42739963
|
@ -36,6 +36,7 @@ uses
|
|||
kern_rwlock,
|
||||
kern_proc,
|
||||
kern_thr,
|
||||
kern_condvar,
|
||||
time,
|
||||
md_sleep,
|
||||
pm4defs,
|
||||
|
@ -170,14 +171,35 @@ var
|
|||
ring_gfx :t_pm4_ring;
|
||||
ring_gfx_lock :Pointer=nil;
|
||||
|
||||
ring_watchdog :PRTLEvent=nil;
|
||||
watchdog_label:QWORD=0;
|
||||
type
|
||||
t_gc_priv=object
|
||||
ring_watchdog:PRTLEvent;
|
||||
GC_SRI_event :t_cv; //suspend-resume-idle event
|
||||
|
||||
GC_SRI_event:PRTLEvent=nil;
|
||||
GC_SRI_label:QWORD=0;
|
||||
GC_IDLE_event:t_cv;
|
||||
|
||||
me_idle_event:PRTLEvent=nil;
|
||||
me_idle_label:QWORD=0;
|
||||
//pfp_event :t_cv;
|
||||
|
||||
gc_suspend_lock:mtx;
|
||||
|
||||
watchdog_label:Integer;
|
||||
GC_SRI_label :Integer;
|
||||
pfp_label :Integer;
|
||||
sync_to_imdone:Integer;
|
||||
end;
|
||||
|
||||
var
|
||||
gc_priv:t_gc_priv=(
|
||||
ring_watchdog:nil;
|
||||
GC_SRI_event :(cv_description:nil;cv_waiters:0);
|
||||
GC_IDLE_event:(cv_description:nil;cv_waiters:0);
|
||||
//pfp_event :(cv_description:nil;cv_waiters:0);
|
||||
|
||||
watchdog_label:0;
|
||||
GC_SRI_label :0;
|
||||
pfp_label :0;
|
||||
sync_to_imdone:0;
|
||||
);
|
||||
|
||||
parse_gfx_started:Pointer=nil;
|
||||
parse_gfx_td:p_kthread;
|
||||
|
@ -207,6 +229,29 @@ begin
|
|||
pctx^.stream[stGfxDcb].SubmitFlipEop(Body^.DATA,Body^.intSel);
|
||||
end;
|
||||
|
||||
procedure _FlushAndWaitMe(pctx:p_pfp_ctx);
|
||||
var
|
||||
event:PRTLEvent;
|
||||
begin
|
||||
if (pctx^.event=nil) then
|
||||
begin
|
||||
pctx^.event:=RTLEventCreate;
|
||||
end;
|
||||
|
||||
event:=pctx^.event;
|
||||
|
||||
pctx^.stream[stGfxDcb].PfpSyncMe(event);
|
||||
|
||||
pctx^.Flush_stream(stGfxDcb);
|
||||
|
||||
RTLEventWaitFor(event);
|
||||
end;
|
||||
|
||||
procedure onSwitchBuffer(pctx:p_pfp_ctx;Body:Pointer);
|
||||
begin
|
||||
_FlushAndWaitMe(pctx);
|
||||
end;
|
||||
|
||||
function pm4_parse_gfx_ring(pctx:p_pfp_ctx;token:DWORD;buff:Pointer):Integer;
|
||||
var
|
||||
ibuf:t_pm4_ibuffer;
|
||||
|
@ -255,6 +300,7 @@ begin
|
|||
begin
|
||||
Writeln('[R]SWITCH_BUFFER');
|
||||
end;
|
||||
onSwitchBuffer(pctx,buff);
|
||||
end;
|
||||
$C0044700: //IT_EVENT_WRITE_EOP
|
||||
begin
|
||||
|
@ -406,11 +452,12 @@ begin
|
|||
|
||||
end; //(bits<>0)
|
||||
|
||||
//PFP idle
|
||||
pfp_idle;
|
||||
|
||||
if (watchdog_label=0) then
|
||||
if (gc_priv.watchdog_label=0) then
|
||||
begin
|
||||
RTLEventWaitFor(ring_watchdog);
|
||||
RTLEventWaitFor(gc_priv.ring_watchdog);
|
||||
end else
|
||||
begin
|
||||
msleep_td(hz div 10000);
|
||||
|
@ -427,108 +474,239 @@ begin
|
|||
pfp_ctx.init;
|
||||
pfp_ctx.on_flush_stream:=@pm4_me_gfx.Push;
|
||||
|
||||
ring_watchdog:=RTLEventCreate;
|
||||
GC_SRI_event :=RTLEventCreate;
|
||||
gc_priv.ring_watchdog:=RTLEventCreate;
|
||||
//gc_priv.GC_SRI_event :=RTLEventCreate;
|
||||
|
||||
cv_init (@gc_priv.GC_SRI_event ,'GC_SRI_event');
|
||||
cv_init (@gc_priv.GC_IDLE_event,'GC_IDLE_event');
|
||||
mtx_init(gc_priv.gc_suspend_lock,'gc_suspend_lock');
|
||||
|
||||
kthread_add(@parse_gfx_ring,nil,@parse_gfx_td,(8*1024*1024) div (16*1024),'[GFX_PFP]');
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure retrigger_watchdog;
|
||||
procedure gc_retrigger_watchdog;
|
||||
begin
|
||||
if (ring_watchdog<>nil) then
|
||||
if (gc_priv.ring_watchdog<>nil) then
|
||||
begin
|
||||
watchdog_label:=1; //thread can`t wait
|
||||
RTLEventSetEvent(ring_watchdog);
|
||||
gc_priv.watchdog_label:=1; //thread can`t wait
|
||||
RTLEventSetEvent(gc_priv.ring_watchdog);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure wait_me_idle; forward;
|
||||
procedure gc_retrigger_watchdog_imdone;
|
||||
begin
|
||||
//if (gc_priv.sync_to_imdone=0) then
|
||||
begin
|
||||
gc_retrigger_watchdog;
|
||||
gc_priv.sync_to_imdone:=1;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure gc_wait_GC_SRI;
|
||||
begin
|
||||
if (GC_SRI_label<>0) then
|
||||
if (pm4_me_gfx.started=nil) then Exit;
|
||||
|
||||
//if (gc_priv.GC_SRI_label=0) then Exit;
|
||||
|
||||
//if (gc_priv.GC_SRI_event<>nil) then
|
||||
begin
|
||||
if (GC_SRI_event<>nil) then
|
||||
//gc_priv.GC_SRI_label:=0;
|
||||
|
||||
//RTLEventResetEvent(gc_priv.GC_SRI_event);
|
||||
|
||||
//gc_priv.GC_SRI_label:=1;
|
||||
|
||||
//pm4_me_gfx.trigger; //update if wait
|
||||
|
||||
//RTLEventWaitFor(gc_priv.GC_SRI_event);
|
||||
|
||||
mtx_lock(gc_priv.gc_suspend_lock);
|
||||
|
||||
//if (gc_priv.pfp_label<>0) then
|
||||
//begin
|
||||
// gc_retrigger_watchdog;
|
||||
//
|
||||
// _cv_wait_sig(@gc_priv.pfp_event,@gc_priv.GC_SRI_lock);
|
||||
//end;
|
||||
|
||||
if (gc_priv.GC_SRI_label<>0) then
|
||||
begin
|
||||
RTLEventWaitFor(GC_SRI_event);
|
||||
pm4_me_gfx.trigger; //update if wait
|
||||
|
||||
_cv_wait_sig(@gc_priv.GC_SRI_event,@gc_priv.gc_suspend_lock);
|
||||
end;
|
||||
|
||||
mtx_unlock(gc_priv.gc_suspend_lock);
|
||||
end;
|
||||
|
||||
wait_me_idle;
|
||||
//pm4_me_gfx.trigger; //update if wait
|
||||
end;
|
||||
|
||||
procedure pfp_idle;
|
||||
begin
|
||||
if (GC_SRI_event<>nil) then
|
||||
|
||||
mtx_lock(gc_priv.gc_suspend_lock);
|
||||
|
||||
//if (gc_priv.pfp_label<>0) then
|
||||
//begin
|
||||
// cv_broadcastpri(@gc_priv.pfp_event,0);
|
||||
//end;
|
||||
|
||||
gc_priv.pfp_label:=0;
|
||||
|
||||
mtx_unlock(gc_priv.gc_suspend_lock);
|
||||
|
||||
pm4_me_gfx.trigger;
|
||||
end;
|
||||
|
||||
procedure gc_idle; register;
|
||||
begin
|
||||
mtx_lock(gc_priv.gc_suspend_lock);
|
||||
|
||||
if (gc_priv.pfp_label=0) then
|
||||
begin
|
||||
RTLEventSetEvent(GC_SRI_event);
|
||||
cv_signal(@gc_priv.GC_IDLE_event);
|
||||
end;
|
||||
GC_SRI_label:=0;
|
||||
|
||||
mtx_unlock(gc_priv.gc_suspend_lock);
|
||||
end;
|
||||
|
||||
procedure gc_imdone_tasklet;
|
||||
var
|
||||
ret:Integer;
|
||||
begin
|
||||
mtx_lock(gc_priv.gc_suspend_lock);
|
||||
|
||||
gc_priv.pfp_label:=1;
|
||||
|
||||
repeat
|
||||
|
||||
gc_retrigger_watchdog;
|
||||
pm4_me_gfx.trigger; //update if wait
|
||||
|
||||
ret:=_cv_timedwait(@gc_priv.GC_IDLE_event,@gc_priv.gc_suspend_lock, hz div 2);
|
||||
|
||||
if (ret<>0) then
|
||||
begin
|
||||
Writeln(stderr,'GPU failed to become idle within 500 ms after submitDone.');
|
||||
end;
|
||||
|
||||
until (ret=0);
|
||||
|
||||
if (gc_priv.GC_SRI_label<>0) then
|
||||
begin
|
||||
cv_broadcastpri(@gc_priv.GC_SRI_event,0);
|
||||
end;
|
||||
|
||||
gc_priv.GC_SRI_label:=0;
|
||||
|
||||
mtx_unlock(gc_priv.gc_suspend_lock);
|
||||
|
||||
if (gc_submits_allowed_vmirr<>nil) then
|
||||
begin
|
||||
gc_submits_allowed_vmirr^:=0; //true
|
||||
end;
|
||||
|
||||
|
||||
end;
|
||||
|
||||
procedure me_idle; register;
|
||||
{
|
||||
procedure gc_idle; register;
|
||||
begin
|
||||
if (me_idle_label=0) then Exit;
|
||||
//
|
||||
if (me_idle_event<>nil) then
|
||||
|
||||
mtx_lock(gc_priv.gc_suspend_lock);
|
||||
|
||||
if (gc_priv.GC_SRI_label<>0) then
|
||||
begin
|
||||
RTLEventSetEvent(me_idle_event);
|
||||
cv_broadcastpri(@gc_priv.GC_SRI_event,0);
|
||||
end;
|
||||
//
|
||||
me_idle_label:=0;
|
||||
end;
|
||||
|
||||
procedure wait_me_idle;
|
||||
begin
|
||||
//
|
||||
me_idle_label:=0; //dont SetEvent
|
||||
//
|
||||
if (me_idle_event=nil) then
|
||||
gc_priv.GC_SRI_label:=0;
|
||||
|
||||
mtx_unlock(gc_priv.gc_suspend_lock);
|
||||
|
||||
if (gc_submits_allowed_vmirr<>nil) then
|
||||
begin
|
||||
me_idle_event:=RTLEventCreate;
|
||||
end else
|
||||
begin
|
||||
RTLEventResetEvent(me_idle_event);
|
||||
gc_submits_allowed_vmirr^:=0; //true
|
||||
end;
|
||||
//
|
||||
me_idle_label:=1; //can SetEvent
|
||||
//
|
||||
pm4_me_gfx.trigger; //update if wait
|
||||
RTLEventWaitFor(me_idle_event);
|
||||
end;
|
||||
|
||||
procedure gc_imdone;
|
||||
var
|
||||
prev:QWORD;
|
||||
begin
|
||||
if (GC_SRI_event=nil) then Exit;
|
||||
if (pm4_me_gfx.started=nil) then Exit;
|
||||
{
|
||||
rw_wlock(ring_gfx_lock);
|
||||
|
||||
gc_wait_GC_SRI;
|
||||
|
||||
prev:=System.InterlockedExchange64(GC_SRI_label,1);
|
||||
|
||||
if (prev=0) then
|
||||
if (gc_priv.GC_SRI_label<>0) then
|
||||
begin
|
||||
if (gc_priv.GC_SRI_event<>nil) then
|
||||
begin
|
||||
//cv_broadcastpri
|
||||
RTLEventSetEvent(gc_priv.GC_SRI_event);
|
||||
end;
|
||||
|
||||
//gc_priv.GC_SRI_label:=0;
|
||||
|
||||
gc_retrigger_watchdog;
|
||||
|
||||
if (gc_submits_allowed_vmirr<>nil) then
|
||||
begin
|
||||
gc_submits_allowed_vmirr^:=1; //false
|
||||
gc_submits_allowed_vmirr^:=0; //true
|
||||
end;
|
||||
|
||||
retrigger_watchdog;
|
||||
pm4_me_gfx.imdone;
|
||||
|
||||
watchdog_label:=0; //thread can wait
|
||||
end;
|
||||
|
||||
gc_wait_GC_SRI;
|
||||
rw_wunlock(ring_gfx_lock);
|
||||
}
|
||||
end;
|
||||
}
|
||||
|
||||
procedure gc_imdone;
|
||||
begin
|
||||
//if (gc_priv.GC_SRI_event=nil) then Exit;
|
||||
if (pm4_me_gfx.started=nil) then Exit;
|
||||
|
||||
//gc_wait_GC_SRI;
|
||||
|
||||
mtx_lock(gc_priv.gc_suspend_lock);
|
||||
|
||||
gc_priv.sync_to_imdone:=0;
|
||||
|
||||
{
|
||||
if (gc_priv.pfp_label<>0) then
|
||||
begin
|
||||
gc_retrigger_watchdog;
|
||||
|
||||
_cv_wait_sig(@gc_priv.pfp_event,@gc_priv.GC_SRI_lock);
|
||||
end;
|
||||
}
|
||||
|
||||
if (gc_priv.GC_SRI_label<>0) then
|
||||
begin
|
||||
pm4_me_gfx.trigger; //update if wait
|
||||
|
||||
_cv_wait_sig(@gc_priv.GC_SRI_event,@gc_priv.gc_suspend_lock);
|
||||
end;
|
||||
|
||||
//gc_priv.pfp_label :=1;
|
||||
gc_priv.GC_SRI_label:=1;
|
||||
|
||||
mtx_unlock(gc_priv.gc_suspend_lock);
|
||||
|
||||
//gc_priv.GC_SRI_label:=1;
|
||||
|
||||
if (gc_submits_allowed_vmirr<>nil) then
|
||||
begin
|
||||
gc_submits_allowed_vmirr^:=1; //false
|
||||
end;
|
||||
|
||||
gc_priv.watchdog_label:=0; //thread can wait
|
||||
|
||||
//-> gc_imdone_tasklet
|
||||
|
||||
pm4_me_gfx.trigger; //update if wait
|
||||
|
||||
gc_imdone_tasklet;
|
||||
|
||||
pm4_me_gfx.imdone;
|
||||
|
||||
//gc_wait_GC_SRI;
|
||||
end;
|
||||
|
||||
Function gc_map_compute_queue(data:p_map_compute_queue_args):Integer;
|
||||
|
@ -844,33 +1022,33 @@ begin
|
|||
begin
|
||||
Writeln('sceGnmSubmitDone');
|
||||
|
||||
rw_wlock(ring_gfx_lock);
|
||||
//rw_wlock(ring_gfx_lock);
|
||||
|
||||
gc_imdone;
|
||||
gc_imdone;
|
||||
|
||||
rw_wunlock(ring_gfx_lock);
|
||||
//rw_wunlock(ring_gfx_lock);
|
||||
end;
|
||||
|
||||
$C0048117: //wait idle
|
||||
begin
|
||||
Writeln('gc_wait_idle');
|
||||
|
||||
rw_wlock(ring_gfx_lock);
|
||||
//rw_wlock(ring_gfx_lock);
|
||||
|
||||
gc_wait_GC_SRI;
|
||||
gc_wait_GC_SRI;
|
||||
|
||||
rw_wunlock(ring_gfx_lock);
|
||||
//rw_wunlock(ring_gfx_lock);
|
||||
end;
|
||||
|
||||
$C004811D: //????
|
||||
begin
|
||||
Writeln('gc_wait_free:',PInteger(data)^);
|
||||
|
||||
rw_wlock(ring_gfx_lock);
|
||||
//rw_wlock(ring_gfx_lock);
|
||||
|
||||
gc_wait_GC_SRI;
|
||||
gc_wait_GC_SRI;
|
||||
|
||||
rw_wunlock(ring_gfx_lock);
|
||||
//rw_wunlock(ring_gfx_lock);
|
||||
end;
|
||||
|
||||
$C0048114: //sceGnmFlushGarlic
|
||||
|
@ -886,27 +1064,25 @@ begin
|
|||
|
||||
rw_wlock(ring_gfx_lock);
|
||||
|
||||
//gc_retrigger_watchdog;
|
||||
|
||||
Result:=gc_submit_internal(@ring_gfx,
|
||||
p_submit_args(data)^.count,
|
||||
p_submit_args(data)^.cmds);
|
||||
|
||||
rw_wunlock(ring_gfx_lock);
|
||||
|
||||
if (Result=0) then
|
||||
begin
|
||||
retrigger_watchdog;
|
||||
|
||||
if sync_me_submit then
|
||||
if (Result=0) then
|
||||
begin
|
||||
//force wait GPU idle
|
||||
rw_wlock(ring_gfx_lock);
|
||||
gc_retrigger_watchdog;
|
||||
|
||||
gc_wait_GC_SRI;
|
||||
|
||||
rw_wunlock(ring_gfx_lock);
|
||||
if sync_me_submit then
|
||||
begin
|
||||
//force wait GPU idle
|
||||
gc_wait_GC_SRI;
|
||||
end;
|
||||
//msleep_td(hz);
|
||||
end;
|
||||
//msleep_td(hz);
|
||||
end;
|
||||
|
||||
rw_wunlock(ring_gfx_lock);
|
||||
|
||||
end;
|
||||
|
||||
|
@ -937,30 +1113,27 @@ begin
|
|||
);
|
||||
end;
|
||||
|
||||
rw_wunlock(ring_gfx_lock);
|
||||
if (Result=0) then
|
||||
begin
|
||||
gc_retrigger_watchdog;
|
||||
end;
|
||||
|
||||
if (Result=0) then
|
||||
begin
|
||||
retrigger_watchdog;
|
||||
end;
|
||||
rw_wunlock(ring_gfx_lock);
|
||||
end;
|
||||
|
||||
$C0088101: //switch_buffer
|
||||
begin
|
||||
start_gfx_ring;
|
||||
|
||||
rw_wlock(ring_gfx_lock);
|
||||
gc_retrigger_watchdog_imdone;
|
||||
|
||||
gc_wait_GC_SRI;
|
||||
|
||||
rw_wlock(ring_gfx_lock);
|
||||
|
||||
Result:=gc_switch_buffer_internal(@ring_gfx);
|
||||
|
||||
rw_wunlock(ring_gfx_lock);
|
||||
|
||||
if (Result=0) then
|
||||
begin
|
||||
retrigger_watchdog;
|
||||
end;
|
||||
end;
|
||||
|
||||
$C030810D: //sceGnmMapComputeQueue
|
||||
|
@ -972,12 +1145,12 @@ begin
|
|||
|
||||
Result:=gc_map_compute_queue(data);
|
||||
|
||||
rw_wunlock(ring_gfx_lock);
|
||||
if (Result=0) then
|
||||
begin
|
||||
gc_retrigger_watchdog;
|
||||
end;
|
||||
|
||||
if (Result=0) then
|
||||
begin
|
||||
retrigger_watchdog;
|
||||
end;
|
||||
rw_wunlock(ring_gfx_lock);
|
||||
end;
|
||||
|
||||
$C030811A: //sceGnmMapComputeQueueWithPriority
|
||||
|
@ -986,19 +1159,19 @@ begin
|
|||
|
||||
Result:=gc_map_compute_queue(data);
|
||||
|
||||
rw_wunlock(ring_gfx_lock);
|
||||
if (Result=0) then
|
||||
begin
|
||||
gc_retrigger_watchdog;
|
||||
end;
|
||||
|
||||
if (Result=0) then
|
||||
begin
|
||||
retrigger_watchdog;
|
||||
end;
|
||||
rw_wunlock(ring_gfx_lock);
|
||||
end;
|
||||
|
||||
$C00C810E: //sceGnmUnmapComputeQueue
|
||||
begin
|
||||
rw_wlock(ring_gfx_lock);
|
||||
gc_wait_GC_SRI;
|
||||
|
||||
gc_wait_GC_SRI;
|
||||
rw_wlock(ring_gfx_lock);
|
||||
|
||||
Result:=gc_unmap_compute_queue(data);
|
||||
|
||||
|
@ -1009,18 +1182,20 @@ begin
|
|||
begin
|
||||
start_gfx_ring;
|
||||
|
||||
rw_wlock(ring_gfx_lock);
|
||||
gc_retrigger_watchdog_imdone;
|
||||
|
||||
gc_wait_GC_SRI;
|
||||
gc_wait_GC_SRI;
|
||||
|
||||
rw_wlock(ring_gfx_lock);
|
||||
|
||||
Result:=gc_ding_dong(data);
|
||||
|
||||
rw_wunlock(ring_gfx_lock);
|
||||
if (Result=0) then
|
||||
begin
|
||||
gc_retrigger_watchdog;
|
||||
end;
|
||||
|
||||
if (Result=0) then
|
||||
begin
|
||||
retrigger_watchdog;
|
||||
end;
|
||||
rw_wunlock(ring_gfx_lock);
|
||||
end;
|
||||
|
||||
$C030811E: //sceGnmSetWaveLimitMultipliers
|
||||
|
@ -1335,7 +1510,7 @@ begin
|
|||
gc_ring_create(@ring_gfx,GC_RING_SIZE);
|
||||
|
||||
pm4_me_gfx.Init(@gc_knlist);
|
||||
pm4_me_gfx.on_idle:=@me_idle;
|
||||
pm4_me_gfx.on_idle:=@gc_idle;
|
||||
pm4_me_gfx.on_submit_flip_eop:=@dev_dce.TriggerFlipEop;
|
||||
end;
|
||||
|
||||
|
|
Loading…
Reference in New Issue