Big refraction of structuring CFG and many minor fixes

This commit is contained in:
Pavel 2025-05-21 23:47:07 +03:00
parent 8e2961f5f6
commit 5b701a35d1
37 changed files with 3457 additions and 3474 deletions

View File

@ -1244,8 +1244,7 @@ type
ENCODING:bit6;
ADDR:Byte; //(vbindex)
DATA0:Byte; //(vsrc0)
DATA1:Byte; //(vsrc1)
DATA:array[0..1] of Byte; //(vsrc0),(vsrc1)
VDST:Byte;
end;
@ -3869,7 +3868,7 @@ begin
TBUFFER_LOAD_FORMAT_X :str:='TBUFFER_LOAD_FORMAT_X';
TBUFFER_LOAD_FORMAT_XY :str:='TBUFFER_LOAD_FORMAT_XY';
TBUFFER_LOAD_FORMAT_XYZ :str:='TBUFFER_LOAD_FORMAT_XYZ';
TBUFFER_LOAD_FORMAT_XYZW :str:='TBUFFER_LOAD_FORMAT_XYZ';
TBUFFER_LOAD_FORMAT_XYZW :str:='TBUFFER_LOAD_FORMAT_XYZW';
TBUFFER_STORE_FORMAT_X :str:='TBUFFER_STORE_FORMAT_X';
TBUFFER_STORE_FORMAT_XY :str:='TBUFFER_STORE_FORMAT_XY';
@ -4056,22 +4055,22 @@ begin
2,3,4:
begin
str:=str+'v['+IntToStr(SPI.MIMG.VDATA)+':'+IntToStr(SPI.MIMG.VDATA+t-1)+']';
str:=str+', ';
str:=str+'v['+IntToStr(SPI.MIMG.VADDR)+':'+IntToStr(SPI.MIMG.VADDR+t-1)+']';
end;
else
begin
str:=str+_get_vdst8(SPI.MIMG.VDATA);
str:=str+', ';
str:=str+_get_vdst8(SPI.MIMG.VADDR);
end;
end;
str:=str+', ';
//operand #2
str:=str+'s['+IntToStr(SPI.MIMG.SRSRC*4)+':'+IntToStr(SPI.MIMG.SRSRC*4+7)+']';
str:=str+'v['+IntToStr(SPI.MIMG.VADDR)+':'+IntToStr(SPI.MIMG.VADDR+2)+']';
str:=str+', ';
//operand #3
str:=str+'s['+IntToStr(SPI.MIMG.SRSRC*4)+':'+IntToStr(SPI.MIMG.SRSRC*4+7)+']';
//operand #4
Case SPI.MIMG.OP of
IMAGE_SAMPLE..IMAGE_SAMPLE_C_CD_CL_O:
begin
@ -4376,19 +4375,50 @@ begin
//VDST vbindex vsrc0 vsrc1 OFFSET0 OFFSET1 GDS
str:=str+_get_vdst8(SPI.DS.VDST);
str:=str+', ';
//vdst
Case SPI.DS.OP of
DS_ADD_RTN_U32..DS_WRXCHG_RTN_B32,
DS_CMPST_RTN_B32..DS_READ_B32,
DS_READ_I8..DS_ORDERED_COUNT:
begin
str:=str+_get_vdst8(SPI.DS.VDST);
str:=str+', ';
end;
DS_WRXCHG2_RTN_B32 ,
DS_WRXCHG2ST64_RTN_B32,
DS_READ2_B32 ,
DS_READ2ST64_B32 ,
DS_ADD_RTN_U64..DS_WRXCHG_RTN_B64,
DS_CMPST_RTN_B64..DS_READ_B64,
DS_CONDXCHG32_RTN_B64:
begin
str:=str+_get_vdst8_cnt(SPI.DS.VDST,2);
str:=str+', ';
end;
DS_WRXCHG2_RTN_B64 ,
DS_WRXCHG2ST64_RTN_B64,
DS_READ2_B64 ,
DS_READ2ST64_B64 :
begin
str:=str+_get_vdst8_cnt(SPI.DS.VDST,4);
str:=str+', ';
end;
else;
end;
//vbindex
str:=str+_get_vdst8(SPI.DS.ADDR);
str:=str+', ';
//vsrc0
str:=str+_get_vdst8(SPI.DS.DATA0);
str:=str+_get_vdst8(SPI.DS.DATA[0]);
str:=str+', ';
//vsrc1
str:=str+_get_vdst8(SPI.DS.DATA1);
str:=str+_get_vdst8(SPI.DS.DATA[1]);
str:=str+' OFFSET:0x'+HexStr(WORD(SPI.DS.OFFSET),4);

View File

@ -1252,10 +1252,6 @@
<Filename Value="spirv\srCapability.pas"/>
<IsPartOfProject Value="True"/>
</Unit>
<Unit>
<Filename Value="spirv\srCFGLabel.pas"/>
<IsPartOfProject Value="True"/>
</Unit>
<Unit>
<Filename Value="spirv\srConfig.pas"/>
<IsPartOfProject Value="True"/>

View File

@ -59,6 +59,8 @@ type
Procedure InitCs(RSRC1:TCOMPUTE_PGM_RSRC1;
RSRC2:TCOMPUTE_PGM_RSRC2);
Procedure cs_set_initial_exec;
Procedure SET_NUM_THREADS(NTX:TCOMPUTE_NUM_THREAD_X;
NTY:TCOMPUTE_NUM_THREAD_Y;
NTZ:TCOMPUTE_NUM_THREAD_Z);
@ -706,6 +708,53 @@ begin
AddCapability(Capability.Shader);
end;
Procedure TSprvEmit.cs_set_initial_exec;
var
total:PtrUint;
val:PtrUint;
vec:TsrRegNode;
src:array[0..2] of TsrRegNode;
begin
if not Config.UseExtendedEXECMask then Exit;
total:=FLocalSize.x*FLocalSize.y*FLocalSize.z;
val:=not PtrUint(0);
if (total<64) then
begin
val:=(PtrUint(1) shl total)-1;
end else
if ((total mod 64)=0) then
begin
val:=not PtrUint(0);
end else
if (total>64) then
begin
Assert(false,'TODO: big unaligned total LocalSize');
end;
SetConst_q(get_exec0,dtUnknow,val and (not DWORD(0)));
SetConst_q(get_exec1,dtUnknow,val shr 32);
vec:=AddInput(@RegsStory.FUnattach,dtVec3u,itThreadId,0);
src[0]:=RegsStory.FUnattach.New(dtUint32);
src[1]:=RegsStory.FUnattach.New(dtUint32);
src[2]:=RegsStory.FUnattach.New(dtUint32);
OpExtract(init_line,src[0],vec,0);
OpExtract(init_line,src[1],vec,1);
OpExtract(init_line,src[2],vec,2);
FThread_id:=OpIMulTo(OpIMulTo(src[0],src[1]),src[2]);
if (total>64) then
begin
FThread_id:=OpAndTo(FThread_id,63);
end;
end;
Procedure TSprvEmit.SET_NUM_THREADS(NTX:TCOMPUTE_NUM_THREAD_X;
NTY:TCOMPUTE_NUM_THREAD_Y;
NTZ:TCOMPUTE_NUM_THREAD_Z);
@ -721,6 +770,8 @@ begin
if (FLocalSize.x=0) then FLocalSize.x:=1;
if (FLocalSize.y=0) then FLocalSize.y:=1;
if (FLocalSize.z=0) then FLocalSize.z:=1;
//
cs_set_initial_exec;
end;
Procedure TSprvEmit.InitCustomGs();

View File

@ -193,25 +193,19 @@ begin
lvl_0.size :=stride;
lvl_0.offset:=offset;
//region_addr = (OFFSET + vbindex) & alignment
if vbindex.is_const then
begin
//#static
//i = #(OFFSET + vbindex) & alignment
lvl_0.offset:=lvl_0.offset + vbindex.AsConst.GetData;
lvl_0.offset:=lvl_0.offset and (not (stride-1));
lvl_0.offset:=lvl_0.offset and (not (stride-1)); //4,8
Result:=pLayout.Fetch(@lvl_0,nil,cflags(atomic));
end else
if ((lvl_0.offset mod stride)=0) then
begin
//i = OFFSET + (vbindex / stride)
lvl_1.pIndex:=OpIDivTo(vbindex,stride);
lvl_1.stride:=stride;
Result:=pLayout.Fetch(@lvl_0,@lvl_1,cflags(atomic));
end else
begin
//#dynamic
//i = (vbindex + OFFSET) / stride
lvl_1.pIndex:=OpIAddTo(vbindex,lvl_0.offset);
@ -236,14 +230,14 @@ begin
if (rtype.BitSize=64) then
begin
vsrc:=fetch_vdst8_64(FSPI.DS.DATA0,dtUint64);
vsrc:=fetch_vdst8_64(FSPI.DS.DATA[0],dtUint64);
end else
if (rtype.BitSize=32) then
begin
vsrc:=fetch_vdst8(FSPI.DS.DATA0,rtype);
vsrc:=fetch_vdst8(FSPI.DS.DATA[0],rtype);
end else
begin
vsrc:=fetch_vdst8(FSPI.DS.DATA0,dtUnknow);
vsrc:=fetch_vdst8(FSPI.DS.DATA[0],dtUnknow);
end;
case rtype of
@ -260,10 +254,10 @@ end;
//vbindex, vsrc0[], vsrc1[] [OFFSET0:<0..255>] [OFFSET1:<0..255>] [GDS:< 0|1>]
procedure TEmit_DS.emit_DS_WRITE2(rtype:TsrDataType;extra_stride:Word);
var
pChain:array[0..1] of TsrChain;
pChain:array[0..3] of TsrChain;
vbindex:TsrRegNode;
vsrc:array[0..1] of TsrRegNode;
vsrc:array[0..3] of TsrRegNode;
i,hi:Byte;
begin
@ -273,15 +267,41 @@ begin
if (rtype.BitSize=64) then
begin
for i:=0 to hi do
begin
vsrc[i]:=fetch_vdst8_64(PBYTE(@FSPI.DS.DATA0)[i],dtUint64);
vsrc[i*2+0]:=fetch_vdst8(FSPI.DS.DATA[i]+0,dtUint32);
vsrc[i*2+1]:=fetch_vdst8(FSPI.DS.DATA[i]+1,dtUint32);
end;
for i:=0 to hi do
begin
pChain[i*2+0]:=fetch_ds_chain(vbindex,dtUint32,dtUnknow,FSPI.DS.OFFSET[i]*(8)*extra_stride+0);
pChain[i*2+1]:=fetch_ds_chain(vbindex,dtUint32,dtUnknow,FSPI.DS.OFFSET[i]*(8)*extra_stride+4);
end;
for i:=0 to hi do
begin
FetchStore(pChain[i*2+0],vsrc[i*2+0]);
FetchStore(pChain[i*2+1],vsrc[i*2+1]);
end;
exit;
{
Assert(false,'DS_WRITE2 64');
for i:=0 to hi do
begin
vsrc[i]:=fetch_vdst8_64(FSPI.DS.DATA[i],dtUint64);
end;
}
end else
begin
for i:=0 to hi do
begin
vsrc[i]:=fetch_vdst8(PBYTE(@FSPI.DS.DATA0)[i],rtype);
vsrc[i]:=fetch_vdst8(FSPI.DS.DATA[i],rtype);
end;
end;
@ -338,10 +358,10 @@ end;
procedure TEmit_DS.emit_DS_READ2(rtype:TsrDataType;extra_stride:Word);
var
pChain:array[0..1] of TsrChain;
pChain:array[0..3] of TsrChain;
vbindex:TsrRegNode;
vdst:array[0..1] of TsrRegNode;
vdst:array[0..3] of TsrRegNode;
dst:array[0..3] of PsrRegSlot;
@ -351,6 +371,33 @@ begin
hi:=ord(FSPI.DS.OFFSET[0]<>FSPI.DS.OFFSET[1]);
if (rtype.BitSize=64) then
begin
for i:=0 to hi do
begin
pChain[i*2+0]:=fetch_ds_chain(vbindex,dtUint32,dtUnknow,FSPI.DS.OFFSET[i]*(8)*extra_stride+0);
pChain[i*2+1]:=fetch_ds_chain(vbindex,dtUint32,dtUnknow,FSPI.DS.OFFSET[i]*(8)*extra_stride+4);
end;
for i:=0 to hi do
begin
vdst[i*2+0]:=FetchLoad(pChain[i*2+0],dtUint32);
vdst[i*2+1]:=FetchLoad(pChain[i*2+1],dtUint32);
end;
for i:=0 to hi do
begin
dst[i*2+0]:=get_vdst8(FSPI.DS.VDST+i*2+0);
dst[i*2+1]:=get_vdst8(FSPI.DS.VDST+i*2+1);
MakeCopy(dst[i*2+0],vdst[i*2+0]);
MakeCopy(dst[i*2+1],vdst[i*2+1]);
end;
exit;
end;
for i:=0 to hi do
begin
pChain[i]:=fetch_ds_chain(vbindex,rtype,dtUnknow,FSPI.DS.OFFSET[i]*(rtype.BitSize div 8)*extra_stride);
@ -398,14 +445,14 @@ begin
if (rtype.BitSize=64) then
begin
vsrc:=fetch_vdst8_64(FSPI.DS.DATA0,dtUint64);
vsrc:=fetch_vdst8_64(FSPI.DS.DATA[0],dtUint64);
end else
if (rtype.BitSize=32) then
begin
vsrc:=fetch_vdst8(FSPI.DS.DATA0,rtype);
vsrc:=fetch_vdst8(FSPI.DS.DATA[0],rtype);
end else
begin
vsrc:=fetch_vdst8(FSPI.DS.DATA0,dtUnknow);
vsrc:=fetch_vdst8(FSPI.DS.DATA[0],dtUnknow);
end;
case rtype of

View File

@ -8,7 +8,8 @@ uses
sysutils,
ps4_pssl,
si_ci_vi_merged_enum,
srCFGLabel,
srCFGCursor,
srCFGParser,
srConfig,
srFlow,
srType,
@ -220,12 +221,12 @@ begin
if (FSPI.EXP.VM<>0) and (FSPI.EXP.DONE<>0) then
begin
parent:=AllocBlockOp;
parent.SetInfo(btOther,Cursor.Adr,Cursor.Adr);
parent.SetInfo(btOther);
PushBlockOp(line,parent);
PushBlockOp(line,parent,Default(TsrCursor));
Inc(push_count);
exc:=MakeRead(get_exec0,dtBool); //It means that lane_id=0
exc:=GetThreadBit(get_exec0,get_exec1,dtBool);
node:=AddSpirvOp(srOpInternal.OpMakeExp);
node.AddParam(exc); //<-fetch read
end;
@ -246,9 +247,9 @@ begin
end;
pOpBlock:=AllocBlockOp; //down
pOpBlock.SetInfo(btOther,Cursor.Adr,Cursor.Adr);
pOpBlock.SetInfo(btOther);
PushBlockOp(line,pOpBlock);
PushBlockOp(line,pOpBlock,Default(TsrCursor));
Inc(push_count);
if (parent<>nil) then

View File

@ -54,9 +54,7 @@ type
function fetch_vdst8(VDST:Word;rtype:TsrDataType):TsrRegNode;
function fetch_vdst8_64(VDST:Word;rtype:TsrDataType):TsrRegNode;
//
procedure MakeCopy64(dst0,dst1:PsrRegSlot;src:TsrRegNode);
//
procedure OpCmpV(OpId:DWORD;dst:PsrRegSlot;src0,src1:TsrRegNode);
procedure OpCmpV(OpId:DWORD;dst0,dst1:PsrRegSlot;src0,src1:TsrRegNode);
procedure OpCmpS(OpId:DWORD;dst:PsrRegSlot;src0,src1:TsrRegNode);
procedure OpConvFloatToHalf2(dst:PsrRegSlot;src0,src1:TsrRegNode);
//
@ -260,7 +258,7 @@ begin
if (pImm=nil) then Exit;
if (pImm.AsUint32<>8) then Exit;
reg:=RegDown(pSelect.ParamNode(2).AsReg);
reg:=RegDown(pSelect.ParamNode(1).AsReg);
if (reg=nil) then Exit;
pBitwiseAnd:=reg.pWriter.specialize AsType<ntOp>;
@ -281,7 +279,7 @@ begin
end;
//final
reg:=RegDown(pSelect.ParamNode(1).AsReg);
reg:=RegDown(pSelect.ParamNode(2).AsReg);
if (reg=nil) then Exit;
regs[0]:=reg;
@ -513,7 +511,6 @@ end;
function TEmitFetch.fetch_vdst8_64(VDST:Word;rtype:TsrDataType):TsrRegNode;
var
src:array[0..1] of TsrRegNode;
dst:TsrRegNode;
begin
src[0]:=fetch_vdst8(VDST+0,dtUint32);
src[1]:=fetch_vdst8(VDST+1,dtUint32);
@ -523,31 +520,12 @@ begin
Assert(False);
end;
dst:=NewReg(dtVec2u);
OpMakeCon(line,dst,@src);
Result:=BitcastList.FetchRead(rtype,dst);
Result:=fetch64(@src,rtype);
end;
//
procedure TEmitFetch.MakeCopy64(dst0,dst1:PsrRegSlot;src:TsrRegNode);
var
dst:TsrRegNode;
node:array[0..1] of TsrRegNode;
begin
dst:=BitcastList.FetchRead(dtVec2u,src);
node[0]:=dst0^.New(dtUint32,line);
node[1]:=dst1^.New(dtUint32,line);
OpExtract(line,node[0],dst,0);
OpExtract(line,node[1],dst,1);
end;
//
procedure TEmitFetch.OpCmpV(OpId:DWORD;dst:PsrRegSlot;src0,src1:TsrRegNode);
procedure TEmitFetch.OpCmpV(OpId:DWORD;dst0,dst1:PsrRegSlot;src0,src1:TsrRegNode);
Var
tmp:TsrRegNode;
exc:TsrRegNode;
@ -565,8 +543,11 @@ begin
_Op2(line,OpId,tmp,src0,src1);
exc:=MakeRead(get_exec0,dtBool);
OpLogicalAnd(dst,tmp,exc);
exc:=GetThreadBit(get_exec0,get_exec1,dtBool);
exc:=OpLogicalAndTo(tmp,exc);
SetThreadBit(dst0,dst1,exc);
end;
procedure TEmitFetch.OpCmpS(OpId:DWORD;dst:PsrRegSlot;src0,src1:TsrRegNode);

View File

@ -12,7 +12,7 @@ uses
srConst,
srReg,
srOp,
srCFGLabel,
srCFGParser,
srOpInternal,
srOpUtils,
srCacheOp,
@ -20,6 +20,15 @@ uses
type
TEmitOp=class(TEmitInterface)
//
procedure MakeCopy64(dst0,dst1:PsrRegSlot;src:TsrRegNode);
function GetThreadBit(exe0,exe1:PsrRegSlot;rtype:TsrDataType;ppLine:PPspirvOp=nil):TsrRegNode;
procedure SetThreadBit(exe0,exe1:PsrRegSlot;val:TsrRegNode);
//
function fetch_vccnz (ppLine:PPspirvOp):TsrRegNode;
function fetch_execnz(ppLine:PPspirvOp):TsrRegNode;
function fetch_execnz_tid(ppLine:PPspirvOp):TsrRegNode;
function fetch_scc :TsrRegNode;
//
function _Op1(pLine:TspirvOp;OpId:DWORD;dst,src:TsrRegNode):TspirvOp;
function _Op2(pLine:TspirvOp;OpId:DWORD;dst,src0,src1:TsrRegNode):TspirvOp;
@ -73,8 +82,8 @@ type
procedure OpFmaI32(dst:PsrRegSlot;src0,src1,src2:TsrRegNode);
procedure OpFmaU32(dst:PsrRegSlot;src0,src1,src2:TsrRegNode);
//
procedure OpSelect(dst:PsrRegSlot;src_false,src_true,cond:TsrRegNode);
function OpSelectTo(src_false,src_true,cond:TsrRegNode):TsrRegNode;
procedure OpSelect(dst:PsrRegSlot;cond,src_true,src_false:TsrRegNode);
function OpSelectTo(cond,src_true,src_false:TsrRegNode):TsrRegNode;
//
procedure OpIAddCar(pLine:TspirvOp;dst,car,src0,src1:TsrRegNode);
procedure OpIAddExt(dst,car:PsrRegSlot;src0,src1:TsrRegNode;rtype:TsrDataType);
@ -91,6 +100,7 @@ type
//
function OpBFITo (src0,src1,src2,src3:TsrRegNode;ppLine:PPspirvOp=nil):TsrRegNode;
function OpBFUETo(src0,src1,src2:TsrRegNode;ppLine:PPspirvOp=nil):TsrRegNode;
function OpBFSETo(src0,src1,src2:TsrRegNode;ppLine:PPspirvOp=nil):TsrRegNode;
//
procedure OpPackAnc(dst:PsrRegSlot;prim,smid,rtid:TsrRegNode);
//
@ -111,6 +121,8 @@ type
function OpMakeCon(pLine:TspirvOp;dst:TsrRegNode;src:PPsrRegNode):TspirvOp;
function OpMakeVec(pLine:TspirvOp;rtype:TsrDataType;src:PPsrRegNode):TsrRegNode;
function OpMakeCub(pLine:TspirvOp;rtype:TsrDataType;src:PPsrRegNode):TsrRegNode;
function fetch64 (src:PPsrRegNode;rtype:TsrDataType;ppLine:PPspirvOp=nil):TsrRegNode;
function fetch64 (src0,src1:TsrRegNode;rtype:TsrDataType;ppLine:PPspirvOp=nil):TsrRegNode;
function OpSampledImage(pLine:TspirvOp;Tgrp,Sgrp:TsrNode;dtype:TsrDataType;info:TsrTypeImageInfo):TsrRegSampledImage;
//
procedure OpIAdd(dst:PsrRegSlot;src0,src1:TsrRegNode);
@ -163,6 +175,8 @@ type
function OpOrTo (src0,src1:TsrRegNode;ppLine:PPspirvOp=nil):TsrRegNode;
function OpAndTo(src0,src1:TsrRegNode;ppLine:PPspirvOp=nil):TsrRegNode;
function OpAndTo(src0:TsrRegNode;src1:QWORD;ppLine:PPspirvOp=nil):TsrRegNode;
function OpLogicalOrTo (src0,src1:TsrRegNode;ppLine:PPspirvOp=nil):TsrRegNode;
function OpLogicalAndTo(src0,src1:TsrRegNode;ppLine:PPspirvOp=nil):TsrRegNode;
//
function OpIsSSignTo(src:TsrRegNode;ppLine:PPspirvOp=nil):TsrRegNode;
function OpIEqualTo(src0,src1:TsrRegNode;ppLine:PPspirvOp=nil):TsrRegNode;
@ -209,6 +223,123 @@ end;
//
procedure TEmitOp.MakeCopy64(dst0,dst1:PsrRegSlot;src:TsrRegNode);
var
dst:TsrRegNode;
node:array[0..1] of TsrRegNode;
begin
dst:=BitcastList.FetchRead(dtVec2u,src);
node[0]:=dst0^.New(dtUint32,line);
node[1]:=dst1^.New(dtUint32,line);
OpExtract(line,node[0],dst,0);
OpExtract(line,node[1],dst,1);
end;
function TEmitOp.GetThreadBit(exe0,exe1:PsrRegSlot;rtype:TsrDataType;ppLine:PPspirvOp=nil):TsrRegNode;
var
mask:TsrRegNode;
begin
if Config.UseExtendedEXECMask and (FExecutionModel=ExecutionModel.GLCompute) then
begin
mask:=fetch64(MakeRead(exe0,dtUint32),MakeRead(exe1,dtUint32),dtUint64,ppLine);
Result:=OpShrTo(mask,FThread_id,ppLine);
Result:=OpUToU (Result,dtUint32,ppLine);
Result:=OpAndTo(Result,1,ppLine);
Result.PrepType(ord(dtUint32));
Result:=BitcastList.FetchRead(rtype,Result);
//Result:=OpBFUETo(mask,FThread_id,NewImm_i(dtUint32,1));
//Result:=OpUToU(Result,dtUint32);
//Result:=BitcastList.FetchRead(rtype,Result);
end else
begin
//It means that lane_id=0
Result:=MakeRead(exe0,rtype);
end;
end;
procedure TEmitOp.SetThreadBit(exe0,exe1:PsrRegSlot;val:TsrRegNode);
var
mask,mask2:TsrRegNode;
begin
if Config.UseExtendedEXECMask and (FExecutionModel=ExecutionModel.GLCompute) then
begin
val:=BitcastList.FetchRead(dtUint32,val);
val:=OpUToU (val,dtUint64);
val:=OpShlTo(val,FThread_id);
mask:=fetch64(MakeRead(exe0,dtUint32),MakeRead(exe1,dtUint32),dtUint64);
mask2:=OpShlTo(NewImm_i(dtUint64,1),FThread_id);
mask2:=OpNotTo(mask2);
mask2.PrepType(ord(dtUint64));
mask:=OpAndTo(mask,mask2);
mask.PrepType(ord(dtUint64));
mask:=OpOrTo(mask,val);
mask.PrepType(ord(dtUint64));
MakeCopy64(exe0,exe1,mask);
//val:=BitcastList.FetchRead(dtUint32,val);
//val:=OpUToU(val,dtUint64);
//mask:=fetch64(exe0^.current,exe1^.current,dtUint64);
//mask:=OpBFITo(mask,val,FThread_id,NewImm_i(dtUint32,1));
//MakeCopy64(exe0,exe1,mask);
//
end else
begin
//It means that lane_id=0
MakeCopy (exe0,val);
SetConst_q(exe1,dtUnknow,0); //set zero
end;
end;
//
function TEmitOp.fetch_vccnz(ppLine:PPspirvOp):TsrRegNode;
var
src:array[0..1] of TsrRegNode;
begin
//It means that (vcc0 != 0) || (vcc1 != 0)
src[0]:=MakeRead(get_vcc0,dtBool); //implict cast (int != 0)
src[1]:=MakeRead(get_vcc1,dtBool); //implict cast (int != 0)
Result:=OpLogicalOrTo(src[0],src[1],ppLine);
end;
function TEmitOp.fetch_execnz(ppLine:PPspirvOp):TsrRegNode;
var
src:array[0..1] of TsrRegNode;
begin
//It means that (exec0 != 0) || (exec1 != 0)
src[0]:=MakeRead(get_exec0,dtBool); //implict cast (int != 0)
src[1]:=MakeRead(get_exec1,dtBool); //implict cast (int != 0)
Result:=OpLogicalOrTo(src[0],src[1],ppLine);
end;
function TEmitOp.fetch_execnz_tid(ppLine:PPspirvOp):TsrRegNode;
begin
//It means that (exec[thread_id:] == 0)
Result:=GetThreadBit(get_exec0,get_exec1,dtBool,ppLine);
end;
function TEmitOp.fetch_scc:TsrRegNode;
begin
Result:=MakeRead(get_scc,dtBool);
end;
//
function TEmitOp._Op1(pLine:TspirvOp;OpId:DWORD;dst,src:TsrRegNode):TspirvOp;
Var
node:TspirvOp;
@ -640,14 +771,14 @@ end;
//
procedure TEmitOp.OpSelect(dst:PsrRegSlot;src_false,src_true,cond:TsrRegNode);
procedure TEmitOp.OpSelect(dst:PsrRegSlot;cond,src_true,src_false:TsrRegNode);
begin
Op3(Op.OpSelect,LazyType2(src_false.dtype,src_true.dtype),dst,cond,src_true,src_false);
Op3(Op.OpSelect,LazyType2(src_true.dtype,src_false.dtype),dst,cond,src_true,src_false);
end;
function TEmitOp.OpSelectTo(src_false,src_true,cond:TsrRegNode):TsrRegNode;
function TEmitOp.OpSelectTo(cond,src_true,src_false:TsrRegNode):TsrRegNode;
begin
Result:=NewReg(LazyType2(src_false.dtype,src_true.dtype));
Result:=NewReg(LazyType2(src_true.dtype,src_false.dtype));
//
_Op3(line,Op.OpSelect,Result,cond,src_true,src_false);
end;
@ -795,6 +926,12 @@ begin
_set_line(ppLine,_Op3(_get_line(ppLine),Op.OpBitFieldUExtract,Result,src0,src1,src2));
end;
function TEmitOp.OpBFSETo(src0,src1,src2:TsrRegNode;ppLine:PPspirvOp=nil):TsrRegNode;
begin
Result:=NewReg(src0.dtype);
_set_line(ppLine,_Op3(_get_line(ppLine),Op.OpBitFieldSExtract,Result,src0,src1,src2));
end;
//
procedure TEmitOp.OpPackAnc(dst:PsrRegSlot;prim,smid,rtid:TsrRegNode);
@ -1022,6 +1159,65 @@ begin
end;
end;
type
t_bridge_info=record
val:TsrRegNode;
pos:PtrUint;
end;
function get_bridge(src:TsrRegNode):t_bridge_info;
var
pLine:TSpirvOp;
begin
Result:=Default(t_bridge_info);
pLine:=src.pWriter.specialize AsType<ntOp>;
if (pLine=nil) then Exit;
if (pLine.OpId<>Op.OpCompositeExtract) then Exit;
if not pLine.ParamNode(1).TryGetValue(Result.pos) then Exit;
Result.val:=pLine.ParamNode(0).AsReg;
end;
function TEmitOp.fetch64(src:PPsrRegNode;rtype:TsrDataType;ppLine:PPspirvOp=nil):TsrRegNode;
var
bri:array[0..1] of t_bridge_info;
dst:TsrRegNode;
begin
bri[0]:=get_bridge(src[0]);
bri[1]:=get_bridge(src[1]);
dst:=nil;
if (bri[0].val<>nil) and
(bri[0].val=bri[1].val) and
(bri[0].pos=0) and
(bri[1].pos=1) then
if (bri[0].val.dtype.Count=2) then
begin
dst:=bri[0].val;
end;
if (dst=nil) then
begin
dst:=NewReg(dtVec2u);
_set_line(ppLine,OpMakeCon(_get_line(ppLine),dst,src));
end;
Result:=BitcastList.FetchRead(rtype,dst);
end;
function TEmitOp.fetch64(src0,src1:TsrRegNode;rtype:TsrDataType;ppLine:PPspirvOp=nil):TsrRegNode;
var
src:array[0..1] of TsrRegNode;
begin
src[0]:=src0;
src[1]:=src1;
Result:=fetch64(@src,rtype,ppLine);
end;
Function FindByHalfSpace(node:TspirvOp;pDst:TsrNode):Boolean;
begin
Result:=False;
@ -1030,7 +1226,7 @@ begin
if (node.pDst=pDst) then Exit(True);
//
if node.IsType(ntOpBlock) then
if IsReal(TsrOpBlock(node).Block.bType) then
if IsReal(TsrOpBlock(node).bType) then
begin
Exit(False);
end;
@ -1439,6 +1635,20 @@ end;
//
function TEmitOp.OpLogicalOrTo(src0,src1:TsrRegNode;ppLine:PPspirvOp=nil):TsrRegNode;
begin
Result:=NewReg(dtBool);
_set_line(ppLine,_Op2(_get_line(ppLine),Op.OpLogicalOr,Result,src0,src1)); //post type
end;
function TEmitOp.OpLogicalAndTo(src0,src1:TsrRegNode;ppLine:PPspirvOp=nil):TsrRegNode;
begin
Result:=NewReg(dtBool);
_set_line(ppLine,_Op2(_get_line(ppLine),Op.OpLogicalAnd,Result,src0,src1)); //post type
end;
//
function TEmitOp.OpIsSSignTo(src:TsrRegNode;ppLine:PPspirvOp=nil):TsrRegNode;
var
zero:TsrRegNode;

View File

@ -247,6 +247,32 @@ begin
until false;
end;
function CompareTypeOp(OpId:DWORD;rtype1,rtype2:TsrDataType):Boolean;
var
relax:Boolean;
begin
Case OpId of
Op.OpLoad ,
Op.OpImageRead ,
Op.OpImageWrite ,
Op.OpBitFieldSExtract ,
Op.OpBitFieldUExtract ,
Op.OpSelect ,
Op.OpIAddCarry ,
Op.OpISubBorrow ,
Op.OpUMulExtended ,
Op.OpSMulExtended ,
Op.OpCompositeConstruct:relax:=False;
else
relax:=True;
end;
Case relax of
True :Result:=CompareType(rtype1,rtype2);
False:Result:=(rtype1=rtype2);
end;
end;
function TSprvEmit_post.RegCollapse(pLine:TspirvOp;var node:TsrRegNode):Integer;
var
rold,rnew:TsrRegNode;
@ -260,7 +286,7 @@ begin
if (rold<>rnew) then //is change?
begin
if (rnew.dtype=dtUnknow) or CompareType(rnew.dtype,rold.dtype) then
if (rnew.dtype=dtUnknow) or CompareTypeOp(pLine.OpId,rnew.dtype,rold.dtype) then
begin
rnew.PrepType(ord(rold.dtype));
if (rnew.dtype<>dtUnknow) then
@ -291,6 +317,8 @@ begin
Result:=0;
if (node=nil) then Exit;
//if not (node.IsUsed) then Exit;
old:=node;
node:=RegDown(old);
@ -609,6 +637,15 @@ function TSprvEmit_post.OnOpStep4(node:TspirvOp):Integer; //forward
begin
Result:=0;
{
//prior
if node.is_post then
begin
Result:=Result+EnumLineRegs(@RegVResolve,node);
Exit;
end;
}
if node.is_cleared then Exit;
if node.can_clear then
@ -972,6 +1009,11 @@ begin
rtGDS:max:=64*1024;
end;
if (max=0) then
begin
Assert(false,'Access to LDS/GDS and the maximum is 0?');
end;
if (Align(_offset,pChain.stride)>max) then
begin
Assert(false,'LDS/GDS big addresing?');
@ -1006,7 +1048,10 @@ begin
//patch dtype
dtype:=F.pField.Fdtype.Child;
end;
frValueInArray :ShiftIndex(pChain,F,_offset);
frValueInArray :
begin
ShiftIndex(pChain,F,_offset);
end;
end;
until false;

View File

@ -9,7 +9,7 @@ uses
bittype,
Half16,
spirv,
srCFGLabel,
srCFGParser,
srNode,
srType,
srTypes,
@ -181,6 +181,8 @@ begin
dtBool :Result:=dtBool;
dtInt32,
dtUint32:Result:=dtUint32;
dtInt64,
dtUint64:Result:=dtUint64;
else
Result:=dtUnknow;
end;
@ -196,7 +198,7 @@ var
procedure _SetConst(dtype:TsrDataType;value:QWORD);
begin
dst.pWriter:=NewImm_q(dtype,value,node);
node.mark_not_used;
node.mark([soNotUsed]);
node.pDst:=nil;
Inc(Result);
end;
@ -204,7 +206,7 @@ var
procedure _SetReg(src:TsrRegNode);
begin
dst.pWriter:=src;
node.mark_not_used;
node.mark([soNotUsed]);
node.pDst:=nil;
Inc(Result);
end;
@ -346,7 +348,7 @@ var
procedure _SetConst(dtype:TsrDataType;value:QWORD);
begin
dst.pWriter:=NewImm_q(dtype,value,node);
node.mark_not_used;
node.mark([soNotUsed]);
node.pDst:=nil;
Inc(Result);
end;
@ -354,7 +356,7 @@ var
procedure _SetReg(src:TsrRegNode);
begin
dst.pWriter:=src;
node.mark_not_used;
node.mark([soNotUsed]);
node.pDst:=nil;
Inc(Result);
end;
@ -482,7 +484,7 @@ var
procedure _SetConst(dtype:TsrDataType;value:QWORD);
begin
dst.pWriter:=NewImm_q(dtype,value,node);
node.mark_not_used;
node.mark([soNotUsed]);
node.pDst:=nil;
Inc(Result);
end;
@ -490,7 +492,7 @@ var
procedure _SetReg(src:TsrRegNode);
begin
dst.pWriter:=src;
node.mark_not_used;
node.mark([soNotUsed]);
node.pDst:=nil;
Inc(Result);
end;
@ -646,7 +648,7 @@ var
procedure _SetConst(dtype:TsrDataType;value:QWORD);
begin
dst.pWriter:=NewImm_q(dtype,value,node);
node.mark_not_used;
node.mark([soNotUsed]);
node.pDst:=nil;
Inc(Result);
end;
@ -654,7 +656,7 @@ var
procedure _SetReg(src:TsrRegNode);
begin
dst.pWriter:=src;
node.mark_not_used;
node.mark([soNotUsed]);
node.pDst:=nil;
Inc(Result);
end;
@ -710,7 +712,7 @@ var
procedure _SetConst(dtype:TsrDataType;value:QWORD);
begin
dst.pWriter:=NewImm_q(dtype,value,node);
node.mark_not_used;
node.mark([soNotUsed]);
node.pDst:=nil;
Inc(Result);
end;
@ -800,7 +802,7 @@ var
procedure _SetReg(src:TsrRegNode);
begin
dst.pWriter:=src;
node.mark_not_used;
node.mark([soNotUsed]);
node.pDst:=nil;
Inc(Result);
end;
@ -850,7 +852,7 @@ begin
Op.OpLabel,
Op.OpSelectionMerge,
Op.OpBranch,
Op.OpBranchConditional:node.mark_not_used(True);
Op.OpBranchConditional:node.mark([soNotUsed,soForce]);
else;
end;
//
@ -904,6 +906,9 @@ var
cst :TsrConst;
begin
Result:=0;
//exit;
src:=RegDown(node.ParamNode(0).AsReg);
if (src=nil) then Exit;
@ -927,10 +932,10 @@ begin
//Get merge block
pMerg:=pCond.Parent;
Assert(pMerg.Block.bType=btMerg);
Assert(pMerg.bType=btMerg);
//set type
pMerg.Block.bType:=btOther;
pMerg.bType:=btOther;
_restore(pCond.vctx);
@ -938,7 +943,7 @@ begin
//PrivateList.build_volatile_ctrue(pCond.pAfter,pCond.Regs.orig,pCond.Regs.prev,pCond.Regs.next);
//set type
pCond.Block.bType:=btOther;
pCond.bType:=btOther;
//clear instructions
mark_not_used_branch_op(pMerg);
@ -991,7 +996,7 @@ var
procedure _SetConst(dtype:TsrDataType;value:QWORD);
begin
dst.pWriter:=NewImm_q(dtype,value,node);
node.mark_not_used;
node.mark([soNotUsed]);
node.pDst:=nil;
Inc(Result);
end;
@ -1038,7 +1043,7 @@ var
procedure _SetConst(dtype:TsrDataType;value:QWORD);
begin
dst.pWriter:=NewImm_q(dtype,value,node);
node.mark_not_used;
node.mark([soNotUsed]);
node.pDst:=nil;
Inc(Result);
end;
@ -1075,7 +1080,7 @@ var
procedure _SetConst(dtype:TsrDataType;value:QWORD);
begin
dst.pWriter:=NewImm_q(dtype,value,node);
node.mark_not_used;
node.mark([soNotUsed]);
node.pDst:=nil;
Inc(Result);
end;
@ -1084,7 +1089,7 @@ var
begin
Assert(dtype=dtFloat32);
dst.pWriter:=NewImm_s(dtype,value,node);
node.mark_not_used;
node.mark([soNotUsed]);
node.pDst:=nil;
Inc(Result);
end;
@ -1092,7 +1097,7 @@ var
procedure _SetReg(src:TsrRegNode);
begin
dst.pWriter:=src;
node.mark_not_used;
node.mark([soNotUsed]);
node.pDst:=nil;
Inc(Result);
end;
@ -1240,7 +1245,7 @@ begin
dst.pWriter:=pc;
node.mark_not_used;
node.mark([soNotUsed]);
node.pDst:=nil;
Inc(Result);
end;
@ -1294,7 +1299,7 @@ var
procedure _SetConst(dtype:TsrDataType;value:QWORD);
begin
dst.pWriter:=NewImm_q(dtype,value,node);
node.mark_not_used;
node.mark([soNotUsed]);
node.pDst:=nil;
Inc(Result);
end;
@ -1302,7 +1307,7 @@ var
procedure _SetReg(src:TsrRegNode);
begin
dst.pWriter:=src;
node.mark_not_used;
node.mark([soNotUsed]);
node.pDst:=nil;
Inc(Result);
end;
@ -1381,7 +1386,7 @@ var
begin
Assert(dtype=dtFloat32);
dst.pWriter:=NewImm_s(dtype,value,node);
node.mark_not_used;
node.mark([soNotUsed]);
node.pDst:=nil;
Inc(Result);
end;
@ -1422,7 +1427,7 @@ var
procedure _SetConst(dtype:TsrDataType;value:QWORD);
begin
dst.pWriter:=NewImm_q(dtype,value,node);
node.mark_not_used;
node.mark([soNotUsed]);
node.pDst:=nil;
Inc(Result);
end;
@ -1430,7 +1435,7 @@ var
procedure _SetReg(src:TsrRegNode);
begin
dst.pWriter:=src;
node.mark_not_used;
node.mark([soNotUsed]);
node.pDst:=nil;
Inc(Result);
end;
@ -1476,7 +1481,7 @@ var
procedure _SetConst(dtype:TsrDataType;value:QWORD);
begin
dst.pWriter:=NewImm_q(dtype,value,node);
node.mark_not_used;
node.mark([soNotUsed]);
node.pDst:=nil;
Inc(Result);
end;
@ -1510,7 +1515,7 @@ var
procedure _SetConst(dtype:TsrDataType;value:QWORD);
begin
dst.pWriter:=NewImm_q(dtype,value,node);
node.mark_not_used;
node.mark([soNotUsed]);
node.pDst:=nil;
Inc(Result);
end;
@ -1600,7 +1605,7 @@ var
procedure _SetConst(dtype:TsrDataType;value:QWORD);
begin
dst.pWriter:=NewImm_q(dtype,value,node);
node.mark_not_used;
node.mark([soNotUsed]);
node.pDst:=nil;
Inc(Result);
end;
@ -1735,7 +1740,7 @@ var
procedure _SetReg(src:TsrRegNode);
begin
dst.pWriter:=src;
node.mark_not_used;
node.mark([soNotUsed]);
node.pDst:=nil;
Inc(Result);
end;
@ -1800,7 +1805,7 @@ var
procedure _SetConst(dtype:TsrDataType;value:QWORD);
begin
dst.pWriter:=NewImm_q(dtype,value,node);
node.mark_not_used;
node.mark([soNotUsed]);
node.pDst:=nil;
Inc(Result);
end;
@ -1808,7 +1813,7 @@ var
procedure _SetReg(src:TsrRegNode);
begin
dst.pWriter:=src;
node.mark_not_used;
node.mark([soNotUsed]);
node.pDst:=nil;
Inc(Result);
end;
@ -1856,7 +1861,7 @@ begin
//else
node.mark_not_used;
node.mark([soNotUsed]);
node.pDst:=nil;
rmax:=OpUMaxTo(src[0],src[1],@node); //update line
@ -1889,7 +1894,7 @@ var
procedure _SetConst(dtype:TsrDataType;value:QWORD);
begin
dst.pWriter:=NewImm_q(dtype,value,node);
node.mark_not_used;
node.mark([soNotUsed]);
node.pDst:=nil;
Inc(Result);
end;
@ -1897,7 +1902,7 @@ var
procedure _SetReg(src:TsrRegNode);
begin
dst.pWriter:=src;
node.mark_not_used;
node.mark([soNotUsed]);
node.pDst:=nil;
Inc(Result);
end;
@ -2005,12 +2010,14 @@ begin
dst.pWriter:=cret;
node.mark_not_used;
node.mark([soNotUsed]);
node.pDst:=nil;
Inc(Result);
end else
begin
src:=node.ParamNode(1).AsReg;
pLine:=src.pLine;
vint6:=NewImm_i(dtInt32,6);
@ -2018,32 +2025,21 @@ begin
Case count of
1:
begin
rvec[0]:=NewReg(dtInt32);
pLine:=_Op3(pLine,Op.OpBitFieldSExtract,rvec[0],src,NewImm_i(dtInt32, 0),vint6);
src:=rvec[0];
src:=OpBFSETo(src,NewImm_i(dtInt32,0),vint6,@pLine);
end;
2:
begin
rvec[0]:=NewReg(dtInt32);
rvec[1]:=NewReg(dtInt32);
pLine:=_Op3(pLine,Op.OpBitFieldSExtract,rvec[0],src,NewImm_i(dtInt32, 0),vint6);
pLine:=_Op3(pLine,Op.OpBitFieldSExtract,rvec[1],src,NewImm_i(dtInt32, 8),vint6);
rvec[0]:=OpBFSETo(src,NewImm_i(dtInt32,0),vint6,@pLine);
rvec[1]:=OpBFSETo(src,NewImm_i(dtInt32,8),vint6,@pLine);
src:=NewReg(dtVec2i);
pLine:=OpMakeCon(pLine,src,@rvec);
end;
3:
begin
rvec[0]:=NewReg(dtInt32);
rvec[1]:=NewReg(dtInt32);
rvec[2]:=NewReg(dtInt32);
pLine:=_Op3(pLine,Op.OpBitFieldSExtract,rvec[0],src,NewImm_i(dtInt32, 0),vint6);
pLine:=_Op3(pLine,Op.OpBitFieldSExtract,rvec[1],src,NewImm_i(dtInt32, 8),vint6);
pLine:=_Op3(pLine,Op.OpBitFieldSExtract,rvec[2],src,NewImm_i(dtInt32,16),vint6);
rvec[0]:=OpBFSETo(src,NewImm_i(dtInt32, 0),vint6,@pLine);
rvec[1]:=OpBFSETo(src,NewImm_i(dtInt32, 8),vint6,@pLine);
rvec[2]:=OpBFSETo(src,NewImm_i(dtInt32,16),vint6,@pLine);
src:=NewReg(dtVec3i);
pLine:=OpMakeCon(pLine,src,@rvec);
@ -2055,7 +2051,7 @@ begin
dst.dtype :=src.dtype;
dst.pWriter:=src;
node.mark_not_used;
node.mark([soNotUsed]);
node.pDst:=nil;
Inc(Result);
@ -2331,7 +2327,7 @@ begin
dst.pWriter:=rsl;
node.mark_not_used;
node.mark([soNotUsed]);
node.pDst:=nil;
Exit;
@ -2402,7 +2398,7 @@ begin
Assert(False);
end;
node.mark_not_used;
node.mark([soNotUsed]);
node.pDst:=nil;
end;
@ -2445,7 +2441,7 @@ begin
_Op4(pLine,Op.OpBitFieldInsert,dst,src[1],src[0],rIndex,rCount);
node.mark_not_used;
node.mark([soNotUsed]);
node.pDst:=nil;
Exit;
@ -2466,7 +2462,7 @@ begin
_Op2(pLine,Op.OpBitwiseOr,dst,src[0],src[1]);
node.mark_not_used;
node.mark([soNotUsed]);
node.pDst:=nil;
end;
@ -2761,7 +2757,7 @@ begin
MakeVecComp(node,dtVec3f,dst,@src);
node.mark_not_used;
node.mark([soNotUsed]);
node.pDst:=nil;
Result:=1;
end;
@ -2774,7 +2770,7 @@ var
procedure _SetReg(src:TsrRegNode);
begin
dst.pWriter:=src;
node.mark_not_used;
node.mark([soNotUsed]);
node.pDst:=nil;
Inc(Result);
end;
@ -2797,7 +2793,7 @@ var
procedure _SetReg(src:TsrRegNode);
begin
dst.pWriter:=src;
node.mark_not_used;
node.mark([soNotUsed]);
node.pDst:=nil;
Inc(Result);
end;
@ -2820,7 +2816,7 @@ var
procedure _SetReg(src:TsrRegNode);
begin
dst.pWriter:=src;
node.mark_not_used;
node.mark([soNotUsed]);
node.pDst:=nil;
Inc(Result);
end;
@ -2843,7 +2839,7 @@ var
begin
Assert(dtype=dtFloat32);
dst.pWriter:=NewImm_s(dtype,value,node);
node.mark_not_used;
node.mark([soNotUsed]);
node.pDst:=nil;
Inc(Result);
end;
@ -2940,7 +2936,7 @@ begin
MakeVecComp(node,rtype,dst,@src);
node.mark_not_used;
node.mark([soNotUsed]);
node.pDst:=nil;
end;
@ -2950,7 +2946,7 @@ begin
if is_term_op(flow_down_prev_up(node)) then
begin
node.mark_not_used;
node.mark([soNotUsed]);
Inc(Result);
end;
@ -2963,7 +2959,6 @@ var
pChild:TsrOpBlock;
pBegOp,pEndOp,pMrgOp:TspirvOp;
exc:TsrRegNode;
b_adr:TSrcAdr;
begin
Result:=1;
@ -2974,7 +2969,7 @@ begin
if exc.is_const then
begin
node.mark_not_used;
node.mark([soNotUsed]);
Case exc.AsConst.AsBool of
True : //is always store
@ -3011,7 +3006,7 @@ begin
Op.OpNop:;
Op.OpKill:;
else
node.mark_not_used(True);
node.mark([soNotUsed,soForce]);
end;
end;
node:=node.Next;
@ -3024,9 +3019,7 @@ begin
//reread
exc:=node.ParamNode(0).AsReg;
node.mark_not_used;
b_adr:=pOpBlock.Block.b_adr;
node.mark([soNotUsed]);
pLine:=node.Next;
if (pLine=nil) then //kill or nop
@ -3036,11 +3029,8 @@ begin
pEndOp:=NewLabelOp(False); //end
pMrgOp:=pEndOp; //merge
pBegOp.Adr:=b_adr;
pEndOp.Adr:=b_adr;
pOpBlock.SetLabels(pBegOp,pEndOp,pMrgOp);
pOpBlock.Block.bType:=btCond;
pOpBlock.bType:=btCond;
pOpBlock.SetCond(exc,false); //reverse
pLine:=node;
@ -3049,7 +3039,7 @@ begin
pLine:=AddSpirvOp (pLine,pBegOp);
pChild:=AllocBlockOp; //create new
pChild.SetInfo(btOther,b_adr,b_adr);
pChild.SetInfo(btOther);
pChild.dummy.OpId:=Op.OpKill; //set kill to dummy
pOpBlock.pBody:=pChild;
@ -3067,15 +3057,11 @@ begin
pEndOp:=NewLabelOp(False); //end
pMrgOp:=NewLabelOp(False); //merge
pBegOp.Adr:=b_adr;
pEndOp.Adr:=b_adr;
pMrgOp.Adr:=b_adr;
pOpBlock.SetLabels(pBegOp,pEndOp,pMrgOp);
pOpBlock.Block.bType:=btCond;
pOpBlock.bType:=btCond;
pOpBlock.SetCond(exc,false); //reverse
pOpBlock.pElse.Block.bType:=btElse;
pOpBlock.pElse.bType:=btElse;
pLine:=node;
pLine:=OpCondMerge (pLine,pMrgOp);
@ -3083,7 +3069,7 @@ begin
pLine:=AddSpirvOp (pLine,pBegOp);
pChild:=AllocBlockOp; //create new
pChild.SetInfo(btOther,b_adr,b_adr);
pChild.SetInfo(btOther);
pChild.dummy.OpId:=Op.OpKill; //set kill to dummy
pOpBlock.pBody:=pChild;
@ -3124,7 +3110,7 @@ begin
if (src[0]=nil) or (src[1]=nil) then Exit;
node.mark_not_used;
node.mark([soNotUsed]);
node.pDst:=nil;
if (car.IsUsed) then //carry is use
@ -3155,7 +3141,7 @@ begin
if (src[0]=nil) or (src[1]=nil) then Exit;
node.mark_not_used;
node.mark([soNotUsed]);
node.pDst:=nil;
if (bor.IsUsed) then //borrow is use
@ -3186,7 +3172,7 @@ begin
if (src[0]=nil) or (src[0]=nil) or (src[1]=nil) then Exit;
node.mark_not_used;
node.mark([soNotUsed]);
node.pDst:=nil;
num4 :=NewImm_q(dtUint32, 4,node);

View File

@ -29,7 +29,7 @@ type
procedure PrintConst;
procedure PrintVariable;
procedure PrintFunc;
procedure PrintOp(node:TSpirvOp;print_offset:Boolean);
procedure PrintOp(node:TSpirvOp);
end;
implementation
@ -91,7 +91,7 @@ begin
begin
pBlock:=node.Parent;
Write(Space(pBlock.Level));
PrintOp(node,false);
PrintOp(node);
end;
node:=flow_down_next_up(node);
end;
@ -187,7 +187,7 @@ begin
end;
end;
procedure TSprvEmit_print.PrintOp(node:TSpirvOp;print_offset:Boolean);
procedure TSprvEmit_print.PrintOp(node:TSpirvOp);
var
Param:POpParamNode;
Info:Op.TOpInfo;
@ -225,15 +225,7 @@ begin
Param:=Param.Next;
end;
if (node.OpId=Op.OpLabel) then
begin
print_offset:=true;
end;
Case print_offset of
True :Writeln(' ;0x',HexStr(Node.Adr.Offdw*4,4){,' (',node.Order,')'});
False:Writeln;
end;
Writeln;
end;

View File

@ -8,7 +8,7 @@ uses
sysutils,
ps4_pssl,
spirv,
srCFGLabel,
srCFGParser,
srFlow,
srType,
srConst,
@ -119,6 +119,10 @@ begin
SetConst_b(get_scc,src0.AsConst.AsBool or src1.AsConst.AsBool);
end else
begin
//force type
src0:=BitcastList.FetchRead(dtBool,src0);
src1:=BitcastList.FetchRead(dtBool,src1);
OpLogicalOr(get_scc,src0,src1); //implict cast (int != 0)
end;
end;
@ -176,16 +180,12 @@ Var
newptr:Pointer;
begin
While (CheckBlockEnd) do;
//ret
if not fetch_ssrc9_pair(FSPI.SOP1.SSRC,@src,dtUnknow) then Assert(false);
newptr:=GetFuncPtr(@src);
set_code_ptr(newptr,btMain);
While (CheckBlockBeg) do;
end;
procedure TEmit_SOP1.emit_S_SWAPPC_B64;

View File

@ -73,7 +73,7 @@ begin
a:=OpEqualTo(x,y);
b:=OpNotEqualTo(d,x);
OpBitwiseAnd(car,a,b);
OpLogicalAnd(car,a,b);
end;
procedure TEmit_SOP2.emit_S_ADD_U32;
@ -118,7 +118,7 @@ begin
a:=OpNotEqualTo(x,y);
b:=OpNotEqualTo(d,x);
OpBitwiseAnd(bor,a,b);
OpLogicalAnd(bor,a,b);
end;
procedure TEmit_SOP2.emit_S_SUB_U32;
@ -207,6 +207,10 @@ begin
SetConst_b(get_scc,src0.AsConst.AsBool or src1.AsConst.AsBool);
end else
begin
//force type
src0:=BitcastList.FetchRead(dtBool,src0);
src1:=BitcastList.FetchRead(dtBool,src1);
OpLogicalOr(get_scc,src0,src1); //implict cast (int != 0)
end;
end;
@ -431,7 +435,8 @@ begin
src[1]:=fetch_ssrc9(FSPI.SOP2.SSRC1,dtUnknow);
scc:=MakeRead(get_scc,dtBool);
OpSelect(dst,src[0],src[1],scc);
//dst,cond,src_true,src_false
OpSelect(dst,scc,src[0],src[1]);
end;
procedure TEmit_SOP2.emit_S_CSELECT_B64; //sdst[2] = SCC ? ssrc0[2] : ssrc1[2]
@ -447,8 +452,9 @@ begin
scc:=MakeRead(get_scc,dtBool);
OpSelect(dst[0],src0[0],src1[0],scc);
OpSelect(dst[1],src0[1],src1[1],scc);
//dst,cond,src_true,src_false
OpSelect(dst[0],scc,src0[0],src1[0]);
OpSelect(dst[1],scc,src0[1],src1[1]);
end;
//offset = ssrc1[4:0].u and 31

View File

@ -73,7 +73,7 @@ begin
a:=OpLogicalNotTo(a);
end;
OpBitwiseAnd(car,a,b);
OpLogicalAnd(car,a,b);
end;
procedure TEmit_SOPK.emit_S_MULK_I32; //sdst.s = (sdst.s * signExtend(imm16.s)) & 0xFFFFFFFF

View File

@ -8,12 +8,7 @@ uses
sysutils,
ps4_pssl,
srType,
srCFGParser,
srCFGLabel,
srCFGCursor,
srFlow,
srConst,
srReg,
srOp,
srOpUtils,
spirv,
@ -22,295 +17,11 @@ uses
type
TEmit_SOPP=class(TEmitFetch)
procedure emit_SOPP;
procedure emit_S_BRANCH_COND(cond:TsrCondition;invert:Boolean);
procedure emit_S_BRANCH;
procedure emit_loop_branch(b_adr:TSrcAdr;pCurr:TsrOpBlock);
function FetchCond(Adr:TSrcAdr):TsrOpBlock;
function FetchElse(Adr:TSrcAdr):Boolean;
function IsInLoop(Adr:TSrcAdr):Boolean;
function IsUnknow(Adr:TSrcAdr):Boolean;
function get_inline_end_addr(adr:TSrcAdr):TSrcAdr;
procedure emit_block_unknow(adr:TSrcAdr);
procedure emit_S_BARRIER;
end;
implementation
function TEmit_SOPP.get_inline_end_addr(adr:TSrcAdr):TSrcAdr;
var
cInline:TsrCursor;
begin
cInline:=fetch_cursor_ptr(adr.get_code_ptr,btInline);
Result :=cInline.pCode.FTop.pELabel.Adr; //get end of code
end;
function _up_to_real(t:TsrOpBlock):TsrOpBlock;
begin
repeat
if not t.IsType(ntOpBlock) then Break;
if IsReal(t.Block.bType) then Break;
t:=t.Parent;
until false;
Result:=t;
end;
function TEmit_SOPP.FetchCond(Adr:TSrcAdr):TsrOpBlock;
var
pOpBlock:TsrOpBlock;
begin
Result:=nil;
pOpBlock:=Main.pBlock.FindUpCond;
if (pOpBlock=nil) then Exit;
if (pOpBlock.Block.b_adr.get_code_ptr=Adr.get_code_ptr) then
begin
Result:=pOpBlock;
end else
begin
//special case
if (pOpBlock.Block.b_adr.get_code_ptr=Cursor.prev_adr.get_code_ptr) then
if (pOpBlock.Block.e_adr.get_code_ptr=Adr.get_code_ptr) then
begin
Result:=pOpBlock;
end;
end;
end;
function TEmit_SOPP.FetchElse(Adr:TSrcAdr):Boolean;
var
pOpBlock:TsrOpBlock;
pElse :TsrOpBlock;
begin
Result:=False;
pOpBlock:=Main.pBlock.FindUpCond;
if (pOpBlock=nil) then Exit;
pElse:=pOpBlock.pElse;
if (pElse<>nil) then
begin
if (pElse.Block.e_adr.get_code_ptr=Adr.get_code_ptr) then
begin
Result:=True;
end;
end;
end;
function TEmit_SOPP.IsInLoop(Adr:TSrcAdr):Boolean;
var
pOpBlock:TsrOpBlock;
begin
Result:=false;
pOpBlock:=Main.pBlock.FindUpLoop;
if (pOpBlock=nil) then Exit(False);
if (pOpBlock.Block.b_adr.get_code_ptr=adr.get_code_ptr) then //is continue?
begin
Result:=True;
end else
if (pOpBlock.Block.e_adr.get_code_ptr=adr.get_code_ptr) then //is break?
begin
Result:=True;
end else
begin
Result:=False;
end;
end;
function TEmit_SOPP.IsUnknow(Adr:TSrcAdr):Boolean;
var
pLabel:TsrLabel;
begin
pLabel:=FindLabel(Adr);
Assert(pLabel<>nil);
Result:=pLabel.IsType(ltUnknow);
end;
procedure TEmit_SOPP.emit_S_BRANCH_COND(cond:TsrCondition;invert:Boolean);
var
c_adr,b_adr:TSrcAdr;
pLabel:TsrLabel;
pCond:TsrOpBlock;
pBegOp,pEndOp:TspirvOp;
src:TsrRegNode;
begin
if (FSPI.SOPP.SIMM=0) then
begin
Exit; //skip
end;
pLabel:=FindLabel(Cursor.prev_adr);
if (pLabel<>nil) then
begin
if (ltGoto in pLabel.lType) then Exit;
end;
While (CheckBlockBeg) do;
c_adr:=Cursor.Adr;
b_adr:=c_adr;
b_adr.Offdw:=get_branch_offset(FSPI);
pLabel:=FindLabel(b_adr);
Assert(pLabel<>nil);
pCond:=FetchCond(c_adr);
Assert(pCond<>nil,'Goto Unknow');
src:=ConvertCond(cond,pCond.vctx.Befor).pNode;
pBegOp:=pCond.Labels.pBegOp;
pEndOp:=pCond.Labels.pEndOp;
pCond.SetCond(src,invert);
//OpBranchConditional
//The instruction specifies which block to skip, so need to invert the condition!
//Since the main condition is this condition equal to zero, then we need to invert it again!
Case invert of
True: //invert of invert of invert!
begin
pCond.Labels.pBcnOp.AddParam(src);
pCond.Labels.pBcnOp.AddParam(pEndOp.pDst); //True
pCond.Labels.pBcnOp.AddParam(pBegOp.pDst); //False
end;
False: //invert of invert!
begin
pCond.Labels.pBcnOp.AddParam(src);
pCond.Labels.pBcnOp.AddParam(pBegOp.pDst); //True
pCond.Labels.pBcnOp.AddParam(pEndOp.pDst); //False
end;
end;
if (pCond.Block.e_adr.get_code_ptr=b_adr.get_code_ptr) then
begin
//if (eval) {}
end else
begin
emit_loop_branch(b_adr,pCond.pBody);
end;
end;
procedure TEmit_SOPP.emit_block_unknow(adr:TSrcAdr);
var
pOpChild:TsrOpBlock;
Info:TsrBlockInfo;
begin
Info:=Default(TsrBlockInfo);
Info.b_adr:=adr;
Info.e_adr:=get_inline_end_addr(adr);
Info.bType:=btInline;
//down group
pOpChild:=AllocBlockOp;
pOpChild.SetInfo(Info);
PushBlockOp(line,pOpChild);
set_code_ptr(adr.get_code_ptr,btInline);
end;
procedure TEmit_SOPP.emit_loop_branch(b_adr:TSrcAdr;pCurr:TsrOpBlock);
var
pOpLabel:TspirvOp;
pLoop:TsrOpBlock;
FVolMark:TsrVolMark;
bnew:Boolean;
begin
pLoop:=Main.pBlock.FindUpLoop;
Assert(pLoop<>nil,'Goto Unknow');
//break/continue
pOpLabel:=nil;
FVolMark:=vmNone;
if (pLoop.Block.b_adr.get_code_ptr=b_adr.get_code_ptr) then //is continue?
begin
pOpLabel:=pLoop.Labels.pMrgOp; //-> OpLoopMerge end -> OpLoopMerge before
pLoop.Cond.FUseCont:=True;
FVolMark:=vmConti;
end else
if (pLoop.Block.e_adr.get_code_ptr=b_adr.get_code_ptr) then //is break?
begin
pOpLabel:=pLoop.Labels.pEndOp;
FVolMark:=vmBreak;
end else
begin
Assert(false,'break/continue');
end;
Assert(pOpLabel<>nil);
bnew:=true;
if pCurr.IsEndOf(Cursor.Adr) then //is last
begin
Case pCurr.Block.bType of
btSetpc:;
else
begin
bnew:=false;
end;
end;
end;
//calc volatile
case FVolMark of
vmBreak:PrivateList.build_volatile_break(pLoop.vctx,pLoop.Regs.orig,pLoop.Regs.prev,pLoop.Regs.next);
vmConti:PrivateList.build_volatile_conti(pLoop.vctx,pLoop.Regs.orig,pLoop.Regs.prev,pLoop.Regs.next);
end;
//mark hints
mark_end_of(FVolMark);
OpBranch(pCurr.line,pOpLabel);
if bnew then
begin
AddSpirvOp(pCurr.line,NewLabelOp(True));
end;
end;
procedure TEmit_SOPP.emit_S_BRANCH;
var
pLabel:TsrLabel;
c_adr,b_adr:TSrcAdr;
begin
if (FSPI.SOPP.SIMM=0) then
begin
Exit; //skip
end;
pLabel:=FindLabel(Cursor.prev_adr);
if (pLabel<>nil) then
begin
if (ltGoto in pLabel.lType) then Exit;
end;
While (CheckBlockBeg) do;
c_adr:=Cursor.Adr;
b_adr:=c_adr;
b_adr.Offdw:=get_branch_offset(FSPI);
if FetchElse(b_adr) then
begin
//{} else {}
end else
begin
emit_loop_branch(b_adr,Main.pBlock);
end;
end;
procedure TEmit_SOPP.emit_S_BARRIER;
Var
node:TspirvOp;
@ -351,14 +62,14 @@ begin
mark_end_of(vmEndpg);
end;
S_CBRANCH_SCC0 :emit_S_BRANCH_COND(cScc0 ,false);
S_CBRANCH_SCC1 :emit_S_BRANCH_COND(cScc0 ,true);
S_CBRANCH_VCCZ :emit_S_BRANCH_COND(cVccz ,false); //It means that lane_id=0
S_CBRANCH_VCCNZ :emit_S_BRANCH_COND(cVccz ,true); //It means that lane_id=0
S_CBRANCH_EXECZ :emit_S_BRANCH_COND(cExecz,false); //It means that lane_id=0
S_CBRANCH_EXECNZ:emit_S_BRANCH_COND(cExecz,true); //It means that lane_id=0
S_CBRANCH_SCC0 :; //It means that (scc == 0)
S_CBRANCH_SCC1 :; //It means that (scc == 1)
S_CBRANCH_VCCZ :; //It means that (vcc0 == 0) && (vcc1 == 0)
S_CBRANCH_VCCNZ :; //It means that (vcc0 != 0) || (vcc1 != 0)
S_CBRANCH_EXECZ :; //It means that (exec0 == 0) && (exec1 == 0)
S_CBRANCH_EXECNZ:; //It means that (exec0 != 0) || (exec1 != 0)
S_BRANCH :emit_S_BRANCH;
S_BRANCH :;
S_BARRIER :emit_S_BARRIER;

View File

@ -168,11 +168,13 @@ begin
cond:=OpCmpTo(Op.OpSLessThan,t3,NewImm_q(dtUint32,$38800000)); //(t3 < 0x38800000)
t1:=OpSelectTo(t1,NewImm_q(dtUint32,0),cond); //if (t3 < 0x38800000) t1 = 0; // Flush-to-zero
//cond,src_true,src_false
t1:=OpSelectTo(cond,NewImm_q(dtUint32,0),t1); //if (t3 < 0x38800000) t1 = 0; // Flush-to-zero
cond:=OpCmpTo(Op.OpSGreaterThan,t3,NewImm_q(dtUint32,$47000000)); //(t3 > 0x47000000)
t1:=OpSelectTo(t1,NewImm_q(dtUint32,$3FF),cond); //if (t3 > 0x47000000) t1 = 0x3FF; // Clamp-to-max
//cond,src_true,src_false
t1:=OpSelectTo(cond,NewImm_q(dtUint32,$3FF),t1); //if (t3 > 0x47000000) t1 = 0x3FF; // Clamp-to-max
Result:=t1;
end;
@ -195,11 +197,13 @@ begin
cond:=OpCmpTo(Op.OpSLessThan,t3,NewImm_q(dtUint32,$38800000)); //(t3 < 0x38800000)
t1:=OpSelectTo(t1,NewImm_q(dtUint32,0),cond); //if (t3 < 0x38800000) t1 = 0; // Flush-to-zero
//cond,src_true,src_false
t1:=OpSelectTo(cond,NewImm_q(dtUint32,0),t1); //if (t3 < 0x38800000) t1 = 0; // Flush-to-zero
cond:=OpCmpTo(Op.OpSGreaterThan,t3,NewImm_q(dtUint32,$87000000)); //(t3 > 0x87000000)
t1:=OpSelectTo(t1,NewImm_q(dtUint32,$7FF),cond); //if (t3 > 0x47000000) t1 = 0x7FF; // Clamp-to-max
//cond,src_true,src_false
t1:=OpSelectTo(cond,NewImm_q(dtUint32,$7FF),t1); //if (t3 > 0x47000000) t1 = 0x7FF; // Clamp-to-max
Result:=t1;
end;

View File

@ -363,6 +363,9 @@ Var
pos:TsrRegNode;
cnd:TsrRegNode;
begin
// Gcn wants the MSB position counting from the left, but SPIR-V counts from the rightmost (LSB)
// position
dst:=get_vdst8(FSPI.VOP1.VDST);
src:=fetch_ssrc9(FSPI.VOP1.SRC0,dtUint32);
@ -371,10 +374,11 @@ begin
pos:=OpISubTo(NewImm_i(dtUint32,31),msb);
cnd:=OpIEqualTo(src,NewImm_i(dtUint32,0));
// Select 0xFFFFFFFF if src was 0
cnd:=OpINotEqualTo(src,NewImm_i(dtUint32,0));
// True, False
OpSelect(dst,NewImm_q(dtUint32,High(DWORD)),pos,cnd);
//dst,cond,src_true,src_false
OpSelect(dst,cnd,pos,NewImm_q(dtUint32,High(DWORD)));
end;
procedure TEmit_VOP1.emit_V_FFBL_B32;

View File

@ -67,18 +67,19 @@ begin
end;
end;
procedure TEmit_VOP2.emit_V_CNDMASK_B32;
procedure TEmit_VOP2.emit_V_CNDMASK_B32; //vdst = smask[thread_id:] ? vsrc1 : vsrc0
Var
dst:PsrRegSlot;
src:array[0..2] of TsrRegNode;
begin
dst:=get_vdst8(FSPI.VOP2.VDST);
src[0]:=fetch_ssrc9(FSPI.VOP2.SRC0 ,dtUnknow);
src[1]:=fetch_vsrc8(FSPI.VOP2.VSRC1,dtUnknow);
src[2]:=MakeRead(get_vcc0,dtBool);
src[0]:=fetch_ssrc9 (FSPI.VOP2.SRC0 ,dtUnknow);
src[1]:=fetch_vsrc8 (FSPI.VOP2.VSRC1,dtUnknow);
src[2]:=GetThreadBit(get_vcc0,get_vcc1,dtBool);
OpSelect(dst,src[0],src[1],src[2]);
//dst,cond,src_true,src_false
OpSelect(dst,src[2],src[1],src[0]);
end;
procedure TEmit_VOP2.emit_V_AND_B32;
@ -143,7 +144,7 @@ begin
src[1]:=OpAndTo(src[1],31);
src[1].PrepType(ord(dtUInt32));
Op2(OpId,src[0].dtype,dst,src[0],src[1]);
Op2(OpId,rtype,dst,src[0],src[1]);
end;
procedure TEmit_VOP2.emit_V_ADD_I32; //vdst = vsrc0.s + vsrc1.s; sdst[thread_id:] = carry_out & EXEC
@ -225,7 +226,7 @@ begin
src[0]:=fetch_ssrc9(FSPI.VOP2.SRC0 ,dtUint32);
src[1]:=fetch_vsrc8(FSPI.VOP2.VSRC1,dtUint32);
src[2]:=MakeRead(get_vcc0,dtUInt32);
src[2]:=GetThreadBit(get_vcc0,get_vcc1,dtUInt32);
src[2]:=OpAndTo(src[2],1);
src[2].PrepType(ord(dtUInt32));
@ -283,7 +284,7 @@ begin
end;
end;
src[2]:=MakeRead(get_vcc0,dtUInt32);
src[2]:=GetThreadBit(get_vcc0,get_vcc1,dtUInt32);
src[2]:=OpAndTo(src[2],1);
src[2].PrepType(ord(dtUInt32));
@ -360,7 +361,8 @@ begin
mul:=NewReg(dtFloat32);
_Op2(line,Op.OpFMul,mul,src[0],src[1]);
OpSelect(dst,mul,zero,cmp); //false,true,cond
//dst,cond,src_true,src_false
OpSelect(dst,cmp,zero,mul);
end;
procedure TEmit_VOP2.emit_V_CVT_PKRTZ_F16_F32;
@ -376,29 +378,23 @@ begin
OpConvFloatToHalf2(dst,src[0],src[1]);
end;
procedure TEmit_VOP2.emit_V_MUL_I32_I24;
procedure TEmit_VOP2.emit_V_MUL_I32_I24; //vdst = (vsrc0[23:0].s * vsrc1[23:0].s)
Var
dst:PsrRegSlot;
src:array[0..1] of TsrRegNode;
bit24:TsrRegNode;
begin
dst:=get_vdst8(FSPI.VOP2.VDST);
src[0]:=fetch_ssrc9(FSPI.VOP2.SRC0 ,dtInt32);
src[1]:=fetch_vsrc8(FSPI.VOP2.VSRC1,dtInt32);
bit24:=NewImm_q(dtUInt32,$FFFFFF);
src[0]:=OpAndTo(src[0],bit24);
src[0].PrepType(ord(dtInt32));
src[1]:=OpAndTo(src[1],bit24);
src[1].PrepType(ord(dtInt32));
src[0]:=OpBFSETo(src[0],NewImm_i(dtInt32,0),NewImm_i(dtInt32,24));
src[1]:=OpBFSETo(src[1],NewImm_i(dtInt32,0),NewImm_i(dtInt32,24));
OpIMul(dst,src[0],src[1]);
end;
procedure TEmit_VOP2.emit_V_MUL_U32_U24;
procedure TEmit_VOP2.emit_V_MUL_U32_U24; //vdst = (vsrc0[23:0].u * vsrc1[23:0].u)
Var
dst:PsrRegSlot;
src:array[0..1] of TsrRegNode;
@ -457,7 +453,8 @@ begin
mul:=MakeRead(dst,dtFloat32);
OpSelect(dst,mul,zero,cmp); //false,true,cond
//dst,cond,src_true,src_false
OpSelect(dst,cmp,zero,mul);
end;
procedure TEmit_VOP2.emit_V_MADAK_F32; //vdst = vsrc0.f * vsrc1.f + kadd.f

View File

@ -91,14 +91,12 @@ begin
emit_src_abs_bit(@src,2,rtype);
emit_src_neg_bit(@src,2,rtype);
OpCmpV(OpId,dst[0],src[0],src[1]);
SetConst_q(dst[1],dtUnknow,0); //set zero
OpCmpV(OpId,dst[0],dst[1],src[0],src[1]);
if x then
begin
MakeCopy (get_exec0,dst[0]^.current);
SetConst_q(get_exec1,dtUnknow,0); //set zero
MakeCopy(get_exec0,dst[0]^.current);
MakeCopy(get_exec1,dst[1]^.current);
end;
end;
@ -221,7 +219,7 @@ begin
end;
end;
procedure TEmit_VOP3.emit_V_CNDMASK_B32;
procedure TEmit_VOP3.emit_V_CNDMASK_B32; //vdst = smask[thread_id:] ? vsrc1 : vsrc0
Var
dst:PsrRegSlot;
src:array[0..2] of TsrRegNode;
@ -245,12 +243,13 @@ begin
src[0]:=fetch_ssrc9(FSPI.VOP3a.SRC0,rtype);
src[1]:=fetch_ssrc9(FSPI.VOP3a.SRC1,rtype);
src[2]:=fetch_ssrc9(FSPI.VOP3a.SRC2,dtBool);
src[2]:=GetThreadBit(get_ssrc9(FSPI.VOP3a.SRC2),get_ssrc9(FSPI.VOP3a.SRC2+1),dtBool);
emit_src_abs_bit(@src,2,rtype);
emit_src_neg_bit(@src,2,rtype);
OpSelect(dst,src[0],src[1],src[2]);
//dst,cond,src_true,src_false
OpSelect(dst,src[2],src[1],src[0]);
end;
procedure TEmit_VOP3.emit_V_MUL_LEGACY_F32;
@ -276,7 +275,8 @@ begin
mul:=NewReg(dtFloat32);
_Op2(line,Op.OpFMul,mul,src[0],src[1]);
OpSelect(dst,mul,zero,cmp); //false,true,cond
//dst,cond,src_true,src_false
OpSelect(dst,cmp,zero,mul);
emit_dst_omod__f(dst,dtFloat32);
emit_dst_clamp_f(dst,dtFloat32);
@ -395,7 +395,7 @@ begin
src[1]:=OpAndTo(src[1],31);
src[1].PrepType(ord(dtUInt32));
Op2(OpId,src[0].dtype,dst,src[0],src[1]);
Op2(OpId,rtype,dst,src[0],src[1]);
end;
procedure TEmit_VOP3.emit_V_MUL_LO(rtype:TsrDataType);
@ -416,11 +416,10 @@ begin
OpIMul(dst,src[0],src[1]);
end;
procedure TEmit_VOP3.emit_V_MUL_I32_I24;
procedure TEmit_VOP3.emit_V_MUL_I32_I24; //vdst = (vsrc0[23:0].s * vsrc1[23:0].s)
Var
dst:PsrRegSlot;
src:array[0..1] of TsrRegNode;
bit24:TsrRegNode;
begin
dst:=get_vdst8(FSPI.VOP3a.VDST);
@ -432,13 +431,8 @@ begin
src[0]:=fetch_ssrc9(FSPI.VOP3a.SRC0,dtInt32);
src[1]:=fetch_ssrc9(FSPI.VOP3a.SRC1,dtInt32);
bit24:=NewImm_q(dtUInt32,$FFFFFF);
src[0]:=OpAndTo(src[0],bit24);
src[0].PrepType(ord(dtInt32));
src[1]:=OpAndTo(src[1],bit24);
src[1].PrepType(ord(dtInt32));
src[0]:=OpBFSETo(src[0],NewImm_i(dtInt32,0),NewImm_i(dtInt32,24));
src[1]:=OpBFSETo(src[1],NewImm_i(dtInt32,0),NewImm_i(dtInt32,24));
OpIMul(dst,src[0],src[1]);
end;
@ -757,14 +751,14 @@ begin
mul:=MakeRead(dst,dtFloat32);
OpSelect(dst,mul,zero,cmp); //false,true,cond
//dst,cond,src_true,src_false
OpSelect(dst,cmp,zero,mul);
end;
procedure TEmit_VOP3.emit_V_MAD_I32_I24;
procedure TEmit_VOP3.emit_V_MAD_I32_I24; //vdst.i = vsrc0[23:0].i * vsrc1[23:0].i + vsrc2.i
Var
dst:PsrRegSlot;
src:array[0..2] of TsrRegNode;
bit24:TsrRegNode;
begin
dst:=get_vdst8(FSPI.VOP3a.VDST);
@ -777,18 +771,13 @@ begin
src[1]:=fetch_ssrc9(FSPI.VOP3a.SRC1,dtInt32);
src[2]:=fetch_ssrc9(FSPI.VOP3a.SRC2,dtInt32);
bit24:=NewImm_q(dtUInt32,$FFFFFF);
src[0]:=OpAndTo(src[0],bit24);
src[0].PrepType(ord(dtInt32));
src[1]:=OpAndTo(src[1],bit24);
src[1].PrepType(ord(dtInt32));
src[0]:=OpBFSETo(src[0],NewImm_i(dtInt32,0),NewImm_i(dtInt32,24));
src[1]:=OpBFSETo(src[1],NewImm_i(dtInt32,0),NewImm_i(dtInt32,24));
OpFmaI32(dst,src[0],src[1],src[2]);
end;
procedure TEmit_VOP3.emit_V_MAD_U32_U24;
procedure TEmit_VOP3.emit_V_MAD_U32_U24; //vdst.u = vsrc0[23:0].u * vsrc1[23:0].u + vsrc2.u
Var
dst:PsrRegSlot;
src:array[0..2] of TsrRegNode;
@ -821,7 +810,8 @@ procedure TEmit_VOP3.emit_V_MAD_U64_U32;
Var
dst:array[0..1] of PsrRegSlot;
src:array[0..2] of TsrRegNode;
mul,sum,car,exc:TsrRegNode;
mul,sum,car:TsrRegNode;
//exc:TsrRegNode;
begin
dst[0]:=get_vdst8(FSPI.VOP3a.VDST+0);
dst[1]:=get_vdst8(FSPI.VOP3a.VDST+1);

View File

@ -32,14 +32,12 @@ begin
src[0]:=fetch_ssrc9(FSPI.VOPC.SRC0 ,rtype);
src[1]:=fetch_vsrc8(FSPI.VOPC.VSRC1,rtype);
OpCmpV(OpId,dst[0],src[0],src[1]);
SetConst_q(dst[1],dtUnknow,0); //set zero
OpCmpV(OpId,dst[0],dst[1],src[0],src[1]);
if x then
begin
MakeCopy (get_exec0,dst[0]^.current);
SetConst_q(get_exec1,dtUnknow,0); //set zero
MakeCopy(get_exec0,dst[0]^.current);
MakeCopy(get_exec1,dst[1]^.current);
end;
end;

View File

@ -25,7 +25,7 @@
<RunParams>
<FormatVersion Value="2"/>
</RunParams>
<Units Count="64">
<Units Count="63">
<Unit0>
<Filename Value="pssl-spirv.lpr"/>
<IsPartOfProject Value="True"/>
@ -250,54 +250,50 @@
<IsPartOfProject Value="True"/>
</Unit51>
<Unit52>
<Filename Value="srCFGLabel.pas"/>
<Filename Value="srCFGParser.pas"/>
<IsPartOfProject Value="True"/>
</Unit52>
<Unit53>
<Filename Value="srCFGParser.pas"/>
<Filename Value="srFlow.pas"/>
<IsPartOfProject Value="True"/>
</Unit53>
<Unit54>
<Filename Value="srFlow.pas"/>
<Filename Value="srLiteral.pas"/>
<IsPartOfProject Value="True"/>
</Unit54>
<Unit55>
<Filename Value="srLiteral.pas"/>
<Filename Value="srNode.pas"/>
<IsPartOfProject Value="True"/>
</Unit55>
<Unit56>
<Filename Value="srNode.pas"/>
<Filename Value="srPrivate.pas"/>
<IsPartOfProject Value="True"/>
</Unit56>
<Unit57>
<Filename Value="srPrivate.pas"/>
<Filename Value="srType.pas"/>
<IsPartOfProject Value="True"/>
</Unit57>
<Unit58>
<Filename Value="srType.pas"/>
<Filename Value="srUniform.pas"/>
<IsPartOfProject Value="True"/>
</Unit58>
<Unit59>
<Filename Value="srUniform.pas"/>
<Filename Value="srVBufInfo.pas"/>
<IsPartOfProject Value="True"/>
</Unit59>
<Unit60>
<Filename Value="srVBufInfo.pas"/>
<Filename Value="..\chip\ps4_pssl.pas"/>
<IsPartOfProject Value="True"/>
</Unit60>
<Unit61>
<Filename Value="..\chip\ps4_pssl.pas"/>
<IsPartOfProject Value="True"/>
</Unit61>
<Unit62>
<Filename Value="emit_ds.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="emit_DS"/>
</Unit62>
<Unit63>
</Unit61>
<Unit62>
<Filename Value="srOpInternal.pas"/>
<IsPartOfProject Value="True"/>
</Unit63>
</Unit62>
</Units>
</ProjectOptions>
<CompilerOptions>

View File

@ -435,9 +435,14 @@ var
begin
Result:=Default(TFieldFetchValue);
Assert(_stride<>0);
Assert(_size <>0);
_count:=_size div _stride;
_size :=_count*_stride; //align
Assert(_count<>0);
//find intersec
node:=FindIntersect(_offset,_size);

View File

@ -6,27 +6,31 @@ interface
uses
sysutils,
srCFGLabel,
srCFGParser,
ginodes,
srNode;
type
PsrCursor=^TsrCursor;
TsrCursor=object(TsrLCursor)
pCode :TsrCodeBlock;
pBlock:TsrCFGBlock;
procedure Init(Code:TsrCodeBlock);
TsrCursor=object
pCode:TsrCodeRegion;
pNode:TsrSourceNode;
b_adr:TSrcAdr;
e_adr:TSrcAdr;
fnext:Boolean;
procedure Init(Code:TsrCodeRegion;node:TsrSourceNode;base:Pointer);
procedure UpdateAdr;
function AsBlock:TsrSourceBlock;
function PopBlock:Boolean;
end;
TsrCodeList=specialize TNodeQueueClass<TsrCodeBlock>;
TsrCodeList=specialize TNodeQueueClass<TsrCodeRegion>;
PsrCodeHeap=^TsrCodeHeap;
TsrCodeHeap=object(TsrCodeList)
FEmit:TCustomEmit;
Procedure Init(Emit:TCustomEmit);
function FindByPtr (base:Pointer):TsrCodeBlock;
function FindByPtr (base:Pointer):TsrCodeRegion;
function FetchByPtr(base:Pointer;bType:TsrBlockType):TsrCursor;
end;
@ -39,15 +43,15 @@ begin
FEmit:=Emit;
end;
function TsrCodeHeap.FindByPtr(base:Pointer):TsrCodeBlock;
function TsrCodeHeap.FindByPtr(base:Pointer):TsrCodeRegion;
var
node:TsrCodeBlock;
node:TsrCodeRegion;
begin
Result:=nil;
node:=pHead;
While (node<>nil) do
begin
if node.IsContain(base) then
if (PtrUint(node.Body)<=PtrUint(base)) and ((PtrUint(node.Body)+node.Size)>PtrUint(base)) then
begin
Exit(node);
end;
@ -57,53 +61,78 @@ end;
function TsrCodeHeap.FetchByPtr(base:Pointer;bType:TsrBlockType):TsrCursor;
var
pCode:TsrCodeBlock;
adr:TSrcAdr;
pCode:TsrCodeRegion;
pNode:TsrSourceNode;
p_err:Integer;
begin
pCode:=FindByPtr(base);
if (pCode=nil) then
begin
pCode:=FEmit.specialize New<TsrCodeBlock>;
pCode.FTop:=FEmit.specialize New<TsrCFGBlock>;
pCode.FEmit:=FEmit;
pCode.Body :=base;
pCode.DMem :=FEmit.GetDmem(base);
//
p_err:=parse_code_cfg(bType,pCode);
if (pCode<>nil) then
begin
pNode:=pCode.FindByPtr(base);
end else
begin
pNode:=nil;
end;
if (pNode=nil) then
begin
p_err:=parse_code_cfg2(pCode,bType,base,FEmit.GetDmem(base),FEmit);
if (p_err>1) then
begin
Assert(False,'parse_code_cfg:'+IntToStr(p_err));
end;
//
Push_tail(pCode);
//
pNode:=pCode.FindByPtr(base);
end;
Result:=Default(TsrCursor);
Result.Init(pCode);
adr:=Default(TSrcAdr);
adr.pCode:=TsrLabelBlock(pCode);
adr.Offdw:=(Pointer(base)-Pointer(pCode.Body)) div 4;
Result.Adr:=adr;
Result.pBlock:=Result.pBlock.WorkBlock(adr);
Result.Init(pCode,pNode,base);
end;
procedure TsrCursor.Init(Code:TsrCodeBlock);
procedure TsrCursor.Init(Code:TsrCodeRegion;node:TsrSourceNode;base:Pointer);
begin
inherited Init(TsrLabelBlock(Code));
pCode :=Code;
pBlock:=Code.FTop;
pCode:=Code;
pNode:=node;
//
b_adr.pCode :=Code;
b_adr.Offset:=0;
e_adr:=b_adr;
//
UpdateAdr;
//
fnext:=(e_adr.get_code_ptr=base);
end;
procedure TsrCursor.UpdateAdr;
begin
if (pNode<>nil) then
begin
if pNode.InheritsFrom(TsrSourceAdr) then
begin
b_adr:=TsrSourceAdr(pNode).b_adr;
e_adr:=TsrSourceAdr(pNode).e_adr;
end;
end;
end;
function TsrCursor.AsBlock:TsrSourceBlock;
begin
Result:=nil;
if (pNode<>nil) then
if (pNode.ntype=TsrSourceBlock) then
begin
Exit(TsrSourceBlock(pNode));
end;
end;
function TsrCursor.PopBlock:Boolean;
begin
Result:=False;
if (pBlock=nil) then Exit;
if (pBlock.pParent=nil) then Exit;
pBlock:=pBlock.pParent;
if (pNode=nil) then Exit;
if (pNode.pParent=nil) then Exit;
pNode:=pNode.pParent;
Result:=True;
end;

View File

@ -1,358 +0,0 @@
unit srCFGLabel;
{$mode ObjFPC}{$H+}
interface
uses
ps4_pssl,
ginodes,
srNode;
type
TsrLabelBlock=class;
PSrcAdr=^TSrcAdr;
TSrcAdr=object
pCode:TsrLabelBlock;
Offdw:PtrUInt;
function get_code_ptr:PDWORD;
function get_dmem_ptr:PDWORD;
end;
TsrLCursor=object(TShaderParser)
private
pCode:TsrLabelBlock;
function get_src_adr:TSrcAdr;
Procedure set_src_adr(src:TSrcAdr);
public
prev_adr:TSrcAdr;
procedure Init(Code:TsrLabelBlock);
property Adr:TSrcAdr read get_src_adr write set_src_adr;
Function Next(Var SPI:TSPI):Integer;
end;
TsrLabelType=(ltUnknow,
ltGoto,
ltContinue,
ltBreak);
TsrSetLabelType=Set of TsrLabelType;
TsrBlockType=(btMain,btSetpc,btCond,btElse,btLoop,btMerg,btExec,btInline,btOther);
TsrCondition=(
cNone,
cFalse,
cTrue,
cScc0,
cScc1,
cVccz,
cVccnz,
cExecz,
cExecnz
);
const
InvertCond:array[TsrCondition] of TsrCondition=(
cNone, //cNone,
cTrue, //cFalse,
cFalse, //cTrue,
cScc1, //cScc0,
cScc0, //cScc1,
cVccnz, //cVccz,
cVccz, //cVccnz,
cExecnz, //cExecz,
cExecz //cExecnz
);
type
TsrLabel=class
public
pLeft,pRight:TsrLabel;
private
key:TSrcAdr;
public
lType:TsrSetLabelType;
class function c(n1,n2:PSrcAdr):Integer; static;
property Adr:TSrcAdr read key;
Procedure AddType(t:TsrLabelType);
Procedure RemType(t:TsrLabelType);
function IsType (t:TsrLabelType):Boolean;
end;
TsrStatementType=(
sCond,
sGoto,
sVar,
sStore,
sLoad,
sBreak,
sNot,
sOr,
sAnd
);
//sCond TsrCondition
//sGoto [sLabel]:TsrLabel [sNext]:TsrLabel [cond]:sCond/sLoad/sNot/sOr/sAnd
//sVar id
//sStore [var]:sVar [false]:sCond/sLoad/sNot/sOr/sAnd
//sLoad [var]:sVar
//sBreak
//sNot [cond]:sCond/sLoad/sNot/sOr
//sOr [cond]:sCond/sLoad/sNot/sOr/sAnd [cond]:sCond/sLoad/sNot/sOr/sAnd
//sAnd [cond]:sCond/sLoad/sNot/sOr/sAnd [cond]:sCond/sLoad/sNot/sOr/sAnd
TsrStatement=class
pPrev :TsrStatement;
pNext :TsrStatement;
//
sType :TsrStatementType;
sLabel:TsrLabel;
sNext :TsrLabel;
pSrc :TsrStatement;
pDst :TsrStatement;
//
pCache:TObject;
u:record
Case Byte of
0:(id :PtrUint);
1:(cond:TsrCondition);
end;
end;
TsrLabels=specialize TNodeTreeClass<TsrLabel>;
TsrLabelBlock=class
FEmit:TCustomEmit;
Body:Pointer;
DMem:Pointer;
Size:ptruint;
FLabels:TsrLabels;
FVarId:Ptruint;
Function FindLabel (Adr:TSrcAdr):TsrLabel;
Function FetchLabel(Adr:TSrcAdr):TsrLabel;
Function IsContain (P:Pointer):Boolean;
//
Function NewCond(cond:TsrCondition):TsrStatement;
Function NewGoto(sLabel,sNext:TsrLabel;pCond:TsrStatement):TsrStatement;
Function NewVar:TsrStatement;
Function NewStore(pVar,pCond:TsrStatement):TsrStatement;
Function NewLoad (pVar:TsrStatement):TsrStatement;
Function NewBreak(sLabel:TsrLabel):TsrStatement;
Function NewNot (pCond:TsrStatement):TsrStatement;
Function NewOr (pCond1,pCond2:TsrStatement):TsrStatement;
Function NewAnd (pCond1,pCond2:TsrStatement):TsrStatement;
end;
function get_branch_offset(var FSPI:TSPI):ptrint;
function IsReal(b:TsrBlockType):Boolean;
implementation
function IsReal(b:TsrBlockType):Boolean;
begin
case b of
btMain,
btSetpc,
btCond,
btElse,
btLoop:Result:=True;
else
Result:=False;
end;
end;
function TSrcAdr.get_code_ptr:PDWORD;
begin
if (pCode=nil) then
begin
Result:=nil;
end else
begin
Result:=PDWORD(pCode.Body);
end;
//
Result:=PDWORD(Result)+Offdw;
end;
function TSrcAdr.get_dmem_ptr:PDWORD;
begin
if (pCode=nil) then
begin
Result:=nil
end else
begin
Result:=PDWORD(pCode.DMem);
end;
//
Result:=PDWORD(Result)+Offdw;
end;
procedure TsrLCursor.Init(Code:TsrLabelBlock);
begin
pCode :=Code;
Body :=Code.DMem;
OFFSET_DW:=0;
prev_adr :=Adr;
end;
Function TsrLCursor.Next(Var SPI:TSPI):Integer;
begin
prev_adr:=Adr;
Result:=inherited Next(SPI);
end;
function TsrLCursor.get_src_adr:TSrcAdr;
begin
Result:=Default(TSrcAdr);
Result.pCode:=pCode;
Result.Offdw:=OFFSET_DW;
end;
Procedure TsrLCursor.set_src_adr(src:TSrcAdr);
begin
pCode :=src.pCode;
Body :=pCode.DMem;
OFFSET_DW:=src.Offdw;
end;
class function TsrLabel.c(n1,n2:PSrcAdr):Integer;
var
p1,p2:Pointer;
begin
p1:=n1^.get_code_ptr;
p2:=n2^.get_code_ptr;
Result:=ord(p1>p2)-ord(p1<p2);
end;
Procedure TsrLabel.AddType(t:TsrLabelType);
begin
lType:=lType+[t];
end;
Procedure TsrLabel.RemType(t:TsrLabelType);
begin
lType:=lType-[t];
end;
function TsrLabel.IsType(t:TsrLabelType):Boolean;
begin
Result:=t in lType;
end;
function get_branch_offset(var FSPI:TSPI):ptrint;
begin
Result:=FSPI.OFFSET_DW+Smallint(FSPI.SOPP.SIMM)+1;
end;
Function TsrLabelBlock.FindLabel(Adr:TSrcAdr):TsrLabel;
begin
Assert(Adr.pCode=self);
Result:=FLabels.Find(@Adr);
end;
Function TsrLabelBlock.FetchLabel(Adr:TSrcAdr):TsrLabel;
begin
Assert(Adr.pCode=self);
Result:=nil;
Result:=FLabels.Find(@Adr);
if (Result=nil) then
begin
Result:=FEmit.specialize New<TsrLabel>;
Result.key:=Adr;
FLabels.Insert(Result);
end;
end;
Function TsrLabelBlock.IsContain(P:Pointer):Boolean;
begin
Result:=(Body<=P) and ((Body+Size)>P);
end;
Function TsrLabelBlock.NewCond(cond:TsrCondition):TsrStatement;
begin
Result:=FEmit.specialize New<TsrStatement>;
Result.sType :=sCond;
Result.u.cond:=cond;
end;
Function TsrLabelBlock.NewGoto(sLabel,sNext:TsrLabel;pCond:TsrStatement):TsrStatement;
begin
Result:=FEmit.specialize New<TsrStatement>;
Result.sType :=sGoto;
Result.sLabel:=sLabel;
Result.sNext :=sNext;
Result.pSrc :=pCond;
end;
Function TsrLabelBlock.NewVar:TsrStatement;
begin
Result:=FEmit.specialize New<TsrStatement>;
Result.sType:=sVar;
Result.u.id :=FVarId;
Inc(FVarId);
end;
Function TsrLabelBlock.NewStore(pVar,pCond:TsrStatement):TsrStatement;
begin
Result:=FEmit.specialize New<TsrStatement>;
Result.sType:=sStore;
Result.pDst :=pVar;
Result.pSrc :=pCond;
end;
Function TsrLabelBlock.NewLoad(pVar:TsrStatement):TsrStatement;
begin
Result:=FEmit.specialize New<TsrStatement>;
Result.sType:=sLoad;
Result.pSrc :=pVar;
Result.u.id :=FVarId;
Inc(FVarId);
end;
Function TsrLabelBlock.NewBreak(sLabel:TsrLabel):TsrStatement;
begin
Result:=FEmit.specialize New<TsrStatement>;
Result.sType :=sBreak;
Result.sLabel:=sLabel;
end;
Function TsrLabelBlock.NewNot(pCond:TsrStatement):TsrStatement;
begin
case pCond.sType of
sCond:Result:=NewCond(InvertCond[pCond.u.cond]);
else
begin
Result:=FEmit.specialize New<TsrStatement>;
Result.sType:=sNot;
Result.pSrc :=pCond;
end;
end;
end;
Function TsrLabelBlock.NewOr(pCond1,pCond2:TsrStatement):TsrStatement;
begin
Result:=FEmit.specialize New<TsrStatement>;
Result.sType:=sOr;
Result.pSrc :=pCond1;
Result.pDst :=pCond2;
end;
Function TsrLabelBlock.NewAnd(pCond1,pCond2:TsrStatement):TsrStatement;
begin
Result:=FEmit.specialize New<TsrStatement>;
Result.sType:=sAnd;
Result.pSrc :=pCond1;
Result.pDst :=pCond2;
end;
end.

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,7 @@ interface
uses
ginodes,
srNode,
srCFGLabel,
srCFGParser,
srType,
srReg,
srOp;
@ -51,7 +51,7 @@ function _up_to_real(t:TsrOpBlock):TsrOpBlock;
begin
repeat
if not t.IsType(ntOpBlock) then Break;
if IsReal(t.Block.bType) then Break;
if IsReal(t.bType) then Break;
t:=t.Parent;
until false;
Result:=t;

View File

@ -9,19 +9,20 @@ type
PsrConfig=^TsrConfig;
TsrConfig=packed object
PrintAsm:Boolean;
PrintCfg:Boolean;
UseVertexInput:Boolean; //True
UseTexelBuffer:Boolean;
UseOutput16:Boolean;
PrintAsm :Boolean;
PrintCfg :Boolean;
UseVertexInput :Boolean; //True
UseTexelBuffer :Boolean;
UseOutput16 :Boolean;
UseOnlyUserdataPushConst:Boolean;
UseExtendedEXECMask :Boolean;
//
DescriptorSet:DWORD; //0
//
SpvVersion:PtrUint; // $10100
maxUniformBufferRange:PtrUint; // $FFFF
PushConstantsOffset:PtrUint; // 0
maxPushConstantsSize:PtrUint; // 128
SpvVersion :PtrUint; // $10100
maxUniformBufferRange :PtrUint; // $FFFF
PushConstantsOffset :PtrUint; // 0
maxPushConstantsSize :PtrUint; // 128
minStorageBufferOffsetAlignment:PtrUint; // $10
minUniformBufferOffsetAlignment:PtrUint; // $100
//

View File

@ -6,6 +6,7 @@ interface
uses
sysutils,
math,
spirv,
ginodes,
srNode,
@ -818,6 +819,7 @@ end;
Function TryTruncInt64(c:Single;var i:int64):Boolean;
begin
if IsNan(c) or IsInfinite(c) then Exit(False);
Result:=(c>=Low(int64)) and (c<=High(int64));
if Result then
begin

File diff suppressed because it is too large Load Diff

View File

@ -205,7 +205,7 @@ var
l:TSpirvOp;
begin
l:=node.pReg.pWriter.specialize AsType<ntOp>;
l.mark_not_used;
l.mark([soNotUsed]);
c:=PsrConstList(FEmit.GetConstList)^.Fetch(node.pReg.dtype,0);
node.pReg.pWriter:=c;

View File

@ -85,6 +85,8 @@ type
FSGPRS :WORD;
FGeometryInfo :TGeometryInfo;
//
FThread_id :TsrRegNode;
//
Config:TsrConfig;
//
FSPI:TSPI;
@ -208,10 +210,6 @@ type
function get_exec0:PsrRegSlot;
function get_exec1:PsrRegSlot;
function get_scc :PsrRegSlot;
//
function fetch_vccz :TsrRegNode;
function fetch_execz:TsrRegNode;
function fetch_scc :TsrRegNode;
end;
implementation
@ -503,7 +501,7 @@ function TEmitInterface.NewSpirvOp(OpId:DWORD):TSpirvOp;
begin
Result:=specialize New<TSpirvOp>;
Result.Init(OpId);
Result.adr:=Cursor.Adr;
//Result.adr:=Cursor.Adr;
end;
function TEmitInterface.NewLabelOp(sdep:Boolean):TSpirvOp;
@ -558,7 +556,7 @@ begin
node:=AddSpirvOp(node,Op.OpNop);
node.AddParam(dst);
node.mark_not_used;
node.mark([soNotUsed,soPost]);
Exit(node);
end;
@ -803,26 +801,6 @@ end;
//
function TEmitInterface.fetch_vccz:TsrRegNode;
begin
//It means that lane_id=0
Result:=MakeRead(get_vcc0,dtBool); //implict cast (int != 0)
end;
function TEmitInterface.fetch_execz:TsrRegNode;
begin
//It means that lane_id=0
Result:=MakeRead(get_exec0,dtBool); //implict cast (int != 0)
end;
function TEmitInterface.fetch_scc:TsrRegNode;
begin
Result:=MakeRead(get_scc,dtBool);
end;
//
end.

View File

@ -926,7 +926,7 @@ var
Writer:TseWriter;
pHeap :PsrCodeHeap;
desc :TsrDescriptor;
block :TsrCodeBlock;
pCode :TsrCodeRegion;
imm :TsrDataImm;
PV :PVSharpResource4;
PS :PTSharpResource4;
@ -1020,11 +1020,11 @@ begin
rtFunPtr2:
begin
//func
block:=pHeap^.FindByPtr(Writer.node.GetData);
Assert(block<>nil);
pCode:=pHeap^.FindByPtr(Writer.node.GetData);
Assert(pCode<>nil);
//
Writer.HexOpt('LEN',block.Size);
Writer.ImmOpt('IMM',block.DMem,block.Size);
Writer.HexOpt('LEN',pCode.Size);
Writer.ImmOpt('IMM',pCode.DMem,pCode.Size);
end;
else;
end;
@ -1215,7 +1215,7 @@ begin
if (dst<>nil) then
begin
old:=dst.dtype;
if (old<>dtUnknow) and (not CompareType(rtype,old)) then
if (old<>dtUnknow) and (rtype<>old) then
begin
//OpLoad -> new -> dst
dst:=pBitcastList^.FetchDstr(rtype,dst);

View File

@ -15,6 +15,7 @@ type
pLeft,pRight:TDependenceNode;
//
key:TsrNode;
//
fread_count :DWORD;
fwrite_count:DWORD;
//

View File

@ -10,7 +10,6 @@ uses
srOpInternal,
ginodes,
srNode,
srCFGLabel,
srCFGParser,
srCFGCursor,
srLiteral,
@ -58,7 +57,7 @@ type
TsrOpList=specialize TNodeListClass<TsrOpCustom>;
TsoFlags=(soClear,soNotUsed,soForce);
TsoFlags=(soClear,soNotUsed,soForce,soPost);
TsoSetFlags=Set of TsoFlags;
TspirvOp=class(TsrOpCustom)
@ -71,7 +70,7 @@ type
Procedure SetDst(r:TsrNode);
Procedure UnClear;
public
Adr :TSrcAdr;
//Adr :TSrcAdr;
OpId:DWORD;
//
Procedure _zero_read; override;
@ -95,8 +94,9 @@ type
procedure AddString(const name:RawByteString);
function is_cleared:Boolean;
function is_force:Boolean;
function is_post:Boolean;
function Clear:Boolean;
procedure mark_not_used(Force:Boolean=False);
procedure mark(f:TsoSetFlags);
function can_clear:Boolean;
end;
@ -104,11 +104,6 @@ type
TsrVolMark=(vmNone,vmEndpg,vmBreak,vmConti,vmMixed);
TsrBlockInfo=packed record
b_adr,e_adr:TSrcAdr;
bType:TsrBlockType;
end;
TsrOpBlockCustom=class(TsrOpCustom)
private
FList :TsrOpList;
@ -138,7 +133,7 @@ type
TsrOpBlock=packed class(TsrOpBlockCustom)
public
Block:TsrBlockInfo;
bType:TsrBlockType;
Labels:record
pBegOp:TspirvOp;
@ -153,7 +148,6 @@ type
vctx :TsrVolatileContext;
FLBlock:TsrCFGBlock;
FCursor:TsrCursor;
Regs:record
@ -166,6 +160,7 @@ type
pReg :TsrRegNode;
FNormalOrder:Boolean;
FUseCont :Boolean;
FExcMerg :Boolean;
end;
FVolMark:TsrVolMark;
@ -173,12 +168,9 @@ type
dummy:TspirvOp;
procedure Init;
procedure SetCFGBlock(pLBlock:TsrCFGBlock);
procedure SetInfo(const b:TsrBlockInfo);
procedure SetInfo(bType:TsrBlockType;b_adr,e_adr:TSrcAdr);
procedure SetInfo(_bType:TsrBlockType);
procedure SetLabels(pBegOp,pEndOp,pMrgOp:TspirvOp);
procedure SetCond(pReg:TsrRegNode;FNormalOrder:Boolean);
function IsEndOf(Adr:TSrcAdr):Boolean;
function FindUpLoop:TsrOpBlock;
function FindUpCond:TsrOpBlock;
function FindUpCondByReg(pReg:TsrRegNode;rDown:Boolean;var Invert:Boolean):TsrOpBlock;
@ -568,12 +560,18 @@ begin
Result:=(soForce in flags);
end;
function TspirvOp.is_post:Boolean;
begin
Result:=(soPost in flags);
end;
function TspirvOp.Clear:Boolean;
var
node:POpParamNode;
b:Byte;
begin
Result:=False;
if not can_clear then Exit;
if (read_count<>0) then
@ -650,13 +648,9 @@ begin
flags:=flags-[soClear];
end;
procedure TspirvOp.mark_not_used(Force:Boolean=False);
procedure TspirvOp.mark(f:TsoSetFlags);
begin
flags:=flags+[soNotUsed];
if Force then
begin
flags:=flags+[soForce];
end;
flags:=flags+f;
end;
function TspirvOp.can_clear:Boolean;
@ -680,28 +674,9 @@ begin
vctx.block:=Self;
end;
procedure TsrOpBlock.SetCFGBlock(pLBlock:TsrCFGBlock);
procedure TsrOpBlock.SetInfo(_bType:TsrBlockType);
begin
dummy.Adr :=pLBlock.pBLabel.Adr;
Block.b_adr:=pLBlock.pBLabel.Adr;
Block.e_adr:=pLBlock.pELabel.Adr;
Block.bType:=pLBlock.bType;
end;
procedure TsrOpBlock.SetInfo(const b:TsrBlockInfo);
begin
dummy.Adr :=b.b_adr;
Block.b_adr:=b.b_adr;
Block.e_adr:=b.e_adr;
Block.bType:=b.bType;
end;
procedure TsrOpBlock.SetInfo(bType:TsrBlockType;b_adr,e_adr:TSrcAdr);
begin
dummy.Adr :=b_adr;
Block.b_adr:=b_adr;
Block.e_adr:=e_adr;
Block.bType:=bType;
bType:=_bType;
end;
procedure TsrOpBlock.SetLabels(pBegOp,pEndOp,pMrgOp:TspirvOp);
@ -717,11 +692,6 @@ begin
Cond.FNormalOrder:=FNormalOrder;
end;
function TsrOpBlock.IsEndOf(Adr:TSrcAdr):Boolean;
begin
Result:=(Block.e_adr.get_code_ptr<=Adr.get_code_ptr);
end;
function TsrOpBlock.FindUpLoop:TsrOpBlock;
var
node:TsrOpBlock;
@ -730,7 +700,7 @@ begin
node:=Self;
While (node<>nil) do
begin
if (node.Block.bType=btLoop) then Exit(node);
if (node.bType=btLoop) then Exit(node);
node:=node.pParent;
end;
end;
@ -743,7 +713,7 @@ begin
node:=Self;
While (node<>nil) do
begin
if (node.Block.bType=btCond) then Exit(node);
if (node.bType=btCond) then Exit(node);
node:=node.pParent;
end;
end;
@ -763,7 +733,7 @@ begin
node:=Self;
While (node<>nil) do
begin
if (node.Block.bType=btCond) then
if (node.bType=btCond) then
begin
//
pCond:=node.Cond.pReg;
@ -777,7 +747,7 @@ begin
Exit(node);
end;
end else
if (node.Block.bType=btElse) then
if (node.bType=btElse) then
begin
Assert(node.pIf<>nil);
node:=node.pIf;

View File

@ -11,7 +11,7 @@ uses
srReg,
srLayout,
srVariable,
srCFGLabel;
srCFGParser;
function InsSpirvOp(pLine,pNew:TSpirvOp):TSpirvOp;
Function get_inverse_left_cmp_op(OpId:DWORD):DWORD;
@ -79,7 +79,7 @@ function flow_prev_up(pLine:TSpirvOp):TSpirvOp;
Result:=nil;
if (p<>nil) then
if p.IsType(ntOpBlock) then
if not IsReal(TsrOpBlock(p).Block.bType) then
if not IsReal(TsrOpBlock(p).bType) then
begin
Result:=p.Last;
end;
@ -114,7 +114,7 @@ begin
tmp:=flow_down_prev_up(tmp);
Assert(tmp<>nil);
end;
pNew.Adr:=tmp.Adr;
//pNew.Adr:=tmp.Adr;
end;
pLine.InsertAfter(pNew);
@ -529,31 +529,101 @@ begin
end;
end;
function GetChainRegNode(node:TsrRegNode):TsrChain;
type
a_volatile_node=array of TsrRegNode;
procedure add_node(var A:a_volatile_node;node:TsrRegNode);
var
i:Integer;
begin
//check exist
if Length(A)<>0 then
For i:=0 to High(A) do
begin
if (A[i]=node) then Exit;
end;
//
Insert([node],A,High(A));
end;
procedure add_volatile(var A:a_volatile_node;V:TsrVolatile);
var
node:TStoreNode;
begin
node:=V.FList.pHead;
while (node<>nil) do
begin
add_node(A,RegDown(node.src));
//
node:=node.pNext;
end;
end;
function next_volatile(var A:a_volatile_node;var i:Integer):TsrRegNode;
begin
if (i<Length(A)) then
begin
Result:=A[i];
Inc(i);
end else
begin
Result:=nil;
end;
end;
type
AsrChain=array of TsrChain;
function GetChainRegNode2(node:TsrRegNode):AsrChain;
var
pOp:TSpirvOp;
V:TsrVolatile;
C:TsrChain;
A:a_volatile_node;
i:Integer;
begin
Result:=nil;
Result:=[];
A:=[];
i:=0;
repeat
while (node<>nil) do
begin
node:=RegDown(node);
if node.pWriter.IsType(TsrVolatile) then
begin
V:=node.pWriter.specialize AsType<TsrVolatile>;
node:=V.FList.pTail.src;
end else
begin
Break;
add_volatile(A,V);
node:=next_volatile(A,i);
end;
until false;
pOp:=node.pWriter.specialize AsType<ntOp>;
if (pOp=nil) then Exit;
pOp:=node.pWriter.specialize AsType<ntOp>;
if (pOp<>nil) then
if (pOp.OpId=Op.OpLoad) then
begin
C:=pOp.ParamNode(0).Value.specialize AsType<ntChain>;
if (pOp.OpId<>Op.OpLoad) then Exit;
Result:=pOp.ParamNode(0).Value.specialize AsType<ntChain>;
if (C<>nil) then
begin
Insert([C],Result,High(Result));
end;
end;
node:=next_volatile(A,i);
end;
end;
function GetChainRegNode(node:TsrRegNode):TsrChain;
Var
A:AsrChain;
begin
A:=GetChainRegNode2(node);
if (Length(A)=0) then Exit(nil);
if (Length(A)>1) then
begin
Assert(false,'Multiple reachable chains are not supported!');
end;
Result:=A[0];
end;
function GetSourceRegNode(node:TsrRegNode):TsrNode;

View File

@ -18,7 +18,7 @@ uses
srVariable,
srConst,
srBitcast,
srCFGLabel;
srCFGParser;
type
TsrPrivate=class;
@ -27,7 +27,7 @@ type
pPrev,pNext:TStoreNode;
//
src :TsrRegNode;
line:TspirvOp;
//line:TspirvOp;
//
end;
TStoreNodeList=specialize TNodeListClass<TStoreNode>;
@ -40,11 +40,13 @@ type
FList :TStoreNodeList;
FBase :TsrRegNode;
FZeroRead:Boolean;
ForceBool:Boolean;
//
Procedure _zero_read; override;
Procedure _zero_unread; override;
Procedure _PrepType(node:PPrepTypeNode); override;
//
function ListCount:Integer;
Procedure AddStore(src:TsrRegNode);
Procedure PushStore(node:TStoreNode);
Function PopStore:TStoreNode;
@ -176,11 +178,29 @@ begin
node:=FList.pHead;
While (node<>nil) do
begin
if node.src.pWriter.IsType(TsrVolatile) then Break;
node.src.PrepType(ord(new));
node:=node.pNext;
end;
end;
function TsrVolatile.ListCount:Integer;
var
node:TStoreNode;
begin
Result:=0;
//
node:=FList.pHead;
While (node<>nil) do
begin
Inc(Result);
//
node:=node.pNext;
end;
end;
Procedure TsrVolatile.AddStore(src:TsrRegNode);
var
node:TStoreNode;
@ -198,7 +218,7 @@ begin
Assert(pLine<>nil);
node:=Emit.specialize New<TStoreNode>; //cache in free list?
node.src :=src;
node.line:=pLine;
//node.line:=pLine;
if FZeroRead then
begin
src.mark_read(Self);
@ -209,8 +229,8 @@ end;
Procedure TsrVolatile.PushStore(node:TStoreNode);
begin
if (node=nil) then Exit;
Assert(node.src.pLine<>nil);
Assert(node.line<>nil);
//Assert(node.src.pLine<>nil);
//Assert(node.line<>nil);
if FZeroRead then
begin
node.src.mark_read(Self);
@ -343,7 +363,7 @@ begin
if (dst<>nil) then
begin
old:=dst.dtype;
if (old<>dtUnknow) and (not CompareType(rtype,old)) then
if (old<>dtUnknow) and (rtype<>old) then
begin
//OpLoad -> new -> dst
dst:=pBitcastList^.FetchDstr(rtype,dst);
@ -406,6 +426,8 @@ begin
end;
end;
{
procedure _update_store_line(pLine:TspirvOp);
var
pReg:TsrRegNode;
@ -422,13 +444,22 @@ begin
pCur.InsertAfter(pLine);
end;
end;
}
Procedure TsrPrivate.SortLines;
var
dnode,dnext:TDependenceNode;
pLine:array[0..1] of TspirvOp;
//pLine:array[0..1] of TspirvOp;
nswp:Boolean;
begin
//indexing
dnode:=FLineList.pHead;
While (dnode<>nil) do
begin
dnode.fread_count:=GetGlobalIndex(dnode.pNode);
dnode:=dnode.pNext;
end;
//bubble sort
repeat
nswp:=True;
dnode:=FLineList.pHead;
@ -437,13 +468,14 @@ begin
dnext:=dnode.pNext;
if (dnext=nil) then Break;
pLine[0]:=dnode.pNode;
pLine[1]:=dnext.pNode;
//pLine[0]:=dnode.pNode;
//pLine[1]:=dnext.pNode;
_update_store_line(pLine[0]);
_update_store_line(pLine[1]);
//_update_store_line(pLine[0]);
//_update_store_line(pLine[1]);
if (MaxLine(pLine[0],pLine[1])=pLine[0]) then //dnode>dnext
//if (MaxLine(pLine[0],pLine[1])=pLine[0]) then //dnode>dnext
if (dnode.fread_count>dnext.fread_count) then
begin
//swap
nswp:=False;
@ -466,7 +498,7 @@ begin
if (node=prev) then Exit(True);
//
if node.IsType(ntOpBlock) then
if IsReal(TsrOpBlock(node).Block.bType) then
if IsReal(TsrOpBlock(node).bType) then
begin
Exit(False);
end;
@ -501,7 +533,7 @@ begin
begin
//Remove dprev
FLineList.Remove(dprev);
pLine[1].mark_not_used;
pLine[1].mark([soNotUsed]);
Continue;
end else
if (pLine[0].OpId=Op.OpStore) and (pLine[1].OpId=Op.OpLoad) then
@ -516,7 +548,7 @@ begin
begin
//Remove dnode
FLineList.Remove(dnode);
pLine[0].mark_not_used;
pLine[0].mark([soNotUsed]);
dnode:=dprev;
if (dnode.pNext<>nil) then
@ -745,7 +777,7 @@ begin
pLine:=ctx.after;
//replace next
_next:=pSlot^.New(rtype,pLine);
_next:=pSlot^._New(rtype,pLine); //<-The slot value will not be updated
_next.pWriter:=pVolatile;
ctx.AddVolatile(pVolatile,_next);
@ -827,7 +859,7 @@ begin
pLine:=ctx.after;
//replace next
_next:=pSlot^.New(rtype,pLine);
_next:=pSlot^._New(rtype,pLine); //<-The slot value will not be updated
_next.pWriter:=pVolatile;
ctx.AddVolatile(pVolatile,_next);
@ -916,6 +948,24 @@ begin
rtype:=dtUnknow;
if (prv<>nil) then
begin
if new_vol then
begin
Assert(prv.pWriter=orig,'123');
//need to use orig to create a loopback dependency
prv:=orig;
//save if new created
pVolatile.AddStore(prv);
end;
rtype:=LazyType2(rtype,prv.dtype);
end;
{
if new_vol then
begin
//use orig
@ -933,6 +983,7 @@ begin
rtype:=LazyType2(rtype,prv.dtype);
end;
end;
}
//
if (cur<>nil) then
begin
@ -949,7 +1000,7 @@ begin
if (prev=nil) then
begin
//The input register is not defined, should it be initialized to make_copy_slot?
prev:=pSlot^.New(rtype,pLine);
prev:=pSlot^._New(rtype,pLine); //<-The slot value will not be updated
end;
//set backedge dependence
@ -1075,6 +1126,56 @@ begin
end;
end;
function calc_most_used_type(V:TsrVolatile):TsrDataType;
type
t_table=array[TsrDataType] of Integer;
var
node :TStoreNode;
Table:t_table;
Count:Integer;
i,max:TsrDataType;
begin
if V.ForceBool then
begin
Exit(dtBool);
end;
//
Table:=Default(t_table);
Count:=0;
//
node:=V.FList.pHead;
While (node<>nil) do
begin
Inc(Table[RegDown(node.src).dtype]);
Inc(Count);
//
node:=node.pNext;
end;
//
if (Count=0) then
begin
Result:=dtUnknow;
end else
if (Count=Table[dtBool]) then
begin
//Result:=dtBool;
Result:=dtUint32;
end else
begin
max:=dtUnknow;
For i:=Low(TsrDataType) to High(TsrDataType) do
if (i<>dtBool) then
begin
if ((max=dtUnknow) and (Table[i]<>0)) or
(Table[i]>Table[max]) then
begin
max:=i;
end;
end;
Result:=max;
end;
end;
function TsrPrivateList.PrepVolatile(dst:TspirvOp;src:TsrRegNode):TsrRegNode; //use forward only
var
tmp:TsrRegNode;
@ -1084,6 +1185,7 @@ var
pLine:TspirvOp;
//pTmp:TspirvOp;
//vtmp:TsrVolatile;
dtype:TsrDataType;
begin
Result:=src;
if (src=nil) then Exit;
@ -1098,18 +1200,42 @@ begin
pVolatile:=src.pWriter.specialize AsType<ntVolatile>;
pPrivate:=pVolatile.FPrivate;
if pVolatile.FSlot^.iUnattach then
begin
pPrivate:=pVolatile.FPrivate;
end else
begin
pPrivate:=TsrPrivate(pVolatile.FSlot^.FPrivate);
end;
if (pPrivate=nil) then
begin
pPrivate:=Fetch(pVolatile.FSlot);
pVolatile.FPrivate:=pPrivate;
if pVolatile.FSlot^.iUnattach then
begin
pVolatile.FPrivate:=pPrivate;
end else
begin
pVolatile.FSlot^.FPrivate:=pPrivate;
end;
end;
dtype:=calc_most_used_type(pVolatile);
dtype:=lazyType2(dtype,StoreType(src.dtype));
dtype:=lazyType2(dtype,dtFloat32);
if (dtype=dtBool) and (pVolatile.FSlot^.Name='S0') then
begin
calc_most_used_type(pVolatile);
end;
pPrivate.InitVar();
pPrivate .PrepType(src.dtype);
pVolatile.PrepType(pPrivate.GetRegType);
pPrivate .PrepType(dtype);
pVolatile.PrepType(dtype);
if (pPrivate.GetRegType=dtUnknow) then
begin
@ -1126,7 +1252,8 @@ begin
begin
//pLine:=TsrRegNode(node.pNode).pLine;
pLine:=node.line;
//pLine:=node.line;
pLine:=node.src.pLine;
Assert(pLine<>nil);
up_merge_line(pLine);
@ -1156,7 +1283,7 @@ begin
//ntVolatile -> src -> next
//Opload -> new
Result:=src.pSlot^.New(src.dtype,dst);
Result:=src.pSlot^._New(src.dtype,dst); //<-The slot value will not be updated
pPrivate.FetchLoad(dst,Result); //before reg
end;

View File

@ -124,6 +124,7 @@ type
FBits :TsrBitKey;
procedure set_current(c:TsrRegNode);
public
FPrivate:TsrNode;
property Emit :TCustomEmit read FEmit;
property current :TsrRegNode read FCurrent write set_current;
property Name :TString7 read FName;
@ -137,6 +138,7 @@ type
function isBoolOnly:Boolean;
function isScalar:Boolean;
function iUnattach:Boolean;
function _New(rtype:TsrDataType;pLine:TsrRegNode):TsrRegNode;
function New(rtype:TsrDataType;pLine:TsrRegNode=nil):TsrRegNode;
end;
@ -1046,7 +1048,7 @@ begin
Result:=(FBits.Category=cUnattach);
end;
function TsrRegSlot.New(rtype:TsrDataType;pLine:TsrRegNode=nil):TsrRegNode;
function TsrRegSlot._New(rtype:TsrDataType;pLine:TsrRegNode):TsrRegNode;
var
node:TsrRegNode;
begin
@ -1059,8 +1061,13 @@ begin
node.dtype:=rtype;
node.CustomLine:=pLine;
Result:=node;
end;
function TsrRegSlot.New(rtype:TsrDataType;pLine:TsrRegNode=nil):TsrRegNode;
begin
Result:=_New(rtype,pLine);
//update
current:=node;
current:=Result;
end;
//

View File

@ -166,16 +166,17 @@ begin
yxEqual:=SprvEmit.OpAndTo(CoordEqualY[i], CoordEqualX[(i + 2) mod 3]);
//
EdgeVertex[i]:=SprvEmit.OpOrTo(xyEqual,yxEqual);
//
barycentric[i]:=SprvEmit.OpSelectTo(pOneId,pMinusOne,EdgeVertex[i]);
//cond,src_true,src_false
barycentric[i]:=SprvEmit.OpSelectTo(EdgeVertex[i],pMinusOne,pOneId);
end;
//calc last pos
Positions[3]:=interpolate(SprvEmit,dtVec4f,@barycentric,@Positions);
//select first index
pIndex:=SprvEmit.OpSelectTo(UintId[0], UintId[1], EdgeVertex[1]);
pIndex:=SprvEmit.OpSelectTo(pIndex , UintId[2], EdgeVertex[2]);
//cond,src_true,src_false
pIndex:=SprvEmit.OpSelectTo(EdgeVertex[1], UintId[1], UintId[0]);
pIndex:=SprvEmit.OpSelectTo(EdgeVertex[2], UintId[2], pIndex );
//Send vertex by index
For i:=0 to 2 do