fpPS4/spirv/emit_vop1.pas
2022-11-15 15:54:47 +03:00

242 lines
4.9 KiB
ObjectPascal

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_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;
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_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_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_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;
else
Assert(false,'VOP1?'+IntToStr(FSPI.VOP1.OP));
end;
end;
end.