This commit is contained in:
Pavel 2024-05-22 11:00:40 +03:00
parent 66b9c5ece0
commit 4ab8a7069c
13 changed files with 462 additions and 77 deletions

View File

@ -36,6 +36,7 @@ uses
sys_event,
time,
md_time,
kern_thr,
md_sleep,
bittype,
@ -47,18 +48,23 @@ uses
si_ci_vi_merged_groups;
type
t_on_submit_flip_eop=function(submit_id:QWORD):Integer;
p_pm4_me=^t_pm4_me;
t_pm4_me=object
//
queue:TIntrusiveMPSCQueue; //p_pm4_stream
event:PRTLEvent;
on_idle:TProcedure;
on_submit_flip_eop:t_on_submit_flip_eop;
//
started:Pointer;
td:p_kthread;
//
gc_knlist:p_knlist;
//
rel_time:QWORD;
//
procedure Init(knlist:p_knlist);
procedure start;
procedure trigger;
@ -252,7 +258,10 @@ begin
for i:=0 to 31 do
begin
Assert(CX_REG^.SPI_PS_INPUT_CNTL[i].OFFSET =0,'SPI_PS_INPUT_CNTL['+IntToStr(i)+'].OFFSET=' +IntToStr(CX_REG^.SPI_PS_INPUT_CNTL[i].OFFSET ));
if (CX_REG^.SPI_PS_INPUT_CNTL[i].OFFSET<>0) and (CX_REG^.SPI_PS_INPUT_CNTL[i].OFFSET<>i) then
begin
Assert(false, 'SPI_PS_INPUT_CNTL['+IntToStr(i)+'].OFFSET=' +IntToStr(CX_REG^.SPI_PS_INPUT_CNTL[i].OFFSET ));
end;
Assert(CX_REG^.SPI_PS_INPUT_CNTL[i].DEFAULT_VAL =0,'SPI_PS_INPUT_CNTL['+IntToStr(i)+'].DEFAULT_VAL=' +IntToStr(CX_REG^.SPI_PS_INPUT_CNTL[i].DEFAULT_VAL ));
Assert(CX_REG^.SPI_PS_INPUT_CNTL[i].FLAT_SHADE =0,'SPI_PS_INPUT_CNTL['+IntToStr(i)+'].FLAT_SHADE=' +IntToStr(CX_REG^.SPI_PS_INPUT_CNTL[i].FLAT_SHADE ));
Assert(CX_REG^.SPI_PS_INPUT_CNTL[i].FP16_INTERP_MODE=0,'SPI_PS_INPUT_CNTL['+IntToStr(i)+'].FP16_INTERP_MODE='+IntToStr(CX_REG^.SPI_PS_INPUT_CNTL[i].FP16_INTERP_MODE));
@ -802,24 +811,63 @@ begin
CmdBuffer.Free;
end;
function mul_div_u64(m,d,v:QWORD):QWORD; sysv_abi_default; assembler; nostackframe;
asm
movq v,%rax
mulq m
divq d
end;
procedure pm4_EventWriteEop(node:p_pm4_node_EventWriteEop;me:p_pm4_me);
var
curr,diff:QWORD;
begin
EndFrameCapture;
curr:=md_rdtsc_unit;
diff:=curr-me^.rel_time;
if (node^.addr<>nil) then
Case node^.dataSel of
//
EVENTWRITEEOP_DATA_SEL_DISCARD :;
EVENTWRITEEOP_DATA_SEL_SEND_DATA32 :PDWORD(node^.addr)^:=node^.data;
EVENTWRITEEOP_DATA_SEL_SEND_DATA64 :PQWORD(node^.addr)^:=node^.data;
EVENTWRITEEOP_DATA_SEL_SEND_GPU_CLOCK :; //system 100Mhz global clock.
EVENTWRITEEOP_DATA_SEL_SEND_CP_PERFCOUNTER:; //GPU 800Mhz clock.
else;
EVENTWRITEEOP_DATA_SEL_DISCARD:;
//32bit data
EVENTWRITEEOP_DATA_SEL_SEND_DATA32:PDWORD(node^.addr)^:=node^.data;
//64bit data
EVENTWRITEEOP_DATA_SEL_SEND_DATA64:PQWORD(node^.addr)^:=node^.data;
//system 100Mhz global clock. (relative time)
EVENTWRITEEOP_DATA_SEL_SEND_GPU_CLOCK:PQWORD(node^.addr)^:=mul_div_u64(100*1000000,UNIT_PER_SEC,diff);
//GPU 800Mhz clock. (relative time)
EVENTWRITEEOP_DATA_SEL_SEND_CP_PERFCOUNTER:PQWORD(node^.addr)^:=mul_div_u64(800*1000000,UNIT_PER_SEC,diff);
else
Assert(false,'pm4_EventWriteEop');
end;
if (node^.intSel<>0) then
begin
//on submit eop
me^.knote_eventid($40,0,rdtsc(),0);
me^.knote_eventid($40,0,curr*NSEC_PER_UNIT,0); //(absolute time) (freq???)
end;
end;
procedure pm4_SubmitFlipEop(node:p_pm4_node_SubmitFlipEop;me:p_pm4_me);
var
curr:QWORD;
begin
if (me^.on_submit_flip_eop<>nil) then
begin
me^.on_submit_flip_eop(node^.eop_value);
end;
curr:=md_rdtsc_unit;
if (node^.intSel<>0) then
begin
me^.knote_eventid($40,0,curr*NSEC_PER_UNIT,0); //(absolute time) (freq???)
end;
end;
@ -837,6 +885,13 @@ begin
repeat
//start relative timer
if (me^.rel_time=0) then
begin
me^.rel_time:=md_rdtsc_unit;
end;
//
stream:=nil;
if me^.queue.Pop(stream) then
begin
@ -850,6 +905,7 @@ begin
ntDrawIndex2 :pm4_DrawIndex2 (Pointer(node));
ntDrawIndexAuto:pm4_DrawIndexAuto(Pointer(node));
ntEventWriteEop:pm4_EventWriteEop(Pointer(node),me);
ntSubmitFlipEop:pm4_SubmitFlipEop(Pointer(node),me);
else
end;
@ -862,6 +918,7 @@ begin
Continue;
end;
me^.rel_time:=0; //reset time
//
if (me^.on_idle<>nil) then
begin

View File

@ -6,6 +6,7 @@ unit pm4_pfp;
interface
uses
sysutils,
mqueue,
bittype,
pm4_ring,
@ -1305,8 +1306,8 @@ end;
procedure onIndexType(pctx:p_pfp_ctx;Body:PPM4CMDDRAWINDEXTYPE);
begin
Assert(Body^.swapMode=0);
pctx^.CX_REG.VGT_DMA_INDEX_TYPE.INDEX_TYPE:=Body^.indexType;
pctx^.CX_REG.VGT_DMA_INDEX_TYPE.SWAP_MODE :=Body^.swapMode;
pctx^.UC_REG.VGT_INDEX_TYPE.INDEX_TYPE :=Body^.indexType;
end;
@ -1373,6 +1374,17 @@ begin
pctx^.UC_REG);
end;
procedure onDispatchDirect(pctx:p_pfp_ctx;Body:PPM4CMDDISPATCHDIRECT);
begin
pctx^.SH_REG.COMPUTE_DIM_X:=Body^.dimX;
pctx^.SH_REG.COMPUTE_DIM_Y:=Body^.dimY;
pctx^.SH_REG.COMPUTE_DIM_Z:=Body^.dimZ;
pctx^.SH_REG.COMPUTE_DISPATCH_INITIATOR:=Body^.dispatchInitiator;
pctx^.stream_dcb.DispatchDirect(pctx^.SH_REG);
end;
procedure onPushMarker(Body:PChar);
begin
Writeln('\HINT_PUSH_MARKER:',Body);
@ -1524,7 +1536,7 @@ begin
IT_DRAW_INDEX_2 :onDrawIndex2 (pctx,buff);
IT_DRAW_INDEX_OFFSET_2:Assert(false,'IT_DRAW_INDEX_OFFSET_2');
IT_DRAW_INDEX_AUTO :onDrawIndexAuto (pctx,buff);
IT_DISPATCH_DIRECT :Assert(false,'IT_DISPATCH_DIRECT');
IT_DISPATCH_DIRECT :onDispatchDirect (pctx,buff);
IT_PFP_SYNC_ME :Assert(false,'IT_PFP_SYNC_ME');
IT_SET_BASE :onSetBase(buff);

View File

@ -9,30 +9,9 @@ uses
errno,
md_map,
systm,
pm4defs,
bittype;
type
//IT_INDIRECT_BUFFER_CNST = $00000033; ccb 0xc0023300
//IT_INDIRECT_BUFFER = $0000003f; dcb 0xc0023f00
PPM4CMDINDIRECTBUFFER=^PM4CMDINDIRECTBUFFER;
PM4CMDINDIRECTBUFFER=bitpacked record
header :DWORD; // PM4_TYPE_3_HEADER
ibBase :bit40; // Indirect buffer base address, must be 4 byte aligned
reserved0:bit24;
//
ibSize :bit20; // Indirect buffer size
reserved1:bit4;
vmid :bit4; // Virtual memory domain ID for command buffer
reserved2:bit4;
end;
PPM4CMDSWITCHBUFFER=^PM4CMDSWITCHBUFFER;
PM4CMDSWITCHBUFFER=bitpacked record
header:DWORD;
data :DWORD;
end;
const
GC_RING_SIZE=$80000;
GC_RING_PADD=64*1024;
@ -59,6 +38,7 @@ function gc_ring_pm4_drain(ring:p_pm4_ring;size:DWORD):Boolean;
function gc_submit_internal (ring:p_pm4_ring;count:DWORD;cmds:Pointer):Integer;
function gc_switch_buffer_internal(ring:p_pm4_ring):Integer;
function gc_pm4_event_write_eop (ring:p_pm4_ring;addr:Pointer;data:QWORD;intSel,wait:Integer):Integer;
implementation
@ -293,5 +273,43 @@ begin
gc_ring_pm4_submit(ring);
end;
function gc_pm4_event_write_eop(ring:p_pm4_ring;addr:Pointer;data:QWORD;intSel,wait:Integer):Integer;
var
buf:PPM4CMDEVENTWRITEEOP;
begin
Result:=0;
buf:=nil;
if not gc_ring_pm4_alloc(ring,sizeof(PM4CMDEVENTWRITEEOP),@buf) then
begin
Writeln(stderr,'### gc_pm4_event_write_eop : Cannot allocate a space in ring buffer.');
Exit(EBUSY);
end;
buf^:=Default(PM4CMDEVENTWRITEEOP);
// IT_EVENT_WRITE_EOP
DWORD(buf^.header):=$C0044700;
if (wait=0) then
begin
buf^.eventType:=kEopCbDbReadsDone;
end else
begin
buf^.eventType:=kEopFlushCbDbCaches;
end;
buf^.eventIndex :=5;
buf^.invalidateL2:=1;
buf^.address :=QWORD(addr);
buf^.intSel :=ord(intSel<>0)*2;
buf^.dataSel :=EVENTWRITEEOP_DATA_SEL_SEND_DATA64;
buf^.DATA :=data;
gc_ring_pm4_submit(ring);
end;
end.

View File

@ -55,13 +55,15 @@ type
ntEventWrite,
ntEventWriteEop,
ntEventWriteEos,
ntSubmitFlipEop,
ntDmaData,
ntWriteData,
ntWaitRegMem,
ntFastClear,
ntResolve,
ntDrawIndex2,
ntDrawIndexAuto
ntDrawIndexAuto,
ntDispatchDirect
);
p_pm4_node=^t_pm4_node;
@ -99,6 +101,12 @@ type
command :Byte;
end;
p_pm4_node_SubmitFlipEop=^t_pm4_node_SubmitFlipEop;
t_pm4_node_SubmitFlipEop=packed object(t_pm4_node)
eop_value:QWORD;
intSel :Byte
end;
p_pm4_node_DmaData=^t_pm4_node_DmaData;
t_pm4_node_DmaData=packed object(t_pm4_node)
dst :QWORD;
@ -151,6 +159,11 @@ type
UC_REG:TUSERCONFIG_REG_SHORT; // 0xC000
end;
p_pm4_node_DispatchDirect=^t_pm4_node_DispatchDirect;
t_pm4_node_DispatchDirect=object(t_pm4_node)
SH_REG:TSH_REG_GROUP; // 0x2C00
end;
p_pm4_stream=^t_pm4_stream;
t_pm4_stream=object
next_:Pointer;
@ -168,6 +181,7 @@ type
procedure EventWrite (eventType:Byte);
procedure EventWriteEop(addr:Pointer;data:QWORD;eventType,dataSel,intSel:Byte);
procedure EventWriteEos(addr:Pointer;data:DWORD;eventType,command:Byte);
procedure SubmitFlipEop(eop_value:QWORD;intSel:Byte);
procedure DmaData (dstSel:Byte;dst:QWORD;srcSel:Byte;srcOrData:QWORD;numBytes:DWORD;isBlocking:Byte);
procedure WriteData (dstSel:Byte;dst,src:QWORD;num_dw:Word);
procedure WaitRegMem (pollAddr:QWORD;refValue,mask:DWORD;compareFunc:Byte);
@ -181,6 +195,7 @@ type
procedure DrawIndexAuto(var SH_REG:TSH_REG_GROUP;
var CX_REG:TCONTEXT_REG_GROUP;
var UC_REG:TUSERCONFIG_REG_SHORT);
procedure DispatchDirect(var SH_REG:TSH_REG_GROUP);
end;
implementation
@ -272,6 +287,19 @@ begin
add_node(node);
end;
procedure t_pm4_stream.SubmitFlipEop(eop_value:QWORD;intSel:Byte);
var
node:p_pm4_node_SubmitFlipEop;
begin
node:=allocator.Alloc(SizeOf(t_pm4_node_SubmitFlipEop));
node^.ntype :=ntSubmitFlipEop;
node^.eop_value:=eop_value;
node^.intSel :=intSel;
add_node(node);
end;
procedure t_pm4_stream.DmaData(dstSel:Byte;dst:QWORD;srcSel:Byte;srcOrData:QWORD;numBytes:DWORD;isBlocking:Byte);
var
node:p_pm4_node_DmaData;
@ -409,6 +437,18 @@ begin
add_node(node);
end;
procedure t_pm4_stream.DispatchDirect(var SH_REG:TSH_REG_GROUP);
var
node:p_pm4_node_DispatchDirect;
begin
node:=allocator.Alloc(SizeOf(t_pm4_node_DispatchDirect));
node^.ntype :=ntDispatchDirect;
node^.SH_REG:=SH_REG;
add_node(node);
end;
//
procedure t_cache_block_allocator.init;

View File

@ -403,8 +403,8 @@ const
kEopCsDone = $00000028; //wait cs shader, label .....EOP
type
PPM4CMDEVENTWRITEEOP=^TPM4CMDEVENTWRITEEOP;
TPM4CMDEVENTWRITEEOP=bitpacked record
PPM4CMDEVENTWRITEEOP=^PM4CMDEVENTWRITEEOP;
PM4CMDEVENTWRITEEOP=bitpacked record
header :PM4_TYPE_3_HEADER;
eventType :bit6; //00 // < event type written to VGT_EVENT_INITIATOR
@ -739,6 +739,27 @@ type
dispatchInitiator:TCOMPUTE_DISPATCH_INITIATOR; ///< Dispatch Initiator Register
end;
//IT_INDIRECT_BUFFER_CNST = $00000033; ccb 0xc0023300
//IT_INDIRECT_BUFFER = $0000003f; dcb 0xc0023f00
PPM4CMDINDIRECTBUFFER=^PM4CMDINDIRECTBUFFER;
PM4CMDINDIRECTBUFFER=bitpacked record
header :DWORD; // PM4_TYPE_3_HEADER
ibBase :bit40; // Indirect buffer base address, must be 4 byte aligned
reserved0:bit24;
//
ibSize :bit20; // Indirect buffer size
reserved1:bit4;
vmid :bit4; // Virtual memory domain ID for command buffer
reserved2:bit4;
end;
PPM4CMDSWITCHBUFFER=^PM4CMDSWITCHBUFFER;
PM4CMDSWITCHBUFFER=bitpacked record
header:DWORD;
data :DWORD;
end;
TUSERCONFIG_REG_SHORT=packed record
CP_COHER_BASE_HI :TCP_COHER_BASE_HI; // 0xC079
CP_COHER_CNTL :TCP_COHER_CNTL; // 0xC07C

View File

@ -30,6 +30,9 @@ function DumpVS(var GPU_REGS:TGPU_REGS):RawByteString;
implementation
uses
kern_dmem;
Procedure DUMP_BLOCK(F:THandle;REG:WORD;P:Pointer;Size:DWORD);
const
MAX_SIZE=($FFFF+1)*4;
@ -173,6 +176,12 @@ begin
base:=GPU_REGS.get_code_addr(vShaderStageCs);
if (base<>nil) then
begin
if not get_dmem_ptr(base,@base,nil) then
begin
Assert(false,'DumpCS:get_dmem_ptr');
end;
size:=_calc_shader_size(base);
hash:=MurmurHash64A(base,size,0);
@ -216,6 +225,12 @@ begin
base:=GPU_REGS.get_code_addr(vShaderStagePs);
if (base<>nil) then
begin
if not get_dmem_ptr(base,@base,nil) then
begin
Assert(false,'DumpPS:get_dmem_ptr');
end;
size:=_calc_shader_size(base);
hash:=MurmurHash64A(base,size,0);
@ -268,6 +283,12 @@ begin
base:=GPU_REGS.get_code_addr(vShaderStageVs);
if (base<>nil) then
begin
if not get_dmem_ptr(base,@base,nil) then
begin
Assert(false,'DumpVS:get_dmem_ptr');
end;
size:=_calc_shader_size(base);
hash:=MurmurHash64A(base,size,0);

View File

@ -17,6 +17,8 @@ uses
procedure dce_initialize();
function TriggerFlipEop(submit_id:QWORD):Integer;
type
p_dce_page=^t_dce_page;
t_dce_page=packed record //0x170
@ -936,6 +938,17 @@ type
rout :PQWORD; //extraout of result
end;
function TriggerFlipEop(submit_id:QWORD):Integer;
begin
if (dce_handle=nil) then
begin
Result:=EINVAL;
end else
begin
Result:=dce_handle.TriggerFlipEop(submit_id);
end;
end;
Function dce_submit_flip(dev:p_cdev;data:p_submit_flip_args):Integer;
var
submit:t_submit_flip;

View File

@ -28,10 +28,13 @@ uses
kern_proc,
kern_thr,
md_sleep,
pm4defs,
pm4_ring,
pm4_pfp,
pm4_me,
dev_dce,
vDevice,
vMemory,
@ -128,6 +131,17 @@ var
pm4_me_gfx:t_pm4_me;
procedure onEventWriteEop(pctx:p_pfp_ctx;Body:PPM4CMDEVENTWRITEEOP);
var
submit_id:DWORD;
begin
submit_id:=Body^.DATA;
Writeln('submit eop flip:',submit_id);
pctx^.stream_dcb.SubmitFlipEop(Body^.DATA,(Body^.intSel shr 1));
end;
function pm4_parse_ring(pctx:p_pfp_ctx;token:DWORD;buff:Pointer):Integer;
var
ibuf:t_pm4_ibuffer;
@ -173,6 +187,10 @@ begin
Writeln('SWITCH_BUFFER');
end;
end;
$C0044700: //IT_EVENT_WRITE_EOP
begin
onEventWriteEop(pctx,buff);
end
else;
end;
@ -276,8 +294,6 @@ begin
if (GC_SRI_event=nil) then Exit;
if (pm4_me_gfx.started=nil) then Exit;
pm4_me_gfx.on_idle:=@gc_idle;
gc_wait_GC_SRI;
GC_SRI_label:=1;
@ -383,9 +399,9 @@ begin
$C0108102: //submit
begin
rw_wlock(ring_gfx_lock);
start_gfx_ring;
start_gfx_ring;
rw_wlock(ring_gfx_lock);
Result:=gc_submit_internal(@ring_gfx,
p_submit_args(data)^.count,
@ -396,11 +412,41 @@ begin
trigger_gfx_ring;
end;
$C0088101: //switch_buffer
$C020810C: //submit eop
begin
start_gfx_ring;
rw_wlock(ring_gfx_lock);
start_gfx_ring;
Result:=gc_submit_internal(@ring_gfx,
p_submit_args(data)^.count,
p_submit_args(data)^.cmds);
if (Result=0) then
begin
{
The original data is an incremental "submit_id | (vmid << 32)",
now this is directly sended "eop_v"
}
Result:=gc_pm4_event_write_eop(@ring_gfx,
nil,
p_submit_args(data)^.eop_v,
1,
p_submit_args(data)^.wait
);
end;
rw_wunlock(ring_gfx_lock);
trigger_gfx_ring;
end;
$C0088101: //switch_buffer
begin
start_gfx_ring;
rw_wlock(ring_gfx_lock);
Result:=gc_switch_buffer_internal(@ring_gfx);
@ -630,6 +676,8 @@ begin
gc_ring_create(@ring_gfx,GC_RING_SIZE);
pm4_me_gfx.Init(@gc_knlist);
pm4_me_gfx.on_idle:=@gc_idle;
pm4_me_gfx.on_submit_flip_eop:=@dev_dce.TriggerFlipEop;
end;

View File

@ -116,6 +116,7 @@ type
function UnregisterBuffer (index:Integer):Integer; virtual;
function SubmitFlip (submit:p_submit_flip):Integer; virtual;
function SubmitFlipEop (submit:p_submit_flip;submit_id:QWORD):Integer; virtual;
function TriggerFlipEop (submit_id:QWORD):Integer; virtual;
function Vblank ():Integer; virtual;
end;
@ -219,6 +220,11 @@ begin
Result:=0;
end;
function TDisplayHandle.TriggerFlipEop(submit_id:QWORD):Integer;
begin
Result:=0;
end;
function TDisplayHandle.Vblank():Integer;
begin
Result:=0;

View File

@ -29,20 +29,36 @@ type
end;
PQNode=^TQNode;
TOnParent=Procedure(node:PQNode) of object;
TQNode=object
next_ :PQNode;
next_:PQNode;
end;
PQNodeSubmit=^TQNodeSubmit;
TQNodeSubmit=object(TQNode)
submit:t_submit_flip;
tsc :QWORD;
end;
TSubmitQueue=object
FNodes:array[0..31] of TQNode;
TSubmitAlloc=object
FNodes:array[0..31] of TQNodeSubmit;
FAlloc:TIntrusiveMPSCQueue;
FQueue:TIntrusiveMPSCQueue;
Procedure Init;
function Alloc:PQNode;
procedure Free(P:PQNode);
function Alloc:PQNodeSubmit;
procedure Free(P:PQNodeSubmit);
end;
PQNodeFlip=^TQNodeFlip;
TQNodeFlip=object(TQNode)
submit :PQNodeSubmit;
submit_id:QWORD;
end;
TFlipAlloc=object
FNodes:array[0..17] of TQNodeFlip;
FAlloc:TIntrusiveMPSCQueue;
Procedure Init;
function Alloc:PQNodeFlip;
procedure Free(P:PQNodeFlip);
end;
TDisplayHandleSoft=class(TDisplayHandle)
@ -51,7 +67,12 @@ type
FEvent:PRTLEvent;
Ftd:p_kthread;
FQueue:TSubmitQueue;
FSubmitAlloc:TSubmitAlloc;
FSubmitQueue:TIntrusiveMPSCQueue;
FFlipAlloc:TFlipAlloc;
FTerminate:Boolean;
flip_rate:Integer;
@ -80,10 +101,11 @@ type
function RegisterBuffer (buf:p_register_buffer):Integer; override;
function UnregisterBuffer (index:Integer):Integer; override;
function SubmitFlip (submit:p_submit_flip):Integer; override;
//function SubmitFlipEop (submit:p_submit_flip;submit_id:QWORD):Integer; virtual;
function SubmitFlipEop (submit:p_submit_flip;submit_id:QWORD):Integer; override;
function TriggerFlipEop (submit_id:QWORD):Integer; override;
function Vblank ():Integer; override;
//
procedure OnSubmit(Node:PQNode);
procedure OnSubmit(Node:PQNodeSubmit);
end;
implementation
@ -100,30 +122,58 @@ uses
kern_dmem,
dev_dce;
Procedure TSubmitQueue.Init;
//
Procedure TSubmitAlloc.Init;
var
i:Integer;
begin
FAlloc.Create;
FQueue.Create;
For i:=0 to High(FNodes) do
begin
FAlloc.Push(@FNodes[i]);
end;
end;
function TSubmitQueue.Alloc:PQNode;
function TSubmitAlloc.Alloc:PQNodeSubmit;
begin
Result:=nil;
FAlloc.Pop(Result);
end;
procedure TSubmitQueue.Free(P:PQNode);
procedure TSubmitAlloc.Free(P:PQNodeSubmit);
begin
if (P=nil) then Exit;
FAlloc.Push(P);
end;
//
Procedure TFlipAlloc.Init;
var
i:Integer;
begin
FAlloc.Create;
For i:=0 to High(FNodes) do
begin
FAlloc.Push(@FNodes[i]);
end;
end;
function TFlipAlloc.Alloc:PQNodeFlip;
begin
Result:=nil;
FAlloc.Pop(Result);
end;
procedure TFlipAlloc.Free(P:PQNodeFlip);
begin
if (P=nil) then Exit;
FAlloc.Push(P);
end;
//
procedure dce_thread(parameter:pointer); SysV_ABI_CDecl; forward;
function TDisplayHandleSoft.Open():Integer;
@ -138,7 +188,10 @@ begin
FEvent:=RTLEventCreate;
FQueue.Init;
FSubmitAlloc.Init;
FSubmitQueue.Create;
FFlipAlloc.Init;
if (Ftd=nil) then
begin
@ -496,7 +549,7 @@ begin
bi.bmiHeader.biBitCount :=32;
bi.bmiHeader.biCompression:=BI_RGB;
if (attr^.attr.tilingMode<>0) then
if {(attr^.attr.tilingMode<>0)} false then
begin
//alloc aligned 128x128
bi.bmiHeader.biWidth :=(attr^.attr.pitchPixel+127) and (not 127);
@ -558,7 +611,7 @@ function TDisplayHandleSoft.SubmitFlip(submit:p_submit_flip):Integer;
var
buf :p_buffer;
attr:p_attr;
Node:PQNode;
Node:PQNodeSubmit;
begin
if (submit^.bufferIndex<>-1) then
begin
@ -568,29 +621,112 @@ begin
if (attr^.init=0) then Exit(EINVAL);
end;
Node:=FQueue.Alloc;
Node:=FSubmitAlloc.Alloc;
if (Node=nil) then Exit(EBUSY);
Node^.submit:=submit^;
Node^.tsc :=rdtsc();
FQueue.FQueue.Push(Node);
if (submit^.bufferIndex<>-1) then
begin
dce_page^.labels[submit^.bufferIndex]:=1;
end;
last_status.flipPendingNum0:=last_status.flipPendingNum0+1;
//
System.InterlockedIncrement(last_status.flipPendingNum0);
if (submit^.flipMode=SCE_VIDEO_OUT_FLIP_MODE_HSYNC) then
FSubmitQueue.Push(Node);
if (Node^.submit.flipMode=SCE_VIDEO_OUT_FLIP_MODE_HSYNC) then
begin
RTLEventSetEvent(FEvent);
end;
//
Result:=0;
end;
function TDisplayHandleSoft.SubmitFlipEop(submit:p_submit_flip;submit_id:QWORD):Integer;
var
buf :p_buffer;
attr:p_attr;
Node:PQNodeSubmit;
Flip:PQNodeFlip;
begin
if (submit^.bufferIndex<>-1) then
begin
buf:=@m_bufs[submit^.bufferIndex];
if (buf^.init=0) then Exit(EINVAL);
attr:=@m_attr[buf^.attr];
if (attr^.init=0) then Exit(EINVAL);
end;
Node:=FSubmitAlloc.Alloc;
if (Node=nil) then Exit(EBUSY);
Flip:=FFlipAlloc.Alloc;
if (Flip=nil) then Exit(EBUSY);
Node^.submit:=submit^;
Node^.tsc :=rdtsc();
Flip^.next_ :=nil;
Flip^.submit :=Node;
Flip^.submit_id:=submit_id;
if (submit^.bufferIndex<>-1) then
begin
dce_page^.labels[submit^.bufferIndex]:=1;
end;
System.InterlockedIncrement(last_status.gcQueueNum);
Result:=0;
end;
function TDisplayHandleSoft.TriggerFlipEop(submit_id:QWORD):Integer;
var
Node:PQNodeSubmit;
Flip:PQNodeFlip;
i:Integer;
begin
Result:=0;
//
For i:=0 to High(FFlipAlloc.FNodes) do
begin
Flip:=@FFlipAlloc.FNodes[i];
if (Flip^.next_=nil) and
(Flip^.submit<>nil) and
(Flip^.submit_id=submit_id) then
begin
Node:=Flip^.submit;
Flip^.submit :=nil;
Flip^.submit_id:=0;
FFlipAlloc.Free(Flip);
System.InterlockedDecrement(last_status.gcQueueNum);
//
System.InterlockedIncrement(last_status.flipPendingNum0);
FSubmitQueue.Push(Node);
if (Node^.submit.flipMode=SCE_VIDEO_OUT_FLIP_MODE_HSYNC) then
begin
RTLEventSetEvent(FEvent);
end;
//
Exit;
end;
end;
//
Result:=1;
end;
function TDisplayHandleSoft.Vblank():Integer;
begin
vblank_count:=vblank_count+1;
@ -604,7 +740,7 @@ begin
Result:=0;
end;
procedure TDisplayHandleSoft.OnSubmit(Node:PQNode);
procedure TDisplayHandleSoft.OnSubmit(Node:PQNodeSubmit);
var
i:Integer;
submit:p_submit_flip;
@ -645,7 +781,8 @@ begin
end;
dce_page^.label_:=0;
last_status.flipPendingNum0:=last_status.flipPendingNum0-1;
System.InterlockedDecrement(last_status.flipPendingNum0);
last_status.flipArg :=submit^.flipArg;
last_status.flipArg2 :=submit^.flipArg2;
last_status.count :=last_status.count+1;
@ -678,7 +815,7 @@ end;
procedure dce_thread(parameter:pointer); SysV_ABI_CDecl;
var
dce:TDisplayHandleSoft;
Node:PQNode;
Node:PQNodeSubmit;
begin
dce:=TDisplayHandleSoft(parameter);
@ -686,10 +823,10 @@ begin
RTLEventWaitFor(dce.FEvent);
Node:=nil;
if dce.FQueue.FQueue.Pop(Node) then
if dce.FSubmitQueue.Pop(Node) then
begin
dce.OnSubmit(Node);
dce.FQueue.Free(Node);
dce.FSubmitAlloc.Free(Node);
end;
until dce.FTerminate;

View File

@ -241,6 +241,7 @@ end;
function ProcessException(p:PExceptionPointers):longint; stdcall;
begin
Result:=EXCEPTION_CONTINUE_SEARCH;
if (curkthread=nil) then Exit;
case p^.ExceptionRecord^.ExceptionCode of
FPC_EXCEPTION_CODE :Exit;
@ -272,7 +273,6 @@ end;
function UnhandledException(p:PExceptionPointers):longint; stdcall;
var
td:p_kthread;
rec:PExceptionRecord;
code: Longint;
ExObj:Exception;
@ -280,14 +280,15 @@ begin
Result:=EXCEPTION_CONTINUE_SEARCH;
case p^.ExceptionRecord^.ExceptionCode of
FPC_EXCEPTION_CODE :Exit;
FPC_SET_EH_HANDLER :Exit(EXCEPTION_CONTINUE_EXECUTION);
EXCEPTION_BREAKPOINT :Exit;
EXCEPTION_SET_THREADNAME:Exit;
FPC_EXCEPTION_CODE :Exit;
FPC_SET_EH_HANDLER :Exit(EXCEPTION_CONTINUE_EXECUTION);
EXCEPTION_BREAKPOINT :Exit;
EXCEPTION_SET_THREADNAME :Exit;
DBG_PRINTEXCEPTION_C :Exit(EXCEPTION_CONTINUE_EXECUTION);
DBG_PRINTEXCEPTION_WIDE_C:Exit(EXCEPTION_CONTINUE_EXECUTION); //RenderDoc issuse
end;
td:=curkthread;
if (td=nil) then Exit;
if (curkthread=nil) then Exit;
rec:=p^.ExceptionRecord;
@ -304,8 +305,10 @@ begin
ExObj:=Exception(TExceptObjProc(ExceptObjProc)(abs(code),rec^));
end;
if curkthread<>nil then
if (curkthread<>nil) then
begin
Writeln('curkthread^.td_name:',curkthread^.td_name);
end;
if (ExObj=nil) then
begin

View File

@ -308,9 +308,13 @@ end;
function itimerfix(tv:p_timeval):Integer;
begin
if (tv^.tv_sec < 0) or (tv^.tv_usec < 0) or (tv^.tv_usec >= 1000000) then
begin
Exit(EINVAL);
end;
if (tv^.tv_sec=0) and (tv^.tv_usec<>0) and (tv^.tv_usec < tick) then
begin
tv^.tv_usec:=tick;
end;
Exit(0);
end;

View File

@ -1403,6 +1403,11 @@ end;
function TGPU_REGS.GET_INDEX_TYPE:TVkIndexType;
begin
if (CX_REG^.VGT_DMA_INDEX_TYPE.SWAP_MODE<>0) then
begin
Assert(false,'swapMode:'+IntToStr(CX_REG^.VGT_DMA_INDEX_TYPE.SWAP_MODE));
end;
Case UC_REG^.VGT_INDEX_TYPE.INDEX_TYPE of
VGT_INDEX_16:Result:=VK_INDEX_TYPE_UINT16;
VGT_INDEX_32:Result:=VK_INDEX_TYPE_UINT32;