This commit is contained in:
Pavel 2024-07-26 07:01:48 +03:00
parent 20caf6debf
commit 20c766eb6b
10 changed files with 1050 additions and 789 deletions

View File

@ -29,8 +29,7 @@ uses
vShaderManager,
vRegs2Vulkan,
vCmdBuffer,
vPipeline,
vSetsPoolManager,
vDescriptorSet,
vSampler,
vSamplerManager,
vMetaManager,
@ -133,6 +132,7 @@ type
//
function OnAlloc(size:Ptruint):Pointer; register; override;
Procedure OnFree (P:Pointer ); register; override;
function IsLinearAlloc:Boolean; register; override;
end;
t_me_render_context=object
@ -471,6 +471,10 @@ begin
//
end;
function TvStreamCmdBuffer.IsLinearAlloc:Boolean; register;
begin
Result:=True;
end;
//
@ -728,21 +732,15 @@ begin
end;
procedure Bind_Uniforms(var ctx:t_me_render_context;
BindPoint:TVkPipelineBindPoint;
var UniformBuilder:TvUniformBuilder;
var DescriptorGroup:TvDescriptorGroup;
ShaderGroup:TvShaderGroup);
procedure _init; inline;
begin
if (DescriptorGroup=nil) then
begin
DescriptorGroup:=FetchDescriptorGroup(ctx.Cmd,ShaderGroup.FLayout);
end;
end;
var
i:Integer;
DescriptorGroup:TvDescriptorInterface;
ri:TvImage2;
iv:TvImageView2;
sm:TvSampler;
@ -755,6 +753,7 @@ var
resource_instance:p_pm4_resource_instance;
begin
DescriptorGroup:=ctx.Cmd.FetchDescriptorInterface(BindPoint);
//images
if (Length(UniformBuilder.FImages)<>0) then
@ -780,11 +779,9 @@ begin
iv:=ri.FetchView(ctx.Cmd,FView,iu_sampled);
_init;
DescriptorGroup.FSets[fset].BindImage(bind,0,
iv.FHandle,
VK_IMAGE_LAYOUT_GENERAL);
DescriptorGroup.BindImage(fset,bind,
iv.FHandle,
VK_IMAGE_LAYOUT_GENERAL);
end;
@ -799,9 +796,7 @@ begin
begin
sm:=FetchSampler(ctx.Cmd,PS);
_init;
DescriptorGroup.FSets[fset].BindSampler(bind,0,sm.FHandle);
DescriptorGroup.BindSampler(fset,bind,sm.FHandle);
end;
end;
@ -841,13 +836,10 @@ begin
range:=size;
_init;
DescriptorGroup.FSets[fset].BindBuffer(bind,0,
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
buf.FHandle,
diff,
range {VK_WHOLE_SIZE});
DescriptorGroup.BindBuffer(fset,bind,
buf.FHandle,
diff,
range {VK_WHOLE_SIZE});
if ((memuse and TM_WRITE)<>0) then
begin
@ -1029,8 +1021,6 @@ var
ri:TvImage2;
iv:TvImageView2;
FDescriptorGroup:TvDescriptorGroup;
resource_instance:p_pm4_resource_instance;
begin
RP_KEY.Clear;
@ -1303,18 +1293,11 @@ begin
ctx.Cmd.SetVertexInput (FAttrBuilder);
ctx.Cmd.BindVertexBuffers(FAttrBuilder);
FDescriptorGroup:=nil;
Bind_Uniforms(ctx,
BP_GRAPHICS,
FUniformBuilder,
FDescriptorGroup,
ctx.rt_info^.ShaderGroup);
if (FDescriptorGroup<>nil) then
begin
ctx.Cmd.BindSets(BP_GRAPHICS,FDescriptorGroup);
end;
Bind_Pushs(ctx,ctx.rt_info^.ShaderGroup,@ctx.rt_info^.USERDATA);
end;
@ -1639,7 +1622,6 @@ var
FUniformBuilder:TvUniformBuilder;
FDescriptorGroup:TvDescriptorGroup;
begin
CP_KEY.FShaderGroup:=node^.ShaderGroup;
CP:=FetchComputePipeline(ctx.Cmd,@CP_KEY);
@ -1672,18 +1654,11 @@ begin
Assert(false ,'BindCompute(CP)');
end;
FDescriptorGroup:=nil;
Bind_Uniforms(ctx,
BP_COMPUTE,
FUniformBuilder,
FDescriptorGroup,
CP_KEY.FShaderGroup);
if (FDescriptorGroup<>nil) then
begin
ctx.Cmd.BindSets(BP_COMPUTE,FDescriptorGroup);
end;
Bind_Pushs(ctx,CP_KEY.FShaderGroup,dst);
end;

View File

@ -1304,6 +1304,14 @@
<Filename Value="vulkan\vMetaManager.pas"/>
<IsPartOfProject Value="True"/>
</Unit>
<Unit>
<Filename Value="vulkan\vSetsPool.pas"/>
<IsPartOfProject Value="True"/>
</Unit>
<Unit>
<Filename Value="vulkan\vDescriptorSet.pas"/>
<IsPartOfProject Value="True"/>
</Unit>
</Units>
</ProjectOptions>
<CompilerOptions>

View File

@ -23,6 +23,8 @@ uses
vImage,
vPipeline,
vPipelineManager,
vSetsPoolManager,
vDescriptorSet,
vRender;
type
@ -74,7 +76,11 @@ type
submit_id:ptruint;
FCurrPipeline:array[BP_GRAPHICS..BP_COMPUTE] of TVkPipeline;
FCurrLayout :array[BP_GRAPHICS..BP_COMPUTE] of TVkPipelineLayout;
FCurrLayout :array[BP_GRAPHICS..BP_COMPUTE] of TvPipelineLayout;
FCurrBinds :array[BP_GRAPHICS..BP_COMPUTE] of PvDescriptorCache;
FCurrGroup :array[BP_GRAPHICS..BP_COMPUTE] of TvDescriptorGroup;
FDescriptorCacheSet:TvDescriptorCacheSet;
FRenderPass:TVkRenderPass;
@ -112,6 +118,8 @@ type
Procedure ReleaseAllPlannedTriggers;
Procedure AddPlannedTrigger(start,__end:QWORD;exclude:Pointer);
Procedure FreeAllDescriptorCache;
Procedure BindLayout(BindPoint:TVkPipelineBindPoint;F:TvPipelineLayout);
Procedure BindSet(BindPoint:TVkPipelineBindPoint;fset:TVkUInt32;FHandle:TVkDescriptorSet);
Procedure PushConstant(BindPoint:TVkPipelineBindPoint;stageFlags:TVkShaderStageFlags;offset,size:TVkUInt32;const pValues:PVkVoid);
@ -167,6 +175,13 @@ type
Procedure InsertLabel(pLabelName:PVkChar);
Procedure BeginLabel(pLabelName:PVkChar);
Procedure EndLabel();
function FetchDescriptorCache(layout:TvPipelineLayout):PvDescriptorCache;
function FetchDescriptorCache(BindPoint:TVkPipelineBindPoint):PvDescriptorCache;
function FetchDescriptorInterface(BindPoint:TVkPipelineBindPoint):TvDescriptorInterface;
Procedure ApplyDescriptorCache(BindPoint:TVkPipelineBindPoint);
Procedure BindSets(BindPoint:TVkPipelineBindPoint;F:TvDescriptorGroup);
end;
TvCmdBuffer=class(TvCustomCmdBuffer)
@ -181,8 +196,6 @@ type
function BindCompute(CP:TvComputePipeline2):Boolean;
Procedure BindSets(BindPoint:TVkPipelineBindPoint;F:TvDescriptorGroup);
Procedure dmaData1(src,dst:Pointer;byteCount:DWORD;isBlocking:Boolean);
Procedure dmaData2(src:DWORD;dst:Pointer;byteCount:DWORD;isBlocking:Boolean);
Procedure WriteEos(eventType:Byte;dst:Pointer;value:DWORD;isBlocking:Boolean);
@ -325,8 +338,14 @@ begin
EndRenderPass;
FCurrLayout[BP_GRAPHICS]:=VK_NULL_HANDLE;
FCurrLayout[BP_COMPUTE ]:=VK_NULL_HANDLE;
FCurrLayout[BP_GRAPHICS]:=nil;
FCurrLayout[BP_COMPUTE ]:=nil;
FCurrBinds[BP_GRAPHICS]:=nil;
FCurrBinds[BP_COMPUTE ]:=nil;
FCurrGroup[BP_GRAPHICS]:=nil;
FCurrGroup[BP_COMPUTE ]:=nil;
FCurrPipeline[BP_GRAPHICS]:=VK_NULL_HANDLE;
FCurrPipeline[BP_COMPUTE ]:=VK_NULL_HANDLE;
@ -443,7 +462,9 @@ begin
vkCmdEndRenderPass(FCmdbuf);
FRenderPass:=VK_NULL_HANDLE;
//
FCurrLayout[BP_GRAPHICS]:=VK_NULL_HANDLE;
FCurrLayout[BP_GRAPHICS]:=nil;
FCurrBinds [BP_GRAPHICS]:=nil;
FCurrGroup [BP_GRAPHICS]:=nil;
//
FCurrPipeline[BP_GRAPHICS]:=VK_NULL_HANDLE;
end;
@ -637,6 +658,8 @@ begin
ReleaseAllPlannedTriggers;
FreeAllDescriptorCache;
FreeAllSemaphores;
cmd_count:=0;
@ -647,14 +670,20 @@ Procedure TvCustomCmdBuffer.FreeAllSemaphores;
var
node:PvSemaphoreWait;
begin
node:=FWaitSemaphores.Min;
while (node<>nil) do
if IsLinearAlloc then
begin
FWaitSemaphores:=Default(TvSemaphoreWaitSet);
end else
begin
FWaitSemaphores.delete(node);
OnFree(node);
node:=FWaitSemaphores.Min;
while (node<>nil) do
begin
FWaitSemaphores.delete(node);
OnFree(node);
node:=FWaitSemaphores.Min;
end;
end;
FWaitSemaphoresCount:=0;
@ -698,12 +727,23 @@ begin
//deffered trigger
vm_map_track_trigger(p_proc.p_vmspace,node^.start,node^.__end,node^.exclude,M_GPU_APPLY);
FPlannedTriggers.delete(node);
OnFree(node);
if IsLinearAlloc then
begin
node:=FPlannedTriggers.Next(node);
end else
begin
FPlannedTriggers.delete(node);
OnFree(node);
//
node:=FPlannedTriggers.Min;
end;
node:=FPlannedTriggers.Min;
end;
if IsLinearAlloc then
begin
FPlannedTriggers:=Default(t_cmd_track_deferred_set);
end;
end;
Procedure TvCustomCmdBuffer.AddPlannedTrigger(start,__end:QWORD;exclude:Pointer);
@ -731,6 +771,27 @@ begin
end;
Procedure TvCustomCmdBuffer.FreeAllDescriptorCache;
var
node:PvDescriptorCache;
begin
if IsLinearAlloc then
begin
FDescriptorCacheSet:=Default(TvDescriptorCacheSet);
end else
begin
node:=FDescriptorCacheSet.Min;
while (node<>nil) do
begin
FDescriptorCacheSet.delete(node);
OnFree(node);
node:=FDescriptorCacheSet.Min;
end;
end;
end;
Procedure TvCustomCmdBuffer.BindLayout(BindPoint:TVkPipelineBindPoint;F:TvPipelineLayout);
begin
@ -741,7 +802,13 @@ begin
end;
if (F=nil) then Exit;
FCurrLayout[BindPoint]:=F.FHandle;
if (FCurrLayout[BindPoint]<>F) then
begin
FCurrLayout[BindPoint]:=F;
FCurrBinds [BindPoint]:=nil;
FCurrGroup [BindPoint]:=nil;
end;
end;
Procedure TvCustomCmdBuffer.BindSet(BindPoint:TVkPipelineBindPoint;fset:TVkUInt32;FHandle:TVkDescriptorSet);
@ -754,7 +821,7 @@ begin
end;
if (FHandle=VK_NULL_HANDLE) then Exit;
if (FCurrLayout[BindPoint]=VK_NULL_HANDLE) then Exit;
if (FCurrLayout[BindPoint]=nil) then Exit;
if (not BeginCmdBuffer) then Exit;
@ -762,7 +829,7 @@ begin
vkCmdBindDescriptorSets(FCmdbuf,
BindPoint,
FCurrLayout[BindPoint],
FCurrLayout[BindPoint].FHandle,
fset,1,
@FHandle,
0,nil);
@ -779,14 +846,14 @@ begin
end;
if (pValues=nil) or (size=0) then Exit;
if (FCurrLayout[BindPoint]=VK_NULL_HANDLE) then Exit;
if (FCurrLayout[BindPoint]=nil) then Exit;
if (not BeginCmdBuffer) then Exit;
Inc(cmd_count);
vkCmdPushConstants(FCmdbuf,
FCurrLayout[BindPoint],
FCurrLayout[BindPoint].FHandle,
stageFlags,
offset,size,
pValues);
@ -806,6 +873,8 @@ begin
if (not BeginCmdBuffer) then Exit;
ApplyDescriptorCache(BP_COMPUTE);
Inc(cmd_count);
vkCmdDispatch(FCmdbuf,X,Y,Z);
@ -1074,72 +1143,6 @@ begin
dstStageMask);
end;
Procedure TvCmdBuffer.BindSets(BindPoint:TVkPipelineBindPoint;F:TvDescriptorGroup);
var
A:array[0..6] of TVkDescriptorSet;
i,start,pos:Integer;
procedure Flush; inline;
begin
Inc(cmd_count);
vkCmdBindDescriptorSets(FCmdbuf,
BindPoint,
FCurrLayout[BindPoint],
start,pos,
@A[0],
0,nil);
pos:=0;
end;
begin
if (Self=nil) then
begin
Writeln(stderr,'Self=nil,',{$I %LINE%});
Exit;
end;
if (F=nil) then Exit;
if (FCurrLayout[BindPoint]=VK_NULL_HANDLE) then Exit;
if (Length(F.FSets)=0) then Exit;
if (not BeginCmdBuffer) then Exit;
pos:=0;
For i:=0 to High(F.FSets) do
begin
if F.FSets[i].IsValid then
begin
if (pos=0) then
begin
start:=i;
end;
A[pos]:=F.FSets[i].FHandle;
Inc(pos);
if (pos=7) then
begin
Flush;
end;
end else
if (pos<>0) then
begin
Flush;
end;
end;
if (pos<>0) then
begin
Flush;
end;
end;
Const
VK_ACCESS_ANY=
ord(VK_ACCESS_INDIRECT_COMMAND_READ_BIT ) or
@ -1486,6 +1489,8 @@ begin
if (not BeginCmdBuffer) then Exit;
ApplyDescriptorCache(BP_GRAPHICS);
if (FinstanceCount=0) then FinstanceCount:=1;
Size:=(indexOffset+indexCount)*GET_INDEX_TYPE_SIZE(FINDEX_TYPE);
@ -1560,6 +1565,8 @@ begin
if (not BeginCmdBuffer) then Exit;
ApplyDescriptorCache(BP_GRAPHICS);
if (FinstanceCount=0) then FinstanceCount:=1;
Case Femulate_primtype of
@ -1626,6 +1633,155 @@ begin
end;
//
function TvCustomCmdBuffer.FetchDescriptorCache(layout:TvPipelineLayout):PvDescriptorCache;
begin
Result:=FDescriptorCacheSet.Find(@layout);
if (Result=nil) then
begin
Result:=AllocDescriptorCache(Self,layout);
FDescriptorCacheSet.Insert(Result);
end;
end;
function TvCustomCmdBuffer.FetchDescriptorCache(BindPoint:TVkPipelineBindPoint):PvDescriptorCache;
begin
Result:=nil;
if (FCurrLayout[BindPoint]=nil) then Exit;
Result:=FCurrBinds[BindPoint];
if (Result=nil) then
begin
Result:=FetchDescriptorCache(FCurrLayout[BindPoint]);
//
FCurrBinds[BindPoint]:=Result;
//
Result^.SetAllChange;
end;
end;
function TvCustomCmdBuffer.FetchDescriptorInterface(BindPoint:TVkPipelineBindPoint):TvDescriptorInterface;
begin
Result:=Default(TvDescriptorInterface);
if (Self=nil) then
begin
Writeln(stderr,'Self=nil,',{$I %LINE%});
Exit;
end;
Result:=TvDescriptorInterface(FetchDescriptorCache(BindPoint));
end;
Procedure TvCustomCmdBuffer.ApplyDescriptorCache(BindPoint:TVkPipelineBindPoint);
var
Cache:PvDescriptorCache;
Group:TvDescriptorGroup;
begin
if (FCurrLayout[BindPoint]=nil) then Exit;
Cache:=FCurrBinds[BindPoint];
if (Cache=nil) then Exit;
if (Cache^.p_count_all=0) then Exit; //no sets
Group:=FCurrGroup[BindPoint];
if (Cache^.p_change_any) or
(Group=nil) then
begin
Group:=FetchDescriptorGroup(Self,FCurrLayout[BindPoint]);
//
FCurrGroup[BindPoint]:=Group;
//
Group.Bind(Cache);
//
BindSets(BindPoint,Group);
//
Cache^.ClearAllChange;
end;
//VK_KHR_push_descriptor vkCmdPushDescriptorSetKHR TODO
end;
Procedure TvCustomCmdBuffer.BindSets(BindPoint:TVkPipelineBindPoint;F:TvDescriptorGroup);
var
A:array[0..6] of TVkDescriptorSet;
i,start,pos:Integer;
procedure Flush; inline;
begin
Inc(cmd_count);
vkCmdBindDescriptorSets(FCmdbuf,
BindPoint,
FCurrLayout[BindPoint].FHandle,
start,pos,
@A[0],
0,nil);
pos:=0;
end;
begin
if (Self=nil) then
begin
Writeln(stderr,'Self=nil,',{$I %LINE%});
Exit;
end;
if (F=nil) then Exit;
if (FCurrLayout[BindPoint]=nil) then Exit;
if (Length(F.FSets)=0) then Exit;
if (not BeginCmdBuffer) then Exit;
pos:=0;
For i:=0 to High(F.FSets) do
begin
if F.FSets[i].IsValid then
begin
if (pos=0) then
begin
start:=i;
end;
A[pos]:=F.FSets[i].FHandle;
Inc(pos);
if (pos=7) then
begin
Flush;
end;
end else
if (pos<>0) then
begin
Flush;
end;
end;
if (pos<>0) then
begin
Flush;
end;
end;
//
end.

View File

@ -44,6 +44,7 @@ type
//
function OnAlloc(size:Ptruint):Pointer; virtual;
Procedure OnFree (P:Pointer ); virtual;
function IsLinearAlloc:Boolean; virtual;
Procedure RefTo(obj:TvRefsObject);
function AddDependence(cb:TvReleaseCb):Boolean;
function DelDependence(cb:TvReleaseCb):Boolean;
@ -132,6 +133,11 @@ begin
FreeMem(P);
end;
function TvDependenciesObject.IsLinearAlloc:Boolean;
begin
Result:=False;
end;
Procedure TvDependenciesObject.RefTo(obj:TvRefsObject);
begin
if (Self=nil) or (obj=nil) then Exit;

488
vulkan/vDescriptorSet.pas Normal file
View File

@ -0,0 +1,488 @@
unit vDescriptorSet;
{$mode ObjFPC}{$H+}
interface
uses
g_node_splay,
Vulkan,
vDevice,
vPipeline,
vDependence;
type
PvDescriptorCache=^TvDescriptorCache;
TvDescriptorCache=packed object
//
layout:TvPipelineLayout; //Must be the first element in memory
//
p_write:PVkWriteDescriptorSet;
//
p_count_all:Byte;
// set bind
p_count:array[0..6] of Byte;
p_binds:array[0..6] of PVkWriteDescriptorSet;
//
p_change_any:Boolean;
p_change:array[0..6] of Boolean;
//
pLeft :PvDescriptorCache;
pRight:PvDescriptorCache;
//
function c(a,b:PvDescriptorCache):Integer; static;
procedure ClearAllChange;
procedure SetAllChange;
procedure BindBuffer (aSet,aBind:TVkUInt32;dtype:TVkDescriptorType;buffer:TVkBuffer;offset,range:TVkDeviceSize);
procedure BindImage (aSet,aBind:TVkUInt32;dtype:TVkDescriptorType;img:TVkImageView;aLayout:TVkImageLayout);
procedure BindSampler(aSet,aBind:TVkUInt32;smp:TVkSampler);
end;
TvDescriptorCacheSet=specialize TNodeSplay<TvDescriptorCache>;
TvDescriptorInterface=object
FHandle:PvDescriptorCache;
Procedure BindBuffer (aSet,aBind:TVkUInt32;buffer:TVkBuffer;offset,range:TVkDeviceSize);
Procedure BindUniform(aSet,aBind:TVkUInt32;buffer:TVkBuffer;offset,range:TVkDeviceSize);
Procedure BindStorage(aSet,aBind:TVkUInt32;img:TVkImageView;Layout:TVkImageLayout);
Procedure BindImage (aSet,aBind:TVkUInt32;img:TVkImageView;Layout:TVkImageLayout);
Procedure BindSampler(aSet,aBind:TVkUInt32;smp:TVkSampler);
end;
TvDescriptorSet2=object
FHandle:TVkDescriptorSet;
Function IsValid:Boolean;
Procedure FillHandle (dwrite:PVkWriteDescriptorSet;count:Integer);
Procedure BindBuffer (aBind,aElem:TVkUInt32;buffer:TVkBuffer;offset,range:TVkDeviceSize);
Procedure BindUniform(aBind,aElem:TVkUInt32;buffer:TVkBuffer;offset,range:TVkDeviceSize);
Procedure BindStorage(aBind,aElem:TVkUInt32;img:TVkImageView;Layout:TVkImageLayout);
Procedure BindImage (aBind,aElem:TVkUInt32;img:TVkImageView;Layout:TVkImageLayout);
Procedure BindSampler(aBind,aElem:TVkUInt32;smp:TVkSampler);
end;
AvDescriptorSet2=Array of TvDescriptorSet2;
TvDescriptorGroup=class(TvRefsObject)
FLayout:TvPipelineLayout;
FSets :AvDescriptorSet2;
Procedure Bind(Cache:PvDescriptorCache);
end;
function AllocDescriptorCache(obj:TvDependenciesObject;layout:TvPipelineLayout):PvDescriptorCache;
implementation
Procedure TvDescriptorGroup.Bind(Cache:PvDescriptorCache);
var
i:Integer;
begin
if (Cache=nil) then Exit;
Assert(FLayout=Cache^.layout,'bind on wrong layout');
if (Length(FSets)<>0) then
For i:=0 to High(FSets) do
begin
FSets[i].FillHandle(Cache^.p_binds[i],Cache^.p_count[i]);
end;
if (Cache^.p_count_all<>0) then
begin
vkUpdateDescriptorSets(Device.FHandle,Cache^.p_count_all,Cache^.p_write,0,nil);
end;
end;
//
Function TvDescriptorSet2.IsValid:Boolean;
begin
Result:=FHandle<>VK_NULL_HANDLE;
end;
Procedure TvDescriptorSet2.FillHandle(dwrite:PVkWriteDescriptorSet;count:Integer);
var
i:Integer;
begin
if (dwrite=nil) or (count=0) then Exit;
For i:=0 to count-1 do
begin
dwrite[i].dstSet:=FHandle;
end;
end;
Procedure TvDescriptorSet2.BindBuffer(aBind,aElem:TVkUInt32;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 :=VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
dwrite.descriptorCount:=1;
dwrite.pBufferInfo :=@buf;
vkUpdateDescriptorSets(Device.FHandle,1,@dwrite,0,nil);
end;
Procedure TvDescriptorSet2.BindUniform(aBind,aElem:TVkUInt32;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 :=VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
dwrite.descriptorCount:=1;
dwrite.pBufferInfo :=@buf;
vkUpdateDescriptorSets(Device.FHandle,1,@dwrite,0,nil);
end;
Procedure TvDescriptorSet2.BindStorage(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.BindImage(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.BindSampler(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;
//
Procedure TvDescriptorInterface.BindBuffer(aSet,aBind:TVkUInt32;buffer:TVkBuffer;offset,range:TVkDeviceSize);
begin
if (FHandle=nil) then Exit;
FHandle^.BindBuffer(aSet,aBind,VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,buffer,offset,range);
end;
Procedure TvDescriptorInterface.BindUniform(aSet,aBind:TVkUInt32;buffer:TVkBuffer;offset,range:TVkDeviceSize);
begin
if (FHandle=nil) then Exit;
FHandle^.BindBuffer(aSet,aBind,VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,buffer,offset,range);
end;
Procedure TvDescriptorInterface.BindStorage(aSet,aBind:TVkUInt32;img:TVkImageView;Layout:TVkImageLayout);
begin
if (FHandle=nil) then Exit;
FHandle^.BindImage(aSet,aBind,VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,img,Layout);
end;
Procedure TvDescriptorInterface.BindImage(aSet,aBind:TVkUInt32;img:TVkImageView;Layout:TVkImageLayout);
begin
if (FHandle=nil) then Exit;
FHandle^.BindImage(aSet,aBind,VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,img,Layout);
end;
Procedure TvDescriptorInterface.BindSampler(aSet,aBind:TVkUInt32;smp:TVkSampler);
begin
if (FHandle=nil) then Exit;
FHandle^.BindSampler(aSet,aBind,smp);
end;
//
function AllocDescriptorCache(obj:TvDependenciesObject;layout:TvPipelineLayout):PvDescriptorCache;
var
i,b :Integer;
dwrite_count:Integer;
dimg_count :Integer;
dbuf_count :Integer;
size :Integer;
base :Pointer;
ends :Pointer;
p_write_base:PVkWriteDescriptorSet;
p_write_ends:PVkWriteDescriptorSet;
function AllocBase(size:Integer):Pointer; inline;
begin
Assert((base+size)<=ends,'AllocBase');
Result:=base;
base:=base+size;
end;
function AllocWrite(count:Integer):PVkWriteDescriptorSet; inline;
begin
Assert((p_write_base+count)<=p_write_ends,'AllocWrite');
Result:=p_write_base;
p_write_base:=p_write_base+count;
end;
begin
Assert(layout<>nil,'layout not binded');
Assert(layout.FCounts[ord(VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER )]=0,'TODO');
Assert(layout.FCounts[ord(VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER )]=0,'TODO');
Assert(layout.FCounts[ord(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC)]=0,'TODO');
Assert(layout.FCounts[ord(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)]=0,'TODO');
Assert(layout.FCounts[ord(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT )]=0,'TODO');
dwrite_count:=layout.FBinds;
Assert(dwrite_count<=255,'dwrite_count limit');
dimg_count:=
layout.FCounts[ord(VK_DESCRIPTOR_TYPE_SAMPLER)]+
layout.FCounts[ord(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)]+
layout.FCounts[ord(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)]+
layout.FCounts[ord(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)];
dbuf_count:=
layout.FCounts[ord(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER)]+
layout.FCounts[ord(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)];
size:=SizeOf(TvDescriptorCache)+
dwrite_count*SizeOf(TVkWriteDescriptorSet)+
dimg_count *SizeOf(TVkDescriptorImageInfo)+
dbuf_count *SizeOf(TVkDescriptorBufferInfo);
base:=obj.OnAlloc(size);
ends:=base+size;
Result:=AllocBase(SizeOf(TvDescriptorCache));
Result^.layout:=layout;
p_write_base:=AllocBase(dwrite_count*SizeOf(TVkWriteDescriptorSet));
p_write_ends:=base;
Result^.p_write:=p_write_base;
Result^.p_count_all:=dwrite_count;
if Length(layout.key.FLayouts)<>0 then
begin
For i:=0 to High(layout.key.FLayouts) do
With layout.key.FLayouts[i] do
if (Length(key.FBinds)<>0) then
begin
Result^.p_count[i]:=Length(key.FBinds);
Result^.p_binds[i]:=AllocWrite(Length(key.FBinds));
For b:=0 to High(key.FBinds) do
with key.FBinds[b] do
begin
Result^.p_binds[i][b].sType :=VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
Result^.p_binds[i][b].dstBinding :=b;
Result^.p_binds[i][b].descriptorCount:=1;
Result^.p_binds[i][b].descriptorType :=descriptorType;
case descriptorType of
VK_DESCRIPTOR_TYPE_SAMPLER,
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
begin
Result^.p_binds[i][b].pImageInfo:=AllocBase(SizeOf(TVkDescriptorImageInfo));
end;
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
begin
Result^.p_binds[i][b].pBufferInfo:=AllocBase(SizeOf(TVkDescriptorBufferInfo));
end;
else;
end;
end;
end;
end;
end;
///
function TvDescriptorCache.c(a,b:PvDescriptorCache):Integer;
begin
Result:=Integer(Pointer(a^.layout)>Pointer(b^.layout))-Integer(Pointer(a^.layout)<Pointer(b^.layout));
end;
procedure TvDescriptorCache.ClearAllChange;
begin
//hack
PQWORD(@p_change_any)^:=0;
end;
procedure TvDescriptorCache.SetAllChange;
begin
//hack
PQWORD(@p_change_any)^:=$0101010101010101;
end;
procedure TvDescriptorCache.BindBuffer(aSet,aBind:TVkUInt32;dtype:TVkDescriptorType;buffer:TVkBuffer;offset,range:TVkDeviceSize);
var
dwrite:PVkWriteDescriptorSet;
dbuf :PVkDescriptorBufferInfo;
change:Boolean;
begin
Assert(aSet<7);
Assert(aBind<p_count[aSet]);
Assert(p_binds[aSet]<>nil);
dwrite:=@p_binds[aSet][aBind];
Assert(dwrite^.descriptorType=dtype);
dbuf:=dwrite^.pBufferInfo;
Assert(dbuf<>nil);
change:=False;
change:=change or (dbuf^.buffer<>buffer);
change:=change or (dbuf^.offset<>offset);
change:=change or (dbuf^.range <>range );
dbuf^.buffer:=buffer;
dbuf^.offset:=offset;
dbuf^.range :=range ;
if change then
begin
p_change_any:=True;
p_change[aSet]:=True;
end;
end;
procedure TvDescriptorCache.BindImage(aSet,aBind:TVkUInt32;dtype:TVkDescriptorType;img:TVkImageView;aLayout:TVkImageLayout);
var
dwrite:PVkWriteDescriptorSet;
dimg :PVkDescriptorImageInfo;
change:Boolean;
begin
Assert(aSet<7);
Assert(aBind<p_count[aSet]);
Assert(p_binds[aSet]<>nil);
dwrite:=@p_binds[aSet][aBind];
Assert(dwrite^.descriptorType=dtype);
dimg:=dwrite^.pImageInfo;
Assert(dimg<>nil);
change:=False;
change:=change or (dimg^.imageView <>img );
change:=change or (dimg^.imageLayout<>aLayout);
dimg^.imageView :=img;
dimg^.imageLayout:=aLayout;
if change then
begin
p_change_any:=True;
p_change[aSet]:=True;
end;
end;
procedure TvDescriptorCache.BindSampler(aSet,aBind:TVkUInt32;smp:TVkSampler);
var
dwrite:PVkWriteDescriptorSet;
dimg :PVkDescriptorImageInfo;
change:Boolean;
begin
Assert(aSet<7);
Assert(aBind<p_count[aSet]);
Assert(p_binds[aSet]<>nil);
dwrite:=@p_binds[aSet][aBind];
Assert(dwrite^.descriptorType=VK_DESCRIPTOR_TYPE_SAMPLER);
dimg:=dwrite^.pImageInfo;
Assert(dimg<>nil);
change:=False;
change:=change or (dimg^.sampler<>smp);
dimg^.sampler:=smp;
if change then
begin
p_change_any:=True;
p_change[aSet]:=True;
end;
end;
end.

View File

@ -64,6 +64,7 @@ type
TvCustomImage=class(TvRefsObject)
FHandle:TVkImage;
FFormat:TVkFormat; //real used format
FBind :TvPointer;
procedure FreeHandle; virtual;
Destructor Destroy; override;
@ -148,7 +149,6 @@ type
end;
TvImage=class(TvCustomImage)
FFormat:TVkFormat;
FExtent:TVkExtent3D;
FUsage :TVkFlags;
Fflags :TVkImageCreateFlags;
@ -281,82 +281,125 @@ Function getFormatSize(cformat:TVkFormat):Byte; //in bytes
begin
Result:=0;
Case cformat of
VK_FORMAT_UNDEFINED :Result:=0;
//pixel size
VK_FORMAT_R8_UNORM :Result:=1;
VK_FORMAT_R8_SNORM :Result:=1;
VK_FORMAT_R8_UINT :Result:=1;
VK_FORMAT_R8_SINT :Result:=1;
VK_FORMAT_R8_SRGB :Result:=1;
VK_FORMAT_R8_UNORM ,
VK_FORMAT_R8_SNORM ,
VK_FORMAT_R8_USCALED ,
VK_FORMAT_R8_SSCALED ,
VK_FORMAT_R8_UINT ,
VK_FORMAT_R8_SINT ,
VK_FORMAT_R8_SRGB :Result:=1;
VK_FORMAT_R8G8_UNORM :Result:=2;
VK_FORMAT_R8G8_SNORM :Result:=2;
VK_FORMAT_R8G8_UINT :Result:=2;
VK_FORMAT_R8G8_SINT :Result:=2;
VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT ,
VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT ,
VK_FORMAT_R4G4B4A4_UNORM_PACK16 ,
VK_FORMAT_B4G4R4A4_UNORM_PACK16 ,
VK_FORMAT_R5G6B5_UNORM_PACK16 ,
VK_FORMAT_B5G6R5_UNORM_PACK16 ,
VK_FORMAT_R8G8B8A8_UNORM :Result:=4;
VK_FORMAT_R8G8B8A8_SRGB :Result:=4;
VK_FORMAT_R8G8B8A8_SNORM :Result:=4;
VK_FORMAT_R8G8B8A8_UINT :Result:=4;
VK_FORMAT_R8G8B8A8_SINT :Result:=4;
VK_FORMAT_R8G8_UNORM ,
VK_FORMAT_R8G8_SNORM ,
VK_FORMAT_R8G8_USCALED ,
VK_FORMAT_R8G8_SSCALED ,
VK_FORMAT_R8G8_UINT ,
VK_FORMAT_R8G8_SINT ,
VK_FORMAT_R8G8_SRGB ,
VK_FORMAT_B8G8R8A8_UNORM :Result:=4;
VK_FORMAT_B8G8R8A8_SRGB :Result:=4;
VK_FORMAT_B8G8R8A8_SNORM :Result:=4;
VK_FORMAT_B8G8R8A8_UINT :Result:=4;
VK_FORMAT_B8G8R8A8_SINT :Result:=4;
VK_FORMAT_R16_UNORM ,
VK_FORMAT_R16_SNORM ,
VK_FORMAT_R16_USCALED ,
VK_FORMAT_R16_SSCALED ,
VK_FORMAT_R16_UINT ,
VK_FORMAT_R16_SINT ,
VK_FORMAT_R16_SFLOAT :Result:=2;
VK_FORMAT_R16_UNORM :Result:=2;
VK_FORMAT_R16_SNORM :Result:=2;
VK_FORMAT_R16_UINT :Result:=2;
VK_FORMAT_R16_SINT :Result:=2;
VK_FORMAT_R16_SFLOAT :Result:=2;
VK_FORMAT_R8G8B8A8_UNORM ,
VK_FORMAT_R8G8B8A8_SNORM ,
VK_FORMAT_R8G8B8A8_USCALED ,
VK_FORMAT_R8G8B8A8_SSCALED ,
VK_FORMAT_R8G8B8A8_UINT ,
VK_FORMAT_R8G8B8A8_SINT ,
VK_FORMAT_R8G8B8A8_SRGB ,
VK_FORMAT_R16G16_UNORM :Result:=4;
VK_FORMAT_R16G16_SNORM :Result:=4;
VK_FORMAT_R16G16_UINT :Result:=4;
VK_FORMAT_R16G16_SINT :Result:=4;
VK_FORMAT_R16G16_SFLOAT :Result:=4;
VK_FORMAT_B8G8R8A8_UNORM ,
VK_FORMAT_B8G8R8A8_SNORM ,
VK_FORMAT_B8G8R8A8_USCALED ,
VK_FORMAT_B8G8R8A8_SSCALED ,
VK_FORMAT_B8G8R8A8_UINT ,
VK_FORMAT_B8G8R8A8_SINT ,
VK_FORMAT_B8G8R8A8_SRGB ,
VK_FORMAT_R16G16B16A16_UNORM :Result:=8;
VK_FORMAT_R16G16B16A16_SNORM :Result:=8;
VK_FORMAT_R16G16B16A16_UINT :Result:=8;
VK_FORMAT_R16G16B16A16_SINT :Result:=8;
VK_FORMAT_R16G16B16A16_SFLOAT :Result:=8;
VK_FORMAT_A8B8G8R8_UNORM_PACK32 ,
VK_FORMAT_A8B8G8R8_SNORM_PACK32 ,
VK_FORMAT_A8B8G8R8_USCALED_PACK32 ,
VK_FORMAT_A8B8G8R8_SSCALED_PACK32 ,
VK_FORMAT_A8B8G8R8_UINT_PACK32 ,
VK_FORMAT_A8B8G8R8_SINT_PACK32 ,
VK_FORMAT_A8B8G8R8_SRGB_PACK32 ,
VK_FORMAT_R32_UINT :Result:=4;
VK_FORMAT_R32_SINT :Result:=4;
VK_FORMAT_R32_SFLOAT :Result:=4;
VK_FORMAT_A2R10G10B10_UNORM_PACK32 ,
VK_FORMAT_A2R10G10B10_SNORM_PACK32 ,
VK_FORMAT_A2R10G10B10_USCALED_PACK32,
VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
VK_FORMAT_A2R10G10B10_UINT_PACK32 ,
VK_FORMAT_A2R10G10B10_SINT_PACK32 ,
VK_FORMAT_A2B10G10R10_UNORM_PACK32 ,
VK_FORMAT_A2B10G10R10_SNORM_PACK32 ,
VK_FORMAT_A2B10G10R10_USCALED_PACK32,
VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
VK_FORMAT_A2B10G10R10_UINT_PACK32 ,
VK_FORMAT_A2B10G10R10_SINT_PACK32 ,
VK_FORMAT_R32G32_UINT :Result:=8;
VK_FORMAT_R32G32_SINT :Result:=8;
VK_FORMAT_R32G32_SFLOAT :Result:=8;
VK_FORMAT_R16G16_UNORM ,
VK_FORMAT_R16G16_SNORM ,
VK_FORMAT_R16G16_USCALED ,
VK_FORMAT_R16G16_SSCALED ,
VK_FORMAT_R16G16_UINT ,
VK_FORMAT_R16G16_SINT ,
VK_FORMAT_R16G16_SFLOAT ,
VK_FORMAT_R32G32B32A32_UINT :Result:=16;
VK_FORMAT_R32G32B32A32_SINT :Result:=16;
VK_FORMAT_R32G32B32A32_SFLOAT :Result:=16;
VK_FORMAT_R32_UINT ,
VK_FORMAT_R32_SINT ,
VK_FORMAT_R32_SFLOAT ,
VK_FORMAT_R5G6B5_UNORM_PACK16 :Result:=2;
VK_FORMAT_R4G4B4A4_UNORM_PACK16:Result:=2;
VK_FORMAT_B10G11R11_UFLOAT_PACK32 ,
VK_FORMAT_R10G11B11_UFLOAT_FAKE32 ,
VK_FORMAT_A2R10G10B10_UNORM_PACK32:Result:=4;
VK_FORMAT_A2B10G10R10_UNORM_PACK32:Result:=4;
VK_FORMAT_E5B9G9R9_UFLOAT_PACK32 :Result:=4;
VK_FORMAT_B10G11R11_UFLOAT_PACK32 :Result:=4;
VK_FORMAT_R10G11B11_UFLOAT_FAKE32 :Result:=4;
VK_FORMAT_R16G16B16A16_UNORM ,
VK_FORMAT_R16G16B16A16_SNORM ,
VK_FORMAT_R16G16B16A16_USCALED ,
VK_FORMAT_R16G16B16A16_SSCALED ,
VK_FORMAT_R16G16B16A16_UINT ,
VK_FORMAT_R16G16B16A16_SINT ,
VK_FORMAT_R16G16B16A16_SFLOAT ,
VK_FORMAT_E5B9G9R9_UFLOAT_PACK32 :Result:=4;
VK_FORMAT_R32G32_UINT ,
VK_FORMAT_R32G32_SINT ,
VK_FORMAT_R32G32_SFLOAT :Result:=8;
VK_FORMAT_R32G32B32_UINT ,
VK_FORMAT_R32G32B32_SINT ,
VK_FORMAT_R32G32B32_SFLOAT :Result:=12;
VK_FORMAT_R32G32B32A32_UINT ,
VK_FORMAT_R32G32B32A32_SINT ,
VK_FORMAT_R32G32B32A32_SFLOAT :Result:=16;
//stencil
VK_FORMAT_S8_UINT :Result:=1;
VK_FORMAT_S8_UINT :Result:=1;
//depth
VK_FORMAT_D16_UNORM :Result:=2;
VK_FORMAT_X8_D24_UNORM_PACK32 :Result:=4;
VK_FORMAT_D32_SFLOAT :Result:=4;
VK_FORMAT_D16_UNORM :Result:=2;
VK_FORMAT_X8_D24_UNORM_PACK32 :Result:=4;
VK_FORMAT_D32_SFLOAT :Result:=4;
//depth stencil
VK_FORMAT_D16_UNORM_S8_UINT :Assert(false,'getFormatSize:VK_FORMAT_D16_UNORM_S8_UINT');
VK_FORMAT_D24_UNORM_S8_UINT :Assert(false,'getFormatSize:VK_FORMAT_D24_UNORM_S8_UINT');
VK_FORMAT_D32_SFLOAT_S8_UINT :Assert(false,'getFormatSize:VK_FORMAT_D32_SFLOAT_S8_UINT');
VK_FORMAT_D16_UNORM_S8_UINT :Result:=3;
VK_FORMAT_D24_UNORM_S8_UINT :Result:=4;
VK_FORMAT_D32_SFLOAT_S8_UINT :Result:=5;
//texel size
VK_FORMAT_BC1_RGB_UNORM_BLOCK..
@ -578,6 +621,11 @@ const
VK_FORMAT_UNDEFINED
);
MUTABLE_5999:array[0..1] of TVkFormat=(
VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
VK_FORMAT_UNDEFINED
);
MUTABLE_3232:array[0..10] of TVkFormat=(
VK_FORMAT_R16G16B16A16_UNORM,
VK_FORMAT_R16G16B16A16_SNORM,
@ -781,6 +829,8 @@ begin
VK_FORMAT_B10G11R11_UFLOAT_PACK32 :Result:=@MUTABLE_8888;
VK_FORMAT_R10G11B11_UFLOAT_FAKE32 :Result:=@MUTABLE_8888;
VK_FORMAT_E5B9G9R9_UFLOAT_PACK32 :Result:=@MUTABLE_5999;
VK_FORMAT_R16G16B16A16_UNORM :Result:=@MUTABLE_3232;
VK_FORMAT_R16G16B16A16_SNORM :Result:=@MUTABLE_3232;
VK_FORMAT_R16G16B16A16_USCALED:Result:=@MUTABLE_3232;
@ -922,6 +972,8 @@ begin
VK_FORMAT_R10G11B11_UFLOAT_FAKE32:Result:=VK_FORMAT_R32_UINT;
VK_FORMAT_E5B9G9R9_UFLOAT_PACK32:Result:=VK_FORMAT_R32_UINT;
VK_FORMAT_R16G16B16A16_SNORM,
VK_FORMAT_R16G16B16A16_USCALED,
VK_FORMAT_R16G16B16A16_SSCALED,
@ -1053,8 +1105,6 @@ begin
end;
Function CompareNormalized(const a,b:TvImageKey):Integer;
var
ma,mb:Pointer;
begin
//1 Addr
Result:=Integer(a.Addr>b.Addr)-Integer(a.Addr<b.Addr);
@ -1063,9 +1113,7 @@ begin
Result:=Integer(a.Addr2>b.Addr2)-Integer(a.Addr2<b.Addr2);
if (Result<>0) then Exit;
//2 cformat
ma:=GET_VK_IMAGE_MUTABLE(a.cformat);
mb:=GET_VK_IMAGE_MUTABLE(b.cformat);
Result:=Integer(ma>mb)-Integer(ma<mb);
Result:=getFormatSize(a.cformat)-getFormatSize(b.cformat);
if (Result<>0) then Exit;
//3 params
Result:=CompareByte(GetNormalizedParams(a),GetNormalizedParams(b),SizeOf(TvImageKeyParams));
@ -1456,6 +1504,9 @@ begin
cinfo:=GetImageInfo;
cinfo.format:=vkFixFormatSupport(cinfo.format,cinfo.tiling,cinfo.usage);
//save real format
FFormat:=cinfo.format;
cinfo.pNext:=@clist;
MUTABLE:=GET_VK_IMAGE_MUTABLE(cinfo.format);

View File

@ -550,6 +550,8 @@ begin
if limits.VK_EXT_image_view_min_lod and
(F.minLod<>0) then
begin
uinfo.pNext:=@minfo;
//
minfo:=Default(TVkImageViewMinLodCreateInfoEXT);
minfo.sType :=VK_STRUCTURE_TYPE_IMAGE_VIEW_MIN_LOD_CREATE_INFO_EXT;
minfo.minLod:=F.minLod;

View File

@ -5,7 +5,6 @@ unit vPipeline;
interface
uses
g23tree,
Vulkan,
vDevice,
vShader,
@ -81,105 +80,10 @@ type
Destructor Destroy; override;
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>;
AvDescriptorPoolSize=array of TVkDescriptorPoolSize;
TvSetsPool=class
FHandle:TVkDescriptorPool;
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;
end;
///////
TvDescriptorSet2=object
FHandle:TVkDescriptorSet;
Function IsValid:Boolean;
Procedure BindBuffer (aBind,aElem:TVkUInt32;dtype:TVkDescriptorType;buffer:TVkBuffer;offset,range:TVkDeviceSize);
Procedure BindStorage(aBind,aElem:TVkUInt32;img:TVkImageView;Layout:TVkImageLayout);
Procedure BindImage (aBind,aElem:TVkUInt32;img:TVkImageView;Layout:TVkImageLayout);
Procedure BindSampler(aBind,aElem:TVkUInt32;smp:TVkSampler);
end;
AvDescriptorSet2=Array of TvDescriptorSet2;
TvDescriptorGroup=class(TvRefsObject)
//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;
@ -436,485 +340,6 @@ begin
end;
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
begin
vkDestroyDescriptorPool(Device.FHandle,FHandle,nil);
end;
FSets.Free;
FLayouts.Free;
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) 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:=LO_DESCRIPTOR_ID to HI_DESCRIPTOR_ID 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;
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;
Result:=True;
end;
procedure TvSetsPool.ClearLayouts;
begin
FLayouts.Free;
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;
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.BindBuffer(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.BindStorage(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.BindImage(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.BindSampler(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
begin
vkDestroyDescriptorPool(Device.FHandle,FHandle,nil);
end;
end;
function TvSetsPool2.Compile:Boolean;
var
i,p:Integer;
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);
SetLength(FSizes,FPipeline.FTypes);
FmaxSets:=FPipeline.FSets*FmaxGroup;
p:=0;
For i:=LO_DESCRIPTOR_ID to HI_DESCRIPTOR_ID do
begin
if (FPipeline.FCounts[i]<>0) then
begin
FSizes[p].type_ :=_GetTypeById(i);
FSizes[p].descriptorCount:=FPipeline.FCounts[i]*FmaxGroup;
Inc(p);
end;
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.

146
vulkan/vSetsPool.pas Normal file
View File

@ -0,0 +1,146 @@
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;
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.

View File

@ -10,9 +10,11 @@ uses
g23tree,
Vulkan,
vPipeline,
vCmdBuffer;
vSetsPool,
vDescriptorSet,
vDependence;
Function FetchDescriptorGroup(cmd:TvCustomCmdBuffer;Pipeline:TvPipelineLayout):TvDescriptorGroup;
Function FetchDescriptorGroup(cmd:TvDependenciesObject;Layout:TvPipelineLayout):TvDescriptorGroup;
implementation
@ -41,11 +43,11 @@ type
end;
TvSetsPoolUnbound=class
FPipeline:TvPipelineLayout;
FLayout:TvPipelineLayout;
FQueue:TIntrusiveMPSCQueue;
FPools:TvSetsPool2Set;
FLast:TvSetsPool2;
Constructor Create(Pipeline:TvPipelineLayout);
Constructor Create(Layout:TvPipelineLayout);
Procedure NewPool;
function Alloc:TvDescriptorGroupNode;
procedure PushNode(N:TvDescriptorGroupNode);
@ -82,9 +84,9 @@ begin
Result:=Integer(Pointer(a^)>Pointer(b^))-Integer(Pointer(a^)<Pointer(b^));
end;
Constructor TvSetsPoolUnbound.Create(Pipeline:TvPipelineLayout);
Constructor TvSetsPoolUnbound.Create(Layout:TvPipelineLayout);
begin
FPipeline:=Pipeline;
FLayout:=Layout;
FQueue.Create;
end;
@ -92,7 +94,7 @@ Procedure TvSetsPoolUnbound.NewPool;
var
N:TvSetsPool2;
begin
N:=TvSetsPool2.Create(FPipeline,2);
N:=TvSetsPool2.Create(FLayout,2);
if N.Compile then
begin
FPools.Insert(N);
@ -113,8 +115,10 @@ begin
if FLast.IsFull then NewPool;
Result:=TvDescriptorGroupNode.Create;
Result.parent:=Self;
Result.FSets:=FLast.Alloc;
Result.parent :=Self;
//
Result.FLayout:=FLayout;
Result.FSets :=FLast.Alloc;
end;
procedure TvSetsPoolUnbound.PushNode(N:TvDescriptorGroupNode);
@ -143,19 +147,19 @@ begin
end;
end;
function _Find(Pipeline:TvPipelineLayout):TvSetsPoolUnbound;
function _Find(Layout:TvPipelineLayout):TvSetsPoolUnbound;
var
i:TvSetsPoolUnbounds.Iterator;
begin
Result:=nil;
i:=FSetsPoolUnbounds.find(@Pipeline);
i:=FSetsPoolUnbounds.find(@Layout);
if (i.Item<>nil) then
begin
Result:=TvSetsPoolUnbound(ptruint(i.Item^)-ptruint(@TvSetsPoolUnbound(nil).FPipeline));
Result:=TvSetsPoolUnbound(ptruint(i.Item^)-ptruint(@TvSetsPoolUnbound(nil).FLayout));
end;
end;
Function _Fetch(Pipeline:TvPipelineLayout):TvDescriptorGroupNode;
Function _Fetch(Layout:TvPipelineLayout):TvDescriptorGroupNode;
var
t:TvSetsPoolUnbound;
n:TvDescriptorGroupNode;
@ -163,12 +167,12 @@ var
begin
Result:=nil;
t:=_Find(Pipeline);
t:=_Find(Layout);
if (t=nil) then
begin
t:=TvSetsPoolUnbound.Create(Pipeline);
FSetsPoolUnbounds.Insert(@t.FPipeline);
t:=TvSetsPoolUnbound.Create(Layout);
FSetsPoolUnbounds.Insert(@t.FLayout);
end;
n:=t.Alloc;
@ -176,15 +180,15 @@ begin
Result:=n;
end;
Function FetchDescriptorGroup(cmd:TvCustomCmdBuffer;Pipeline:TvPipelineLayout):TvDescriptorGroup;
Function FetchDescriptorGroup(cmd:TvDependenciesObject;Layout:TvPipelineLayout):TvDescriptorGroup;
begin
Result:=nil;
if (Pipeline=nil) then Exit;
if Pipeline.isSpace then Exit;
if (Layout=nil) then Exit;
if Layout.isSpace then Exit;
FSetsPoolUnbounds.Lock_wr;
Result:=_Fetch(Pipeline);
Result:=_Fetch(Layout);
cmd.RefTo(Result);