This commit is contained in:
Pavel 2024-08-07 14:05:56 +03:00
parent 628fd33e4d
commit e211346def
12 changed files with 287 additions and 87 deletions

View File

@ -1122,7 +1122,7 @@ begin
if (ctx.rt_info^.DB_INFO.HTILE_INFO.TILE_SURFACE_ENABLE<>0) then
begin
htile_instance:=ctx.node^.scope.find_htile_resource_instance(ctx.rt_info^.DB_INFO.HTILE_INFO.KEY.Addr,
ctx.rt_info^.DB_INFO.HTILE_INFO.SIZE);
ctx.rt_info^.DB_INFO.HTILE_INFO.SIZE);
Assert(htile_instance<>nil);
if htile_instance^.resource^.rclear then
@ -1712,19 +1712,19 @@ begin
Assert(resource<>nil);
//set flag by buffer in current stream
resource^.rclear:=True;
//set flag by buffer to next stream
hb:=FetchBuffer(ctx.Cmd,resource^.rkey.Addr,resource^.rsize);
hb.rclear:=True;
if (iu_htile in resource_instance^.next.img_usage) then
//set flag by htile in current stream
resource:=ctx.stream^.find_htile_resource(resource^.rkey.Addr,resource^.rsize);
//
if (resource<>nil) then
begin
resource:=ctx.stream^.find_htile_resource(resource^.rkey.Addr,resource^.rsize);
//
if (resource<>nil) then
begin
resource^.rclear:=True;
end;
resource^.rclear:=True;
end;
end;
@ -2311,8 +2311,15 @@ begin
if use_renderdoc_capture then
begin
renderdoc.LoadRenderDoc;
renderdoc.UnloadCrashHandler;
if not IsRenderDocPreLoaded then
begin
//disable capture if we are not working with Renderdoc GUI
use_renderdoc_capture:=False;
end else
begin
renderdoc.LoadRenderDoc;
renderdoc.UnloadCrashHandler;
end;
end;
me^.reset_sheduler;

View File

@ -172,10 +172,17 @@ const
kDccBlockSize128 = 1; ///< 128-byte blocks.
kDccBlockSize256 = 2; ///< 256-byte blocks.
kNumBanks2 = $0;
kNumBanks4 = $1;
kNumBanks8 = $2;
kNumBanks16 = $3;
kNumBanks2 = 0;
kNumBanks4 = 1;
kNumBanks8 = 2;
kNumBanks16 = 3;
kTextureChannel0 = 0;
kTextureChannel1 = 1;
kTextureChannelX = 4;
kTextureChannelY = 5;
kTextureChannelZ = 6;
kTextureChannelW = 7;
type
TDATA_FORMAT=bitpacked record
@ -1859,22 +1866,22 @@ begin
end;
const
chY_1:array[0..2] of Integer=(5,0,4);
chX_1:array[0..2] of Integer=(4,4,5);
chW_1:array[0..2] of Integer=(1,5,1);
chY_1:array[0..2] of Integer=(kTextureChannelY,kTextureChannel0,kTextureChannelX); //(5,0,4);
chX_1:array[0..2] of Integer=(kTextureChannelX,kTextureChannelX,kTextureChannelY); //(4,4,5);
chW_1:array[0..2] of Integer=(kTextureChannel1,kTextureChannelY,kTextureChannel1); //(1,5,1);
chY_2:array[0..2] of Integer=(5,5,6);
chZ_2:array[0..2] of Integer=(6,4,5);
chX_2:array[0..2] of Integer=(4,6,7);
chW_2:array[0..2] of Integer=(7,7,4);
chY_2:array[0..2] of Integer=(kTextureChannelY,kTextureChannelY,kTextureChannelZ); //(5,5,6);
chZ_2:array[0..2] of Integer=(kTextureChannelZ,kTextureChannelX,kTextureChannelY); //(6,4,5);
chX_2:array[0..2] of Integer=(kTextureChannelX,kTextureChannelZ,kTextureChannelW); //(4,6,7);
chW_2:array[0..2] of Integer=(kTextureChannelW,kTextureChannelW,kTextureChannelX); //(7,7,4);
chZ_3:array[0..2] of Integer=(6,0,4);
chX_3:array[0..2] of Integer=(4,4,6);
chW_3:array[0..2] of Integer=(1,6,1);
chZ_3:array[0..2] of Integer=(kTextureChannelZ,kTextureChannel0,kTextureChannelX); //(6,0,4);
chX_3:array[0..2] of Integer=(kTextureChannelX,kTextureChannelX,kTextureChannelZ); //(4,4,6);
chW_3:array[0..2] of Integer=(kTextureChannel1,kTextureChannelZ,kTextureChannel1); //(1,6,1);
chZ_4:array[0..2] of Integer=(0,0,4);
chY_4:array[0..2] of Integer=(0,4,0);
chX_4:array[0..2] of Integer=(4,0,0);
chZ_4:array[0..2] of Integer=(kTextureChannel0,kTextureChannel0,kTextureChannelX); //(0,0,4);
chY_4:array[0..2] of Integer=(kTextureChannel0,kTextureChannelX,kTextureChannel0); //(0,4,0);
chX_4:array[0..2] of Integer=(kTextureChannelX,kTextureChannel0,kTextureChannel0); //(4,0,0);
function sce_Gnm_DataFormat_build(FORMAT,NUMBER_TYPE,COMP_SWAP:Byte):TDATA_FORMAT;
var
@ -1888,34 +1895,34 @@ label
_end,_zero;
begin
if (($1800004000000016 shr (FORMAT and $3f) and 1)=0) then
if ((QWORD($1800004000000016) shr (FORMAT and $3f) and 1)=0) then
begin
if (($3fff08000700828 shr (FORMAT and $3f) and 1)<>0) then
if ((QWORD($3fff08000700828) shr (FORMAT and $3f) and 1)<>0) then
begin
IS_SWAP_ALT_REV:=COMP_SWAP=3;
if (COMP_SWAP<3) then
IS_SWAP_ALT_REV:=(COMP_SWAP=SWAP_ALT_REV);
if (COMP_SWAP<SWAP_ALT_REV) then
begin
m_channelY:=chY_1[COMP_SWAP];
m_channelX:=chX_1[COMP_SWAP];
m_channelW:=chW_1[COMP_SWAP];
m_channelZ:=0;
m_channelZ:=kTextureChannel0;
end else
begin
m_channelY:=0;
m_channelY:=kTextureChannel0;
m_channelX:=ord(IS_SWAP_ALT_REV)+ord(IS_SWAP_ALT_REV)*4;
m_channelW:=ord(IS_SWAP_ALT_REV)*3+1;
m_channelZ:=0;
m_channelZ:=kTextureChannel0;
end;
goto _end;
end;
if (($4000107000120c0 shr (FORMAT and $3f) and 1)=0) then
if ((QWORD($4000107000120c0) shr (FORMAT and $3f) and 1)=0) then
begin
if (($238000e5700 shr (FORMAT and $3f) and 1)=0) then
if ((QWORD($238000e5700) shr (FORMAT and $3f) and 1)=0) then
begin
m_channelW:=1;
m_channelW:=kTextureChannel1;
goto _zero;
end;
@ -1928,35 +1935,35 @@ begin
goto _end;
end;
IS_SWAP_ALT_REV:=COMP_SWAP=3;
IS_SWAP_ALT_REV:=(COMP_SWAP=SWAP_ALT_REV);
m_channelX:=ord(IS_SWAP_ALT_REV)*5;
m_channelY:=6;
m_channelZ:=7;
m_channelY:=kTextureChannelZ;
m_channelZ:=kTextureChannelW;
if (not IS_SWAP_ALT_REV) then
begin
m_channelZ:=0;
m_channelY:=0;
m_channelZ:=kTextureChannel0;
m_channelY:=kTextureChannel0;
end;
end else
begin
if (COMP_SWAP<3) then
if (COMP_SWAP<SWAP_ALT_REV) then
begin
m_channelZ:=chZ_3[COMP_SWAP];
m_channelX:=chX_3[COMP_SWAP];
m_channelW:=chW_3[COMP_SWAP];
m_channelY:=5;
m_channelY:=kTextureChannelY;
goto _end;
end;
m_channelX:=6;
m_channelY:=ord(COMP_SWAP=3)*5;
m_channelZ:=0;
m_channelX:=kTextureChannelZ;
m_channelY:=ord(COMP_SWAP=SWAP_ALT_REV)*5;
m_channelZ:=kTextureChannel0;
if (COMP_SWAP<>3) then
begin
m_channelX:=0;
m_channelX:=kTextureChannel0;
end;
end;
@ -1966,30 +1973,30 @@ begin
end else
begin
if (COMP_SWAP<3) then
if (COMP_SWAP<SWAP_ALT_REV) then
begin
m_channelW:=1;
m_channelW:=kTextureChannel1;
m_channelZ:=chZ_4[COMP_SWAP];
m_channelY:=chY_4[COMP_SWAP];
m_channelX:=chX_4[COMP_SWAP];
goto _end;
end;
m_channelW:=ord(COMP_SWAP=3)*3+1;
m_channelW:=ord(COMP_SWAP=SWAP_ALT_REV)*3+1;
_zero:
m_channelZ:=0;
m_channelY:=0;
m_channelX:=0;
m_channelZ:=kTextureChannel0;
m_channelY:=kTextureChannel0;
m_channelX:=kTextureChannel0;
end;
_end:
m_channelType:=$9;
m_channelType:=9;
if (NUMBER_TYPE<>6) then
if (NUMBER_TYPE<>NUMBER_SRGB) then
begin
m_channelType:=(NUMBER_TYPE and $F);
end;

View File

@ -1,7 +1,7 @@
object frmMain: TfrmMain
Left = 430
Left = 390
Height = 343
Top = 264
Top = 308
Width = 623
Caption = 'fpPS4'
ClientHeight = 343
@ -155,6 +155,10 @@ object frmMain: TfrmMain
Caption = 'Run'
OnClick = MIRunClick
end
object MIShowExplorer: TMenuItem
Caption = 'Show in Explorer'
OnClick = MIShowExplorerClick
end
object MIDevide3: TMenuItem
Caption = '-'
end

View File

@ -75,6 +75,7 @@ type
TfrmMain = class(TForm)
MainImageList: TImageList;
MIShowExplorer: TMenuItem;
MIDevide3: TMenuItem;
MIRun: TMenuItem;
MIEdit: TMenuItem;
@ -107,6 +108,7 @@ type
procedure ListGridDragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean);
procedure ListGridEndDrag(Sender, Target: TObject; X, Y: Integer);
procedure ListGridMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
procedure MIShowExplorerClick(Sender: TObject);
procedure OnIdleUpdate(Sender:TObject;var Done:Boolean);
procedure MIAddClick(Sender: TObject);
procedure MIAddFolderClick(Sender: TObject);
@ -924,6 +926,32 @@ begin
//
end;
procedure TfrmMain.MIShowExplorerClick(Sender: TObject);
var
Item:TGameItem;
aRow:Integer;
S:RawByteString;
begin
aRow:=ListGrid.Row;
if (aRow=0) then Exit;
if (aRow>ListGrid.RowCount) then Exit;
Item:=FGameList.GetItemRow(aRow);
S:=ExtractRelativePath('/app0/',Item.GameInfo.Exec);
if Length(S)<Length(Item.GameInfo.Exec) then
begin
S:=IncludeTrailingPathDelimiter(Item.MountList.app0)+ExtractFilePath(S);
end else
begin
S:=Item.MountList.app0;
end;
OpenDocument(S);
end;
procedure TfrmMain.MIRunClick(Sender: TObject);
var
Item:TGameItem;

View File

@ -5,7 +5,9 @@ unit renderdoc;
interface
uses
Classes, SysUtils;
Windows,
Classes,
SysUtils;
type
RENDERDOC_Version=(
@ -184,6 +186,7 @@ type
RENDERDOC_DevicePointer=THandle;
RENDERDOC_WindowHandle =THandle;
function IsRenderDocPreLoaded:Boolean;
procedure LoadRenderDoc;
procedure GetAPIVersion(major,minor,patch:PInteger);
@ -295,6 +298,11 @@ var
RENDERDOC_GetAPI:pRENDERDOC_GetAPI=nil;
RENDERDOC_API :PRENDERDOC_API_1_6_0=nil;
function IsRenderDocPreLoaded:Boolean;
begin
Result:=Windows.GetModuleHandle('renderdoc.dll')<>0;
end;
procedure LoadRenderDoc;
var
fname:RawByteString;
@ -302,12 +310,12 @@ var
begin
if (LibHandle<>0) then Exit;
fname:=GetEnvironmentVariable('ProgramFiles')+DirectorySeparator+'RenderDoc'+DirectorySeparator+'renderdoc.dll';
fname:=Sysutils.GetEnvironmentVariable('ProgramFiles')+DirectorySeparator+'RenderDoc'+DirectorySeparator+'renderdoc.dll';
LibHandle:=LoadLibrary(fname);
LibHandle:=System.LoadLibrary(fname);
if (LibHandle=NilHandle) then Exit;
Pointer(RENDERDOC_GetAPI):=GetProcedureAddress(LibHandle,'RENDERDOC_GetAPI');
Pointer(RENDERDOC_GetAPI):=System.GetProcedureAddress(LibHandle,'RENDERDOC_GetAPI');
if (RENDERDOC_GetAPI=nil) then Exit;
r:=RENDERDOC_GetAPI(eRENDERDOC_API_Version_1_6_0,@RENDERDOC_API);

View File

@ -478,6 +478,7 @@ begin
if (COUNT<>0) then
for i:=0 to COUNT-1 do
begin
FExportInfo[i].FORMAT :=R[i].INFO.FORMAT;
FExportInfo[i].NUMBER_TYPE:=R[i].INFO.NUMBER_TYPE;
FExportInfo[i].COMP_SWAP :=R[i].INFO.COMP_SWAP;
end;

View File

@ -20,20 +20,91 @@ uses
emit_fetch;
type
Tdst_sel=array[0..3] of Byte;
TEmit_EXP=class(TEmitFetch)
procedure emit_EXP;
function get_export_type(TGT:Byte):TsrDataType;
function is_bindless(TGT:Byte):Boolean;
function get_export_sel(TGT:Byte):Tdst_sel;
procedure fetch_vsrc8_vec2h(VSRC:Word;var dst0,dst1:PsrRegNode);
procedure shuffle(dst_sel:Tdst_sel;rtype:TsrDataType;src:PPsrRegNode;count:Byte);
end;
implementation
const
COLOR_COUNT:array[0..31] of Byte=(
0, //COLOR_INVALID
1, //COLOR_8
1, //COLOR_16
2, //COLOR_8_8
1, //COLOR_32
2, //COLOR_16_16
3, //COLOR_10_11_11
3, //COLOR_11_11_10
4, //COLOR_10_10_10_2
4, //COLOR_2_10_10_10
4, //COLOR_8_8_8_8
2, //COLOR_32_32
4, //COLOR_16_16_16_16
3, //COLOR_RESERVED_13 //32_32_32
4, //COLOR_32_32_32_32
0, //COLOR_RESERVED_15
3, //COLOR_5_6_5
4, //COLOR_1_5_5_5
4, //COLOR_5_5_5_1
4, //COLOR_4_4_4_4
2, //COLOR_8_24
2, //COLOR_24_8
3, //COLOR_X24_8_32_FLOAT
0, //COLOR_RESERVED_23
0,
0,
0,
0,
0,
0,
0,
0
);
const
z=0;
dst_sel_ident:Tdst_sel=(4,5,6,7);
shader_swizzle_map:array[1..4,SWAP_STD..SWAP_ALT_REV] of Tdst_sel=(
(
(4,z,z,z),
(z,4,z,z),
(z,z,4,z),
(z,z,z,4)
),(
(4,5,z,z),
(4,z,z,5),
(5,4,z,z),
(5,z,z,4)
),(
(4,5,6,z),
(4,5,z,6),
(6,5,4,z),
(6,5,z,4)
),(
(4,5,6,7),
(6,5,4,7),
(7,6,5,4),
(5,6,7,4)
)
);
function TEmit_EXP.get_export_type(TGT:Byte):TsrDataType;
begin
Result:=dtFloat32;
case TpsslExportType(TGT) of
etMrt0..etMrt7:
begin
case FExportInfo[TGT].NUMBER_TYPE of
case (FExportInfo[TGT].NUMBER_TYPE and 7) of
NUMBER_UINT:Result:=dtUint32;
NUMBER_SINT:Result:=dtInt32;
else;
@ -43,6 +114,80 @@ begin
end;
end;
function TEmit_EXP.is_bindless(TGT:Byte):Boolean;
begin
Result:=False;
case TpsslExportType(TGT) of
etMrt0..etMrt7:
begin
Result:=COLOR_COUNT[FExportInfo[TGT].FORMAT and 31]=0;
end;
else;
end;
end;
function TEmit_EXP.get_export_sel(TGT:Byte):Tdst_sel;
var
i:Byte;
begin
Result:=dst_sel_ident;
case TpsslExportType(TGT) of
etMrt0..etMrt7:
begin
i:=COLOR_COUNT[FExportInfo[TGT].FORMAT and 31];
Assert(i<>0);
//
Result:=shader_swizzle_map[i,FExportInfo[TGT].COMP_SWAP and 3];
end;
else;
end;
end;
procedure TEmit_EXP.fetch_vsrc8_vec2h(VSRC:Word;var dst0,dst1:PsrRegNode);
var
pSlot:PsrRegSlot;
dst:PsrRegNode;
begin
pSlot:=RegsStory.get_vsrc8(VSRC);
dst:=MakeRead(pSlot,dtVec2h);
Assert(dst<>nil,'fetch_vsrc8_vec2h');
dst0:=NewReg(dtHalf16);
dst1:=NewReg(dtHalf16);
OpExtract(line,dst0,dst,0);
OpExtract(line,dst1,dst,1);
end;
procedure TEmit_EXP.shuffle(dst_sel:Tdst_sel;rtype:TsrDataType;src:PPsrRegNode;count:Byte);
var
i:Byte;
dst:array[0..3] of PsrRegNode;
begin
For i:=0 to count-1 do
begin
case dst_sel[i] of
0:dst[i]:=NewReg_i(rtype.Child,0);
//1?
4:dst[i]:=src[0];
5:dst[i]:=src[1];
6:dst[i]:=src[2];
7:dst[i]:=src[3];
else;
Assert(False);
end;
end;
//
For i:=0 to count-1 do
begin
src[i]:=dst[i];
end;
end;
procedure TEmit_EXP.emit_EXP;
Var
exc:PsrRegNode;
@ -55,6 +200,8 @@ Var
rtype:TsrDataType;
f,i,p:DWORD;
dst_sel:Tdst_sel;
push_count:DWORD;
begin
//if (VM<>0) and (EXEC<>0) = set pixel else (if DONE=1) discard pixel /(PS only)
@ -76,8 +223,9 @@ begin
end;
//before
if (TpsslExportType(FSPI.EXP.TGT)=etNull) //only set kill mask
or (FSPI.EXP.EN=0) then //nop
if (TpsslExportType(FSPI.EXP.TGT)=etNull) or //only set kill mask
(FSPI.EXP.EN=0) or //nop
is_bindless(FSPI.EXP.TGT) then //not binded
begin
While (push_count<>0) do
@ -124,6 +272,8 @@ begin
Assert(false,'FSPI.EXP.COMPR='+HexStr(f,1));
end;
//shuffle ???
dout:=FetchOutput(TpsslExportType(FSPI.EXP.TGT),rtype); //output in FSPI.EXP.TGT
OpStore(line,dout,src[0]);
end else
@ -156,6 +306,10 @@ begin
Inc(i);
end;
dst_sel:=get_export_sel(FSPI.EXP.TGT);
shuffle(dst_sel,rtype,@src,p);
dst:=OpMakeVec(line,rtype,@src);
dout:=FetchOutput(TpsslExportType(FSPI.EXP.TGT),rtype); //output in FSPI.EXP.TGT
@ -164,6 +318,7 @@ begin
end else
begin //half16
Case f of
3,
$F:
@ -193,6 +348,10 @@ begin
rtype:=dtVec4f;
end;
dst_sel:=get_export_sel(FSPI.EXP.TGT);
shuffle(dst_sel,rtype,@src,4);
dst:=OpMakeVec(line,rtype,@src);
dout:=FetchOutput(TpsslExportType(FSPI.EXP.TGT),rtype); //output in FSPI.EXP.TGT

View File

@ -62,7 +62,6 @@ type
function fetch_ssrc9_pair(SSRC:Word;src:PPsrRegNode;rtype:TsrDataType):Boolean;
function fetch_vsrc8(VSRC:Word;rtype:TsrDataType):PsrRegNode;
function fetch_vdst8(VDST:Word;rtype:TsrDataType):PsrRegNode;
procedure fetch_vsrc8_vec2h(VSRC:Word;var dst0,dst1:PsrRegNode);
//
procedure OpCmpV(OpId:DWORD;dst:PsrRegSlot;src0,src1:PsrRegNode);
procedure OpCmpS(OpId:DWORD;dst:PsrRegSlot;src0,src1:PsrRegNode);
@ -486,23 +485,6 @@ begin
Assert(Result<>nil,'fetch_vdst8');
end;
procedure TEmitFetch.fetch_vsrc8_vec2h(VSRC:Word;var dst0,dst1:PsrRegNode);
var
pSlot:PsrRegSlot;
dst:PsrRegNode;
begin
pSlot:=RegsStory.get_vsrc8(VSRC);
dst:=MakeRead(pSlot,dtVec2h);
Assert(dst<>nil,'fetch_vsrc8_vec2h');
dst0:=NewReg(dtHalf16);
dst1:=NewReg(dtHalf16);;
OpExtract(line,dst0,dst,0);
OpExtract(line,dst1,dst,1);
end;
//
procedure TEmitFetch.OpCmpV(OpId:DWORD;dst:PsrRegSlot;src0,src1:PsrRegNode);

View File

@ -54,6 +54,7 @@ type
end;
TExportInfo=packed record
FORMAT :Byte;
NUMBER_TYPE:Byte;
COMP_SWAP :Byte;
end;

View File

@ -496,7 +496,7 @@ begin
BLEND_CONTROL:=CX_REG^.CB_BLEND_CONTROL[i];
m:=GetRTCompCount(RENDER_TARGET.INFO.FORMAT);
COMP_MAP:=GetCompMap(RENDER_TARGET.INFO.COMP_SWAP,m);
COMP_MAP:=GetCompMap({RENDER_TARGET.INFO.COMP_SWAP}0,m);
//COMP_SWAP depend (B=>0, G=>1, R=>2, A=>3)
m:=_COMP_MASK(i);
@ -928,7 +928,7 @@ begin
COLOR_8_8,
COLOR_8_8_8_8:
begin
COMP_MAP:=GetCompMap(RENDER_TARGET.INFO.COMP_SWAP,4);
COMP_MAP:=GetCompMap({RENDER_TARGET.INFO.COMP_SWAP}0,4);
//VK_COLOR_COMPONENT_R_BIT=$00000001, 0001
//VK_COLOR_COMPONENT_G_BIT=$00000002, 0010
@ -952,7 +952,7 @@ begin
COLOR_16_16,
COLOR_16_16_16_16:
begin
COMP_MAP:=GetCompMap(RENDER_TARGET.INFO.COMP_SWAP,4);
COMP_MAP:=GetCompMap({RENDER_TARGET.INFO.COMP_SWAP}0,4);
W:=RENDER_TARGET.CLEAR_WORD;
@ -965,7 +965,7 @@ begin
COLOR_32,
COLOR_32_32:
begin
COMP_MAP:=GetCompMap(RENDER_TARGET.INFO.COMP_SWAP,4);
COMP_MAP:=GetCompMap({RENDER_TARGET.INFO.COMP_SWAP}0,4);
W:=RENDER_TARGET.CLEAR_WORD;

View File

@ -81,6 +81,7 @@ type
PRENDER_TARGET=^TRENDER_TARGET;
TEXPORT_INFO=packed record
FORMAT :Byte;
NUMBER_TYPE:Byte;
COMP_SWAP :Byte;
end;
@ -801,6 +802,7 @@ begin
if (COUNT<>0) then
for i:=0 to COUNT-1 do
begin
FParams.EXPORT_INFO[i].FORMAT :=R[i].INFO.FORMAT;
FParams.EXPORT_INFO[i].NUMBER_TYPE:=R[i].INFO.NUMBER_TYPE;
FParams.EXPORT_INFO[i].COMP_SWAP :=R[i].INFO.COMP_SWAP;
end;

View File

@ -453,6 +453,7 @@ begin
if (FShader.FParams.EXPORT_COUNT<>0) then
for i:=0 to FShader.FParams.EXPORT_COUNT-1 do
begin
if (FShader.FParams.EXPORT_INFO[i].FORMAT <>R[i].INFO.FORMAT ) then Exit(False);
if (FShader.FParams.EXPORT_INFO[i].NUMBER_TYPE<>R[i].INFO.NUMBER_TYPE) then Exit(False);
if (FShader.FParams.EXPORT_INFO[i].COMP_SWAP <>R[i].INFO.COMP_SWAP ) then Exit(False);
end;