FPPS4/spirv/srInput.pas

201 lines
3.5 KiB
Plaintext

unit srInput;
{$mode ObjFPC}{$H+}
interface
uses
typinfo,
sysutils,
spirv,
srNodes,
srReg,
srOp,
srLayout,
srVariable,
srDecorate;
type
TpsslInputType=(
itUnknow,
itVsState,
itWriteIndex,
itOffset,
itWaveId,
itScratch,
itVIndex,
itVInstance,
itPsState,
itWaveCnt,
itPerspSample,
itPerspCenter,
itPerspCentroid,
itPerspW,
itLinearSample,
itLinearCenter,
itLinearCentroid,
itFloatPos,
itFrontFace,
itAncillary,
itSampleCoverage,
itPosFixed,
itTgid,
itTgSize,
itThreadId
);
PsrInput=^TsrInput;
TsrInput=object(TsrDescriptor)
pLeft,pRight:PsrInput;
//----
key:packed record
itype:TpsslInputType;
typeid:Byte;
end;
pReg:PsrRegNode;
function c(n1,n2:PsrInput):Integer; static;
function GetName:RawByteString;
end;
TsrInputList=object
type
TNodeFetch=specialize TNodeFetch<PsrInput,TsrInput>;
var
Alloc:TfnAlloc;
FNTree:TNodeFetch;
procedure Init(cb:TfnAlloc);
function Search(itype:TpsslInputType;id:Byte=0):PsrInput;
function Fetch(itype:TpsslInputType;id:Byte=0):PsrInput;
Function First:PsrInput;
Function Next(node:PsrInput):PsrInput;
procedure AllocBinding(Decorates:PsrDecorateList);
procedure AllocEntryPoint(EntryPoint:PSpirvOp);
end;
implementation
function TsrInput.c(n1,n2:PsrInput):Integer;
begin
Result:=CompareByte(n1^.key,n2^.key,SizeOf(TsrInput.key));
end;
function TsrInput.GetName:RawByteString;
begin
Result:=GetEnumName(TypeInfo(TpsslInputType),ord(key.itype))+IntToStr(key.typeid);
end;
procedure TsrInputList.Init(cb:TfnAlloc);
begin
Alloc:=cb;
end;
function TsrInputList.Search(itype:TpsslInputType;id:Byte=0):PsrInput;
var
node:TsrInput;
begin
node:=Default(TsrInput);
node.key.itype:=itype;
node.key.typeid:=id;
Result:=FNTree.Find(@node);
end;
function TsrInputList.Fetch(itype:TpsslInputType;id:Byte=0):PsrInput;
var
node:TsrInput;
begin
node:=Default(TsrInput);
node.key.itype:=itype;
node.key.typeid:=id;
node.FStorage:=StorageClass.Input;
node.FBinding:=-1;
Result:=FNTree.Find(@node);
if (Result=nil) then
begin
Result:=Alloc(SizeOf(TsrInput));
Move(node,Result^,SizeOf(TsrInput));
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(Decorates:PsrDecorateList);
var
node:PsrInput;
pVar:PsrVariable;
begin
if (Decorates=nil) then Exit;
node:=First;
While (node<>nil) do
begin
pVar:=node^.pVar;
if (pVar<>nil) then
begin
Case node^.key.itype of
itFloatPos:
begin
Decorates^.emit_decorate(ntVar,pVar,Decoration.BuiltIn,BuiltIn.FragCoord);
end;
itTgid:
begin
Decorates^.emit_decorate(ntVar,pVar,Decoration.BuiltIn,BuiltIn.WorkgroupId);
end;
itThreadId:
begin
Decorates^.emit_decorate(ntVar,pVar,Decoration.BuiltIn,BuiltIn.LocalInvocationID);
end;
itVIndex:
begin
Decorates^.emit_decorate(ntVar,pVar,Decoration.BuiltIn,BuiltIn.VertexIndex);
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) then
begin
EntryPoint^.AddParam(ntVar,pVar);
end;
node:=Next(node);
end;
end;
end.