This commit is contained in:
Pavel 2024-03-27 12:46:07 +03:00
parent 80d44546cd
commit 0932250ac4
8 changed files with 270 additions and 18 deletions

View File

@ -319,6 +319,36 @@ type
addressHi:bit16; // < base address Hi of buffer
end;
const
SET_PRED_CLEAR =0;
SET_PRED_ZPASS =1;
SET_PRED_PRIMCOUNT=2;
SET_PRED_MEM =3;
type
PPM4CMDSETPREDICATION=^PM4CMDSETPREDICATION;
PM4CMDSETPREDICATION=bitpacked record
header :PM4_TYPE_3_HEADER;
startAddressLo :bit32; // < start address low
startAddrHi :bit8; // < start address hi
predicationBoolean:bit1; // < predication boolean
reserved1 :bit3;
hint :bit1; // < hint
// < (only valid for Zpass/Occlusion Predicate)
reserved2 :bit3;
predOp :bit3; // < predicate operation
reserved3 :bit12;
continueBit :bit1; // < continue set predication
end;
PPM4CMDDRAWPREAMBLE=^PM4CMDDRAWPREAMBLE;
PM4CMDDRAWPREAMBLE=bitpacked record
header :PM4_TYPE_3_HEADER;
control1 :TVGT_PRIMITIVE_TYPE; //< writes to VGT_PRIMITIVE_TYPE reg
control2 :TIA_MULTI_VGT_PARAM; //< writes to IA_MULTI_VGT_PARAM reg
control3 :TVGT_LS_HS_CONFIG; //< writes to VGT_LS_HS_CONFIG reg
end;
// WRITE_DATA DST_SEL and ENGINE definitions
const
WRITE_DATA_DST_SEL_REGISTER =0;

View File

@ -635,7 +635,7 @@ begin
cfg.hOutput:=FAddHandle;
cfg.hError :=FAddHandle;
cfg.fork_proc:=False;
cfg.fork_proc:=True;
if Item.FLock then Exit;

View File

@ -165,22 +165,52 @@ begin
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;
procedure onContextControl(Body:PPM4CMDCONTEXTCONTROL);
begin
Writeln(' loadControl =b',BinStr(DWORD(Body^.loadControl ),32));
Writeln(' shadowEnable=b',BinStr(DWORD(Body^.shadowEnable),32));
Writeln(' loadControl =b',revbinstr(DWORD(Body^.loadControl ),32));
Writeln(' shadowEnable=b',revbinstr(DWORD(Body^.shadowEnable),32));
end;
procedure onSetBase(Body:PPM4CMDDRAWSETBASE);
var
addr:QWORD;
begin
addr:=Body^.addressLo or Body^.addressHi;
addr:=Body^.addressLo or (Body^.addressHi shl 32);
Writeln(' baseIndex=0x',HexStr(Body^.baseIndex,4));
Writeln(' address =0x',HexStr(addr,16));
end;
procedure onSetPredication(Body:PPM4CMDSETPREDICATION);
var
addr:QWORD;
begin
addr:=Body^.startAddressLo or (Body^.startAddrHi shl 32);
Writeln(' startAddress=0x',HexStr(addr,16));
Writeln(' pred =',Body^.predicationBoolean);
Writeln(' hint =',Body^.hint);
Writeln(' predOp =',Body^.predOp);
Writeln(' continueBit =',Body^.continueBit);
end;
procedure onDrawPreamble(Body:PPM4CMDDRAWPREAMBLE);
begin
//Writeln;
end;
procedure onSetShReg(Body:PPM4CMDSETDATA);
begin
Writeln(' 0x',HexStr(SH_REG_BASE+Body^.REG_OFFSET,4),'..',
@ -240,8 +270,8 @@ begin
IT_PFP_SYNC_ME :;
IT_SET_BASE :onSetBase(buff);
IT_DRAW_PREAMBLE :;
IT_SET_PREDICATION :;
IT_DRAW_PREAMBLE :onDrawPreamble(buff);
IT_SET_PREDICATION :onSetPredication(buff);
else;
end;

View File

@ -383,7 +383,7 @@ var
),
(//[65]
sy_narg:3;
sy_call:nil;
sy_call:@sys_msync;
sy_name:'sys_msync'
),
(//[66]
@ -1443,7 +1443,7 @@ var
),
(//[277]
sy_narg:3;
sy_call:nil;
sy_call:@sys_msync;
sy_name:'sys_msync'
),
(//[278]

View File

@ -45,6 +45,7 @@ function readlink(path,buf:PChar;count:QWORD):Integer;
function _execve(fname:pchar;argv,envv:ppchar):Integer;
function umask(newmask:Integer):Integer;
function chroot(path:PChar):Integer;
function msync(addr:Pointer;len:QWORD;flags:Integer):Integer;
function munmap(addr:Pointer;len:QWORD):Integer;
function mprotect(addr:Pointer;len:QWORD;prot:Integer):Integer;
function madvise(addr:Pointer;len:QWORD;behav:Integer):Integer;
@ -525,6 +526,13 @@ asm
jmp cerror
end;
function msync(addr:Pointer;len:QWORD;flags:Integer):Integer; assembler; nostackframe;
asm
movq $65,%rax
call fast_syscall
jmp cerror
end;
function munmap(addr:Pointer;len:QWORD):Integer; assembler; nostackframe;
asm
movq $73,%rax

View File

@ -225,6 +225,12 @@ function vm_map_madvise(map :vm_map_t;
__end:vm_offset_t;
behav:Integer):Integer;
function vm_map_sync(map :vm_map_t;
start :vm_offset_t;
__end :vm_offset_t;
syncio :Boolean;
invalidate:Boolean):Integer;
function vm_map_find(map :vm_map_t;
vm_obj :vm_object_t;
offset :vm_ooffset_t;
@ -257,7 +263,7 @@ function vm_map_stack(map :vm_map_t;
function vm_map_growstack(map:vm_map_t;addr:vm_offset_t):Integer;
function vmspace_exec(minuser,maxuser:vm_offset_t):Integer;
procedure vm_map_lock(map:vm_map_t);
procedure vm_map_lock(map:vm_map_t;tm:Boolean=True);
function vm_map_trylock(map:vm_map_t):Boolean;
procedure vm_map_unlock(map:vm_map_t);
@ -277,6 +283,7 @@ procedure vminit; //SYSINIT
implementation
uses
md_map,
kern_proc,
rmem_map,
kern_budget;
@ -398,10 +405,13 @@ begin
Result:=vm;
end;
procedure vm_map_lock(map:vm_map_t);
procedure vm_map_lock(map:vm_map_t;tm:Boolean=True);
begin
mtx_lock(map^.lock);
Inc(map^.timestamp);
if tm then
begin
Inc(map^.timestamp);
end;
end;
function vm_map_trylock(map:vm_map_t):Boolean;
@ -2088,9 +2098,9 @@ end;
*
* Returns an error if any part of the specified range is not mapped.
}
function vm_map_sync(map :vm_map_t;
start:vm_offset_t;
__end:vm_offset_t;
function vm_map_sync(map :vm_map_t;
start :vm_offset_t;
__end :vm_offset_t;
syncio :Boolean;
invalidate:Boolean):Integer;
var
@ -2118,12 +2128,20 @@ begin
start:=entry^.start;
__end:=entry^.__end;
end;
{
* Make a first pass to check for user-wired memory and holes.
}
current:=entry;
while (current<>@map^.header) and (current^.start<__end) do
begin
if invalidate and
((current^.eflags and MAP_ENTRY_USER_WIRED)<>0) then
begin
vm_map_unlock(map);
Exit(KERN_INVALID_ARGUMENT);
end;
if (__end>current^.__end) and
((current^.next=@map^.header) or
(current^.__end<>current^.next^.start)) then
@ -2137,8 +2155,10 @@ begin
if invalidate then
begin
//
md_cacheflush(Pointer(start),__end-start,ICACHE or DCACHE);
//pmap_remove(map^.pmap, start, end);
end;
failed:=FALSE;
{
@ -2183,11 +2203,16 @@ begin
vm_object_reference(obj);
last_timestamp:=map^.timestamp;
vm_map_unlock(map);
//if (not vm_object_sync(_object, offset, size, syncio, invalidate)) then
// failed:=TRUE;
if (not vm_object_sync(obj, offset, size, syncio, invalidate)) then
begin
failed:=TRUE;
end;
start:=start+size;
vm_object_deallocate(obj);
vm_map_lock(map);
vm_map_lock(map,False);
if (last_timestamp=map^.timestamp) or
(not vm_map_lookup_entry(map, start, @current)) then
begin

View File

@ -28,6 +28,7 @@ type
pos :QWORD):Pointer;
function sys_munmap(addr:Pointer;len:QWORD):Integer;
function sys_msync(addr:Pointer;len:QWORD;flags:Integer):Integer;
function sys_mprotect(addr:Pointer;len:QWORD;prot:Integer):Integer;
function sys_madvise(addr:Pointer;len:QWORD;behav:Integer):Integer;
function sys_mname(addr:Pointer;len:QWORD;name:PChar):Integer;
@ -842,6 +843,50 @@ begin
Exit(0);
end;
function sys_msync(addr:Pointer;len:QWORD;flags:Integer):Integer;
var
map:vm_map_t;
_addr:vm_offset_t;
pageoff:vm_size_t;
begin
_addr:=vm_offset_t(addr);
pageoff:=(_addr and PAGE_MASK);
_addr:=_addr-pageoff;
len:=len+pageoff;
len:=round_page(len);
if ((_addr + len) < _addr) then
begin
Exit(EINVAL);
end;
if ((flags and (MS_ASYNC or MS_INVALIDATE))=(MS_ASYNC or MS_INVALIDATE)) then
begin
Exit(EINVAL);
end;
map:=p_proc.p_vmspace;
// Clean the pages and interpret the Exit value.
Result:=vm_map_sync(map,
_addr,
_addr + len,
(flags and MS_ASYNC)=0,
(flags and MS_INVALIDATE)<>0);
case Result of
KERN_SUCCESS :Result:=0;
KERN_INVALID_ADDRESS :Result:=ENOMEM;
KERN_INVALID_ARGUMENT:Result:=EBUSY;
KERN_FAILURE :Result:=EIO;
else
Result:=EINVAL;
end;
end;
function sys_mprotect(addr:Pointer;len:QWORD;prot:Integer):Integer;
var
size,pageoff:vm_size_t;

View File

@ -39,6 +39,12 @@ procedure vm_object_madvise(pmap :Pointer;
__end :vm_offset_t;
advise:Integer);
function vm_object_sync(obj :vm_object_t;
offset :vm_ooffset_t;
size :vm_size_t;
syncio :Boolean;
invalidate:Boolean):Boolean;
implementation
uses
@ -504,6 +510,114 @@ begin
VM_OBJECT_UNLOCK(obj);
end;
{
* Note that there is absolutely no sense in writing out
* anonymous objects, so we track down the vnode object
* to write out.
* We invalidate (remove) all pages from the address space
* for semantic correctness.
*
* If the backing object is a device object with unmanaged pages, then any
* mappings to the specified range of pages must be removed before this
* function is called.
*
* Note: certain anonymous maps, such as MAP_NOSYNC maps,
* may start out with a nil object.
}
function vm_object_sync(obj :vm_object_t;
offset :vm_ooffset_t;
size :vm_size_t;
syncio :Boolean;
invalidate:Boolean):Boolean;
var
vp:p_vnode;
mp:p_mount;
error,flags:Integer;
vfslocked:Integer;
fsync_after:Boolean;
res:Boolean;
begin
if (obj=nil) then Exit(TRUE);
res:=TRUE;
error:=0;
VM_OBJECT_LOCK(obj);
{
* Flush pages if writing is allowed, invalidate them
* if invalidation requested. Pages undergoing I/O
* will be ignored by vm_object_page_remove().
*
* We cannot lock the vnode and then wait for paging
* to complete without deadlocking against vm_fault.
* Instead we simply call vm_object_page_remove() and
* allow it to block internally on a page-by-page
* basis when it encounters pages undergoing async
* I/O.
}
if (obj^.otype=OBJT_VNODE) and
((obj^.flags and OBJ_MIGHTBEDIRTY)<>0) then
begin
vp:=obj^.handle;
VM_OBJECT_UNLOCK(obj);
vn_start_write(vp, @mp, V_WAIT);
vfslocked:=VFS_LOCK_GIANT(vp^.v_mount);
vn_lock(vp, LK_EXCLUSIVE or LK_RETRY);
if (syncio) and
(not invalidate) and
(offset=0) and
(OFF_TO_IDX(size)=obj^.size) then
begin
{
* If syncing the whole mapping of the file,
* it is faster to schedule all the writes in
* async mode, also allowing the clustering,
* and then wait for i/o to complete.
}
flags:=0;
fsync_after:=TRUE;
end else
begin
flags:=0;
if (syncio or invalidate) then
begin
flags:=flags or OBJPC_SYNC;
end;
if (invalidate) then
begin
flags:=flags or (OBJPC_SYNC or OBJPC_INVAL);
end;
fsync_after:=FALSE;
end;
VM_OBJECT_LOCK(obj);
res:=vm_object_page_clean(obj, offset, offset + size, flags);
VM_OBJECT_UNLOCK(obj);
if (fsync_after) then
begin
error:=VOP_FSYNC(vp, MNT_WAIT);
end;
VOP_UNLOCK(vp, 0);
VFS_UNLOCK_GIANT(vfslocked);
vn_finished_write(mp);
if (error<>0) then
begin
res:=FALSE;
end;
VM_OBJECT_LOCK(obj);
end;
VM_OBJECT_UNLOCK(obj);
Exit(res);
end;