From 9da60ed0ca3c8e810adcf1b1b7b9204768fc76c9 Mon Sep 17 00:00:00 2001 From: Pavel <68122101+red-prig@users.noreply.github.com> Date: Fri, 1 Jul 2022 15:53:39 +0300 Subject: [PATCH] + --- chip/ps4_gpu_regs.pas | 5 ++++ chip/ps4_videodrv.pas | 15 ++++++++++-- ps4_libscesavedata.pas | 42 ++++++++++++++++++++++++++++++++ ps4_libscevideoout.pas | 53 ++++++++++++++++++++++++++++++++++++++++- spirv/emit_mimg.pas | 13 ++++++---- spirv/emit_op.pas | 8 +++++++ spirv/emit_post.pas | 2 +- spirv/emit_sopp.pas | 52 ++++++++++++++++++++++++++++++++++++++-- spirv/emit_vop1.pas | 43 +++++++++++++++++++++++++++++++++ spirv/emit_vop2.pas | 19 +++++++++++++++ spirv/emit_vop3.pas | 25 +++++++++++++++++++ spirv/srVolatile.pas | 2 +- vulkan/vImageTiling.pas | 3 +++ 13 files changed, 270 insertions(+), 12 deletions(-) diff --git a/chip/ps4_gpu_regs.pas b/chip/ps4_gpu_regs.pas index 25121e8..d66af48 100644 --- a/chip/ps4_gpu_regs.pas +++ b/chip/ps4_gpu_regs.pas @@ -1307,7 +1307,12 @@ begin IMG_DATA_FORMAT_32_32 :Result:=VK_FORMAT_R32G32_UINT; IMG_DATA_FORMAT_32_32_32 :Result:=VK_FORMAT_R32G32B32_UINT; IMG_DATA_FORMAT_32_32_32_32 :Result:=VK_FORMAT_R32G32B32A32_UINT; + IMG_DATA_FORMAT_FMASK8_S2_F1:Result:=VK_FORMAT_R8_UINT; + IMG_DATA_FORMAT_FMASK8_S4_F1:Result:=VK_FORMAT_R8_UINT; IMG_DATA_FORMAT_FMASK8_S8_F1:Result:=VK_FORMAT_R8_UINT; + IMG_DATA_FORMAT_FMASK8_S2_F2:Result:=VK_FORMAT_R8_UINT; + IMG_DATA_FORMAT_FMASK8_S4_F2:Result:=VK_FORMAT_R8_UINT; + IMG_DATA_FORMAT_FMASK8_S4_F4:Result:=VK_FORMAT_R8_UINT; else Assert(false,_get_tex_dfmt_str(PT^.dfmt)); end; diff --git a/chip/ps4_videodrv.pas b/chip/ps4_videodrv.pas index adccc0e..e67e63c 100644 --- a/chip/ps4_videodrv.pas +++ b/chip/ps4_videodrv.pas @@ -406,7 +406,13 @@ begin if (GFXMicroEngine.Current<>nil) then begin - if not me_node_test(GFXMicroEngine.Current) then + if me_node_test(GFXMicroEngine.Current) then + begin + if (GFXMicroEngine.Current^.mode=metCmdBuffer) then + begin + RTLEventSetEvent(FIdleEvent); + end; + end else begin time:=-100000; NtDelayExecution(True,@time); @@ -731,6 +737,9 @@ begin Case Body^.eventType of THREAD_TRACE_MARKER :Writeln(' THREAD_TRACE_MARKER'); FLUSH_AND_INV_CB_PIXEL_DATA:Writeln(' FLUSH_AND_INV_CB_PIXEL_DATA'); + FLUSH_AND_INV_DB_DATA_TS :Writeln(' FLUSH_AND_INV_DB_DATA_TS'); + FLUSH_AND_INV_DB_META :Writeln(' FLUSH_AND_INV_DB_META'); + FLUSH_AND_INV_CB_DATA_TS :Writeln(' FLUSH_AND_INV_CB_DATA_TS'); FLUSH_AND_INV_CB_META :Writeln(' FLUSH_AND_INV_CB_META'); else Assert(False,IntToStr(Body^.eventType)); @@ -2232,7 +2241,9 @@ function gfx_test(CmdBuffer:TvCmdBuffer):Boolean; begin Result:=True; if (CmdBuffer=nil) then Exit; - Result:=(CmdBuffer.ret<>0) or (CmdBuffer.Fence.Status=VK_SUCCESS); + Result:=(CmdBuffer.ret<>0) or + (CmdBuffer.cmd_count=0) or + (CmdBuffer.Fence.Status=VK_SUCCESS); if Result then begin CmdBuffer.ReleaseResource; diff --git a/ps4_libscesavedata.pas b/ps4_libscesavedata.pas index 798b060..8224add 100644 --- a/ps4_libscesavedata.pas +++ b/ps4_libscesavedata.pas @@ -116,6 +116,37 @@ type reserved:array[0..31] of Byte; end; + pSceSaveDataDirNameSearchCond=^SceSaveDataDirNameSearchCond; + SceSaveDataDirNameSearchCond=packed record + userId:Integer; + _align:Integer; + titleId:pSceSaveDataTitleId; + dirName:pSceSaveDataDirName; + key:DWORD; //SceSaveDataSortKey + order:DWORD; //SceSaveDataSortOrder + reserved:array[0..31] of Byte; + end; + + pSceSaveDataSearchInfo=^SceSaveDataSearchInfo; + SceSaveDataSearchInfo=packed record + blocks:QWORD; //SceSaveDataBlocks + freeBlocks:QWORD; //SceSaveDataBlocks + reserved:array[0..31] of Byte; + end; + + pSceSaveDataDirNameSearchResult=^SceSaveDataDirNameSearchResult; + SceSaveDataDirNameSearchResult=packed record + hitNum:DWORD; + _align:Integer; + dirNames:pSceSaveDataDirName; + dirNamesNum:DWORD; + setNum:DWORD; + params:pSceSaveDataParam; + infos:pSceSaveDataSearchInfo; + reserved:array[0..11] of Byte; + _align2:Integer; + end; + implementation uses @@ -210,6 +241,16 @@ begin end; end; +function ps4_sceSaveDataDirNameSearch(cond:pSceSaveDataDirNameSearchCond; + sres:pSceSaveDataDirNameSearchResult):Integer; SysV_ABI_CDecl; +begin + Result:=0; + if (sres<>nil) then + begin + sres^:=Default(SceSaveDataDirNameSearchResult); + end; +end; + type SceSaveDataParamType=DWORD; @@ -241,6 +282,7 @@ begin lib^.set_proc($D33E393C81FE48D2,@ps4_sceSaveDataMount2); lib^.set_proc($04C47817F51E9371,@ps4_sceSaveDataUmount); lib^.set_proc($EB9547D1069ACFAB,@ps4_sceSaveDataGetMountInfo); + lib^.set_proc($7722219D7ABFD123,@ps4_sceSaveDataDirNameSearch); lib^.set_proc($F39CEE97FFDE197B,@ps4_sceSaveDataSetParam); end; diff --git a/ps4_libscevideoout.pas b/ps4_libscevideoout.pas index 78cd5d3..7f3aa71 100644 --- a/ps4_libscevideoout.pas +++ b/ps4_libscevideoout.pas @@ -84,6 +84,11 @@ type pad1:array[0..6] of Byte; end; + pSceVideoOutDeviceCapabilityInfo=^SceVideoOutDeviceCapabilityInfo; + SceVideoOutDeviceCapabilityInfo=packed record + capability:QWORD; //SceVideoOutDeviceCapability + end; + const //SceVideoOutBufferAttributeOption SCE_VIDEO_OUT_BUFFER_ATTRIBUTE_OPTION_NONE = 0; @@ -1429,7 +1434,18 @@ begin end; function ps4_sceVideoOutSetWindowModeMargins(hVideo:Integer;top,bottom:Integer):Integer; SysV_ABI_CDecl; +var + H:TVideoOut; begin + _sig_lock; + H:=TVideoOut(FVideoOutMap.Acqure(hVideo)); + _sig_unlock; + if (H=nil) then Exit(SCE_VIDEO_OUT_ERROR_INVALID_HANDLE); + + _sig_lock; + H.Release; + _sig_unlock; + Result:=0; end; @@ -1556,13 +1572,47 @@ type pSceVideoOutConfigureOptions=^SceVideoOutConfigureOptions; -function ps4_sceVideoOutConfigureOutputMode_(handle:Integer; +function ps4_sceVideoOutConfigureOutputMode_(hVideo:Integer; reserved:DWORD; pMode:pSceVideoOutMode; pOptions:pSceVideoOutConfigureOptions; sizeOfMode:DWORD; sizeOfOptions:DWORD):Integer; SysV_ABI_CDecl; +var + H:TVideoOut; begin + _sig_lock; + H:=TVideoOut(FVideoOutMap.Acqure(hVideo)); + _sig_unlock; + if (H=nil) then Exit(SCE_VIDEO_OUT_ERROR_INVALID_HANDLE); + + _sig_lock; + H.Release; + _sig_unlock; + + Result:=0; +end; + +function ps4_sceVideoOutGetDeviceCapabilityInfo_(hVideo:Integer; + pInfo:pSceVideoOutDeviceCapabilityInfo; + sizeOfInfo:QWORD):Integer; SysV_ABI_CDecl; +var + H:TVideoOut; +begin + if (pInfo=nil) or (sizeOfInfo0) then //fragid T# 2D MSAA begin - Assert(false,'TODO'); - end; + smp:=fetch_vsrc8(FSPI.MIMG.VADDR+roffset,dtUint32); + Inc(roffset); + node^.AddLiteral(ImageOperands.Sample,'Sample'); + node^.AddParam(ntReg,smp); + end; end; IMAGE_LOAD_MIP: //All except MSAA begin @@ -625,6 +627,7 @@ begin lod:=fetch_vsrc8(FSPI.MIMG.VADDR+roffset,dtUint32); Inc(roffset); + node^.AddLiteral(ImageOperands.Lod,'Lod'); node^.AddParam(ntReg,lod); end; diff --git a/spirv/emit_op.pas b/spirv/emit_op.pas index 547753f..3306c6b 100644 --- a/spirv/emit_op.pas +++ b/spirv/emit_op.pas @@ -127,6 +127,7 @@ type procedure emit_OpNot(dst:PsrRegSlot;src:PsrRegNode); procedure emit_OpLogicalNot(dst:PsrRegSlot;src:PsrRegNode); procedure emit_OpBitwiseOr(dst:PsrRegSlot;src0,src1:PsrRegNode); + procedure emit_OpBitwiseXor(dst:PsrRegSlot;src0,src1:PsrRegNode); procedure emit_OpLogicalOr(dst:PsrRegSlot;src0,src1:PsrRegNode); procedure emit_OpBitwiseAnd(dst:PsrRegSlot;src0,src1:PsrRegNode); procedure emit_OpLogicalAnd(dst:PsrRegSlot;src0,src1:PsrRegNode); @@ -239,6 +240,8 @@ procedure TEmitOp.emit_OpStore(pLine:PspirvOp;dst:PsrVariable;src:PsrRegNode); Var p:TOpParamSingle; begin + if (dst^.dtype<>src^.dtype) then Assert(false); + dst^.mark_write; p.SetParam(ntVar,dst); emit_OpStore(pLine,p,src); @@ -1133,6 +1136,11 @@ begin emit_Op2(Op.OpBitwiseOr,dtUnknow{dtUint32},dst,src0,src1); end; +procedure TEmitOp.emit_OpBitwiseXor(dst:PsrRegSlot;src0,src1:PsrRegNode); +begin + emit_Op2(Op.OpBitwiseXor,{dtUnknow}dtUint32,dst,src0,src1); +end; + procedure TEmitOp.emit_OpLogicalOr(dst:PsrRegSlot;src0,src1:PsrRegNode); begin emit_Op2(Op.OpLogicalOr,dtBool,dst,src0,src1); diff --git a/spirv/emit_post.pas b/spirv/emit_post.pas index 35ab951..ad593bd 100644 --- a/spirv/emit_post.pas +++ b/spirv/emit_post.pas @@ -400,7 +400,7 @@ begin if (old<>node) then //is change? begin - if (node^.dtype=dtUnknow) or CompareType(node^.dtype,old^.dtype) then + if (node^.dtype=dtUnknow) or (node^.dtype=old^.dtype) then begin node:=old; //set new Inc(Result); diff --git a/spirv/emit_sopp.pas b/spirv/emit_sopp.pas index 3016ec0..59edf41 100644 --- a/spirv/emit_sopp.pas +++ b/spirv/emit_sopp.pas @@ -30,6 +30,7 @@ type procedure emit_block_unknow(adr:TSrcAdr); procedure UpBuildVol(last:PsrOpBlock); procedure emit_loop(adr:TSrcAdr); + procedure emit_loop_cond(pSlot:PsrRegSlot;n:Boolean;adr:TSrcAdr); end; implementation @@ -187,6 +188,53 @@ begin end; end; +procedure TEmit_SOPP.emit_loop_cond(pSlot:PsrRegSlot;n:Boolean;adr:TSrcAdr); +var + src:PsrRegNode; + node,pOpBlock:PsrOpBlock; + pOpLabel:array[0..1] of PspirvOp; + FVolMark:TsrVolMark; +begin + src:=MakeRead(pSlot,dtBool); + + node:=FMain^.pBlock; + pOpBlock:=node^.FindUpLoop; + Assert(pOpBlock<>nil,'not found'); + + pOpLabel[0]:=nil; + + FVolMark:=vmNone; + if (pOpBlock^.Block.b_adr.get_pc=adr.get_pc) then //is continue? + begin + pOpLabel[0]:=pOpBlock^.Labels.pMrgOp; //-> OpLoopMerge end -> OpLoopMerge before + pOpBlock^.Cond.FUseCont:=True; + FVolMark:=vmCont; + end else + if (pOpBlock^.Block.b_adr.get_pc=adr.get_pc) then //is break? + begin + pOpLabel[0]:=pOpBlock^.Labels.pEndOp; + FVolMark:=vmBreak; + end else + begin + Assert(false,'emit_loop'); + end; + + Assert(pOpLabel[0]<>nil); + pOpLabel[1]:=NewLabelOp; + + UpBuildVol(pOpBlock); + node^.Regs.FVolMark:=FVolMark; //mark end of + + emit_OpCondMerge(line,pOpLabel[1]); + + Case n of + True :emit_OpBranchCond(line,pOpLabel[0],pOpLabel[1],src); + False:emit_OpBranchCond(line,pOpLabel[1],pOpLabel[0],src); + end; + + AddSpirvOp(line,pOpLabel[1]); +end; + function TEmit_SOPP.IsBegLoop(Adr:TSrcAdr):Boolean; var node:PsrCFGBlock; @@ -242,13 +290,13 @@ begin if (SmallInt(FSPI.SOPP.SIMM)<0) then //up begin //continue? if not IsBegLoop(b_adr) then Assert(false,'Unknow'); - Assert(false,'TODO'); + emit_loop_cond(pSlot,n,b_adr); end else begin //down if FCursor.pBlock^.IsBigOf(b_adr) then begin //break? if not IsEndLoop(b_adr) then Assert(false,'Unknow'); - Assert(false,'TODO'); + emit_loop_cond(pSlot,n,b_adr); end else begin //cond emit_cond_block(pSlot,n,c_adr); diff --git a/spirv/emit_vop1.pas b/spirv/emit_vop1.pas index f933df0..4b82077 100644 --- a/spirv/emit_vop1.pas +++ b/spirv/emit_vop1.pas @@ -19,8 +19,10 @@ type procedure _emit_V_MOV_B32; procedure _emit_V_CVT(OpId:DWORD;dst_type,src_type:TsrDataType); procedure _emit_V_CVT_OFF_F32_I4; + procedure _emit_V_CVT_F32_UBYTE0; procedure _emit_V_EXT_F32(OpId:DWORD); procedure _emit_V_RCP_F32; + procedure _emit_V_FFBL_B32; end; implementation @@ -81,6 +83,25 @@ begin emit_OpFDiv(dst,subf,num_16); end; +procedure TEmit_VOP1._emit_V_CVT_F32_UBYTE0; +Var + dst,tmp:PsrRegSlot; + src:PsrRegNode; + num_FF:PsrRegNode; + +begin + dst:=FRegsStory.get_vdst8(FSPI.VOP1.VDST); + src:=fetch_ssrc9(FSPI.VOP1.SRC0,dtUInt32); + + tmp:=@FRegsStory.FUnattach; + num_FF:=FetchReg(FConsts.Fetch(dtUInt32,$FF)); + + emit_OpBitwiseAnd(tmp,src,num_FF); + src:=MakeRead(tmp,dtUInt32); + + emit_Op1(Op.OpConvertUToF,dtFloat32,dst,src); +end; + procedure TEmit_VOP1._emit_V_EXT_F32(OpId:DWORD); Var dst:PsrRegSlot; @@ -105,6 +126,18 @@ begin emit_OpFDiv(dst,one,src); end; +procedure TEmit_VOP1._emit_V_FFBL_B32; +Var + dst:PsrRegSlot; + src:PsrRegNode; +begin + dst:=FRegsStory.get_vdst8(FSPI.VOP1.VDST); + src:=fetch_ssrc9(FSPI.VOP1.SRC0,dtInt32); + + emit_OpExt1(GlslOp.FindILsb,dtInt32,dst,src); +end; + + procedure TEmit_VOP1._emit_VOP1; begin @@ -127,6 +160,11 @@ begin _emit_V_CVT_OFF_F32_I4; end; + V_CVT_F32_UBYTE0: + begin + _emit_V_CVT_F32_UBYTE0; + 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); @@ -147,6 +185,11 @@ begin _emit_V_RCP_F32; end; + V_FFBL_B32: + begin + _emit_V_FFBL_B32; + end; + else Assert(false,'VOP1?'+IntToStr(FSPI.VOP1.OP)); end; diff --git a/spirv/emit_vop2.pas b/spirv/emit_vop2.pas index 2c17d60..cac75c5 100644 --- a/spirv/emit_vop2.pas +++ b/spirv/emit_vop2.pas @@ -19,6 +19,7 @@ type procedure _emit_V_CNDMASK_B32; procedure _emit_V_AND_B32; procedure _emit_V_OR_B32; + procedure _emit_V_XOR_B32; procedure _emit_V_LSHL_B32; procedure _emit_V_LSHLREV_B32; procedure _emit_V_LSHR_B32; @@ -82,6 +83,19 @@ begin emit_OpBitwiseOr(dst,src[0],src[1]); end; +procedure TEmit_VOP2._emit_V_XOR_B32; +Var + dst:PsrRegSlot; + src:array[0..1] of PsrRegNode; +begin + dst:=FRegsStory.get_vdst8(FSPI.VOP2.VDST); + + src[0]:=fetch_ssrc9(FSPI.VOP2.SRC0 ,{dtUnknow}dtUInt32); + src[1]:=fetch_vsrc8(FSPI.VOP2.VSRC1,{dtUnknow}dtUInt32); + + emit_OpBitwiseXor(dst,src[0],src[1]); +end; + procedure TEmit_VOP2._emit_V_LSHL_B32; Var dst,tmp:PsrRegSlot; @@ -402,6 +416,11 @@ begin _emit_V_OR_B32; end; + V_XOR_B32: + begin + _emit_V_XOR_B32; + end; + V_LSHL_B32: begin _emit_V_LSHL_B32; diff --git a/spirv/emit_vop3.pas b/spirv/emit_vop3.pas index 7f6c6d0..1e6d8c6 100644 --- a/spirv/emit_vop3.pas +++ b/spirv/emit_vop3.pas @@ -37,6 +37,7 @@ type procedure _emit_V_MUL_LO_I32; procedure _emit_V_MUL_F32; procedure _emit_V_MUL_I32_I24; + procedure _emit_V_MUL_U32_U24; procedure _emit_V_MAC_F32; procedure _emit_V_BFE_U32; @@ -367,6 +368,25 @@ begin emit_OpIMul(dst,src[0],src[1]); end; +procedure TEmit_VOP3._emit_V_MUL_U32_U24; +Var + dst:PsrRegSlot; + src:array[0..1] of PsrRegNode; +begin + dst:=FRegsStory.get_vdst8(FSPI.VOP3a.VDST); + + Assert(FSPI.VOP3a.OMOD =0,'FSPI.VOP3a.OMOD'); + Assert(FSPI.VOP3a.ABS =0,'FSPI.VOP3a.ABS'); + Assert(FSPI.VOP3a.CLAMP=0,'FSPI.VOP3a.CLAMP'); + Assert(FSPI.VOP3a.NEG =0,'FSPI.VOP3a.NEG'); + + src[0]:=fetch_ssrc9(FSPI.VOP3a.SRC0,dtUInt32); + src[1]:=fetch_ssrc9(FSPI.VOP3a.SRC1,dtUInt32); + + //24bit mask TODO + emit_OpIMul(dst,src[0],src[1]); +end; + procedure TEmit_VOP3._emit_V_MAC_F32; //vdst = vsrc0.f * vsrc1.f + vdst.f -> fma Var dst:PsrRegSlot; @@ -912,6 +932,11 @@ begin _emit_V_MUL_I32_I24; end; + 256+V_MUL_U32_U24: + begin + _emit_V_MUL_U32_U24; + end; + 256+V_MAC_F32: begin _emit_V_MAC_F32; diff --git a/spirv/srVolatile.pas b/spirv/srVolatile.pas index 3697ed5..4d2032f 100644 --- a/spirv/srVolatile.pas +++ b/spirv/srVolatile.pas @@ -430,7 +430,7 @@ begin Assert(pReg^.pWriter.ntype<>ntVolatile);} - TSprvEmit_post(Self).PrepTypeNode(pReg,rtype); + TSprvEmit_post(Self).PrepTypeNode(pReg,rtype,False); {if pLine^.Adr.Offdw*4=$AC then begin diff --git a/vulkan/vImageTiling.pas b/vulkan/vImageTiling.pas index 686e8ba..55903e8 100644 --- a/vulkan/vImageTiling.pas +++ b/vulkan/vImageTiling.pas @@ -104,6 +104,9 @@ var buf:TvHostImage2; ImageCopy:TVkImageCopy; begin + + if (image.key.params.samples>ord(VK_SAMPLE_COUNT_1_BIT)) then Exit; + buf:=image.FetchHostImage(cmd,ord(VK_IMAGE_USAGE_TRANSFER_SRC_BIT) or ord(VK_IMAGE_USAGE_TRANSFER_DST_BIT));