diff --git a/spirv/emit_mimg.pas b/spirv/emit_mimg.pas index a84e819d..8853ec52 100644 --- a/spirv/emit_mimg.pas +++ b/spirv/emit_mimg.pas @@ -42,7 +42,8 @@ type procedure emit_image_sample_gather(Tgrp:PsrNode;info:PsrImageInfo); procedure emit_image_load(Tgrp:PsrNode;info:PsrImageInfo); procedure emit_image_store(Tgrp:PsrNode;info:PsrImageInfo); - procedure emit_get_resinfo(Tgrp:PsrNode;info:PsrImageInfo); + procedure emit_image_get_resinfo(Tgrp:PsrNode;info:PsrImageInfo); + procedure emit_image_get_lod(Tgrp:PsrNode;info:PsrImageInfo); end; implementation @@ -1006,7 +1007,7 @@ begin end; -procedure TEmit_MIMG.emit_get_resinfo(Tgrp:PsrNode;info:PsrImageInfo); +procedure TEmit_MIMG.emit_image_get_resinfo(Tgrp:PsrNode;info:PsrImageInfo); var offset:DWORD; dst,lod:PsrRegNode; @@ -1037,6 +1038,51 @@ begin AddCapability(Capability.ImageQuery); end; +procedure TEmit_MIMG.emit_image_get_lod(Tgrp:PsrNode;info:PsrImageInfo); +var + src:array[0..3] of PsrRegSlot; + + pLayout:PsrDataLayout; + Sgrp:PsrNode; + + dst,cmb:PsrRegNode; + + param:TImgSampleParam; + + mask:Byte; +begin + if not get_srsrc(FSPI.MIMG.SSAMP,4,@src) then Assert(false); + + pLayout:=GroupingSharp(src,rtSSharp4); + Sgrp:=FetchSampler(pLayout); + + cmb:=OpSampledImage(line,Tgrp,Sgrp,info^.dtype,info^.tinfo); + + Assert(FSPI.MIMG.DMASK=1,'FSPI.MIMG.DMASK<>1'); + + //gather + param:=Default(TImgSampleParam); + param.coord:=GatherCoord_f(param.roffset,info); + //gather + + dst:=NewReg(param.coord^.dtype); + + _Op2(line,Op.OpImageQueryLod,dst,PsrRegNode(cmb),param.coord); + + case param.coord^.dtype.Count of + 1:mask:=1; + 2:mask:=3; + 3:mask:=7; + 4:mask:=15; + else + mask:=0; + end; + + DistribDmask(mask,dst,info); + + AddCapability(Capability.ImageQuery); +end; + procedure TEmit_MIMG.emit_MIMG; var src:array[0..7] of PsrRegSlot; @@ -1111,7 +1157,15 @@ begin info.tinfo.Sampled:=1; Tgrp:=FetchImage(pLayout,info.dtype,info.tinfo); - emit_GET_RESINFO(Tgrp,@info); + emit_image_get_resinfo(Tgrp,@info); + end; + + IMAGE_GET_LOD: + begin + info.tinfo.Sampled:=1; + Tgrp:=FetchImage(pLayout,info.dtype,info.tinfo); + + emit_image_get_lod(Tgrp,@info); end; else diff --git a/spirv/emit_op.pas b/spirv/emit_op.pas index 3db882a5..9b8b84da 100644 --- a/spirv/emit_op.pas +++ b/spirv/emit_op.pas @@ -74,7 +74,7 @@ type function OpAbsDiff(pLine:PspirvOp;dst,src0,src1:PsrRegNode):PSpirvOp; procedure OpWQM32(dst:PsrRegSlot;src:PsrRegNode); // - procedure OpBFEU32(dst:PsrRegSlot;base,src0,src1:PsrRegNode); + procedure OpBFE_32(dst:PsrRegSlot;base,src0,src1:PsrRegNode); procedure OpBFIB32(dst:PsrRegSlot;bitmsk,src0,src1:PsrRegNode); // function OpBFITo(src0,src1,src2,src3:PsrRegNode;ppLine:PPspirvOp=nil):PsrRegNode; @@ -638,9 +638,9 @@ begin Op1(srOpUtils.OpWQM32,dtUnknow,dst,src); end; -procedure TEmitOp.OpBFEU32(dst:PsrRegSlot;base,src0,src1:PsrRegNode); +procedure TEmitOp.OpBFE_32(dst:PsrRegSlot;base,src0,src1:PsrRegNode); begin - Op3(srOpUtils.OpBFEU32,dtUint32,dst,base,src0,src1); + Op3(srOpUtils.OpBFE_32,base^.dtype,dst,base,src0,src1); end; procedure TEmitOp.OpBFIB32(dst:PsrRegSlot;bitmsk,src0,src1:PsrRegNode); diff --git a/spirv/emit_post.pas b/spirv/emit_post.pas index 23fde86d..1fe68a61 100644 --- a/spirv/emit_post.pas +++ b/spirv/emit_post.pas @@ -63,6 +63,7 @@ type end; function EnumLineRegs(cb:TRegsCb;pLine:PSpirvOp):Integer; +function EnumFirstReg(cb:TRegsCb;pLine:PSpirvOp):Integer; function EnumBlockOpForward(cb:TPostCb;pBlock:PsrOpBlock):Integer; function EnumBlockOpBackward(cb:TPostCb;pBlock:PsrOpBlock):Integer; @@ -101,6 +102,25 @@ begin end; end; +function EnumFirstReg(cb:TRegsCb;pLine:PSpirvOp):Integer; +var + node:POpParamNode; + pReg:PsrRegNode; +begin + Result:=0; + if (cb=nil) or (pLine=nil) then Exit; + node:=pLine^.ParamFirst; + if (node<>nil) then + begin + if node^.Value^.IsType(ntReg) then + begin + pReg:=node^.AsReg; + Result:=Result+cb(pLine,pReg); + node^.Value:=pReg; + end; + end; +end; + function EnumBlockOpForward(cb:TPostCb;pBlock:PsrOpBlock):Integer; var node,prev:PSpirvOp; @@ -429,7 +449,8 @@ begin if not node^.pDst^.IsType(ntReg) then Exit; //is reg Case node^.OpId of - Op.OpBitFieldUExtract , + Op.OpBitFieldSExtract , + Op.OpBitFieldUExtract :Result:=EnumFirstReg(@RegSTStrict,node); Op.OpSelect :Result:=EnumLineRegs(@RegSTStrict,node); Op.OpIAddCarry , Op.OpISubBorrow , diff --git a/spirv/emit_post_op.pas b/spirv/emit_post_op.pas index 7cb6c7df..338edf4c 100644 --- a/spirv/emit_post_op.pas +++ b/spirv/emit_post_op.pas @@ -38,7 +38,7 @@ type function OnWQM32__1(node:PSpirvOp):Integer; function OnPackOfs1(node:PSpirvOp):Integer; function _Fetch_PackAnc(node:PsrRegNode;index,count:Byte):PsrRegNode; - function OnBFEU32_1(node:PSpirvOp):Integer; + function OnBFE_32_1(node:PSpirvOp):Integer; function OnBFIB32_1(node:PSpirvOp):Integer; function OnMakeCub1(node:PSpirvOp):Integer; // @@ -92,7 +92,7 @@ begin srOpUtils.OpAbsDiff :Result:=OnAbsDiff1(node); srOpUtils.OpWQM32 :Result:=OnWQM32__1(node); srOpUtils.OpPackOfs :Result:=OnPackOfs1(node); - srOpUtils.OpBFEU32 :Result:=OnBFEU32_1(node); + srOpUtils.OpBFE_32 :Result:=OnBFE_32_1(node); srOpUtils.OpBFIB32 :Result:=OnBFIB32_1(node); srOpUtils.OpMakeCub :Result:=OnMakeCub1(node); @@ -1889,7 +1889,7 @@ begin end; -function TEmitPostOp.OnBFEU32_1(node:PSpirvOp):Integer; +function TEmitPostOp.OnBFE_32_1(node:PSpirvOp):Integer; var dst:PsrRegNode; rBase,rIndex,rCount:PsrRegNode; @@ -1897,6 +1897,7 @@ var num_31:PsrRegNode; data:array[0..1] of QWORD; index,count:Byte; + dtype:TsrDataType; begin Result:=0; dst:=node^.pDst^.AsType(ntReg); @@ -1908,6 +1909,8 @@ begin if (rBase=nil) or (rIndex=nil) or (rCount=nil) then Exit; + dtype:=rBase^.dtype; + //else node^.mark_not_used; node^.pDst:=nil; @@ -1942,7 +1945,7 @@ begin num_31:=NewReg_q(dtUInt32,data[1],@Node); // rsl:=OpAndTo(rsl,num_31,@node); - rsl^.PrepType(ord(dtUInt32)); + rsl^.PrepType(ord(dtype)); end; dst^.pWriter:=rsl; @@ -2002,7 +2005,13 @@ begin rCount^.PrepType(ord(dtUInt32)); end; - _Op3(node,Op.OpBitFieldUExtract,dst,rBase,rIndex,rCount); + case dtype of + dtUint32:_Op3(node,Op.OpBitFieldUExtract,dst,rBase,rIndex,rCount); + dtInt32 :_Op3(node,Op.OpBitFieldSExtract,dst,rBase,rIndex,rCount); + else + Assert(False); + end; + end; function TEmitPostOp.OnBFIB32_1(node:PSpirvOp):Integer; diff --git a/spirv/emit_vop1.pas b/spirv/emit_vop1.pas index 0d14da18..82d9dbc5 100644 --- a/spirv/emit_vop1.pas +++ b/spirv/emit_vop1.pas @@ -24,6 +24,9 @@ type procedure emit_V_CVT_FLR_I32_F32; procedure emit_V_CVT_RPI_I32_F32; procedure emit_V_CVT_F32_UBYTE0; + procedure emit_V_CVT_F32_UBYTE1; + procedure emit_V_CVT_F32_UBYTE2; + procedure emit_V_CVT_F32_UBYTE3; procedure emit_V_EXT_F32(OpId:DWORD); procedure emit_V_RSQ_CLAMP_F32; procedure emit_V_SIN_COS(OpId:DWORD); @@ -152,6 +155,51 @@ begin Op1(Op.OpConvertUToF,dtFloat32,dst,src); end; +procedure TEmit_VOP1.emit_V_CVT_F32_UBYTE1; +Var + dst:PsrRegSlot; + src:PsrRegNode; +begin + dst:=get_vdst8(FSPI.VOP1.VDST); + src:=fetch_ssrc9(FSPI.VOP1.SRC0,dtUInt32); + + src:=OpShrTo(src,8); + src:=OpAndTo(src,$FF); + src^.PrepType(ord(dtUInt32)); + + Op1(Op.OpConvertUToF,dtFloat32,dst,src); +end; + +procedure TEmit_VOP1.emit_V_CVT_F32_UBYTE2; +Var + dst:PsrRegSlot; + src:PsrRegNode; +begin + dst:=get_vdst8(FSPI.VOP1.VDST); + src:=fetch_ssrc9(FSPI.VOP1.SRC0,dtUInt32); + + src:=OpShrTo(src,16); + src:=OpAndTo(src,$FF); + src^.PrepType(ord(dtUInt32)); + + Op1(Op.OpConvertUToF,dtFloat32,dst,src); +end; + +procedure TEmit_VOP1.emit_V_CVT_F32_UBYTE3; +Var + dst:PsrRegSlot; + src:PsrRegNode; +begin + dst:=get_vdst8(FSPI.VOP1.VDST); + src:=fetch_ssrc9(FSPI.VOP1.SRC0,dtUInt32); + + src:=OpShrTo(src,24); + src:=OpAndTo(src,$FF); + src^.PrepType(ord(dtUInt32)); + + Op1(Op.OpConvertUToF,dtFloat32,dst,src); +end; + procedure TEmit_VOP1.emit_V_EXT_F32(OpId:DWORD); Var dst:PsrRegSlot; @@ -254,7 +302,9 @@ begin V_CVT_RPI_I32_F32: emit_V_CVT_RPI_I32_F32; V_CVT_F32_UBYTE0: emit_V_CVT_F32_UBYTE0; - + V_CVT_F32_UBYTE1: emit_V_CVT_F32_UBYTE1; + V_CVT_F32_UBYTE2: emit_V_CVT_F32_UBYTE2; + V_CVT_F32_UBYTE3: emit_V_CVT_F32_UBYTE3; V_FRACT_F32: emit_V_EXT_F32(GlslOp.Fract); V_TRUNC_F32: emit_V_EXT_F32(GlslOp.Trunc); diff --git a/spirv/emit_vop3.pas b/spirv/emit_vop3.pas index fdcf54b5..cdcfbdf6 100644 --- a/spirv/emit_vop3.pas +++ b/spirv/emit_vop3.pas @@ -47,6 +47,7 @@ type procedure emit_V_MBCNT_HI_U32_B32; procedure emit_V_BFE_U32; + procedure emit_V_BFE_I32; procedure emit_V_BFI_B32; procedure emit_V_MAD_F32; procedure emit_V_MAD_LEGACY_F32; @@ -555,7 +556,26 @@ begin src[1]:=fetch_ssrc9(FSPI.VOP3a.SRC1,dtUint32); src[2]:=fetch_ssrc9(FSPI.VOP3a.SRC2,dtUint32); - OpBFEU32(dst,src[0],src[1],src[2]); + OpBFE_32(dst,src[0],src[1],src[2]); +end; + +procedure TEmit_VOP3.emit_V_BFE_I32; +Var + dst:PsrRegSlot; + src:array[0..2] of PsrRegNode; +begin + dst:=get_vdst8(FSPI.VOP3a.VDST); + + Assert(FSPI.VOP3a.OMOD =0,'FSPI.VOP3a.OMOD'); + Assert(FSPI.VOP3a.ABS =0,'FSPI.VOP3a.ABS'); + Assert(FSPI.VOP3a.CLAMP=0,'FSPI.VOP3a.CLAMP'); + Assert(FSPI.VOP3a.NEG =0,'FSPI.VOP3a.NEG'); + + src[0]:=fetch_ssrc9(FSPI.VOP3a.SRC0,dtInt32); + src[1]:=fetch_ssrc9(FSPI.VOP3a.SRC1,dtUint32); + src[2]:=fetch_ssrc9(FSPI.VOP3a.SRC2,dtUint32); + + OpBFE_32(dst,src[0],src[1],src[2]); end; procedure TEmit_VOP3.emit_V_BFI_B32; @@ -1235,7 +1255,9 @@ begin V_MUL_HI_I32: emit_V_MUL_HI(dtInt32); V_BFE_U32: emit_V_BFE_U32; + V_BFE_I32: emit_V_BFE_I32; V_BFI_B32: emit_V_BFI_B32; + V_MAD_F32: emit_V_MAD_F32; V_MAD_LEGACY_F32: emit_V_MAD_LEGACY_F32; diff --git a/spirv/srOpUtils.pas b/spirv/srOpUtils.pas index 043d4b54..e17aa862 100644 --- a/spirv/srOpUtils.pas +++ b/spirv/srOpUtils.pas @@ -19,7 +19,7 @@ const OpAbsDiff=DWORD(-3); OpWQM32 =DWORD(-4); - OpBFEU32 =DWORD(-5); + OpBFE_32 =DWORD(-5); OpBFIB32 =DWORD(-6); OpPackAnc=DWORD(-7);