diff --git a/spirv/SprvEmit.pas b/spirv/SprvEmit.pas index a58615e9..2d804f85 100644 --- a/spirv/SprvEmit.pas +++ b/spirv/SprvEmit.pas @@ -200,7 +200,8 @@ uses emit_EXP, emit_VINTRP, emit_SMRD, - emit_MIMG; + emit_MIMG, + emit_DS; function TSprvEmit.Alloc(Size:ptruint):Pointer; begin @@ -1721,7 +1722,7 @@ begin else TEmit_VOP3(Self)._emit_VOP3a; end; - W_DS :_emit_DS; + W_DS :TEmit_DS(Self)._emit_DS; W_MUBUF :TEmit_MUBUF(Self)._emit_MUBUF; W_MTBUF :TEmit_MTBUF(Self)._emit_MTBUF; W_EXP :TEmit_EXP(Self)._emit_EXP; diff --git a/spirv/emit_ds.pas b/spirv/emit_ds.pas new file mode 100644 index 00000000..3acaf227 --- /dev/null +++ b/spirv/emit_ds.pas @@ -0,0 +1,64 @@ +unit emit_DS; + +{$mode objfpc}{$H+} + +interface + +uses + sysutils, + ps4_pssl, + srTypes, + srReg, + spirv, + SprvEmit, + emit_op; + +type + TEmit_DS=object(TEmitOp) + procedure _emit_DS; + procedure _emit_DS_SWIZZLE_B32; + end; + +implementation + +procedure TEmit_DS._emit_DS_SWIZZLE_B32; //TODO +Var + dst:PsrRegSlot; +begin + dst:=FRegsStory.get_vdst8(FSPI.DS.VDST); + SetConst(dst,dtFloat32,0); +end; + +procedure TEmit_DS._emit_DS; +begin + + Case FSPI.DS.OP of + + DS_NOP:; + + //DS_SWIZZLE_B32 v4 v3 v0 v0 OFFSET:0x80AA GDS:0 + + DS_SWIZZLE_B32: //TODO + begin; + _emit_DS_SWIZZLE_B32; + end; + + else + Assert(false,'DS?'); + end; + +end; + +{ +OFFSET0:Byte; +OFFSET1:Byte; +GDS:bit1; +ADDR:Byte; (vbindex) +DATA0:Byte; (vsrc0) +DATA1:Byte; (vsrc1) +VDST:Byte; +} + +end. + + diff --git a/spirv/emit_op.pas b/spirv/emit_op.pas index 90dc6784..547753fe 100644 --- a/spirv/emit_op.pas +++ b/spirv/emit_op.pas @@ -66,6 +66,7 @@ type procedure emit_OpFract(dst:PsrRegSlot;src:PsrRegNode); procedure emit_OpSqrt(dst:PsrRegSlot;src:PsrRegNode); procedure emit_OpInverseSqrt(dst:PsrRegSlot;src:PsrRegNode); + procedure emit_OpLog2(dst:PsrRegSlot;src:PsrRegNode); procedure emit_OpExp2(dst:PsrRegSlot;src:PsrRegNode); procedure emit_OpSin(dst:PsrRegSlot;src:PsrRegNode); procedure emit_OpFMin(dst:PsrRegSlot;src0,src1:PsrRegNode); @@ -584,6 +585,11 @@ begin emit_OpExt1(GlslOp.InverseSqrt,dtFloat32,dst,src); end; +procedure TEmitOp.emit_OpLog2(dst:PsrRegSlot;src:PsrRegNode); +begin + emit_OpExt1(GlslOp.Log2,dtFloat32,dst,src); +end; + procedure TEmitOp.emit_OpExp2(dst:PsrRegSlot;src:PsrRegNode); begin emit_OpExt1(GlslOp.Exp2,dtFloat32,dst,src); diff --git a/spirv/emit_sopp.pas b/spirv/emit_sopp.pas index 8d8ed997..3016ec07 100644 --- a/spirv/emit_sopp.pas +++ b/spirv/emit_sopp.pas @@ -25,7 +25,9 @@ type procedure _emit_S_BRANCH; function IsBegLoop(Adr:TSrcAdr):Boolean; function IsEndLoop(Adr:TSrcAdr):Boolean; + function IsUnknow(Adr:TSrcAdr):Boolean; procedure emit_cond_block(pSlot:PsrRegSlot;n:Boolean;adr:TSrcAdr); + procedure emit_block_unknow(adr:TSrcAdr); procedure UpBuildVol(last:PsrOpBlock); procedure emit_loop(adr:TSrcAdr); end; @@ -209,6 +211,16 @@ begin end; end; +function TEmit_SOPP.IsUnknow(Adr:TSrcAdr):Boolean; +var + pLabel:PsrLabel; +begin + pLabel:=FindLabel(Adr); + Assert(pLabel<>nil); + + Result:=pLabel^.IsType(ltUnknow); +end; + procedure TEmit_SOPP._emit_S_BRANCH_COND(pSlot:PsrRegSlot;n:Boolean); var c_adr,b_adr:TSrcAdr; @@ -245,6 +257,32 @@ begin end; +procedure TEmit_SOPP.emit_block_unknow(adr:TSrcAdr); +var + c_adr:TSrcAdr; + e_adr:TSrcAdr; + pOpChild:PsrOpBlock; + Info:TsrBlockInfo; +begin + Info:=Default(TsrBlockInfo); + + c_adr:=FCursor.Adr; //get current + SetPtr(adr.get_pc,btAdr); //set new + e_adr:=FCursor.pCode^.FTop.pELabel^.Adr; //get end of code + SetPtr(c_adr.get_pc,btMain); //ret current + + Info.b_adr:=adr; + Info.e_adr:=e_adr; + Info.bType:=btAdr; + + //down group + pOpChild:=AllocBlockOp; + pOpChild^.SetInfo(Info); + PushBlockOp(line,pOpChild,nil); + + SetPtr(adr.get_pc,btAdr); +end; + procedure TEmit_SOPP._emit_S_BRANCH; var c_adr,b_adr:TSrcAdr; @@ -254,7 +292,10 @@ begin b_adr:=c_adr; b_adr.Offdw:=get_branch_offset(FSPI); - + if IsUnknow(b_adr) then + begin + emit_block_unknow(b_adr); + end else if (SmallInt(FSPI.SOPP.SIMM)<0) then //up begin //continue? if not IsBegLoop(b_adr) then Assert(false,'Unknow'); diff --git a/spirv/emit_vop1.pas b/spirv/emit_vop1.pas index 86d0bdea..f933df0f 100644 --- a/spirv/emit_vop1.pas +++ b/spirv/emit_vop1.pas @@ -17,18 +17,10 @@ type TEmit_VOP1=object(TEmitOp) procedure _emit_VOP1; procedure _emit_V_MOV_B32; - procedure _emit_V_CVT_F32_I32; - procedure _emit_V_CVT_U32_F32; - procedure _emit_V_CVT_I32_F32; - procedure _emit_V_CVT_F32_U32; + procedure _emit_V_CVT(OpId:DWORD;dst_type,src_type:TsrDataType); procedure _emit_V_CVT_OFF_F32_I4; - procedure _emit_V_SQRT_F32; - procedure _emit_V_RSQ_F32; - procedure _emit_V_FLOOR_F32; - procedure _emit_V_FRACT_F32; - procedure _emit_V_EXP_F32; + procedure _emit_V_EXT_F32(OpId:DWORD); procedure _emit_V_RCP_F32; - procedure _emit_V_SIN_F32; end; implementation @@ -43,44 +35,14 @@ begin _MakeCopy(dst,src); end; -procedure TEmit_VOP1._emit_V_CVT_F32_I32; +procedure TEmit_VOP1._emit_V_CVT(OpId:DWORD;dst_type,src_type:TsrDataType); Var dst:PsrRegSlot; src:PsrRegNode; begin dst:=FRegsStory.get_vdst8(FSPI.VOP1.VDST); - src:=fetch_ssrc9(FSPI.VOP1.SRC0,dtInt32); - emit_Op1(Op.OpConvertSToF,dtFloat32,dst,src); -end; - -procedure TEmit_VOP1._emit_V_CVT_I32_F32; -Var - dst:PsrRegSlot; - src:PsrRegNode; -begin - dst:=FRegsStory.get_vdst8(FSPI.VOP1.VDST); - src:=fetch_ssrc9(FSPI.VOP1.SRC0,dtFloat32); - emit_Op1(Op.OpConvertFToS,dtInt32,dst,src); -end; - -procedure TEmit_VOP1._emit_V_CVT_U32_F32; -Var - dst:PsrRegSlot; - src:PsrRegNode; -begin - dst:=FRegsStory.get_vdst8(FSPI.VOP1.VDST); - src:=fetch_ssrc9(FSPI.VOP1.SRC0,dtFloat32); - emit_Op1(Op.OpConvertFToU,dtUInt32,dst,src); -end; - -procedure TEmit_VOP1._emit_V_CVT_F32_U32; -Var - dst:PsrRegSlot; - src:PsrRegNode; -begin - dst:=FRegsStory.get_vdst8(FSPI.VOP1.VDST); - src:=fetch_ssrc9(FSPI.VOP1.SRC0,dtUInt32); - emit_Op1(Op.OpConvertUToF,dtFloat32,dst,src); + src:=fetch_ssrc9(FSPI.VOP1.SRC0,src_type); + emit_Op1(OpId,dst_type,dst,src); end; //V_CVT_OFF_F32_I4 @@ -119,54 +81,14 @@ begin emit_OpFDiv(dst,subf,num_16); end; -procedure TEmit_VOP1._emit_V_SQRT_F32; +procedure TEmit_VOP1._emit_V_EXT_F32(OpId:DWORD); Var dst:PsrRegSlot; src:PsrRegNode; begin dst:=FRegsStory.get_vdst8(FSPI.VOP1.VDST); src:=fetch_ssrc9(FSPI.VOP1.SRC0,dtFloat32); - emit_OpSqrt(dst,src); -end; - -procedure TEmit_VOP1._emit_V_RSQ_F32; -Var - dst:PsrRegSlot; - src:PsrRegNode; -begin - dst:=FRegsStory.get_vdst8(FSPI.VOP1.VDST); - src:=fetch_ssrc9(FSPI.VOP1.SRC0,dtFloat32); - emit_OpInverseSqrt(dst,src); -end; - -procedure TEmit_VOP1._emit_V_FLOOR_F32; -Var - dst:PsrRegSlot; - src:PsrRegNode; -begin - dst:=FRegsStory.get_vdst8(FSPI.VOP1.VDST); - src:=fetch_ssrc9(FSPI.VOP1.SRC0,dtFloat32); - emit_OpFloor(dst,src); -end; - -procedure TEmit_VOP1._emit_V_FRACT_F32; -Var - dst:PsrRegSlot; - src:PsrRegNode; -begin - dst:=FRegsStory.get_vdst8(FSPI.VOP1.VDST); - src:=fetch_ssrc9(FSPI.VOP1.SRC0,dtFloat32); - emit_OpFract(dst,src); -end; - -procedure TEmit_VOP1._emit_V_EXP_F32; -Var - dst:PsrRegSlot; - src:PsrRegNode; -begin - dst:=FRegsStory.get_vdst8(FSPI.VOP1.VDST); - src:=fetch_ssrc9(FSPI.VOP1.SRC0,dtFloat32); - emit_OpExp2(dst,src); + emit_OpExt1(OpId,dtFloat32,dst,src); end; procedure TEmit_VOP1._emit_V_RCP_F32; @@ -183,86 +105,48 @@ begin emit_OpFDiv(dst,one,src); end; -procedure TEmit_VOP1._emit_V_SIN_F32; -Var - dst:PsrRegSlot; - src:PsrRegNode; -begin - dst:=FRegsStory.get_vdst8(FSPI.VOP1.VDST); - src:=fetch_ssrc9(FSPI.VOP1.SRC0,dtFloat32); - emit_OpSin(dst,src); -end; - procedure TEmit_VOP1._emit_VOP1; begin Case FSPI.VOP1.OP of + V_NOP:; + V_MOV_B32: begin _emit_V_MOV_B32; end; - V_CVT_F32_I32: - begin - _emit_V_CVT_F32_I32; - end; - - V_CVT_I32_F32: - begin - _emit_V_CVT_I32_F32; - end; - - V_CVT_U32_F32: - begin - _emit_V_CVT_U32_F32; - end; - - V_CVT_F32_U32: - begin - _emit_V_CVT_F32_U32; - end; + 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_OFF_F32_I4: begin _emit_V_CVT_OFF_F32_I4; end; - V_SQRT_F32: - begin - _emit_V_SQRT_F32; - end; + 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_RSQ_F32: - begin - _emit_V_RSQ_F32; - end; + 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_FLOOR_F32: - begin - _emit_V_FLOOR_F32; - end; + V_RSQ_F32 : _emit_V_EXT_F32(GlslOp.InverseSqrt); - V_FRACT_F32: - begin - _emit_V_FRACT_F32; - end; + V_SQRT_F32 : _emit_V_EXT_F32(GlslOp.Sqrt); - V_EXP_F32: - begin - _emit_V_EXP_F32; - end; + V_SIN_F32 : _emit_V_EXT_F32(GlslOp.Sin); + V_COS_F32 : _emit_V_EXT_F32(GlslOp.Cos); V_RCP_F32: begin _emit_V_RCP_F32; end; - V_SIN_F32: - begin - _emit_V_SIN_F32; - end; - else Assert(false,'VOP1?'+IntToStr(FSPI.VOP1.OP)); end; diff --git a/spirv/emit_vop3.pas b/spirv/emit_vop3.pas index 7a2629e9..7f6c6d00 100644 --- a/spirv/emit_vop3.pas +++ b/spirv/emit_vop3.pas @@ -50,7 +50,7 @@ type procedure _emit_V_FMA_F32; procedure _emit_V_CUBE(OpId:DWORD); procedure _emit_V_MOV_B32; - procedure _emit_V_SQRT_F32; + procedure _emit_V_EXT_F32(OpId:DWORD); procedure _emit_V_RCP_F32; end; @@ -681,7 +681,7 @@ begin end; -procedure TEmit_VOP3._emit_V_SQRT_F32; +procedure TEmit_VOP3._emit_V_EXT_F32(OpId:DWORD); Var dst:PsrRegSlot; src:PsrRegNode; @@ -693,7 +693,7 @@ begin _emit_src_abs_bit(@src,1); _emit_src_neg_bit(@src,1); - emit_OpSqrt(dst,src); + emit_OpExt1(OpId,dtFloat32,dst,src); _emit_dst_omod_f(dst); _emit_dst_clamp_f(dst); @@ -868,6 +868,8 @@ end; procedure TEmit_VOP3._emit_VOP3a; begin + //VOP2 analog + Case FSPI.VOP3a.OP of 256+V_CNDMASK_B32: @@ -915,6 +917,8 @@ begin _emit_V_MAC_F32; end; + //VOP3 only + V_MUL_LO_I32: begin _emit_V_MUL_LO_I32; @@ -970,15 +974,29 @@ begin V_CUBETC_F32:_emit_V_CUBE(OpCUBETC); V_CUBEMA_F32:_emit_V_CUBE(OpCUBEMA); + //VOP1 analog + + 384+V_NOP:; + 384+V_MOV_B32: begin _emit_V_MOV_B32; end; - 384+V_SQRT_F32: - begin - _emit_V_SQRT_F32; - end; + 384+V_FRACT_F32: _emit_V_EXT_F32(GlslOp.Fract); + 384+V_TRUNC_F32: _emit_V_EXT_F32(GlslOp.Trunc); + 384+V_CEIL_F32 : _emit_V_EXT_F32(GlslOp.Ceil); + + 384+V_FLOOR_F32: _emit_V_EXT_F32(GlslOp.Floor); + 384+V_EXP_F32 : _emit_V_EXT_F32(GlslOp.Exp2); + 384+V_LOG_F32 : _emit_V_EXT_F32(GlslOp.Log2); + + 384+V_RSQ_F32 : _emit_V_EXT_F32(GlslOp.InverseSqrt); + + 384+V_SQRT_F32 : _emit_V_EXT_F32(GlslOp.Sqrt); + + 384+V_SIN_F32 : _emit_V_EXT_F32(GlslOp.Sin); + 384+V_COS_F32 : _emit_V_EXT_F32(GlslOp.Cos); 384+V_RCP_F32: begin