fpPS4/vulkan/vSamplerManager.pas
red-prig fb40aa7070 +
2022-06-26 23:50:32 +03:00

146 lines
2.2 KiB
ObjectPascal

unit vSamplerManager;
{$mode objfpc}{$H+}
interface
uses
ps4_shader,
ps4_gpu_regs,
SysUtils,
RWLock,
g23tree,
Vulkan,
vDevice,
vSampler,
vCmdBuffer;
function FetchSampler(cmd:TvCustomCmdBuffer;PS:PSSharpResource4):TvSampler;
implementation
type
TvSampler2Compare=object
function c(a,b:PSSharpResource4):Integer; static;
end;
TvSampler2=class(TvSampler)
key:TSSharpResource4;
//
FRefs:ptruint;
Procedure Acquire;
procedure Release(Sender:TObject);
end;
_TvSampler2Set=specialize T23treeSet<PSSharpResource4,TvSampler2Compare>;
TvSampler2Set=object(_TvSampler2Set)
lock:TRWLock;
Procedure Init;
Procedure Lock_wr;
Procedure Unlock;
end;
var
FSampler2Set:TvSampler2Set;
Procedure TvSampler2Set.Init;
begin
rwlock_init(lock);
end;
Procedure TvSampler2Set.Lock_wr;
begin
rwlock_wrlock(lock);
end;
Procedure TvSampler2Set.Unlock;
begin
rwlock_unlock(lock);
end;
Procedure TvSampler2.Acquire;
begin
System.InterlockedIncrement(Pointer(FRefs));
end;
procedure TvSampler2.Release(Sender:TObject);
begin
if System.InterlockedDecrement(Pointer(FRefs))=nil then
begin
Free;
end;
end;
function TvSampler2Compare.c(a,b:PSSharpResource4):Integer;
begin
Result:=CompareByte(a^,b^,SizeOf(TSSharpResource4));
end;
function _Find(PS:PSSharpResource4):TvSampler2;
var
i:TvSampler2Set.Iterator;
begin
Result:=nil;
i:=FSampler2Set.find(PS);
if (i.Item<>nil) then
begin
Result:=TvSampler2(ptruint(i.Item^)-ptruint(@TvSampler2(nil).key));
end;
end;
function _FetchSampler(PS:PSSharpResource4):TvSampler2;
var
t:TvSampler2;
info:TVkSamplerCreateInfo;
begin
Result:=nil;
t:=_Find(PS);
if (t=nil) then
begin
info:=_get_ssharp_info(PS);
t:=TvSampler2.Create;
t.key:=PS^;
if not t.Compile(@info) then
begin
FreeAndNil(t);
end else
begin
t.Acquire;
FSampler2Set.Insert(@t.key);
end;
end;
Result:=t;
end;
function FetchSampler(cmd:TvCustomCmdBuffer;PS:PSSharpResource4):TvSampler;
begin
Result:=nil;
if (PS=nil) then Exit;
FSampler2Set.Lock_wr;
Result:=_FetchSampler(PS);
if (cmd<>nil) and (Result<>nil) then
begin
if cmd.AddDependence(@TvSampler2(Result).Release) then
begin
TvSampler2(Result).Acquire;
end;
end;
FSampler2Set.Unlock;
end;
initialization
FSampler2Set.Init;
end.