fpPS4/spirv/srDecorate.pas
2022-11-15 15:54:47 +03:00

186 lines
3.7 KiB
ObjectPascal

unit srDecorate;
{$mode ObjFPC}{$H+}
interface
uses
spirv,
ginodes,
srNode,
srOp;
type
PsrHeaderList=^TsrHeaderList;
TsrHeaderList=object(TsrOpBlockCustom)
FGLSL_std_450:PSpirvOp;
function emit_glsl_ext:PSpirvOp;
end;
PsrDecorate=^TsrDecorate;
TsrDecorate=object
private
pLeft,pRight:PsrDecorate;
//----
key:packed record
data:PsrNode;
param:array[0..2] of DWORD;
end;
function c(n1,n2:PsrDecorate):Integer; static;
public
node:PSpirvOp;
end;
PsrDecorateList=^TsrDecorateList;
TsrDecorateList=object(TsrOpBlockCustom)
type
TNodeFetch=specialize TNodeFetch<PsrDecorate,TsrDecorate>;
var
FNTree:TNodeFetch;
function Fetch(data:PsrNode;param1,param2,param3:DWORD):PsrDecorate;
procedure OpDecorate(Data:PsrNode;dec_id,param:DWORD);
procedure OpMember (Data:PsrNode;index,offset:DWORD);
end;
PsrDebugInfoList=^TsrDebugInfoList;
TsrDebugInfoList=object(TsrOpBlockCustom)
procedure OpSource(const n:RawByteString);
procedure OpName (Data:PsrNode;const n:RawByteString);
function OpString(const n:RawByteString):PsrNode;
end;
implementation
//
function TsrHeaderList.emit_glsl_ext:PSpirvOp;
begin
if (FGLSL_std_450=nil) then
begin
FGLSL_std_450:=AddSpirvOp(Op.OpExtInstImport);
FGLSL_std_450^.pDst:=Emit.NewRefNode;
FGLSL_std_450^.AddString('GLSL.std.450');
end;
Result:=FGLSL_std_450;
end;
//
function TsrDecorate.c(n1,n2:PsrDecorate):Integer;
var
i:Byte;
begin
//first data
Result:=Integer(n1^.key.data>n2^.key.data)-Integer(n1^.key.data<n2^.key.data);
if (Result<>0) then Exit;
//param[i]
For i:=0 to 2 do
begin
Result:=Integer(n1^.key.param[i]>n2^.key.param[i])-Integer(n1^.key.param[i]<n2^.key.param[i]);
if (Result<>0) then Exit;
end;
end;
//
function TsrDecorateList.Fetch(data:PsrNode;param1,param2,param3:DWORD):PsrDecorate;
var
node:TsrDecorate;
begin
node:=Default(TsrDecorate);
node.key.data:=data;
node.key.param[0]:=param1;
node.key.param[1]:=param2;
node.key.param[2]:=param3;
Result:=FNTree.Find(@node);
if (Result=nil) then
begin
Result:=Emit.Alloc(SizeOf(TsrDecorate));
Move(node,Result^,SizeOf(TsrDecorate));
FNTree.Insert(Result);
end;
end;
procedure TsrDecorateList.OpDecorate(Data:PsrNode;dec_id,param:DWORD);
var
deco:PsrDecorate;
node:PSpirvOp;
begin
deco:=Fetch(Data,Op.OpDecorate,dec_id,param);
if (deco^.node<>nil) then Exit;
node:=AddSpirvOp(Op.OpDecorate);
node^.AddParam(Data);
node^.AddLiteral(dec_id,Decoration.GetStr(dec_id));
Case dec_id of
Decoration.BuiltIn:
node^.AddLiteral(param,BuiltIn.GetStr(param));
Decoration.ArrayStride,
Decoration.MatrixStride,
Decoration.Location,
Decoration.Index,
Decoration.Binding,
Decoration.DescriptorSet:
node^.AddLiteral(param);
else;
end;
deco^.node:=node;
end;
procedure TsrDecorateList.OpMember(Data:PsrNode;index,offset:DWORD);
var
deco:PsrDecorate;
node:PSpirvOp;
begin
deco:=Fetch(Data,Op.OpMemberDecorate,index,offset);
if (deco^.node<>nil) then Exit;
node:=AddSpirvOp(Op.OpMemberDecorate);
node^.AddParam(Data);
node^.AddLiteral(index);
node^.AddLiteral(Decoration.Offset,Decoration.GetStr(Decoration.Offset));
node^.AddLiteral(offset);
deco^.node:=node;
end;
//
procedure TsrDebugInfoList.OpSource(const n:RawByteString);
var
node:PSpirvOp;
begin
node:=AddSpirvOp(Op.OpSourceExtension);
node^.AddString(n);
end;
procedure TsrDebugInfoList.OpName(Data:PsrNode;const n:RawByteString);
var
node:PSpirvOp;
begin
node:=AddSpirvOp(Op.OpName);
node^.AddParam(Data);
node^.AddString(n);
end;
function TsrDebugInfoList.OpString(const n:RawByteString):PsrNode;
var
node:PSpirvOp;
begin
node:=AddSpirvOp(Op.OpString);
node^.pDst:=Emit.NewRefNode;
node^.AddString(n);
Result:=node^.pDst;
end;
//
end.