unit srFragLayout; {$mode ObjFPC}{$H+} interface uses typinfo, sysutils, spirv, ginodes, srNode, srType, srReg, srOp, srLayout, srVariable, srInput, srCapability, srDecorate; type //itPerspSample, //Sample //itPerspCenter, //itPerspCentroid, //Centroid //itLinearSample, //NoPerspective Sample //itLinearCenter, //NoPerspective //itLinearCentroid, //NoPerspective Centroid PsrFragLayoutKey=^TsrFragLayoutKey; TsrFragLayoutKey=packed record itype :TpsslInputType; location:Integer; end; TsrFragLayout=class(TsrDescriptor) public pLeft,pRight:TsrFragLayout; key:TsrFragLayoutKey; class function c(n1,n2:PsrFragLayoutKey):Integer; static; public pReg:TsrRegNode; // function _GetStorageName:RawByteString; override; // property itype:TpsslInputType read key.itype; Procedure Init; inline; function GetStorageName:RawByteString; end; ntFragLayout=TsrFragLayout; PsrFragLayoutList=^TsrFragLayoutList; TsrFragLayoutList=object type TNodeFetch=specialize TNodeTreeClass; var FEmit:TCustomEmit; FTree:TNodeFetch; procedure Init(Emit:TCustomEmit); inline; function Fetch(itype:TpsslInputType;location:DWORD;rtype:TsrDataType):TsrFragLayout; Function First:TsrFragLayout; Function Next(node:TsrFragLayout):TsrFragLayout; procedure AllocBinding; procedure AllocEntryPoint(EntryPoint:TSpirvOp); end; implementation function TsrFragLayout._GetStorageName:RawByteString; begin Result:=GetStorageName; end; // class function TsrFragLayout.c(n1,n2:PsrFragLayoutKey):Integer; begin //first itype Result:=ord(n1^.itype>n2^.itype)-ord(n1^.itype0) then Exit; //second location Result:=ord(n1^.location>n2^.location)-ord(n1^.location; Result.Init; Result.key:=key; Result.FBinding:=location; // Result.InitType(rtype); Result.InitVar(); // FTree.Insert(Result); end; end; Function TsrFragLayoutList.First:TsrFragLayout; begin Result:=FTree.Min; end; Function TsrFragLayoutList.Next(node:TsrFragLayout):TsrFragLayout; begin Result:=FTree.Next(node); end; procedure TsrFragLayoutList.AllocBinding; var pDecorateList:TsrDecorateList; pCapabilityList:PsrCapabilityList; node:TsrFragLayout; pVar:TsrVariable; begin pDecorateList:=FEmit.GetDecorateList; pCapabilityList:=FEmit.GetCapabilityList; //interpolate param node:=First; While (node<>nil) do begin pVar:=node.pVar; if (pVar<>nil) and node.IsUsed then begin pDecorateList.OpDecorate(pVar,Decoration.Location,node.FBinding); case node.itype of itPerspSample: //Sample begin pCapabilityList^.Add(Capability.SampleRateShading); pDecorateList.OpDecorate(pVar,Decoration.Sample,0); end; itPerspCenter:; //default itPerspCentroid: //Centroid begin pDecorateList.OpDecorate(pVar,Decoration.Centroid,0); end; itLinearSample: //NoPerspective Sample begin pDecorateList.OpDecorate(pVar,Decoration.NoPerspective,0); pDecorateList.OpDecorate(pVar,Decoration.Sample,0); end; itLinearCenter: //NoPerspective begin pDecorateList.OpDecorate(pVar,Decoration.NoPerspective,0); end; itLinearCentroid: //NoPerspective Centroid begin pDecorateList.OpDecorate(pVar,Decoration.NoPerspective,0); pDecorateList.OpDecorate(pVar,Decoration.Centroid,0); end; itFlat: begin pDecorateList.OpDecorate(pVar,Decoration.Flat,0); end; else Assert(false,'AllocBinding:'+GetEnumName(TypeInfo(TpsslInputType),ord(node.itype))); end; end; node:=Next(node); end; end; procedure TsrFragLayoutList.AllocEntryPoint(EntryPoint:TSpirvOp); var node:TsrFragLayout; pVar:TsrVariable; begin if (EntryPoint=nil) then Exit; node:=First; While (node<>nil) do begin pVar:=node.pVar; if (pVar<>nil) and node.IsUsed then begin EntryPoint.AddParam(pVar); end; node:=Next(node); end; end; end.