From 26bd331cf63cd6222b2bf534497072ae478eb156 Mon Sep 17 00:00:00 2001 From: Pavel <68122101+red-prig@users.noreply.github.com> Date: Tue, 10 Jun 2025 10:33:52 +0300 Subject: [PATCH] + --- chip/ps4_shader.pas | 6 ++--- spirv/emit_mtbuf.pas | 11 ++++++-- spirv/emit_mubuf.pas | 19 +++++++++----- spirv/emit_vbuf_load.pas | 2 +- spirv/srLayout.pas | 16 ++++++++++-- spirv/srVBufInfo.pas | 18 ++++++------- vulkan/vShaderExt.pas | 56 ++++++++++++++++++++++++++++++++-------- 7 files changed, 93 insertions(+), 35 deletions(-) diff --git a/chip/ps4_shader.pas b/chip/ps4_shader.pas index 75e2fb7d..27d63983 100644 --- a/chip/ps4_shader.pas +++ b/chip/ps4_shader.pas @@ -246,7 +246,7 @@ type num_records:bit32; //n units of 'stride' //32 dst_sel_x:bit3; //Destination channel select: - dst_sel_y:bit3; //0=0, 1=1, 4=R, 5=G, 6=B, 7=A + dst_sel_y:bit3; //0=0, 1=1, 2=0, 3=0, 4=R, 5=G, 6=B, 7=A dst_sel_z:bit3; dst_sel_w:bit3; nfmt:bit3; //numeric data type (float, int, ...) @@ -277,7 +277,7 @@ type interlaced:bit1; //texture is interlaced //32 dst_sel_x:bit3; //Destination channel select: - dst_sel_y:bit3; //0=0, 1=1, 4=R, 5=G, 6=B, 7=A + dst_sel_y:bit3; //0=0, 1=1, 2=0, 3=0, 4=R, 5=G, 6=B, 7=A dst_sel_z:bit3; dst_sel_w:bit3; base_level:bit4; //first mip level (0..15) @@ -305,7 +305,7 @@ type interlaced:bit1; //texture is interlaced //32 dst_sel_x:bit3; //Destination channel select: - dst_sel_y:bit3; //0=0, 1=1, 4=R, 5=G, 6=B, 7=A + dst_sel_y:bit3; //0=0, 1=1, 2=0, 3=0, 4=R, 5=G, 6=B, 7=A dst_sel_z:bit3; dst_sel_w:bit3; base_level:bit4; //first mip level (0..15) diff --git a/spirv/emit_mtbuf.pas b/spirv/emit_mtbuf.pas index 2cb6c185..2427dddf 100644 --- a/spirv/emit_mtbuf.pas +++ b/spirv/emit_mtbuf.pas @@ -7,6 +7,7 @@ interface uses sysutils, ps4_pssl, + ps4_shader, srReg, srLayout, emit_fetch, @@ -28,11 +29,13 @@ var src:array[0..3] of PsrRegSlot; grp:TsrDataLayout; + PV:PVSharpResource4; begin if not get_srsrc(FSPI.MTBUF.SRSRC,4,@src) then Assert(false); grp:=GroupingSharp(@src,rtVSharp4); + PV:=grp.GetSharp; TEmit_vbuf_load(TObject(Self)).buf_load( Buf_info(grp, @@ -41,7 +44,8 @@ begin FSPI.MTBUF.NFMT, count, FSPI.MTBUF.GLC, - FSPI.MTBUF.SLC) + FSPI.MTBUF.SLC, + PV^.num_records) ); end; @@ -51,11 +55,13 @@ var src:array[0..3] of PsrRegSlot; grp:TsrDataLayout; + PV:PVSharpResource4; begin if not get_srsrc(FSPI.MTBUF.SRSRC,4,@src) then Assert(false); grp:=GroupingSharp(@src,rtVSharp4); + PV:=grp.GetSharp; TEmit_vbuf_store(TObject(Self)).buf_store( Buf_info(grp, @@ -64,7 +70,8 @@ begin FSPI.MTBUF.NFMT, count, FSPI.MTBUF.GLC, - FSPI.MTBUF.SLC) + FSPI.MTBUF.SLC, + PV^.num_records) ); end; diff --git a/spirv/emit_mubuf.pas b/spirv/emit_mubuf.pas index 2cf15ae5..214dd618 100644 --- a/spirv/emit_mubuf.pas +++ b/spirv/emit_mubuf.pas @@ -106,21 +106,22 @@ begin PV^.nfmt, count, FSPI.MUBUF.GLC, - FSPI.MUBUF.SLC); + FSPI.MUBUF.SLC, + PV^.num_records); elem_res:=info.GetResultType; elem_vec:=elem_res.AsVector(info.GetElemCount); rsl:=AddVertLayout(grp,elem_vec); - elem_count:=GetElemCount(PV^.dfmt); + elem_count:=info.GetElemCount; For i:=0 to count-1 do begin dst:=get_vdst8(FSPI.MUBUF.VDATA+i); if (dst=nil) then Assert(false); - //0=0, 1=1, 4=R, 5=G, 6=B, 7=A + //0=0, 1=1, 2=0, 3=0, 4=R, 5=G, 6=B, 7=A Case info.dsel[i] of 0:begin //0 make_load_zero(dst,elem_res); @@ -196,7 +197,8 @@ begin PV^.nfmt, count, FSPI.MUBUF.GLC, - FSPI.MUBUF.SLC) + FSPI.MUBUF.SLC, + PV^.num_records) ); end; @@ -234,7 +236,8 @@ begin PV^.nfmt, count, FSPI.MUBUF.GLC, - FSPI.MUBUF.SLC) + FSPI.MUBUF.SLC, + PV^.num_records) ); end; @@ -266,7 +269,8 @@ begin BUF_NUM_FORMAT_FLOAT, count, FSPI.MUBUF.GLC, - FSPI.MUBUF.SLC) + FSPI.MUBUF.SLC, + PV^.num_records) ); end; @@ -298,7 +302,8 @@ begin BUF_NUM_FORMAT_FLOAT, count, FSPI.MUBUF.GLC, - FSPI.MUBUF.SLC) + FSPI.MUBUF.SLC, + PV^.num_records) ); end; diff --git a/spirv/emit_vbuf_load.pas b/spirv/emit_vbuf_load.pas index bd49640e..289601fe 100644 --- a/spirv/emit_vbuf_load.pas +++ b/spirv/emit_vbuf_load.pas @@ -292,7 +292,7 @@ begin lc.dst:=get_vdst8(FSPI.MUBUF.VDATA+i); if (lc.dst=nil) then Assert(false); - //0=0, 1=1, 4=R, 5=G, 6=B, 7=A + //0=0, 1=1, 2=0, 3=0, 4=R, 5=G, 6=B, 7=A Case info.dsel[i] of 0:begin //0 make_load_zero(lc); diff --git a/spirv/srLayout.pas b/spirv/srLayout.pas index 4e4bbfa1..d448fa0b 100644 --- a/spirv/srLayout.pas +++ b/spirv/srLayout.pas @@ -911,6 +911,11 @@ begin //pList.OpSource(Space(deep+1)+name+':'+HexLen(P,len)); end; +function IsInvalidVSharp(dfmt,num_records:DWORD):Boolean; inline; +begin + Result:=(dfmt=0) or (num_records=0); +end; + procedure TsrDataLayoutList.AllocSourceExtension2; var Writer:TseWriter; @@ -962,14 +967,21 @@ begin begin if (Writer.node.RINF) then begin - Writer.StrOpt('RINF','1'); + Writer.IntOpt('RINF',1); + if IsInvalidVSharp(dfmt,num_records) then + begin + Writer.IntOpt('INVL',1); + end; Writer.IntOpt('DFMT',dfmt); Writer.IntOpt('NFMT',nfmt); Writer.IntOpt('STRD',stride); Writer.StrOpt('DSEL',_get_dst_sel_str(dst_sel_x,dst_sel_y,dst_sel_z,dst_sel_w)); end else begin - Writer.IntOpt('DFMT',dfmt); //0->invalid + if IsInvalidVSharp(dfmt,num_records) then + begin + Writer.IntOpt('INVL',1); + end; end; end; diff --git a/spirv/srVBufInfo.pas b/spirv/srVBufInfo.pas index d36dc432..5d6b3da0 100644 --- a/spirv/srVBufInfo.pas +++ b/spirv/srVBufInfo.pas @@ -12,7 +12,7 @@ uses type //Destination channel select: - //0=0, 1=1, 4=R, 5=G, 6=B, 7=A + //0=0, 1=1, 2=0, 3=0, 4=R, 5=G, 6=B, 7=A Tdst_sel=array[0..3] of Byte; TBuf_info=packed object @@ -40,10 +40,9 @@ type const dst_sel_identity:Tdst_sel=(4,5,6,7); -function Buf_info(grp:TsrDataLayout;dsel:Tdst_sel;DFMT,NFMT,count,GLC,SLC:Byte):TBuf_info; inline; +function Buf_info(grp:TsrDataLayout;dsel:Tdst_sel;DFMT,NFMT,count,GLC,SLC:Byte;num_records:DWORD):TBuf_info; inline; function dst_sel(r,g,b,a:Byte):Tdst_sel; inline; function get_reverse_dst_sel(dst:Tdst_sel):Tdst_sel; -function GetElemCount(DFMT:Byte):Byte; inline; implementation @@ -102,7 +101,7 @@ const 16, //BUF_DATA_FORMAT_32_32_32_32 //shr 4 0); //BUF_DATA_FORMAT_RESERVED -function Buf_info(grp:TsrDataLayout;dsel:Tdst_sel;DFMT,NFMT,count,GLC,SLC:Byte):TBuf_info; inline; +function Buf_info(grp:TsrDataLayout;dsel:Tdst_sel;DFMT,NFMT,count,GLC,SLC:Byte;num_records:DWORD):TBuf_info; inline; begin Result.grp :=grp; Result.dsel :=dsel; @@ -111,6 +110,12 @@ begin Result.count:=count; Result.GLC :=GLC; Result.SLC :=SLC; + // + if (num_records=0) then + begin + //force to invalid + Result.DFMT:=0; + end; end; function dst_sel(r,g,b,a:Byte):Tdst_sel; inline; @@ -186,11 +191,6 @@ begin end; end; -function GetElemCount(DFMT:Byte):Byte; inline; -begin - Result:=DFMT_ELEM_COUNT[DFMT]; -end; - function TBuf_info.GetElemCount:Byte; begin Result:=DFMT_ELEM_COUNT[DFMT]; diff --git a/vulkan/vShaderExt.pas b/vulkan/vShaderExt.pas index bcd5fdb3..0b35cdb6 100644 --- a/vulkan/vShaderExt.pas +++ b/vulkan/vShaderExt.pas @@ -56,8 +56,8 @@ type end; TvResInfo=bitpacked record - enable:Boolean; //1 -> dfmt,nfmt,dstsel - align :Boolean; //1 + enable :Boolean; //1 -> dfmt,nfmt,dstsel + invalid:Boolean; //1 dfmt :0..63; //6 nfmt :0..15; //4 rtype :0..15; //4 @@ -774,7 +774,8 @@ begin 'FLG':L^.flags:=StrToFlags(V); - 'RINF':L^.rinfo.enable:=(StrToDWord2(V)<>0); + 'RINF':L^.rinfo.enable :=(StrToDWord2(V)<>0); + 'INVL':L^.rinfo.invalid:=(StrToDWord2(V)<>0); 'DFMT':L^.rinfo.dfmt :=StrToDWord2(V); 'NFMT':L^.rinfo.nfmt :=StrToDWord2(V); 'STRD':L^.rinfo.stride :=StrToDWord2(V); @@ -1472,6 +1473,11 @@ begin Insert(b,FBuffers,Length(FBuffers)); end; +function IsInvalidVSharp(dfmt,num_records:DWORD):Boolean; inline; +begin + Result:=(dfmt=0) or (num_records=0); +end; + Procedure TvUniformBuilder.AddVSharp4(PV:PVSharpResource4;fset,bind,size,offset:DWord;flags:TvLayoutFlags); var b:TBufBindExt; @@ -1484,7 +1490,7 @@ begin //print_vsharp(PV); - invalid:=ord(PV^.dfmt=0)*TM_INVAL; + invalid:=ord(IsInvalidVSharp(PV^.dfmt,PV^.num_records))*TM_INVAL; b:=Default(TBufBindExt); b.fset :=fset; @@ -1530,6 +1536,8 @@ Procedure TvUniformBuilder.AddTSharp4(PT:PTSharpResource4;btype:TvBindImageType; var b:TImageBindExt; hint:s_image_usage; + + //start,__end:QWORD; begin Assert(PT<>nil); if (PT=nil) then Exit; @@ -1553,6 +1561,20 @@ begin b.FImage:=_get_tsharp4_image_info(PT,hint); b.FView :=_get_tsharp4_image_view(PT,hint); + { + //Marking textures that contain incorrect + // virtual memory as invalid, + // I don't know how correct this approach is + start:=QWORD(get_dmem_ptr(b.FImage.Addr)); + __end:=start+1; + gpu_get_bound(start,__end); + if (start=0) then + begin + Writeln(HexStr(QWORD(b.FImage.Addr),10),'->INVALID'); + b.FImage.params.invalid:=1; + end; + } + b.memuse:=b.memuse or (b.FImage.params.invalid)*TM_INVAL; Insert(b,FImages,Length(FImages)); @@ -1562,6 +1584,8 @@ Procedure TvUniformBuilder.AddTSharp8(PT:PTSharpResource8;btype:TvBindImageType; var b:TImageBindExt; hint:s_image_usage; + + //start,__end:QWORD; begin Assert(PT<>nil); if (PT=nil) then Exit; @@ -1585,6 +1609,20 @@ begin b.FImage:=_get_tsharp8_image_info(PT,hint); b.FView :=_get_tsharp8_image_view(PT,hint); + { + //Marking textures that contain incorrect + // virtual memory as invalid, + // I don't know how correct this approach is + start:=QWORD(get_dmem_ptr(b.FImage.Addr)); + __end:=start+1; + gpu_get_bound(start,__end); + if (start=0) then + begin + Writeln(HexStr(QWORD(b.FImage.Addr),10),'->INVALID'); + b.FImage.params.invalid:=1; + end; + } + b.memuse:=b.memuse or (b.FImage.params.invalid)*TM_INVAL; Insert(b,FImages,Length(FImages)); @@ -1889,11 +1927,6 @@ begin end; end; -function IsInvalid(dfmt:Byte):Boolean; inline; -begin - Result:=(dfmt=0); -end; - procedure TvUnifChecker.AddAttr(const b:TvCustomLayout;Fset:TVkUInt32;pUserData,pImmData:PDWORD); var P:Pointer; @@ -1957,7 +1990,8 @@ begin if rinfo.enable then begin - if ( dfmt<>rinfo.dfmt ) or + if (IsInvalidVSharp(dfmt,num_records)<>rinfo.invalid) or + ( dfmt<>rinfo.dfmt ) or ( nfmt<>rinfo.nfmt ) or ( stride<>rinfo.stride ) or (dst_sel_x<>rinfo.dstsel.x) or @@ -1970,7 +2004,7 @@ begin end; end else begin - if (IsInvalid(dfmt)<>IsInvalid(rinfo.dfmt)) then + if (IsInvalidVSharp(dfmt,num_records)<>rinfo.invalid) then begin FResult:=False; Exit;