mirror of https://github.com/red-prig/fpPS4.git
This commit is contained in:
parent
146b57a28e
commit
6dc7235d61
|
@ -1165,7 +1165,7 @@ begin
|
|||
|
||||
GP_KEY.SetBlendInfo(ctx.rt_info^.BLEND_INFO.logicOp,@ctx.rt_info^.BLEND_INFO.blendConstants);
|
||||
|
||||
GP_KEY.SetPrimType (TVkPrimitiveTopology(ctx.rt_info^.PRIM_TYPE));
|
||||
GP_KEY.SetPrimType (ctx.rt_info^.PRIM_TYPE,GP_KEY.FShaderGroup.FKey.FPrimtype);
|
||||
GP_KEY.SetPrimReset(ctx.rt_info^.PRIM_RESET);
|
||||
|
||||
if (ctx.rt_info^.VP_COUNT<>0) then
|
||||
|
@ -1751,7 +1751,7 @@ begin
|
|||
CP_KEY.FShaderGroup.ExportUnifBuilder(FUniformBuilder,dst);
|
||||
|
||||
//htile heuristic
|
||||
if (CP_KEY.FShaderGroup.FKey.FShaders[vShaderStageCs].FHash_gcn=$7DCE68F83F66B337) then
|
||||
if (CP_KEY.FShaderGroup.FKey.FShaders[vShaderStageCs].IsCSClearShader) then
|
||||
begin
|
||||
Prepare_htile(ctx,FUniformBuilder);
|
||||
//
|
||||
|
|
|
@ -1364,25 +1364,6 @@ begin
|
|||
Init_Uniforms(node,FUniformBuilder);
|
||||
end;
|
||||
|
||||
function IsClearDepthShaders(const FShaders:AvShaderStage):Boolean; inline;
|
||||
begin
|
||||
Result:=False;
|
||||
|
||||
if (FShaders[vShaderStageLs]=nil) and
|
||||
(FShaders[vShaderStageHs]=nil) and
|
||||
(FShaders[vShaderStageEs]=nil) and
|
||||
(FShaders[vShaderStageGs]=nil) and
|
||||
(FShaders[vShaderStageVs]<>nil) and
|
||||
(FShaders[vShaderStagePs]<>nil) and
|
||||
(FShaders[vShaderStageCs]=nil) then
|
||||
|
||||
if (FShaders[vShaderStageVs].FHash_gcn=QWORD($00DF6E6331449451)) and
|
||||
(FShaders[vShaderStagePs].FHash_gcn=QWORD($E9FF5D4699E5B9AD)) then
|
||||
begin
|
||||
Result:=True;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure t_pm4_stream.BuildDraw(ntype:t_pm4_node_type;
|
||||
var SG_REG:TSH_REG_GFX_GROUP;
|
||||
var CX_REG:TCONTEXT_REG_GROUP;
|
||||
|
|
|
@ -1312,6 +1312,10 @@
|
|||
<Filename Value="vulkan\vDescriptorSet.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit>
|
||||
<Unit>
|
||||
<Filename Value="vulkan\vRectGS.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit>
|
||||
</Units>
|
||||
</ProjectOptions>
|
||||
<CompilerOptions>
|
||||
|
|
|
@ -58,6 +58,8 @@ type
|
|||
NTY:TCOMPUTE_NUM_THREAD_Y;
|
||||
NTZ:TCOMPUTE_NUM_THREAD_Z);
|
||||
|
||||
Procedure InitCustomGs();
|
||||
|
||||
procedure emit_spi; override;
|
||||
|
||||
Procedure PostStage;
|
||||
|
@ -558,6 +560,19 @@ begin
|
|||
AddCapability(Capability.Shader);
|
||||
end;
|
||||
|
||||
Procedure TSprvEmit.InitCustomGs();
|
||||
begin
|
||||
FExecutionModel:=ExecutionModel.Geometry;
|
||||
|
||||
FGeometryInfo.outputVertCount:=4;
|
||||
FGeometryInfo.invocationCount:=1;
|
||||
FGeometryInfo.InputMode :=ExecutionMode.Triangles;
|
||||
FGeometryInfo.OutputMode :=ExecutionMode.OutputTriangleStrip;
|
||||
|
||||
AddCapability(Capability.Shader);
|
||||
AddCapability(Capability.Geometry);
|
||||
end;
|
||||
|
||||
//
|
||||
|
||||
procedure TSprvEmit.emit_spi;
|
||||
|
|
|
@ -213,6 +213,19 @@ begin
|
|||
node^.AddLiteral(FLocalSize.y);
|
||||
node^.AddLiteral(FLocalSize.z);
|
||||
end;
|
||||
|
||||
ExecutionModel.Geometry:
|
||||
begin
|
||||
node:=AddExecutionMode(ExecutionMode.OutputVertices);
|
||||
node^.AddLiteral(FGeometryInfo.outputVertCount);
|
||||
//
|
||||
node:=AddExecutionMode(ExecutionMode.Invocations);
|
||||
node^.AddLiteral(FGeometryInfo.invocationCount);
|
||||
//
|
||||
node:=AddExecutionMode(FGeometryInfo.InputMode);
|
||||
node:=AddExecutionMode(FGeometryInfo.OutputMode);
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
end;
|
||||
|
|
|
@ -42,7 +42,7 @@ type
|
|||
TSVInstrBuffer=object
|
||||
Data:array of DWORD;
|
||||
COUNT:DWORD;
|
||||
Procedure AllocData;
|
||||
function FetchData(dcount:DWORD):PDWORD;
|
||||
Procedure NewOp(OpId:WORD);
|
||||
Procedure Reset;
|
||||
Procedure Flush(Stream:TStream);
|
||||
|
@ -65,12 +65,19 @@ type
|
|||
|
||||
implementation
|
||||
|
||||
Procedure TSVInstrBuffer.AllocData;
|
||||
function TSVInstrBuffer.FetchData(dcount:DWORD):PDWORD;
|
||||
var
|
||||
i:DWORD;
|
||||
begin
|
||||
i:=COUNT;
|
||||
COUNT:=COUNT+dcount;
|
||||
//
|
||||
if (Length(Data)<COUNT) then
|
||||
begin
|
||||
SetLength(Data,COUNT);
|
||||
end;
|
||||
//
|
||||
Result:=@Data[i];
|
||||
end;
|
||||
|
||||
Procedure TSVInstrBuffer.NewOp(OpId:WORD);
|
||||
|
@ -78,14 +85,12 @@ var
|
|||
I:TSPIRVInstruction;
|
||||
begin
|
||||
Assert(COUNT=0,'prev op not flushed');
|
||||
|
||||
COUNT:=1;
|
||||
AllocData;
|
||||
COUNT:=0;
|
||||
|
||||
I.OP:=OpId;
|
||||
I.COUNT:=0;
|
||||
|
||||
Data[0]:=DWORD(I);
|
||||
FetchData(1)^:=DWORD(I);
|
||||
end;
|
||||
|
||||
Procedure TSVInstrBuffer.Reset;
|
||||
|
@ -102,20 +107,17 @@ begin
|
|||
end;
|
||||
|
||||
procedure TSVInstrBuffer.AddParam(P:DWORD);
|
||||
var
|
||||
I:DWORD;
|
||||
begin
|
||||
Assert(COUNT<>0,'new op not created');
|
||||
I:=COUNT;
|
||||
Inc(COUNT);
|
||||
AllocData;
|
||||
Data[i]:=P;
|
||||
|
||||
FetchData(1)^:=DWORD(P);
|
||||
end;
|
||||
|
||||
procedure TSVInstrBuffer.AddNode(node:PsrNode);
|
||||
var
|
||||
R:PsrRefId;
|
||||
I,L,D:DWORD;
|
||||
L,D:DWORD;
|
||||
P:PDWORD;
|
||||
begin
|
||||
Assert(node<>nil);
|
||||
Assert(COUNT<>0,'new op not created');
|
||||
|
@ -123,22 +125,17 @@ begin
|
|||
R:=node^.GetRef;
|
||||
if (R<>nil) then
|
||||
begin
|
||||
I:=COUNT;
|
||||
Inc(COUNT);
|
||||
AllocData;
|
||||
Data[i]:=R^.ID;
|
||||
FetchData(1)^:=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;
|
||||
P:=FetchData(D);
|
||||
|
||||
FillDWord(Data[i],D,0);
|
||||
node^.GetData(@Data[i]);
|
||||
FillDWord(P^,D,0);
|
||||
node^.GetData(P);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
@ -222,14 +219,38 @@ begin
|
|||
While (node<>nil) do
|
||||
begin
|
||||
buf.NewOp(node^.OpId);
|
||||
buf.AddNode(node);
|
||||
|
||||
if (node^.ItemCount<>0) then
|
||||
if (node^.OpId=Op.OpConstant) then
|
||||
begin
|
||||
For i:=0 to node^.ItemCount-1 do
|
||||
//Array Const
|
||||
if (node^.ItemCount>0) then
|
||||
begin
|
||||
buf.AddNode(node^.GetItem(i));
|
||||
buf.AddNode(node^.GetItem(0));
|
||||
end;
|
||||
|
||||
buf.AddNode(node);
|
||||
|
||||
if (node^.ItemCount>1) then
|
||||
begin
|
||||
For i:=1 to node^.ItemCount-1 do
|
||||
begin
|
||||
buf.AddNode(node^.GetItem(i));
|
||||
end;
|
||||
end;
|
||||
//Array Const
|
||||
end else
|
||||
begin
|
||||
//Types
|
||||
buf.AddNode(node);
|
||||
|
||||
if (node^.ItemCount<>0) then
|
||||
begin
|
||||
For i:=0 to node^.ItemCount-1 do
|
||||
begin
|
||||
buf.AddNode(node^.GetItem(i));
|
||||
end;
|
||||
end;
|
||||
//Types
|
||||
end;
|
||||
|
||||
buf.Flush(Stream);
|
||||
|
|
|
@ -79,6 +79,7 @@ type
|
|||
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 AddPositionsInput(count:Byte):PsrVariable;
|
||||
function FetchUniform(src:PsrDataLayout;pType:PsrType):PsrNode;
|
||||
function FetchImage(src:PsrDataLayout;dtype:TsrDataType;info:TsrTypeImageInfo):PsrNode;
|
||||
function FetchSampler(src:PsrDataLayout):PsrNode;
|
||||
|
@ -699,6 +700,18 @@ begin
|
|||
OpExtract(init_line,dst^.New(line,rtype),rsl,id);
|
||||
end;
|
||||
|
||||
function TEmitFetch.AddPositionsInput(count:Byte):PsrVariable;
|
||||
var
|
||||
i:PsrInput;
|
||||
t:PsrType;
|
||||
begin
|
||||
t:=TypeList.FetchArray(TypeList.Fetch(dtVec4f),count);
|
||||
|
||||
i:=InputList.Fetch(t,itPosition,0);
|
||||
|
||||
Result:=i^.pVar;
|
||||
end;
|
||||
|
||||
////
|
||||
|
||||
function TEmitFetch.FetchUniform(src:PsrDataLayout;pType:PsrType):PsrNode;
|
||||
|
|
|
@ -11,7 +11,6 @@ uses
|
|||
srTypes,
|
||||
srConst,
|
||||
srReg,
|
||||
srLayout,
|
||||
srVariable,
|
||||
srOp,
|
||||
srCFGLabel,
|
||||
|
@ -49,21 +48,29 @@ type
|
|||
function OpStore(nLine, dst,src:PsrNode):PsrNode; override;
|
||||
//
|
||||
function OpLoad(pLine:PspirvOp;dst:PsrRegNode;src:PsrNode):PSpirvOp;
|
||||
function OpLoadTo(nLine:PspirvOp;pType:PsrType;src:PsrNode):PsrRegNode;
|
||||
//
|
||||
function OpExtract(pLine:PspirvOp;dst,src:PsrRegNode;id:DWORD):PSpirvOp;
|
||||
function OpConstruct(pLine:PspirvOp;dst:PsrRegNode):PSpirvOp;
|
||||
function OpAccessChain(pLine:PspirvOp;vType:PsrType;dst:PsrChain;src:PsrVariable):PSpirvOp;
|
||||
function OpAccessChain(pLine:PspirvOp;vType:PsrType;dst:PsrNode;src:PsrVariable):PSpirvOp;
|
||||
function OpAccessChainTo(pLine:PspirvOp;vType:PsrType;src:PsrVariable;idx0:PsrNode):PsrNode;
|
||||
function OpCondMerge(pLine,pLabel:PspirvOp):PSpirvOp;
|
||||
function OpLoopMerge(pLine,pLabel0,pLabel1:PspirvOp):PSpirvOp;
|
||||
function OpBranch(pLine,pLabel:PspirvOp):PSpirvOp;
|
||||
function OpBranchCond(pLine,pLabel0,pLabel1:PspirvOp;src:PsrRegNode):PSpirvOp;
|
||||
function OpReturnValue(pLine:PspirvOp;src:PsrRegNode):PSpirvOp;
|
||||
//
|
||||
function OpReturn(pLine:PspirvOp):PSpirvOp;
|
||||
function OpFunctionEnd(pLine:PspirvOp):PSpirvOp;
|
||||
function OpEmitVertex(pLine:PspirvOp):PSpirvOp;
|
||||
function OpEndPrimitive(pLine:PspirvOp):PSpirvOp;
|
||||
//
|
||||
procedure OpFmaF32(dst:PsrRegSlot;src0,src1,src2:PsrRegNode);
|
||||
procedure OpFmaI32(dst:PsrRegSlot;src0,src1,src2:PsrRegNode);
|
||||
procedure OpFmaU32(dst:PsrRegSlot;src0,src1,src2:PsrRegNode);
|
||||
//
|
||||
procedure OpSelect(dst:PsrRegSlot;src0,src1,cond:PsrRegNode);
|
||||
function OpSelectTo(src0,src1,cond:PsrRegNode):PsrRegNode;
|
||||
//
|
||||
procedure OpIAddCar(pLine:PspirvOp;dst,car,src0,src1:PsrRegNode);
|
||||
procedure OpIAddExt(dst,car:PsrRegSlot;src0,src1:PsrRegNode);
|
||||
|
@ -117,6 +124,7 @@ type
|
|||
function OpIMulTo(src0:PsrRegNode;src1:QWORD;ppLine:PPspirvOp=nil):PsrRegNode;
|
||||
function OpIDivTo(src0,src1:PsrRegNode;ppLine:PPspirvOp=nil):PsrRegNode;
|
||||
function OpIDivTo(src0:PsrRegNode;src1:QWORD;ppLine:PPspirvOp=nil):PsrRegNode;
|
||||
function OpIModTo(src0,src1:PsrRegNode;ppLine:PPspirvOp=nil):PsrRegNode;
|
||||
//
|
||||
function OpFAddTo(src0,src1:PsrRegNode;ppLine:PPspirvOp=nil):PsrRegNode;
|
||||
function OpFSubTo(src0,src1:PsrRegNode;ppLine:PPspirvOp=nil):PsrRegNode;
|
||||
|
@ -420,6 +428,13 @@ begin
|
|||
Result:=PSpirvOp(OpLoad(pLine,dtype,dst,src));
|
||||
end;
|
||||
|
||||
function TEmitOp.OpLoadTo(nLine:PspirvOp;pType:PsrType;src:PsrNode):PsrRegNode;
|
||||
begin
|
||||
Result:=NewReg(pType^.dtype);
|
||||
//
|
||||
OpLoad(line,pType,Result,src);
|
||||
end;
|
||||
|
||||
function TEmitOp.OpExtract(pLine:PspirvOp;dst,src:PsrRegNode;id:DWORD):PSpirvOp;
|
||||
Var
|
||||
node:PSpirvOp;
|
||||
|
@ -445,7 +460,7 @@ begin
|
|||
//child add later
|
||||
end;
|
||||
|
||||
function TEmitOp.OpAccessChain(pLine:PspirvOp;vType:PsrType;dst:PsrChain;src:PsrVariable):PSpirvOp;
|
||||
function TEmitOp.OpAccessChain(pLine:PspirvOp;vType:PsrType;dst:PsrNode;src:PsrVariable):PSpirvOp;
|
||||
Var
|
||||
node:PSpirvOp;
|
||||
begin
|
||||
|
@ -459,6 +474,16 @@ begin
|
|||
//index add later
|
||||
end;
|
||||
|
||||
function TEmitOp.OpAccessChainTo(pLine:PspirvOp;vType:PsrType;src:PsrVariable;idx0:PsrNode):PsrNode;
|
||||
Var
|
||||
node:PSpirvOp;
|
||||
begin
|
||||
Result:=NewRefNode;
|
||||
//
|
||||
node:=OpAccessChain(line,vType,Result,src);
|
||||
node^.AddParam(idx0);
|
||||
end;
|
||||
|
||||
function TEmitOp.OpCondMerge(pLine,pLabel:PspirvOp):PSpirvOp;
|
||||
Var
|
||||
node:PSpirvOp;
|
||||
|
@ -511,6 +536,28 @@ end;
|
|||
|
||||
//
|
||||
|
||||
function TEmitOp.OpReturn(pLine:PspirvOp):PSpirvOp;
|
||||
begin
|
||||
Result:=AddSpirvOp(pLine,Op.OpReturn);
|
||||
end;
|
||||
|
||||
function TEmitOp.OpFunctionEnd(pLine:PspirvOp):PSpirvOp;
|
||||
begin
|
||||
Result:=AddSpirvOp(pLine,Op.OpFunctionEnd);
|
||||
end;
|
||||
|
||||
function TEmitOp.OpEmitVertex(pLine:PspirvOp):PSpirvOp;
|
||||
begin
|
||||
Result:=AddSpirvOp(pLine,Op.OpEmitVertex);
|
||||
end;
|
||||
|
||||
function TEmitOp.OpEndPrimitive(pLine:PspirvOp):PSpirvOp;
|
||||
begin
|
||||
Result:=AddSpirvOp(pLine,Op.OpEndPrimitive);
|
||||
end;
|
||||
|
||||
//
|
||||
|
||||
procedure TEmitOp.OpFmaF32(dst:PsrRegSlot;src0,src1,src2:PsrRegNode);
|
||||
begin
|
||||
//vdst = vsrc0.f * vsrc1.f + vdst.f -> fma
|
||||
|
@ -549,6 +596,13 @@ begin
|
|||
Op3(Op.OpSelect,LazyType2(src0^.dtype,src1^.dtype),dst,cond,src1,src0);
|
||||
end;
|
||||
|
||||
function TEmitOp.OpSelectTo(src0,src1,cond:PsrRegNode):PsrRegNode;
|
||||
begin
|
||||
Result:=NewReg(LazyType2(src0^.dtype,src1^.dtype));
|
||||
//
|
||||
_Op3(line,Op.OpSelect,Result,cond,src1,src0);
|
||||
end;
|
||||
|
||||
procedure TEmitOp.OpIAddCar(pLine:PspirvOp;dst,car,src0,src1:PsrRegNode);
|
||||
Var
|
||||
node:PSpirvOp;
|
||||
|
@ -1150,6 +1204,20 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
function TEmitOp.OpIModTo(src0,src1:PsrRegNode;ppLine:PPspirvOp=nil):PsrRegNode;
|
||||
begin
|
||||
if (src1=nil) then Exit(src0);
|
||||
|
||||
Result:=NewReg(src0^.dtype);
|
||||
if (src0^.dtype.Sign<>0) then
|
||||
begin
|
||||
_set_line(ppLine,_Op2(_get_line(ppLine),Op.OpSMod,Result,src0,src1));
|
||||
end else
|
||||
begin
|
||||
_set_line(ppLine,_Op2(_get_line(ppLine),Op.OpUMod,Result,src0,src1));
|
||||
end;
|
||||
end;
|
||||
|
||||
//
|
||||
|
||||
function TEmitOp.OpFAddTo(src0,src1:PsrRegNode;ppLine:PPspirvOp=nil):PsrRegNode;
|
||||
|
|
|
@ -11,6 +11,7 @@ uses
|
|||
ginodes,
|
||||
srNode,
|
||||
srType,
|
||||
srTypes,
|
||||
srReg,
|
||||
srOp,
|
||||
srConst,
|
||||
|
@ -59,7 +60,9 @@ type
|
|||
itSampleId,
|
||||
itLayer,
|
||||
|
||||
itSubgroupLocalInvocationId
|
||||
itSubgroupLocalInvocationId,
|
||||
|
||||
itPosition
|
||||
);
|
||||
|
||||
ntInput=class(ntDescriptor)
|
||||
|
@ -95,6 +98,7 @@ type
|
|||
Procedure Init(Emit:TCustomEmit); inline;
|
||||
function Search(itype:TpsslInputType;id:Byte):PsrInput;
|
||||
function Fetch(rtype:TsrDataType;itype:TpsslInputType;id:Byte):PsrInput;
|
||||
function Fetch(pType:PsrType;itype:TpsslInputType;id:Byte):PsrInput;
|
||||
Function First:PsrInput;
|
||||
Function Next(node:PsrInput):PsrInput;
|
||||
procedure Test;
|
||||
|
@ -149,6 +153,15 @@ begin
|
|||
end;
|
||||
|
||||
function TsrInputList.Fetch(rtype:TsrDataType;itype:TpsslInputType;id:Byte):PsrInput;
|
||||
var
|
||||
pTypeList:PsrTypeList;
|
||||
begin
|
||||
pTypeList:=FEmit.GetTypeList;
|
||||
//
|
||||
Result:=Fetch(pTypeList^.Fetch(rtype),itype,id);
|
||||
end;
|
||||
|
||||
function TsrInputList.Fetch(pType:PsrType;itype:TpsslInputType;id:Byte):PsrInput;
|
||||
var
|
||||
node:TsrInput;
|
||||
begin
|
||||
|
@ -162,7 +175,7 @@ begin
|
|||
Result:=FEmit.Alloc(SizeOf(TsrInput));
|
||||
Move(node,Result^,SizeOf(TsrInput));
|
||||
//
|
||||
Result^.InitType(rtype,FEmit);
|
||||
Result^.pType:=pType;
|
||||
Result^.InitVar(FEmit);
|
||||
//
|
||||
FNTree.Insert(Result);
|
||||
|
@ -300,6 +313,11 @@ begin
|
|||
//
|
||||
end;
|
||||
|
||||
itPosition:
|
||||
begin
|
||||
pDecorateList^.OpDecorate(pVar,Decoration.BuiltIn,BuiltIn.Position);
|
||||
end;
|
||||
|
||||
else
|
||||
Assert(false,'AllocBinding:'+GetEnumName(TypeInfo(TpsslInputType),ord(node^.key.itype)));
|
||||
end;
|
||||
|
|
|
@ -38,6 +38,13 @@ type
|
|||
x,y,z:DWORD;
|
||||
end;
|
||||
|
||||
TGeometryInfo=record
|
||||
outputVertCount:DWORD; //4
|
||||
invocationCount:DWORD; //1
|
||||
InputMode :DWORD; //Triangles
|
||||
OutputMode :DWORD; //OutputTriangleStrip
|
||||
end;
|
||||
|
||||
PPSInputCntl=^TPSInputCntl;
|
||||
TPSInputCntl=packed record
|
||||
OFFSET :Byte;
|
||||
|
@ -51,6 +58,7 @@ type
|
|||
FEarlyFragmentTests:Boolean;
|
||||
FPSInputCntl:array[0..31] of TPSInputCntl;
|
||||
FLocalSize:TLocalSize;
|
||||
FGeometryInfo:TGeometryInfo;
|
||||
Config:TsrConfig;
|
||||
//
|
||||
FSPI:TSPI;
|
||||
|
|
|
@ -510,7 +510,7 @@ begin
|
|||
Result:=False;
|
||||
if not can_clear then Exit;
|
||||
|
||||
Assert(read_count=0);
|
||||
Assert(read_count=0,IntToStr(OpId));
|
||||
|
||||
if is_write_op(OpId) then
|
||||
begin
|
||||
|
|
|
@ -144,6 +144,7 @@ begin
|
|||
if (FHandle<>VK_NULL_HANDLE) then
|
||||
begin
|
||||
vkDestroyBuffer(Device.FHandle,FHandle,nil);
|
||||
FHandle:=VK_NULL_HANDLE;
|
||||
end;
|
||||
//
|
||||
UnBindMem(True);
|
||||
|
|
|
@ -189,7 +189,8 @@ type
|
|||
|
||||
FRender:TvRenderPassBeginInfo;
|
||||
|
||||
Femulate_primtype:Integer;
|
||||
Femulate_primtype:SmallInt;
|
||||
Fshader_primtype :SmallInt;
|
||||
FinstanceCount:DWORD;
|
||||
FINDEX_TYPE:TVkIndexType;
|
||||
|
||||
|
@ -423,6 +424,7 @@ begin
|
|||
end;
|
||||
|
||||
Femulate_primtype:=GP.Key.emulate_primtype;
|
||||
Fshader_primtype :=GP.Key.shader_primtype;
|
||||
|
||||
BindPipeline(BP_GRAPHICS,GP.FHandle);
|
||||
BindLayout (BP_GRAPHICS,GP.Key.FShaderGroup.FLayout);
|
||||
|
@ -1541,6 +1543,8 @@ begin
|
|||
end;
|
||||
DI_PT_QUADLIST:
|
||||
begin
|
||||
InsertLabel('DI_PT_QUADLIST');
|
||||
|
||||
Assert(FinstanceCount<=1,'instance DI_PT_QUADLIST');
|
||||
Assert(indexOffset=0,'OFFSET DI_PT_QUADLIST');
|
||||
h:=indexCount div 4;
|
||||
|
@ -1590,6 +1594,7 @@ begin
|
|||
Case Femulate_primtype of
|
||||
0:
|
||||
begin
|
||||
Inc(cmd_count);
|
||||
vkCmdDraw(
|
||||
FCmdbuf,
|
||||
indexCount, //vertexCount
|
||||
|
@ -1598,8 +1603,10 @@ begin
|
|||
0); //firstInstance
|
||||
end;
|
||||
|
||||
DI_PT_RECTLIST :
|
||||
DI_PT_RECTLIST:
|
||||
begin
|
||||
InsertLabel('DI_PT_RECTLIST');
|
||||
|
||||
Assert(FinstanceCount<=1,'instance DI_PT_RECTLIST');
|
||||
{
|
||||
VK_EXT_primitive_topology_list_restart ???
|
||||
|
@ -1610,23 +1617,41 @@ begin
|
|||
//0 1 2
|
||||
//0 2 3
|
||||
|
||||
h:=indexCount div 3;
|
||||
if (h>0) then h:=h-1;
|
||||
For i:=0 to h do
|
||||
if (Fshader_primtype=-1) then
|
||||
begin
|
||||
|
||||
h:=indexCount div 3;
|
||||
if (h>0) then h:=h-1;
|
||||
For i:=0 to h do
|
||||
begin
|
||||
Inc(cmd_count);
|
||||
vkCmdDraw(
|
||||
FCmdbuf,
|
||||
4, //vertexCount
|
||||
1, //instanceCount
|
||||
0, //firstVertex
|
||||
0); //firstInstance
|
||||
end;
|
||||
|
||||
end else
|
||||
begin
|
||||
//geom shader emulate
|
||||
|
||||
Inc(cmd_count);
|
||||
vkCmdDraw(
|
||||
FCmdbuf,
|
||||
4, //vertexCount
|
||||
1, //instanceCount
|
||||
0, //firstVertex
|
||||
0); //firstInstance
|
||||
FCmdbuf,
|
||||
indexCount, //vertexCount
|
||||
FinstanceCount, //instanceCount
|
||||
0, //firstVertex
|
||||
0); //firstInstance
|
||||
end;
|
||||
|
||||
end;
|
||||
//DI_PT_LINELOOP :;
|
||||
DI_PT_QUADLIST:
|
||||
begin
|
||||
InsertLabel('DI_PT_QUADLIST');
|
||||
|
||||
Assert(FinstanceCount<=1,'instance DI_PT_QUADLIST');
|
||||
h:=indexCount div 4;
|
||||
if (h>0) then h:=h-1;
|
||||
|
|
|
@ -823,6 +823,9 @@ begin
|
|||
set_tiling_cbs(kTileModeDepth_2dThin_64 ,0,@Load_Linear,@Writeback_Linear,@GetLinearAlignSize); //@load_clear;
|
||||
set_tiling_cbs(kTileModeDepth_2dThin_64 ,1,@Load_Linear,@Writeback_Linear,@GetLinearAlignSize); //@load_clear;
|
||||
|
||||
set_tiling_cbs(kTileModeThin_2dThin ,0,@Load_Linear,@Writeback_Linear,@GetLinearAlignSize); //@load_clear;
|
||||
set_tiling_cbs(kTileModeThin_2dThin ,1,@Load_Linear,@Writeback_Linear,@GetLinearAlignSize); //@load_clear;
|
||||
|
||||
//
|
||||
set_tiling_cbs(kTileModeDepth_1dThin ,0,@load_1dThin,nil,@Get1dThinSize);
|
||||
set_tiling_cbs(kTileModeDepth_1dThin ,1,@load_1dThin,nil,@Get1dThinSize);
|
||||
|
@ -838,6 +841,47 @@ begin
|
|||
set_tiling_cbs(kTileModeDisplay_LinearAligned,1,@Load_Linear,@Writeback_Linear,@GetLinearAlignSize);
|
||||
end;
|
||||
|
||||
function get_tiling_name(i:Byte):RawByteString;
|
||||
begin
|
||||
case i of
|
||||
// Depth modes (for depth buffers)
|
||||
kTileModeDepth_2dThin_64 :Result:='Depth_2dThin_64';
|
||||
kTileModeDepth_2dThin_128 :Result:='Depth_2dThin_128';
|
||||
kTileModeDepth_2dThin_256 :Result:='Depth_2dThin_256';
|
||||
kTileModeDepth_2dThin_512 :Result:='Depth_2dThin_512';
|
||||
kTileModeDepth_2dThin_1K :Result:='Depth_2dThin_1K';
|
||||
kTileModeDepth_1dThin :Result:='Depth_1dThin';
|
||||
kTileModeDepth_2dThinPrt_256:Result:='Depth_2dThinPrt_256';
|
||||
kTileModeDepth_2dThinPrt_1K :Result:='Depth_2dThinPrt_1K';
|
||||
// Display modes
|
||||
kTileModeDisplay_LinearAligned:Result:='LinearAligned';
|
||||
kTileModeDisplay_1dThin :Result:='Display_1dThin';
|
||||
kTileModeDisplay_2dThin :Result:='Display_2dThin';
|
||||
kTileModeDisplay_ThinPrt :Result:='Display_ThinPrt';
|
||||
kTileModeDisplay_2dThinPrt :Result:='Display_2dThinPrt';
|
||||
// Thin modes (for non-displayable 1D/2D/3D
|
||||
kTileModeThin_1dThin :Result:='Thin_1dThin';
|
||||
kTileModeThin_2dThin :Result:='Thin_2dThin';
|
||||
kTileModeThin_3dThin :Result:='Thin_3dThin';
|
||||
kTileModeThin_ThinPrt :Result:='Thin_ThinPrt';
|
||||
kTileModeThin_2dThinPrt:Result:='Thin_2dThinPrt';
|
||||
kTileModeThin_3dThinPrt:Result:='Thin_3dThinPrt';
|
||||
// Thick modes (for 3D textures)
|
||||
kTileModeThick_1dThick :Result:='Thick_1dThick';
|
||||
kTileModeThick_2dThick :Result:='Thick_2dThick';
|
||||
kTileModeThick_3dThick :Result:='Thick_3dThick';
|
||||
kTileModeThick_ThickPrt :Result:='Thick_ThickPrt';
|
||||
kTileModeThick_2dThickPrt:Result:='Thick_2dThickPrt';
|
||||
kTileModeThick_3dThickPrt:Result:='Thick_3dThickPrt';
|
||||
kTileModeThick_2dXThick :Result:='Thick_2dXThick';
|
||||
kTileModeThick_3dXThick :Result:='Thick_3dXThick';
|
||||
// Hugely inefficient linear display mode -
|
||||
kTileModeDisplay_LinearGeneral:Result:='LinearGeneral';
|
||||
else
|
||||
Result:=IntToStr(i);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure pm4_load_from(cmd:TvCustomCmdBuffer;image:TvCustomImage2;IMAGE_USAGE:Byte);
|
||||
var
|
||||
cb:t_load_from_cb;
|
||||
|
@ -862,8 +906,8 @@ begin
|
|||
|
||||
if (cb=nil) then
|
||||
begin
|
||||
Writeln(stderr,'tiling:'+IntToStr(image.key.params.tiling.idx)+' alt:'+IntToStr(image.key.params.tiling.alt));
|
||||
Assert (false ,'tiling:'+IntToStr(image.key.params.tiling.idx)+' alt:'+IntToStr(image.key.params.tiling.alt));
|
||||
Writeln(stderr,'tiling:'+get_tiling_name(image.key.params.tiling.idx)+' alt:'+IntToStr(image.key.params.tiling.alt));
|
||||
Assert (false ,'tiling:'+get_tiling_name(image.key.params.tiling.idx)+' alt:'+IntToStr(image.key.params.tiling.alt));
|
||||
end;
|
||||
|
||||
cmd.EndRenderPass;
|
||||
|
@ -900,8 +944,8 @@ begin
|
|||
|
||||
if (cb=nil) then
|
||||
begin
|
||||
Writeln(stderr,'tiling:'+IntToStr(image.key.params.tiling.idx)+' alt:'+IntToStr(image.key.params.tiling.alt));
|
||||
Assert (false ,'tiling:'+IntToStr(image.key.params.tiling.idx)+' alt:'+IntToStr(image.key.params.tiling.alt));
|
||||
Writeln(stderr,'tiling:'+get_tiling_name(image.key.params.tiling.idx)+' alt:'+IntToStr(image.key.params.tiling.alt));
|
||||
Assert (false ,'tiling:'+get_tiling_name(image.key.params.tiling.idx)+' alt:'+IntToStr(image.key.params.tiling.alt));
|
||||
end;
|
||||
|
||||
cmd.EndRenderPass;
|
||||
|
@ -928,8 +972,8 @@ begin
|
|||
|
||||
if (cb=nil) then
|
||||
begin
|
||||
Writeln(stderr,'tiling:'+IntToStr(key.params.tiling.idx)+' alt:'+IntToStr(key.params.tiling.alt));
|
||||
Assert (false ,'tiling:'+IntToStr(key.params.tiling.idx)+' alt:'+IntToStr(key.params.tiling.alt));
|
||||
Writeln(stderr,'tiling:'+get_tiling_name(key.params.tiling.idx)+' alt:'+IntToStr(key.params.tiling.alt));
|
||||
Assert (false ,'tiling:'+get_tiling_name(key.params.tiling.idx)+' alt:'+IntToStr(key.params.tiling.alt));
|
||||
end;
|
||||
|
||||
Result:=cb(key);
|
||||
|
|
|
@ -49,11 +49,12 @@ type
|
|||
|
||||
viewportCount :Byte;
|
||||
provokingVertex :Byte;
|
||||
emulate_primtype:Byte;
|
||||
emulate_primtype:ShortInt;
|
||||
shader_primtype :ShortInt;
|
||||
|
||||
Procedure Clear;
|
||||
Procedure SetVertexInput(const FAttrBuilder:TvAttrBuilder);
|
||||
Procedure SetPrimType(t:TVkPrimitiveTopology);
|
||||
Procedure SetPrimType(t,s:Integer);
|
||||
Procedure SetPrimReset(enable:TVkBool32);
|
||||
Procedure SetProvoking(t:TVkProvokingVertexModeEXT);
|
||||
Procedure AddVPort(const V:TVkViewport;const S:TVkRect2D);
|
||||
|
@ -166,19 +167,28 @@ begin
|
|||
vertexInputInfo.VertexAttributeDescriptions :=FAttrBuilder.FAttrDescs;
|
||||
end;
|
||||
|
||||
Procedure TvGraphicsPipelineKey.SetPrimType(t:TVkPrimitiveTopology);
|
||||
Procedure TvGraphicsPipelineKey.SetPrimType(t,s:Integer);
|
||||
begin
|
||||
Case ord(t) of
|
||||
ord(VK_PRIMITIVE_TOPOLOGY_POINT_LIST)..ord(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY):
|
||||
begin
|
||||
inputAssembly.topology:=t;
|
||||
inputAssembly.topology:=TVkPrimitiveTopology(t);
|
||||
emulate_primtype:=0;
|
||||
shader_primtype :=-1;
|
||||
end;
|
||||
|
||||
DI_PT_RECTLIST:
|
||||
begin
|
||||
inputAssembly.topology:=VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
|
||||
emulate_primtype:=ord(t);
|
||||
if (s<>-1) then
|
||||
begin
|
||||
inputAssembly.topology:=TVkPrimitiveTopology(s);
|
||||
shader_primtype:=s;
|
||||
end else
|
||||
begin
|
||||
inputAssembly.topology:=VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
|
||||
shader_primtype :=-1;
|
||||
end;
|
||||
end;
|
||||
DI_PT_LINELOOP ,
|
||||
DI_PT_QUADLIST ,
|
||||
|
@ -187,6 +197,7 @@ begin
|
|||
begin
|
||||
inputAssembly.topology:=VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN;
|
||||
emulate_primtype:=ord(t);
|
||||
shader_primtype :=-1;
|
||||
end;
|
||||
|
||||
end;
|
||||
|
|
|
@ -0,0 +1,185 @@
|
|||
unit vRectGS;
|
||||
|
||||
{$mode ObjFPC}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes,
|
||||
|
||||
Vulkan,
|
||||
|
||||
spirv,
|
||||
srNode,
|
||||
srType,
|
||||
srTypes,
|
||||
srReg,
|
||||
srVariable,
|
||||
srOutput,
|
||||
|
||||
SprvEmit;
|
||||
|
||||
function CompileRectangleGeometryShader():TMemoryStream;
|
||||
|
||||
implementation
|
||||
|
||||
function interpolate(SprvEmit:TSprvEmit;
|
||||
rtype :TsrDataType;
|
||||
barycentric,inputs:PPsrRegNode):PsrRegNode;
|
||||
var
|
||||
tmp:array[0..2] of PsrRegNode;
|
||||
//
|
||||
i:Byte;
|
||||
begin
|
||||
For i:=0 to 2 do
|
||||
begin
|
||||
tmp[i]:=SprvEmit.NewReg(rtype);
|
||||
//
|
||||
SprvEmit._Op2(SprvEmit.line,Op.OpVectorTimesScalar,tmp[i],inputs[i],barycentric[i]);
|
||||
end;
|
||||
//
|
||||
Result:=SprvEmit.OpFAddTo(tmp[0],tmp[1]);
|
||||
Result:=SprvEmit.OpFAddTo(Result,tmp[2]);
|
||||
end;
|
||||
|
||||
function CompileRectangleGeometryShader():TMemoryStream;
|
||||
var
|
||||
SprvEmit:TSprvEmit;
|
||||
//
|
||||
pVec4f :PsrType;
|
||||
InputPos :PsrVariable;
|
||||
OutputPos :PsrVariable;
|
||||
pChain :PsrNode;
|
||||
UintId :array[0..3] of PsrRegNode;
|
||||
Positions :array[0..3] of PsrRegNode;
|
||||
positionsX :array[0..2] of PsrRegNode;
|
||||
positionsY :array[0..2] of PsrRegNode;
|
||||
CoordEqualX:array[0..2] of PsrRegNode;
|
||||
CoordEqualY:array[0..2] of PsrRegNode;
|
||||
EdgeVertex :array[0..2] of PsrRegNode;
|
||||
barycentric:array[0..2] of PsrRegNode;
|
||||
xyEqual :PsrRegNode;
|
||||
yxEqual :PsrRegNode;
|
||||
pOneId :PsrRegNode;
|
||||
pMinusOne :PsrRegNode;
|
||||
pIndex :PsrRegNode;
|
||||
//
|
||||
i:Byte;
|
||||
begin
|
||||
Result:=nil;
|
||||
SprvEmit:=TSprvEmit.Create;
|
||||
|
||||
SprvEmit.InitCustomGs();
|
||||
|
||||
pVec4f :=SprvEmit.TypeList.Fetch(dtVec4f);
|
||||
|
||||
InputPos :=SprvEmit.AddPositionsInput(3);
|
||||
OutputPos:=SprvEmit.FetchOutput(etPos0,dtVec4f);
|
||||
|
||||
//gen const id
|
||||
For i:=0 to 3 do
|
||||
begin
|
||||
UintId[i]:=SprvEmit.NewReg_i(dtUint32,i);
|
||||
end;
|
||||
|
||||
//load positions
|
||||
For i:=0 to 2 do
|
||||
begin
|
||||
pChain:=SprvEmit.OpAccessChainTo(SprvEmit.line,pVec4f,InputPos,UintId[i]);
|
||||
//
|
||||
Positions[i]:=SprvEmit.OpLoadTo(SprvEmit.line,pVec4f,pChain);
|
||||
end;
|
||||
|
||||
//extract
|
||||
For i:=0 to 2 do
|
||||
begin
|
||||
positionsX[i]:=SprvEmit.NewReg(dtFloat32);
|
||||
positionsY[i]:=SprvEmit.NewReg(dtFloat32);
|
||||
//
|
||||
SprvEmit.OpExtract(SprvEmit.line,positionsX[i],Positions[i],0);
|
||||
SprvEmit.OpExtract(SprvEmit.line,positionsY[i],Positions[i],1);
|
||||
end;
|
||||
|
||||
//compare
|
||||
For i:=0 to 2 do
|
||||
begin
|
||||
CoordEqualX[i]:=SprvEmit.NewReg(dtBool);
|
||||
CoordEqualY[i]:=SprvEmit.NewReg(dtBool);
|
||||
//
|
||||
SprvEmit._Op2(SprvEmit.line,Op.OpFOrdEqual,CoordEqualX[i],positionsX[i],positionsX[(i + 1) mod 3]);
|
||||
SprvEmit._Op2(SprvEmit.line,Op.OpFOrdEqual,CoordEqualY[i],positionsY[i],positionsY[(i + 1) mod 3]);
|
||||
end;
|
||||
|
||||
pOneId :=SprvEmit.NewReg_s(dtFloat32, 1);
|
||||
pMinusOne:=SprvEmit.NewReg_s(dtFloat32,-1);
|
||||
|
||||
//calc barycentric
|
||||
For i:=0 to 2 do
|
||||
begin
|
||||
xyEqual:=SprvEmit.OpAndTo(CoordEqualX[i], CoordEqualY[(i + 2) mod 3]);
|
||||
yxEqual:=SprvEmit.OpAndTo(CoordEqualY[i], CoordEqualX[(i + 2) mod 3]);
|
||||
//
|
||||
EdgeVertex[i]:=SprvEmit.OpOrTo(xyEqual,yxEqual);
|
||||
//
|
||||
barycentric[i]:=SprvEmit.OpSelectTo(pOneId,pMinusOne,EdgeVertex[i]);
|
||||
end;
|
||||
|
||||
//calc last pos
|
||||
Positions[3]:=interpolate(SprvEmit,dtVec4f,@barycentric,@Positions);
|
||||
|
||||
//select first index
|
||||
pIndex:=SprvEmit.OpSelectTo(UintId[0], UintId[1], EdgeVertex[1]);
|
||||
pIndex:=SprvEmit.OpSelectTo(pIndex , UintId[2], EdgeVertex[2]);
|
||||
|
||||
//Send vertex by index
|
||||
For i:=0 to 2 do
|
||||
begin
|
||||
pChain:=SprvEmit.OpAccessChainTo(SprvEmit.line,pVec4f,InputPos,pIndex);
|
||||
//
|
||||
Positions[i]:=SprvEmit.OpLoadTo(SprvEmit.line,pVec4f,pChain);
|
||||
//
|
||||
|
||||
SprvEmit.OpStore(SprvEmit.line,OutputPos,Positions[i]);
|
||||
|
||||
//emit input attr
|
||||
|
||||
//end vertex
|
||||
SprvEmit.OpEmitVertex(SprvEmit.line);
|
||||
|
||||
if (i<>2) then
|
||||
begin
|
||||
//next index
|
||||
pIndex:=SprvEmit.OpIAddTo(pIndex,UintId[1]);
|
||||
pIndex:=SprvEmit.OpIModTo(pIndex,UintId[3]);
|
||||
end;
|
||||
end; //for
|
||||
|
||||
//send last vertex
|
||||
SprvEmit.OpStore(SprvEmit.line,OutputPos,Positions[3]);
|
||||
|
||||
//emit input attr
|
||||
|
||||
//end vertex
|
||||
SprvEmit.OpEmitVertex(SprvEmit.line);
|
||||
|
||||
//end prim
|
||||
SprvEmit.OpEndPrimitive(SprvEmit.line);
|
||||
|
||||
//end function
|
||||
SprvEmit.OpReturn(SprvEmit.line);
|
||||
SprvEmit.OpFunctionEnd(SprvEmit.line);
|
||||
|
||||
//ending stage
|
||||
SprvEmit.PostStage;
|
||||
SprvEmit.AllocStage;
|
||||
|
||||
//SprvEmit.Print;
|
||||
|
||||
Result:=TMemoryStream.Create;
|
||||
SprvEmit.SaveToStream(Result);
|
||||
|
||||
SprvEmit.Free;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
|
@ -108,7 +108,7 @@ type
|
|||
Function GET_MULTISAMPLE:TVkPipelineMultisampleStateCreateInfo;
|
||||
|
||||
function GET_PRIM_RESET:TVkBool32;
|
||||
function GET_PRIM_TYPE :TVkPrimitiveTopology;
|
||||
function GET_PRIM_TYPE :Integer;
|
||||
function GET_INDEX_TYPE:TVkIndexType;
|
||||
|
||||
function get_reg(i:word):DWORD;
|
||||
|
@ -1483,26 +1483,26 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
function TGPU_REGS.GET_PRIM_TYPE:TVkPrimitiveTopology;
|
||||
function TGPU_REGS.GET_PRIM_TYPE:Integer;
|
||||
begin
|
||||
case UC_REG^.VGT_PRIMITIVE_TYPE.PRIM_TYPE of
|
||||
DI_PT_POINTLIST :Result:=VK_PRIMITIVE_TOPOLOGY_POINT_LIST ;
|
||||
DI_PT_LINELIST :Result:=VK_PRIMITIVE_TOPOLOGY_LINE_LIST ;
|
||||
DI_PT_LINESTRIP :Result:=VK_PRIMITIVE_TOPOLOGY_LINE_STRIP ;
|
||||
DI_PT_TRILIST :Result:=VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST ;
|
||||
DI_PT_TRIFAN :Result:=VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN ;
|
||||
DI_PT_TRISTRIP :Result:=VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP ;
|
||||
DI_PT_PATCH :Result:=VK_PRIMITIVE_TOPOLOGY_PATCH_LIST ;
|
||||
DI_PT_LINELIST_ADJ :Result:=VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY ;
|
||||
DI_PT_LINESTRIP_ADJ:Result:=VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY ;
|
||||
DI_PT_TRILIST_ADJ :Result:=VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY ;
|
||||
DI_PT_TRISTRIP_ADJ :Result:=VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY;
|
||||
DI_PT_POINTLIST :Result:=ord(VK_PRIMITIVE_TOPOLOGY_POINT_LIST) ;
|
||||
DI_PT_LINELIST :Result:=ord(VK_PRIMITIVE_TOPOLOGY_LINE_LIST) ;
|
||||
DI_PT_LINESTRIP :Result:=ord(VK_PRIMITIVE_TOPOLOGY_LINE_STRIP) ;
|
||||
DI_PT_TRILIST :Result:=ord(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST) ;
|
||||
DI_PT_TRIFAN :Result:=ord(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN) ;
|
||||
DI_PT_TRISTRIP :Result:=ord(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP) ;
|
||||
DI_PT_PATCH :Result:=ord(VK_PRIMITIVE_TOPOLOGY_PATCH_LIST) ;
|
||||
DI_PT_LINELIST_ADJ :Result:=ord(VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY) ;
|
||||
DI_PT_LINESTRIP_ADJ:Result:=ord(VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY) ;
|
||||
DI_PT_TRILIST_ADJ :Result:=ord(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY) ;
|
||||
DI_PT_TRISTRIP_ADJ :Result:=ord(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY);
|
||||
|
||||
DI_PT_RECTLIST ,
|
||||
DI_PT_LINELOOP ,
|
||||
DI_PT_QUADLIST ,
|
||||
DI_PT_QUADSTRIP ,
|
||||
DI_PT_POLYGON :Result:=TVkPrimitiveTopology(UC_REG^.VGT_PRIMITIVE_TYPE.PRIM_TYPE); //need to emulate
|
||||
DI_PT_POLYGON :Result:=UC_REG^.VGT_PRIMITIVE_TYPE.PRIM_TYPE; //need to emulate
|
||||
|
||||
else
|
||||
Assert(False,'unknow prim type:0x'+HexStr(UC_REG^.VGT_PRIMITIVE_TYPE.PRIM_TYPE,1));
|
||||
|
@ -1946,10 +1946,8 @@ begin
|
|||
Result.params.mipLevels:=PT^.last_level+1;
|
||||
end;
|
||||
|
||||
//Assert(Result.params.mipLevels=1,'TODO');
|
||||
//Result.params.mipLevels:=1; /////
|
||||
|
||||
Result.params.arrayLayers:=1;
|
||||
Result.params.pitch :=Result.params.width;
|
||||
|
||||
//TODO: Calculate padding by tilling mode
|
||||
Result.params.pad_width :=Result.params.width;
|
||||
|
|
|
@ -54,6 +54,7 @@ type
|
|||
procedure LoadFromStream(Stream:TStream);
|
||||
procedure LoadFromFile(const FileName:RawByteString);
|
||||
procedure LoadFromResource(const FileName:RawByteString);
|
||||
procedure SetObjectName(const name:RawByteString);
|
||||
end;
|
||||
|
||||
///
|
||||
|
@ -178,6 +179,11 @@ begin
|
|||
Stream.Free;
|
||||
end;
|
||||
|
||||
procedure TvShader.SetObjectName(const name:RawByteString);
|
||||
begin
|
||||
DebugReport.SetObjectName(VK_OBJECT_TYPE_SHADER_MODULE,FHandle,PChar(name));
|
||||
end;
|
||||
|
||||
type
|
||||
PSPIRVHeader=^TSPIRVHeader;
|
||||
TSPIRVHeader=packed record
|
||||
|
|
|
@ -109,6 +109,8 @@ type
|
|||
INPUT_CNTL :A_INPUT_CNTL;
|
||||
end;
|
||||
|
||||
FGeomRectList:TvShaderExt;
|
||||
|
||||
procedure ClearInfo; override;
|
||||
Destructor Destroy; override;
|
||||
function parser:CvShaderParser; override;
|
||||
|
@ -133,6 +135,8 @@ type
|
|||
Procedure SetInstance (VGPR_COMP_CNT:Byte;STEP_RATE_0,STEP_RATE_1:DWORD);
|
||||
Procedure SET_SHADER_CONTROL(const SHADER_CONTROL:TDB_SHADER_CONTROL);
|
||||
Procedure SET_INPUT_CNTL (const INPUT_CNTL:A_INPUT_CNTL;NUM_INTERP:Byte);
|
||||
function IsCSClearShader:Boolean;
|
||||
function IsVSRectListShader:Boolean;
|
||||
end;
|
||||
|
||||
TBufBindExt=packed record
|
||||
|
@ -179,6 +183,7 @@ type
|
|||
PvShadersKey=^TvShadersKey;
|
||||
TvShadersKey=object
|
||||
FShaders:AvShaderStage;
|
||||
FPrimtype:Integer;
|
||||
Procedure SetLSShader(Shader:TvShaderExt);
|
||||
Procedure SetHSShader(Shader:TvShaderExt);
|
||||
Procedure SetESShader(Shader:TvShaderExt);
|
||||
|
@ -253,6 +258,8 @@ type
|
|||
|
||||
function GetSharpByPatch(pUserData,pImmData:Pointer;const addr:ADataLayout):Pointer;
|
||||
|
||||
function IsClearDepthShaders(const FShaders:AvShaderStage):Boolean; inline;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
|
@ -772,6 +779,38 @@ begin
|
|||
Move(INPUT_CNTL,FParams.INPUT_CNTL,SizeOf(TSPI_PS_INPUT_CNTL_0)*NUM_INTERP);
|
||||
end;
|
||||
|
||||
function TvShaderExt.IsCSClearShader:Boolean;
|
||||
begin
|
||||
if (self=nil) then Exit(False);
|
||||
|
||||
Result:=(FHash_gcn=$7DCE68F83F66B337);
|
||||
end;
|
||||
|
||||
function TvShaderExt.IsVSRectListShader:Boolean;
|
||||
begin
|
||||
if (self=nil) then Exit(False);
|
||||
|
||||
Result:=(FHash_gcn=$00DF6E6331449451);
|
||||
end;
|
||||
|
||||
function IsClearDepthShaders(const FShaders:AvShaderStage):Boolean; inline;
|
||||
begin
|
||||
Result:=False;
|
||||
|
||||
if (FShaders[vShaderStageLs]=nil) and
|
||||
(FShaders[vShaderStageHs]=nil) and
|
||||
(FShaders[vShaderStageEs]=nil) and
|
||||
(FShaders[vShaderStageGs]=nil) and
|
||||
(FShaders[vShaderStageVs]<>nil) and
|
||||
(FShaders[vShaderStagePs]<>nil) and
|
||||
(FShaders[vShaderStageCs]=nil) then
|
||||
|
||||
if (FShaders[vShaderStageVs].FHash_gcn=QWORD($00DF6E6331449451)) and
|
||||
(FShaders[vShaderStagePs].FHash_gcn=QWORD($E9FF5D4699E5B9AD)) then
|
||||
begin
|
||||
Result:=True;
|
||||
end;
|
||||
end;
|
||||
|
||||
///
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ interface
|
|||
uses
|
||||
SysUtils,
|
||||
Classes,
|
||||
Vulkan,
|
||||
murmurhash,
|
||||
g23tree,
|
||||
ps4_pssl,
|
||||
|
@ -15,6 +16,7 @@ uses
|
|||
vRegs2Vulkan,
|
||||
shader_dump,
|
||||
|
||||
si_ci_vi_merged_enum,
|
||||
si_ci_vi_merged_registers,
|
||||
|
||||
vDevice,
|
||||
|
@ -91,6 +93,8 @@ function GetDumpSpvName(FStage:TvShaderStage;hash:QWORD):RawByteString;
|
|||
implementation
|
||||
|
||||
uses
|
||||
vRectGS,
|
||||
//
|
||||
kern_rwlock,
|
||||
kern_dmem;
|
||||
|
||||
|
@ -555,6 +559,11 @@ begin
|
|||
//set hash
|
||||
FShader.FHash_spv:=FHash_spv;
|
||||
|
||||
//setname
|
||||
FShader.SetObjectName(LowerCase(STAGE_NAME[FStage])+
|
||||
'_gcn:0x'+HexStr(FShader.FHash_gcn,16)+
|
||||
'_spv:0x'+HexStr(FShader.FHash_spv,16));
|
||||
|
||||
//free spv data
|
||||
M.Free;
|
||||
|
||||
|
@ -671,6 +680,43 @@ begin
|
|||
FShaderGroupSet.Unlock_wr;
|
||||
end;
|
||||
|
||||
procedure EmitShaderGroupExtension(var GPU_REGS:TGPU_REGS;F:PvShadersKey);
|
||||
Var
|
||||
M:TMemoryStream;
|
||||
VS:TvShaderExt;
|
||||
GS:TvShaderExt;
|
||||
begin
|
||||
VS:=F^.FShaders[vShaderStageVs];
|
||||
|
||||
if (VS<>nil) and
|
||||
(not VS.IsVSRectListShader) and
|
||||
(ord(GPU_REGS.GET_PRIM_TYPE)=DI_PT_RECTLIST) then
|
||||
begin
|
||||
Assert(F^.FShaders[vShaderStageGs]=nil,'Geometry shader is already present');
|
||||
|
||||
GS:=VS.FGeomRectList;
|
||||
|
||||
if (GS=nil) then
|
||||
begin
|
||||
M:=CompileRectangleGeometryShader();
|
||||
//M.SaveToFile('rect_geom.spv');
|
||||
|
||||
GS:=TvShaderExt.Create;
|
||||
GS.LoadFromStream(M);
|
||||
|
||||
GS.SetObjectName('GS_RECT');
|
||||
|
||||
M.Free;
|
||||
|
||||
VS.FGeomRectList:=GS;
|
||||
end;
|
||||
|
||||
F^.FShaders[vShaderStageGs]:=GS;
|
||||
F^.FPrimtype:=ord(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST);
|
||||
//
|
||||
end;
|
||||
end;
|
||||
|
||||
function FetchShaderGroupRT(var GPU_REGS:TGPU_REGS;pc:PPushConstAllocator):TvShaderGroup;
|
||||
var
|
||||
FShadersKey:TvShadersKey;
|
||||
|
@ -678,6 +724,7 @@ var
|
|||
FDescSetId:Integer;
|
||||
begin
|
||||
FShadersKey:=Default(TvShadersKey);
|
||||
FShadersKey.FPrimtype:=-1;
|
||||
|
||||
FDescSetId:=0;
|
||||
|
||||
|
@ -691,6 +738,8 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
EmitShaderGroupExtension(GPU_REGS,@FShadersKey);
|
||||
|
||||
Result:=FetchShaderGroup(@FShadersKey);
|
||||
end;
|
||||
|
||||
|
@ -699,6 +748,7 @@ var
|
|||
FShadersKey:TvShadersKey;
|
||||
begin
|
||||
FShadersKey:=Default(TvShadersKey);
|
||||
FShadersKey.FPrimtype:=-1;
|
||||
|
||||
FShadersKey.FShaders[vShaderStageCs]:=FetchShader(vShaderStageCs,0,GPU_REGS,pc);
|
||||
|
||||
|
|
Loading…
Reference in New Issue