fpPS4/vulkan/vBuffer.pas
Kagamma 2e04d5d3fa
Fix cross-compilation on Linux host (#67)
* Unit names should match with file names to avoid case sensitive issue on Unix system

* Explicit state the build is for win64 target
2023-01-21 16:58:38 +03:00

172 lines
4.6 KiB
ObjectPascal

unit vBuffer;
{$mode objfpc}{$H+}
interface
uses
Vulkan,
vDevice,
vMemory;
type
TvBuffer=class
FHandle:TVkBuffer;
FSize:TVkDeviceSize;
FUsage:TVkFlags;
Constructor Create(size:TVkDeviceSize;usage:TVkFlags;ext:Pointer=nil);
Constructor CreateSparce(size:TVkDeviceSize;usage:TVkFlags;ext:Pointer=nil);
Destructor Destroy; override;
function GetRequirements:TVkMemoryRequirements;
function GetDedicatedAllocation:Boolean;
function BindMem(P:TvPointer):TVkResult;
end;
function VkBindSparseBufferMemory(queue:TVkQueue;buffer:TVkBuffer;bindCount:TVkUInt32;pBinds:PVkSparseMemoryBind):TVkResult;
function GetRequirements(sparce:boolean;size:TVkDeviceSize;usage:TVkFlags;ext:Pointer=nil):TVkMemoryRequirements;
implementation
function VkBindSparseBufferMemory(queue:TVkQueue;buffer:TVkBuffer;bindCount:TVkUInt32;pBinds:PVkSparseMemoryBind):TVkResult;
var
finfo:TVkFenceCreateInfo;
fence:TVkFence;
bind:TVkSparseBufferMemoryBindInfo;
info:TVkBindSparseInfo;
begin
finfo:=Default(TVkFenceCreateInfo);
finfo.sType:=VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
Result:=vkCreateFence(Device.FHandle,@finfo,nil,@fence);
if (Result<>VK_SUCCESS) then
begin
Writeln(StdErr,'vkCreateFence:',Result);
Exit;
end;
bind:=Default(TVkSparseBufferMemoryBindInfo);
bind.buffer :=buffer;
bind.bindCount:=bindCount;
bind.pBinds :=pBinds;
info:=Default(TVkBindSparseInfo);
info.sType :=VK_STRUCTURE_TYPE_BIND_SPARSE_INFO;
info.bufferBindCount:=1;
info.pBufferBinds :=@bind;
Result:=vkQueueBindSparse(queue,1,@info,fence);
if (Result<>VK_SUCCESS) then
begin
Writeln(StdErr,'vkQueueBindSparse:',Result);
vkDestroyFence(Device.FHandle,fence,nil);
Exit;
end;
Result:=vkWaitForFences(Device.FHandle,1,@fence,VK_TRUE,TVkUInt64(-1));
if (Result<>VK_SUCCESS) then
begin
Writeln(StdErr,'vkWaitForFences:',Result);
end;
vkDestroyFence(Device.FHandle,fence,nil);
end;
function GetRequirements(sparce:boolean;size:TVkDeviceSize;usage:TVkFlags;ext:Pointer=nil):TVkMemoryRequirements;
var
Buffer:TvBuffer;
begin
Case sparce of
True :Buffer:=TvBuffer.CreateSparce(size,usage,ext);
False:Buffer:=TvBuffer.Create(size,usage,ext);
end;
Result:=Buffer.GetRequirements;
Buffer.Free;
end;
Constructor TvBuffer.Create(size:TVkDeviceSize;usage:TVkFlags;ext:Pointer=nil);
var
cinfo:TVkBufferCreateInfo;
r:TVkResult;
begin
Assert(size<>0);
FSize:=size;
FUsage:=usage;
cinfo:=Default(TVkBufferCreateInfo);
cinfo.sType:=VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
cinfo.size :=size;
cinfo.usage:=usage;
cinfo.sharingMode:=VK_SHARING_MODE_EXCLUSIVE;
cinfo.pNext:=ext;
r:=vkCreateBuffer(Device.FHandle,@cinfo,nil,@FHandle);
if (r<>VK_SUCCESS) then
begin
Writeln(StdErr,'vkCreateBuffer:',r);
Exit;
end;
end;
Constructor TvBuffer.CreateSparce(size:TVkDeviceSize;usage:TVkFlags;ext:Pointer=nil);
var
cinfo:TVkBufferCreateInfo;
r:TVkResult;
begin
Assert(size<>0);
FSize:=size;
FUsage:=usage;
cinfo:=Default(TVkBufferCreateInfo);
cinfo.sType:=VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
cinfo.flags:=ord(VK_BUFFER_CREATE_SPARSE_BINDING_BIT) or ord(VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT) or ord(VK_BUFFER_CREATE_SPARSE_ALIASED_BIT);
cinfo.size :=size;
cinfo.usage:=usage;
cinfo.sharingMode:=VK_SHARING_MODE_EXCLUSIVE;
cinfo.pNext:=ext;
r:=vkCreateBuffer(Device.FHandle,@cinfo,nil,@FHandle);
if (r<>VK_SUCCESS) then
begin
Writeln(StdErr,'vkCreateBuffer:',r);
Exit;
end;
end;
Destructor TvBuffer.Destroy;
begin
if (FHandle<>VK_NULL_HANDLE) then
vkDestroyBuffer(Device.FHandle,FHandle,nil);
end;
function TvBuffer.GetRequirements:TVkMemoryRequirements;
begin
Result:=Default(TVkMemoryRequirements);
vkGetBufferMemoryRequirements(Device.FHandle,FHandle,@Result);
end;
function TvBuffer.GetDedicatedAllocation:Boolean;
var
info:TVkBufferMemoryRequirementsInfo2;
rmem:TVkMemoryRequirements2;
rded:TVkMemoryDedicatedRequirements;
begin
Result:=false;
if Pointer(vkGetImageMemoryRequirements2)=nil then Exit;
info:=Default(TVkBufferMemoryRequirementsInfo2);
info.sType:=VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2;
info.buffer:=FHandle;
rmem:=Default(TVkMemoryRequirements2);
rmem.sType:=VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2;
rded:=Default(TVkMemoryDedicatedRequirements);
rded.sType:=VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS;
rmem.pNext:=@rded;
vkGetBufferMemoryRequirements2(Device.FHandle,@info,@rmem);
Result:=(rded.requiresDedicatedAllocation<>VK_FALSE) or
(rded.prefersDedicatedAllocation <>VK_FALSE);
end;
function TvBuffer.BindMem(P:TvPointer):TVkResult;
begin
Result:=vkBindBufferMemory(Device.FHandle,FHandle,P.FHandle,P.FOffset);
end;
end.