This commit is contained in:
Pavel 2024-08-06 11:27:08 +03:00
parent 146b57a28e
commit 6dc7235d61
20 changed files with 591 additions and 91 deletions

View File

@ -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);
//

View File

@ -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;

View File

@ -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>

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -144,6 +144,7 @@ begin
if (FHandle<>VK_NULL_HANDLE) then
begin
vkDestroyBuffer(Device.FHandle,FHandle,nil);
FHandle:=VK_NULL_HANDLE;
end;
//
UnBindMem(True);

View File

@ -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;

View File

@ -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);

View File

@ -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;

185
vulkan/vRectGS.pas Normal file
View File

@ -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.

View File

@ -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;

View File

@ -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

View File

@ -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;
///

View File

@ -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);