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; 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.