mirror of
https://github.com/red-prig/fpPS4.git
synced 2024-12-02 11:26:33 +00:00
1026 lines
26 KiB
ObjectPascal
1026 lines
26 KiB
ObjectPascal
unit vPipeline;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
g23tree,
|
|
vulkan,
|
|
vDevice,
|
|
vShader;
|
|
|
|
type
|
|
AVkDescriptorSetLayoutBinding=array of TVkDescriptorSetLayoutBinding;
|
|
|
|
PvSetLayoutKey=^TvSetLayoutKey;
|
|
TvSetLayoutKey=record
|
|
FStage:TVkShaderStageFlags;
|
|
FFlags:TVkUInt32;
|
|
FBinds:AVkDescriptorSetLayoutBinding;
|
|
end;
|
|
|
|
TvSetLayout=class
|
|
FHandle:TVkDescriptorSetLayout;
|
|
FEdit,FCompile:ptruint;
|
|
key:TvSetLayoutKey;
|
|
Procedure SetUsePushDescriptor(b:Boolean);
|
|
function GetUsePushDescriptor:Boolean;
|
|
Destructor Destroy; override;
|
|
Procedure Add(aBind:TVkUInt32;dType:TVkDescriptorType;Flags:TVkShaderStageFlags;count:TVkUInt32=1);
|
|
Procedure SetBinds(const A:AVkDescriptorSetLayoutBinding);
|
|
Function IsSpace:Boolean; inline;
|
|
procedure Clear;
|
|
function Compile:Boolean;
|
|
function IsEdit:Boolean;
|
|
end;
|
|
|
|
AvSetLayout=array of TvSetLayout;
|
|
AvPushConstantRange=array of TVkPushConstantRange;
|
|
|
|
PvPipelineLayoutKey=^TvPipelineLayoutKey;
|
|
TvPipelineLayoutKey=record
|
|
FLayouts :AvSetLayout;
|
|
FPushConsts:AvPushConstantRange;
|
|
end;
|
|
|
|
TvPipelineLayout=class
|
|
FHandle:TVkPipelineLayout;
|
|
FEdit,FCompile:ptruint;
|
|
FBinds:ptruint;
|
|
key:TvPipelineLayoutKey;
|
|
Destructor Destroy; override;
|
|
Procedure AddLayout(F:TvSetLayout);
|
|
Procedure SetLayouts(const A:AvSetLayout);
|
|
Procedure AddPushConst(offset,size:TVkUInt32;Flags:TVkShaderStageFlags);
|
|
Procedure SetPushConst(const A:AvPushConstantRange);
|
|
Function isSpace:Boolean;
|
|
procedure Clear;
|
|
function Compile:Boolean;
|
|
function IsEdit:Boolean;
|
|
end;
|
|
|
|
TvPipeline=class
|
|
FHandle:TVkPipeline;
|
|
FEdit,FCompile:ptruint;
|
|
Destructor Destroy; override;
|
|
end;
|
|
|
|
TvRenderPass=class
|
|
FHandle:TVkRenderPass;
|
|
Destructor Destroy; override;
|
|
end;
|
|
|
|
TvComputePipeline=class(TvPipeline)
|
|
FLayout:TvPipelineLayout;
|
|
FComputeShader:TvShader;
|
|
procedure SetLayout(Layout:TvPipelineLayout);
|
|
Procedure SetShader(Shader:TvShader);
|
|
function Compile:Boolean;
|
|
function IsEdit:Boolean;
|
|
end;
|
|
|
|
TvSetsPool=class;
|
|
|
|
TvDescriptorSet=class
|
|
FParent:TvSetsPool;
|
|
FLayout:TvSetLayout;
|
|
FHandle:TVkDescriptorSet;
|
|
procedure _AllocDesc;
|
|
procedure _FreeDesc;
|
|
Destructor Destroy; override;
|
|
Procedure BindBuf(aBind,aElem:TVkUInt32;dtype:TVkDescriptorType;buffer:TVkBuffer;offset,range:TVkDeviceSize);
|
|
Procedure BindSTI(aBind,aElem:TVkUInt32;img:TVkImageView;Layout:TVkImageLayout);
|
|
end;
|
|
|
|
_TvSetLayoutKey=object
|
|
Layout:TvSetLayout;
|
|
fcount:TVkUInt32;
|
|
function c(const a,b:_TvSetLayoutKey):Integer; static;
|
|
end;
|
|
|
|
_TvSetLayoutSet=specialize T23treeSet<_TvSetLayoutKey,_TvSetLayoutKey>;
|
|
|
|
_TvDescriptorSetCompare=object
|
|
function c(const a,b:TvDescriptorSet):Integer; static;
|
|
end;
|
|
|
|
_TvDescriptorSetSet=specialize T23treeSet<TvDescriptorSet,_TvDescriptorSetCompare>;
|
|
|
|
TvCountsGroup=array[0..14] of TVkUInt32;
|
|
AvDescriptorPoolSize=array of TVkDescriptorPoolSize;
|
|
|
|
TvSetsPool=class
|
|
FHandle:TVkDescriptorPool;
|
|
FEdit,FCompile:ptruint;
|
|
FmaxSets:TVkUInt32;
|
|
FLayouts:_TvSetLayoutSet;
|
|
FSets:_TvDescriptorSetSet;
|
|
Destructor Destroy; override;
|
|
function _FindLayout(L:TvSetLayout):Boolean;
|
|
procedure ClearLayouts;
|
|
Procedure AddLayout(L:TvSetLayout;count:TVkUInt32=1);
|
|
Procedure AddFormPipelineLayout(L:TvPipelineLayout;count:TVkUInt32=1);
|
|
function Alloc(L:TvSetLayout):TvDescriptorSet;
|
|
function Compile:Boolean;
|
|
function IsEdit:Boolean;
|
|
end;
|
|
|
|
///////
|
|
|
|
TvDescriptorSet2=object
|
|
FHandle:TVkDescriptorSet;
|
|
Function IsValid:Boolean;
|
|
Procedure BindBuf(aBind,aElem:TVkUInt32;dtype:TVkDescriptorType;buffer:TVkBuffer;offset,range:TVkDeviceSize);
|
|
Procedure BindSTI(aBind,aElem:TVkUInt32;img:TVkImageView;Layout:TVkImageLayout);
|
|
Procedure BindImg(aBind,aElem:TVkUInt32;img:TVkImageView;Layout:TVkImageLayout);
|
|
Procedure BindSmp(aBind,aElem:TVkUInt32;smp:TVkSampler);
|
|
end;
|
|
|
|
AvDescriptorSet2=Array of TvDescriptorSet2;
|
|
|
|
TvDescriptorGroup=class
|
|
//lock:Ptruint;
|
|
FSets:AvDescriptorSet2;
|
|
//Procedure Release;
|
|
end;
|
|
|
|
AvDescriptorGroup=Array of TvDescriptorGroup;
|
|
|
|
//PvSetsPoolKey=^TvSetsPoolKey;
|
|
//TvSetsPoolKey=record
|
|
// FPipeline:TvPipelineLayout;
|
|
// FNumber :PtrUint;
|
|
//end;
|
|
|
|
TvSetsPool2=class
|
|
FHandle:TVkDescriptorPool;
|
|
//key:TvSetsPoolKey;
|
|
FPipeline:TvPipelineLayout;
|
|
FmaxGroup:TVkUInt32;
|
|
FmaxSets :TVkUInt32;
|
|
FAlcGroup:TVkUInt32;
|
|
//FGroups :AvDescriptorGroup;
|
|
Constructor Create(Pipeline:TvPipelineLayout;maxGroup:TVkUInt32);
|
|
Destructor Destroy; override;
|
|
function Compile:Boolean;
|
|
function Alloc(L:TvSetLayout):TvDescriptorSet2;
|
|
//function Alloc:TvDescriptorGroup;
|
|
function IsFull:Boolean;
|
|
function Alloc:AvDescriptorSet2;
|
|
end;
|
|
|
|
implementation
|
|
|
|
function _TvSetLayoutKey.c(const a,b:_TvSetLayoutKey):Integer;
|
|
begin
|
|
Result:=CompareByte(a.Layout,b.Layout,SizeOf(TvSetLayout));
|
|
end;
|
|
|
|
function _TvDescriptorSetCompare.c(const a,b:TvDescriptorSet):Integer;
|
|
begin
|
|
Result:=CompareByte(a,b,SizeOf(TvDescriptorSet));
|
|
end;
|
|
|
|
Procedure TvSetLayout.Add(aBind:TVkUInt32;dType:TVkDescriptorType;Flags:TVkShaderStageFlags;count:TVkUInt32=1);
|
|
var
|
|
i:Integer;
|
|
begin
|
|
i:=Length(key.FBinds);
|
|
SetLength(key.FBinds,i+1);
|
|
key.FBinds[i]:=Default(TVkDescriptorSetLayoutBinding);
|
|
key.FBinds[i].binding:=aBind;
|
|
key.FBinds[i].descriptorType:=dType;
|
|
key.FBinds[i].descriptorCount:=count;
|
|
key.FBinds[i].stageFlags:=Flags;
|
|
Inc(FEdit);
|
|
end;
|
|
|
|
Procedure TvSetLayout.SetBinds(const A:AVkDescriptorSetLayoutBinding);
|
|
begin
|
|
key.FBinds:=A;
|
|
Inc(FEdit);
|
|
end;
|
|
|
|
Function TvSetLayout.IsSpace:Boolean; inline;
|
|
begin
|
|
Result:=Length(key.FBinds)=0;
|
|
end;
|
|
|
|
Procedure TvSetLayout.Clear;
|
|
begin
|
|
SetLength(key.FBinds,0);
|
|
key.FFlags:=0;
|
|
Inc(FEdit);
|
|
end;
|
|
|
|
function TvSetLayout.Compile:Boolean;
|
|
var
|
|
cinfo:TVkDescriptorSetLayoutCreateInfo;
|
|
r:TVkResult;
|
|
begin
|
|
Result:=False;
|
|
if (FHandle<>VK_NULL_HANDLE) then
|
|
begin
|
|
if (FEdit=FCompile) then Exit(true);
|
|
vkDestroyDescriptorSetLayout(Device.FHandle,FHandle,nil);
|
|
FHandle:=VK_NULL_HANDLE;
|
|
end;
|
|
cinfo:=Default(TVkDescriptorSetLayoutCreateInfo);
|
|
cinfo.sType:=VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
|
|
cinfo.flags:=key.FFlags;
|
|
cinfo.bindingCount:=Length(key.FBinds);
|
|
if (cinfo.bindingCount<>0) then
|
|
begin
|
|
cinfo.pBindings:=@key.FBinds[0];
|
|
end;
|
|
r:=vkCreateDescriptorSetLayout(Device.FHandle,@cinfo,nil,@FHandle);
|
|
if (r<>VK_SUCCESS) then
|
|
begin
|
|
Writeln(StdErr,'vkCreateDescriptorSetLayout:',r);
|
|
Exit;
|
|
end;
|
|
FCompile:=FEdit;
|
|
Result:=True;
|
|
end;
|
|
|
|
Destructor TvSetLayout.Destroy;
|
|
begin
|
|
if (FHandle<>VK_NULL_HANDLE) then
|
|
vkDestroyDescriptorSetLayout(Device.FHandle,FHandle,nil);
|
|
end;
|
|
|
|
function TvSetLayout.IsEdit:Boolean;
|
|
begin
|
|
Result:=FEdit<>FCompile;
|
|
end;
|
|
|
|
Procedure TvSetLayout.SetUsePushDescriptor(b:Boolean);
|
|
begin
|
|
Case b of
|
|
True:
|
|
if (key.FFlags<>ord(VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR)) then
|
|
begin
|
|
key.FFlags:=ord(VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR);
|
|
Inc(FEdit);
|
|
end;
|
|
False:
|
|
if (key.FFlags=ord(VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR)) then
|
|
begin
|
|
key.FFlags:=0;
|
|
Inc(FEdit);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TvSetLayout.GetUsePushDescriptor:Boolean;
|
|
begin
|
|
Result:=(key.FFlags=ord(VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR));
|
|
end;
|
|
|
|
Destructor TvPipelineLayout.Destroy;
|
|
begin
|
|
if (FHandle<>VK_NULL_HANDLE) then
|
|
vkDestroyPipelineLayout(Device.FHandle,FHandle,nil);
|
|
end;
|
|
|
|
Procedure TvPipelineLayout.AddLayout(F:TvSetLayout);
|
|
var
|
|
i:Integer;
|
|
begin
|
|
if (F=nil) then Exit;
|
|
i:=Length(key.FLayouts);
|
|
SetLength(key.FLayouts,i+1);
|
|
key.FLayouts[i]:=F;
|
|
Inc(FEdit);
|
|
end;
|
|
|
|
Procedure TvPipelineLayout.SetLayouts(const A:AvSetLayout);
|
|
begin
|
|
key.FLayouts:=A;
|
|
Inc(FEdit);
|
|
end;
|
|
|
|
Procedure TvPipelineLayout.AddPushConst(offset,size:TVkUInt32;Flags:TVkShaderStageFlags);
|
|
var
|
|
i:Integer;
|
|
begin
|
|
i:=Length(key.FPushConsts);
|
|
SetLength(key.FPushConsts,i+1);
|
|
key.FPushConsts[i].stageFlags:=Flags;
|
|
key.FPushConsts[i].offset :=offset;
|
|
key.FPushConsts[i].size :=size;
|
|
Inc(FEdit);
|
|
end;
|
|
|
|
Procedure TvPipelineLayout.SetPushConst(const A:AvPushConstantRange);
|
|
begin
|
|
key.FPushConsts:=A;
|
|
Inc(FEdit);
|
|
end;
|
|
|
|
Function TvPipelineLayout.isSpace:Boolean;
|
|
begin
|
|
Result:=FBinds=0;
|
|
end;
|
|
|
|
procedure TvPipelineLayout.Clear;
|
|
begin
|
|
SetLength(key.FLayouts,0);
|
|
SetLength(key.FPushConsts,0);
|
|
FBinds:=0;
|
|
Inc(FEdit);
|
|
end;
|
|
|
|
function TvPipelineLayout.Compile:Boolean;
|
|
var
|
|
cinfo:TVkPipelineLayoutCreateInfo;
|
|
r:TVkResult;
|
|
_data_set:array of TVkDescriptorSetLayout;
|
|
i:Integer;
|
|
begin
|
|
Result:=false;
|
|
if (FHandle<>VK_NULL_HANDLE) then
|
|
begin
|
|
if (not IsEdit) then Exit(true);
|
|
vkDestroyPipelineLayout(Device.FHandle,FHandle,nil);
|
|
FHandle:=VK_NULL_HANDLE;
|
|
end;
|
|
FBinds:=0;
|
|
if (Length(key.FLayouts)<>0) then
|
|
begin
|
|
_data_set:=nil;
|
|
SetLength(_data_set,Length(key.FLayouts));
|
|
For i:=0 to High(key.FLayouts) do
|
|
begin
|
|
if not key.FLayouts[i].Compile then Exit;
|
|
_data_set[i]:=key.FLayouts[i].FHandle;
|
|
FBinds:=FBinds+Length(key.FLayouts[i].key.FBinds);
|
|
end;
|
|
end;
|
|
cinfo:=Default(TVkPipelineLayoutCreateInfo);
|
|
cinfo.sType :=VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
|
cinfo.setLayoutCount:=Length(_data_set);
|
|
if (cinfo.setLayoutCount<>0) then
|
|
begin
|
|
cinfo.pSetLayouts:=@_data_set[0];
|
|
end;
|
|
cinfo.pushConstantRangeCount:=Length(key.FPushConsts);
|
|
if (cinfo.pushConstantRangeCount<>0) then
|
|
begin
|
|
cinfo.pPushConstantRanges:=@key.FPushConsts[0];
|
|
end;
|
|
r:=vkCreatePipelineLayout(Device.FHandle,@cinfo,nil,@FHandle);
|
|
if (r<>VK_SUCCESS) then
|
|
begin
|
|
Writeln(StdErr,'vkCreatePipelineLayout:',r);
|
|
Exit;
|
|
end;
|
|
FCompile:=FEdit;
|
|
Result:=True;
|
|
end;
|
|
|
|
function TvPipelineLayout.IsEdit:Boolean;
|
|
var
|
|
i:Integer;
|
|
begin
|
|
Result:=FEdit<>FCompile;
|
|
if not Result then
|
|
if (Length(key.FLayouts)<>0) then
|
|
For i:=0 to High(key.FLayouts) do
|
|
if key.FLayouts[i].IsEdit then Exit(true);
|
|
end;
|
|
|
|
Destructor TvPipeline.Destroy;
|
|
begin
|
|
if (FHandle<>VK_NULL_HANDLE) then
|
|
vkDestroyPipeline(Device.FHandle,FHandle,nil);
|
|
end;
|
|
|
|
Destructor TvRenderPass.Destroy;
|
|
begin
|
|
if (FHandle<>VK_NULL_HANDLE) then
|
|
vkDestroyRenderPass(Device.FHandle,FHandle,nil);
|
|
end;
|
|
|
|
procedure TvComputePipeline.SetLayout(Layout:TvPipelineLayout);
|
|
begin
|
|
if (FLayout<>Layout) then
|
|
begin
|
|
Inc(FEdit);
|
|
FLayout:=Layout;
|
|
Compile;
|
|
end;
|
|
end;
|
|
|
|
Procedure TvComputePipeline.SetShader(Shader:TvShader);
|
|
begin
|
|
if (FComputeShader<>Shader) then
|
|
begin
|
|
Inc(FEdit);
|
|
if (Shader=nil) then
|
|
begin
|
|
FComputeShader:=nil;
|
|
end else
|
|
if (Shader.FStage=VK_SHADER_STAGE_COMPUTE_BIT) then
|
|
begin
|
|
FComputeShader:=Shader;
|
|
Compile;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TvComputePipeline.Compile:Boolean;
|
|
var
|
|
cinfo:TVkComputePipelineCreateInfo;
|
|
r:TVkResult;
|
|
begin
|
|
Result:=False;
|
|
if (FLayout=nil) or (FComputeShader=nil) then Exit;
|
|
if (FHandle<>VK_NULL_HANDLE) then
|
|
begin
|
|
if (not IsEdit) then Exit(true);
|
|
vkDestroyPipeline(Device.FHandle,FHandle,nil);
|
|
FHandle:=VK_NULL_HANDLE;
|
|
end;
|
|
if not FLayout.Compile then Exit;
|
|
cinfo:=Default(TVkComputePipelineCreateInfo);
|
|
cinfo.sType:=VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
|
|
cinfo.stage.sType:=VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
|
cinfo.stage.stage:=VK_SHADER_STAGE_COMPUTE_BIT;
|
|
cinfo.stage.module:=FComputeShader.FHandle;
|
|
cinfo.stage.pName:=PChar(FComputeShader.FEntry);
|
|
cinfo.layout:=FLayout.FHandle;
|
|
r:=vkCreateComputePipelines(Device.FHandle,VK_NULL_HANDLE,1,@cinfo,nil,@FHandle);
|
|
if (r<>VK_SUCCESS) then
|
|
begin
|
|
Writeln(StdErr,'vkCreateComputePipelines:',r);
|
|
Exit;
|
|
end;
|
|
FCompile:=FEdit;
|
|
Result:=True;
|
|
end;
|
|
|
|
function TvComputePipeline.IsEdit:Boolean;
|
|
begin
|
|
Result:=(FEdit<>FCompile);
|
|
if (not Result) and (FLayout<>nil) then
|
|
Result:=Result or FLayout.IsEdit;
|
|
end;
|
|
|
|
Destructor TvSetsPool.Destroy;
|
|
var
|
|
It:_TvDescriptorSetSet.Iterator;
|
|
begin
|
|
It:=FSets.cbegin;
|
|
if (It.Item<>nil) then
|
|
repeat
|
|
It.Item^.FHandle:=VK_NULL_HANDLE;
|
|
until not It.Next;
|
|
if (FHandle<>VK_NULL_HANDLE) then
|
|
vkDestroyDescriptorPool(Device.FHandle,FHandle,nil);
|
|
FSets.Free;
|
|
FLayouts.Free;
|
|
end;
|
|
|
|
function _GetTypeById(i:Byte):TVkDescriptorType;
|
|
begin
|
|
Result:=VK_DESCRIPTOR_TYPE_SAMPLER;
|
|
Case i of
|
|
0:Result:=VK_DESCRIPTOR_TYPE_SAMPLER ;
|
|
1:Result:=VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER ;
|
|
2:Result:=VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE ;
|
|
3:Result:=VK_DESCRIPTOR_TYPE_STORAGE_IMAGE ;
|
|
4:Result:=VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER ;
|
|
5:Result:=VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER ;
|
|
6:Result:=VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ;
|
|
7:Result:=VK_DESCRIPTOR_TYPE_STORAGE_BUFFER ;
|
|
8:Result:=VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC ;
|
|
9:Result:=VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC ;
|
|
10:Result:=VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT ;
|
|
11:Result:=VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT ;
|
|
12:Result:=VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR;
|
|
13:Result:=VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV ;
|
|
14:Result:=VK_DESCRIPTOR_TYPE_MUTABLE_VALVE ;
|
|
else;
|
|
end;
|
|
end;
|
|
|
|
function _GetIdByType(i:TVkDescriptorType):Byte;
|
|
begin
|
|
Result:=0;
|
|
Case i of
|
|
VK_DESCRIPTOR_TYPE_SAMPLER :Result:=0;
|
|
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER :Result:=1;
|
|
VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE :Result:=2;
|
|
VK_DESCRIPTOR_TYPE_STORAGE_IMAGE :Result:=3;
|
|
VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER :Result:=4;
|
|
VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER :Result:=5;
|
|
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER :Result:=6;
|
|
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER :Result:=7;
|
|
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC :Result:=8;
|
|
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC :Result:=9;
|
|
VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT :Result:=10;
|
|
VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT :Result:=11;
|
|
VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR:Result:=12;
|
|
VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV :Result:=13;
|
|
VK_DESCRIPTOR_TYPE_MUTABLE_VALVE :Result:=14;
|
|
else;
|
|
end;
|
|
end;
|
|
|
|
function TvSetsPool.Compile:Boolean;
|
|
var
|
|
i,b,L:Integer;
|
|
It:_TvSetLayoutSet.Iterator;
|
|
Ik:_TvSetLayoutKey;
|
|
Id:_TvDescriptorSetSet.Iterator;
|
|
FCounts:TvCountsGroup;
|
|
FSizes:AvDescriptorPoolSize;
|
|
cinfo:TVkDescriptorPoolCreateInfo;
|
|
r:TVkResult;
|
|
begin
|
|
Result:=False;
|
|
if (FHandle<>VK_NULL_HANDLE) and (not IsEdit) then Exit(true);
|
|
if (FLayouts.Size=0) then Exit;
|
|
FSizes:=Default(AvDescriptorPoolSize);
|
|
|
|
FmaxSets:=0;
|
|
FCounts:=Default(TvCountsGroup);
|
|
It:=FLayouts.cbegin;
|
|
repeat
|
|
Ik:=It.Item^;
|
|
if (Ik.Layout<>nil) and (Ik.fcount<>0) then
|
|
if (Length(Ik.Layout.key.FBinds)<>0) then
|
|
begin
|
|
FmaxSets:=FmaxSets+Ik.fcount;
|
|
For i:=0 to Ik.fcount-1 do
|
|
For b:=0 to High(Ik.Layout.key.FBinds) do
|
|
with Ik.Layout.key.FBinds[b] do
|
|
begin
|
|
Inc(FCounts[_GetIdByType(descriptorType)],descriptorCount);
|
|
end;
|
|
end;
|
|
until not It.Next;
|
|
|
|
For i:=0 to 14 do
|
|
if (FCounts[i]<>0) then
|
|
begin
|
|
L:=Length(FSizes);
|
|
SetLength(FSizes,L+1);
|
|
FSizes[L].type_ :=_GetTypeById(i);
|
|
FSizes[L].descriptorCount:=FCounts[i];
|
|
end;
|
|
if (Length(FSizes)=0) then Exit;
|
|
|
|
Id:=FSets.cbegin;
|
|
if (Id.Item<>nil) then
|
|
repeat
|
|
Id.Item^.FHandle:=VK_NULL_HANDLE;
|
|
until not Id.Next;
|
|
|
|
if (FHandle<>VK_NULL_HANDLE) then
|
|
begin
|
|
vkDestroyDescriptorPool(Device.FHandle,FHandle,nil);
|
|
FHandle:=VK_NULL_HANDLE;
|
|
end;
|
|
|
|
It:=FLayouts.cbegin;
|
|
repeat
|
|
Ik:=It.Item^;
|
|
if (Ik.Layout<>nil) and (Ik.fcount<>0) then
|
|
begin
|
|
if not Ik.Layout.Compile then Exit;
|
|
end;
|
|
until not It.Next;
|
|
|
|
cinfo:=Default(TVkDescriptorPoolCreateInfo);
|
|
cinfo.sType :=VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
|
|
cinfo.flags :=ord(VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT);
|
|
cinfo.poolSizeCount:=Length(FSizes);
|
|
cinfo.pPoolSizes :=@FSizes[0];
|
|
cinfo.maxSets :=FmaxSets;
|
|
|
|
r:=vkCreateDescriptorPool(Device.FHandle,@cinfo,nil,@FHandle);
|
|
if (r<>VK_SUCCESS) then
|
|
begin
|
|
Writeln(StdErr,'vkCreateDescriptorPool:',r);
|
|
Exit;
|
|
end;
|
|
|
|
i:=0;
|
|
Id:=FSets.cbegin;
|
|
if (Id.Item<>nil) then
|
|
repeat
|
|
Id.Item^._AllocDesc;
|
|
Inc(i);
|
|
if (i>=FmaxSets) then Break;
|
|
until not Id.Next;
|
|
|
|
FCompile:=FEdit;
|
|
Result:=True;
|
|
end;
|
|
|
|
function TvSetsPool.IsEdit:Boolean;
|
|
var
|
|
It:_TvSetLayoutSet.Iterator;
|
|
Ik:_TvSetLayoutKey;
|
|
begin
|
|
Result:=False;
|
|
if (FEdit<>FCompile) then Exit(True);
|
|
It:=FLayouts.cbegin;
|
|
if (It.Item=nil) then Exit;
|
|
repeat
|
|
Ik:=It.Item^;
|
|
if (Ik.Layout<>nil) and (Ik.fcount<>0) then
|
|
if Ik.Layout.IsEdit then Exit(True);
|
|
until not It.Next;
|
|
end;
|
|
|
|
procedure TvSetsPool.ClearLayouts;
|
|
begin
|
|
FLayouts.Free;
|
|
Inc(FEdit);
|
|
end;
|
|
|
|
function TvSetsPool._FindLayout(L:TvSetLayout):Boolean;
|
|
var
|
|
Ik:_TvSetLayoutKey;
|
|
begin
|
|
Ik.Layout:=L;
|
|
Ik.fcount:=0;
|
|
Result:=FLayouts.Contains(Ik);
|
|
end;
|
|
|
|
Procedure TvSetsPool.AddLayout(L:TvSetLayout;count:TVkUInt32);
|
|
var
|
|
It:_TvSetLayoutSet.Iterator;
|
|
Ik:_TvSetLayoutKey;
|
|
begin
|
|
if (L=nil) then Exit;
|
|
if (count=0) then count:=1;
|
|
Ik.Layout:=L;
|
|
Ik.fcount:=count;
|
|
It:=FLayouts.find(Ik);
|
|
if (It.Item<>nil) then
|
|
begin
|
|
It.Item^.fcount:=It.Item^.fcount+count;
|
|
end else
|
|
begin
|
|
FLayouts.Insert(Ik);
|
|
end;
|
|
Inc(FEdit);
|
|
end;
|
|
|
|
Procedure TvSetsPool.AddFormPipelineLayout(L:TvPipelineLayout;count:TVkUInt32);
|
|
var
|
|
i:Integer;
|
|
begin
|
|
if (L=nil) then Exit;
|
|
if (Length(L.key.FLayouts)<>0) then
|
|
For i:=0 to High(L.key.FLayouts) do
|
|
begin
|
|
AddLayout(L.key.FLayouts[i],count);
|
|
end;
|
|
end;
|
|
|
|
function TvSetsPool.Alloc(L:TvSetLayout):TvDescriptorSet;
|
|
var
|
|
ainfo:TVkDescriptorSetAllocateInfo;
|
|
FResult:TVkDescriptorSet;
|
|
r:TVkResult;
|
|
begin
|
|
Result:=nil;
|
|
if (L=nil) then Exit;
|
|
if not _FindLayout(L) then Exit;
|
|
if not Compile then Exit;
|
|
if (FSets.Size>=FmaxSets) then Exit;
|
|
ainfo:=Default(TVkDescriptorSetAllocateInfo);
|
|
ainfo.sType :=VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
|
|
ainfo.descriptorPool :=FHandle;
|
|
ainfo.descriptorSetCount:=1;
|
|
ainfo.pSetLayouts:=@L.FHandle;
|
|
r:=vkAllocateDescriptorSets(Device.FHandle,@ainfo,@FResult);
|
|
if (r<>VK_SUCCESS) then
|
|
begin
|
|
Writeln(StdErr,'vkAllocateDescriptorSets:',r);
|
|
Exit;
|
|
end;
|
|
Result:=TvDescriptorSet.Create;
|
|
Result.FParent:=Self;
|
|
Result.FLayout:=L;
|
|
Result.FHandle:=FResult;
|
|
FSets.Insert(Result);
|
|
end;
|
|
|
|
procedure TvDescriptorSet._AllocDesc;
|
|
var
|
|
ainfo:TVkDescriptorSetAllocateInfo;
|
|
r:TVkResult;
|
|
begin
|
|
if (FParent<>nil) and (FLayout<>nil) then
|
|
if (FHandle=VK_NULL_HANDLE) and
|
|
(FParent.FHandle<>VK_NULL_HANDLE) then
|
|
begin
|
|
ainfo:=Default(TVkDescriptorSetAllocateInfo);
|
|
ainfo.sType :=VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
|
|
ainfo.descriptorPool :=FParent.FHandle;
|
|
ainfo.descriptorSetCount:=1;
|
|
ainfo.pSetLayouts:=@FLayout.FHandle;
|
|
r:=vkAllocateDescriptorSets(Device.FHandle,@ainfo,@FHandle);
|
|
if (r<>VK_SUCCESS) then
|
|
begin
|
|
Writeln(StdErr,'vkAllocateDescriptorSets:',r);
|
|
Exit;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TvDescriptorSet._FreeDesc;
|
|
var
|
|
r:TVkResult;
|
|
begin
|
|
if (FParent<>nil) then
|
|
if (FHandle<>VK_NULL_HANDLE) and
|
|
(FParent.FHandle<>VK_NULL_HANDLE) then
|
|
begin
|
|
r:=vkFreeDescriptorSets(Device.FHandle,FParent.FHandle,1,@FHandle);
|
|
if (r<>VK_SUCCESS) then
|
|
begin
|
|
Writeln(StdErr,'vkFreeDescriptorSets:',r);
|
|
end;
|
|
end;
|
|
FHandle:=VK_NULL_HANDLE;
|
|
end;
|
|
|
|
Destructor TvDescriptorSet.Destroy;
|
|
begin
|
|
if (FParent<>nil) then
|
|
begin
|
|
_FreeDesc;
|
|
FParent.FSets.delete(Self);
|
|
end;
|
|
inherited;
|
|
end;
|
|
|
|
//VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER
|
|
//VK_DESCRIPTOR_TYPE_STORAGE_BUFFER
|
|
//VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC
|
|
//VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC
|
|
|
|
Procedure TvDescriptorSet.BindBuf(aBind,aElem:TVkUInt32;dtype:TVkDescriptorType;buffer:TVkBuffer;offset,range:TVkDeviceSize);
|
|
var
|
|
dwrite:TVkWriteDescriptorSet;
|
|
buf:TVkDescriptorBufferInfo;
|
|
begin
|
|
buf:=Default(TVkDescriptorBufferInfo);
|
|
buf.buffer:=buffer;
|
|
buf.offset:=offset;
|
|
buf.range :=range ;
|
|
|
|
dwrite:=Default(TVkWriteDescriptorSet);
|
|
dwrite.sType :=VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
|
dwrite.dstSet :=FHandle;
|
|
dwrite.dstBinding :=aBind;
|
|
dwrite.dstArrayElement:=aElem;
|
|
dwrite.descriptorType :=dtype;
|
|
dwrite.descriptorCount:=1;
|
|
dwrite.pBufferInfo :=@buf;
|
|
|
|
vkUpdateDescriptorSets(Device.FHandle,1,@dwrite,0,nil);
|
|
end;
|
|
|
|
Procedure TvDescriptorSet.BindSTI(aBind,aElem:TVkUInt32;img:TVkImageView;Layout:TVkImageLayout);
|
|
var
|
|
dwrite:TVkWriteDescriptorSet;
|
|
dimg:TVkDescriptorImageInfo;
|
|
begin
|
|
dimg:=Default(TVkDescriptorImageInfo);
|
|
dimg.imageView :=img;
|
|
dimg.imageLayout:=Layout;
|
|
dwrite:=Default(TVkWriteDescriptorSet);
|
|
dwrite.sType :=VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
|
dwrite.dstSet :=FHandle;
|
|
dwrite.dstBinding :=aBind;
|
|
dwrite.dstArrayElement:=aElem;
|
|
dwrite.descriptorType :=VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
|
|
dwrite.descriptorCount:=1;
|
|
dwrite.pImageInfo :=@dimg;
|
|
vkUpdateDescriptorSets(Device.FHandle,1,@dwrite,0,nil);
|
|
end;
|
|
|
|
//
|
|
|
|
Function TvDescriptorSet2.IsValid:Boolean;
|
|
begin
|
|
Result:=FHandle<>VK_NULL_HANDLE;
|
|
end;
|
|
|
|
Procedure TvDescriptorSet2.BindBuf(aBind,aElem:TVkUInt32;dtype:TVkDescriptorType;buffer:TVkBuffer;offset,range:TVkDeviceSize);
|
|
var
|
|
dwrite:TVkWriteDescriptorSet;
|
|
buf:TVkDescriptorBufferInfo;
|
|
begin
|
|
buf:=Default(TVkDescriptorBufferInfo);
|
|
buf.buffer:=buffer;
|
|
buf.offset:=offset;
|
|
buf.range :=range ;
|
|
|
|
dwrite:=Default(TVkWriteDescriptorSet);
|
|
dwrite.sType :=VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
|
dwrite.dstSet :=FHandle;
|
|
dwrite.dstBinding :=aBind;
|
|
dwrite.dstArrayElement:=aElem;
|
|
dwrite.descriptorType :=dtype;
|
|
dwrite.descriptorCount:=1;
|
|
dwrite.pBufferInfo :=@buf;
|
|
|
|
vkUpdateDescriptorSets(Device.FHandle,1,@dwrite,0,nil);
|
|
end;
|
|
|
|
Procedure TvDescriptorSet2.BindSTI(aBind,aElem:TVkUInt32;img:TVkImageView;Layout:TVkImageLayout);
|
|
var
|
|
dwrite:TVkWriteDescriptorSet;
|
|
dimg:TVkDescriptorImageInfo;
|
|
begin
|
|
dimg:=Default(TVkDescriptorImageInfo);
|
|
dimg.imageView :=img;
|
|
dimg.imageLayout:=Layout;
|
|
dwrite:=Default(TVkWriteDescriptorSet);
|
|
dwrite.sType :=VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
|
dwrite.dstSet :=FHandle;
|
|
dwrite.dstBinding :=aBind;
|
|
dwrite.dstArrayElement:=aElem;
|
|
dwrite.descriptorType :=VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
|
|
dwrite.descriptorCount:=1;
|
|
dwrite.pImageInfo :=@dimg;
|
|
vkUpdateDescriptorSets(Device.FHandle,1,@dwrite,0,nil);
|
|
end;
|
|
|
|
Procedure TvDescriptorSet2.BindImg(aBind,aElem:TVkUInt32;img:TVkImageView;Layout:TVkImageLayout);
|
|
var
|
|
dwrite:TVkWriteDescriptorSet;
|
|
dimg:TVkDescriptorImageInfo;
|
|
begin
|
|
dimg:=Default(TVkDescriptorImageInfo);
|
|
dimg.imageView :=img;
|
|
dimg.imageLayout:=Layout;
|
|
dwrite:=Default(TVkWriteDescriptorSet);
|
|
dwrite.sType :=VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
|
dwrite.dstSet :=FHandle;
|
|
dwrite.dstBinding :=aBind;
|
|
dwrite.dstArrayElement:=aElem;
|
|
dwrite.descriptorType :=VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
|
|
dwrite.descriptorCount:=1;
|
|
dwrite.pImageInfo :=@dimg;
|
|
vkUpdateDescriptorSets(Device.FHandle,1,@dwrite,0,nil);
|
|
end;
|
|
|
|
Procedure TvDescriptorSet2.BindSmp(aBind,aElem:TVkUInt32;smp:TVkSampler);
|
|
var
|
|
dwrite:TVkWriteDescriptorSet;
|
|
dimg:TVkDescriptorImageInfo;
|
|
begin
|
|
dimg:=Default(TVkDescriptorImageInfo);
|
|
dimg.sampler:=smp;
|
|
dwrite:=Default(TVkWriteDescriptorSet);
|
|
dwrite.sType :=VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
|
dwrite.dstSet :=FHandle;
|
|
dwrite.dstBinding :=aBind;
|
|
dwrite.dstArrayElement:=aElem;
|
|
dwrite.descriptorType :=VK_DESCRIPTOR_TYPE_SAMPLER;
|
|
dwrite.descriptorCount:=1;
|
|
dwrite.pImageInfo :=@dimg;
|
|
vkUpdateDescriptorSets(Device.FHandle,1,@dwrite,0,nil);
|
|
end;
|
|
|
|
Constructor TvSetsPool2.Create(Pipeline:TvPipelineLayout;maxGroup:TVkUInt32);
|
|
begin
|
|
FPipeline:=Pipeline;
|
|
FmaxGroup:=maxGroup;
|
|
end;
|
|
|
|
Destructor TvSetsPool2.Destroy;
|
|
begin
|
|
if (FHandle<>VK_NULL_HANDLE) then
|
|
vkDestroyDescriptorPool(Device.FHandle,FHandle,nil);
|
|
end;
|
|
|
|
function TvSetsPool2.Compile:Boolean;
|
|
var
|
|
i,b,L:Integer;
|
|
FCounts:TvCountsGroup;
|
|
FSizes:AvDescriptorPoolSize;
|
|
cinfo:TVkDescriptorPoolCreateInfo;
|
|
r:TVkResult;
|
|
begin
|
|
Result:=False;
|
|
if (FHandle<>VK_NULL_HANDLE) then Exit(true);
|
|
|
|
if (FPipeline=nil) then Exit;
|
|
if (FmaxGroup=0) then Exit;
|
|
|
|
if (not FPipeline.Compile) then Exit;
|
|
FSizes:=Default(AvDescriptorPoolSize);
|
|
|
|
FmaxSets:=0;
|
|
FCounts:=Default(TvCountsGroup);
|
|
|
|
if Length(FPipeline.key.FLayouts)<>0 then
|
|
For i:=0 to High(FPipeline.key.FLayouts) do
|
|
With FPipeline.key.FLayouts[i] do
|
|
if (Length(key.FBinds)<>0) then
|
|
begin
|
|
Inc(FmaxSets,FmaxGroup);
|
|
For b:=0 to High(key.FBinds) do
|
|
with key.FBinds[b] do
|
|
begin
|
|
Inc(FCounts[_GetIdByType(descriptorType)],descriptorCount*FmaxGroup);
|
|
end;
|
|
end;
|
|
|
|
For i:=0 to 14 do
|
|
if (FCounts[i]<>0) then
|
|
begin
|
|
L:=Length(FSizes);
|
|
SetLength(FSizes,L+1);
|
|
FSizes[L].type_ :=_GetTypeById(i);
|
|
FSizes[L].descriptorCount:=FCounts[i];
|
|
end;
|
|
if (Length(FSizes)=0) then Exit;
|
|
|
|
cinfo:=Default(TVkDescriptorPoolCreateInfo);
|
|
cinfo.sType :=VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
|
|
//cinfo.flags :=ord(VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT);
|
|
cinfo.poolSizeCount:=Length(FSizes);
|
|
cinfo.pPoolSizes :=@FSizes[0];
|
|
cinfo.maxSets :=FmaxSets;
|
|
|
|
r:=vkCreateDescriptorPool(Device.FHandle,@cinfo,nil,@FHandle);
|
|
if (r<>VK_SUCCESS) then
|
|
begin
|
|
Writeln(StdErr,'vkCreateDescriptorPool:',r);
|
|
Exit;
|
|
end;
|
|
|
|
Result:=True;
|
|
end;
|
|
|
|
function TvSetsPool2.Alloc(L:TvSetLayout):TvDescriptorSet2;
|
|
var
|
|
ainfo:TVkDescriptorSetAllocateInfo;
|
|
FResult:TVkDescriptorSet;
|
|
r:TVkResult;
|
|
begin
|
|
Result:=Default(TvDescriptorSet2);
|
|
|
|
if (L=nil) then Exit;
|
|
if L.IsSpace then Exit;
|
|
|
|
if not Compile then Exit;
|
|
|
|
ainfo:=Default(TVkDescriptorSetAllocateInfo);
|
|
ainfo.sType :=VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
|
|
ainfo.descriptorPool :=FHandle;
|
|
ainfo.descriptorSetCount:=1;
|
|
ainfo.pSetLayouts:=@L.FHandle;
|
|
r:=vkAllocateDescriptorSets(Device.FHandle,@ainfo,@FResult);
|
|
if (r<>VK_SUCCESS) then
|
|
begin
|
|
Writeln(StdErr,'vkAllocateDescriptorSets:',r);
|
|
Exit;
|
|
end;
|
|
|
|
Result.FHandle:=FResult;
|
|
end;
|
|
|
|
function TvSetsPool2.IsFull:Boolean;
|
|
begin
|
|
Result:=(FAlcGroup>=FmaxGroup);
|
|
end;
|
|
|
|
function TvSetsPool2.Alloc:AvDescriptorSet2;
|
|
var
|
|
i:Integer;
|
|
begin
|
|
Result:=nil;
|
|
if IsFull then Exit;
|
|
SetLength(Result,Length(FPipeline.key.FLayouts));
|
|
If (Length(Result)<>0) then
|
|
For i:=0 to High(Result) do
|
|
begin
|
|
Result[i]:=Alloc(FPipeline.key.FLayouts[i]);
|
|
end;
|
|
Inc(FAlcGroup);
|
|
end;
|
|
|
|
{
|
|
Procedure TvDescriptorGroup.Release;
|
|
begin
|
|
lock:=0;
|
|
end;
|
|
}
|
|
|
|
end.
|
|
|