unit srVBufInfo; {$mode ObjFPC}{$H+} interface uses ps4_pssl, srType, srLayout, spirv; type //Destination channel select: //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 grp :TsrDataLayout; dsel :Tdst_sel; DFMT :Byte; //BUF_DATA_FORMAT_* NFMT :Byte; //BUF_NUM_FORMAT_* count:Byte; //count reg dst GLC :Byte; //Coherent SLC :Byte; //Volatile function GetResultType:TsrDataType; function GetElemType:TsrDataType; function GetElemCount:Byte; function GetElemSize:Byte; function GetSizeFormat:Byte; function GetAlignSize:Byte; function IsComp:Boolean; function IsExtFormat:Boolean; function GetImageFormat:Byte; function GetImageFormatElement:Byte; function GetImageInfo:TsrImageInfo; function GetImageInfoElement:TsrImageInfo; end; const dst_sel_identity:Tdst_sel=(4,5,6,7); 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; implementation const DFMT_ELEM_COUNT:array[0..15] of Byte=( 0, //BUF_DATA_FORMAT_INVALID 1, //BUF_DATA_FORMAT_8 1, //BUF_DATA_FORMAT_16 2, //BUF_DATA_FORMAT_8_8 1, //BUF_DATA_FORMAT_32 2, //BUF_DATA_FORMAT_16_16 3, //BUF_DATA_FORMAT_10_11_11 3, //BUF_DATA_FORMAT_11_11_10 4, //BUF_DATA_FORMAT_10_10_10_2 4, //BUF_DATA_FORMAT_2_10_10_10 4, //BUF_DATA_FORMAT_8_8_8_8 2, //BUF_DATA_FORMAT_32_32 4, //BUF_DATA_FORMAT_16_16_16_16 3, //BUF_DATA_FORMAT_32_32_32 4, //BUF_DATA_FORMAT_32_32_32_32 0); //BUF_DATA_FORMAT_RESERVED DFMT_ELEM_SIZE:array[0..15] of Byte=( 0, //BUF_DATA_FORMAT_INVALID 1, //BUF_DATA_FORMAT_8 2, //BUF_DATA_FORMAT_16 1, //BUF_DATA_FORMAT_8_8 4, //BUF_DATA_FORMAT_32 2, //BUF_DATA_FORMAT_16_16 4, //BUF_DATA_FORMAT_10_11_11 4, //BUF_DATA_FORMAT_11_11_10 4, //BUF_DATA_FORMAT_10_10_10_2 4, //BUF_DATA_FORMAT_2_10_10_10 1, //BUF_DATA_FORMAT_8_8_8_8 4, //BUF_DATA_FORMAT_32_32 2, //BUF_DATA_FORMAT_16_16_16_16 4, //BUF_DATA_FORMAT_32_32_32 4, //BUF_DATA_FORMAT_32_32_32_32 0); //BUF_DATA_FORMAT_RESERVED DFMT_SIZE:array[0..15] of Byte=( 0, //BUF_DATA_FORMAT_INVALID 1, //BUF_DATA_FORMAT_8 //shr 2 2, //BUF_DATA_FORMAT_16 //shr 2 2, //BUF_DATA_FORMAT_8_8 //shr 2 4, //BUF_DATA_FORMAT_32 //shr 2 4, //BUF_DATA_FORMAT_16_16 //shr 2 4, //BUF_DATA_FORMAT_10_11_11 //shr 2 4, //BUF_DATA_FORMAT_11_11_10 //shr 2 4, //BUF_DATA_FORMAT_10_10_10_2 //shr 2 4, //BUF_DATA_FORMAT_2_10_10_10 //shr 2 4, //BUF_DATA_FORMAT_8_8_8_8 //shr 2 8, //BUF_DATA_FORMAT_32_32 //shr 3 8, //BUF_DATA_FORMAT_16_16_16_16 //shr 3 12, //BUF_DATA_FORMAT_32_32_32 //div 12 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;num_records:DWORD):TBuf_info; inline; begin Result.grp :=grp; Result.dsel :=dsel; Result.DFMT :=DFMT; Result.NFMT :=NFMT; 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; begin Result[0]:=r; Result[1]:=g; Result[2]:=b; Result[3]:=a; end; function get_reverse_dst_sel(dst:Tdst_sel):Tdst_sel; var i,f,d:Byte; begin Result:=Default(Tdst_sel); For i:=0 to 3 do For f:=0 to 3 do begin d:=dst[f]; Case d of 4..7: begin d:=d-4; if (i=d) then begin Result[i]:=f+4; Break; end; end; else; end; end; end; function TBuf_info.GetResultType:TsrDataType; begin Result:=dtFloat32; Case NFMT of BUF_NUM_FORMAT_UINT:Result:=dtUint32; BUF_NUM_FORMAT_SINT:Result:=dtInt32; else; end; end; function TBuf_info.GetElemType:TsrDataType; begin Result:=dtUnknow; Case DFMT_ELEM_SIZE[DFMT] of 1:Case NFMT of BUF_NUM_FORMAT_SNORM , BUF_NUM_FORMAT_SSCALED , BUF_NUM_FORMAT_SINT , BUF_NUM_FORMAT_SNORM_NZ:Result:=dtInt8; else Result:=dtUint8; end; 2:Case NFMT of BUF_NUM_FORMAT_SNORM , BUF_NUM_FORMAT_SSCALED , BUF_NUM_FORMAT_SINT , BUF_NUM_FORMAT_SNORM_NZ:Result:=dtInt16; BUF_NUM_FORMAT_FLOAT :Result:=dtHalf16; else Result:=dtUint16; end; 4:Case NFMT of BUF_NUM_FORMAT_SNORM , BUF_NUM_FORMAT_SSCALED , BUF_NUM_FORMAT_SINT , BUF_NUM_FORMAT_SNORM_NZ:Result:=dtInt32; BUF_NUM_FORMAT_FLOAT :Result:=dtFloat32; else Result:=dtUint32; end; else; end; end; function TBuf_info.GetElemCount:Byte; begin Result:=DFMT_ELEM_COUNT[DFMT]; end; function TBuf_info.GetElemSize:Byte; begin Result:=DFMT_ELEM_SIZE[DFMT]; end; function TBuf_info.GetSizeFormat:Byte; begin Result:=DFMT_SIZE[DFMT]; end; function Min(a,b:PtrInt):PtrInt; inline; begin if (a