unit srDecorate; {$mode ObjFPC}{$H+} interface uses spirv, ginodes, srNode, srOp; type PsrHeaderList=^TsrHeaderList; TsrHeaderList=object(TsrOpBlockCustom) FGLSL_std_450:PSpirvOp; function emit_glsl_ext:PSpirvOp; end; PsrDecorate=^TsrDecorate; TsrDecorate=object private pLeft,pRight:PsrDecorate; //---- key:packed record data:PsrNode; param:array[0..2] of DWORD; end; function c(n1,n2:PsrDecorate):Integer; static; public node:PSpirvOp; end; PsrDecorateList=^TsrDecorateList; TsrDecorateList=object(TsrOpBlockCustom) type TNodeFetch=specialize TNodeFetch; var FNTree:TNodeFetch; function Fetch(data:PsrNode;param1,param2,param3:DWORD):PsrDecorate; procedure OpDecorate(Data:PsrNode;dec_id,param:DWORD); procedure OpMember (Data:PsrNode;index,offset:DWORD); end; PsrDebugInfoList=^TsrDebugInfoList; TsrDebugInfoList=object(TsrOpBlockCustom) procedure OpSource(const n:RawByteString); procedure OpName (Data:PsrNode;const n:RawByteString); function OpString(const n:RawByteString):PsrNode; end; implementation // function TsrHeaderList.emit_glsl_ext:PSpirvOp; begin if (FGLSL_std_450=nil) then begin FGLSL_std_450:=AddSpirvOp(Op.OpExtInstImport); FGLSL_std_450^.pDst:=Emit.NewRefNode; FGLSL_std_450^.AddString('GLSL.std.450'); end; Result:=FGLSL_std_450; end; // function TsrDecorate.c(n1,n2:PsrDecorate):Integer; var i:Byte; begin //first data Result:=Integer(n1^.key.data>n2^.key.data)-Integer(n1^.key.data0) then Exit; //param[i] For i:=0 to 2 do begin Result:=Integer(n1^.key.param[i]>n2^.key.param[i])-Integer(n1^.key.param[i]0) then Exit; end; end; // function TsrDecorateList.Fetch(data:PsrNode;param1,param2,param3:DWORD):PsrDecorate; var node:TsrDecorate; begin node:=Default(TsrDecorate); node.key.data:=data; node.key.param[0]:=param1; node.key.param[1]:=param2; node.key.param[2]:=param3; Result:=FNTree.Find(@node); if (Result=nil) then begin Result:=Emit.Alloc(SizeOf(TsrDecorate)); Move(node,Result^,SizeOf(TsrDecorate)); FNTree.Insert(Result); end; end; procedure TsrDecorateList.OpDecorate(Data:PsrNode;dec_id,param:DWORD); var deco:PsrDecorate; node:PSpirvOp; begin deco:=Fetch(Data,Op.OpDecorate,dec_id,param); if (deco^.node<>nil) then Exit; node:=AddSpirvOp(Op.OpDecorate); node^.AddParam(Data); node^.AddLiteral(dec_id,Decoration.GetStr(dec_id)); Case dec_id of Decoration.BuiltIn: node^.AddLiteral(param,BuiltIn.GetStr(param)); Decoration.ArrayStride, Decoration.MatrixStride, Decoration.Location, Decoration.Index, Decoration.Binding, Decoration.DescriptorSet: node^.AddLiteral(param); else; end; deco^.node:=node; end; procedure TsrDecorateList.OpMember(Data:PsrNode;index,offset:DWORD); var deco:PsrDecorate; node:PSpirvOp; begin deco:=Fetch(Data,Op.OpMemberDecorate,index,offset); if (deco^.node<>nil) then Exit; node:=AddSpirvOp(Op.OpMemberDecorate); node^.AddParam(Data); node^.AddLiteral(index); node^.AddLiteral(Decoration.Offset,Decoration.GetStr(Decoration.Offset)); node^.AddLiteral(offset); deco^.node:=node; end; // procedure TsrDebugInfoList.OpSource(const n:RawByteString); var node:PSpirvOp; begin node:=AddSpirvOp(Op.OpSourceExtension); node^.AddString(n); end; procedure TsrDebugInfoList.OpName(Data:PsrNode;const n:RawByteString); var node:PSpirvOp; begin node:=AddSpirvOp(Op.OpName); node^.AddParam(Data); node^.AddString(n); end; function TsrDebugInfoList.OpString(const n:RawByteString):PsrNode; var node:PSpirvOp; begin node:=AddSpirvOp(Op.OpString); node^.pDst:=Emit.NewRefNode; node^.AddString(n); Result:=node^.pDst; end; // end.