mirror of https://github.com/red-prig/fpPS4.git
207 lines
3.8 KiB
Plaintext
207 lines
3.8 KiB
Plaintext
unit vSetsPoolManager;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
SysUtils,
|
|
LFQueue,
|
|
g23tree,
|
|
Vulkan,
|
|
vPipeline,
|
|
vSetsPool,
|
|
vDescriptorSet,
|
|
vDependence;
|
|
|
|
Function FetchDescriptorGroup(cmd:TvDependenciesObject;Layout:TvPipelineLayout):TvDescriptorGroup;
|
|
|
|
implementation
|
|
|
|
uses
|
|
kern_rwlock;
|
|
|
|
type
|
|
TvSetsPoolUnbound=class;
|
|
|
|
TvDescriptorGroupNode=class(TvDescriptorGroup)
|
|
parent:TvSetsPoolUnbound;
|
|
pNext :Pointer;
|
|
function Drop(Sender:TObject):Boolean; override;
|
|
end;
|
|
|
|
TvSetsPool2Compare=object
|
|
function c(a,b:TvSetsPool2):Integer; static;
|
|
end;
|
|
|
|
TvSetsPool2Set=specialize T23treeSet<TvSetsPool2,TvSetsPool2Compare>;
|
|
|
|
PvPipelineLayout=^TvPipelineLayout;
|
|
|
|
TvSetsPoolUnboundCompare=object
|
|
function c(a,b:PvPipelineLayout):Integer; static;
|
|
end;
|
|
|
|
TvSetsPoolUnbound=class
|
|
FLayout:TvPipelineLayout;
|
|
FQueue :TIntrusiveMPSCQueue;
|
|
FPools :TvSetsPool2Set;
|
|
FLast :TvSetsPool2;
|
|
Constructor Create(Layout:TvPipelineLayout);
|
|
Procedure NewPool;
|
|
function Alloc:TvDescriptorGroupNode;
|
|
procedure PushNode(N:TvDescriptorGroupNode);
|
|
function PopNode:TvDescriptorGroupNode;
|
|
end;
|
|
|
|
_TvSetsPoolUnbounds=specialize T23treeSet<PvPipelineLayout,TvSetsPoolUnboundCompare>;
|
|
TvSetsPoolUnbounds=object(_TvSetsPoolUnbounds)
|
|
lock:Pointer;
|
|
Procedure Lock_wr;
|
|
Procedure Unlock_wr;
|
|
end;
|
|
|
|
var
|
|
FSetsPoolUnbounds:TvSetsPoolUnbounds;
|
|
|
|
Procedure TvSetsPoolUnbounds.Lock_wr;
|
|
begin
|
|
rw_wlock(lock);
|
|
end;
|
|
|
|
Procedure TvSetsPoolUnbounds.Unlock_wr;
|
|
begin
|
|
rw_wunlock(lock);
|
|
end;
|
|
|
|
function TvSetsPool2Compare.c(a,b:TvSetsPool2):Integer;
|
|
begin
|
|
Result:=Integer(Pointer(a)>Pointer(b))-Integer(Pointer(a)<Pointer(b));
|
|
end;
|
|
|
|
function TvSetsPoolUnboundCompare.c(a,b:PvPipelineLayout):Integer;
|
|
begin
|
|
Result:=Integer(Pointer(a^)>Pointer(b^))-Integer(Pointer(a^)<Pointer(b^));
|
|
end;
|
|
|
|
Constructor TvSetsPoolUnbound.Create(Layout:TvPipelineLayout);
|
|
begin
|
|
FLayout:=Layout;
|
|
FQueue.Create;
|
|
end;
|
|
|
|
Procedure TvSetsPoolUnbound.NewPool;
|
|
var
|
|
N:TvSetsPool2;
|
|
begin
|
|
N:=TvSetsPool2.Create(FLayout,2);
|
|
if N.Compile then
|
|
begin
|
|
FPools.Insert(N);
|
|
FLast:=N;
|
|
end else
|
|
begin
|
|
Assert(False,'NewPool');
|
|
N.Free;
|
|
end;
|
|
end;
|
|
|
|
function TvSetsPoolUnbound.Alloc:TvDescriptorGroupNode;
|
|
begin
|
|
Result:=PopNode;
|
|
if (Result<>nil) then Exit;
|
|
|
|
if (FLast=nil) then NewPool;
|
|
if FLast.IsFull then NewPool;
|
|
|
|
Result:=TvDescriptorGroupNode.Create;
|
|
Result.parent :=Self;
|
|
//
|
|
Result.FLayout:=FLayout;
|
|
Result.FSets :=FLast.Alloc;
|
|
//
|
|
Result.Acquire(nil);
|
|
end;
|
|
|
|
procedure TvSetsPoolUnbound.PushNode(N:TvDescriptorGroupNode);
|
|
begin
|
|
FQueue.Push(@N.pNext);
|
|
end;
|
|
|
|
function TvSetsPoolUnbound.PopNode:TvDescriptorGroupNode;
|
|
var
|
|
Node:PPointer;
|
|
begin
|
|
Result:=nil;
|
|
Node:=nil;
|
|
if FQueue.Pop(Node) then
|
|
begin
|
|
Result:=TvDescriptorGroupNode(ptruint(Node)-ptruint(@TvDescriptorGroupNode(nil).pNext));
|
|
end;
|
|
end;
|
|
|
|
function TvDescriptorGroupNode.Drop(Sender:TObject):Boolean;
|
|
begin
|
|
Result:=True;
|
|
if System.InterlockedDecrement(FHold)=0 then
|
|
begin
|
|
if (parent<>nil) then
|
|
begin
|
|
parent.PushNode(Self);
|
|
end;
|
|
Result:=Release(Sender);
|
|
end;
|
|
end;
|
|
|
|
function _Find(Layout:TvPipelineLayout):TvSetsPoolUnbound;
|
|
var
|
|
i:TvSetsPoolUnbounds.Iterator;
|
|
begin
|
|
Result:=nil;
|
|
i:=FSetsPoolUnbounds.find(@Layout);
|
|
if (i.Item<>nil) then
|
|
begin
|
|
Result:=TvSetsPoolUnbound(ptruint(i.Item^)-ptruint(@TvSetsPoolUnbound(nil).FLayout));
|
|
end;
|
|
end;
|
|
|
|
Function _Fetch(Layout:TvPipelineLayout):TvDescriptorGroupNode;
|
|
var
|
|
t:TvSetsPoolUnbound;
|
|
n:TvDescriptorGroupNode;
|
|
|
|
begin
|
|
Result:=nil;
|
|
|
|
t:=_Find(Layout);
|
|
|
|
if (t=nil) then
|
|
begin
|
|
t:=TvSetsPoolUnbound.Create(Layout);
|
|
FSetsPoolUnbounds.Insert(@t.FLayout);
|
|
end;
|
|
|
|
n:=t.Alloc;
|
|
|
|
Result:=n;
|
|
end;
|
|
|
|
Function FetchDescriptorGroup(cmd:TvDependenciesObject;Layout:TvPipelineLayout):TvDescriptorGroup;
|
|
begin
|
|
Result:=nil;
|
|
if (Layout=nil) then Exit;
|
|
if Layout.isSpace then Exit;
|
|
|
|
FSetsPoolUnbounds.Lock_wr;
|
|
|
|
Result:=_Fetch(Layout);
|
|
|
|
cmd.RefTo(Result);
|
|
|
|
FSetsPoolUnbounds.Unlock_wr;
|
|
end;
|
|
|
|
|
|
end.
|
|
|