diff --git a/chip/pm4_me.pas b/chip/pm4_me.pas
index 1cc48a36..c79fa5e6 100644
--- a/chip/pm4_me.pas
+++ b/chip/pm4_me.pas
@@ -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);
//
diff --git a/chip/pm4_stream.pas b/chip/pm4_stream.pas
index 27465550..9f94bbad 100644
--- a/chip/pm4_stream.pas
+++ b/chip/pm4_stream.pas
@@ -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;
diff --git a/fpPS4.lpi b/fpPS4.lpi
index 0c8b64f0..19ee25e7 100644
--- a/fpPS4.lpi
+++ b/fpPS4.lpi
@@ -1312,6 +1312,10 @@
+
+
+
+
diff --git a/spirv/SprvEmit.pas b/spirv/SprvEmit.pas
index 05e36059..48d99530 100644
--- a/spirv/SprvEmit.pas
+++ b/spirv/SprvEmit.pas
@@ -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;
diff --git a/spirv/emit_alloc.pas b/spirv/emit_alloc.pas
index ca3a0abc..544787bd 100644
--- a/spirv/emit_alloc.pas
+++ b/spirv/emit_alloc.pas
@@ -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;
diff --git a/spirv/emit_bin.pas b/spirv/emit_bin.pas
index 3cd7d29d..5a6f85a3 100644
--- a/spirv/emit_bin.pas
+++ b/spirv/emit_bin.pas
@@ -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)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);
diff --git a/spirv/emit_fetch.pas b/spirv/emit_fetch.pas
index 254f2382..98e7c9ee 100644
--- a/spirv/emit_fetch.pas
+++ b/spirv/emit_fetch.pas
@@ -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;
diff --git a/spirv/emit_op.pas b/spirv/emit_op.pas
index 72072a3e..320a3350 100644
--- a/spirv/emit_op.pas
+++ b/spirv/emit_op.pas
@@ -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;
diff --git a/spirv/srInput.pas b/spirv/srInput.pas
index 305ad0b5..a019d47e 100644
--- a/spirv/srInput.pas
+++ b/spirv/srInput.pas
@@ -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;
diff --git a/spirv/srInterface.pas b/spirv/srInterface.pas
index a6c4d224..83a97dbe 100644
--- a/spirv/srInterface.pas
+++ b/spirv/srInterface.pas
@@ -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;
diff --git a/spirv/srOp.pas b/spirv/srOp.pas
index 5d10e7c9..60b86aeb 100644
--- a/spirv/srOp.pas
+++ b/spirv/srOp.pas
@@ -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
diff --git a/vulkan/vBuffer.pas b/vulkan/vBuffer.pas
index 48c3e1bf..a02155fb 100644
--- a/vulkan/vBuffer.pas
+++ b/vulkan/vBuffer.pas
@@ -144,6 +144,7 @@ begin
if (FHandle<>VK_NULL_HANDLE) then
begin
vkDestroyBuffer(Device.FHandle,FHandle,nil);
+ FHandle:=VK_NULL_HANDLE;
end;
//
UnBindMem(True);
diff --git a/vulkan/vCmdBuffer.pas b/vulkan/vCmdBuffer.pas
index 629d171f..36a7ded0 100644
--- a/vulkan/vCmdBuffer.pas
+++ b/vulkan/vCmdBuffer.pas
@@ -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;
diff --git a/vulkan/vImageTiling.pas b/vulkan/vImageTiling.pas
index 4fb23a3e..354e8ee4 100644
--- a/vulkan/vImageTiling.pas
+++ b/vulkan/vImageTiling.pas
@@ -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);
diff --git a/vulkan/vPipelineManager.pas b/vulkan/vPipelineManager.pas
index b5d28d73..aa8183c9 100644
--- a/vulkan/vPipelineManager.pas
+++ b/vulkan/vPipelineManager.pas
@@ -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;
diff --git a/vulkan/vRectGS.pas b/vulkan/vRectGS.pas
new file mode 100644
index 00000000..fa9e9591
--- /dev/null
+++ b/vulkan/vRectGS.pas
@@ -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.
+
diff --git a/vulkan/vRegs2Vulkan.pas b/vulkan/vRegs2Vulkan.pas
index 8a3adf05..4f6a2f5d 100644
--- a/vulkan/vRegs2Vulkan.pas
+++ b/vulkan/vRegs2Vulkan.pas
@@ -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;
diff --git a/vulkan/vShader.pas b/vulkan/vShader.pas
index 819abf1e..0ac382a3 100644
--- a/vulkan/vShader.pas
+++ b/vulkan/vShader.pas
@@ -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
diff --git a/vulkan/vShaderExt.pas b/vulkan/vShaderExt.pas
index c4d8ae5e..374961c5 100644
--- a/vulkan/vShaderExt.pas
+++ b/vulkan/vShaderExt.pas
@@ -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;
///
diff --git a/vulkan/vShaderManager.pas b/vulkan/vShaderManager.pas
index a618d037..e711c9ca 100644
--- a/vulkan/vShaderManager.pas
+++ b/vulkan/vShaderManager.pas
@@ -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);