FPPS4/vulkan/vSetsPool.pas

148 lines
3.1 KiB
Plaintext

unit vSetsPool;
{$mode ObjFPC}{$H+}
interface
uses
Vulkan,
vDevice,
vShader,
vDescriptorSet,
vPipeline;
type
TvSetsPool2=class
FHandle :TVkDescriptorPool;
FLayout :TvPipelineLayout;
FmaxGroup:TVkUInt32;
FmaxSets :TVkUInt32;
FAlcGroup:TVkUInt32;
Constructor Create(Layout:TvPipelineLayout;maxGroup:TVkUInt32);
Destructor Destroy; override;
function Compile:Boolean;
function Alloc(L:TvSetLayout):TvDescriptorSet2;
function IsFull:Boolean;
function Alloc:AvDescriptorSet2;
end;
implementation
Constructor TvSetsPool2.Create(Layout:TvPipelineLayout;maxGroup:TVkUInt32);
begin
FLayout :=Layout;
FmaxGroup:=maxGroup;
end;
Destructor TvSetsPool2.Destroy;
begin
if (FHandle<>VK_NULL_HANDLE) then
begin
vkDestroyDescriptorPool(Device.FHandle,FHandle,nil);
end;
end;
function TvSetsPool2.Compile:Boolean;
type
AvDescriptorPoolSize=array[0..HI_DESCRIPTOR_ID] of TVkDescriptorPoolSize;
var
i,p:Integer;
FSizes:AvDescriptorPoolSize;
cinfo:TVkDescriptorPoolCreateInfo;
r:TVkResult;
begin
Result:=False;
if (FHandle<>VK_NULL_HANDLE) then Exit(true);
if (FLayout=nil) then Exit;
if (FmaxGroup=0) then Exit;
if (not FLayout.Compile) then Exit;
if (FLayout.FTypes=0) then Exit;
FSizes:=Default(AvDescriptorPoolSize);
FmaxSets:=FLayout.FSets*FmaxGroup;
p:=0;
For i:=LO_DESCRIPTOR_ID to HI_DESCRIPTOR_ID do
begin
if (FLayout.FCounts[i]<>0) then
begin
FSizes[p].type_ :=_GetTypeById(i);
FSizes[p].descriptorCount:=FLayout.FCounts[i]*FmaxGroup;
Inc(p);
end;
end;
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:=FLayout.FTypes;
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;
//VkDescriptorSetVariableDescriptorCountAllocateInfo -> RuntimeArray
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(FLayout.key.FLayouts));
If (Length(Result)<>0) then
For i:=0 to High(Result) do
begin
Result[i]:=Alloc(FLayout.key.FLayouts[i]);
end;
Inc(FAlcGroup);
end;
end.