unit emit_VOP1; {$mode objfpc}{$H+} interface uses sysutils, ps4_pssl, spirv, srType, srReg, srConst, emit_fetch; type TEmit_VOP1=class(TEmitFetch) procedure emit_VOP1; procedure emit_V_MOV_B32; procedure emit_V_CVT(OpId:DWORD;dst_type,src_type:TsrDataType); procedure emit_V_CVT_F16_F32; procedure emit_V_CVT_F32_F16; procedure emit_V_CVT_OFF_F32_I4; procedure emit_V_CVT_FLR_I32_F32; procedure emit_V_CVT_RPI_I32_F32; procedure emit_V_CVT_F32_UBYTE0; procedure emit_V_EXT_F32(OpId:DWORD); procedure emit_V_RSQ_CLAMP_F32; procedure emit_V_SIN_COS(OpId:DWORD); procedure emit_V_RCP_F32; procedure emit_V_FFBL_B32; procedure emit_V_BFREV_B32; end; implementation procedure TEmit_VOP1.emit_V_MOV_B32; Var dst:PsrRegSlot; src:PsrRegNode; begin dst:=get_vdst8(FSPI.VOP1.VDST); src:=fetch_ssrc9(FSPI.VOP1.SRC0,dtUnknow); MakeCopy(dst,src); end; procedure TEmit_VOP1.emit_V_CVT(OpId:DWORD;dst_type,src_type:TsrDataType); Var dst:PsrRegSlot; src:PsrRegNode; begin dst:=get_vdst8(FSPI.VOP1.VDST); src:=fetch_ssrc9(FSPI.VOP1.SRC0,src_type); Op1(OpId,dst_type,dst,src); end; procedure TEmit_VOP1.emit_V_CVT_F16_F32; //vdst[15:0].hf = ConvertFloatToHalfFloat(vsrc.f) Var dst:PsrRegSlot; src:array[0..1] of PsrRegNode; dstv:PsrRegNode; begin dst:=get_vdst8(FSPI.VOP1.VDST); src[0]:=fetch_ssrc9(FSPI.VOP1.SRC0,dtFloat32); src[0]:=OpFToF(src[0],dtHalf16); src[1]:=NewReg_s(dtHalf16,0); dstv:=OpMakeVec(line,dtVec2h,@src); dst^.New(line,dtVec2h)^.pWriter:=dstv; end; procedure TEmit_VOP1.emit_V_CVT_F32_F16; //vdst.f = ConvertHalfFloatToFloat(vsrc[15:0].hf) Var dst:PsrRegSlot; src:PsrRegNode; dst0:PsrRegNode; begin dst:=get_vdst8(FSPI.VOP1.VDST); src:=fetch_ssrc9(FSPI.VOP1.SRC0,dtVec2h{dtUnknow}); //src:=OpBitwiseAndTo(src,$FFFF); //src^.PrepType(ord(dtHalf16)); dst0:=NewReg(dtHalf16); OpExtract(line,dst0,src,0); Op1(Op.OpFConvert,dtFloat32,dst,{src}dst0); end; //V_CVT_OFF_F32_I4 //([0..3]-8)/16 procedure TEmit_VOP1.emit_V_CVT_OFF_F32_I4; Var dst:PsrRegSlot; src:PsrRegNode; num_16:PsrRegNode; begin dst:=get_vdst8(FSPI.VOP1.VDST); src:=fetch_ssrc9(FSPI.VOP1.SRC0,dtUInt32); src:=OpAndTo(src,15); src^.PrepType(ord(dtInt32)); src:=OpISubTo(src,8); src:=OpSToF(src,dtFloat32); num_16:=NewReg_s(dtFloat32,16); Op2(Op.OpFDiv,dtFloat32,dst,src,num_16); end; procedure TEmit_VOP1.emit_V_CVT_FLR_I32_F32; //ConvertFloatToSignedInt(floor(vsrc.f)) Var dst:PsrRegSlot; src:PsrRegNode; begin dst:=get_vdst8(FSPI.VOP1.VDST); src:=fetch_ssrc9(FSPI.VOP1.SRC0,dtFloat32); src:=OpFloorTo(src); Op1(Op.OpConvertFToS,dtInt32,dst,src); end; procedure TEmit_VOP1.emit_V_CVT_RPI_I32_F32; //ConvertFloatToSignedInt(floor(vsrc.f+0.5)) Var dst:PsrRegSlot; src:PsrRegNode; begin dst:=get_vdst8(FSPI.VOP1.VDST); src:=fetch_ssrc9(FSPI.VOP1.SRC0,dtFloat32); src:=OpFAddToS(src,0.5); src:=OpFloorTo(src); Op1(Op.OpConvertFToS,dtInt32,dst,src); end; procedure TEmit_VOP1.emit_V_CVT_F32_UBYTE0; Var dst:PsrRegSlot; src:PsrRegNode; begin dst:=get_vdst8(FSPI.VOP1.VDST); src:=fetch_ssrc9(FSPI.VOP1.SRC0,dtUInt32); 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; src:PsrRegNode; begin dst:=get_vdst8(FSPI.VOP1.VDST); src:=fetch_ssrc9(FSPI.VOP1.SRC0,dtFloat32); OpGlsl1(OpId,dtFloat32,dst,src); end; procedure TEmit_VOP1.emit_V_RSQ_CLAMP_F32; Var dst:PsrRegSlot; src:PsrRegNode; flt:PsrRegNode; begin dst:=get_vdst8(FSPI.VOP1.VDST); src:=fetch_ssrc9(FSPI.VOP1.SRC0,dtFloat32); OpGlsl1(GlslOp.InverseSqrt,dtFloat32,dst,src); src:=MakeRead(dst,dtFloat32); flt:=NewReg_s(dtFloat32,FLT_MAX); OpGlsl2(GlslOp.NMin,dtFloat32,dst,src,flt); end; procedure TEmit_VOP1.emit_V_SIN_COS(OpId:DWORD); const PI2:Single=2*PI; Var dst:PsrRegSlot; src:PsrRegNode; begin dst:=get_vdst8(FSPI.VOP1.VDST); src:=fetch_ssrc9(FSPI.VOP1.SRC0,dtFloat32); src:=OpFMulToS(src,PI2); OpGlsl1(OpId,dtFloat32,dst,src); end; procedure TEmit_VOP1.emit_V_RCP_F32; Var dst:PsrRegSlot; src:PsrRegNode; one:PsrRegNode; begin dst:=get_vdst8(FSPI.VOP1.VDST); src:=fetch_ssrc9(FSPI.VOP1.SRC0,dtFloat32); one:=NewReg_s(dtFloat32,1); Op2(Op.OpFDiv,dtFloat32,dst,one,src); end; procedure TEmit_VOP1.emit_V_FFBL_B32; Var dst:PsrRegSlot; src:PsrRegNode; begin dst:=get_vdst8(FSPI.VOP1.VDST); src:=fetch_ssrc9(FSPI.VOP1.SRC0,dtInt32); OpGlsl1(GlslOp.FindILsb,dtInt32,dst,src); end; procedure TEmit_VOP1.emit_V_BFREV_B32; Var dst:PsrRegSlot; src:PsrRegNode; one:PsrRegNode; begin dst:=get_vdst8(FSPI.VOP1.VDST); src:=fetch_ssrc9(FSPI.VOP1.SRC0,dtUInt32); Op1(Op.OpBitReverse,dtUInt32,dst,src); end; procedure TEmit_VOP1.emit_VOP1; begin Case FSPI.VOP1.OP of V_NOP:; V_MOV_B32: emit_V_MOV_B32; V_CVT_F32_I32: emit_V_CVT(Op.OpConvertSToF,dtFloat32,dtInt32); V_CVT_F32_U32: emit_V_CVT(Op.OpConvertUToF,dtFloat32,dtUInt32); V_CVT_U32_F32: emit_V_CVT(Op.OpConvertFToU,dtUInt32 ,dtFloat32); V_CVT_I32_F32: emit_V_CVT(Op.OpConvertFToS,dtInt32 ,dtFloat32); V_CVT_F16_F32: emit_V_CVT_F16_F32; V_CVT_F32_F16: emit_V_CVT_F32_F16; V_CVT_OFF_F32_I4: emit_V_CVT_OFF_F32_I4; V_CVT_FLR_I32_F32: emit_V_CVT_FLR_I32_F32; V_CVT_RPI_I32_F32: emit_V_CVT_RPI_I32_F32; V_CVT_F32_UBYTE0: emit_V_CVT_F32_UBYTE0; V_FRACT_F32: emit_V_EXT_F32(GlslOp.Fract); V_TRUNC_F32: emit_V_EXT_F32(GlslOp.Trunc); V_CEIL_F32 : emit_V_EXT_F32(GlslOp.Ceil); V_RNDNE_F32: emit_V_EXT_F32(GlslOp.RoundEven); V_FLOOR_F32: emit_V_EXT_F32(GlslOp.Floor); V_EXP_F32 : emit_V_EXT_F32(GlslOp.Exp2); V_LOG_F32 : emit_V_EXT_F32(GlslOp.Log2); V_RSQ_F32 : emit_V_EXT_F32(GlslOp.InverseSqrt); V_RSQ_CLAMP_F32: emit_V_RSQ_CLAMP_F32; V_SQRT_F32 : emit_V_EXT_F32(GlslOp.Sqrt); V_SIN_F32 : emit_V_SIN_COS(GlslOp.Sin); V_COS_F32 : emit_V_SIN_COS(GlslOp.Cos); V_RCP_F32 : emit_V_RCP_F32; V_FFBL_B32 : emit_V_FFBL_B32; V_BFREV_B32: emit_V_BFREV_B32; else Assert(false,'VOP1?'+IntToStr(FSPI.VOP1.OP)); end; end; end.