unit srType; {$mode objfpc}{$H+} {$modeswitch typehelpers} interface uses bittype, Half16; type TsrDataType=( //Real types dtUnknow, dtBool, dtHalf16, dtFloat32, dtFloat64, dtInt8, dtUint8, dtInt16, dtUint16, dtInt32, dtUint32, dtInt64, dtUint64, //Composite types dtVec2b, dtVec3b, dtVec4b, dtStruct2i, dtStruct2u, dtStruct2i64, dtStruct2u64, dtVec2u8, dtVec4u8, dtVec2i8, dtVec4i8, dtVec2u16, dtVec4u16, dtVec2i16, dtVec4i16, dtVec2u, dtVec3u, dtVec4u, dtVec2i, dtVec3i, dtVec4i, dtVec2h, dtVec4h, dtVec2f, dtVec3f, dtVec4f, //Spirv types dtTypeVoid, dtTypeFunction, dtTypePointer, dtTypeStruct, dtTypeArray, dtTypeRuntimeArray, dtTypeImage, dtTypeSampler, dtTypeSampledImage, dtString, dtConstant ); TsrDataTypeHelper = type helper for TsrDataType function isInt:Boolean; function isFloat:Boolean; function isBool:Boolean; function isVector:Boolean; function isScalar:Boolean; function Child:TsrDataType; function Count:Byte; function Sign:Byte; function BitSize:Byte; function High:QWORD; function AsVector(_count:Byte):TsrDataType; function AsStruct2:TsrDataType; end; Pvec2f=^Tvec2f; Tvec2f=array[0..1] of Single; Pvec3f=^Tvec3f; Tvec3f=array[0..2] of Single; Pvec4f=^Tvec4f; Tvec4f=array[0..3] of Single; Pvec2h=^Tvec2h; Tvec2h=array[0..1] of THalf16; Pvec4h=^Tvec4h; Tvec4h=array[0..3] of THalf16; //child - result type TsrTypeImageInfo=bitpacked record Dim :bit3; //Dim.* Depth :bit2; //0:no,1:yes,2:any Arrayed:bit1; //0:no,1:yes MS :bit1; //0:no,1:yes Sampled:bit2; //0:runtime,1:sampling,2:read/write Format :bit23; //ImageFormat.* end; PsrImageInfo=^TsrImageInfo; TsrImageInfo=packed record dtype:TsrDataType; tinfo:TsrTypeImageInfo; count:Byte; Cube :Boolean; GLC :Boolean; SLC :Boolean; degam:Boolean; //[S#] force_degamma end; function type_get_base_name1(dtype:TsrDataType):RawByteString; function LazyType2(t1,t2:TsrDataType):TsrDataType; function LazyType3(t1,t2,t3:TsrDataType):TsrDataType; function LazyIntType(dtype0,dtype1:TsrDataType):TsrDataType; function StoreType(t:TsrDataType):TsrDataType; function CompareType(rtype1,rtype2:TsrDataType):Boolean; function TryBitcastType(rtype1,rtype2:TsrDataType):Boolean; function is_unprep_type(old,new:TsrDataType;weak:Boolean):Boolean; implementation function type_get_base_name1(dtype:TsrDataType):RawByteString; begin Result:=''; case dtype of dtBool :Result:='bool'; dtHalf16 :Result:='half'; dtFloat32 :Result:='float'; dtFloat64 :Result:='double'; dtInt8 :Result:='int8'; dtUint8 :Result:='uint8'; dtInt16 :Result:='int16'; dtUint16 :Result:='uint16'; dtInt32 :Result:='int'; dtUint32 :Result:='uint'; dtInt64 :Result:='int64'; dtUint64 :Result:='uint64'; //Composite types dtVec2b :Result:='bvec2'; dtVec3b :Result:='bvec3'; dtVec4b :Result:='bvec4'; dtStruct2i :Result:='rec2i'; dtStruct2u :Result:='rec2u'; dtStruct2i64 :Result:='rec2i64'; dtStruct2u64 :Result:='rec2u64'; dtVec2u8 :Result:='u8vec2'; dtVec4u8 :Result:='u8vec4'; dtVec2i8 :Result:='i8vec2'; dtVec4i8 :Result:='i8vec4'; dtVec2u16 :Result:='u16vec2'; dtVec4u16 :Result:='u16vec4'; dtVec2i16 :Result:='i16vec2'; dtVec4i16 :Result:='i16vec4'; dtVec2u :Result:='uvec2'; dtVec3u :Result:='uvec3'; dtVec4u :Result:='uvec4'; dtVec2i :Result:='ivec2'; dtVec3i :Result:='ivec3'; dtVec4i :Result:='ivec4'; dtVec2h :Result:='hvec2'; dtVec4h :Result:='hvec4'; dtVec2f :Result:='vec2'; dtVec3f :Result:='vec3'; dtVec4f :Result:='vec4'; dtTypeVoid :Result:='void'; dtTypeSampler:Result:='samp'; else; end; end; function LazyType2(t1,t2:TsrDataType):TsrDataType; begin if (t1<>dtUnknow) then Result:=t1 else Result:=t2; end; function LazyType3(t1,t2,t3:TsrDataType):TsrDataType; begin if (t1<>dtUnknow) then Result:=t1 else Result:=t2; if (Result=dtUnknow) then Result:=t3; end; function LazyIntType(dtype0,dtype1:TsrDataType):TsrDataType; begin if (dtype0=dtInt32) or (dtype1=dtInt32) then begin Result:=dtInt32; end else if (dtype0=dtInt64) or (dtype1=dtInt64) then begin Result:=dtInt64; end else begin Result:=LazyType2(dtype0,dtype1); end; end; function StoreType(t:TsrDataType):TsrDataType; begin if (t=dtBool) then Result:=dtUint32 else Result:=t; end; function TsrDataTypeHelper.isInt:Boolean; begin Case Self of dtInt8, dtUint8, dtInt16, dtUint16, dtInt32, dtUint32, dtInt64, dtUint64, dtStruct2i, dtStruct2u, dtStruct2i64, dtStruct2u64, dtVec2u8, dtVec4u8, dtVec2i8, dtVec4i8, dtVec2u16, dtVec4u16, dtVec2i16, dtVec4i16, dtVec2u, dtVec3u, dtVec4u, dtVec2i, dtVec3i, dtVec4i, dtVec2f, dtVec3f, dtVec4f: Result:=True; else Result:=False; end; end; function TsrDataTypeHelper.isFloat:Boolean; begin Case Self of dtHalf16, dtFloat32, dtFloat64, dtVec2h, dtVec4h, dtVec2f, dtVec3f, dtVec4f: Result:=True; else Result:=False; end; end; function TsrDataTypeHelper.isBool:Boolean; begin Case Self of dtBool, dtVec2b, dtVec3b, dtVec4b:Result:=True; else Result:=False; end; end; function TsrDataTypeHelper.isVector:Boolean; begin Case Self of dtVec2b, dtVec3b, dtVec4b, dtStruct2i, dtStruct2u, dtStruct2i64, dtStruct2u64, dtVec2u8, dtVec4u8, dtVec2i8, dtVec4i8, dtVec2u16, dtVec4u16, dtVec2i16, dtVec4i16, dtVec2u, dtVec3u, dtVec4u, dtVec2i, dtVec3i, dtVec4i, dtVec2h, dtVec4h, dtVec2f, dtVec3f, dtVec4f: Result:=True; else Result:=False; end; end; function TsrDataTypeHelper.isScalar:Boolean; begin Result:=not isVector; end; function TsrDataTypeHelper.Child:TsrDataType; begin Case Self of dtVec2b, dtVec3b, dtVec4b:Result:=dtBool; dtVec2u8, dtVec4u8:Result:=dtUint8; dtVec2i8, dtVec4i8:Result:=dtInt8; dtVec2u16, dtVec4u16:Result:=dtUint16; dtVec2i16, dtVec4i16:Result:=dtInt16; dtStruct2u, dtVec2u, dtVec3u, dtVec4u:Result:=dtUint32; dtStruct2i, dtVec2i, dtVec3i, dtVec4i:Result:=dtInt32; dtVec2h, dtVec4h:Result:=dtHalf16; dtVec2f, dtVec3f, dtVec4f:Result:=dtFloat32; dtStruct2u64:Result:=dtUint64; dtStruct2i64:Result:=dtInt64; else Result:=dtUnknow; end; end; function TsrDataTypeHelper.Count:Byte; begin Case Self of dtVec2b, dtVec2u8, dtVec2i8, dtVec2u16, dtVec2i16, dtVec2u, dtVec2i, dtVec2h, dtVec2f, dtStruct2i, dtStruct2u, dtStruct2i64, dtStruct2u64:Result:=2; dtVec3b, dtVec3u, dtVec3i, dtVec3f:Result:=3; dtVec4b, dtVec4u8, dtVec4i8, dtVec4u16, dtVec4i16, dtVec4u, dtVec4i, dtVec4f, dtVec4h:Result:=4; else Result:=0; end; end; function TsrDataTypeHelper.Sign:Byte; begin Case Self of dtInt8, dtInt16, dtInt32, dtInt64, dtStruct2i, dtStruct2i64, dtHalf16, dtFloat32, dtFloat64, dtVec2h, dtVec4h, dtVec2f, dtVec3f, dtVec4f:Result:=1; else Result:=0; end; end; function TsrDataTypeHelper.BitSize:Byte; begin Case Self of dtInt8, dtUint8:Result:=8; dtHalf16, dtInt16, dtUint16, dtVec2u8, dtVec2i8:Result:=16; dtUnknow, dtBool, //for typecast dtFloat32, dtInt32, dtUint32, dtVec4u8, dtVec4i8, dtVec2u16, dtVec2i16, dtVec2h:Result:=32; dtFloat64, dtInt64, dtUint64, dtVec4u16, dtVec4i16, dtVec2u, dtVec2i, dtVec2f, dtVec4h, dtStruct2i, dtStruct2u:Result:=64; dtVec3u, dtVec3i, dtVec3f:Result:=96; dtVec4u, dtVec4i, dtVec4f:Result:=128; else Result:=0; end; end; function TsrDataTypeHelper.High:QWORD; var s:Byte; begin Result:=0; if (Self=dtBool) then Exit(1); s:=BitSize; Case s of 8:Result:=System.High(Byte); 16:Result:=System.High(Word); 32:Result:=System.High(DWord); 64:Result:=System.High(QWord); else Assert(false); end; end; function TsrDataTypeHelper.AsVector(_count:Byte):TsrDataType; begin Result:=dtUnknow; if (_count<=1) then Exit(Self); Case Self of dtBool: Case _count of 2:Result:=dtVec2b; 3:Result:=dtVec3b; 4:Result:=dtVec4b; end; dtUint8: Case _count of 2:Result:=dtVec2u8; 4:Result:=dtVec4u8; end; dtInt8: Case _count of 2:Result:=dtVec2i8; 4:Result:=dtVec4i8; end; dtUint16: Case _count of 2:Result:=dtVec2u16; 4:Result:=dtVec4u16; end; dtInt16: Case _count of 2:Result:=dtVec2i16; 4:Result:=dtVec4i16; end; dtHalf16: Case _count of 2:Result:=dtVec2h; 4:Result:=dtVec4h; end; dtFloat32: Case _count of 2:Result:=dtVec2f; 3:Result:=dtVec3f; 4:Result:=dtVec4f; end; dtInt32: Case _count of 2:Result:=dtVec2i; 3:Result:=dtVec3i; 4:Result:=dtVec4i; end; dtUint32: Case _count of 2:Result:=dtVec2u; 3:Result:=dtVec3u; 4:Result:=dtVec4u; end; else; end; end; function TsrDataTypeHelper.AsStruct2:TsrDataType; begin Result:=dtUnknow; Case Self of dtInt32 :Result:=dtStruct2i; dtUint32:Result:=dtStruct2u; dtInt64 :Result:=dtStruct2i64; dtUint64:Result:=dtStruct2u64; else; end; end; function CompareType(rtype1,rtype2:TsrDataType):Boolean; begin Case rtype1 of dtInt8, dtUint8:Result:=(rtype2=dtInt8) or (rtype2=dtUint8); dtInt16, dtUint16:Result:=(rtype2=dtInt16) or (rtype2=dtUint16); dtInt32, dtUint32:Result:=(rtype2=dtInt32) or (rtype2=dtUint32); dtVec2u8, dtVec2i8:Result:=(rtype2=dtVec2u8) or (rtype2=dtVec2i8); dtVec4u8, dtVec4i8:Result:=(rtype2=dtVec4u8) or (rtype2=dtVec4i8); dtVec2u16, dtVec2i16:Result:=(rtype2=dtVec2u16) or (rtype2=dtVec2i16); dtVec4u16, dtVec4i16:Result:=(rtype2=dtVec4u16) or (rtype2=dtVec4i16); dtVec2u, dtVec2i:Result:=(rtype2=dtVec2u) or (rtype2=dtVec2i); dtVec3u, dtVec3i:Result:=(rtype2=dtVec3u) or (rtype2=dtVec3i); dtVec4u, dtVec4i:Result:=(rtype2=dtVec4u) or (rtype2=dtVec4i); else Result:=(rtype1=rtype2); end; end; function TryBitcastType(rtype1,rtype2:TsrDataType):Boolean; var s,d:Byte; begin s:=rtype1.BitSize; d:=rtype2.BitSize; Result:=(s<>0) and (d<>0) and (s=d); end; function is_unprep_type(old,new:TsrDataType;weak:Boolean):Boolean; begin Result:=False; if (new<>dtUnknow) and (old<>new) then begin Case old of dtUnknow:Result:=True; dtBool :Result:=weak; else; end; end; end; end.