mirror of
https://github.com/red-prig/fpPS4.git
synced 2024-11-23 06:19:57 +00:00
206 lines
3.8 KiB
ObjectPascal
206 lines
3.8 KiB
ObjectPascal
unit vSetsPoolManager;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
SysUtils,
|
|
RWLock,
|
|
LFQueue,
|
|
g23tree,
|
|
Vulkan,
|
|
vPipeline,
|
|
vCmdBuffer;
|
|
|
|
Function FetchDescriptorGroup(cmd:TvCustomCmdBuffer;Pipeline:TvPipelineLayout):TvDescriptorGroup;
|
|
|
|
implementation
|
|
|
|
type
|
|
TvSetsPoolUnbound=class;
|
|
|
|
TvDescriptorGroupNode=class(TvDescriptorGroup)
|
|
parent:TvSetsPoolUnbound;
|
|
pNext:Pointer;
|
|
Procedure Release(Sender:TObject);
|
|
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
|
|
FPipeline:TvPipelineLayout;
|
|
FQueue:TIntrusiveMPSCQueue;
|
|
FPools:TvSetsPool2Set;
|
|
FLast:TvSetsPool2;
|
|
Constructor Create(Pipeline:TvPipelineLayout);
|
|
Procedure NewPool;
|
|
function Alloc:TvDescriptorGroupNode;
|
|
procedure PushNode(N:TvDescriptorGroupNode);
|
|
function PopNode:TvDescriptorGroupNode;
|
|
end;
|
|
|
|
_TvSetsPoolUnbounds=specialize T23treeSet<PvPipelineLayout,TvSetsPoolUnboundCompare>;
|
|
TvSetsPoolUnbounds=object(_TvSetsPoolUnbounds)
|
|
lock:TRWLock;
|
|
Procedure Init;
|
|
Procedure Lock_wr;
|
|
Procedure Unlock;
|
|
end;
|
|
|
|
var
|
|
FSetsPoolUnbounds:TvSetsPoolUnbounds;
|
|
|
|
Procedure TvSetsPoolUnbounds.Init;
|
|
begin
|
|
rwlock_init(lock);
|
|
end;
|
|
|
|
Procedure TvSetsPoolUnbounds.Lock_wr;
|
|
begin
|
|
rwlock_wrlock(lock);
|
|
end;
|
|
|
|
Procedure TvSetsPoolUnbounds.Unlock;
|
|
begin
|
|
rwlock_unlock(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(Pipeline:TvPipelineLayout);
|
|
begin
|
|
FPipeline:=Pipeline;
|
|
FQueue.Create;
|
|
end;
|
|
|
|
Procedure TvSetsPoolUnbound.NewPool;
|
|
var
|
|
N:TvSetsPool2;
|
|
begin
|
|
N:=TvSetsPool2.Create(FPipeline,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.FSets:=FLast.Alloc;
|
|
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;
|
|
|
|
Procedure TvDescriptorGroupNode.Release(Sender:TObject);
|
|
begin
|
|
if (parent<>nil) then
|
|
begin
|
|
parent.PushNode(Self);
|
|
end;
|
|
end;
|
|
|
|
function _Find(Pipeline:TvPipelineLayout):TvSetsPoolUnbound;
|
|
var
|
|
i:TvSetsPoolUnbounds.Iterator;
|
|
begin
|
|
Result:=nil;
|
|
i:=FSetsPoolUnbounds.find(@Pipeline);
|
|
if (i.Item<>nil) then
|
|
begin
|
|
Result:=TvSetsPoolUnbound(ptruint(i.Item^)-ptruint(@TvSetsPoolUnbound(nil).FPipeline));
|
|
end;
|
|
end;
|
|
|
|
Function _Fetch(Pipeline:TvPipelineLayout):TvDescriptorGroupNode;
|
|
var
|
|
t:TvSetsPoolUnbound;
|
|
n:TvDescriptorGroupNode;
|
|
|
|
begin
|
|
Result:=nil;
|
|
|
|
t:=_Find(Pipeline);
|
|
|
|
if (t=nil) then
|
|
begin
|
|
t:=TvSetsPoolUnbound.Create(Pipeline);
|
|
FSetsPoolUnbounds.Insert(@t.FPipeline);
|
|
end;
|
|
|
|
n:=t.Alloc;
|
|
|
|
Result:=n;
|
|
end;
|
|
|
|
Function FetchDescriptorGroup(cmd:TvCustomCmdBuffer;Pipeline:TvPipelineLayout):TvDescriptorGroup;
|
|
begin
|
|
Result:=nil;
|
|
if (Pipeline=nil) then Exit;
|
|
if Pipeline.isSpace then Exit;
|
|
|
|
FSetsPoolUnbounds.Lock_wr;
|
|
|
|
Result:=_Fetch(Pipeline);
|
|
|
|
if (cmd<>nil) and (Result<>nil) then
|
|
begin
|
|
cmd.AddDependence(@TvDescriptorGroupNode(Result).Release);
|
|
end;
|
|
|
|
FSetsPoolUnbounds.Unlock;
|
|
end;
|
|
|
|
|
|
initialization
|
|
FSetsPoolUnbounds.Init;
|
|
|
|
end.
|
|
|