diff --git a/spirv/emit_mimg.pas b/spirv/emit_mimg.pas index 522cd051..cb71cedc 100644 --- a/spirv/emit_mimg.pas +++ b/spirv/emit_mimg.pas @@ -23,22 +23,22 @@ type TImgSampleParam=object roffset:DWORD; - mods:TsrImageMods; - img_op:Integer; + mods :TsrImageMods; + img_op :Integer; coord,pcf,bias,lod,min_lod,offset:TsrRegNode; end; TEmit_MIMG=class(TEmitFetch) procedure emit_MIMG; - procedure DistribDmask(DMASK:Byte;dst:TsrRegNode;info:PsrImageInfo); - function GatherDmask(telem:TsrDataType):TsrRegNode; - Function GatherCoord_f(var offset:DWORD;info:PsrImageInfo):TsrRegNode; - Function GatherCoord_u(var offset:DWORD;info:PsrImageInfo):TsrRegNode; - Function Gather_value(var offset:DWORD;rtype:TsrDataType):TsrRegNode; - Function Gather_packed_offset(var offset:DWORD;dim:Byte):TsrRegNode; - procedure Gather_sample_param(var p:TImgSampleParam;info:PsrImageInfo); - procedure add_sample_op(var p:TImgSampleParam;node:TSpirvOp); + procedure DistribDmask (DMASK:Byte;dst:TsrRegNode;info:PsrImageInfo); + function GatherDmask (info:PsrImageInfo):TsrRegNode; + Function GatherCoord_f (var offset:DWORD;info:PsrImageInfo):TsrRegNode; + Function GatherCoord_u (var offset:DWORD;info:PsrImageInfo):TsrRegNode; + Function Gather_value (var offset:DWORD;rtype:TsrDataType):TsrRegNode; + Function Gather_packed_offset (var offset:DWORD;dim:Byte):TsrRegNode; + procedure Gather_sample_param (var p:TImgSampleParam;info:PsrImageInfo); + procedure add_sample_op (var p:TImgSampleParam;node:TSpirvOp); procedure emit_image_sample (Tgrp:TsrNode;info:PsrImageInfo); procedure emit_image_sample_gather(Tgrp:TsrNode;info:PsrImageInfo); procedure emit_image_load (Tgrp:TsrNode;info:PsrImageInfo); @@ -49,6 +49,80 @@ type implementation +function GetImageElemCount(PT:PTSharpResource4):Byte; +begin + Result:=0; + if (PT=nil) then Exit; + Case PT^.dfmt of + + IMG_DATA_FORMAT_8 :Result:=1; + IMG_DATA_FORMAT_ETC2_R :Result:=1; + IMG_DATA_FORMAT_BC4 :Result:=1; + IMG_DATA_FORMAT_1 :Result:=1; + IMG_DATA_FORMAT_32_AS_8 :Result:=1; + IMG_DATA_FORMAT_16 :Result:=1; + IMG_DATA_FORMAT_32 :Result:=1; + + IMG_DATA_FORMAT_8_8 :Result:=2; + IMG_DATA_FORMAT_16_16 :Result:=2; + IMG_DATA_FORMAT_ETC2_RG :Result:=2; + IMG_DATA_FORMAT_BC5 :Result:=2; + IMG_DATA_FORMAT_4_4 :Result:=2; + IMG_DATA_FORMAT_32_AS_8_8 :Result:=2; + IMG_DATA_FORMAT_32_32 :Result:=2; + IMG_DATA_FORMAT_8_24 :Result:=2; + IMG_DATA_FORMAT_24_8 :Result:=2; + IMG_DATA_FORMAT_X24_8_32 :Result:=2; + + IMG_DATA_FORMAT_10_11_11 :Result:=3; + IMG_DATA_FORMAT_11_11_10 :Result:=3; + IMG_DATA_FORMAT_5_6_5 :Result:=3; + IMG_DATA_FORMAT_ETC2_RGB :Result:=3; + IMG_DATA_FORMAT_GB_GR :Result:=3; + IMG_DATA_FORMAT_BG_RG :Result:=3; + IMG_DATA_FORMAT_BC1 :Result:=3; + IMG_DATA_FORMAT_BC6 :Result:=3; + IMG_DATA_FORMAT_6_5_5 :Result:=3; + IMG_DATA_FORMAT_32_32_32 :Result:=3; + + IMG_DATA_FORMAT_10_10_10_2 :Result:=4; + IMG_DATA_FORMAT_2_10_10_10 :Result:=4; + IMG_DATA_FORMAT_8_8_8_8 :Result:=4; + IMG_DATA_FORMAT_1_5_5_5 :Result:=4; + IMG_DATA_FORMAT_5_5_5_1 :Result:=4; + IMG_DATA_FORMAT_4_4_4_4 :Result:=4; + IMG_DATA_FORMAT_ETC2_RGBA :Result:=4; + IMG_DATA_FORMAT_ETC2_RGBA1 :Result:=4; + IMG_DATA_FORMAT_5_9_9_9 :Result:=4; + IMG_DATA_FORMAT_BC2 :Result:=4; + IMG_DATA_FORMAT_BC3 :Result:=4; + IMG_DATA_FORMAT_BC7 :Result:=4; + IMG_DATA_FORMAT_16_16_16_16 :Result:=4; + IMG_DATA_FORMAT_32_32_32_32 :Result:=4; + + IMG_DATA_FORMAT_FMASK8_S2_F1 :Result:=1; + IMG_DATA_FORMAT_FMASK8_S4_F1 :Result:=1; + IMG_DATA_FORMAT_FMASK8_S8_F1 :Result:=1; + IMG_DATA_FORMAT_FMASK8_S2_F2 :Result:=1; + IMG_DATA_FORMAT_FMASK8_S4_F2 :Result:=1; + IMG_DATA_FORMAT_FMASK8_S4_F4 :Result:=1; + + IMG_DATA_FORMAT_FMASK16_S16_F1 :Result:=1; + IMG_DATA_FORMAT_FMASK16_S8_F2 :Result:=1; + + IMG_DATA_FORMAT_FMASK32_S16_F2 :Result:=1; + IMG_DATA_FORMAT_FMASK32_S8_F4 :Result:=1; + IMG_DATA_FORMAT_FMASK32_S8_F8 :Result:=1; + + IMG_DATA_FORMAT_FMASK64_S16_F4 :Result:=1; + IMG_DATA_FORMAT_FMASK64_S16_F8 :Result:=1; + + IMG_DATA_FORMAT_32_AS_32_32_32_32:Result:=4; + + else; + end; +end; + function GetImageFormat(PT:PTSharpResource4):Byte; begin Result:=ImageFormat.Unknown; @@ -383,6 +457,7 @@ function GetImageInfo(PT:PTSharpResource4):TsrImageInfo; begin Result:=Default(TsrImageInfo); Result.dtype:=GetElemType(PT); + Result.count:=GetImageElemCount(PT); Result.tinfo.Dim :=GetDimType(PT); Result.tinfo.Depth :=2; @@ -529,36 +604,33 @@ begin end; end; -function TEmit_MIMG.GatherDmask(telem:TsrDataType):TsrRegNode; +function TEmit_MIMG.GatherDmask(info:PsrImageInfo):TsrRegNode; var src:array[0..3] of TsrRegNode; i,d,m:Byte; begin + Assert(info^.count<>0); + d:=0; - For i:=0 to 3 do - if Byte(FSPI.MIMG.DMASK).TestBit(i) then + m:=info^.count; + For i:=0 to m-1 do begin - src[i]:=fetch_vsrc8(FSPI.MIMG.VDATA+d,telem); - Inc(d); - m:=i; - end else - begin - src[i]:=nil; + if Byte(FSPI.MIMG.DMASK).TestBit(i) then + begin + src[i]:=fetch_vsrc8(FSPI.MIMG.VDATA+d,info^.dtype); + Inc(d); + end else + begin + src[i]:=NewReg_i(info^.dtype,0); + end; end; - //Result:=telem.AsVector(4); - For i:=0 to m do - begin - //TODO: zero or prev value? - Assert(src[i]<>nil,'TODO: zero or prev value?'); - end; - - if (m=0) then + if (m=1) then begin Result:=src[0]; end else begin - Result:=OpMakeVec(line,telem.AsVector(m+1),@src); + Result:=OpMakeVec(line,info^.dtype.AsVector(m),@src); end; end; @@ -986,7 +1058,7 @@ var node:TSpirvOp; begin - dst:=GatherDmask(info^.dtype); + dst:=GatherDmask(info); roffset:=0; diff --git a/spirv/emit_post_op.pas b/spirv/emit_post_op.pas index 92157a62..22347d9f 100644 --- a/spirv/emit_post_op.pas +++ b/spirv/emit_post_op.pas @@ -66,6 +66,11 @@ type function OnIAddExt2(node:TSpirvOp):Integer; function OnISubExt2(node:TSpirvOp):Integer; function OnPackAnc2(node:TSpirvOp):Integer; + // + function OnCUBEID2(node:TSpirvOp):Integer; + function OnCUBESC2(node:TSpirvOp):Integer; + function OnCUBETC2(node:TSpirvOp):Integer; + function OnCUBEMA2(node:TSpirvOp):Integer; end; implementation @@ -131,11 +136,10 @@ begin Op.OpReturn:Result:=OnReturn_2(node); OpMakeExp :Result:=OnMakeExp2(node); - OpCUBEID:Assert(False,'TODO: CUBEID'); //TODO: CUBEID - OpCUBESC:Assert(False,'TODO: CUBESC'); //TODO: CUBESC - OpCUBETC:Assert(False,'TODO: CUBETC'); //TODO: CUBETC - OpCUBEMA:Assert(False,'TODO: CUBEMA'); //TODO: CUBEMA - + OpCUBEID:OnCUBEID2(node); + OpCUBESC:OnCUBESC2(node); + OpCUBETC:OnCUBETC2(node); + OpCUBEMA:OnCUBEMA2(node); end; end; @@ -2381,6 +2385,24 @@ begin Result:=1; end; +{ +float3 __GetCubemapUv(float3 uv) +{ + float faceId = __v_cubeid_f32(uv.x, uv.y, uv.z); + float sc = __v_cubesc_f32(uv.x, uv.y, uv.z); + float tc = __v_cubetc_f32(uv.x, uv.y, uv.z); + float ima = 1.f / abs( __v_cubema_f32(uv.x, uv.y, uv.z) ); + return float3(sc * ima + 1.5f, tc * ima + 1.5f, faceId); +} + +float4 __GetCubemapArrayUv(float4 uv) +{ + float3 cuv = __GetCubemapUv(uv.xyz); + cuv.z = cuv.z + (uv.w * 8.f); + return float4(cuv, uv.w); +} +} + function TEmitPostOp.OnMakeCub1(node:TSpirvOp):Integer; var dst:TsrRegNode; @@ -2482,6 +2504,98 @@ begin Result:=1; end; +function TEmitPostOp.OnCUBEID2(node:TSpirvOp):Integer; +var + dst:TsrRegNode; + src:TsrRegNode; + + procedure _SetReg(src:TsrRegNode); + begin + dst.pWriter:=src; + node.mark_not_used; + node.pDst:=nil; + Inc(Result); + end; + +begin + Result:=0; + dst:=node.pDst.specialize AsType; + src:=node.ParamNode(2).AsReg; + + if (dst=nil) or (src=nil) then Exit; + + _SetReg(src); //fake out +end; + +function TEmitPostOp.OnCUBESC2(node:TSpirvOp):Integer; +var + dst:TsrRegNode; + src:TsrRegNode; + + procedure _SetReg(src:TsrRegNode); + begin + dst.pWriter:=src; + node.mark_not_used; + node.pDst:=nil; + Inc(Result); + end; + +begin + Result:=0; + dst:=node.pDst.specialize AsType; + src:=node.ParamNode(0).AsReg; + + if (dst=nil) or (src=nil) then Exit; + + _SetReg(src); //fake out +end; + +function TEmitPostOp.OnCUBETC2(node:TSpirvOp):Integer; +var + dst:TsrRegNode; + src:TsrRegNode; + + procedure _SetReg(src:TsrRegNode); + begin + dst.pWriter:=src; + node.mark_not_used; + node.pDst:=nil; + Inc(Result); + end; + +begin + Result:=0; + dst:=node.pDst.specialize AsType; + src:=node.ParamNode(1).AsReg; + + if (dst=nil) or (src=nil) then Exit; + + _SetReg(src); //fake out +end; + +function TEmitPostOp.OnCUBEMA2(node:TSpirvOp):Integer; +var + dst:TsrRegNode; + + procedure _SetConst_s(dtype:TsrDataType;value:Single); + begin + Assert(dtype=dtFloat32); + dst.pWriter:=NewReg_s(dtype,value,@node); + node.mark_not_used; + node.pDst:=nil; + Inc(Result); + end; + +begin + Result:=0; + dst:=node.pDst.specialize AsType; + + if (dst=nil) then Exit; + + _SetConst_s(dtFloat32,1); //fake out +end; + + procedure TEmitPostOp.MakeVecConst(rtype:TsrDataType;dst:TsrRegNode;src:PPsrRegNode); var nodes:array[0..3] of TsrConst; diff --git a/spirv/srType.pas b/spirv/srType.pas index e5d4712f..1de8b8a1 100644 --- a/spirv/srType.pas +++ b/spirv/srType.pas @@ -128,6 +128,7 @@ type TsrImageInfo=packed record dtype:TsrDataType; tinfo:TsrTypeImageInfo; + count:Byte; GLC:Boolean; SLC:Boolean; end;