New shader recompiler version

This commit is contained in:
Pavel 2022-09-05 16:30:24 +03:00
parent 80d3bf043b
commit 818cddd5b7
64 changed files with 12960 additions and 10583 deletions

File diff suppressed because it is too large Load Diff

View File

@ -7,36 +7,35 @@ interface
uses
sysutils,
spirv,
srNodes,
srNode,
srType,
srTypes,
srConst,
srRefId,
srReg,
srLayout,
srBuffer,
srVariable,
srInput,
srOutput,
srVertLayout,
srFragLayout,
srUniform,
srBuffer,
srDecorate,
srOp,
srOpUtils,
SprvEmit;
emit_fetch;
type
TSprvEmit_alloc=object(TSprvEmit)
procedure Alloc;
TSprvEmit_alloc=class(TEmitFetch)
procedure AllocStage;
procedure AllocSpirvID(P:PsrRefId);
procedure AllocBinding;
procedure AllocTypeBinding;
procedure AllocSourceExtension;
procedure AllocTypeName;
Procedure AllocVarName;
procedure AllocEntryPoint;
procedure AllocHeader;
procedure AllocOpListId(node:PspirvOp);
procedure AllocHeaderId;
procedure AllocTypesId;
procedure AllocConstId;
procedure AllocVariableId;
procedure AllocOpSingle(const Param:TOpParamSingle);
procedure AllocOpParamNode(node:POpParamNode);
procedure AllocListId(node:PsrNode);
procedure AllocFuncId;
procedure AllocOpId(node:PSpirvOp);
procedure AllocOpBlock(pBlock:PsrOpBlock);
@ -44,134 +43,99 @@ type
implementation
procedure TSprvEmit_alloc.Alloc;
procedure TSprvEmit_alloc.AllocStage;
begin
AllocBinding;
BufferList.AllocTypeBinding;
AllocTypeBinding;
AllocHeader;
AllocSourceExtension;
AllocTypeName;
AllocVarName;
//Source Extension
DataLayoutList.AllocSourceExtension;
DataLayoutList.AllocFuncExt;
VertLayoutList.AllocSourceExtension;
UniformList .AllocSourceExtension;
BufferList .AllocSourceExtension;
AllocHeaderId;
//Decorate Name
BufferList .AllocName;
VariableList.AllocName;
//header id
AllocOpListId(HeaderList.First);
AllocOpListId(DebugInfoList.First);
AllocOpListId(DecorateList.First);
//element id
AllocListId(TypeList.First);
AllocListId(ConstList.First);
AllocListId(VariableList.First);
AllocTypesId;
AllocConstId;
AllocVariableId;
AllocFuncId;
end;
procedure TSprvEmit_alloc.AllocSpirvID(P:PsrRefId);
begin
FSpirvIdAlloc.FetchSpirvID(P);
RefIdAlloc.FetchSpirvID(P);
end;
procedure TSprvEmit_alloc.AllocBinding;
var
FBinding:Integer;
begin
FInputs .AllocBinding(@FDecorates);
FOutputs .AllocBinding(@FDecorates);
FVertLayouts.AllocBinding(@FDecorates);
FFragLayouts.AllocBinding(@FDecorates,@FSpirvCaps);
InputList .AllocBinding;
OutputList.AllocBinding;
VertLayoutList.AllocBinding;
FragLayoutList.AllocBinding;
FBinding:=0;
FUniforms.AllocBinding(FBinding,@FDecorates);
FBuffers .AllocBinding(FBinding,@FDecorates);
UniformList.AllocBinding(FBinding);
BufferList .AllocBinding(FBinding);
end;
procedure TSprvEmit_alloc.AllocTypeBinding;
var
node:PsrType;
pField:PsrField;
begin
node:=FSpirvTypes.FList.pHead;
node:=TypeList.First;
While (node<>nil) do
begin
case node^.dtype of
dtTypeStruct:
case node^.OpId of
Op.OpTypeArray,
Op.OpTypeRuntimeArray:
begin
pField:=node^.key.ext.pField;
if (pField<>nil) then
DecorateList.OpDecorate(node,Decoration.ArrayStride,node^.array_stride);
end;
Op.OpTypeFloat:
begin
if (pField^.GetStructDecorate<>DWORD(-1)) then
begin
FDecorates.emit_decorate(ntType,node,pField^.GetStructDecorate,0);
case node^.dtype.BitSize of
16:AddCapability(Capability.Float16);
64:AddCapability(Capability.Float64);
else;
end;
pField^.AllocBinding(node,@FDecorates);
end;
end;
dtTypeArray,
dtTypeRuntimeArray:
begin
FDecorates.emit_decorate(ntType,node,Decoration.ArrayStride,node^.key.ext.array_stride);
end;
else;
end;
node:=node^.pNext;
end;
end;
procedure TSprvEmit_alloc.AllocSourceExtension;
begin
FDataLayouts.AllocSourceExtension(@FDebugInfo);
FDataLayouts.AllocFuncExt(@FDebugInfo,FCodeHeap);
FVertLayouts.AllocSourceExtension(@FDebugInfo);
FUniforms .AllocSourceExtension(@FDebugInfo);
FBuffers .AllocSourceExtension(@FDebugInfo);
end;
procedure TSprvEmit_alloc.AllocTypeName;
var
node:PsrType;
pField:PsrField;
begin
node:=FSpirvTypes.FList.pHead;
While (node<>nil) do
begin
case node^.dtype of
dtTypeStruct:
begin
pField:=node^.key.ext.pField;
if (pField<>nil) and
(pField^.parent=nil) and
(pField^.pBuffer<>nil) then
Op.OpTypeInt:
begin
FDebugInfo.emit_name(ntType,node,pField^.pBuffer^.GetStructName);
case node^.dtype.BitSize of
8:AddCapability(Capability.Int8);
16:AddCapability(Capability.Int16);
64:AddCapability(Capability.Int64);
else;
end;
end;
end;
else;
end;
node:=node^.pNext;
end;
end;
Procedure TSprvEmit_alloc.AllocVarName;
var
node:PsrVariable;
n:RawByteString;
begin
node:=FVariables.pHead;
While (node<>nil) do
begin
if (node^.pType<>nil) then
begin
n:=node^.GetName;
if (n<>'') then
begin
FDebugInfo.emit_name(ntVar,node,n);
end;
end;
node:=node^.pNext;
node:=node^.Next;
end;
end;
@ -180,7 +144,7 @@ begin
While (node<>nil) do
begin
AllocOpId(node);
node:=node^.pNext;
node:=node^.Next;
end;
end;
@ -188,24 +152,24 @@ procedure TSprvEmit_alloc.AllocEntryPoint;
var
node:PSpirvOp;
begin
node:=FHeader.AddSpirvOp(Op.OpEntryPoint);
node:=HeaderList.AddSpirvOp(Op.OpEntryPoint);
node^.AddLiteral(FExecutionModel,ExecutionModel.GetStr(FExecutionModel));
node^.AddParam(ntFunc,FMain);
node^.AddString(FMain^.name);
node^.AddParam(Main);
node^.AddString(Main^.name);
FInputs .AllocEntryPoint(node);
FVertLayouts.AllocEntryPoint(node);
FFragLayouts.AllocEntryPoint(node);
FOutputs .AllocEntryPoint(node);
InputList .AllocEntryPoint(node);
VertLayoutList.AllocEntryPoint(node);
FragLayoutList.AllocEntryPoint(node);
OutputList .AllocEntryPoint(node);
end;
procedure TSprvEmit_alloc.AllocHeader;
var
node:PSpirvOp;
begin
node:=FHeader.AddSpirvOp(Op.OpMemoryModel);
node:=HeaderList.AddSpirvOp(Op.OpMemoryModel);
node^.AddLiteral(AddressingModel.Logical,AddressingModel.GetStr(AddressingModel.Logical));
node^.AddLiteral(MemoryModel.GLSL450,MemoryModel.GetStr(MemoryModel.GLSL450));
@ -214,14 +178,14 @@ begin
Case FExecutionModel of
ExecutionModel.Fragment:
begin
node:=FHeader.AddSpirvOp(Op.OpExecutionMode);
node^.AddParam(ntFunc,FMain);
node:=HeaderList.AddSpirvOp(Op.OpExecutionMode);
node^.AddParam(Main);
node^.AddLiteral(ExecutionMode.OriginUpperLeft,ExecutionMode.GetStr(ExecutionMode.OriginUpperLeft));
end;
ExecutionModel.GLCompute:
begin
node:=FHeader.AddSpirvOp(Op.OpExecutionMode);
node^.AddParam(ntFunc,FMain);
node:=HeaderList.AddSpirvOp(Op.OpExecutionMode);
node^.AddParam(Main);
node^.AddLiteral(ExecutionMode.LocalSize,ExecutionMode.GetStr(ExecutionMode.LocalSize));
node^.AddLiteral(FLocalSize.x);
node^.AddLiteral(FLocalSize.y);
@ -231,135 +195,12 @@ begin
end;
procedure TSprvEmit_alloc.AllocHeaderId;
procedure TSprvEmit_alloc.AllocListId(node:PsrNode);
begin
AllocOpListId(FHeader.pHead);
AllocOpListId(FDebugInfo.pHead);
AllocOpListId(FDecorates.pHead);
end;
procedure TSprvEmit_alloc.AllocTypesId;
var
node:PsrType;
pConst:PsrConst;
begin
node:=FSpirvTypes.FList.pHead;
While (node<>nil) do
begin
case node^.dtype of
dtTypeArray:
begin
//find a const
pConst:=FConsts.Fetchi(dtUInt32,node^.key.ext.array_count);
if (pConst^.pType=nil) then
begin
pConst^.pType:=FSpirvTypes.Fetch(pConst^.key.dtype);
AllocSpirvID(@pConst^.pType^.ID);
end;
FConsts.FList.Remove(pConst);
AllocSpirvID(@pConst^.ID);
end;
else;
end;
AllocSpirvID(@node^.ID);
node:=node^.pNext;
end;
end;
procedure TSprvEmit_alloc.AllocConstId;
var
node:PsrConst;
begin
node:=FConsts.FList.pHead;
While (node<>nil) do
begin
if (node^.key.dtype<>dtUnknow) then
begin
AllocSpirvID(@node^.ID)
end;
node:=node^.pNext;
end;
end;
procedure TSprvEmit_alloc.AllocVariableId;
var
node:PsrVariable;
begin
node:=FVariables.pHead;
While (node<>nil) do
begin
if (node^.pType<>nil) then
begin
AllocSpirvID(@node^.ID);
AllocSpirvID(@node^.pType^.ID);
end;
node:=node^.pNext;
end;
end;
procedure TSprvEmit_alloc.AllocOpSingle(const Param:TOpParamSingle);
var
pReg:PsrRegNode;
begin
Assert(Param.pData<>nil,'AllocOpSingle$1');
Case Param.ntype of
ntFunc:
begin
AllocSpirvID(@PSpirvFunc(Param.pData)^.ID);
end;
ntRefId:
begin
AllocSpirvID(Param.pData);
end;
ntType:
begin
AllocSpirvID(@PsrType(Param.pData)^.ID);
end;
ntReg:
begin
pReg:=Param.pData;
Case pReg^.pWriter.ntype of
ntConst:;
ntOp:AllocSpirvID(@pReg^.ID);
else
Assert(false,'AllocOpSingle$2');
end;
end;
ntVar:
begin
AllocSpirvID(@PsrVariable(Param.pData)^.ID);
end;
ntChain:
begin
AllocSpirvID(@PsrChain(Param.pData)^.ID);
end;
ntConst:
begin
AllocSpirvID(@PsrConst(Param.pData)^.ID)
end;
else
Assert(false,'AllocOpSingle$3');
end;
end;
procedure TSprvEmit_alloc.AllocOpParamNode(node:POpParamNode);
begin
Case node^.ntype of
ntLiteral:;
ntString :;
else
begin
AllocOpSingle(node^.AsParam);
end;
AllocSpirvID(node^.GetRef);
node:=node^.Next;
end;
end;
@ -367,11 +208,11 @@ procedure TSprvEmit_alloc.AllocFuncId;
var
pFunc:PSpirvFunc;
begin
pFunc:=FSpirvFuncs.FList.pHead;
pFunc:=FuncList.First;
While (pFunc<>nil) do
begin
AllocOpBlock(@pFunc^.FTop);
pFunc:=pFunc^.pNext;
AllocOpBlock(pFunc^.pTop);
pFunc:=pFunc^.Next;
end;
end;
@ -387,34 +228,38 @@ begin
if Info.result then //dst
begin
Assert(node^.dst.ntype<>ntUnknow,'AllocOp$1');
Assert(node^.dst.pData<>nil ,'AllocOp$2');
AllocOpSingle(node^.dst);
Assert(node^.pDst<>nil,'AllocOp$1');
if (node^.pDst<>nil) then
begin
AllocSpirvID(node^.pDst^.GetRef);
end;
end else
begin //no dst
if (node^.dst.ntype<>ntUnknow) then
if (node^.pDst<>nil) then
begin
Assert(node^.dst.pData<>nil,'AllocOp$3');
AllocOpSingle(node^.dst);
AllocSpirvID(node^.pDst^.GetRef);
end;
end;
if Info.rstype then //dst type
begin
if (node^.dst_type=nil) then
if (node^.pType=nil) then
begin
pReg:=node^.dst.AsReg;
if (pReg^.dtype=dtUnknow) then pReg^.dtype:=dtFloat32;
node^.dst_type:=FSpirvTypes.Fetch(pReg^.dtype);
//Assert(false,'AllocOp$4');
pReg:=node^.pDst^.AsType(ntReg);
Assert(pReg<>nil,'AllocOp$2');
Assert(pReg^.dtype<>dtUnknow,'AllocOp$3');
if (pReg<>nil) then
begin
node^.pType:=TypeList.Fetch(pReg^.dtype);
end;
end;
end;
Param:=node^.pParam.pHead;
Param:=node^.ParamFirst;
While (Param<>nil) do
begin
AllocOpParamNode(Param);
Param:=Param^.pNext;
AllocSpirvID(Param^.Value^.GetRef);
Param:=Param^.Next;
end;
end;
@ -424,22 +269,14 @@ var
node:PSpirvOp;
begin
if (pBlock=nil) then Exit;
node:=pBlock^.pHead;
node:=pBlock^.First;
While (node<>nil) do
begin
if (node^.OpId=OpBlock) then
begin
if (node^.dst.ntype=ntBlock) then
begin
AllocOpBlock(node^.dst.pData);
end;
end else
if node^.IsType(ntOp) then
begin
AllocOpId(node);
end;
node:=node^.pNext;
node:=flow_down_next_up(node);
end;
end;

View File

@ -8,17 +8,16 @@ uses
SySutils,
Classes,
spirv,
srNodes,
srNode,
srType,
srTypes,
srConst,
srReg,
srLayout,
srVariable,
srOp,
srOpUtils,
srCap,
srCapability,
srRefId,
SprvEmit;
emit_fetch;
type
TSPIRVHeader=packed record
@ -30,7 +29,7 @@ type
TOOL_VERSION:WORD;
TOOL_ID:WORD;
BOUND:DWORD;
RESERVED:DWORD;
SCHEMA:DWORD;
end;
PSPIRVInstruction=^TSPIRVInstruction;
@ -45,31 +44,23 @@ type
COUNT:DWORD;
Procedure AllocData;
Procedure NewOp(OpId:WORD);
Procedure Reset;
Procedure Flush(Stream:TStream);
procedure AddParamId(P:DWORD);
procedure AddString(const name:PChar);
procedure AddRefId(P:PsrRefId);
procedure AddConstId(P:PsrConst);
procedure AddVarId(P:PsrVariable);
procedure AddTypeId(P:PsrType);
procedure AddFuncId(P:PSpirvFunc);
procedure AddChainId(P:PsrChain);
procedure AddRegId(P:PsrRegNode);
procedure AddParam(P:DWORD);
procedure AddNode(node:PsrNode);
end;
TSprvEmit_bin=object(TSprvEmit)
TSprvEmit_bin=class(TEmitFetch)
procedure SaveToStream(Stream:TStream);
procedure SaveHeader(Stream:TStream;var Header:TSPIRVHeader);
procedure SaveCaps(Stream:TStream);
procedure SaveOpList(Stream:TStream;node:PspirvOp);
procedure SaveOpBlock(Stream:TStream;pBlock:PsrOpBlock);
procedure SaveHeaderInfo(Stream:TStream);
procedure SaveTypes(Stream:TStream);
procedure SaveConst(var buf:TSVInstrBuffer;node:PsrConst);
procedure SaveConst(Stream:TStream);
procedure SaveVariable(Stream:TStream);
procedure SaveFunc(Stream:TStream);
procedure SaveOp(Stream:TStream;node:PSpirvOp);
procedure SaveOpBlock(Stream:TStream;pBlock:PsrOpBlock);
end;
implementation
@ -97,15 +88,20 @@ begin
Data[0]:=DWORD(I);
end;
Procedure TSVInstrBuffer.Reset;
begin
COUNT:=0;
end;
Procedure TSVInstrBuffer.Flush(Stream:TStream);
begin
if (Stream=nil) or (COUNT=0) then Exit;
TSPIRVInstruction(Data[0]).COUNT:=COUNT;
Stream.Write(Data[0],COUNT*SizeOf(DWORD));
COUNT:=0;
Reset;
end;
procedure TSVInstrBuffer.AddParamId(P:DWORD);
procedure TSVInstrBuffer.AddParam(P:DWORD);
var
I:DWORD;
begin
@ -116,75 +112,33 @@ begin
Data[i]:=P;
end;
procedure TSVInstrBuffer.AddString(const name:PChar);
procedure TSVInstrBuffer.AddNode(node:PsrNode);
var
R:PsrRefId;
I,L,D:DWORD;
begin
Assert(name<>nil);
Assert(node<>nil);
Assert(COUNT<>0,'new op not created');
L:=StrLen(name);
D:=(L+SizeOf(DWORD)) div SizeOf(DWORD);
R:=node^.GetRef;
if (R<>nil) then
begin
I:=COUNT;
Inc(COUNT);
AllocData;
Data[i]:=R^.ID;
end else
begin
L:=node^.GetData(nil); //get size
D:=(L+(SizeOf(DWORD)-1)) div 4; //align
Assert(D<>0,'AddNode:'+node^.ntype.ClassName);
I:=COUNT;
COUNT:=COUNT+D;
AllocData;
I:=COUNT;
COUNT:=COUNT+D;
AllocData;
FillDWord(Data[i],D,0);
Move(PChar(name)^,Data[i],L);
end;
procedure TSVInstrBuffer.AddRefId(P:PsrRefId);
begin
Assert(P<>nil ,'AddRefId$1');
Assert(P^.Alloc,'AddRefId$2');
AddParamId(P^.ID);
end;
procedure TSVInstrBuffer.AddConstId(P:PsrConst);
begin
Assert(P<>nil,'AddConstId');
AddRefId(@P^.ID);
end;
procedure TSVInstrBuffer.AddVarId(P:PsrVariable);
begin
Assert(P<>nil,'AddVarId');
AddRefId(@P^.ID);
end;
procedure TSVInstrBuffer.AddTypeId(P:PsrType);
begin
Assert(P<>nil,'AddTypeId');
AddRefId(@P^.ID);
end;
procedure TSVInstrBuffer.AddFuncId(P:PSpirvFunc);
begin
Assert(P<>nil,'AddFuncId');
AddRefId(@P^.ID);
end;
procedure TSVInstrBuffer.AddChainId(P:PsrChain);
begin
Assert(P<>nil,'AddChainId');
AddRefId(@P^.ID);
end;
procedure TSVInstrBuffer.AddRegId(P:PsrRegNode);
begin
Assert(P<>nil,'AddRegId$1');
Case P^.pWriter.ntype of
ntConst:
begin
AddConstId(P^.pWriter.pData);
end;
ntOp:
begin
AddRefId(@P^.ID);
end;
else
Assert(false,'AddRegId$2');
FillDWord(Data[i],D,0);
node^.GetData(@Data[i]);
end;
end;
@ -196,10 +150,12 @@ begin
Header:=Default(TSPIRVHeader);
Header.MAGIC:=spirv.MagicNumber;
DWORD(Header.VERSION):=FBuffers.cfg.SpvVersion;
Header.TOOL_VERSION:=1;
Header.BOUND:=FSpirvIdAlloc.GetSpirvIDBound;
Header.MAGIC :=MagicNumber;
DWORD(Header.VERSION) :=Config.SpvVersion;
Header.TOOL_VERSION:=2;
Header.TOOL_ID :=0;
Header.BOUND :=RefIdAlloc.GetSpirvIDBound;
Header.SCHEMA :=0;
SaveHeader(Stream,Header);
@ -219,199 +175,96 @@ end;
procedure TSprvEmit_bin.SaveCaps(Stream:TStream);
var
buf:TSVInstrBuffer;
node:PSpirvCap;
node:PsrCapability;
begin
buf:=Default(TSVInstrBuffer);
node:=FSpirvCaps.First;
node:=CapabilityList.First;
While (node<>nil) do
begin
buf.NewOp(Op.OpCapability);
buf.AddParamId(node^.ID);
buf.AddParam(node^.ID);
buf.Flush(Stream);
node:=FSpirvCaps.Next(node);
node:=CapabilityList.Next(node);
end;
end;
procedure TSprvEmit_bin.SaveOpList(Stream:TStream;node:PspirvOp);
procedure TSprvEmit_bin.SaveOpBlock(Stream:TStream;pBlock:PsrOpBlock);
var
node:PSpirvOp;
begin
if (pBlock=nil) then Exit;
node:=pBlock^.First;
While (node<>nil) do
begin
SaveOp(Stream,node);
node:=node^.pNext;
if node^.IsType(ntOp) then
begin
SaveOp(Stream,node);
end;
node:=flow_down_next_up(node);
end;
end;
procedure TSprvEmit_bin.SaveHeaderInfo(Stream:TStream);
begin
SaveOpList(Stream,FHeader.pHead);
SaveOpList(Stream,FDebugInfo.pHead);
SaveOpList(Stream,FDecorates.pHead);
SaveOpBlock(Stream,@HeaderList);
SaveOpBlock(Stream,@DebugInfoList);
SaveOpBlock(Stream,@DecorateList);
end;
procedure TSprvEmit_bin.SaveTypes(Stream:TStream);
var
buf:TSVInstrBuffer;
node:PsrType;
pConst:PsrConst;
i:dword;
ie:Boolean;
i:Word;
begin
buf:=Default(TSVInstrBuffer);
node:=FSpirvTypes.FList.pHead;
node:=TypeList.First;
While (node<>nil) do
begin
ie:=True;
buf.NewOp(node^.OpId);
buf.AddNode(node);
pConst:=nil;
case node^.dtype of
dtTypeArray:
begin
//find a const
pConst:=FConsts.Fetchi(dtUInt32,node^.key.ext.array_count);
SaveConst(buf,pConst);
buf.Flush(Stream);
end;
else;
end;
buf.NewOp(node^.key.OpId);
buf.AddTypeId(node);
case node^.key.OpId of
Op.OpTypeFloat:
begin
buf.AddParamId(node^.key.ext.float_size);
end;
Op.OpTypeInt:
begin
buf.AddParamId(node^.key.ext.int_size);
buf.AddParamId(node^.key.ext.int_sign);
end;
Op.OpTypeVector:
begin
ie:=False;
buf.AddTypeId(node^.GetCompItem(0));
buf.AddParamId(node^.key.ext.array_count);
end;
Op.OpTypePointer:
begin
buf.AddParamId(node^.key.ext.Storage_Class);
end;
Op.OpTypeArray:
begin
ie:=False;
buf.AddTypeId(node^.GetCompItem(0));
buf.AddConstId(pConst);
end;
Op.OpTypeRuntimeArray:
begin
ie:=False;
buf.AddTypeId(node^.GetCompItem(0));
end;
Op.OpTypeImage:
begin
ie:=False;
buf.AddTypeId(node^.GetCompItem(0));
With node^.key.ext.image do
begin
buf.AddParamId(Dim);
buf.AddParamId(Depth);
buf.AddParamId(Arrayed);
buf.AddParamId(MS);
buf.AddParamId(Sampled);
buf.AddParamId(Format);
end;
end;
end;
if ie then
if (node^.key.count<>0) then
if (node^.ItemCount<>0) then
begin
For i:=0 to node^.ItemCount-1 do
begin
For i:=0 to node^.key.count-1 do
begin
buf.AddTypeId(node^.GetCompItem(i));
end;
buf.AddNode(node^.GetItem(i));
end;
end;
buf.Flush(Stream);
node:=node^.pNext;
node:=node^.Next;
end;
end;
procedure TSprvEmit_bin.SaveConst(var buf:TSVInstrBuffer;node:PsrConst);
var
i:dword;
begin
if (node^.key.count=0) then
begin
if (node^.key.dtype=dtBool) then
begin
Case node^.AsBool of
True :buf.NewOp(Op.OpConstantTrue);
False:buf.NewOp(Op.OpConstantFalse);
end;
buf.AddTypeId(node^.pType);
buf.AddConstId(node);
end else
begin
buf.NewOp(Op.OpConstant);
buf.AddTypeId(node^.pType);
buf.AddConstId(node);
Case BitSizeType(node^.key.dtype) of
8:buf.AddParamId(node^.AsByte);
16:buf.AddParamId(node^.AsWord);
32:buf.AddParamId(node^.AsUint);
64:begin
buf.AddParamId(Lo(node^.AsUint64));
buf.AddParamId(Hi(node^.AsUint64));
end;
else
Assert(false,'SaveConst');
end;
end;
end else
begin
buf.NewOp(Op.OpConstantComposite);
buf.AddTypeId(node^.pType);
buf.AddConstId(node);
For i:=0 to node^.key.count-1 do
begin
buf.AddConstId(node^.GetCompItem(i));
end;
end;
end;
procedure TSprvEmit_bin.SaveConst(Stream:TStream);
var
buf:TSVInstrBuffer;
node:PsrConst;
i:Word;
begin
buf:=Default(TSVInstrBuffer);
node:=FConsts.FList.pHead;
node:=ConstList.FList.pHead;
While (node<>nil) do
begin
if (node^.key.dtype<>dtUnknow) then
if (node^.dtype<>dtUnknow) then
begin
SaveConst(buf,node);
buf.NewOp(node^.OpId);
buf.AddNode(node^.pType);
buf.AddNode(node);
if (node^.dtype<>dtBool) and (node^.ItemCount<>0) then
begin
For i:=0 to node^.ItemCount-1 do
begin
buf.AddNode(node^.GetItem(i));
end;
end;
buf.Flush(Stream);
end;
node:=node^.pNext;
node:=node^.Next;
end;
end;
@ -421,52 +274,19 @@ var
node:PsrVariable;
begin
buf:=Default(TSVInstrBuffer);
node:=FVariables.pHead;
node:=VariableList.First;
While (node<>nil) do
begin
if (node^.pType<>nil) then
begin
buf.NewOp(Op.OpVariable);
buf.AddTypeId(node^.pType);
buf.AddVarId(node);
buf.AddParamId(node^.GetStorageClass);
buf.AddNode(node^.pType);
buf.AddNode(node);
buf.AddParam(node^.GetStorageClass);
buf.Flush(Stream);
end;
node:=node^.pNext;
end;
end;
procedure SaveOpSingle(var buf:TSVInstrBuffer;const Param:TOpParamSingle);
begin
Assert(Param.pData<>nil,'SaveOpSingle$1');
Case Param.ntype of
ntFunc :buf.AddFuncId(Param.pData);
ntRefId:buf.AddRefId(Param.pData);
ntType :buf.AddTypeId(Param.pData);
ntReg :buf.AddRegId(Param.pData);
ntVar :buf.AddVarId(Param.pData);
ntChain:buf.AddChainId(Param.pData);
ntConst:buf.AddConstId(Param.pData);
else
Assert(false,'PrintOpSingle$3');
end;
end;
procedure SaveOpParamNode(var buf:TSVInstrBuffer;node:POpParamNode);
begin
Case node^.ntype of
ntLiteral:
begin
buf.AddParamId(node^.Value);
end;
ntString:
begin
buf.AddString(@node^.name);
end;
else
begin
SaveOpSingle(buf,node^.AsParam);
end;
node:=node^.Next;
end;
end;
@ -474,11 +294,11 @@ procedure TSprvEmit_bin.SaveFunc(Stream:TStream);
var
pFunc:PSpirvFunc;
begin
pFunc:=FSpirvFuncs.FList.pHead;
pFunc:=FuncList.First;
While (pFunc<>nil) do
begin
SaveOpBlock(Stream,@pFunc^.FTop);
pFunc:=pFunc^.pNext;
SaveOpBlock(Stream,pFunc^.pTop);
pFunc:=pFunc^.Next;
end;
end;
@ -497,58 +317,46 @@ begin
if Info.rstype then //dst type
begin
Assert(node^.dst_type<>nil,'SaveOp$4');
buf.AddTypeId(node^.dst_type);
Assert(node^.pType<>nil,'SaveOp$1');
if (node^.pType<>nil) then
begin
buf.AddNode(node^.pType);
end else
begin
buf.Reset;
Exit;
end;
end;
if Info.result then //dst
begin
Assert(node^.dst.ntype<>ntUnknow,'SaveOp$1');
Assert(node^.dst.pData<>nil,'SaveOp$2');
SaveOpSingle(buf,node^.dst);
Assert(node^.pDst<>nil,'SaveOp$2');
if (node^.pDst<>nil) then
begin
buf.AddNode(node^.pDst);
end else
begin
buf.Reset;
Exit;
end;
end else
begin //no dst
if (node^.dst.ntype<>ntUnknow) then
if (node^.pDst<>nil) then
begin
Assert(node^.dst.pData<>nil,'SaveOp$3');
SaveOpSingle(buf,node^.dst);
buf.AddNode(node^.pDst);
end;
end;
Param:=node^.pParam.pHead;
Param:=node^.ParamFirst;
While (Param<>nil) do
begin
SaveOpParamNode(buf,Param);
Param:=Param^.pNext;
buf.AddNode(Param^.Value);
Param:=Param^.Next;
end;
buf.Flush(Stream);
end;
procedure TSprvEmit_bin.SaveOpBlock(Stream:TStream;pBlock:PsrOpBlock);
var
node:PSpirvOp;
begin
if (pBlock=nil) then Exit;
node:=pBlock^.pHead;
While (node<>nil) do
begin
if (node^.OpId=OpBlock) then
begin
if (node^.dst.ntype=ntBlock) then
begin
SaveOpBlock(Stream,node^.dst.pData);
end;
end else
begin
SaveOp(Stream,node);
end;
node:=node^.pNext;
end;
end;
end.

View File

@ -1,64 +0,0 @@
unit emit_DS;
{$mode objfpc}{$H+}
interface
uses
sysutils,
ps4_pssl,
srTypes,
srReg,
spirv,
SprvEmit,
emit_op;
type
TEmit_DS=object(TEmitOp)
procedure _emit_DS;
procedure _emit_DS_SWIZZLE_B32;
end;
implementation
procedure TEmit_DS._emit_DS_SWIZZLE_B32; //TODO
Var
dst:PsrRegSlot;
begin
dst:=FRegsStory.get_vdst8(FSPI.DS.VDST);
SetConst(dst,dtFloat32,0);
end;
procedure TEmit_DS._emit_DS;
begin
Case FSPI.DS.OP of
DS_NOP:;
//DS_SWIZZLE_B32 v4 v3 v0 v0 OFFSET:0x80AA GDS:0
DS_SWIZZLE_B32: //TODO
begin;
_emit_DS_SWIZZLE_B32;
end;
else
Assert(false,'DS?');
end;
end;
{
OFFSET0:Byte;
OFFSET1:Byte;
GDS:bit1;
ADDR:Byte; (vbindex)
DATA0:Byte; (vsrc0)
DATA1:Byte; (vsrc1)
VDST:Byte;
}
end.

View File

@ -6,27 +6,26 @@ interface
uses
sysutils,
spirv,
ps4_pssl,
srNodes,
srLabel,
srTypes,
srCFGLabel,
srConfig,
srFlow,
srType,
srReg,
srVariable,
srOutput,
srOp,
srOpUtils,
SprvEmit,
emit_op;
emit_fetch;
type
TEmit_EXP=object(TEmitOp)
procedure _emit_EXP;
TEmit_EXP=class(TEmitFetch)
procedure emit_EXP;
end;
implementation
procedure TEmit_EXP._emit_EXP;
procedure TEmit_EXP.emit_EXP;
Var
exc:PsrRegNode;
node:PSpirvOp;
@ -35,7 +34,7 @@ Var
dout:PsrVariable;
dst:PsrRegNode;
src:array[0..3] of PsrRegNode;
rsl:array[0..3] of PsrRegNode;
//rsl:array[0..3] of PsrRegNode;
rtype:TsrDataType;
f,i,p:Byte;
@ -46,12 +45,12 @@ begin
if (FSPI.EXP.VM<>0) and (FSPI.EXP.DONE<>0) then
begin
pOpBlock:=AllocBlockOp;
pOpBlock^.SetInfo(btOther,FCursor.Adr,FCursor.Adr);
pOpBlock^.SetInfo(btOther,Cursor.Adr,Cursor.Adr);
PushBlockOp(line,pOpBlock,nil);
exc:=MakeRead(@FRegsStory.EXEC[0],dtBool);
exc:=MakeRead(get_exec0,dtBool);
node:=AddSpirvOp(OpMakeExp);
node^.AddParam(ntReg,exc); //<-fetch read
node^.AddParam(exc); //<-fetch read
end;
//before
@ -60,13 +59,13 @@ begin
begin
if (pOpBlock<>nil) then //is pushed
begin
FMain^.PopBlock;
Main^.PopBlock;
end;
Exit;
end;
pOpBlock:=AllocBlockOp; //down
pOpBlock^.SetInfo(btOther,FCursor.Adr,FCursor.Adr);
pOpBlock^.SetInfo(btOther,Cursor.Adr,Cursor.Adr);
PushBlockOp(line,pOpBlock,nil);
//output
@ -94,7 +93,7 @@ begin
Assert(false);
end;
dout:=FetchOutput(TpsslExportType(FSPI.EXP.TGT),dtFloat32); //output in FSPI.EXP.TGT
emit_OpStore(line,dout,src[0]);
OpStore(line,dout,src[0]);
end else
begin
@ -128,11 +127,10 @@ begin
Inc(i);
end;
dst:=emit_OpMakeVec(line,rtype,p,@src);
dst^.mark_read;
dst:=OpMakeVec(line,rtype,@src);
dout:=FetchOutput(TpsslExportType(FSPI.EXP.TGT),rtype); //output in FSPI.EXP.TGT
emit_OpStore(line,dout,dst);
OpStore(line,dout,dst);
end;
end else
@ -153,43 +151,31 @@ begin
Assert(false);
end;
if FUseOutput16 then
if Config.UseOutput16 then
begin
dst:=emit_OpMakeVec(line,dtVec4h,4,@src);
dst^.mark_read;
dst:=OpMakeVec(line,dtVec4h,@src);
rtype:=dtVec4h;
end else
begin
rsl[0]:=NewReg(dtFloat32);
rsl[1]:=NewReg(dtFloat32);
rsl[2]:=NewReg(dtFloat32);
rsl[3]:=NewReg(dtFloat32);
_emit_Op1(line,Op.OpFConvert,rsl[0],src[0]);
_emit_Op1(line,Op.OpFConvert,rsl[1],src[1]);
_emit_Op1(line,Op.OpFConvert,rsl[2],src[2]);
_emit_Op1(line,Op.OpFConvert,rsl[3],src[3]);
rsl[0]^.mark_read;
rsl[1]^.mark_read;
rsl[2]^.mark_read;
rsl[3]^.mark_read;
dst:=emit_OpMakeVec(line,dtVec4f,4,@rsl);
dst^.mark_read;
src[0]:=OpFToF(src[0],dtFloat32);
src[1]:=OpFToF(src[1],dtFloat32);
src[2]:=OpFToF(src[2],dtFloat32);
src[3]:=OpFToF(src[3],dtFloat32);
rtype:=dtVec4f;
end;
dst:=OpMakeVec(line,rtype,@src);
dout:=FetchOutput(TpsslExportType(FSPI.EXP.TGT),rtype); //output in FSPI.EXP.TGT
emit_OpStore(line,dout,dst);
OpStore(line,dout,dst);
end;
if (pOpBlock<>nil) then //is pushed
begin
FMain^.PopBlock;
FMain^.PopBlock;
Main^.PopBlock;
Main^.PopBlock;
end;
end;

613
spirv/emit_fetch.pas Normal file
View File

@ -0,0 +1,613 @@
unit emit_fetch;
{$mode objfpc}{$H+}
interface
uses
ps4_pssl,
srNode,
srBitcast,
srType,
srTypes,
srConst,
srReg,
srOp,
srOpUtils,
srLayout,
srVertLayout,
srFragLayout,
srVariable,
srInput,
srOutput,
srUniform,
srFlow;
type
TEmitFetch=class(TEmitFlow)
//
function GroupingSharp(src:PPsrRegSlot;rtype:TsrResourceType):PsrDataLayout;
//
procedure PrepTypeSlot(pSlot:PsrRegSlot;rtype:TsrDataType);
function MakeRead(pSlot:PsrRegSlot;rtype:TsrDataType):PsrRegNode;
//
function PrepTypeNode(var node:PsrRegNode;rtype:TsrDataType;relax:Boolean=true):Integer;
function PrepTypeDst(var node:PsrRegNode;rtype:TsrDataType;relax:Boolean=true):Integer;
function PrepTypeParam(node:POpParamNode;rtype:TsrDataType;relax:Boolean=true):Integer;
//
function get_vcc0:PsrRegSlot;
function get_vcc1:PsrRegSlot;
function get_m0:PsrRegSlot;
function get_exec0:PsrRegSlot;
function get_exec1:PsrRegSlot;
function get_scc:PsrRegSlot;
//
function get_sdst7(SDST:Byte):PsrRegSlot;
function get_sdst7_pair(SDST:Byte;dst:PPsrRegSlot):Boolean;
function get_ssrc8(SSRC:Byte):PsrRegSlot;
function get_ssrc9(SSRC:Word):PsrRegSlot;
function get_ssrc9_pair(SSRC:Word;src:PPsrRegSlot):Boolean;
function get_vsrc8(VSRC:Byte):PsrRegSlot;
function get_vdst8(VDST:Byte):PsrRegSlot;
function get_sbase(SBASE,count:Byte;src:PPsrRegSlot):Boolean;
function get_srsrc(SRSRC,count:Byte;src:PPsrRegSlot):Boolean;
//
function get_snapshot:TsrRegsSnapshot;
//
function fetch_ssrc8(SOFFSET:Word;rtype:TsrDataType):PsrRegNode;
function fetch_ssrc9(SSRC:Word;rtype:TsrDataType):PsrRegNode;
function fetch_ssrc9_pair(SSRC:Word;src:PPsrRegNode;rtype:TsrDataType):Boolean;
function fetch_vsrc8(VSRC:Word;rtype:TsrDataType):PsrRegNode;
function fetch_vdst8(VDST:Word;rtype:TsrDataType):PsrRegNode;
procedure fetch_vsrc8_vec2h(VSRC:Word;var dst0,dst1:PsrRegNode);
//
procedure OpCmpV(OpId:DWORD;dst:PsrRegSlot;src0,src1:PsrRegNode);
procedure OpCmpS(OpId:DWORD;dst:PsrRegSlot;src0,src1:PsrRegNode);
procedure OpConvFloatToHalf2(dst:PsrRegSlot;src0,src1:PsrRegNode);
//
function AddInput(dst:PsrRegSlot;rtype:TsrDataType;itype:TpsslInputType;id:Byte=0):PsrRegNode;
function AddAncillary(dst:PsrRegSlot):PsrRegNode;
function AddVertLayout(pLayout:PsrDataLayout;rtype:TsrDataType):PsrRegNode;
function AddFragLayout(itype:TpsslInputType;rtype:TsrDataType;location:DWORD):PsrRegNode;
function FetchLoad(pChain:PsrChain;rtype:TsrDataType):PsrRegNode;
Procedure FetchStore(pChain:PsrChain;src:PsrRegNode);
procedure AddUserdata(dst:PsrRegSlot;offset_dw:Byte);
function FetchChain(grp:PsrDataLayout;lvl_0:PsrChainLvl_0;lvl_1:PsrChainLvl_1):PsrRegNode;
function MakeChain(pSlot:PsrRegSlot;grp:PsrDataLayout;lvl_0:PsrChainLvl_0;lvl_1:PsrChainLvl_1):PsrRegNode;
Procedure AddVecInput(dst:PsrRegSlot;vtype,rtype:TsrDataType;itype:TpsslInputType;id:Byte);
function FetchUniform(src:PsrDataLayout;pType:PsrType):PsrNode;
function FetchImage(src:PsrDataLayout;dtype:TsrDataType;info:TsrTypeImageInfo):PsrNode;
function FetchSampler(src:PsrDataLayout):PsrNode;
function FetchOutput(etype:TpsslExportType;rtype:TsrDataType):PsrVariable;
end;
function GetInputRegNode(node:PsrRegNode):PsrInput;
implementation
function GetInputRegNode(node:PsrRegNode):PsrInput;
var
pSource:PsrNode;
begin
pSource:=GetSourceRegNode(node);
Result:=pSource^.AsType(ntInput);
end;
//
function TEmitFetch.GroupingSharp(src:PPsrRegSlot;rtype:TsrResourceType):PsrDataLayout;
var
chain:TsrChains;
i,n:Byte;
begin
Result:=nil;
chain:=Default(TsrChains);
n:=GetResourceSizeDw(rtype);
For i:=0 to n-1 do
begin
chain[i]:=GetChainRegNode(src[i]^.current);
end;
Result:=DataLayoutList.Grouping(chain,rtype);
end;
//
procedure TEmitFetch.PrepTypeSlot(pSlot:PsrRegSlot;rtype:TsrDataType);
begin
if (pSlot=nil) then Exit;
if (pSlot^.current=nil) then
begin
pSlot^.New(line,rtype); //Unresolve
Exit;
end;
pSlot^.current^.PrepType(ord(rtype));
end;
function TEmitFetch.MakeRead(pSlot:PsrRegSlot;rtype:TsrDataType):PsrRegNode;
var
node:PsrRegNode;
begin
Result:=nil;
if (pSlot=nil) then Exit;
PrepTypeSlot(pSlot,rtype);
node:=pSlot^.current;
if (rtype<>dtUnknow) and (not CompareType(node^.dtype,rtype)) then
begin
Result:=BitcastList.FetchRead(rtype,node);
end else
begin
Result:=node;
end;
if (rtype<>dtUnknow) then
begin
Result^.Weak:=False;
end;
end;
//
function TEmitFetch.PrepTypeNode(var node:PsrRegNode;rtype:TsrDataType;relax:Boolean=true):Integer;
begin
Result:=0;
if (node=nil) then Exit;
if (rtype=dtUnknow) then Exit;
if is_unprep_type(node^.dtype,rtype,node^.Weak) then
begin
node^.PrepType(ord(rtype));
Inc(Result);
end else
begin
Case relax of
True :relax:=CompareType(node^.dtype,rtype);
False:relax:=(node^.dtype=rtype);
end;
if not relax then
begin
node:=BitcastList.FetchRead(rtype,node);
Inc(Result);
end;
end;
end;
function TEmitFetch.PrepTypeDst(var node:PsrRegNode;rtype:TsrDataType;relax:Boolean=true):Integer;
begin
Result:=0;
if (node=nil) then Exit;
if (rtype=dtUnknow) then Exit;
if is_unprep_type(node^.dtype,rtype,node^.Weak) then
begin
node^.PrepType(ord(rtype));
Inc(Result);
end else
begin
Case relax of
True :relax:=CompareType(node^.dtype,rtype);
False:relax:=(node^.dtype=rtype);
end;
if not relax then
begin
node:=BitcastList.FetchDstr(rtype,node);
Inc(Result);
end;
end;
end;
function TEmitFetch.PrepTypeParam(node:POpParamNode;rtype:TsrDataType;relax:Boolean=true):Integer;
var
pReg:PsrRegNode;
begin
Result:=0;
if (node=nil) then Exit;
if (rtype=dtUnknow) then Exit;
if node^.Value^.IsType(ntReg) then
begin
pReg:=node^.AsReg;
Result:=PrepTypeNode(pReg,rtype,relax);
node^.Value:=pReg;
end else
begin
node^.Value^.PrepType(ord(rtype));
end;
end;
//
function TEmitFetch.get_vcc0:PsrRegSlot;
begin
Result:=@RegsStory.VCC[0];
end;
function TEmitFetch.get_vcc1:PsrRegSlot;
begin
Result:=@RegsStory.VCC[1];
end;
function TEmitFetch.get_m0:PsrRegSlot;
begin
Result:=@RegsStory.M0;
end;
function TEmitFetch.get_exec0:PsrRegSlot;
begin
Result:=@RegsStory.EXEC[0];
end;
function TEmitFetch.get_exec1:PsrRegSlot;
begin
Result:=@RegsStory.EXEC[1];
end;
function TEmitFetch.get_scc:PsrRegSlot;
begin
Result:=@RegsStory.SCC;
end;
//
function TEmitFetch.get_sdst7(SDST:Byte):PsrRegSlot;
begin
Result:=RegsStory.get_sdst7(SDST);
end;
function TEmitFetch.get_sdst7_pair(SDST:Byte;dst:PPsrRegSlot):Boolean;
begin
Result:=RegsStory.get_sdst7_pair(SDST,dst);
end;
function TEmitFetch.get_ssrc8(SSRC:Byte):PsrRegSlot;
begin
Result:=RegsStory.get_ssrc8(SSRC);
end;
function TEmitFetch.get_ssrc9(SSRC:Word):PsrRegSlot;
begin
Result:=RegsStory.get_ssrc9(SSRC);
end;
function TEmitFetch.get_ssrc9_pair(SSRC:Word;src:PPsrRegSlot):Boolean;
begin
Result:=RegsStory.get_ssrc9_pair(SSRC,src);
end;
function TEmitFetch.get_vsrc8(VSRC:Byte):PsrRegSlot;
begin
Result:=RegsStory.get_vsrc8(VSRC);
end;
function TEmitFetch.get_vdst8(VDST:Byte):PsrRegSlot;
begin
Result:=RegsStory.get_vdst8(VDST);
end;
function TEmitFetch.get_sbase(SBASE,count:Byte;src:PPsrRegSlot):Boolean;
begin
Result:=RegsStory.get_sbase(SBASE,count,src);
end;
function TEmitFetch.get_srsrc(SRSRC,count:Byte;src:PPsrRegSlot):Boolean;
begin
Result:=RegsStory.get_srsrc(SRSRC,count,src);
end;
//
function TEmitFetch.get_snapshot:TsrRegsSnapshot;
begin
Result:=RegsStory.get_snapshot;
end;
//
function TEmitFetch.fetch_ssrc8(SOFFSET:Word;rtype:TsrDataType):PsrRegNode;
Var
src:PsrRegSlot;
pConst:PsrConst;
begin
if is_const_ssrc8(SOFFSET) then
begin
pConst:=ConstList.Fetch_ssrc8_const(SOFFSET,0,rtype);
Result:=NewReg(pConst);
end else
begin
src:=RegsStory.get_ssrc8(SOFFSET);
Result:=MakeRead(src,rtype);
end;
end;
function TEmitFetch.fetch_ssrc9(SSRC:Word;rtype:TsrDataType):PsrRegNode;
Var
src:PsrRegSlot;
pConst:PsrConst;
begin
if is_const_ssrc9(SSRC) then
begin
pConst:=ConstList.Fetch_ssrc9_const(SSRC,FSPI.INLINE32,rtype);
Result:=NewReg(pConst);
end else
begin
src:=RegsStory.get_ssrc9(SSRC);
Result:=MakeRead(src,rtype);
end;
end;
function TEmitFetch.fetch_ssrc9_pair(SSRC:Word;src:PPsrRegNode;rtype:TsrDataType):Boolean;
Var
pSlot:array[0..1] of PsrRegSlot;
begin
if is_const_ssrc9(SSRC) then
begin
src[0]:=NewReg(ConstList.Fetch_ssrc9_const(SSRC,FSPI.INLINE32,rtype));
src[1]:=NewReg(ConstList.Fetch(dtUnknow,0));
Result:=True;
end else
begin
pSlot[0]:=nil;
pSlot[1]:=nil;
Result:=RegsStory.get_ssrc9_pair(SSRC,pSlot);
if not Result then Exit;
src[0]:=MakeRead(pSlot[0],rtype);
src[1]:=MakeRead(pSlot[1],rtype);
end;
end;
function TEmitFetch.fetch_vsrc8(VSRC:Word;rtype:TsrDataType):PsrRegNode;
var
src:PsrRegSlot;
begin
src:=RegsStory.get_vsrc8(VSRC);
Result:=MakeRead(src,rtype);
end;
function TEmitFetch.fetch_vdst8(VDST:Word;rtype:TsrDataType):PsrRegNode;
var
src:PsrRegSlot;
begin
src:=RegsStory.get_vdst8(VDST);
Result:=MakeRead(src,rtype);
end;
procedure TEmitFetch.fetch_vsrc8_vec2h(VSRC:Word;var dst0,dst1:PsrRegNode);
var
pSlot:PsrRegSlot;
dst:PsrRegNode;
begin
pSlot:=RegsStory.get_vsrc8(VSRC);
dst:=MakeRead(pSlot,dtVec2h);
dst0:=NewReg(dtHalf16);
dst1:=NewReg(dtHalf16);;
OpExtract(line,dst0,dst,0);
OpExtract(line,dst1,dst,1);
end;
//
procedure TEmitFetch.OpCmpV(OpId:DWORD;dst:PsrRegSlot;src0,src1:PsrRegNode);
Var
tmp:PsrRegNode;
exc:PsrRegNode;
begin
tmp:=NewReg(dtBool);
_Op2(line,OpId,tmp,src0,src1);
exc:=MakeRead(get_exec0,dtBool);
OpLogicalAnd(dst,tmp,exc);
end;
procedure TEmitFetch.OpCmpS(OpId:DWORD;dst:PsrRegSlot;src0,src1:PsrRegNode);
begin
Op2(OpId,dtBool,dst,src0,src1);
end;
procedure TEmitFetch.OpConvFloatToHalf2(dst:PsrRegSlot;src0,src1:PsrRegNode);
var
rsl:array[0..1] of PsrRegNode;
begin
rsl[0]:=OpFToF(src0,dtHalf16);
rsl[1]:=OpFToF(src1,dtHalf16);
dst^.New(line,dtVec2h);
OpMakeCon(line,dst^.current,@rsl);
end;
//
function TEmitFetch.AddInput(dst:PsrRegSlot;rtype:TsrDataType;itype:TpsslInputType;id:Byte=0):PsrRegNode;
var
i:PsrInput;
v:PsrVariable;
r:PsrRegNode;
begin
i:=InputList.Fetch(rtype,itype,id);
v:=i^.pVar;
r:=i^.pReg;
if (r=nil) then
begin
r:=dst^.New(line,rtype);
i^.pReg :=r;
OpLoad(init_line,r,v); //one in any scope
end else
if (dst^.current<>r) then
begin
MakeCopy(dst,r);
end;
Result:=r;
end;
function TEmitFetch.AddAncillary(dst:PsrRegSlot):PsrRegNode;
var
src:array[0..2] of PsrRegNode;
begin
src[0]:=NewReg_q(dtUInt32,0); //vPrimType
src[1]:=AddInput(@RegsStory.FUnattach,dtUInt32,itSampleId);
src[2]:=AddInput(@RegsStory.FUnattach,dtUInt32,itLayer);
OpPackAnc(dst,src[0],src[1],src[2]);
//Render target array index[26:16], BuiltIn.Layer
//Iterated sample number[11:8], BuiltIn.SampleId
//Primitive type[1:0] 0..3
//IL_REGTYPE_PRIMTYPE vPrimType
//The first component has sign bit = 1, this is a point. Values in other bits are undefined.
//The second component has sign bit = 1, this is a line. Values in other bits are undefined.
//PID ISID RTAI
//01|234567|89AB|CDEF|0123456789A|
//00|000000| |0000| |
Result:=dst^.current;
end;
function TEmitFetch.AddVertLayout(pLayout:PsrDataLayout;rtype:TsrDataType):PsrRegNode;
var
i:PsrVertLayout;
v:PsrVariable;
dst:PsrRegNode;
begin
i:=VertLayoutList.Fetch(pLayout,rtype);
v:=i^.pVar;
dst:=i^.pReg;
if (dst=nil) then
begin
dst:=NewReg(rtype);
i^.pReg:=dst;
OpLoad(init_line,dst,v); //one in any scope
end;
Result:=dst;
end;
function TEmitFetch.AddFragLayout(itype:TpsslInputType;rtype:TsrDataType;location:DWORD):PsrRegNode;
var
i:PsrFragLayout;
v:PsrVariable;
dst:PsrRegNode;
begin
i:=FragLayoutList.Fetch(itype,location,rtype);
v:=i^.pVar;
dst:=i^.pReg;
if (dst=nil) then
begin
dst:=NewReg(rtype);
i^.pReg:=dst;
OpLoad(init_line,dst,v); //one in any scope
end;
Result:=dst;
end;
function TEmitFetch.FetchLoad(pChain:PsrChain;rtype:TsrDataType):PsrRegNode;
begin
Result:=nil;
if (pChain=nil) then Exit;
Result:=NewReg(rtype);
pChain^.FetchLoad(line,Result);
end;
Procedure TEmitFetch.FetchStore(pChain:PsrChain;src:PsrRegNode);
begin
if (pChain=nil) or (src=nil) then Exit;
pChain^.FetchStore(line,src);
end;
procedure TEmitFetch.AddUserdata(dst:PsrRegSlot;offset_dw:Byte);
var
lvl_0:TsrChainLvl_0;
pLayout:PsrDataLayout;
pChain:PsrChain;
pReg:PsrRegNode;
begin
pLayout:=DataLayoutList.pRoot;
lvl_0.offset:=offset_dw*4;
lvl_0.size :=4;
pChain:=pLayout^.Fetch(@lvl_0,nil);
pReg:=FetchLoad(pChain,dtUnknow);
MakeCopy(dst,pReg);
end;
function TEmitFetch.FetchChain(grp:PsrDataLayout;lvl_0:PsrChainLvl_0;lvl_1:PsrChainLvl_1):PsrRegNode;
var
pChain:PsrChain;
begin
pChain:=grp^.Fetch(lvl_0,lvl_1);
Result:=FetchLoad(pChain,dtUnknow);
end;
function TEmitFetch.MakeChain(pSlot:PsrRegSlot;grp:PsrDataLayout;lvl_0:PsrChainLvl_0;lvl_1:PsrChainLvl_1):PsrRegNode;
var
pChain:PsrChain;
pReg:PsrRegNode;
begin
pChain:=grp^.Fetch(lvl_0,lvl_1);
pReg:=FetchLoad(pChain,dtUnknow);
MakeCopy(pSlot,pReg);
Result:=pSlot^.current;
end;
Procedure TEmitFetch.AddVecInput(dst:PsrRegSlot;vtype,rtype:TsrDataType;itype:TpsslInputType;id:Byte);
var
rsl:PsrRegNode;
begin
rsl:=AddInput(@RegsStory.FUnattach,vtype,itype,0);
OpExtract(init_line,dst^.New(line,rtype),rsl,id);
end;
////
function TEmitFetch.FetchUniform(src:PsrDataLayout;pType:PsrType):PsrNode;
var
u:PsrUniform;
v:PsrVariable;
r:PsrRegUniform;
begin
u:=UniformList.Fetch(src,pType);
v:=u^.pVar;
r:=u^.pReg;
if (r^.pLine=nil) then
begin
OpLoad(init_line,pType,r,v); //one in any scope
end;
Result:=r;
end;
function TEmitFetch.FetchImage(src:PsrDataLayout;dtype:TsrDataType;info:TsrTypeImageInfo):PsrNode;
var
pType:PsrType;
begin
pType:=TypeList.Fetch(dtype);
pType:=TypeList.FetchImage(pType,info);
Result:=FetchUniform(src,pType);
end;
function TEmitFetch.FetchSampler(src:PsrDataLayout):PsrNode;
var
pType:PsrType;
begin
pType:=TypeList.Fetch(dtTypeSampler);
Result:=FetchUniform(src,pType);
end;
function TEmitFetch.FetchOutput(etype:TpsslExportType;rtype:TsrDataType):PsrVariable;
var
o:PsrOutput;
begin
o:=OutputList.Fetch(etype,rtype);
Result:=o^.pVar;
end;
end.

View File

@ -10,24 +10,24 @@ uses
si_ci_vi_merged_enum,
ps4_shader,
ps4_pssl,
srNodes,
srTypes,
srConst,
srNode,
srType,
srReg,
srLayout,
srOp,
SprvEmit,
emit_op;
emit_fetch;
type
TEmit_MIMG=object(TEmitOp)
procedure _emit_MIMG;
procedure _DistribDmask(dst:PsrRegNode;telem:TsrDataType);
Function _GatherCoord_f(var offset:DWORD;dim_id:Byte):PsrRegNode;
Function _GatherCoord_u(var offset:DWORD;dim_id:Byte):PsrRegNode;
Function _Gather_packed_offset(var offset:DWORD;dim:Byte):PsrRegNode;
procedure _emit_image_sample(Tgrp:PsrRegNode;info:PsrImageInfo);
procedure _emit_image_load(Tgrp:PsrRegNode;info:PsrImageInfo);
TEmit_MIMG=class(TEmitFetch)
procedure emit_MIMG;
procedure DistribDmask(dst:PsrRegNode;telem:TsrDataType);
function GatherDmask(telem:TsrDataType):PsrRegNode;
Function GatherCoord_f(var offset:DWORD;dim_id:Byte):PsrRegNode;
Function GatherCoord_u(var offset:DWORD;dim_id:Byte):PsrRegNode;
Function Gather_packed_offset(var offset:DWORD;dim:Byte):PsrRegNode;
procedure emit_image_sample(Tgrp:PsrNode;info:PsrImageInfo);
procedure emit_image_load(Tgrp:PsrNode;info:PsrImageInfo);
procedure emit_image_store(Tgrp:PsrNode;info:PsrImageInfo);
end;
implementation
@ -373,7 +373,7 @@ begin
Result.tinfo.Format :=GetImageFormat(PT);
end;
procedure TEmit_MIMG._DistribDmask(dst:PsrRegNode;telem:TsrDataType); //result
procedure TEmit_MIMG.DistribDmask(dst:PsrRegNode;telem:TsrDataType); //result
var
pSlot:PsrRegSlot;
i,d:Byte;
@ -382,14 +382,40 @@ begin
For i:=0 to 3 do
if Byte(FSPI.MIMG.DMASK).TestBit(i) then
begin
pSlot:=FRegsStory.get_vdst8(FSPI.MIMG.VDATA+d); Inc(d);
pSlot:=get_vdst8(FSPI.MIMG.VDATA+d);
Inc(d);
Assert(pSlot<>nil);
dst^.mark_read;
emit_OpCompExtract(line,pSlot^.New(line,telem),dst,i);
OpExtract(line,pSlot^.New(line,telem),dst,i);
end;
end;
Function TEmit_MIMG._GatherCoord_f(var offset:DWORD;dim_id:Byte):PsrRegNode; //src
function TEmit_MIMG.GatherDmask(telem:TsrDataType):PsrRegNode;
var
src:array[0..3] of PsrRegNode;
i,d,m:Byte;
begin
d:=0;
For i:=0 to 3 do
if Byte(FSPI.MIMG.DMASK).TestBit(i) then
begin
src[i]:=fetch_vsrc8(FSPI.MIMG.VDATA+d,telem);
Inc(d);
m:=i;
end else
begin
src[i]:=nil;
end;
//Result:=telem.AsVector(4);
For i:=0 to m do
begin
Assert(src[i]<>nil,'TODO: zero or prev value?');
end;
Result:=OpMakeVec(line,telem.AsVector(m+1),@src);
end;
Function TEmit_MIMG.GatherCoord_f(var offset:DWORD;dim_id:Byte):PsrRegNode; //src
var
src:array[0..3] of PsrRegNode;
i,count:Byte;
@ -416,8 +442,7 @@ begin
src[2]:=fetch_vsrc8(FSPI.MIMG.VADDR+offset+2,dtFloat32); //face
end;
Result:=emit_OpMakeCube(line,GetVecType(dtFloat32,count),count,@src);
Result^.mark_read;
Result:=OpMakeCub(line,TsrDataType(dtFloat32).AsVector(count),@src);
end else
begin
@ -432,8 +457,7 @@ begin
Result:=src[0];
end else
begin
Result:=emit_OpMakeVec(line,GetVecType(dtFloat32,count),count,@src);
Result^.mark_read;
Result:=OpMakeVec(line,TsrDataType(dtFloat32).AsVector(count),@src);
end;
end;
@ -441,7 +465,7 @@ begin
offset:=offset+count;
end;
Function TEmit_MIMG._GatherCoord_u(var offset:DWORD;dim_id:Byte):PsrRegNode; //src
Function TEmit_MIMG.GatherCoord_u(var offset:DWORD;dim_id:Byte):PsrRegNode; //src
var
src:array[0..3] of PsrRegNode;
i,count:Byte;
@ -468,8 +492,7 @@ begin
src[2]:=fetch_vsrc8(FSPI.MIMG.VADDR+offset+2,dtInt32); //face
end;
Result:=emit_OpMakeCube(line,GetVecType(dtInt32,count),count,@src);
Result^.mark_read;
Result:=OpMakeCub(line,TsrDataType(dtInt32).AsVector(count),@src);
end else
begin
@ -484,8 +507,7 @@ begin
Result:=src[0];
end else
begin
Result:=emit_OpMakeVec(line,GetVecType(dtInt32,count),count,@src);
Result^.mark_read;
Result:=OpMakeVec(line,TsrDataType(dtInt32).AsVector(count),@src);
end;
end;
@ -493,7 +515,7 @@ begin
offset:=offset+count;
end;
Function TEmit_MIMG._Gather_packed_offset(var offset:DWORD;dim:Byte):PsrRegNode;
Function TEmit_MIMG.Gather_packed_offset(var offset:DWORD;dim:Byte):PsrRegNode;
var
src:PsrRegNode;
begin
@ -503,22 +525,21 @@ begin
Inc(offset);
Case dim of
1:Result:=emit_OpPackOfs(line,dtInt32,dim,src);
2:Result:=emit_OpPackOfs(line,dtVec2i,dim,src);
3:Result:=emit_OpPackOfs(line,dtVec3i,dim,src);
1:Result:=OpPackOfs(line,dtInt32,dim,src);
2:Result:=OpPackOfs(line,dtVec2i,dim,src);
3:Result:=OpPackOfs(line,dtVec3i,dim,src);
else
Assert(False);
end;
Result^.mark_read;
end;
procedure TEmit_MIMG._emit_image_sample(Tgrp:PsrRegNode;info:PsrImageInfo);
procedure TEmit_MIMG.emit_image_sample(Tgrp:PsrNode;info:PsrImageInfo);
var
src:array[0..3] of PsrRegSlot;
pLayout:PsrDataLayout;
Sgrp:PsrRegNode;
Sgrp:PsrNode;
dst,cmb,coord,lod,offset:PsrRegNode;
@ -527,72 +548,71 @@ var
node:PSpirvOp;
begin
if not FRegsStory.get_srsrc(FSPI.MIMG.SSAMP,4,@src) then Assert(false);
if not get_srsrc(FSPI.MIMG.SSAMP,4,@src) then Assert(false);
pLayout:=GroupingSharp(src,rtSSharp4);
Sgrp:=FetchSampler(pLayout);
cmb:=emit_OpSampledImage(line,Tgrp,Sgrp,info^.dtype,info^.tinfo);
cmb^.mark_read;
cmb:=OpSampledImage(line,Tgrp,Sgrp,info^.dtype,info^.tinfo);
dst:=NewReg(GetVecType(info^.dtype,4));
dst:=NewReg(info^.dtype.AsVector(4));
roffset:=0;
Case FSPI.MIMG.OP of
IMAGE_SAMPLE:
begin
coord:=_GatherCoord_f(roffset,info^.tinfo.Dim);
coord:=GatherCoord_f(roffset,info^.tinfo.Dim);
if (FExecutionModel=ExecutionModel.Fragment) then
begin
node:=emit_OpImageSampleImplicitLod(line,dst,cmb,coord);
node:=OpImageSampleImplicitLod(line,cmb,dst,coord);
end else
begin
node:=emit_OpImageSampleExplicitLod(line,dst,cmb,coord);
node:=OpImageSampleExplicitLod(line,cmb,dst,coord);
end;
end;
IMAGE_SAMPLE_LZ:
begin
coord:=_GatherCoord_f(roffset,info^.tinfo.Dim);
coord:=GatherCoord_f(roffset,info^.tinfo.Dim);
node:=emit_OpImageSampleExplicitLod(line,dst,cmb,coord);
node:=OpImageSampleExplicitLod(line,cmb,dst,coord);
node^.AddLiteral(ImageOperands.Lod,'Lod');
//0
lod:=FetchReg(FConsts.Fetchf(dtFloat32,0));
node^.AddParam(ntReg,lod);
lod:=NewReg_s(dtFloat32,0);
node^.AddParam(lod);
end;
IMAGE_SAMPLE_LZ_O:
begin
offset:=_Gather_packed_offset(roffset,GetDimCount(info^.tinfo.Dim));
offset:=Gather_packed_offset(roffset,GetDimCount(info^.tinfo.Dim));
coord:=_GatherCoord_f(roffset,info^.tinfo.Dim);
coord:=GatherCoord_f(roffset,info^.tinfo.Dim);
node:=emit_OpImageSampleExplicitLod(line,dst,cmb,coord);
node:=OpImageSampleExplicitLod(line,cmb,dst,coord);
node^.AddLiteral(ImageOperands.Lod or ImageOperands.ConstOffset,'Lod|ConstOffset');
//0
lod:=FetchReg(FConsts.Fetchf(dtFloat32,0));
node^.AddParam(ntReg,lod);
lod:=NewReg_s(dtFloat32,0);
node^.AddParam(lod);
//1
node^.AddParam(ntReg,offset);
node^.AddParam(offset);
end;
else
Assert(false);
end;
_DistribDmask(dst,info^.dtype);
DistribDmask(dst,info^.dtype);
end;
procedure TEmit_MIMG._emit_image_load(Tgrp:PsrRegNode;info:PsrImageInfo);
procedure TEmit_MIMG.emit_image_load(Tgrp:PsrNode;info:PsrImageInfo);
var
dst,coord,lod,smp:PsrRegNode;
@ -601,15 +621,15 @@ var
node:PSpirvOp;
begin
dst:=NewReg(GetVecType(info^.dtype,4));
dst:=NewReg(info^.dtype.AsVector(4));
roffset:=0;
Case FSPI.MIMG.OP of
IMAGE_LOAD:
begin
coord:=_GatherCoord_u(roffset,info^.tinfo.Dim);
node:=emit_OpImageFetch(line,Tgrp,dst,coord);
coord:=GatherCoord_u(roffset,info^.tinfo.Dim);
node:=OpImageFetch(line,Tgrp,dst,coord);
if (info^.tinfo.MS<>0) then //fragid T# 2D MSAA
begin
@ -617,35 +637,79 @@ begin
Inc(roffset);
node^.AddLiteral(ImageOperands.Sample,'Sample');
node^.AddParam(ntReg,smp);
node^.AddParam(smp);
end;
end;
IMAGE_LOAD_MIP: //All except MSAA
begin
coord:=_GatherCoord_u(roffset,info^.tinfo.Dim);
node:=emit_OpImageFetch(line,Tgrp,dst,coord);
coord:=GatherCoord_u(roffset,info^.tinfo.Dim);
node:=OpImageFetch(line,Tgrp,dst,coord);
lod:=fetch_vsrc8(FSPI.MIMG.VADDR+roffset,dtUint32);
Inc(roffset);
node^.AddLiteral(ImageOperands.Lod,'Lod');
node^.AddParam(ntReg,lod);
node^.AddParam(lod);
end;
else
Assert(false);
end;
_DistribDmask(dst,info^.dtype);
DistribDmask(dst,info^.dtype);
end;
procedure TEmit_MIMG._emit_MIMG;
procedure TEmit_MIMG.emit_image_store(Tgrp:PsrNode;info:PsrImageInfo);
var
dst,coord,lod,smp:PsrRegNode;
roffset:DWORD;
node:PSpirvOp;
begin
dst:=GatherDmask(info^.dtype);
roffset:=0;
Case FSPI.MIMG.OP of
IMAGE_STORE:
begin
coord:=GatherCoord_u(roffset,info^.tinfo.Dim);
node:=OpImageWrite(line,Tgrp,coord,dst);
if (info^.tinfo.MS<>0) then //fragid T# 2D MSAA
begin
smp:=fetch_vsrc8(FSPI.MIMG.VADDR+roffset,dtUint32);
Inc(roffset);
node^.AddLiteral(ImageOperands.Sample,'Sample');
node^.AddParam(smp);
end;
end;
IMAGE_STORE_MIP: //All except MSAA
begin
coord:=GatherCoord_u(roffset,info^.tinfo.Dim);
node:=OpImageWrite(line,Tgrp,coord,dst);
lod:=fetch_vsrc8(FSPI.MIMG.VADDR+roffset,dtUint32);
Inc(roffset);
node^.AddLiteral(ImageOperands.Lod,'Lod');
node^.AddParam(lod);
end;
else
Assert(false);
end;
end;
procedure TEmit_MIMG.emit_MIMG;
var
src:array[0..7] of PsrRegSlot;
pLayout:PsrDataLayout;
info:TsrImageInfo;
Tgrp:PsrRegNode;
Tgrp:PsrNode;
begin
@ -656,17 +720,13 @@ begin
Case FSPI.MIMG.R128 of
0:
begin
if not FRegsStory.get_srsrc(FSPI.MIMG.SRSRC,8,@src) then Assert(false);
if not get_srsrc(FSPI.MIMG.SRSRC,8,@src) then Assert(false);
pLayout:=GroupingSharp(src,rtTSharp4);
//print_tsharp4(pLayout^.pData);
//Tgrp:=GroupingSharp(@src,rtTSharp8);
end;
1:
begin
if not FRegsStory.get_srsrc(FSPI.MIMG.SRSRC,4,@src) then Assert(false);
if not get_srsrc(FSPI.MIMG.SRSRC,4,@src) then Assert(false);
pLayout:=GroupingSharp(src,rtTSharp8);
//print_tsharp8(pLayout^.pData);
//Tgrp:=GroupingSharp(@src,rtTSharp4);
end;
end;
@ -678,7 +738,7 @@ begin
info.tinfo.Sampled:=1;
Tgrp:=FetchImage(pLayout,info.dtype,info.tinfo);
_emit_image_sample(Tgrp,@info);
emit_image_sample(Tgrp,@info);
end;
IMAGE_LOAD..IMAGE_LOAD_MIP_PCK_SGN: //loaded
@ -686,10 +746,16 @@ begin
info.tinfo.Sampled:=1;
Tgrp:=FetchImage(pLayout,info.dtype,info.tinfo);
_emit_image_load(Tgrp,@info);
emit_image_load(Tgrp,@info);
end;
IMAGE_STORE:; //TODO
IMAGE_STORE..IMAGE_STORE_MIP_PCK: //stored
begin
info.tinfo.Sampled:=2;
Tgrp:=FetchImage(pLayout,info.dtype,info.tinfo);
emit_image_store(Tgrp,@info);
end;
else
Assert(false,'MIMG?'+IntToStr(FSPI.MIMG.OP));

View File

@ -9,33 +9,32 @@ uses
ps4_pssl,
srReg,
srLayout,
SprvEmit,
emit_fetch,
srVBufInfo,
emit_vbuf_load,
emit_vbuf_store,
emit_op;
emit_vbuf_store;
type
TEmit_MTBUF=object(TEmitOp)
procedure _emit_MTBUF;
procedure _emit_TBUFFER_LOAD_FORMAT(count:Byte);
procedure _emit_TBUFFER_STORE_FORMAT(count:Byte);
TEmit_MTBUF=class(TEmitFetch)
procedure emit_MTBUF;
procedure emit_TBUFFER_LOAD_FORMAT(count:Byte);
procedure emit_TBUFFER_STORE_FORMAT(count:Byte);
end;
implementation
procedure TEmit_MTBUF._emit_TBUFFER_LOAD_FORMAT(count:Byte);
procedure TEmit_MTBUF.emit_TBUFFER_LOAD_FORMAT(count:Byte);
var
src:array[0..3] of PsrRegSlot;
grp:PsrDataLayout;
begin
if not FRegsStory.get_srsrc(FSPI.MTBUF.SRSRC,4,@src) then Assert(false);
if not get_srsrc(FSPI.MTBUF.SRSRC,4,@src) then Assert(false);
grp:=GroupingSharp(@src,rtVSharp4);
TEmit_vbuf_load(Self).buf_load(
TEmit_vbuf_load(TObject(Self)).buf_load(
Buf_info(grp,
dst_sel_identity,
FSPI.MTBUF.DFMT,
@ -45,18 +44,18 @@ begin
end;
procedure TEmit_MTBUF._emit_TBUFFER_STORE_FORMAT(count:Byte);
procedure TEmit_MTBUF.emit_TBUFFER_STORE_FORMAT(count:Byte);
var
src:array[0..3] of PsrRegSlot;
grp:PsrDataLayout;
begin
if not FRegsStory.get_srsrc(FSPI.MTBUF.SRSRC,4,@src) then Assert(false);
if not get_srsrc(FSPI.MTBUF.SRSRC,4,@src) then Assert(false);
grp:=GroupingSharp(@src,rtVSharp4);
TEmit_vbuf_store(Self).buf_store(
TEmit_vbuf_store(TObject(Self)).buf_store(
Buf_info(grp,
dst_sel_identity,
FSPI.MTBUF.DFMT,
@ -66,19 +65,19 @@ begin
end;
procedure TEmit_MTBUF._emit_MTBUF;
procedure TEmit_MTBUF.emit_MTBUF;
begin
case FSPI.MTBUF.OP of
TBUFFER_LOAD_FORMAT_X :_emit_TBUFFER_LOAD_FORMAT(1);
TBUFFER_LOAD_FORMAT_XY :_emit_TBUFFER_LOAD_FORMAT(2);
TBUFFER_LOAD_FORMAT_XYZ :_emit_TBUFFER_LOAD_FORMAT(3);
TBUFFER_LOAD_FORMAT_XYZW :_emit_TBUFFER_LOAD_FORMAT(4);
TBUFFER_LOAD_FORMAT_X :emit_TBUFFER_LOAD_FORMAT(1);
TBUFFER_LOAD_FORMAT_XY :emit_TBUFFER_LOAD_FORMAT(2);
TBUFFER_LOAD_FORMAT_XYZ :emit_TBUFFER_LOAD_FORMAT(3);
TBUFFER_LOAD_FORMAT_XYZW :emit_TBUFFER_LOAD_FORMAT(4);
TBUFFER_STORE_FORMAT_X :_emit_TBUFFER_STORE_FORMAT(1);
TBUFFER_STORE_FORMAT_XY :_emit_TBUFFER_STORE_FORMAT(2);
TBUFFER_STORE_FORMAT_XYZ :_emit_TBUFFER_STORE_FORMAT(3);
TBUFFER_STORE_FORMAT_XYZW:_emit_TBUFFER_STORE_FORMAT(4);
TBUFFER_STORE_FORMAT_X :emit_TBUFFER_STORE_FORMAT(1);
TBUFFER_STORE_FORMAT_XY :emit_TBUFFER_STORE_FORMAT(2);
TBUFFER_STORE_FORMAT_XYZ :emit_TBUFFER_STORE_FORMAT(3);
TBUFFER_STORE_FORMAT_XYZW:emit_TBUFFER_STORE_FORMAT(4);
end;
//OFFSET:bit12; //Unsigned byte offset.

View File

@ -8,48 +8,53 @@ uses
sysutils,
ps4_shader,
ps4_pssl,
srTypes,
srConfig,
srType,
srReg,
srLayout,
srInput,
spirv,
SprvEmit,
emit_fetch,
srVBufInfo,
emit_vbuf_load,
emit_vbuf_store,
emit_op;
emit_vbuf_store;
type
TEmit_MUBUF=object(TEmitOp)
procedure _emit_MUBUF;
procedure _make_load_zero(dst:PsrRegSlot);
procedure _make_load_one(dst:PsrRegSlot);
procedure _make_load_comp(dst:PsrRegSlot;rsl:PsrRegNode;i:Byte);
function _emit_BUFFER_LOAD_VA(src:PPsrRegSlot;count:Byte):Boolean;
procedure _emit_BUFFER_LOAD_FORMAT(count:Byte);
procedure _emit_BUFFER_STORE_FORMAT(count:Byte);
TEmit_MUBUF=class(TEmitFetch)
procedure emit_MUBUF;
procedure make_load_zero(dst:PsrRegSlot;dtype:TsrDataType);
procedure make_load_one(dst:PsrRegSlot;dtype:TsrDataType);
procedure make_load_comp(dst:PsrRegSlot;dtype:TsrDataType;rsl:PsrRegNode;i:Byte);
function emit_BUFFER_LOAD_VA(src:PPsrRegSlot;count:Byte):Boolean;
procedure emit_BUFFER_LOAD_FORMAT(count:Byte);
procedure emit_BUFFER_STORE_FORMAT(count:Byte);
end;
implementation
procedure TEmit_MUBUF._make_load_zero(dst:PsrRegSlot);
procedure TEmit_MUBUF.make_load_zero(dst:PsrRegSlot;dtype:TsrDataType);
begin
SetConst(dst,FConsts.Fetchi(dtFloat32,0));
SetConst_q(dst,dtype,0);
end;
procedure TEmit_MUBUF._make_load_one(dst:PsrRegSlot);
procedure TEmit_MUBUF.make_load_one(dst:PsrRegSlot;dtype:TsrDataType);
begin
SetConst(dst,FConsts.Fetchf(dtFloat32,1));
if (dtype=dtFloat32) then
begin
SetConst_s(dst,dtype,1);
end else
begin
SetConst_i(dst,dtype,1);
end;
end;
procedure TEmit_MUBUF._make_load_comp(dst:PsrRegSlot;rsl:PsrRegNode;i:Byte);
procedure TEmit_MUBUF.make_load_comp(dst:PsrRegSlot;dtype:TsrDataType;rsl:PsrRegNode;i:Byte);
begin
dst^.New(line,dtFloat32);
rsl^.mark_read;
emit_OpCompExtract(line,dst^.current,rsl,i);
dst^.New(line,dtype);
OpExtract(line,dst^.current,rsl,i);
end;
function TEmit_MUBUF._emit_BUFFER_LOAD_VA(src:PPsrRegSlot;count:Byte):Boolean;
function TEmit_MUBUF.emit_BUFFER_LOAD_VA(src:PPsrRegSlot;count:Byte):Boolean;
var
dst:PsrRegSlot;
@ -61,59 +66,69 @@ var
inp_idx:PsrInput;
dsel:Tdst_sel;
info:TBuf_info;
elem_res:TsrDataType;
elem_vec:TsrDataType;
i,d,elem_count:Byte;
begin
Result:=False;
idx:=FRegsStory.get_vsrc8(FSPI.MUBUF.VADDR+0)^.current;
idx:=get_vsrc8(FSPI.MUBUF.VADDR+0)^.current;
inp_idx:=GetInputRegNode(idx);
if (inp_idx<>nil) then
if (inp_idx^.key.itype=itVIndex) then //is input attach
if (inp_idx^.itype=itVIndex) then //is input attach
begin
grp:=GroupingSharp(src,rtVSharp4);
PV:=grp^.pData;
rsl:=AddVertLayout(grp,dtVec4f);
dsel:=dst_sel(PV^.dst_sel_x,
PV^.dst_sel_y,
PV^.dst_sel_z,
PV^.dst_sel_w);
info:=Buf_info(grp,
dst_sel(PV^.dst_sel_x,
PV^.dst_sel_y,
PV^.dst_sel_z,
PV^.dst_sel_w),
PV^.dfmt,
PV^.nfmt,
count);
elem_res:=info.GetResultType;
elem_vec:=elem_res.AsVector(info.GetElemCount);
rsl:=AddVertLayout(grp,elem_vec);
elem_count:=GetElemCount(PV^.dfmt);
For i:=0 to count-1 do
begin
dst:=FRegsStory.get_vdst8(FSPI.MUBUF.VDATA+i);
dst:=get_vdst8(FSPI.MUBUF.VDATA+i);
if (dst=nil) then Assert(false);
//0=0, 1=1, 4=R, 5=G, 6=B, 7=A
Case dsel[i] of
Case info.dsel[i] of
0:begin //0
_make_load_zero(dst);
make_load_zero(dst,elem_res);
end;
1:begin //1
_make_load_one(dst);
make_load_one(dst,elem_res);
end;
4..7:
begin //RGBA
d:=dsel[i]-4;
d:=info.dsel[i]-4;
if (d<elem_count) then
begin
_make_load_comp(dst,rsl,d);
make_load_comp(dst,elem_res,rsl,d);
end else
begin //as zero
_make_load_zero(dst);
make_load_zero(dst,elem_res);
end;
end;
else
begin //as zero
_make_load_zero(dst);
make_load_zero(dst,elem_res);
end;
end;
@ -124,32 +139,31 @@ begin
end;
procedure TEmit_MUBUF._emit_BUFFER_LOAD_FORMAT(count:Byte);
procedure TEmit_MUBUF.emit_BUFFER_LOAD_FORMAT(count:Byte);
var
src:array[0..3] of PsrRegSlot;
grp:PsrDataLayout;
PV:PVSharpResource4;
begin
Assert(FSPI.MUBUF.LDS=0,'FSPI.MUBUF.LDS');
if not FRegsStory.get_srsrc(FSPI.MUBUF.SRSRC,4,@src) then Assert(false);
if not get_srsrc(FSPI.MUBUF.SRSRC,4,@src) then Assert(false);
if FUseVertexInput then
if Config.UseVertexInput then
if (FExecutionModel=ExecutionModel.Vertex) then //Vertex only
if (FSPI.MUBUF.IDXEN=1) and
(FSPI.MUBUF.OFFEN=0) and
(FSPI.MUBUF.SOFFSET=128) and
(FSPI.MUBUF.LDS=0) then
begin
if _emit_BUFFER_LOAD_VA(@src,count) then Exit;
if emit_BUFFER_LOAD_VA(@src,count) then Exit;
end;
grp:=GroupingSharp(@src,rtVSharp4);
PV:=grp^.pData;
TEmit_vbuf_load(Self).buf_load(
TEmit_vbuf_load(TObject(Self)).buf_load(
Buf_info(grp,
dst_sel(PV^.dst_sel_x,
PV^.dst_sel_y,
@ -162,7 +176,7 @@ begin
end;
procedure TEmit_MUBUF._emit_BUFFER_STORE_FORMAT(count:Byte);
procedure TEmit_MUBUF.emit_BUFFER_STORE_FORMAT(count:Byte);
var
src:array[0..3] of PsrRegSlot;
@ -172,12 +186,12 @@ var
begin
Assert(FSPI.MUBUF.LDS=0,'FSPI.MUBUF.LDS');
if not FRegsStory.get_srsrc(FSPI.MUBUF.SRSRC,4,@src) then Assert(false);
if not get_srsrc(FSPI.MUBUF.SRSRC,4,@src) then Assert(false);
grp:=GroupingSharp(@src,rtVSharp4);
PV:=grp^.pData;
TEmit_vbuf_store(Self).buf_store(
TEmit_vbuf_store(TObject(Self)).buf_store(
Buf_info(grp,
dst_sel(PV^.dst_sel_x,
PV^.dst_sel_y,
@ -190,42 +204,18 @@ begin
end;
procedure TEmit_MUBUF._emit_MUBUF;
procedure TEmit_MUBUF.emit_MUBUF;
begin
case FSPI.MUBUF.OP of
BUFFER_LOAD_FORMAT_X:
begin
_emit_BUFFER_LOAD_FORMAT(1);
end;
BUFFER_LOAD_FORMAT_XY:
begin
_emit_BUFFER_LOAD_FORMAT(2);
end;
BUFFER_LOAD_FORMAT_XYZ:
begin
_emit_BUFFER_LOAD_FORMAT(3);
end;
BUFFER_LOAD_FORMAT_XYZW:
begin
_emit_BUFFER_LOAD_FORMAT(4);
end;
BUFFER_LOAD_FORMAT_X : emit_BUFFER_LOAD_FORMAT(1);
BUFFER_LOAD_FORMAT_XY : emit_BUFFER_LOAD_FORMAT(2);
BUFFER_LOAD_FORMAT_XYZ : emit_BUFFER_LOAD_FORMAT(3);
BUFFER_LOAD_FORMAT_XYZW : emit_BUFFER_LOAD_FORMAT(4);
BUFFER_STORE_FORMAT_X:
begin
_emit_BUFFER_STORE_FORMAT(1);
end;
BUFFER_STORE_FORMAT_XY:
begin
_emit_BUFFER_STORE_FORMAT(2);
end;
BUFFER_STORE_FORMAT_XYZ:
begin
_emit_BUFFER_STORE_FORMAT(3);
end;
BUFFER_STORE_FORMAT_XYZW:
begin
_emit_BUFFER_STORE_FORMAT(4);
end;
BUFFER_STORE_FORMAT_X : emit_BUFFER_STORE_FORMAT(1);
BUFFER_STORE_FORMAT_XY : emit_BUFFER_STORE_FORMAT(2);
BUFFER_STORE_FORMAT_XYZ : emit_BUFFER_STORE_FORMAT(3);
BUFFER_STORE_FORMAT_XYZW: emit_BUFFER_STORE_FORMAT(4);
else
Assert(false,'MUBUF?'+IntToStr(FSPI.MUBUF.OP));

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -7,32 +7,27 @@ interface
uses
sysutils,
spirv,
srNodes,
srNode,
srType,
srTypes,
srConst,
srReg,
srLayout,
srVariable,
srOp,
srOpUtils,
srCap,
srRefId,
Half16,
SprvEmit;
srCapability,
emit_fetch;
type
TSprvEmit_print=object(TSprvEmit)
TSprvEmit_print=class(TEmitFetch)
procedure Print;
procedure PrintCaps;
procedure PrintOpList(node:PspirvOp);
procedure PrintOpBlock(pBlock:PsrOpBlock);
procedure PrintHeaderInfo;
procedure PrintTypes;
procedure PrintConst(node:PsrConst);
procedure PrintConst;
procedure PrintVariable;
procedure PrintFunc;
procedure PrintOp(node:PSpirvOp;print_offset:Boolean);
procedure PrintOpBlock(pBlock:PsrOpBlock);
end;
implementation
@ -42,637 +37,141 @@ begin
PrintCaps;
Writeln;
PrintHeaderInfo;
Writeln;
PrintTypes;
Writeln;
PrintConst;
Writeln;
PrintVariable;
PrintFunc;
end;
procedure PrintRefId(P:PsrRefId);
begin
Assert(P<>nil ,'PrintRefId$1');
Assert(P^.Alloc,'PrintRefId$2');
Write('%',P^.ID);
end;
procedure PrintConstId(P:PsrConst);
procedure PrintNode(Node:PsrNode);
var
s:Single;
i:Int64;
u:QWORD;
name:RawByteString;
begin
Assert(P<>nil ,'PrintConstId$1');
Assert(P^.ID.Alloc,'PrintConstId$2');
Case P^.key.dtype of
dtBool:
begin
Case P^.AsBool of
true :Write('%true');
False:Write('%false');
end;
end;
dtHalf16:
begin
s:=Single(P^.AsHalf16);
i:=Trunc(s);
if (s=i) then
begin
Case i of
0..99:Write('%ch',i);
else
Write('%c',P^.ID.ID);
end;
end else
begin
Write('%c',P^.ID.ID);
end;
end;
dtFloat32:
begin
s:=P^.AsFloat32;
i:=Trunc(s);
if (s=i) then
begin
Case i of
0..99:Write('%cf',i);
-9..-1:Write('%cfm',abs(i));
else
Write('%c',P^.ID.ID);
end;
end else
begin
Write('%c',P^.ID.ID);
end;
end;
dtInt32 :
begin
i:=P^.AsInt;
Case i of
0..99:Write('%ci',i);
-9..-1:Write('%cim',abs(i));
else
Write('%c',P^.ID.ID);
end;
end;
dtUint32:
begin
u:=P^.AsUint;
Case u of
0..99:Write('%cu',u);
else
Write('%c',P^.ID.ID);
end;
end;
else
Write('%c',P^.ID.ID);
end;
end;
procedure PrintVar(P:PsrVariable);
Var
n:RawByteString;
begin
Assert(P<>nil ,'PrintVar$1');
Assert(P^.ID.Alloc,'PrintVar$2');
if (P^.pSource.pData<>nil) then
Assert(Node<>nil,'PrintNode$1');
name:=node^.GetPrintName;
if (name<>'') then
begin
n:=P^.GetName;
if (n<>'') then
begin
Write('%',n);
end else
begin
Write('%v',P^.ID.ID);
end;
Write('%',name);
end else
begin
Write('%v',P^.ID.ID);
end;
end;
function type_get_base_name(dtype:TsrDataType):RawByteString;
begin
Result:='';
case dtype of
dtBool :Result:='bool';
dtFloat32 :Result:='float';
dtHalf16 :Result:='half';
dtInt8 :Result:='int8';
dtUint8 :Result:='uint8';
dtInt16 :Result:='int16';
dtUint16 :Result:='uint16';
dtInt32 :Result:='int';
dtUint32 :Result:='uint';
dtInt64 :Result:='int64';
dtUint64 :Result:='uint64';
//Composite types
dtVec2b :Result:='bvec2';
dtVec3b :Result:='bvec3';
dtVec4b :Result:='bvec4';
dtStruct2u :Result:='rec2u';
dtVec2u8 :Result:='u8vec2';
dtVec4u8 :Result:='u8vec4';
dtVec2i8 :Result:='i8vec2';
dtVec4i8 :Result:='i8vec4';
dtVec2u16 :Result:='u16vec2';
dtVec4u16 :Result:='u16vec4';
dtVec2i16 :Result:='i16vec2';
dtVec4i16 :Result:='i16vec4';
dtVec2u :Result:='uvec2';
dtVec3u :Result:='uvec3';
dtVec4u :Result:='uvec4';
dtVec2i :Result:='ivec2';
dtVec3i :Result:='ivec3';
dtVec4i :Result:='ivec4';
dtVec2f :Result:='vec2';
dtVec3f :Result:='vec3';
dtVec4f :Result:='vec4';
dtVec2h :Result:='hvec2';
dtVec4h :Result:='hvec4';
dtTypeVoid :Result:='void';
dtTypeSampler:Result:='samp';
else;
end;
end;
function type_get_base_name(node:PsrType):RawByteString;
var
n:PsrType;
begin
Result:='';
case node^.dtype of
{dtTypeImage:
begin
if DWORD(node^.key.ext.image)=DWORD(ExtImgBuf) then
begin
Result:='buf';
end else
if DWORD(node^.key.ext.image)=DWORD(ExtImage2D) then
begin
Result:='img2D';
end;
end;}
dtTypeSampledImage:
begin
if (node^.key.count<>1) then Exit;
n:=node^.GetCompItem(0);
Result:=type_get_base_name(n);
if (Result='') then Exit;
Result:='sm'+Result;
end;
dtTypeArray:
begin
n:=node^.GetCompItem(0);
Result:=type_get_base_name(n);
if (Result='') then Exit;
Result:='ar'+IntToStr(node^.key.ext.array_count)+Result;
end;
dtTypeRuntimeArray:
begin
n:=node^.GetCompItem(0);
Result:=type_get_base_name(n);
if (Result='') then Exit;
Result:='ra'+Result;
end;
dtTypeStruct:
begin
if (node^.key.count<>1) then Exit;
n:=node^.GetCompItem(0);
Result:=type_get_base_name(n);
if (Result='') then Exit;
Result:='st'+Result;
end;
dtTypeFunction:
begin
if (node^.key.count<>1) then Exit;
n:=node^.GetCompItem(0);
Result:=type_get_base_name(n);
if (Result='') then Exit;
Result:='fn'+Result;
end;
else
Result:=type_get_base_name(node^.dtype);
end;
end;
procedure PrintTypeId(node:PsrType);
var
s:RawByteString;
n:PsrType;
begin
case node^.dtype of
dtTypePointer:
begin
n:=node^.GetCompItem(0);
S:=type_get_base_name(n);
if (S='') then
PrintRefId(@node^.ID)
else
begin
S:='p'+S;
Case node^.key.ext.storage_class of
StorageClass.UniformConstant :S:=S+'_uc';
StorageClass.Input :S:=S+'_in';
StorageClass.Uniform :S:=S+'_uf';
StorageClass.Output :S:=S+'_ot';
StorageClass.Workgroup :S:=S+'_wg';
StorageClass.CrossWorkgroup :S:=S+'_cw';
StorageClass.Private_ :S:=S+'_pv';
StorageClass.Function_ :S:=S+'_fc';
StorageClass.PushConstant :S:=S+'_pc';
StorageClass.Image :S:=S+'_im';
StorageClass.StorageBuffer :S:=S+'_sb';
else
S:='';
end;
if (S='') then
PrintRefId(@node^.ID)
else
Write('%',S);
end;
end;
else
begin
S:=type_get_base_name(node);
if (S='') then
PrintRefId(@node^.ID)
else
Write('%',S);
end;
end;
end;
procedure PrintChain(P:PsrChain);
begin
Assert(P<>nil ,'PrintChain$1');
Assert(P^.ID.Alloc,'PrintChain$2');
Write('%ac',P^.ID.ID);
end;
procedure PrintReg(P:PsrRegNode);
begin
Assert(P<>nil,'PrintReg$1');
Case P^.pWriter.ntype of
ntConst:
begin
PrintConstId(P^.pWriter.pData);
end;
ntOp:
begin
if (not P^.ID.Alloc) then Assert(false,'PrintReg$2');
Write('%r',P^.ID.ID);
//Write('(',P^.read_count,')');
end;
else
Assert(false,'PrintReg$3');
name:=node^.GetPrintData;
Assert(name<>'','PrintNode$2');
Write(name);
end;
end;
procedure TSprvEmit_print.PrintCaps;
var
node:PSpirvCap;
node:PsrCapability;
begin
node:=FSpirvCaps.First;
node:=CapabilityList.First;
While (node<>nil) do
begin
Writeln(Op.GetStr(Op.OpCapability),' ',Capability.GetStr(node^.ID));
node:=FSpirvCaps.Next(node);
node:=CapabilityList.Next(node);
end;
end;
procedure TSprvEmit_print.PrintOpList(node:PspirvOp);
procedure TSprvEmit_print.PrintOpBlock(pBlock:PsrOpBlock);
var
node:PSpirvOp;
begin
if (pBlock=nil) then Exit;
node:=pBlock^.First;
While (node<>nil) do
begin
PrintOp(node,false);
node:=node^.pNext;
if node^.IsType(ntOp) then
begin
pBlock:=node^.Parent;
Write(Space(pBlock^.Level));
PrintOp(node,false);
end;
node:=flow_down_next_up(node);
end;
end;
procedure TSprvEmit_print.PrintHeaderInfo;
begin
PrintOpList(FHeader.pHead);
Writeln;
PrintOpList(FDebugInfo.pHead);
if (FDebugInfo.pHead<>nil) then Writeln;
PrintOpList(FDecorates.pHead);
end;
function Dim_GetStr(w:Word):RawByteString;
begin
Result:='';
Case w of
Dim.Dim1D :Result:='1D';
Dim.Dim2D :Result:='2D';
Dim.Dim3D :Result:='3D';
Dim.Cube :Result:='Cube';
Dim.Rect :Result:='Rect';
Dim.Buffer :Result:='Buffer';
Dim.SubpassData:Result:='SubpassData';
else
Assert(False,'Dim_GetStr');
end;
PrintOpBlock(@HeaderList);
if (HeaderList.First<>nil) then Writeln;
PrintOpBlock(@DebugInfoList);
if (DebugInfoList.First<>nil) then Writeln;
PrintOpBlock(@DecorateList);
if (DecorateList.First<>nil) then Writeln;
end;
procedure TSprvEmit_print.PrintTypes;
var
node:PsrType;
pConst:PsrConst;
i:dword;
ie:Boolean;
i:Word;
begin
node:=FSpirvTypes.FList.pHead;
node:=TypeList.First;
While (node<>nil) do
begin
ie:=True;
pConst:=nil;
case node^.dtype of
dtTypeArray:
begin
//find a const
pConst:=FConsts.Fetchi(dtUInt32,node^.key.ext.array_count);
PrintConst(pConst);
end;
else;
end;
PrintTypeId(node);
Write(' = ');
Write(Op.GetStr(node^.key.OpId));
case node^.key.OpId of
Op.OpTypeFloat:
begin
Write(' ',node^.key.ext.float_size);
end;
Op.OpTypeInt:
begin
Write(' ',node^.key.ext.int_size);
Write(' ',node^.key.ext.int_sign);
end;
Op.OpTypeVector:
begin
ie:=False;
Write(' ');
PrintTypeId(node^.GetCompItem(0));
Write(' ',node^.key.ext.array_count);
end;
Op.OpTypePointer:
begin
Write(' ',StorageClass.GetStr(node^.key.ext.Storage_Class));
end;
Op.OpTypeArray:
begin
ie:=False;
Write(' ');
PrintTypeId(node^.GetCompItem(0));
Write(' ');
PrintConstId(pConst);
end;
Op.OpTypeRuntimeArray:
begin
ie:=False;
Write(' ');
PrintTypeId(node^.GetCompItem(0));
end;
Op.OpTypeImage:
begin
ie:=False;
Write(' ');
PrintTypeId(node^.GetCompItem(0));
With node^.key.ext.image do
Write(' ',
Dim_GetStr(Dim),' ',
Depth,' ',
Arrayed,' ',
MS,' ',
Sampled,' ',
Spirv.ImageFormat.GetStr(Format));
end;
end;
if ie then
if (node^.key.count<>0) then
PrintNode(node);
Write(' = ',Op.GetStr(node^.OpId));
if (node^.ItemCount<>0) then
begin
For i:=0 to node^.ItemCount-1 do
begin
For i:=0 to node^.key.count-1 do
begin
Write(' ');
PrintTypeId(node^.GetCompItem(i));
end;
Write(' ');
PrintNode(node^.GetItem(i));
end;
end;
Writeln;
node:=node^.pNext;
node:=node^.Next;
end;
end;
const
DefaultFormatSettings : TFormatSettings = (
CurrencyFormat: 1;
NegCurrFormat: 5;
ThousandSeparator: ',';
DecimalSeparator: '.';
CurrencyDecimals: 2;
DateSeparator: '-';
TimeSeparator: ':';
ListSeparator: ',';
CurrencyString: '$';
ShortDateFormat: 'd/m/y';
LongDateFormat: 'dd" "mmmm" "yyyy';
TimeAMString: 'AM';
TimePMString: 'PM';
ShortTimeFormat: 'hh:nn';
LongTimeFormat: 'hh:nn:ss';
ShortMonthNames: ('Jan','Feb','Mar','Apr','May','Jun',
'Jul','Aug','Sep','Oct','Nov','Dec');
LongMonthNames: ('January','February','March','April','May','June',
'July','August','September','October','November','December');
ShortDayNames: ('Sun','Mon','Tue','Wed','Thu','Fri','Sat');
LongDayNames: ('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday');
TwoDigitYearCenturyWindow: 50;
);
procedure TSprvEmit_print.PrintConst(node:PsrConst);
var
i:dword;
begin
PrintConstId(node);
Write(' = ');
if (node^.key.count=0) then
begin
if (node^.key.dtype=dtBool) then
begin
Case node^.AsBool of
True :Write(Op.GetStr(Op.OpConstantTrue));
False:Write(Op.GetStr(Op.OpConstantFalse));
end;
Write(' ');
PrintTypeId(node^.pType);
end else
begin
Write(Op.GetStr(Op.OpConstant));
Write(' ');
PrintTypeId(node^.pType);
Write(' ');
case node^.key.dtype of
dtFloat32:Write(FloatToStr(node^.AsFloat32,DefaultFormatSettings));
dtHalf16 :Write(FloatToStr(Single(node^.AsHalf16),DefaultFormatSettings));
dtInt32 :Write(node^.AsInt);
dtUint32 :Write(node^.AsUint);
dtInt64 :Write(node^.AsInt64);
dtUint64 :Write(node^.AsUint64);
else
Assert(false,'PrintConst');
end;
end;
end else
begin
Write(Op.GetStr(Op.OpConstantComposite));
Write(' ');
PrintTypeId(node^.pType);
For i:=0 to node^.key.count-1 do
begin
Write(' ');
PrintConstId(node^.GetCompItem(i));
end;
end;
Writeln;
end;
procedure TSprvEmit_print.PrintConst;
var
node:PsrConst;
i:Word;
begin
node:=FConsts.FList.pHead;
node:=ConstList.First;
While (node<>nil) do
begin
//if not node^.is_first then
//begin
if (node^.key.dtype=dtUnknow) then
if (node^.dtype=dtUnknow) then
begin
Write('; ');
Writeln(' = dtUnknow: read_count=',node^.read_count,' value=',node^.GetData);
end else
begin
PrintNode(node);
Write(' = ',Op.GetStr(node^.OpId),' ');
PrintNode(node^.pType);
if (node^.dtype<>dtBool) then
begin
Write('; ');
//PrintConstId(node);
Writeln(' = dtUnknow: read_count=',node^.read_count,' value=',node^.Data);
end else
//Assert(node^.dtype<>dtUnknow);
PrintConst(node);
//end;
node:=node^.pNext;
For i:=0 to node^.ItemCount-1 do
begin
Write(' ');
PrintNode(node^.GetItem(i));
end;
end;
Writeln;
end;
node:=node^.Next;
end;
if (ConstList.First<>nil) then Writeln;
end;
procedure TSprvEmit_print.PrintVariable;
var
node:PsrVariable;
begin
node:=FVariables.pHead;
node:=VariableList.First;
While (node<>nil) do
begin
if (node^.pType<>nil) then
begin
PrintVar(node);
PrintNode(node);
Write(' = ',Op.GetStr(Op.OpVariable),' ');
PrintTypeId(node^.pType);
PrintNode(node^.pType);
Writeln(' ',StorageClass.GetStr(node^.GetStorageClass));
end;
node:=node^.pNext;
end;
end;
procedure PrintFuncId(P:PSpirvFunc);
begin
Assert(P<>nil,'PrintFuncId');
if (P^.name<>'') then
begin
Write('%',P^.name);
end else
begin
PrintRefId(@P^.ID);
end;
end;
procedure PrintOpParamSingle(const Param:TOpParamSingle);
begin
Assert(Param.pData<>nil,'PrintOpParamSingle$1');
Case Param.ntype of
ntFunc :PrintFuncId(Param.pData);
ntRefId:PrintRefId(Param.pData);
ntType :PrintTypeId(Param.pData);
ntReg :PrintReg(Param.pData);
ntVar :PrintVar(Param.pData);
ntChain:PrintChain(Param.pData);
ntConst:PrintConstId(Param.pData);
else
Assert(false,'PrintOpParamSingle$2');
end;
end;
procedure PrintOpParamNode(node:POpParamNode);
begin
Case node^.ntype of
ntLiteral:
begin
if StrLen(@node^.name)=0 then
begin
Write(node^.Value);
end else
begin
Write(PChar(@node^.name));
end;
end;
ntString:
begin
Write('"',PChar(@node^.name),'"');
end;
else
begin
PrintOpParamSingle(node^.AsParam);
end;
node:=node^.Next;
end;
end;
@ -680,12 +179,12 @@ procedure TSprvEmit_print.PrintFunc;
var
pFunc:PSpirvFunc;
begin
pFunc:=FSpirvFuncs.FList.pHead;
pFunc:=FuncList.First;
While (pFunc<>nil) do
begin
Writeln;
PrintOpBlock(@pFunc^.FTop);
pFunc:=pFunc^.pNext;
PrintOpBlock(pFunc^.pTop);
pFunc:=pFunc^.Next;
end;
end;
@ -700,35 +199,39 @@ begin
if Info.result then //dst
begin
Assert(node^.dst.ntype<>ntUnknow,'PrintOp$1');
Assert(node^.dst.pData<>nil,'PrintOp$2');
PrintOpParamSingle(node^.dst);
Assert(node^.pDst<>nil,'PrintOp$1');
if (node^.pDst<>nil) then
begin
PrintNode(node^.pDst);
end;
Write(' = ');
Write(Op.GetStr(node^.OpId));
end else
begin //no dst
Write(Op.GetStr(node^.OpId));
if (node^.dst.ntype<>ntUnknow) then
if (node^.pDst<>nil) then
begin
Assert(node^.dst.pData<>nil,'PrintOp$3');
Write(' ');
PrintOpParamSingle(node^.dst);
PrintNode(node^.pDst);
end;
end;
if Info.rstype then //dst type
begin
Assert(node^.dst_type<>nil,'PrintOp$4');
Assert(node^.pType<>nil,'PrintOp$2');
Write(' ');
PrintTypeId(node^.dst_type);
if (node^.pType<>nil) then
begin
PrintNode(node^.pType);
end;
end;
Param:=node^.pParam.pHead;
Param:=node^.ParamFirst;
While (Param<>nil) do
begin
Write(' ');
PrintOpParamNode(Param);
Param:=Param^.pNext;
PrintNode(Param^.Value);
Param:=Param^.Next;
end;
if (node^.OpId=Op.OpLabel) then
@ -742,31 +245,6 @@ begin
end;
end;
procedure TSprvEmit_print.PrintOpBlock(pBlock:PsrOpBlock);
var
node:PSpirvOp;
begin
if (pBlock=nil) then Exit;
node:=pBlock^.pHead;
While (node<>nil) do
begin
if (node^.OpId=OpBlock) then
begin
if (node^.dst.ntype=ntBlock) then
begin
PrintOpBlock(node^.dst.pData);
end;
end else
begin
Write(Space(pBlock^.FLevel));
PrintOp(node,false);
end;
node:=node^.pNext;
end;
end;
end.

View File

@ -7,30 +7,29 @@ interface
uses
sysutils,
ps4_pssl,
srTypes,
srType,
srReg,
srLayout,
SprvEmit,
emit_op;
emit_fetch;
type
TEmit_SMRD=object(TEmitOp)
procedure _emit_SMRD;
procedure _emit_LOAD_DWORDX(grp:PsrDataLayout;count:Byte);
TEmit_SMRD=class(TEmitFetch)
procedure emit_SMRD;
procedure emit_LOAD_DWORDX(grp:PsrDataLayout;count:Byte);
procedure emit_LOAD_DWORDX(count:Byte);
procedure emit_BUFFER_LOAD_DWORDX(count:Byte);
end;
implementation
procedure TEmit_SMRD._emit_LOAD_DWORDX(grp:PsrDataLayout;count:Byte);
procedure TEmit_SMRD.emit_LOAD_DWORDX(grp:PsrDataLayout;count:Byte);
var
dst:PsrRegSlot;
ofs_r,idx_r:PsrRegNode;
dtype:TsrDataType;
ext:TsrChainExt;
lvl_0:TsrChainLvl_0;
lvl_1:TsrChainLvl_1;
i:Byte;
@ -40,22 +39,23 @@ begin
begin
For i:=0 to count-1 do
begin
dst:=FRegsStory.get_sdst7(FSPI.SMRD.SDST+i);
dst:=get_sdst7(FSPI.SMRD.SDST+i);
Assert(dst<>nil);
MakeChain(dst,grp,(FSPI.SMRD.OFFSET+i)*4,4,nil);
lvl_0.offset:=(FSPI.SMRD.OFFSET+i)*4;
lvl_0.size :=4;
MakeChain(dst,grp,@lvl_0,nil);
end;
end else
begin
ofs_r:=fetch_ssrc9(FSPI.SMRD.OFFSET,dtUint32);
dtype:=ofs_r^.dtype;
idx_r:=NewReg(dtype);
_emit_OpShr(line,idx_r,ofs_r,FetchReg(FConsts.Fetchi(dtype,2)));
idx_r:=OpShrTo(ofs_r,2);
For i:=0 to count-1 do
begin
dst:=FRegsStory.get_sdst7(FSPI.SMRD.SDST+i);
dst:=get_sdst7(FSPI.SMRD.SDST+i);
Assert(dst<>nil);
if (i=0) then
@ -63,17 +63,16 @@ begin
ofs_r:=idx_r;
end else
begin
ofs_r:=NewReg(dtype);
idx_r^.mark_read;
_emit_OpIAdd(line,ofs_r,idx_r,FetchReg(FConsts.Fetchi(dtype,i)));
ofs_r:=OpIAddTo(idx_r,i);
end;
ofs_r^.mark_read;
lvl_0.offset:=0;
lvl_0.size :=4;
ext:=Default(TsrChainExt);
ext.pIndex:=ofs_r;
ext.stride:=4;
MakeChain(dst,grp,0,4,@ext);
lvl_1.pIndex:=ofs_r;
lvl_1.stride:=4;
MakeChain(dst,grp,@lvl_0,@lvl_1);
end;
end;
@ -84,9 +83,9 @@ var
src:array[0..3] of PsrRegSlot;
grp:PsrDataLayout;
begin
if not FRegsStory.get_sbase(FSPI.SMRD.SBASE,2,@src) then Assert(false);
if not get_sbase(FSPI.SMRD.SBASE,2,@src) then Assert(false);
grp:=GroupingSharp(@src,rtBufPtr2);
_emit_LOAD_DWORDX(grp,count);
emit_LOAD_DWORDX(grp,count);
end;
procedure TEmit_SMRD.emit_BUFFER_LOAD_DWORDX(count:Byte);
@ -94,56 +93,26 @@ var
src:array[0..3] of PsrRegSlot;
grp:PsrDataLayout;
begin
if not FRegsStory.get_sbase(FSPI.SMRD.SBASE,4,@src) then Assert(false);
if not get_sbase(FSPI.SMRD.SBASE,4,@src) then Assert(false);
grp:=GroupingSharp(@src,rtVSharp4);
_emit_LOAD_DWORDX(grp,count);
emit_LOAD_DWORDX(grp,count);
end;
procedure TEmit_SMRD._emit_SMRD;
procedure TEmit_SMRD.emit_SMRD;
begin
Case FSPI.SMRD.OP of
S_BUFFER_LOAD_DWORD:
begin
emit_BUFFER_LOAD_DWORDX(1);
end;
S_BUFFER_LOAD_DWORDX2:
begin
emit_BUFFER_LOAD_DWORDX(2);
end;
S_BUFFER_LOAD_DWORDX4:
begin
emit_BUFFER_LOAD_DWORDX(4);
end;
S_BUFFER_LOAD_DWORDX8:
begin
emit_BUFFER_LOAD_DWORDX(8);
end;
S_BUFFER_LOAD_DWORDX16:
begin
emit_BUFFER_LOAD_DWORDX(16);
end;
S_BUFFER_LOAD_DWORD : emit_BUFFER_LOAD_DWORDX(1);
S_BUFFER_LOAD_DWORDX2 : emit_BUFFER_LOAD_DWORDX(2);
S_BUFFER_LOAD_DWORDX4 : emit_BUFFER_LOAD_DWORDX(4);
S_BUFFER_LOAD_DWORDX8 : emit_BUFFER_LOAD_DWORDX(8);
S_BUFFER_LOAD_DWORDX16: emit_BUFFER_LOAD_DWORDX(16);
S_LOAD_DWORD:
begin
emit_LOAD_DWORDX(1);
end;
S_LOAD_DWORDX2:
begin
emit_LOAD_DWORDX(2);
end;
S_LOAD_DWORDX4:
begin
emit_LOAD_DWORDX(4);
end;
S_LOAD_DWORDX8:
begin
emit_LOAD_DWORDX(8);
end;
S_LOAD_DWORDX16:
begin
emit_LOAD_DWORDX(16);
end;
S_LOAD_DWORD : emit_LOAD_DWORDX(1);
S_LOAD_DWORDX2 : emit_LOAD_DWORDX(2);
S_LOAD_DWORDX4 : emit_LOAD_DWORDX(4);
S_LOAD_DWORDX8 : emit_LOAD_DWORDX(8);
S_LOAD_DWORDX16: emit_LOAD_DWORDX(16);
else
Assert(false,'SMRD?'+IntToStr(FSPI.SMRD.OP));

View File

@ -7,172 +7,148 @@ interface
uses
sysutils,
ps4_pssl,
srLabel,
srTypes,
srCFGLabel,
srFlow,
srType,
srConst,
srReg,
srLayout,
SprvEmit,
emit_op;
srOpUtils,
emit_fetch;
type
TEmit_SOP1=object(TEmitOp)
procedure _emit_SOP1;
Function _GetFuncPtr(src:PPsrRegSlot):Pointer;
procedure _emit_S_MOV_B32;
procedure _emit_S_MOV_B64;
procedure _emit_S_SWAPPC_B64;
procedure _emit_S_SETPC_B64;
procedure _emit_S_AND_SAVEEXEC_B64;
procedure _emit_S_WQM_B64;
TEmit_SOP1=class(TEmitFetch)
procedure emit_SOP1;
Function GetFuncPtr(src:PPsrRegNode):Pointer;
procedure emit_S_MOV_B32;
procedure emit_S_MOV_B64;
procedure emit_S_SWAPPC_B64;
procedure emit_S_SETPC_B64;
procedure emit_S_AND_SAVEEXEC_B64;
procedure emit_S_WQM_B64;
end;
implementation
Function TEmit_SOP1._GetFuncPtr(src:PPsrRegSlot):Pointer;
Function TEmit_SOP1.GetFuncPtr(src:PPsrRegNode):Pointer;
var
chain:TsrChains;
pConst:array[0..1] of PsrConst;
pLayout:PsrDataLayout;
begin
Result:=nil;
chain:=Default(TsrChains);
chain[0]:=GetChainRegNode(src[0]^.current);
chain[1]:=GetChainRegNode(src[1]^.current);
src[0]:=RegDown(src[0]);
src[1]:=RegDown(src[1]);
pLayout:=FDataLayouts.Grouping(chain,rtFunPtr2);
Result:=pLayout^.pData;
Assert(src[0]<>nil);
Assert(src[1]<>nil);
if (src[0]^.is_const) and (src[1]^.is_const) then
begin
pConst[0]:=src[0]^.AsConst;
pConst[1]:=src[1]^.AsConst;
QWORD(Result):=QWORD(pConst[0]^.AsUint32) or (QWORD(pConst[1]^.AsUint32) shl 32);
end else
begin
chain:=Default(TsrChains);
chain[0]:=GetChainRegNode(src[0]);
chain[1]:=GetChainRegNode(src[1]);
pLayout:=DataLayoutList.Grouping(chain,rtFunPtr2);
Result:=pLayout^.pData;
end;
Assert(Result<>nil);
end;
procedure TEmit_SOP1._emit_S_MOV_B32;
procedure TEmit_SOP1.emit_S_MOV_B32;
Var
dst:PsrRegSlot;
src:PsrRegNode;
begin
dst:=FRegsStory.get_sdst7(FSPI.SOP1.SDST);
dst:=get_sdst7(FSPI.SOP1.SDST);
src:=fetch_ssrc9(FSPI.SOP1.SSRC,dtUnknow);
_MakeCopy(dst,src);
MakeCopy(dst,src);
end;
procedure TEmit_SOP1._emit_S_MOV_B64;
procedure TEmit_SOP1.emit_S_MOV_B64;
Var
dst:array[0..1] of PsrRegSlot;
src:array[0..1] of PsrRegNode;
begin
dst[0]:=FRegsStory.get_sdst7(FSPI.SOP1.SDST+0);
dst[1]:=FRegsStory.get_sdst7(FSPI.SOP1.SDST+1);
dst[0]:=get_sdst7(FSPI.SOP1.SDST+0);
dst[1]:=get_sdst7(FSPI.SOP1.SDST+1);
src[0]:=fetch_ssrc9(FSPI.SOP1.SSRC+0,dtUnknow);
src[1]:=fetch_ssrc9(FSPI.SOP1.SSRC+1,dtUnknow);
_MakeCopy(dst[0],src[0]);
_MakeCopy(dst[1],src[1]);
MakeCopy(dst[0],src[0]);
MakeCopy(dst[1],src[1]);
end;
procedure TEmit_SOP1._emit_S_SWAPPC_B64;
procedure TEmit_SOP1.emit_S_SWAPPC_B64;
Var
dst:array[0..1] of PsrRegSlot;
src:array[0..1] of PsrRegSlot;
src:array[0..1] of PsrRegNode;
oldptr,newptr:Pointer;
begin
if not FRegsStory.get_sdst7_pair(FSPI.SOP1.SDST,@dst) then Assert(false);
if not get_sdst7_pair(FSPI.SOP1.SDST,@dst) then Assert(false);
Assert(not is_const_ssrc9(FSPI.SOP1.SSRC));
if not fetch_ssrc9_pair(FSPI.SOP1.SSRC,@src,dtUnknow) then Assert(false);
if not FRegsStory.get_ssrc9_pair(FSPI.SOP1.SSRC,@src) then Assert(false);
newptr:=GetFuncPtr(@src);
newptr:=_GetFuncPtr(@src);
Assert(newptr<>nil);
oldptr:=GetPtr;
oldptr:=FCursor.Adr.get_pc;
SetConst(dst[0],dtUint32,{%H-}QWORD(oldptr));
SetConst(dst[1],dtUint32,{%H-}QWORD(oldptr) shr 32);
SetConst_q(dst[0],dtUint32,QWORD(oldptr));
SetConst_q(dst[1],dtUint32,QWORD(oldptr) shr 32);
SetPtr(newptr,btSetpc);
end;
procedure TEmit_SOP1._emit_S_SETPC_B64;
procedure TEmit_SOP1.emit_S_SETPC_B64;
Var
src:array[0..1] of PsrRegSlot;
node:array[0..1] of PsrRegNode;
pConst:array[0..1] of PsrConst;
src:array[0..1] of PsrRegNode;
newptr:Pointer;
begin
Assert(not is_const_ssrc9(FSPI.SOP1.SSRC));
if not FRegsStory.get_ssrc9_pair(FSPI.SOP1.SSRC,@src) then Assert(false);
if not fetch_ssrc9_pair(FSPI.SOP1.SSRC,@src,dtUnknow) then Assert(false);
node[0]:=RegDown(src[0]^.current);
node[1]:=RegDown(src[1]^.current);
Assert(node[0]<>nil);
Assert(node[1]<>nil);
if (node[0]^.is_const) and (node[1]^.is_const) then
begin
//ret of func
pConst[0]:=node[0]^.AsConst;
pConst[1]:=node[1]^.AsConst;
{%H-}QWORD(newptr):=QWORD(pConst[0]^.AsUint) or (QWORD(pConst[1]^.AsUint) shl 32);
SetPtr(newptr,btMain);
end else
begin
Assert(false);
end;
newptr:=GetFuncPtr(@src);
SetPtr(newptr,btMain);
end;
procedure TEmit_SOP1._emit_S_AND_SAVEEXEC_B64; //sdst.du = EXEC;| EXEC = (ssrc.du & EXEC);| SCC = (sdst != 0)
procedure TEmit_SOP1.emit_S_AND_SAVEEXEC_B64; //sdst.du = EXEC;| EXEC = (ssrc.du & EXEC);| SCC = (sdst != 0)
Var
dst:array[0..1] of PsrRegSlot;
src:array[0..1] of PsrRegNode;
exc:array[0..1] of PsrRegNode;
begin
if not get_sdst7_pair(FSPI.SOP1.SDST,@dst) then Assert(False);
dst[0]:=FRegsStory.get_sdst7(FSPI.SOP1.SDST+0);
dst[1]:=FRegsStory.get_sdst7(FSPI.SOP1.SDST+1);
if not fetch_ssrc9_pair(FSPI.SOP1.SSRC,@src,dtUnknow) then Assert(False); //ssrc8
Assert(dst[0]<>nil);
Assert(dst[1]<>nil);
if not fetch_ssrc9_pair(@src,FSPI.SOP1.SSRC,dtUnknow) then Assert(False); //ssrc8
PrepTypeSlot(@FRegsStory.EXEC[0],dtUnknow);
PrepTypeSlot(@FRegsStory.EXEC[1],dtUnknow);
exc[0]:=FRegsStory.EXEC[0].current;
exc[1]:=FRegsStory.EXEC[1].current;
exc[0]:=MakeRead(get_exec0,dtUnknow);
exc[1]:=MakeRead(get_exec1,dtUnknow);
MakeCopy(dst[0],exc[0]);
MakeCopy(dst[1],exc[1]);
exc[0]^.mark_read;
exc[1]^.mark_read;
emit_OpBitwiseAnd(@FRegsStory.EXEC[0],src[0],exc[0]);
emit_OpBitwiseAnd(@FRegsStory.EXEC[1],src[1],exc[1]);
OpBitwiseAnd(get_exec0,src[0],exc[0]);
OpBitwiseAnd(get_exec1,src[1],exc[1]);
//SCC = ((exc[0] != 0) or ((exc[1] != 0))
exc[0]^.mark_read;
exc[1]^.mark_read;
emit_OpLogicalOr(@FRegsStory.SCC,exc[0],exc[1]); //implict cast (int != 0)
OpLogicalOr(get_scc,exc[0],exc[1]); //implict cast (int != 0)
//SCC = (sdst != 0) SCC = ((exc[0] != 0) or ((exc[1] != 0))
end;
procedure TEmit_SOP1._emit_S_WQM_B64;
procedure TEmit_SOP1.emit_S_WQM_B64;
Var
dst:array[0..1] of PsrRegSlot;
src:array[0..1] of PsrRegNode;
@ -184,51 +160,24 @@ begin
//dst[63:60].du = (ssrc[63:60].du != 0) ? 0xF : 0
//if (ssrc[3:0].du != 0) then dst[63:60].du=0xF else dst[63:60].du=0
dst[0]:=FRegsStory.get_sdst7(FSPI.SOP1.SDST+0);
dst[1]:=FRegsStory.get_sdst7(FSPI.SOP1.SDST+1);
if not get_sdst7_pair(FSPI.SOP1.SDST,@dst) then Assert(False);
Assert(dst[0]<>nil);
Assert(dst[1]<>nil);
if not fetch_ssrc9_pair(FSPI.SOP1.SSRC,@src,dtUnknow) then Assert(False); //ssrc8
if not fetch_ssrc9_pair(@src,FSPI.SOP1.SSRC,dtUnknow) then Assert(False); //ssrc8
emit_WQM_32(dst[0],src[0]);
emit_WQM_32(dst[1],src[1]);
OpWQM32(dst[0],src[0]);
OpWQM32(dst[1],src[1]);
end;
procedure TEmit_SOP1._emit_SOP1;
procedure TEmit_SOP1.emit_SOP1;
begin
Case FSPI.SOP1.OP of
S_MOV_B32:
begin
_emit_S_MOV_B32;
end;
S_MOV_B64:
begin
_emit_S_MOV_B64;
end;
S_WQM_B64:
begin
_emit_S_WQM_B64;
end;
S_SWAPPC_B64:
begin
_emit_S_SWAPPC_B64;
end;
S_SETPC_B64:
begin
_emit_S_SETPC_B64;
end;
S_AND_SAVEEXEC_B64:
begin
_emit_S_AND_SAVEEXEC_B64;
end;
S_MOV_B32 : emit_S_MOV_B32;
S_MOV_B64 : emit_S_MOV_B64;
S_WQM_B64 : emit_S_WQM_B64;
S_SWAPPC_B64 : emit_S_SWAPPC_B64;
S_SETPC_B64 : emit_S_SETPC_B64;
S_AND_SAVEEXEC_B64: emit_S_AND_SAVEEXEC_B64;
else
Assert(false,'SOP1?'+IntToStr(FSPI.SOP1.OP));

View File

@ -6,359 +6,276 @@ interface
uses
sysutils,
spirv,
ps4_pssl,
srTypes,
srConst,
srType,
srReg,
SprvEmit,
emit_op;
emit_fetch;
type
TEmit_SOP2=object(TEmitOp)
procedure _emit_SOP2;
procedure _emit_S_ADD_I32;
procedure _emit_S_MUL_I32;
procedure _emit_S_LSHL_B32;
procedure _emit_S_LSHR_B32;
procedure _emit_S_AND_B32;
procedure _emit_S_AND_B64;
procedure _emit_S_ANDN2_B64;
procedure _emit_S_OR_B64;
procedure _emit_S_NOR_B64;
procedure _emit_S_CSELECT_B32;
procedure _emit_S_CSELECT_B64;
procedure _emit_S_BFE_U32;
TEmit_SOP2=class(TEmitFetch)
procedure emit_SOP2;
procedure emit_S_ADD_I32;
procedure emit_S_MUL_I32;
procedure OpISccNotZero(src:PsrRegNode);
procedure emit_S_LSHL_B32;
procedure emit_S_LSHR_B32;
procedure emit_S_AND_B32;
procedure emit_S_AND_B64;
procedure emit_S_ANDN2_B64;
procedure emit_S_OR_B64;
procedure emit_S_NOR_B64;
procedure emit_S_CSELECT_B32;
procedure emit_S_CSELECT_B64;
procedure emit_S_BFE_U32;
end;
implementation
procedure TEmit_SOP2._emit_S_ADD_I32;
procedure TEmit_SOP2.emit_S_ADD_I32;
Var
dst,car:PsrRegSlot;
src:array[0..1] of PsrRegNode;
begin
dst:=FRegsStory.get_sdst7(FSPI.SOP2.SDST);
car:=@FRegsStory.SCC;
dst:=get_sdst7(FSPI.SOP2.SDST);
car:=get_scc;
src[0]:=fetch_ssrc9(FSPI.SOP2.SSRC0,dtInt32);
src[1]:=fetch_ssrc9(FSPI.SOP2.SSRC1,dtInt32);
emit_OpIAddExt(dst,car,src[0],src[1]);
OpIAddExt(dst,car,src[0],src[1]);
end;
procedure TEmit_SOP2._emit_S_MUL_I32;
procedure TEmit_SOP2.emit_S_MUL_I32;
Var
dst:PsrRegSlot;
src:array[0..1] of PsrRegNode;
begin
dst:=FRegsStory.get_sdst7(FSPI.SOP2.SDST);
dst:=get_sdst7(FSPI.SOP2.SDST);
src[0]:=fetch_ssrc9(FSPI.SOP2.SSRC0,dtInt32);
src[1]:=fetch_ssrc9(FSPI.SOP2.SSRC1,dtInt32);
emit_OpIMul(dst,src[0],src[1]);
OpIMul(dst,src[0],src[1]);
end;
procedure TEmit_SOP2._emit_S_LSHL_B32; //SCC = (sdst.u != 0)
Var
dst,tmp:PsrRegSlot;
src:array[0..2] of PsrRegNode;
procedure TEmit_SOP2.OpISccNotZero(src:PsrRegNode); //SCC = (sdst.u != 0)
begin
dst:=FRegsStory.get_sdst7(FSPI.SOP2.SDST);
tmp:=@FRegsStory.FUnattach;
src[0]:=fetch_ssrc9(FSPI.SOP2.SSRC0,dtUInt32);
src[1]:=fetch_ssrc9(FSPI.SOP2.SSRC1,dtUInt32);
src[2]:=FetchReg(FConsts.Fetch(dtUInt32,31));
emit_OpBitwiseAnd(tmp,src[1],src[2]);
src[1]:=MakeRead(tmp,dtUInt32);
emit_OpShl(dst,src[0],src[1]);
//dst = dtUint32
tmp:=@FRegsStory.SCC;
MakeCopy(tmp,dst^.current);
tmp^.current^.dtype:=dtBool;
//dst^.current^.mark_read;
//emit_IntToBool(line,FRegsStory.SCC.New(dtBool),dst^.current);
MakeCopy(get_scc,src);
get_scc^.current^.dtype:=dtBool; //implict cast (int != 0)
end;
procedure TEmit_SOP2._emit_S_LSHR_B32; //SCC = (sdst.u != 0)
procedure TEmit_SOP2.emit_S_LSHL_B32;
Var
dst,tmp:PsrRegSlot;
src:array[0..2] of PsrRegNode;
begin
dst:=FRegsStory.get_sdst7(FSPI.SOP2.SDST);
tmp:=@FRegsStory.FUnattach;
src[0]:=fetch_ssrc9(FSPI.SOP2.SSRC0,dtUInt32);
src[1]:=fetch_ssrc9(FSPI.SOP2.SSRC1,dtUInt32);
src[2]:=FetchReg(FConsts.Fetch(dtUInt32,31));
emit_OpBitwiseAnd(tmp,src[1],src[2]);
src[1]:=MakeRead(tmp,dtUInt32);
emit_OpShr(dst,src[0],src[1]);
tmp:=@FRegsStory.SCC;
MakeCopy(tmp,dst^.current);
tmp^.current^.dtype:=dtBool;
end;
procedure TEmit_SOP2._emit_S_AND_B32; //SCC = (sdst.u != 0)
Var
dst,tmp:PsrRegSlot;
dst:PsrRegSlot;
src:array[0..1] of PsrRegNode;
begin
dst:=FRegsStory.get_sdst7(FSPI.SOP2.SDST);
dst:=get_sdst7(FSPI.SOP2.SDST);
src[0]:=fetch_ssrc9(FSPI.SOP2.SSRC0,dtUInt32);
src[1]:=fetch_ssrc9(FSPI.SOP2.SSRC1,dtUInt32);
emit_OpBitwiseAnd(dst,src[0],src[1]);
src[1]:=OpBitwiseAndTo(src[1],31);
src[1]^.PrepType(ord(dtUInt32));
tmp:=@FRegsStory.SCC;
MakeCopy(tmp,dst^.current);
tmp^.current^.dtype:=dtBool;
Op2(Op.OpShiftLeftLogical,src[0]^.dtype,dst,src[0],src[1]);
OpISccNotZero(dst^.current); //SCC = (sdst.u != 0)
end;
procedure TEmit_SOP2._emit_S_AND_B64; //SCC = (sdst[2] != 0)
procedure TEmit_SOP2.emit_S_LSHR_B32;
Var
dst:PsrRegSlot;
src:array[0..1] of PsrRegNode;
begin
dst:=get_sdst7(FSPI.SOP2.SDST);
src[0]:=fetch_ssrc9(FSPI.SOP2.SSRC0,dtUInt32);
src[1]:=fetch_ssrc9(FSPI.SOP2.SSRC1,dtUInt32);
src[1]:=OpBitwiseAndTo(src[1],31);
src[1]^.PrepType(ord(dtUInt32));
Op2(Op.OpShiftRightLogical,src[0]^.dtype,dst,src[0],src[1]);
OpISccNotZero(dst^.current); //SCC = (sdst.u != 0)
end;
procedure TEmit_SOP2.emit_S_AND_B32;
Var
dst:PsrRegSlot;
src:array[0..1] of PsrRegNode;
begin
dst:=get_sdst7(FSPI.SOP2.SDST);
src[0]:=fetch_ssrc9(FSPI.SOP2.SSRC0,dtUInt32);
src[1]:=fetch_ssrc9(FSPI.SOP2.SSRC1,dtUInt32);
OpBitwiseAnd(dst,src[0],src[1]);
OpISccNotZero(dst^.current); //SCC = (sdst.u != 0)
end;
procedure TEmit_SOP2.emit_S_AND_B64; //SCC = (sdst[2] != 0)
Var
dst:array[0..1] of PsrRegSlot;
src0,src1,src2:array[0..1] of PsrRegNode;
begin
if not FRegsStory.get_sdst7_pair(FSPI.SOP2.SDST,@dst) then Assert(False);
if not get_sdst7_pair(FSPI.SOP2.SDST,@dst) then Assert(False);
if not fetch_ssrc9_pair(@src0,FSPI.SOP2.SSRC0,dtUInt32) then Assert(False);
if not fetch_ssrc9_pair(@src1,FSPI.SOP2.SSRC1,dtUInt32) then Assert(False);
if not fetch_ssrc9_pair(FSPI.SOP2.SSRC0,@src0,dtUInt32) then Assert(False);
if not fetch_ssrc9_pair(FSPI.SOP2.SSRC1,@src1,dtUInt32) then Assert(False);
emit_OpBitwiseAnd(dst[0],src0[0],src1[0]);
emit_OpBitwiseAnd(dst[1],src0[1],src1[1]);
OpBitwiseAnd(dst[0],src0[0],src1[0]);
OpBitwiseAnd(dst[1],src0[1],src1[1]);
src2[0]:=dst[0]^.current;
src2[1]:=dst[1]^.current;
src2[0]^.mark_read;
src2[1]^.mark_read;
emit_OpLogicalOr(@FRegsStory.SCC,src2[0],src2[1]); //implict cast (int != 0)
OpLogicalOr(get_scc,src2[0],src2[1]); //implict cast (int != 0)
end;
procedure TEmit_SOP2._emit_S_ANDN2_B64; //SCC = (sdst[2] != 0)
Var
dst:array[0..1] of PsrRegSlot;
tmp:PsrRegSlot;
src0,src1,src2:array[0..1] of PsrRegNode;
begin
if not FRegsStory.get_sdst7_pair(FSPI.SOP2.SDST,@dst) then Assert(False);
if not fetch_ssrc9_pair(@src0,FSPI.SOP2.SSRC0,dtUInt32) then Assert(False);
if not fetch_ssrc9_pair(@src1,FSPI.SOP2.SSRC1,dtUInt32) then Assert(False);
tmp:=@FRegsStory.FUnattach;
emit_OpNot(tmp,src1[0]);
src1[0]:=MakeRead(tmp,dtUnknow);
emit_OpNot(tmp,src1[1]);
src1[1]:=MakeRead(tmp,dtUnknow);
emit_OpBitwiseAnd(dst[0],src0[0],src1[0]);
emit_OpBitwiseAnd(dst[1],src0[1],src1[1]);
src2[0]:=dst[0]^.current;
src2[1]:=dst[1]^.current;
src2[0]^.mark_read;
src2[1]^.mark_read;
emit_OpLogicalOr(@FRegsStory.SCC,src2[0],src2[1]); //implict cast (int != 0)
end;
procedure TEmit_SOP2._emit_S_OR_B64; //SCC = (sdst[2] != 0)
procedure TEmit_SOP2.emit_S_ANDN2_B64; //SCC = (sdst[2] != 0)
Var
dst:array[0..1] of PsrRegSlot;
src0,src1,src2:array[0..1] of PsrRegNode;
begin
if not FRegsStory.get_sdst7_pair(FSPI.SOP2.SDST,@dst) then Assert(False);
if not get_sdst7_pair(FSPI.SOP2.SDST,@dst) then Assert(False);
if not fetch_ssrc9_pair(@src0,FSPI.SOP2.SSRC0,dtUInt32) then Assert(False);
if not fetch_ssrc9_pair(@src1,FSPI.SOP2.SSRC1,dtUInt32) then Assert(False);
if not fetch_ssrc9_pair(FSPI.SOP2.SSRC0,@src0,dtUInt32) then Assert(False);
if not fetch_ssrc9_pair(FSPI.SOP2.SSRC1,@src1,dtUInt32) then Assert(False);
emit_OpBitwiseOr(dst[0],src0[0],src1[0]);
emit_OpBitwiseOr(dst[1],src0[1],src1[1]);
src1[0]:=OpNotTo(src1[0]);
src1[1]:=OpNotTo(src1[1]);
OpBitwiseAnd(dst[0],src0[0],src1[0]);
OpBitwiseAnd(dst[1],src0[1],src1[1]);
src2[0]:=dst[0]^.current;
src2[1]:=dst[1]^.current;
src2[0]^.mark_read;
src2[1]^.mark_read;
emit_OpLogicalOr(@FRegsStory.SCC,src2[0],src2[1]); //implict cast (int != 0)
OpLogicalOr(get_scc,src2[0],src2[1]); //implict cast (int != 0)
end;
procedure TEmit_SOP2._emit_S_NOR_B64; //SCC = (sdst[2] != 0)
procedure TEmit_SOP2.emit_S_OR_B64; //SCC = (sdst[2] != 0)
Var
dst:array[0..1] of PsrRegSlot;
src0,src1,src2:array[0..1] of PsrRegNode;
begin
if not FRegsStory.get_sdst7_pair(FSPI.SOP2.SDST,@dst) then Assert(False);
if not get_sdst7_pair(FSPI.SOP2.SDST,@dst) then Assert(False);
if not fetch_ssrc9_pair(@src0,FSPI.SOP2.SSRC0,dtUInt32) then Assert(False);
if not fetch_ssrc9_pair(@src1,FSPI.SOP2.SSRC1,dtUInt32) then Assert(False);
if not fetch_ssrc9_pair(FSPI.SOP2.SSRC0,@src0,dtUInt32) then Assert(False);
if not fetch_ssrc9_pair(FSPI.SOP2.SSRC1,@src1,dtUInt32) then Assert(False);
emit_OpBitwiseOr(dst[0],src0[0],src1[0]);
emit_OpBitwiseOr(dst[1],src0[1],src1[1]);
OpBitwiseOr(dst[0],src0[0],src1[0]);
OpBitwiseOr(dst[1],src0[1],src1[1]);
src2[0]:=dst[0]^.current;
src2[1]:=dst[1]^.current;
src2[0]^.mark_read;
src2[1]^.mark_read;
emit_OpNot(dst[0],src2[0]);
emit_OpNot(dst[1],src2[1]);
src2[0]:=dst[0]^.current;
src2[1]:=dst[1]^.current;
src2[0]^.mark_read;
src2[1]^.mark_read;
emit_OpLogicalOr(@FRegsStory.SCC,src2[0],src2[1]); //implict cast (int != 0)
OpLogicalOr(get_scc,src2[0],src2[1]); //implict cast (int != 0)
end;
procedure TEmit_SOP2._emit_S_CSELECT_B32; //sdst = SCC ? ssrc0 : ssrc1
procedure TEmit_SOP2.emit_S_NOR_B64; //SCC = (sdst[2] != 0)
Var
dst:array[0..1] of PsrRegSlot;
src0,src1,src2:array[0..1] of PsrRegNode;
begin
if not get_sdst7_pair(FSPI.SOP2.SDST,@dst) then Assert(False);
if not fetch_ssrc9_pair(FSPI.SOP2.SSRC0,@src0,dtUInt32) then Assert(False);
if not fetch_ssrc9_pair(FSPI.SOP2.SSRC1,@src1,dtUInt32) then Assert(False);
src2[0]:=OpBitwiseOrTo(src0[0],src1[0]);
src2[1]:=OpBitwiseOrTo(src0[1],src1[1]);
OpNot(dst[0],src2[0]);
OpNot(dst[1],src2[1]);
src2[0]:=dst[0]^.current;
src2[1]:=dst[1]^.current;
OpLogicalOr(get_scc,src2[0],src2[1]); //implict cast (int != 0)
end;
procedure TEmit_SOP2.emit_S_CSELECT_B32; //sdst = SCC ? ssrc0 : ssrc1
Var
dst:PsrRegSlot;
src:array[0..1] of PsrRegNode;
scc:PsrRegNode;
begin
dst:=FRegsStory.get_sdst7(FSPI.SOP2.SDST);
dst:=get_sdst7(FSPI.SOP2.SDST);
src[0]:=fetch_ssrc9(FSPI.SOP2.SSRC0,dtUnknow);
src[1]:=fetch_ssrc9(FSPI.SOP2.SSRC1,dtUnknow);
scc:=MakeRead(@FRegsStory.SCC,dtBool);
scc:=MakeRead(get_scc,dtBool);
emit_OpSelect(dst,src[0],src[1],scc);
OpSelect(dst,src[0],src[1],scc);
end;
procedure TEmit_SOP2._emit_S_CSELECT_B64; //sdst[2] = SCC ? ssrc0[2] : ssrc1[2]
procedure TEmit_SOP2.emit_S_CSELECT_B64; //sdst[2] = SCC ? ssrc0[2] : ssrc1[2]
Var
dst:array[0..1] of PsrRegSlot;
src0,src1:array[0..1] of PsrRegNode;
scc:PsrRegNode;
begin
if not FRegsStory.get_sdst7_pair(FSPI.SOP2.SDST,@dst) then Assert(False);
if not get_sdst7_pair(FSPI.SOP2.SDST,@dst) then Assert(False);
if not fetch_ssrc9_pair(@src0,FSPI.SOP2.SSRC0,dtUnknow) then Assert(False);
if not fetch_ssrc9_pair(@src1,FSPI.SOP2.SSRC1,dtUnknow) then Assert(False);
if not fetch_ssrc9_pair(FSPI.SOP2.SSRC0,@src0,dtUnknow) then Assert(False);
if not fetch_ssrc9_pair(FSPI.SOP2.SSRC1,@src1,dtUnknow) then Assert(False);
scc:=MakeRead(@FRegsStory.SCC,dtBool);
scc^.mark_read;
scc:=MakeRead(get_scc,dtBool);
emit_OpSelect(dst[0],src0[0],src1[0],scc);
emit_OpSelect(dst[1],src0[1],src1[1],scc);
OpSelect(dst[0],src0[0],src1[0],scc);
OpSelect(dst[1],src0[1],src1[1],scc);
end;
//offset = ssrc1[4:0].u and 31
//width = ssrc1[22:16].u shr 16
procedure TEmit_SOP2._emit_S_BFE_U32; //sdst.u = bitFieldExtract(ssrc0); SCC = (sdst.u != 0)
procedure TEmit_SOP2.emit_S_BFE_U32; //sdst.u = bitFieldExtract(ssrc0); SCC = (sdst.u != 0)
Var
dst,tmp:PsrRegSlot;
dst:PsrRegSlot;
src:array[0..1] of PsrRegNode;
num_31,num_16:PsrRegNode;
offset,count:PsrRegNode;
begin
dst:=FRegsStory.get_sdst7(FSPI.SOP2.SDST);
tmp:=@FRegsStory.FUnattach;
dst:=get_sdst7(FSPI.SOP2.SDST);
src[0]:=fetch_ssrc9(FSPI.SOP2.SSRC0,dtUint32);
src[1]:=fetch_ssrc9(FSPI.SOP2.SSRC1,dtUint32);
num_31:=FetchReg(FConsts.Fetch(dtUInt32,31));
offset:=OpBitwiseAndTo(src[1],31);
count :=OpShrTo(src[1],16);
emit_OpBitwiseAnd(tmp,src[1],num_31);
offset:=MakeRead(tmp,dtUInt32);
Op3(Op.OpBitFieldUExtract,dtUInt32,dst,src[0],offset,count);
num_16:=FetchReg(FConsts.Fetch(dtUInt32,16));
src[1]^.mark_read;
emit_OpShr(tmp,src[1],num_16);
count:=MakeRead(tmp,dtUInt32);
emit_OpBfeU(dst,src[0],offset,count);
tmp:=@FRegsStory.SCC;
MakeCopy(tmp,dst^.current);
tmp^.current^.dtype:=dtBool;
OpISccNotZero(dst^.current); //SCC = (sdst.u != 0)
end;
procedure TEmit_SOP2._emit_SOP2;
procedure TEmit_SOP2.emit_SOP2;
begin
Case FSPI.SOP2.OP of
S_ADD_I32:
begin
_emit_S_ADD_I32;
end;
S_ADD_I32: emit_S_ADD_I32;
S_MUL_I32: emit_S_MUL_I32;
S_MUL_I32: //& 0xFFFFFFFF
begin
_emit_S_MUL_I32;
end;
S_LSHL_B32: emit_S_LSHL_B32;
S_LSHR_B32: emit_S_LSHR_B32;
S_LSHL_B32: //SCC = (sdst.u != 0)
begin
_emit_S_LSHL_B32;
end;
S_AND_B32: emit_S_AND_B32;
S_AND_B64: emit_S_AND_B64;
S_LSHR_B32:
begin
_emit_S_LSHR_B32;
end;
S_ANDN2_B64: emit_S_ANDN2_B64;
S_AND_B32:
begin
_emit_S_AND_B32;
end;
S_OR_B64: emit_S_OR_B64;
S_AND_B64:
begin
_emit_S_AND_B64;
end;
S_NOR_B64: emit_S_NOR_B64;
S_ANDN2_B64:
begin
_emit_S_ANDN2_B64;
end;
S_CSELECT_B32: emit_S_CSELECT_B32;
S_CSELECT_B64: emit_S_CSELECT_B64;
S_OR_B64:
begin
_emit_S_OR_B64;
end;
S_NOR_B64:
begin
_emit_S_NOR_B64;
end;
S_CSELECT_B32:
begin
_emit_S_CSELECT_B32;
end;
S_CSELECT_B64:
begin
_emit_S_CSELECT_B64;
end;
S_BFE_U32:
begin
_emit_S_BFE_U32;
end;
S_BFE_U32: emit_S_BFE_U32;
else
Assert(False,'SOP2?'+IntToStr(FSPI.SOP2.OP));

View File

@ -8,48 +8,47 @@ uses
sysutils,
spirv,
ps4_pssl,
srTypes,
srType,
srReg,
SprvEmit,
emit_op;
emit_fetch;
type
TEmit_SOPC=object(TEmitOp)
procedure _emit_SOPC;
procedure _emit_S_CMP_32(OpId:DWORD;rtype:TsrDataType);
TEmit_SOPC=class(TEmitFetch)
procedure emit_SOPC;
procedure emit_S_CMP_32(OpId:DWORD;rtype:TsrDataType);
end;
implementation
procedure TEmit_SOPC._emit_S_CMP_32(OpId:DWORD;rtype:TsrDataType);
procedure TEmit_SOPC.emit_S_CMP_32(OpId:DWORD;rtype:TsrDataType);
Var
dst:PsrRegSlot;
src:array[0..1] of PsrRegNode;
begin
dst:=@FRegsStory.SCC;
dst:=get_scc;
src[0]:=fetch_ssrc9(FSPI.SOPC.SSRC0,rtype);
src[1]:=fetch_ssrc9(FSPI.SOPC.SSRC1,rtype);
emit_OpCmpS(OpId,dst,src[0],src[1]);
OpCmpS(OpId,dst,src[0],src[1]);
end;
procedure TEmit_SOPC._emit_SOPC;
procedure TEmit_SOPC.emit_SOPC;
begin
Case FSPI.SOPC.OP of
S_CMP_EQ_I32 :_emit_S_CMP_32(Op.OpIEqual ,dtInt32);
S_CMP_LG_I32 :_emit_S_CMP_32(Op.OpINotEqual ,dtInt32);
S_CMP_GT_I32 :_emit_S_CMP_32(Op.OpSGreaterThan ,dtInt32);
S_CMP_GE_I32 :_emit_S_CMP_32(Op.OpSGreaterThanEqual,dtInt32);
S_CMP_LT_I32 :_emit_S_CMP_32(Op.OpSLessThan ,dtInt32);
S_CMP_LE_I32 :_emit_S_CMP_32(Op.OpSLessThanEqual ,dtInt32);
S_CMP_EQ_I32 :emit_S_CMP_32(Op.OpIEqual ,dtInt32);
S_CMP_LG_I32 :emit_S_CMP_32(Op.OpINotEqual ,dtInt32);
S_CMP_GT_I32 :emit_S_CMP_32(Op.OpSGreaterThan ,dtInt32);
S_CMP_GE_I32 :emit_S_CMP_32(Op.OpSGreaterThanEqual,dtInt32);
S_CMP_LT_I32 :emit_S_CMP_32(Op.OpSLessThan ,dtInt32);
S_CMP_LE_I32 :emit_S_CMP_32(Op.OpSLessThanEqual ,dtInt32);
S_CMP_EQ_U32 :_emit_S_CMP_32(Op.OpIEqual ,dtUint32);
S_CMP_LG_U32 :_emit_S_CMP_32(Op.OpINotEqual ,dtUint32);
S_CMP_GT_U32 :_emit_S_CMP_32(Op.OpUGreaterThan ,dtUint32);
S_CMP_GE_U32 :_emit_S_CMP_32(Op.OpUGreaterThanEqual,dtUint32);
S_CMP_LT_U32 :_emit_S_CMP_32(Op.OpULessThan ,dtUint32);
S_CMP_LE_U32 :_emit_S_CMP_32(Op.OpULessThanEqual ,dtUint32);
S_CMP_EQ_U32 :emit_S_CMP_32(Op.OpIEqual ,dtUint32);
S_CMP_LG_U32 :emit_S_CMP_32(Op.OpINotEqual ,dtUint32);
S_CMP_GT_U32 :emit_S_CMP_32(Op.OpUGreaterThan ,dtUint32);
S_CMP_GE_U32 :emit_S_CMP_32(Op.OpUGreaterThanEqual,dtUint32);
S_CMP_LT_U32 :emit_S_CMP_32(Op.OpULessThan ,dtUint32);
S_CMP_LE_U32 :emit_S_CMP_32(Op.OpULessThanEqual ,dtUint32);
//S_BITCMP0_B32:;
//S_BITCMP1_B32:;

View File

@ -7,39 +7,32 @@ interface
uses
sysutils,
ps4_pssl,
srTypes,
srConst,
srType,
srReg,
SprvEmit,
emit_op;
emit_fetch;
type
TEmit_SOPK=object(TEmitOp)
procedure _emit_SOPK;
procedure _emit_S_MOVK_I32;
TEmit_SOPK=class(TEmitFetch)
procedure emit_SOPK;
procedure emit_S_MOVK_I32;
end;
implementation
procedure TEmit_SOPK._emit_S_MOVK_I32;
procedure TEmit_SOPK.emit_S_MOVK_I32;
Var
dst:PsrRegSlot;
src:PsrRegNode;
begin
dst:=FRegsStory.get_sdst7(FSPI.SOPK.SDST);
src:=FetchReg(FConsts.Fetchi(dtInt32,SmallInt(FSPI.SOPK.SIMM)));
_MakeCopy(dst,src);
dst:=get_sdst7(FSPI.SOPK.SDST);
SetConst_i(dst,dtInt32,SmallInt(FSPI.SOPK.SIMM));
end;
procedure TEmit_SOPK._emit_SOPK;
procedure TEmit_SOPK.emit_SOPK;
begin
Case FSPI.SOPK.OP of
S_MOVK_I32:
begin
_emit_S_MOVK_I32;
end;
S_MOVK_I32: emit_S_MOVK_I32;
else
Assert(false,'SOPK?'+IntToStr(FSPI.SOPK.OP));

View File

@ -7,22 +7,23 @@ interface
uses
sysutils,
ps4_pssl,
srTypes,
srParser,
srLabel,
srCFG,
srType,
srCFGParser,
srCFGLabel,
srCFGCursor,
srFlow,
srReg,
srOp,
srOpUtils,
spirv,
SprvEmit,
emit_op;
emit_fetch;
type
TEmit_SOPP=object(TEmitOp)
procedure _emit_SOPP;
procedure _emit_S_BRANCH_COND(pSlot:PsrRegSlot;n:Boolean);
procedure _emit_S_BRANCH;
TEmit_SOPP=class(TEmitFetch)
procedure emit_SOPP;
procedure emit_S_BRANCH_COND(pSlot:PsrRegSlot;n:Boolean);
procedure emit_S_BRANCH;
procedure mark_end_of;
function IsBegLoop(Adr:TSrcAdr):Boolean;
function IsEndLoop(Adr:TSrcAdr):Boolean;
function IsUnknow(Adr:TSrcAdr):Boolean;
@ -35,9 +36,6 @@ type
implementation
uses
srVolatile;
procedure TEmit_SOPP.emit_cond_block(pSlot:PsrRegSlot;n:Boolean;adr:TSrcAdr);
var
src:PsrRegNode;
@ -49,11 +47,11 @@ var
begin
src:=MakeRead(pSlot,dtBool); //get before OpBranchConditional
pOpLabel[0]:=NewLabelOp;
pOpLabel[1]:=NewLabelOp;
pOpLabel[0]:=NewLabelOp(False);
pOpLabel[1]:=NewLabelOp(False);
pLBlock:=FCursor.pCode^.FTop.DownBlock(adr);
Assert(pLBlock<>@FCursor.pCode^.FTop,'not found');
pLBlock:=Cursor.pCode^.FTop.DownBlock(adr);
Assert(pLBlock<>@Cursor.pCode^.FTop,'not found');
Info[0]:=Default(TsrBlockInfo);
Info[1]:=Default(TsrBlockInfo);
@ -61,8 +59,8 @@ begin
Case pLBlock^.bType of
btAdr: //set new adr
begin
Info[0].b_adr:=FCursor.Adr;
Info[0].e_adr:=FCursor.Adr;
Info[0].b_adr:=Cursor.Adr;
Info[0].e_adr:=Cursor.Adr;
Info[0].bType:=btCond;
//
Info[1].b_adr:=pLBlock^.pBLabel^.Adr;
@ -86,18 +84,18 @@ begin
pOpLabel[0]^.Adr:=Info[0].b_adr;
pOpLabel[1]^.Adr:=Info[0].e_adr;
pOpBlock:=NewBlockOp(FRegsStory.get_snapshot);
pOpBlock:=NewBlockOp(get_snapshot);
pOpBlock^.SetLabels(pOpLabel[0],pOpLabel[1],nil);
pOpBlock^.SetInfo(Info[0]);
pOpBlock^.SetCond(src,not n);
PushBlockOp(line,pOpBlock,pLBlock);
emit_OpCondMerge(line,pOpLabel[1]);
OpCondMerge(line,pOpLabel[1]);
Case n of
True :emit_OpBranchCond(line,pOpLabel[1],pOpLabel[0],src);
False:emit_OpBranchCond(line,pOpLabel[0],pOpLabel[1],src);
True :OpBranchCond(line,pOpLabel[1],pOpLabel[0],src);
False:OpBranchCond(line,pOpLabel[0],pOpLabel[1],src);
end;
AddSpirvOp(line,pOpLabel[0]);
@ -117,57 +115,56 @@ procedure TEmit_SOPP.UpBuildVol(last:PsrOpBlock);
var
node:PsrOpBlock;
begin
node:=FMain^.pBlock;
node:=Main^.pBlock;
While (node<>nil) do
begin
Case node^.Block.bType of
btCond:TEmitVolatile(Self).build_volatile_cur(node^.Regs.pSnap);
btLoop:TEmitVolatile(Self).build_volatile_old(node^.Regs.pSnap);
btCond:PrivateList.build_volatile_cur(node^.Regs.pSnap);
btLoop:PrivateList.build_volatile_old(node^.Regs.pSnap);
else;
end;
if (node=last) then Break;
node:=node^.pParent;
node:=node^.Parent;
end;
end;
procedure TEmit_SOPP.emit_loop(adr:TSrcAdr);
var
node,pOpBlock:PsrOpBlock;
pOpLabel:array[0..1] of PspirvOp;
pOpLabel:PspirvOp;
FVolMark:TsrVolMark;
bnew:Boolean;
begin
node:=FMain^.pBlock;
node:=Main^.pBlock;
pOpBlock:=node^.FindUpLoop;
Assert(pOpBlock<>nil,'not found');
pOpLabel[0]:=nil;
pOpLabel:=nil;
FVolMark:=vmNone;
if (pOpBlock^.Block.b_adr.get_pc=adr.get_pc) then //is continue?
begin
pOpLabel[0]:=pOpBlock^.Labels.pMrgOp; //-> OpLoopMerge end -> OpLoopMerge before
pOpLabel:=pOpBlock^.Labels.pMrgOp; //-> OpLoopMerge end -> OpLoopMerge before
pOpBlock^.Cond.FUseCont:=True;
FVolMark:=vmCont;
end else
if (pOpBlock^.Block.b_adr.get_pc=adr.get_pc) then //is break?
begin
pOpLabel[0]:=pOpBlock^.Labels.pEndOp;
pOpLabel:=pOpBlock^.Labels.pEndOp;
FVolMark:=vmBreak;
end else
begin
Assert(false,'emit_loop');
end;
Assert(pOpLabel[0]<>nil);
Assert(pOpLabel<>nil);
bnew:=true;
if FCursor.pBlock^.IsEndOf(FCursor.Adr) then //is last
if Cursor.pBlock^.IsEndOf(Cursor.Adr) then //is last
begin
Assert(node^.Block.e_adr.get_pc=FCursor.Adr.get_pc);
Assert(node^.Block.e_adr.get_pc=Cursor.Adr.get_pc);
Case node^.Block.bType of
btSetpc:;
else
@ -180,11 +177,10 @@ begin
UpBuildVol(pOpBlock);
node^.Regs.FVolMark:=FVolMark; //mark end of
emit_OpBranch(line,pOpLabel[0]);
OpBranch(line,pOpLabel);
if bnew then
begin
pOpLabel[1]:=NewLabelOp;
AddSpirvOp(line,pOpLabel[1]);
AddSpirvOp(line,NewLabelOp(True));
end;
end;
@ -197,7 +193,7 @@ var
begin
src:=MakeRead(pSlot,dtBool);
node:=FMain^.pBlock;
node:=Main^.pBlock;
pOpBlock:=node^.FindUpLoop;
Assert(pOpBlock<>nil,'not found');
@ -220,16 +216,16 @@ begin
end;
Assert(pOpLabel[0]<>nil);
pOpLabel[1]:=NewLabelOp;
pOpLabel[1]:=NewLabelOp(False);
UpBuildVol(pOpBlock);
node^.Regs.FVolMark:=FVolMark; //mark end of
emit_OpCondMerge(line,pOpLabel[1]);
OpCondMerge(line,pOpLabel[1]);
Case n of
True :emit_OpBranchCond(line,pOpLabel[0],pOpLabel[1],src);
False:emit_OpBranchCond(line,pOpLabel[1],pOpLabel[0],src);
True :OpBranchCond(line,pOpLabel[0],pOpLabel[1],src);
False:OpBranchCond(line,pOpLabel[1],pOpLabel[0],src);
end;
AddSpirvOp(line,pOpLabel[1]);
@ -240,7 +236,7 @@ var
node:PsrCFGBlock;
begin
Result:=false;
node:=FCursor.pBlock^.FindUpLoop;
node:=Cursor.pBlock^.FindUpLoop;
if (node<>nil) then
begin
Result:=node^.pBLabel^.Adr.get_pc=Adr.get_pc;
@ -252,7 +248,7 @@ var
node:PsrCFGBlock;
begin
Result:=false;
node:=FCursor.pBlock^.FindUpLoop;
node:=Cursor.pBlock^.FindUpLoop;
if (node<>nil) then
begin
Result:=node^.pELabel^.Adr.get_pc=Adr.get_pc;
@ -269,13 +265,12 @@ begin
Result:=pLabel^.IsType(ltUnknow);
end;
procedure TEmit_SOPP._emit_S_BRANCH_COND(pSlot:PsrRegSlot;n:Boolean);
procedure TEmit_SOPP.emit_S_BRANCH_COND(pSlot:PsrRegSlot;n:Boolean);
var
c_adr,b_adr:TSrcAdr;
pLabel:PsrLabel;
begin
c_adr:=FCursor.Adr;
c_adr:=Cursor.Adr;
b_adr:=c_adr;
b_adr.Offdw:=get_branch_offset(FSPI);
@ -293,7 +288,7 @@ begin
emit_loop_cond(pSlot,n,b_adr);
end else
begin //down
if FCursor.pBlock^.IsBigOf(b_adr) then
if Cursor.pBlock^.IsBigOf(b_adr) then
begin //break?
if not IsEndLoop(b_adr) then Assert(false,'Unknow');
emit_loop_cond(pSlot,n,b_adr);
@ -314,9 +309,9 @@ var
begin
Info:=Default(TsrBlockInfo);
c_adr:=FCursor.Adr; //get current
c_adr:=Cursor.Adr; //get current
SetPtr(adr.get_pc,btAdrBranch); //set new
e_adr:=FCursor.pCode^.FTop.pELabel^.Adr; //get end of code
e_adr:=Cursor.pCode^.FTop.pELabel^.Adr; //get end of code
SetPtr(c_adr.get_pc,btMain); //ret current
Info.b_adr:=adr;
@ -331,12 +326,12 @@ begin
SetPtr(adr.get_pc,btAdrBranch);
end;
procedure TEmit_SOPP._emit_S_BRANCH;
procedure TEmit_SOPP.emit_S_BRANCH;
var
c_adr,b_adr:TSrcAdr;
begin
c_adr:=FCursor.Adr;
c_adr:=Cursor.Adr;
b_adr:=c_adr;
b_adr.Offdw:=get_branch_offset(FSPI);
@ -356,7 +351,12 @@ begin
end;
procedure TEmit_SOPP._emit_SOPP;
procedure TEmit_SOPP.mark_end_of;
begin
Main^.pBlock^.Regs.FVolMark:=vmEnd; //mark end of
end;
procedure TEmit_SOPP.emit_SOPP;
begin
Case FSPI.SOPP.OP of
S_NOP,
@ -368,17 +368,17 @@ begin
begin
AddSpirvOp(Op.OpReturn);
end;
FMain^.pBlock^.Regs.FVolMark:=vmEnd; //mark end of
mark_end_of;
end;
S_CBRANCH_SCC0 :_emit_S_BRANCH_COND(@FRegsStory.SCC,false);
S_CBRANCH_SCC1 :_emit_S_BRANCH_COND(@FRegsStory.SCC,true);
S_CBRANCH_VCCZ :_emit_S_BRANCH_COND(@FRegsStory.VCC[0],false);
S_CBRANCH_VCCNZ :_emit_S_BRANCH_COND(@FRegsStory.VCC[0],true);
S_CBRANCH_EXECZ :_emit_S_BRANCH_COND(@FRegsStory.EXEC[0],false);
S_CBRANCH_EXECNZ:_emit_S_BRANCH_COND(@FRegsStory.EXEC[0],true);
S_CBRANCH_SCC0 :emit_S_BRANCH_COND(get_scc ,false);
S_CBRANCH_SCC1 :emit_S_BRANCH_COND(get_scc ,true);
S_CBRANCH_VCCZ :emit_S_BRANCH_COND(get_vcc0 ,false);
S_CBRANCH_VCCNZ :emit_S_BRANCH_COND(get_vcc0 ,true);
S_CBRANCH_EXECZ :emit_S_BRANCH_COND(get_exec0,false);
S_CBRANCH_EXECNZ:emit_S_BRANCH_COND(get_exec0,true);
S_BRANCH :_emit_S_BRANCH;
S_BRANCH :emit_S_BRANCH;
else
Assert(false,'SOPP?'+IntToStr(FSPI.SOPP.OP));

View File

@ -8,12 +8,12 @@ uses
sysutils,
ps4_shader,
ps4_pssl,
srTypes,
srType,
srConst,
srReg,
srLayout,
SprvEmit,
emit_op,
srConfig,
emit_fetch,
srVBufInfo;
type
@ -30,11 +30,7 @@ type
data:array[0..1] of Pointer;
end;
TEmit_vbuf_chain=object(TEmitOp)
function OpDivTo(pReg:PsrRegNode;i:QWORD):PsrRegNode;
function OpMulTo(pReg:PsrRegNode;i:QWORD):PsrRegNode;
function OpAddTo(pReg:PsrRegNode;i:QWORD):PsrRegNode;
function OpAddTo(pReg0,pReg1:PsrRegNode):PsrRegNode;
TEmit_vbuf_chain=class(TEmitFetch)
procedure get_reg_adr(var adr:TBuf_adr);
function get_sum_ofs(var adr:TBuf_adr):PsrRegNode;
function get_idx_elm(var adr:TBuf_adr):PsrRegNode;
@ -44,76 +40,6 @@ type
implementation
function isPowerOfTwo(x:QWORD):Boolean; inline;
begin
Result:=((x-1) and x)=0;
end;
function fastIntLog2(i:QWORD):QWORD; inline;
begin
Result:=BsfQWORD(i);
end;
function TEmit_vbuf_chain.OpDivTo(pReg:PsrRegNode;i:QWORD):PsrRegNode;
begin
if (pReg=nil) or (i<=1) then Exit(pReg);
Result:=NewReg(pReg^.dtype);
pReg^.mark_read;
if isPowerOfTwo(i) then
begin
i:=fastIntLog2(i);
if (SignType(pReg^.dtype)<>0) then
begin
_emit_OpShrA(line,Result,pReg,FetchReg(FConsts.Fetchi(pReg^.dtype,i)));
end else
begin
_emit_OpShr(line,Result,pReg,FetchReg(FConsts.Fetchi(pReg^.dtype,i)));
end;
end else
begin
if (SignType(pReg^.dtype)<>0) then
begin
_emit_OpSDiv(line,Result,pReg,FetchReg(FConsts.Fetchi(pReg^.dtype,i)));
end else
begin
_emit_OpUDiv(line,Result,pReg,FetchReg(FConsts.Fetchi(pReg^.dtype,i)));
end;
end;
end;
function TEmit_vbuf_chain.OpMulTo(pReg:PsrRegNode;i:QWORD):PsrRegNode;
begin
if (pReg=nil) or (i<=1) then Exit(pReg);
Result:=NewReg(pReg^.dtype);
pReg^.mark_read;
if isPowerOfTwo(i) then
begin
i:=fastIntLog2(i);
_emit_OpShl(line,Result,pReg,FetchReg(FConsts.Fetchi(pReg^.dtype,i)));
end else
begin
_emit_OpIMul(line,Result,pReg,FetchReg(FConsts.Fetchi(pReg^.dtype,i)));
end;
end;
function TEmit_vbuf_chain.OpAddTo(pReg:PsrRegNode;i:QWORD):PsrRegNode;
begin
if (pReg=nil) or (i=0) then Exit(pReg);
Result:=NewReg(pReg^.dtype);
pReg^.mark_read;
_emit_OpIAdd(line,Result,pReg,FetchReg(FConsts.Fetchi(pReg^.dtype,i)));
end;
function TEmit_vbuf_chain.OpAddTo(pReg0,pReg1:PsrRegNode):PsrRegNode;
begin
if (pReg0=nil) then Exit(pReg1);
if (pReg1=nil) then Exit(pReg0);
Result:=NewReg(pReg0^.dtype);
pReg0^.mark_read;
pReg1^.mark_read;
_emit_OpIAdd(line,Result,pReg0,pReg1);
end;
procedure TEmit_vbuf_chain.get_reg_adr(var adr:TBuf_adr);
var
ofs:PsrRegSlot;
@ -123,7 +49,7 @@ begin
adr.soffset:=get_soffset_const_int(FSPI.MUBUF.SOFFSET);
end else
begin
ofs:=FRegsStory.get_ssrc8(FSPI.MUBUF.SOFFSET);
ofs:=get_ssrc8(FSPI.MUBUF.SOFFSET);
if (ofs<>nil) then
begin
adr.sof:=ofs^.current;
@ -131,7 +57,7 @@ begin
begin
if (adr.sof^.is_const) then
begin
adr.soffset:=adr.sof^.AsConst^.AsInt;
adr.soffset:=adr.sof^.AsConst^.AsInt32;
adr.sof:=nil;
end else
begin
@ -147,12 +73,12 @@ begin
adr.idx:=fetch_vsrc8(FSPI.MUBUF.VADDR+0,dtInt32);
if (FSPI.MUBUF.OFFEN=1) then
begin
ofs:=FRegsStory.get_vsrc8(FSPI.MUBUF.VADDR+1);
ofs:=get_vsrc8(FSPI.MUBUF.VADDR+1);
end;
end else
if (FSPI.MUBUF.OFFEN=1) then
begin
ofs:=FRegsStory.get_vsrc8(FSPI.MUBUF.VADDR+0);
ofs:=get_vsrc8(FSPI.MUBUF.VADDR+0);
end;
if (ofs<>nil) then
@ -162,7 +88,7 @@ begin
begin
if (adr.ofs^.is_const) then
begin
adr.voffset:=adr.ofs^.AsConst^.AsInt;
adr.voffset:=adr.ofs^.AsConst^.AsInt32;
adr.ofs:=nil;
end else
begin
@ -190,15 +116,13 @@ begin
//(stride is Align)
//result=(foffset/Align+ofs/Align+idx*(stride/Align)) in elem
adr.ofs^.mark_unread;
ofs_d:=OpDivTo(adr.ofs,adr.align); //ofs/Align
sum_d:=OpAddTo(ofs_d,foffset div adr.align); //foffset/Align+ofs/Align
ofs_d:=OpIDivTo(adr.ofs,adr.align); //ofs/Align
sum_d:=OpIAddTo(ofs_d,foffset div adr.align); //foffset/Align+ofs/Align
if (adr.idx<>nil) then
begin
adr.idx^.mark_unread;
idx_m:=OpMulTo(adr.idx,adr.stride div adr.align); //idx*(stride/Align)
sum_d:=OpAddTo(sum_d,idx_m);
idx_m:=OpIMulTo(adr.idx,adr.stride div adr.align); //idx*(stride/Align)
sum_d:=OpIAddTo(sum_d,idx_m);
end;
end else
@ -206,17 +130,15 @@ begin
//result=(foffset+ofs+idx*stride)/Align in elem
adr.ofs^.mark_unread;
sum_d:=OpAddTo(adr.ofs,foffset); //foffset+ofs
sum_d:=OpIAddTo(adr.ofs,foffset); //foffset+ofs
if (adr.idx<>nil) then
begin
adr.idx^.mark_unread;
idx_m:=OpMulTo(adr.idx,adr.stride); //idx*stride
sum_d:=OpAddTo(sum_d,idx_m);
idx_m:=OpIMulTo(adr.idx,adr.stride); //idx*stride
sum_d:=OpIAddTo(sum_d,idx_m);
end;
sum_d:=OpDivTo(sum_d,adr.align); // sum/Align
sum_d:=OpIDivTo(sum_d,adr.align); // sum/Align
end;
Result:=sum_d;
@ -236,13 +158,11 @@ begin
if (adr.idx=nil) then
begin
sum_d:=FetchReg(FConsts.Fetchi(dtUint32,foffset));
sum_d^.mark_unread;
sum_d:=NewReg_q(dtUint32,foffset);
end else
begin
adr.idx^.mark_unread;
idx_m:=OpMulTo(adr.idx,adr.stride div adr.align); //idx*(stride/Align)
sum_d:=OpAddTo(idx_m,foffset);
idx_m:=OpIMulTo(adr.idx,adr.stride div adr.align); //idx*(stride/Align)
sum_d:=OpIAddTo(idx_m,foffset);
end;
Result:=sum_d;
@ -262,13 +182,11 @@ begin
if (adr.idx=nil) then
begin
sum_d:=FetchReg(FConsts.Fetchi(dtUint32,foffset));
sum_d^.mark_unread;
sum_d:=NewReg_q(dtUint32,foffset);
end else
begin
adr.idx^.mark_unread;
idx_m:=OpMulTo(adr.idx,adr.stride div adr.fsize); //idx*(stride/size)
sum_d:=OpAddTo(idx_m,foffset);
idx_m:=OpIMulTo(adr.idx,adr.stride div adr.fsize); //idx*(stride/size)
sum_d:=OpIAddTo(idx_m,foffset);
end;
Result:=sum_d;
@ -288,7 +206,8 @@ var
sum_d:PsrRegNode;
ext:TsrChainExt;
lvl_0:TsrChainLvl_0;
lvl_1:TsrChainLvl_1;
img:TsrImageInfo;
@ -322,9 +241,11 @@ begin
if (adr.ofs=nil) and (adr.idx=nil) then //simple
begin
Result.vType :=vcChainVector;
Result.data[0]:=info.grp^.Fetch(foffset,adr.csize,nil);
lvl_0.offset:=foffset;
lvl_0.size :=adr.csize;
Result.data[0]:=info.grp^.Fetch(@lvl_0,nil);
Result.vType :=vcChainVector;
Exit;
end;
@ -335,7 +256,7 @@ begin
sum_d:=get_sum_ofs(adr);
//minTexelBufferOffsetAlignment
if FUseTexelBuffer then
if Config.UseTexelBuffer then
if (info.IsComp) and
(adr.stride div adr.align=0) then
begin
@ -350,21 +271,21 @@ begin
Exit;
end;
sum_d^.mark_read;
ext:=Default(TsrChainExt);
ext.pIndex:=sum_d;
ext.stride:=adr.align;
lvl_0.offset:=0;
lvl_0.size :=adr.align;
lvl_1.pIndex:=sum_d;
lvl_1.stride:=adr.align;
Result.data[0]:=info.grp^.Fetch(@lvl_0,@lvl_1);
Result:=Default(TvarChain);
Result.vType :=vcChainElement;
Result.data[0]:=info.grp^.Fetch(0,adr.align,@ext);
Exit;
end else
begin //idx<>nil
//minTexelBufferOffsetAlignment
if FUseTexelBuffer then
if Config.UseTexelBuffer then
if (info.IsComp) and
(adr.stride mod adr.fsize=0) and
(foffset mod adr.fsize=0) then
@ -383,7 +304,7 @@ begin
end;
//minTexelBufferOffsetAlignment
if FUseTexelBuffer then
if Config.UseTexelBuffer then
if (info.IsComp) and
(adr.stride div adr.align=0) then
begin
@ -400,14 +321,15 @@ begin
Exit;
end;
//adr.idx^.mark_read;
ext:=Default(TsrChainExt);
ext.pIndex:=adr.idx;
ext.stride:=adr.stride;
lvl_0.offset:=foffset;
lvl_0.size :=adr.csize;
lvl_1.pIndex:=adr.idx;
lvl_1.stride:=adr.stride;
Result.data[0]:=info.grp^.Fetch(@lvl_0,@lvl_1);
Result.vType :=vcChainVector;
Result.data[0]:=info.grp^.Fetch(foffset,adr.csize,@ext);
Exit;
end;

View File

@ -6,14 +6,11 @@ interface
uses
sysutils,
spirv,
ps4_pssl,
srTypes,
srConst,
srType,
srReg,
srLayout,
SprvEmit,
emit_op,
emit_fetch,
srVBufInfo,
emit_vbuf_chain;
@ -29,21 +26,15 @@ type
elm:array[0..3] of PsrRegNode;
end;
TEmit_vbuf_load=object(TEmitOp)
TEmit_vbuf_load=class(TEmitFetch)
procedure buf_load(info:TBuf_info);
function OpMulF(pReg:PsrRegNode;s:Single):PsrRegNode;
function OpAddF(pReg:PsrRegNode;s:Single):PsrRegNode;
function OpUToF(pReg:PsrRegNode):PsrRegNode;
function OpSToF(pReg:PsrRegNode):PsrRegNode;
function OpShlI(pReg:PsrRegNode;i:DWORD):PsrRegNode;
function OpAddI(pReg:PsrRegNode;i:DWORD):PsrRegNode;
function _convert_e(var lc:Tload_cache;src:PsrRegNode):PsrRegNode;
procedure _make_load_cv_id(var lc:Tload_cache;i:Byte);
procedure _make_load_ce_id(var lc:Tload_cache;i:Byte);
procedure _make_load_uv_id(var lc:Tload_cache;i:Byte);
procedure _make_load_ue_id(var lc:Tload_cache;i:Byte);
procedure _make_load_zero(var lc:Tload_cache);
procedure _make_load_one(var lc:Tload_cache);
function convert_e(var lc:Tload_cache;src:PsrRegNode):PsrRegNode;
procedure make_load_cv_id(var lc:Tload_cache;i:Byte);
procedure make_load_ce_id(var lc:Tload_cache;i:Byte);
procedure make_load_uv_id(var lc:Tload_cache;i:Byte);
procedure make_load_ue_id(var lc:Tload_cache;i:Byte);
procedure make_load_zero(var lc:Tload_cache);
procedure make_load_one(var lc:Tload_cache);
procedure buf_load_cv(info:TBuf_info;v:TvarChain);
end;
@ -53,7 +44,7 @@ procedure TEmit_vbuf_load.buf_load(info:TBuf_info);
var
v:TvarChain;
begin
v:=TEmit_vbuf_chain(Self).get_chain(info);
v:=TEmit_vbuf_chain(TObject(Self)).get_chain(info);
if (v.vType=vcUniformVector) then
begin
@ -64,131 +55,77 @@ begin
buf_load_cv(info,v);
end;
function TEmit_vbuf_load.OpMulF(pReg:PsrRegNode;s:Single):PsrRegNode;
begin
if (pReg=nil) or (s=1) then Exit(pReg);
Result:=NewReg(pReg^.dtype);
pReg^.mark_read;
_emit_Op2(line,Op.OpFMul,Result,pReg,FetchReg(FConsts.Fetchf(dtFloat32,s)));
end;
function TEmit_vbuf_load.OpAddF(pReg:PsrRegNode;s:Single):PsrRegNode;
begin
if (pReg=nil) or (s=0) then Exit(pReg);
Result:=NewReg(pReg^.dtype);
pReg^.mark_read;
_emit_Op2(line,Op.OpFAdd,Result,pReg,FetchReg(FConsts.Fetchf(dtFloat32,s)));
end;
function TEmit_vbuf_load.OpUToF(pReg:PsrRegNode):PsrRegNode;
begin
if (pReg=nil) then Exit(pReg);
Result:=NewReg(dtFloat32);
pReg^.mark_read;
_emit_Op1(line,Op.OpConvertUToF,Result,pReg);
end;
function TEmit_vbuf_load.OpSToF(pReg:PsrRegNode):PsrRegNode;
begin
if (pReg=nil) then Exit(pReg);
Result:=NewReg(dtFloat32);
pReg^.mark_read;
_emit_Op1(line,Op.OpConvertSToF,Result,pReg);
end;
function TEmit_vbuf_load.OpShlI(pReg:PsrRegNode;i:DWORD):PsrRegNode;
begin
if (pReg=nil) or (i=0) then Exit(pReg);
Result:=NewReg(pReg^.dtype);
pReg^.mark_read;
_emit_OpShl(line,Result,pReg,FetchReg(FConsts.Fetchi(dtUint32,i)));
end;
function TEmit_vbuf_load.OpAddI(pReg:PsrRegNode;i:DWORD):PsrRegNode;
begin
if (pReg=nil) or (i=0) then Exit(pReg);
Result:=NewReg(pReg^.dtype);
pReg^.mark_read;
_emit_OpIAdd(line,Result,pReg,FetchReg(FConsts.Fetchi(dtUint32,i)));
end;
function TEmit_vbuf_load._convert_e(var lc:Tload_cache;src:PsrRegNode):PsrRegNode;
function TEmit_vbuf_load.convert_e(var lc:Tload_cache;src:PsrRegNode):PsrRegNode;
begin
Result:=src;
if (lc.elem_resl<>lc.elem_orig) then
Case lc.info.NFMT of
BUF_NUM_FORMAT_UNORM : //Unsigned, normalized to range [0.0..1.0]; data/(1<<nbits-1)
begin
Result:=OpUToF(src);
Result:=OpMulF(Result,1/GetTypeHigh(lc.elem_orig));
Result:=OpUToF(src,dtFloat32);
Result:=OpFMulToS(Result,1/lc.elem_orig.High);
end;
BUF_NUM_FORMAT_SNORM : //Signed, normalized to range [-1.0..1.0]; data/(1<<(nbits-1)-1) clamped
begin
Result:=OpSToF(src);
Result:=OpMulF(Result,1/(GetTypeHigh(lc.elem_orig) shr 1));
Result:=OpAddF(Result,-1);
Result:=OpSToF(src,dtFloat32);
Result:=OpFMulToS(Result,1/(lc.elem_orig.High shr 1));
Result:=OpFAddToS(Result,-1);
end;
BUF_NUM_FORMAT_USCALED : //Unsigned integer to float [0.0 .. (1<<nbits)-1]
begin
Result:=OpUToF(src);
Result:=OpUToF(src,dtFloat32);
end;
BUF_NUM_FORMAT_SSCALED : //Signed integer to float [-(1<<(nbits-1)) ..(1<<(nbits-1))-1]
begin
Result:=OpSToF(src);
Result:=OpSToF(src,dtFloat32);
end;
BUF_NUM_FORMAT_SNORM_NZ: //Signed, normalized to range [-1.0..1.0]; (data*2+1)/(1<<nbits-1)
begin
if (lc.info.GetElemSize=4) then
begin
Result:=OpSToF(src);
Result:=OpMulF(Result,2);
Result:=OpAddF(Result,1);
Result:=OpMulF(Result,1/GetTypeHigh(lc.elem_orig));
Result:=OpSToF(src,dtFloat32);
Result:=OpFMulToS(Result,2);
Result:=OpFAddToS(Result,1);
Result:=OpFMulToS(Result,1/lc.elem_orig.High);
end else
begin
Result:=OpShlI(src,1);
Result:=OpAddI(Result,1);
Result:=OpSToF(Result);
Result:=OpMulF(Result,1/GetTypeHigh(lc.elem_orig));
Result:=OpShlTo(src,1);
Result:=OpIAddTo(Result,1);
Result:=OpSToF(Result,dtFloat32);
Result:=OpFMulToS(Result,1/lc.elem_orig.High);
end;
end;
BUF_NUM_FORMAT_UINT :
begin
Result:=NewReg(lc.elem_resl);
src^.mark_read;
_emit_Op1(line,Op.OpUConvert,Result,src);
Result:=OpUToU(src,lc.elem_resl);
end;
BUF_NUM_FORMAT_SINT :
begin
Result:=NewReg(lc.elem_resl);
src^.mark_read;
_emit_Op1(line,Op.OpSConvert,Result,src);
Result:=OpSToS(src,lc.elem_resl);
end;
BUF_NUM_FORMAT_FLOAT :
begin
Result:=NewReg(lc.elem_resl);
src^.mark_read;
_emit_Op1(line,Op.OpFConvert,Result,src);
Result:=OpFToF(src,lc.elem_resl);
end;
end;
end;
procedure TEmit_vbuf_load._make_load_cv_id(var lc:Tload_cache;i:Byte);
procedure TEmit_vbuf_load.make_load_cv_id(var lc:Tload_cache;i:Byte);
var
rsl:PsrRegNode;
begin
rsl:=lc.rsl;
if (rsl=nil) then
begin
rsl:=FetchLoad(lc.v.data[0],GetVecType(lc.elem_orig,lc.elem_count));
rsl:=FetchLoad(lc.v.data[0],lc.elem_orig.AsVector(lc.elem_count));
lc.rsl:=rsl;
end;
@ -197,17 +134,16 @@ begin
if (lc.elem_count=1) then
begin
rsl:=_convert_e(lc,rsl);
rsl:=convert_e(lc,rsl);
lc.elm[i]:=rsl;
end else
begin
lc.elm[i]:=NewReg(lc.elem_orig);
rsl^.mark_read;
emit_OpCompExtract(line,lc.elm[i],rsl,i);
OpExtract(line,lc.elm[i],rsl,i);
lc.elm[i]:=_convert_e(lc,lc.elm[i]);
lc.elm[i]:=convert_e(lc,lc.elm[i]);
end;
end;
@ -215,37 +151,39 @@ begin
MakeCopy(lc.dst,lc.elm[i]);
end;
procedure TEmit_vbuf_load._make_load_ce_id(var lc:Tload_cache;i:Byte);
procedure TEmit_vbuf_load.make_load_ce_id(var lc:Tload_cache;i:Byte);
var
orig,elm:PsrChain;
sum_d:PsrRegNode;
ext:TsrChainExt;
lvl_0:TsrChainLvl_0;
lvl_1:TsrChainLvl_1;
rsl:PsrRegNode;
begin
if (lc.elm[i]=nil) then
begin
orig:=lc.v.data[0];
sum_d:=orig^.key.ext.pIndex;
sum_d:=orig^.pIndex;
if (i=0) then
begin
elm:=orig;
end else
begin
sum_d:=TEmit_vbuf_chain(Self).OpAddTo(sum_d,i);
sum_d:=OpIAddTo(sum_d,i);
sum_d^.mark_read;
ext:=Default(TsrChainExt);
ext.pIndex:=sum_d;
ext.stride:=orig^.key.ext.stride;
lvl_0.offset:=0;
lvl_0.size :=orig^.size;
elm:=lc.info.grp^.Fetch(0,orig^.key.size,@ext);
lvl_1.pIndex:=sum_d;
lvl_1.stride:=orig^.stride;
elm:=lc.info.grp^.Fetch(@lvl_0,@lvl_1);
end;
rsl:=FetchLoad(elm,lc.elem_orig);
rsl:=_convert_e(lc,rsl);
rsl:=convert_e(lc,rsl);
lc.elm[i]:=rsl;
end;
@ -253,7 +191,7 @@ begin
MakeCopy(lc.dst,lc.elm[i]);
end;
procedure TEmit_vbuf_load._make_load_uv_id(var lc:Tload_cache;i:Byte);
procedure TEmit_vbuf_load.make_load_uv_id(var lc:Tload_cache;i:Byte);
var
rsl,idx:PsrRegNode;
begin
@ -261,20 +199,18 @@ begin
rsl:=lc.rsl;
if (rsl=nil) then
begin
rsl:=NewReg(GetVecType(lc.elem_resl,4));
rsl:=NewReg(lc.elem_resl.AsVector(4));
idx:=lc.v.data[1];
idx^.mark_read;
emit_OpImageRead(line,lc.v.data[0],rsl,idx);
OpImageRead(line,lc.v.data[0],rsl,idx);
lc.rsl:=rsl;
end;
if (lc.elm[i]=nil) then
begin
rsl^.mark_read;
lc.dst^.New(line,lc.elem_resl);
emit_OpCompExtract(line,lc.dst^.current,rsl,i);
OpExtract(line,lc.dst^.current,rsl,i);
lc.elm[i]:=lc.dst^.current;
end else
@ -283,7 +219,7 @@ begin
end;
end;
procedure TEmit_vbuf_load._make_load_ue_id(var lc:Tload_cache;i:Byte);
procedure TEmit_vbuf_load.make_load_ue_id(var lc:Tload_cache;i:Byte);
var
rsl,idx,sum_d:PsrRegNode;
begin
@ -297,13 +233,12 @@ begin
sum_d:=idx;
end else
begin
sum_d:=TEmit_vbuf_chain(Self).OpAddTo(idx,i);
sum_d:=OpIAddTo(idx,i);
end;
rsl:=lc.dst^.New(line,lc.elem_resl);
sum_d^.mark_read;
emit_OpImageRead(line,lc.v.data[0],rsl,sum_d);
OpImageRead(line,lc.v.data[0],rsl,sum_d);
lc.elm[i]:=rsl;
end else
@ -312,19 +247,19 @@ begin
end;
end;
procedure TEmit_vbuf_load._make_load_zero(var lc:Tload_cache);
procedure TEmit_vbuf_load.make_load_zero(var lc:Tload_cache);
begin
SetConst(lc.dst,FConsts.Fetchi(lc.elem_resl,0));
SetConst_i(lc.dst,lc.elem_resl,0);
end;
procedure TEmit_vbuf_load._make_load_one(var lc:Tload_cache);
procedure TEmit_vbuf_load.make_load_one(var lc:Tload_cache);
begin
if (lc.elem_resl=dtFloat32) then
begin
SetConst(lc.dst,FConsts.Fetchf(lc.elem_resl,1));
SetConst_s(lc.dst,lc.elem_resl,1);
end else
begin
SetConst(lc.dst,FConsts.Fetchi(lc.elem_resl,1));
SetConst_i(lc.dst,lc.elem_resl,1);
end;
end;
@ -348,16 +283,16 @@ begin
For i:=0 to count-1 do
begin
lc.dst:=FRegsStory.get_vdst8(FSPI.MUBUF.VDATA+i);
lc.dst:=get_vdst8(FSPI.MUBUF.VDATA+i);
if (lc.dst=nil) then Assert(false);
//0=0, 1=1, 4=R, 5=G, 6=B, 7=A
Case info.dsel[i] of
0:begin //0
_make_load_zero(lc);
make_load_zero(lc);
end;
1:begin //1
_make_load_one(lc);
make_load_one(lc);
end;
4..7:
begin //RGBA
@ -367,22 +302,22 @@ begin
begin
Case v.vType of
vcInvalid :_make_load_zero(lc);
vcChainVector :_make_load_cv_id(lc,d);
vcChainElement :_make_load_ce_id(lc,d);
vcUniformVector :_make_load_uv_id(lc,d);
vcUniformElement:_make_load_ue_id(lc,d);
vcInvalid :make_load_zero(lc);
vcChainVector :make_load_cv_id(lc,d);
vcChainElement :make_load_ce_id(lc,d);
vcUniformVector :make_load_uv_id(lc,d);
vcUniformElement:make_load_ue_id(lc,d);
end;
end else
begin //as zero
_make_load_zero(lc);
make_load_zero(lc);
end;
end;
else
begin //as zero
_make_load_zero(lc);
make_load_zero(lc);
end;
end;

View File

@ -7,12 +7,10 @@ interface
uses
sysutils,
ps4_pssl,
srTypes,
srConst,
srType,
srReg,
srLayout,
SprvEmit,
emit_op,
emit_fetch,
srVBufInfo,
emit_vbuf_chain;
@ -26,15 +24,15 @@ type
elm:array[0..3] of PsrRegNode;
end;
TEmit_vbuf_store=object(TEmitOp)
TEmit_vbuf_store=class(TEmitFetch)
procedure buf_store(info:TBuf_info);
function _fetch_id(var lc:Tstore_cache;i:Byte):PsrRegNode;
function _fetch_zero(var lc:Tstore_cache):PsrRegNode;
function _fetch_one(var lc:Tstore_cache):PsrRegNode;
procedure _make_store_cv(var lc:Tstore_cache);
procedure _make_store_ce(var lc:Tstore_cache);
procedure _make_store_uv(var lc:Tstore_cache);
procedure _make_store_ue(var lc:Tstore_cache);
function fetch_id(var lc:Tstore_cache;i:Byte):PsrRegNode;
function fetch_zero(var lc:Tstore_cache):PsrRegNode;
function fetch_one(var lc:Tstore_cache):PsrRegNode;
procedure make_store_cv(var lc:Tstore_cache);
procedure make_store_ce(var lc:Tstore_cache);
procedure make_store_uv(var lc:Tstore_cache);
procedure make_store_ue(var lc:Tstore_cache);
procedure buf_store_cv(info:TBuf_info;v:TvarChain);
end;
@ -44,7 +42,7 @@ procedure TEmit_vbuf_store.buf_store(info:TBuf_info);
var
v:TvarChain;
begin
v:=TEmit_vbuf_chain(Self).get_chain(info);
v:=TEmit_vbuf_chain(TObject(Self)).get_chain(info);
if (v.vType=vcUniformVector) then
begin
@ -58,25 +56,25 @@ begin
buf_store_cv(info,v);
end;
function TEmit_vbuf_store._fetch_id(var lc:Tstore_cache;i:Byte):PsrRegNode;
function TEmit_vbuf_store.fetch_id(var lc:Tstore_cache;i:Byte):PsrRegNode;
begin
Result:=fetch_vdst8(FSPI.MUBUF.VDATA+i,lc.elem_resl);
if (Result=nil) then Assert(false);
end;
function TEmit_vbuf_store._fetch_zero(var lc:Tstore_cache):PsrRegNode;
function TEmit_vbuf_store.fetch_zero(var lc:Tstore_cache):PsrRegNode;
begin
Result:=FetchReg(FConsts.Fetchi(lc.elem_resl,0));
Result:=NewReg_q(lc.elem_resl,0);
end;
function TEmit_vbuf_store._fetch_one(var lc:Tstore_cache):PsrRegNode;
function TEmit_vbuf_store.fetch_one(var lc:Tstore_cache):PsrRegNode;
begin
if (lc.elem_resl=dtFloat32) then
begin
Result:=FetchReg(FConsts.Fetchf(lc.elem_resl,1));
Result:=NewReg_s(lc.elem_resl,1);
end else
begin
Result:=FetchReg(FConsts.Fetchi(lc.elem_resl,1));
Result:=NewReg_i(lc.elem_resl,1);
end;
end;
@ -85,23 +83,24 @@ begin
if (a<b) then Result:=a else Result:=b;
end;
procedure TEmit_vbuf_store._make_store_cv(var lc:Tstore_cache);
procedure TEmit_vbuf_store.make_store_cv(var lc:Tstore_cache);
var
rsl:PsrRegNode;
i:Byte;
csize:PtrUInt;
orig,new:PsrChain;
idx:PsrRegNode;
ext:TsrChainExt;
lvl_0:TsrChainLvl_0;
lvl_1:TsrChainLvl_1;
begin
For i:=0 to lc.elem_count-1 do //fill
if (lc.elm[i]=nil) then
begin
Case lc.info.dsel[i] of
1:lc.elm[i]:=_fetch_one(lc);
1:lc.elm[i]:=fetch_one(lc);
else
lc.elm[i]:=_fetch_zero(lc);
lc.elm[i]:=fetch_zero(lc);
end;
end;
@ -109,8 +108,7 @@ begin
1:rsl:=lc.elm[0];
else
begin
rsl:=emit_OpMakeVec(line,GetVecType(lc.elem_resl,lc.elem_count),lc.elem_count,@lc.elm);
rsl^.mark_read;
rsl:=OpMakeVec(line,lc.elem_resl.AsVector(lc.elem_count),@lc.elm);
end;
end;
@ -119,19 +117,24 @@ begin
csize:=Min(lc.info.GetElemSize*lc.elem_count,lc.info.GetSizeFormat);
orig:=lc.v.data[0];
if (orig^.key.size<>csize) then //refetch
if (orig^.size<>csize) then //refetch
begin
idx:=orig^.key.ext.pIndex;
idx:=orig^.pIndex;
if (idx<>nil) then
begin
idx^.mark_read;
ext:=Default(TsrChainExt);
ext.pIndex:=idx;
ext.stride:=orig^.key.ext.stride;
new:=lc.info.grp^.Fetch(orig^.key.offset,csize,@ext);
lvl_0.offset:=orig^.offset;
lvl_0.size :=csize;
lvl_1.pIndex:=idx;
lvl_1.stride:=orig^.stride;
new:=lc.info.grp^.Fetch(@lvl_0,@lvl_1);
end else
begin
new:=lc.info.grp^.Fetch(orig^.key.offset,csize,nil);
lvl_0.offset:=orig^.offset;
lvl_0.size :=csize;
new:=lc.info.grp^.Fetch(@lvl_0,nil);
end;
orig:=new;
end;
@ -139,15 +142,16 @@ begin
FetchStore(orig,rsl);
end;
procedure TEmit_vbuf_store._make_store_ce(var lc:Tstore_cache);
procedure TEmit_vbuf_store.make_store_ce(var lc:Tstore_cache);
var
orig,elm:PsrChain;
sum_d:PsrRegNode;
ext:TsrChainExt;
lvl_0:TsrChainLvl_0;
lvl_1:TsrChainLvl_1;
i:Byte;
begin
orig:=lc.v.data[0];
sum_d:=orig^.key.ext.pIndex;
sum_d:=orig^.pIndex;
For i:=0 to lc.elem_count-1 do
if (lc.elm[i]<>nil) then
@ -158,14 +162,15 @@ begin
elm:=orig;
end else
begin
sum_d:=TEmit_vbuf_chain(Self).OpAddTo(sum_d,i);
sum_d:=OpIAddTo(sum_d,i);
sum_d^.mark_read;
ext:=Default(TsrChainExt);
ext.pIndex:=sum_d;
ext.stride:=orig^.key.ext.stride;
lvl_0.offset:=0;
lvl_0.size :=orig^.size;
elm:=lc.info.grp^.Fetch(0,orig^.key.size,@ext);
lvl_1.pIndex:=sum_d;
lvl_1.stride:=orig^.stride;
elm:=lc.info.grp^.Fetch(@lvl_0,@lvl_1);
end;
Assert(lc.elem_resl=lc.elem_orig,'TODO CONVERT');
@ -176,7 +181,7 @@ begin
end;
procedure TEmit_vbuf_store._make_store_uv(var lc:Tstore_cache);
procedure TEmit_vbuf_store.make_store_uv(var lc:Tstore_cache);
var
rsl,idx:PsrRegNode;
i:Byte;
@ -186,9 +191,9 @@ begin
if (lc.elm[i]=nil) then
begin
Case lc.info.dsel[i] of
1:lc.elm[i]:=_fetch_one(lc);
1:lc.elm[i]:=fetch_one(lc);
else
lc.elm[i]:=_fetch_zero(lc);
lc.elm[i]:=fetch_zero(lc);
end;
end;
@ -196,18 +201,16 @@ begin
1:rsl:=lc.elm[0];
else
begin
rsl:=emit_OpMakeVec(line,GetVecType(lc.elem_resl,lc.elem_count),lc.elem_count,@lc.elm);
rsl^.mark_read;
rsl:=OpMakeVec(line,lc.elem_resl.AsVector(lc.elem_count),@lc.elm);
end;
end;
idx:=lc.v.data[1];
idx^.mark_read;
rsl^.mark_read;
emit_OpImageWrite(line,lc.v.data[0],idx,rsl);
OpImageWrite(line,lc.v.data[0],idx,rsl);
end;
procedure TEmit_vbuf_store._make_store_ue(var lc:Tstore_cache);
procedure TEmit_vbuf_store.make_store_ue(var lc:Tstore_cache);
var
sum_d,idx,rsl:PsrRegNode;
i:Byte;
@ -224,12 +227,10 @@ begin
sum_d:=idx;
end else
begin
sum_d:=TEmit_vbuf_chain(Self).OpAddTo(idx,i);
sum_d:=OpIAddTo(idx,i);
end;
sum_d^.mark_read;
rsl^.mark_read;
emit_OpImageWrite(line,lc.v.data[0],sum_d,rsl);
OpImageWrite(line,lc.v.data[0],sum_d,rsl);
end;
end;
@ -261,7 +262,7 @@ begin
Case lc.info.dsel[i] of
4..7:
begin //RGBA
lc.elm[i]:=_fetch_id(lc,lc.info.dsel[i]-4);
lc.elm[i]:=fetch_id(lc,lc.info.dsel[i]-4);
end;
else;
end;
@ -277,10 +278,10 @@ begin
if (lc.elem_count=0) then Exit;
Case v.vType of
vcChainVector :_make_store_cv(lc);
vcChainElement :_make_store_ce(lc);
vcUniformVector :_make_store_uv(lc);
vcUniformElement:_make_store_ue(lc)
vcChainVector :make_store_cv(lc);
vcChainElement :make_store_ce(lc);
vcUniformVector :make_store_uv(lc);
vcUniformElement:make_store_ue(lc)
else;
end;

View File

@ -6,22 +6,21 @@ interface
uses
sysutils,
spirv,
ps4_pssl,
srTypes,
srType,
srInput,
srReg,
spirv,
SprvEmit,
emit_op;
emit_fetch;
type
TEmit_VINTRP=object(TEmitOp)
procedure _emit_VINTRP;
TEmit_VINTRP=class(TEmitFetch)
procedure emit_VINTRP;
end;
implementation
procedure TEmit_VINTRP._emit_VINTRP;
procedure TEmit_VINTRP.emit_VINTRP;
var
inp_M0:PsrInput;
@ -35,23 +34,23 @@ var
begin
Assert(FExecutionModel=ExecutionModel.Fragment); //only pixel shader
dst:=FRegsStory.get_vdst8(FSPI.VINTRP.VDST);
dst:=get_vdst8(FSPI.VINTRP.VDST);
inp_M0:=GetInputRegNode(FRegsStory.M0.current);
inp_M0:=GetInputRegNode(get_m0^.current);
Assert(inp_M0<>nil);
Assert(inp_M0^.key.itype=itPsState);
Assert(inp_M0^.itype=itPsState);
Case FSPI.VINTRP.OP of
V_INTERP_P1_F32:
begin
src:=FRegsStory.get_vsrc8(FSPI.VINTRP.VSRC);
src:=get_vsrc8(FSPI.VINTRP.VSRC);
inp_SRC:=GetInputRegNode(src^.current);
Assert(inp_SRC<>nil);
Case inp_SRC^.key.itype of
Case inp_SRC^.itype of
itPerspSample,
itPerspCenter, //barycentrics with perspective interpolation
itPerspCentroid,
@ -62,24 +61,23 @@ begin
Assert(false);
end;
Assert(inp_SRC^.key.typeid=0); //I
Assert(inp_SRC^.typeid=0); //I
rsl:=AddFragLayout(inp_SRC^.key.itype,dtVec4f,FSPI.VINTRP.ATTR);
rsl^.mark_read;
rsl:=AddFragLayout(inp_SRC^.itype,dtVec4f,FSPI.VINTRP.ATTR);
dst^.New(line,dtFloat32);
emit_OpCompExtract(line,dst^.current,rsl,FSPI.VINTRP.ATTRCHAN);
OpExtract(line,dst^.current,rsl,FSPI.VINTRP.ATTRCHAN);
end;
V_INTERP_P2_F32:
begin
src:=FRegsStory.get_vsrc8(FSPI.VINTRP.VSRC);
src:=get_vsrc8(FSPI.VINTRP.VSRC);
inp_SRC:=GetInputRegNode(src^.current);
Assert(inp_SRC<>nil);
Case inp_SRC^.key.itype of
Case inp_SRC^.itype of
itPerspSample,
itPerspCenter, //barycentrics with perspective interpolation
itPerspCentroid,
@ -90,13 +88,12 @@ begin
Assert(false);
end;
Assert(inp_SRC^.key.typeid=1); //J
Assert(inp_SRC^.typeid=1); //J
rsl:=AddFragLayout(inp_SRC^.key.itype,dtVec4f,FSPI.VINTRP.ATTR);
rsl^.mark_read;
rsl:=AddFragLayout(inp_SRC^.itype,dtVec4f,FSPI.VINTRP.ATTR);
dst^.New(line,dtFloat32);
emit_OpCompExtract(line,dst^.current,rsl,FSPI.VINTRP.ATTRCHAN);
OpExtract(line,dst^.current,rsl,FSPI.VINTRP.ATTRCHAN);
end;

View File

@ -7,188 +7,153 @@ interface
uses
sysutils,
ps4_pssl,
srTypes,
srReg,
spirv,
SprvEmit,
emit_op;
srType,
srReg,
emit_fetch;
type
TEmit_VOP1=object(TEmitOp)
procedure _emit_VOP1;
procedure _emit_V_MOV_B32;
procedure _emit_V_CVT(OpId:DWORD;dst_type,src_type:TsrDataType);
procedure _emit_V_CVT_OFF_F32_I4;
procedure _emit_V_CVT_F32_UBYTE0;
procedure _emit_V_EXT_F32(OpId:DWORD);
procedure _emit_V_RCP_F32;
procedure _emit_V_FFBL_B32;
TEmit_VOP1=class(TEmitFetch)
procedure emit_VOP1;
procedure emit_V_MOV_B32;
procedure emit_V_CVT(OpId:DWORD;dst_type,src_type:TsrDataType);
procedure emit_V_CVT_OFF_F32_I4;
procedure emit_V_CVT_F32_UBYTE0;
procedure emit_V_EXT_F32(OpId:DWORD);
procedure emit_V_RCP_F32;
procedure emit_V_FFBL_B32;
end;
implementation
procedure TEmit_VOP1._emit_V_MOV_B32;
procedure TEmit_VOP1.emit_V_MOV_B32;
Var
dst:PsrRegSlot;
src:PsrRegNode;
begin
dst:=FRegsStory.get_vdst8(FSPI.VOP1.VDST);
dst:=get_vdst8(FSPI.VOP1.VDST);
src:=fetch_ssrc9(FSPI.VOP1.SRC0,dtUnknow);
_MakeCopy(dst,src);
MakeCopy(dst,src);
end;
procedure TEmit_VOP1._emit_V_CVT(OpId:DWORD;dst_type,src_type:TsrDataType);
procedure TEmit_VOP1.emit_V_CVT(OpId:DWORD;dst_type,src_type:TsrDataType);
Var
dst:PsrRegSlot;
src:PsrRegNode;
begin
dst:=FRegsStory.get_vdst8(FSPI.VOP1.VDST);
dst:=get_vdst8(FSPI.VOP1.VDST);
src:=fetch_ssrc9(FSPI.VOP1.SRC0,src_type);
emit_Op1(OpId,dst_type,dst,src);
Op1(OpId,dst_type,dst,src);
end;
//V_CVT_OFF_F32_I4
//([0..3]-8)/16
procedure TEmit_VOP1._emit_V_CVT_OFF_F32_I4;
procedure TEmit_VOP1.emit_V_CVT_OFF_F32_I4;
Var
dst,tmp:PsrRegSlot;
dst:PsrRegSlot;
src:PsrRegNode;
num_8:PsrRegNode;
num_15:PsrRegNode;
num_16:PsrRegNode;
subi,subf:PsrRegNode;
begin
dst:=FRegsStory.get_vdst8(FSPI.VOP1.VDST);
dst:=get_vdst8(FSPI.VOP1.VDST);
src:=fetch_ssrc9(FSPI.VOP1.SRC0,dtUInt32);
tmp:=@FRegsStory.FUnattach;
num_15:=FetchReg(FConsts.Fetch(dtUInt32,15));
src:=OpBitwiseAndTo(src,15);
src^.PrepType(ord(dtInt32));
emit_OpBitwiseAnd(tmp,src,num_15);
src:=MakeRead(tmp,dtUInt32);
src:=OpISubTo(src,8);
num_8:=FetchReg(FConsts.Fetch(dtInt32,8));
subi:=dst^.New(line,dtInt32);
src:=OpSToF(src,dtFloat32);
_emit_OpISub(line,subi,src,num_8);
subi^.mark_read;
subf:=dst^.New(line,dtFloat32);
_emit_Op1(line,Op.OpConvertSToF,subf,subi);
subf^.mark_read;
num_16:=FetchReg(FConsts.Fetchf(dtFloat32,16));
emit_OpFDiv(dst,subf,num_16);
num_16:=NewReg_s(dtFloat32,16);
Op2(Op.OpFDiv,dtFloat32,dst,src,num_16);
end;
procedure TEmit_VOP1._emit_V_CVT_F32_UBYTE0;
Var
dst,tmp:PsrRegSlot;
src:PsrRegNode;
num_FF:PsrRegNode;
begin
dst:=FRegsStory.get_vdst8(FSPI.VOP1.VDST);
src:=fetch_ssrc9(FSPI.VOP1.SRC0,dtUInt32);
tmp:=@FRegsStory.FUnattach;
num_FF:=FetchReg(FConsts.Fetch(dtUInt32,$FF));
emit_OpBitwiseAnd(tmp,src,num_FF);
src:=MakeRead(tmp,dtUInt32);
emit_Op1(Op.OpConvertUToF,dtFloat32,dst,src);
end;
procedure TEmit_VOP1._emit_V_EXT_F32(OpId:DWORD);
procedure TEmit_VOP1.emit_V_CVT_F32_UBYTE0;
Var
dst:PsrRegSlot;
src:PsrRegNode;
begin
dst:=FRegsStory.get_vdst8(FSPI.VOP1.VDST);
src:=fetch_ssrc9(FSPI.VOP1.SRC0,dtFloat32);
emit_OpExt1(OpId,dtFloat32,dst,src);
dst:=get_vdst8(FSPI.VOP1.VDST);
src:=fetch_ssrc9(FSPI.VOP1.SRC0,dtUInt32);
src:=OpBitwiseAndTo(src,$FF);
src^.PrepType(ord(dtUInt32));
Op1(Op.OpConvertUToF,dtFloat32,dst,src);
end;
procedure TEmit_VOP1._emit_V_RCP_F32;
procedure TEmit_VOP1.emit_V_EXT_F32(OpId:DWORD);
Var
dst:PsrRegSlot;
src:PsrRegNode;
begin
dst:=get_vdst8(FSPI.VOP1.VDST);
src:=fetch_ssrc9(FSPI.VOP1.SRC0,dtFloat32);
OpGlsl1(OpId,dtFloat32,dst,src);
end;
procedure TEmit_VOP1.emit_V_RCP_F32;
Var
dst:PsrRegSlot;
src:PsrRegNode;
one:PsrRegNode;
begin
dst:=FRegsStory.get_vdst8(FSPI.VOP1.VDST);
dst:=get_vdst8(FSPI.VOP1.VDST);
src:=fetch_ssrc9(FSPI.VOP1.SRC0,dtFloat32);
one:=FetchReg(FConsts.Fetchf(dtFloat32,1));
one:=NewReg_s(dtFloat32,1);
emit_OpFDiv(dst,one,src);
Op2(Op.OpFDiv,dtFloat32,dst,one,src);
end;
procedure TEmit_VOP1._emit_V_FFBL_B32;
procedure TEmit_VOP1.emit_V_FFBL_B32;
Var
dst:PsrRegSlot;
src:PsrRegNode;
begin
dst:=FRegsStory.get_vdst8(FSPI.VOP1.VDST);
dst:=get_vdst8(FSPI.VOP1.VDST);
src:=fetch_ssrc9(FSPI.VOP1.SRC0,dtInt32);
emit_OpExt1(GlslOp.FindILsb,dtInt32,dst,src);
OpGlsl1(GlslOp.FindILsb,dtInt32,dst,src);
end;
procedure TEmit_VOP1._emit_VOP1;
procedure TEmit_VOP1.emit_VOP1;
begin
Case FSPI.VOP1.OP of
V_NOP:;
V_MOV_B32:
begin
_emit_V_MOV_B32;
end;
V_MOV_B32: emit_V_MOV_B32;
V_CVT_F32_I32: _emit_V_CVT(Op.OpConvertSToF,dtFloat32,dtInt32);
V_CVT_F32_U32: _emit_V_CVT(Op.OpConvertUToF,dtFloat32,dtUInt32);
V_CVT_U32_F32: _emit_V_CVT(Op.OpConvertFToU,dtUInt32 ,dtFloat32);
V_CVT_I32_F32: _emit_V_CVT(Op.OpConvertFToS,dtInt32 ,dtFloat32);
V_CVT_F32_I32: emit_V_CVT(Op.OpConvertSToF,dtFloat32,dtInt32);
V_CVT_F32_U32: emit_V_CVT(Op.OpConvertUToF,dtFloat32,dtUInt32);
V_CVT_U32_F32: emit_V_CVT(Op.OpConvertFToU,dtUInt32 ,dtFloat32);
V_CVT_I32_F32: emit_V_CVT(Op.OpConvertFToS,dtInt32 ,dtFloat32);
V_CVT_OFF_F32_I4:
begin
_emit_V_CVT_OFF_F32_I4;
end;
V_CVT_OFF_F32_I4: emit_V_CVT_OFF_F32_I4;
V_CVT_F32_UBYTE0:
begin
_emit_V_CVT_F32_UBYTE0;
end;
V_CVT_F32_UBYTE0: emit_V_CVT_F32_UBYTE0;
V_FRACT_F32: _emit_V_EXT_F32(GlslOp.Fract);
V_TRUNC_F32: _emit_V_EXT_F32(GlslOp.Trunc);
V_CEIL_F32 : _emit_V_EXT_F32(GlslOp.Ceil);
V_FRACT_F32: emit_V_EXT_F32(GlslOp.Fract);
V_TRUNC_F32: emit_V_EXT_F32(GlslOp.Trunc);
V_CEIL_F32 : emit_V_EXT_F32(GlslOp.Ceil);
V_FLOOR_F32: _emit_V_EXT_F32(GlslOp.Floor);
V_EXP_F32 : _emit_V_EXT_F32(GlslOp.Exp2);
V_LOG_F32 : _emit_V_EXT_F32(GlslOp.Log2);
V_FLOOR_F32: emit_V_EXT_F32(GlslOp.Floor);
V_EXP_F32 : emit_V_EXT_F32(GlslOp.Exp2);
V_LOG_F32 : emit_V_EXT_F32(GlslOp.Log2);
V_RSQ_F32 : _emit_V_EXT_F32(GlslOp.InverseSqrt);
V_RSQ_F32 : emit_V_EXT_F32(GlslOp.InverseSqrt);
V_SQRT_F32 : _emit_V_EXT_F32(GlslOp.Sqrt);
V_SQRT_F32 : emit_V_EXT_F32(GlslOp.Sqrt);
V_SIN_F32 : _emit_V_EXT_F32(GlslOp.Sin);
V_COS_F32 : _emit_V_EXT_F32(GlslOp.Cos);
V_SIN_F32 : emit_V_EXT_F32(GlslOp.Sin);
V_COS_F32 : emit_V_EXT_F32(GlslOp.Cos);
V_RCP_F32:
begin
_emit_V_RCP_F32;
end;
V_RCP_F32 : emit_V_RCP_F32;
V_FFBL_B32:
begin
_emit_V_FFBL_B32;
end;
V_FFBL_B32 : emit_V_FFBL_B32;
else
Assert(false,'VOP1?'+IntToStr(FSPI.VOP1.OP));

View File

@ -8,506 +8,360 @@ uses
sysutils,
ps4_pssl,
spirv,
srTypes,
srConst,
srType,
srReg,
SprvEmit,
emit_op;
emit_fetch;
type
TEmit_VOP2=object(TEmitOp)
procedure _emit_VOP2;
procedure _emit_V_CNDMASK_B32;
procedure _emit_V_AND_B32;
procedure _emit_V_OR_B32;
procedure _emit_V_XOR_B32;
procedure _emit_V_LSHL_B32;
procedure _emit_V_LSHLREV_B32;
procedure _emit_V_LSHR_B32;
procedure _emit_V_LSHRREV_B32;
procedure _emit_V_ASHR_I32;
procedure _emit_V_ASHRREV_I32;
procedure _emit_V_ADD_I32;
procedure _emit_V_SUB_I32;
procedure _emit_V_SUBREV_I32;
procedure _emit_V_ADD_F32;
procedure _emit_V_SUB_F32;
procedure _emit_V_SUBREV_F32;
procedure _emit_V_MUL_F32;
procedure _emit_V_CVT_PKRTZ_F16_F32;
procedure _emit_V_MAC_F32;
procedure _emit_V_MADAK_F32;
procedure _emit_V_MADMK_F32;
procedure _emit_V_MIN_MAX(OpId:DWORD;rtype:TsrDataType);
TEmit_VOP2=class(TEmitFetch)
procedure emit_VOP2;
procedure emit_V_CNDMASK_B32;
procedure emit_V_AND_B32;
procedure emit_V_OR_B32;
procedure emit_V_XOR_B32;
procedure emit_V_SH(OpId:DWORD;rtype:TsrDataType);
procedure emit_V_SHREV(OpId:DWORD;rtype:TsrDataType);
procedure emit_V_ADD_I32;
procedure emit_V_SUB_I32;
procedure emit_V_SUBREV_I32;
procedure emit_V2_F32(OpId:DWORD);
procedure emit_V_SUBREV_F32;
procedure emit_V_CVT_PKRTZ_F16_F32;
procedure emit_V_MUL_I32_I24;
procedure emit_V_MUL_U32_U24;
procedure emit_V_MAC_F32;
procedure emit_V_MADAK_F32;
procedure emit_V_MADMK_F32;
procedure emit_V_MMX(OpId:DWORD;rtype:TsrDataType);
end;
implementation
procedure TEmit_VOP2._emit_V_CNDMASK_B32;
procedure TEmit_VOP2.emit_V_CNDMASK_B32;
Var
dst:PsrRegSlot;
src:array[0..2] of PsrRegNode;
begin
dst:=FRegsStory.get_vdst8(FSPI.VOP2.VDST);
dst:=get_vdst8(FSPI.VOP2.VDST);
src[0]:=fetch_ssrc9(FSPI.VOP2.SRC0 ,dtUnknow);
src[1]:=fetch_vsrc8(FSPI.VOP2.VSRC1,dtUnknow);
src[2]:=MakeRead(@FRegsStory.VCC[0],dtBool);
src[2]:=MakeRead(get_vcc0,dtBool);
emit_OpSelect(dst,src[0],src[1],src[2]);
OpSelect(dst,src[0],src[1],src[2]);
end;
procedure TEmit_VOP2._emit_V_AND_B32;
procedure TEmit_VOP2.emit_V_AND_B32;
Var
dst:PsrRegSlot;
src:array[0..1] of PsrRegNode;
begin
dst:=FRegsStory.get_vdst8(FSPI.VOP2.VDST);
dst:=get_vdst8(FSPI.VOP2.VDST);
src[0]:=fetch_ssrc9(FSPI.VOP2.SRC0 ,dtUnknow);
src[1]:=fetch_vsrc8(FSPI.VOP2.VSRC1,dtUnknow);
emit_OpBitwiseAnd(dst,src[0],src[1]);
OpBitwiseAnd(dst,src[0],src[1]);
end;
procedure TEmit_VOP2._emit_V_OR_B32;
procedure TEmit_VOP2.emit_V_OR_B32;
Var
dst:PsrRegSlot;
src:array[0..1] of PsrRegNode;
begin
dst:=FRegsStory.get_vdst8(FSPI.VOP2.VDST);
dst:=get_vdst8(FSPI.VOP2.VDST);
src[0]:=fetch_ssrc9(FSPI.VOP2.SRC0 ,dtUnknow);
src[1]:=fetch_vsrc8(FSPI.VOP2.VSRC1,dtUnknow);
emit_OpBitwiseOr(dst,src[0],src[1]);
OpBitwiseOr(dst,src[0],src[1]);
end;
procedure TEmit_VOP2._emit_V_XOR_B32;
procedure TEmit_VOP2.emit_V_XOR_B32;
Var
dst:PsrRegSlot;
src:array[0..1] of PsrRegNode;
begin
dst:=FRegsStory.get_vdst8(FSPI.VOP2.VDST);
dst:=get_vdst8(FSPI.VOP2.VDST);
src[0]:=fetch_ssrc9(FSPI.VOP2.SRC0 ,{dtUnknow}dtUInt32);
src[1]:=fetch_vsrc8(FSPI.VOP2.VSRC1,{dtUnknow}dtUInt32);
src[0]:=fetch_ssrc9(FSPI.VOP2.SRC0 ,dtUInt32);
src[1]:=fetch_vsrc8(FSPI.VOP2.VSRC1,dtUInt32);
emit_OpBitwiseXor(dst,src[0],src[1]);
OpBitwiseXor(dst,src[0],src[1]);
end;
procedure TEmit_VOP2._emit_V_LSHL_B32;
procedure TEmit_VOP2.emit_V_SH(OpId:DWORD;rtype:TsrDataType);
Var
dst,tmp:PsrRegSlot;
src:array[0..2] of PsrRegNode;
dst:PsrRegSlot;
src:array[0..1] of PsrRegNode;
begin
dst:=FRegsStory.get_vdst8(FSPI.VOP2.VDST);
tmp:=@FRegsStory.FUnattach;
dst:=get_vdst8(FSPI.VOP2.VDST);
src[0]:=fetch_ssrc9(FSPI.VOP2.SRC0 ,rtype);
src[1]:=fetch_vsrc8(FSPI.VOP2.VSRC1,dtUint32);
src[1]:=OpBitwiseAndTo(src[1],31);
src[1]^.PrepType(ord(dtUInt32));
Op2(OpId,src[0]^.dtype,dst,src[0],src[1]);
end;
procedure TEmit_VOP2.emit_V_SHREV(OpId:DWORD;rtype:TsrDataType);
Var
dst:PsrRegSlot;
src:array[0..1] of PsrRegNode;
begin
dst:=get_vdst8(FSPI.VOP2.VDST);
src[0]:=fetch_ssrc9(FSPI.VOP2.SRC0 ,dtUint32);
src[1]:=fetch_vsrc8(FSPI.VOP2.VSRC1,rtype);
src[0]:=OpBitwiseAndTo(src[0],31);
src[0]^.PrepType(ord(dtUInt32));
Op2(OpId,src[1]^.dtype,dst,src[1],src[0]);
end;
procedure TEmit_VOP2.emit_V_ADD_I32; //vdst = vsrc0.s + vsrc1.s; sdst[thread_id:] = carry_out & EXEC
Var
dst,car:PsrRegSlot;
src:array[0..1] of PsrRegNode;
exc:PsrRegNode;
begin
dst:=get_vdst8(FSPI.VOP2.VDST);
car:=get_vcc0;
src[0]:=fetch_ssrc9(FSPI.VOP2.SRC0 ,dtUint32);
src[1]:=fetch_vsrc8(FSPI.VOP2.VSRC1,dtUint32);
src[2]:=FetchReg(FConsts.Fetch(dtUInt32,31));
emit_OpBitwiseAnd(tmp,src[1],src[2]);
src[1]:=MakeRead(tmp,dtUInt32);
OpIAddExt(dst,car,src[0],src[1]);
emit_OpShl(dst,src[0],src[1]);
exc:=MakeRead(get_exec0,dtUnknow);
OpBitwiseAnd(car,car^.current,exc); //carry_out & EXEC
end;
procedure TEmit_VOP2._emit_V_LSHLREV_B32;
procedure TEmit_VOP2.emit_V_SUB_I32; //vdst = vsrc0.u - vsub.u; sdst[thread_id:] = borrow_out & EXEC
Var
dst,tmp:PsrRegSlot;
src:array[0..2] of PsrRegNode;
dst,bor:PsrRegSlot;
src:array[0..1] of PsrRegNode;
exc:PsrRegNode;
begin
dst:=FRegsStory.get_vdst8(FSPI.VOP2.VDST);
tmp:=@FRegsStory.FUnattach;
dst:=get_vdst8(FSPI.VOP2.VDST);
bor:=get_vcc0;
src[0]:=fetch_ssrc9(FSPI.VOP2.SRC0 ,dtUint32);
src[1]:=fetch_vsrc8(FSPI.VOP2.VSRC1,dtUint32);
src[2]:=FetchReg(FConsts.Fetch(dtUInt32,31));
emit_OpBitwiseAnd(tmp,src[0],src[2]);
src[0]:=MakeRead(tmp,dtUInt32);
OpISubExt(dst,bor,src[0],src[1]);
emit_OpShl(dst,src[1],src[0]);
exc:=MakeRead(get_exec0,dtUnknow);
OpBitwiseAnd(bor,bor^.current,exc); //borrow_out & EXEC
end;
procedure TEmit_VOP2._emit_V_LSHR_B32;
procedure TEmit_VOP2.emit_V_SUBREV_I32; //vdst = vsrc1.u - vsub.u; sdst[thread_id:] = borrow_out & EXEC
Var
dst,tmp:PsrRegSlot;
src:array[0..2] of PsrRegNode;
dst,bor:PsrRegSlot;
src:array[0..1] of PsrRegNode;
exc:PsrRegNode;
begin
dst:=FRegsStory.get_vdst8(FSPI.VOP2.VDST);
tmp:=@FRegsStory.FUnattach;
dst:=get_vdst8(FSPI.VOP2.VDST);
bor:=get_vcc0;
src[0]:=fetch_ssrc9(FSPI.VOP2.SRC0 ,dtUint32);
src[1]:=fetch_vsrc8(FSPI.VOP2.VSRC1,dtUint32);
src[2]:=FetchReg(FConsts.Fetch(dtUInt32,31));
emit_OpBitwiseAnd(tmp,src[1],src[2]);
src[1]:=MakeRead(tmp,dtUInt32);
OpISubExt(dst,bor,src[1],src[0]);
emit_OpShr(dst,src[0],src[1]);
exc:=MakeRead(get_exec0,dtUnknow);
OpBitwiseAnd(bor,bor^.current,exc); //borrow_out & EXEC
end;
procedure TEmit_VOP2._emit_V_LSHRREV_B32;
procedure TEmit_VOP2.emit_V2_F32(OpId:DWORD);
Var
dst,tmp:PsrRegSlot;
src:array[0..2] of PsrRegNode;
dst:PsrRegSlot;
src:array[0..1] of PsrRegNode;
begin
dst:=FRegsStory.get_vdst8(FSPI.VOP2.VDST);
tmp:=@FRegsStory.FUnattach;
dst:=get_vdst8(FSPI.VOP2.VDST);
src[0]:=fetch_ssrc9(FSPI.VOP2.SRC0 ,dtUint32);
src[1]:=fetch_vsrc8(FSPI.VOP2.VSRC1,dtUint32);
src[0]:=fetch_ssrc9(FSPI.VOP2.SRC0 ,dtFloat32);
src[1]:=fetch_vsrc8(FSPI.VOP2.VSRC1,dtFloat32);
src[2]:=FetchReg(FConsts.Fetch(dtUInt32,31));
emit_OpBitwiseAnd(tmp,src[0],src[2]);
src[0]:=MakeRead(tmp,dtUInt32);
emit_OpShr(dst,src[1],src[0]);
Op2(OpId,dtFloat32,dst,src[0],src[1]);
end;
procedure TEmit_VOP2._emit_V_ASHR_I32;
procedure TEmit_VOP2.emit_V_SUBREV_F32;
Var
dst,tmp:PsrRegSlot;
src:array[0..2] of PsrRegNode;
dst:PsrRegSlot;
src:array[0..1] of PsrRegNode;
begin
dst:=FRegsStory.get_vdst8(FSPI.VOP2.VDST);
tmp:=@FRegsStory.FUnattach;
dst:=get_vdst8(FSPI.VOP2.VDST);
src[0]:=fetch_ssrc9(FSPI.VOP2.SRC0 ,dtFloat32);
src[1]:=fetch_vsrc8(FSPI.VOP2.VSRC1,dtFloat32);
Op2(Op.OpFSub,dtFloat32,dst,src[1],src[0]);
end;
procedure TEmit_VOP2.emit_V_CVT_PKRTZ_F16_F32;
Var
dst:PsrRegSlot;
src:array[0..1] of PsrRegNode;
begin
dst:=get_vdst8(FSPI.VOP2.VDST);
src[0]:=fetch_ssrc9(FSPI.VOP2.SRC0 ,dtFloat32);
src[1]:=fetch_vsrc8(FSPI.VOP2.VSRC1,dtFloat32);
OpConvFloatToHalf2(dst,src[0],src[1]);
end;
procedure TEmit_VOP2.emit_V_MUL_I32_I24;
Var
dst:PsrRegSlot;
src:array[0..1] of PsrRegNode;
bit24:PsrRegNode;
begin
dst:=get_vdst8(FSPI.VOP2.VDST);
src[0]:=fetch_ssrc9(FSPI.VOP2.SRC0 ,dtInt32);
src[1]:=fetch_vsrc8(FSPI.VOP2.VSRC1,dtUint32);
src[2]:=FetchReg(FConsts.Fetch(dtInt32,31));
emit_OpBitwiseAnd(tmp,src[1],src[2]);
src[1]:=MakeRead(tmp,dtInt32);
emit_OpShrA(dst,src[0],src[1]);
end;
procedure TEmit_VOP2._emit_V_ASHRREV_I32;
Var
dst,tmp:PsrRegSlot;
src:array[0..2] of PsrRegNode;
begin
dst:=FRegsStory.get_vdst8(FSPI.VOP2.VDST);
tmp:=@FRegsStory.FUnattach;
src[0]:=fetch_ssrc9(FSPI.VOP2.SRC0 ,dtUint32);
src[1]:=fetch_vsrc8(FSPI.VOP2.VSRC1,dtInt32);
src[2]:=FetchReg(FConsts.Fetch(dtInt32,31));
emit_OpBitwiseAnd(tmp,src[0],src[2]);
src[0]:=MakeRead(tmp,dtInt32);
bit24:=NewReg_q(dtUInt32,$FFFFFF);
emit_OpShrA(dst,src[1],src[0]);
src[0]:=OpBitwiseAndTo(src[0],bit24);
src[0]^.PrepType(ord(dtInt32));
src[1]:=OpBitwiseAndTo(src[1],bit24);
src[1]^.PrepType(ord(dtInt32));
OpIMul(dst,src[0],src[1]);
end;
procedure TEmit_VOP2._emit_V_ADD_I32; //vdst = vsrc0.s + vsrc1.s; sdst[thread_id:] = carry_out & EXEC
Var
dst,car:PsrRegSlot;
src:array[0..1] of PsrRegNode;
exc,tmp:PsrRegNode;
begin
dst:=FRegsStory.get_vdst8(FSPI.VOP2.VDST);
car:=@FRegsStory.VCC[0];
src[0]:=fetch_ssrc9(FSPI.VOP2.SRC0 ,dtUint32);
src[1]:=fetch_vsrc8(FSPI.VOP2.VSRC1,dtUint32);
emit_OpIAddExt(dst,@FRegsStory.FUnattach,src[0],src[1]);
tmp:=FRegsStory.FUnattach.current;
tmp^.mark_read;
exc:=MakeRead(@FRegsStory.EXEC[0],dtUnknow);
emit_OpBitwiseAnd(car,tmp,exc);
end;
procedure TEmit_VOP2._emit_V_SUB_I32; //vdst = vsrc0.u - vsub.u; sdst[thread_id:] = borrow_out & EXEC
Var
dst,car:PsrRegSlot;
src:array[0..1] of PsrRegNode;
exc,tmp:PsrRegNode;
begin
dst:=FRegsStory.get_vdst8(FSPI.VOP2.VDST);
car:=@FRegsStory.VCC[0];
src[0]:=fetch_ssrc9(FSPI.VOP2.SRC0 ,dtUint32);
src[1]:=fetch_vsrc8(FSPI.VOP2.VSRC1,dtUint32);
emit_OpISubExt(dst,@FRegsStory.FUnattach,src[0],src[1]);
tmp:=FRegsStory.FUnattach.current;
tmp^.mark_read;
exc:=MakeRead(@FRegsStory.EXEC[0],dtUnknow);
emit_OpBitwiseAnd(car,tmp,exc);
end;
procedure TEmit_VOP2._emit_V_SUBREV_I32; //vdst = vsrc1.u - vsub.u; sdst[thread_id:] = borrow_out & EXEC
Var
dst,car:PsrRegSlot;
src:array[0..1] of PsrRegNode;
exc,tmp:PsrRegNode;
begin
dst:=FRegsStory.get_vdst8(FSPI.VOP2.VDST);
car:=@FRegsStory.VCC[0];
src[0]:=fetch_ssrc9(FSPI.VOP2.SRC0 ,dtUint32);
src[1]:=fetch_vsrc8(FSPI.VOP2.VSRC1,dtUint32);
emit_OpISubExt(dst,@FRegsStory.FUnattach,src[1],src[0]);
tmp:=FRegsStory.FUnattach.current;
tmp^.mark_read;
exc:=MakeRead(@FRegsStory.EXEC[0],dtUnknow);
emit_OpBitwiseAnd(car,tmp,exc);
end;
procedure TEmit_VOP2._emit_V_ADD_F32;
procedure TEmit_VOP2.emit_V_MUL_U32_U24;
Var
dst:PsrRegSlot;
src:array[0..1] of PsrRegNode;
bit24:PsrRegNode;
begin
dst:=FRegsStory.get_vdst8(FSPI.VOP2.VDST);
dst:=get_vdst8(FSPI.VOP2.VDST);
src[0]:=fetch_ssrc9(FSPI.VOP2.SRC0 ,dtFloat32);
src[1]:=fetch_vsrc8(FSPI.VOP2.VSRC1,dtFloat32);
src[0]:=fetch_ssrc9(FSPI.VOP2.SRC0 ,dtUInt32);
src[1]:=fetch_vsrc8(FSPI.VOP2.VSRC1,dtUInt32);
emit_OpFAdd(dst,src[0],src[1]);
bit24:=NewReg_q(dtUInt32,$FFFFFF);
src[0]:=OpBitwiseAndTo(src[0],bit24);
src[0]^.PrepType(ord(dtUInt32));
src[1]:=OpBitwiseAndTo(src[1],bit24);
src[1]^.PrepType(ord(dtUInt32));
OpIMul(dst,src[0],src[1]);
end;
procedure TEmit_VOP2._emit_V_SUB_F32;
Var
dst:PsrRegSlot;
src:array[0..1] of PsrRegNode;
begin
dst:=FRegsStory.get_vdst8(FSPI.VOP2.VDST);
src[0]:=fetch_ssrc9(FSPI.VOP2.SRC0 ,dtFloat32);
src[1]:=fetch_vsrc8(FSPI.VOP2.VSRC1,dtFloat32);
emit_OpFSub(dst,src[0],src[1]);
end;
procedure TEmit_VOP2._emit_V_SUBREV_F32;
Var
dst:PsrRegSlot;
src:array[0..1] of PsrRegNode;
begin
dst:=FRegsStory.get_vdst8(FSPI.VOP2.VDST);
src[0]:=fetch_ssrc9(FSPI.VOP2.SRC0 ,dtFloat32);
src[1]:=fetch_vsrc8(FSPI.VOP2.VSRC1,dtFloat32);
emit_OpFSub(dst,src[1],src[0]);
end;
procedure TEmit_VOP2._emit_V_MUL_F32;
Var
dst:PsrRegSlot;
src:array[0..1] of PsrRegNode;
begin
dst:=FRegsStory.get_vdst8(FSPI.VOP2.VDST);
src[0]:=fetch_ssrc9(FSPI.VOP2.SRC0 ,dtFloat32);
src[1]:=fetch_vsrc8(FSPI.VOP2.VSRC1,dtFloat32);
emit_OpFMul(dst,src[0],src[1]);
end;
procedure TEmit_VOP2._emit_V_CVT_PKRTZ_F16_F32;
Var
dst:PsrRegSlot;
src:array[0..1] of PsrRegNode;
begin
dst:=FRegsStory.get_vdst8(FSPI.VOP2.VDST);
src[0]:=fetch_ssrc9(FSPI.VOP2.SRC0 ,dtFloat32);
src[1]:=fetch_vsrc8(FSPI.VOP2.VSRC1,dtFloat32);
_emit_ConvFloatToHalf(dst,src[0],src[1]);
end;
procedure TEmit_VOP2._emit_V_MAC_F32; //vdst = vsrc0.f * vsrc1.f + vdst.f -> fma
procedure TEmit_VOP2.emit_V_MAC_F32; //vdst = vsrc0.f * vsrc1.f + vdst.f -> fma
Var
dst:PsrRegSlot;
src:array[0..2] of PsrRegNode;
begin
dst:=FRegsStory.get_vdst8(FSPI.VOP2.VDST);
dst:=get_vdst8(FSPI.VOP2.VDST);
src[0]:=fetch_ssrc9(FSPI.VOP2.SRC0 ,dtFloat32);
src[1]:=fetch_vsrc8(FSPI.VOP2.VSRC1,dtFloat32);
src[2]:=MakeRead(dst,dtFloat32);
emit_OpFmaF32(dst,src[0],src[1],src[2]);
OpFmaF32(dst,src[0],src[1],src[2]);
end;
procedure TEmit_VOP2._emit_V_MADAK_F32; //vdst = vsrc0.f * vsrc1.f + kadd.f
procedure TEmit_VOP2.emit_V_MADAK_F32; //vdst = vsrc0.f * vsrc1.f + kadd.f
Var
dst:PsrRegSlot;
src:array[0..2] of PsrRegNode;
begin
dst:=FRegsStory.get_vdst8(FSPI.VOP2.VDST);
dst:=get_vdst8(FSPI.VOP2.VDST);
src[0]:=fetch_ssrc9(FSPI.VOP2.SRC0 ,dtFloat32);
src[1]:=fetch_vsrc8(FSPI.VOP2.VSRC1,dtFloat32);
src[2]:=FetchReg(FConsts.Fetch(dtFloat32,FSPI.INLINE32));
src[2]:=NewReg_q(dtFloat32,FSPI.INLINE32);
emit_OpFmaF32(dst,src[0],src[1],src[2]);
OpFmaF32(dst,src[0],src[1],src[2]);
end;
procedure TEmit_VOP2._emit_V_MADMK_F32; //vdst = vsrc0.f * kmul.f + vadd.f
procedure TEmit_VOP2.emit_V_MADMK_F32; //vdst = vsrc0.f * kmul.f + vadd.f
Var
dst:PsrRegSlot;
src:array[0..2] of PsrRegNode;
begin
dst:=FRegsStory.get_vdst8(FSPI.VOP2.VDST);
dst:=get_vdst8(FSPI.VOP2.VDST);
src[0]:=fetch_ssrc9(FSPI.VOP2.SRC0 ,dtFloat32);
src[1]:=FetchReg(FConsts.Fetch(dtFloat32,FSPI.INLINE32));
src[1]:=NewReg_q(dtFloat32,FSPI.INLINE32);
src[2]:=fetch_vsrc8(FSPI.VOP2.VSRC1,dtFloat32);
emit_OpFmaF32(dst,src[0],src[1],src[2]);
OpFmaF32(dst,src[0],src[1],src[2]);
end;
procedure TEmit_VOP2._emit_V_MIN_MAX(OpId:DWORD;rtype:TsrDataType);
procedure TEmit_VOP2.emit_V_MMX(OpId:DWORD;rtype:TsrDataType);
Var
dst:PsrRegSlot;
src:array[0..1] of PsrRegNode;
begin
dst:=FRegsStory.get_vdst8(FSPI.VOP2.VDST);
dst:=get_vdst8(FSPI.VOP2.VDST);
src[0]:=fetch_ssrc9(FSPI.VOP2.SRC0 ,rtype);
src[1]:=fetch_vsrc8(FSPI.VOP2.VSRC1,rtype);
emit_OpExt2(OpId,rtype,dst,src[0],src[1]);
OpGlsl2(OpId,rtype,dst,src[0],src[1]);
end;
procedure TEmit_VOP2._emit_VOP2;
procedure TEmit_VOP2.emit_VOP2;
begin
Case FSPI.VOP2.OP of
V_CNDMASK_B32:
begin
_emit_V_CNDMASK_B32;
end;
V_CNDMASK_B32: emit_V_CNDMASK_B32;
V_AND_B32:
begin
_emit_V_AND_B32;
end;
V_AND_B32 : emit_V_AND_B32;
V_OR_B32 : emit_V_OR_B32;
V_XOR_B32 : emit_V_XOR_B32;
V_OR_B32:
begin
_emit_V_OR_B32;
end;
V_LSHL_B32 : emit_V_SH(Op.OpShiftLeftLogical,dtUint32);
V_LSHLREV_B32: emit_V_SHREV(Op.OpShiftLeftLogical,dtUint32);
V_LSHR_B32 : emit_V_SH(Op.OpShiftRightLogical,dtUint32);
V_LSHRREV_B32: emit_V_SHREV(Op.OpShiftRightLogical,dtUint32);
V_ASHR_I32 : emit_V_SH(Op.OpShiftRightLogical,dtInt32);
V_ASHRREV_I32: emit_V_SHREV(Op.OpShiftRightLogical,dtInt32);
V_XOR_B32:
begin
_emit_V_XOR_B32;
end;
V_ADD_I32 : emit_V_ADD_I32;
V_SUB_I32 : emit_V_SUB_I32;
V_SUBREV_I32 : emit_V_SUBREV_I32;
V_LSHL_B32:
begin
_emit_V_LSHL_B32;
end;
V_ADD_F32 : emit_V2_F32(Op.OpFAdd);
V_SUB_F32 : emit_V2_F32(Op.OpFSub);
V_SUBREV_F32 : emit_V_SUBREV_F32;
V_LSHLREV_B32:
begin
_emit_V_LSHLREV_B32;
end;
V_MUL_F32 :emit_V2_F32(Op.OpFMul);
V_LSHR_B32:
begin
_emit_V_LSHR_B32;
end;
V_CVT_PKRTZ_F16_F32: emit_V_CVT_PKRTZ_F16_F32;
V_LSHRREV_B32:
begin
_emit_V_LSHRREV_B32
end;
V_MUL_I32_I24: emit_V_MUL_I32_I24;
V_MUL_U32_U24: emit_V_MUL_U32_U24;
V_ASHR_I32:
begin
_emit_V_ASHR_I32;
end;
V_MAC_F32 : emit_V_MAC_F32;
V_MADAK_F32: emit_V_MADAK_F32;
V_MADMK_F32: emit_V_MADMK_F32;
V_ASHRREV_I32:
begin
_emit_V_ASHRREV_I32
end;
V_MIN_LEGACY_F32: emit_V_MMX(GlslOp.NMin,dtFloat32);
V_MAX_LEGACY_F32: emit_V_MMX(GlslOp.NMax,dtFloat32);
V_ADD_I32: //vdst = vsrc0.s + vsrc1.s; sdst[thread_id:] = carry_out & EXEC
begin
// Vector ALU (except v_readlane, v_readfirstlane, v_writelane),
// Vector Memory,
// Local and Global Data Share
// and Export.
_emit_V_ADD_I32;
end;
V_MIN_F32: emit_V_MMX(GlslOp.FMin,dtFloat32);
V_MAX_F32: emit_V_MMX(GlslOp.FMax,dtFloat32);
V_SUB_I32:
begin
_emit_V_SUB_I32;
end;
V_MIN_I32: emit_V_MMX(GlslOp.SMin,dtInt32);
V_MAX_I32: emit_V_MMX(GlslOp.SMax,dtInt32);
V_SUBREV_I32:
begin
_emit_V_SUBREV_I32;
end;
V_ADD_F32:
begin
_emit_V_ADD_F32;
end;
V_SUB_F32:
begin
_emit_V_SUB_F32;
end;
V_SUBREV_F32:
begin
_emit_V_SUBREV_F32;
end;
V_MUL_F32:
begin
_emit_V_MUL_F32;
end;
V_CVT_PKRTZ_F16_F32:
begin
_emit_V_CVT_PKRTZ_F16_F32;
end;
V_MAC_F32: //vdst = vsrc0.f * vsrc1.f + vdst.f -> fma
begin
_emit_V_MAC_F32;
end;
V_MADAK_F32:
begin
_emit_V_MADAK_F32;
end;
V_MADMK_F32:
begin
_emit_V_MADMK_F32;
end;
V_MIN_LEGACY_F32:_emit_V_MIN_MAX(GlslOp.NMin,dtFloat32);
V_MAX_LEGACY_F32:_emit_V_MIN_MAX(GlslOp.NMax,dtFloat32);
V_MIN_F32:_emit_V_MIN_MAX(GlslOp.FMin,dtFloat32);
V_MAX_F32:_emit_V_MIN_MAX(GlslOp.FMax,dtFloat32);
V_MIN_I32:_emit_V_MIN_MAX(GlslOp.SMin,dtInt32);
V_MAX_I32:_emit_V_MIN_MAX(GlslOp.SMax,dtInt32);
V_MIN_U32:_emit_V_MIN_MAX(GlslOp.UMin,dtUint32);
V_MAX_U32:_emit_V_MIN_MAX(GlslOp.UMax,dtUint32);
V_MIN_U32: emit_V_MMX(GlslOp.UMin,dtUint32);
V_MAX_U32: emit_V_MMX(GlslOp.UMax,dtUint32);
else
Assert(false,'VOP2?'+IntToStr(FSPI.VOP2.OP));

File diff suppressed because it is too large Load Diff

View File

@ -7,60 +7,59 @@ interface
uses
sysutils,
ps4_pssl,
srTypes,
srType,
srReg,
spirv,
SprvEmit,
emit_op;
emit_fetch;
type
TEmit_VOPC=object(TEmitOp)
procedure _emit_VOPC;
procedure _emit_V_CMP_32(OpId:DWORD;rtype:TsrDataType;x:Boolean);
procedure _emit_V_CMP_C(r,x:Boolean);
TEmit_VOPC=class(TEmitFetch)
procedure emit_VOPC;
procedure emit_V_CMP_32(OpId:DWORD;rtype:TsrDataType;x:Boolean);
procedure emit_V_CMP_C(r,x:Boolean);
end;
implementation
procedure TEmit_VOPC._emit_V_CMP_32(OpId:DWORD;rtype:TsrDataType;x:Boolean);
procedure TEmit_VOPC.emit_V_CMP_32(OpId:DWORD;rtype:TsrDataType;x:Boolean);
Var
dst:array[0..1] of PsrRegSlot;
src:array[0..1] of PsrRegNode;
begin
dst[0]:=@FRegsStory.VCC[0];
dst[1]:=@FRegsStory.VCC[1];
dst[0]:=get_vcc0;
dst[1]:=get_vcc1;
src[0]:=fetch_ssrc9(FSPI.VOPC.SRC0 ,rtype);
src[1]:=fetch_vsrc8(FSPI.VOPC.VSRC1,rtype);
emit_OpCmpV(OpId,dst[0],src[0],src[1]);
OpCmpV(OpId,dst[0],src[0],src[1]);
SetConst(dst[1],dtUnknow,0); //set zero
SetConst_q(dst[1],dtUnknow,0); //set zero
if x then
begin
MakeCopy(@FRegsStory.EXEC[0],dst[0]^.current);
SetConst(@FRegsStory.EXEC[1],dtUnknow,0); //set zero
MakeCopy(get_exec0,dst[0]^.current);
SetConst_q(get_exec1,dtUnknow,0); //set zero
end;
end;
procedure TEmit_VOPC._emit_V_CMP_C(r,x:Boolean);
procedure TEmit_VOPC.emit_V_CMP_C(r,x:Boolean);
Var
dst:array[0..1] of PsrRegSlot;
begin
dst[0]:=@FRegsStory.VCC[0];
dst[1]:=@FRegsStory.VCC[1];
dst[0]:=get_vcc0;
dst[1]:=get_vcc1;
SetConst(dst[0],dtBool,QWORD(r));
SetConst(dst[1],dtUnknow,0); //set zero
SetConst_b(dst[0],r);
SetConst_q(dst[1],dtUnknow,0); //set zero
if x then
begin
MakeCopy(@FRegsStory.EXEC[0],dst[0]^.current);
SetConst(@FRegsStory.EXEC[1],dtUnknow,0); //set zero
MakeCopy(get_exec0,dst[0]^.current);
SetConst_q(get_exec1,dtUnknow,0); //set zero
end;
end;
procedure TEmit_VOPC._emit_VOPC;
procedure TEmit_VOPC.emit_VOPC;
begin
Case FSPI.VOPC.OP of
@ -72,7 +71,7 @@ begin
V_CMP_F_U32,
V_CMP_F_U64,
V_CMPS_F_F32,
V_CMPS_F_F64:_emit_V_CMP_C(false,false);
V_CMPS_F_F64:emit_V_CMP_C(false,false);
V_CMP_T_F32,
V_CMP_T_F64,
@ -81,7 +80,7 @@ begin
V_CMP_T_U32,
V_CMP_T_U64,
V_CMPS_T_F32,
V_CMPS_T_F64:_emit_V_CMP_C(true,false);
V_CMPS_T_F64:emit_V_CMP_C(true,false);
V_CMPX_F_F32,
V_CMPX_F_F64,
@ -90,7 +89,7 @@ begin
V_CMPX_F_U32,
V_CMPX_F_U64,
V_CMPSX_F_F32,
V_CMPSX_F_F64:_emit_V_CMP_C(false,true);
V_CMPSX_F_F64:emit_V_CMP_C(false,true);
V_CMPX_T_F32,
V_CMPX_T_F64,
@ -99,101 +98,101 @@ begin
V_CMPX_T_U32,
V_CMPX_T_U64,
V_CMPSX_T_F32,
V_CMPSX_T_F64:_emit_V_CMP_C(true,true);
V_CMPSX_T_F64:emit_V_CMP_C(true,true);
//
V_CMP_LT_F32 :_emit_V_CMP_32(Op.OpFOrdLessThan ,dtFloat32,false);
V_CMP_EQ_F32 :_emit_V_CMP_32(Op.OpFOrdEqual ,dtFloat32,false);
V_CMP_LE_F32 :_emit_V_CMP_32(Op.OpFOrdLessThanEqual ,dtFloat32,false);
V_CMP_GT_F32 :_emit_V_CMP_32(Op.OpFOrdGreaterThan ,dtFloat32,false);
V_CMP_LG_F32 :_emit_V_CMP_32(Op.OpFOrdNotEqual ,dtFloat32,false);
V_CMP_GE_F32 :_emit_V_CMP_32(Op.OpFOrdGreaterThanEqual ,dtFloat32,false);
V_CMP_O_F32 :_emit_V_CMP_32(Op.OpOrdered ,dtFloat32,false);
V_CMP_U_F32 :_emit_V_CMP_32(Op.OpUnordered ,dtFloat32,false);
V_CMP_NGE_F32 :_emit_V_CMP_32(Op.OpFUnordLessThan ,dtFloat32,false);
V_CMP_NLG_F32 :_emit_V_CMP_32(Op.OpFUnordEqual ,dtFloat32,false);
V_CMP_NGT_F32 :_emit_V_CMP_32(Op.OpFUnordLessThanEqual ,dtFloat32,false);
V_CMP_NLE_F32 :_emit_V_CMP_32(Op.OpFUnordGreaterThan ,dtFloat32,false);
V_CMP_NEQ_F32 :_emit_V_CMP_32(Op.OpFUnordNotEqual ,dtFloat32,false);
V_CMP_NLT_F32 :_emit_V_CMP_32(Op.OpFUnordGreaterThanEqual,dtFloat32,false);
V_CMP_LT_F32 :emit_V_CMP_32(Op.OpFOrdLessThan ,dtFloat32,false);
V_CMP_EQ_F32 :emit_V_CMP_32(Op.OpFOrdEqual ,dtFloat32,false);
V_CMP_LE_F32 :emit_V_CMP_32(Op.OpFOrdLessThanEqual ,dtFloat32,false);
V_CMP_GT_F32 :emit_V_CMP_32(Op.OpFOrdGreaterThan ,dtFloat32,false);
V_CMP_LG_F32 :emit_V_CMP_32(Op.OpFOrdNotEqual ,dtFloat32,false);
V_CMP_GE_F32 :emit_V_CMP_32(Op.OpFOrdGreaterThanEqual ,dtFloat32,false);
V_CMP_O_F32 :emit_V_CMP_32(Op.OpOrdered ,dtFloat32,false);
V_CMP_U_F32 :emit_V_CMP_32(Op.OpUnordered ,dtFloat32,false);
V_CMP_NGE_F32 :emit_V_CMP_32(Op.OpFUnordLessThan ,dtFloat32,false);
V_CMP_NLG_F32 :emit_V_CMP_32(Op.OpFUnordEqual ,dtFloat32,false);
V_CMP_NGT_F32 :emit_V_CMP_32(Op.OpFUnordLessThanEqual ,dtFloat32,false);
V_CMP_NLE_F32 :emit_V_CMP_32(Op.OpFUnordGreaterThan ,dtFloat32,false);
V_CMP_NEQ_F32 :emit_V_CMP_32(Op.OpFUnordNotEqual ,dtFloat32,false);
V_CMP_NLT_F32 :emit_V_CMP_32(Op.OpFUnordGreaterThanEqual,dtFloat32,false);
V_CMPX_LT_F32 :_emit_V_CMP_32(Op.OpFOrdLessThan ,dtFloat32,true);
V_CMPX_EQ_F32 :_emit_V_CMP_32(Op.OpFOrdEqual ,dtFloat32,true);
V_CMPX_LE_F32 :_emit_V_CMP_32(Op.OpFOrdLessThanEqual ,dtFloat32,true);
V_CMPX_GT_F32 :_emit_V_CMP_32(Op.OpFOrdGreaterThan ,dtFloat32,true);
V_CMPX_LG_F32 :_emit_V_CMP_32(Op.OpFOrdNotEqual ,dtFloat32,true);
V_CMPX_GE_F32 :_emit_V_CMP_32(Op.OpFOrdGreaterThanEqual ,dtFloat32,true);
V_CMPX_O_F32 :_emit_V_CMP_32(Op.OpOrdered ,dtFloat32,true);
V_CMPX_U_F32 :_emit_V_CMP_32(Op.OpUnordered ,dtFloat32,true);
V_CMPX_NGE_F32 :_emit_V_CMP_32(Op.OpFUnordLessThan ,dtFloat32,true);
V_CMPX_NLG_F32 :_emit_V_CMP_32(Op.OpFUnordEqual ,dtFloat32,true);
V_CMPX_NGT_F32 :_emit_V_CMP_32(Op.OpFUnordLessThanEqual ,dtFloat32,true);
V_CMPX_NLE_F32 :_emit_V_CMP_32(Op.OpFUnordGreaterThan ,dtFloat32,true);
V_CMPX_NEQ_F32 :_emit_V_CMP_32(Op.OpFUnordNotEqual ,dtFloat32,true);
V_CMPX_NLT_F32 :_emit_V_CMP_32(Op.OpFUnordGreaterThanEqual,dtFloat32,true);
V_CMPX_LT_F32 :emit_V_CMP_32(Op.OpFOrdLessThan ,dtFloat32,true);
V_CMPX_EQ_F32 :emit_V_CMP_32(Op.OpFOrdEqual ,dtFloat32,true);
V_CMPX_LE_F32 :emit_V_CMP_32(Op.OpFOrdLessThanEqual ,dtFloat32,true);
V_CMPX_GT_F32 :emit_V_CMP_32(Op.OpFOrdGreaterThan ,dtFloat32,true);
V_CMPX_LG_F32 :emit_V_CMP_32(Op.OpFOrdNotEqual ,dtFloat32,true);
V_CMPX_GE_F32 :emit_V_CMP_32(Op.OpFOrdGreaterThanEqual ,dtFloat32,true);
V_CMPX_O_F32 :emit_V_CMP_32(Op.OpOrdered ,dtFloat32,true);
V_CMPX_U_F32 :emit_V_CMP_32(Op.OpUnordered ,dtFloat32,true);
V_CMPX_NGE_F32 :emit_V_CMP_32(Op.OpFUnordLessThan ,dtFloat32,true);
V_CMPX_NLG_F32 :emit_V_CMP_32(Op.OpFUnordEqual ,dtFloat32,true);
V_CMPX_NGT_F32 :emit_V_CMP_32(Op.OpFUnordLessThanEqual ,dtFloat32,true);
V_CMPX_NLE_F32 :emit_V_CMP_32(Op.OpFUnordGreaterThan ,dtFloat32,true);
V_CMPX_NEQ_F32 :emit_V_CMP_32(Op.OpFUnordNotEqual ,dtFloat32,true);
V_CMPX_NLT_F32 :emit_V_CMP_32(Op.OpFUnordGreaterThanEqual,dtFloat32,true);
//
V_CMPS_LT_F32 :_emit_V_CMP_32(Op.OpFOrdLessThan ,dtFloat32,false);
V_CMPS_EQ_F32 :_emit_V_CMP_32(Op.OpFOrdEqual ,dtFloat32,false);
V_CMPS_LE_F32 :_emit_V_CMP_32(Op.OpFOrdLessThanEqual ,dtFloat32,false);
V_CMPS_GT_F32 :_emit_V_CMP_32(Op.OpFOrdGreaterThan ,dtFloat32,false);
V_CMPS_LG_F32 :_emit_V_CMP_32(Op.OpFOrdNotEqual ,dtFloat32,false);
V_CMPS_GE_F32 :_emit_V_CMP_32(Op.OpFOrdGreaterThanEqual ,dtFloat32,false);
V_CMPS_O_F32 :_emit_V_CMP_32(Op.OpOrdered ,dtFloat32,false);
V_CMPS_U_F32 :_emit_V_CMP_32(Op.OpUnordered ,dtFloat32,false);
V_CMPS_NGE_F32 :_emit_V_CMP_32(Op.OpFUnordLessThan ,dtFloat32,false);
V_CMPS_NLG_F32 :_emit_V_CMP_32(Op.OpFUnordEqual ,dtFloat32,false);
V_CMPS_NGT_F32 :_emit_V_CMP_32(Op.OpFUnordLessThanEqual ,dtFloat32,false);
V_CMPS_NLE_F32 :_emit_V_CMP_32(Op.OpFUnordGreaterThan ,dtFloat32,false);
V_CMPS_NEQ_F32 :_emit_V_CMP_32(Op.OpFUnordNotEqual ,dtFloat32,false);
V_CMPS_NLT_F32 :_emit_V_CMP_32(Op.OpFUnordGreaterThanEqual,dtFloat32,false);
V_CMPS_LT_F32 :emit_V_CMP_32(Op.OpFOrdLessThan ,dtFloat32,false);
V_CMPS_EQ_F32 :emit_V_CMP_32(Op.OpFOrdEqual ,dtFloat32,false);
V_CMPS_LE_F32 :emit_V_CMP_32(Op.OpFOrdLessThanEqual ,dtFloat32,false);
V_CMPS_GT_F32 :emit_V_CMP_32(Op.OpFOrdGreaterThan ,dtFloat32,false);
V_CMPS_LG_F32 :emit_V_CMP_32(Op.OpFOrdNotEqual ,dtFloat32,false);
V_CMPS_GE_F32 :emit_V_CMP_32(Op.OpFOrdGreaterThanEqual ,dtFloat32,false);
V_CMPS_O_F32 :emit_V_CMP_32(Op.OpOrdered ,dtFloat32,false);
V_CMPS_U_F32 :emit_V_CMP_32(Op.OpUnordered ,dtFloat32,false);
V_CMPS_NGE_F32 :emit_V_CMP_32(Op.OpFUnordLessThan ,dtFloat32,false);
V_CMPS_NLG_F32 :emit_V_CMP_32(Op.OpFUnordEqual ,dtFloat32,false);
V_CMPS_NGT_F32 :emit_V_CMP_32(Op.OpFUnordLessThanEqual ,dtFloat32,false);
V_CMPS_NLE_F32 :emit_V_CMP_32(Op.OpFUnordGreaterThan ,dtFloat32,false);
V_CMPS_NEQ_F32 :emit_V_CMP_32(Op.OpFUnordNotEqual ,dtFloat32,false);
V_CMPS_NLT_F32 :emit_V_CMP_32(Op.OpFUnordGreaterThanEqual,dtFloat32,false);
V_CMPSX_LT_F32 :_emit_V_CMP_32(Op.OpFOrdLessThan ,dtFloat32,true);
V_CMPSX_EQ_F32 :_emit_V_CMP_32(Op.OpFOrdEqual ,dtFloat32,true);
V_CMPSX_LE_F32 :_emit_V_CMP_32(Op.OpFOrdLessThanEqual ,dtFloat32,true);
V_CMPSX_GT_F32 :_emit_V_CMP_32(Op.OpFOrdGreaterThan ,dtFloat32,true);
V_CMPSX_LG_F32 :_emit_V_CMP_32(Op.OpFOrdNotEqual ,dtFloat32,true);
V_CMPSX_GE_F32 :_emit_V_CMP_32(Op.OpFOrdGreaterThanEqual ,dtFloat32,true);
V_CMPSX_O_F32 :_emit_V_CMP_32(Op.OpOrdered ,dtFloat32,true);
V_CMPSX_U_F32 :_emit_V_CMP_32(Op.OpUnordered ,dtFloat32,true);
V_CMPSX_NGE_F32 :_emit_V_CMP_32(Op.OpFUnordLessThan ,dtFloat32,true);
V_CMPSX_NLG_F32 :_emit_V_CMP_32(Op.OpFUnordEqual ,dtFloat32,true);
V_CMPSX_NGT_F32 :_emit_V_CMP_32(Op.OpFUnordLessThanEqual ,dtFloat32,true);
V_CMPSX_NLE_F32 :_emit_V_CMP_32(Op.OpFUnordGreaterThan ,dtFloat32,true);
V_CMPSX_NEQ_F32 :_emit_V_CMP_32(Op.OpFUnordNotEqual ,dtFloat32,true);
V_CMPSX_NLT_F32 :_emit_V_CMP_32(Op.OpFUnordGreaterThanEqual,dtFloat32,true);
V_CMPSX_LT_F32 :emit_V_CMP_32(Op.OpFOrdLessThan ,dtFloat32,true);
V_CMPSX_EQ_F32 :emit_V_CMP_32(Op.OpFOrdEqual ,dtFloat32,true);
V_CMPSX_LE_F32 :emit_V_CMP_32(Op.OpFOrdLessThanEqual ,dtFloat32,true);
V_CMPSX_GT_F32 :emit_V_CMP_32(Op.OpFOrdGreaterThan ,dtFloat32,true);
V_CMPSX_LG_F32 :emit_V_CMP_32(Op.OpFOrdNotEqual ,dtFloat32,true);
V_CMPSX_GE_F32 :emit_V_CMP_32(Op.OpFOrdGreaterThanEqual ,dtFloat32,true);
V_CMPSX_O_F32 :emit_V_CMP_32(Op.OpOrdered ,dtFloat32,true);
V_CMPSX_U_F32 :emit_V_CMP_32(Op.OpUnordered ,dtFloat32,true);
V_CMPSX_NGE_F32 :emit_V_CMP_32(Op.OpFUnordLessThan ,dtFloat32,true);
V_CMPSX_NLG_F32 :emit_V_CMP_32(Op.OpFUnordEqual ,dtFloat32,true);
V_CMPSX_NGT_F32 :emit_V_CMP_32(Op.OpFUnordLessThanEqual ,dtFloat32,true);
V_CMPSX_NLE_F32 :emit_V_CMP_32(Op.OpFUnordGreaterThan ,dtFloat32,true);
V_CMPSX_NEQ_F32 :emit_V_CMP_32(Op.OpFUnordNotEqual ,dtFloat32,true);
V_CMPSX_NLT_F32 :emit_V_CMP_32(Op.OpFUnordGreaterThanEqual,dtFloat32,true);
//
V_CMP_LT_I32 :_emit_V_CMP_32(Op.OpSLessThan ,dtInt32,false);
V_CMP_EQ_I32 :_emit_V_CMP_32(Op.OpIEqual ,dtInt32,false);
V_CMP_LE_I32 :_emit_V_CMP_32(Op.OpSLessThanEqual ,dtInt32,false);
V_CMP_GT_I32 :_emit_V_CMP_32(Op.OpSGreaterThan ,dtInt32,false);
V_CMP_LG_I32 :_emit_V_CMP_32(Op.OpINotEqual ,dtInt32,false);
V_CMP_GE_I32 :_emit_V_CMP_32(Op.OpSGreaterThanEqual ,dtInt32,false);
V_CMP_LT_I32 :emit_V_CMP_32(Op.OpSLessThan ,dtInt32,false);
V_CMP_EQ_I32 :emit_V_CMP_32(Op.OpIEqual ,dtInt32,false);
V_CMP_LE_I32 :emit_V_CMP_32(Op.OpSLessThanEqual ,dtInt32,false);
V_CMP_GT_I32 :emit_V_CMP_32(Op.OpSGreaterThan ,dtInt32,false);
V_CMP_LG_I32 :emit_V_CMP_32(Op.OpINotEqual ,dtInt32,false);
V_CMP_GE_I32 :emit_V_CMP_32(Op.OpSGreaterThanEqual ,dtInt32,false);
V_CMPX_LT_I32 :_emit_V_CMP_32(Op.OpSLessThan ,dtInt32,true);
V_CMPX_EQ_I32 :_emit_V_CMP_32(Op.OpIEqual ,dtInt32,true);
V_CMPX_LE_I32 :_emit_V_CMP_32(Op.OpSLessThanEqual ,dtInt32,true);
V_CMPX_GT_I32 :_emit_V_CMP_32(Op.OpSGreaterThan ,dtInt32,true);
V_CMPX_LG_I32 :_emit_V_CMP_32(Op.OpINotEqual ,dtInt32,true);
V_CMPX_GE_I32 :_emit_V_CMP_32(Op.OpSGreaterThanEqual ,dtInt32,true);
V_CMPX_LT_I32 :emit_V_CMP_32(Op.OpSLessThan ,dtInt32,true);
V_CMPX_EQ_I32 :emit_V_CMP_32(Op.OpIEqual ,dtInt32,true);
V_CMPX_LE_I32 :emit_V_CMP_32(Op.OpSLessThanEqual ,dtInt32,true);
V_CMPX_GT_I32 :emit_V_CMP_32(Op.OpSGreaterThan ,dtInt32,true);
V_CMPX_LG_I32 :emit_V_CMP_32(Op.OpINotEqual ,dtInt32,true);
V_CMPX_GE_I32 :emit_V_CMP_32(Op.OpSGreaterThanEqual ,dtInt32,true);
V_CMP_LT_U32 :_emit_V_CMP_32(Op.OpULessThan ,dtUint32,false);
V_CMP_EQ_U32 :_emit_V_CMP_32(Op.OpIEqual ,dtUint32,false);
V_CMP_LE_U32 :_emit_V_CMP_32(Op.OpULessThanEqual ,dtUint32,false);
V_CMP_GT_U32 :_emit_V_CMP_32(Op.OpUGreaterThan ,dtUint32,false);
V_CMP_LG_U32 :_emit_V_CMP_32(Op.OpINotEqual ,dtUint32,false);
V_CMP_GE_U32 :_emit_V_CMP_32(Op.OpUGreaterThanEqual ,dtUint32,false);
V_CMP_LT_U32 :emit_V_CMP_32(Op.OpULessThan ,dtUint32,false);
V_CMP_EQ_U32 :emit_V_CMP_32(Op.OpIEqual ,dtUint32,false);
V_CMP_LE_U32 :emit_V_CMP_32(Op.OpULessThanEqual ,dtUint32,false);
V_CMP_GT_U32 :emit_V_CMP_32(Op.OpUGreaterThan ,dtUint32,false);
V_CMP_LG_U32 :emit_V_CMP_32(Op.OpINotEqual ,dtUint32,false);
V_CMP_GE_U32 :emit_V_CMP_32(Op.OpUGreaterThanEqual ,dtUint32,false);
V_CMPX_LT_U32 :_emit_V_CMP_32(Op.OpULessThan ,dtUint32,true);
V_CMPX_EQ_U32 :_emit_V_CMP_32(Op.OpIEqual ,dtUint32,true);
V_CMPX_LE_U32 :_emit_V_CMP_32(Op.OpULessThanEqual ,dtUint32,true);
V_CMPX_GT_U32 :_emit_V_CMP_32(Op.OpUGreaterThan ,dtUint32,true);
V_CMPX_LG_U32 :_emit_V_CMP_32(Op.OpINotEqual ,dtUint32,true);
V_CMPX_GE_U32 :_emit_V_CMP_32(Op.OpUGreaterThanEqual ,dtUint32,true);
V_CMPX_LT_U32 :emit_V_CMP_32(Op.OpULessThan ,dtUint32,true);
V_CMPX_EQ_U32 :emit_V_CMP_32(Op.OpIEqual ,dtUint32,true);
V_CMPX_LE_U32 :emit_V_CMP_32(Op.OpULessThanEqual ,dtUint32,true);
V_CMPX_GT_U32 :emit_V_CMP_32(Op.OpUGreaterThan ,dtUint32,true);
V_CMPX_LG_U32 :emit_V_CMP_32(Op.OpINotEqual ,dtUint32,true);
V_CMPX_GE_U32 :emit_V_CMP_32(Op.OpUGreaterThanEqual ,dtUint32,true);
else
Assert(false,'VOPC?');

View File

@ -1,4 +1,4 @@
unit srNodes;
unit ginodes;
{$mode objfpc}{$H+}
@ -45,45 +45,7 @@ type
procedure Insert(new:PNode);
end;
TsrNodeType=(
ntUnknow,
ntLiteral,
ntString,
ntConst,
ntType,
ntLabel,
ntBlock,
ntFunc,
ntVar,
ntRefId,
ntOp,
ntReg,
ntVolatile,
ntInput,
ntVertLayout,
ntFragLayout,
ntOutput,
ntChain,
ntUniform,
ntBuffer
);
TOpParamSingle=packed object
ntype:TsrNodeType;
pData:Pointer;
procedure SetParam(_ntype:TsrNodeType;_Data:Pointer);
function AsConst:Pointer;
function AsOp:Pointer;
function AsReg:Pointer;
function AsVar:Pointer;
function AsBlock:Pointer;
function AsInput:Pointer;
function AsRefId:Pointer;
function AsUniform:Pointer;
end;
TfnAlloc=Function(Size:ptruint):Pointer of object;
function ComparePChar(buf1,buf2:PChar):Integer;
function ComparePtruint(buf1,buf2:PPtruint;count:PtrUint):Integer;
implementation
@ -169,10 +131,7 @@ function TNodeFetch.Next(node:PNode):PNode;
begin
Result:=nil;
if (pRoot=nil) or (node=nil) then Exit;
if (node^.pRight=nil) then
begin
_Splay(node);
end;
_Splay(node);
node:=node^.pRight;
While (node<>nil) do
begin
@ -185,10 +144,7 @@ function TNodeFetch.Prev(node:PNode):PNode;
begin
Result:=nil;
if (pRoot=nil) or (node=nil) then Exit;
if (node^.pLeft=nil) then
begin
_Splay(node);
end;
_Splay(node);
node:=node^.pLeft;
While (node<>nil) do
begin
@ -483,74 +439,32 @@ begin
end;
end;
procedure TOpParamSingle.SetParam(_ntype:TsrNodeType;_Data:Pointer);
begin
ntype:=_ntype;
pData:=_Data;
end;
//
function TOpParamSingle.AsConst:Pointer;
function ComparePChar(buf1,buf2:PChar):Integer;
begin
Result:=nil;
if (@Self=nil) then Exit;
if (ntype<>ntConst) then Exit;
Result:=pData;
end;
function TOpParamSingle.AsOp:Pointer;
begin
Result:=nil;
if (@Self=nil) then Exit;
if (ntype<>ntOp) then Exit;
Result:=pData;
end;
function TOpParamSingle.AsReg:Pointer;
begin
Result:=nil;
if (@Self=nil) then Exit;
if (ntype<>ntReg) then Exit;
Result:=pData;
end;
function TOpParamSingle.AsVar:Pointer;
begin
Result:=nil;
if (@Self=nil) then Exit;
if (ntype<>ntVar) then Exit;
Result:=pData;
end;
function TOpParamSingle.AsBlock:Pointer;
begin
Result:=nil;
if (@Self=nil) then Exit;
if (ntype<>ntBlock) then Exit;
Result:=pData;
end;
function TOpParamSingle.AsInput:Pointer;
begin
Result:=nil;
if (@Self=nil) then Exit;
if (ntype<>ntInput) then Exit;
Result:=pData;
end;
function TOpParamSingle.AsRefId:Pointer;
begin
Result:=nil;
if (@Self=nil) then Exit;
if (ntype<>ntRefId) then Exit;
Result:=pData;
end;
function TOpParamSingle.AsUniform:Pointer;
begin
Result:=nil;
if (@Self=nil) then Exit;
if (ntype<>ntUniform) then Exit;
Result:=pData;
Result:=0;
if (buf1=nil) and (buf2=nil) then
begin
Exit;
end else
if (buf1=nil) then
begin
Result:=-Integer(buf2^);
end else
if (buf2=nil) then
begin
Result:=Integer(buf1^);
end else
begin
While true do
begin
Result:=Integer(buf1^)-Integer(buf2^);
if (Result<>0) or (buf1^=#0) or (buf2^=#0) then Exit;
Inc(buf1);
Inc(buf2);
end;
end;
end;
function ComparePtruint(buf1,buf2:PPtruint;count:PtrUint):Integer;

View File

@ -25,7 +25,7 @@
<RunParams>
<FormatVersion Value="2"/>
</RunParams>
<Units Count="49">
<Units Count="50">
<Unit0>
<Filename Value="pssl-spirv.lpr"/>
<IsPartOfProject Value="True"/>
@ -239,6 +239,10 @@
<Filename Value="emit_bin.pas"/>
<IsPartOfProject Value="True"/>
</Unit48>
<Unit49>
<Filename Value="srConfig.pas"/>
<IsPartOfProject Value="True"/>
</Unit49>
</Units>
</ProjectOptions>
<CompilerOptions>
@ -263,7 +267,7 @@
</CodeGeneration>
<Linking>
<Debugging>
<DebugInfoType Value="dsDwarf2Set"/>
<DebugInfoType Value="dsDwarf2"/>
<UseLineInfoUnit Value="False"/>
</Debugging>
<LinkSmart Value="True"/>

View File

@ -7,8 +7,8 @@ Uses
si_ci_vi_merged_registers,
ps4_pssl,
ps4_shader,
//spirv,
srBuffer,
srConfig,
SprvEmit,
emit_post,
@ -21,13 +21,9 @@ var
FName:RawByteString;
FSave:RawByteString;
FPrintInfo:Boolean;
FPrintAsm:Boolean;
FPrintSpv:Boolean;
FUseVertexInput:Boolean;
FUseTexelBuffer:Boolean;
FUseOutput16:Boolean;
BufferCfg:TsrBufferCfg;
//
cfg:TsrConfig;
end;
type
@ -35,67 +31,12 @@ type
REG,COUNT:WORD;
end;
{
procedure load_spv(const fname:RawByteString);
var
M:TMemoryStream;
Header:TSPIRVHeader;
DW:TSPIRVInstruction;
label
_exit;
begin
M:=TMemoryStream.Create;
M.LoadFromFile(fname);
M.Position:=0;
Header:=Default(TSPIRVHeader);
M.Read(Header,SizeOf(TSPIRVHeader));
if (Header.MAGIC<>spirv.MagicNumber) then Goto _exit;
Writeln(HexStr(Header.TOOL_ID,8));
DW:=Default(TSPIRVInstruction);
repeat
if M.Read(DW,SizeOf(TSPIRVInstruction))<>SizeOf(TSPIRVInstruction) then Break;
Writeln(spirv.Op.GetStr(DW.OP));
if (DW.COUNT>1) then
begin
M.Seek(SizeOf(DWORD)*(DW.COUNT-1),soCurrent);
end;
until false;
_exit:
M.Free;
end;
}
procedure post_SprvEmit(var SprvEmit:TSprvEmit);
begin
TSprvEmit_post(SprvEmit).Post;
end;
procedure alloc_SprvEmit(var SprvEmit:TSprvEmit);
begin
TSprvEmit_alloc(SprvEmit).Alloc;
end;
procedure print_SprvEmit(var SprvEmit:TSprvEmit);
begin
TSprvEmit_print(SprvEmit).Print;
end;
procedure SaveToStream_SprvEmit(Stream:TStream;var SprvEmit:TSprvEmit);
begin
TSprvEmit_bin(SprvEmit).SaveToStream(Stream);
end;
procedure SaveToFile_SprvEmit(const FName:RawByteString;var SprvEmit:TSprvEmit);
procedure SaveToFile_Spv(const FName:RawByteString;var SprvEmit:TSprvEmit);
var
F:TFileStream;
begin
F:=TFileStream.Create(FName,fmCreate);
SaveToStream_SprvEmit(F,SprvEmit);
SprvEmit.SaveToStream(F);
F.Free;
end;
@ -325,9 +266,6 @@ var
SprvEmit:TSprvEmit;
//LParser:TsrLParser;
//FCode:TsrCodeBlock;
i:Byte;
begin
@ -410,6 +348,8 @@ begin
Assert(info<>nil);
SprvEmit:=TSprvEmit.Create;
case info^.m_type of
kShaderTypePs :
begin
@ -444,39 +384,34 @@ begin
end;
end;
SprvEmit.FPrintAsm :=cfg.FPrintAsm;
SprvEmit.FUseVertexInput:=cfg.FUseVertexInput;
SprvEmit.FUseTexelBuffer:=cfg.FUseTexelBuffer;
SprvEmit.FUseOutput16 :=cfg.FUseOutput16;
SprvEmit.Config:=cfg.cfg;
SprvEmit.FBuffers.cfg:=cfg.BufferCfg;
if (SprvEmit.Parse(base)>1) then
if (SprvEmit.ParseStage(base)>1) then
begin
Writeln(StdErr,'Shader Parse Err');
end;
if cfg.FPrintAsm or cfg.FPrintSpv or (cfg.FSave<>'') then
if cfg.cfg.PrintAsm or cfg.FPrintSpv or (cfg.FSave<>'') then
begin
post_SprvEmit(SprvEmit);
alloc_SprvEmit(SprvEmit);
SprvEmit.PostStage;
SprvEmit.AllocStage;
end;
if cfg.FPrintSpv then
begin
print_SprvEmit(SprvEmit);
SprvEmit.Print;
Writeln;
end;
if (cfg.FSave<>'') then
begin
SaveToFile_SprvEmit(cfg.FSave,SprvEmit);
SaveToFile_Spv(cfg.FSave,SprvEmit);
end;
if cfg.FPrintInfo then
Writeln('used_size=',SprvEmit.FAllocator.used_size);
Writeln('used_size=',SprvEmit.Allocator.used_size);
SprvEmit.FAllocator.Free;
SprvEmit.Free;
end;
function ParseCmd:Boolean;
@ -492,25 +427,28 @@ begin
Exit(False);
end;
cfg.FUseVertexInput:=True;
cfg.BufferCfg.Init;
cfg.FName:='';
cfg.FSave:='';
cfg.FPrintInfo:=False;
cfg.FPrintSpv :=False;
cfg.cfg.Init;
n:=-1;
For i:=1 to ParamCount do
begin
case LowerCase(ParamStr(i)) of
'-i':cfg.FPrintInfo:=True;
'-a':cfg.FPrintAsm:=True;
'-a':cfg.cfg.PrintAsm:=True;
'-p':cfg.FPrintSpv:=True;
'-eva':cfg.FUseVertexInput:=True;
'-dva':cfg.FUseVertexInput:=False;
'-eva':cfg.cfg.UseVertexInput:=True;
'-dva':cfg.cfg.UseVertexInput:=False;
'-etb':cfg.FUseTexelBuffer:=True;
'-dtb':cfg.FUseTexelBuffer:=False;
'-etb':cfg.cfg.UseTexelBuffer:=True;
'-dtb':cfg.cfg.UseTexelBuffer:=False;
'-eoh':cfg.FUseOutput16:=True;
'-doh':cfg.FUseOutput16:=False;
'-eoh':cfg.cfg.UseOutput16:=True;
'-doh':cfg.cfg.UseOutput16:=False;
'-b':n:=0;
@ -525,11 +463,11 @@ begin
Case n of
-1:cfg.FName:=ParamStr(i);
0:cfg.FSave:=ParamStr(i);
1:cfg.BufferCfg.maxUniformBufferRange :=StrToInt64Def(ParamStr(i),0);
2:cfg.BufferCfg.PushConstantsOffset :=StrToInt64Def(ParamStr(i),0);
3:cfg.BufferCfg.maxPushConstantsSize :=StrToInt64Def(ParamStr(i),0);
4:cfg.BufferCfg.minStorageBufferOffsetAlignment:=StrToInt64Def(ParamStr(i),0);
5:cfg.BufferCfg.minUniformBufferOffsetAlignment:=StrToInt64Def(ParamStr(i),0);
1:cfg.cfg.maxUniformBufferRange :=StrToInt64Def(ParamStr(i),0);
2:cfg.cfg.PushConstantsOffset :=StrToInt64Def(ParamStr(i),0);
3:cfg.cfg.maxPushConstantsSize :=StrToInt64Def(ParamStr(i),0);
4:cfg.cfg.minStorageBufferOffsetAlignment:=StrToInt64Def(ParamStr(i),0);
5:cfg.cfg.minUniformBufferOffsetAlignment:=StrToInt64Def(ParamStr(i),0);
end;
n:=-1;
end;
@ -552,81 +490,47 @@ begin
if (cfg.FName='') then
begin
//loadspv('vert.spv');
//branch adr
//load_dump('shader_dump\MomodoraRUtM\MomodoraRUtM_ps_595F5E5D.dump');
//load_dump('shader_dump\MomodoraRUtM\MomodoraRUtM_vs_B9E80F51.dump');
//load_dump('shader_dump\MomodoraRUtM\MomodoraRUtM_vs_72685B15.dump');
//branch
//load_dump('shader_dump\tutorial_anti-aliasing_debug\tutorial_anti-aliasing_debug_cs_3685EFC7.dump');
//branch
//load_dump('shader_dump\tutorial_anti-aliasing_debug\tutorial_anti-aliasing_debug_ps_8D309F69.dump');
//load_dump('shader_dump\tutorial_anti-aliasing_debug\tutorial_anti-aliasing_debug_ps_30AC6582.dump');
//V_MED3_F32
//load_dump('shader_dump\tutorial_anti-aliasing_debug\tutorial_anti-aliasing_debug_ps_46F7D0CB.dump');
//branch
//load_dump('shader_dump\tutorial_anti-aliasing_debug\tutorial_anti-aliasing_debug_ps_897BFEFF.dump');
//load_dump('shader_dump\tutorial_anti-aliasing_debug\tutorial_anti-aliasing_debug_ps_A9A43387.dump');
//load_dump('shader_dump\tutorial_anti-aliasing_debug\tutorial_anti-aliasing_debug_ps_BD5B57D5.dump');
//load_dump('shader_dump\tutorial_anti-aliasing_debug\tutorial_anti-aliasing_debug_ps_C342C7CD.dump');
//V_MED3_F32
//load_dump('shader_dump\tutorial_anti-aliasing_debug\tutorial_anti-aliasing_debug_ps_E125C5F7.dump');
//branch cycle
//load_dump('shader_dump\tutorial_anti-aliasing_debug\tutorial_anti-aliasing_debug_ps_E820FFDE.dump');
//load_dump('shader_dump\tutorial_anti-aliasing_debug\tutorial_anti-aliasing_debug_vs_1CE5C47E.dump');
//load_dump('shader_dump\tutorial_anti-aliasing_debug\tutorial_anti-aliasing_debug_vs_22E9CA76.dump');
//load_dump('shader_dump\tutorial_anti-aliasing_debug\tutorial_anti-aliasing_debug_vs_48FA7A4C.dump');
//load_dump('shader_dump\tutorial_anti-aliasing_debug\tutorial_anti-aliasing_debug_vs_243D8C75.dump');
//load_dump('shader_dump\tutorial_anti-aliasing_debug\tutorial_anti-aliasing_debug_vs_B4E470AF.dump');
//load_dump('shader_dump\tutorial_anti-aliasing_debug\tutorial_anti-aliasing_debug_vs_E1C90BE3.dump');
//branch
////load_dump('shader_dump\WeAreDoomed\WeAreDoomed_ps4_cs_FEA061C5.dump');
//load_dump('shader_dump\simplet-single-triangle_debug\simplet-single-triangle_debug_vs_78EF9008.dump');
//load_dump('shader_dump\simplet-single-triangle_debug\simplet-single-triangle_debug_ps_FBCA196D.dump');
//load_dump('shader_dump\simplet-simple-fs_debug\simplet-simple-fs_debug_vs_398C5BF6.dump');
//load_dump('shader_dump\simplet-simple-fs_debug\simplet-simple-fs_debug_ps_F327ABD1.dump');
//load_dump('shader_dump\simplet-single-triangle_debug\simplet-single-triangle_debug_vs_78EF9008.dump');
load_dump('shader_dump\simplet-single-triangle_debug\simplet-single-triangle_debug_ps_FBCA196D.dump');
//load_dump('shader_dump\WeAreDoomed\WeAreDoomed_ps4_cs_FEA061C5.dump');
//load_dump('shader_dump\WeAreDoomed\WeAreDoomed_ps4_ps_B9680888.dump');
//load_dump('shader_dump\WeAreDoomed\WeAreDoomed_ps4_ps_BA60EAD7.dump');
//load_dump('shader_dump\WeAreDoomed\WeAreDoomed_ps4_vs_0C420DE0.dump');
//load_dump('shader_dump\basic_quad_debug\basic_quad_debug_ps_C342C7CD.dump');
//load_dump('shader_dump\basic_quad_debug\basic_quad_debug_vs_D216FEB8.dump');
//load_dump('shader_dump\basic_quad_debug\basic_quad_debug_cs_3685EFC7.dump');
load_dump('shader_dump\basic-sample\basic-sample_debug_ps_E125C5F7.dump');
//load_dump('shader_dump\basic_quad_debug\basic_quad_debug_ps_A9F64695.dump');
//load_dump('shader_dump\basic_quad_debug\basic_quad_debug_vs_B4E470AF.dump');
//load_dump('shader_dump\basic_quad_debug\basic_quad_debug_vs_1CE5C47E.dump');
//load_dump('shader_dump\basic-compute_debug\basic-compute_debug_ps_4BD7E17E.dump');
//load_dump('shader_dump\basic-compute_debug\basic-compute_debug_vs_0C30DA0F.dump');
//load_dump('shader_dump\SonicMania\SonicMania_ps_0C48E8B2.dump');
//load_dump('shader_dump\SonicMania\SonicMania_ps_B4281DBF.dump');
//load_dump('shader_dump\basic_quad_debug\basic_quad_debug_cs_3685EFC7.dump');
//load_dump('shader_dump\SonicMania\SonicMania_ps_11DF2A32.dump');
//load_dump('shader_dump\SonicMania\SonicMania_ps_3CC22A00.dump');
//load_dump('shader_dump\SonicMania\SonicMania_ps_3CC22A00.dump'); //cfg
//load_dump('shader_dump\MomodoraRUtM\MomodoraRUtM_ps_595F5E5D.dump');
load_dump('shader_dump\MomodoraRUtM\MomodoraRUtM_ps_B42E92C3.dump');
//load_dump('shader_dump\MomodoraRUtM\MomodoraRUtM_vs_B9E80F51.dump');
//load_dump('shader_dump\basic-sample\basic-sample_debug_cs_4303E70D.dump');
//load_dump('shader_dump\basic-sample\basic-sample_debug_cs_C4EA2D91.dump');
//load_dump('shader_dump\Cladun_Returns\ClassicDungeon3ORBIS_ps_B2ED8D0C.dump');
//load_dump('shader_dump\Cladun_Returns\ClassicDungeon3ORBIS_ps_B39D802A.dump');
//load_dump('shader_dump\depth-mode-sample\depth-mode-sample_debug_ps_E125C5F7.dump');
//load_dump('shader_dump\tutorial_anti-aliasing_debug\tutorial_anti-aliasing_debug_ps_E820FFDE.dump');
//load_dump('shader_dump\JETPACKJOYRIDE\mgjp_cs_2D246406.dump');
end;
if (cfg.FName<>'') then
begin
load_dump(cfg.FName);
end;
load_pssl(GPU_REGS.CS.Addr);
@ -634,7 +538,9 @@ begin
load_pssl(GPU_REGS.PS.Addr);
if cfg.FPrintInfo then
begin
readln;
end;
end.
{

View File

@ -5,7 +5,7 @@ unit srAllocator;
interface
uses
srNodes;
ginodes;
type
PsrAllocNode=^TsrAllocNode;

View File

@ -5,11 +5,11 @@ unit srBitcast;
interface
uses
sysutils,
srNodes,
srTypes,
srConst,
srReg;
ginodes,
srNode,
srType,
srConst,
srReg;
type
PsrBitcast=^TsrBitcast;
@ -24,27 +24,34 @@ type
function c(n1,n2:PsrBitcast):Integer; static;
end;
PsrBitcastList=^TsrBitcastList;
TsrBitcastList=object
type
TNodeFetch=specialize TNodeFetch<PsrBitcast,TsrBitcast>;
var
pRoot:Pointer;
FNTree:TNodeFetch;
function Find(dtype:TsrDataType;src:PsrRegNode):PsrBitcast;
function FetchRead(dtype:TsrDataType;src:PsrRegNode):PsrRegNode;
function FetchDst(dtype:TsrDataType;src:PsrRegNode):PsrRegNode;
function FetchCast(dtype:TsrDataType;src:PsrRegNode):PsrRegNode;
rSlot:TsrRegSlot;
procedure Init(Emit:TCustomEmit); inline;
function Find(dtype:TsrDataType;src:PsrRegNode):PsrBitcast;
function FetchRead(dtype:TsrDataType;src:PsrRegNode):PsrRegNode;
function FetchDstr(dtype:TsrDataType;src:PsrRegNode):PsrRegNode;
function FetchCast(dtype:TsrDataType;src:PsrRegNode):PsrRegNode;
end;
implementation
uses
SprvEmit,
emit_op;
function TsrBitcast.c(n1,n2:PsrBitcast):Integer;
begin
Result:=CompareByte(n1^.key,n2^.key,SizeOf(TsrBitcast.key));
//first dtype
Result:=Integer(n1^.key.dtype>n2^.key.dtype)-Integer(n1^.key.dtype<n2^.key.dtype);
if (Result<>0) then Exit;
//second src
Result:=Integer(n1^.key.src>n2^.key.src)-Integer(n1^.key.src<n2^.key.src);
end;
procedure TsrBitcastList.Init(Emit:TCustomEmit); inline;
begin
rSlot.Init(Emit,'BCAST');
end;
function TsrBitcastList.Find(dtype:TsrDataType;src:PsrRegNode):PsrBitcast;
@ -63,37 +70,33 @@ var
begin
Result:=src;
if (src=nil) then Exit;
if (dtype=dtUnknow) or (dtype=src^.dtype) then
begin
src^.mark_read;
Exit;
end;
if (dtype=dtUnknow) or (dtype=src^.dtype) then Exit;
src^.mark_read;
dst:=PSprvEmit(pRoot)^.NewReg(dtype);
dst^.pLine:=src^.pLine;
dst^.SetReg(src);
dst:=rSlot.New(src^.pLine,dtype);
dst^.pWriter:=src;
dst^.mark_read;
Result:=dst;
end;
function TsrBitcastList.FetchDst(dtype:TsrDataType;src:PsrRegNode):PsrRegNode;
function TsrBitcastList.FetchDstr(dtype:TsrDataType;src:PsrRegNode):PsrRegNode;
var
dst:PsrRegNode;
begin
Result:=src;
if (src=nil) then Exit;
if (dtype=dtUnknow) or (dtype=src^.dtype) then Exit;
Result:=PSprvEmit(pRoot)^.NewReg(dtype);
Result^.pLine:=src^.pLine;
Result^.mark_read;
dst:=rSlot.New(src^.pLine,dtype);
dst^.pWriter:=src^.pWriter;
Result^.pWriter:=src^.pWriter;
src^.SetReg(Result);
src^.pWriter:=dst;
Result:=dst;
end;
function TsrBitcastList.FetchCast(dtype:TsrDataType;src:PsrRegNode):PsrRegNode;
var
pConstList:PsrConstList;
node:PsrBitcast;
dst:PsrRegNode;
pConst:PsrConst;
@ -101,52 +104,46 @@ var
begin
Result:=src;
if (src=nil) then Exit;
if (dtype=dtUnknow) or (dtype=src^.dtype) then
begin
src^.mark_read;
Exit;
end;
if (dtype=dtUnknow) or (dtype=src^.dtype) then Exit;
dst:=nil;
node:=Find(dtype,src);
if (node<>nil) then
begin
dst:=node^.dst;
dst^.mark_read;
Result:=dst;
Result:=node^.dst;
Exit;
end;
if src^.is_const then
begin
pConst:=src^.AsConst;
pConst^.mark_unread;
dst:=PSprvEmit(pRoot)^.NewReg(dtype);
dst^.pLine:=src^.pLine;
dst^.SetConst(PSprvEmit(pRoot)^.FConsts.Bitcast(dtype,pConst))
pConstList:=rSlot.FEmit.GetConstList;
pConst:=pConstList^.Bitcast(dtype,pConst);
dst:=rSlot.New(src^.pLine,dtype);
dst^.pWriter:=pConst;
end else
begin
if TryBitcastType(src^.dtype,dtype) then
begin
src^.mark_read;
dst:=PSprvEmit(pRoot)^.NewReg(dtype);
dst^.pLine:=src^.pLine;
PEmitOp(pRoot)^.emit_OpCastExt(src^.pLine,dst,src);
dst:=rSlot.New(src^.pLine,dtype);
rSlot.FEmit.OpCast(src^.pLine,dst,src)
end else
begin
Assert(false,'bitcast');
end;
end;
node:=PSprvEmit(pRoot)^.Alloc(SizeOf(TsrBitcast));
node:=rSlot.FEmit.Alloc(SizeOf(TsrBitcast));
node^:=Default(TsrBitcast);
node^.key.dtype:=dtype;
node^.key.src:=src;
node^.dst:=dst;
FNTree.Insert(node);
dst^.mark_read;
Result:=dst;
end;

View File

@ -5,14 +5,23 @@ unit srBuffer;
interface
uses
spirv,
srNodes,
srTypes,
srVariable,
srLayout,
srDecorate;
sysutils,
spirv,
ginodes,
srNode,
srType,
srTypes,
srVariable,
srLayout,
srDecorate,
srConfig;
type
ntBuffer=class(ntDescriptor)
class Function pwrite_count (node:PsrNode):PDWORD; override;
class function GetStorageName(node:PsrNode):RawByteString; override;
end;
PsrBuffer=^TsrBuffer;
PsrField=^TsrField;
@ -33,7 +42,7 @@ type
//----
pBuffer:PsrBuffer;
parent:PsrField;
pParent:PsrField;
offset:PtrUint;
size:PtrUint;
stride:PtrUint;
@ -45,7 +54,6 @@ type
//
Alloc:TfnAlloc;
FList:TFieldFetch;
function c(n1,n2:PsrField):Integer; static;
@ -60,80 +68,90 @@ type
function FetchValue(_offset,_size:PtrUint;_dtype:TsrDataType):TFieldFetchValue;
function FetchRuntimeArray(_offset,_stride:PtrUint):TFieldFetchValue;
function IsStructUsedRuntimeArray:Boolean;
function IsStructNotUsed:Boolean;
function IsStructNotUsed:Boolean; inline;
function IsTop:Boolean; inline;
function GetStructDecorate:DWORD;
procedure UpdateSize;
function GetSize:PtrUint;
procedure FillNode(o,s:PtrUint);
function FillSpace:Integer;
procedure AllocID;
procedure AllocBinding(aType:PsrType;Decorates:PsrDecorateList);
end;
TsrBufferType=(btStorageBuffer,btUniformBuffer,btPushConstant);
TsrBuffer=object(TsrDescriptor)
TsrBuffer=packed object(TsrDescriptor)
pLeft,pRight:PsrBuffer;
//----
fwrite_count:DWORD;
fchain_read :DWORD;
fchain_write:DWORD;
//
align_offset:DWORD;
key:packed record
pLayout:PsrDataLayout;
CastNum:PtrInt;
end;
FEmit:TCustomEmit;
bType:TsrBufferType;
write_count:DWORD;
align_offset:DWORD;
key:packed record
pLayout:PsrDataLayout;
AliasId:PtrInt;
end;
FTop:TsrField;
function c(n1,n2:PsrBuffer):Integer; static;
Procedure Init(Emit:TCustomEmit); inline;
function GetStorageName:RawByteString;
function GetTypeChar:Char;
function GetString:RawByteString;
function GetStructName:RawByteString;
procedure UpdateSize;
function GetSize:PtrUint;
procedure TakeChain(node:PsrChain);
procedure EnumAllField(cb:TFieldEnumCb);
procedure ShiftOffset(Offset:PtrUint);
end;
TsrBufferCfg=object
SpvVersion:PtrUint;
maxUniformBufferRange:PtrUint; // $FFFF
PushConstantsOffset:PtrUint; // 0
maxPushConstantsSize:PtrUint; // 128
minStorageBufferOffsetAlignment:PtrUint; // $10
minUniformBufferOffsetAlignment:PtrUint; // $100
Procedure Init;
Function CanUseStorageBufferClass:Boolean;
end;
PsrBufferList=^TsrBufferList;
TsrBufferList=object
type
TNodeFetch=specialize TNodeFetch<PsrBuffer,TsrBuffer>;
var
Alloc:TfnAlloc;
cfg:TsrBufferCfg;
FEmit:TCustomEmit;
FNTree:TNodeFetch;
FPushConstant:PsrBuffer;
procedure Init(cb:TfnAlloc);
procedure Init(Emit:TCustomEmit); inline;
function Fetch(s:PsrDataLayout;n:PtrInt):PsrBuffer;
function NextCast(buf:PsrBuffer):PsrBuffer;
function NextAlias(buf:PsrBuffer):PsrBuffer;
Function First:PsrBuffer;
Function Next(node:PsrBuffer):PsrBuffer;
procedure EnumAllField(cb:TFieldEnumCb);
procedure OnFillSpace(node:PsrField);
procedure FillSpace;
procedure OnAllocID(node:PsrField);
procedure OnAllocID(pField:PsrField);
procedure AllocID;
procedure AllocBinding(Var FBinding:Integer;Decorates:PsrDecorateList);
procedure AllocSourceExtension(FDebugInfo:PsrDebugInfoList);
procedure UpdateStorage(node:PsrChain;pBuffer:PsrBuffer);
procedure AllocBinding(Var FBinding:Integer);
procedure AllocSourceExtension;
function FindUserDataBuf:PsrBuffer;
procedure ApplyBufferType;
procedure AlignOffset(node:PsrBuffer;offset:PtrUint);
procedure AlignOffset;
procedure OnAllocTypeBinding(pField:PsrField);
procedure AllocTypeBinding;
procedure AllocName;
end;
implementation
class Function ntBuffer.pwrite_count(node:PsrNode):PDWORD;
begin
Result:=@PsrBuffer(node)^.fwrite_count;
end;
class function ntBuffer.GetStorageName(node:PsrNode):RawByteString;
begin
Result:=PsrBuffer(node)^.GetStorageName;
end;
//---
function TsrField.c(n1,n2:PsrField):Integer;
@ -194,12 +212,12 @@ begin
Result:=FList.Find(@node);
if (Result=nil) then
begin
Result:=Alloc(SizeOf(TsrField));
Result^.Alloc:=Alloc;
Assert(pBuffer^.FEmit<>nil);
Result:=pBuffer^.FEmit.Alloc(SizeOf(TsrField));
Result^.pBuffer:=pBuffer;
Result^.parent:=@Self;
Result^.offset:=o;
Result^.FID:=-1;
Result^.pParent:=@Self;
Result^.offset :=o;
Result^.FID :=-1;
FList.Insert(Result);
Inc(FCount);
end;
@ -213,9 +231,9 @@ begin
Result:=Default(TFieldFetchValue);
_stride:=0;
if isVector(_dtype) then
if _dtype.isVector then
begin
_stride:=BitSizeType(GetVecChild(_dtype)) div 8;
_stride:=_dtype.Child.BitSize div 8;
end;
node:=Find_le(_offset);
@ -262,9 +280,9 @@ begin
end;
else
begin
if isVector(node^.dtype) then
if node^.dtype.isVector then
begin //ftVector
if isVector(_dtype) then
if _dtype.isVector then
begin
if (node^.offset=_offset) and
(node^.size =_size) and
@ -287,7 +305,7 @@ begin
end;
end else
begin //ftValue
if isVector(_dtype) then
if _dtype.isVector then
begin
if (node^.offset=_offset) and
(node^.size =_size) then
@ -350,15 +368,20 @@ begin
end;
end;
function TsrField.IsStructNotUsed:Boolean;
function TsrField.IsStructNotUsed:Boolean; inline;
begin
Result:=(FCount<=1) and (parent<>nil);
Result:=(FCount<=1) and (pParent<>nil);
end;
function TsrField.IsTop:Boolean; inline;
begin
Result:=(pParent=nil);
end;
function TsrField.GetStructDecorate:DWORD;
begin
Result:=DWORD(-1); //dont use
if (parent=nil) then //is top
if IsTop then
if (dtype=dtTypeStruct) then //is struct
begin
@ -374,6 +397,23 @@ begin
end;
end;
procedure TsrField.UpdateSize;
var
node:PsrField;
begin
node:=FList.Max;
if (node<>nil) then
begin
size:=node^.offset+node^.size;
end;
end;
function TsrField.GetSize:PtrUint;
begin
UpdateSize;
Result:=size;
end;
procedure TsrField.FillNode(o,s:PtrUint);
procedure _Pad(p,v:PtrUint;_dtype:TsrDataType); //inline;
@ -477,43 +517,6 @@ begin
end;
end;
procedure TsrField.AllocID;
var
node:PsrField;
ID:Integer;
begin
ID:=0;
node:=First;
While (node<>nil) do
begin
if IsVector(dtype) then
begin
ID:=node^.offset div stride;
node^.FID:=ID;
end else
begin
node^.FID:=ID;
Inc(ID);
end;
node:=Next(node);
end;
end;
procedure TsrField.AllocBinding(aType:PsrType;Decorates:PsrDecorateList);
var
node:PsrField;
begin
if (aType=nil) then Exit;
if (Decorates=nil) then Exit;
if isVector(dtype) then Exit;
node:=First;
While (node<>nil) do
begin
Decorates^.emit_member_decorate(ntType,aType,node^.FID,node^.offset);
node:=Next(node);
end;
end;
//--
function TsrBuffer.c(n1,n2:PsrBuffer):Integer;
@ -522,7 +525,30 @@ begin
Result:=Integer(n1^.key.pLayout>n2^.key.pLayout)-Integer(n1^.key.pLayout<n2^.key.pLayout);
if (Result<>0) then Exit;
//second CastNum
Result:=Integer(n1^.key.CastNum>n2^.key.CastNum)-Integer(n1^.key.CastNum<n2^.key.CastNum);
Result:=Integer(n1^.key.AliasId>n2^.key.AliasId)-Integer(n1^.key.AliasId<n2^.key.AliasId);
end;
Procedure TsrBuffer.Init(Emit:TCustomEmit); inline;
begin
FEmit:=Emit;
fntype :=ntBuffer;
bType :=btStorageBuffer;
FStorage:=StorageClass.Uniform;
FBinding:=-1;
FTop.FID:=-1;
FTop.dtype:=dtTypeStruct;
end;
function TsrBuffer.GetStorageName:RawByteString;
begin
Result:='';
Case bType of
btStorageBuffer:Result:='sBuf'+IntToStr(FBinding);
btUniformBuffer:Result:='uBuf'+IntToStr(FBinding);
btPushConstant :Result:='cBuf';
end;
end;
function TsrBuffer.GetTypeChar:Char;
@ -556,21 +582,19 @@ begin
Result:='TD'+HexStr(FBinding,8);
end;
procedure TsrBuffer.UpdateSize;
var
node:PsrField;
begin
node:=FTop.FList.Max;
if (node<>nil) then
begin
FTop.size:=node^.offset+node^.size;
end;
end;
function TsrBuffer.GetSize:PtrUint;
begin
UpdateSize;
Result:=FTop.size;
Result:=FTop.GetSize;
end;
procedure TsrBuffer.TakeChain(node:PsrChain);
begin
if (@Self=nil) or (node=nil) then Exit;
mark_read(node);
fchain_read :=fchain_read +node^.read_count;
fchain_write:=fchain_write+node^.write_count;
end;
procedure TsrBuffer.EnumAllField(cb:TFieldEnumCb);
@ -583,9 +607,8 @@ begin
repeat
While (node<>nil) do
begin
if (node^.FList.pRoot<>nil) then //child exist
if (node^.First<>nil) then //child exist
begin
curr^.FList._Splay(node); //Move to root
curr:=node;
node:=curr^.First; //down
end else
@ -595,9 +618,9 @@ begin
end;
end;
cb(curr);
curr:=curr^.parent; //up
node:=curr;
curr:=curr^.pParent; //up
if (curr=nil) then Break;
node:=curr^.FList.pRoot; //last find
node:=curr^.Next(node);
until false;
end;
@ -619,24 +642,9 @@ begin
end;
end;
Procedure TsrBufferCfg.Init;
procedure TsrBufferList.Init(Emit:TCustomEmit); inline;
begin
SpvVersion:=$10100;
maxUniformBufferRange:=$FFFF;
maxPushConstantsSize:=128;
minStorageBufferOffsetAlignment:=0;
minUniformBufferOffsetAlignment:=0;
end;
Function TsrBufferCfg.CanUseStorageBufferClass:Boolean;
begin
Result:=(SpvVersion>=$10300);
end;
procedure TsrBufferList.Init(cb:TfnAlloc);
begin
Alloc:=cb;
cfg.Init;
FEmit:=Emit;
end;
function TsrBufferList.Fetch(s:PsrDataLayout;n:PtrInt):PsrBuffer;
@ -644,30 +652,27 @@ var
node:TsrBuffer;
begin
node:=Default(TsrBuffer);
node.Init(FEmit);
node.key.pLayout:=s;
node.key.CastNum:=n;
node.key.AliasId:=n;
Result:=FNTree.Find(@node);
if (Result=nil) then
begin
Result:=Alloc(SizeOf(TsrBuffer));
Result^.key.pLayout:=s;
Result^.key.CastNum:=n;
Result^.bType :=btStorageBuffer;
Result^.FStorage:=StorageClass.Uniform;
Result^.FBinding:=-1;
Result^.FTop.Alloc:=Alloc;
Result:=FEmit.Alloc(SizeOf(TsrBuffer));
Move(node,Result^,SizeOf(TsrBuffer));
Result^.FTop.pBuffer:=Result;
Result^.FTop.FID:=-1;
Result^.FTop.dtype:=dtTypeStruct;
//
Result^.InitVar(FEmit);
//
FNTree.Insert(Result);
end;
end;
function TsrBufferList.NextCast(buf:PsrBuffer):PsrBuffer;
function TsrBufferList.NextAlias(buf:PsrBuffer):PsrBuffer;
begin
Result:=nil;
if (buf=nil) then Exit;
Result:=Fetch(buf^.key.pLayout,buf^.key.CastNum+1);
Result:=Fetch(buf^.key.pLayout,buf^.key.AliasId+1);
end;
Function TsrBufferList.First:PsrBuffer;
@ -688,7 +693,10 @@ begin
node:=First;
While (node<>nil) do
begin
node^.EnumAllField(cb);
if node^.IsUsed then
begin
node^.EnumAllField(cb);
end;
node:=Next(node);
end;
end;
@ -703,9 +711,26 @@ begin
EnumAllField(@OnFillSpace);
end;
procedure TsrBufferList.OnAllocID(node:PsrField);
procedure TsrBufferList.OnAllocID(pField:PsrField);
var
node:PsrField;
ID:Integer;
begin
node^.AllocID;
ID:=0;
node:=pField^.First;
While (node<>nil) do
begin
if pField^.dtype.IsVector then
begin
ID:=node^.offset div pField^.stride;
node^.FID:=ID;
end else
begin
node^.FID:=ID;
Inc(ID);
end;
node:=pField^.Next(node);
end;
end;
procedure TsrBufferList.AllocID;
@ -713,80 +738,108 @@ begin
EnumAllField(@OnAllocID);
end;
procedure TsrBufferList.AllocBinding(Var FBinding:Integer;Decorates:PsrDecorateList);
procedure TsrBufferList.AllocBinding(Var FBinding:Integer);
var
pConfig:PsrConfig;
pDecorateList:PsrDecorateList;
node:PsrBuffer;
pVar:PsrVariable;
begin
if (Decorates=nil) then Exit;
pConfig:=FEmit.GetConfig;
pDecorateList:=FEmit.GetDecorateList;
node:=First;
While (node<>nil) do
begin
pVar:=node^.pVar;
if (pVar<>nil) then
if (pVar<>nil) and node^.IsUsed then
if (node^.bType<>btPushConstant) then
if (node^.FBinding=-1) then //alloc
begin
if (node^.bType<>btPushConstant) then
if (node^.FBinding=-1) then //alloc
pDecorateList^.OpDecorate(pVar,Decoration.Binding,FBinding);
pDecorateList^.OpDecorate(pVar,Decoration.DescriptorSet,pConfig^.DescriptorSet);
node^.FBinding:=FBinding;
Inc(FBinding);
end;
node:=Next(node);
end;
end;
procedure TsrBufferList.AllocSourceExtension;
var
pDebugInfoList:PsrDebugInfoList;
node:PsrBuffer;
pVar:PsrVariable;
begin
pDebugInfoList:=FEmit.GetDebugInfoList;
node:=First;
While (node<>nil) do
begin
pVar:=node^.pVar;
if (pVar<>nil) and node^.IsUsed then
begin
pDebugInfoList^.OpSourceExtension(node^.GetString);
end;
node:=Next(node);
end;
end;
function TsrBufferList.FindUserDataBuf:PsrBuffer;
var
node:PsrBuffer;
begin
Result:=nil;
node:=First;
While (node<>nil) do
begin
if node^.IsUsed then
begin
if node^.key.pLayout^.IsUserData then
begin
Decorates^.emit_decorate(ntVar,pVar,Decoration.Binding,FBinding);
Decorates^.emit_decorate(ntVar,pVar,Decoration.DescriptorSet,Decorates^.FDescriptorSet);
node^.FBinding:=FBinding;
Inc(FBinding);
Exit(node);
end;
end;
node:=Next(node);
end;
end;
procedure TsrBufferList.AllocSourceExtension(FDebugInfo:PsrDebugInfoList);
var
node:PsrBuffer;
pVar:PsrVariable;
begin
if (FDebugInfo=nil) then Exit;
node:=First;
While (node<>nil) do
begin
pVar:=node^.pVar;
if (pVar<>nil) then
begin
FDebugInfo^.emit_source_extension(node^.GetString);
end;
node:=Next(node);
end;
end;
procedure TsrBufferList.UpdateStorage(node:PsrChain;pBuffer:PsrBuffer);
begin
if (node=nil) or (pBuffer=nil) then Exit;
pBuffer^.write_count:=pBuffer^.write_count+node^.write_count;
end;
procedure TsrBufferList.ApplyBufferType;
var
pConfig:PsrConfig;
node:PsrBuffer;
begin
pConfig:=FEmit.GetConfig;
node:=FindUserDataBuf;
if (node<>nil) and (FPushConstant=nil) then
if (node^.write_count=0) and
(node^.GetSize<=pConfig^.maxPushConstantsSize) then
begin
node^.bType :=btPushConstant;
node^.FStorage:=StorageClass.PushConstant;
FPushConstant :=node;
end;
node:=First;
While (node<>nil) do
begin
if (node^.bType=btStorageBuffer) then
if node^.IsUsed and (node^.bType=btStorageBuffer) then
begin
if (FPushConstant=nil) and
(node^.write_count=0) and
(node^.GetSize<=cfg.maxPushConstantsSize) then
(node^.fchain_write=0) and
(node^.GetSize<=pConfig^.maxPushConstantsSize) then
begin
node^.bType :=btPushConstant;
node^.FStorage:=StorageClass.PushConstant;
FPushConstant:=node;
FPushConstant :=node;
end else
if (node^.write_count=0) and
(node^.GetSize<=cfg.maxUniformBufferRange) then
if (node^.fchain_write=0) and
(node^.GetSize<=pConfig^.maxUniformBufferRange) then
begin
node^.bType :=btUniformBuffer;
node^.FStorage:=StorageClass.Uniform;
end else
if cfg.CanUseStorageBufferClass then
if pConfig^.CanUseStorageBufferClass then
begin
node^.FStorage:=StorageClass.StorageBuffer;
end else
@ -822,25 +875,97 @@ end;
procedure TsrBufferList.AlignOffset;
var
pConfig:PsrConfig;
node:PsrBuffer;
begin
pConfig:=FEmit.GetConfig;
node:=First;
While (node<>nil) do
begin
Case node^.bType of
btStorageBuffer:
begin
AlignOffset(node,cfg.minStorageBufferOffsetAlignment);
end;
btUniformBuffer:
begin
AlignOffset(node,cfg.minUniformBufferOffsetAlignment);
end;
btPushConstant:
begin
node^.align_offset:=cfg.PushConstantsOffset;
node^.ShiftOffset(cfg.PushConstantsOffset);
end;
if node^.IsUsed then
begin
Case node^.bType of
btStorageBuffer:
begin
AlignOffset(node,pConfig^.minStorageBufferOffsetAlignment);
end;
btUniformBuffer:
begin
AlignOffset(node,pConfig^.minUniformBufferOffsetAlignment);
end;
btPushConstant:
begin
node^.align_offset:=pConfig^.PushConstantsOffset;
node^.ShiftOffset(pConfig^.PushConstantsOffset);
end;
end;
end;
node:=Next(node);
end;
end;
procedure TsrBufferList.OnAllocTypeBinding(pField:PsrField);
var
pDecorateList:PsrDecorateList;
node:PsrField;
SD:DWORD;
begin
if (pField^.dtype<>dtTypeStruct) then Exit;
if (pField^.pType=nil) then Exit;
pDecorateList:=FEmit.GetDecorateList;
SD:=pField^.GetStructDecorate;
if (SD<>DWORD(-1)) then
begin
pDecorateList^.OpDecorate(pField^.pType,SD,0);
end;
node:=pField^.First;
While (node<>nil) do
begin
pDecorateList^.OpMemberDecorate(pField^.pType,node^.FID,node^.offset);
node:=pField^.Next(node);
end;
end;
procedure TsrBufferList.AllocTypeBinding;
var
pDecorateList:PsrDecorateList;
node:PsrBuffer;
begin
EnumAllField(@OnAllocTypeBinding);
//
pDecorateList:=FEmit.GetDecorateList;
//
node:=First;
While (node<>nil) do
begin
if node^.IsUsed and (node^.pVar<>nil) then
if (node^.bType=btStorageBuffer) then
begin
if (node^.fchain_read=0) then
begin
pDecorateList^.OpDecorate(node^.pVar,Decoration.NonReadable,0);
end;
if (node^.fchain_write=0) then
begin
pDecorateList^.OpDecorate(node^.pVar,Decoration.NonWritable,0);
end;
end;
node:=Next(node);
end;
end;
procedure TsrBufferList.AllocName;
var
FDebugInfo:PsrDebugInfoList;
node:PsrBuffer;
begin
FDebugInfo:=FEmit.GetDebugInfoList;
node:=First;
While (node<>nil) do
begin
if node^.IsUsed and (node^.FTop.pType<>nil) then
begin
FDebugInfo^.OpName(node^.FTop.pType,node^.GetStructName);
end;
node:=Next(node);
end;

View File

@ -1,16 +1,17 @@
unit srParser;
unit srCFGCursor;
{$mode ObjFPC}{$H+}
interface
uses
sysutils,
srLabel,
srCFG,
srNodes;
srCFGLabel,
srCFGParser,
ginodes,
srNode;
type
PsrCursor=^TsrCursor;
TsrCursor=object(TsrLCursor)
pCode:PsrCodeBlock;
pBlock:PsrCFGBlock;
@ -18,8 +19,11 @@ type
end;
TsrCodeList=specialize TNodeQueue<PsrCodeBlock>;
PsrCodeHeap=^TsrCodeHeap;
TsrCodeHeap=object(TsrCodeList)
Alloc:TfnAlloc;
FEmit:TCustomEmit;
Procedure Init(Emit:TCustomEmit);
function FindByPtr(base:Pointer):PsrCodeBlock;
function FetchByPtr(base:Pointer;bType:TsrBlockType):TsrCursor;
end;
@ -28,6 +32,11 @@ implementation
//
Procedure TsrCodeHeap.Init(Emit:TCustomEmit);
begin
FEmit:=Emit;
end;
function TsrCodeHeap.FindByPtr(base:Pointer):PsrCodeBlock;
var
node:PsrCodeBlock;
@ -52,8 +61,8 @@ begin
node:=FindByPtr(base);
if (node=nil) then
begin
node:=Alloc(SizeOf(TsrCodeBlock));
node^.Alloc:=Alloc;
node:=FEmit.Alloc(SizeOf(TsrCodeBlock));
node^.FEmit:=FEmit;
if parse_code_cfg(bType,base,node)>1 then Assert(False);
Push_tail(node);
end;

View File

@ -1,13 +1,12 @@
unit srLabel;
unit srCFGLabel;
{$mode ObjFPC}{$H+}
interface
uses
sysutils,
ps4_pssl,
srNodes;
ginodes;
type
TSrcAdr=object

View File

@ -1,14 +1,14 @@
unit srCFG;
unit srCFGParser;
{$mode ObjFPC}{$H+}
interface
uses
sysutils,
ps4_pssl,
srNodes,
srLabel;
ginodes,
srNode,
srCFGLabel;
type
PsrCFGBlock=^TsrCFGBlock;
@ -42,7 +42,7 @@ type
TsrCodeBlock=object
pNext:PsrCodeBlock;
//----
Alloc:TfnAlloc;
FEmit:TCustomEmit;
Body:Pointer;
Size:ptruint;
FLabels:TsrLabels;
@ -475,10 +475,9 @@ begin
Result:=FLabels.FNTree.Find(@node);
if (Result=nil) then
begin
Result:=Alloc(SizeOf(TsrLabel));
Result:=FEmit.Alloc(SizeOf(TsrLabel));
Result^.Adr:=Adr;
FLabels.FNTree.Insert(Result);
//FLabels.FList.Push_tail(Result);
end;
end;
@ -489,7 +488,7 @@ end;
Function TsrCFGParser.NewBlock:PsrCFGBlock;
begin
Result:=pCode^.Alloc(SizeOf(TsrCFGBlock));
Result:=pCode^.FEmit.Alloc(SizeOf(TsrCFGBlock));
end;
Procedure TsrCFGParser.PushBlock(New:PsrCFGBlock);

114
spirv/srCacheOp.pas Normal file
View File

@ -0,0 +1,114 @@
unit srCacheOp;
{$mode objfpc}{$H+}
interface
uses
ginodes,
srNode,
srCFGLabel,
srType,
srReg,
srOp;
type
PsrCacheOp=^TsrCacheOp;
TsrCacheOp=object
private
pLeft,pRight:PsrCacheOp;
//----
key:packed record
place:PsrOpBlock;
OpId:DWORD;
dtype:TsrDataType;
count:DWORD;
end;
pData:PPsrRegNode;
function c(n1,n2:PsrCacheOp):Integer; static;
public
pDst:PsrNode;
end;
PsrCacheOpList=^TsrCacheOpList;
TsrCacheOpList=object
type
TNodeFetch=specialize TNodeFetch<PsrCacheOp,TsrCacheOp>;
var
FEmit:TCustomEmit;
FNTree:TNodeFetch;
Procedure Init(Emit:TCustomEmit); inline;
function Fetch(place:PsrOpBlock;OpId:DWORD;rtype:TsrDataType;count:Byte;src:PPsrRegNode):PsrCacheOp;
end;
function _up_to_real(t:PsrOpBlock):PsrOpBlock;
implementation
function _up_to_real(t:PsrOpBlock):PsrOpBlock;
begin
repeat
if not t^.IsType(ntOpBlock) then Break;
Case t^.Block.bType of
btMain,
btCond,
btLoop:Break;
else;
end;
t:=t^.Parent;
until false;
Result:=t;
end;
//--
function TsrCacheOp.c(n1,n2:PsrCacheOp):Integer;
var
count:DWORD;
begin
Result:=CompareByte(n1^.key,n2^.key,SizeOf(TsrCacheOp.key));
if (Result=0) then
begin
count:=n1^.key.count;
if (count<>0) then
begin
Result:=CompareByte(n1^.pData^,n2^.pData^,count*SizeOf(Pointer));
end;
end;
end;
Procedure TsrCacheOpList.Init(Emit:TCustomEmit); inline;
begin
FEmit:=Emit;
end;
function TsrCacheOpList.Fetch(place:PsrOpBlock;OpId:DWORD;rtype:TsrDataType;count:Byte;src:PPsrRegNode):PsrCacheOp;
var
size:ptruint;
node:TsrCacheOp;
begin
Assert(place<>nil);
place:=_up_to_real(place);
Result:=nil;
node:=Default(TsrCacheOp);
node.key.place:=place;
node.key.OpId :=OpId;
node.key.dtype:=rtype;
node.key.count:=count;
node.pData:=src;
Result:=FNTree.Find(@node);
if (Result=nil) then
begin
Result:=FEmit.Alloc(SizeOf(TsrCacheOp));
Move(node,Result^,SizeOf(TsrCacheOp));
size:=count*SizeOf(Pointer);
Result^.pData:=FEmit.Alloc(size);
Move(src^,Result^.pData^,size);
FNTree.Insert(Result);
end;
end;
end.

View File

@ -1,62 +0,0 @@
unit srCap;
{$mode ObjFPC}{$H+}
interface
uses
srNodes;
type
PSpirvCap=^TSpirvCap;
TSpirvCap=object
pLeft,pRight:PSpirvCap;
//----
ID:DWORD;
function c(n1,n2:PSpirvCap):Integer; static;
end;
PsrCapList=^TsrCapList;
TsrCapList=object
type
TNodeFetch=specialize TNodeFetch<PSpirvCap,TSpirvCap>;
var
Alloc:TfnAlloc;
FNTree:TNodeFetch;
procedure Add(ID:DWORD);
Function First:PSpirvCap;
Function Next(node:PSpirvCap):PSpirvCap;
end;
implementation
function TSpirvCap.c(n1,n2:PSpirvCap):Integer;
begin
Result:=Integer(n1^.ID>n2^.ID)-Integer(n1^.ID<n2^.ID);
end;
procedure TsrCapList.Add(ID:DWORD);
var
fnode:TSpirvCap;
pnode:PSpirvCap;
begin
fnode:=Default(TSpirvCap);
fnode.ID:=ID;
if (FNTree.Find(@fnode)<>nil) then Exit;
pnode:=Alloc(SizeOf(TSpirvCap));
Move(fnode,pnode^,SizeOf(TSpirvCap));
FNTree.Insert(pnode);
end;
Function TsrCapList.First:PSpirvCap;
begin
Result:=FNTree.Min;
end;
Function TsrCapList.Next(node:PSpirvCap):PSpirvCap;
begin
Result:=FNTree.Next(node);
end;
end.

69
spirv/srCapability.pas Normal file
View File

@ -0,0 +1,69 @@
unit srCapability;
{$mode ObjFPC}{$H+}
interface
uses
ginodes,
srNode;
type
PsrCapability=^TsrCapability;
TsrCapability=object
pLeft,pRight:PsrCapability;
//----
ID:DWORD;
function c(n1,n2:PsrCapability):Integer; static;
end;
PsrCapabilityList=^TsrCapabilityList;
TsrCapabilityList=object
type
TNodeFetch=specialize TNodeFetch<PsrCapability,TsrCapability>;
var
FEmit:TCustomEmit;
FNTree:TNodeFetch;
Procedure Init(Emit:TCustomEmit);
procedure Add(ID:DWORD);
Function First:PsrCapability;
Function Next(node:PsrCapability):PsrCapability;
end;
implementation
function TsrCapability.c(n1,n2:PsrCapability):Integer;
begin
Result:=Integer(n1^.ID>n2^.ID)-Integer(n1^.ID<n2^.ID);
end;
Procedure TsrCapabilityList.Init(Emit:TCustomEmit);
begin
FEmit:=Emit;
end;
procedure TsrCapabilityList.Add(ID:DWORD);
var
fnode:TsrCapability;
pnode:PsrCapability;
begin
fnode:=Default(TsrCapability);
fnode.ID:=ID;
if (FNTree.Find(@fnode)<>nil) then Exit;
pnode:=FEmit.Alloc(SizeOf(TsrCapability));
Move(fnode,pnode^,SizeOf(TsrCapability));
FNTree.Insert(pnode);
end;
Function TsrCapabilityList.First:PsrCapability;
begin
Result:=FNTree.Min;
end;
Function TsrCapabilityList.Next(node:PsrCapability):PsrCapability;
begin
Result:=FNTree.Next(node);
end;
end.

47
spirv/srConfig.pas Normal file
View File

@ -0,0 +1,47 @@
unit srConfig;
{$mode ObjFPC}{$H+}
interface
type
PsrConfig=^TsrConfig;
TsrConfig=packed object
PrintAsm:Boolean;
UseVertexInput:Boolean; //True
UseTexelBuffer:Boolean;
UseOutput16:Boolean;
//
DescriptorSet:DWORD; //0
//
SpvVersion:PtrUint; // $10100
maxUniformBufferRange:PtrUint; // $FFFF
PushConstantsOffset:PtrUint; // 0
maxPushConstantsSize:PtrUint; // 128
minStorageBufferOffsetAlignment:PtrUint; // $10
minUniformBufferOffsetAlignment:PtrUint; // $100
//
Procedure Init;
Function CanUseStorageBufferClass:Boolean;
end;
implementation
Procedure TsrConfig.Init;
begin
UseVertexInput:=True;
//
SpvVersion:=$10100;
maxUniformBufferRange:=$FFFF;
maxPushConstantsSize:=128;
minStorageBufferOffsetAlignment:=0;
minUniformBufferOffsetAlignment:=0;
end;
Function TsrConfig.CanUseStorageBufferClass:Boolean;
begin
Result:=(SpvVersion>=$10300);
end;
end.

File diff suppressed because it is too large Load Diff

View File

@ -6,31 +6,48 @@ interface
uses
spirv,
srNodes,
srNode,
srOp;
type
PsrHeaderList=^TsrHeaderList;
TsrHeaderList=object(TsrOpBlockCustom)
FGLSL_std_450:PSpirvOp;
function emit_glsl_ext:PSpirvOp;
end;
PsrDecorateList=^TsrDecorateList;
TsrDecorateList=object(TsrOpBlockSimple)
FDescriptorSet:DWORD;
procedure emit_decorate(ntype:TsrNodeType;Data:Pointer;dec_id,param:DWORD);
procedure emit_member_decorate(ntype:TsrNodeType;Data:Pointer;index,offset:DWORD);
TsrDecorateList=object(TsrOpBlockCustom)
procedure OpDecorate(Data:PsrNode;dec_id,param:DWORD);
procedure OpMemberDecorate(Data:PsrNode;index,offset:DWORD);
end;
PsrDebugInfoList=^TsrDebugInfoList;
TsrDebugInfoList=object(TsrOpBlockSimple)
procedure emit_source_extension(const n:RawByteString);
procedure emit_name(ntype:TsrNodeType;Data:Pointer;const n:RawByteString);
TsrDebugInfoList=object(TsrOpBlockCustom)
procedure OpSourceExtension(const n:RawByteString);
procedure OpName(Data:PsrNode;const n:RawByteString);
function OpString(const n:RawByteString):PsrNode;
end;
implementation
procedure TsrDecorateList.emit_decorate(ntype:TsrNodeType;Data:Pointer;dec_id,param:DWORD);
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;
procedure TsrDecorateList.OpDecorate(Data:PsrNode;dec_id,param:DWORD);
var
node:PSpirvOp;
begin
node:=AddSpirvOp(Op.OpDecorate);
node^.AddParam(ntype,Data);
node^.AddParam(Data);
node^.AddLiteral(dec_id,Decoration.GetStr(dec_id));
Case dec_id of
Decoration.BuiltIn:
@ -48,18 +65,18 @@ begin
end;
end;
procedure TsrDecorateList.emit_member_decorate(ntype:TsrNodeType;Data:Pointer;index,offset:DWORD);
procedure TsrDecorateList.OpMemberDecorate(Data:PsrNode;index,offset:DWORD);
var
node:PSpirvOp;
begin
node:=AddSpirvOp(Op.OpMemberDecorate);
node^.AddParam(ntype,Data);
node^.AddParam(Data);
node^.AddLiteral(index);
node^.AddLiteral(Decoration.Offset,Decoration.GetStr(Decoration.Offset));
node^.AddLiteral(offset);
end;
procedure TsrDebugInfoList.emit_source_extension(const n:RawByteString);
procedure TsrDebugInfoList.OpSourceExtension(const n:RawByteString);
var
node:PSpirvOp;
begin
@ -67,14 +84,24 @@ begin
node^.AddString(n);
end;
procedure TsrDebugInfoList.emit_name(ntype:TsrNodeType;Data:Pointer;const n:RawByteString);
procedure TsrDebugInfoList.OpName(Data:PsrNode;const n:RawByteString);
var
node:PSpirvOp;
begin
node:=AddSpirvOp(Op.OpName);
node^.AddParam(ntype,Data);
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.

418
spirv/srFlow.pas Normal file
View File

@ -0,0 +1,418 @@
unit srFlow;
{$mode objfpc}{$H+}
interface
uses
sysutils,
ps4_pssl,
spirv,
srNode,
srCFGLabel,
srCFGParser,
srCFGCursor,
srReg,
srOp,
srOpUtils,
srConfig,
emit_op;
type
TEmitFlow=class(TEmitOp)
//
Procedure InitFlow;
Procedure PushBlockOp(pLine:PspirvOp;pChild:PsrOpBlock;pLBlock:PsrCFGBlock);
function PopBlockOp:Boolean;
function CheckBlockBeg:Boolean;
function CheckBlockEnd:Boolean;
//
function GetPtr:Pointer;
procedure SetPtr(base:Pointer;bType:TsrBlockType);
function IsFinalize:Boolean;
function FindLabel(Adr:TSrcAdr):PsrLabel;
//
procedure Finalize;
//
function NextParse:Byte;
function ParseStage(base:Pointer):Byte;
end;
implementation
Procedure TEmitFlow.InitFlow;
begin
CodeHeap.Init(Self);
//
InitBlock:=AllocBlockOp;
InitBlock^.SetInfo(btOther,Cursor.Adr,Cursor.Adr);
PushBlockOp(line,InitBlock,nil);
Main^.PopBlock;
end;
Procedure TEmitFlow.PushBlockOp(pLine:PspirvOp;pChild:PsrOpBlock;pLBlock:PsrCFGBlock);
begin
pChild^.FCursor:=Cursor; //prev
InsSpirvOp(pLine,PspirvOp(pChild));
Main^.PushBlock(pChild);
if (pLBlock<>nil) then
begin
Cursor.pBlock:=pLBlock; //push
end;
end;
procedure UpdateVolMark(pBlock:PsrOpBlock);
var
pChild:PsrOpBlock;
begin
if (not pBlock^.IsType(ntOpBlock)) then Exit;
if (pBlock^.Regs.FVolMark<>vmNone) then Exit;
pChild:=pBlock^.line; //last
if (not pChild^.IsType(ntOpBlock)) then Exit;
Case pChild^.Block.bType of
btAdr,
btAdrBranch,
btOther:;
else
Exit;
end;
pBlock^.Regs.FVolMark:=pChild^.Regs.FVolMark;
end;
function TEmitFlow.PopBlockOp:Boolean;
var
pOpBlock:PsrOpBlock;
pOpChild:PsrOpBlock;
pOpLabel:array[0..2] of PspirvOp;
branch_up:Boolean;
procedure pop_cond;
begin
Assert(pOpLabel[1]<>nil);
Case pOpBlock^.Regs.FVolMark of
vmNone:PrivateList.build_volatile_cur(pOpBlock^.Regs.pSnap);
vmEnd :PrivateList.build_volatile_dis(pOpBlock^.Regs.pSnap);
else;
end;
if not is_term_op(line) then
begin
OpBranch(line,pOpLabel[1]);
end;
AddSpirvOp(line,pOpLabel[1]); //end
end;
procedure pop_loop;
begin
//add OpLoopMerge continue
Assert(pOpLabel[0]<>nil);
Assert(pOpLabel[1]<>nil);
Assert(pOpLabel[2]<>nil);
Case pOpBlock^.Regs.FVolMark of
vmNone:PrivateList.build_volatile_old(pOpBlock^.Regs.pSnap);
else;
end;
if pOpBlock^.Cond.FUseCont then //use continue
begin
if not is_term_op(line) then
begin
OpBranch(line,pOpLabel[1]); //break
end;
AddSpirvOp(line,pOpLabel[2]); //OpLoopMerge end
pOpChild:=AllocBlockOp;
pOpChild^.SetInfo(btOther,Cursor.Adr,Cursor.Adr);
PushBlockOp(line,pOpChild,nil);
OpBranch(line,pOpLabel[0]); //continue
Main^.PopBlock;
AddSpirvOp(line,pOpLabel[1]); //end
end else //dont used continue
begin
if not is_term_op(line) then
begin
AddSpirvOp(line,NewLabelOp(True)); //devide
end;
AddSpirvOp(line,pOpLabel[2]); //OpLoopMerge end
pOpChild:=AllocBlockOp;
pOpChild^.SetInfo(btOther,Cursor.Adr,Cursor.Adr);
PushBlockOp(line,pOpChild,nil);
OpBranch(line,pOpLabel[1]); //break
Main^.PopBlock;
AddSpirvOp(line,pOpLabel[1]); //end
end;
end;
procedure pop_else;
begin
if (pOpLabel[1]<>nil) then
begin
if not is_term_op(line) then
begin
OpBranch(line,pOpLabel[1]);
end;
AddSpirvOp(line,pOpLabel[1]);
end;
end;
begin
Result:=False;
if (Main=nil) then Exit;
branch_up:=False;
repeat
pOpBlock:=Main^.pBlock;
if (pOpBlock=nil) then Exit;
UpdateVolMark(pOpBlock);
pOpLabel[0]:=pOpBlock^.Labels.pBegOp;
pOpLabel[1]:=pOpBlock^.Labels.pEndOp;
pOpLabel[2]:=pOpBlock^.Labels.pMrgOp;
Case pOpBlock^.Block.bType of
btCond:
begin
pop_cond;
branch_up:=False;
end;
btLoop:
begin
pop_loop;
branch_up:=False;
end;
else
pop_else;
end;
Case pOpBlock^.Block.bType of
btAdr:
begin
Cursor:=pOpBlock^.FCursor;
end;
btAdrBranch:
begin
Cursor:=pOpBlock^.FCursor;
branch_up:=True;
end;
btOther:; //nop
else
begin
Cursor.PopBlock;
end;
end;
Result:=Main^.PopBlock;
until (not branch_up) or (not Result);
end;
function TEmitFlow.CheckBlockBeg:Boolean;
var
pLBlock:PsrCFGBlock;
pOpLabel:array[0..3] of PspirvOp;
pOpBlock:PsrOpBlock;
pOpChild:PsrOpBlock;
adr:TSrcAdr;
Info:TsrBlockInfo;
begin
Result:=False;
adr:=Cursor.Adr;
if (FindLabel(adr)=nil) then Exit;
pLBlock:=Cursor.pBlock^.FindBlock(adr);
if (pLBlock<>nil) then
Case pLBlock^.bType of
btLoop:
begin
PrivateList.make_copy_all;
Info:=Default(TsrBlockInfo);
Info.b_adr:=pLBlock^.pBLabel^.Adr;
Info.e_adr:=pLBlock^.pELabel^.Adr;
Info.bType:=btLoop;
pOpLabel[0]:=NewLabelOp(False); //continue
pOpLabel[1]:=NewLabelOp(False); //end
pOpLabel[2]:=NewLabelOp(False); //cond
pOpLabel[3]:=NewLabelOp(False); //start
pOpLabel[0]^.Adr:=Info.b_adr;
pOpLabel[1]^.Adr:=Info.e_adr;
pOpLabel[2]^.Adr:=Info.e_adr;
pOpLabel[3]^.Adr:=Info.b_adr;
pOpBlock:=NewBlockOp(RegsStory.get_snapshot);
pOpBlock^.SetLabels(pOpLabel[0],pOpLabel[1],pOpLabel[2]);
pOpBlock^.SetInfo(Info);
PushBlockOp(line,pOpBlock,pLBlock);
OpBranch(line,pOpLabel[0]);
AddSpirvOp(line,pOpLabel[0]); //continue loop
OpLoopMerge(line,pOpLabel[1],pOpLabel[2]);
OpBranch(line,pOpLabel[3]);
AddSpirvOp(line,pOpLabel[3]);
//down group
Info.bType:=btOther;
pOpChild:=AllocBlockOp;
pOpChild^.SetInfo(Info);
PushBlockOp(line,pOpChild,nil);
end;
btAdr,
btAdrBranch: //skip
begin
adr:=pLBlock^.pELabel^.Adr;
Cursor.Adr:=adr;
end;
else;
end;
end;
function TEmitFlow.CheckBlockEnd:Boolean;
begin
Result:=False;
if (Main=nil) then Exit;
if (Main^.pBlock=nil) then Exit;
if (Main^.pBlock^.Parent<>nil) and
Main^.pBlock^.IsEndOf(Cursor.Adr) then
begin
Result:=PopBlockOp;
end;
end;
//
function TEmitFlow.GetPtr:Pointer;
begin
Result:=Cursor.Adr.get_pc;
end;
procedure TEmitFlow.SetPtr(base:Pointer;bType:TsrBlockType);
begin
if (Cursor.Adr.get_pc=base) then Exit;
Cursor:=CodeHeap.FetchByPtr(base,bType);
end;
function TEmitFlow.IsFinalize:Boolean;
begin
Result:=False;
if (Main^.pBlock^.Parent=nil) then
if Cursor.pBlock^.IsEndOf(Cursor.Adr) then
begin
Result:=True;
end;
end;
function TEmitFlow.FindLabel(Adr:TSrcAdr):PsrLabel;
begin
Result:=nil;
if (Cursor.pCode=nil) then Exit;
Result:=Cursor.pCode^.FindLabel(Adr);
end;
procedure TEmitFlow.Finalize;
begin
if (Main=nil) then Exit;
if (Main^.pBlock<>nil) then
While (Main^.pBlock^.Parent<>nil) do
begin
PopBlockOp;
end;
AddSpirvOp(Op.OpFunctionEnd);
end;
//
function TEmitFlow.NextParse:Byte;
var
FLevel:DWORD;
begin
if (Cursor.pCode=nil) then Exit(2);
if (Cursor.pBlock=nil) then Exit(3);
if (Main=nil) then Exit(4);
if (Main^.pBlock=nil) then Exit(5);
if Config.PrintAsm then
begin
Write(HexStr(Cursor.OFFSET_DW*4,4));
FLevel:=0;
if (Main<>nil) then
if (Main^.pBlock<>nil) then
begin
FLevel:=Main^.pBlock^.Level;
end;
Write(Space(FLevel+1));
end;
Result:=Cursor.Next(FSPI);
if (Result>1) then Exit;
if Config.PrintAsm then
begin
print_spi(FSPI);
end;
emit_spi;
While (CheckBlockBeg) do;
While (CheckBlockEnd) do;
Result:=0;
if IsFinalize then
begin
Finalize;
Result:=1;
end;
end;
function TEmitFlow.ParseStage(base:Pointer):Byte;
begin
Result:=0;
SetPtr(base,btMain);
Main^.pTop^.SetCFGBlock(Cursor.pBlock);
While (CheckBlockBeg) do;
repeat
Result:=NextParse;
Case Result of
0:;
1:Break;
else
Break;
end;
until false;
end;
end.

View File

@ -5,16 +5,18 @@ unit srFragLayout;
interface
uses
sysutils,
spirv,
srNodes,
srReg,
srOp,
srLayout,
srVariable,
srInput,
srCap,
srDecorate;
sysutils,
spirv,
ginodes,
srNode,
srType,
srReg,
srOp,
srLayout,
srVariable,
srInput,
srCapability,
srDecorate;
type
//itPerspSample, //Sample
@ -24,44 +26,63 @@ type
//itLinearCenter, //NoPerspective
//itLinearCentroid, //NoPerspective Centroid
PsrFragLayout=^TsrFragLayout;
TsrFragLayout=object(TsrDescriptor)
pLeft,pRight:PsrFragLayout;
//----
itype:TpsslInputType;
pReg:PsrRegNode;
function c(n1,n2:PsrFragLayout):Integer; static;
function GetName:RawByteString;
ntFragLayout=class(ntDescriptor)
class function GetStorageName(node:PsrNode):RawByteString; override;
end;
PsrFragLayout=^TsrFragLayout;
TsrFragLayout=object(TsrDescriptor)
private
pLeft,pRight:PsrFragLayout;
//----
itype:TpsslInputType;
function c(n1,n2:PsrFragLayout):Integer; static;
public
pReg:PsrRegNode;
Procedure Init; inline;
function GetStorageName:RawByteString;
end;
PsrFragLayoutList=^TsrFragLayoutList;
TsrFragLayoutList=object
type
TNodeFetch=specialize TNodeFetch<PsrFragLayout,TsrFragLayout>;
var
Alloc:TfnAlloc;
FEmit:TCustomEmit;
FNTree:TNodeFetch;
procedure Init(cb:TfnAlloc);
function Fetch(itype:TpsslInputType;location:DWORD):PsrFragLayout;
procedure Init(Emit:TCustomEmit); inline;
function Fetch(itype:TpsslInputType;location:DWORD;rtype:TsrDataType):PsrFragLayout;
Function First:PsrFragLayout;
Function Next(node:PsrFragLayout):PsrFragLayout;
procedure AllocBinding(Decorates:PsrDecorateList;Cap:PsrCapList);
procedure AllocBinding;
procedure AllocEntryPoint(EntryPoint:PSpirvOp);
end;
implementation
class function ntFragLayout.GetStorageName(node:PsrNode):RawByteString;
begin
Result:=PsrFragLayout(node)^.GetStorageName;
end;
//
function TsrFragLayout.c(n1,n2:PsrFragLayout):Integer;
begin
//first itype
Result:=Integer(n1^.itype>n2^.itype)-Integer(n1^.itype<n2^.itype);
if (Result<>0) then Exit;
//second location
Result:=Integer(n1^.FBinding>n2^.FBinding)-Integer(n1^.FBinding<n2^.FBinding);
//Result:=CompareByte(n1^.key,n2^.key,SizeOf(TsrFragLayout.key));
end;
function TsrFragLayout.GetName:RawByteString;
Procedure TsrFragLayout.Init; inline;
begin
fntype :=ntFragLayout;
FStorage:=StorageClass.Input;
end;
function TsrFragLayout.GetStorageName:RawByteString;
begin
Case itype of
itPerspSample:
@ -81,24 +102,28 @@ begin
end;
end;
procedure TsrFragLayoutList.Init(cb:TfnAlloc);
procedure TsrFragLayoutList.Init(Emit:TCustomEmit); inline;
begin
Alloc:=cb;
FEmit:=Emit;
end;
function TsrFragLayoutList.Fetch(itype:TpsslInputType;location:DWORD):PsrFragLayout;
function TsrFragLayoutList.Fetch(itype:TpsslInputType;location:DWORD;rtype:TsrDataType):PsrFragLayout;
var
node:TsrFragLayout;
begin
node:=Default(TsrFragLayout);
node.Init;
node.itype:=itype;
node.FStorage:=StorageClass.Input;
node.FBinding:=location;
Result:=FNTree.Find(@node);
if (Result=nil) then
begin
Result:=Alloc(SizeOf(TsrFragLayout));
Result:=FEmit.Alloc(SizeOf(TsrFragLayout));
Move(node,Result^,SizeOf(TsrFragLayout));
//
Result^.InitType(rtype,FEmit);
Result^.InitVar(FEmit);
//
FNTree.Insert(Result);
end;
end;
@ -113,45 +138,48 @@ begin
Result:=FNTree.Next(node);
end;
procedure TsrFragLayoutList.AllocBinding(Decorates:PsrDecorateList;Cap:PsrCapList);
procedure TsrFragLayoutList.AllocBinding;
var
pDecorateList:PsrDecorateList;
pCapabilityList:PsrCapabilityList;
node:PsrFragLayout;
pVar:PsrVariable;
begin
if (Decorates=nil) then Exit;
pDecorateList:=FEmit.GetDecorateList;
pCapabilityList:=FEmit.GetCapabilityList;
//interpolate param
node:=First;
While (node<>nil) do
begin
pVar:=node^.pVar;
if (pVar<>nil) then
if (pVar<>nil) and node^.IsUsed then
begin
Decorates^.emit_decorate(ntVar,pVar,Decoration.Location,node^.FBinding);
pDecorateList^.OpDecorate(pVar,Decoration.Location,node^.FBinding);
case node^.itype of
itPerspSample: //Sample
begin
Cap^.Add(Capability.SampleRateShading);
Decorates^.emit_decorate(ntVar,pVar,Decoration.Sample,0);
pCapabilityList^.Add(Capability.SampleRateShading);
pDecorateList^.OpDecorate(pVar,Decoration.Sample,0);
end;
itPerspCenter:; //default
itPerspCentroid: //Centroid
begin
Decorates^.emit_decorate(ntVar,pVar,Decoration.Centroid,0);
pDecorateList^.OpDecorate(pVar,Decoration.Centroid,0);
end;
itLinearSample: //NoPerspective Sample
begin
Decorates^.emit_decorate(ntVar,pVar,Decoration.NoPerspective,0);
Decorates^.emit_decorate(ntVar,pVar,Decoration.Sample,0);
pDecorateList^.OpDecorate(pVar,Decoration.NoPerspective,0);
pDecorateList^.OpDecorate(pVar,Decoration.Sample,0);
end;
itLinearCenter: //NoPerspective
begin
Decorates^.emit_decorate(ntVar,pVar,Decoration.NoPerspective,0);
pDecorateList^.OpDecorate(pVar,Decoration.NoPerspective,0);
end;
itLinearCentroid: //NoPerspective Centroid
begin
Decorates^.emit_decorate(ntVar,pVar,Decoration.NoPerspective,0);
Decorates^.emit_decorate(ntVar,pVar,Decoration.Centroid,0);
pDecorateList^.OpDecorate(pVar,Decoration.NoPerspective,0);
pDecorateList^.OpDecorate(pVar,Decoration.Centroid,0);
end;
else
Assert(false,'AllocBinding');
@ -172,9 +200,9 @@ begin
While (node<>nil) do
begin
pVar:=node^.pVar;
if (pVar<>nil) then
if (pVar<>nil) and node^.IsUsed then
begin
EntryPoint^.AddParam(ntVar,pVar);
EntryPoint^.AddParam(pVar);
end;
node:=Next(node);
end;

View File

@ -5,15 +5,18 @@ unit srInput;
interface
uses
typinfo,
sysutils,
spirv,
srNodes,
srReg,
srOp,
srLayout,
srVariable,
srDecorate;
typinfo,
sysutils,
spirv,
ginodes,
srNode,
srType,
srReg,
srOp,
srLayout,
srVariable,
srCapability,
srDecorate;
type
TpsslInputType=(
@ -42,90 +45,123 @@ type
itFloatPos,
itFrontFace,
itAncillary,
itSampleCoverage,
itPosFixed,
itTgid,
itTgSize,
itThreadId
itThreadId,
//
itSampleId,
itLayer,
itSubgroupLocalInvocationId
);
ntInput=class(ntDescriptor)
class function GetStorageName(node:PsrNode):RawByteString; override;
end;
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;
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
Alloc:TfnAlloc;
FEmit:TCustomEmit;
FNTree:TNodeFetch;
procedure Init(cb:TfnAlloc);
function Search(itype:TpsslInputType;id:Byte=0):PsrInput;
function Fetch(itype:TpsslInputType;id:Byte=0):PsrInput;
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(Decorates:PsrDecorateList);
procedure AllocBinding;
procedure AllocEntryPoint(EntryPoint:PSpirvOp);
end;
implementation
function TsrInput.c(n1,n2:PsrInput):Integer;
class function ntInput.GetStorageName(node:PsrNode):RawByteString;
begin
Result:=CompareByte(n1^.key,n2^.key,SizeOf(TsrInput.key));
Result:=PsrInput(node)^.GetStorageName;
end;
function TsrInput.GetName:RawByteString;
//
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(cb:TfnAlloc);
Procedure TsrInputList.Init(Emit:TCustomEmit); inline;
begin
Alloc:=cb;
FEmit:=Emit;
end;
function TsrInputList.Search(itype:TpsslInputType;id:Byte=0):PsrInput;
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(itype:TpsslInputType;id:Byte=0):PsrInput;
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;
node.FStorage:=StorageClass.Input;
node.FBinding:=-1;
Result:=FNTree.Find(@node);
if (Result=nil) then
begin
Result:=Alloc(SizeOf(TsrInput));
Result:=FEmit.Alloc(SizeOf(TsrInput));
Move(node,Result^,SizeOf(TsrInput));
//
Result^.InitType(rtype,FEmit);
Result^.InitVar(FEmit);
//
FNTree.Insert(Result);
end;
end;
@ -140,40 +176,54 @@ begin
Result:=FNTree.Next(node);
end;
procedure TsrInputList.AllocBinding(Decorates:PsrDecorateList);
procedure TsrInputList.AllocBinding;
var
pDecorateList:PsrDecorateList;
pCapabilityList:PsrCapabilityList;
node:PsrInput;
pVar:PsrVariable;
begin
if (Decorates=nil) then Exit;
pDecorateList :=FEmit.GetDecorateList;
pCapabilityList:=FEmit.GetCapabilityList;
node:=First;
While (node<>nil) do
begin
pVar:=node^.pVar;
if (pVar<>nil) then
if (pVar<>nil) and node^.IsUsed then
begin
Case node^.key.itype of
itFloatPos:
begin
Decorates^.emit_decorate(ntVar,pVar,Decoration.BuiltIn,BuiltIn.FragCoord);
pDecorateList^.OpDecorate(pVar,Decoration.BuiltIn,BuiltIn.FragCoord);
end;
itTgid:
begin
Decorates^.emit_decorate(ntVar,pVar,Decoration.BuiltIn,BuiltIn.WorkgroupId);
pDecorateList^.OpDecorate(pVar,Decoration.BuiltIn,BuiltIn.WorkgroupId);
end;
itThreadId:
begin
Decorates^.emit_decorate(ntVar,pVar,Decoration.BuiltIn,BuiltIn.LocalInvocationID);
pDecorateList^.OpDecorate(pVar,Decoration.BuiltIn,BuiltIn.LocalInvocationID);
end;
itVIndex:
begin
Decorates^.emit_decorate(ntVar,pVar,Decoration.BuiltIn,BuiltIn.VertexIndex);
pDecorateList^.OpDecorate(pVar,Decoration.BuiltIn,BuiltIn.VertexIndex);
end;
itFrontFace:
begin
Decorates^.emit_decorate(ntVar,pVar,Decoration.BuiltIn,BuiltIn.FrontFacing);
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;
@ -192,9 +242,9 @@ begin
While (node<>nil) do
begin
pVar:=node^.pVar;
if (pVar<>nil) then
if (pVar<>nil) and node^.IsUsed then
begin
EntryPoint^.AddParam(ntVar,pVar);
EntryPoint^.AddParam(pVar);
end;
node:=Next(node);
end;

518
spirv/srInterface.pas Normal file
View File

@ -0,0 +1,518 @@
unit srInterface;
{$mode objfpc}{$H+}
interface
uses
ps4_pssl,
spirv,
srNode,
srConfig,
srAllocator,
srCFGCursor,
srRefId,
srLiteral,
srCapability,
srDecorate,
srType,
srTypes,
srConst,
srReg,
srVariable,
srInput,
srOutput,
srLayout,
srVertLayout,
srFragLayout,
srBuffer,
srUniform,
srPrivate,
srBitcast,
srOp,
srOpUtils,
srCacheOp;
type
TLocalSize=packed record
x,y,z:DWORD;
end;
TEmitInterface=class(TCustomEmit)
FExecutionModel:Word;
FLocalSize:TLocalSize;
Config:TsrConfig;
//
FSPI:TSPI;
//
Allocator:TsrAllocator;
//
LiteralList :TsrLiteralList;
TypeList :TsrTypeList;
ConstList :TsrConstList;
RegsStory :TsrRegsStory;
CapabilityList:TsrCapabilityList;
HeaderList :TsrHeaderList;
DecorateList :TsrDecorateList;
DebugInfoList :TsrDebugInfoList;
VariableList :TsrVariableList;
//
InputList :TsrInputList;
OutputList :TsrOutputList;
//
DataLayoutList:TsrDataLayoutList;
VertLayoutList:TsrVertLayoutList;
FragLayoutList:TsrFragLayoutList;
//
BufferList :TsrBufferList;
UniformList :TsrUniformList;
PrivateList :TsrPrivateList;
//
BitcastList :TsrBitcastList;
CacheOpList :TsrCacheOpList;
//
FuncList :TsrFuncList;
//
CodeHeap :TsrCodeHeap;
Cursor :TsrCursor;
Main :PSpirvFunc;
InitBlock:PsrOpBlock;
//
RefIdAlloc:TsrRefIdAlloc;
//
function Alloc(Size:ptruint):Pointer; override;
Function GetConfig :Pointer; override;
Function GetCodeHeap :Pointer; override;
Function GetLiteralList :Pointer; override;
Function GetTypeList :Pointer; override;
Function GetConstList :Pointer; override;
Function GetRegsStory :Pointer; override;
Function GetCapabilityList :Pointer; override;
Function GetHeaderList :Pointer; override;
Function GetDecorateList :Pointer; override;
Function GetDebugInfoList :Pointer; override;
Function GetVariableList :Pointer; override;
Function GetInputList :Pointer; override;
Function GetOutputList :Pointer; override;
Function GetDataLayoutList :Pointer; override;
Function GetVertLayoutList :Pointer; override;
Function GetFragLayoutList :Pointer; override;
Function GetBufferList :Pointer; override;
Function GetUniformList :Pointer; override;
Function GetBitcastList :Pointer; override;
Function GetCacheOpList :Pointer; override;
Function GetFuncList :Pointer; override;
Function GetCursor :Pointer; override;
function NewRefNode :PsrNode; override;
//
Function line :PspirvOp;
Function curr_line :Pointer; override;
function init_line :Pointer; override;
//
Procedure InitLists;
//
function NewVariable:Pointer;
//
function _get_line(ppLine:PPspirvOp):PspirvOp;
//
Function NewRegPair:PsrRegPair;
Function NewReg(rtype:TsrDataType):PsrRegNode;
Function NewReg(pConst:PsrConst;ppLine:PPspirvOp=nil):PsrRegNode;
//
Function NewReg_q(dtype:TsrDataType;value:QWORD;ppLine:PPspirvOp=nil):PsrRegNode;
Function NewReg_b(value:Boolean;ppLine:PPspirvOp=nil):PsrRegNode;
Function NewReg_i(dtype:TsrDataType;value:Integer;ppLine:PPspirvOp=nil):PsrRegNode;
Function NewReg_s(dtype:TsrDataType;value:Single;ppLine:PPspirvOp=nil):PsrRegNode;
//
function NewSpirvOp(OpId:DWORD):PSpirvOp;
function NewLabelOp(sdep:Boolean):PSpirvOp;
function AddSpirvOp(OpId:DWORD):PSpirvOp;
function AddSpirvOp(pLine:PspirvOp;OpId:DWORD):PSpirvOp;
function AddSpirvOp(pLine,pNew:PspirvOp):PSpirvOp;
function AddSGlslOp(pLine:PspirvOp;OpId:DWORD):PSpirvOp;
//
procedure PostLink(pLine,dst:PsrNode); override;
procedure MakeCopy(dst:PsrRegSlot;src:PsrRegNode);
//
Procedure SetConst(pSlot:PsrRegSlot;pConst:PsrConst);
Procedure SetConst_q(pSlot:PsrRegSlot;dtype:TsrDataType;value:QWORD);
Procedure SetConst_b(pSlot:PsrRegSlot;value:Boolean);
Procedure SetConst_i(pSlot:PsrRegSlot;dtype:TsrDataType;value:Integer);
Procedure SetConst_s(pSlot:PsrRegSlot;dtype:TsrDataType;value:Single);
//
function AllocBlockOp:PsrOpBlock;
function NewBlockOp(Snap:TsrRegsSnapshot):PsrOpBlock;
function InsertBlockOp(pLine:PspirvOp;pChild:PsrOpBlock):PspirvOp;
//
procedure AddCapability(ID:DWORD);
end;
implementation
function TEmitInterface.Alloc(Size:ptruint):Pointer;
begin
Result:=Allocator.Alloc(Size);
end;
Function TEmitInterface.GetConfig:Pointer;
begin
Result:=@Config;
end;
Function TEmitInterface.GetCodeHeap:Pointer;
begin
Result:=@CodeHeap;
end;
Function TEmitInterface.GetLiteralList:Pointer;
begin
Result:=@LiteralList;
end;
Function TEmitInterface.GetTypeList:Pointer;
begin
Result:=@TypeList;
end;
Function TEmitInterface.GetConstList:Pointer;
begin
Result:=@ConstList;
end;
Function TEmitInterface.GetRegsStory:Pointer;
begin
Result:=@RegsStory;
end;
Function TEmitInterface.GetCapabilityList:Pointer;
begin
Result:=@CapabilityList;
end;
Function TEmitInterface.GetHeaderList:Pointer;
begin
Result:=@HeaderList;
end;
Function TEmitInterface.GetDecorateList:Pointer;
begin
Result:=@DecorateList;
end;
Function TEmitInterface.GetDebugInfoList:Pointer;
begin
Result:=@DebugInfoList;
end;
Function TEmitInterface.GetVariableList:Pointer;
begin
Result:=@VariableList;
end;
Function TEmitInterface.GetInputList:Pointer;
begin
Result:=@InputList;
end;
Function TEmitInterface.GetOutputList:Pointer;
begin
Result:=@OutputList;
end;
Function TEmitInterface.GetDataLayoutList:Pointer;
begin
Result:=@DataLayoutList;
end;
Function TEmitInterface.GetVertLayoutList:Pointer;
begin
Result:=@VertLayoutList;
end;
Function TEmitInterface.GetFragLayoutList:Pointer;
begin
Result:=@FragLayoutList;
end;
Function TEmitInterface.GetBufferList:Pointer;
begin
Result:=@BufferList;
end;
Function TEmitInterface.GetUniformList:Pointer;
begin
Result:=@UniformList;
end;
Function TEmitInterface.GetBitcastList:Pointer;
begin
Result:=@BitcastList;
end;
Function TEmitInterface.GetCacheOpList:Pointer;
begin
Result:=@CacheOpList;
end;
Function TEmitInterface.GetFuncList:Pointer;
begin
Result:=@FuncList;
end;
Function TEmitInterface.GetCursor:Pointer;
begin
Result:=@Cursor;
end;
//
function TEmitInterface.NewRefNode:PsrNode;
begin
Result:=Alloc(SizeOf(TsrRefNode));
PsrRefNode(Result)^.Init;
end;
Function TEmitInterface.line:PspirvOp;
begin
Result:=nil;
if (Main<>nil) then
begin
Result:=Main^.line;
end;
end;
function TEmitInterface.curr_line:Pointer;
begin
Result:=line;
end;
function TEmitInterface.init_line:Pointer;
begin
Assert(InitBlock<>nil);
if (InitBlock^.dummy.Parent=nil) then //is not init?
begin
InitBlock^.Init(Self);
end;
Result:=InitBlock^.line;
Assert(Result<>nil);
end;
Procedure TEmitInterface.InitLists;
begin
Config.Init;
LiteralList .Init(Self);
TypeList .Init(Self);
ConstList .Init(Self);
RegsStory .Init(Self);
CapabilityList.Init(Self);
HeaderList .Init(Self);
DecorateList .Init(Self);
DebugInfoList .Init(Self);
VariableList .Init(Self);
InputList .Init(Self);
OutputList .Init(Self);
DataLayoutList.Init(Self);
VertLayoutList.Init(Self);
FragLayoutList.Init(Self);
BufferList .Init(Self);
UniformList .Init(Self);
PrivateList .Init(Self);
BitcastList .Init(Self);
CacheOpList .Init(Self);
end;
function TEmitInterface.NewVariable:Pointer;
begin
Result:=VariableList.Fetch;
end;
//
function TEmitInterface._get_line(ppLine:PPspirvOp):PspirvOp;
begin
if (ppLine=nil) then Exit(line);
if (ppLine^=nil) then Exit(line);
Result:=ppLine^;
end;
//
Function TEmitInterface.NewRegPair:PsrRegPair;
begin
Result:=Alloc(SizeOf(TsrRegPair));
Result^.Init;
end;
Function TEmitInterface.NewReg(rtype:TsrDataType):PsrRegNode;
begin
Result:=RegsStory.FUnattach.New(line,rtype);
end;
Function TEmitInterface.NewReg(pConst:PsrConst;ppLine:PPspirvOp=nil):PsrRegNode;
begin
if (pConst=nil) then Exit(nil);
Result:=NewReg(pConst^.dtype);
Result^.pWriter:=pConst;
Result^.pLine:=_get_line(ppLine);
end;
//
Function TEmitInterface.NewReg_q(dtype:TsrDataType;value:QWORD;ppLine:PPspirvOp=nil):PsrRegNode;
begin
Result:=NewReg(ConstList.Fetch(dtype,value),ppLine);
end;
Function TEmitInterface.NewReg_b(value:Boolean;ppLine:PPspirvOp=nil):PsrRegNode;
begin
Result:=NewReg(ConstList.Fetch_b(value),ppLine);
end;
Function TEmitInterface.NewReg_i(dtype:TsrDataType;value:Integer;ppLine:PPspirvOp=nil):PsrRegNode;
begin
Result:=NewReg(ConstList.Fetch_i(dtype,value),ppLine);
end;
Function TEmitInterface.NewReg_s(dtype:TsrDataType;value:Single;ppLine:PPspirvOp=nil):PsrRegNode;
begin
Result:=NewReg(ConstList.Fetch_s(dtype,value),ppLine);
end;
function TEmitInterface.NewSpirvOp(OpId:DWORD):PSpirvOp;
begin
Result:=Alloc(SizeOf(TSpirvOp));
Result^.Init(OpId);
Result^.adr:=Cursor.Adr;
end;
function TEmitInterface.NewLabelOp(sdep:Boolean):PSpirvOp;
Var
node:PSpirvOp;
begin
node:=NewSpirvOp(Op.OpLabel);
node^.pDst:=NewRefNode;
Result:=node;
if sdep then node^.pDst^.mark_read(nil);
end;
function TEmitInterface.AddSpirvOp(OpId:DWORD):PSpirvOp;
begin
Result:=AddSpirvOp(line,OpId);
end;
function TEmitInterface.AddSpirvOp(pLine:PspirvOp;OpId:DWORD):PSpirvOp;
begin
Result:=InsSpirvOp(pLine,NewSpirvOp(OpId));
end;
function TEmitInterface.AddSpirvOp(pLine,pNew:PspirvOp):PSpirvOp;
begin
Result:=InsSpirvOp(pLine,pNew);
end;
function TEmitInterface.AddSGlslOp(pLine:PspirvOp;OpId:DWORD):PSpirvOp;
var
ext,node:PSpirvOp;
begin
ext:=HeaderList.emit_glsl_ext;
node:=AddSpirvOp(pLine,Op.OpExtInst);
node^.AddParam(ext^.pDst);
node^.AddLiteral(OpId,GlslOp.GetStr(OpId));
Result:=node;
end;
procedure TEmitInterface.PostLink(pLine,dst:PsrNode);
var
node:PspirvOp;
begin
node:=pLine^.AsType(ntOpCustom);
Assert(node<>nil);
if node^.IsType(ntOp) then
if (node^.OpId=Op.OpNop) then
begin
node^.AddParam(dst);
Exit;
end;
node:=AddSpirvOp(node,Op.OpNop);
node^.AddParam(dst);
node^.mark_not_used;
end;
procedure TEmitInterface.MakeCopy(dst:PsrRegSlot;src:PsrRegNode);
var
node:PsrRegNode;
begin
node:=dst^.New(line,src^.dtype);
node^.pWriter:=src;
PostLink(line,node); //post processing
end;
Procedure TEmitInterface.SetConst(pSlot:PsrRegSlot;pConst:PsrConst);
var
dst:PsrRegNode;
begin
dst:=pSlot^.New(line,pConst^.dtype);
dst^.pWriter:=pConst;
PostLink(line,dst); //post processing
end;
Procedure TEmitInterface.SetConst_q(pSlot:PsrRegSlot;dtype:TsrDataType;value:QWORD);
begin
SetConst(pSlot,ConstList.Fetch(dtype,value));
end;
Procedure TEmitInterface.SetConst_b(pSlot:PsrRegSlot;value:Boolean);
begin
SetConst(pSlot,ConstList.Fetch_b(value));
end;
Procedure TEmitInterface.SetConst_i(pSlot:PsrRegSlot;dtype:TsrDataType;value:Integer);
begin
SetConst(pSlot,ConstList.Fetch_i(dtype,value));
end;
Procedure TEmitInterface.SetConst_s(pSlot:PsrRegSlot;dtype:TsrDataType;value:Single);
begin
SetConst(pSlot,ConstList.Fetch_s(dtype,value));
end;
function TEmitInterface.AllocBlockOp:PsrOpBlock;
begin
Result:=Alloc(SizeOf(TsrOpBlock));
Result^.Init(Self);
end;
function TEmitInterface.NewBlockOp(Snap:TsrRegsSnapshot):PsrOpBlock;
begin
Result:=AllocBlockOp;
Result^.Regs.pSnap :=Alloc(SizeOf(TsrRegsSnapshot));
Result^.Regs.pSnap^:=Snap;
Result^.Regs.FVolMark:=vmNone;
Result^.Cond.FUseCont:=false;
end;
function TEmitInterface.InsertBlockOp(pLine:PspirvOp;pChild:PsrOpBlock):PspirvOp;
begin
pLine:=InsSpirvOp(pLine,PspirvOp(pChild));
pChild^.UpdateLevel;
Result:=pLine;
end;
//
procedure TEmitInterface.AddCapability(ID:DWORD);
begin
CapabilityList.Add(ID);
end;
end.

View File

@ -5,18 +5,25 @@ unit srLayout;
interface
uses
ps4_shader,
srNodes,
srParser,
srCFG,
srTypes,
srReg,
srVariable,
srRefId,
srDecorate;
sysutils,
ps4_shader,
spirv,
ginodes,
srNode,
srCFGParser,
srCFGCursor,
srType,
srTypes,
srReg,
srOp,
srVariable,
srBitcast,
srRefId,
srDecorate;
type
TsrResourceType=(
rtRoot,
rtBufPtr2,
rtFunPtr2,
rtVSharp4,
@ -26,41 +33,82 @@ type
);
type
ntChain=class(TsrNodeVmt)
class Procedure zero_read (node:PsrNode); override;
class Procedure zero_unread (node:PsrNode); override;
class Function pwrite_count(node:PsrNode):PDWORD; override;
class function Next (node:PsrNode):Pointer; override;
class function Prev (node:PsrNode):Pointer; override;
class function Parent (node:PsrNode):Pointer; override;
class Procedure PrepType (node:PPrepTypeNode); override;
class function GetPrintName(node:PsrNode):RawByteString; override;
class function GetRef (node:PsrNode):Pointer; override;
end;
PsrDataLayout=^TsrDataLayout;
PsrChainExt=^TsrChainExt;
TsrChainExt=object
PsrChainLvl_1=^TsrChainLvl_1;
TsrChainLvl_1=object
pIndex:PsrRegNode;
stride:PtrUint;
function c(n1,n2:PsrChainExt):Integer; static;
function c(n1,n2:PsrChainLvl_1):Integer; static;
end;
PsrChainLvl_0=^TsrChainLvl_0;
TsrChainLvl_0=object
size :PtrUint;
offset:PtrUint;
function c(n1,n2:PsrChainLvl_0):Integer; static;
end;
PsrChain=^TsrChain;
TsrChain=object
pLeft,pRight:PsrChain;
//----
read_count:DWORD;
write_count:DWORD;
parent:PsrDataLayout;
key:packed record
ext:TsrChainExt;
size,offset:PtrUint;
end;
rSlot:TsrRegSlot;
pField:Pointer;
pLine:Pointer;
ID:TsrRefId; //post id
function c(n1,n2:PsrChain):Integer; static;
Procedure mark_read;
Procedure mark_unread;
Procedure mark_write;
Procedure SetRegType(rtype:TsrDataType);
function GetRegType:TsrDataType;
function IsUsed:Boolean;
TsrChain=object(TsrNode)
type
PVNode=^TVNode;
TVNode=record
pPrev,pNext:PVNode;
pLine:PspirvOp;
end;
TNodeList=specialize TNodeList<PVNode>;
private
pLeft,pRight:PsrChain;
//--
fwrite_count:DWORD;
//--
ID:TsrRefId; //post id
FParent:PsrDataLayout;
key:packed record
lvl_1:TsrChainLvl_1;
lvl_0:TsrChainLvl_0;
end;
Fdtype:TsrDataType;
FList:TNodeList;
function c(n1,n2:PsrChain):Integer; static;
Procedure SetRegType(rtype:TsrDataType);
public
pField:Pointer;
//pLine:Pointer;
property Parent:PsrDataLayout read FParent;
property pIndex:PsrRegNode read key.lvl_1.pIndex;
property stride:PtrUint read key.lvl_1.stride;
property size :PtrUint read key.lvl_0.size;
property offset:PtrUint read key.lvl_0.offset;
property dtype:TsrDataType read Fdtype write SetRegType;
Procedure Init(L:PsrDataLayout);
function Emit:TCustomEmit;
Procedure UpdateRegType;
Procedure PrepType(new:TsrDataType);
procedure AddLine(pLine:PspirvOp);
function FirstLine:PspirvOp;
procedure FetchLoad(pLine:PspirvOp;dst:PsrRegNode);
Procedure FetchStore(pLine:PspirvOp;src:PsrRegNode);
function GetPrintName:RawByteString;
end;
TsrChains=array[0..7] of PsrChain;
TChainCb=function(node:PsrChain):Integer of object;
//----
TsrDataLayout=object
@ -76,45 +124,65 @@ type
end;
pData:Pointer;
FID:Integer;
Alloc:TfnAlloc;
FEmit:TCustomEmit;
FList:TChainFetch;
function c(n1,n2:PsrDataLayout):Integer; static;
function Fetch(o,s:PtrUint;ext:PsrChainExt):PsrChain;
function Fetch(lvl_0:PsrChainLvl_0;lvl_1:PsrChainLvl_1):PsrChain;
Function First:PsrChain;
Function Last:PsrChain;
Function Next(node:PsrChain):PsrChain;
Function Prev(node:PsrChain):PsrChain;
Function NextChain(node:PsrChain):PsrChain;
Function PrevChain(node:PsrChain):PsrChain;
function EnumChain(cb:TChainCb):Integer;
function GetData:Pointer;
function IsUserData:Boolean; inline;
function GetStride:PtrUint;
function GetTypeChar:Char;
function GetString:RawByteString;
function GetFuncString(LEN:DWORD):RawByteString;
end;
PsrDataLayoutList=^TsrDataLayoutList;
TsrDataLayoutList=object
type
TNodeFetch=specialize TNodeFetch<PsrDataLayout,TsrDataLayout>;
var
FTop:TsrDataLayout;
FNTree:TNodeFetch;
procedure Init(cb:TfnAlloc);
procedure Init(Emit:TCustomEmit);
procedure SetUserData(pData:Pointer);
function pRoot:PsrDataLayout;
function Fetch(p:PsrDataLayout;o:PtrUint;t:TsrResourceType):PsrDataLayout;
Function First:PsrDataLayout;
Function Next(node:PsrDataLayout):PsrDataLayout;
function Grouping(const chain:TsrChains;rtype:TsrResourceType):PsrDataLayout;
function EnumChain(cb:TChainCb):Integer;
Procedure AllocID;
procedure AllocSourceExtension(FDebugInfo:PsrDebugInfoList);
procedure AllocFuncExt(FDebugInfo:PsrDebugInfoList;var Heap:TsrCodeHeap);
procedure AllocSourceExtension;
procedure AllocFuncExt;
end;
//----
ntDescriptor=class(TsrNodeVmt)
class Procedure zero_read (node:PsrNode); override;
class Procedure zero_unread (node:PsrNode); override;
class Function GetPtype (node:PsrNode):PsrNode; override;
class Function GetStorageClass(node:PsrNode):DWORD; override;
end;
PsrDescriptor=^TsrDescriptor;
TsrDescriptor=object
pVar:PsrVariable;
FStorage:DWORD;
FBinding:Integer;
TsrDescriptor=packed object(TsrNode)
protected
FVar:PsrVariable;
FType:PsrType;
FStorage:DWORD;
FBinding:Integer;
procedure InitVar(Emit:TCustomEmit);
procedure InitType(rtype:TsrDataType;Emit:TCustomEmit);
procedure SetType(t:PsrType);
public
property pVar:PsrVariable read FVar;
property pType:PsrType read FType write SetType;
end;
function is_consistents(const chains:TsrChains;count:Byte):Boolean;
@ -124,6 +192,88 @@ function GetResourceSizeDw(r:TsrResourceType):Byte;
implementation
class Procedure ntChain.zero_read(node:PsrNode);
begin
With PsrChain(node)^ do
begin
key.lvl_1.pIndex^.mark_read(node);
end;
end;
class Procedure ntChain.zero_unread(node:PsrNode);
begin
With PsrChain(node)^ do
begin
key.lvl_1.pIndex^.mark_unread(node);
end;
end;
class Function ntChain.pwrite_count(node:PsrNode):PDWORD;
begin
Result:=@PsrChain(node)^.fwrite_count;
end;
class function ntChain.Next(node:PsrNode):Pointer;
begin
Result:=PsrChain(node)^.FParent^.NextChain(PsrChain(node));
end;
class function ntChain.Prev(node:PsrNode):Pointer;
begin
Result:=PsrChain(node)^.FParent^.PrevChain(PsrChain(node));
end;
class function ntChain.Parent(node:PsrNode):Pointer;
begin
Result:=PsrChain(node)^.FParent;
end;
class Procedure ntChain.PrepType(node:PPrepTypeNode);
begin
PsrChain(node^.dnode)^.PrepType(TsrDataType(node^.rtype));
node^.dnode:=nil;
end;
class function ntChain.GetPrintName(node:PsrNode):RawByteString;
begin
Result:=PsrChain(node)^.GetPrintName;
end;
class function ntChain.GetRef(node:PsrNode):Pointer;
begin
Result:=@PsrChain(node)^.ID;
end;
//
class Procedure ntDescriptor.zero_read(node:PsrNode);
begin
With PsrDescriptor(node)^ do
begin
pType^.mark_read(node);
end;
end;
class Procedure ntDescriptor.zero_unread(node:PsrNode);
begin
With PsrDescriptor(node)^ do
begin
pType^.mark_unread(node);
end;
end;
class Function ntDescriptor.GetPtype(node:PsrNode):PsrNode;
begin
Result:=PsrDescriptor(node)^.FType;
end;
class Function ntDescriptor.GetStorageClass(node:PsrNode):DWORD;
begin
Result:=PsrDescriptor(node)^.FStorage;
end;
//
function TsrDataLayout.c(n1,n2:PsrDataLayout):Integer;
begin
//first parent
@ -136,37 +286,29 @@ begin
Result:=Integer(n1^.key.rtype>n2^.key.rtype)-Integer(n1^.key.rtype<n2^.key.rtype);
end;
function TsrDataLayout.Fetch(o,s:PtrUint;ext:PsrChainExt):PsrChain;
function TsrDataLayout.Fetch(lvl_0:PsrChainLvl_0;lvl_1:PsrChainLvl_1):PsrChain;
var
node:TsrChain;
begin
node:=Default(TsrChain);
node.key.offset:=o;
node.key.size :=s;
if (ext<>nil) then
if (lvl_0<>nil) then
begin
node.key.ext:=ext^;
node.key.lvl_0:=lvl_0^;
end;
if (lvl_1<>nil) then
begin
node.key.lvl_1:=lvl_1^;
end;
Result:=FList.Find(@node);
if (Result=nil) then
begin
Result:=Alloc(SizeOf(TsrChain));
Result^.parent:=@Self;
Result^.key.offset:=o;
Result^.key.size :=s;
if (ext<>nil) then
begin
Result^.key.ext:=ext^;
end;
Result^.rSlot.Init(Alloc,'CHAIN');
Result:=FEmit.Alloc(SizeOf(TsrChain));
Move(node,Result^,SizeOf(TsrChain));
Result^.Init(@Self);
FList.Insert(Result);
end else
begin
if (ext<>nil) then
if (ext^.pIndex<>nil) then
begin
ext^.pIndex^.mark_unread;
end;
end;
end;
@ -180,21 +322,38 @@ begin
Result:=FList.Max;
end;
Function TsrDataLayout.Next(node:PsrChain):PsrChain;
Function TsrDataLayout.NextChain(node:PsrChain):PsrChain;
begin
Result:=FList.Next(node);
end;
Function TsrDataLayout.Prev(node:PsrChain):PsrChain;
Function TsrDataLayout.PrevChain(node:PsrChain):PsrChain;
begin
Result:=FList.Prev(node);
end;
function TsrDataLayout.EnumChain(cb:TChainCb):Integer;
var
node:PsrChain;
begin
Result:=0;
node:=First;
While (node<>nil) do
begin
if node^.IsUsed then
begin
Result:=Result+cb(node);
end;
node:=node^.Next;
end;
end;
function TsrDataLayout.GetData:Pointer;
begin
Result:=nil;
if (pData<>nil) then
Case key.rtype of
rtRoot,
rtBufPtr2,
rtFunPtr2:Result:=pData;
rtVSharp4:Result:={%H-}Pointer(PVSharpResource4(pData)^.base);
@ -209,16 +368,23 @@ begin
Result:=0;
if (pData<>nil) then
Case key.rtype of
rtRoot,
rtBufPtr2:Result:=4;
rtVSharp4:Result:=PVSharpResource4(pData)^.stride;
else;
end;
end;
function TsrDataLayout.IsUserData:Boolean; inline;
begin
Result:=(key.rtype=rtRoot);
end;
function TsrDataLayout.GetTypeChar:Char;
begin
Result:=#0;
case key.rtype of
rtRoot :Result:='R';
rtBufPtr2:Result:='B';
rtFunPtr2:Result:='F';
rtVSharp4:Result:='V';
@ -249,9 +415,9 @@ begin
';LEN='+HexStr(LEN,8);
end;
procedure TsrDataLayoutList.Init(cb:TfnAlloc);
procedure TsrDataLayoutList.Init(Emit:TCustomEmit);
begin
FTop.Alloc:=cb;
FTop.FEmit:=Emit;
FNTree.Insert(@FTop);
end;
@ -260,38 +426,42 @@ begin
FTop.pData:=pData;
end;
function TsrDataLayoutList.pRoot:PsrDataLayout;
begin
Result:=@FTop;
end;
function TsrDataLayoutList.Fetch(p:PsrDataLayout;o:PtrUint;t:TsrResourceType):PsrDataLayout;
var
node:TsrDataLayout;
pData:Pointer;
begin
Assert(p<>nil);
node:=Default(TsrDataLayout);
node.Alloc:=FTop.Alloc;
node.FEmit:=FTop.FEmit;
node.key.parent:=p;
node.key.offset:=o;
node.key.rtype :=t;
Result:=FNTree.Find(@node);
if (Result=nil) then
begin
Result:=FTop.Alloc(SizeOf(TsrDataLayout));
Result:=FTop.FEmit.Alloc(SizeOf(TsrDataLayout));
Move(node,Result^,SizeOf(TsrDataLayout));
FNTree.Insert(Result);
Result^.FID:=-1;
if (p<>nil) then
begin
pData:=p^.GetData;
if (pData<>nil) then
case t of
rtBufPtr2,
rtFunPtr2:Result^.pData:={%H-}Pointer(PPtrUint(pData+o)^ and (not 3));
rtVSharp4,
rtSSharp4,
rtTSharp4,
rtTSharp8:Result^.pData:=pData+o;
end;
end;
pData:=p^.GetData;
if (pData<>nil) then
case t of
rtRoot,
rtBufPtr2,
rtFunPtr2:Result^.pData:={%H-}Pointer(PPtrUint(pData+o)^ and (not 3));
rtVSharp4,
rtSSharp4,
rtTSharp4,
rtTSharp8:Result^.pData:=pData+o;
end;
end;
end;
@ -310,6 +480,7 @@ function GetResourceSizeDw(r:TsrResourceType):Byte;
begin
Result:=0;
Case r of
rtRoot :Result:=2;
rtBufPtr2:Result:=2;
rtFunPtr2:Result:=2;
rtVSharp4:Result:=4;
@ -333,7 +504,21 @@ begin
Assert(False,'indexed chain not support');
end;
Result:=Fetch(chain[0]^.parent,chain[0]^.key.offset,rtype);
Result:=Fetch(chain[0]^.Parent,chain[0]^.offset,rtype);
end;
function TsrDataLayoutList.EnumChain(cb:TChainCb):Integer;
var
node:PsrDataLayout;
begin
Result:=0;
if (cb=nil) then Exit;
node:=First;
While (node<>nil) do
begin
Result:=Result+node^.EnumChain(cb);
node:=Next(node);
end;
end;
Procedure TsrDataLayoutList.AllocID;
@ -354,40 +539,53 @@ begin
end;
end;
procedure TsrDataLayoutList.AllocSourceExtension(FDebugInfo:PsrDebugInfoList);
procedure TsrDataLayoutList.AllocSourceExtension;
var
pDebugInfoList:PsrDebugInfoList;
node:PsrDataLayout;
begin
if (FDebugInfo=nil) then Exit;
pDebugInfoList:=FTop.FEmit.GetDebugInfoList;
node:=First;
While (node<>nil) do
begin
FDebugInfo^.emit_source_extension(node^.GetString);
pDebugInfoList^.OpSourceExtension(node^.GetString);
node:=Next(node);
end;
end;
procedure TsrDataLayoutList.AllocFuncExt(FDebugInfo:PsrDebugInfoList;var Heap:TsrCodeHeap);
procedure TsrDataLayoutList.AllocFuncExt;
var
pDebugInfoList:PsrDebugInfoList;
pHeap:PsrCodeHeap;
node:PsrDataLayout;
block:PsrCodeBlock;
begin
pDebugInfoList:=FTop.FEmit.GetDebugInfoList;
pHeap:=FTop.FEmit.GetCodeHeap;
node:=First;
While (node<>nil) do
begin
if (node^.key.rtype=rtFunPtr2) then
begin
block:=Heap.FindByPtr(node^.pData);
block:=pHeap^.FindByPtr(node^.pData);
if (block<>nil) then
begin
FDebugInfo^.emit_source_extension(node^.GetFuncString(block^.Size));
pDebugInfoList^.OpSourceExtension(node^.GetFuncString(block^.Size));
end;
end;
node:=Next(node);
end;
end;
function TsrChainExt.c(n1,n2:PsrChainExt):Integer;
//
Procedure TsrChain.Init(L:PsrDataLayout);
begin
fntype:=ntChain;
FParent:=L;
end;
function TsrChainLvl_1.c(n1,n2:PsrChainLvl_1):Integer;
begin
//first pIndex forward
Result:=Integer(n1^.pIndex>n2^.pIndex)-Integer(n1^.pIndex<n2^.pIndex);
@ -397,62 +595,237 @@ begin
Result:=Integer(n1^.stride>n2^.stride)-Integer(n1^.stride<n2^.stride);
end;
function TsrChainLvl_0.c(n1,n2:PsrChainLvl_0):Integer;
begin
//first size backward
Result:=Integer(n1^.size<n2^.size)-Integer(n1^.size>n2^.size);
if (Result<>0) then Exit;
//second offset forward
Result:=Integer(n1^.offset>n2^.offset)-Integer(n1^.offset<n2^.offset);
end;
function TsrChain.c(n1,n2:PsrChain):Integer;
begin
//first ext
Result:=TsrChainExt.c(@n1^.key.ext,@n2^.key.ext);
//first lvl_1
Result:=TsrChainLvl_1.c(@n1^.key.lvl_1,@n2^.key.lvl_1);
if (Result<>0) then Exit;
//second size backward
Result:=Integer(n1^.key.size<n2^.key.size)-Integer(n1^.key.size>n2^.key.size);
if (Result<>0) then Exit;
//third offset forward
Result:=Integer(n1^.key.offset>n2^.key.offset)-Integer(n1^.key.offset<n2^.key.offset);
//second lvl_0
Result:=TsrChainLvl_0.c(@n1^.key.lvl_0,@n2^.key.lvl_0);
end;
Procedure TsrChain.mark_read;
function TsrChain.Emit:TCustomEmit;
begin
Inc(read_count);
end;
Procedure TsrChain.mark_unread;
begin
if (read_count<>0) then Dec(read_count);
end;
Procedure TsrChain.mark_write;
begin
Inc(write_count);
Result:=FParent^.FEmit;
end;
Procedure TsrChain.SetRegType(rtype:TsrDataType);
var
node:PsrRegNode;
pTypeList:PsrTypeList;
FType:PsrType;
node:PVNode;
pLine:PspirvOp;
begin
node:=rSlot.pStory.pHead;
Fdtype:=rtype;
pTypeList:=Emit.GetTypeList;
FType:=pTypeList^.Fetch(rtype);
node:=FList.pHead;
While (node<>nil) do
begin
node^.dtype:=rtype;
pLine:=node^.pLine;
Case pLine^.OpId of
Op.OpLoad:
begin
pLine^.pDst^.PrepType(ord(rtype));
pLine^.pType:=Ftype;
end;
Op.OpStore:
begin
pLine^.ParamFirst^.Value^.PrepType(ord(rtype));
end;
else;
end;
node:=node^.pNext;
end;
end;
function TsrChain.GetRegType:TsrDataType;
Procedure TsrChain.UpdateRegType;
var
pReg:PsrRegNode;
pTypeList:PsrTypeList;
pBitcastList:PsrBitcastList;
FType:PsrType;
node:PVNode;
pLine:PspirvOp;
dst:PsrRegNode;
old,rtype:TsrDataType;
begin
Result:=dtUnknow;
pReg:=rSlot.current;
if (pReg=nil) then Exit;
Result:=pReg^.dtype;
rtype:=Fdtype;
pTypeList:=Emit.GetTypeList;
FType:=pTypeList^.Fetch(rtype);
pBitcastList:=Emit.GetBitcastList;
node:=FList.pHead;
While (node<>nil) do
begin
pLine:=node^.pLine;
Case pLine^.OpId of
Op.OpLoad:
begin
pLine^.pDst^.PrepType(ord(rtype));
pLine^.pType:=Ftype;
dst:=pLine^.pDst^.AsType(ntReg);
if (dst<>nil) then
begin
old:=dst^.dtype;
if (old<>dtUnknow) and (not CompareType(rtype,old)) then
begin
//OpLoad -> new -> dst
pBitcastList:=Emit.GetBitcastList;
dst:=pBitcastList^.FetchDstr(rtype,dst);
pLine^.pDst:=dst;
end;
end;
end;
Op.OpStore:
begin
pLine^.ParamFirst^.Value^.PrepType(ord(rtype));
dst:=pLine^.ParamFirst^.Value^.AsType(ntReg);
if (dst<>nil) then
begin
old:=dst^.dtype;
if (old<>dtUnknow) and (rtype<>old) then
begin
//OpStore <- new <- dst
pBitcastList:=Emit.GetBitcastList;
dst:=pBitcastList^.FetchRead(rtype,dst);
pLine^.ParamFirst^.Value:=dst;
end;
end;
end;
else;
end;
node:=node^.pNext;
end;
end;
function TsrChain.IsUsed:Boolean;
Procedure TsrChain.PrepType(new:TsrDataType);
var
old:TsrDataType;
begin
Result:=((read_count<>0) or
(write_count<>0)) and
(rSlot.current<>nil);
if (new=dtUnknow) then Exit;
old:=Fdtype;
if is_unprep_type(old,new,True) then
begin
old:=StoreType(new);
SetRegType(old);
end;
end;
procedure TsrChain.AddLine(pLine:PspirvOp);
var
node:PVNode;
begin
node:=Emit.Alloc(SizeOf(TVNode));
node^.pLine:=pLine;
FList.Push_tail(node);
end;
function TsrChain.FirstLine:PspirvOp;
var
node:PVNode;
begin
Result:=nil;
node:=FList.pHead;
if (node<>nil) then
begin
Result:=node^.pLine;
end;
end;
procedure TsrChain.FetchLoad(pLine:PspirvOp;dst:PsrRegNode);
var
pTypeList:PsrTypeList;
begin
Assert(dst<>nil);
PrepType(dst^.dtype);
pTypeList:=Emit.GetTypeList;
pLine:=PspirvOp(Emit.OpLoad(pLine,pTypeList^.Fetch(Fdtype),dst,@Self));
AddLine(pLine);
end;
Procedure TsrChain.FetchStore(pLine:PspirvOp;src:PsrRegNode);
begin
if (src=nil) then Exit;
PrepType(src^.dtype);
pLine:=PspirvOp(Emit.OpStore(pLine,@Self,src));
AddLine(pLine);
end;
function TsrChain.GetPrintName:RawByteString;
begin
Assert(ID.Alloc);
Result:='ac'+IntToStr(ID.ID);
end;
//
procedure TsrDescriptor.InitVar(Emit:TCustomEmit);
var
pVariableList:PsrVariableList;
begin
if (Emit=nil) then Exit;
if (FVar<>nil) then Exit;
//
pVariableList:=Emit.GetVariableList;
//
FVar:=pVariableList^.Fetch;
FVar^.pSource:=@Self;
end;
procedure TsrDescriptor.InitType(rtype:TsrDataType;Emit:TCustomEmit);
var
pTypeList:PsrTypeList;
begin
if (Emit=nil) then Exit;
if (FType<>nil) then Exit;
//
pTypeList:=Emit.GetTypeList;
//
SetType(pTypeList^.Fetch(rtype));
end;
procedure TsrDescriptor.SetType(t:PsrType);
begin
if (FType=t) then Exit;
if not IsUsed then
begin
t^.mark_read (@Self);
FType^.mark_unread(@Self);
end;
FType:=t;
end;
function is_consistents(const chains:TsrChains;count:Byte):Boolean;
@ -467,14 +840,14 @@ begin
Result:=False;
if (chains[0]=nil) then Exit;
parent:=chains[0]^.parent;
offset:=chains[0]^.key.offset;
offset:=chains[0]^.offset;
For i:=1 to count-1 do
begin
t:=chains[i-1]^.key.size;
t:=chains[i-1]^.size;
offset:=offset+t;
if (chains[i]=nil) then Exit;
if (chains[i]^.parent<>parent) then Exit;
t:=chains[i]^.key.offset;
t:=chains[i]^.offset;
if (offset<>t) then Exit;
end;
Result:=True;
@ -489,7 +862,7 @@ begin
For i:=0 to count-1 do
begin
if (chains[i]=nil) then Exit;
if (chains[i]^.key.ext.pIndex<>nil) then Exit;
if (chains[i]^.key.lvl_1.pIndex<>nil) then Exit;
end;
Result:=True;
end;

443
spirv/srLiteral.pas Normal file
View File

@ -0,0 +1,443 @@
unit srLiteral;
{$mode objfpc}{$H+}
interface
uses
sysutils,
half16,
srType,
ginodes,
srNode;
type
ntLiteral=class(TsrNodeVmt)
class function GetPrintData(node:PsrNode):RawByteString; override;
class function GetData(node:PsrNode;data:Pointer):Ptruint; override;
end;
ntLiteralString=class(ntLiteral)
class function GetPrintData(node:PsrNode):RawByteString; override;
class function GetData(node:PsrNode;data:Pointer):Ptruint; override;
end;
ntLiteralConst=class(ntLiteral)
class function GetPrintData(node:PsrNode):RawByteString; override;
class function GetData(node:PsrNode;data:Pointer):Ptruint; override;
end;
PsrLiteral=^TsrLiteral;
TsrLiteral=object(TsrNode)
private
pLeft,pRight:PsrLiteral;
public
dtype:TsrDataType;
Value:PtrUint;
name:PChar;
function c(n1,n2:PsrLiteral):Integer; static;
Procedure Init; inline;
Function AsBool:Boolean; inline;
Function AsUint8:Byte; inline;
Function AsInt8:Shortint; inline;
Function AsUint16:Word; inline;
Function AsInt16:Smallint; inline;
Function AsUint32:DWORD; inline;
function AsInt32:Integer; inline;
Function AsUint64:QWORD; inline;
Function AsInt64:Int64; inline;
Function AsHalf16:THalf16; inline;
Function AsFloat32:Single; inline;
Function AsFloat64:Double; inline;
Function GetPrintData:RawByteString;
Function GetData(data:Pointer):Ptruint;
end;
PsrLiteralString=^TsrLiteralString;
TsrLiteralString=object(TsrLiteral)
Procedure Init; inline;
Function GetPrintData:RawByteString;
Function GetData(data:Pointer):Ptruint;
end;
PsrLiteralConst=^TsrLiteralConst;
TsrLiteralConst=object(TsrLiteral)
Procedure Init; inline;
Function GetPrintData:RawByteString;
Function GetData(data:Pointer):Ptruint;
end;
PsrLiteralList=^TsrLiteralList;
TsrLiteralList=object
type
TNodeFetch=specialize TNodeFetch<PsrLiteral,TsrLiteral>;
var
FEmit:TCustomEmit;
FNTree:TNodeFetch;
Procedure Init(Emit:TCustomEmit);
function FetchLiteral(Value:PtrUint;name:PChar):PsrLiteral;
function FetchString(name:PChar):PsrLiteralString;
function FetchConst(dtype:TsrDataType;Value:PtrUint):PsrLiteralConst;
end;
implementation
class function ntLiteral.GetPrintData(node:PsrNode):RawByteString;
begin
Result:=PsrLiteral(node)^.GetPrintData;
end;
class function ntLiteral.GetData(node:PsrNode;data:Pointer):Ptruint;
begin
Result:=PsrLiteral(node)^.GetData(data);
end;
//
class function ntLiteralString.GetPrintData(node:PsrNode):RawByteString;
begin
Result:=PsrLiteralString(node)^.GetPrintData;
end;
class function ntLiteralString.GetData(node:PsrNode;data:Pointer):Ptruint;
begin
Result:=PsrLiteralString(node)^.GetData(data);
end;
//
class function ntLiteralConst.GetPrintData(node:PsrNode):RawByteString;
begin
Result:=PsrLiteralConst(node)^.GetPrintData;
end;
class function ntLiteralConst.GetData(node:PsrNode;data:Pointer):Ptruint;
begin
Result:=PsrLiteralConst(node)^.GetData(data);
end;
//
function TsrLiteral.c(n1,n2:PsrLiteral):Integer;
begin
Result:=ord(ptruint(n1^.fntype)>ptruint(n2^.fntype))-ord(ptruint(n1^.fntype)<ptruint(n2^.fntype));
if (Result<>0) then Exit;
//
Result:=Integer(ord(n1^.dtype)>ord(n2^.dtype))-Integer(ord(n1^.dtype)<ord(n2^.dtype));
if (Result<>0) then Exit;
//
Result:=Integer(n1^.Value>n2^.Value)-Integer(n1^.Value<n2^.Value);
if (Result<>0) then Exit;
//
Result:=ComparePChar(n1^.name,n2^.name);
end;
//
Procedure TsrLiteral.Init; inline;
begin
fntype:=ntLiteral;
end;
Function TsrLiteral.AsBool:Boolean; inline;
begin
Assert(@Self<>nil);
Result:=PBoolean(@Value)^;
end;
Function TsrLiteral.AsUint8:Byte; inline;
begin
Assert(@Self<>nil);
Result:=PByte(@Value)^;
end;
Function TsrLiteral.AsInt8:Shortint; inline;
begin
Assert(@Self<>nil);
Result:=PShortint(@Value)^;
end;
Function TsrLiteral.AsUint16:Word; inline;
begin
Assert(@Self<>nil);
Result:=PWord(@Value)^;
end;
Function TsrLiteral.AsInt16:Smallint; inline;
begin
Assert(@Self<>nil);
Result:=PSmallint(@Value)^;
end;
Function TsrLiteral.AsUint32:DWORD; inline;
begin
Assert(@Self<>nil);
Result:=PDWORD(@Value)^;
end;
Function TsrLiteral.AsInt32:Integer; inline;
begin
Assert(@Self<>nil);
Result:=PInteger(@Value)^;
end;
Function TsrLiteral.AsUint64:QWORD; inline;
begin
Assert(@Self<>nil);
Result:=Value;
end;
Function TsrLiteral.AsInt64:Int64; inline;
begin
Assert(@Self<>nil);
Result:=Int64(Value);
end;
Function TsrLiteral.AsHalf16:THalf16; inline;
begin
Assert(@Self<>nil);
Result:=PHalf16(@Value)^
end;
Function TsrLiteral.AsFloat32:Single; inline;
begin
Assert(@Self<>nil);
Result:=PSingle(@Value)^;
end;
Function TsrLiteral.AsFloat64:Double; inline;
begin
Assert(@Self<>nil);
Result:=PDouble(@Value)^;
end;
Function TsrLiteral.GetPrintData:RawByteString;
begin
if (name=nil) or (StrLen(name)=0) then
begin
Result:=IntToStr(Value);
end else
begin
Result:=name;
end;
end;
Function TsrLiteral.GetData(data:Pointer):Ptruint;
begin
Result:=SizeOf(DWORD);
if (data<>nil) then
begin
PDWORD(data)^:=DWORD(Value);
end;
end;
//
Procedure TsrLiteralString.Init; inline;
begin
fntype:=ntLiteralString;
end;
Function TsrLiteralString.GetPrintData:RawByteString;
begin
Result:='"'+name+'"';
end;
Function TsrLiteralString.GetData(data:Pointer):Ptruint;
begin
Result:=StrLen(name)+1;
if (data<>nil) then
begin
Move(name^,data^,Result);
end;
end;
//
Procedure TsrLiteralConst.Init; inline;
begin
fntype:=ntLiteralConst;
end;
const
DefaultFormatSettings : TFormatSettings = (
CurrencyFormat: 1;
NegCurrFormat: 5;
ThousandSeparator: ',';
DecimalSeparator: '.';
CurrencyDecimals: 2;
DateSeparator: '-';
TimeSeparator: ':';
ListSeparator: ',';
CurrencyString: '$';
ShortDateFormat: '';
LongDateFormat: '';
TimeAMString: '';
TimePMString: '';
ShortTimeFormat: '';
LongTimeFormat : '';
ShortMonthNames:('','','','','','','','','','','','');
LongMonthNames :('','','','','','','','','','','','');
ShortDayNames :('','','','','','','');
LongDayNames :('','','','','','','');
TwoDigitYearCenturyWindow: 50;
);
Function TsrLiteralConst.GetPrintData:RawByteString;
begin
Result:='';
case dtype of
dtUnknow :Result:='0x'+HexStr(Value,4);
dtBool :
Case AsBool of
true :Result:='true';
false:Result:='false';
end;
dtHalf16 : Result:=FloatToStr(Single(AsHalf16),DefaultFormatSettings);
dtFloat32: Result:=FloatToStr( AsFloat32,DefaultFormatSettings);
dtFloat64: Result:=FloatToStr( AsFloat64,DefaultFormatSettings);
dtInt8 : Result:=IntToStr(AsInt8);
dtUint8 : Result:=IntToStr(AsUint8);
dtInt16 : Result:=IntToStr(AsInt16);
dtUint16 : Result:=IntToStr(AsUint16);
dtInt32 : Result:=IntToStr(AsInt32);
dtUint32 : Result:=IntToStr(AsUint32);
dtInt64 : Result:=IntToStr(AsInt64);
dtUint64 : Result:=IntToStr(AsUint64);
else;
end;
end;
Function TsrLiteralConst.GetData(data:Pointer):Ptruint;
begin
Result:=0;
Case dtype.BitSize of
8:begin
Result:=SizeOf(BYTE);
if (data<>nil) then
begin
PBYTE(data)^:=BYTE(Value);
end;
end;
16:begin
Result:=SizeOf(WORD);
if (data<>nil) then
begin
PWORD(data)^:=WORD(Value);
end;
end;
32:begin
Result:=SizeOf(DWORD);
if (data<>nil) then
begin
PDWORD(data)^:=DWORD(Value);
end;
end;
64:begin
Result:=SizeOf(QWORD);
if (data<>nil) then
begin
PQWORD(data)^:=Value;
end;
end;
else;
end;
end;
//
Procedure TsrLiteralList.Init(Emit:TCustomEmit);
begin
FEmit:=Emit;
end;
function TsrLiteralList.FetchLiteral(Value:PtrUint;name:PChar):PsrLiteral;
var
node:TsrLiteral;
size:ptrint;
begin
node:=Default(TsrLiteral);
node.Init;
node.dtype:=dtUint32;
node.Value:=Value;
node.name :=name;
Result:=FNTree.Find(@node);
if (Result=nil) then
begin
Result:=FEmit.Alloc(SizeOf(TsrLiteral));
Move(node,Result^,SizeOf(TsrLiteral));
if (name<>nil) then
begin
size:=StrLen(name)+1;
Result^.name:=FEmit.Alloc(size);
Move(name^,Result^.name^,size);
end;
FNTree.Insert(Result);
end;
end;
function TsrLiteralList.FetchString(name:PChar):PsrLiteralString;
var
node:TsrLiteralString;
size_o:ptrint;
size_a:ptrint;
begin
node:=Default(TsrLiteralString);
node.Init;
node.dtype:=dtString;
node.name:=name;
Result:=Pointer(FNTree.Find(Pointer(@node)));
if (Result=nil) then
begin
Result:=FEmit.Alloc(SizeOf(TsrLiteralString));
Move(node,Result^,SizeOf(TsrLiteralString));
if (name<>nil) then
begin
size_o:=StrLen(name);
size_a:=Align(size_o+1,SizeOf(DWORD)); //align DW
Result^.name:=FEmit.Alloc(size_a);
Move(name^,Result^.name^,size_o);
end else
begin
Result^.name:=FEmit.Alloc(SizeOf(DWORD));
//space DW
end;
FNTree.Insert(Result);
end;
end;
function TsrLiteralList.FetchConst(dtype:TsrDataType;Value:PtrUint):PsrLiteralConst;
var
node:TsrLiteralConst;
begin
node:=Default(TsrLiteralConst);
node.Init;
node.dtype:=dtype;
node.Value:=Value;
Result:=Pointer(FNTree.Find(Pointer(@node)));
if (Result=nil) then
begin
Result:=FEmit.Alloc(SizeOf(TsrLiteralConst));
Move(node,Result^,SizeOf(TsrLiteralConst));
FNTree.Insert(Result);
end;
end;
end.

548
spirv/srNode.pas Normal file
View File

@ -0,0 +1,548 @@
unit srNode;
{$mode objfpc}{$H+}
interface
type
PsrNode=^TsrNode;
PPsrNode=^PsrNode;
PPrepTypeNode=^TPrepTypeNode;
TPrepTypeNode=record
dnode:PsrNode;
rtype:Integer;
end;
TsrNodeVmt=class
class Procedure add_read (node,src:PsrNode); virtual;
class Procedure rem_read (node,src:PsrNode); virtual;
//
class Procedure add_write (node,src:PsrNode); virtual;
class Procedure rem_write (node,src:PsrNode); virtual;
//
class Procedure mark_read (node,src:PsrNode); virtual;
class Procedure mark_unread (node,src:PsrNode); virtual;
//
class Procedure zero_read (node:PsrNode); virtual;
class Procedure zero_unread (node:PsrNode); virtual;
//
class Procedure mark_write (node,src:PsrNode); virtual;
class Procedure mark_unwrite(node,src:PsrNode); virtual;
//
class Function pwrite_count(node:PsrNode):PDWORD virtual;
class Procedure SetWriter(node,w,line:PsrNode); virtual;
class Procedure ResetWriter(node,w:PsrNode); virtual;
class Function is_used(node:PsrNode):Boolean virtual;
class Function GetPtype(node:PsrNode):PsrNode; virtual;
class Function GetStorageClass(node:PsrNode):DWORD; virtual;
class function GetStorageName(node:PsrNode):RawByteString; virtual;
class function GetPrintName(node:PsrNode):RawByteString; virtual;
class function GetPrintData(node:PsrNode):RawByteString; virtual;
class function Down(node:PsrNode):Pointer; virtual;
class function Next(node:PsrNode):Pointer; virtual;
class function Prev(node:PsrNode):Pointer; virtual;
class function Parent(node:PsrNode):Pointer; virtual;
class function First(node:PsrNode):Pointer; virtual;
class function Last(node:PsrNode):Pointer; virtual;
class Procedure PrepType(node:PPrepTypeNode); virtual;
//
class function GetIndexCount(node:PsrNode):DWORD; virtual;
//
class function GetRef(node:PsrNode):Pointer; virtual;
//
class function GetData(node:PsrNode;data:Pointer):Ptruint; virtual;
end;
TsrNodeType=class of TsrNodeVmt;
TsrNode=packed object
protected
fntype:TsrNodeType;
private
fread_count:DWORD;
public
property ntype:TsrNodeType read fntype;
property read_count:DWORD read fread_count;
function IsType(t:TsrNodeType):Boolean;
function AsType(t:TsrNodeType):Pointer;
Procedure mark_read (src:PsrNode);
Procedure mark_unread (src:PsrNode);
Procedure mark_write (src:PsrNode);
Procedure mark_unwrite(src:PsrNode);
function write_count:DWORD;
Procedure SetWriter(w,line:PsrNode);
Procedure ResetWriter(w:PsrNode);
function IsUsed:Boolean;
Function pType:Pointer;
Function GetStorageClass:DWORD;
function GetStorageName:RawByteString;
function GetPrintName:RawByteString;
function GetPrintData:RawByteString;
function Next:Pointer;
function Prev:Pointer;
function Parent:Pointer;
function First:Pointer;
function Last:Pointer;
procedure PrepType(rtype:Integer);
function GetIndexCount:DWORD;
function GetRef:Pointer;
function GetData(data:Pointer):Ptruint;
end;
TCustomEmit=class
Function Alloc(Size:ptruint):Pointer; virtual abstract;
Function GetConfig :Pointer; virtual abstract;
Function GetCodeHeap :Pointer; virtual abstract;
Function GetLiteralList :Pointer; virtual abstract;
Function GetTypeList :Pointer; virtual abstract;
Function GetConstList :Pointer; virtual abstract;
Function GetRegsStory :Pointer; virtual abstract;
Function GetCapabilityList :Pointer; virtual abstract;
Function GetHeaderList :Pointer; virtual abstract;
Function GetDecorateList :Pointer; virtual abstract;
Function GetDebugInfoList :Pointer; virtual abstract;
Function GetVariableList :Pointer; virtual abstract;
Function GetInputList :Pointer; virtual abstract;
Function GetOutputList :Pointer; virtual abstract;
Function GetDataLayoutList :Pointer; virtual abstract;
Function GetVertLayoutList :Pointer; virtual abstract;
Function GetFragLayoutList :Pointer; virtual abstract;
Function GetBufferList :Pointer; virtual abstract;
Function GetUniformList :Pointer; virtual abstract;
Function GetBitcastList :Pointer; virtual abstract;
Function GetCacheOpList :Pointer; virtual abstract;
Function GetFuncList :Pointer; virtual abstract;
Function GetCursor :Pointer; virtual abstract;
function curr_line :Pointer; virtual abstract;
function init_line :Pointer; virtual abstract;
function NewRefNode :PsrNode; virtual abstract;
function OpCast (pLine, dst,src:PsrNode):PsrNode; virtual abstract;
function OpLoad (pLine,dtype,dst,src:PsrNode):PsrNode; virtual abstract;
function OpStore (pLine, dst,src:PsrNode):PsrNode; virtual abstract;
procedure PostLink(pLine, dst:PsrNode); virtual abstract;
procedure emit_spi; virtual abstract;
end;
implementation
class Procedure TsrNodeVmt.add_read(node,src:PsrNode);
begin
Inc(node^.fread_count);
end;
class Procedure TsrNodeVmt.rem_read(node,src:PsrNode);
begin
Assert(node^.fread_count<>0);
if (node^.fread_count=0) then Exit;
Dec(node^.fread_count);
end;
class Procedure TsrNodeVmt.add_write(node,src:PsrNode);
var
p:PDWORD;
begin
p:=node^.fntype.pwrite_count(node);
if (p<>nil) then
begin
Inc(p^);
end;
end;
class Procedure TsrNodeVmt.rem_write(node,src:PsrNode);
var
p:PDWORD;
begin
p:=node^.fntype.pwrite_count(node);
if (p<>nil) then
begin
Assert(p^<>0);
if (p^=0) then Exit;
Dec(p^);
end;
end;
class Procedure TsrNodeVmt.mark_read(node,src:PsrNode);
var
prv:Boolean;
begin
repeat
Assert(node^.fntype<>nil);
prv:=node^.IsUsed;
node^.fntype.add_read(node,src);
if (prv=node^.IsUsed) then Exit;
node^.fntype.zero_read(node);
src :=node;
node:=node^.fntype.Down(node);
until (node=nil);
end;
class Procedure TsrNodeVmt.mark_unread(node,src:PsrNode);
var
prv:Boolean;
begin
repeat
Assert(node^.fntype<>nil);
prv:=node^.IsUsed;
node^.fntype.rem_read(node,src);
if (prv=node^.IsUsed) then Exit;
node^.fntype.zero_unread(node);
src :=node;
node:=node^.fntype.Down(node);
until (node=nil);
end;
class Procedure TsrNodeVmt.zero_read(node:PsrNode);
begin
//
end;
class Procedure TsrNodeVmt.zero_unread(node:PsrNode);
begin
//
end;
class Procedure TsrNodeVmt.mark_write(node,src:PsrNode);
var
prv:Boolean;
begin
repeat
Assert(node^.fntype<>nil);
prv:=node^.IsUsed;
node^.fntype.add_write(node,src);
if (prv=node^.IsUsed) then Exit;
node^.fntype.zero_read(node);
src :=node;
node:=node^.fntype.Down(node);
until (node=nil);
end;
class Procedure TsrNodeVmt.mark_unwrite(node,src:PsrNode);
var
prv:Boolean;
begin
repeat
Assert(node^.fntype<>nil);
prv:=node^.IsUsed;
node^.fntype.rem_write(node,src);
if (prv=node^.IsUsed) then Exit;
node^.fntype.zero_unread(node);
src :=node;
node:=node^.fntype.Down(node);
until (node=nil);
end;
class Function TsrNodeVmt.pwrite_count(node:PsrNode):PDWORD;
begin
Result:=nil;
end;
class Procedure TsrNodeVmt.SetWriter(node,w,line:PsrNode);
begin
w^.mark_read(node);
end;
class Procedure TsrNodeVmt.ResetWriter(node,w:PsrNode);
begin
w^.mark_unread(node);
end;
class Function TsrNodeVmt.is_used(node:PsrNode):Boolean;
begin
Result:=(node^.read_count<>0) or (node^.write_count<>0);
end;
class Function TsrNodeVmt.GetPtype(node:PsrNode):PsrNode;
begin
Result:=nil;
end;
class Function TsrNodeVmt.GetStorageClass(node:PsrNode):DWORD;
begin
Result:=6;
end;
class function TsrNodeVmt.GetStorageName(node:PsrNode):RawByteString;
begin
Result:='';
end;
class function TsrNodeVmt.GetPrintName(node:PsrNode):RawByteString;
begin
Result:='';
end;
class function TsrNodeVmt.GetPrintData(node:PsrNode):RawByteString;
begin
Result:='';
end;
class function TsrNodeVmt.Down(node:PsrNode):Pointer;
begin
Result:=nil;
end;
class function TsrNodeVmt.Next(node:PsrNode):Pointer;
begin
Result:=nil;
end;
class function TsrNodeVmt.Prev(node:PsrNode):Pointer;
begin
Result:=nil;
end;
class function TsrNodeVmt.Parent(node:PsrNode):Pointer;
begin
Result:=nil;
end;
class function TsrNodeVmt.First(node:PsrNode):Pointer;
begin
Result:=nil;
end;
class function TsrNodeVmt.Last(node:PsrNode):Pointer;
begin
Result:=nil;
end;
class Procedure TsrNodeVmt.PrepType(node:PPrepTypeNode);
begin
node^.dnode:=nil;
end;
class function TsrNodeVmt.GetIndexCount(node:PsrNode):DWORD;
begin
Result:=0;
end;
class function TsrNodeVmt.GetRef(node:PsrNode):Pointer;
begin
Result:=nil;
end;
class function TsrNodeVmt.GetData(node:PsrNode;data:Pointer):Ptruint;
begin
Result:=0;
end;
//
function TsrNode.IsType(t:TsrNodeType):Boolean;
begin
Result:=False;
if (@Self=nil) then Exit;
Result:=fntype.InheritsFrom(t);
end;
function TsrNode.AsType(t:TsrNodeType):Pointer;
begin
Result:=nil;
if (@Self=nil) then Exit;
if not fntype.InheritsFrom(t) then Exit;
Result:=@Self;
end;
Procedure TsrNode.mark_read(src:PsrNode);
begin
if (@Self=nil) then Exit;
Assert(fntype<>nil);
fntype.mark_read(@Self,src);
end;
Procedure TsrNode.mark_unread(src:PsrNode);
begin
if (@Self=nil) then Exit;
Assert(fntype<>nil);
fntype.mark_unread(@Self,src);
end;
Procedure TsrNode.mark_write(src:PsrNode);
begin
if (@Self=nil) then Exit;
Assert(fntype<>nil);
fntype.mark_write(@Self,src);
end;
Procedure TsrNode.mark_unwrite(src:PsrNode);
begin
if (@Self=nil) then Exit;
Assert(fntype<>nil);
fntype.mark_unwrite(@Self,src);
end;
function TsrNode.write_count:DWORD;
var
p:PDWORD;
begin
Result:=0;
if (@Self=nil) then Exit;
Assert(fntype<>nil);
p:=fntype.pwrite_count(@Self);
if (p=nil) then Exit;
Result:=p^;
end;
Procedure TsrNode.SetWriter(w,line:PsrNode);
begin
if (@Self=nil) then Exit;
Assert(fntype<>nil);
fntype.SetWriter(@Self,w,line);
end;
Procedure TsrNode.ResetWriter(w:PsrNode);
begin
if (@Self=nil) then Exit;
Assert(fntype<>nil);
fntype.ResetWriter(@Self,w);
end;
function TsrNode.IsUsed:Boolean;
begin
Result:=False;
if (@Self=nil) then Exit;
Assert(fntype<>nil);
Result:=fntype.is_used(@Self);
end;
Function TsrNode.pType:Pointer;
begin
Result:=nil;
if (@Self=nil) then Exit;
Assert(fntype<>nil);
Result:=fntype.GetPtype(@Self);
end;
Function TsrNode.GetStorageClass:DWORD;
begin
Result:=6;
if (@Self=nil) then Exit;
Assert(fntype<>nil);
Result:=fntype.GetStorageClass(@Self);
end;
function TsrNode.GetStorageName:RawByteString;
begin
Result:='';
if (@Self=nil) then Exit;
Assert(fntype<>nil);
Result:=fntype.GetStorageName(@Self);
end;
function TsrNode.GetPrintName:RawByteString;
begin
Result:='';
if (@Self=nil) then Exit;
Assert(fntype<>nil);
Result:=fntype.GetPrintName(@Self);
end;
function TsrNode.GetPrintData:RawByteString;
begin
Result:='';
if (@Self=nil) then Exit;
Assert(fntype<>nil);
Result:=fntype.GetPrintData(@Self);
end;
function TsrNode.Next:Pointer;
begin
Result:=nil;
if (@Self=nil) then Exit;
Assert(fntype<>nil);
Result:=fntype.Next(@Self);
end;
function TsrNode.Prev:Pointer;
begin
Result:=nil;
if (@Self=nil) then Exit;
Assert(fntype<>nil);
Result:=fntype.Prev(@Self);
end;
function TsrNode.Parent:Pointer;
begin
Result:=nil;
if (@Self=nil) then Exit;
Assert(fntype<>nil);
Result:=fntype.Parent(@Self);
end;
function TsrNode.First:Pointer;
begin
Result:=nil;
if (@Self=nil) then Exit;
Assert(fntype<>nil);
Result:=fntype.First(@Self);
end;
function TsrNode.Last:Pointer;
begin
Result:=nil;
if (@Self=nil) then Exit;
Assert(fntype<>nil);
Result:=fntype.Last(@Self);
end;
procedure TsrNode.PrepType(rtype:Integer);
var
node:TPrepTypeNode;
begin
node:=Default(TPrepTypeNode);
node.dnode:=@Self;
node.rtype:=rtype;
While (node.dnode<>nil) do
begin
Assert(node.dnode^.fntype<>nil);
node.dnode^.fntype.PrepType(@node);
end;
end;
function TsrNode.GetIndexCount:DWORD;
begin
Result:=0;
if (@Self=nil) then Exit;
Assert(fntype<>nil);
Result:=fntype.GetIndexCount(@Self);
end;
function TsrNode.GetRef:Pointer;
begin
Result:=nil;
if (@Self=nil) then Exit;
Assert(fntype<>nil);
Result:=fntype.GetRef(@Self);
end;
function TsrNode.GetData(data:Pointer):Ptruint;
begin
Result:=0;
if (@Self=nil) then Exit;
Assert(fntype<>nil);
Result:=fntype.GetData(@Self,data);
end;
end.

File diff suppressed because it is too large Load Diff

View File

@ -1,228 +1,241 @@
unit srOpUtils;
{$mode objfpc}{$H+}
{$MODESWITCH ADVANCEDRECORDS}
interface
uses
spirv,
srNodes,
srTypes,
srNode,
srOp,
srReg,
srConst,
srLayout,
srVariable,
srOp;
srVariable;
const
OpLinks =DWORD(-1);
OpBlock =DWORD(-2);
OpMakeExp=DWORD(-3);
OpMakeVec=DWORD(-4);
OpIAddExt=DWORD(-5);
OpISubExt=DWORD(-6);
OpAbsDiff=DWORD(-7);
OpWQM32 =DWORD(-8);
OpPackOfs=DWORD(-9);
//OpMED3F
OpIAddExt=DWORD(-1);
OpISubExt=DWORD(-2);
OpAbsDiff=DWORD(-3);
OpWQM32 =DWORD(-4);
OpCUBEID =DWORD(-10);
OpCUBESC =DWORD(-11);
OpCUBETC =DWORD(-12);
OpCUBEMA =DWORD(-13);
OpBFEU32 =DWORD(-5);
OpBFIB32 =DWORD(-6);
OpMakeCM =DWORD(-14);
OpPackAnc=DWORD(-7);
OpPackOfs=DWORD(-8);
OpMakeExp=DWORD(-9);
OpMakeVec=DWORD(-10);
OpMakeCub=DWORD(-11);
type
TOpParamNodeHelper = record helper for TOpParamNode
function AsParam:TOpParamSingle;
function AsReg:Pointer;
function AsVar:Pointer;
function AsChain:Pointer;
function TryGetValue(var V:DWORD):Boolean;
end;
OpCUBEID =DWORD(-12);
OpCUBESC =DWORD(-13);
OpCUBETC =DWORD(-14);
OpCUBEMA =DWORD(-15);
function InsSpirvOp(pLine,pNew:PspirvOp):PSpirvOp;
Procedure MarkUnreadParamSingle(const node:TOpParamSingle);
function InsSpirvOp(pLine,pNew:PspirvOp):PspirvOp;
Function get_inverse_cmp_op(OpId:DWORD):DWORD;
Function is_term_op(OpId:DWORD):Boolean;
Function is_merge_op(OpId:DWORD):Boolean;
Function is_term_op(pLine:PspirvOp):Boolean;
procedure _up_merge_line(var pLine:PspirvOp);
procedure up_merge_line(var pLine:PspirvOp);
function FindUpSameOp(pLine,node:PspirvOp):PspirvOp;
function isGTLine(p1,p2:PspirvOp):Boolean; //(p1>p2)
function IsGTFlow(pSrc,pDst:PSpirvOp):Boolean;
function GetGlobalIndex(pLine:PspirvOp):DWORD;
function MaxLine(p1,p2:PspirvOp):PspirvOp;
function GetMaxPlace(pLine:PSpirvOp;count:Byte;src:PPsrRegNode):PSpirvOp;
function GetChainRegNode(node:PsrRegNode):PsrChain;
function GetSourceRegNode(node:PsrRegNode):PsrNode;
function flow_down_next_up(pLine:PspirvOp):PspirvOp;
function flow_down_prev_up(pLine:PspirvOp):PspirvOp;
implementation
function TOpParamNodeHelper.AsParam:TOpParamSingle;
begin
Result:=Default(TOpParamSingle);
if (@Self=nil) then Exit;
Result.ntype:=ntype;
Result.pData:=pData;
end;
function TOpParamNodeHelper.AsReg:Pointer;
begin
Result:=nil;
if (@Self=nil) then Exit;
if (ntype<>ntReg) then Exit;
Result:=pData;
end;
function TOpParamNodeHelper.AsVar:Pointer;
begin
Result:=nil;
if (@Self=nil) then Exit;
if (ntype<>ntVar) then Exit;
Result:=pData;
end;
function TOpParamNodeHelper.AsChain:Pointer;
begin
Result:=nil;
if (@Self=nil) then Exit;
if (ntype<>ntChain) then Exit;
Result:=pData;
end;
function TOpParamNodeHelper.TryGetValue(var V:DWORD):Boolean;
begin
Result:=False;
if (@Self=nil) then Exit;
if (ntype<>ntLiteral) then Exit;
V:=Value;
Result:=True;
end;
//--
function InsSpirvOp(pLine,pNew:PspirvOp):PSpirvOp;
function flow_down_next_up(pLine:PspirvOp):PspirvOp;
begin
Result:=pLine^.First;
if (Result=nil) then
begin
repeat
Result:=pLine^.Next;
pLine:=pLine^.Parent;
until (pLine=nil) or (Result<>nil);
end;
end;
function flow_down_prev_up(pLine:PspirvOp):PspirvOp;
begin
Result:=pLine^.Last;
if (Result=nil) then
begin
repeat
Result:=pLine^.Prev;
pLine:=pLine^.Parent;
until (pLine=nil) or (Result<>nil);
end;
end;
function flow_prev_up(pLine:PspirvOp):PspirvOp;
begin
repeat
Result:=pLine^.Prev;
pLine:=pLine^.Parent;
until (pLine=nil) or (Result<>nil);
end;
function InsSpirvOp(pLine,pNew:PspirvOp):PspirvOp;
var
tmp:PspirvOp;
begin
Result:=nil;
Assert(pLine<>nil);
if (pLine=nil) or (pNew=nil) then Exit;
if (pLine^.pNext<>nil) then
if (pLine^.Next<>nil) then
if pNew^.IsType(ntOp) then
begin
pNew^.adr:=pLine^.adr;
tmp:=pLine;
while (not tmp^.IsType(ntOp)) do
begin
tmp:=flow_down_prev_up(tmp);
Assert(tmp<>nil);
end;
pNew^.Adr:=tmp^.Adr;
end;
pLine^.InsertAfter(pNew);
Result:=pNew;
end;
Procedure MarkUnreadParamSingle(const node:TOpParamSingle);
function GetCurrentIndex(pLine:PspirvOp):DWORD;
var
pParent:PsrOpBlock;
node:PspirvOp;
begin
Case node.ntype of
ntLiteral:;
ntConst:PsrConst (node.pData)^.mark_unread;
ntType :PsrType (node.pData)^.mark_unread;
ntFunc :PSpirvFunc (node.pData)^.mark_unread;
ntVar :PsrVariable(node.pData)^.mark_unread;
ntRefId:;
ntReg :PsrRegNode (node.pData)^.mark_unread;
//ntReg :RegUnmark(node.pData);
ntChain:PsrChain (node.pData)^.mark_unread;
else
Assert(false);
Result:=0;
if (pLine=nil) then Exit;
pParent:=pLine^.Parent;
if (pParent=nil) then Exit;
node:=pParent^.First;
While (node<>nil) and (node<>pLine) do
begin
Result:=Result+node^.GetIndexCount;
node:=node^.Next;
end;
end;
function GetGlobalIndex(pLine:PspirvOp):DWORD;
var
pParent:PsrOpBlock;
node:PspirvOp;
begin
Result:=0;
if (pLine=nil) then Exit;
node:=pLine;
pParent:=node^.Parent;
While (pParent<>nil) do
begin
Result:=Result+GetCurrentIndex(node);
node:=PspirvOp(pParent);
pParent:=node^.Parent;
end;
end;
function isGTLine(p1,p2:PspirvOp):Boolean; //(p1>p2)
begin
Result:=False;
p2:=p2^.pNext;
p2:=p2^.Next;
While (p2<>nil) do
begin
if (p1=p2) then Exit(True);
p2:=p2^.pNext;
p2:=p2^.Next;
end;
end;
function isGTELine(p1,p2:PspirvOp):Boolean; //(p1>=p2)
Function IsGTLevel(p1,p2:PspirvOp):Boolean; //(p1>p2)
var
pParent1:PsrOpBlock;
pParent2:PsrOpBlock;
begin
Result:=False;
While (p2<>nil) do
pParent1:=p1^.Parent;
pParent2:=p2^.Parent;
Result:=(pParent1^.Level>pParent2^.Level);
end;
function MaxLine(p1,p2:PspirvOp):PspirvOp;
var
pParent:PsrOpBlock;
node:PspirvOp;
i,w:DWORD;
begin
Result:=nil;
if (p1=nil) then Exit(p2);
if (p2=nil) or (p1=p2) then Exit(p1);
if IsGTLevel(p2,p1) then //(p2>p1)
begin
if (p1=p2) then Exit(True);
p2:=p2^.pNext;
//swap
node:=p1;
p1:=p2;
p2:=node;
end;
i:=0;
node:=p1;
pParent:=node^.Parent;
While (pParent<>nil) do
begin
if (pParent=p2^.Parent) then
begin
if isGTLine(node,p2) then //(node>p2)
begin
//Assert(not isGTLine(p2,node));
Exit(p1);
end else
begin
//Assert(isGTLine(p2,node));
Exit(p2);
end;
end;
i:=i+GetCurrentIndex(node);
node:=PspirvOp(pParent);
pParent:=node^.Parent;
end;
w:=GetGlobalIndex(p2);
if (i>w) then
begin
Result:=p1;
end else
begin
Result:=p2;
end;
end;
Function IsParentOf(pLine,pCurr:PsrOpBlock):Boolean;
begin
Result:=False;
if not pLine^.IsType(ntOpBlock) then Exit;
if not pCurr^.IsType(ntOpBlock) then Exit;
While (pLine<>nil) do
begin
if (pLine=pCurr) then Exit(True);
pLine:=pLine^.pParent;
pLine:=pLine^.Parent;
end;
end;
function FindBlockLine(pCurent,node:PsrOpBlock):PspirvOp;
var
tmp:PspirvOp;
Function IsParentOfLine(pLine,pCurr:PSpirvOp):Boolean;
begin
Result:=nil;
if (pCurent=nil) then Exit;
tmp:=pCurent^.pHead;
While (tmp<>nil) do
begin
if (tmp^.OpId=OpBlock) and (tmp^.dst.pData=node) then
begin
Exit(tmp);
end;
tmp:=tmp^.pNext;
end;
end;
{
[pSrc]
|
V
[pBlock] -> [pDst]
}
function IsGTFlow(pSrc,pDst:PSpirvOp):Boolean;
var
pLine,pCurr:PsrOpBlock;
tmp:PSpirvOp;
begin
Result:=False;
pLine:=pDst^.pParent;
pCurr:=pSrc^.pParent;
While (pLine<>nil) do
begin
if (pLine=pCurr) then
begin
Result:=isGTELine(pSrc,pDst);
Exit;
end;
if (pLine^.pParent=nil) then Exit;
tmp:=pLine^.pUpLine;
if (tmp=nil) then
begin
tmp:=FindBlockLine(pLine^.pParent,pLine);
end;
pDst:=tmp;
pLine:=pDst^.pParent;
end;
Result:=IsParentOf(pLine^.Parent,pCurr^.Parent);
end;
function GetMaxPlace(pLine:PSpirvOp;count:Byte;src:PPsrRegNode):PSpirvOp;
var
m,t:PSpirvOp;
m:PSpirvOp;
i:Byte;
begin
Result:=pLine;
@ -230,25 +243,10 @@ begin
m:=nil;
For i:=0 to count-1 do
begin
t:=src[i]^.pLine;
if not src[i]^.is_const then
if IsParentOf(pLine^.pParent,t^.pParent) then
if (not src[i]^.is_const) then
if IsParentOfLine(pLine,src[i]^.pLine) then
begin
if (m=nil) then
begin
m:=t;
end else
if (m^.pParent=t^.pParent) then
begin
if isGTLine(t,m) then
begin
m:=t;
end;
end else
if (t^.pParent^.FLevel>m^.pParent^.FLevel) then
begin
m:=t;
end;
m:=MaxLine(m,src[i]^.pLine);
end;
end;
if (m<>nil) then
@ -325,36 +323,57 @@ begin
if (pLine=nil) then Exit;
repeat //up
Case pLine^.OpId of
Op.OpNop,
OpLinks:pLine:=pLine^.pPrev;
OpBlock:pLine:=PsrOpBlock(pLine^.dst.pData)^.pTail;
else
Break;
if pLine^.IsType(ntOpBlock) then
begin
//
end else
if pLine^.IsType(ntOp) then
begin
if not pLine^.is_cleared then
begin
Case pLine^.OpId of
Op.OpNop:; //
else
Break;
end;
end;
end else
begin
Exit;
end;
if (pLine=nil) then Exit;
pLine:=flow_down_prev_up(pLine);
until false;
Result:=is_term_op(pLine^.OpId);
end;
procedure _up_merge_line(var pLine:PspirvOp);
procedure up_merge_line(var pLine:PspirvOp);
var
node:PspirvOp;
begin
repeat
if is_merge_op(pLine^.OpId) then
if pLine^.IsType(ntOp) then
begin
pLine:=pLine^.pPrev;
Assert(pLine<>nil);
end else
begin
Break;
if pLine^.is_cleared or is_merge_op(pLine^.OpId) then
begin
node:=pLine^.Prev;
if (node<>nil) then
begin
pLine:=node;
Continue;
end;
end;
end;
Break;
until false;
end;
function CompareParam(p1,p2:POpParamNode):Boolean;
begin
Result:=(p1^.ntype=p2^.ntype) and (p1^.pData=p2^.pData);
Result:=(p1^.Value=p2^.Value);
end;
function CompareOp(p1,p2:PspirvOp):Boolean;
@ -362,51 +381,68 @@ var
n1,n2:POpParamNode;
begin
Result:=False;
if (p1^.OpId<>p2^.OpId) then Exit;
if (p1^.dst_type<>p2^.dst_type) then Exit;
n1:=p1^.pParam.pHead;
n2:=p2^.pParam.pHead;
if not p1^.IsType(ntOp) then Exit;
if not p2^.IsType(ntOp) then Exit;
if (p1^.OpId<>p2^.OpId) then Exit;
if (p1^.pDst<>p2^.pDst) then Exit;
n1:=p1^.ParamNode(0);
n2:=p2^.ParamNode(0);
While (n1<>nil) do
begin
if (n2=nil) then Exit;
if not CompareParam(n1,n2) then Exit;
n1:=n1^.pNext;
n2:=n2^.pNext;
n1:=n1^.Next;
n2:=n2^.Next;
end;
Result:=(n2=nil);
end;
function FindUpSameOp(pLine,node:PspirvOp):PspirvOp;
var
tmp:PspirvOp;
pBlock:PsrOpBlock;
begin
Result:=nil;
if (pLine=nil) or (node=nil) then Exit;
While (pLine<>nil) do
begin
if CompareOp(pLine,node) then Exit(pLine);
tmp:=pLine^.pPrev;
if (tmp=nil) then
if not pLine^.is_cleared then
begin
pBlock:=pLine^.pParent;
if (pBlock=nil) then Exit;
if (pBlock^.pParent=nil) then Exit;
tmp:=pBlock^.pUpLine;
if (tmp=nil) then
begin
tmp:=FindBlockLine(pBlock^.pParent,pBlock);
end;
tmp:=tmp^.pPrev;
if CompareOp(pLine,node) then Exit(pLine);
end;
pLine:=tmp;
pLine:=flow_prev_up(pLine);
end;
end;
function GetChainRegNode(node:PsrRegNode):PsrChain;
var
pOp:PSpirvOp;
begin
Result:=nil;
node:=RegDown(node);
pOp:=node^.pWriter^.AsType(ntOp);
if (pOp=nil) then Exit;
if (pOp^.OpId<>Op.OpLoad) then Exit;
Result:=pOp^.ParamNode(0)^.Value^.AsType(ntChain);
end;
function GetSourceRegNode(node:PsrRegNode):PsrNode;
var
pOp:PSpirvOp;
pVar:PsrVariable;
begin
Result:=nil;
node:=RegDown(node);
pOp:=node^.pWriter^.AsType(ntOp);
if (pOp=nil) then Exit;
if (pOp^.OpId<>Op.OpLoad) then Exit;
pVar:=pOp^.ParamNode(0)^.Value^.AsType(ntVariable);
if (pVar=nil) then Exit;
Result:=pVar^.pSource;
end;
end.

View File

@ -5,13 +5,14 @@ unit srOutput;
interface
uses
typinfo,
spirv,
srNodes,
srOp,
srLayout,
srVariable,
srDecorate;
typinfo,
spirv,
srNode,
srType,
srOp,
srLayout,
srVariable,
srDecorate;
type
TpsslExportType=(
@ -39,55 +40,83 @@ type
etParam28,etParam29,etParam30,etParam31
);
PsrOutput=^TsrOutput;
TsrOutput=object(TsrDescriptor)
etype:TpsslExportType;
function GetName:RawByteString;
ntOutput=class(ntDescriptor)
class Function pwrite_count (node:PsrNode):PDWORD; override;
class function GetStorageName(node:PsrNode):RawByteString; override;
end;
PsrOutput=^TsrOutput;
TsrOutput=object(TsrDescriptor)
fwrite_count:DWORD;
etype:TpsslExportType;
function GetStorageName:RawByteString;
end;
PsrOutputList=^TsrOutputList;
TsrOutputList=object
FEmit:TCustomEmit;
data:array[TpsslExportType] of TsrOutput;
Procedure Init;
function Fetch(etype:TpsslExportType):PsrOutput;
procedure AllocBinding(Decorates:PsrDecorateList);
Procedure Init(Emit:TCustomEmit); inline;
function Fetch(etype:TpsslExportType;rtype:TsrDataType):PsrOutput;
procedure AllocBinding;
procedure AllocEntryPoint(EntryPoint:PSpirvOp);
end;
implementation
function TsrOutput.GetName:RawByteString;
class Function ntOutput.pwrite_count(node:PsrNode):PDWORD;
begin
Result:=@PsrOutput(node)^.fwrite_count;
end;
class function ntOutput.GetStorageName(node:PsrNode):RawByteString;
begin
Result:=PsrOutput(node)^.GetStorageName;
end;
//
function TsrOutput.GetStorageName:RawByteString;
begin
Result:=GetEnumName(TypeInfo(TpsslExportType),ord(etype));
end;
Procedure TsrOutputList.Init;
Procedure TsrOutputList.Init(Emit:TCustomEmit); inline;
var
i:TpsslExportType;
begin
FEmit:=Emit;
For i:=Low(TpsslExportType) to High(TpsslExportType) do
begin
data[i].etype:=i;
data[i].fntype :=ntOutput;
data[i].etype :=i;
data[i].FStorage:=StorageClass.Output;
data[i].FBinding:=-1;
end;
end;
function TsrOutputList.Fetch(etype:TpsslExportType):PsrOutput;
function TsrOutputList.Fetch(etype:TpsslExportType;rtype:TsrDataType):PsrOutput;
begin
Result:=@data[etype];
//
Result^.InitType(rtype,FEmit);
Result^.InitVar(FEmit);
end;
procedure TsrOutputList.AllocBinding(Decorates:PsrDecorateList);
//
procedure TsrOutputList.AllocBinding;
var
pDecorateList:PsrDecorateList;
i:TpsslExportType;
pVar:PsrVariable;
FLocation:Integer;
begin
if (Decorates=nil) then Exit;
pDecorateList:=FEmit.GetDecorateList;
For i:=Low(TpsslExportType) to High(TpsslExportType) do
begin
pVar:=data[i].pVar;
if (pVar<>nil) then
if (pVar<>nil) and data[i].IsUsed then
begin
Case i of
etMrt0..etMrt7:
@ -95,7 +124,7 @@ begin
if (data[i].FBinding=-1) then //alloc
begin
FLocation:=ord(i)-ord(etMrt0);
Decorates^.emit_decorate(ntVar,pVar,Decoration.Location,FLocation);
pDecorateList^.OpDecorate(pVar,Decoration.Location,FLocation);
data[i].FBinding:=FLocation;
end;
//Decoration.Index; ???
@ -103,13 +132,13 @@ begin
//etMrtz,
etPos0:
begin
Decorates^.emit_decorate(ntVar,pVar,Decoration.BuiltIn,BuiltIn.Position);
pDecorateList^.OpDecorate(pVar,Decoration.BuiltIn,BuiltIn.Position);
end;
//etPos1..etPos3,
etParam0..etParam31: //interpolate param
begin
FLocation:=ord(i)-ord(etParam0);
Decorates^.emit_decorate(ntVar,pVar,Decoration.Location,FLocation);
pDecorateList^.OpDecorate(pVar,Decoration.Location,FLocation);
data[i].FBinding:=FLocation;
end;
else
@ -129,9 +158,10 @@ begin
For i:=Low(TpsslExportType) to High(TpsslExportType) do
begin
pVar:=data[i].pVar;
if (pVar<>nil) then
if (not data[i].IsUsed) and (pVar<>nil) then assert(false);
if (pVar<>nil) and data[i].IsUsed then
begin
EntryPoint^.AddParam(ntVar,pVar);
EntryPoint^.AddParam(pVar);
end;
end;
end;

873
spirv/srPrivate.pas Normal file
View File

@ -0,0 +1,873 @@
unit srPrivate;
{$mode ObjFPC}{$H+}
interface
uses
sysutils,
spirv,
ginodes,
srNode,
srType,
srTypes,
srLayout,
srOp,
srOpUtils,
srReg,
srVariable,
srBitcast;
type
ntPrivate=class(ntDescriptor)
class Function pwrite_count (node:PsrNode):PDWORD; override;
class Procedure PrepType (node:PPrepTypeNode); override;
class function GetStorageName(node:PsrNode):RawByteString; override;
end;
ntVolatile=class(TsrNodeVmt)
class Procedure zero_read (node:PsrNode); override;
class Procedure zero_unread (node:PsrNode); override;
class Procedure PrepType (node:PPrepTypeNode); override;
end;
PsrPrivate=^TsrPrivate;
PsrVolatile=^TsrVolatile;
TsrVolatile=object(TsrNode)
type
PVNode=^TVNode;
TVNode=record
pPrev,pNext:PVNode;
pReg:PsrRegNode;
end;
TNodeList=specialize TNodeList<PVNode>;
var
pPrev,pNext:PsrVolatile;
FSource:PsrPrivate;
FList:TNodeList;
Procedure Init(Source:PsrPrivate); inline;
Procedure AddStore(src:PsrRegNode);
Procedure PushStore(node:PVNode);
Function PopStore:PVNode;
Procedure RemoveAllStore;
Procedure zero_read;
Procedure zero_unread;
procedure PrepType(new:TsrDataType);
end;
TsrPrivate=object(TsrDescriptor)
type
PVNode=^TVNode;
TVNode=record
pPrev,pNext:PVNode;
pLine:PspirvOp;
end;
TNodeList=specialize TNodeList<PVNode>;
TVoltList=specialize TNodeList<PsrVolatile>;
private
pLeft,pRight:PsrPrivate;
//----
fwrite_count:DWORD;
//
FSource:PsrRegSlot;
//
FLineList:TNodeList;
FVoltList:TVoltList;
function c(n1,n2:PsrPrivate):Integer; static;
Procedure SetRegType(rtype:TsrDataType);
function GetRegType:TsrDataType;
public
//FVolatile:TsrVolatile;
property dtype:TsrDataType read GetRegType write SetRegType;
property Source:PsrRegSlot read FSource;
Procedure Init; inline;
function Emit:TCustomEmit;
function GetStorageName:RawByteString;
function isBoolOnly:Boolean;
Procedure UpdateRegType;
Procedure PrepType(new:TsrDataType);
Procedure SortLines;
Procedure Optimize;
procedure AddLine(pLine:PspirvOp);
procedure AddLine(pLine:PspirvOp;node:TsrVolatile.PVNode);
procedure FetchLoad(pLine:PspirvOp;dst:PsrRegNode);
Procedure FetchStore(pLine:PspirvOp;node:TsrVolatile.PVNode);
function NewVolatile:PsrVolatile;
procedure RemoveAllStore;
end;
PsrPrivateList=^TsrPrivateList;
TsrPrivateList=object
type
TNodeFetch=specialize TNodeFetch<PsrPrivate,TsrPrivate>;
var
FEmit:TCustomEmit;
FNTree:TNodeFetch;
procedure Init(Emit:TCustomEmit); inline;
function Fetch(pSource:PsrRegSlot):PsrPrivate;
function First:PsrPrivate; inline;
Function Next(node:PsrPrivate):PsrPrivate;
//
procedure build_slot_dis(pSlot:PsrRegSlot;var old:PsrRegNode);
procedure build_slot_cur(pSlot:PsrRegSlot;var old:PsrRegNode);
procedure build_slot_old(pSlot:PsrRegSlot;var old:PsrRegNode);
procedure build_volatile_dis(old:PsrRegsSnapshot);
procedure build_volatile_cur(old:PsrRegsSnapshot);
procedure build_volatile_old(old:PsrRegsSnapshot);
procedure make_copy_slot(pSlot:PsrRegSlot);
procedure make_copy_all;
procedure PrepVolatile(dst:PspirvOp;src:PsrRegNode);
Procedure Post;
end;
implementation
class Procedure ntVolatile.zero_read(node:PsrNode);
begin
PsrVolatile(node)^.zero_read;
end;
class Procedure ntVolatile.zero_unread(node:PsrNode);
begin
PsrVolatile(node)^.zero_unread;
end;
class Procedure ntVolatile.PrepType(node:PPrepTypeNode);
begin
PsrVolatile(node^.dnode)^.PrepType(TsrDataType(node^.rtype));
node^.dnode:=nil;
end;
//
Procedure TsrVolatile.Init(Source:PsrPrivate); inline;
begin
fntype :=ntVolatile;
FSource:=Source;
end;
procedure TsrVolatile.PrepType(new:TsrDataType);
var
node:PVNode;
begin
if FSource^.isBoolOnly then
begin
new:=dtBool;
end;
if (new=dtUnknow) then exit;
node:=FList.pHead;
While (node<>nil) do
begin
node^.pReg^.PrepType(ord(new));
node:=node^.pNext;
end;
end;
Procedure TsrVolatile.AddStore(src:PsrRegNode);
var
node:PVNode;
begin
if (src=nil) then Exit;
node:=FSource^.Emit.Alloc(SizeOf(TVNode));
node^.pReg:=src;
if IsUsed then
begin
src^.mark_read(@Self);
end;
FList.Push_head(node);
end;
Procedure TsrVolatile.PushStore(node:PVNode);
begin
if (node=nil) then Exit;
if IsUsed then
begin
node^.pReg^.mark_read(@Self);
end;
FList.Push_head(node);
end;
Function TsrVolatile.PopStore:PVNode;
begin
Result:=FList.Pop_head;
if (Result<>nil) and IsUsed then
begin
Result^.pReg^.mark_unread(@Self);
end;
end;
Procedure TsrVolatile.RemoveAllStore;
var
node:PVNode;
begin
repeat
node:=PopStore;
until (node=nil);
end;
Procedure TsrVolatile.zero_read;
var
node:PVNode;
begin
node:=FList.pHead;
While (node<>nil) do
begin
node^.pReg^.mark_read(@Self);
node:=node^.pNext;
end;
end;
Procedure TsrVolatile.zero_unread;
var
node:PVNode;
begin
node:=FList.pHead;
While (node<>nil) do
begin
node^.pReg^.mark_unread(@Self);
node:=node^.pNext;
end;
end;
//
class Function ntPrivate.pwrite_count(node:PsrNode):PDWORD;
begin
Result:=@PsrPrivate(node)^.fwrite_count;
end;
class Procedure ntPrivate.PrepType(node:PPrepTypeNode);
begin
PsrPrivate(node^.dnode)^.PrepType(TsrDataType(node^.rtype));
node^.dnode:=nil;
end;
class function ntPrivate.GetStorageName(node:PsrNode):RawByteString;
begin
Result:=PsrPrivate(node)^.GetStorageName;
end;
//
function TsrPrivate.c(n1,n2:PsrPrivate):Integer;
begin
Result:=Integer(n1^.FSource>n2^.FSource)-Integer(n1^.FSource<n2^.FSource);
end;
Procedure TsrPrivate.Init; inline;
begin
fntype :=ntPrivate;
FStorage:=StorageClass.Private_;
FBinding:=-1;
end;
function TsrPrivate.Emit:TCustomEmit;
begin
Result:=FSource^.FEmit;
end;
function TsrPrivate.GetStorageName:RawByteString;
begin
Result:='v'+FSource^.rid;
end;
function TsrPrivate.isBoolOnly:Boolean;
begin
Result:=(FSource^.isBoolOnly);
end;
Procedure TsrPrivate.SetRegType(rtype:TsrDataType);
var
pTypeList:PsrTypeList;
node:PVNode;
pLine:PspirvOp;
begin
pTypeList:=Emit.GetTypeList;
Ftype:=pTypeList^.Fetch(rtype);
node:=FLineList.pHead;
While (node<>nil) do
begin
pLine:=node^.pLine;
Case pLine^.OpId of
Op.OpLoad:
begin
pLine^.pDst^.PrepType(ord(rtype));
pLine^.pType:=Ftype;
end;
Op.OpStore:
begin
pLine^.ParamFirst^.Value^.PrepType(ord(rtype));
end;
else;
end;
node:=node^.pNext;
end;
end;
function TsrPrivate.GetRegType:TsrDataType;
begin
Result:=FType^.dtype;
end;
Procedure TsrPrivate.UpdateRegType;
var
pBitcastList:PsrBitcastList;
node:PVNode;
pLine:PspirvOp;
dst:PsrRegNode;
old,rtype:TsrDataType;
begin
rtype:=FType^.dtype;
pBitcastList:=Emit.GetBitcastList;
node:=FLineList.pHead;
While (node<>nil) do
begin
pLine:=node^.pLine;
Case pLine^.OpId of
Op.OpLoad:
begin
pLine^.pDst^.PrepType(ord(rtype));
pLine^.pType:=Ftype;
dst:=pLine^.pDst^.AsType(ntReg);
if (dst<>nil) then
begin
old:=dst^.dtype;
if (old<>dtUnknow) and (not CompareType(rtype,old)) then
begin
//OpLoad -> new -> dst
pBitcastList:=Emit.GetBitcastList;
dst:=pBitcastList^.FetchDstr(rtype,dst);
pLine^.pDst:=dst;
end;
end;
end;
Op.OpStore:
begin
pLine^.ParamFirst^.Value^.PrepType(ord(rtype));
dst:=pLine^.ParamFirst^.Value^.AsType(ntReg);
if (dst<>nil) then
begin
old:=dst^.dtype;
if (old<>dtUnknow) and (rtype<>old) then
begin
//OpStore <- new <- dst
pBitcastList:=Emit.GetBitcastList;
dst:=pBitcastList^.FetchRead(rtype,dst);
pLine^.ParamFirst^.Value:=dst;
end;
end;
end;
else;
end;
node:=node^.pNext;
end;
end;
Procedure TsrPrivate.PrepType(new:TsrDataType);
var
old:TsrDataType;
begin
if isBoolOnly then
begin
new:=dtBool;
end;
if (new=dtUnknow) then Exit;
old:=GetRegType;
if is_unprep_type(old,new,True) then
begin
SetRegType(new);
end;
end;
Procedure TsrPrivate.SortLines;
var
pnode,pnext:PVNode;
pLine:array[0..1] of PspirvOp;
nswp:Boolean;
begin
repeat
nswp:=True;
pnode:=FLineList.pHead;
While true do
begin
pnext:=pnode^.pNext;
if (pnext=nil) then Break;
pLine[0]:=pnode^.pLine;
pLine[1]:=pnext^.pLine;
if (MaxLine(pLine[0],pLine[1])=pLine[0]) then //pnode>pnext
begin
//swap
nswp:=False;
FLineList.Remove(pnode);
FLineList.InsertAfter(pnext,pnode);
end else
begin
pnode:=pnext;
end;
end;
until nswp;
end;
Procedure TsrPrivate.Optimize;
var
pnode,pprev:PVNode;
pLine:array[0..1] of PspirvOp;
begin
pnode:=FLineList.pTail;
While true do
begin
pprev:=pnode^.pPrev;
if (pprev=nil) then Break;
pLine[0]:=pnode^.pLine;
pLine[1]:=pprev^.pLine;
if (pLine[0]^.Parent=pLine[1]^.Parent) then
begin
//OpStore %v %r
//OpStore %v %r
if (pLine[0]^.OpId=Op.OpStore) and (pLine[1]^.OpId=Op.OpStore) then
begin
//Remove pprev
FLineList.Remove(pprev);
pLine[1]^.mark_not_used;
Continue;
end else
if (pLine[0]^.OpId=Op.OpStore) and (pLine[1]^.OpId=Op.OpLoad) then
begin
//%r = OpLoad %type %v ; pLine[1] ; pprev
//OpStore %v %r ; pLine[0] ; pnode
if CompareReg(RegDown(pLine[0]^.pDst^.AsType(ntReg)),RegDown(pLine[1]^.ParamFirst^.Value^.AsType(ntReg))) then
begin
//Remove pnode
FLineList.Remove(pnode);
pLine[0]^.mark_not_used;
pnode:=pprev;
Continue;
end;
end;
end;
pnode:=pprev;
end;
end;
procedure TsrPrivate.AddLine(pLine:PspirvOp);
var
node:PVNode;
begin
node:=Emit.Alloc(SizeOf(TVNode));
node^.pLine:=pLine;
FLineList.Push_tail(node);
end;
procedure TsrPrivate.AddLine(pLine:PspirvOp;node:TsrVolatile.PVNode);
var
_node:PVNode;
begin
_node:=Pointer(node); //hack
_node^:=Default(TVNode);
_node^.pLine:=pLine;
FLineList.Push_tail(_node);
end;
procedure TsrPrivate.FetchLoad(pLine:PspirvOp;dst:PsrRegNode);
begin
Assert(dst<>nil);
pLine:=PspirvOp(Emit.OpLoad(pLine,FType,dst,FVar));
AddLine(pLine);
end;
Procedure TsrPrivate.FetchStore(pLine:PspirvOp;node:TsrVolatile.PVNode);
var
src:PsrRegNode;
begin
if (node=nil) then Exit;
src:=node^.pReg;
if (src=nil) then Exit;
pLine:=PspirvOp(Emit.OpStore(pLine,FVar,src));
AddLine(pLine,node);
end;
function TsrPrivate.NewVolatile:PsrVolatile;
begin
Result:=Emit.Alloc(SizeOf(TsrVolatile));
Result^.Init(@Self);
FVoltList.Push_tail(Result);
end;
procedure TsrPrivate.RemoveAllStore;
var
node:PsrVolatile;
begin
node:=FVoltList.pHead;
While (node<>nil) do
begin
node^.RemoveAllStore;
node:=node^.pNext;
end;
end;
//
procedure TsrPrivateList.Init(Emit:TCustomEmit); inline;
begin
FEmit:=Emit;
end;
function TsrPrivateList.Fetch(pSource:PsrRegSlot):PsrPrivate;
var
node:TsrPrivate;
begin
Assert(pSource<>nil);
node:=Default(TsrPrivate);
node.Init;
node.FSource:=pSource;
Result:=FNTree.Find(@node);
if (Result=nil) then
begin
Result:=FEmit.Alloc(SizeOf(TsrPrivate));
Move(node,Result^,SizeOf(TsrPrivate));
//
//Result^.FVolatile.Init(Result);
//
FNTree.Insert(Result);
end;
end;
Function TsrPrivateList.First:PsrPrivate;
begin
Result:=FNTree.Min;
end;
Function TsrPrivateList.Next(node:PsrPrivate):PsrPrivate;
begin
Result:=FNTree.Next(node);
end;
procedure TsrPrivateList.build_slot_dis(pSlot:PsrRegSlot;var old:PsrRegNode);
var
cur:PsrRegNode;
begin
cur:=pSlot^.current;
While (cur<>old) do
begin
pSlot^.Remove(cur);
cur:=pSlot^.current;
end;
end;
procedure TsrPrivateList.build_slot_cur(pSlot:PsrRegSlot;var old:PsrRegNode);
var
cur,prv,new:PsrRegNode;
pPrivate :PsrPrivate;
pVolatile:PsrVolatile;
rtype:TsrDataType;
begin
cur:=RegDownSlot(pSlot^.current);
prv:=RegDownSlot(old);
if CompareReg(cur,prv) then Exit;
cur:=pSlot^.current;
if (cur=nil) then
begin
Assert(false,'WTF');
end;
if (old=nil) then
begin
//////old:=pSlot^.New(line,rtype); //Unresolve
end;
pPrivate :=Fetch(pSlot);
//pVolatile:=@pPrivate^.FVolatile;
pVolatile:=pPrivate^.NewVolatile;
rtype:=dtUnknow;
if (old<>nil) then
//if (old^.pWriter^.AsType(ntVolatile)<>pVolatile) then
//if not old^.pWriter^.IsType(ntVolatile) then
begin
pVolatile^.AddStore(old);
rtype:=old^.dtype;
end;
//
if (cur<>nil) then
//if (cur^.pWriter^.AsType(ntVolatile)<>pVolatile) then
//if not cur^.pWriter^.IsType(ntVolatile) then
begin
pVolatile^.AddStore(cur);
rtype:=cur^.dtype;
end;
//old^.PrepType(ord(pVolatile^.Ftype));
//cur^.PrepType(ord(pVolatile^.Ftype));
new:=pSlot^.New(cur^.pLine,rtype);
new^.pWriter:=pVolatile;
FEmit.PostLink(cur^.pLine,new); //post processing
old:=new; //update snap
end;
procedure TsrPrivateList.build_slot_old(pSlot:PsrRegSlot;var old:PsrRegNode);
var
cur,prv,new:PsrRegNode;
pPrivate :PsrPrivate;
pVolatile:PsrVolatile;
begin
cur:=RegDownSlot(pSlot^.current);
prv:=RegDownSlot(old);
if CompareReg(cur,prv) then Exit;
cur:=pSlot^.current;
if (old<>nil) then
if old^.pWriter^.IsType(ntVolatile) then
begin
pVolatile:=old^.pWriter^.AsType(ntVolatile);
//if (pVolatile<>cur^.pWriter^.AsType(ntVolatile)) then
begin
pVolatile^.AddStore(cur);
end;
Exit;
end;
prv:=nil;
if (old<>nil) then
begin
prv:=old^.pWriter^.AsType(ntReg);
Assert(prv<>nil);
end;
pPrivate :=Fetch(pSlot);
//pVolatile:=@pPrivate^.FVolatile;
pVolatile:=pPrivate^.NewVolatile;
//if (pVolatile<>prv^.pWriter^.AsType(ntVolatile)) then
begin
pVolatile^.AddStore(prv);
end;
//if (pVolatile<>cur^.pWriter^.AsType(ntVolatile)) then
begin
pVolatile^.AddStore(cur);
end;
if (old<>nil) then
begin
old^.pWriter:=pVolatile;
end else
if (cur<>nil) then
begin
new:=pSlot^.New(cur^.pLine,cur^.dtype);
new^.pWriter:=pVolatile;
FEmit.PostLink(FEmit.curr_line,new); //post processing
end;
end;
procedure TsrPrivateList.build_volatile_dis(old:PsrRegsSnapshot);
var
pRegsStory:PsrRegsStory;
begin
//exit;
pRegsStory:=FEmit.GetRegsStory;
pRegsStory^.ForEachSnap(@build_slot_dis,old);
end;
procedure TsrPrivateList.build_volatile_cur(old:PsrRegsSnapshot);
var
pRegsStory:PsrRegsStory;
begin
//exit;
pRegsStory:=FEmit.GetRegsStory;
//NextVolatileID; FVolatileID:SizeUint;
pRegsStory^.ForEachSnap(@build_slot_cur,old);
end;
procedure TsrPrivateList.build_volatile_old(old:PsrRegsSnapshot);
var
pRegsStory:PsrRegsStory;
begin
//exit;
pRegsStory:=FEmit.GetRegsStory;
//NextVolatileID; FVolatileID:SizeUint;
pRegsStory^.ForEachSnap(@build_slot_old,old);
end;
procedure TsrPrivateList.make_copy_slot(pSlot:PsrRegSlot);
var
cur,node:PsrRegNode;
begin
//exit;
if (pSlot^.current<>nil) then
begin
cur:=pSlot^.current;
//MakeCopy(pSlot,cur);
node:=pSlot^.New(FEmit.curr_line,cur^.dtype);
node^.pWriter:=cur;
FEmit.PostLink(FEmit.curr_line,node); //post processing
pSlot^.current^.pLine:=cur^.pLine;
end;
end;
procedure TsrPrivateList.make_copy_all;
var
pRegsStory:PsrRegsStory;
begin
//exit;
pRegsStory:=FEmit.GetRegsStory;
pRegsStory^.ForEachSlot(@make_copy_slot);
end;
function get_load_from(r:PsrRegNode):PsrVariable;
var
pOp:PspirvOp;
begin
Result:=nil;
pOp:=r^.pWriter^.AsType(ntOp);
if (pOp=nil) then Exit;
if (pOp^.OpId<>Op.OpLoad) then Exit;
Result:=pOp^.ParamFirst^.Value^.AsType(ntVariable);
end;
function get_load_from2(r:PsrRegNode):PsrVolatile;
begin
Result:=r^.pWriter^.AsType(ntVolatile);
end;
procedure _Move(dst,src:PsrVolatile);
var
node:TsrVolatile.PVNode;
begin
node:=src^.PopStore;
While (node<>nil) do
begin
dst^.PushStore(node);
node:=src^.PopStore;
end;
end;
procedure TsrPrivateList.PrepVolatile(dst:PspirvOp;src:PsrRegNode); //use forward only
var
tmp:PsrRegNode;
pPrivate :PsrPrivate;
pVolatile:PsrVolatile;
node:TsrVolatile.PVNode;
pLine:PspirvOp;
vtmp:PsrVolatile;
begin
if (src=nil) then Exit;
if (not src^.pWriter^.IsType(ntVolatile)) then Exit;
pVolatile:=src^.pWriter^.AsType(ntVolatile);
pPrivate :=pVolatile^.FSource;
src^.pWriter:=nil;
pPrivate^.InitVar(FEmit);
pPrivate ^.PrepType(src^.dtype);
pVolatile^.PrepType(pPrivate^.GetRegType);
if (pPrivate^.GetRegType=dtUnknow) then
begin
Assert(false);
end;
node:=pVolatile^.PopStore;
While (node<>nil) do
begin
tmp:=RegDown{Slot}(node^.pReg);
if (src<>tmp) {and (pPrivate^.pVar<>get_load_from(tmp))} then
begin
pLine:=node^.pReg^.pLine;
Assert(pLine<>nil);
if (tmp^.pWriter^.IsType(ntVolatile)) then
begin
vtmp:=tmp^.pWriter^.AsType(ntVolatile);
Assert(vtmp<>nil);
_Move(pVolatile,vtmp);
tmp^.pWriter:=src;
Continue;
end;
up_merge_line(pLine);
pPrivate^.FetchStore(pLine,node);
end;
node:=pVolatile^.PopStore;
end;
pLine:=dst;
Assert(pLine<>nil);
pLine:=pLine^.Prev;
Assert(pLine<>nil);
up_merge_line(pLine);
Assert(pLine<>nil);
//ntVolatile -> src -> next
//Opload -> src -> next
pPrivate^.FetchLoad(pLine,src); //before reg
end;
Procedure TsrPrivateList.Post;
var
node:PsrPrivate;
begin
node:=FNTree.Min;
While (node<>nil) do
begin
if node^.IsUsed then
begin
node^.RemoveAllStore;
node^.SortLines;
node^.Optimize;
node^.UpdateRegType;
end;
node:=FNTree.Next(node);
end;
end;
end.

View File

@ -4,11 +4,27 @@ unit srRefId;
interface
uses
sysutils,
srNode;
type
ntRefId=class(TsrNodeVmt)
class function GetPrintName(node:PsrNode):RawByteString; override;
class function GetRef(node:PsrNode):Pointer; override;
end;
PsrRefId=^TsrRefId;
TsrRefId=packed object
TsrRefId=object
ID:DWORD;
function Alloc:Boolean; inline;
function Alloc:Boolean; inline;
end;
PsrRefNode=^TsrRefNode;
TsrRefNode=object(TsrNode)
ID:TsrRefId;
Procedure Init; inline;
function GetPrintName:RawByteString;
end;
PsrRefIdAlloc=^TsrRefIdAlloc;
@ -21,6 +37,27 @@ type
implementation
class function ntRefId.GetPrintName(node:PsrNode):RawByteString;
begin
Result:=PsrRefNode(node)^.GetPrintName;
end;
class function ntRefId.GetRef(node:PsrNode):Pointer;
begin
Result:=@PsrRefNode(node)^.ID;
end;
Procedure TsrRefNode.Init; inline;
begin
fntype:=ntRefId;
end;
function TsrRefNode.GetPrintName:RawByteString;
begin
Assert(ID.ID<>0);
Result:=IntToStr(ID.ID);
end;
function TsrRefId.Alloc:Boolean; inline;
begin
Result:=(ID<>0);

View File

@ -5,38 +5,101 @@ unit srReg;
interface
uses
srNodes,
srRefId,
srTypes,
srConst;
sysutils,
ginodes,
srNode,
srRefId,
srType,
srConst;
type
ntReg=class(TsrNodeVmt)
class Procedure add_read (node,src:PsrNode); override;
class Procedure rem_read (node,src:PsrNode); override;
class Procedure SetWriter (node,w,line:PsrNode); override;
class Procedure ResetWriter (node,w:PsrNode); override;
class function Down (node:PsrNode):Pointer; override;
class function Next (node:PsrNode):Pointer; override;
class function Prev (node:PsrNode):Pointer; override;
class Procedure PrepType (node:PPrepTypeNode); override;
class function GetPrintName(node:PsrNode):RawByteString; override;
class function GetRef (node:PsrNode):Pointer; override;
end;
ntRegPair=class(TsrNodeVmt)
class function Down (node:PsrNode):Pointer; override;
class Procedure SetWriter (node,w,line:PsrNode); override;
class Procedure ResetWriter(node,w:PsrNode); override;
end;
PPsrRegSlot=^PsrRegSlot;
PsrRegSlot=^TsrRegSlot;
PPsrRegNode=^PsrRegNode;
PsrRegNode=^TsrRegNode;
TsrRegNode=packed object
pPrev,pNext:PsrRegNode;
//----
read_count:DWORD;
ID:TsrRefId; //post id
pSlot:PsrRegSlot;
pWriter:TOpParamSingle; //ntReg,ntConst,ntOp,ntVolatile
pLine:Pointer; //PspirvOp;
dtype:TsrDataType;
function GetName:RawByteString;
Procedure mark_read;
Procedure mark_unread;
procedure SetConst(pConst:PsrConst);
procedure SetReg(pReg:PsrRegNode);
function AsConst:PsrConst;
function AsOp:Pointer;
function AsReg:PsrRegNode;
function is_const:Boolean;
function is_bool:Boolean;
function is_bool_or_const_bool:Boolean;
function is_unknow:Boolean;
PRegDNode=^TRegDNode;
TRegDNode=record
pNext:PRegDNode;
pNode:PsrNode;
end;
TRegDNodeList=specialize TNodeStack<PRegDNode>;
TsrRegNode=packed object(TsrNode)
private
pPrev,pNext:PsrRegNode;
//
ID:TsrRefId; //post id
F:bitpacked record
dtype:TsrDataType;
weak:Boolean;
end;
FSlot:PsrRegSlot;
FWriter:PsrNode; //ntReg,ntConst,ntOp,ntVolatile
FDList:TRegDNodeList;
FLine:Pointer;
Procedure AddDep(t:PsrNode);
Procedure RemDep(t:PsrNode);
function GetDtype:TsrDataType;
Procedure SetDtype(t:TsrDataType);
function GetWeak:Boolean;
Procedure SetWeak(t:Boolean);
Procedure SetWriter(t:PsrNode);
Function GetWriter:PsrNode;
Procedure SetLine(t:Pointer);
public
property pLine :Pointer read FLine write SetLine; //PspirvOp;
property pSlot :PsrRegSlot read FSlot;
property dtype :TsrDataType read GetDtype write SetDtype;
property Weak :Boolean read GetWeak write SetWeak;
property pWriter:PsrNode read GetWriter write SetWriter;
Procedure Init; inline;
function FirstDep:PRegDNode;
function GetName:RawByteString;
function AsConst:PsrConst;
function AsReg:PsrRegNode;
function is_const:Boolean;
function is_bool:Boolean;
function is_bool_or_const_bool:Boolean;
function is_unknow:Boolean;
function GetPrintName:RawByteString;
end;
PsrRegPair=^TsrRegPair;
TsrRegPair=object(TsrNode)
private
FWriter:PsrNode;
FDst0:PsrNode;
FDst1:PsrNode;
Procedure SetWriter(t:PsrNode);
Procedure SetDst0(r:PsrNode);
Procedure SetDst1(r:PsrNode);
public
property pLine:PsrNode read FWriter;
property pWriter:PsrNode read FWriter write SetWriter;
property pDst0:PsrNode read FDst0 write SetDst0;
property pDst1:PsrNode read FDst1 write SetDst1;
Procedure Init; inline;
end;
TRegStory=specialize TNodeList<PsrRegNode>;
@ -44,15 +107,16 @@ type
TString5=string[5];
TsrRegSlot=object
Alloc:TfnAlloc;
pVar:Pointer;
FEmit:TCustomEmit;
pStory:TRegStory;
rid:TString5;
Procedure Init(a:TfnAlloc;const n:TString5);
Procedure Init(Emit:TCustomEmit;const n:TString5);
function first:PsrRegNode;
function current:PsrRegNode;
function isBoolOnly:Boolean;
function New(pLine:Pointer;rtype:TsrDataType):PsrRegNode;
function NewAfter(rtype:TsrDataType;r:PsrRegNode):PsrRegNode;
function NewBefore(rtype:TsrDataType;r:PsrRegNode):PsrRegNode;
procedure Remove(r:PsrRegNode);
end;
@ -69,6 +133,7 @@ type
TForEachSlot=procedure(pSlot:PsrRegSlot) of object;
TForEachSnap=procedure(pSlot:PsrRegSlot;var old:PsrRegNode) of object;
PsrRegsStory=^TsrRegsStory;
TsrRegsStory=object
SGRP:array[0..103] of TsrRegSlot;
VCC:array[0..1] of TsrRegSlot;
@ -77,25 +142,171 @@ type
SCC:TsrRegSlot;
VGRP:array[0..255] of TsrRegSlot;
FUnattach:TsrRegSlot;
Procedure Init(Alloc:TfnAlloc);
function get_sdst7_pair(SDST:Byte;dst:PPsrRegSlot):Boolean;
//
FDList:TRegDNodeList;
//
Procedure Init(Emit:TCustomEmit);
//
Function AllocDep:PRegDNode;
Procedure FreeDep(node:PRegDNode);
//
function get_sdst7(SDST:Byte):PsrRegSlot;
function get_sdst7_pair(SDST:Byte;dst:PPsrRegSlot):Boolean;
function get_ssrc8(SSRC:Byte):PsrRegSlot;
function get_ssrc9_pair(SSRC:Word;src:PPsrRegSlot):Boolean;
function get_ssrc9(SSRC:Word):PsrRegSlot;
function get_ssrc9_pair(SSRC:Word;src:PPsrRegSlot):Boolean;
function get_vsrc8(VSRC:Byte):PsrRegSlot;
function get_vdst8(VDST:Byte):PsrRegSlot;
function get_sbase(SBASE,count:Byte;src:PPsrRegSlot):Boolean;
function get_srsrc(SRSRC,count:Byte;src:PPsrRegSlot):Boolean;
//
function get_snapshot:TsrRegsSnapshot;
procedure ForEachSlot(cb:TForEachSlot);
procedure ForEachSnap(cb:TForEachSnap;old:PsrRegsSnapshot);
end;
function RegDown(node:PsrRegNode):PsrRegNode;
function RegDownSlot(node:PsrRegNode):PsrRegNode;
function CompareReg(r1,r2:PsrRegNode):Boolean;
implementation
Procedure TsrRegsStory.Init(Alloc:TfnAlloc);
//
class Procedure ntReg.add_read(node,src:PsrNode);
begin
inherited;
PsrRegNode(node)^.AddDep(src);
end;
class Procedure ntReg.rem_read(node,src:PsrNode);
begin
inherited;
PsrRegNode(node)^.RemDep(src);
end;
class Procedure ntReg.SetWriter(node,w,line:PsrNode);
begin
With PsrRegNode(node)^ do
begin
SetWriter(w);
pLine:=line;
end;
end;
class Procedure ntReg.ResetWriter(node,w:PsrNode);
begin
With PsrRegNode(node)^ do
if (FWriter=w) then
begin
SetWriter(nil);
pLine:=nil;
end;
end;
class function ntReg.Down(node:PsrNode):Pointer;
begin
Result:=PsrRegNode(node)^.FWriter;
end;
class function ntReg.Next(node:PsrNode):Pointer;
begin
Result:=PsrRegNode(node)^.pNext;
end;
class function ntReg.Prev(node:PsrNode):Pointer;
begin
Result:=PsrRegNode(node)^.pPrev;
end;
class Procedure ntReg.PrepType(node:PPrepTypeNode);
var
new:TsrDataType;
pConstList:PsrConstList;
begin
With PsrRegNode(node^.dnode)^ do
begin
new:=TsrDataType(node^.rtype);
if (new=dtUnknow) then
begin
node^.dnode:=nil;
Exit;
end;
if FSlot^.isBoolOnly then
begin
//next
node^.rtype:=ord(dtBool);
node^.dnode:=pWriter;
Exit;
end else
if is_unprep_type(dtype,new,Weak) then
begin
dtype:=new;
Weak:=True;
if is_const then
begin
pConstList:=FSlot^.FEmit.GetConstList;
pWriter:=pConstList^.Bitcast(new,pWriter^.AsType(ntConst));
end else
begin
//next
node^.dnode:=pWriter;
Exit;
end;
end;
end;
node^.dnode:=nil;
end;
class function ntReg.GetPrintName(node:PsrNode):RawByteString;
begin
Result:=PsrRegNode(node)^.GetPrintName;
end;
class function ntReg.GetRef(node:PsrNode):Pointer;
begin
With PsrRegNode(node)^ do
begin
if is_const then
begin
Result:=AsConst^.GetRef;
end else
begin
Result:=@ID;
end;
end;
end;
//
class function ntRegPair.Down(node:PsrNode):Pointer;
begin
Result:=PsrRegPair(node)^.FWriter;
end;
class Procedure ntRegPair.SetWriter(node,w,line:PsrNode);
begin
With PsrRegPair(node)^ do
begin
SetWriter(w);
end;
end;
class Procedure ntRegPair.ResetWriter(node,w:PsrNode);
begin
With PsrRegPair(node)^ do
if (FWriter=w) then
begin
SetWriter(nil);
end;
end;
//
Procedure TsrRegsStory.Init(Emit:TCustomEmit);
var
i:Word;
n:TString5;
@ -104,20 +315,50 @@ begin
For i:=0 to 103 do
begin
Str(i,n);
SGRP[i].Init(Alloc,'S'+n);
SGRP[i].Init(Emit,'S'+n);
end;
VCC[0].Init(Alloc,'VCCL');
VCC[1].Init(Alloc,'VCCH');
M0.Init(Alloc,'M0');
EXEC[0].Init(Alloc,'EXECL');
EXEC[1].Init(Alloc,'EXECH');
SCC.Init(Alloc,'SCC');
VCC[0].Init(Emit,'VCCL');
VCC[1].Init(Emit,'VCCH');
M0.Init(Emit,'M0');
EXEC[0].Init(Emit,'EXECL');
EXEC[1].Init(Emit,'EXECH');
SCC.Init(Emit,'SCC');
For i:=0 to 255 do
begin
Str(i,n);
VGRP[i].Init(Alloc,'V'+n);
VGRP[i].Init(Emit,'V'+n);
end;
FUnattach.Init(Emit,'UNATT');
end;
Function TsrRegsStory.AllocDep:PRegDNode;
begin
Result:=FDList.Pop_head;
if (Result=nil) then
begin
Result:=FUnattach.FEmit.Alloc(SizeOf(TRegDNode));
end;
end;
Procedure TsrRegsStory.FreeDep(node:PRegDNode);
begin
if (node=nil) then Exit;
node^:=Default(TRegDNode);
FDList.Push_head(node);
end;
function TsrRegsStory.get_sdst7(SDST:Byte):PsrRegSlot;
begin
Case SDST of
0..103:Result:=@SGRP[SDST];
106:Result:=@VCC[0];
107:Result:=@VCC[1];
124:Result:=@M0;
126:Result:=@EXEC[0];
127:Result:=@EXEC[1];
else
Result:=nil;
end;
FUnattach.Init(Alloc,'UNATT');
end;
function TsrRegsStory.get_sdst7_pair(SDST:Byte;dst:PPsrRegSlot):Boolean;
@ -145,20 +386,6 @@ begin
end;
end;
function TsrRegsStory.get_sdst7(SDST:Byte):PsrRegSlot;
begin
Case SDST of
0..103:Result:=@SGRP[SDST];
106:Result:=@VCC[0];
107:Result:=@VCC[1];
124:Result:=@M0;
126:Result:=@EXEC[0];
127:Result:=@EXEC[1];
else
Result:=nil;
end;
end;
function TsrRegsStory.get_ssrc8(SSRC:Byte):PsrRegSlot;
begin
Case SSRC of
@ -179,6 +406,27 @@ begin
end;
end;
function TsrRegsStory.get_ssrc9(SSRC:Word):PsrRegSlot;
begin
Case SSRC of
0..103:Result:=@SGRP[SSRC];
106:Result:=@VCC[0];
107:Result:=@VCC[1];
124:Result:=@M0;
126:Result:=@EXEC[0];
127:Result:=@EXEC[1];
//251:Result:=@VCC[0]; //VCCZ
//252:Result:=@EXEC[0]; //EXECZ
253:Result:=@SCC;
//254:Write('LDS_DIRECT');
256..511:Result:=@VGRP[SSRC-256];
else
Result:=nil;
end;
end;
function TsrRegsStory.get_ssrc9_pair(SSRC:Word;src:PPsrRegSlot):Boolean;
begin
Result:=True;
@ -209,27 +457,6 @@ begin
end;
end;
function TsrRegsStory.get_ssrc9(SSRC:Word):PsrRegSlot;
begin
Case SSRC of
0..103:Result:=@SGRP[SSRC];
106:Result:=@VCC[0];
107:Result:=@VCC[1];
124:Result:=@M0;
126:Result:=@EXEC[0];
127:Result:=@EXEC[1];
//251:Result:=@VCC[0]; //VCCZ
//252:Result:=@EXEC[0]; //EXECZ
253:Result:=@SCC;
//254:Write('LDS_DIRECT');
256..511:Result:=@VGRP[SSRC-256];
else
Result:=nil;
end;
end;
function TsrRegsStory.get_vsrc8(VSRC:Byte):PsrRegSlot;
begin
Result:=@VGRP[VSRC];
@ -350,85 +577,210 @@ end;
//--
Procedure TsrRegNode.Init; inline;
begin
fntype:=ntReg;
end;
function TsrRegNode.GetName:RawByteString;
begin
Result:='';
if (pSlot<>nil) then Result:=pSlot^.rid;
if (FSlot<>nil) then Result:=FSlot^.rid;
end;
Procedure TsrRegNode.mark_read;
Procedure TsrRegNode.AddDep(t:PsrNode);
var
pRegsStory:PsrRegsStory;
node:PRegDNode;
begin
Inc(read_count);
if (t=nil) or (@Self=nil) then Exit;
pRegsStory:=FSlot^.FEmit.GetRegsStory;
node:=pRegsStory^.AllocDep;
node^.pNode:=t;
FDList.Push_head(node);
end;
Procedure TsrRegNode.mark_unread;
Procedure TsrRegNode.RemDep(t:PsrNode);
var
pRegsStory:PsrRegsStory;
node,_prev:PRegDNode;
begin
Assert(read_count<>0);
if (read_count<>0) then Dec(read_count);
if (t=nil) or (@Self=nil) then Exit;
node:=FDList.pHead;
_prev:=nil;
While (node<>nil) do
begin
if (node^.pNode=t) then
begin
if (_prev=nil) then
begin
FDList.pHead:=node^.pNext;
end else
begin
_prev^.pNext:=node^.pNext;
end;
pRegsStory:=FSlot^.FEmit.GetRegsStory;
pRegsStory^.FreeDep(node);
Exit;
end;
_prev:=node;
node:=node^.pNext;
end;
end;
procedure TsrRegNode.SetConst(pConst:PsrConst);
function TsrRegNode.FirstDep:PRegDNode;
begin
pWriter.SetParam(ntConst,pConst);
dtype:=pConst^.key.dtype;
Result:=nil;
if (@Self=nil) then Exit;
Result:=FDList.pHead;
end;
procedure TsrRegNode.SetReg(pReg:PsrRegNode);
function TsrRegNode.GetDtype:TsrDataType;
begin
Assert(@Self<>pReg);
pWriter.SetParam(ntReg,pReg);
Result:=F.dtype;
end;
Procedure TsrRegNode.SetDtype(t:TsrDataType);
begin
F.dtype:=t;
end;
function TsrRegNode.GetWeak:Boolean;
begin
Result:=F.weak;
end;
Procedure TsrRegNode.SetWeak(t:Boolean);
begin
F.weak:=t;
end;
Procedure TsrRegNode.SetWriter(t:PsrNode);
begin
if (@Self=nil) then Exit;
if (FWriter=t) then Exit;
Assert(RegDown(t^.AsType(ntReg))<>@Self,'Circular reference');
if isUsed then
begin
t^.mark_read (@Self);
FWriter^.mark_unread(@Self);
end;
FWriter:=t;
end;
Function TsrRegNode.GetWriter:PsrNode;
begin
Result:=nil;
if (@Self=nil) then Exit;
Result:=FWriter;
end;
Procedure TsrRegNode.SetLine(t:Pointer);
begin
if (@Self=nil) then Exit;
if (FWriter<>nil) then
if (FWriter^.ntype.ClassName='ntOp') then
begin
Assert(FWriter=t);
end;
FLine:=t;
end;
function TsrRegNode.AsConst:PsrConst;
begin
Result:=nil;
if (@Self=nil) then Exit;
if (pWriter.ntype<>ntConst) then Exit;
Result:=pWriter.pData;
end;
function TsrRegNode.AsOp:Pointer;
begin
Result:=nil;
if (@Self=nil) then Exit;
if (pWriter.ntype<>ntOp) then Exit;
Result:=pWriter.pData;
if (@Self=nil) then Exit(nil);
Result:=PsrConst(FWriter^.AsType(ntConst));
end;
function TsrRegNode.AsReg:PsrRegNode;
begin
Result:=nil;
if (@Self=nil) then Exit;
if (pWriter.ntype<>ntReg) then Exit;
Result:=pWriter.pData;
if (@Self=nil) then Exit(nil);
Result:=PsrRegNode(FWriter^.AsType(ntReg));
end;
function TsrRegNode.is_const:Boolean;
begin
Result:=(pWriter.ntype=ntConst);
if (@Self=nil) then Exit(False);
Result:=FWriter^.IsType(ntConst);
end;
function TsrRegNode.is_bool:Boolean;
begin
if (@Self=nil) then Exit(False);
Result:=(dtype=dtBool);
end;
function TsrRegNode.is_bool_or_const_bool:Boolean;
begin
if (@Self=nil) then Exit(False);
Result:=is_bool or
(is_const and (AsConst<>nil) and AsConst^.isBoolVal);
(is_const and AsConst^.isBoolVal);
end;
function TsrRegNode.is_unknow:Boolean;
begin
if (@Self=nil) then Exit(True);
Result:=(dtype=dtUnknow);
end;
function TsrRegNode.GetPrintName:RawByteString;
begin
if is_const then
begin
Result:=AsConst^.GetPrintName;
end else
begin
Assert(ID.Alloc);
Result:='r'+IntToStr(ID.ID);
end;
end;
//
Procedure TsrRegPair.SetWriter(t:PsrNode);
begin
if (FWriter=t) then Exit;
if isUsed then
begin
t^.mark_read (@Self);
FWriter^.mark_unread(@Self);
end;
FWriter:=t;
end;
Procedure TsrRegPair.SetDst0(r:PsrNode);
begin
if (FDst0=r) then Exit;
FDst0^.ResetWriter(@Self);
FDst0:=r;
FDst0^.SetWriter(@Self,pLine);
end;
Procedure TsrRegPair.SetDst1(r:PsrNode);
begin
if (FDst1=r) then Exit;
FDst1^.ResetWriter(@Self);
FDst1:=r;
FDst1^.SetWriter(@Self,pLine);
end;
Procedure TsrRegPair.Init; inline;
begin
fntype:=ntRegPair;
end;
//--
Procedure TsrRegSlot.Init(a:TfnAlloc;const n:TString5);
Procedure TsrRegSlot.Init(Emit:TCustomEmit;const n:TString5);
begin
Alloc:=a;
FEmit:=Emit;
rid :=n;
end;
@ -442,12 +794,22 @@ begin
Result:=pStory.pTail;
end;
function TsrRegSlot.isBoolOnly:Boolean;
begin
Result:=(rid='SCC');
end;
function TsrRegSlot.New(pLine:Pointer;rtype:TsrDataType):PsrRegNode;
var
node:PsrRegNode;
begin
node:=Alloc(SizeOf(TsrRegNode));
node^.pSlot:=@Self;
if isBoolOnly then
begin
rtype:=dtBool;
end;
node:=FEmit.Alloc(SizeOf(TsrRegNode));
node^.Init;
node^.FSlot:=@Self;
node^.dtype:=rtype;
node^.pLine:=pLine;
pStory.Push_tail(node);
@ -458,19 +820,85 @@ function TsrRegSlot.NewAfter(rtype:TsrDataType;r:PsrRegNode):PsrRegNode;
var
node:PsrRegNode;
begin
node:=Alloc(SizeOf(TsrRegNode));
node^.pSlot:=@Self;
if isBoolOnly then
begin
rtype:=dtBool;
end;
node:=FEmit.Alloc(SizeOf(TsrRegNode));
node^.Init;
node^.FSlot:=@Self;
node^.dtype:=rtype;
node^.pLine:=r^.pLine;
pStory.InsertAfter(r,node);
Result:=node;
end;
function TsrRegSlot.NewBefore(rtype:TsrDataType;r:PsrRegNode):PsrRegNode;
var
node:PsrRegNode;
begin
if isBoolOnly then
begin
rtype:=dtBool;
end;
node:=FEmit.Alloc(SizeOf(TsrRegNode));
node^.Init;
node^.FSlot:=@Self;
node^.dtype:=rtype;
node^.pLine:=r^.pLine;
pStory.InsertBefore(r,node);
Result:=node;
end;
procedure TsrRegSlot.Remove(r:PsrRegNode);
begin
if (r=nil) then Exit;
pStory.Remove(r);
end;
//
function RegDown(node:PsrRegNode):PsrRegNode;
var
tmp:PsrRegNode;
begin
//backtrace
Result:=node;
While (Result<>nil) do
begin
tmp:=Result^.AsReg; //next
if (tmp=nil) then Break;
Assert(tmp<>Result);
Result:=tmp;
end;
end;
function RegDownSlot(node:PsrRegNode):PsrRegNode;
var
tmp:PsrRegNode;
begin
//backtrace
Result:=node;
While (Result<>nil) do
begin
tmp:=Result^.AsReg; //next
if (tmp=nil) then Break;
Assert(tmp<>Result);
if (tmp^.pSlot<>Result^.pSlot) then Break;
Result:=tmp;
end;
end;
function CompareReg(r1,r2:PsrRegNode):Boolean;
begin
r1:=RegDown(r1);
r2:=RegDown(r2);
Result:=(r1=r2);
if not Result then
begin
Result:=CompareConst(r1^.AsConst,r2^.AsConst);
end;
end;
end.

623
spirv/srType.pas Normal file
View File

@ -0,0 +1,623 @@
unit srType;
{$mode objfpc}{$H+}
{$modeswitch typehelpers}
interface
uses
bittype,
Half16;
type
TsrDataType=(
//Real types
dtUnknow,
dtBool,
dtHalf16,
dtFloat32,
dtFloat64,
dtInt8,
dtUint8,
dtInt16,
dtUint16,
dtInt32,
dtUint32,
dtInt64,
dtUint64,
//Composite types
dtVec2b,
dtVec3b,
dtVec4b,
dtStruct2u,
dtVec2u8,
dtVec4u8,
dtVec2i8,
dtVec4i8,
dtVec2u16,
dtVec4u16,
dtVec2i16,
dtVec4i16,
dtVec2u,
dtVec3u,
dtVec4u,
dtVec2i,
dtVec3i,
dtVec4i,
dtVec2h,
dtVec4h,
dtVec2f,
dtVec3f,
dtVec4f,
//Spirv types
dtTypeVoid,
dtTypeFunction,
dtTypePointer,
dtTypeStruct,
dtTypeArray,
dtTypeRuntimeArray,
dtTypeImage,
dtTypeSampler,
dtTypeSampledImage,
dtString,
dtConstant
);
TsrDataTypeHelper = type helper for TsrDataType
function isInt:Boolean;
function isFloat:Boolean;
function isBool:Boolean;
function isVector:Boolean;
function isScalar:Boolean;
function Child:TsrDataType;
function Count:Byte;
function Sign:Byte;
function BitSize:Byte;
function High:QWORD;
function AsVector(_count:Byte):TsrDataType;
end;
Pvec2f=^Tvec2f;
Tvec2f=array[0..1] of Single;
Pvec3f=^Tvec3f;
Tvec3f=array[0..2] of Single;
Pvec4f=^Tvec4f;
Tvec4f=array[0..3] of Single;
Pvec2h=^Tvec2h;
Tvec2h=array[0..1] of THalf16;
Pvec4h=^Tvec4h;
Tvec4h=array[0..3] of THalf16;
//child - result type
TsrTypeImageInfo=bitpacked record
Dim :bit3; //Dim.*
Depth :bit2; //0:no,1:yes,2:any
Arrayed:bit1; //0:no,1:yes
MS :bit1; //0:no,1:yes
Sampled:bit2; //0:runtime,1:sampling,2:read/write
Format :bit23; //ImageFormat.*
end;
PsrImageInfo=^TsrImageInfo;
TsrImageInfo=packed record
dtype:TsrDataType;
tinfo:TsrTypeImageInfo;
end;
function type_get_base_name1(dtype:TsrDataType):RawByteString;
function LazyType2(t1,t2:TsrDataType):TsrDataType;
function LazyType3(t1,t2,t3:TsrDataType):TsrDataType;
function StoreType(t:TsrDataType):TsrDataType;
function CompareType(rtype1,rtype2:TsrDataType):Boolean;
function TryBitcastType(rtype1,rtype2:TsrDataType):Boolean;
function is_unprep_type(old,new:TsrDataType;weak:Boolean):Boolean;
implementation
function type_get_base_name1(dtype:TsrDataType):RawByteString;
begin
Result:='';
case dtype of
dtBool :Result:='bool';
dtHalf16 :Result:='half';
dtFloat32 :Result:='float';
dtFloat64 :Result:='double';
dtInt8 :Result:='int8';
dtUint8 :Result:='uint8';
dtInt16 :Result:='int16';
dtUint16 :Result:='uint16';
dtInt32 :Result:='int';
dtUint32 :Result:='uint';
dtInt64 :Result:='int64';
dtUint64 :Result:='uint64';
//Composite types
dtVec2b :Result:='bvec2';
dtVec3b :Result:='bvec3';
dtVec4b :Result:='bvec4';
dtStruct2u :Result:='rec2u';
dtVec2u8 :Result:='u8vec2';
dtVec4u8 :Result:='u8vec4';
dtVec2i8 :Result:='i8vec2';
dtVec4i8 :Result:='i8vec4';
dtVec2u16 :Result:='u16vec2';
dtVec4u16 :Result:='u16vec4';
dtVec2i16 :Result:='i16vec2';
dtVec4i16 :Result:='i16vec4';
dtVec2u :Result:='uvec2';
dtVec3u :Result:='uvec3';
dtVec4u :Result:='uvec4';
dtVec2i :Result:='ivec2';
dtVec3i :Result:='ivec3';
dtVec4i :Result:='ivec4';
dtVec2h :Result:='hvec2';
dtVec4h :Result:='hvec4';
dtVec2f :Result:='vec2';
dtVec3f :Result:='vec3';
dtVec4f :Result:='vec4';
dtTypeVoid :Result:='void';
dtTypeSampler:Result:='samp';
else;
end;
end;
function LazyType2(t1,t2:TsrDataType):TsrDataType;
begin
if (t1<>dtUnknow) then Result:=t1 else Result:=t2;
end;
function LazyType3(t1,t2,t3:TsrDataType):TsrDataType;
begin
if (t1<>dtUnknow) then Result:=t1 else Result:=t2;
if (Result=dtUnknow) then Result:=t3;
end;
function StoreType(t:TsrDataType):TsrDataType;
begin
if (t=dtBool) then
Result:=dtUint32
else
Result:=t;
end;
function TsrDataTypeHelper.isInt:Boolean;
begin
Case Self of
dtInt8,
dtUint8,
dtInt16,
dtUint16,
dtInt32,
dtUint32,
dtInt64,
dtUint64,
dtStruct2u,
dtVec2u8,
dtVec4u8,
dtVec2i8,
dtVec4i8,
dtVec2u16,
dtVec4u16,
dtVec2i16,
dtVec4i16,
dtVec2u,
dtVec3u,
dtVec4u,
dtVec2i,
dtVec3i,
dtVec4i,
dtVec2f,
dtVec3f,
dtVec4f:
Result:=True;
else
Result:=False;
end;
end;
function TsrDataTypeHelper.isFloat:Boolean;
begin
Case Self of
dtHalf16,
dtFloat32,
dtFloat64,
dtVec2h,
dtVec4h,
dtVec2f,
dtVec3f,
dtVec4f:
Result:=True;
else
Result:=False;
end;
end;
function TsrDataTypeHelper.isBool:Boolean;
begin
Case Self of
dtBool,
dtVec2b,
dtVec3b,
dtVec4b:Result:=True;
else
Result:=False;
end;
end;
function TsrDataTypeHelper.isVector:Boolean;
begin
Case Self of
dtVec2b,
dtVec3b,
dtVec4b,
dtStruct2u,
dtVec2u8,
dtVec4u8,
dtVec2i8,
dtVec4i8,
dtVec2u16,
dtVec4u16,
dtVec2i16,
dtVec4i16,
dtVec2u,
dtVec3u,
dtVec4u,
dtVec2i,
dtVec3i,
dtVec4i,
dtVec2h,
dtVec4h,
dtVec2f,
dtVec3f,
dtVec4f:
Result:=True;
else
Result:=False;
end;
end;
function TsrDataTypeHelper.isScalar:Boolean;
begin
Result:=not isVector;
end;
function TsrDataTypeHelper.Child:TsrDataType;
begin
Case Self of
dtVec2b,
dtVec3b,
dtVec4b:Result:=dtBool;
dtVec2u8,
dtVec4u8:Result:=dtUint8;
dtVec2i8,
dtVec4i8:Result:=dtInt8;
dtVec2u16,
dtVec4u16:Result:=dtUint16;
dtVec2i16,
dtVec4i16:Result:=dtInt16;
dtStruct2u,
dtVec2u,
dtVec3u,
dtVec4u:Result:=dtUint32;
dtVec2i,
dtVec3i,
dtVec4i:Result:=dtInt32;
dtVec2h,
dtVec4h:Result:=dtHalf16;
dtVec2f,
dtVec3f,
dtVec4f:Result:=dtFloat32;
else
Result:=dtUnknow;
end;
end;
function TsrDataTypeHelper.Count:Byte;
begin
Case Self of
dtVec2b,
dtVec2u8,
dtVec2i8,
dtVec2u16,
dtVec2i16,
dtVec2u,
dtVec2i,
dtVec2h,
dtVec2f,
dtStruct2u:Result:=2;
dtVec3b,
dtVec3u,
dtVec3i,
dtVec3f:Result:=3;
dtVec4b,
dtVec4u8,
dtVec4i8,
dtVec4u16,
dtVec4i16,
dtVec4u,
dtVec4i,
dtVec4f,
dtVec4h:Result:=4;
else
Result:=0;
end;
end;
function TsrDataTypeHelper.Sign:Byte;
begin
Case Self of
dtInt8,
dtInt16,
dtInt32,
dtInt64,
dtHalf16,
dtFloat32,
dtFloat64,
dtVec2h,
dtVec4h,
dtVec2f,
dtVec3f,
dtVec4f:Result:=1;
else
Result:=0;
end;
end;
function TsrDataTypeHelper.BitSize:Byte;
begin
Case Self of
dtInt8,
dtUint8:Result:=8;
dtHalf16,
dtInt16,
dtUint16,
dtVec2u8,
dtVec2i8:Result:=16;
dtUnknow,
dtBool, //for typecast
dtFloat32,
dtInt32,
dtUint32,
dtVec4u8,
dtVec4i8,
dtVec2u16,
dtVec2i16,
dtVec2h:Result:=32;
dtFloat64,
dtInt64,
dtUint64,
dtVec4u16,
dtVec4i16,
dtVec2f,
dtVec4h,
dtStruct2u:Result:=64;
dtVec3u,
dtVec3i,
dtVec3f:Result:=96;
dtVec4u,
dtVec4i,
dtVec4f:Result:=128;
else
Result:=0;
end;
end;
function TsrDataTypeHelper.High:QWORD;
var
s:Byte;
begin
Result:=0;
if (Self=dtBool) then Exit(1);
s:=BitSize;
Case s of
8:Result:=System.High(Byte);
16:Result:=System.High(Word);
32:Result:=System.High(DWord);
64:Result:=System.High(QWord);
else
Assert(false);
end;
end;
function TsrDataTypeHelper.AsVector(_count:Byte):TsrDataType;
begin
Result:=dtUnknow;
if (_count<=1) then Exit(Self);
Case Self of
dtBool:
Case _count of
2:Result:=dtVec2b;
3:Result:=dtVec3b;
4:Result:=dtVec4b;
end;
dtUint8:
Case _count of
2:Result:=dtVec2u8;
4:Result:=dtVec4u8;
end;
dtInt8:
Case _count of
2:Result:=dtVec2i8;
4:Result:=dtVec4i8;
end;
dtUint16:
Case _count of
2:Result:=dtVec2u16;
4:Result:=dtVec4u16;
end;
dtInt16:
Case _count of
2:Result:=dtVec2i16;
4:Result:=dtVec4i16;
end;
dtHalf16:
Case _count of
2:Result:=dtVec2h;
4:Result:=dtVec4h;
end;
dtFloat32:
Case _count of
2:Result:=dtVec2f;
3:Result:=dtVec3f;
4:Result:=dtVec4f;
end;
dtInt32:
Case _count of
2:Result:=dtVec2i;
3:Result:=dtVec3i;
4:Result:=dtVec4i;
end;
dtUint32:
Case _count of
2:Result:=dtVec2u;
3:Result:=dtVec3u;
4:Result:=dtVec4u;
end;
else;
end;
end;
function CompareType(rtype1,rtype2:TsrDataType):Boolean;
begin
Case rtype1 of
dtInt8,
dtUint8:Result:=(rtype2=dtInt8) or (rtype2=dtUint8);
dtInt16,
dtUint16:Result:=(rtype2=dtInt16) or (rtype2=dtUint16);
dtInt32,
dtUint32:Result:=(rtype2=dtInt32) or (rtype2=dtUint32);
dtVec2u8,
dtVec2i8:Result:=(rtype2=dtVec2u8) or (rtype2=dtVec2i8);
dtVec4u8,
dtVec4i8:Result:=(rtype2=dtVec4u8) or (rtype2=dtVec4i8);
dtVec2u16,
dtVec2i16:Result:=(rtype2=dtVec2u16) or (rtype2=dtVec2i16);
dtVec4u16,
dtVec4i16:Result:=(rtype2=dtVec4u16) or (rtype2=dtVec4i16);
dtVec2u,
dtVec2i:Result:=(rtype2=dtVec2u) or (rtype2=dtVec2i);
dtVec3u,
dtVec3i:Result:=(rtype2=dtVec3u) or (rtype2=dtVec3i);
dtVec4u,
dtVec4i:Result:=(rtype2=dtVec4u) or (rtype2=dtVec4i);
else
Result:=(rtype1=rtype2);
end;
end;
function TryBitcastType(rtype1,rtype2:TsrDataType):Boolean;
var
s,d:Byte;
begin
s:=rtype1.BitSize;
d:=rtype2.BitSize;
Result:=(s<>0) and (d<>0) and (s=d);
end;
function is_unprep_type(old,new:TsrDataType;weak:Boolean):Boolean;
begin
Result:=False;
if (new<>dtUnknow) and (old<>new) then
begin
Case old of
dtUnknow:Result:=True;
dtBool :Result:=weak;
else;
end;
end;
end;
end.

File diff suppressed because it is too large Load Diff

View File

@ -5,77 +5,245 @@ unit srUniform;
interface
uses
spirv,
srNodes,
srTypes,
srLayout,
srReg,
srVariable,
srDecorate;
sysutils,
spirv,
ginodes,
srNode,
srRefId,
srType,
srTypes,
srLayout,
srVariable,
srCapability,
srDecorate,
srConfig;
type
ntRegUniform=class(TsrNodeVmt)
class function Down (node:PsrNode):Pointer; override;
class Procedure SetWriter (node,w,line:PsrNode); override;
class Procedure ResetWriter (node,w:PsrNode); override;
class Function pwrite_count(node:PsrNode):PDWORD; override;
class function GetPrintName(node:PsrNode):RawByteString; override;
class function GetRef (node:PsrNode):Pointer; override;
end;
ntUniform=class(ntDescriptor)
class Function pwrite_count (node:PsrNode):PDWORD; override;
class function GetStorageName(node:PsrNode):RawByteString; override;
end;
String2=String[2];
PsrRegUniform=^TsrRegUniform;
TsrRegUniform=packed object(TsrNode)
private
fwrite_count:DWORD;
ID:TsrRefId; //post id
//
FWriter:PsrNode;
FVar:PsrVariable;
Procedure SetWriter(t:PsrNode);
public
property pLine:PsrNode read FWriter;
Procedure Init(pVar:PsrVariable); inline;
function GetPrintName:RawByteString;
end;
PsrUniform=^TsrUniform;
TsrUniform=object(TsrDescriptor)
pLeft,pRight:PsrUniform;
//----
key:packed record
private
pLeft,pRight:PsrUniform;
//----
pLayout:PsrDataLayout;
pType:PsrType;
end;
pReg:PsrRegNode;
function c(n1,n2:PsrUniform):Integer; static;
function GetTypeChar:String2;
function GetString:RawByteString;
//
fwrite_count:DWORD;
//
FReg:TsrRegUniform;
function c(n1,n2:PsrUniform):Integer; static;
public
Procedure Init; inline;
function pReg:PsrRegUniform; inline;
function GetStorageName:RawByteString;
function GetTypeChar:String2;
function GetString:RawByteString;
end;
PsrUniformList=^TsrUniformList;
TsrUniformList=object
type
TNodeFetch=specialize TNodeFetch<PsrUniform,TsrUniform>;
var
Alloc:TfnAlloc;
FEmit:TCustomEmit;
FNTree:TNodeFetch;
procedure Init(cb:TfnAlloc);
procedure Init(Emit:TCustomEmit); inline;
function Fetch(s:PsrDataLayout;t:PsrType):PsrUniform;
Function First:PsrUniform;
Function Next(node:PsrUniform):PsrUniform;
procedure AllocBinding(Var FBinding:Integer;Decorates:PsrDecorateList);
procedure AllocSourceExtension(FDebugInfo:PsrDebugInfoList);
procedure AllocBinding(Var FBinding:Integer);
procedure AllocSourceExtension;
end;
implementation
class function ntRegUniform.Down(node:PsrNode):Pointer;
begin
Result:=PsrRegUniform(node)^.FVar;
end;
class Procedure ntRegUniform.SetWriter(node,w,line:PsrNode);
begin
With PsrRegUniform(node)^ do
begin
SetWriter(w);
end;
end;
class Procedure ntRegUniform.ResetWriter(node,w:PsrNode);
begin
With PsrRegUniform(node)^ do
if (FWriter=w) then
begin
SetWriter(nil);
end;
end;
class Function ntRegUniform.pwrite_count(node:PsrNode):PDWORD;
begin
Result:=@PsrRegUniform(node)^.fwrite_count;
end;
class function ntRegUniform.GetPrintName(node:PsrNode):RawByteString;
begin
Result:=PsrRegUniform(node)^.GetPrintName;
end;
class function ntRegUniform.GetRef(node:PsrNode):Pointer;
begin
Result:=@PsrRegUniform(node)^.ID;
end;
//
class Function ntUniform.pwrite_count(node:PsrNode):PDWORD;
begin
Result:=@PsrUniform(node)^.fwrite_count;
end;
class function ntUniform.GetStorageName(node:PsrNode):RawByteString;
begin
Result:=PsrUniform(node)^.GetStorageName;
end;
//
Procedure TsrRegUniform.Init(pVar:PsrVariable); inline;
begin
fntype:=ntRegUniform;
FVar:=pVar;
end;
Procedure TsrRegUniform.SetWriter(t:PsrNode);
begin
if (FWriter=t) then Exit;
if isUsed then
begin
t^.mark_read (@Self);
FWriter^.mark_unread(@Self);
end;
FWriter:=t;
end;
function TsrRegUniform.GetPrintName:RawByteString;
begin
Result:=FVar^.GetStorageName;
if (Result<>'') then
begin
Result:='r_'+Result;
end else
begin
Assert(ID.Alloc);
Result:='r'+IntToStr(ID.ID);
end;
end;
//
function TsrUniform.c(n1,n2:PsrUniform):Integer;
begin
//first pLayout
Result:=Integer(n1^.key.pLayout>n2^.key.pLayout)-Integer(n1^.key.pLayout<n2^.key.pLayout);
Result:=Integer(n1^.pLayout>n2^.pLayout)-Integer(n1^.pLayout<n2^.pLayout);
if (Result<>0) then Exit;
//second pType
Result:=Integer(n1^.key.pType>n2^.key.pType)-Integer(n1^.key.pType<n2^.key.pType);
Result:=Integer(n1^.FType>n2^.FType)-Integer(n1^.FType<n2^.FType);
end;
function TsrUniform.GetTypeChar:String2;
Procedure TsrUniform.Init; inline;
begin
fntype :=ntUniform;
FStorage:=StorageClass.UniformConstant;
FBinding:=-1;
end;
function TsrUniform.pReg:PsrRegUniform; inline;
begin
Result:=@FReg;
end;
function TsrUniform.GetStorageName:RawByteString;
var
image_info:TsrTypeImageInfo;
begin
Result:='';
if (key.pType<>nil) then
With key.pType^.key do
Case key.pType^.dtype of
if (FType<>nil) then
Case FType^.dtype of
dtTypeImage:
begin
if (ext.image.Dim=Dim.Buffer) then
image_info:=FType^.image_info;
if (image_info.Dim=Dim.Buffer) then
begin
Case ext.image.Sampled of
Case image_info.Sampled of
1:Result:='uTex'+IntToStr(FBinding);
2:Result:='sTex'+IntToStr(FBinding);
else Result:='rTex'+IntToStr(FBinding);
end;
end else
begin
Case image_info.Sampled of
1:Result:='uImg'+IntToStr(FBinding);
2:Result:='sImg'+IntToStr(FBinding);
else Result:='rImg'+IntToStr(FBinding);
end;
end;
end;
dtTypeSampler:Result:='uSmp'+IntToStr(FBinding);
else;
end;
end;
function TsrUniform.GetTypeChar:String2;
var
image_info:TsrTypeImageInfo;
begin
Result:='';
if (FType<>nil) then
Case FType^.dtype of
dtTypeImage:
begin
image_info:=FType^.image_info;
if (image_info.Dim=Dim.Buffer) then
begin
Case image_info.Sampled of
1:Result:='UB'; //VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER
2:Result:='SB'; //VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER
else Result:='RB'; //runtime texel buffer
end;
end else
begin
Case ext.image.Sampled of
Case image_info.Sampled of
1:Result:='UI'; //VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE
2:Result:='SI'; //VK_DESCRIPTOR_TYPE_STORAGE_IMAGE
else Result:='RI'; //runtime image
@ -92,18 +260,18 @@ var
PID:DWORD;
begin
PID:=0;
if (key.pLayout<>nil) then
if (pLayout<>nil) then
begin
PID:=key.pLayout^.FID;
PID:=pLayout^.FID;
end;
Result:=GetTypeChar+
';PID='+HexStr(PID,8)+
';BND='+HexStr(FBinding,8);
end;
procedure TsrUniformList.Init(cb:TfnAlloc);
procedure TsrUniformList.Init(Emit:TCustomEmit); inline;
begin
Alloc:=cb;
FEmit:=Emit;
end;
function TsrUniformList.Fetch(s:PsrDataLayout;t:PsrType):PsrUniform;
@ -111,19 +279,19 @@ var
node:TsrUniform;
begin
node:=Default(TsrUniform);
node.key.pLayout:=s;
node.key.pType:=t;
node.FStorage:=StorageClass.UniformConstant;
node.FBinding:=-1;
node.Init;
node.pLayout:=s;
node.FType :=t;
Result:=FNTree.Find(@node);
if (Result=nil) then
begin
Result:=Alloc(SizeOf(TsrUniform));
Result:=FEmit.Alloc(SizeOf(TsrUniform));
Move(node,Result^,SizeOf(TsrUniform));
//
Result^.InitVar(FEmit);
Result^.FReg.Init(Result^.FVar);
//
FNTree.Insert(Result);
end else
begin
t^.mark_unread;
end;
end;
@ -137,43 +305,144 @@ begin
Result:=FNTree.Next(node);
end;
procedure TsrUniformList.AllocBinding(Var FBinding:Integer;Decorates:PsrDecorateList);
procedure TsrUniformList.AllocBinding(Var FBinding:Integer);
var
pConfig:PsrConfig;
pDecorateList:PsrDecorateList;
pCapabilityList:PsrCapabilityList;
//
node:PsrUniform;
pVar:PsrVariable;
//
FType:PsrType;
image_info:TsrTypeImageInfo;
begin
if (Decorates=nil) then Exit;
pConfig :=FEmit.GetConfig;
pDecorateList :=FEmit.GetDecorateList;
pCapabilityList:=FEmit.GetCapabilityList;
node:=First;
While (node<>nil) do
begin
pVar:=node^.pVar;
if (pVar<>nil) then
if (pVar<>nil) and node^.IsUsed and (node^.FBinding=-1) then
begin
if (node^.FBinding=-1) then //alloc
pDecorateList^.OpDecorate(pVar,Decoration.Binding,FBinding);
pDecorateList^.OpDecorate(pVar,Decoration.DescriptorSet,pConfig^.DescriptorSet);
node^.FBinding:=FBinding;
Inc(FBinding);
FType:=node^.pType;
if (FType<>nil) then
begin
Decorates^.emit_decorate(ntVar,pVar,Decoration.Binding,FBinding);
Decorates^.emit_decorate(ntVar,pVar,Decoration.DescriptorSet,Decorates^.FDescriptorSet);
node^.FBinding:=FBinding;
Inc(FBinding);
Case FType^.dtype of
dtTypeImage:
begin
image_info:=FType^.image_info;
if (image_info.Sampled=2) then //storage image
begin
if (node^.FReg.read_count=0) then
begin
pDecorateList^.OpDecorate(pVar,Decoration.NonReadable,0);
end;
if (node^.FReg.write_count=0) then
begin
pDecorateList^.OpDecorate(pVar,Decoration.NonWritable,0);
end;
end;
Case image_info.Dim of
Dim.Dim1D:
Case image_info.Sampled of
1:pCapabilityList^.Add(Capability.Sampled1D); //sampling
2:pCapabilityList^.Add(Capability.Image1D); //read/write
else;
end;
Dim.Buffer:
Case image_info.Sampled of
1:pCapabilityList^.Add(Capability.SampledBuffer); //sampling
2:pCapabilityList^.Add(Capability.ImageBuffer); //read/write
else;
end;
else;
end;
if (image_info.Sampled=2) and
(image_info.Arrayed=1) then
begin
pCapabilityList^.Add(Capability.ImageMSArray);
end;
Case image_info.Format of
ImageFormat.Unknown:
begin
if (node^.FReg.read_count<>0) then
begin
pCapabilityList^.Add(Capability.StorageImageWriteWithoutFormat);
end;
if (node^.FReg.write_count<>0) then
begin
pCapabilityList^.Add(Capability.StorageImageWriteWithoutFormat);
end;
end;
ImageFormat.Rg32f ,
ImageFormat.Rg16f ,
ImageFormat.R11fG11fB10f,
ImageFormat.R16f ,
ImageFormat.Rgba16 ,
ImageFormat.Rgb10A2 ,
ImageFormat.Rg16 ,
ImageFormat.Rg8 ,
ImageFormat.R16 ,
ImageFormat.R8 ,
ImageFormat.Rgba16Snorm ,
ImageFormat.Rg16Snorm ,
ImageFormat.Rg8Snorm ,
ImageFormat.R16Snorm ,
ImageFormat.R8Snorm ,
ImageFormat.Rg32i ,
ImageFormat.Rg16i ,
ImageFormat.Rg8i ,
ImageFormat.R16i ,
ImageFormat.R8i ,
ImageFormat.Rgb10a2ui ,
ImageFormat.Rg32ui ,
ImageFormat.Rg16ui ,
ImageFormat.Rg8ui ,
ImageFormat.R16ui ,
ImageFormat.R8ui :pCapabilityList^.Add(Capability.StorageImageExtendedFormats);
else;
end;
end;
else;
end;
end;
end;
node:=Next(node);
end;
end;
procedure TsrUniformList.AllocSourceExtension(FDebugInfo:PsrDebugInfoList);
procedure TsrUniformList.AllocSourceExtension;
var
pDebugInfoList:PsrDebugInfoList;
node:PsrUniform;
pVar:PsrVariable;
begin
if (FDebugInfo=nil) then Exit;
pDebugInfoList:=FEmit.GetDebugInfoList;
node:=First;
While (node<>nil) do
begin
pVar:=node^.pVar;
if (pVar<>nil) then
if (pVar<>nil) and node^.IsUsed then
begin
FDebugInfo^.emit_source_extension(node^.GetString);
pDebugInfoList^.OpSourceExtension(node^.GetString);
end;
node:=Next(node);
end;

View File

@ -5,9 +5,8 @@ unit srVBufInfo;
interface
uses
sysutils,
ps4_pssl,
srTypes,
srType,
srLayout,
spirv;

View File

@ -5,112 +5,235 @@ unit srVariable;
interface
uses
spirv,
srNodes,
srTypes,
srRefId;
sysutils,
ginodes,
srNode,
srTypes,
srRefId,
srDecorate;
type
PsrVariable=^TsrVariable;
TsrVariable=object
pPrev,pNext:PsrVariable;
//----
read_count:DWORD;
write_count:DWORD;
ID:TsrRefId; //post id
pType:PsrType;
dtype:TsrDataType;
pSource:TOpParamSingle; //ntInput,ntVertLayout,ntFragLayout,ntOutput,ntUniform,ntBuffer
Procedure mark_read;
Procedure mark_unread;
Procedure mark_write;
Function GetStorageClass:DWORD;
Procedure Clear;
function GetName:RawByteString;
ntVariable=class(TsrNodeVmt)
class Procedure zero_read (node:PsrNode); override;
class Procedure zero_unread (node:PsrNode); override;
class Function pwrite_count (node:PsrNode):PDWORD; override;
class Function GetStorageClass(node:PsrNode):DWORD; override;
class function GetStorageName (node:PsrNode):RawByteString; override;
class function Down (node:PsrNode):Pointer; override;
class function Next (node:PsrNode):Pointer; override;
class function Prev (node:PsrNode):Pointer; override;
class Procedure PrepType (node:PPrepTypeNode); override;
class Function GetPtype (node:PsrNode):PsrNode; override;
class function GetPrintName (node:PsrNode):RawByteString; override;
class function GetRef (node:PsrNode):Pointer; override;
end;
TsrVariableList=specialize TNodeList<PsrVariable>;
PsrVariable=^TsrVariable;
TsrVariable=packed object(TsrNode)
private
pPrev,pNext:PsrVariable;
//
fwrite_count:DWORD;
ID:TsrRefId; //post id
FType:PsrType;
FSource:PsrNode; //ntInput,ntVertLayout,ntFragLayout,ntUniform,ntBuffer,ntOutput
procedure SetType(t:PsrType);
procedure SetSource(t:PsrNode);
public
property pSource:PsrNode read FSource write SetSource;
procedure UpdateType(Emit:TCustomEmit);
Procedure Init; inline;
function GetPrintName:RawByteString;
end;
PsrVariableList=^TsrVariableList;
TsrVariableList=object
type
TNodeList=specialize TNodeList<PsrVariable>;
var
FEmit:TCustomEmit;
FList:TNodeList;
procedure Init(Emit:TCustomEmit); inline;
function Fetch:PsrVariable;
function First:PsrVariable; inline;
procedure AllocName;
end;
implementation
uses
srLayout,
srVertLayout,
srFragLayout,
srInput,
srOutput;
Procedure TsrVariable.mark_read;
class Procedure ntVariable.zero_read(node:PsrNode);
begin
Inc(read_count);
end;
Procedure TsrVariable.mark_unread;
begin
if (read_count<>0) then Dec(read_count);
end;
Procedure TsrVariable.mark_write;
begin
Inc(write_count);
end;
Function TsrVariable.GetStorageClass:DWORD;
begin
Result:=StorageClass.Private_;
if (pSource.pData<>nil) then
Case pSource.ntype of
ntInput,
ntVertLayout,
ntFragLayout,
ntOutput ,
ntUniform ,
ntBuffer :Result:=PsrDescriptor(pSource.pData)^.FStorage;
else
Assert(false,'GetStorageClass');
With PsrVariable(node)^ do
begin
FType^.mark_read(@Self);
end;
end;
Procedure TsrVariable.Clear;
class Procedure ntVariable.zero_unread(node:PsrNode);
begin
if (pType<>nil) then
With PsrVariable(node)^ do
begin
pType^.mark_unread;
pType:=nil;
FType^.mark_unread(@Self);
end;
if (pSource.pData<>nil) then
end;
class Function ntVariable.pwrite_count(node:PsrNode):PDWORD;
begin
Result:=@PsrVariable(node)^.fwrite_count;
end;
class Function ntVariable.GetStorageClass(node:PsrNode):DWORD;
begin
Result:=inherited;
With PsrVariable(node)^ do
if (FSource<>nil) then
if (FSource^.ntype<>nil) then
begin
Case pSource.ntype of
ntInput ,
ntVertLayout,
ntFragLayout,
ntOutput ,
ntUniform ,
ntBuffer :PsrDescriptor(pSource.pData)^.pVar:=nil;
else
Assert(false,'Clear');
end;
pSource.pData:=nil;
end;
end;
function TsrVariable.GetName:RawByteString;
begin
Result:='';
if (pSource.pData<>nil) then
begin
Case pSource.ntype of
ntInput :
Result:=PsrInput(pSource.pData)^.GetName;
ntVertLayout:
Result:=PsrVertLayout(pSource.pData)^.GetName;
ntFragLayout:
Result:=PsrFragLayout(pSource.pData)^.GetName;
ntOutput:
Result:=PsrOutput(pSource.pData)^.GetName;
else;
Result:=FSource^.ntype.GetStorageClass(FSource);
end;
end;
class function ntVariable.GetStorageName(node:PsrNode):RawByteString;
begin
Result:=inherited;
With PsrVariable(node)^ do
if (FSource<>nil) then
if (FSource^.ntype<>nil) then
begin
Result:=FSource^.ntype.GetStorageName(FSource);
end;
end;
class function ntVariable.Down(node:PsrNode):Pointer;
begin
Result:=PsrVariable(node)^.FSource;
end;
class function ntVariable.Next(node:PsrNode):Pointer;
begin
Result:=PsrVariable(node)^.pNext;
end;
class function ntVariable.Prev(node:PsrNode):Pointer;
begin
Result:=PsrVariable(node)^.pPrev;
end;
class Procedure ntVariable.PrepType(node:PPrepTypeNode);
begin
node^.dnode:=PsrVariable(node^.dnode)^.FSource;
end;
class Function ntVariable.GetPtype(node:PsrNode):PsrNode;
begin
Result:=PsrVariable(node)^.FType;
end;
class function ntVariable.GetPrintName(node:PsrNode):RawByteString;
begin
Result:=PsrVariable(node)^.GetPrintName;
end;
class function ntVariable.GetRef(node:PsrNode):Pointer;
begin
Result:=@PsrVariable(node)^.ID;
end;
//
Procedure TsrVariable.Init; inline;
begin
fntype:=ntVariable;
end;
procedure TsrVariable.SetType(t:PsrType);
begin
if (FType=t) then Exit;
if IsUsed then
begin
t^.mark_read (@Self);
FType^.mark_unread(@Self);
end;
FType:=t;
end;
procedure TsrVariable.UpdateType(Emit:TCustomEmit);
var
_Type:PsrType;
pTypeList:PsrTypeList;
begin
if (@Self=nil) then Exit;
_Type:=FSource^.pType;
if (_Type=nil) then
begin
SetType(nil);
end else
begin
pTypeList:=Emit.GetTypeList;
_Type:=pTypeList^.FetchPointer(_Type,FSource^.GetStorageClass);
SetType(_Type);
end;
end;
procedure TsrVariable.SetSource(t:PsrNode);
begin
if (FSource=t) then Exit;
if IsUsed then
begin
t^.mark_read (@Self);
FSource^.mark_unread(@Self);
end;
FSource:=t;
end;
function TsrVariable.GetPrintName:RawByteString;
begin
Result:=GetStorageName;
if (Result='') then
begin
Assert(ID.Alloc);
Result:='v'+IntToStr(ID.ID);
end;
end;
//
procedure TsrVariableList.Init(Emit:TCustomEmit); inline;
begin
FEmit:=Emit;
end;
function TsrVariableList.Fetch:PsrVariable;
begin
Result:=FEmit.Alloc(SizeOf(TsrVariable));
Result^.Init;
FList.Push_tail(Result);
end;
function TsrVariableList.First:PsrVariable; inline;
begin
Result:=FList.pHead;
end;
procedure TsrVariableList.AllocName;
var
FDebugInfo:PsrDebugInfoList;
node:PsrVariable;
n:RawByteString;
begin
FDebugInfo:=FEmit.GetDebugInfoList;
node:=First;
While (node<>nil) do
begin
if (node^.pType<>nil) then
begin
n:=node^.GetStorageName;
if (n<>'') then
begin
FDebugInfo^.OpName(node,n);
end;
end;
node:=node^.Next;
end;
end;

View File

@ -5,48 +5,72 @@ unit srVertLayout;
interface
uses
sysutils,
spirv,
srNodes,
srReg,
srOp,
srVariable,
srLayout,
srDecorate;
sysutils,
spirv,
ginodes,
srNode,
srType,
srReg,
srOp,
srVariable,
srLayout,
srDecorate;
type
PsrVertLayout=^TsrVertLayout;
TsrVertLayout=object(TsrDescriptor)
pLeft,pRight:PsrVertLayout;
//----
pLayout:PsrDataLayout;
pReg:PsrRegNode;
function c(n1,n2:PsrVertLayout):Integer; static;
function GetString:RawByteString;
function GetName:RawByteString;
ntVertLayout=class(ntDescriptor)
class function GetStorageName(node:PsrNode):RawByteString; override;
end;
PsrVertLayout=^TsrVertLayout;
TsrVertLayout=object(TsrDescriptor)
private
pLeft,pRight:PsrVertLayout;
//----
pLayout:PsrDataLayout;
function c(n1,n2:PsrVertLayout):Integer; static;
public
pReg:PsrRegNode;
procedure Init(p:PsrDataLayout); inline;
function GetString:RawByteString;
function GetStorageName:RawByteString;
end;
PsrVertLayoutList=^TsrVertLayoutList;
TsrVertLayoutList=object
type
TNodeFetch=specialize TNodeFetch<PsrVertLayout,TsrVertLayout>;
var
Alloc:TfnAlloc;
FEmit:TCustomEmit;
FNTree:TNodeFetch;
procedure Init(cb:TfnAlloc);
function Fetch(p:PsrDataLayout):PsrVertLayout;
procedure Init(Emit:TCustomEmit); inline;
function Fetch(p:PsrDataLayout;rtype:TsrDataType):PsrVertLayout;
Function First:PsrVertLayout;
Function Next(node:PsrVertLayout):PsrVertLayout;
procedure AllocBinding(Decorates:PsrDecorateList);
procedure AllocBinding;
procedure AllocEntryPoint(EntryPoint:PSpirvOp);
procedure AllocSourceExtension(FDebugInfo:PsrDebugInfoList);
procedure AllocSourceExtension;
end;
implementation
class function ntVertLayout.GetStorageName(node:PsrNode):RawByteString;
begin
Result:=PsrVertLayout(node)^.GetStorageName;
end;
//
function TsrVertLayout.c(n1,n2:PsrVertLayout):Integer;
begin
Result:=Integer(n1^.pLayout>n2^.pLayout)-Integer(n1^.pLayout<n2^.pLayout);
//Result:=CompareByte(n1^.key,n2^.key,SizeOf(TsrVertLayout.key));
end;
procedure TsrVertLayout.Init(p:PsrDataLayout); inline;
begin
fntype :=ntVertLayout;
FStorage:=StorageClass.Input;
FBinding:=-1;
pLayout :=p;
end;
function TsrVertLayout.GetString:RawByteString;
@ -62,29 +86,31 @@ begin
';BND='+HexStr(FBinding,8);
end;
function TsrVertLayout.GetName:RawByteString;
function TsrVertLayout.GetStorageName:RawByteString;
begin
Result:='atParam'+IntToStr(FBinding);
end;
procedure TsrVertLayoutList.Init(cb:TfnAlloc);
procedure TsrVertLayoutList.Init(Emit:TCustomEmit); inline;
begin
Alloc:=cb;
FEmit:=Emit;
end;
function TsrVertLayoutList.Fetch(p:PsrDataLayout):PsrVertLayout;
function TsrVertLayoutList.Fetch(p:PsrDataLayout;rtype:TsrDataType):PsrVertLayout;
var
node:TsrVertLayout;
begin
node:=Default(TsrVertLayout);
node.pLayout:=p;
node.Init(p);
Result:=FNTree.Find(@node);
if (Result=nil) then
begin
Result:=Alloc(SizeOf(TsrVertLayout));
Result^.pLayout:=p;
Result^.FStorage:=StorageClass.Input;
Result^.FBinding:=-1;
Result:=FEmit.Alloc(SizeOf(TsrVertLayout));
Move(node,Result^,SizeOf(TsrVertLayout));
//
Result^.InitType(rtype,FEmit);
Result^.InitVar(FEmit);
//
FNTree.Insert(Result);
end;
end;
@ -99,26 +125,24 @@ begin
Result:=FNTree.Next(node);
end;
procedure TsrVertLayoutList.AllocBinding(Decorates:PsrDecorateList);
procedure TsrVertLayoutList.AllocBinding;
var
pDecorateList:PsrDecorateList;
node:PsrVertLayout;
pVar:PsrVariable;
FBinding:Integer;
begin
if (Decorates=nil) then Exit;
pDecorateList:=FEmit.GetDecorateList;
FBinding:=0;
node:=First;
While (node<>nil) do
begin
pVar:=node^.pVar;
if (pVar<>nil) then
if (pVar<>nil) and node^.IsUsed and (node^.FBinding=-1) then
begin
if (node^.FBinding=-1) then //alloc
begin
Decorates^.emit_decorate(ntVar,pVar,Decoration.Location,FBinding);
node^.FBinding:=FBinding;
Inc(FBinding);
end;
pDecorateList^.OpDecorate(pVar,Decoration.Location,FBinding);
node^.FBinding:=FBinding;
Inc(FBinding);
end;
node:=Next(node);
end;
@ -134,27 +158,28 @@ begin
While (node<>nil) do
begin
pVar:=node^.pVar;
if (pVar<>nil) then
if (pVar<>nil) and node^.IsUsed then
begin
EntryPoint^.AddParam(ntVar,pVar);
EntryPoint^.AddParam(pVar);
end;
node:=Next(node);
end;
end;
procedure TsrVertLayoutList.AllocSourceExtension(FDebugInfo:PsrDebugInfoList);
procedure TsrVertLayoutList.AllocSourceExtension;
var
FDebugInfo:PsrDebugInfoList;
node:PsrVertLayout;
pVar:PsrVariable;
begin
if (FDebugInfo=nil) then Exit;
FDebugInfo:=FEmit.GetDebugInfoList;
node:=First;
While (node<>nil) do
begin
pVar:=node^.pVar;
if (pVar<>nil) then
if (pVar<>nil) and node^.IsUsed then
begin
FDebugInfo^.emit_source_extension(node^.GetString);
FDebugInfo^.OpSourceExtension(node^.GetString);
end;
node:=Next(node);
end;

View File

@ -1,489 +0,0 @@
unit srVolatile;
{$mode ObjFPC}{$H+}
interface
uses
spirv,
srNodes,
srTypes,
srConst,
srReg,
srVariable,
srOp,
srOpUtils,
SprvEmit;
type
PsrVolatile=^TsrVolatile;
TsrVolatile=object
pNext:PsrVolatile;
pReg:PsrRegNode;
pPar:PsrOpBlock;
FID:SizeUint;
end;
PsrVolatiles=^TsrVolatiles;
_TsrVolatiles=specialize TNodeStack<PsrVolatile>;
TsrVolatiles=object(_TsrVolatiles)
function pop_reg:PsrRegNode;
function find_reg(pReg:PsrRegNode):PsrVolatile;
end;
TEmitVolatile=object(TSprvEmit)
procedure NextVolatileID;
function AllocVolatile:PsrVolatile;
function NewVolatile(pReg:PsrRegNode):PsrVolatile;
procedure build_slot_dis(pSlot:PsrRegSlot;var old:PsrRegNode);
procedure build_slot_cur(pSlot:PsrRegSlot;var old:PsrRegNode);
procedure build_slot_old(pSlot:PsrRegSlot;var old:PsrRegNode);
procedure build_volatile_dis(old:PsrRegsSnapshot);
procedure build_volatile_cur(old:PsrRegsSnapshot);
procedure build_volatile_old(old:PsrRegsSnapshot);
procedure make_copy_slot(pSlot:PsrRegSlot);
procedure make_copy_all;
procedure PrepVolatile(dst:PspirvOp;src:PsrRegNode);
end;
implementation
uses
emit_post;
function CompareReg(r1,r2:PsrRegNode):Boolean;
begin
r1:=RegDown(r1);
r2:=RegDown(r2);
Result:=(r1=r2);
if not Result then
begin
Result:=CompareConst(r1^.AsConst,r2^.AsConst);
end;
end;
function TsrVolatiles.pop_reg:PsrRegNode;
var
node:PsrVolatile;
begin
Result:=nil;
node:=Pop_head;
if (node=nil) then Exit;
Result:=node^.pReg;
end;
function TsrVolatiles.find_reg(pReg:PsrRegNode):PsrVolatile;
var
node:PsrVolatile;
begin
Result:=nil;
//pReg:=RegDownSlot(pReg);
node:=pHead;
While (node<>nil) do
begin
if (pReg={RegDownSlot}(node^.pReg)) then Exit(node);
node:=node^.pNext;
end;
end;
procedure TEmitVolatile.NextVolatileID;
begin
Inc(FVolatileID);
end;
function TEmitVolatile.AllocVolatile:PsrVolatile;
begin
Result:=Alloc(SizeOf(TsrVolatile));
end;
function TEmitVolatile.NewVolatile(pReg:PsrRegNode):PsrVolatile;
begin
Result:=AllocVolatile;
Result^.pReg:=pReg;
Result^.pPar:=FMain^.pBlock;
Result^.FID :=FVolatileID;
pReg^.mark_read;
end;
procedure TEmitVolatile.build_slot_dis(pSlot:PsrRegSlot;var old:PsrRegNode);
var
cur:PsrRegNode;
begin
cur:=pSlot^.current;
While (cur<>old) do
begin
pSlot^.Remove(cur);
cur:=pSlot^.current;
end;
end;
procedure TEmitVolatile.build_slot_cur(pSlot:PsrRegSlot;var old:PsrRegNode);
var
cur,prv,new:PsrRegNode;
st_cur:TsrVolatiles;
rtype:TsrDataType;
begin
cur:=RegDownSlot(pSlot^.current);
prv:=RegDownSlot(old);
if CompareReg(cur,prv) then Exit;
cur:=pSlot^.current;
if (cur<>nil) then
begin
rtype:=cur^.dtype;
end else
begin
rtype:=old^.dtype;
end;
if (cur=nil) then
begin
Assert(false,'WTF');
//cur:=pSlot^.New(rtype); //Unresolve
end;
if (old=nil) then
begin
//old:=pSlot^.New(rtype); //Unresolve
end;
st_cur:=Default(TsrVolatiles);
if (old<>nil) then
begin
st_cur.Push_head(NewVolatile(old));
end;
st_cur.Push_head(NewVolatile(cur));
new:=pSlot^.New(cur^.pLine,rtype);
new^.pWriter.SetParam(ntVolatile,st_cur.pHead);
new^.mark_read;
PostReg(new);
old:=new; //update snap
end;
procedure TEmitVolatile.build_slot_old(pSlot:PsrRegSlot;var old:PsrRegNode);
var
cur,prv:PsrRegNode;
st_old:TsrVolatiles;
begin
cur:=RegDownSlot(pSlot^.current);
prv:=RegDownSlot(old);
if (prv=nil) or CompareReg(cur,prv) then Exit;
cur:=pSlot^.current;
if (old^.pWriter.ntype=ntVolatile) then
begin
st_old.pHead:=old^.pWriter.pData;
st_old.Push_head(NewVolatile(cur));
Exit;
end;
Assert(old^.pWriter.ntype=ntReg);
Assert(old^.pWriter.pData<>nil);
prv:=old^.pWriter.pData;
st_old:=Default(TsrVolatiles);
st_old.Push_head(NewVolatile(prv));
st_old.Push_head(NewVolatile(cur));
prv^.mark_unread;
old^.pWriter.SetParam(ntVolatile,st_old.pHead);
end;
procedure TEmitVolatile.build_volatile_dis(old:PsrRegsSnapshot);
begin
FRegsStory.ForEachSnap(@build_slot_dis,old);
end;
procedure TEmitVolatile.build_volatile_cur(old:PsrRegsSnapshot);
begin
NextVolatileID;
FRegsStory.ForEachSnap(@build_slot_cur,old);
end;
procedure TEmitVolatile.build_volatile_old(old:PsrRegsSnapshot);
begin
NextVolatileID;
FRegsStory.ForEachSnap(@build_slot_old,old);
end;
procedure TEmitVolatile.make_copy_slot(pSlot:PsrRegSlot);
var
cur:PsrRegNode;
begin
if (pSlot^.current<>nil) then
begin
cur:=pSlot^.current;
MakeCopy(pSlot,cur);
pSlot^.current^.pLine:=cur^.pLine;
end;
end;
procedure TEmitVolatile.make_copy_all;
begin
FRegsStory.ForEachSlot(@make_copy_slot);
end;
{
function is_load_from(dst:PspirvOp;r:PsrRegNode;v:PsrVariable):Boolean;
var
src:PspirvOp;
pVar:PsrVariable;
begin
Result:=False;
src:=r^.AsOp;
if (src=nil) then Exit;
if (src^.OpId<>Op.OpLoad) then Exit;
pVar:=src^.pParam.pHead^.AsVar;
if (pVar<>v) then Exit;
Result:=IsGTFlow(src,dst);
end;
}
function get_load_from(r:PsrRegNode):PsrVariable;
var
pOp:PspirvOp;
begin
Result:=nil;
pOp:=r^.AsOp;
if (pOp=nil) then Exit;
if (pOp^.OpId<>Op.OpLoad) then Exit;
Result:=pOp^.pParam.pHead^.AsVar;
end;
type
TsrTypesA=array[Low(TsrDataType)..High(TsrDataType)] of DWORD;
function calc_best_type(pSlot:PsrRegSlot;st:TsrVolatiles):TsrDataType;
var
node:PsrVolatile;
pReg:PsrRegNode;
types:TsrTypesA;
i,max_id:TsrDataType;
bonly:Boolean;
begin
Result:=dtUnknow;
case pSlot^.rid of
'SCC':Exit(dtBool); //only bool
end;
types:=Default(TsrTypesA);
bonly:=true;
node:=st.pHead;
While (node<>nil) do
begin
if (node^.pReg<>nil) then
begin
pReg:=RegDown(node^.pReg);
if (pReg^.dtype<>dtBool) then bonly:=false;
Inc(types[pReg^.dtype]);
end;
node:=node^.pNext;
end;
case pSlot^.rid of
'VCCL',
'VCCH',
'EXECL',
'EXECH':if (types[dtBool]<>0) then Exit(dtBool); //prior bool
end;
if bonly and (types[dtBool]<>0) then
begin
Exit(dtBool);
end else
begin
//types[dtBool]:=0;
end;
max_id:=dtUnknow;
For i:=Low(TsrDataType) to High(TsrDataType) do
begin
if (max_id=dtUnknow) and (types[i]<>0) then
begin
max_id:=i;
end else
begin
if (types[i]>types[max_id]) then max_id:=i
end;
end;
Result:=max_id;
end;
{
procedure MoveVolatiles(dst,src:PsrVolatiles);
var
node:PsrVolatile;
begin
repeat
node:=src^.Pop_head;
if (node=nil) then Break;
if (dst^.find_reg(node^.pReg)=nil) then
begin
//Writeln(node^.pReg^.GetName);
dst^.Push_head(node);
end else
begin
RegUnmark(node^.pReg);
end;
until false;
end;
function TEmitVolatile._PrepVolatile(src:PsrRegNode):Integer;
var
st_tmp:TsrVolatiles;
node:PsrVolatile;
pReg:PsrRegNode;
begin
Result:=0;
if (src=nil) then Exit;
if (src^.pWriter.ntype<>ntVolatile) then Exit;
node:=src^.pWriter.pData;
While (node<>nil) do
begin
pReg:=RegDownSlot(node^.pReg);
if (pReg<>nil) then
begin
if (pReg^.pWriter.ntype=ntVolatile) then
begin
st_tmp.pHead:=pReg^.pWriter.pData;
Assert(st_tmp.pHead<>nil);
MoveVolatiles(@src^.pWriter.pData,@st_tmp);
pReg^.SetReg(src);
node^.pReg:=nil;
Inc(Result);
end;
end;
node:=node^.pNext;
end;
end;
}
procedure TEmitVolatile.PrepVolatile(dst:PspirvOp;src:PsrRegNode);
var
rtype:TsrDataType;
pSlot:PsrRegSlot;
pReg,tmp:PsrRegNode;
v:PsrVariable;
node:PsrVolatile;
st,st_tmp:TsrVolatiles;
pLine:PspirvOp;
begin
if (src=nil) then Exit;
if (src^.pWriter.ntype<>ntVolatile) then Exit;
pSlot:=src^.pSlot;
st.pHead:=src^.pWriter.pData;
Assert(st.pHead<>nil);
//While _PrepVolatile(src)<>0 do;
v:=pSlot^.pVar;
if (v=nil) then
begin
rtype:=calc_best_type(pSlot,st);
v:=NewVariable;
v^.dtype:=rtype;
pSlot^.pVar:=v;
end else
begin
rtype:=v^.dtype;
end;
repeat
node:=st.Pop_head;
if (node=nil) then Break;
pReg:=node^.pReg;
if (pReg=nil) then Continue;
//Assert(pReg<>nil);
//Assert(pReg^.pWriter.ntype<>ntVolatile);
tmp:=RegDownSlot(pReg);
if (src<>tmp) and (v<>get_load_from(tmp)) then
begin
//mark_read volatile->emit_OpStore
pLine:=tmp^.pLine;
Assert(pLine<>nil);
if (tmp^.pWriter.ntype=ntVolatile) then
begin
begin
st_tmp.pHead:=tmp^.pWriter.pData;
Assert(st_tmp.pHead<>nil);
st.Move_from(st_tmp);
src^.mark_read;
tmp^.SetReg(src);
//tmp^.pLine:=dst;
//writeln;
//PrepVolatile(pReg^.pLine,pReg);
node^.pReg:=nil;
Continue;
end;
end;
{Case pLine^.OpId of
OpLinks:Writeln('OpLinks');
OpBlock:Writeln('OpBlock');
else
Writeln(Op.GetStr(pLine^.OpId));
end;
Writeln(HexStr(pLine^.Adr.Offdw*4,4));
Assert(pReg^.pWriter.ntype<>ntVolatile);}
TSprvEmit_post(Self).PrepTypeNode(pReg,rtype,False);
{if pLine^.Adr.Offdw*4=$AC then
begin
writeln('dst:',Op.GetStr(dst^.OpId),' ',HexStr(dst^.Adr.Offdw*4,4));
writeln;
end;}
_up_merge_line(pLine);
TSprvEmit_post(Self).emit_OpStore(pLine,v,pReg); //after reg
end else
begin
node^.pReg:=nil;
RegUnmark(pReg);
//pReg^.mark_unread;
end;
until false;
v^.mark_read;
//src^.dtype:=rtype; //reuse
pLine:=dst;
Assert(pLine<>nil);
pLine:=pLine^.pPrev;
Assert(pLine<>nil);
_up_merge_line(pLine);
Assert(pLine<>nil);
TSprvEmit_post(Self).PrepTypeDst(src,rtype); //reuse
TSprvEmit_post(Self).emit_OpLoad(pLine,src,v); //before reg
end;
end.

View File

@ -21,6 +21,7 @@ uses
type
TvResourceType=(
vtRoot,
vtBufPtr2,
vtFunPtr2,
vtVSharp4,
@ -279,6 +280,7 @@ end;
procedure TvShaderExt.OnDataLayout(P:PChar);
begin
Case P[1] of
'R':AddDataLayout(vtRoot ,_get_hex_dword(@P[7]),_get_hex_dword(@P[$14]));
'B':AddDataLayout(vtBufPtr2,_get_hex_dword(@P[7]),_get_hex_dword(@P[$14]));
'F':AddDataLayout(vtFunPtr2,_get_hex_dword(@P[7]),_get_hex_dword(@P[$14]));
'V':AddDataLayout(vtVSharp4,_get_hex_dword(@P[7]),_get_hex_dword(@P[$14]));
@ -473,12 +475,15 @@ begin
pSharp:=pData;
if (Length(addr)>1) then
For i:=High(addr)-1 downto 0 do
For i:=High(addr) downto 0 do
begin
pData:=pData+addr[i].offset;
Case addr[i].rtype of
vtRoot:
begin
pSharp:=pData;
end;
vtBufPtr2:
begin
pData:=Pointer(PPtrUint(pData)^ and (not 3));
@ -895,6 +900,7 @@ begin
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
Case b.addr[0].rtype of
vtRoot,
vtBufPtr2:
begin
a:=AlignShift(P,limits.minStorageBufferOffsetAlignment);
@ -905,7 +911,8 @@ begin
a:=AlignShift(Pointer(PVSharpResource4(P)^.base),limits.minStorageBufferOffsetAlignment);
if (a<>b.offset) then FResult:=False;
end;
else;
else
Assert(false);
end;
else;

View File

@ -14,6 +14,8 @@ uses
ps4_gpu_regs,
shader_dump,
ps4_program,
vDevice,
vShaderExt,
@ -163,12 +165,39 @@ begin
end;
end;
Procedure DumpSpv(FStage:TvShaderStage;M:TMemoryStream);
var
hash:DWORD;
F:THandle;
fname:RawByteString;
begin
hash:=FastHash(M.Memory,M.Size);
case FStage of
vShaderStagePs:fname:='_ps_';
vShaderStageVs:fname:='_vs_';
vShaderStageCs:fname:='_cs_';
else
Exit;
end;
fname:='shader_dump\'+get_dev_progname+fname+HexStr(hash,8)+'.spv';
if FileExists(fname) then Exit;
CreateDir('shader_dump');
F:=FileCreate(fname);
FileWrite(F,M.Memory^,M.Size);
FileClose(F);
end;
function ParseShader(FStage:TvShaderStage;pData:PDWORD;var GPU_REGS:TGPU_REGS):TMemoryStream;
var
SprvEmit:TSprvEmit;
begin
Result:=nil;
SprvEmit:=Default(TSprvEmit);
SprvEmit:=TSprvEmit.Create;
case FStage of
vShaderStagePs :
@ -191,37 +220,37 @@ begin
Exit;
end;
SprvEmit.FPrintAsm :=False;
SprvEmit.FUseVertexInput:=True;
SprvEmit.FUseTexelBuffer:=False;
SprvEmit.FUseOutput16 :=storageInputOutput16;
SprvEmit.Config.PrintAsm :=False;
SprvEmit.Config.UseVertexInput:=True;
SprvEmit.Config.UseTexelBuffer:=False;
SprvEmit.Config.UseOutput16 :=storageInputOutput16;
SprvEmit.FBuffers.cfg.maxUniformBufferRange :=0; // $FFFF
SprvEmit.FBuffers.cfg.PushConstantsOffset :=0; // 0
SprvEmit.FBuffers.cfg.maxPushConstantsSize :=limits.maxPushConstantsSize; // 128
SprvEmit.FBuffers.cfg.minStorageBufferOffsetAlignment:=limits.minStorageBufferOffsetAlignment; // $10
SprvEmit.FBuffers.cfg.minUniformBufferOffsetAlignment:=limits.minUniformBufferOffsetAlignment; // $100
SprvEmit.Config.maxUniformBufferRange :=0; // $FFFF
SprvEmit.Config.PushConstantsOffset :=0; // 0
SprvEmit.Config.maxPushConstantsSize :=limits.maxPushConstantsSize; // 128
SprvEmit.Config.minStorageBufferOffsetAlignment:=limits.minStorageBufferOffsetAlignment; // $10
SprvEmit.Config.minUniformBufferOffsetAlignment:=limits.minUniformBufferOffsetAlignment; // $100
SprvEmit.FBuffers.cfg.maxPushConstantsSize:=16*4;
SprvEmit.FBuffers.cfg.maxPushConstantsSize:=12;
//SprvEmit.FUseVertexInput:=False;
SprvEmit.Config.maxPushConstantsSize:=16*4;
SprvEmit.Config.maxPushConstantsSize:=12;
//SprvEmit.Config.UseVertexInput:=False;
if (SprvEmit.Parse(pData)>1) then
if (SprvEmit.ParseStage(pData)>1) then
begin
Writeln(StdErr,'Shader Parse Err');
SprvEmit.FAllocator.Free;
SprvEmit.Free;
Exit;
end;
TSprvEmit_post(SprvEmit).Post;
TSprvEmit_alloc(SprvEmit).Alloc;
//TSprvEmit_print(SprvEmit).Print;
SprvEmit.PostStage;
SprvEmit.AllocStage;
Result:=TMemoryStream.Create;
TSprvEmit_bin(SprvEmit).SaveToStream(Result);
SprvEmit.SaveToStream(Result);
SprvEmit.FAllocator.Free;
SprvEmit.Free;
//DumpSpv(FStage,Result);
end;
function _FetchShader(FStage:TvShaderStage;pData:PDWORD;FDescSetId:Integer;var GPU_REGS:TGPU_REGS):TvShaderExt;