diff --git a/spirv/emit_fetch.pas b/spirv/emit_fetch.pas index 78c1db9b..5b156afb 100644 --- a/spirv/emit_fetch.pas +++ b/spirv/emit_fetch.pas @@ -29,8 +29,9 @@ uses type TEmitFetch=class(TEmitFlow) // - function GroupingVImm(regs:PPsrRegNode;rtype:TsrResourceType):TsrDataLayout; - function GroupingSharp(src:PPsrRegSlot;rtype:TsrResourceType):TsrDataLayout; + function GroupingVImm (regs:PPsrRegNode;rtype:TsrResourceType):TsrDataLayout; + function TryShortVSharp(regs:PPsrRegNode;rtype:TsrResourceType):TsrDataLayout; + function GroupingSharp (src :PPsrRegSlot;rtype:TsrResourceType):TsrDataLayout; // function get_sdst7(SDST:Byte):PsrRegSlot; function get_sdst7_pair(SDST:Byte;dst:PPsrRegSlot):Boolean; @@ -288,6 +289,43 @@ begin Result:=True; end; +function TEmitFetch.TryShortVSharp(regs:PPsrRegNode;rtype:TsrResourceType):TsrDataLayout; +var + chain:TsrChains; + reg:TsrRegNode; + pImm:TsrConst; + V2,V3:DWORD; +begin + Result:=nil; + if (rtype<>rtVSharp4) then Exit; + + reg:=RegDown(regs[2]); + + pImm:=reg.AsConst; + if (pImm=nil) then Exit; + + V2:=pImm.AsUint32; + + reg:=RegDown(regs[3]); + + pImm:=reg.AsConst; + if (pImm=nil) then Exit; + + V3:=pImm.AsUint32; + + chain:=Default(TsrChains); + chain[0]:=GetChainRegNode(regs[0]); + chain[1]:=GetChainRegNode(regs[1]); + + Result:=DataLayoutList.Grouping(chain,rtVSharp2); + + if (Result<>nil) then + begin + Result.FData[2]:=V2; + Result.FData[3]:=V3; + end; +end; + function TEmitFetch.GroupingSharp(src:PPsrRegSlot;rtype:TsrResourceType):TsrDataLayout; type TsrRegs=array[0..7] of TsrRegNode; @@ -309,6 +347,9 @@ begin Result:=GroupingVImm(@regs,rtype); if (Result<>nil) then Exit; + Result:=TryShortVSharp(@regs,rtype); + if (Result<>nil) then Exit; + //TODO: mark "disable_aniso" TryDisableAnisoLod0(@regs,rtype); diff --git a/spirv/emit_mimg.pas b/spirv/emit_mimg.pas index d9247b3d..dfa107ea 100644 --- a/spirv/emit_mimg.pas +++ b/spirv/emit_mimg.pas @@ -19,7 +19,7 @@ uses emit_fetch; type - TsrImageMods=Set Of (imMinLod,imGrad,imLod,imBiasLod,imZeroLod,imDref,imOffset); + TsrImageMods=Set Of (imMinLod,imGrad,imLod,imBiasLod,imZeroLod,imDref,imOffset,imGather); TImgSampleParam=object roffset:DWORD; @@ -29,9 +29,18 @@ type coord,pcf,bias,lod,min_lod,offset:TsrRegNode; end; + TExtDistrib=record + dst :TsrRegNode; + dtype:TsrDataType; + id :Integer; + end; + + AExtDistrib=array[0..3] of TExtDistrib; + TEmit_MIMG=class(TEmitFetch) procedure emit_MIMG; procedure DistribDmask (DMASK:Byte;dst:TsrRegNode;info:PsrImageInfo); + procedure DistribDmaskExt (DMASK:Byte;const ext:AExtDistrib;info:PsrImageInfo); function GatherDmask (info:PsrImageInfo;relax:Boolean):TsrRegNode; Function GatherCoord_f (var offset:DWORD;info:PsrImageInfo):TsrRegNode; Function GatherCoord_u (var offset:DWORD;info:PsrImageInfo):TsrRegNode; @@ -503,29 +512,29 @@ begin IMAGE_SAMPLE_C_B_CL_O :Result:=[imDref,imBiasLod,imMinLod,imOffset]; IMAGE_SAMPLE_C_LZ_O :Result:=[imDref,imZeroLod,imOffset]; // - IMAGE_GATHER4_CL :Result:=[imMinLod]; - IMAGE_GATHER4_L :Result:=[imLod]; - IMAGE_GATHER4_B :Result:=[imBiasLod]; - IMAGE_GATHER4_B_CL :Result:=[imBiasLod,imMinLod]; - IMAGE_GATHER4_LZ :Result:=[imZeroLod]; - IMAGE_GATHER4_C :Result:=[imDref]; - IMAGE_GATHER4_C_CL :Result:=[imDref,imMinLod]; - IMAGE_GATHER4_C_L :Result:=[imDref,imLod]; - IMAGE_GATHER4_C_B :Result:=[imDref,imBiasLod]; - IMAGE_GATHER4_C_B_CL :Result:=[imDref,imBiasLod,imMinLod]; - IMAGE_GATHER4_C_LZ :Result:=[imDref,imMinLod]; - IMAGE_GATHER4_O :Result:=[imOffset]; - IMAGE_GATHER4_CL_O :Result:=[imMinLod,imOffset]; - IMAGE_GATHER4_L_O :Result:=[imLod,imOffset]; - IMAGE_GATHER4_B_O :Result:=[imBiasLod,imOffset]; - IMAGE_GATHER4_B_CL_O :Result:=[imBiasLod,imMinLod,imOffset]; - IMAGE_GATHER4_LZ_O :Result:=[imZeroLod,imOffset]; - IMAGE_GATHER4_C_O :Result:=[imDref,imOffset]; - IMAGE_GATHER4_C_CL_O :Result:=[imDref,imMinLod,imOffset]; - IMAGE_GATHER4_C_L_O :Result:=[imDref,imLod,imOffset]; - IMAGE_GATHER4_C_B_O :Result:=[imDref,imBiasLod,imOffset]; - IMAGE_GATHER4_C_B_CL_O:Result:=[imDref,imBiasLod,imMinLod,imOffset]; - IMAGE_GATHER4_C_LZ_O :Result:=[imDref,imZeroLod,imOffset]; + IMAGE_GATHER4_CL :Result:=[imGather,imMinLod]; + IMAGE_GATHER4_L :Result:=[imGather,imLod]; + IMAGE_GATHER4_B :Result:=[imGather,imBiasLod]; + IMAGE_GATHER4_B_CL :Result:=[imGather,imBiasLod,imMinLod]; + IMAGE_GATHER4_LZ :Result:=[imGather,imZeroLod]; + IMAGE_GATHER4_C :Result:=[imGather,imDref]; + IMAGE_GATHER4_C_CL :Result:=[imGather,imDref,imMinLod]; + IMAGE_GATHER4_C_L :Result:=[imGather,imDref,imLod]; + IMAGE_GATHER4_C_B :Result:=[imGather,imDref,imBiasLod]; + IMAGE_GATHER4_C_B_CL :Result:=[imGather,imDref,imBiasLod,imMinLod]; + IMAGE_GATHER4_C_LZ :Result:=[imGather,imDref,imMinLod]; + IMAGE_GATHER4_O :Result:=[imGather,imOffset]; + IMAGE_GATHER4_CL_O :Result:=[imGather,imMinLod,imOffset]; + IMAGE_GATHER4_L_O :Result:=[imGather,imLod,imOffset]; + IMAGE_GATHER4_B_O :Result:=[imGather,imBiasLod,imOffset]; + IMAGE_GATHER4_B_CL_O :Result:=[imGather,imBiasLod,imMinLod,imOffset]; + IMAGE_GATHER4_LZ_O :Result:=[imGather,imZeroLod,imOffset]; + IMAGE_GATHER4_C_O :Result:=[imGather,imDref,imOffset]; + IMAGE_GATHER4_C_CL_O :Result:=[imGather,imDref,imMinLod,imOffset]; + IMAGE_GATHER4_C_L_O :Result:=[imGather,imDref,imLod,imOffset]; + IMAGE_GATHER4_C_B_O :Result:=[imGather,imDref,imBiasLod,imOffset]; + IMAGE_GATHER4_C_B_CL_O:Result:=[imGather,imDref,imBiasLod,imMinLod,imOffset]; + IMAGE_GATHER4_C_LZ_O :Result:=[imGather,imDref,imZeroLod,imOffset]; // IMAGE_SAMPLE_CD :Result:=[imGrad]; IMAGE_SAMPLE_CD_CL :Result:=[imGrad,imMinLod]; @@ -568,43 +577,70 @@ begin end; procedure TEmit_MIMG.DistribDmask(DMASK:Byte;dst:TsrRegNode;info:PsrImageInfo); //result +var + i:Integer; + ext:AExtDistrib; +begin + ext:=Default(AExtDistrib); + For i:=0 to 3 do + begin + ext[i].dst :=dst; + ext[i].dtype:=dst.dtype.Child; + ext[i].id :=i; + end; + + DistribDmaskExt(DMASK,ext,info); +end; + +procedure TEmit_MIMG.DistribDmaskExt(DMASK:Byte;const ext:AExtDistrib;info:PsrImageInfo); //result var pSlot:PsrRegSlot; - dtype:TsrDataType; i,d,max:Byte; begin - dtype:=dst.dtype.Child; - max :=dst.dtype.Count; d:=0; For i:=0 to 3 do + begin if DMASK.TestBit(i) then begin pSlot:=get_vdst8(FSPI.MIMG.VDATA+d); Inc(d); Assert(pSlot<>nil); - if (dst.dtype.isScalar) then + if (ext[i].dst=nil) then begin + + SetConst_i(pSlot,ext[i].dtype,0); + + end else + if (ext[i].dst.dtype.isScalar) then + begin + if (i=0) then begin - MakeCopy(pSlot,dst); + MakeCopy(pSlot,ext[i].dst); end else begin - SetConst_i(pSlot,dtype,0); + SetConst_i(pSlot,ext[i].dtype,0); end; + end else begin + max:=ext[i].dst.dtype.Count; + if (i ImageOperands.Offset + + if (imGather in p.mods) then + begin + p.img_op:=p.img_op or ImageOperands.Offset; + AddCapability(Capability.ImageGatherExtended); //-> ImageOperands.Offset + end else + begin + p.img_op:=p.img_op or ImageOperands.ConstOffset; + end; + end; if (imBiasLod in p.mods) then @@ -1126,27 +1170,58 @@ var dst,lod:TsrRegNode; dvec:TsrDataType; - count:Byte; + i,count_dim,count_query:Byte; + + ext:AExtDistrib; begin offset:=0; lod:=Gather_value(offset,dtUint32); - count:=1; - Case info^.tinfo.Dim of - Dim.Dim2D:count:=2; - Dim.Cube :count:=2; - Dim.Dim3D:count:=3; - else; - end; - if (info^.tinfo.Arrayed<>0) then Inc(count); + //{width, height, depth, num_mip_levels} - dvec:=TsrDataType(dtUint32).AsVector(count); + if (FSPI.MIMG.DMASK and 8)<>0 then + begin + Assert(false,'TODO: IMAGE_GET_RESINFO->OpImageQueryLevels'); + end; + + Case info^.tinfo.Dim of + Dim.Dim2D:count_dim:=2; + Dim.Cube :count_dim:=2; + Dim.Dim3D:count_dim:=3; + else + count_dim:=1; + end; + + count_query:=count_dim; + if (info^.tinfo.Arrayed<>0) then + begin + Inc(count_query); + end; + + // + + dvec:=TsrDataType(dtUint32).AsVector(count_query); dst:=NewReg(dvec); - _Op2(line,Op.OpImageQuerySizeLod,dst,Tgrp,lod); + //(width [, height] [, depth] [, elements]) + OpImageQuerySizeLod(line,Tgrp,dst,lod); - DistribDmask(FSPI.MIMG.DMASK,dst,info); + //fill + ext:=Default(AExtDistrib); + For i:=0 to 3 do + begin + ext[i].dtype:=dtUint32; + end; + + //fill except arrayed elements + For i:=0 to count_dim-1 do + begin + ext[i].dst:=dst; + ext[i].id :=i; + end; + + DistribDmaskExt(FSPI.MIMG.DMASK,ext,info); end; procedure TEmit_MIMG.emit_image_get_lod(Tgrp:TsrNode;info:PsrImageInfo); @@ -1176,7 +1251,8 @@ begin dst:=NewReg(dtVec2f); - _Op2(line,Op.OpImageQueryLod,dst,cmb,param.coord); + //{mipmap_level, lod} + OpImageQueryLod(line,cmb,dst,param.coord); DistribDmask(FSPI.MIMG.DMASK,dst,info); @@ -1208,7 +1284,7 @@ begin end; end; - info:=GetImageInfo(pLayout.pData); + info:=GetImageInfo(pLayout.GetSharp); info.GLC:=(FSPI.MIMG.GLC<>0); diff --git a/spirv/emit_mubuf.pas b/spirv/emit_mubuf.pas index 5aa5cda0..2cf15ae5 100644 --- a/spirv/emit_mubuf.pas +++ b/spirv/emit_mubuf.pas @@ -91,7 +91,7 @@ begin begin grp:=GroupingSharp(src,rtVSharp4); - PV:=grp.pData; + PV:=grp.GetSharp; // grp.RINF:=True; @@ -180,7 +180,7 @@ begin end; grp:=GroupingSharp(@src,rtVSharp4); - PV:=grp.pData; + PV:=grp.GetSharp; // grp.RINF:=True; @@ -218,7 +218,7 @@ begin end; grp:=GroupingSharp(@src,rtVSharp4); - PV:=grp.pData; + PV:=grp.GetSharp; // grp.RINF:=True; @@ -256,7 +256,7 @@ begin end; grp:=GroupingSharp(@src,rtVSharp4); - PV:=grp.pData; + PV:=grp.GetSharp; TEmit_vbuf_load(TObject(Self)).buf_load( Buf_info(grp, @@ -288,7 +288,7 @@ begin end; grp:=GroupingSharp(@src,rtVSharp4); - PV:=grp.pData; + PV:=grp.GetSharp; TEmit_vbuf_store(TObject(Self)).buf_store( Buf_info(grp, diff --git a/spirv/emit_op.pas b/spirv/emit_op.pas index c4bb389a..1a5dfe06 100644 --- a/spirv/emit_op.pas +++ b/spirv/emit_op.pas @@ -111,7 +111,7 @@ 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 OpSampledImage(pLine:TspirvOp;Tgrp,Sgrp:TsrNode;dtype:TsrDataType;info:TsrTypeImageInfo):TsrRegNode; + function OpSampledImage(pLine:TspirvOp;Tgrp,Sgrp:TsrNode;dtype:TsrDataType;info:TsrTypeImageInfo):TsrRegSampledImage; // procedure OpIAdd(dst:PsrRegSlot;src0,src1:TsrRegNode); procedure OpISub(dst:PsrRegSlot;src0,src1:TsrRegNode); @@ -181,6 +181,8 @@ type function OpImageFetch(pLine:TspirvOp;Tgrp:TsrNode;dst,coord:TsrRegNode):TspirvOp; function OpImageRead(pLine:TspirvOp;Tgrp:TsrNode;dst,idx:TsrRegNode):TspirvOp; function OpImageWrite(pLine:TspirvOp;Tgrp:TsrNode;idx,src:TsrRegNode):TspirvOp; + function OpImageQuerySizeLod(pLine:TspirvOp;img:TsrNode;dst,lod:TsrRegNode):TspirvOp; + function OpImageQueryLod(pLine:TspirvOp;img:TsrNode;dst,coord:TsrRegNode):TspirvOp; end; function isPowerOfTwo(x:QWORD):Boolean; inline; @@ -1036,12 +1038,12 @@ begin end; end; -function TEmitOp.OpSampledImage(pLine:TspirvOp;Tgrp,Sgrp:TsrNode;dtype:TsrDataType;info:TsrTypeImageInfo):TsrRegNode; +function TEmitOp.OpSampledImage(pLine:TspirvOp;Tgrp,Sgrp:TsrNode;dtype:TsrDataType;info:TsrTypeImageInfo):TsrRegSampledImage; Var src:array[0..1] of TsrNode; pType:TsrType; p:TsrCacheOp; - dst:TsrRegNode; + dst:TsrRegSampledImage; node:TspirvOp; begin src[0]:=Tgrp; @@ -1067,14 +1069,20 @@ begin begin node:=AddSpirvOp(pLine,Op.OpSampledImage); //need first - dst:=NewReg(dtTypeSampledImage); + dst:=specialize New; + dst.pSlot:=@RegsStory.FUnattach; + dst.dtype:=dtTypeSampledImage; + dst.Tgrp :=Tgrp; + dst.Sgrp :=Sgrp; + dst.etype:=dtype; + dst.info :=info; pType:=TypeList.Fetch(dtype); pType:=TypeList.FetchImage(pType,info); pType:=TypeList.FetchSampledImage(pType); node.pType:=pType; - node.pDst:=dst; + node.pDst :=dst; node.AddParam(Tgrp); node.AddParam(Sgrp); @@ -1083,7 +1091,7 @@ begin Result:=dst; end else begin - Result:=p.pDst; + Result:=TsrRegSampledImage(p.pDst); end; end; @@ -1298,7 +1306,7 @@ begin if (src=nil) then Exit(src); Result:=NewReg(rtype); - _Op1(_get_line(ppLine),Op.OpConvertUToF,Result,src); + _set_line(ppLine,_Op1(_get_line(ppLine),Op.OpConvertUToF,Result,src)); end; function TEmitOp.OpFToU(src:TsrRegNode;rtype:TsrDataType;ppLine:PPspirvOp=nil):TsrRegNode; @@ -1306,7 +1314,7 @@ begin if (src=nil) then Exit(src); Result:=NewReg(rtype); - _Op1(_get_line(ppLine),Op.OpConvertFToU,Result,src); + _set_line(ppLine,_Op1(_get_line(ppLine),Op.OpConvertFToU,Result,src)); end; function TEmitOp.OpSToF(src:TsrRegNode;rtype:TsrDataType;ppLine:PPspirvOp=nil):TsrRegNode; @@ -1314,7 +1322,7 @@ begin if (src=nil) then Exit(src); Result:=NewReg(rtype); - _Op1(_get_line(ppLine),Op.OpConvertSToF,Result,src); + _set_line(ppLine,_Op1(_get_line(ppLine),Op.OpConvertSToF,Result,src)); end; function TEmitOp.OpUToU(src:TsrRegNode;rtype:TsrDataType;ppLine:PPspirvOp=nil):TsrRegNode; @@ -1322,7 +1330,7 @@ begin if (src=nil) then Exit(src); Result:=NewReg(rtype); - _Op1(_get_line(ppLine),Op.OpUConvert,Result,src); + _set_line(ppLine,_Op1(_get_line(ppLine),Op.OpUConvert,Result,src)); end; function TEmitOp.OpSToS(src:TsrRegNode;rtype:TsrDataType;ppLine:PPspirvOp=nil):TsrRegNode; @@ -1330,7 +1338,7 @@ begin if (src=nil) then Exit(src); Result:=NewReg(rtype); - _Op1(_get_line(ppLine),Op.OpSConvert,Result,src); + _set_line(ppLine,_Op1(_get_line(ppLine),Op.OpSConvert,Result,src)); end; function TEmitOp.OpFToF(src:TsrRegNode;rtype:TsrDataType;ppLine:PPspirvOp=nil):TsrRegNode; @@ -1338,7 +1346,7 @@ begin if (src=nil) then Exit(src); Result:=NewReg(rtype); - _Op1(_get_line(ppLine),Op.OpFConvert,Result,src); + _set_line(ppLine,_Op1(_get_line(ppLine),Op.OpFConvert,Result,src)); end; // @@ -1348,7 +1356,7 @@ begin if (src=nil) then Exit(src); Result:=NewReg(src.dtype); - _OpGlsl1(_get_line(ppLine),GlslOp.Floor,Result,src) + _set_line(ppLine,_OpGlsl1(_get_line(ppLine),GlslOp.Floor,Result,src)); end; function TEmitOp.OpPowTo(src0,src1:TsrRegNode;ppLine:PPspirvOp=nil):TsrRegNode; @@ -1653,6 +1661,15 @@ begin Result:=node; end; +function TEmitOp.OpImageQuerySizeLod(pLine:TspirvOp;img:TsrNode;dst,lod:TsrRegNode):TspirvOp; +begin + Result:=_Op2(pLine,Op.OpImageQuerySizeLod,dst,img,lod); +end; + +function TEmitOp.OpImageQueryLod(pLine:TspirvOp;img:TsrNode;dst,coord:TsrRegNode):TspirvOp; +begin + Result:=_Op2(pLine,Op.OpImageQueryLod,dst,img,coord); +end; end. diff --git a/spirv/emit_post_op.pas b/spirv/emit_post_op.pas index a152ca06..b582a209 100644 --- a/spirv/emit_post_op.pas +++ b/spirv/emit_post_op.pas @@ -17,6 +17,7 @@ uses srConst, srReg, srPrivate, + srLiteral, srOp, srOpInternal, srOpUtils, @@ -72,6 +73,8 @@ type function OnCUBESC2(node:TSpirvOp):Integer; function OnCUBETC2(node:TSpirvOp):Integer; function OnCUBEMA2(node:TSpirvOp):Integer; + // + function OnImageSample2(node:TSpirvOp):Integer; end; implementation @@ -142,6 +145,12 @@ begin OpCUBEMA:OnCUBEMA2(node); srOpInternal.OpMakeCub:Assert(false,'OpMakeCub'); + + Op.OpImageSampleImplicitLod, + Op.OpImageSampleExplicitLod, + Op.OpImageSampleDrefImplicitLod, + Op.OpImageSampleDrefExplicitLod:Result:=OnImageSample2(node); + end; end; @@ -2053,6 +2062,157 @@ begin end; end; +function TEmitPostOp.OnImageSample2(node:TSpirvOp):Integer; +var + i,param,count_ofs,count_dim,count_query:Integer; + L:TsrLiteral; + + pLine:TSpirvOp; + roffset:TsrRegNode; + coffset:TsrConst; + + cvec:array[0..2] of TsrConst; + + img:TsrRegSampledImage; + coord:TsrRegNode; + sizes:TsrRegNode; + + dvec:TsrDataType; +begin + Result:=0; + + param:=0; + Case node.OpId of + Op.OpImageSampleImplicitLod :param:=2; + Op.OpImageSampleExplicitLod :param:=2; + Op.OpImageSampleDrefImplicitLod:param:=3; + Op.OpImageSampleDrefExplicitLod:param:=3; + end; + + L:=node.ParamNode(param).Value.specialize AsType; + if (L=nil) then Exit; + + i:=L.AsInt32; + + //ConstOffset is used? + if (i and ImageOperands.ConstOffset)=0 then Exit; + + //get position + if (i and ImageOperands.Bias)<>0 then + begin + Inc(param); + end; + // + if (i and ImageOperands.Lod)<>0 then + begin + Inc(param); + end; + // + if (i and ImageOperands.Grad)<>0 then + begin + Inc(param); + end; + // + Inc(param); + //get position + + roffset:=RegDown(node.ParamNode(param).AsReg); + if (roffset=nil) then Exit; + + coffset:=roffset.pWriter.specialize AsType; + + if (coffset<>nil) then Exit; //valid const offset + + pLine:=roffset.pWriter.specialize AsType; + + if (pLine<>nil) then + begin + if (pLine.OpId=srOpInternal.OpPackOfs) then Exit; //skip + end; + + // + + count_ofs:=roffset.dtype.Count; + + //get zero offset + coffset:=nil; + Case count_ofs of + 1: + begin + coffset:=ConstList.Fetch_i(dtInt32,0); + end; + 2: + begin + cvec[0]:=ConstList.Fetch_i(dtInt32,0); + cvec[1]:=ConstList.Fetch_i(dtInt32,0); + + coffset:=ConstList.FetchVector(dtVec2i,@cvec,true); + end; + 3: + begin + cvec[0]:=ConstList.Fetch_i(dtInt32,0); + cvec[1]:=ConstList.Fetch_i(dtInt32,0); + cvec[2]:=ConstList.Fetch_i(dtInt32,0); + + coffset:=ConstList.FetchVector(dtVec3i,@cvec,true); + end; + else + Assert(False); + end; + + //set zero to ConstOffset + node.ParamNode(param).Value:=coffset; + + //get image/coord + img :=node.ParamNode(0).Value.specialize AsType; + coord:=node.ParamNode(1).AsReg; + + Assert(img<>nil); + Assert(coord<>nil); + + pLine:=node.pPrev; + Assert(pLine<>nil); + + Case img.info.Dim of + Dim.Dim2D:count_dim:=2; + Dim.Cube :count_dim:=2; + Dim.Dim3D:count_dim:=3; + else + count_dim:=1; + end; + + count_query:=count_dim; + if (img.info.Arrayed<>0) then + begin + Inc(count_query); + end; + + dvec:=TsrDataType(dtUint32).AsVector(count_query); + + sizes:=NewReg(dvec); + + pLine:=OpImageQuerySizeLod(pLine,img.Tgrp,sizes,NewImm_s(dtUint32,0)); //first lod???? + + if (count_ofs<>count_query) then + begin + Assert(false,'TODO:count_ofs<>count_query'); + end; + + dvec:=TsrDataType(dtFloat32).AsVector(count_ofs); + + sizes :=OpUToF(sizes ,dvec,@pLine); + roffset:=OpSToF(roffset,dvec,@pLine); + + roffset:=OpFDivTo(roffset,sizes,@pLine); //(offset.x/WIDTH,offset.y/HEIGHT) + + coord :=OpFAddTo(coord,roffset,@pLine); //coord + (offset.x/WIDTH,offset.y/HEIGHT) + + //replace + node.ParamNode(1).Value:=coord; + + Result:=1; +end; + //////// function TEmitPostOp._Fetch_PackAnc(node:TsrRegNode;index,count:Byte):TsrRegNode; diff --git a/spirv/emit_sop1.pas b/spirv/emit_sop1.pas index bcf4ae8d..8c0d6dc1 100644 --- a/spirv/emit_sop1.pas +++ b/spirv/emit_sop1.pas @@ -67,7 +67,7 @@ begin chain[1]:=GetChainRegNode(src[1]); pLayout:=DataLayoutList.Grouping(chain,rtFunPtr2); - Result:=pLayout.pData; + Result:=pLayout.GetData; end; Assert(Result<>nil); diff --git a/spirv/emit_vbuf_chain.pas b/spirv/emit_vbuf_chain.pas index 7f60d27a..c2676170 100644 --- a/spirv/emit_vbuf_chain.pas +++ b/spirv/emit_vbuf_chain.pas @@ -226,7 +226,7 @@ begin Exit; end; - PV:=info.grp.pData; + PV:=info.grp.GetSharp; Assert(PV^.swizzle_en=0,'swizzle_en'); Assert(PV^.addtid_en =0,'addtid_en'); diff --git a/spirv/srLayout.pas b/spirv/srLayout.pas index 88b495e3..7dba6c1f 100644 --- a/spirv/srLayout.pas +++ b/spirv/srLayout.pas @@ -29,6 +29,7 @@ type rtImmData, rtBufPtr2, rtFunPtr2, + rtVSharp2, rtVSharp4, rtSSharp4, rtTSharp4, @@ -150,12 +151,13 @@ type TDescList =specialize TNodeListClass; TChainList=specialize TNodeListClass; TChainTree=specialize TNodeTreeClass; + TInplaceData =array[0..7] of DWORD; var pPrev,pNext :TsrDataLayout; pLeft,pRight:TsrDataLayout; //---- key :TsrDataLayoutKey; - pData :Pointer; + FData :TInplaceData; FID :Integer; FOrder :Integer; FSetid :Integer; @@ -177,6 +179,7 @@ type Function Last :TsrChain; function EnumChain(cb:TChainCb):Integer; function GetData:Pointer; + function GetSharp:Pointer; function IsUserData:Boolean; inline; function IsLocalDataShare:Boolean; inline; function IsGlobalDataShare:Boolean; inline; @@ -499,29 +502,45 @@ end; function TsrDataLayout.GetData:Pointer; begin Result:=nil; - if (pData<>nil) then - Case key.rtype of - rtRoot, - rtBufPtr2, - rtFunPtr2:Result:=pData; - rtVSharp4:Result:={%H-}Pointer(PVSharpResource4(pData)^.base); - rtTSharp4, - rtTSharp8:Result:={%H-}Pointer(QWORD(PTSharpResource4(pData)^.base) shl 8); - rtImmData:Result:=TsrDataImm(pData).key.pData; - else; - end; + Case key.rtype of + rtRoot, + rtBufPtr2, + rtFunPtr2:Result:=PPointer(@FData)^; + rtVSharp2, + rtVSharp4:Result:=Pointer(PVSharpResource4(@FData)^.base); //and (not 3)? + rtTSharp4, + rtTSharp8:Result:=Pointer(QWORD(PTSharpResource4(@FData)^.base) shl 8); + rtImmData:Result:=TsrDataImm(PPointer(@FData)^).key.pData; + else; + end; +end; + +function TsrDataLayout.GetSharp:Pointer; +begin + Result:=nil; + Case key.rtype of + rtRoot, + rtBufPtr2, + rtFunPtr2:Result:=PPointer(@FData)^; + rtVSharp2, + rtVSharp4, + rtTSharp4, + rtTSharp8:Result:=@FData; + rtImmData:Result:=TsrDataImm(PPointer(@FData)^); + else; + end; end; function TsrDataLayout.GetStride:PtrUint; begin Result:=0; - if (pData<>nil) then - Case key.rtype of - rtRoot, - rtBufPtr2:Result:=4; - rtVSharp4:Result:=PVSharpResource4(pData)^.stride; - else; - end; + Case key.rtype of + rtRoot, + rtBufPtr2:Result:=4; + rtVSharp2, + rtVSharp4:Result:=PVSharpResource4(@FData)^.stride; + else; + end; end; function TsrDataLayout.IsUserData:Boolean; inline; @@ -569,6 +588,7 @@ begin rtImmData:Result:='D'; rtBufPtr2:Result:='B'; rtFunPtr2:Result:='F'; + rtVSharp2:Result:='v'; rtVSharp4:Result:='V'; rtSSharp4:Result:='S'; rtTSharp4:Result:='t'; @@ -601,7 +621,7 @@ end; procedure TsrDataLayoutList.SetUserData(pData:Pointer); begin - FTop.pData:=pData; + PPointer(@FTop.FData)^:=pData; end; function TsrDataLayoutList.pRoot:TsrDataLayout; @@ -634,17 +654,23 @@ begin FDataList.Push_tail(Result); if (pData<>nil) then + begin + Result.FData:=Default(TsrDataLayout.TInplaceData); + case t of - rtRoot :Result.pData:=pData; - rtFunPtr2:Result.pData:={%H-}Pointer(PPtrUint(pData+o)^); - rtBufPtr2:Result.pData:={%H-}Pointer(PPtrUint(pData+o)^ and (not 3)); + rtRoot :PPointer(@Result.FData)^:=pData; + rtFunPtr2:PPointer(@Result.FData)^:=Pointer(PPtrUint(pData+o)^); + rtBufPtr2:PPointer(@Result.FData)^:=Pointer(PPtrUint(pData+o)^ and (not 3)); + rtImmData:PPointer(@Result.FData)^:=pData; + rtVSharp2, rtVSharp4, rtSSharp4, rtTSharp4, - rtTSharp8:Result.pData:=pData+o; - rtImmData:Result.pData:=pData; + rtTSharp8:Move(Pointer(pData+o)^,Result.FData,GetResourceSizeDw(t)*SizeOf(DWORD)); end; + end; + end; end; @@ -665,6 +691,7 @@ begin rtRoot :Result:=2; rtBufPtr2:Result:=2; rtFunPtr2:Result:=2; + rtVSharp2:Result:=2; rtVSharp4:Result:=4; rtSSharp4:Result:=4; rtTSharp4:Result:=4; @@ -901,6 +928,8 @@ var desc :TsrDescriptor; block :TsrCodeBlock; imm :TsrDataImm; + PV :PVSharpResource4; + PS :PTSharpResource4; begin pHeap:=FTop.FEmit.GetCodeHeap; @@ -916,6 +945,7 @@ begin case Writer.node.key.rtype of rtFunPtr2, rtBufPtr2, + rtVSharp2, rtVSharp4, rtSSharp4, rtTSharp4, @@ -931,11 +961,14 @@ begin end; case Writer.node.key.rtype of + rtVSharp2, rtVSharp4: begin //Resource data precompiled - with PVSharpResource4(Writer.node.pData)^ do + PV:=Writer.node.GetSharp; + + with PV^ do begin if (Writer.node.RINF) then begin @@ -953,7 +986,9 @@ begin begin //Resource data precompiled - with PTSharpResource4(Writer.node.pData)^ do + PS:=Writer.node.GetSharp; + + with PS^ do begin Writer.IntOpt('TYPE',_type); if (Writer.node.RINF) then @@ -976,7 +1011,7 @@ begin rtImmData: begin //imm data - imm:=TsrDataImm(Writer.node.pData); + imm:=TsrDataImm(Writer.node.GetSharp); Assert(imm<>nil); // Writer.HexOpt('LEN',imm.key.FImmSize); @@ -985,7 +1020,7 @@ begin rtFunPtr2: begin //func - block:=pHeap^.FindByPtr(Writer.node.pData); + block:=pHeap^.FindByPtr(Writer.node.GetData); Assert(block<>nil); // Writer.HexOpt('LEN',block.Size); diff --git a/spirv/srOp.pas b/spirv/srOp.pas index 28dda29e..1ca2c916 100644 --- a/spirv/srOp.pas +++ b/spirv/srOp.pas @@ -30,11 +30,12 @@ type private pParent:TspirvOp; pValue:TsrNode; + function GetValue:TsrNode; procedure SetValue(v:TsrNode); public property Next:TOpParamNode read pNext; property Parent:TspirvOp read pParent; - property Value:TsrNode read pValue write SetValue; + property Value:TsrNode read GetValue write SetValue; function AsReg:TsrRegNode; function TryGetValue(var V:PtrUint):Boolean; end; @@ -382,10 +383,17 @@ end; // +function TOpParamNode.GetValue:TsrNode; +begin + if (Self=nil) then Exit(nil); + Result:=pValue; +end; + procedure TOpParamNode.SetValue(v:TsrNode); var b:Byte; begin + if (Self=nil) then Exit; if (pValue=v) then Exit; // Assert(pParent<>nil); diff --git a/spirv/srReg.pas b/spirv/srReg.pas index 505dc9e1..e85803d0 100644 --- a/spirv/srReg.pas +++ b/spirv/srReg.pas @@ -92,6 +92,13 @@ type ntRegPair=TsrRegPair; + TsrRegSampledImage=class(TsrRegNode) + Tgrp :TsrNode; + Sgrp :TsrNode; + etype:TsrDataType; + info :TsrTypeImageInfo; + end; + TsrVectorArray=class(TsrRegNode) FLanes:array[0..LaneCount-1] of TsrRegNode; //[0..63] end;