unit srInterface; {$mode objfpc}{$H+} interface uses ps4_pssl, spirv, srNode, srConfig, srAllocator, srCFGCursor, srRefId, srLiteral, srCapability, srDecorate, srType, srTypes, srConst, srReg, srVariable, srInput, srOutput, srLayout, srVertLayout, srFragLayout, srBuffer, srUniform, srPrivate, srBitcast, srOp, srOpUtils, srCacheOp; type TLocalSize=packed record x,y,z:DWORD; end; TEmitInterface=class(TCustomEmit) FExecutionModel:Word; FLocalSize:TLocalSize; Config:TsrConfig; // FSPI:TSPI; // Allocator:TsrAllocator; // LiteralList :TsrLiteralList; TypeList :TsrTypeList; ConstList :TsrConstList; RegsStory :TsrRegsStory; CapabilityList:TsrCapabilityList; HeaderList :TsrHeaderList; DecorateList :TsrDecorateList; DebugInfoList :TsrDebugInfoList; VariableList :TsrVariableList; // InputList :TsrInputList; OutputList :TsrOutputList; // DataLayoutList:TsrDataLayoutList; VertLayoutList:TsrVertLayoutList; FragLayoutList:TsrFragLayoutList; // BufferList :TsrBufferList; UniformList :TsrUniformList; PrivateList :TsrPrivateList; // BitcastList :TsrBitcastList; CacheOpList :TsrCacheOpList; // FuncList :TsrFuncList; // CodeHeap :TsrCodeHeap; Cursor :TsrCursor; Main :PSpirvFunc; InitBlock:PsrOpBlock; // RefIdAlloc:TsrRefIdAlloc; // function Alloc(Size:ptruint):Pointer; override; Function GetExecutionModel :Word; override; Function GetConfig :Pointer; override; Function GetCodeHeap :Pointer; override; Function GetLiteralList :Pointer; override; Function GetTypeList :Pointer; override; Function GetConstList :Pointer; override; Function GetRegsStory :Pointer; override; Function GetCapabilityList :Pointer; override; Function GetHeaderList :Pointer; override; Function GetDecorateList :Pointer; override; Function GetDebugInfoList :Pointer; override; Function GetVariableList :Pointer; override; Function GetInputList :Pointer; override; Function GetOutputList :Pointer; override; Function GetDataLayoutList :Pointer; override; Function GetVertLayoutList :Pointer; override; Function GetFragLayoutList :Pointer; override; Function GetBufferList :Pointer; override; Function GetUniformList :Pointer; override; Function GetBitcastList :Pointer; override; Function GetCacheOpList :Pointer; override; Function GetFuncList :Pointer; override; Function GetCursor :Pointer; override; function NewRefNode :PsrNode; override; // Function line :PspirvOp; Function curr_line :Pointer; override; function init_line :Pointer; override; // Procedure InitLists; // function NewVariable:Pointer; // function _get_line(ppLine:PPspirvOp):PspirvOp; // Function NewRegPair:PsrRegPair; Function NewReg(rtype:TsrDataType):PsrRegNode; Function NewReg(pConst:PsrConst;ppLine:PPspirvOp=nil):PsrRegNode; // Function NewReg_q(dtype:TsrDataType;value:QWORD;ppLine:PPspirvOp=nil):PsrRegNode; Function NewReg_b(value:Boolean;ppLine:PPspirvOp=nil):PsrRegNode; Function NewReg_i(dtype:TsrDataType;value:Integer;ppLine:PPspirvOp=nil):PsrRegNode; Function NewReg_s(dtype:TsrDataType;value:Single;ppLine:PPspirvOp=nil):PsrRegNode; // function NewSpirvOp(OpId:DWORD):PSpirvOp; function NewLabelOp(sdep:Boolean):PSpirvOp; function AddSpirvOp(OpId:DWORD):PSpirvOp; function AddSpirvOp(pLine:PspirvOp;OpId:DWORD):PSpirvOp; function AddSpirvOp(pLine,pNew:PspirvOp):PSpirvOp; function AddSGlslOp(pLine:PspirvOp;OpId:DWORD):PSpirvOp; // procedure PostLink(pLine,dst:PsrNode); override; procedure MakeCopy(dst:PsrRegSlot;src:PsrRegNode); // Procedure SetConst(pSlot:PsrRegSlot;pConst:PsrConst); Procedure SetConst_q(pSlot:PsrRegSlot;dtype:TsrDataType;value:QWORD); Procedure SetConst_b(pSlot:PsrRegSlot;value:Boolean); Procedure SetConst_i(pSlot:PsrRegSlot;dtype:TsrDataType;value:Integer); Procedure SetConst_s(pSlot:PsrRegSlot;dtype:TsrDataType;value:Single); // function AllocBlockOp:PsrOpBlock; function NewBlockOp(Snap:TsrRegsSnapshot):PsrOpBlock; function InsertBlockOp(pLine:PspirvOp;pChild:PsrOpBlock):PspirvOp; // procedure AddCapability(ID:DWORD); end; implementation function TEmitInterface.Alloc(Size:ptruint):Pointer; begin Result:=Allocator.Alloc(Size); end; Function TEmitInterface.GetExecutionModel:Word; begin Result:=FExecutionModel; end; Function TEmitInterface.GetConfig:Pointer; begin Result:=@Config; end; Function TEmitInterface.GetCodeHeap:Pointer; begin Result:=@CodeHeap; end; Function TEmitInterface.GetLiteralList:Pointer; begin Result:=@LiteralList; end; Function TEmitInterface.GetTypeList:Pointer; begin Result:=@TypeList; end; Function TEmitInterface.GetConstList:Pointer; begin Result:=@ConstList; end; Function TEmitInterface.GetRegsStory:Pointer; begin Result:=@RegsStory; end; Function TEmitInterface.GetCapabilityList:Pointer; begin Result:=@CapabilityList; end; Function TEmitInterface.GetHeaderList:Pointer; begin Result:=@HeaderList; end; Function TEmitInterface.GetDecorateList:Pointer; begin Result:=@DecorateList; end; Function TEmitInterface.GetDebugInfoList:Pointer; begin Result:=@DebugInfoList; end; Function TEmitInterface.GetVariableList:Pointer; begin Result:=@VariableList; end; Function TEmitInterface.GetInputList:Pointer; begin Result:=@InputList; end; Function TEmitInterface.GetOutputList:Pointer; begin Result:=@OutputList; end; Function TEmitInterface.GetDataLayoutList:Pointer; begin Result:=@DataLayoutList; end; Function TEmitInterface.GetVertLayoutList:Pointer; begin Result:=@VertLayoutList; end; Function TEmitInterface.GetFragLayoutList:Pointer; begin Result:=@FragLayoutList; end; Function TEmitInterface.GetBufferList:Pointer; begin Result:=@BufferList; end; Function TEmitInterface.GetUniformList:Pointer; begin Result:=@UniformList; end; Function TEmitInterface.GetBitcastList:Pointer; begin Result:=@BitcastList; end; Function TEmitInterface.GetCacheOpList:Pointer; begin Result:=@CacheOpList; end; Function TEmitInterface.GetFuncList:Pointer; begin Result:=@FuncList; end; Function TEmitInterface.GetCursor:Pointer; begin Result:=@Cursor; end; // function TEmitInterface.NewRefNode:PsrNode; begin Result:=Alloc(SizeOf(TsrRefNode)); PsrRefNode(Result)^.Init; end; Function TEmitInterface.line:PspirvOp; begin Result:=nil; if (Main<>nil) then begin Result:=Main^.line; end; end; function TEmitInterface.curr_line:Pointer; begin Result:=line; end; function TEmitInterface.init_line:Pointer; begin Assert(InitBlock<>nil); if (InitBlock^.dummy.Parent=nil) then //is not init? begin InitBlock^.Init(Self); end; Result:=InitBlock^.line; Assert(Result<>nil); end; Procedure TEmitInterface.InitLists; begin Config.Init; LiteralList .Init(Self); TypeList .Init(Self); ConstList .Init(Self); RegsStory .Init(Self); CapabilityList.Init(Self); HeaderList .Init(Self); DecorateList .Init(Self); DebugInfoList .Init(Self); VariableList .Init(Self); InputList .Init(Self); OutputList .Init(Self); DataLayoutList.Init(Self); VertLayoutList.Init(Self); FragLayoutList.Init(Self); BufferList .Init(Self); UniformList .Init(Self); PrivateList .Init(Self); BitcastList .Init(Self); CacheOpList .Init(Self); end; function TEmitInterface.NewVariable:Pointer; begin Result:=VariableList.Fetch; end; // function TEmitInterface._get_line(ppLine:PPspirvOp):PspirvOp; begin if (ppLine=nil) then Exit(line); if (ppLine^=nil) then Exit(line); Result:=ppLine^; end; // Function TEmitInterface.NewRegPair:PsrRegPair; begin Result:=Alloc(SizeOf(TsrRegPair)); Result^.Init; end; Function TEmitInterface.NewReg(rtype:TsrDataType):PsrRegNode; begin Result:=RegsStory.FUnattach.New(line,rtype); end; Function TEmitInterface.NewReg(pConst:PsrConst;ppLine:PPspirvOp=nil):PsrRegNode; begin if (pConst=nil) then Exit(nil); Result:=NewReg(pConst^.dtype); Result^.pWriter:=pConst; Result^.pLine:=_get_line(ppLine); end; // Function TEmitInterface.NewReg_q(dtype:TsrDataType;value:QWORD;ppLine:PPspirvOp=nil):PsrRegNode; begin Result:=NewReg(ConstList.Fetch(dtype,value),ppLine); end; Function TEmitInterface.NewReg_b(value:Boolean;ppLine:PPspirvOp=nil):PsrRegNode; begin Result:=NewReg(ConstList.Fetch_b(value),ppLine); end; Function TEmitInterface.NewReg_i(dtype:TsrDataType;value:Integer;ppLine:PPspirvOp=nil):PsrRegNode; begin Result:=NewReg(ConstList.Fetch_i(dtype,value),ppLine); end; Function TEmitInterface.NewReg_s(dtype:TsrDataType;value:Single;ppLine:PPspirvOp=nil):PsrRegNode; begin Result:=NewReg(ConstList.Fetch_s(dtype,value),ppLine); end; function TEmitInterface.NewSpirvOp(OpId:DWORD):PSpirvOp; begin Result:=Alloc(SizeOf(TSpirvOp)); Result^.Init(OpId); Result^.adr:=Cursor.Adr; end; function TEmitInterface.NewLabelOp(sdep:Boolean):PSpirvOp; Var node:PSpirvOp; begin node:=NewSpirvOp(Op.OpLabel); node^.pDst:=NewRefNode; Result:=node; if sdep then node^.pDst^.mark_read(nil); end; function TEmitInterface.AddSpirvOp(OpId:DWORD):PSpirvOp; begin Result:=AddSpirvOp(line,OpId); end; function TEmitInterface.AddSpirvOp(pLine:PspirvOp;OpId:DWORD):PSpirvOp; begin Result:=InsSpirvOp(pLine,NewSpirvOp(OpId)); end; function TEmitInterface.AddSpirvOp(pLine,pNew:PspirvOp):PSpirvOp; begin Result:=InsSpirvOp(pLine,pNew); end; function TEmitInterface.AddSGlslOp(pLine:PspirvOp;OpId:DWORD):PSpirvOp; var ext,node:PSpirvOp; begin ext:=HeaderList.emit_glsl_ext; node:=AddSpirvOp(pLine,Op.OpExtInst); node^.AddParam(ext^.pDst); node^.AddLiteral(OpId,GlslOp.GetStr(OpId)); Result:=node; end; procedure TEmitInterface.PostLink(pLine,dst:PsrNode); var node:PspirvOp; begin node:=pLine^.AsType(ntOpCustom); Assert(node<>nil); if node^.IsType(ntOp) then if (node^.OpId=Op.OpNop) then begin node^.AddParam(dst); Exit; end; node:=AddSpirvOp(node,Op.OpNop); node^.AddParam(dst); node^.mark_not_used; end; procedure TEmitInterface.MakeCopy(dst:PsrRegSlot;src:PsrRegNode); var node:PsrRegNode; begin node:=dst^.New(line,src^.dtype); node^.pWriter:=src; PostLink(line,node); //post processing end; Procedure TEmitInterface.SetConst(pSlot:PsrRegSlot;pConst:PsrConst); var dst:PsrRegNode; begin dst:=pSlot^.New(line,pConst^.dtype); dst^.pWriter:=pConst; PostLink(line,dst); //post processing end; Procedure TEmitInterface.SetConst_q(pSlot:PsrRegSlot;dtype:TsrDataType;value:QWORD); begin SetConst(pSlot,ConstList.Fetch(dtype,value)); end; Procedure TEmitInterface.SetConst_b(pSlot:PsrRegSlot;value:Boolean); begin SetConst(pSlot,ConstList.Fetch_b(value)); end; Procedure TEmitInterface.SetConst_i(pSlot:PsrRegSlot;dtype:TsrDataType;value:Integer); begin SetConst(pSlot,ConstList.Fetch_i(dtype,value)); end; Procedure TEmitInterface.SetConst_s(pSlot:PsrRegSlot;dtype:TsrDataType;value:Single); begin SetConst(pSlot,ConstList.Fetch_s(dtype,value)); end; function TEmitInterface.AllocBlockOp:PsrOpBlock; begin Result:=Alloc(SizeOf(TsrOpBlock)); Result^.Init(Self); end; function TEmitInterface.NewBlockOp(Snap:TsrRegsSnapshot):PsrOpBlock; begin Result:=AllocBlockOp; Result^.Regs.pSnap_org :=Alloc(SizeOf(TsrRegsSnapshot)); Result^.Regs.pSnap_cur :=Alloc(SizeOf(TsrRegsSnapshot)); Result^.Regs.pSnap_org^:=Snap; Result^.Regs.pSnap_cur^:=Snap; Result^.Regs.FVolMark:=vmNone; Result^.Cond.FUseCont:=false; end; function TEmitInterface.InsertBlockOp(pLine:PspirvOp;pChild:PsrOpBlock):PspirvOp; begin pLine:=InsSpirvOp(pLine,PspirvOp(pChild)); pChild^.UpdateLevel; Result:=pLine; end; // procedure TEmitInterface.AddCapability(ID:DWORD); begin CapabilityList.Add(ID); end; end.