fpPS4/spirv/srInput.pas
2022-09-05 16:30:24 +03:00

255 lines
4.8 KiB
ObjectPascal

unit srInput;
{$mode ObjFPC}{$H+}
interface
uses
typinfo,
sysutils,
spirv,
ginodes,
srNode,
srType,
srReg,
srOp,
srLayout,
srVariable,
srCapability,
srDecorate;
type
TpsslInputType=(
itUnknow,
itVsState,
itWriteIndex,
itOffset,
itWaveId,
itScratch,
itVIndex,
itVInstance,
itPsState,
itWaveCnt,
itPerspSample,
itPerspCenter,
itPerspCentroid,
itPerspW,
itLinearSample,
itLinearCenter,
itLinearCentroid,
itFloatPos,
itFrontFace,
itSampleCoverage,
itPosFixed,
itTgid,
itTgSize,
itThreadId,
//
itSampleId,
itLayer,
itSubgroupLocalInvocationId
);
ntInput=class(ntDescriptor)
class function GetStorageName(node:PsrNode):RawByteString; override;
end;
PsrInput=^TsrInput;
TsrInput=object(TsrDescriptor)
private
pLeft,pRight:PsrInput;
//----
key:packed record
itype:TpsslInputType;
typeid:Byte;
end;
function c(n1,n2:PsrInput):Integer; static;
public
pReg:PsrRegNode;
property itype:TpsslInputType read key.itype;
property typeid:Byte read key.typeid;
Procedure Init; inline;
function GetStorageName:RawByteString;
end;
PsrInputList=^TsrInputList;
TsrInputList=object
type
TNodeFetch=specialize TNodeFetch<PsrInput,TsrInput>;
var
FEmit:TCustomEmit;
FNTree:TNodeFetch;
Procedure Init(Emit:TCustomEmit); inline;
function Search(itype:TpsslInputType;id:Byte):PsrInput;
function Fetch(rtype:TsrDataType;itype:TpsslInputType;id:Byte):PsrInput;
Function First:PsrInput;
Function Next(node:PsrInput):PsrInput;
procedure AllocBinding;
procedure AllocEntryPoint(EntryPoint:PSpirvOp);
end;
implementation
class function ntInput.GetStorageName(node:PsrNode):RawByteString;
begin
Result:=PsrInput(node)^.GetStorageName;
end;
//
function TsrInput.c(n1,n2:PsrInput):Integer;
begin
//first itype
Result:=Integer(n1^.key.itype>n2^.key.itype)-Integer(n1^.key.itype<n2^.key.itype);
if (Result<>0) then Exit;
//second typeid
Result:=Integer(n1^.key.typeid>n2^.key.typeid)-Integer(n1^.key.typeid<n2^.key.typeid);
end;
Procedure TsrInput.Init; inline;
begin
fntype :=ntInput;
FStorage:=StorageClass.Input;
FBinding:=-1;
end;
function TsrInput.GetStorageName:RawByteString;
begin
Result:=GetEnumName(TypeInfo(TpsslInputType),ord(key.itype))+IntToStr(key.typeid);
end;
Procedure TsrInputList.Init(Emit:TCustomEmit); inline;
begin
FEmit:=Emit;
end;
function TsrInputList.Search(itype:TpsslInputType;id:Byte):PsrInput;
var
node:TsrInput;
begin
node:=Default(TsrInput);
node.Init;
node.key.itype:=itype;
node.key.typeid:=id;
Result:=FNTree.Find(@node);
end;
function TsrInputList.Fetch(rtype:TsrDataType;itype:TpsslInputType;id:Byte):PsrInput;
var
node:TsrInput;
begin
node:=Default(TsrInput);
node.Init;
node.key.itype:=itype;
node.key.typeid:=id;
Result:=FNTree.Find(@node);
if (Result=nil) then
begin
Result:=FEmit.Alloc(SizeOf(TsrInput));
Move(node,Result^,SizeOf(TsrInput));
//
Result^.InitType(rtype,FEmit);
Result^.InitVar(FEmit);
//
FNTree.Insert(Result);
end;
end;
Function TsrInputList.First:PsrInput;
begin
Result:=FNTree.Min;
end;
Function TsrInputList.Next(node:PsrInput):PsrInput;
begin
Result:=FNTree.Next(node);
end;
procedure TsrInputList.AllocBinding;
var
pDecorateList:PsrDecorateList;
pCapabilityList:PsrCapabilityList;
node:PsrInput;
pVar:PsrVariable;
begin
pDecorateList :=FEmit.GetDecorateList;
pCapabilityList:=FEmit.GetCapabilityList;
node:=First;
While (node<>nil) do
begin
pVar:=node^.pVar;
if (pVar<>nil) and node^.IsUsed then
begin
Case node^.key.itype of
itFloatPos:
begin
pDecorateList^.OpDecorate(pVar,Decoration.BuiltIn,BuiltIn.FragCoord);
end;
itTgid:
begin
pDecorateList^.OpDecorate(pVar,Decoration.BuiltIn,BuiltIn.WorkgroupId);
end;
itThreadId:
begin
pDecorateList^.OpDecorate(pVar,Decoration.BuiltIn,BuiltIn.LocalInvocationID);
end;
itVIndex:
begin
pDecorateList^.OpDecorate(pVar,Decoration.BuiltIn,BuiltIn.VertexIndex);
end;
itFrontFace:
begin
pDecorateList^.OpDecorate(pVar,Decoration.BuiltIn,BuiltIn.FrontFacing);
end;
itLayer:
begin
pDecorateList^.OpDecorate(pVar,Decoration.BuiltIn,BuiltIn.Layer);
pCapabilityList^.Add(Capability.Geometry);
end;
itSampleId:
begin
pDecorateList^.OpDecorate(pVar,Decoration.BuiltIn,BuiltIn.SampleId);
end;
else
{Assert(false,'AllocBinding')};
end;
end;
node:=Next(node);
end;
end;
procedure TsrInputList.AllocEntryPoint(EntryPoint:PSpirvOp);
var
node:PsrInput;
pVar:PsrVariable;
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.