fpPS4/spirv/srInput.pas

326 lines
6.0 KiB
ObjectPascal
Raw Normal View History

2022-05-31 07:17:14 +00:00
unit srInput;
{$mode ObjFPC}{$H+}
interface
uses
2022-09-05 13:30:24 +00:00
typinfo,
sysutils,
spirv,
ginodes,
srNode,
srType,
srReg,
srOp,
2022-11-05 14:48:13 +00:00
srConst,
2022-09-05 13:30:24 +00:00
srLayout,
srVariable,
srCapability,
srDecorate;
2022-05-31 07:17:14 +00:00
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,
2022-09-05 13:30:24 +00:00
itThreadId,
2022-05-31 07:17:14 +00:00
2022-09-05 13:30:24 +00:00
//
itSampleId,
itLayer,
itSubgroupLocalInvocationId
2022-05-31 07:17:14 +00:00
);
2022-09-05 13:30:24 +00:00
ntInput=class(ntDescriptor)
class function GetStorageName(node:PsrNode):RawByteString; override;
end;
2022-05-31 07:17:14 +00:00
PsrInput=^TsrInput;
TsrInput=object(TsrDescriptor)
2022-09-05 13:30:24 +00:00
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;
2022-05-31 07:17:14 +00:00
end;
2022-09-05 13:30:24 +00:00
PsrInputList=^TsrInputList;
2022-05-31 07:17:14 +00:00
TsrInputList=object
type
TNodeFetch=specialize TNodeFetch<PsrInput,TsrInput>;
var
2022-09-05 13:30:24 +00:00
FEmit:TCustomEmit;
2022-05-31 07:17:14 +00:00
FNTree:TNodeFetch;
2022-09-05 13:30:24 +00:00
Procedure Init(Emit:TCustomEmit); inline;
function Search(itype:TpsslInputType;id:Byte):PsrInput;
function Fetch(rtype:TsrDataType;itype:TpsslInputType;id:Byte):PsrInput;
2022-05-31 07:17:14 +00:00
Function First:PsrInput;
Function Next(node:PsrInput):PsrInput;
2022-11-05 14:48:13 +00:00
procedure Test;
2022-09-05 13:30:24 +00:00
procedure AllocBinding;
2022-05-31 07:17:14 +00:00
procedure AllocEntryPoint(EntryPoint:PSpirvOp);
end;
implementation
2022-09-05 13:30:24 +00:00
class function ntInput.GetStorageName(node:PsrNode):RawByteString;
begin
Result:=PsrInput(node)^.GetStorageName;
end;
//
2022-05-31 07:17:14 +00:00
function TsrInput.c(n1,n2:PsrInput):Integer;
begin
2022-09-05 13:30:24 +00:00
//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);
2022-05-31 07:17:14 +00:00
end;
2022-09-05 13:30:24 +00:00
Procedure TsrInput.Init; inline;
begin
fntype :=ntInput;
FStorage:=StorageClass.Input;
FBinding:=-1;
end;
function TsrInput.GetStorageName:RawByteString;
2022-05-31 07:17:14 +00:00
begin
Result:=GetEnumName(TypeInfo(TpsslInputType),ord(key.itype))+IntToStr(key.typeid);
end;
2022-09-05 13:30:24 +00:00
Procedure TsrInputList.Init(Emit:TCustomEmit); inline;
2022-05-31 07:17:14 +00:00
begin
2022-09-05 13:30:24 +00:00
FEmit:=Emit;
2022-05-31 07:17:14 +00:00
end;
2022-09-05 13:30:24 +00:00
function TsrInputList.Search(itype:TpsslInputType;id:Byte):PsrInput;
2022-05-31 07:17:14 +00:00
var
node:TsrInput;
begin
node:=Default(TsrInput);
2022-09-05 13:30:24 +00:00
node.Init;
2022-05-31 07:17:14 +00:00
node.key.itype:=itype;
node.key.typeid:=id;
Result:=FNTree.Find(@node);
end;
2022-09-05 13:30:24 +00:00
function TsrInputList.Fetch(rtype:TsrDataType;itype:TpsslInputType;id:Byte):PsrInput;
2022-05-31 07:17:14 +00:00
var
node:TsrInput;
begin
node:=Default(TsrInput);
2022-09-05 13:30:24 +00:00
node.Init;
2022-05-31 07:17:14 +00:00
node.key.itype:=itype;
node.key.typeid:=id;
Result:=FNTree.Find(@node);
if (Result=nil) then
begin
2022-09-05 13:30:24 +00:00
Result:=FEmit.Alloc(SizeOf(TsrInput));
2022-05-31 07:17:14 +00:00
Move(node,Result^,SizeOf(TsrInput));
2022-09-05 13:30:24 +00:00
//
Result^.InitType(rtype,FEmit);
Result^.InitVar(FEmit);
//
2022-05-31 07:17:14 +00:00
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;
2022-11-05 14:48:13 +00:00
procedure TsrInputList.Test;
var
node:PsrInput;
pVar:PsrVariable;
procedure SetConst;
var
c:PsrConst;
l:PspirvOp;
begin
l:=node^.pReg^.pWriter^.AsType(ntOp);
l^.mark_not_used;
c:=PsrConstList(FEmit.GetConstList)^.Fetch(node^.pReg^.dtype,0);
node^.pReg^.pWriter:=c;
end;
begin
node:=First;
While (node<>nil) do
begin
pVar:=node^.pVar;
if (pVar<>nil) and node^.IsUsed then
begin
Case node^.key.itype of
itPerspSample,
itPerspCenter,
itPerspCentroid,
itLinearSample,
itLinearCenter,
itLinearCentroid:
begin
//need support for barycentric coordinates, just a constant for now
SetConst;
end;
else;
end;
end;
node:=Next(node);
end;
end;
2022-09-05 13:30:24 +00:00
procedure TsrInputList.AllocBinding;
2022-05-31 07:17:14 +00:00
var
2022-09-05 13:30:24 +00:00
pDecorateList:PsrDecorateList;
pCapabilityList:PsrCapabilityList;
2022-05-31 07:17:14 +00:00
node:PsrInput;
pVar:PsrVariable;
2022-11-05 14:48:13 +00:00
procedure TestFlat;
begin
//only pixel shader
if (FEmit.GetExecutionModel=ExecutionModel.Fragment) then
if (node^.pReg<>nil) then
if (node^.pReg^.dtype.isInt) then //only integer
begin
pDecorateList^.OpDecorate(pVar,Decoration.Flat,0);
end;
end;
2022-05-31 07:17:14 +00:00
begin
2022-09-05 13:30:24 +00:00
pDecorateList :=FEmit.GetDecorateList;
pCapabilityList:=FEmit.GetCapabilityList;
2022-05-31 07:17:14 +00:00
node:=First;
While (node<>nil) do
begin
pVar:=node^.pVar;
2022-09-05 13:30:24 +00:00
if (pVar<>nil) and node^.IsUsed then
2022-05-31 07:17:14 +00:00
begin
2022-11-05 14:48:13 +00:00
2022-05-31 07:17:14 +00:00
Case node^.key.itype of
itFloatPos:
begin
2022-09-05 13:30:24 +00:00
pDecorateList^.OpDecorate(pVar,Decoration.BuiltIn,BuiltIn.FragCoord);
2022-05-31 07:17:14 +00:00
end;
itTgid:
begin
2022-09-05 13:30:24 +00:00
pDecorateList^.OpDecorate(pVar,Decoration.BuiltIn,BuiltIn.WorkgroupId);
2022-05-31 07:17:14 +00:00
end;
itThreadId:
begin
2022-09-05 13:30:24 +00:00
pDecorateList^.OpDecorate(pVar,Decoration.BuiltIn,BuiltIn.LocalInvocationID);
2022-05-31 07:17:14 +00:00
end;
itVIndex:
begin
2022-09-05 13:30:24 +00:00
pDecorateList^.OpDecorate(pVar,Decoration.BuiltIn,BuiltIn.VertexIndex);
2022-05-31 07:17:14 +00:00
end;
2022-07-09 20:22:16 +00:00
itFrontFace:
begin
2022-09-05 13:30:24 +00:00
pDecorateList^.OpDecorate(pVar,Decoration.BuiltIn,BuiltIn.FrontFacing);
2022-07-09 20:22:16 +00:00
end;
2022-09-05 13:30:24 +00:00
itLayer:
begin
2022-11-05 14:48:13 +00:00
TestFlat;
2022-09-05 13:30:24 +00:00
pDecorateList^.OpDecorate(pVar,Decoration.BuiltIn,BuiltIn.Layer);
pCapabilityList^.Add(Capability.Geometry);
end;
itSampleId:
begin
2022-11-05 14:48:13 +00:00
TestFlat;
2022-09-05 13:30:24 +00:00
pDecorateList^.OpDecorate(pVar,Decoration.BuiltIn,BuiltIn.SampleId);
end;
2022-11-05 14:48:13 +00:00
itPerspSample,
itPerspCenter,
itPerspCentroid,
itLinearSample,
itLinearCenter,
itLinearCentroid:
begin
//
end;
2022-05-31 07:17:14 +00:00
else
2022-11-05 14:48:13 +00:00
Assert(false,'AllocBinding:'+GetEnumName(TypeInfo(TpsslInputType),ord(node^.key.itype)));
2022-05-31 07:17:14 +00:00
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;
2022-09-05 13:30:24 +00:00
if (pVar<>nil) and node^.IsUsed then
2022-05-31 07:17:14 +00:00
begin
2022-09-05 13:30:24 +00:00
EntryPoint^.AddParam(pVar);
2022-05-31 07:17:14 +00:00
end;
node:=Next(node);
end;
end;
end.