mirror of https://github.com/red-prig/fpPS4.git
2299 lines
64 KiB
Plaintext
2299 lines
64 KiB
Plaintext
unit pm4_pfp;
|
|
|
|
{$mode ObjFPC}{$H+}
|
|
{$CALLING SysV_ABI_CDecl}
|
|
|
|
interface
|
|
|
|
uses
|
|
sysutils,
|
|
mqueue,
|
|
pm4defs,
|
|
pm4_stream,
|
|
time,
|
|
md_sleep,
|
|
si_ci_vi_merged_offset,
|
|
si_ci_vi_merged_enum,
|
|
si_ci_vi_merged_registers,
|
|
si_ci_vi_merged_groups;
|
|
|
|
type
|
|
p_pfp_ctx=^t_pfp_ctx;
|
|
|
|
t_pm4_parse_cb=function(pctx:p_pfp_ctx;token:DWORD;buff:Pointer):Integer;
|
|
|
|
p_pm4_ibuffer=^t_pm4_ibuffer;
|
|
t_pm4_ibuffer=record
|
|
next:TAILQ_ENTRY;
|
|
base:Pointer;
|
|
buff:Pointer;
|
|
size:Ptruint;
|
|
bpos:Ptruint;
|
|
picb:t_pm4_parse_cb;
|
|
buft:t_pm4_stream_type;
|
|
c_id:Byte;
|
|
end;
|
|
|
|
t_flush_stream=procedure(var stream:t_pm4_stream) of object;
|
|
|
|
t_pfp_ctx=object
|
|
freen:TAILQ_HEAD;
|
|
stall:array[t_pm4_stream_type] of TAILQ_HEAD;
|
|
//
|
|
stream:array[t_pm4_stream_type] of t_pm4_stream;
|
|
//
|
|
on_flush_stream:t_flush_stream;
|
|
//
|
|
SG_REG:TSH_REG_GFX_GROUP; // 0x2C00
|
|
SC_REG:TSH_REG_COMPUTE_GROUP; // 0x2E00
|
|
CX_REG:TCONTEXT_REG_GROUP; // 0xA000
|
|
UC_REG:TUSERCONFIG_REG_SHORT; // 0xC000
|
|
//
|
|
ASC_COMPUTE:array[0..63] of TSH_REG_COMPUTE_GROUP;
|
|
//
|
|
PixelPipeStatControl:TPixelPipeStatControl;
|
|
//
|
|
curr_ibuf :p_pm4_ibuffer;
|
|
//
|
|
LastSetReg:Word;
|
|
event:PRTLEvent;
|
|
//
|
|
function stream_type:t_pm4_stream_type;
|
|
procedure init;
|
|
procedure add_stall(ibuf:p_pm4_ibuffer);
|
|
procedure free;
|
|
//
|
|
Procedure Flush_stream(t:t_pm4_stream_type);
|
|
//
|
|
procedure set_esgs_gsvs_ring_size(esgsRingSize,gsvsRingSize:DWORD);
|
|
//
|
|
procedure set_reg(i:word;data:DWORD);
|
|
procedure set_sh_reg(i:word;data:DWORD);
|
|
procedure set_sh_reg_compute(i:word;data:DWORD);
|
|
procedure set_ctx_reg(i:word;data:DWORD);
|
|
function get_reg(i:word):DWORD;
|
|
procedure clear_state;
|
|
end;
|
|
|
|
function pm4_ibuf_init(ibuf:p_pm4_ibuffer;
|
|
buff:Pointer;
|
|
size:Ptruint;
|
|
icb:t_pm4_parse_cb;
|
|
buft:t_pm4_stream_type;
|
|
c_id:Byte=0):Boolean;
|
|
|
|
function pm4_ibuf_init(ibuf:p_pm4_ibuffer;
|
|
buf:PPM4CMDINDIRECTBUFFER;
|
|
icb:t_pm4_parse_cb;
|
|
buft:t_pm4_stream_type):Boolean;
|
|
|
|
function pm4_ibuf_parse(pctx:p_pfp_ctx;ibuf:p_pm4_ibuffer):Integer;
|
|
|
|
function pm4_parse_ccb(pctx:p_pfp_ctx;token:DWORD;buff:Pointer):Integer;
|
|
function pm4_parse_dcb(pctx:p_pfp_ctx;token:DWORD;buff:Pointer):Integer;
|
|
function pm4_parse_compute_ring(pctx:p_pfp_ctx;token:DWORD;buff:Pointer):Integer;
|
|
|
|
implementation
|
|
|
|
uses
|
|
sys_bootparam,
|
|
kern_dmem,
|
|
kern_proc,
|
|
vm_map,
|
|
vm_tracking_map;
|
|
|
|
function PM4_TYPE(token:DWORD):Byte; inline;
|
|
begin
|
|
Result:=(token shr 30) and 3;
|
|
end;
|
|
|
|
function PM4_LENGTH(token:DWORD):DWORD; inline;
|
|
begin
|
|
Result:=((token shr 14) and $FFFC) + 8;
|
|
end;
|
|
|
|
function pm4_ibuf_init(ibuf:p_pm4_ibuffer;
|
|
buff:Pointer;
|
|
size:Ptruint;
|
|
icb:t_pm4_parse_cb;
|
|
buft:t_pm4_stream_type;
|
|
c_id:Byte=0):Boolean;
|
|
begin
|
|
Result:=True;
|
|
ibuf^.next:=Default(TAILQ_ENTRY);
|
|
ibuf^.base:=nil;
|
|
ibuf^.buff:=buff;
|
|
ibuf^.size:=size;
|
|
ibuf^.bpos:=0;
|
|
ibuf^.picb:=icb;
|
|
ibuf^.buft:=buft;
|
|
ibuf^.c_id:=c_id;
|
|
end;
|
|
|
|
function pm4_ibuf_init(ibuf:p_pm4_ibuffer;
|
|
buf:PPM4CMDINDIRECTBUFFER;
|
|
icb:t_pm4_parse_cb;
|
|
buft:t_pm4_stream_type):Boolean;
|
|
var
|
|
ib_base:QWORD;
|
|
ib_size:QWORD;
|
|
addr:Pointer;
|
|
begin
|
|
Result:=False;
|
|
|
|
case buf^.header.opcode of
|
|
IT_INDIRECT_BUFFER_CNST:;
|
|
IT_INDIRECT_BUFFER :;
|
|
else
|
|
begin
|
|
Writeln('init not indirect buffer:0x',HexStr(DWORD(buf^.header),8));
|
|
Assert(false,'init not indirect buffer');
|
|
end;
|
|
end;
|
|
|
|
ib_base:=QWORD(buf^.ibBase);
|
|
ib_size:=QWORD(buf^.ibSize)*sizeof(DWORD);
|
|
|
|
addr:=get_dmem_ptr(Pointer(ib_base));
|
|
|
|
//Writeln(' addr:0x'+HexStr(ib_base,16)+' '+HexStr(ib_size,16));
|
|
|
|
ibuf^.next:=Default(TAILQ_ENTRY);
|
|
ibuf^.base:=Pointer(ib_base); //adjust guest addr
|
|
ibuf^.buff:=addr;
|
|
ibuf^.size:=ib_size;
|
|
ibuf^.bpos:=0;
|
|
ibuf^.picb:=icb;
|
|
ibuf^.buft:=buft;
|
|
ibuf^.c_id:=0;
|
|
|
|
Result:=True;
|
|
end;
|
|
|
|
function pm4_ibuf_parse(pctx:p_pfp_ctx;ibuf:p_pm4_ibuffer):Integer;
|
|
var
|
|
buff:Pointer;
|
|
i,token,len:DWORD;
|
|
begin
|
|
Result:=0;
|
|
|
|
pctx^.curr_ibuf :=ibuf;
|
|
|
|
case pctx^.stream_type of
|
|
stGfxDcb,
|
|
stGfxCcb:pctx^.LastSetReg:=0;
|
|
else;
|
|
end;
|
|
|
|
i:=ibuf^.bpos;
|
|
buff:=ibuf^.buff+i;
|
|
i:=ibuf^.size-i;
|
|
|
|
while (i<>0) do
|
|
begin
|
|
token:=PDWORD(buff)^;
|
|
|
|
if (PM4_TYPE(token)=2) then
|
|
begin
|
|
len:=sizeof(DWORD);
|
|
end else
|
|
begin
|
|
len:=PM4_LENGTH(token);
|
|
end;
|
|
|
|
if (len>i) then
|
|
begin
|
|
i:=0;
|
|
Break;
|
|
end;
|
|
|
|
Result:=ibuf^.picb(pctx,token,buff);
|
|
if (Result<>0) then
|
|
begin
|
|
Break;
|
|
end;
|
|
|
|
Inc(buff,len);
|
|
Dec(i,len);
|
|
end;
|
|
|
|
ibuf^.bpos:=ibuf^.size-i;
|
|
|
|
pctx^.curr_ibuf:=nil;
|
|
end;
|
|
|
|
function t_pfp_ctx.stream_type:t_pm4_stream_type;
|
|
begin
|
|
Result:=curr_ibuf^.buft;
|
|
end;
|
|
|
|
procedure t_pfp_ctx.init;
|
|
var
|
|
i:t_pm4_stream_type;
|
|
begin
|
|
for i:=Low(t_pm4_stream_type) to High(t_pm4_stream_type) do
|
|
begin
|
|
stream[i]:=Default(t_pm4_stream);
|
|
stream[i].buft:=i;
|
|
end;
|
|
end;
|
|
|
|
procedure t_pfp_ctx.add_stall(ibuf:p_pm4_ibuffer);
|
|
var
|
|
node:p_pm4_ibuffer;
|
|
buft:t_pm4_stream_type;
|
|
begin
|
|
node:=TAILQ_FIRST(@freen);
|
|
if (node<>nil) then
|
|
begin
|
|
TAILQ_REMOVE(@freen,node,@node^.next);
|
|
end else
|
|
begin
|
|
node:=AllocMem(SizeOf(t_pm4_ibuffer));
|
|
end;
|
|
|
|
node^:=ibuf^;
|
|
|
|
buft:=node^.buft;
|
|
|
|
if (stall[buft].tqh_last=nil) then
|
|
begin
|
|
TAILQ_INIT(@stall[buft]);
|
|
end;
|
|
|
|
TAILQ_INSERT_TAIL(@stall[buft],node,@node^.next);
|
|
end;
|
|
|
|
procedure free_nodes(head:P_TAILQ_HEAD);
|
|
var
|
|
node:p_pm4_ibuffer;
|
|
begin
|
|
node:=TAILQ_FIRST(head);
|
|
while (node<>nil) do
|
|
begin
|
|
TAILQ_REMOVE(head,node,@node^.next);
|
|
FreeMem(node);
|
|
node:=TAILQ_FIRST(head);
|
|
end;
|
|
end;
|
|
|
|
procedure t_pfp_ctx.free;
|
|
var
|
|
i:t_pm4_stream_type;
|
|
begin
|
|
free_nodes(@freen);
|
|
|
|
for i:=Low(t_pm4_stream_type) to High(t_pm4_stream_type) do
|
|
begin
|
|
free_nodes(@stall[i]);
|
|
end;
|
|
end;
|
|
|
|
Procedure t_pfp_ctx.Flush_stream(t:t_pm4_stream_type);
|
|
begin
|
|
Assert(on_flush_stream<>nil,'on_flush_stream');
|
|
|
|
on_flush_stream(stream[t]);
|
|
end;
|
|
|
|
procedure t_pfp_ctx.set_esgs_gsvs_ring_size(esgsRingSize,gsvsRingSize:DWORD);
|
|
begin
|
|
UC_REG.VGT_ESGS_RING_SIZE:=esgsRingSize;
|
|
UC_REG.VGT_GSVS_RING_SIZE:=gsvsRingSize;
|
|
end;
|
|
|
|
procedure t_pfp_ctx.set_reg(i:word;data:DWORD);
|
|
begin
|
|
case i of
|
|
$2C00..$2D8C:PDWORD(@SG_REG)[i-$2C00]:=data;
|
|
$2E00..$2E7F:PDWORD(@SC_REG)[i-$2E00]:=data;
|
|
$A000..$A38F:PDWORD(@CX_REG)[i-$A000]:=data;
|
|
$C079:PDWORD(@UC_REG.CP_COHER_BASE_HI )^:=data;
|
|
$C07C:PDWORD(@UC_REG.CP_COHER_CNTL )^:=data;
|
|
$C07D:PDWORD(@UC_REG.CP_COHER_SIZE )^:=data;
|
|
$C07E:PDWORD(@UC_REG.CP_COHER_BASE )^:=data;
|
|
$C08C:PDWORD(@UC_REG.CP_COHER_SIZE_HI )^:=data;
|
|
$C200:PDWORD(@UC_REG.GRBM_GFX_INDEX )^:=data;
|
|
$C240:PDWORD(@UC_REG.VGT_ESGS_RING_SIZE)^:=data;
|
|
$C241:PDWORD(@UC_REG.VGT_GSVS_RING_SIZE)^:=data;
|
|
$C242:PDWORD(@UC_REG.VGT_PRIMITIVE_TYPE)^:=data;
|
|
$C243:PDWORD(@UC_REG.VGT_INDEX_TYPE )^:=data;
|
|
$C24C:PDWORD(@UC_REG.VGT_NUM_INDICES )^:=data;
|
|
$C24D:PDWORD(@UC_REG.VGT_NUM_INSTANCES )^:=data;
|
|
$C258:PDWORD(@CX_REG.IA_MULTI_VGT_PARAM)^:=data;
|
|
else
|
|
if p_print_gpu_ops then
|
|
begin
|
|
Writeln(stderr,'Unknow:',getRegName(i),':=0x',HexStr(data,8));
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure t_pfp_ctx.set_sh_reg(i:word;data:DWORD);
|
|
begin
|
|
case i of
|
|
$000..$18C:PDWORD(@SG_REG)[i]:=data;
|
|
$200..$27F:PDWORD(@SC_REG)[i-$200]:=data;
|
|
else
|
|
if p_print_gpu_ops then
|
|
begin
|
|
Writeln(stderr,'Unknow:',getRegName(i+$2C00),':=0x',HexStr(data,8));
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure t_pfp_ctx.set_sh_reg_compute(i:word;data:DWORD);
|
|
var
|
|
c_id:Byte;
|
|
begin
|
|
c_id:=curr_ibuf^.c_id;
|
|
|
|
case i of
|
|
$200..$27F:PDWORD(@ASC_COMPUTE[c_id])[i-$200]:=data;
|
|
else
|
|
if p_print_gpu_ops then
|
|
begin
|
|
Writeln(stderr,'Unknow:',getRegName(i+$2C00),':=0x',HexStr(data,8));
|
|
end;
|
|
end;
|
|
|
|
end;
|
|
|
|
procedure t_pfp_ctx.set_ctx_reg(i:word;data:DWORD);
|
|
begin
|
|
if (i<=$38F) then
|
|
begin
|
|
PDWORD(@CX_REG)[i]:=data;
|
|
end else
|
|
if p_print_gpu_ops then
|
|
begin
|
|
Writeln(stderr,'Unknow:',getRegName(i+$A000),':=0x',HexStr(data,8));
|
|
end;
|
|
end;
|
|
|
|
function t_pfp_ctx.get_reg(i:word):DWORD;
|
|
begin
|
|
case i of
|
|
$2C00..$2D8C:Result:=PDWORD(@SG_REG)[i-$2C00];
|
|
$2E00..$2E7F:Result:=PDWORD(@SC_REG)[i-$2E00];
|
|
$A000..$A38F:Result:=PDWORD(@CX_REG)[i-$A000];
|
|
$C079:Result:=PDWORD(@UC_REG.CP_COHER_BASE_HI )^;
|
|
$C07C:Result:=PDWORD(@UC_REG.CP_COHER_CNTL )^;
|
|
$C07D:Result:=PDWORD(@UC_REG.CP_COHER_SIZE )^;
|
|
$C07E:Result:=PDWORD(@UC_REG.CP_COHER_BASE )^;
|
|
$C08C:Result:=PDWORD(@UC_REG.CP_COHER_SIZE_HI )^;
|
|
$C200:Result:=PDWORD(@UC_REG.GRBM_GFX_INDEX )^;
|
|
$C240:Result:=PDWORD(@UC_REG.VGT_ESGS_RING_SIZE)^;
|
|
$C241:Result:=PDWORD(@UC_REG.VGT_GSVS_RING_SIZE)^;
|
|
$C242:Result:=PDWORD(@UC_REG.VGT_PRIMITIVE_TYPE)^;
|
|
$C243:Result:=PDWORD(@UC_REG.VGT_INDEX_TYPE )^;
|
|
$C24C:Result:=PDWORD(@UC_REG.VGT_NUM_INDICES )^;
|
|
$C24D:Result:=PDWORD(@UC_REG.VGT_NUM_INSTANCES )^;
|
|
$C258:Result:=PDWORD(@CX_REG.IA_MULTI_VGT_PARAM)^;
|
|
else
|
|
Result:=0;
|
|
end;
|
|
end;
|
|
|
|
procedure t_pfp_ctx.clear_state;
|
|
begin
|
|
PDWORD(@CX_REG)[$000]:=$00000000;
|
|
PDWORD(@CX_REG)[$001]:=$00000000;
|
|
PDWORD(@CX_REG)[$002]:=$00000000;
|
|
PDWORD(@CX_REG)[$003]:=$00000000;
|
|
PDWORD(@CX_REG)[$004]:=$00000000;
|
|
PDWORD(@CX_REG)[$005]:=$00000000;
|
|
PDWORD(@CX_REG)[$008]:=$00000000;
|
|
PDWORD(@CX_REG)[$009]:=$00000000;
|
|
PDWORD(@CX_REG)[$00a]:=$00000000;
|
|
PDWORD(@CX_REG)[$00b]:=$00000000;
|
|
PDWORD(@CX_REG)[$00c]:=$00000000;
|
|
PDWORD(@CX_REG)[$00d]:=$40004000;
|
|
PDWORD(@CX_REG)[$00f]:=$00000000;
|
|
PDWORD(@CX_REG)[$010]:=$00000000;
|
|
PDWORD(@CX_REG)[$011]:=$00000000;
|
|
PDWORD(@CX_REG)[$012]:=$00000000;
|
|
PDWORD(@CX_REG)[$013]:=$00000000;
|
|
PDWORD(@CX_REG)[$014]:=$00000000;
|
|
PDWORD(@CX_REG)[$015]:=$00000000;
|
|
PDWORD(@CX_REG)[$016]:=$00000000;
|
|
PDWORD(@CX_REG)[$017]:=$00000000;
|
|
PDWORD(@CX_REG)[$020]:=$00000000;
|
|
PDWORD(@CX_REG)[$021]:=$00000000;
|
|
PDWORD(@CX_REG)[$07a]:=$00000000;
|
|
PDWORD(@CX_REG)[$07b]:=$00000000;
|
|
PDWORD(@CX_REG)[$07c]:=$00000000;
|
|
PDWORD(@CX_REG)[$07d]:=$00000000;
|
|
PDWORD(@CX_REG)[$07e]:=$00000000;
|
|
PDWORD(@CX_REG)[$07f]:=$00000000;
|
|
PDWORD(@CX_REG)[$080]:=$00000000;
|
|
PDWORD(@CX_REG)[$081]:=$80000000;
|
|
PDWORD(@CX_REG)[$082]:=$40004000;
|
|
PDWORD(@CX_REG)[$084]:=$00000000;
|
|
PDWORD(@CX_REG)[$085]:=$40004000;
|
|
PDWORD(@CX_REG)[$086]:=$00000000;
|
|
PDWORD(@CX_REG)[$087]:=$40004000;
|
|
PDWORD(@CX_REG)[$088]:=$00000000;
|
|
PDWORD(@CX_REG)[$089]:=$40004000;
|
|
PDWORD(@CX_REG)[$08a]:=$00000000;
|
|
PDWORD(@CX_REG)[$08b]:=$40004000;
|
|
PDWORD(@CX_REG)[$08c]:=$aa99aaaa;
|
|
PDWORD(@CX_REG)[$08d]:=$00000000;
|
|
PDWORD(@CX_REG)[$090]:=$80000000;
|
|
PDWORD(@CX_REG)[$091]:=$40004000;
|
|
PDWORD(@CX_REG)[$092]:=$00000000;
|
|
PDWORD(@CX_REG)[$093]:=$00000000;
|
|
PDWORD(@CX_REG)[$094]:=$80000000;
|
|
PDWORD(@CX_REG)[$095]:=$40004000;
|
|
PDWORD(@CX_REG)[$096]:=$80000000;
|
|
PDWORD(@CX_REG)[$097]:=$40004000;
|
|
PDWORD(@CX_REG)[$098]:=$80000000;
|
|
PDWORD(@CX_REG)[$099]:=$40004000;
|
|
PDWORD(@CX_REG)[$09a]:=$80000000;
|
|
PDWORD(@CX_REG)[$09b]:=$40004000;
|
|
PDWORD(@CX_REG)[$09c]:=$80000000;
|
|
PDWORD(@CX_REG)[$09d]:=$40004000;
|
|
PDWORD(@CX_REG)[$09e]:=$80000000;
|
|
PDWORD(@CX_REG)[$09f]:=$40004000;
|
|
PDWORD(@CX_REG)[$0a0]:=$80000000;
|
|
PDWORD(@CX_REG)[$0a1]:=$40004000;
|
|
PDWORD(@CX_REG)[$0a2]:=$80000000;
|
|
PDWORD(@CX_REG)[$0a3]:=$40004000;
|
|
PDWORD(@CX_REG)[$0a4]:=$80000000;
|
|
PDWORD(@CX_REG)[$0a5]:=$40004000;
|
|
PDWORD(@CX_REG)[$0a6]:=$80000000;
|
|
PDWORD(@CX_REG)[$0a7]:=$40004000;
|
|
PDWORD(@CX_REG)[$0a8]:=$80000000;
|
|
PDWORD(@CX_REG)[$0a9]:=$40004000;
|
|
PDWORD(@CX_REG)[$0aa]:=$80000000;
|
|
PDWORD(@CX_REG)[$0ab]:=$40004000;
|
|
PDWORD(@CX_REG)[$0ac]:=$80000000;
|
|
PDWORD(@CX_REG)[$0ad]:=$40004000;
|
|
PDWORD(@CX_REG)[$0ae]:=$80000000;
|
|
PDWORD(@CX_REG)[$0af]:=$40004000;
|
|
PDWORD(@CX_REG)[$0b0]:=$80000000;
|
|
PDWORD(@CX_REG)[$0b1]:=$40004000;
|
|
PDWORD(@CX_REG)[$0b2]:=$80000000;
|
|
PDWORD(@CX_REG)[$0b3]:=$40004000;
|
|
PDWORD(@CX_REG)[$0b4]:=$00000000;
|
|
PDWORD(@CX_REG)[$0b5]:=$3f800000;
|
|
PDWORD(@CX_REG)[$0b6]:=$00000000;
|
|
PDWORD(@CX_REG)[$0b7]:=$3f800000;
|
|
PDWORD(@CX_REG)[$0b8]:=$00000000;
|
|
PDWORD(@CX_REG)[$0b9]:=$3f800000;
|
|
PDWORD(@CX_REG)[$0ba]:=$00000000;
|
|
PDWORD(@CX_REG)[$0bb]:=$3f800000;
|
|
PDWORD(@CX_REG)[$0bc]:=$00000000;
|
|
PDWORD(@CX_REG)[$0bd]:=$3f800000;
|
|
PDWORD(@CX_REG)[$0be]:=$00000000;
|
|
PDWORD(@CX_REG)[$0bf]:=$3f800000;
|
|
PDWORD(@CX_REG)[$0c0]:=$00000000;
|
|
PDWORD(@CX_REG)[$0c1]:=$3f800000;
|
|
PDWORD(@CX_REG)[$0c2]:=$00000000;
|
|
PDWORD(@CX_REG)[$0c3]:=$3f800000;
|
|
PDWORD(@CX_REG)[$0c4]:=$00000000;
|
|
PDWORD(@CX_REG)[$0c5]:=$3f800000;
|
|
PDWORD(@CX_REG)[$0c6]:=$00000000;
|
|
PDWORD(@CX_REG)[$0c7]:=$3f800000;
|
|
PDWORD(@CX_REG)[$0c8]:=$00000000;
|
|
PDWORD(@CX_REG)[$0c9]:=$3f800000;
|
|
PDWORD(@CX_REG)[$0ca]:=$00000000;
|
|
PDWORD(@CX_REG)[$0cb]:=$3f800000;
|
|
PDWORD(@CX_REG)[$0cc]:=$00000000;
|
|
PDWORD(@CX_REG)[$0cd]:=$3f800000;
|
|
PDWORD(@CX_REG)[$0ce]:=$00000000;
|
|
PDWORD(@CX_REG)[$0cf]:=$3f800000;
|
|
PDWORD(@CX_REG)[$0d0]:=$00000000;
|
|
PDWORD(@CX_REG)[$0d1]:=$3f800000;
|
|
PDWORD(@CX_REG)[$0d2]:=$00000000;
|
|
PDWORD(@CX_REG)[$0d3]:=$3f800000;
|
|
PDWORD(@CX_REG)[$0d4]:=$2a00161a;
|
|
PDWORD(@CX_REG)[$0d5]:=$00000000;
|
|
PDWORD(@CX_REG)[$0d6]:=$00000000;
|
|
PDWORD(@CX_REG)[$0d8]:=$00000000;
|
|
PDWORD(@CX_REG)[$103]:=$00000000;
|
|
PDWORD(@CX_REG)[$105]:=$00000000;
|
|
PDWORD(@CX_REG)[$106]:=$00000000;
|
|
PDWORD(@CX_REG)[$107]:=$00000000;
|
|
PDWORD(@CX_REG)[$108]:=$00000000;
|
|
PDWORD(@CX_REG)[$10b]:=$00000000;
|
|
PDWORD(@CX_REG)[$10c]:=$00000000;
|
|
PDWORD(@CX_REG)[$10d]:=$00000000;
|
|
PDWORD(@CX_REG)[$10f]:=$00000000;
|
|
PDWORD(@CX_REG)[$110]:=$00000000;
|
|
PDWORD(@CX_REG)[$111]:=$00000000;
|
|
PDWORD(@CX_REG)[$112]:=$00000000;
|
|
PDWORD(@CX_REG)[$113]:=$00000000;
|
|
PDWORD(@CX_REG)[$114]:=$00000000;
|
|
PDWORD(@CX_REG)[$115]:=$00000000;
|
|
PDWORD(@CX_REG)[$116]:=$00000000;
|
|
PDWORD(@CX_REG)[$117]:=$00000000;
|
|
PDWORD(@CX_REG)[$118]:=$00000000;
|
|
PDWORD(@CX_REG)[$119]:=$00000000;
|
|
PDWORD(@CX_REG)[$11a]:=$00000000;
|
|
PDWORD(@CX_REG)[$11b]:=$00000000;
|
|
PDWORD(@CX_REG)[$11c]:=$00000000;
|
|
PDWORD(@CX_REG)[$11d]:=$00000000;
|
|
PDWORD(@CX_REG)[$11e]:=$00000000;
|
|
PDWORD(@CX_REG)[$11f]:=$00000000;
|
|
PDWORD(@CX_REG)[$120]:=$00000000;
|
|
PDWORD(@CX_REG)[$121]:=$00000000;
|
|
PDWORD(@CX_REG)[$122]:=$00000000;
|
|
PDWORD(@CX_REG)[$123]:=$00000000;
|
|
PDWORD(@CX_REG)[$124]:=$00000000;
|
|
PDWORD(@CX_REG)[$125]:=$00000000;
|
|
PDWORD(@CX_REG)[$126]:=$00000000;
|
|
PDWORD(@CX_REG)[$127]:=$00000000;
|
|
PDWORD(@CX_REG)[$128]:=$00000000;
|
|
PDWORD(@CX_REG)[$129]:=$00000000;
|
|
PDWORD(@CX_REG)[$12a]:=$00000000;
|
|
PDWORD(@CX_REG)[$12b]:=$00000000;
|
|
PDWORD(@CX_REG)[$12c]:=$00000000;
|
|
PDWORD(@CX_REG)[$12d]:=$00000000;
|
|
PDWORD(@CX_REG)[$12e]:=$00000000;
|
|
PDWORD(@CX_REG)[$12f]:=$00000000;
|
|
PDWORD(@CX_REG)[$130]:=$00000000;
|
|
PDWORD(@CX_REG)[$131]:=$00000000;
|
|
PDWORD(@CX_REG)[$132]:=$00000000;
|
|
PDWORD(@CX_REG)[$133]:=$00000000;
|
|
PDWORD(@CX_REG)[$134]:=$00000000;
|
|
PDWORD(@CX_REG)[$135]:=$00000000;
|
|
PDWORD(@CX_REG)[$136]:=$00000000;
|
|
PDWORD(@CX_REG)[$137]:=$00000000;
|
|
PDWORD(@CX_REG)[$138]:=$00000000;
|
|
PDWORD(@CX_REG)[$139]:=$00000000;
|
|
PDWORD(@CX_REG)[$13a]:=$00000000;
|
|
PDWORD(@CX_REG)[$13b]:=$00000000;
|
|
PDWORD(@CX_REG)[$13c]:=$00000000;
|
|
PDWORD(@CX_REG)[$13d]:=$00000000;
|
|
PDWORD(@CX_REG)[$13e]:=$00000000;
|
|
PDWORD(@CX_REG)[$13f]:=$00000000;
|
|
PDWORD(@CX_REG)[$140]:=$00000000;
|
|
PDWORD(@CX_REG)[$141]:=$00000000;
|
|
PDWORD(@CX_REG)[$142]:=$00000000;
|
|
PDWORD(@CX_REG)[$143]:=$00000000;
|
|
PDWORD(@CX_REG)[$144]:=$00000000;
|
|
PDWORD(@CX_REG)[$145]:=$00000000;
|
|
PDWORD(@CX_REG)[$146]:=$00000000;
|
|
PDWORD(@CX_REG)[$147]:=$00000000;
|
|
PDWORD(@CX_REG)[$148]:=$00000000;
|
|
PDWORD(@CX_REG)[$149]:=$00000000;
|
|
PDWORD(@CX_REG)[$14a]:=$00000000;
|
|
PDWORD(@CX_REG)[$14b]:=$00000000;
|
|
PDWORD(@CX_REG)[$14c]:=$00000000;
|
|
PDWORD(@CX_REG)[$14d]:=$00000000;
|
|
PDWORD(@CX_REG)[$14e]:=$00000000;
|
|
PDWORD(@CX_REG)[$14f]:=$00000000;
|
|
PDWORD(@CX_REG)[$150]:=$00000000;
|
|
PDWORD(@CX_REG)[$151]:=$00000000;
|
|
PDWORD(@CX_REG)[$152]:=$00000000;
|
|
PDWORD(@CX_REG)[$153]:=$00000000;
|
|
PDWORD(@CX_REG)[$154]:=$00000000;
|
|
PDWORD(@CX_REG)[$155]:=$00000000;
|
|
PDWORD(@CX_REG)[$156]:=$00000000;
|
|
PDWORD(@CX_REG)[$157]:=$00000000;
|
|
PDWORD(@CX_REG)[$158]:=$00000000;
|
|
PDWORD(@CX_REG)[$159]:=$00000000;
|
|
PDWORD(@CX_REG)[$15a]:=$00000000;
|
|
PDWORD(@CX_REG)[$15b]:=$00000000;
|
|
PDWORD(@CX_REG)[$15c]:=$00000000;
|
|
PDWORD(@CX_REG)[$15d]:=$00000000;
|
|
PDWORD(@CX_REG)[$15e]:=$00000000;
|
|
PDWORD(@CX_REG)[$15f]:=$00000000;
|
|
PDWORD(@CX_REG)[$160]:=$00000000;
|
|
PDWORD(@CX_REG)[$161]:=$00000000;
|
|
PDWORD(@CX_REG)[$162]:=$00000000;
|
|
PDWORD(@CX_REG)[$163]:=$00000000;
|
|
PDWORD(@CX_REG)[$164]:=$00000000;
|
|
PDWORD(@CX_REG)[$165]:=$00000000;
|
|
PDWORD(@CX_REG)[$166]:=$00000000;
|
|
PDWORD(@CX_REG)[$167]:=$00000000;
|
|
PDWORD(@CX_REG)[$168]:=$00000000;
|
|
PDWORD(@CX_REG)[$169]:=$00000000;
|
|
PDWORD(@CX_REG)[$16a]:=$00000000;
|
|
PDWORD(@CX_REG)[$16b]:=$00000000;
|
|
PDWORD(@CX_REG)[$16c]:=$00000000;
|
|
PDWORD(@CX_REG)[$16d]:=$00000000;
|
|
PDWORD(@CX_REG)[$16e]:=$00000000;
|
|
PDWORD(@CX_REG)[$16f]:=$00000000;
|
|
PDWORD(@CX_REG)[$170]:=$00000000;
|
|
PDWORD(@CX_REG)[$171]:=$00000000;
|
|
PDWORD(@CX_REG)[$172]:=$00000000;
|
|
PDWORD(@CX_REG)[$173]:=$00000000;
|
|
PDWORD(@CX_REG)[$174]:=$00000000;
|
|
PDWORD(@CX_REG)[$175]:=$00000000;
|
|
PDWORD(@CX_REG)[$176]:=$00000000;
|
|
PDWORD(@CX_REG)[$177]:=$00000000;
|
|
PDWORD(@CX_REG)[$178]:=$00000000;
|
|
PDWORD(@CX_REG)[$179]:=$00000000;
|
|
PDWORD(@CX_REG)[$17a]:=$00000000;
|
|
PDWORD(@CX_REG)[$17b]:=$00000000;
|
|
PDWORD(@CX_REG)[$17c]:=$00000000;
|
|
PDWORD(@CX_REG)[$17d]:=$00000000;
|
|
PDWORD(@CX_REG)[$17e]:=$00000000;
|
|
PDWORD(@CX_REG)[$17f]:=$00000000;
|
|
PDWORD(@CX_REG)[$180]:=$00000000;
|
|
PDWORD(@CX_REG)[$181]:=$00000000;
|
|
PDWORD(@CX_REG)[$182]:=$00000000;
|
|
PDWORD(@CX_REG)[$183]:=$00000000;
|
|
PDWORD(@CX_REG)[$184]:=$00000000;
|
|
PDWORD(@CX_REG)[$185]:=$00000000;
|
|
PDWORD(@CX_REG)[$186]:=$00000000;
|
|
PDWORD(@CX_REG)[$191]:=$00000000;
|
|
PDWORD(@CX_REG)[$192]:=$00000000;
|
|
PDWORD(@CX_REG)[$193]:=$00000000;
|
|
PDWORD(@CX_REG)[$194]:=$00000000;
|
|
PDWORD(@CX_REG)[$195]:=$00000000;
|
|
PDWORD(@CX_REG)[$196]:=$00000000;
|
|
PDWORD(@CX_REG)[$197]:=$00000000;
|
|
PDWORD(@CX_REG)[$198]:=$00000000;
|
|
PDWORD(@CX_REG)[$199]:=$00000000;
|
|
PDWORD(@CX_REG)[$19a]:=$00000000;
|
|
PDWORD(@CX_REG)[$19b]:=$00000000;
|
|
PDWORD(@CX_REG)[$19c]:=$00000000;
|
|
PDWORD(@CX_REG)[$19d]:=$00000000;
|
|
PDWORD(@CX_REG)[$19e]:=$00000000;
|
|
PDWORD(@CX_REG)[$19f]:=$00000000;
|
|
PDWORD(@CX_REG)[$1a0]:=$00000000;
|
|
PDWORD(@CX_REG)[$1a1]:=$00000000;
|
|
PDWORD(@CX_REG)[$1a2]:=$00000000;
|
|
PDWORD(@CX_REG)[$1a3]:=$00000000;
|
|
PDWORD(@CX_REG)[$1a4]:=$00000000;
|
|
PDWORD(@CX_REG)[$1a5]:=$00000000;
|
|
PDWORD(@CX_REG)[$1a6]:=$00000000;
|
|
PDWORD(@CX_REG)[$1a7]:=$00000000;
|
|
PDWORD(@CX_REG)[$1a8]:=$00000000;
|
|
PDWORD(@CX_REG)[$1a9]:=$00000000;
|
|
PDWORD(@CX_REG)[$1aa]:=$00000000;
|
|
PDWORD(@CX_REG)[$1ab]:=$00000000;
|
|
PDWORD(@CX_REG)[$1ac]:=$00000000;
|
|
PDWORD(@CX_REG)[$1ad]:=$00000000;
|
|
PDWORD(@CX_REG)[$1ae]:=$00000000;
|
|
PDWORD(@CX_REG)[$1af]:=$00000000;
|
|
PDWORD(@CX_REG)[$1b0]:=$00000000;
|
|
PDWORD(@CX_REG)[$1b1]:=$00000000;
|
|
PDWORD(@CX_REG)[$1b3]:=$00000000;
|
|
PDWORD(@CX_REG)[$1b4]:=$00000000;
|
|
PDWORD(@CX_REG)[$1b5]:=$00000000;
|
|
PDWORD(@CX_REG)[$1b6]:=$00000002;
|
|
PDWORD(@CX_REG)[$1b8]:=$00000000;
|
|
PDWORD(@CX_REG)[$1ba]:=$00000000;
|
|
PDWORD(@CX_REG)[$1c3]:=$00000000;
|
|
PDWORD(@CX_REG)[$1c4]:=$00000000;
|
|
PDWORD(@CX_REG)[$1c5]:=$00000000;
|
|
PDWORD(@CX_REG)[$1e0]:=$00000000;
|
|
PDWORD(@CX_REG)[$1e1]:=$00000000;
|
|
PDWORD(@CX_REG)[$1e2]:=$00000000;
|
|
PDWORD(@CX_REG)[$1e3]:=$00000000;
|
|
PDWORD(@CX_REG)[$1e4]:=$00000000;
|
|
PDWORD(@CX_REG)[$1e5]:=$00000000;
|
|
PDWORD(@CX_REG)[$1e6]:=$00000000;
|
|
PDWORD(@CX_REG)[$1e7]:=$00000000;
|
|
PDWORD(@CX_REG)[$1f5]:=$00000000;
|
|
PDWORD(@CX_REG)[$1f6]:=$00000000;
|
|
PDWORD(@CX_REG)[$1f7]:=$00000000;
|
|
PDWORD(@CX_REG)[$1f8]:=$00000000;
|
|
PDWORD(@CX_REG)[$200]:=$00000000;
|
|
PDWORD(@CX_REG)[$201]:=$00000000;
|
|
PDWORD(@CX_REG)[$202]:=$00000000;
|
|
PDWORD(@CX_REG)[$203]:=$00000000;
|
|
PDWORD(@CX_REG)[$204]:=$00090000;
|
|
PDWORD(@CX_REG)[$205]:=$00000004;
|
|
PDWORD(@CX_REG)[$206]:=$00000000;
|
|
PDWORD(@CX_REG)[$207]:=$00000000;
|
|
PDWORD(@CX_REG)[$208]:=$00000000;
|
|
PDWORD(@CX_REG)[$209]:=$00000000;
|
|
PDWORD(@CX_REG)[$20a]:=$00000000;
|
|
PDWORD(@CX_REG)[$20b]:=$00000000;
|
|
PDWORD(@CX_REG)[$280]:=$00000000;
|
|
PDWORD(@CX_REG)[$281]:=$00000000;
|
|
PDWORD(@CX_REG)[$282]:=$00000000;
|
|
PDWORD(@CX_REG)[$283]:=$00000000;
|
|
PDWORD(@CX_REG)[$284]:=$00000000;
|
|
PDWORD(@CX_REG)[$285]:=$00000000;
|
|
PDWORD(@CX_REG)[$286]:=$00000000;
|
|
PDWORD(@CX_REG)[$287]:=$00000000;
|
|
PDWORD(@CX_REG)[$288]:=$00000000;
|
|
PDWORD(@CX_REG)[$289]:=$00000000;
|
|
PDWORD(@CX_REG)[$28a]:=$00000000;
|
|
PDWORD(@CX_REG)[$28b]:=$00000000;
|
|
PDWORD(@CX_REG)[$28c]:=$00000000;
|
|
PDWORD(@CX_REG)[$28d]:=$00000000;
|
|
PDWORD(@CX_REG)[$28e]:=$00000000;
|
|
PDWORD(@CX_REG)[$28f]:=$00000000;
|
|
PDWORD(@CX_REG)[$290]:=$00000000;
|
|
PDWORD(@CX_REG)[$291]:=$00000000;
|
|
PDWORD(@CX_REG)[$292]:=$00000000;
|
|
PDWORD(@CX_REG)[$293]:=$00000000;
|
|
PDWORD(@CX_REG)[$294]:=$00000000;
|
|
PDWORD(@CX_REG)[$295]:=$00000100;
|
|
PDWORD(@CX_REG)[$296]:=$00000080;
|
|
PDWORD(@CX_REG)[$297]:=$00000002;
|
|
PDWORD(@CX_REG)[$298]:=$00000000;
|
|
PDWORD(@CX_REG)[$299]:=$00000000;
|
|
PDWORD(@CX_REG)[$29a]:=$00000000;
|
|
PDWORD(@CX_REG)[$29b]:=$00000000;
|
|
PDWORD(@CX_REG)[$29c]:=$00000000;
|
|
PDWORD(@CX_REG)[$2a0]:=$00000000;
|
|
PDWORD(@CX_REG)[$2a1]:=$00000000;
|
|
PDWORD(@CX_REG)[$2a3]:=$00000000;
|
|
PDWORD(@CX_REG)[$2a5]:=$00000000;
|
|
PDWORD(@CX_REG)[$2a8]:=$00000000;
|
|
PDWORD(@CX_REG)[$2a9]:=$00000000;
|
|
PDWORD(@CX_REG)[$2aa]:=$000000ff;
|
|
PDWORD(@CX_REG)[$2ab]:=$00000000;
|
|
PDWORD(@CX_REG)[$2ac]:=$00000000;
|
|
PDWORD(@CX_REG)[$2ad]:=$00000000;
|
|
PDWORD(@CX_REG)[$2ae]:=$00000000;
|
|
PDWORD(@CX_REG)[$2af]:=$00000000;
|
|
PDWORD(@CX_REG)[$2b0]:=$00000000;
|
|
PDWORD(@CX_REG)[$2b1]:=$00000000;
|
|
PDWORD(@CX_REG)[$2b2]:=$00000000;
|
|
PDWORD(@CX_REG)[$2b4]:=$00000000;
|
|
PDWORD(@CX_REG)[$2b5]:=$00000000;
|
|
PDWORD(@CX_REG)[$2b7]:=$00000000;
|
|
PDWORD(@CX_REG)[$2b8]:=$00000000;
|
|
PDWORD(@CX_REG)[$2b9]:=$00000000;
|
|
PDWORD(@CX_REG)[$2bb]:=$00000000;
|
|
PDWORD(@CX_REG)[$2bc]:=$00000000;
|
|
PDWORD(@CX_REG)[$2bd]:=$00000000;
|
|
PDWORD(@CX_REG)[$2bf]:=$00000000;
|
|
PDWORD(@CX_REG)[$2c0]:=$00000000;
|
|
PDWORD(@CX_REG)[$2c1]:=$00000000;
|
|
PDWORD(@CX_REG)[$2c3]:=$00000000;
|
|
PDWORD(@CX_REG)[$2ca]:=$00000000;
|
|
PDWORD(@CX_REG)[$2cb]:=$00000000;
|
|
PDWORD(@CX_REG)[$2cc]:=$00000000;
|
|
PDWORD(@CX_REG)[$2ce]:=$00000000;
|
|
PDWORD(@CX_REG)[$2d5]:=$00000000;
|
|
PDWORD(@CX_REG)[$2d6]:=$00000000;
|
|
PDWORD(@CX_REG)[$2d7]:=$00000000;
|
|
PDWORD(@CX_REG)[$2d8]:=$00000000;
|
|
PDWORD(@CX_REG)[$2d9]:=$00000000;
|
|
PDWORD(@CX_REG)[$2da]:=$00000000;
|
|
PDWORD(@CX_REG)[$2db]:=$00000000;
|
|
PDWORD(@CX_REG)[$2dc]:=$00000000;
|
|
PDWORD(@CX_REG)[$2dd]:=$00000000;
|
|
PDWORD(@CX_REG)[$2de]:=$00000000;
|
|
PDWORD(@CX_REG)[$2df]:=$00000000;
|
|
PDWORD(@CX_REG)[$2e0]:=$00000000;
|
|
PDWORD(@CX_REG)[$2e1]:=$00000000;
|
|
PDWORD(@CX_REG)[$2e2]:=$00000000;
|
|
PDWORD(@CX_REG)[$2e3]:=$00000000;
|
|
PDWORD(@CX_REG)[$2e4]:=$00000000;
|
|
PDWORD(@CX_REG)[$2e5]:=$00000000;
|
|
PDWORD(@CX_REG)[$2e6]:=$00000000;
|
|
PDWORD(@CX_REG)[$2f5]:=$00000000;
|
|
PDWORD(@CX_REG)[$2f6]:=$00000000;
|
|
PDWORD(@CX_REG)[$2f7]:=$00001000;
|
|
PDWORD(@CX_REG)[$2f8]:=$00000000;
|
|
PDWORD(@CX_REG)[$2f9]:=$00000005;
|
|
PDWORD(@CX_REG)[$2fa]:=$3f800000;
|
|
PDWORD(@CX_REG)[$2fb]:=$3f800000;
|
|
PDWORD(@CX_REG)[$2fc]:=$3f800000;
|
|
PDWORD(@CX_REG)[$2fd]:=$3f800000;
|
|
PDWORD(@CX_REG)[$2fe]:=$00000000;
|
|
PDWORD(@CX_REG)[$2ff]:=$00000000;
|
|
PDWORD(@CX_REG)[$300]:=$00000000;
|
|
PDWORD(@CX_REG)[$301]:=$00000000;
|
|
PDWORD(@CX_REG)[$302]:=$00000000;
|
|
PDWORD(@CX_REG)[$303]:=$00000000;
|
|
PDWORD(@CX_REG)[$304]:=$00000000;
|
|
PDWORD(@CX_REG)[$305]:=$00000000;
|
|
PDWORD(@CX_REG)[$306]:=$00000000;
|
|
PDWORD(@CX_REG)[$307]:=$00000000;
|
|
PDWORD(@CX_REG)[$308]:=$00000000;
|
|
PDWORD(@CX_REG)[$309]:=$00000000;
|
|
PDWORD(@CX_REG)[$30a]:=$00000000;
|
|
PDWORD(@CX_REG)[$30b]:=$00000000;
|
|
PDWORD(@CX_REG)[$30c]:=$00000000;
|
|
PDWORD(@CX_REG)[$30d]:=$00000000;
|
|
PDWORD(@CX_REG)[$316]:=$0000000e;
|
|
PDWORD(@CX_REG)[$317]:=$00000010;
|
|
PDWORD(@CX_REG)[$318]:=$00000000;
|
|
PDWORD(@CX_REG)[$319]:=$00000000;
|
|
PDWORD(@CX_REG)[$31a]:=$00000000;
|
|
PDWORD(@CX_REG)[$31b]:=$00000000;
|
|
PDWORD(@CX_REG)[$31c]:=$00000000;
|
|
PDWORD(@CX_REG)[$31d]:=$00000000;
|
|
PDWORD(@CX_REG)[$31f]:=$00000000;
|
|
PDWORD(@CX_REG)[$320]:=$00000000;
|
|
PDWORD(@CX_REG)[$321]:=$00000000;
|
|
PDWORD(@CX_REG)[$322]:=$00000000;
|
|
PDWORD(@CX_REG)[$323]:=$00000000;
|
|
PDWORD(@CX_REG)[$324]:=$00000000;
|
|
PDWORD(@CX_REG)[$327]:=$00000000;
|
|
PDWORD(@CX_REG)[$328]:=$00000000;
|
|
PDWORD(@CX_REG)[$329]:=$00000000;
|
|
PDWORD(@CX_REG)[$32a]:=$00000000;
|
|
PDWORD(@CX_REG)[$32b]:=$00000000;
|
|
PDWORD(@CX_REG)[$32c]:=$00000000;
|
|
PDWORD(@CX_REG)[$32e]:=$00000000;
|
|
PDWORD(@CX_REG)[$32f]:=$00000000;
|
|
PDWORD(@CX_REG)[$330]:=$00000000;
|
|
PDWORD(@CX_REG)[$331]:=$00000000;
|
|
PDWORD(@CX_REG)[$332]:=$00000000;
|
|
PDWORD(@CX_REG)[$333]:=$00000000;
|
|
PDWORD(@CX_REG)[$336]:=$00000000;
|
|
PDWORD(@CX_REG)[$337]:=$00000000;
|
|
PDWORD(@CX_REG)[$338]:=$00000000;
|
|
PDWORD(@CX_REG)[$339]:=$00000000;
|
|
PDWORD(@CX_REG)[$33a]:=$00000000;
|
|
PDWORD(@CX_REG)[$33b]:=$00000000;
|
|
PDWORD(@CX_REG)[$33d]:=$00000000;
|
|
PDWORD(@CX_REG)[$33e]:=$00000000;
|
|
PDWORD(@CX_REG)[$33f]:=$00000000;
|
|
PDWORD(@CX_REG)[$340]:=$00000000;
|
|
PDWORD(@CX_REG)[$341]:=$00000000;
|
|
PDWORD(@CX_REG)[$342]:=$00000000;
|
|
PDWORD(@CX_REG)[$345]:=$00000000;
|
|
PDWORD(@CX_REG)[$346]:=$00000000;
|
|
PDWORD(@CX_REG)[$347]:=$00000000;
|
|
PDWORD(@CX_REG)[$348]:=$00000000;
|
|
PDWORD(@CX_REG)[$349]:=$00000000;
|
|
PDWORD(@CX_REG)[$34a]:=$00000000;
|
|
PDWORD(@CX_REG)[$34c]:=$00000000;
|
|
PDWORD(@CX_REG)[$34d]:=$00000000;
|
|
PDWORD(@CX_REG)[$34e]:=$00000000;
|
|
PDWORD(@CX_REG)[$34f]:=$00000000;
|
|
PDWORD(@CX_REG)[$350]:=$00000000;
|
|
PDWORD(@CX_REG)[$351]:=$00000000;
|
|
PDWORD(@CX_REG)[$354]:=$00000000;
|
|
PDWORD(@CX_REG)[$355]:=$00000000;
|
|
PDWORD(@CX_REG)[$356]:=$00000000;
|
|
PDWORD(@CX_REG)[$357]:=$00000000;
|
|
PDWORD(@CX_REG)[$358]:=$00000000;
|
|
PDWORD(@CX_REG)[$359]:=$00000000;
|
|
PDWORD(@CX_REG)[$35b]:=$00000000;
|
|
PDWORD(@CX_REG)[$35c]:=$00000000;
|
|
PDWORD(@CX_REG)[$35d]:=$00000000;
|
|
PDWORD(@CX_REG)[$35e]:=$00000000;
|
|
PDWORD(@CX_REG)[$35f]:=$00000000;
|
|
PDWORD(@CX_REG)[$360]:=$00000000;
|
|
PDWORD(@CX_REG)[$363]:=$00000000;
|
|
PDWORD(@CX_REG)[$364]:=$00000000;
|
|
PDWORD(@CX_REG)[$365]:=$00000000;
|
|
PDWORD(@CX_REG)[$366]:=$00000000;
|
|
PDWORD(@CX_REG)[$367]:=$00000000;
|
|
PDWORD(@CX_REG)[$368]:=$00000000;
|
|
PDWORD(@CX_REG)[$36a]:=$00000000;
|
|
PDWORD(@CX_REG)[$36b]:=$00000000;
|
|
PDWORD(@CX_REG)[$36c]:=$00000000;
|
|
PDWORD(@CX_REG)[$36d]:=$00000000;
|
|
PDWORD(@CX_REG)[$36e]:=$00000000;
|
|
PDWORD(@CX_REG)[$36f]:=$00000000;
|
|
PDWORD(@CX_REG)[$372]:=$00000000;
|
|
PDWORD(@CX_REG)[$373]:=$00000000;
|
|
PDWORD(@CX_REG)[$374]:=$00000000;
|
|
PDWORD(@CX_REG)[$375]:=$00000000;
|
|
PDWORD(@CX_REG)[$376]:=$00000000;
|
|
PDWORD(@CX_REG)[$377]:=$00000000;
|
|
PDWORD(@CX_REG)[$379]:=$00000000;
|
|
PDWORD(@CX_REG)[$37a]:=$00000000;
|
|
PDWORD(@CX_REG)[$37b]:=$00000000;
|
|
PDWORD(@CX_REG)[$37c]:=$00000000;
|
|
PDWORD(@CX_REG)[$37d]:=$00000000;
|
|
PDWORD(@CX_REG)[$37e]:=$00000000;
|
|
PDWORD(@CX_REG)[$381]:=$00000000;
|
|
PDWORD(@CX_REG)[$382]:=$00000000;
|
|
PDWORD(@CX_REG)[$383]:=$00000000;
|
|
PDWORD(@CX_REG)[$384]:=$00000000;
|
|
PDWORD(@CX_REG)[$385]:=$00000000;
|
|
PDWORD(@CX_REG)[$386]:=$00000000;
|
|
PDWORD(@CX_REG)[$388]:=$00000000;
|
|
PDWORD(@CX_REG)[$389]:=$00000000;
|
|
PDWORD(@CX_REG)[$38a]:=$00000000;
|
|
PDWORD(@CX_REG)[$38b]:=$00000000;
|
|
PDWORD(@CX_REG)[$38c]:=$00000000;
|
|
PDWORD(@CX_REG)[$38d]:=$00000000;
|
|
end;
|
|
|
|
///
|
|
|
|
procedure onLoadConstRam(pctx:p_pfp_ctx;Body:PPM4CMDCONSTRAMLOAD);
|
|
begin
|
|
Assert(pctx^.stream_type=stGfxCcb);
|
|
|
|
{
|
|
Writeln(' adr=0x',HexStr(Body^.addr,16));
|
|
Writeln(' len=0x',HexStr(Body^.numDwords*4,4));
|
|
Writeln(' ofs=0x',HexStr(Body^.offset,4));
|
|
}
|
|
|
|
pctx^.stream[stGfxCcb].LoadConstRam(Pointer(Body^.addr and (not QWORD(31))),
|
|
Body^.numDwords and (not 7),
|
|
Body^.offset and (not 31));
|
|
end;
|
|
|
|
function PM4_BODY_LENGTH_DW(header:PM4_TYPE_3_HEADER;sizeof:WORD):WORD; inline;
|
|
begin
|
|
Result:=header.count + 2;
|
|
sizeof:=sizeof div 4;
|
|
if (Result>sizeof) then
|
|
begin
|
|
Result:=Result-sizeof;
|
|
end else
|
|
begin
|
|
Result:=0;
|
|
end;
|
|
end;
|
|
|
|
procedure onWriteConstRam(pctx:p_pfp_ctx;Body:PPM4CMDCONSTRAMWRITE);
|
|
var
|
|
count:Word;
|
|
|
|
src:PDWORD;
|
|
src_dmem:PDWORD;
|
|
begin
|
|
Assert(pctx^.stream_type=stGfxCcb);
|
|
|
|
count:=PM4_BODY_LENGTH_DW(Body^.header,SizeOf(PM4CMDCONSTRAMWRITE));
|
|
if (count=0) then Exit;
|
|
|
|
src_dmem:=@Body^.data;
|
|
|
|
//convert src_dmem -> src
|
|
|
|
with pctx^.curr_ibuf^ do
|
|
begin
|
|
src:=base+(Int64(src_dmem)-Int64(buff));
|
|
end;
|
|
|
|
pctx^.stream[stGfxCcb].LoadConstRam(src,count,Body^.offset and (not 3));
|
|
end;
|
|
|
|
procedure onDumpConstRam(pctx:p_pfp_ctx;Body:PPM4CMDCONSTRAMDUMP);
|
|
begin
|
|
Assert(pctx^.stream_type=stGfxCcb);
|
|
|
|
Assert(Body^.incrementCs=0);
|
|
Assert(Body^.incrementCe=0);
|
|
|
|
pctx^.stream[stGfxCcb].DumpConstRam(Pointer(Body^.addr and (not QWORD(3))),
|
|
Body^.numDwords,
|
|
Body^.offset and (not 3));
|
|
end;
|
|
|
|
procedure onIncrementCECounter(pctx:p_pfp_ctx;Body:Pointer);
|
|
begin
|
|
Assert(pctx^.stream_type=stGfxCcb);
|
|
|
|
pctx^.stream[stGfxCcb].IncrementCE();
|
|
end;
|
|
|
|
procedure onIncrementDECounter(pctx:p_pfp_ctx;Body:Pointer);
|
|
begin
|
|
Assert(pctx^.stream_type=stGfxDcb);
|
|
|
|
pctx^.stream[stGfxDcb].IncrementDE();
|
|
end;
|
|
|
|
procedure onWaitOnCECounter(pctx:p_pfp_ctx;Body:PPM4CMDWAITONCECOUNTER);
|
|
begin
|
|
Assert(pctx^.stream_type=stGfxDcb);
|
|
|
|
pctx^.stream[stGfxDcb].WaitOnCECounter();
|
|
end;
|
|
|
|
procedure onWaitOnDECounterDiff(pctx:p_pfp_ctx;Body:PPM4CMDWAITONDECOUNTERDIFF);
|
|
begin
|
|
Assert(pctx^.stream_type=stGfxCcb);
|
|
|
|
//(DE_COUNT - CE_COMPARE_COUNT) < DIFF
|
|
|
|
pctx^.stream[stGfxCcb].WaitOnDECounterDiff(Body^.counterDiff);
|
|
end;
|
|
|
|
const
|
|
ShdrType:array[0..1] of Pchar=('(GX)','(CS)');
|
|
|
|
function pm4_parse_ccb(pctx:p_pfp_ctx;token:DWORD;buff:Pointer):Integer;
|
|
begin
|
|
Result:=0;
|
|
|
|
case PM4_TYPE(token) of
|
|
0:begin //PM4_TYPE_0
|
|
if p_print_gpu_ops then Writeln('PM4_TYPE_0');
|
|
end;
|
|
2:begin //PM4_TYPE_2
|
|
if p_print_gpu_ops then Writeln('PM4_TYPE_2');
|
|
//no body
|
|
end;
|
|
3:begin //PM4_TYPE_3
|
|
if p_print_gpu_ops then
|
|
if (PM4_TYPE_3_HEADER(token).opcode<>IT_NOP) or
|
|
(not p_print_gpu_hint) then
|
|
begin
|
|
Writeln('IT_',get_op_name(PM4_TYPE_3_HEADER(token).opcode),
|
|
' ',ShdrType[PM4_TYPE_3_HEADER(token).shaderType],
|
|
' len:',PM4_LENGTH(token));
|
|
end;
|
|
|
|
case PM4_TYPE_3_HEADER(token).opcode of
|
|
IT_NOP:;
|
|
|
|
IT_LOAD_CONST_RAM :onLoadConstRam (pctx,buff);
|
|
IT_WRITE_CONST_RAM :onWriteConstRam (pctx,buff);
|
|
IT_DUMP_CONST_RAM :onDumpConstRam (pctx,buff);
|
|
|
|
IT_INCREMENT_CE_COUNTER :onIncrementCECounter (pctx,buff);
|
|
IT_WAIT_ON_DE_COUNTER_DIFF:onWaitOnDECounterDiff(pctx,buff);
|
|
|
|
else
|
|
begin
|
|
Writeln(stderr,'PM4_TYPE_3.opcode:',get_op_name(PM4_TYPE_3_HEADER(token).opcode));
|
|
Assert(False);
|
|
end;
|
|
end;
|
|
|
|
end;
|
|
else
|
|
begin
|
|
Writeln(stderr,'PM4_TYPE_',PM4_TYPE(token));
|
|
Assert(False);
|
|
end;
|
|
end;
|
|
|
|
end;
|
|
|
|
procedure FlushAndWaitMe(pctx:p_pfp_ctx);
|
|
var
|
|
event:PRTLEvent;
|
|
begin
|
|
if (pctx^.stream_type=stGfxDcb) then
|
|
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;
|
|
end;
|
|
|
|
procedure onEventWrite(pctx:p_pfp_ctx;Body:PTPM4CMDEVENTWRITE);
|
|
const
|
|
c_p_stride:array[0..3] of PChar=('32_BITS','64_BITS','128_BITS','256_BITS');
|
|
begin
|
|
Assert(pctx^.stream_type=stGfxDcb);
|
|
|
|
DWORD(pctx^.CX_REG.VGT_EVENT_INITIATOR):=Body^.eventType;
|
|
|
|
if p_print_gpu_ops then
|
|
Case Body^.eventType of
|
|
CS_PARTIAL_FLUSH :Writeln(' eventType=CS_PARTIAL_FLUSH');
|
|
CACHE_FLUSH_AND_INV_EVENT :Writeln(' eventType=FLUSH_AND_INV_EVENT');
|
|
DB_CACHE_FLUSH_AND_INV :Writeln(' eventType=DB_CACHE_FLUSH_AND_INV');
|
|
FLUSH_AND_INV_DB_DATA_TS :Writeln(' eventType=FLUSH_AND_INV_DB_DATA_TS');
|
|
FLUSH_AND_INV_DB_META :Writeln(' eventType=FLUSH_AND_INV_DB_META');
|
|
FLUSH_AND_INV_CB_DATA_TS :Writeln(' eventType=FLUSH_AND_INV_CB_DATA_TS');
|
|
FLUSH_AND_INV_CB_META :Writeln(' eventType=FLUSH_AND_INV_CB_META');
|
|
FLUSH_AND_INV_CB_PIXEL_DATA:Writeln(' eventType=FLUSH_AND_INV_CB_PIXEL_DATA');
|
|
THREAD_TRACE_MARKER :Writeln(' eventType=THREAD_TRACE_MARKER');
|
|
PIXEL_PIPE_STAT_CONTROL :Writeln(' eventType=PIXEL_PIPE_STAT_CONTROL');
|
|
PIXEL_PIPE_STAT_DUMP :Writeln(' eventType=PIXEL_PIPE_STAT_DUMP');
|
|
PIXEL_PIPE_STAT_RESET :Writeln(' eventType=PIXEL_PIPE_STAT_RESET');
|
|
PIPELINESTAT_STOP :Writeln(' eventType=PIPELINESTAT_STOP');
|
|
PERFCOUNTER_START :Writeln(' eventType=PERFCOUNTER_START');
|
|
PERFCOUNTER_STOP :Writeln(' eventType=PERFCOUNTER_STOP');
|
|
PERFCOUNTER_SAMPLE :Writeln(' eventType=PERFCOUNTER_SAMPLE');
|
|
else
|
|
Writeln(' eventType=0x',HexStr(Body^.eventType,2));
|
|
end;
|
|
|
|
if p_print_gpu_ops then
|
|
Case Body^.eventType of
|
|
PIXEL_PIPE_STAT_CONTROL:
|
|
begin
|
|
Writeln(' counter_id=',Body^.u.Control.counter_id);
|
|
Writeln(' stride =',c_p_stride[Body^.u.Control.stride]);
|
|
end;
|
|
PIXEL_PIPE_STAT_DUMP:
|
|
begin
|
|
Writeln(' address=0x',HexStr(Body^.u.address and QWORD($FFFFFFFFF8),10));
|
|
end;
|
|
end;
|
|
|
|
Case Body^.eventType of
|
|
PIXEL_PIPE_STAT_CONTROL:
|
|
begin
|
|
pctx^.PixelPipeStatControl:=Body^.u.Control;
|
|
end;
|
|
PIXEL_PIPE_STAT_DUMP:
|
|
begin
|
|
pctx^.stream[stGfxDcb].PipeStatDump(Body^.u.address and QWORD($FFFFFFFFF8),pctx^.PixelPipeStatControl);
|
|
end;
|
|
else
|
|
begin
|
|
pctx^.stream[stGfxDcb].EventWrite(Body^.eventType);
|
|
end;
|
|
end;
|
|
|
|
end;
|
|
|
|
procedure onEventWriteEop(pctx:p_pfp_ctx;Body:PPM4CMDEVENTWRITEEOP);
|
|
begin
|
|
Assert(pctx^.stream_type=stGfxDcb);
|
|
|
|
//FlushAndWaitMe(pctx);
|
|
|
|
Case Body^.eventType of
|
|
CACHE_FLUSH_TS, //FlushCbDbCaches
|
|
CACHE_FLUSH_AND_INV_TS_EVENT, //FlushAndInvalidateCbDbCaches
|
|
BOTTOM_OF_PIPE_TS:; //CbDbReadsDone
|
|
else
|
|
Assert(False,'EventWriteEop: eventType=0x'+HexStr(Body^.eventType,1));
|
|
end;
|
|
|
|
if (Body^.eventIndex<>EVENT_WRITE_INDEX_ANY_EOP_TIMESTAMP) then
|
|
begin
|
|
Assert(False,'EventWriteEop: eventIndex=0x'+HexStr(Body^.eventIndex,1));
|
|
end;
|
|
|
|
DWORD(pctx^.CX_REG.VGT_EVENT_INITIATOR):=Body^.eventType;
|
|
|
|
if p_print_gpu_ops then
|
|
begin
|
|
Case Body^.eventType of
|
|
CACHE_FLUSH_TS :Writeln(' eventType =','FlushCbDbCaches');
|
|
CACHE_FLUSH_AND_INV_TS_EVENT:Writeln(' eventType =','FlushAndInvalidateCbDbCaches');
|
|
BOTTOM_OF_PIPE_TS :Writeln(' eventType =','CbDbReadsDone');
|
|
else;
|
|
end;
|
|
|
|
Writeln(' interrupt =0x',HexStr(Body^.intSel,2));
|
|
Writeln(' srcSelector=0x',HexStr(Body^.dataSel,2));
|
|
Writeln(' dstGpuAddr =0x',HexStr(Body^.address,10));
|
|
Writeln(' immValue =0x',HexStr(Body^.DATA,16));
|
|
end;
|
|
|
|
//if (Body^.destTcL2<>0) then Exit; //write to L2
|
|
|
|
pctx^.stream[stGfxDcb].EventWriteEop(Pointer(Body^.address),Body^.DATA,Body^.eventType,Body^.dataSel,Body^.intSel);
|
|
|
|
pctx^.Flush_stream(stGfxDcb);
|
|
end;
|
|
|
|
procedure onEventWriteEos(pctx:p_pfp_ctx;Body:PPM4CMDEVENTWRITEEOS);
|
|
begin
|
|
Assert(pctx^.stream_type=stGfxDcb);
|
|
|
|
//shaderType is any?
|
|
//Assert(Body^.header.shaderType=1,'shaderType<>CS');
|
|
|
|
Case Body^.eventType of
|
|
CS_DONE:;
|
|
PS_DONE:;
|
|
else
|
|
Assert(False,'EventWriteEos: eventType=0x'+HexStr(Body^.eventType,1));
|
|
//Writeln(stderr,'EventWriteEos: eventType=0x'+HexStr(Body^.eventType,1));
|
|
end;
|
|
|
|
if p_print_gpu_ops then
|
|
Case Body^.eventType of
|
|
CS_DONE:Writeln(' CS_DONE');
|
|
PS_DONE:Writeln(' PS_DONE');
|
|
else;
|
|
end;
|
|
|
|
if (Body^.eventIndex<>EVENT_WRITE_INDEX_ANY_EOS_TIMESTAMP) then
|
|
begin
|
|
Assert(False,'EventWriteEos: eventIndex=0x'+HexStr(Body^.eventIndex,1));
|
|
//Writeln(stderr,'EventWriteEos: eventIndex=0x'+HexStr(Body^.eventIndex,1));
|
|
end;
|
|
|
|
DWORD(pctx^.CX_REG.VGT_EVENT_INITIATOR):=Body^.eventType;
|
|
|
|
pctx^.stream[stGfxDcb].EventWriteEos(Pointer(Body^.address),Body^.data,Body^.eventType,Body^.command);
|
|
|
|
//FlushAndWaitMe(pctx);
|
|
end;
|
|
|
|
const
|
|
engine_str:array[0..3] of RawByteString=('ME','PFP','CE','3');
|
|
|
|
procedure onDmaData(pctx:p_pfp_ctx;Body:PPM4DMADATA);
|
|
var
|
|
adrSrc:QWORD;
|
|
adrDst:QWORD;
|
|
adrSrc_dmem:Pointer;
|
|
adrDst_dmem:Pointer;
|
|
byteCount:DWORD;
|
|
srcSel,dstSel:Byte;
|
|
begin
|
|
//Assert(pctx^.stream_type=stGfxDcb);
|
|
|
|
if (Body^.Flags2.saic=CPDMA_ADDR_SPACE_REG) then
|
|
begin
|
|
Assert(Body^.Flags2.saic<>0,'DmaData: read from fifo reg');
|
|
end;
|
|
|
|
if (Body^.Flags2.das=CPDMA_ADDR_SPACE_REG) then
|
|
begin
|
|
Assert(Body^.Flags2.daic<>0,'DmaData: send to fifo reg');
|
|
end;
|
|
|
|
srcSel:=((PDWORD(Body)[1] shr $1d) and 3) or ((PDWORD(Body)[6] shr $19) and 8) or ((PDWORD(Body)[6] shr $18) and 4);
|
|
dstSel:=((PDWORD(Body)[1] shr $14) and 1) or ((PDWORD(Body)[6] shr $1a) and 8) or ((PDWORD(Body)[6] shr $19) and 4);
|
|
|
|
adrSrc:=Body^.srcAddr;
|
|
adrDst:=Body^.dstAddr;
|
|
byteCount:=Body^.Flags2.byteCount;
|
|
|
|
case dstSel of
|
|
kDmaDataDstRegister,
|
|
kDmaDataDstRegisterNoIncrement:
|
|
if (DWORD(adrDst)=$3022C) then
|
|
begin
|
|
//prefetchIntoL2
|
|
Exit;
|
|
end;
|
|
else;
|
|
end;
|
|
|
|
Case Body^.Flags1.engine of
|
|
CP_DMA_ENGINE_ME:
|
|
begin
|
|
|
|
if p_print_gpu_ops then
|
|
begin
|
|
Writeln('[1]DmaData:0x',HexStr(adrSrc,10),'->',HexStr(adrDst,10),':size=0x',HexStr(byteCount,6));
|
|
end;
|
|
|
|
pctx^.stream[stGfxDcb].DmaData(dstSel,adrDst,srcSel,adrSrc,byteCount,Body^.Flags1.cpSync);
|
|
end;
|
|
CP_DMA_ENGINE_PFP:
|
|
begin
|
|
//Execute on the parser side
|
|
|
|
//FlushAndWaitMe(pctx);
|
|
|
|
if p_print_gpu_ops then
|
|
begin
|
|
Writeln('[2]DmaData:0x',HexStr(adrSrc,10),'->',HexStr(adrDst,10),':size=0x',HexStr(byteCount,6));
|
|
end;
|
|
|
|
adrDst_dmem:=get_dmem_ptr(Pointer(adrDst));
|
|
|
|
case (srcSel or (dstSel shl 4)) of
|
|
(kDmaDataSrcMemory or (kDmaDataDstMemory shl 4)),
|
|
(kDmaDataSrcMemoryUsingL2 or (kDmaDataDstMemory shl 4)),
|
|
(kDmaDataSrcMemory or (kDmaDataDstMemoryUsingL2 shl 4)),
|
|
(kDmaDataSrcMemoryUsingL2 or (kDmaDataDstMemoryUsingL2 shl 4)):
|
|
begin
|
|
adrSrc_dmem:=get_dmem_ptr(Pointer(adrSrc));
|
|
|
|
Move(adrSrc_dmem^,adrDst_dmem^,byteCount);
|
|
|
|
vm_map_track_trigger(p_proc.p_vmspace,QWORD(adrDst),QWORD(adrDst)+byteCount,nil,M_DMEM_WRITE);
|
|
end;
|
|
(kDmaDataSrcData or (kDmaDataDstMemory shl 4)),
|
|
(kDmaDataSrcData or (kDmaDataDstMemoryUsingL2 shl 4)):
|
|
begin
|
|
FillDWORD(adrDst_dmem^,(byteCount div 4),DWORD(adrSrc));
|
|
|
|
vm_map_track_trigger(p_proc.p_vmspace,QWORD(adrDst),QWORD(adrDst)+byteCount,nil,M_DMEM_WRITE);
|
|
end;
|
|
else
|
|
Assert(false,'DmaData: srcSel=0x'+HexStr(srcSel,1)+' dstSel=0x'+HexStr(dstSel,1));
|
|
end;
|
|
|
|
end;
|
|
else
|
|
Assert(false,'DmaData: engine='+engine_str[Body^.Flags1.engine]);
|
|
end;
|
|
|
|
end;
|
|
|
|
procedure onWriteData(pctx:p_pfp_ctx;Body:PPM4CMDWRITEDATA);
|
|
var
|
|
src:PDWORD;
|
|
dst:PDWORD;
|
|
src_dmem:PDWORD;
|
|
dst_dmem:PDWORD;
|
|
count:Word;
|
|
engineSel:Byte;
|
|
dstSel:Byte;
|
|
begin
|
|
if (Body^.CONTROL.dstSel=WRITE_DATA_DST_SEL_REGISTER) then
|
|
begin
|
|
Assert(Body^.CONTROL.wrOneAddr=0,'WriteData: send to fifo reg');
|
|
end;
|
|
|
|
count:=PM4_BODY_LENGTH_DW(Body^.header,SizeOf(PM4CMDWRITEDATA));
|
|
|
|
if p_print_gpu_ops then
|
|
begin
|
|
Writeln(' engine =',engine_str[Body^.CONTROL.engineSel]);
|
|
Writeln(' dstSel =',Body^.CONTROL.dstSel,' ',Body^.CONTROL.wrConfirm);
|
|
Writeln(' dstAddr =0x',HexStr(Body^.dstAddr,10));
|
|
Writeln(' length =',count*4);
|
|
|
|
case count of
|
|
1:Writeln(' data =0x',HexStr(PDWORD(@Body^.DATA)^,8 ));
|
|
2:Writeln(' data =0x',HexStr(PQWORD(@Body^.DATA)^,16));
|
|
else;
|
|
end;
|
|
end;
|
|
|
|
if (count=0) then Exit;
|
|
|
|
dst:=Pointer(Body^.dstAddr);
|
|
src_dmem:=@Body^.DATA;
|
|
|
|
engineSel:=Body^.CONTROL.engineSel;
|
|
dstSel :=Body^.CONTROL.dstSel;
|
|
|
|
Case engineSel of
|
|
WRITE_DATA_ENGINE_ME:
|
|
begin
|
|
//convert src_dmem -> src
|
|
|
|
with pctx^.curr_ibuf^ do
|
|
begin
|
|
src:=base+(Int64(src_dmem)-Int64(buff));
|
|
end;
|
|
|
|
pctx^.stream[pctx^.stream_type].WriteData(dstSel,dst,src,count,Body^.CONTROL.wrConfirm);
|
|
end;
|
|
WRITE_DATA_ENGINE_PFP:
|
|
begin
|
|
|
|
//FlushAndWaitMe(pctx);
|
|
|
|
case dstSel of
|
|
WRITE_DATA_DST_SEL_MEMORY_SYNC, //writeDataInline
|
|
WRITE_DATA_DST_SEL_TCL2, //writeDataInlineThroughL2
|
|
WRITE_DATA_DST_SEL_MEMORY_ASYNC:
|
|
begin
|
|
dst_dmem:=get_dmem_ptr(dst);
|
|
|
|
Move(src_dmem^,dst_dmem^,count*SizeOf(DWORD));
|
|
|
|
vm_map_track_trigger(p_proc.p_vmspace,QWORD(dst),QWORD(dst)+count*SizeOf(DWORD),nil,M_DMEM_WRITE);
|
|
end;
|
|
else
|
|
Assert(false,'WriteData: dstSel=0x'+HexStr(dstSel,1));
|
|
end;
|
|
|
|
end;
|
|
else
|
|
Assert(false,'WriteData: engineSel='+engine_str[engineSel]);
|
|
end;
|
|
|
|
end;
|
|
|
|
Function me_test_mem(pollAddr:Pointer;ref,mask:DWORD;compareFunc:Byte):Boolean;
|
|
var
|
|
val:DWORD;
|
|
begin
|
|
val:=PQWORD(pollAddr)^ and mask;
|
|
Case compareFunc of
|
|
WAIT_REG_MEM_FUNC_ALWAYS :Result:=True;
|
|
WAIT_REG_MEM_FUNC_LESS :Result:=(val<ref);
|
|
WAIT_REG_MEM_FUNC_LESS_EQUAL :Result:=(val<=ref);
|
|
WAIT_REG_MEM_FUNC_EQUAL :Result:=(val=ref);
|
|
WAIT_REG_MEM_FUNC_NOT_EQUAL :Result:=(val<>ref);
|
|
WAIT_REG_MEM_FUNC_GREATER_EQUAL:Result:=(val>=ref);
|
|
WAIT_REG_MEM_FUNC_GREATER :Result:=(val>ref);
|
|
else
|
|
Assert(false,'me_test_mem');
|
|
end;
|
|
end;
|
|
|
|
procedure onWaitRegMem(pctx:p_pfp_ctx;Body:PPM4CMDWAITREGMEM);
|
|
begin
|
|
|
|
if p_print_gpu_ops then
|
|
begin
|
|
Writeln(' engine =',engine_str[Body^.engine]);
|
|
Writeln(' memSpace =',Body^.memSpace);
|
|
Writeln(' operation =',Body^.operation);
|
|
Writeln(' pollAddress=0x',HexStr(Body^.pollAddress,10));
|
|
Writeln(' reference =0x',HexStr(Body^.reference,8));
|
|
Writeln(' mask =0x',HexStr(Body^.mask,8));
|
|
Writeln(' compareFunc=0x',HexStr(Body^.compareFunc,1));
|
|
end;
|
|
|
|
Assert(Body^.operation=0,'WaitRegMem: operation=0x'+HexStr(Body^.operation,1));
|
|
|
|
Case Body^.memSpace of
|
|
WAIT_REG_MEM_SPACE_MEMORY:;
|
|
else
|
|
Assert(False,'WaitRegMem: memSpace=0x'+HexStr(Body^.memSpace,1));
|
|
end;
|
|
|
|
Case Body^.engine of
|
|
WAIT_REG_MEM_ENGINE_ME:
|
|
begin
|
|
pctx^.stream[pctx^.stream_type].WaitRegMem(Pointer(Body^.pollAddress),Body^.reference,Body^.mask,Body^.compareFunc);
|
|
end;
|
|
WAIT_REG_MEM_ENGINE_PFP:
|
|
begin
|
|
|
|
pctx^.Flush_stream(pctx^.stream_type);
|
|
|
|
while not me_test_mem(Pointer(Body^.pollAddress),Body^.reference,Body^.mask,Body^.compareFunc) do
|
|
begin
|
|
msleep_td(hz div 10000);
|
|
end;
|
|
|
|
end;
|
|
else
|
|
Assert(false,'WaitRegMem: engine='+engine_str[Body^.engine]);
|
|
end;
|
|
|
|
end;
|
|
|
|
function revbinstr(val:int64;cnt:byte):shortstring;
|
|
var
|
|
i:Integer;
|
|
begin
|
|
Result[0]:=AnsiChar(cnt);
|
|
for i:=1 to cnt do
|
|
begin
|
|
Result[i]:=AnsiChar(48+val and 1);
|
|
val:=val shr 1;
|
|
end;
|
|
end;
|
|
|
|
function coherCntl_str(CNTL:TCP_COHER_CNTL):shortstring;
|
|
begin
|
|
Result:='';
|
|
if (CNTL.DEST_BASE_0_ENA <>0) then Result:=Result+'DS_B0 ';
|
|
if (CNTL.DEST_BASE_1_ENA <>0) then Result:=Result+'DS_B1 ';
|
|
if (CNTL.CB0_DEST_BASE_ENA <>0) then Result:=Result+'CB0_D ';
|
|
if (CNTL.CB1_DEST_BASE_ENA <>0) then Result:=Result+'CB1_D ';
|
|
if (CNTL.CB2_DEST_BASE_ENA <>0) then Result:=Result+'CB2_D ';
|
|
if (CNTL.CB3_DEST_BASE_ENA <>0) then Result:=Result+'CB3_D ';
|
|
if (CNTL.CB4_DEST_BASE_ENA <>0) then Result:=Result+'CB4_D ';
|
|
if (CNTL.CB5_DEST_BASE_ENA <>0) then Result:=Result+'CB5_D ';
|
|
if (CNTL.CB6_DEST_BASE_ENA <>0) then Result:=Result+'CB6_D ';
|
|
if (CNTL.CB7_DEST_BASE_ENA <>0) then Result:=Result+'CB7_D ';
|
|
if (CNTL.DB_DEST_BASE_ENA <>0) then Result:=Result+'DB_DS ';
|
|
if (CNTL.TCL1_VOL_ACTION_ENA <>0) then Result:=Result+'TCL1V ';
|
|
if (CNTL.TC_VOL_ACTION_ENA <>0) then Result:=Result+'TC_VA ';
|
|
if (CNTL.TC_WB_ACTION_ENA <>0) then Result:=Result+'TC_WB ';
|
|
if (CNTL.DEST_BASE_2_ENA <>0) then Result:=Result+'DS_B2 ';
|
|
if (CNTL.DEST_BASE_3_ENA <>0) then Result:=Result+'DS_B3 ';
|
|
if (CNTL.TCL1_ACTION_ENA <>0) then Result:=Result+'TCL1A ';
|
|
if (CNTL.TC_ACTION_ENA <>0) then Result:=Result+'TC_AC ';
|
|
if (CNTL.CB_ACTION_ENA <>0) then Result:=Result+'CB_AC ';
|
|
if (CNTL.DB_ACTION_ENA <>0) then Result:=Result+'DB_AC ';
|
|
if (CNTL.SH_KCACHE_ACTION_ENA <>0) then Result:=Result+'SH_KA ';
|
|
if (CNTL.SH_KCACHE_VOL_ACTION_ENA<>0) then Result:=Result+'SH_KV ';
|
|
if (CNTL.SH_ICACHE_ACTION_ENA <>0) then Result:=Result+'SH_IA ';
|
|
end;
|
|
|
|
procedure onAcquireMem(pctx:p_pfp_ctx;Body:PPM4ACQUIREMEM);
|
|
var
|
|
addr,size:QWORD;
|
|
begin
|
|
//Assert(pctx^.stream_type=stGfxDcb);
|
|
|
|
pctx^.UC_REG.CP_COHER_BASE_HI.COHER_BASE_HI_256B:=Body^.coherBaseHi;
|
|
DWORD(pctx^.UC_REG.CP_COHER_CNTL) :=Body^.coherCntl;
|
|
pctx^.UC_REG.CP_COHER_SIZE :=Body^.coherSizeLo;
|
|
pctx^.UC_REG.CP_COHER_BASE :=Body^.coherBaseLo;
|
|
pctx^.UC_REG.CP_COHER_SIZE_HI.COHER_SIZE_HI_256B:=Body^.coherSizeHi;
|
|
|
|
if p_print_gpu_ops then
|
|
begin
|
|
addr:=(QWORD(Body^.coherBaseLo) shl 8) or (QWORD(Body^.coherBaseHi) shl 40);
|
|
size:=(QWORD(Body^.coherSizeLo) shl 8) or (QWORD(Body^.coherSizeHi) shl 40);
|
|
|
|
Writeln('onAcquireMem:');
|
|
Writeln(' Cntl=',coherCntl_str(pctx^.UC_REG.CP_COHER_CNTL));
|
|
Writeln(' addr=0x',HexStr(addr,10));
|
|
Writeln(' size=0x',HexStr(size,10));
|
|
end;
|
|
|
|
//FlushAndWaitMe(pctx);
|
|
end;
|
|
|
|
procedure onContextControl(pctx:p_pfp_ctx;Body:PPM4CMDCONTEXTCONTROL);
|
|
begin
|
|
Assert(pctx^.stream_type=stGfxDcb);
|
|
|
|
if (DWORD(Body^.loadControl )<>$80000000) or
|
|
(DWORD(Body^.shadowEnable)<>$80000000) then
|
|
if p_print_gpu_ops then
|
|
begin
|
|
Writeln(stderr,' loadControl =b',revbinstr(DWORD(Body^.loadControl ),32));
|
|
Writeln(stderr,' shadowEnable=b',revbinstr(DWORD(Body^.shadowEnable),32));
|
|
end;
|
|
end;
|
|
|
|
procedure onSetBase(pctx:p_pfp_ctx;Body:PPM4CMDDRAWSETBASE);
|
|
var
|
|
addr:QWORD;
|
|
begin
|
|
Assert(pctx^.stream_type=stGfxDcb);
|
|
|
|
addr:=QWORD(Body^.address);
|
|
if (addr<>0) then
|
|
if p_print_gpu_ops then
|
|
begin
|
|
Writeln(' baseIndex=0x',HexStr(Body^.baseIndex,4));
|
|
Writeln(' address =0x',HexStr(addr,16));
|
|
end;
|
|
end;
|
|
|
|
procedure onSetPredication(pctx:p_pfp_ctx;Body:PPM4CMDSETPREDICATION);
|
|
const
|
|
c_pred_b:array[0..1] of PChar=('DrawIfNotVisible','DrawIfVisible');
|
|
c_hint_v:array[0..1] of PChar=('Wait','Draw');
|
|
c_pred_o:array[0..3] of PChar=('CLEAR','ZPASS','PRIMCOUNT','MEM');
|
|
begin
|
|
Assert(pctx^.stream_type=stGfxDcb);
|
|
|
|
if p_print_gpu_ops then
|
|
if (Body^.predOp<>SET_PRED_CLEAR) or (Body^.startAddress<>0) then
|
|
begin
|
|
Writeln(' startAddress=0x',HexStr(Body^.startAddress,10));
|
|
Writeln(' pred =',c_pred_b[Body^.predicationBoolean]);
|
|
Writeln(' hint =',c_hint_v[Body^.hint]);
|
|
Writeln(' predOp =',c_pred_o[Body^.predOp and 3]);
|
|
Writeln(' continueBit =',Body^.continueBit);
|
|
end;
|
|
end;
|
|
|
|
procedure onDrawPreamble(pctx:p_pfp_ctx;Body:PPM4CMDDRAWPREAMBLE);
|
|
begin
|
|
Assert(pctx^.stream_type=stGfxDcb);
|
|
|
|
pctx^.UC_REG.VGT_PRIMITIVE_TYPE:=Body^.control1;
|
|
pctx^.CX_REG.IA_MULTI_VGT_PARAM:=Body^.control2;
|
|
pctx^.CX_REG.VGT_LS_HS_CONFIG :=Body^.control3;
|
|
end;
|
|
|
|
procedure onClearState(pctx:p_pfp_ctx;Body:Pointer);
|
|
begin
|
|
Assert(pctx^.stream_type=stGfxDcb);
|
|
|
|
pctx^.clear_state;
|
|
end;
|
|
|
|
const
|
|
CONFIG_SPACE_START=$2000;
|
|
|
|
procedure onSetConfigReg(pctx:p_pfp_ctx;Body:PPM4CMDSETDATA);
|
|
var
|
|
i,c,r:WORD;
|
|
v:DWORD;
|
|
begin
|
|
Assert(pctx^.stream_type=stGfxDcb);
|
|
|
|
c:=Body^.header.count;
|
|
if (c<>0) then
|
|
begin
|
|
For i:=0 to c-1 do
|
|
begin
|
|
r:=CONFIG_SPACE_START+Body^.REG_OFFSET+i;
|
|
v:=PDWORD(@Body^.REG_DATA)[i];
|
|
//
|
|
if p_print_gpu_ops then
|
|
begin
|
|
Writeln(' SET:',getRegName(r),':=0x',HexStr(v,8));
|
|
end;
|
|
//
|
|
pctx^.set_reg(r,v);
|
|
end;
|
|
//
|
|
pctx^.LastSetReg:=CONFIG_SPACE_START+Body^.REG_OFFSET+c-1;
|
|
end;
|
|
end;
|
|
|
|
const
|
|
CONTEXT_REG_BASE=$A000;
|
|
|
|
procedure onSetContextReg(pctx:p_pfp_ctx;Body:PPM4CMDSETDATA);
|
|
var
|
|
i,c,r:WORD;
|
|
v:DWORD;
|
|
begin
|
|
Assert(pctx^.stream_type=stGfxDcb);
|
|
|
|
c:=Body^.header.count;
|
|
if (c<>0) then
|
|
begin
|
|
For i:=0 to c-1 do
|
|
begin
|
|
r:=Body^.REG_OFFSET+i;
|
|
v:=PDWORD(@Body^.REG_DATA)[i];
|
|
//
|
|
if p_print_gpu_ops then
|
|
begin
|
|
Writeln(' SET:',getRegName(r+CONTEXT_REG_BASE),':=0x',HexStr(v,8));
|
|
end;
|
|
//
|
|
pctx^.set_ctx_reg(r,v);
|
|
end;
|
|
//
|
|
pctx^.LastSetReg:=CONTEXT_REG_BASE+Body^.REG_OFFSET+c-1;
|
|
end;
|
|
end;
|
|
|
|
const
|
|
SH_REG_BASE=$2C00;
|
|
|
|
procedure onSetShReg(pctx:p_pfp_ctx;Body:PPM4CMDSETDATA);
|
|
var
|
|
i,c,r:WORD;
|
|
v:DWORD;
|
|
begin
|
|
Assert(pctx^.stream_type=stGfxDcb);
|
|
|
|
c:=Body^.header.count;
|
|
if (c<>0) then
|
|
begin
|
|
For i:=0 to c-1 do
|
|
begin
|
|
r:=Body^.REG_OFFSET+i;
|
|
v:=PDWORD(@Body^.REG_DATA)[i];
|
|
//
|
|
if p_print_gpu_ops then
|
|
begin
|
|
Writeln(' SET:',getRegName(r+SH_REG_BASE),':=0x',HexStr(v,8));
|
|
end;
|
|
//
|
|
pctx^.set_sh_reg(r,v);
|
|
end;
|
|
//
|
|
pctx^.LastSetReg:=SH_REG_BASE+Body^.REG_OFFSET+c-1;
|
|
end;
|
|
end;
|
|
|
|
Const
|
|
USERCONFIG_REG_BASE=$C000;
|
|
|
|
procedure onSetUConfigReg(pctx:p_pfp_ctx;Body:PPM4CMDSETDATA);
|
|
var
|
|
i,c,r:WORD;
|
|
v:DWORD;
|
|
begin
|
|
Assert(pctx^.stream_type=stGfxDcb);
|
|
|
|
c:=Body^.header.count;
|
|
if (c<>0) then
|
|
begin
|
|
For i:=0 to c-1 do
|
|
begin
|
|
r:=USERCONFIG_REG_BASE+Body^.REG_OFFSET+i;
|
|
v:=PDWORD(@Body^.REG_DATA)[i];
|
|
//
|
|
if p_print_gpu_ops then
|
|
begin
|
|
Writeln(' SET:',getRegName(r),':=0x',HexStr(v,8));
|
|
end;
|
|
//
|
|
pctx^.set_reg(r,v);
|
|
end;
|
|
//
|
|
pctx^.LastSetReg:=USERCONFIG_REG_BASE+Body^.REG_OFFSET+c-1;
|
|
end;
|
|
end;
|
|
|
|
procedure onPm40(pctx:p_pfp_ctx;Body:PPM4_TYPE_0_HEADER);
|
|
var
|
|
i,c,r:WORD;
|
|
v:DWORD;
|
|
begin
|
|
c:=Body^.count;
|
|
if (c<>0) then
|
|
For i:=0 to c-1 do
|
|
begin
|
|
r:=Body^.baseIndex+i;
|
|
v:=PDWORD(@Body[1])[i];
|
|
pctx^.set_reg(r,v);
|
|
end;
|
|
end;
|
|
|
|
procedure onIndexBufferSize(pctx:p_pfp_ctx;Body:PPM4CMDDRAWINDEXBUFFERSIZE);
|
|
begin
|
|
Assert(pctx^.stream_type=stGfxDcb);
|
|
|
|
pctx^.UC_REG.VGT_NUM_INDICES:=Body^.numIndices;
|
|
end;
|
|
|
|
procedure onIndexType(pctx:p_pfp_ctx;Body:PPM4CMDDRAWINDEXTYPE);
|
|
begin
|
|
Assert(pctx^.stream_type=stGfxDcb);
|
|
|
|
pctx^.CX_REG.VGT_DMA_INDEX_TYPE:=Body^.data;
|
|
pctx^.UC_REG.VGT_INDEX_TYPE.INDEX_TYPE:=pctx^.CX_REG.VGT_DMA_INDEX_TYPE.INDEX_TYPE;
|
|
end;
|
|
|
|
procedure onIndexBase(pctx:p_pfp_ctx;Body:PPM4CMDDRAWINDEXBASE);
|
|
begin
|
|
Assert(pctx^.stream_type=stGfxDcb);
|
|
|
|
Assert(Body^.baseSelect=0);
|
|
|
|
if p_print_gpu_ops then
|
|
begin
|
|
Writeln(' indexBase=',HexStr(PQWORD(@Body^.indexBaseLo)^,10));
|
|
end;
|
|
|
|
pctx^.CX_REG.VGT_DMA_BASE :=Body^.indexBaseLo and (not 1);
|
|
pctx^.CX_REG.VGT_DMA_BASE_HI.BASE_ADDR:=Body^.indexBaseHi;
|
|
end;
|
|
|
|
procedure onNumInstances(pctx:p_pfp_ctx;Body:PPM4CMDDRAWNUMINSTANCES);
|
|
begin
|
|
Assert(pctx^.stream_type=stGfxDcb);
|
|
|
|
if p_print_gpu_ops then
|
|
begin
|
|
Writeln(' numInstances=',Body^.numInstances);
|
|
end;
|
|
|
|
pctx^.CX_REG.VGT_DMA_NUM_INSTANCES:=Body^.numInstances;
|
|
pctx^.UC_REG.VGT_NUM_INSTANCES :=Body^.numInstances;
|
|
end;
|
|
|
|
procedure onDrawIndex2(pctx:p_pfp_ctx;Body:PPM4CMDDRAWINDEX2);
|
|
begin
|
|
Assert(pctx^.stream_type=stGfxDcb);
|
|
|
|
if (DWORD(Body^.drawInitiator)<>0) then
|
|
if p_print_gpu_ops then
|
|
begin
|
|
Writeln(stderr,' drawInitiator=b',revbinstr(DWORD(Body^.drawInitiator),32));
|
|
end;
|
|
|
|
if p_print_gpu_ops then
|
|
begin
|
|
Writeln(' indexBase =',HexStr(PQWORD(@Body^.indexBaseLo)^,10));
|
|
Writeln(' indexCount=',Body^.indexCount);
|
|
end;
|
|
|
|
pctx^.CX_REG.VGT_DMA_MAX_SIZE :=Body^.maxSize;
|
|
pctx^.CX_REG.VGT_DMA_BASE :=Body^.indexBaseLo and (not 1);
|
|
pctx^.CX_REG.VGT_DMA_BASE_HI.BASE_ADDR:=Body^.indexBaseHi;
|
|
pctx^.CX_REG.VGT_DMA_SIZE :=Body^.indexCount;
|
|
pctx^.UC_REG.VGT_NUM_INDICES :=Body^.indexCount;
|
|
pctx^.CX_REG.VGT_DRAW_INITIATOR :=Body^.drawInitiator;
|
|
|
|
pctx^.stream[stGfxDcb].DrawIndex2(pctx^.SG_REG,
|
|
pctx^.CX_REG,
|
|
pctx^.UC_REG);
|
|
|
|
//FlushAndWaitMe(pctx);
|
|
end;
|
|
|
|
procedure onDrawIndexOffset2(pctx:p_pfp_ctx;Body:PPM4CMDDRAWINDEXOFFSET2);
|
|
begin
|
|
Assert(pctx^.stream_type=stGfxDcb);
|
|
|
|
if (DWORD(Body^.drawInitiator)<>0) then
|
|
if p_print_gpu_ops then
|
|
begin
|
|
Writeln(stderr,' drawInitiator=b',revbinstr(DWORD(Body^.drawInitiator),32));
|
|
end;
|
|
|
|
pctx^.CX_REG.VGT_DMA_MAX_SIZE :=Body^.maxSize;
|
|
pctx^.CX_REG.VGT_DMA_SIZE :=Body^.indexCount;
|
|
pctx^.UC_REG.VGT_NUM_INDICES :=Body^.indexCount;
|
|
pctx^.CX_REG.VGT_DRAW_INITIATOR :=Body^.drawInitiator;
|
|
|
|
pctx^.stream[stGfxDcb].DrawIndexOffset2(pctx^.SG_REG,
|
|
pctx^.CX_REG,
|
|
pctx^.UC_REG,
|
|
Body^.indexOffset);
|
|
|
|
//FlushAndWaitMe(pctx);
|
|
end;
|
|
|
|
procedure onDrawIndexAuto(pctx:p_pfp_ctx;Body:PPM4CMDDRAWINDEXAUTO);
|
|
begin
|
|
Assert(pctx^.stream_type=stGfxDcb);
|
|
|
|
if (DWORD(Body^.drawInitiator)<>2) then
|
|
if p_print_gpu_ops then
|
|
begin
|
|
Writeln(stderr,' drawInitiator=b',revbinstr(DWORD(Body^.drawInitiator),32));
|
|
end;
|
|
|
|
if p_print_gpu_ops then
|
|
begin
|
|
Writeln(' indexCount=',Body^.indexCount);
|
|
end;
|
|
|
|
pctx^.CX_REG.VGT_DMA_SIZE :=Body^.indexCount;
|
|
pctx^.UC_REG.VGT_NUM_INDICES :=Body^.indexCount;
|
|
pctx^.CX_REG.VGT_DRAW_INITIATOR:=Body^.drawInitiator;
|
|
|
|
pctx^.stream[stGfxDcb].DrawIndexAuto(pctx^.SG_REG,
|
|
pctx^.CX_REG,
|
|
pctx^.UC_REG);
|
|
|
|
//FlushAndWaitMe(pctx);
|
|
end;
|
|
|
|
procedure onDrawIndexIndirectCountMulti(pctx:p_pfp_ctx;Body:PPM4CMDDRAWINDEXINDIRECTMULTI);
|
|
begin
|
|
Assert(pctx^.stream_type=stGfxDcb);
|
|
|
|
Assert(false,'IT_DRAW_INDEX_INDIRECT_COUNT_MULTI')
|
|
end;
|
|
|
|
procedure onDispatchDirect(pctx:p_pfp_ctx;Body:PPM4CMDDISPATCHDIRECT);
|
|
begin
|
|
Assert(pctx^.stream_type=stGfxDcb);
|
|
|
|
Assert(Body^.header.shaderType=1,'shaderType<>CS');
|
|
|
|
if (DWORD(Body^.dispatchInitiator)<>1) then
|
|
if p_print_gpu_ops then
|
|
begin
|
|
Writeln(stderr,' dispatchInitiator=b',revbinstr(DWORD(Body^.dispatchInitiator),32));
|
|
end;
|
|
|
|
if p_print_gpu_ops then
|
|
begin
|
|
Writeln(' dim=',Body^.dimX,' ',Body^.dimY,' ',Body^.dimZ);
|
|
end;
|
|
|
|
pctx^.SC_REG.COMPUTE_DIM_X:=Body^.dimX;
|
|
pctx^.SC_REG.COMPUTE_DIM_Y:=Body^.dimY;
|
|
pctx^.SC_REG.COMPUTE_DIM_Z:=Body^.dimZ;
|
|
pctx^.SC_REG.COMPUTE_DISPATCH_INITIATOR:=Body^.dispatchInitiator;
|
|
|
|
pctx^.stream[stGfxDcb].DispatchDirect(pctx^.SC_REG);
|
|
end;
|
|
|
|
procedure onPfpSyncMe(pctx:p_pfp_ctx;Body:Pointer);
|
|
begin
|
|
Assert(pctx^.stream_type=stGfxDcb);
|
|
|
|
//stallCommandBufferParser
|
|
//PFP waits until the ME completes all preceding commands before allowing the next batch to proceed.
|
|
|
|
FlushAndWaitMe(pctx);
|
|
end;
|
|
|
|
procedure onPushMarker(pctx:p_pfp_ctx;Body:PChar;size:Integer);
|
|
begin
|
|
if p_print_gpu_hint then
|
|
begin
|
|
Writeln('\HINT_PUSH_MARKER:',Body);
|
|
end;
|
|
pctx^.stream[pctx^.stream_type].Hint('\HINT_PUSH_MARKER:',Body,size);
|
|
end;
|
|
|
|
procedure onPopMarker(pctx:p_pfp_ctx);
|
|
begin
|
|
if p_print_gpu_hint then
|
|
begin
|
|
Writeln('\HINT_POP_MARKER');
|
|
end;
|
|
pctx^.stream[pctx^.stream_type].Hint('\HINT_POP_MARKER','',0);
|
|
end;
|
|
|
|
procedure onSetMarker(pctx:p_pfp_ctx;Body:PChar;size:Integer);
|
|
begin
|
|
if p_print_gpu_hint then
|
|
begin
|
|
Writeln('\HINT_SET_MARKER:',Body);
|
|
end;
|
|
pctx^.stream[pctx^.stream_type].Hint('\HINT_SET_MARKER:',Body,size);
|
|
end;
|
|
|
|
procedure onMarker(pctx:p_pfp_ctx;Body:PChar;size:Integer);
|
|
begin
|
|
if p_print_gpu_hint then
|
|
begin
|
|
Writeln('\HINT_MARKER');
|
|
end;
|
|
pctx^.stream[pctx^.stream_type].Hint('\HINT_MARKER','',0);
|
|
end;
|
|
|
|
procedure onWidthHeight(Body:PWORD);
|
|
begin
|
|
if p_print_gpu_hint then
|
|
begin
|
|
Writeln('\HINT_',Body[0],'_',Body[1]);
|
|
end;
|
|
end;
|
|
|
|
procedure onPrepareFlipLabel(Body:PPM4PrepareFlip);
|
|
begin
|
|
if p_print_gpu_hint then
|
|
begin
|
|
Writeln('\HINT_PREPARE_FLIP_LABEL:0x',HexStr(Body^.ADDRES,16),':',HexStr(Body^.DATA,8));
|
|
end;
|
|
end;
|
|
|
|
procedure onPrepareFlipWithEopInterrupt(Body:PPM4PrepareFlipWithEopInterrupt);
|
|
begin
|
|
if p_print_gpu_hint then
|
|
begin
|
|
Writeln('\HINT_PREPARE_FLIP_WITH_EOP_INTERRUPT:0x',HexStr(Body^.ADDRES,16),':',HexStr(Body^.DATA,8));
|
|
end;
|
|
end;
|
|
|
|
procedure onPrepareFlipWithEopInterruptLabel(Body:PPM4PrepareFlipWithEopInterrupt);
|
|
begin
|
|
if p_print_gpu_hint then
|
|
begin
|
|
Writeln('\HINT_PREPARE_FLIP_WITH_EOP_INTERRUPT_LABEL:0x',HexStr(Body^.ADDRES,16),':',HexStr(Body^.DATA,8));
|
|
end;
|
|
end;
|
|
|
|
procedure onNop(pctx:p_pfp_ctx;Body:PDWORD);
|
|
begin
|
|
|
|
case pctx^.stream_type of
|
|
stGfxDcb,
|
|
stGfxCcb:
|
|
begin
|
|
|
|
Case pctx^.LastSetReg of
|
|
mmPA_SC_SCREEN_SCISSOR_BR,
|
|
|
|
mmCB_COLOR0_FMASK_SLICE,
|
|
mmCB_COLOR1_FMASK_SLICE,
|
|
mmCB_COLOR2_FMASK_SLICE,
|
|
mmCB_COLOR3_FMASK_SLICE,
|
|
mmCB_COLOR4_FMASK_SLICE,
|
|
mmCB_COLOR5_FMASK_SLICE,
|
|
mmCB_COLOR6_FMASK_SLICE,
|
|
mmCB_COLOR7_FMASK_SLICE,
|
|
|
|
mmCB_COLOR0_DCC_BASE,
|
|
mmCB_COLOR1_DCC_BASE,
|
|
mmCB_COLOR2_DCC_BASE,
|
|
mmCB_COLOR3_DCC_BASE,
|
|
mmCB_COLOR4_DCC_BASE,
|
|
mmCB_COLOR5_DCC_BASE,
|
|
mmCB_COLOR6_DCC_BASE,
|
|
mmCB_COLOR7_DCC_BASE,
|
|
|
|
mmDB_STENCIL_CLEAR,
|
|
//mmDB_RENDER_CONTROL,
|
|
|
|
mmDB_HTILE_SURFACE:
|
|
begin
|
|
onWidthHeight(@Body[1]);
|
|
Exit;
|
|
end;
|
|
else;
|
|
end;
|
|
|
|
end;
|
|
else;
|
|
end;
|
|
|
|
case Body[1] of
|
|
|
|
OP_HINT_PUSH_MARKER:
|
|
begin
|
|
onPushMarker(pctx,@Body[2],PM4_LENGTH(Body[0]) - 8);
|
|
end;
|
|
|
|
OP_HINT_POP_MARKER:
|
|
begin
|
|
onPopMarker(pctx);
|
|
end;
|
|
|
|
OP_HINT_SET_MARKER:
|
|
begin
|
|
onSetMarker(pctx,@Body[2],PM4_LENGTH(Body[0]) - 8);
|
|
end;
|
|
|
|
OP_HINT_MARKER:
|
|
begin
|
|
onMarker(pctx,@Body[2],PM4_LENGTH(Body[0]) - 8);
|
|
end;
|
|
|
|
OP_HINT_PREPARE_FLIP_LABEL:
|
|
begin
|
|
onPrepareFlipLabel(@Body[2]);
|
|
end;
|
|
|
|
OP_HINT_PREPARE_FLIP_WITH_EOP_INTERRUPT_VOID:
|
|
begin
|
|
onPrepareFlipWithEopInterrupt(@Body[2]);
|
|
end;
|
|
|
|
OP_HINT_PREPARE_FLIP_WITH_EOP_INTERRUPT_LABEL:
|
|
begin
|
|
onPrepareFlipWithEopInterruptLabel(@Body[2]);
|
|
end;
|
|
|
|
else
|
|
if p_print_gpu_hint then
|
|
begin
|
|
Writeln('\HINT_',get_hint_name(Body[1]));
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function pm4_parse_dcb(pctx:p_pfp_ctx;token:DWORD;buff:Pointer):Integer;
|
|
begin
|
|
Result:=0;
|
|
|
|
case PM4_TYPE(token) of
|
|
0:begin //PM4_TYPE_0
|
|
if p_print_gpu_ops then Writeln('PM4_TYPE_0 len:',PM4_LENGTH(token));
|
|
onPm40(pctx,buff);
|
|
end;
|
|
2:begin //PM4_TYPE_2
|
|
if p_print_gpu_ops then Writeln('PM4_TYPE_2');
|
|
//no body
|
|
end;
|
|
3:begin //PM4_TYPE_3
|
|
if p_print_gpu_ops then
|
|
if (PM4_TYPE_3_HEADER(token).opcode<>IT_NOP) or
|
|
(not p_print_gpu_hint) then
|
|
begin
|
|
Writeln('IT_',get_op_name(PM4_TYPE_3_HEADER(token).opcode),
|
|
' ',ShdrType[PM4_TYPE_3_HEADER(token).shaderType],
|
|
' len:',PM4_LENGTH(token));
|
|
end;
|
|
|
|
case PM4_TYPE_3_HEADER(token).opcode of
|
|
IT_NOP :onNop (pctx,buff);
|
|
IT_WRITE_DATA :onWriteData (pctx,buff);
|
|
IT_EVENT_WRITE :onEventWrite (pctx,buff);
|
|
IT_EVENT_WRITE_EOP :onEventWriteEop (pctx,buff);
|
|
IT_EVENT_WRITE_EOS :onEventWriteEos (pctx,buff);
|
|
IT_DMA_DATA :onDmaData (pctx,buff);
|
|
IT_WAIT_REG_MEM :onWaitRegMem (pctx,buff);
|
|
IT_ACQUIRE_MEM :onAcquireMem (pctx,buff);
|
|
IT_CONTEXT_CONTROL :onContextControl (pctx,buff);
|
|
IT_DRAW_PREAMBLE :onDrawPreamble (pctx,buff);
|
|
IT_CLEAR_STATE :onClearState (pctx,buff);
|
|
IT_SET_CONFIG_REG :onSetConfigReg (pctx,buff);
|
|
IT_SET_CONTEXT_REG :onSetContextReg (pctx,buff);
|
|
IT_SET_SH_REG :onSetShReg (pctx,buff);
|
|
IT_SET_UCONFIG_REG :onSetUConfigReg (pctx,buff);
|
|
IT_INDEX_BUFFER_SIZE :onIndexBufferSize (pctx,buff);
|
|
IT_INDEX_TYPE :onIndexType (pctx,buff);
|
|
IT_INDEX_BASE :onIndexBase (pctx,buff);
|
|
IT_NUM_INSTANCES :onNumInstances (pctx,buff);
|
|
IT_DRAW_INDEX_2 :onDrawIndex2 (pctx,buff);
|
|
IT_DRAW_INDEX_OFFSET_2 :onDrawIndexOffset2 (pctx,buff);
|
|
IT_DRAW_INDEX_AUTO :onDrawIndexAuto (pctx,buff);
|
|
IT_DRAW_INDEX_INDIRECT_COUNT_MULTI:onDrawIndexIndirectCountMulti(pctx,buff);
|
|
IT_DISPATCH_DIRECT :onDispatchDirect (pctx,buff);
|
|
IT_PFP_SYNC_ME :onPfpSyncMe (pctx,buff);
|
|
|
|
IT_SET_BASE :onSetBase (pctx,buff);
|
|
IT_SET_PREDICATION :onSetPredication (pctx,buff);
|
|
|
|
IT_INCREMENT_DE_COUNTER :onIncrementDECounter (pctx,buff);
|
|
IT_WAIT_ON_CE_COUNTER :onWaitOnCECounter (pctx,buff);
|
|
|
|
else
|
|
begin
|
|
Writeln(stderr,'PM4_TYPE_3.opcode:',get_op_name(PM4_TYPE_3_HEADER(token).opcode));
|
|
Assert(False);
|
|
end;
|
|
end;
|
|
|
|
case PM4_TYPE_3_HEADER(token).opcode of
|
|
IT_SET_CONFIG_REG :;
|
|
IT_SET_CONTEXT_REG:;
|
|
IT_SET_SH_REG :;
|
|
IT_SET_UCONFIG_REG:;
|
|
else
|
|
pctx^.LastSetReg:=0;
|
|
end;
|
|
|
|
|
|
end;
|
|
else
|
|
begin
|
|
Writeln(stderr,'PM4_TYPE_',PM4_TYPE(token));
|
|
Assert(False);
|
|
end;
|
|
end;
|
|
|
|
end;
|
|
|
|
procedure onSetShRegCompute(pctx:p_pfp_ctx;Body:PPM4CMDSETDATA);
|
|
var
|
|
i,c,r:WORD;
|
|
v:DWORD;
|
|
begin
|
|
c:=Body^.header.count;
|
|
if (c<>0) then
|
|
begin
|
|
For i:=0 to c-1 do
|
|
begin
|
|
r:=Body^.REG_OFFSET+i;
|
|
v:=PDWORD(@Body^.REG_DATA)[i];
|
|
//
|
|
if p_print_gpu_ops then
|
|
begin
|
|
Writeln(' [ASC]SET:',getRegName(r+$2C00),':=0x',HexStr(v,8));
|
|
end;
|
|
//
|
|
pctx^.set_sh_reg_compute(r,v);
|
|
end;
|
|
//
|
|
end;
|
|
end;
|
|
|
|
procedure onDispatchDirectCompute(pctx:p_pfp_ctx;Body:PPM4CMDDISPATCHDIRECT);
|
|
var
|
|
c_id:Byte;
|
|
begin
|
|
Assert(Body^.header.shaderType=1,'shaderType<>CS');
|
|
|
|
if (DWORD(Body^.dispatchInitiator)<>1) then
|
|
if p_print_gpu_ops then
|
|
begin
|
|
Writeln(stderr,' dispatchInitiator=b',revbinstr(DWORD(Body^.dispatchInitiator),32));
|
|
end;
|
|
|
|
c_id:=pctx^.curr_ibuf^.c_id;
|
|
|
|
pctx^.ASC_COMPUTE[c_id].COMPUTE_DIM_X:=Body^.dimX;
|
|
pctx^.ASC_COMPUTE[c_id].COMPUTE_DIM_Y:=Body^.dimY;
|
|
pctx^.ASC_COMPUTE[c_id].COMPUTE_DIM_Z:=Body^.dimZ;
|
|
pctx^.ASC_COMPUTE[c_id].COMPUTE_DISPATCH_INITIATOR:=Body^.dispatchInitiator;
|
|
|
|
pctx^.stream[pctx^.stream_type].DispatchDirect(pctx^.ASC_COMPUTE[c_id]);
|
|
end;
|
|
|
|
procedure onReleaseMemCompute(pctx:p_pfp_ctx;Body:PPM4CMDRELEASEMEM);
|
|
begin
|
|
Case Body^.eventType of
|
|
CS_DONE,
|
|
CACHE_FLUSH_TS, //FlushCbDbCache
|
|
CACHE_FLUSH_AND_INV_TS_EVENT, //FlushAndInvalidateCbDbCaches
|
|
BOTTOM_OF_PIPE_TS, //CbDbReadsDone
|
|
FLUSH_AND_INV_DB_DATA_TS, //FlushAndInvalidateDbCache
|
|
FLUSH_AND_INV_CB_DATA_TS:; //FlushAndInvalidateCbCache
|
|
else
|
|
Assert(False,'ReleaseMem: eventType=0x'+HexStr(Body^.eventType,1));
|
|
end;
|
|
|
|
case Body^.eventIndex of
|
|
EVENT_WRITE_INDEX_ANY_EOP_TIMESTAMP:;
|
|
EVENT_WRITE_INDEX_ANY_EOS_TIMESTAMP:;
|
|
else
|
|
Assert(False,'ReleaseMem: eventIndex=0x'+HexStr(Body^.eventIndex,1));
|
|
end;
|
|
|
|
DWORD(pctx^.CX_REG.VGT_EVENT_INITIATOR):=Body^.eventType;
|
|
|
|
if p_print_gpu_ops then
|
|
begin
|
|
Case Body^.eventType of
|
|
CS_DONE,
|
|
CACHE_FLUSH_TS :Writeln(' eventType =','FlushCbDbCache');
|
|
CACHE_FLUSH_AND_INV_TS_EVENT:Writeln(' eventType =','FlushAndInvalidateCbDbCaches');
|
|
BOTTOM_OF_PIPE_TS :Writeln(' eventType =','CbDbReadsDone');
|
|
FLUSH_AND_INV_DB_DATA_TS :Writeln(' eventType =','FlushAndInvalidateDbCache');
|
|
FLUSH_AND_INV_CB_DATA_TS :Writeln(' eventType =','FlushAndInvalidateCbCache');
|
|
else;
|
|
end;
|
|
|
|
Writeln(' interrupt =0x',HexStr(Body^.intSel,2));
|
|
Writeln(' srcSelector=0x',HexStr(Body^.dataSel,2));
|
|
Writeln(' dstSelector=0x',HexStr(Body^.dstSel,2));
|
|
Writeln(' dstGpuAddr =0x',HexStr(Body^.address,10));
|
|
Writeln(' immValue =0x',HexStr(Body^.data,16));
|
|
end;
|
|
|
|
pctx^.stream[pctx^.stream_type].ReleaseMem(Pointer(Body^.address),Body^.data,Body^.eventType,Body^.dataSel,Body^.dstSel,Body^.intSel);
|
|
|
|
pctx^.Flush_stream(pctx^.stream_type);
|
|
end;
|
|
|
|
procedure onIndirectBufferCompute(pctx:p_pfp_ctx;Body:PPM4CMDINDIRECTBUFFER);
|
|
var
|
|
curr_ibuf:p_pm4_ibuffer;
|
|
ibuf:t_pm4_ibuffer;
|
|
i:Integer;
|
|
begin
|
|
if p_print_gpu_ops then
|
|
begin
|
|
Writeln('[ASC]INDIRECT_BUFFER (CS) 0x',HexStr(Body^.ibBase,10));
|
|
end;
|
|
|
|
if pm4_ibuf_init(@ibuf,Body,@pm4_parse_compute_ring,pctx^.stream_type) then
|
|
begin
|
|
curr_ibuf:=pctx^.curr_ibuf;
|
|
|
|
i:=pm4_ibuf_parse(pctx,@ibuf);
|
|
|
|
if (i<>0) then
|
|
begin
|
|
pctx^.add_stall(@ibuf);
|
|
end;
|
|
|
|
pctx^.curr_ibuf:=curr_ibuf;
|
|
end;
|
|
end;
|
|
|
|
function pm4_parse_compute_ring(pctx:p_pfp_ctx;token:DWORD;buff:Pointer):Integer;
|
|
var
|
|
ibuf:t_pm4_ibuffer;
|
|
i:Integer;
|
|
begin
|
|
Result:=0;
|
|
|
|
case PM4_TYPE(token) of
|
|
0:begin //PM4_TYPE_0
|
|
if p_print_gpu_ops then Writeln('[ASC]PM4_TYPE_0 len:',PM4_LENGTH(token));
|
|
onPm40(pctx,buff);
|
|
end;
|
|
2:begin //PM4_TYPE_2
|
|
if p_print_gpu_ops then Writeln('[ASC]PM4_TYPE_2');
|
|
//no body
|
|
end;
|
|
3:begin //PM4_TYPE_3
|
|
if p_print_gpu_ops then
|
|
if (PM4_TYPE_3_HEADER(token).opcode<>IT_NOP) or
|
|
(not p_print_gpu_hint) then
|
|
begin
|
|
Writeln('[ASC]IT_',get_op_name(PM4_TYPE_3_HEADER(token).opcode),
|
|
' ',ShdrType[PM4_TYPE_3_HEADER(token).shaderType],
|
|
' len:',PM4_LENGTH(token));
|
|
end;
|
|
|
|
case PM4_TYPE_3_HEADER(token).opcode of
|
|
IT_NOP :onNop (pctx,buff);
|
|
IT_WRITE_DATA :onWriteData (pctx,buff);
|
|
IT_DMA_DATA :onDmaData (pctx,buff);
|
|
IT_SET_SH_REG :onSetShRegCompute (pctx,buff);
|
|
IT_DISPATCH_DIRECT :onDispatchDirectCompute(pctx,buff);
|
|
IT_RELEASE_MEM :onReleaseMemCompute (pctx,buff);
|
|
IT_WAIT_REG_MEM :onWaitRegMem (pctx,buff);
|
|
IT_ACQUIRE_MEM :onAcquireMem (pctx,buff);
|
|
IT_INDIRECT_BUFFER :onIndirectBufferCompute(pctx,buff);
|
|
else
|
|
begin
|
|
Writeln(stderr,'[ASC]PM4_TYPE_3.opcode:',get_op_name(PM4_TYPE_3_HEADER(token).opcode));
|
|
Assert (False ,'[ASC]PM4_TYPE_3.opcode:'+get_op_name(PM4_TYPE_3_HEADER(token).opcode));
|
|
end;
|
|
end;
|
|
|
|
end;
|
|
else
|
|
begin
|
|
Writeln(stderr,'[ASC]PM4_TYPE_',PM4_TYPE(token));
|
|
Assert (False ,'[ASC]PM4_TYPE_'+IntToStr(PM4_TYPE(token)));
|
|
end;
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
end.
|
|
|