diff --git a/chip/ps4_gpu_regs.pas b/chip/ps4_gpu_regs.pas index 17fa78f..d8a1696 100644 --- a/chip/ps4_gpu_regs.pas +++ b/chip/ps4_gpu_regs.pas @@ -895,14 +895,18 @@ begin Result.COMP_SWAP:=RENDER_TARGET[i].INFO.COMP_SWAP; - Result.IMAGE_USAGE:=(TM_CLEAR*RENDER_TARGET[i].INFO.FAST_CLEAR); - - if (Result.blend.blendEnable<>0) then + if (RENDER_TARGET[i].INFO.FAST_CLEAR<>0) then begin - Result.IMAGE_USAGE:=Result.IMAGE_USAGE or TM_READ; + Result.IMAGE_USAGE:=TM_CLEAR or TM_WRITE; + end else + begin + Result.IMAGE_USAGE:=TM_READ or TM_WRITE; end; - Result.IMAGE_USAGE:=Result.IMAGE_USAGE or TM_WRITE; + //if (Result.blend.blendEnable<>0) then + //begin + // Result.IMAGE_USAGE:=Result.IMAGE_USAGE or TM_READ; + //end; Case RENDER_TARGET[i].INFO.FORMAT of COLOR_8_8_8_8: diff --git a/chip/ps4_videodrv.pas b/chip/ps4_videodrv.pas index 07d1404..ff8a340 100644 --- a/chip/ps4_videodrv.pas +++ b/chip/ps4_videodrv.pas @@ -90,6 +90,7 @@ type Queue:TIntrusiveMPSCQueue; Current:PvSubmitNode; CmdBuffer:TvCmdBuffer; + submit_id:ptruint; SetShCount:ptruint; SetCxCount:ptruint; LastSetReg:WORD; @@ -174,6 +175,7 @@ begin begin FreeMem(Current); Current:=nil; + Inc(submit_id); end; LastSetReg:=0; @@ -190,6 +192,7 @@ begin if (CmdBuffer=nil) then begin CmdBuffer:=TvCmdBuffer.Create(FCmdPool,RenderQueue); + CmdBuffer.submit_id:=submit_id; end; end; @@ -1812,21 +1815,21 @@ begin RT_INFO.FImageInfo.params.samples:=1; - if (RT_INFO.IMAGE_USAGE and TM_READ)=0 then - begin - //RT_INFO.IMAGE_USAGE:=RT_INFO.IMAGE_USAGE or TM_CLEAR; - end; + //if (RT_INFO.IMAGE_USAGE and TM_READ)=0 then + //begin + // RT_INFO.IMAGE_USAGE:=RT_INFO.IMAGE_USAGE or TM_CLEAR; + //end; - if (RT_INFO.IMAGE_USAGE and TM_CLEAR)=0 then - begin - RT_INFO.IMAGE_USAGE:=RT_INFO.IMAGE_USAGE or TM_READ; - end; + //if (RT_INFO.IMAGE_USAGE and TM_CLEAR)=0 then + //begin + // RT_INFO.IMAGE_USAGE:=RT_INFO.IMAGE_USAGE or TM_READ; + //end; - if (RT_INFO.blend.blendEnable<>0) then - begin - //Exit(false); - //RT_INFO.IMAGE_USAGE:=RT_INFO.IMAGE_USAGE or TM_CLEAR; - end; + //if (RT_INFO.blend.blendEnable<>0) then + //begin + // Exit(false); + // RT_INFO.IMAGE_USAGE:=RT_INFO.IMAGE_USAGE or TM_CLEAR; + //end; //RT_INFO.IMAGE_USAGE:=RT_INFO.IMAGE_USAGE or TM_CLEAR; //RT_INFO.IMAGE_USAGE:=RT_INFO.IMAGE_USAGE and (not TM_READ); @@ -1841,9 +1844,9 @@ begin ); //if (RT_INFO.blend.blendEnable=0) then - begin - //ri.data_usage:=ri.data_usage and (not TM_READ); //reset read - end; + //begin + // ri.data_usage:=ri.data_usage and (not TM_READ); //reset read + //end; iv:=ri.FetchView(GFXRing.CmdBuffer,RT_INFO.FImageView); @@ -1923,7 +1926,7 @@ begin ord(VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) or ord(VK_IMAGE_USAGE_TRANSFER_SRC_BIT) or ord(VK_IMAGE_USAGE_TRANSFER_DST_BIT), - {DB_INFO.DEPTH_USAGE}0 + DB_INFO.DEPTH_USAGE ); //ri.data_usage:=ri.data_usage and (not TM_READ); //reset read diff --git a/fpPS4.lpr b/fpPS4.lpr index 6e3f253..423aabc 100644 --- a/fpPS4.lpr +++ b/fpPS4.lpr @@ -544,6 +544,12 @@ begin //ps4_app.app_path:='G:\Games\JETPACKJOYRIDE\CUSA03633\'; //ps4_app.app_file:='G:\Games\JETPACKJOYRIDE\CUSA03633\eboot.bin'; + //ps4_app.app_path:='C:\Users\User\Desktop\Games\Dont.Die.Mr.Robot\CUSA02782\'; + //ps4_app.app_file:='C:\Users\User\Desktop\Games\Dont.Die.Mr.Robot\CUSA02782\eboot.bin'; + + //ps4_app.app_path:='C:\Users\User\Desktop\Games\Patapon\CUSA07184\'; + //ps4_app.app_file:='C:\Users\User\Desktop\Games\Patapon\CUSA07184\eboot.bin'; + //elf:=Telf_file(LoadPs4ElfFromFile('libSceLibcInternal.sprx')); //elf.Prepare; //elf.SavePs4ElfToFile('libSceLibcInternal.prx'); diff --git a/ps4_libkernel/ps4_kernel_file.pas b/ps4_libkernel/ps4_kernel_file.pas index 78217bc..1a5ccaa 100644 --- a/ps4_libkernel/ps4_kernel_file.pas +++ b/ps4_libkernel/ps4_kernel_file.pas @@ -206,6 +206,8 @@ function ps4_read(fd:Integer;data:Pointer;size:DWORD):Integer; SysV_ABI_CDecl; function ps4_sceKernelMkdir(path:PChar;mode:Integer):Integer; SysV_ABI_CDecl; function ps4_mkdir(path:PChar):Integer; SysV_ABI_CDecl; +function ps4_sceKernelCheckReachability(path:PChar):Integer; SysV_ABI_CDecl; + implementation uses @@ -817,5 +819,32 @@ begin end; +function ps4_sceKernelCheckReachability(path:PChar):Integer; SysV_ABI_CDecl; +var + fn:RawByteString; +begin + Result:=0; + + if (path=nil) then Exit(SCE_KERNEL_ERROR_EINVAL); + if (path[0]=#0) then Exit(SCE_KERNEL_ERROR_ENOENT); + + Writeln('sceKernelCheckReachability:',path); + + _sig_lock; + fn:=_parse_filename(path); + _sig_unlock; + + if (fn='') then Exit(SCE_KERNEL_ERROR_EACCES); + + if FileExists(fn) or DirectoryExists(fn) then + begin + Result:=0; + end else + begin + Result:=SCE_KERNEL_ERROR_ENOENT; + end; + +end; + end. diff --git a/ps4_libkernel/ps4_libkernel.pas b/ps4_libkernel/ps4_libkernel.pas index 1b0da55..57ea3bb 100644 --- a/ps4_libkernel/ps4_libkernel.pas +++ b/ps4_libkernel/ps4_libkernel.pas @@ -1000,6 +1000,8 @@ begin lib^.set_proc($D7F2C52E6445C713,@ps4_sceKernelMkdir); lib^.set_proc($246322A3EDB52F87,@ps4_mkdir); + lib^.set_proc($B96C96DEFF7CB14E,@ps4_sceKernelCheckReachability); + //file px:=Result._add_lib('libScePosix'); diff --git a/ps4_libsceappcontent.pas b/ps4_libsceappcontent.pas index 2f5c469..0367ad6 100644 --- a/ps4_libsceappcontent.pas +++ b/ps4_libsceappcontent.pas @@ -16,6 +16,7 @@ type SceAppContentInitParam=packed record reserved:array[0..31] of Byte; end; + PSceAppContentBootParam=^SceAppContentBootParam; SceAppContentBootParam=packed record reserved1:array[0..3] of Byte; @@ -52,6 +53,24 @@ begin end; end; +const + SCE_APP_CONTENT_MOUNTPOINT_DATA_MAXSIZE=16; + SCE_APP_CONTENT_ADDCONT_MOUNT_MAXNUM =64; + + //E temporary data option + SCE_APP_CONTENT_TEMPORARY_DATA_OPTION_NONE =0; + SCE_APP_CONTENT_TEMPORARY_DATA_OPTION_FORMAT=1; + +type + pSceAppContentMountPoint=^SceAppContentMountPoint; + SceAppContentMountPoint=array[0..SCE_APP_CONTENT_MOUNTPOINT_DATA_MAXSIZE-1] of AnsiChar; + +function ps4_sceAppContentTemporaryDataMount2(option:DWORD;mountPoint:pSceAppContentMountPoint):Integer; SysV_ABI_CDecl; +begin + Result:=0; + Assert(false,'TODO'); +end; + function Load_libSceAppContent(Const name:RawByteString):TElf_node; var lib:PLIBRARY; @@ -63,6 +82,7 @@ begin lib^.set_proc($47D940F363AB68DB,@ps4_sceAppContentInitialize); lib^.set_proc($F7D6FCD88297A47E,@ps4_sceAppContentAppParamGetInt); + lib^.set_proc($6EE61B78B3865A60,@ps4_sceAppContentTemporaryDataMount2); end; diff --git a/ps4_libscedialogs.pas b/ps4_libscedialogs.pas index 5234884..0dc550e 100644 --- a/ps4_libscedialogs.pas +++ b/ps4_libscedialogs.pas @@ -247,6 +247,56 @@ begin Result:=0; //SCE_COMMON_DIALOG_STATUS_NONE end; +const + //SceNpCommercePsStoreIconPos + SCE_NP_COMMERCE_PS_STORE_ICON_CENTER=0; + SCE_NP_COMMERCE_PS_STORE_ICON_LEFT =1; + SCE_NP_COMMERCE_PS_STORE_ICON_RIGHT =2; + +function ps4_sceNpCommerceShowPsStoreIcon(pos:Integer):Integer; SysV_ABI_CDecl; +begin + Writeln('sceNpCommerceShowPsStoreIcon:',pos); + Result:=0; +end; + +// + +function ps4_sceSigninDialogInitialize():Integer; SysV_ABI_CDecl; +begin + Writeln('sceSigninDialogInitialize'); + Result:=0; +end; + +function ps4_sceSigninDialogTerminate():Integer; SysV_ABI_CDecl; +begin + Writeln('sceSigninDialogTerminate'); + Result:=0; +end; + +type + pSceSigninDialogParam=^SceSigninDialogParam; + SceSigninDialogParam=packed record + size:Integer; + userId:Integer; + reserved:array[0..1] of Integer; + end; + +const + SCE_SIGNIN_DIALOG_STATUS_NONE =0; + SCE_SIGNIN_DIALOG_STATUS_INITIALIZED=1; + SCE_SIGNIN_DIALOG_STATUS_RUNNING =2; + SCE_SIGNIN_DIALOG_STATUS_FINISHED =3; + +function ps4_sceSigninDialogOpen(param:pSceSigninDialogParam):Integer; SysV_ABI_CDecl; +begin + Result:=0; +end; + +function ps4_sceSigninDialogUpdateStatus:Integer; SysV_ABI_CDecl; +begin + Result:=SCE_SIGNIN_DIALOG_STATUS_FINISHED; +end; + // function Load_libSceCommonDialog(Const name:RawByteString):TElf_node; @@ -324,15 +374,30 @@ begin lib:=Result._add_lib('libSceNpCommerce'); lib^.set_proc($D1A4766969906A5E,@ps4_sceNpCommerceDialogInitialize); lib^.set_proc($2D1E5CC0530C0951,@ps4_sceNpCommerceDialogUpdateStatus); + lib^.set_proc($0C79B0B1AE92F137,@ps4_sceNpCommerceShowPsStoreIcon); +end; + +function Load_libSceSigninDialog(Const name:RawByteString):TElf_node; +var + lib:PLIBRARY; +begin + Result:=TElf_node.Create; + Result.pFileName:=name; + lib:=Result._add_lib('libSceSigninDialog'); + lib^.set_proc($9A56067E6A84DDF4,@ps4_sceSigninDialogInitialize); + lib^.set_proc($265A49568456BFB5,@ps4_sceSigninDialogOpen); + lib^.set_proc($070DF59624C54F70,@ps4_sceSigninDialogUpdateStatus); + lib^.set_proc($2D79664BA3EF25D5,@ps4_sceSigninDialogTerminate); end; initialization - ps4_app.RegistredPreLoad('libSceCommonDialog.prx',@Load_libSceCommonDialog); - ps4_app.RegistredPreLoad('libSceErrorDialog.prx',@Load_libSceErrorDialog); + ps4_app.RegistredPreLoad('libSceCommonDialog.prx' ,@Load_libSceCommonDialog); + ps4_app.RegistredPreLoad('libSceErrorDialog.prx' ,@Load_libSceErrorDialog); ps4_app.RegistredPreLoad('libSceNpProfileDialog.prx',@Load_libSceNpProfileDialog); - ps4_app.RegistredPreLoad('libSceSaveDataDialog.prx',@Load_libSceSaveDataDialog); - ps4_app.RegistredPreLoad('libSceMsgDialog.prx',@Load_libSceMsgDialog); - ps4_app.RegistredPreLoad('libSceNpCommerce.prx',@Load_libSceNpCommerce); + ps4_app.RegistredPreLoad('libSceSaveDataDialog.prx' ,@Load_libSceSaveDataDialog); + ps4_app.RegistredPreLoad('libSceMsgDialog.prx' ,@Load_libSceMsgDialog); + ps4_app.RegistredPreLoad('libSceNpCommerce.prx' ,@Load_libSceNpCommerce); + ps4_app.RegistredPreLoad('libSceSigninDialog.prx' ,@Load_libSceSigninDialog); end. diff --git a/ps4_libscenpmanager.pas b/ps4_libscenpmanager.pas index d9233a8..ec0f2e5 100644 --- a/ps4_libscenpmanager.pas +++ b/ps4_libscenpmanager.pas @@ -178,6 +178,25 @@ begin Result:=0; end; +function ps4_sceNpCreateRequest():Integer; SysV_ABI_CDecl; +begin + Result:=11; +end; + +function ps4_sceNpDeleteRequest(reqId:Integer):Integer; SysV_ABI_CDecl; +begin + Result:=0; +end; + +function ps4_sceNpCheckNpAvailability(reqId:Integer;onlineId:pSceNpOnlineId;pReserved:Pointer):Integer; SysV_ABI_CDecl; +begin + onlineId^:=Default(SceNpOnlineId); + onlineId^.data:='user'; + Result:=0; +end; + +// + function ps4_sceNpCheckCallbackForLib():Integer; SysV_ABI_CDecl; begin if (Cb4Toolkit.callback<>nil) then @@ -281,6 +300,9 @@ begin lib^.set_proc($55F45298F9A3F10F,@ps4_sceNpRegisterStateCallback); lib^.set_proc($B8526968A341023E,@ps4_sceNpRegisterGamePresenceCallback); lib^.set_proc($1889880A787E6E80,@ps4_sceNpRegisterPlusEventCallback); + lib^.set_proc($1A92D00CD28809A7,@ps4_sceNpCreateRequest); + lib^.set_proc($4BB4139FBD8FAC3C,@ps4_sceNpDeleteRequest); + lib^.set_proc($DABB059A519695E4,@ps4_sceNpCheckNpAvailability); lib:=Result._add_lib('libSceNpManagerForToolkit'); lib^.set_proc($D1CEC76D744A52DE,@ps4_sceNpRegisterStateCallbackForToolkit); @@ -302,7 +324,7 @@ end; initialization ps4_app.RegistredPreLoad('libSceNpManager.prx',@Load_libSceNpManager); - ps4_app.RegistredPreLoad('libSceNpCommon.prx',@Load_libSceNpCommon); + ps4_app.RegistredPreLoad('libSceNpCommon.prx' ,@Load_libSceNpCommon); end. diff --git a/ps4_libscepad.pas b/ps4_libscepad.pas index b377574..4b2571b 100644 --- a/ps4_libscepad.pas +++ b/ps4_libscepad.pas @@ -344,6 +344,16 @@ begin Result:=0; end; +function ps4_scePadResetOrientation(handle:Integer):Integer; SysV_ABI_CDecl; +begin + Result:=0; +end; + +function ps4_scePadSetTiltCorrectionState(handle:Integer;bEnable:BOOL):Integer; SysV_ABI_CDecl; +begin + Result:=0; +end; + function Load_libScePad(Const name:RawByteString):TElf_node; var lib:PLIBRARY; @@ -363,6 +373,8 @@ begin lib^.set_proc($8233FDFCA433A149,@ps4_scePadGetControllerInformation); lib^.set_proc($72556F2F86439EDC,@ps4_scePadSetMotionSensorState); lib^.set_proc($451E27A2F50410D6,@ps4_scePadSetLightBar); + lib^.set_proc($AC866747A792A6F9,@ps4_scePadResetOrientation); + lib^.set_proc($BC32CCA092DD7BC2,@ps4_scePadSetTiltCorrectionState); end; initialization diff --git a/ps4_libsceuserservice.pas b/ps4_libsceuserservice.pas index 6cb450f..c4aab0b 100644 --- a/ps4_libsceuserservice.pas +++ b/ps4_libsceuserservice.pas @@ -45,6 +45,11 @@ begin Result:=0; end; +function ps4_sceUserServiceInitialize2(threadPriority:Integer;cpuAffinityMask:qword):Integer; SysV_ABI_CDecl; +begin + Result:=0; +end; + function ps4_sceUserServiceTerminate:Integer; SysV_ABI_CDecl; begin Result:=0; @@ -102,6 +107,7 @@ begin lib:=Result._add_lib('libSceUserService'); lib^.set_proc($8F760CBB531534DA,@ps4_sceUserServiceInitialize); + lib^.set_proc($6B3FF447A7AF899D,@ps4_sceUserServiceInitialize2); lib^.set_proc($6F01634BE6D7F660,@ps4_sceUserServiceTerminate); lib^.set_proc($7CF87298A36F2BF0,@ps4_sceUserServiceGetLoginUserIdList); lib^.set_proc($09D5A9D281D61ABD,@ps4_sceUserServiceGetInitialUser); diff --git a/ps4_libscevideoout.pas b/ps4_libscevideoout.pas index d7724cc..87a180c 100644 --- a/ps4_libscevideoout.pas +++ b/ps4_libscevideoout.pas @@ -1114,7 +1114,7 @@ begin //SwSaveTime(t1); - if (time<>0) then + if (time>100) then begin ps4_usleep(time); end; diff --git a/spirv/SprvEmit.pas b/spirv/SprvEmit.pas index 4937bba..349d74d 100644 --- a/spirv/SprvEmit.pas +++ b/spirv/SprvEmit.pas @@ -344,7 +344,8 @@ begin pOpChild^.SetInfo(Info); PushBlockOp(line,pOpChild,nil); end; - btAdr: //skip + btAdr, + btAdrBranch: //skip begin adr:=pLBlock^.pELabel^.Adr; FCursor.Adr:=adr; @@ -487,6 +488,7 @@ begin if (pChild=nil) then Exit; Case pChild^.Block.bType of btAdr, + btAdrBranch, btOther:; else Exit; @@ -499,115 +501,145 @@ var pOpBlock:PsrOpBlock; pOpChild:PsrOpBlock; pOpLabel:array[0..2] of PspirvOp; + + branch_up:Boolean; + + procedure pop_cond; + begin + Assert(pOpLabel[1]<>nil); + + Case pOpBlock^.Regs.FVolMark of + vmNone:TEmitVolatile(Self).build_volatile_cur(pOpBlock^.Regs.pSnap); + vmEnd :TEmitVolatile(Self).build_volatile_dis(pOpBlock^.Regs.pSnap); + else; + end; + + if not is_term_op(line) then + begin + TEmitOp(Self).emit_OpBranch(line,pOpLabel[1]); + end; + + AddSpirvOp(line,pOpLabel[1]); //end + end; + + procedure pop_loop; + begin + //add OpLoopMerge continue + + Assert(pOpLabel[0]<>nil); + Assert(pOpLabel[1]<>nil); + Assert(pOpLabel[2]<>nil); + + Case pOpBlock^.Regs.FVolMark of + vmNone:TEmitVolatile(Self).build_volatile_old(pOpBlock^.Regs.pSnap); + else; + end; + + if pOpBlock^.Cond.FUseCont then //use continue + begin + + if not is_term_op(line) then + begin + TEmitOp(Self).emit_OpBranch(line,pOpLabel[1]); //break + end; + + AddSpirvOp(line,pOpLabel[2]); //OpLoopMerge end + + pOpChild:=AllocBlockOp; + pOpChild^.SetInfo(btOther,FCursor.Adr,FCursor.Adr); + PushBlockOp(line,pOpChild,nil); + TEmitOp(Self).emit_OpBranch(line,pOpLabel[0]); //continue + FMain^.PopBlock; + + AddSpirvOp(line,pOpLabel[1]); //end + + end else //dont used continue + begin + + if not is_term_op(line) then + begin + AddSpirvOp(line,NewLabelOp); //devide + end; + + AddSpirvOp(line,pOpLabel[2]); //OpLoopMerge end + + pOpChild:=AllocBlockOp; + pOpChild^.SetInfo(btOther,FCursor.Adr,FCursor.Adr); + PushBlockOp(line,pOpChild,nil); + TEmitOp(Self).emit_OpBranch(line,pOpLabel[1]); //break + FMain^.PopBlock; + + AddSpirvOp(line,pOpLabel[1]); //end + + end; + + end; + + procedure pop_else; + begin + if (pOpLabel[1]<>nil) then + begin + if not is_term_op(line) then + begin + TEmitOp(Self).emit_OpBranch(line,pOpLabel[1]); + end; + AddSpirvOp(line,pOpLabel[1]); + end; + end; + begin Result:=False; if (FMain=nil) then Exit; - if (FMain^.pBlock=nil) then Exit; - pOpBlock:=FMain^.pBlock; - UpdateVolMark(pOpBlock); + branch_up:=False; - pOpLabel[0]:=pOpBlock^.Labels.pBegOp; - pOpLabel[1]:=pOpBlock^.Labels.pEndOp; - pOpLabel[2]:=pOpBlock^.Labels.pMrgOp; + repeat - Case pOpBlock^.Block.bType of - btCond: - begin + pOpBlock:=FMain^.pBlock; + if (pOpBlock=nil) then Exit; - Assert(pOpLabel[1]<>nil); + UpdateVolMark(pOpBlock); - Case pOpBlock^.Regs.FVolMark of - vmNone:TEmitVolatile(Self).build_volatile_cur(pOpBlock^.Regs.pSnap); - vmEnd :TEmitVolatile(Self).build_volatile_dis(pOpBlock^.Regs.pSnap); - else; - end; + pOpLabel[0]:=pOpBlock^.Labels.pBegOp; + pOpLabel[1]:=pOpBlock^.Labels.pEndOp; + pOpLabel[2]:=pOpBlock^.Labels.pMrgOp; - if not is_term_op(line) then + Case pOpBlock^.Block.bType of + btCond: begin - TEmitOp(Self).emit_OpBranch(line,pOpLabel[1]); + pop_cond; + branch_up:=False; end; - - AddSpirvOp(line,pOpLabel[1]); //end - - end; - btLoop: - begin - - //add OpLoopMerge continue - - Assert(pOpLabel[0]<>nil); - Assert(pOpLabel[1]<>nil); - Assert(pOpLabel[2]<>nil); - - Case pOpBlock^.Regs.FVolMark of - vmNone:TEmitVolatile(Self).build_volatile_old(pOpBlock^.Regs.pSnap); - else; - end; - - if pOpBlock^.Cond.FUseCont then //use continue + btLoop: begin - - if not is_term_op(line) then - begin - TEmitOp(Self).emit_OpBranch(line,pOpLabel[1]); //break - end; - - AddSpirvOp(line,pOpLabel[2]); //OpLoopMerge end - - pOpChild:=AllocBlockOp; - pOpChild^.SetInfo(btOther,FCursor.Adr,FCursor.Adr); - PushBlockOp(line,pOpChild,nil); - TEmitOp(Self).emit_OpBranch(line,pOpLabel[0]); //continue - FMain^.PopBlock; - - AddSpirvOp(line,pOpLabel[1]); //end - - end else //dont used continue - begin - - if not is_term_op(line) then - begin - AddSpirvOp(line,NewLabelOp); //devide - end; - - AddSpirvOp(line,pOpLabel[2]); //OpLoopMerge end - - pOpChild:=AllocBlockOp; - pOpChild^.SetInfo(btOther,FCursor.Adr,FCursor.Adr); - PushBlockOp(line,pOpChild,nil); - TEmitOp(Self).emit_OpBranch(line,pOpLabel[1]); //break - FMain^.PopBlock; - - AddSpirvOp(line,pOpLabel[1]); //end - + pop_loop; + branch_up:=False; end; + else + pop_else; + end; - end; - else - if (pOpLabel[1]<>nil) then - begin - if not is_term_op(line) then + Case pOpBlock^.Block.bType of + btAdr: begin - TEmitOp(Self).emit_OpBranch(line,pOpLabel[1]); + FCursor:=pOpBlock^.FCursor; end; - AddSpirvOp(line,pOpLabel[1]); - end; - end; + btAdrBranch: + begin + FCursor:=pOpBlock^.FCursor; + branch_up:=True; + end; + btOther:; //nop + else + begin + FCursor.PopBlock; + end; + end; - Case pOpBlock^.Block.bType of - btAdr: - begin - FCursor:=pOpBlock^.FCursor; - end; - btOther:; //nop - else - begin - FCursor.PopBlock; - end; - end; + Result:=FMain^.PopBlock; + + until (not branch_up) or (not Result); - Result:=FMain^.PopBlock; end; function TSprvEmit.NewSpirvOp(OpId:DWORD):PSpirvOp; @@ -823,7 +855,7 @@ begin TEmitOp(Self).emit_OpStore(line,dst,pReg); pReg^.pLine:=line; //update line - pReg^.pWriter.SetParam(ntReg,src); + pReg^.SetReg(src); end; procedure TSprvEmit.AddUserdata(dst:PsrRegSlot;offset_dw:Byte); @@ -1461,7 +1493,7 @@ var node:PsrRegNode; begin node:=dst^.New(line,src^.dtype); - node^.pWriter.SetParam(ntReg,src); + node^.SetReg(src); dst^.current^.mark_read; PostReg(dst^.current); //post processing @@ -1595,7 +1627,7 @@ begin pReg^.pLine :=node^.pLine; pReg^.pWriter:=node^.pWriter; pReg^.mark_read; - node^.pWriter.SetParam(ntReg,pReg); + node^.SetReg(pReg); rtype:=ctype; end; end; diff --git a/spirv/emit_alloc.pas b/spirv/emit_alloc.pas index e12b1fd..6c2fbff 100644 --- a/spirv/emit_alloc.pas +++ b/spirv/emit_alloc.pas @@ -379,6 +379,7 @@ procedure TSprvEmit_alloc.AllocOpId(node:PSpirvOp); var Param:POpParamNode; Info:Op.TOpInfo; + pReg:PsrRegNode; begin if (node=nil) then Exit; @@ -400,7 +401,13 @@ begin if Info.rstype then //dst type begin - Assert(node^.dst_type<>nil,'AllocOp$4'); + if (node^.dst_type=nil) then + begin + pReg:=node^.dst.AsReg; + if (pReg^.dtype=dtUnknow) then pReg^.dtype:=dtFloat32; + node^.dst_type:=FSpirvTypes.Fetch(pReg^.dtype); + //Assert(false,'AllocOp$4'); + end; end; Param:=node^.pParam.pHead; diff --git a/spirv/emit_op.pas b/spirv/emit_op.pas index 3306c6b..a0e357a 100644 --- a/spirv/emit_op.pas +++ b/spirv/emit_op.pas @@ -224,6 +224,7 @@ Var begin p.SetParam(ntVar,src); dtype:=FSpirvTypes.Fetch(dst^.dtype); + //Assert(dtype<>nil); emit_OpLoad(pLine,dtype,dst,p); end; @@ -891,7 +892,7 @@ begin end else begin p^.pReg^.mark_read; - dst^.pWriter.SetParam(ntReg,p^.pReg); + dst^.SetReg(p^.pReg); //deref For i:=0 to count-1 do begin diff --git a/spirv/emit_post.pas b/spirv/emit_post.pas index ad593bd..78265a9 100644 --- a/spirv/emit_post.pas +++ b/spirv/emit_post.pas @@ -362,7 +362,7 @@ begin end else begin //save to another step node^.mark_read; - node^.pWriter.SetParam(ntReg,old); + node^.SetReg(old); end; end; end; @@ -573,7 +573,7 @@ begin if (src=nil) or (dst=nil) then Exit; src^.mark_read; - dst^.pWriter.SetParam(ntReg,src); + dst^.SetReg(src); node^.OpId:=OpLinks; //mark remove node^.dst:=Default(TOpParamSingle); diff --git a/spirv/emit_post_op.pas b/spirv/emit_post_op.pas index 0895873..98f6088 100644 --- a/spirv/emit_post_op.pas +++ b/spirv/emit_post_op.pas @@ -179,7 +179,7 @@ var procedure _SetReg(src:PsrRegNode); begin src^.mark_read; - dst^.pWriter.SetParam(ntReg,src); + dst^.SetReg(src); node^.OpId:=OpLinks; //mark remove node^.dst:=Default(TOpParamSingle); Inc(Result); @@ -336,7 +336,7 @@ var procedure _SetReg(src:PsrRegNode); begin src^.mark_read; - dst^.pWriter.SetParam(ntReg,src); + dst^.SetReg(src); node^.OpId:=OpLinks; //mark remove node^.dst:=Default(TOpParamSingle); Inc(Result); @@ -416,7 +416,7 @@ var procedure _SetReg(src:PsrRegNode); begin src^.mark_read; - dst^.pWriter.SetParam(ntReg,src); + dst^.SetReg(src); node^.OpId:=OpLinks; //mark remove node^.dst:=Default(TOpParamSingle); Inc(Result); @@ -542,7 +542,7 @@ var procedure _SetReg(src:PsrRegNode); begin src^.mark_read; - dst^.pWriter.SetParam(ntReg,src); + dst^.SetReg(src); node^.OpId:=OpLinks; //mark remove node^.dst:=Default(TOpParamSingle); Inc(Result); @@ -748,7 +748,7 @@ var procedure _SetReg(src:PsrRegNode); begin src^.mark_read; - dst^.pWriter.SetParam(ntReg,src); + dst^.SetReg(src); node^.OpId:=OpLinks; //mark remove node^.dst:=Default(TOpParamSingle); Inc(Result); @@ -1020,7 +1020,7 @@ var procedure _SetReg(src:PsrRegNode); begin src^.mark_read; - dst^.pWriter.SetParam(ntReg,src); + dst^.SetReg(src); node^.OpId:=OpLinks; //mark remove node^.dst:=Default(TOpParamSingle); Inc(Result); @@ -1337,7 +1337,7 @@ var procedure _SetReg(src:PsrRegNode); begin src^.mark_read; - dst^.pWriter.SetParam(ntReg,src); + dst^.SetReg(src); node^.OpId:=OpLinks; //mark remove node^.dst:=Default(TOpParamSingle); Inc(Result); @@ -1483,7 +1483,7 @@ var procedure _SetReg(src:PsrRegNode); begin src^.mark_read; - dst^.pWriter.SetParam(ntReg,src); + dst^.SetReg(src); node^.OpId:=OpLinks; //mark remove node^.dst:=Default(TOpParamSingle); Inc(Result); @@ -1867,7 +1867,7 @@ begin end; h:=FConsts.Fetch_vec(rtype,count,@nodes); - dst^.pWriter.SetParam(ntConst,h); + dst^.SetConst(h); end; procedure TEmitPostOp.MakeVecOne(dst:PsrRegNode;src:PPsrRegNode); @@ -1878,7 +1878,7 @@ begin pLine:=src[0]^.AsOp; rsrc:=pLine^.ParamNode(0)^.AsReg; rsrc^.mark_read; - dst^.pWriter.SetParam(ntReg,rsrc); + dst^.SetReg(rsrc); end; function TEmitPostOp.MakeVecComp(pLine:PSpirvOp;rtype:TsrDataType;dst:PsrRegNode;count:Byte;src:PPsrRegNode):PSpirvOp; diff --git a/spirv/emit_print.pas b/spirv/emit_print.pas index 79e27b0..51637f7 100644 --- a/spirv/emit_print.pas +++ b/spirv/emit_print.pas @@ -595,7 +595,7 @@ begin if (node^.key.dtype=dtUnknow) then begin Write('; '); - PrintConstId(node); + //PrintConstId(node); Writeln(' = dtUnknow: read_count=',node^.read_count,' value=',node^.Data); end else //Assert(node^.dtype<>dtUnknow); diff --git a/spirv/emit_sop2.pas b/spirv/emit_sop2.pas index c90d977..6e6ea51 100644 --- a/spirv/emit_sop2.pas +++ b/spirv/emit_sop2.pas @@ -232,15 +232,16 @@ end; procedure TEmit_SOP2._emit_S_CSELECT_B32; //sdst = SCC ? ssrc0 : ssrc1 Var dst:PsrRegSlot; - src:array[0..2] of PsrRegNode; + src:array[0..1] of PsrRegNode; + scc:PsrRegNode; begin dst:=FRegsStory.get_sdst7(FSPI.SOP2.SDST); src[0]:=fetch_ssrc9(FSPI.SOP2.SSRC0,dtUnknow); src[1]:=fetch_ssrc9(FSPI.SOP2.SSRC1,dtUnknow); - src[2]:=MakeRead(@FRegsStory.SCC,dtBool); + scc:=MakeRead(@FRegsStory.SCC,dtBool); - emit_OpSelect(dst,src[0],src[1],src[2]); + emit_OpSelect(dst,src[0],src[1],scc); end; procedure TEmit_SOP2._emit_S_CSELECT_B64; //sdst[2] = SCC ? ssrc0[2] : ssrc1[2] @@ -251,8 +252,8 @@ Var begin if not FRegsStory.get_sdst7_pair(FSPI.SOP2.SDST,@dst) then Assert(False); - if not fetch_ssrc9_pair(@src0,FSPI.SOP2.SSRC0,dtUInt32) then Assert(False); - if not fetch_ssrc9_pair(@src1,FSPI.SOP2.SSRC1,dtUInt32) then Assert(False); + if not fetch_ssrc9_pair(@src0,FSPI.SOP2.SSRC0,dtUnknow) then Assert(False); + if not fetch_ssrc9_pair(@src1,FSPI.SOP2.SSRC1,dtUnknow) then Assert(False); scc:=MakeRead(@FRegsStory.SCC,dtBool); scc^.mark_read; diff --git a/spirv/emit_sopp.pas b/spirv/emit_sopp.pas index 59edf41..73ad8e8 100644 --- a/spirv/emit_sopp.pas +++ b/spirv/emit_sopp.pas @@ -315,20 +315,20 @@ begin Info:=Default(TsrBlockInfo); c_adr:=FCursor.Adr; //get current - SetPtr(adr.get_pc,btAdr); //set new + SetPtr(adr.get_pc,btAdrBranch); //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; + Info.bType:=btAdrBranch; //down group pOpChild:=AllocBlockOp; pOpChild^.SetInfo(Info); PushBlockOp(line,pOpChild,nil); - SetPtr(adr.get_pc,btAdr); + SetPtr(adr.get_pc,btAdrBranch); end; procedure TEmit_SOPP._emit_S_BRANCH; diff --git a/spirv/emit_vop2.pas b/spirv/emit_vop2.pas index cac75c5..838b7d9 100644 --- a/spirv/emit_vop2.pas +++ b/spirv/emit_vop2.pas @@ -7,6 +7,7 @@ interface uses sysutils, ps4_pssl, + spirv, srTypes, srConst, srReg, @@ -37,8 +38,7 @@ type procedure _emit_V_MAC_F32; procedure _emit_V_MADAK_F32; procedure _emit_V_MADMK_F32; - procedure _emit_V_MIN_F32; - procedure _emit_V_MAX_F32; + procedure _emit_V_MIN_MAX(OpId:DWORD;rtype:TsrDataType); end; implementation @@ -370,30 +370,17 @@ begin emit_OpFmaF32(dst,src[0],src[1],src[2]); end; -procedure TEmit_VOP2._emit_V_MIN_F32; +procedure TEmit_VOP2._emit_V_MIN_MAX(OpId:DWORD;rtype:TsrDataType); Var dst:PsrRegSlot; src:array[0..1] of PsrRegNode; begin dst:=FRegsStory.get_vdst8(FSPI.VOP2.VDST); - src[0]:=fetch_ssrc9(FSPI.VOP2.SRC0 ,dtFloat32); - src[1]:=fetch_vsrc8(FSPI.VOP2.VSRC1,dtFloat32); + src[0]:=fetch_ssrc9(FSPI.VOP2.SRC0 ,rtype); + src[1]:=fetch_vsrc8(FSPI.VOP2.VSRC1,rtype); - emit_OpFMin(dst,src[0],src[1]); -end; - -procedure TEmit_VOP2._emit_V_MAX_F32; -Var - dst:PsrRegSlot; - src:array[0..1] of PsrRegNode; -begin - dst:=FRegsStory.get_vdst8(FSPI.VOP2.VDST); - - src[0]:=fetch_ssrc9(FSPI.VOP2.SRC0 ,dtFloat32); - src[1]:=fetch_vsrc8(FSPI.VOP2.VSRC1,dtFloat32); - - emit_OpFMax(dst,src[0],src[1]); + emit_OpExt2(OpId,rtype,dst,src[0],src[1]); end; procedure TEmit_VOP2._emit_VOP2; @@ -510,15 +497,17 @@ begin _emit_V_MADMK_F32; end; - V_MIN_F32: - begin - _emit_V_MIN_F32; - end; + V_MIN_LEGACY_F32:_emit_V_MIN_MAX(GlslOp.NMin,dtFloat32); + V_MAX_LEGACY_F32:_emit_V_MIN_MAX(GlslOp.NMax,dtFloat32); - V_MAX_F32: - begin - _emit_V_MAX_F32; - end; + V_MIN_F32:_emit_V_MIN_MAX(GlslOp.FMin,dtFloat32); + V_MAX_F32:_emit_V_MIN_MAX(GlslOp.FMax,dtFloat32); + + V_MIN_I32:_emit_V_MIN_MAX(GlslOp.SMin,dtInt32); + V_MAX_I32:_emit_V_MIN_MAX(GlslOp.SMax,dtInt32); + + V_MIN_U32:_emit_V_MIN_MAX(GlslOp.UMin,dtUint32); + V_MAX_U32:_emit_V_MIN_MAX(GlslOp.UMax,dtUint32); else Assert(false,'VOP2?'+IntToStr(FSPI.VOP2.OP)); diff --git a/spirv/emit_vop3.pas b/spirv/emit_vop3.pas index 30e7a4a..b8f3f46 100644 --- a/spirv/emit_vop3.pas +++ b/spirv/emit_vop3.pas @@ -32,8 +32,7 @@ type procedure _emit_V_ADD_F32; procedure _emit_V_SUB_F32; procedure _emit_V_CVT_PKRTZ_F16_F32; - procedure _emit_V_MIN_F32; - procedure _emit_V_MAX_F32; + procedure _emit_V_MIN_MAX_F32(OpId:DWORD); procedure _emit_V_MUL_LO_I32; procedure _emit_V_MUL_F32; procedure _emit_V_MUL_I32_I24; @@ -276,7 +275,7 @@ begin _emit_ConvFloatToHalf(dst,src[0],src[1]); end; -procedure TEmit_VOP3._emit_V_MIN_F32; +procedure TEmit_VOP3._emit_V_MIN_MAX_F32(OpId:DWORD); Var dst:PsrRegSlot; src:array[0..1] of PsrRegNode; @@ -289,26 +288,7 @@ begin _emit_src_abs_bit(@src,2); _emit_src_neg_bit(@src,2); - emit_OpFMin(dst,src[0],src[1]); - - _emit_dst_omod_f(dst); - _emit_dst_clamp_f(dst); -end; - -procedure TEmit_VOP3._emit_V_MAX_F32; -Var - dst:PsrRegSlot; - src:array[0..1] of PsrRegNode; -begin - dst:=FRegsStory.get_vdst8(FSPI.VOP3a.VDST); - - src[0]:=fetch_ssrc9(FSPI.VOP3a.SRC0,dtFloat32); - src[1]:=fetch_ssrc9(FSPI.VOP3a.SRC1,dtFloat32); - - _emit_src_abs_bit(@src,2); - _emit_src_neg_bit(@src,2); - - emit_OpFMax(dst,src[0],src[1]); + emit_OpExt2(OpId,dtFloat32,dst,src[0],src[1]); _emit_dst_omod_f(dst); _emit_dst_clamp_f(dst); @@ -353,10 +333,12 @@ end; procedure TEmit_VOP3._emit_V_MUL_I32_I24; Var - dst:PsrRegSlot; + dst,tmp:PsrRegSlot; src:array[0..1] of PsrRegNode; + bit24:PsrRegNode; begin dst:=FRegsStory.get_vdst8(FSPI.VOP3a.VDST); + tmp:=@FRegsStory.FUnattach; Assert(FSPI.VOP3a.OMOD =0,'FSPI.VOP3a.OMOD'); Assert(FSPI.VOP3a.ABS =0,'FSPI.VOP3a.ABS'); @@ -366,16 +348,27 @@ begin src[0]:=fetch_ssrc9(FSPI.VOP3a.SRC0,dtInt32); src[1]:=fetch_ssrc9(FSPI.VOP3a.SRC1,dtInt32); - //24bit mask TODO + bit24:=FetchReg(FConsts.Fetch(dtUInt32,$FFFFFF)); + + emit_OpBitwiseAnd(tmp,src[0],bit24); + src[0]:=MakeRead(tmp,dtInt32); + + bit24^.mark_read; + + emit_OpBitwiseAnd(tmp,src[1],bit24); + src[1]:=MakeRead(tmp,dtInt32); + emit_OpIMul(dst,src[0],src[1]); end; procedure TEmit_VOP3._emit_V_MUL_U32_U24; Var - dst:PsrRegSlot; + dst,tmp:PsrRegSlot; src:array[0..1] of PsrRegNode; + bit24:PsrRegNode; begin dst:=FRegsStory.get_vdst8(FSPI.VOP3a.VDST); + tmp:=@FRegsStory.FUnattach; Assert(FSPI.VOP3a.OMOD =0,'FSPI.VOP3a.OMOD'); Assert(FSPI.VOP3a.ABS =0,'FSPI.VOP3a.ABS'); @@ -385,7 +378,16 @@ begin src[0]:=fetch_ssrc9(FSPI.VOP3a.SRC0,dtUInt32); src[1]:=fetch_ssrc9(FSPI.VOP3a.SRC1,dtUInt32); - //24bit mask TODO + bit24:=FetchReg(FConsts.Fetch(dtUInt32,$FFFFFF)); + + emit_OpBitwiseAnd(tmp,src[0],bit24); + src[0]:=MakeRead(tmp,dtUInt32); + + bit24^.mark_read; + + emit_OpBitwiseAnd(tmp,src[1],bit24); + src[1]:=MakeRead(tmp,dtUInt32); + emit_OpIMul(dst,src[0],src[1]); end; @@ -423,7 +425,7 @@ begin src[0]:=fetch_ssrc9(FSPI.VOP3a.SRC0,dtFloat32); src[1]:=fetch_ssrc9(FSPI.VOP3a.SRC1,dtFloat32); - src[2]:=fetch_ssrc9(FSPI.VOP3a.SRC2,dtFloat32); + src[2]:=MakeRead(dst,dtFloat32); _emit_src_abs_bit(@src,3); _emit_src_neg_bit(@src,3); @@ -517,10 +519,12 @@ end; procedure TEmit_VOP3._emit_V_MAD_I32_I24; Var - dst:PsrRegSlot; + dst,tmp:PsrRegSlot; src:array[0..2] of PsrRegNode; + bit24:PsrRegNode; begin dst:=FRegsStory.get_vdst8(FSPI.VOP3a.VDST); + tmp:=@FRegsStory.FUnattach; Assert(FSPI.VOP3a.OMOD =0,'FSPI.VOP3a.OMOD'); Assert(FSPI.VOP3a.ABS =0,'FSPI.VOP3a.ABS'); @@ -531,15 +535,27 @@ begin src[1]:=fetch_ssrc9(FSPI.VOP3a.SRC1,dtInt32); src[2]:=fetch_ssrc9(FSPI.VOP3a.SRC2,dtInt32); + bit24:=FetchReg(FConsts.Fetch(dtUInt32,$FFFFFF)); + + emit_OpBitwiseAnd(tmp,src[0],bit24); + src[0]:=MakeRead(tmp,dtInt32); + + bit24^.mark_read; + + emit_OpBitwiseAnd(tmp,src[1],bit24); + src[1]:=MakeRead(tmp,dtInt32); + emit_OpFmaI32(dst,src[0],src[1],src[2]); end; procedure TEmit_VOP3._emit_V_MAD_U32_U24; Var - dst:PsrRegSlot; + dst,tmp:PsrRegSlot; src:array[0..2] of PsrRegNode; + bit24:PsrRegNode; begin dst:=FRegsStory.get_vdst8(FSPI.VOP3a.VDST); + tmp:=@FRegsStory.FUnattach; Assert(FSPI.VOP3a.OMOD =0,'FSPI.VOP3a.OMOD'); Assert(FSPI.VOP3a.ABS =0,'FSPI.VOP3a.ABS'); @@ -550,6 +566,16 @@ begin src[1]:=fetch_ssrc9(FSPI.VOP3a.SRC1,dtUInt32); src[2]:=fetch_ssrc9(FSPI.VOP3a.SRC2,dtUInt32); + bit24:=FetchReg(FConsts.Fetch(dtUInt32,$FFFFFF)); + + emit_OpBitwiseAnd(tmp,src[0],bit24); + src[0]:=MakeRead(tmp,dtUInt32); + + bit24^.mark_read; + + emit_OpBitwiseAnd(tmp,src[1],bit24); + src[1]:=MakeRead(tmp,dtUInt32); + emit_OpFmaU32(dst,src[0],src[1],src[2]); end; @@ -969,15 +995,11 @@ begin _emit_V_CVT_PKRTZ_F16_F32; end; - 256+V_MIN_F32: - begin - _emit_V_MIN_F32; - end; + 256+V_MIN_LEGACY_F32:_emit_V_MIN_MAX_F32(GlslOp.NMin); + 256+V_MAX_LEGACY_F32:_emit_V_MIN_MAX_F32(GlslOp.NMax); - 256+V_MAX_F32: - begin - _emit_V_MAX_F32; - end; + 256+V_MIN_F32:_emit_V_MIN_MAX_F32(GlslOp.FMin); + 256+V_MAX_F32:_emit_V_MIN_MAX_F32(GlslOp.FMax); 256+V_MUL_F32: begin diff --git a/spirv/srBitcast.pas b/spirv/srBitcast.pas index 5f662d5..55601f3 100644 --- a/spirv/srBitcast.pas +++ b/spirv/srBitcast.pas @@ -72,7 +72,7 @@ begin src^.mark_read; dst:=PSprvEmit(pRoot)^.NewReg(dtype); dst^.pLine:=src^.pLine; - dst^.pWriter.SetParam(ntReg,src); + dst^.SetReg(src); dst^.mark_read; Result:=dst; @@ -89,13 +89,14 @@ begin Result^.mark_read; Result^.pWriter:=src^.pWriter; - src^.pWriter.SetParam(ntReg,Result); + src^.SetReg(Result); end; function TsrBitcastList.FetchCast(dtype:TsrDataType;src:PsrRegNode):PsrRegNode; var node:PsrBitcast; dst:PsrRegNode; + pConst:PsrConst; begin Result:=src; @@ -119,10 +120,11 @@ begin if src^.is_const then begin - src^.AsConst^.mark_unread; + pConst:=src^.AsConst; + pConst^.mark_unread; dst:=PSprvEmit(pRoot)^.NewReg(dtype); dst^.pLine:=src^.pLine; - dst^.pWriter.SetParam(ntConst,PSprvEmit(pRoot)^.FConsts.Bitcast(dtype,src^.AsConst)); + dst^.SetConst(PSprvEmit(pRoot)^.FConsts.Bitcast(dtype,pConst)) end else begin if TryBitcastType(src^.dtype,dtype) then diff --git a/spirv/srBuffer.pas b/spirv/srBuffer.pas index 7344378..6f0bd0d 100644 --- a/spirv/srBuffer.pas +++ b/spirv/srBuffer.pas @@ -624,8 +624,8 @@ begin SpvVersion:=$10100; maxUniformBufferRange:=$FFFF; maxPushConstantsSize:=128; - minStorageBufferOffsetAlignment:=$10; - minUniformBufferOffsetAlignment:=$100; + minStorageBufferOffsetAlignment:=0; + minUniformBufferOffsetAlignment:=0; end; Function TsrBufferCfg.CanUseStorageBufferClass:Boolean; diff --git a/spirv/srInput.pas b/spirv/srInput.pas index 50e473a..a8335d1 100644 --- a/spirv/srInput.pas +++ b/spirv/srInput.pas @@ -175,7 +175,7 @@ begin Decorates^.emit_decorate(ntVar,pVar,Decoration.BuiltIn,BuiltIn.FrontFacing); end; else - Assert(false,'AllocBinding'); + {Assert(false,'AllocBinding')}; end; end; node:=Next(node); diff --git a/spirv/srLabel.pas b/spirv/srLabel.pas index c14834d..3772f8f 100644 --- a/spirv/srLabel.pas +++ b/spirv/srLabel.pas @@ -29,7 +29,7 @@ type TsrSetLabelType=Set of TsrLabelType; - TsrBlockType=(btMain,btAdr,btSetpc,btCond,btLoop,btOther); + TsrBlockType=(btMain,btAdr,btAdrBranch,btSetpc,btCond,btLoop,btOther); PsrLabel=^TsrLabel; TsrLabel=object diff --git a/spirv/srOpUtils.pas b/spirv/srOpUtils.pas index 8ada5cc..858739e 100644 --- a/spirv/srOpUtils.pas +++ b/spirv/srOpUtils.pas @@ -52,7 +52,8 @@ Function is_term_op(pLine:PspirvOp):Boolean; procedure _up_merge_line(var pLine:PspirvOp); function FindUpSameOp(pLine,node:PspirvOp):PspirvOp; -function GreaterThanLine(p1,p2:PspirvOp):Boolean; //(p1>p2) +function isGTLine(p1,p2:PspirvOp):Boolean; //(p1>p2) +function IsGTFlow(pSrc,pDst:PSpirvOp):Boolean; function GetMaxPlace(pLine:PSpirvOp;count:Byte;src:PPsrRegNode):PSpirvOp; implementation @@ -132,7 +133,7 @@ begin end; end; -function GreaterThanLine(p1,p2:PspirvOp):Boolean; //(p1>p2) +function isGTLine(p1,p2:PspirvOp):Boolean; //(p1>p2) begin Result:=False; p2:=p2^.pNext; @@ -143,7 +144,17 @@ begin end; end; -Function ParentOf(pLine,pCurr:PsrOpBlock):Boolean; +function isGTELine(p1,p2:PspirvOp):Boolean; //(p1>=p2) +begin + Result:=False; + While (p2<>nil) do + begin + if (p1=p2) then Exit(True); + p2:=p2^.pNext; + end; +end; + +Function IsParentOf(pLine,pCurr:PsrOpBlock):Boolean; begin Result:=False; While (pLine<>nil) do @@ -153,6 +164,62 @@ begin end; end; +function FindBlockLine(pCurent,node:PsrOpBlock):PspirvOp; +var + tmp:PspirvOp; +begin + Result:=nil; + if (pCurent=nil) then Exit; + tmp:=pCurent^.pHead; + While (tmp<>nil) do + begin + if (tmp^.OpId=OpBlock) and (tmp^.dst.pData=node) then + begin + Exit(tmp); + end; + tmp:=tmp^.pNext; + end; +end; + +{ + [pSrc] + | + V + [pBlock] -> [pDst] +} + +function IsGTFlow(pSrc,pDst:PSpirvOp):Boolean; +var + pLine,pCurr:PsrOpBlock; + tmp:PSpirvOp; +begin + Result:=False; + + pLine:=pDst^.pParent; + pCurr:=pSrc^.pParent; + + While (pLine<>nil) do + begin + + if (pLine=pCurr) then + begin + Result:=isGTELine(pSrc,pDst); + Exit; + end; + + if (pLine^.pParent=nil) then Exit; + + tmp:=pLine^.pUpLine; + if (tmp=nil) then + begin + tmp:=FindBlockLine(pLine^.pParent,pLine); + end; + pDst:=tmp; + + pLine:=pDst^.pParent; + end; +end; + function GetMaxPlace(pLine:PSpirvOp;count:Byte;src:PPsrRegNode):PSpirvOp; var m,t:PSpirvOp; @@ -165,7 +232,7 @@ begin begin t:=src[i]^.pLine; if not src[i]^.is_const then - if ParentOf(pLine^.pParent,t^.pParent) then + if IsParentOf(pLine^.pParent,t^.pParent) then begin if (m=nil) then begin @@ -173,7 +240,7 @@ begin end else if (m^.pParent=t^.pParent) then begin - if GreaterThanLine(t,m) then + if isGTLine(t,m) then begin m:=t; end; @@ -328,25 +395,13 @@ begin begin pBlock:=pLine^.pParent; if (pBlock=nil) then Exit; + if (pBlock^.pParent=nil) then Exit; tmp:=pBlock^.pUpLine; if (tmp=nil) then begin - pBlock:=pBlock^.pParent; - if (pBlock=nil) then Exit; - tmp:=pBlock^.pHead; - While (tmp<>nil) do - begin - if (tmp^.OpId=OpBlock) and (tmp^.dst.pData=pBlock) then - begin - tmp:=tmp^.pPrev; - Break; - end; - tmp:=tmp^.pNext; - end; - end else - begin - tmp:=tmp^.pPrev; + tmp:=FindBlockLine(pBlock^.pParent,pBlock); end; + tmp:=tmp^.pPrev; end; pLine:=tmp; end; diff --git a/spirv/srReg.pas b/spirv/srReg.pas index ef91047..75276b2 100644 --- a/spirv/srReg.pas +++ b/spirv/srReg.pas @@ -29,9 +29,10 @@ type Procedure mark_read; Procedure mark_unread; procedure SetConst(pConst:PsrConst); + procedure SetReg(pReg:PsrRegNode); function AsConst:PsrConst; function AsOp:Pointer; - function AsReg:Pointer; + function AsReg:PsrRegNode; function is_const:Boolean; function is_bool:Boolean; function is_bool_or_const_bool:Boolean; @@ -372,6 +373,12 @@ begin dtype:=pConst^.key.dtype; end; +procedure TsrRegNode.SetReg(pReg:PsrRegNode); +begin + Assert(@Self<>pReg); + pWriter.SetParam(ntReg,pReg); +end; + function TsrRegNode.AsConst:PsrConst; begin Result:=nil; @@ -388,7 +395,7 @@ begin Result:=pWriter.pData; end; -function TsrRegNode.AsReg:Pointer; +function TsrRegNode.AsReg:PsrRegNode; begin Result:=nil; if (@Self=nil) then Exit; diff --git a/spirv/srVolatile.pas b/spirv/srVolatile.pas index 4d2032f..b57bbe2 100644 --- a/spirv/srVolatile.pas +++ b/spirv/srVolatile.pas @@ -227,6 +227,21 @@ begin FRegsStory.ForEachSlot(@make_copy_slot); end; +{ +function is_load_from(dst:PspirvOp;r:PsrRegNode;v:PsrVariable):Boolean; +var + src:PspirvOp; + pVar:PsrVariable; +begin + Result:=False; + src:=r^.AsOp; + if (src=nil) then Exit; + if (src^.OpId<>Op.OpLoad) then Exit; + pVar:=src^.pParam.pHead^.AsVar; + if (pVar<>v) then Exit; + Result:=IsGTFlow(src,dst); +end; +} function get_load_from(r:PsrRegNode):PsrVariable; var @@ -342,7 +357,7 @@ begin MoveVolatiles(@src^.pWriter.pData,@st_tmp); - pReg^.pWriter.SetParam(ntReg,src); + pReg^.SetReg(src); node^.pReg:=nil; Inc(Result); @@ -396,7 +411,8 @@ begin //Assert(pReg<>nil); //Assert(pReg^.pWriter.ntype<>ntVolatile); tmp:=RegDownSlot(pReg); - if (v<>get_load_from(tmp)) then + + if (src<>tmp) and (v<>get_load_from(tmp)) then begin //mark_read volatile->emit_OpStore pLine:=tmp^.pLine; @@ -404,20 +420,23 @@ begin if (tmp^.pWriter.ntype=ntVolatile) then begin - st_tmp.pHead:=tmp^.pWriter.pData; - Assert(st_tmp.pHead<>nil); - st.Move_from(st_tmp); + begin + st_tmp.pHead:=tmp^.pWriter.pData; + Assert(st_tmp.pHead<>nil); - src^.mark_read; - tmp^.pWriter.SetParam(ntReg,src); + st.Move_from(st_tmp); - //tmp^.pLine:=dst; - //writeln; - //PrepVolatile(pReg^.pLine,pReg); + src^.mark_read; + tmp^.SetReg(src); - node^.pReg:=nil; - Continue; + //tmp^.pLine:=dst; + //writeln; + //PrepVolatile(pReg^.pLine,pReg); + + node^.pReg:=nil; + Continue; + end; end; {Case pLine^.OpId of @@ -443,9 +462,11 @@ begin TSprvEmit_post(Self).emit_OpStore(pLine,v,pReg); //after reg end else begin + node^.pReg:=nil; RegUnmark(pReg); //pReg^.mark_unread; end; + until false; v^.mark_read; diff --git a/vulkan/vCmdBuffer.pas b/vulkan/vCmdBuffer.pas index c954dba..fd16e5a 100644 --- a/vulkan/vCmdBuffer.pas +++ b/vulkan/vCmdBuffer.pas @@ -70,6 +70,8 @@ type cmd_count:qword; ret:Integer; + submit_id:ptruint; + FCurrPipeline:array[0..1] of TVkPipeline; FCurrLayout:array[0..1] of TVkPipelineLayout; diff --git a/vulkan/vImage.pas b/vulkan/vImage.pas index 68607eb..2486f17 100644 --- a/vulkan/vImage.pas +++ b/vulkan/vImage.pas @@ -179,8 +179,20 @@ begin VK_FORMAT_R8G8B8A8_UNORM :Result:=4; VK_FORMAT_R8G8_UNORM :Result:=2; VK_FORMAT_R8_UNORM :Result:=1; - VK_FORMAT_R8_UINT :Result:=4; + VK_FORMAT_R8_UINT :Result:=1; VK_FORMAT_R5G6B5_UNORM_PACK16 :Result:=2; + VK_FORMAT_R32_SFLOAT :Result:=4; + + //stencil + VK_FORMAT_S8_UINT :Result:=1; + //depth + VK_FORMAT_D16_UNORM :Result:=2; + VK_FORMAT_X8_D24_UNORM_PACK32 :Result:=4; + VK_FORMAT_D32_SFLOAT :Result:=4; + //depth stencil + VK_FORMAT_D16_UNORM_S8_UINT :Result:=3; + VK_FORMAT_D24_UNORM_S8_UINT :Result:=4; + VK_FORMAT_D32_SFLOAT_S8_UINT :Result:=5; //texel size VK_FORMAT_BC1_RGB_UNORM_BLOCK.. diff --git a/vulkan/vImageManager.pas b/vulkan/vImageManager.pas index 259a32a..7a4a7d0 100644 --- a/vulkan/vImageManager.pas +++ b/vulkan/vImageManager.pas @@ -73,6 +73,9 @@ type FRefs:ptruint; FDeps:TObjectSetLock; // + submit_id:ptruint; + hash:dword; + // data_usage:Byte; Constructor Create; Destructor Destroy; override; @@ -611,12 +614,24 @@ begin end; if not cmd.IsRenderPass then - if ((Result.data_usage and TM_READ)=0) and - ((data_usage and TM_READ)<>0) and - ((data_usage and TM_CLEAR)=0) then begin - Result.data_usage:=Result.data_usage or TM_READ; - LoadFromBuffer(cmd,Result); + + if ((Result.data_usage and TM_READ)<>0) and (Result.submit_id<>cmd.submit_id) then + begin + //hash test + if CheckFromBuffer(Result) then + begin + Result.data_usage:=Result.data_usage and (not TM_READ); + end; + end; + + if ((Result.data_usage and TM_READ)=0) and ((data_usage and TM_READ)<>0) then + begin + Result.submit_id:=cmd.submit_id; + Result.data_usage:=Result.data_usage or TM_READ; + LoadFromBuffer(cmd,Result); + end; + end; Result.data_usage:=Result.data_usage or (data_usage and TM_WRITE); diff --git a/vulkan/vImageTiling.pas b/vulkan/vImageTiling.pas index 7f45dfc..0696c63 100644 --- a/vulkan/vImageTiling.pas +++ b/vulkan/vImageTiling.pas @@ -18,10 +18,12 @@ uses vCmdBuffer; Procedure LoadFromBuffer(cmd:TvCustomCmdBuffer;image:TObject); //TvImage2 +function CheckFromBuffer(image:TObject):Boolean; //TvImage2 implementation uses + shader_dump, vImageManager; Function GetAlignWidth(format:TVkFormat;width:DWORD):DWORD; @@ -465,7 +467,11 @@ begin kTileModeDisplay_2dThin: //render target tiling todo _Load_Linear(cmd,TvImage2(image)); - kTileModeDepth_2dThin_64: //depth tiling todo + kTileModeDepth_2dThin_64 , + kTileModeDepth_2dThin_128, + kTileModeDepth_2dThin_256, + kTileModeDepth_2dThin_512, + kTileModeDepth_2dThin_1K : //depth tiling todo _Load_Linear(cmd,TvImage2(image)); kTileModeThin_1dThin: //texture @@ -480,5 +486,128 @@ begin end; +//FastHash(data:PByte;len:DWORD):DWORD; + +function _Check_Linear(image:TvImage2):Boolean; +var + size:Ptruint; + cur:DWORD; +begin + Result:=False; + + if (image.key.params.samples>ord(VK_SAMPLE_COUNT_1_BIT)) then Exit; + + size:=GetLinearSize(image,(image.key.params.tiling_idx=8)); + + cur:=FastHash(image.key.Addr,size); + + if (cur<>image.hash) then + begin + image.hash:=cur; + Result:=True; + end; + +end; + +function _Check_Thin_1dThin(image:TvImage2):Boolean; +var + tiler:Tiler1d; + + size:QWORD; + + m_bytePerElement:Word; + m_bitsPerElement:Word; + + cur:DWORD; +begin + Result:=False; + + if (image.key.params.samples>ord(VK_SAMPLE_COUNT_1_BIT)) then Exit; + + tiler:=Texture2d_32; + + m_bytePerElement:=getFormatSize(image.key.cformat); + m_bitsPerElement:=m_bytePerElement*8; + + tiler.m_bitsPerElement:=m_bitsPerElement; + + tiler.m_linearWidth :=image.key.params.extend.width; + tiler.m_linearHeight:=image.key.params.extend.height; + tiler.m_linearDepth :=image.key.params.extend.depth; + + if IsTexelFormat(image.key.cformat) then + begin + tiler.m_linearWidth :=(tiler.m_linearWidth +3) div 4; + tiler.m_linearHeight:=(tiler.m_linearHeight+3) div 4; + tiler.m_linearDepth :=(tiler.m_linearDepth +3) div 4; + end; + + if IsTexelFormat(image.key.cformat) then + begin + tiler.m_paddedWidth :=tiler.m_linearWidth ; + tiler.m_paddedHeight:=tiler.m_linearHeight; + tiler.m_paddedDepth :=tiler.m_linearDepth ; + end else + Case m_bitsPerElement of + 32:begin + tiler.m_paddedWidth :=(tiler.m_linearWidth +7) and (not 7); + tiler.m_paddedHeight:=(tiler.m_linearHeight+7) and (not 7); + tiler.m_paddedDepth :=tiler.m_linearDepth; + end; + 8:begin + tiler.m_paddedWidth :=(tiler.m_linearWidth +31) and (not 31); + tiler.m_paddedHeight:=(tiler.m_linearHeight+ 7) and (not 7); + tiler.m_paddedDepth :=tiler.m_linearDepth; + end; + else + Assert(false); + end; + + size:=tiler.m_paddedWidth* + tiler.m_paddedHeight* + tiler.m_paddedDepth* + m_bytePerElement; + + cur:=FastHash(image.key.Addr,size); + + if (cur<>image.hash) then + begin + image.hash:=cur; + Result:=True; + end; + +end; + +function CheckFromBuffer(image:TObject):Boolean; +begin + Result:=False; + + Case TvImage2(image).key.params.tiling_idx of + kTileModeDisplay_LinearAligned, + kTileModeDisplay_LinearGeneral: + Result:=_Check_Linear(TvImage2(image)); + + kTileModeDisplay_2dThin: //render target tiling todo + Result:=false; + + kTileModeDepth_2dThin_64 , + kTileModeDepth_2dThin_128, + kTileModeDepth_2dThin_256, + kTileModeDepth_2dThin_512, + kTileModeDepth_2dThin_1K : //depth tiling todo + Result:=false; + + kTileModeThin_1dThin: //texture + Result:=_Check_Thin_1dThin(TvImage2(image)); + + kTileModeThin_2dThin: + Result:=_Check_Linear(TvImage2(image)); //TODO + + else + Assert(false,'TODO'); + end; + +end; + end.