diff --git a/projects/triangle/triangle.lpi b/projects/triangle/triangle.lpi
index d830415..2c203dd 100644
--- a/projects/triangle/triangle.lpi
+++ b/projects/triangle/triangle.lpi
@@ -33,7 +33,7 @@
-
+
@@ -74,25 +74,85 @@
-
+
-
+
-
+
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/projects/triangle/triangle.lps b/projects/triangle/triangle.lps
index 311b57e..b2018b3 100644
--- a/projects/triangle/triangle.lps
+++ b/projects/triangle/triangle.lps
@@ -4,13 +4,13 @@
-
+
-
+
@@ -18,383 +18,502 @@
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
+
+
-
+
-
-
-
+
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
-
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
-
-
-
-
-
-
-
diff --git a/projects/triangle/uMainForm.pas b/projects/triangle/uMainForm.pas
index e2635e3..fdf3b12 100644
--- a/projects/triangle/uMainForm.pas
+++ b/projects/triangle/uMainForm.pas
@@ -6,12 +6,7 @@ interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls,
- Vulkan, uvkuAllocationHandler,
- uvkuInstance, uvkuInstanceFactory,
- uvkuPhysicalDevice, uvkuPhysicalDeviceFactory,
- uvkuSurface, uvkuSurfaceFactory,
- uvkuDevice, uvkuDeviceFactory,
- uvkuSwapChain, uvkuSwapChainFactory;
+ Vulkan, VulkanUtils;
type
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -32,6 +27,7 @@ type
fInstance: TvkuInstance;
fPhyDevice: TvkuPhysicalDevice;
fDevice: TvkuDevice;
+ fQueue: TvkuQueue;
fSurface: TvkuSurface;
fSwapChain: TvkuSwapChain;
public
@@ -78,7 +74,6 @@ procedure TMainForm.FormCreate(Sender: TObject);
var
PhyDevices: TvkuPhysicalDeviceArr;
iFactory: TvkuInstanceFactory;
- pdFactory: TvkuPhysicalDeviceFactory;
dFactory: TvkuDeviceFactory;
sFactory: TvkuSurfaceFactory;
scFactory: TvkuSwapChainFactory;
@@ -107,13 +102,7 @@ begin
PhyDevices := fInstance.GetPhysicalDevices;
if (Length(PhyDevices) <= 0) then
raise Exception.Create('unable to get physical device');
- pdFactory := TvkuPhysicalDeviceFactory.Create(fInstance);
- try
- fPhyDevice := pdFactory.CreatePhysicalDevice(PhyDevices[0]);
- finally
- FreeAndNil(pdFactory);
- end;
-
+ fPhyDevice := TvkuPhysicalDevice.Create(PhyDevices[0], fInstance.InstanceCommands);
WriteLn('create vulkan surface');
sFactory := TvkuSurfaceFactory.Create(fInstance);
@@ -141,6 +130,11 @@ begin
FreeAndNil(dFactory);
end;
+
+ WriteLn('get queue from device');
+ fQueue := TvkuQueue.Create(fDevice.GetQueue(0, 0), fDevice.DeviceCommands);
+
+
WriteLn('create swap chain');
scFactory := TvkuSwapChainFactory.Create(fDevice);
try
@@ -210,6 +204,7 @@ end;
procedure TMainForm.FormDestroy(Sender: TObject);
begin
FreeAndNil(fSwapChain);
+ FreeAndNil(fQueue);
FreeAndNil(fDevice);
FreeAndNil(fSurface);
FreeAndNil(fPhyDevice);
diff --git a/projects/utils/VulkanUtils.pas b/projects/utils/VulkanUtils.pas
new file mode 100644
index 0000000..adb7ab8
--- /dev/null
+++ b/projects/utils/VulkanUtils.pas
@@ -0,0 +1,87 @@
+unit VulkanUtils;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes, SysUtils,
+ uvkuTypes, uvkuAllocationHandler,
+ uvkuInstance, uvkuInstanceFactory,
+ uvkuPhysicalDevice, uvkuDevice, uvkuDeviceFactory, uvkuDeviceMemory, uvkuQueue,
+ uvkuSurface, uvkuSurfaceFactory,
+ uvkuSwapChain, uvkuSwapChainFactory,
+ uvkuImage, uvkuImageFactory, uvkuImageView, uvkuImageViewFactory,
+ uvkuBuffer, uvkuBufferFactory, uvkuBufferView, uvkuBufferViewFactory,
+ uvkuCommandPool, uvkuCommandPoolFactory, uvkuCommandBuffer;
+
+type
+ { Types }
+ TvkuFloatArr = uvkuTypes.TvkuFloatArr;
+ TvkuUint32Arr = uvkuTypes.TvkuUint32Arr;
+ TvkuImageArr = uvkuTypes.TvkuImageArr;
+ TvkuPhysicalDeviceArr = uvkuTypes.TvkuPhysicalDeviceArr;
+ TvkuQueueFamilyPropertiesArr = uvkuTypes.TvkuQueueFamilyPropertiesArr;
+ TvkuSparseImageFormatPropertiesArr = uvkuTypes.TvkuSparseImageFormatPropertiesArr;
+ TvkuSurfaceFormatArr = uvkuTypes.TvkuSurfaceFormatArr;
+ TvkuPresentModeArr = uvkuTypes.TvkuPresentModeArr;
+ TvkuDisplayPropertiesArr = uvkuTypes.TvkuDisplayPropertiesArr;
+ TvkuDisplayPlanePropertiesArr = uvkuTypes.TvkuDisplayPlanePropertiesArr;
+ TvkuDisplayArr = uvkuTypes.TvkuDisplayArr;
+ TvkuDisplayModePropertiesArr = uvkuTypes.TvkuDisplayModePropertiesArr;
+ TvkuCommandBufferArr = uvkuTypes.TvkuCommandBufferArr;
+ TvkuApplicationInfo = uvkuTypes.TvkuApplicationInfo;
+ TvkuQueueCreateInfo = uvkuTypes.TvkuQueueCreateInfo;
+ TvkuQueueCreateInfoArr = uvkuTypes.TvkuQueueCreateInfoArr;
+
+ TvkuAllocationHandler = uvkuAllocationHandler.TvkuAllocationHandler;
+
+ { Instance }
+ TvkuInstance = uvkuInstance.TvkuInstance;
+ TvkuInstanceEx = uvkuInstanceFactory.TvkuInstanceEx;
+ TvkuInstanceFactory = uvkuInstanceFactory.TvkuInstanceFactory;
+
+ { Device }
+ TvkuPhysicalDevice = uvkuPhysicalDevice.TvkuPhysicalDevice;
+ TvkuDevice = uvkuDevice.TvkuDevice;
+ TvkuDeviceEx = uvkuDeviceFactory.TvkuDeviceEx;
+ TvkuDeviceFactory = uvkuDeviceFactory.TvkuDeviceFactory;
+ TvkuDeviceMemory = uvkuDeviceMemory.TvkuDeviceMemory;
+ TvkuQueue = uvkuQueue.TvkuQueue;
+
+ { Surface }
+ TvkuSurface = uvkuSurface.TvkuSurface;
+ TvkuSurfaceEx = uvkuSurfaceFactory.TvkuSurfaceEx;
+ TvkuSurfaceFactory = uvkuSurfaceFactory.TvkuSurfaceFactory;
+
+ { SwapChain }
+ TvkuSwapChain = uvkuSwapChain.TvkuSwapChain;
+ TvkuSwapChainEx = uvkuSwapChainFactory.TvkuSwapChainEx;
+ TvkuSwapChainFactory = uvkuSwapChainFactory.TvkuSwapChainFactory;
+
+ { Image }
+ TvkuImage = uvkuImage.TvkuImage;
+ TvkuImageEx = uvkuImageFactory.TvkuImageEx;
+ TvkuImageFactory = uvkuImageFactory.TvkuImageFactory;
+ TvkuImageView = uvkuImageView.TvkuImageView;
+ TvkuImageViewEx = uvkuImageViewFactory.TvkuImageViewEx;
+ TvkuImageViewFactory = uvkuImageViewFactory.TvkuImageViewFactory;
+
+ { Buffer }
+ TvkuBuffer = uvkuBuffer.TvkuBuffer;
+ TvkuBufferEx = uvkuBufferFactory.TvkuBufferEx;
+ TvkuBufferFactory = uvkuBufferFactory.TvkuBufferFactory;
+ TvkuBufferView = uvkuBufferView.TvkuBufferView;
+ TvkuBufferViewEx = uvkuBufferViewFactory.TvkuBufferViewEx;
+ TvkuBufferViewFactory = uvkuBufferViewFactory.TvkuBufferViewFactory;
+
+ { Commands }
+ TvkuCommandPool = uvkuCommandPool.TvkuCommandPool;
+ TvkuCommandPoolEx = uvkuCommandPoolFactory.TvkuCommandPoolEx;
+ TvkuCommandPoolFactory = uvkuCommandPoolFactory.TvkuCommandPoolFactory;
+ TvkuCommandBuffer = uvkuCommandBuffer.TvkuCommandBuffer;
+
+implementation
+
+end.
+
diff --git a/projects/utils/uvkuAllocationHandler.pas b/projects/utils/uvkuAllocationHandler.pas
index 8dea193..11a8e84 100644
--- a/projects/utils/uvkuAllocationHandler.pas
+++ b/projects/utils/uvkuAllocationHandler.pas
@@ -11,6 +11,8 @@ uses
type
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TvkuAllocationHandler = class(TObject)
+ private
+ fAllocCallbacks: PVkAllocationCallbacks;
protected
function AllocateMemory(const aSize: VkSize; const aAlignment: VkSize; const aScope: TVkSystemAllocationScope): PVkVoid; virtual;
function ReallocateMemory(const aOriginal: PVkVoid; const aSize: VkSize; const aAlignment: VkSize; const aScope: TVkSystemAllocationScope): PVkVoid; virtual;
@@ -20,6 +22,10 @@ type
procedure InternalFreeNotification(const aSize: VkSize; const aType: TVkInternalAllocationType; const aScope: TVkSystemAllocationScope);
public
function GetAllocationCallbacks: TVkAllocationCallbacks;
+ function GetAllocationCallbacksPtr: PVkAllocationCallbacks;
+
+ constructor Create;
+ destructor Destroy; override;
end;
implementation
@@ -90,13 +96,40 @@ end;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuAllocationHandler.GetAllocationCallbacks: TVkAllocationCallbacks;
begin
- FillByte(result{%H-}, SizeOf(result), 0);
- result.pUserData := self;
- result.pfnAllocation := @AllocateMemoryCallback;
- result.pfnReallocation := @ReallocateMemoryCallback;
- result.pfnFree := @FreeMemoryCallback;
- result.pfnInternalAllocation := @InternalAllocationCallback;
- result.pfnInternalFree := @InternalFreeCallback;
+ result := GetAllocationCallbacksPtr^;
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TvkuAllocationHandler.GetAllocationCallbacksPtr: PVkAllocationCallbacks;
+begin
+ if not Assigned(fAllocCallbacks) then begin
+ new(fAllocCallbacks);
+ FillByte(fAllocCallbacks^, SizeOf(result), 0);
+ fAllocCallbacks^.pUserData := self;
+ fAllocCallbacks^.pfnAllocation := @AllocateMemoryCallback;
+ fAllocCallbacks^.pfnReallocation := @ReallocateMemoryCallback;
+ fAllocCallbacks^.pfnFree := @FreeMemoryCallback;
+ fAllocCallbacks^.pfnInternalAllocation := @InternalAllocationCallback;
+ fAllocCallbacks^.pfnInternalFree := @InternalFreeCallback;
+ end;
+ result := fAllocCallbacks;
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TvkuAllocationHandler.Create;
+begin
+ inherited Create;
+ fAllocCallbacks := nil;
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+destructor TvkuAllocationHandler.Destroy;
+begin
+ if Assigned(fAllocCallbacks) then begin
+ Dispose(fAllocCallbacks);
+ fAllocCallbacks := nil;
+ end;
+ inherited Destroy;
end;
end.
diff --git a/projects/utils/uvkuBase.pas b/projects/utils/uvkuBase.pas
new file mode 100644
index 0000000..a53331e
--- /dev/null
+++ b/projects/utils/uvkuBase.pas
@@ -0,0 +1,92 @@
+unit uvkuBase;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes, SysUtils,
+ Vulkan;
+
+type
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ TvkuObject = class(TObject)
+ end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ TvkuHandle = class(TvkuObject)
+ private
+ fOwnsHandle: Boolean;
+ public
+ property OwnsHandle: Boolean read fOwnsHandle write fOwnsHandle;
+ constructor Create;
+ end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ TvkuAllocHandle = class(TvkuHandle)
+ private
+ fAllocCallbacks: PVkAllocationCallbacks;
+ protected
+ property AllocCallbacks: PVkAllocationCallbacks read fAllocCallbacks;
+
+ procedure SetAllocCallbacks(const aAllocCallbacks: TVkAllocationCallbacks);
+ procedure SetAllocCallbacks(const aAllocCallbacks: PVkAllocationCallbacks);
+ procedure DisposeAllocCallbacks;
+ public
+ constructor Create;
+ destructor Destroy; override;
+ end;
+
+implementation
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TvkuHandle/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TvkuHandle.Create;
+begin
+ inherited Create;
+ fOwnsHandle := true;
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TvkuAllocHandle////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TvkuAllocHandle.SetAllocCallbacks(const aAllocCallbacks: TVkAllocationCallbacks);
+begin
+ if not Assigned(fAllocCallbacks) then
+ new(fAllocCallbacks);
+ fAllocCallbacks^ := aAllocCallbacks;
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TvkuAllocHandle.SetAllocCallbacks(const aAllocCallbacks: PVkAllocationCallbacks);
+begin
+ if Assigned(aAllocCallbacks) then
+ SetAllocCallbacks(aAllocCallbacks^);
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TvkuAllocHandle.DisposeAllocCallbacks;
+begin
+ if not Assigned(fAllocCallbacks) then
+ exit;
+ Dispose(fAllocCallbacks);
+ fAllocCallbacks := nil;
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TvkuAllocHandle.Create;
+begin
+ inherited Create;
+ fAllocCallbacks := nil;
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+destructor TvkuAllocHandle.Destroy;
+begin
+ inherited Destroy;
+ DisposeAllocCallbacks;
+end;
+
+end.
+
diff --git a/projects/utils/uvkuBuffer.pas b/projects/utils/uvkuBuffer.pas
new file mode 100644
index 0000000..39aee69
--- /dev/null
+++ b/projects/utils/uvkuBuffer.pas
@@ -0,0 +1,82 @@
+unit uvkuBuffer;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes, SysUtils,
+ Vulkan, uvkuBase;
+
+type
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ TvkuBuffer = class(TvkuAllocHandle)
+ private
+ fHandle: VkBuffer;
+ fDeviceCommands: TVkDeviceCommands;
+
+ procedure CreateHandle(const aCreateInfo: TVkBufferCreateInfo);
+ public
+ property Handle: VkBuffer read fHandle;
+ property DeviceCommands: TVkDeviceCommands read fDeviceCommands;
+
+ constructor Create(
+ const aCreateInfo: TVkBufferCreateInfo;
+ const aDeviceCommands: TVkDeviceCommands;
+ const aAllocCallbacks: PVkAllocationCallbacks = nil);
+ constructor Create(
+ const aHandle: VkBuffer;
+ const aOwnsHandle: Boolean;
+ const aDeviceCommands: TVkDeviceCommands;
+ const aAllocCallbacks: PVkAllocationCallbacks = nil);
+ destructor Destroy; override;
+ end;
+
+implementation
+
+uses
+ uvkuUtils;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TvkuBuffer/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TvkuBuffer.CreateHandle(const aCreateInfo: TVkBufferCreateInfo);
+var err: TVkResult;
+begin
+ err := fDeviceCommands.vkCreateBuffer(fDeviceCommands.Device, @aCreateInfo, AllocCallbacks, @fHandle);
+ if (err < VK_SUCCESS) then
+ raise TvkuErrorException.Create('unable to create buffer', err);
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TvkuBuffer.Create(const aCreateInfo: TVkBufferCreateInfo; const aDeviceCommands: TVkDeviceCommands;
+ const aAllocCallbacks: PVkAllocationCallbacks);
+begin
+ inherited Create;
+ fDeviceCommands := aDeviceCommands;
+ SetAllocCallbacks(aAllocCallbacks);
+ CreateHandle(aCreateInfo);
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TvkuBuffer.Create(const aHandle: VkBuffer; const aOwnsHandle: Boolean;
+ const aDeviceCommands: TVkDeviceCommands; const aAllocCallbacks: PVkAllocationCallbacks);
+begin
+ inherited Create;
+ fHandle := aHandle;
+ fDeviceCommands := aDeviceCommands;
+ OwnsHandle := aOwnsHandle;
+ SetAllocCallbacks(aAllocCallbacks);
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+destructor TvkuBuffer.Destroy;
+begin
+ if OwnsHandle and (fHandle <> VK_INVALID_NDP_HANDLE) then
+ fDeviceCommands.vkDestroyBuffer(fDeviceCommands.Device, fHandle, AllocCallbacks);
+ fHandle := VK_INVALID_NDP_HANDLE;
+ inherited Destroy;
+end;
+
+end.
+
diff --git a/projects/utils/uvkuBufferFactory.pas b/projects/utils/uvkuBufferFactory.pas
new file mode 100644
index 0000000..1e93f21
--- /dev/null
+++ b/projects/utils/uvkuBufferFactory.pas
@@ -0,0 +1,140 @@
+unit uvkuBufferFactory;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes, SysUtils,
+ Vulkan, uvkuBuffer, uvkuDevice, uvkuAllocationHandler, uvkuTypes;
+
+type
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ TvkuBufferEx = class(TvkuBuffer)
+ private
+ fAllocHandler: TvkuAllocationHandler;
+ fOwnsHandle: Boolean;
+ public
+ destructor Destroy; override;
+ end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ TvkuBufferFactory = class(TObject)
+ private
+ fDeviceCommands: TVkDeviceCommands;
+ fFlags: VkBufferCreateFlags;
+ fSize: VkDeviceSize;
+ fUsage: VkBufferUsageFlags;
+ fSharingMode: TVkSharingMode;
+ fQueueFamilyIndices: TvkuUint32Arr;
+
+ function GetQueueFamilyIndex(const aIndex: Integer): VkUint32;
+ function GetQueueFamilyIndexCount: Integer;
+ procedure SetQueueFamilyIndex(const aIndex: Integer; aValue: VkUint32);
+ public
+ property DeviceCommands: TVkDeviceCommands read fDeviceCommands;
+ property Flags: VkBufferCreateFlags read fFlags write fFlags;
+ property Size: VkDeviceSize read fSize write fSize;
+ property Usage: VkBufferUsageFlags read fUsage write fUsage;
+ property SharingMode: TVkSharingMode read fSharingMode write fSharingMode;
+
+ property QueueFamilyIndices: TvkuUint32Arr read fQueueFamilyIndices;
+ property QueueFamilyIndexCount: Integer read GetQueueFamilyIndexCount;
+ property QueueFamilyIndex[const aIndex: Integer]: VkUint32 read GetQueueFamilyIndex write SetQueueFamilyIndex;
+
+ function CreateBuffer: TvkuBufferEx;
+ function CreateBuffer(
+ const aAllocHandler: TvkuAllocationHandler;
+ const aOwnsHandler: Boolean): TvkuBufferEx;
+
+ constructor Create(const aDevice: TvkuDevice);
+ constructor Create(const aDeviceCommands: TVkDeviceCommands);
+ end;
+
+implementation
+
+uses
+ uvkuUtils;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TvkuBufferEx///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+destructor TvkuBufferEx.Destroy;
+begin
+ if fOwnsHandle then
+ FreeAndNil(fAllocHandler);
+ inherited Destroy;
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TvkuBufferFactory//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TvkuBufferFactory.GetQueueFamilyIndex(const aIndex: Integer): VkUint32;
+begin
+ if (aIndex < low(fQueueFamilyIndices)) or (aIndex > high(fQueueFamilyIndices)) then
+ raise TvkuException.CreateFmt('index (%d) out of range (%d : %d)', [aIndex, Low(fQueueFamilyIndices), High(fQueueFamilyIndices)]);
+ result := fQueueFamilyIndices[aIndex];
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TvkuBufferFactory.GetQueueFamilyIndexCount: Integer;
+begin
+ result := Length(fQueueFamilyIndices);
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TvkuBufferFactory.SetQueueFamilyIndex(const aIndex: Integer; aValue: VkUint32);
+begin
+ if (aIndex < low(fQueueFamilyIndices)) or (aIndex > high(fQueueFamilyIndices)) then
+ raise TvkuException.CreateFmt('index (%d) out of range (%d : %d)', [aIndex, Low(fQueueFamilyIndices), High(fQueueFamilyIndices)]);
+ fQueueFamilyIndices[aIndex] := aValue;
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TvkuBufferFactory.CreateBuffer: TvkuBufferEx;
+begin
+ result := CreateBuffer(nil, false);
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TvkuBufferFactory.CreateBuffer(const aAllocHandler: TvkuAllocationHandler; const aOwnsHandler: Boolean): TvkuBufferEx;
+var
+ CreateInfo: TVkBufferCreateInfo;
+begin
+ FillByte(CreateInfo, 0, SizeOf(CreateInfo));
+ CreateInfo.sType := VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
+ CreateInfo.pNext := nil;
+ CreateInfo.flags := fFlags;
+ CreateInfo.size := fSize;
+ CreateInfo.usage := fUsage;
+ CreateInfo.sharingMode := fSharingMode;
+ CreateInfo.queueFamilyIndexCount := Length(fQueueFamilyIndices);
+ CreateInfo.pQueueFamilyIndices := @fQueueFamilyIndices[0];
+
+ if Assigned(aAllocHandler)
+ then result := TvkuBufferEx.Create(CreateInfo, fDeviceCommands, aAllocHandler.GetAllocationCallbacksPtr)
+ else result := TvkuBufferEx.Create(CreateInfo, fDeviceCommands);
+ try
+ TvkuBufferEx(result).fAllocHandler := aAllocHandler;
+ TvkuBufferEx(result).fOwnsHandle := aOwnsHandler;
+ except
+ FreeAndNil(result);
+ raise;
+ end;
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TvkuBufferFactory.Create(const aDevice: TvkuDevice);
+begin
+ Create(aDevice.DeviceCommands);
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TvkuBufferFactory.Create(const aDeviceCommands: TVkDeviceCommands);
+begin
+ inherited Create;
+ fDeviceCommands := aDeviceCommands;
+end;
+
+end.
+
diff --git a/projects/utils/uvkuBufferView.pas b/projects/utils/uvkuBufferView.pas
new file mode 100644
index 0000000..3c85465
--- /dev/null
+++ b/projects/utils/uvkuBufferView.pas
@@ -0,0 +1,82 @@
+unit uvkuBufferView;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes, SysUtils,
+ Vulkan, uvkuBase;
+
+type
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ TvkuBufferView = class(TvkuAllocHandle)
+ private
+ fHandle: VkBufferView;
+ fDeviceCommands: TVkDeviceCommands;
+
+ procedure CreateHandle(const aCreateInfo: TVkBufferViewCreateInfo);
+ public
+ property Handle: VkBufferView read fHandle;
+ property DeviceCommands: TVkDeviceCommands read fDeviceCommands;
+
+ constructor Create(
+ const aCreateInfo: TVkBufferViewCreateInfo;
+ const aDeviceCommands: TVkDeviceCommands;
+ const aAllocCallbacks: PVkAllocationCallbacks = nil);
+ constructor Create(
+ const aHandle: VkBufferView;
+ const aOwnsHandle: Boolean;
+ const aDeviceCommands: TVkDeviceCommands;
+ const aAllocCallbacks: PVkAllocationCallbacks = nil);
+ destructor Destroy; override;
+ end;
+
+implementation
+
+uses
+ uvkuUtils;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TvkuBufferView/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TvkuBufferView.CreateHandle(const aCreateInfo: TVkBufferViewCreateInfo);
+var err: TVkResult;
+begin
+ err := fDeviceCommands.vkCreateBufferView(fDeviceCommands.Device, @aCreateInfo, AllocCallbacks, @fHandle);
+ if (err < VK_SUCCESS) then
+ raise TvkuErrorException.Create('unable to create buffer view', err);
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TvkuBufferView.Create(const aCreateInfo: TVkBufferViewCreateInfo; const aDeviceCommands: TVkDeviceCommands;
+ const aAllocCallbacks: PVkAllocationCallbacks);
+begin
+ inherited Create;
+ fDeviceCommands := aDeviceCommands;
+ SetAllocCallbacks(aAllocCallbacks);
+ CreateHandle(aCreateInfo);
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TvkuBufferView.Create(const aHandle: VkBufferView; const aOwnsHandle: Boolean;
+ const aDeviceCommands: TVkDeviceCommands; const aAllocCallbacks: PVkAllocationCallbacks);
+begin
+ inherited Create;
+ fHandle := aHandle;
+ fDeviceCommands := aDeviceCommands;
+ OwnsHandle := aOwnsHandle;
+ SetAllocCallbacks(aAllocCallbacks);
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+destructor TvkuBufferView.Destroy;
+begin
+ if OwnsHandle and (fHandle <> VK_INVALID_NDP_HANDLE) then
+ fDeviceCommands.vkDestroyBufferView(fDeviceCommands.Device, fHandle, AllocCallbacks);
+ fHandle := VK_INVALID_NDP_HANDLE;
+ inherited Destroy;
+end;
+
+end.
+
diff --git a/projects/utils/uvkuBufferViewFactory.pas b/projects/utils/uvkuBufferViewFactory.pas
new file mode 100644
index 0000000..44ca264
--- /dev/null
+++ b/projects/utils/uvkuBufferViewFactory.pas
@@ -0,0 +1,107 @@
+unit uvkuBufferViewFactory;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes, SysUtils,
+ Vulkan, uvkuBufferView, uvkuAllocationHandler, uvkuDevice;
+
+type
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ TvkuBufferViewEx = class(TvkuBufferView)
+ private
+ fAllocHandler: TvkuAllocationHandler;
+ fOwnsHandler: Boolean;
+ public
+ destructor Destroy; override;
+ end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ TvkuBufferViewFactory = class(TObject)
+ private
+ fDeviceCommands: TVkDeviceCommands;
+
+ fFlags: VkBufferViewCreateFlags;
+ fBuffer: VkBuffer;
+ fFormat: TVkFormat;
+ fOffset: VkDeviceSize;
+ fRange: VkDeviceSize;
+ public
+ property DeviceCommands: TVkDeviceCommands read fDeviceCommands;
+
+ property Flags: VkBufferViewCreateFlags read fFlags write fFlags;
+ property Buffer: VkBuffer read fBuffer write fBuffer;
+ property Format: TVkFormat read fFormat write fFormat;
+ property Offset: VkDeviceSize read fOffset write fOffset;
+ property Range: VkDeviceSize read fRange write fRange;
+
+ function CreateBufferView: TvkuBufferViewEx;
+ function CreateBufferView(
+ const aAllocHandler: TvkuAllocationHandler;
+ const aOwnsHandler: Boolean): TvkuBufferViewEx;
+
+ constructor Create(const aDevice: TvkuDevice);
+ constructor Create(const aDeviceCommands: TVkDeviceCommands);
+ end;
+
+implementation
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TvkuBufferViewEx///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+destructor TvkuBufferViewEx.Destroy;
+begin
+ inherited Destroy;
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TvkuBufferViewFactory//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TvkuBufferViewFactory.CreateBufferView: TvkuBufferViewEx;
+begin
+ result := CreateBufferView(nil, false);
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TvkuBufferViewFactory.CreateBufferView(const aAllocHandler: TvkuAllocationHandler; const aOwnsHandler: Boolean): TvkuBufferViewEx;
+var
+ CreateInfo: TVkBufferViewCreateInfo;
+begin
+ FillByte(CreateInfo, SizeOf(CreateInfo), 0);
+ CreateInfo.sType := VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
+ CreateInfo.pNext := nil;
+ CreateInfo.flags := fFlags;
+ CreateInfo.buffer := fBuffer;
+ CreateInfo.format := fFormat;
+ CreateInfo.offset := fOffset;
+ CreateInfo.range := fRange;
+
+ if Assigned(aAllocHandler)
+ then result := TvkuBufferViewEx.Create(CreateInfo, fDeviceCommands, aAllocHandler.GetAllocationCallbacksPtr)
+ else result := TvkuBufferViewEx.Create(CreateInfo, fDeviceCommands);
+ try
+ TvkuBufferViewEx(result).fAllocHandler := aAllocHandler;
+ TvkuBufferViewEx(result).fOwnsHandler := aOwnsHandler;
+ except
+ FreeAndNil(result);
+ raise;
+ end;
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TvkuBufferViewFactory.Create(const aDevice: TvkuDevice);
+begin
+ Create(aDevice.DeviceCommands);
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TvkuBufferViewFactory.Create(const aDeviceCommands: TVkDeviceCommands);
+begin
+ inherited Create;
+ fDeviceCommands := aDeviceCommands;
+end;
+
+end.
+
diff --git a/projects/utils/uvkuCommandBuffer.pas b/projects/utils/uvkuCommandBuffer.pas
new file mode 100644
index 0000000..64aad9b
--- /dev/null
+++ b/projects/utils/uvkuCommandBuffer.pas
@@ -0,0 +1,56 @@
+unit uvkuCommandBuffer;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes, SysUtils,
+ Vulkan, uvkuBase;
+
+type
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ TvkuCommandBuffer = class(TvkuHandle)
+ private
+ fHandle: VkCommandBuffer;
+ fCommandPool: VkCommandPool;
+ fDeviceCommands: TVkDeviceCommands;
+ public
+ property Handle: VkCommandBuffer read fHandle;
+ property CommandPool: VkCommandPool read fCommandPool;
+ property DeviceCommands: TVkDeviceCommands read fDeviceCommands;
+
+ constructor Create(
+ const aHandle: VkCommandBuffer;
+ const aOwnsHandle: Boolean;
+ const aCommandPool: VkCommandPool;
+ const aDeviceCommands: TVkDeviceCommands);
+ destructor Destroy; override;
+ end;
+
+implementation
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TvkuCommandBuffer//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TvkuCommandBuffer.Create(const aHandle: VkCommandBuffer; const aOwnsHandle: Boolean;
+ const aCommandPool: VkCommandPool; const aDeviceCommands: TVkDeviceCommands);
+begin
+ inherited Create;
+ fHandle := aHandle;
+ fCommandPool := aCommandPool;
+ fDeviceCommands := aDeviceCommands;
+ OwnsHandle := aOwnsHandle;
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+destructor TvkuCommandBuffer.Destroy;
+begin
+ if OwnsHandle and (fHandle <> VK_INVALID_HANDLE) then
+ fDeviceCommands.vkFreeCommandBuffers(fDeviceCommands.Device, fCommandPool, 1, @fHandle);
+ fHandle := VK_INVALID_HANDLE;
+ inherited Destroy;
+end;
+
+end.
+
diff --git a/projects/utils/uvkuCommandPool.pas b/projects/utils/uvkuCommandPool.pas
new file mode 100644
index 0000000..0b5f251
--- /dev/null
+++ b/projects/utils/uvkuCommandPool.pas
@@ -0,0 +1,128 @@
+unit uvkuCommandPool;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes, SysUtils,
+ Vulkan, uvkuBase, uvkuTypes;
+
+type
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ TvkuCommandPool = class(TvkuAllocHandle)
+ private
+ fHandle: VkCommandPool;
+ fDeviceCommands: TVkDeviceCommands;
+
+ procedure CreateHandle(const aCreateInfo: TVkCommandPoolCreateInfo);
+ public
+ property Handle: VkCommandPool read fHandle;
+ property DeviceCommands: TVkDeviceCommands read fDeviceCommands;
+
+ function CreateCommandBuffer(
+ const aLevel: TVkCommandBufferLevel): VkCommandBuffer;
+ function CreateCommandBuffers(
+ const aLevel: TVkCommandBufferLevel;
+ const aCount: Integer): TvkuCommandBufferArr;
+ procedure FreeCommandBuffer(
+ const aBuffer: VkCommandBuffer);
+ procedure FreeCommandBuffers(
+ const aBuffers: TvkuCommandBufferArr);
+
+ constructor Create(
+ const aCreateInfo: TVkCommandPoolCreateInfo;
+ const aDeviceCommands: TVkDeviceCommands;
+ const aAllocCallbacks: PVkAllocationCallbacks = nil);
+ constructor Create(
+ const aHandle: VkCommandPool;
+ const aOwnsHandle: Boolean;
+ const aDeviceCommands: TVkDeviceCommands;
+ const aAllocCallbacks: PVkAllocationCallbacks = nil);
+ destructor Destroy; override;
+ end;
+
+implementation
+
+uses
+ uvkuUtils;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TvkuCommandPool////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TvkuCommandPool.CreateHandle(const aCreateInfo: TVkCommandPoolCreateInfo);
+var err: TVkResult;
+begin
+ err := fDeviceCommands.vkCreateCommandPool(fDeviceCommands.Device, @aCreateInfo, AllocCallbacks, @fHandle);
+ if (err < VK_SUCCESS) then
+ raise TvkuErrorException.Create('unable to create command pool', err);
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TvkuCommandPool.CreateCommandBuffer(const aLevel: TVkCommandBufferLevel): VkCommandBuffer;
+begin
+ result := CreateCommandBuffers(aLevel, 1)[0];
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TvkuCommandPool.CreateCommandBuffers(const aLevel: TVkCommandBufferLevel; const aCount: Integer): TvkuCommandBufferArr;
+var
+ AllocInfo: TVkCommandBufferAllocateInfo;
+ err: TVkResult;
+begin
+ FillByte(AllocInfo, SizeOf(AllocInfo), 0);
+ AllocInfo.sType := VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
+ AllocInfo.pNext := nil;
+ AllocInfo.commandPool := fHandle;
+ AllocInfo.level := aLevel;
+ AllocInfo.commandBufferCount := aCount;
+ SetLength(result, aCount);
+ err := fDeviceCommands.vkAllocateCommandBuffers(fDeviceCommands.Device, @AllocInfo, @result[0]);
+ if (err < VK_SUCCESS) then
+ raise TvkuErrorException.Create('unable to create command buffers', err);
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TvkuCommandPool.FreeCommandBuffer(const aBuffer: VkCommandBuffer);
+begin
+ FreeCommandBuffers(TvkuCommandBufferArr.Create(aBuffer));
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TvkuCommandPool.FreeCommandBuffers(const aBuffers: TvkuCommandBufferArr);
+begin
+ fDeviceCommands.vkFreeCommandBuffers(fDeviceCommands.Device, fHandle, Length(aBuffers), @aBuffers[0]);
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TvkuCommandPool.Create(const aCreateInfo: TVkCommandPoolCreateInfo;
+ const aDeviceCommands: TVkDeviceCommands; const aAllocCallbacks: PVkAllocationCallbacks);
+begin
+ inherited Create;
+ fDeviceCommands := aDeviceCommands;
+ SetAllocCallbacks(aAllocCallbacks);
+ CreateHandle(aCreateInfo);
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TvkuCommandPool.Create(const aHandle: VkCommandPool; const aOwnsHandle: Boolean;
+ const aDeviceCommands: TVkDeviceCommands; const aAllocCallbacks: PVkAllocationCallbacks);
+begin
+ inherited Create;
+ fHandle := aHandle;
+ fDeviceCommands := aDeviceCommands;
+ OwnsHandle := aOwnsHandle;
+ SetAllocCallbacks(aAllocCallbacks);
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+destructor TvkuCommandPool.Destroy;
+begin
+ if OwnsHandle and (fHandle <> VK_INVALID_NDP_HANDLE) then
+ fDeviceCommands.vkDestroyCommandPool(fDeviceCommands.Device, fHandle, AllocCallbacks);
+ fHandle := VK_INVALID_NDP_HANDLE;
+ inherited Destroy;
+end;
+
+end.
+
diff --git a/projects/utils/uvkuCommandPoolFactory.pas b/projects/utils/uvkuCommandPoolFactory.pas
new file mode 100644
index 0000000..c6a144b
--- /dev/null
+++ b/projects/utils/uvkuCommandPoolFactory.pas
@@ -0,0 +1,92 @@
+unit uvkuCommandPoolFactory;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes, SysUtils,
+ Vulkan, uvkuCommandPool, uvkuDevice, uvkuAllocationHandler;
+
+type
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ TvkuCommandPoolEx = class(TvkuCommandPool)
+ private
+ fAllocHandler: TvkuAllocationHandler;
+ fOwnsHandler: Boolean;
+ public
+ destructor Destroy; override;
+ end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ TvkuCommandPoolFactory = class(TObject)
+ private
+ fDeviceCommands: TVkDeviceCommands;
+ fFlags: VkCommandPoolCreateFlags;
+ fQueueFamilyIndex: VkUint32;
+ public
+ function CreateCommandPool: TvkuCommandPoolEx;
+ function CreateCommandPool(
+ const aAllocHandler: TvkuAllocationHandler;
+ const aOwnsHandler: Boolean): TvkuCommandPoolEx;
+
+ constructor Create(const aDevice: TvkuDevice);
+ constructor Create(const aDeviceCommands: TVkDeviceCommands);
+ end;
+
+implementation
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TvkuCommandPoolEx//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+destructor TvkuCommandPoolEx.Destroy;
+begin
+ if fOwnsHandler then
+ FreeAndNil(fAllocHandler);
+ inherited Destroy;
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TvkuCommandPoolFactory/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TvkuCommandPoolFactory.CreateCommandPool: TvkuCommandPoolEx;
+begin
+ result := CreateCommandPool(nil, false);
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TvkuCommandPoolFactory.CreateCommandPool(const aAllocHandler: TvkuAllocationHandler; const aOwnsHandler: Boolean): TvkuCommandPoolEx;
+var CreateInfo: TVkCommandPoolCreateInfo;
+begin
+ FillByte(CreateInfo, SizeOf(CreateInfo), 0);
+ CreateInfo.sType := VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
+ CreateInfo.pNext := nil;
+ CreateInfo.flags := fFlags;
+ CreateInfo.queueFamilyIndex := fQueueFamilyIndex;
+ if Assigned(aAllocHandler)
+ then result := TvkuCommandPoolEx.Create(CreateInfo, fDeviceCommands, aAllocHandler.GetAllocationCallbacksPtr)
+ else result := TvkuCommandPoolEx.Create(CreateInfo, fDeviceCommands);
+ try
+ TvkuCommandPoolEx(result).fAllocHandler := aAllocHandler;
+ TvkuCommandPoolEx(result).fOwnsHandler := aOwnsHandler;
+ except
+ FreeAndNil(result);
+ raise;
+ end;
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TvkuCommandPoolFactory.Create(const aDevice: TvkuDevice);
+begin
+ Create(aDevice.DeviceCommands);
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TvkuCommandPoolFactory.Create(const aDeviceCommands: TVkDeviceCommands);
+begin
+ inherited Create;
+ fDeviceCommands := aDeviceCommands;
+end;
+
+end.
+
diff --git a/projects/utils/uvkuDevice.pas b/projects/utils/uvkuDevice.pas
index 9f1fdc5..d3dcd23 100644
--- a/projects/utils/uvkuDevice.pas
+++ b/projects/utils/uvkuDevice.pas
@@ -6,35 +6,35 @@ interface
uses
Classes, SysUtils,
- Vulkan;
+ Vulkan, uvkuBase;
type
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- TvkuDevice = class(TObject)
+ TvkuDevice = class(TvkuAllocHandle)
private
fHandle: VkDevice;
- fPhysicalDevice: VkPhysicalDevice;
- fAllocCallbacks: PVkAllocationCallbacks;
fInstanceCommands: TVkInstanceCommands;
fDeviceCommands: TVkDeviceCommands;
procedure CreateHandle(
- const aCreateInfo: PVkDeviceCreateInfo;
- const aAllocCallbacks: PVkAllocationCallbacks);
+ const aPhyDevice: VkPhysicalDevice;
+ const aCreateInfo: PVkDeviceCreateInfo);
public
property Handle: VkDevice read fHandle;
- property PhysicalDevice: VkPhysicalDevice read fPhysicalDevice;
property DeviceCommands: TVkDeviceCommands read fDeviceCommands;
+ function GetQueue(const aQueueFamilyIndex, aQueueIndex: VkUint32): VkQueue;
+
constructor Create(
const aPhysicalDevice: VkPhysicalDevice;
const aCreateInfo: TVkDeviceCreateInfo;
- const aInstanceCommands: TVkInstanceCommands);
+ const aInstanceCommands: TVkInstanceCommands;
+ const aAllocCallbacks: PVkAllocationCallbacks = nil);
constructor Create(
- const aPhysicalDevice: VkPhysicalDevice;
- const aCreateInfo: TVkDeviceCreateInfo;
+ const aHandle: VkDevice;
+ const aOwnsHandle: Boolean;
const aInstanceCommands: TVkInstanceCommands;
- const aAllocCallbacks: TVkAllocationCallbacks);
+ const aAllocCallbacks: PVkAllocationCallbacks = nil);
destructor Destroy; override;
end;
@@ -46,16 +46,12 @@ uses
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TvkuDevice/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-procedure TvkuDevice.CreateHandle(const aCreateInfo: PVkDeviceCreateInfo; const aAllocCallbacks: PVkAllocationCallbacks);
+procedure TvkuDevice.CreateHandle(const aPhyDevice: VkPhysicalDevice; const aCreateInfo: PVkDeviceCreateInfo);
var err: TVkResult;
begin
if not Assigned(fInstanceCommands.vkCreateDevice) then
- raise TvkuException.Create('invalid function pointer: vkCreateDevice; did you load the vulkan core commands?');
- if Assigned(aAllocCallbacks) then begin
- new(fAllocCallbacks);
- fAllocCallbacks^ := aAllocCallbacks^;
- end;
- err := fInstanceCommands.vkCreateDevice(fPhysicalDevice, aCreateInfo, fAllocCallbacks, @fHandle);
+ raise TvkuInvalidFuncPtrException.Create('vkCreateDevice');
+ err := fInstanceCommands.vkCreateDevice(aPhyDevice, aCreateInfo, AllocCallbacks, @fHandle);
if (err < VK_SUCCESS) then
raise TvkuErrorException.Create('unable to create device', err);
fDeviceCommands := LoadDeviceCommands(fInstanceCommands.Instance, fHandle);
@@ -63,39 +59,44 @@ begin
raise TvkuException.Create('unable to load device commands');
end;
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TvkuDevice.GetQueue(const aQueueFamilyIndex, aQueueIndex: VkUint32): VkQueue;
+begin
+ if not Assigned(fDeviceCommands.vkGetDeviceQueue) then
+ raise TvkuInvalidFuncPtrException.Create('vkGetDeviceQueue');
+ fDeviceCommands.vkGetDeviceQueue(fHandle, aQueueFamilyIndex, aQueueIndex, @result);
+ if (result = VK_INVALID_HANDLE) then
+ raise TvkuException.Create('unable to get device queue');
+end;
+
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor TvkuDevice.Create(const aPhysicalDevice: VkPhysicalDevice; const aCreateInfo: TVkDeviceCreateInfo;
- const aInstanceCommands: TVkInstanceCommands);
+ const aInstanceCommands: TVkInstanceCommands; const aAllocCallbacks: PVkAllocationCallbacks);
begin
inherited Create;
fHandle := nil;
- fPhysicalDevice := aPhysicalDevice;
fInstanceCommands := aInstanceCommands;
- CreateHandle(@aCreateInfo, nil);
+ SetAllocCallbacks(aAllocCallbacks);
+ CreateHandle(aPhysicalDevice, @aCreateInfo);
end;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-constructor TvkuDevice.Create(const aPhysicalDevice: VkPhysicalDevice; const aCreateInfo: TVkDeviceCreateInfo;
- const aInstanceCommands: TVkInstanceCommands; const aAllocCallbacks: TVkAllocationCallbacks);
+constructor TvkuDevice.Create(const aHandle: VkDevice; const aOwnsHandle: Boolean;
+ const aInstanceCommands: TVkInstanceCommands; const aAllocCallbacks: PVkAllocationCallbacks);
begin
inherited Create;
- fHandle := nil;
- fPhysicalDevice := aPhysicalDevice;
+ fHandle := aHandle;
fInstanceCommands := aInstanceCommands;
- CreateHandle(@aCreateInfo, @aAllocCallbacks);
+ OwnsHandle := aOwnsHandle;
+ SetAllocCallbacks(aAllocCallbacks);
end;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
destructor TvkuDevice.Destroy;
begin
- if (fHandle <> VK_INVALID_HANDLE) then begin
- fDeviceCommands.vkDestroyDevice(fHandle, fAllocCallbacks);
- fHandle := VK_INVALID_HANDLE;
- end;
- if Assigned(fAllocCallbacks) then begin
- Dispose(fAllocCallbacks);
- fAllocCallbacks := nil;
- end;
+ if OwnsHandle and (fHandle <> VK_INVALID_HANDLE) then
+ fDeviceCommands.vkDestroyDevice(fHandle, AllocCallbacks);
+ fHandle := VK_INVALID_HANDLE;
FreeAndNil(fDeviceCommands);
inherited Destroy;
end;
diff --git a/projects/utils/uvkuDeviceFactory.pas b/projects/utils/uvkuDeviceFactory.pas
index 81af413..e1451de 100644
--- a/projects/utils/uvkuDeviceFactory.pas
+++ b/projects/utils/uvkuDeviceFactory.pas
@@ -6,18 +6,9 @@ interface
uses
Classes, SysUtils,
- Vulkan, uvkuInstance, uvkuDevice, uvkuAllocationHandler;
+ Vulkan, uvkuInstance, uvkuDevice, uvkuAllocationHandler, uvkuTypes;
type
-/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- TvkuQueuePriorityArr = array of VkFloat;
- TvkuQueueCreateInfo = packed record
- Flags: VkDeviceQueueCreateFlags;
- FamilyIndex: VkUint32;
- Priorities: TvkuQueuePriorityArr;
- end;
- TvkuQueueCreateInfoArr = array of TvkuQueueCreateInfo;
-
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TvkuDeviceEx = class(TvkuDevice)
private
@@ -58,11 +49,11 @@ type
property QueueCreateInfo[const aIndex: Integer]: TvkuQueueCreateInfo read GetQueueCreateInfo write SetQueueCreateInfo;
function CreateDevice(
- const aPhysicalDevice: VkPhysicalDevice): TvkuDevice;
+ const aPhysicalDevice: VkPhysicalDevice): TvkuDeviceEx;
function CreateDevice(
const aPhysicalDevice: VkPhysicalDevice;
const aAllocHandler: TvkuAllocationHandler;
- const aOwnsHandler: Boolean): TvkuDevice;
+ const aOwnsHandler: Boolean): TvkuDeviceEx;
constructor Create(const aInstance: TvkuInstance);
constructor Create(const aInstanceCommands: TVkInstanceCommands);
@@ -141,14 +132,14 @@ begin
end;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-function TvkuDeviceFactory.CreateDevice(const aPhysicalDevice: VkPhysicalDevice): TvkuDevice;
+function TvkuDeviceFactory.CreateDevice(const aPhysicalDevice: VkPhysicalDevice): TvkuDeviceEx;
begin
result := CreateDevice(aPhysicalDevice, nil, false);
end;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuDeviceFactory.CreateDevice(const aPhysicalDevice: VkPhysicalDevice;
- const aAllocHandler: TvkuAllocationHandler; const aOwnsHandler: Boolean): TvkuDevice;
+ const aAllocHandler: TvkuAllocationHandler; const aOwnsHandler: Boolean): TvkuDeviceEx;
var
CreateInfo: TVkDeviceCreateInfo;
QueueInfos: array of TVkDeviceQueueCreateInfo;
@@ -193,7 +184,7 @@ begin
CreateInfo.pEnabledFeatures := @fFeatures;
if Assigned(aAllocHandler)
- then result := TvkuDeviceEx.Create(aPhysicalDevice, CreateInfo, fInstanceCommands, aAllocHandler.GetAllocationCallbacks)
+ then result := TvkuDeviceEx.Create(aPhysicalDevice, CreateInfo, fInstanceCommands, aAllocHandler.GetAllocationCallbacksPtr)
else result := TvkuDeviceEx.Create(aPhysicalDevice, CreateInfo, fInstanceCommands);
try
TvkuDeviceEx(result).fAllocHandler := aAllocHandler;
diff --git a/projects/utils/uvkuDeviceMemory.pas b/projects/utils/uvkuDeviceMemory.pas
new file mode 100644
index 0000000..7cc6ed3
--- /dev/null
+++ b/projects/utils/uvkuDeviceMemory.pas
@@ -0,0 +1,100 @@
+unit uvkuDeviceMemory;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes, SysUtils,
+ Vulkan, uvkuBase;
+
+type
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ TvkuDeviceMemory = class(TvkuAllocHandle)
+ private
+ fHandle: VkDeviceMemory;
+ fDeviceCommands: TVkDeviceCommands;
+
+ procedure CreateHandle(const aAllocInfo: TVkMemoryAllocateInfo);
+ public
+ property Handle: VkDeviceMemory read fHandle;
+ property DeviceCommands: TVkDeviceCommands read fDeviceCommands;
+
+ function Map(const aOffset: VkDeviceSize; aSize: VkDeviceSize; aFlags: VkMemoryMapFlags): PVkVoid;
+ procedure Unmap;
+
+ constructor Create(const aAllocInfo: TVkMemoryAllocateInfo; const aDeviceCommands: TVkDeviceCommands;
+ const aAllocCallbacks: PVkAllocationCallbacks);
+ constructor Create(
+ const aHandle: VkDeviceMemory;
+ const aOwnsHandle: Boolean;
+ const aDeviceCommands: TVkDeviceCommands;
+ const aAllocCallbacks: PVkAllocationCallbacks = nil);
+ destructor Destroy; override;
+ end;
+
+implementation
+
+uses
+ uvkuUtils;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TvkuDeviceMemory///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TvkuDeviceMemory.CreateHandle(const aAllocInfo: TVkMemoryAllocateInfo);
+var err: TVkResult;
+begin
+ if not Assigned(fDeviceCommands.vkAllocateMemory) then
+ raise TvkuInvalidFuncPtrException.Create('vkAllocateMemory');
+ err := fDeviceCommands.vkAllocateMemory(fDeviceCommands.Device, @aAllocInfo, AllocCallbacks, @fHandle);
+ if (err < VK_SUCCESS) then
+ raise TvkuErrorException.Create('unable to allocate device memory', err);
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TvkuDeviceMemory.Map(const aOffset: VkDeviceSize; aSize: VkDeviceSize; aFlags: VkMemoryMapFlags): PVkVoid;
+var err: TVkResult;
+begin
+ err := fDeviceCommands.vkMapMemory(fDeviceCommands.Device, fHandle, aOffset, aSize, aFlags, @result);
+ if (err < VK_SUCCESS) then
+ raise TvkuErrorException.Create('unable to map device memory', err);
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TvkuDeviceMemory.Unmap;
+begin
+ fDeviceCommands.vkUnmapMemory(fDeviceCommands.Device, fHandle);
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TvkuDeviceMemory.Create(const aAllocInfo: TVkMemoryAllocateInfo; const aDeviceCommands: TVkDeviceCommands;
+ const aAllocCallbacks: PVkAllocationCallbacks);
+begin
+ inherited Create;
+ fDeviceCommands := aDeviceCommands;
+ SetAllocCallbacks(aAllocCallbacks);
+ CreateHandle(aAllocInfo);
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TvkuDeviceMemory.Create(const aHandle: VkDeviceMemory; const aOwnsHandle: Boolean;
+ const aDeviceCommands: TVkDeviceCommands; const aAllocCallbacks: PVkAllocationCallbacks);
+begin
+ inherited Create;
+ fHandle := aHandle;
+ fDeviceCommands := aDeviceCommands;
+ OwnsHandle := aOwnsHandle;
+ SetAllocCallbacks(aAllocCallbacks);
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+destructor TvkuDeviceMemory.Destroy;
+begin
+ if OwnsHandle and (fHandle <> VK_INVALID_NDP_HANDLE) then
+ fDeviceCommands.vkFreeMemory(fDeviceCommands.Device, fHandle, AllocCallbacks);
+ fHandle := VK_INVALID_NDP_HANDLE;
+ inherited Destroy;
+end;
+
+end.
+
diff --git a/projects/utils/uvkuImage.pas b/projects/utils/uvkuImage.pas
new file mode 100644
index 0000000..eca9d36
--- /dev/null
+++ b/projects/utils/uvkuImage.pas
@@ -0,0 +1,177 @@
+unit uvkuImage;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes, SysUtils,
+ Vulkan, uvkuBase;
+
+type
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ TvkuImage = class(TvkuAllocHandle)
+ private
+ fHandle: VkImage;
+ fDeviceCommands: TVkDeviceCommands;
+
+ procedure CreateHandle(const aCreateInfo: TVkImageCreateInfo);
+ public
+ property Handle: VkImage read fHandle;
+ property DeviceCommands: TVkDeviceCommands read fDeviceCommands;
+
+ function GetMemoryBarrier(
+ const aAspectMask: VkImageAspectFlags;
+ const aOldLayout: TVkImageLayout;
+ const aNewLayout: TVkImageLayout): TVkImageMemoryBarrier;
+
+ constructor Create(
+ const aCreateInfo: TVkImageCreateInfo;
+ const aDeviceCommands: TVkDeviceCommands;
+ const aAllocCallbacks: PVkAllocationCallbacks = nil);
+ constructor Create(
+ const aHandle: VkImage;
+ const aOwnsHandle: Boolean;
+ const aDeviceCommands: TVkDeviceCommands;
+ const aAllocCallbacks: PVkAllocationCallbacks = nil);
+ destructor Destroy; override;
+ end;
+
+implementation
+
+uses
+ uvkuUtils;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TvkuImage//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TvkuImage.CreateHandle(const aCreateInfo: TVkImageCreateInfo);
+var err: TVkResult;
+begin
+ err := fDeviceCommands.vkCreateImage(fDeviceCommands.Device, @aCreateInfo, AllocCallbacks, @fHandle);
+ if (err < VK_SUCCESS) then
+ TvkuErrorException.Create('unable to create image', err);
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TvkuImage.GetMemoryBarrier(
+ const aAspectMask: VkImageAspectFlags;
+ const aOldLayout: TVkImageLayout;
+ const aNewLayout: TVkImageLayout): TVkImageMemoryBarrier;
+var
+ range: TVkImageSubresourceRange;
+begin
+ FillByte(range, SizeOf(range), 0);
+ range.aspectMask := aAspectMask;
+ range.baseMipLevel := 0;
+ range.levelCount := 1;
+ range.baseArrayLayer := 0;
+ range.layerCount := 1;
+
+ FillByte(result, SizeOf(result), 0);
+ result.sType := VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
+ result.pNext := nil;
+ result.srcAccessMask := [];
+ result.dstAccessMask := [];
+ result.oldLayout := aOldLayout;
+ result.newLayout := aNewLayout;
+ result.srcQueueFamilyIndex := 0;
+ result.dstQueueFamilyIndex := 0;
+ result.image := fHandle;
+ result.subresourceRange := range;
+
+ case aOldLayout of
+ // Undefined layout:
+ // Note: Only allowed as initial layout!
+ // Note: Make sure any writes to the image have been finished
+ VK_IMAGE_LAYOUT_UNDEFINED: begin
+ result.srcAccessMask := [ VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_TRANSFER_WRITE_BIT ];
+ end;
+
+ // Old layout is color attachment:
+ // Note: Make sure any writes to the color buffer have been finished
+ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL: begin
+ result.srcAccessMask := [ VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT ];
+ end;
+
+ // Old layout is transfer source:
+ // Note: Make sure any reads from the image have been finished
+ VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL: begin
+ result.srcAccessMask := [ VK_ACCESS_TRANSFER_READ_BIT ];
+ end;
+
+ // Old layout is shader read (sampler, input attachment):
+ // Note: Make sure any shader reads from the image have been finished
+ VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: begin
+ result.srcAccessMask := [ VK_ACCESS_SHADER_READ_BIT ];
+ end;
+ end;
+
+ case aNewLayout of
+ // New layout is transfer destination (copy, blit):
+ // Note: Make sure any copyies to the image have been finished
+ VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL: begin
+ result.dstAccessMask := [ VK_ACCESS_TRANSFER_WRITE_BIT ];
+ end;
+
+ // New layout is transfer source (copy, blit):
+ // Note: Make sure any reads from and writes to the image have been finished
+ VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL: begin
+ result.srcAccessMask := result.srcAccessMask + [ VK_ACCESS_TRANSFER_READ_BIT ];
+ result.dstAccessMask := [ VK_ACCESS_TRANSFER_READ_BIT ];
+ end;
+
+ // New layout is color attachment:
+ // Note: Make sure any writes to the color buffer hav been finished
+ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL: begin
+ result.dstAccessMask := [ VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT ];
+ result.srcAccessMask := [ VK_ACCESS_TRANSFER_READ_BIT ];
+ end;
+
+ // New layout is depth attachment:
+ // Note: Make sure any writes to depth/stencil buffer have been finished
+ VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL: begin
+ result.dstAccessMask := result.dstAccessMask + [ VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT ];
+ end;
+
+ // New layout is shader read (sampler, input attachment):
+ // Note: Make sure any writes to the image have been finished
+ VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: begin
+ result.srcAccessMask := [ VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_TRANSFER_WRITE_BIT ];
+ result.dstAccessMask := [ VK_ACCESS_SHADER_READ_BIT ];
+ end;
+ end;
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TvkuImage.Create(const aCreateInfo: TVkImageCreateInfo; const aDeviceCommands: TVkDeviceCommands;
+ const aAllocCallbacks: PVkAllocationCallbacks);
+begin
+ inherited Create;
+ fDeviceCommands := aDeviceCommands;
+ SetAllocCallbacks(aAllocCallbacks);
+ CreateHandle(aCreateInfo);
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TvkuImage.Create(const aHandle: VkImage; const aOwnsHandle: Boolean;
+ const aDeviceCommands: TVkDeviceCommands; const aAllocCallbacks: PVkAllocationCallbacks);
+begin
+ inherited Create;
+ fHandle := aHandle;
+ fDeviceCommands := aDeviceCommands;
+ OwnsHandle := aOwnsHandle;
+ SetAllocCallbacks(aAllocCallbacks);
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+destructor TvkuImage.Destroy;
+begin
+ if OwnsHandle and (fHandle <> VK_INVALID_NDP_HANDLE) then
+ fDeviceCommands.vkDestroyImage(fDeviceCommands.Device, fHandle, AllocCallbacks);
+ fHandle := VK_INVALID_NDP_HANDLE;
+ inherited Destroy;
+end;
+
+end.
+
diff --git a/projects/utils/uvkuImageFactory.pas b/projects/utils/uvkuImageFactory.pas
new file mode 100644
index 0000000..2c03673
--- /dev/null
+++ b/projects/utils/uvkuImageFactory.pas
@@ -0,0 +1,161 @@
+unit uvkuImageFactory;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes, SysUtils,
+ Vulkan, uvkuImage, uvkuDevice, uvkuAllocationHandler, uvkuTypes;
+
+type
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ TvkuImageEx = class(TvkuImage)
+ private
+ fAllocHandler: TvkuAllocationHandler;
+ fOwnsHandle: Boolean;
+ public
+ destructor Destroy; override;
+ end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ TvkuImageFactory = class(TObject)
+ private
+ fDeviceCommands: TVkDeviceCommands;
+ fFlags: VkImageCreateFlags;
+ fImageType: TVkImageType;
+ fFormat: TVkFormat;
+ fExtent: TVkExtent3D;
+ fMipLevels: VkUint32;
+ fArrayLayers: VkUint32;
+ fSamples: TVkSampleCountFlagBits;
+ fTiling: TVkImageTiling;
+ fUsage: VkImageUsageFlags;
+ fSharingMode: TVkSharingMode;
+ fQueueFamilyIndices: TvkuUint32Arr;
+ fInitialLayout: TVkImageLayout;
+
+ function GetQueueFamilyIndex(const aIndex: Integer): VkUint32;
+ function GetQueueFamilyIndexCount: Integer;
+ procedure SetQueueFamilyIndex(const aIndex: Integer; aValue: VkUint32);
+ public
+ property DeviceCommands: TVkDeviceCommands read fDeviceCommands;
+ property Flags: VkImageCreateFlags read fFlags write fFlags;
+ property ImageType: TVkImageType read fImageType write fImageType;
+ property Format: TVkFormat read fFormat write fFormat;
+ property Extent: TVkExtent3D read fExtent write fExtent;
+ property MipLevels: VkUint32 read fMipLevels write fMipLevels;
+ property ArrayLayers: VkUint32 read fArrayLayers write fArrayLayers;
+ property Samples: TVkSampleCountFlagBits read fSamples write fSamples;
+ property Tiling: TVkImageTiling read fTiling write fTiling;
+ property Usage: VkImageUsageFlags read fUsage write fUsage;
+ property SharingMode: TVkSharingMode read fSharingMode write fSharingMode;
+ property InitialLayout: TVkImageLayout read fInitialLayout write fInitialLayout;
+
+ property QueueFamilyIndices: TvkuUint32Arr read fQueueFamilyIndices;
+ property QueueFamilyIndexCount: Integer read GetQueueFamilyIndexCount;
+ property QueueFamilyIndex[const aIndex: Integer]: VkUint32 read GetQueueFamilyIndex write SetQueueFamilyIndex;
+
+ function CreateImage: TvkuImageEx;
+ function CreateImage(
+ const aAllocHandler: TvkuAllocationHandler;
+ const aOwnsHandler: Boolean): TvkuImageEx;
+
+ constructor Create(const aDevice: TvkuDevice);
+ constructor Create(const aDeviceCommands: TVkDeviceCommands);
+ end;
+
+implementation
+
+uses
+ uvkuUtils;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TvkuImageEx////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+destructor TvkuImageEx.Destroy;
+begin
+ if fOwnsHandle then
+ FreeAndNil(fAllocHandler);
+ inherited Destroy;
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TvkuImageFactory///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TvkuImageFactory.GetQueueFamilyIndex(const aIndex: Integer): VkUint32;
+begin
+ if (aIndex < low(fQueueFamilyIndices)) or (aIndex > high(fQueueFamilyIndices)) then
+ raise TvkuException.CreateFmt('index (%d) out of range (%d : %d)', [aIndex, Low(fQueueFamilyIndices), High(fQueueFamilyIndices)]);
+ result := fQueueFamilyIndices[aIndex];
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TvkuImageFactory.GetQueueFamilyIndexCount: Integer;
+begin
+ result := Length(fQueueFamilyIndices);
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TvkuImageFactory.SetQueueFamilyIndex(const aIndex: Integer; aValue: VkUint32);
+begin
+ if (aIndex < low(fQueueFamilyIndices)) or (aIndex > high(fQueueFamilyIndices)) then
+ raise TvkuException.CreateFmt('index (%d) out of range (%d : %d)', [aIndex, Low(fQueueFamilyIndices), High(fQueueFamilyIndices)]);
+ fQueueFamilyIndices[aIndex] := aValue;
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TvkuImageFactory.CreateImage: TvkuImageEx;
+begin
+ result := CreateImage(nil, false);
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TvkuImageFactory.CreateImage(const aAllocHandler: TvkuAllocationHandler; const aOwnsHandler: Boolean): TvkuImageEx;
+var
+ CreateInfo: TVkImageCreateInfo;
+begin
+ FillByte(CreateInfo, 0, SizeOf(CreateInfo));
+ CreateInfo.sType := VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
+ CreateInfo.pNext := nil;
+ CreateInfo.flags := fFlags;
+ CreateInfo.imageType := fImageType;
+ CreateInfo.format := fFormat;
+ CreateInfo.extent := fExtent;
+ CreateInfo.mipLevels := fMipLevels;
+ CreateInfo.arrayLayers := fArrayLayers;
+ CreateInfo.samples := fSamples;
+ CreateInfo.tiling := fTiling;
+ CreateInfo.usage := fUsage;
+ CreateInfo.sharingMode := fSharingMode;
+ CreateInfo.queueFamilyIndexCount := Length(fQueueFamilyIndices);
+ CreateInfo.pQueueFamilyIndices := @fQueueFamilyIndices[0];
+ CreateInfo.initialLayout := fInitialLayout;
+
+ if Assigned(aAllocHandler)
+ then result := TvkuImageEx.Create(CreateInfo, fDeviceCommands, aAllocHandler.GetAllocationCallbacksPtr)
+ else result := TvkuImageEx.Create(CreateInfo, fDeviceCommands);
+ try
+ TvkuImageEx(result).fAllocHandler := aAllocHandler;
+ TvkuImageEx(result).fOwnsHandle := aOwnsHandler;
+ except
+ FreeAndNil(result);
+ raise;
+ end;
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TvkuImageFactory.Create(const aDevice: TvkuDevice);
+begin
+ Create(aDevice.DeviceCommands);
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TvkuImageFactory.Create(const aDeviceCommands: TVkDeviceCommands);
+begin
+ inherited Create;
+ fDeviceCommands := aDeviceCommands;
+end;
+
+end.
+
diff --git a/projects/utils/uvkuImageView.pas b/projects/utils/uvkuImageView.pas
new file mode 100644
index 0000000..e4ec45a
--- /dev/null
+++ b/projects/utils/uvkuImageView.pas
@@ -0,0 +1,84 @@
+unit uvkuImageView;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes, SysUtils,
+ Vulkan, uvkuBase;
+
+type
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ TvkuImageView = class(TvkuAllocHandle)
+ private
+ fHandle: VkImageView;
+ fDeviceCommands: TVkDeviceCommands;
+
+ procedure CreateHandle(const aCreateInfo: TVkImageViewCreateInfo);
+ public
+ property Handle: VkImageView read fHandle;
+ property DeviceCommands: TVkDeviceCommands read fDeviceCommands;
+
+ constructor Create(
+ const aCreateInfo: TVkImageViewCreateInfo;
+ const aDeviceCommands: TVkDeviceCommands;
+ const aAllocCallbacks: PVkAllocationCallbacks = nil);
+ constructor Create(
+ const aHandle: VkImageView;
+ const aOwnsHandle: Boolean;
+ const aDeviceCommands: TVkDeviceCommands;
+ const aAllocCallbacks: PVkAllocationCallbacks = nil);
+ destructor Destroy; override;
+ end;
+
+implementation
+
+uses
+ uvkuUtils;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TvkuImageView//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TvkuImageView.CreateHandle(const aCreateInfo: TVkImageViewCreateInfo);
+var err: TVkResult;
+begin
+ if not Assigned(fDeviceCommands.vkCreateImageView) then
+ raise TvkuInvalidFuncPtrException.Create('vkCreateImageView');
+ err := fDeviceCommands.vkCreateImageView(fDeviceCommands.Device, @aCreateInfo, AllocCallbacks, @fHandle);
+ if (err < VK_SUCCESS) then
+ raise TvkuErrorException.Create('unable to create image view', err);
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TvkuImageView.Create(const aCreateInfo: TVkImageViewCreateInfo; const aDeviceCommands: TVkDeviceCommands;
+ const aAllocCallbacks: PVkAllocationCallbacks);
+begin
+ inherited Create;
+ fDeviceCommands := aDeviceCommands;
+ SetAllocCallbacks(aAllocCallbacks);
+ CreateHandle(aCreateInfo);
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TvkuImageView.Create(const aHandle: VkImageView; const aOwnsHandle: Boolean;
+ const aDeviceCommands: TVkDeviceCommands; const aAllocCallbacks: PVkAllocationCallbacks);
+begin
+ inherited Create;
+ fHandle := aHandle;
+ fDeviceCommands := aDeviceCommands;
+ OwnsHandle := aOwnsHandle;
+ SetAllocCallbacks(aAllocCallbacks);
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+destructor TvkuImageView.Destroy;
+begin
+ if OwnsHandle and (fHandle <> VK_INVALID_NDP_HANDLE) then
+ fDeviceCommands.vkDestroyImageView(fDeviceCommands.Device, fHandle, AllocCallbacks);
+ fHandle := VK_INVALID_NDP_HANDLE;
+ inherited Destroy;
+end;
+
+end.
+
diff --git a/projects/utils/uvkuImageViewFactory.pas b/projects/utils/uvkuImageViewFactory.pas
new file mode 100644
index 0000000..e59b285
--- /dev/null
+++ b/projects/utils/uvkuImageViewFactory.pas
@@ -0,0 +1,110 @@
+unit uvkuImageViewFactory;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes, SysUtils,
+ Vulkan, uvkuAllocationHandler, uvkuImageView, uvkuDevice;
+
+type
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ TvkuImageViewEx = class(TvkuImageView)
+ private
+ fAllocHandler: TvkuAllocationHandler;
+ fOwnsHandler: Boolean;
+ public
+ destructor Destroy; override;
+ end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ TvkuImageViewFactory = class(TObject)
+ private
+ fDeviceCommands: TVkDeviceCommands;
+
+ fFlags: VkImageViewCreateFlags;
+ fImage: VkImage;
+ fViewType: TVkImageViewType;
+ fFormat: TVkFormat;
+ fComponents: TVkComponentMapping;
+ fSubresourceRange: TVkImageSubresourceRange;
+ public
+ property DeviceCommands: TVkDeviceCommands read fDeviceCommands;
+
+ property Flags: VkImageViewCreateFlags read fFlags write fFlags;
+ property Image: VkImage read fImage write fImage;
+ property ViewType: TVkImageViewType read fViewType write fViewType;
+ property Format: TVkFormat read fFormat write fFormat;
+ property Components: TVkComponentMapping read fComponents write fComponents;
+ property SubresourceRange: TVkImageSubresourceRange read fSubresourceRange write fSubresourceRange;
+
+ function CreateImageView: TvkuImageViewEx;
+ function CreateImageView(
+ const aAllocHandler: TvkuAllocationHandler;
+ const aOwnsHandler: Boolean): TvkuImageViewEx;
+
+ constructor Create(const aDevice: TvkuDevice);
+ constructor Create(const aDeviceCommands: TVkDeviceCommands);
+ end;
+
+implementation
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TvkuImageViewEx////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+destructor TvkuImageViewEx.Destroy;
+begin
+ inherited Destroy;
+ if fOwnsHandler then
+ FreeAndNil(fAllocHandler);
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TvkuImageViewFactory///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TvkuImageViewFactory.CreateImageView: TvkuImageViewEx;
+begin
+ result := CreateImageView(nil, false);
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TvkuImageViewFactory.CreateImageView(const aAllocHandler: TvkuAllocationHandler; const aOwnsHandler: Boolean): TvkuImageViewEx;
+var CreateInfo: TVkImageViewCreateInfo;
+begin
+ FillByte(CreateInfo, SizeOf(CreateInfo), 0);
+ CreateInfo.sType := VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
+ CreateInfo.pNext := nil;
+ CreateInfo.flags := fFlags;
+ CreateInfo.image := fImage;
+ CreateInfo.viewType := fViewType;
+ CreateInfo.format := fFormat;
+ CreateInfo.components := fComponents;
+ CreateInfo.subresourceRange := fSubresourceRange;
+ if Assigned(aAllocHandler)
+ then result := TvkuImageViewEx.Create(CreateInfo, fDeviceCommands, aAllocHandler.GetAllocationCallbacksPtr)
+ else result := TvkuImageViewEx.Create(CreateInfo, fDeviceCommands);
+ try
+ TvkuImageViewEx(result).fAllocHandler := aAllocHandler;
+ TvkuImageViewEx(result).fOwnsHandler := aOwnsHandler;
+ except
+ FreeAndNil(result);
+ raise;
+ end;
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TvkuImageViewFactory.Create(const aDevice: TvkuDevice);
+begin
+ Create(aDevice.DeviceCommands);
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TvkuImageViewFactory.Create(const aDeviceCommands: TVkDeviceCommands);
+begin
+ inherited Create;
+ fDeviceCommands := aDeviceCommands;
+end;
+
+end.
+
diff --git a/projects/utils/uvkuInstance.pas b/projects/utils/uvkuInstance.pas
index 9424ccb..8789f2a 100644
--- a/projects/utils/uvkuInstance.pas
+++ b/projects/utils/uvkuInstance.pas
@@ -6,35 +6,32 @@ interface
uses
Classes, SysUtils,
- Vulkan;
+ Vulkan, uvkuBase, uvkuTypes;
type
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- TvkuPhysicalDeviceArr = array of VkPhysicalDevice;
- TvkuInstance = class(TObject)
+ TvkuInstance = class(TvkuAllocHandle)
private
fHandle: VkInstance;
- fAllocCallbacks: PVkAllocationCallbacks;
fPhysicalDevices: TvkuPhysicalDeviceArr;
fInstanceCommands: TVkInstanceCommands;
procedure UpdatePhysicalDevices;
protected
- procedure CreateHandle(const aCreateInfo: PVkInstanceCreateInfo; const aAllocCallbacks: PVkAllocationCallbacks);
- {%H-}constructor Create;
+ procedure CreateHandle(const aCreateInfo: PVkInstanceCreateInfo);
public
property Handle: VkInstance read fHandle;
property InstanceCommands: TVkInstanceCommands read fInstanceCommands;
function GetPhysicalDevices: TvkuPhysicalDeviceArr;
- constructor Create(
- const aCreateInfo: TVkInstanceCreateInfo);
-
constructor Create(
const aCreateInfo: TVkInstanceCreateInfo;
- const aAllocCallbacks: TVkAllocationCallbacks);
-
+ const aAllocCallbacks: PVkAllocationCallbacks = nil);
+ constructor Create(
+ const aHandle: VkInstance;
+ const aOwnsHandle: Boolean;
+ const aAllocCallbacks: PVkAllocationCallbacks = nil);
destructor Destroy; override;
end;
@@ -65,14 +62,10 @@ begin
end;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-procedure TvkuInstance.CreateHandle(const aCreateInfo: PVkInstanceCreateInfo; const aAllocCallbacks: PVkAllocationCallbacks);
+procedure TvkuInstance.CreateHandle(const aCreateInfo: PVkInstanceCreateInfo);
var e: TVkResult;
begin
- if Assigned(aAllocCallbacks) then begin
- new(fAllocCallbacks);
- fAllocCallbacks^ := aAllocCallbacks^;
- end;
- e := vkCreateInstance(aCreateInfo, fAllocCallbacks, @fHandle);
+ e := vkCreateInstance(aCreateInfo, AllocCallbacks, @fHandle);
if (e < VK_SUCCESS) then
raise TvkuErrorException.Create('unable to create vulkan instance', e);
fInstanceCommands := LoadInstanceCommands(fHandle);
@@ -80,14 +73,6 @@ begin
raise TvkuException.Create('unable to load instance commands');
end;
-/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-constructor TvkuInstance.Create;
-begin
- inherited Create;
- fHandle := nil;
- fAllocCallbacks := nil;
-end;
-
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuInstance.GetPhysicalDevices: TvkuPhysicalDeviceArr;
begin
@@ -96,30 +81,29 @@ begin
end;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-constructor TvkuInstance.Create(const aCreateInfo: TVkInstanceCreateInfo);
+constructor TvkuInstance.Create(const aCreateInfo: TVkInstanceCreateInfo; const aAllocCallbacks: PVkAllocationCallbacks);
begin
- Create;
- CreateHandle(@aCreateInfo, nil);
+ inherited Create;
+ fHandle := VK_INVALID_HANDLE;
+ SetAllocCallbacks(aAllocCallbacks);
+ CreateHandle(@aCreateInfo);
end;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-constructor TvkuInstance.Create(const aCreateInfo: TVkInstanceCreateInfo; const aAllocCallbacks: TVkAllocationCallbacks);
+constructor TvkuInstance.Create(const aHandle: VkInstance; const aOwnsHandle: Boolean; const aAllocCallbacks: PVkAllocationCallbacks);
begin
- Create;
- CreateHandle(@aCreateInfo, @aAllocCallbacks);
+ inherited Create;
+ fHandle := aHandle;
+ OwnsHandle := aOwnsHandle;
+ SetAllocCallbacks(aAllocCallbacks);
end;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
destructor TvkuInstance.Destroy;
begin
- if (fHandle <> VK_INVALID_HANDLE) then begin
- InstanceCommands.vkDestroyInstance(fHandle, fAllocCallbacks);
- fHandle := VK_INVALID_HANDLE;
- end;
- if Assigned(fAllocCallbacks) then begin
- Dispose(fAllocCallbacks);
- fAllocCallbacks := nil;
- end;
+ if OwnsHandle and (fHandle <> VK_INVALID_HANDLE) then
+ InstanceCommands.vkDestroyInstance(fHandle, AllocCallbacks);
+ fHandle := VK_INVALID_HANDLE;
FreeAndNil(fInstanceCommands);
inherited Destroy;
end;
diff --git a/projects/utils/uvkuInstanceFactory.pas b/projects/utils/uvkuInstanceFactory.pas
index 6b6d666..a8e94f5 100644
--- a/projects/utils/uvkuInstanceFactory.pas
+++ b/projects/utils/uvkuInstanceFactory.pas
@@ -7,18 +7,9 @@ interface
uses
Classes, SysUtils,
- Vulkan, uvkuInstance, uvkuAllocationHandler;
+ Vulkan, uvkuInstance, uvkuAllocationHandler, uvkuTypes;
type
-/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- TvkuApplicationInfo = packed record
- AppName: String;
- AppVersion: VkVersion;
- EngineName: String;
- EngineVersion: VkVersion;
- ApiVersion: VkVersion;
- end;
-
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TvkuInstanceEx = class(TvkuInstance)
private
@@ -45,10 +36,10 @@ type
property Layers: TStrings read GetLayers;
property Extensions: TStrings read GetExtensions;
- function CreateInstance: TvkuInstance;
+ function CreateInstance: TvkuInstanceEx;
function CreateInstance(
const aAllocHandler: TvkuAllocationHandler;
- const aOwnsHandler: Boolean): TvkuInstance;
+ const aOwnsHandler: Boolean): TvkuInstanceEx;
constructor Create;
destructor Destroy; override;
@@ -110,13 +101,13 @@ begin
end;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-function TvkuInstanceFactory.CreateInstance: TvkuInstance;
+function TvkuInstanceFactory.CreateInstance: TvkuInstanceEx;
begin
result := CreateInstance(nil, false);
end;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-function TvkuInstanceFactory.CreateInstance(const aAllocHandler: TvkuAllocationHandler; const aOwnsHandler: Boolean): TvkuInstance;
+function TvkuInstanceFactory.CreateInstance(const aAllocHandler: TvkuAllocationHandler; const aOwnsHandler: Boolean): TvkuInstanceEx;
var
CreateInfo: TVkInstanceCreateInfo;
AppInfo: TVkApplicationInfo;
@@ -152,7 +143,7 @@ begin
CreateInfo.ppEnabledExtensionNames := @ext[0];
if Assigned(aAllocHandler)
- then result := TvkuInstanceEx.Create(CreateInfo, aAllocHandler.GetAllocationCallbacks)
+ then result := TvkuInstanceEx.Create(CreateInfo, aAllocHandler.GetAllocationCallbacksPtr)
else result := TvkuInstanceEx.Create(CreateInfo);
try
TvkuInstanceEx(result).fAllocHandler := aAllocHandler;
diff --git a/projects/utils/uvkuPhysicalDevice.pas b/projects/utils/uvkuPhysicalDevice.pas
index bf2764e..37f4a3b 100644
--- a/projects/utils/uvkuPhysicalDevice.pas
+++ b/projects/utils/uvkuPhysicalDevice.pas
@@ -6,20 +6,11 @@ interface
uses
Classes, SysUtils,
- Vulkan, uvkuInstance;
+ Vulkan, uvkuBase, uvkuTypes;
type
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- TvkuQueueFamilyPropertiesArr = array of TVkQueueFamilyProperties;
- TvkuSparseImageFormatPropertiesArr = array of TVkSparseImageFormatProperties;
- TvkuSurfaceFormatArr = array of TVkSurfaceFormatKHR;
- TvkuPresentModeArr = array of TVkPresentModeKHR;
- TvkuDisplayPropertiesArr = array of TVkDisplayPropertiesKHR;
- TvkuDisplayPlanePropertiesArr = array of TVkDisplayPlanePropertiesKHR;
- TvkuDisplayArr = array of VkDisplayKHR;
- TvkuDisplayModePropertiesArr = array of TVkDisplayModePropertiesKHR;
-
- TvkuPhysicalDevice = class(TObject)
+ TvkuPhysicalDevice = class(TvkuObject)
private
fHandle: VkPhysicalDevice;
fInstanceCommands: TVkInstanceCommands;
@@ -59,7 +50,9 @@ type
property Handle: VkPhysicalDevice read fHandle;
property InstanceCommands: TVkInstanceCommands read fInstanceCommands;
- constructor Create(const aHandle: VkPhysicalDevice; const aInstanceCommands: TVkInstanceCommands);
+ constructor Create(
+ const aHandle: VkPhysicalDevice;
+ const aInstanceCommands: TVkInstanceCommands);
end;
implementation
@@ -73,7 +66,7 @@ uses
function TvkuPhysicalDevice.GetFeatures: TVkPhysicalDeviceFeatures;
begin
if not Assigned(fInstanceCommands.vkGetPhysicalDeviceFeatures) then
- raise TvkuException.Create('invalid function pointer: vkGetPhysicalDeviceFeatures; did you load the vulkan core commands?');
+ raise TvkuInvalidFuncPtrException.Create('vkGetPhysicalDeviceFeatures');
fInstanceCommands.vkGetPhysicalDeviceFeatures(fHandle, @result);
end;
@@ -81,7 +74,7 @@ end;
function TvkuPhysicalDevice.GetProperties: TVkPhysicalDeviceProperties;
begin
if not Assigned(fInstanceCommands.vkGetPhysicalDeviceProperties) then
- raise TvkuException.Create('invalid function pointer: vkGetPhysicalDeviceProperties; did you load the vulkan core commands?');
+ raise TvkuInvalidFuncPtrException.Create('vkGetPhysicalDeviceProperties');
fInstanceCommands.vkGetPhysicalDeviceProperties(fHandle, @result);
end;
@@ -89,7 +82,7 @@ end;
function TvkuPhysicalDevice.GetMemoryProperties: TVkPhysicalDeviceMemoryProperties;
begin
if not Assigned(fInstanceCommands.vkGetPhysicalDeviceMemoryProperties) then
- raise TvkuException.Create('invalid function pointer: vkGetPhysicalDeviceMemoryProperties; did you load the vulkan core commands?');
+ raise TvkuInvalidFuncPtrException.Create('vkGetPhysicalDeviceMemoryProperties');
fInstanceCommands.vkGetPhysicalDeviceMemoryProperties(fHandle, @result);
end;
@@ -99,7 +92,7 @@ var c: VkUint32;
begin
result := nil;
if not Assigned(fInstanceCommands.vkGetPhysicalDeviceQueueFamilyProperties) then
- raise TvkuException.Create('invalid function pointer: vkGetPhysicalDeviceQueueFamilyProperties; did you load the vulkan core commands?');
+ raise TvkuInvalidFuncPtrException.Create('vkGetPhysicalDeviceQueueFamilyProperties');
fInstanceCommands.vkGetPhysicalDeviceQueueFamilyProperties(fHandle, @c, nil);
SetLength(result, c);
fInstanceCommands.vkGetPhysicalDeviceQueueFamilyProperties(fHandle, @c, @result[0]);
@@ -109,7 +102,7 @@ end;
function TvkuPhysicalDevice.GetFormatProperties(const aFormat: TVkFormat): TVkFormatProperties;
begin
if not Assigned(fInstanceCommands.vkGetPhysicalDeviceFormatProperties) then
- raise TvkuException.Create('invalid function pointer: vkGetPhysicalDeviceFormatProperties; did you load the vulkan core commands?');
+ raise TvkuInvalidFuncPtrException.Create('vkGetPhysicalDeviceFormatProperties');
fInstanceCommands.vkGetPhysicalDeviceFormatProperties(fHandle, aFormat, @result);
end;
@@ -119,7 +112,7 @@ function TvkuPhysicalDevice.GetImageFormatProperties(const aFormat: TVkFormat; c
var err: TVkResult;
begin
if not Assigned(fInstanceCommands.vkGetPhysicalDeviceImageFormatProperties) then
- raise TvkuException.Create('invalid function pointer: vkGetPhysicalDeviceImageFormatProperties; did you load the vulkan core commands?');
+ raise TvkuInvalidFuncPtrException.Create('vkGetPhysicalDeviceImageFormatProperties');
err := fInstanceCommands.vkGetPhysicalDeviceImageFormatProperties(fHandle, aFormat, aImageType, aTiling, aUsage, aFlags, @result);
if (err < VK_SUCCESS) then
raise TvkuErrorException.Create('unable to get physical device image format properties', err);
@@ -132,7 +125,7 @@ var c: VkUint32;
begin
result := nil;
if not Assigned(fInstanceCommands.vkGetPhysicalDeviceSparseImageFormatProperties) then
- raise TvkuException.Create('invalid function pointer: vkGetPhysicalDeviceSparseImageFormatProperties; did you load the vulkan core commands?');
+ raise TvkuInvalidFuncPtrException.Create('vkGetPhysicalDeviceSparseImageFormatProperties');
fInstanceCommands.vkGetPhysicalDeviceSparseImageFormatProperties(fHandle, aFormat, aImageType, aSamples, aUsage, aTiling, @c, nil);
SetLength(result, c);
fInstanceCommands.vkGetPhysicalDeviceSparseImageFormatProperties(fHandle, aFormat, aImageType, aSamples, aUsage, aTiling, @c, @result[0]);
@@ -145,7 +138,7 @@ var
err: TVkResult;
begin
if not Assigned(fInstanceCommands.vkGetPhysicalDeviceSurfaceSupportKHR) then
- raise TvkuException.Create('invalid function pointer: vkGetPhysicalDeviceSurfaceSupportKHR; did you enabled the VK_KHR_surface extension?');
+ raise TvkuInvalidFuncPtrException.Create('vkGetPhysicalDeviceSurfaceSupportKHR', 'VK_KHR_surface');
err := fInstanceCommands.vkGetPhysicalDeviceSurfaceSupportKHR(fHandle, aQueueFamilyIndex, aSurface, @b);
if (err < VK_SUCCESS) then
raise TvkuErrorException.Create('unable to get physical device surface support', err);
@@ -158,7 +151,7 @@ var
err: TVkResult;
begin
if not Assigned(fInstanceCommands.vkGetPhysicalDeviceSurfaceCapabilitiesKHR) then
- raise TvkuException.Create('invalid function pointer: vkGetPhysicalDeviceSurfaceCapabilitiesKHR; did you enabled the VK_KHR_surface extension?');
+ raise TvkuInvalidFuncPtrException.Create('vkGetPhysicalDeviceSurfaceCapabilitiesKHR', 'VK_KHR_surface');
err := fInstanceCommands.vkGetPhysicalDeviceSurfaceCapabilitiesKHR(fHandle, aSurface, @result);
if (err < VK_SUCCESS) then
raise TvkuErrorException.Create('unable to get physical device surface capabilities', err);
@@ -170,7 +163,7 @@ var c: VkUint32;
begin
result := nil;
if not Assigned(fInstanceCommands.vkGetPhysicalDeviceSurfaceFormatsKHR) then
- raise TvkuException.Create('invalid function pointer: vkGetPhysicalDeviceSurfaceFormatsKHR; did you enabled the VK_KHR_surface extension?');
+ raise TvkuInvalidFuncPtrException.Create('vkGetPhysicalDeviceSurfaceFormatsKHR', 'VK_KHR_surface');
fInstanceCommands.vkGetPhysicalDeviceSurfaceFormatsKHR(fHandle, aSurface, @c, nil);
SetLength(result, c);
fInstanceCommands.vkGetPhysicalDeviceSurfaceFormatsKHR(fHandle, aSurface, @c, @result[0]);
@@ -184,7 +177,7 @@ var
begin
result := nil;
if not Assigned(fInstanceCommands.vkGetPhysicalDeviceSurfacePresentModesKHR) then
- raise TvkuException.Create('invalid function pointer: vkGetPhysicalDeviceSurfacePresentModesKHR; did you enabled the VK_KHR_surface extension?');
+ raise TvkuInvalidFuncPtrException.Create('vkGetPhysicalDeviceSurfacePresentModesKHR', 'VK_KHR_surface');
err := fInstanceCommands.vkGetPhysicalDeviceSurfacePresentModesKHR(fHandle, aSurface, @c, nil);
if (err < VK_SUCCESS) then
raise TvkuErrorException.Create('unable to get physical device surface present mode count', err);
@@ -202,7 +195,7 @@ var
begin
result := nil;
if not Assigned(fInstanceCommands.vkGetPhysicalDeviceDisplayPropertiesKHR) then
- raise TvkuException.Create('invalid function pointer: vkGetPhysicalDeviceDisplayPropertiesKHR; did you enabled the VK_KHR_display extension?');
+ raise TvkuInvalidFuncPtrException.Create('vkGetPhysicalDeviceDisplayPropertiesKHR', 'VK_KHR_display');
err := fInstanceCommands.vkGetPhysicalDeviceDisplayPropertiesKHR(fHandle, @c, nil);
if (err < VK_SUCCESS) then
raise TvkuErrorException.Create('unable to get physical device display property count', err);
@@ -220,7 +213,7 @@ var
begin
result := nil;
if not Assigned(fInstanceCommands.vkGetPhysicalDeviceDisplayPlanePropertiesKHR) then
- raise TvkuException.Create('invalid function pointer: vkGetPhysicalDeviceDisplayPlanePropertiesKHR; did you enabled the VK_KHR_display extension?');
+ raise TvkuInvalidFuncPtrException.Create('vkGetPhysicalDeviceDisplayPlanePropertiesKHR', 'VK_KHR_display');
err := fInstanceCommands.vkGetPhysicalDeviceDisplayPlanePropertiesKHR(fHandle, @c, nil);
if (err < VK_SUCCESS) then
raise TvkuErrorException.Create('unable to get physical device display plane property count', err);
@@ -238,7 +231,7 @@ var
begin
result := nil;
if not Assigned(fInstanceCommands.vkGetDisplayPlaneSupportedDisplaysKHR) then
- raise TvkuException.Create('invalid function pointer: vkGetDisplayPlaneSupportedDisplaysKHR; did you enabled the VK_KHR_display extension?');
+ raise TvkuInvalidFuncPtrException.Create('vkGetDisplayPlaneSupportedDisplaysKHR', 'VK_KHR_display');
err := fInstanceCommands.vkGetDisplayPlaneSupportedDisplaysKHR(fHandle, aPlaneIndex, @c, nil);
if (err < VK_SUCCESS) then
raise TvkuErrorException.Create('unable to get supported display plane count', err);
@@ -256,7 +249,7 @@ var
begin
result := nil;
if not Assigned(fInstanceCommands.vkGetDisplayModePropertiesKHR) then
- raise TvkuException.Create('invalid function pointer: vkGetDisplayModePropertiesKHR; did you enabled the VK_KHR_display extension?');
+ raise TvkuInvalidFuncPtrException.Create('vkGetDisplayModePropertiesKHR', 'VK_KHR_display');
err := fInstanceCommands.vkGetDisplayModePropertiesKHR(fHandle, aDisplay, @c, nil);
if (err < VK_SUCCESS) then
raise TvkuErrorException.Create('unable to get display mode property count', err);
diff --git a/projects/utils/uvkuPhysicalDeviceFactory.pas b/projects/utils/uvkuPhysicalDeviceFactory.pas
deleted file mode 100644
index 89923f4..0000000
--- a/projects/utils/uvkuPhysicalDeviceFactory.pas
+++ /dev/null
@@ -1,41 +0,0 @@
-unit uvkuPhysicalDeviceFactory;
-
-{$mode objfpc}{$H+}
-
-interface
-
-uses
- Classes, SysUtils,
- Vulkan, uvkuInstance, uvkuPhysicalDevice;
-
-type
-/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- TvkuPhysicalDeviceFactory = class(TObject)
- private
- fInstance: TvkuInstance;
- public
- function CreatePhysicalDevice(
- const aHandle: VkPhysicalDevice): TvkuPhysicalDevice;
-
- constructor Create(const aInstance: TvkuInstance);
- end;
-
-implementation
-
-/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//TvkuPhysicalDeviceFactory//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-function TvkuPhysicalDeviceFactory.CreatePhysicalDevice(const aHandle: VkPhysicalDevice): TvkuPhysicalDevice;
-begin
- result := TvkuPhysicalDevice.Create(aHandle, fInstance.InstanceCommands);
-end;
-
-/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-constructor TvkuPhysicalDeviceFactory.Create(const aInstance: TvkuInstance);
-begin
- inherited Create;
- fInstance := aInstance;
-end;
-
-end.
-
diff --git a/projects/utils/uvkuQueue.pas b/projects/utils/uvkuQueue.pas
new file mode 100644
index 0000000..d36f3ab
--- /dev/null
+++ b/projects/utils/uvkuQueue.pas
@@ -0,0 +1,39 @@
+unit uvkuQueue;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes, SysUtils,
+ Vulkan, uvkuBase;
+
+type
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ TvkuQueue = class(TvkuObject)
+ private
+ fHandle: VkQueue;
+ fDeviceCommands: TVkDeviceCommands;
+ public
+ property Handle: VkQueue read fHandle;
+ property DeviceCommands: TVkDeviceCommands read fDeviceCommands;
+
+ constructor Create(
+ const aHandle: VkQueue;
+ const aDeviceCommands: TVkDeviceCommands);
+ end;
+
+implementation
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TvkuQueue//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TvkuQueue.Create(const aHandle: VkQueue; const aDeviceCommands: TVkDeviceCommands);
+begin
+ inherited Create;
+ fHandle := aHandle;
+ fDeviceCommands := aDeviceCommands;
+end;
+
+end.
+
diff --git a/projects/utils/uvkuSurface.pas b/projects/utils/uvkuSurface.pas
index 1844f4d..ddb5dd8 100644
--- a/projects/utils/uvkuSurface.pas
+++ b/projects/utils/uvkuSurface.pas
@@ -7,36 +7,34 @@ interface
uses
Classes, SysUtils,
- Vulkan;
+ Vulkan, uvkuBase;
type
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- TvkuSurface = class(TObject)
+ TvkuSurface = class(TvkuAllocHandle)
private
fHandle: VkSurfaceKHR;
- fInstance: VkInstance;
- fAllocCallbacks: PVkAllocationCallbacks;
fInstanceCommands: TVkInstanceCommands;
- procedure CreateHandle(const aCreateInfo: Pointer; const aAllocCallbacks: PVkAllocationCallbacks);
+ procedure CreateHandle(const aCreateInfo: Pointer);
public
property Handle: VkSurfaceKHR read fHandle;
- property Instance: VkInstance read fInstance;
property InstanceCommands: TVkInstanceCommands read fInstanceCommands;
{$IF DEFINED(VK_USE_PLATFORM_WIN32_KHR)}
constructor Create(
- const aInstance: VkInstance;
- const aCreateInfo: TVkWin32SurfaceCreateInfoKHR;
- const aInstanceCommands: TVkInstanceCommands);
- constructor Create(
- const aInstance: VkInstance;
const aCreateInfo: TVkWin32SurfaceCreateInfoKHR;
const aInstanceCommands: TVkInstanceCommands;
- const aAllocCallbacks: TVkAllocationCallbacks);
+ const aAllocCallbacks: PVkAllocationCallbacks = nil);
{$ELSE}
{$ERROR 'unknown or unsupportet platform'}
{$ENDIF}
+
+ constructor Create(
+ const aHandle: VkSurfaceKHR;
+ const aOwnsHandle: Boolean;
+ const aInstanceCommands: TVkInstanceCommands;
+ const aAllocCallbacks: PVkAllocationCallbacks = nil);
destructor Destroy; override;
public
class function GetPlatformSurfaceExtensionName: String;
@@ -50,17 +48,13 @@ uses
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TvkuSurface////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-procedure TvkuSurface.CreateHandle(const aCreateInfo: Pointer; const aAllocCallbacks: PVkAllocationCallbacks);
+procedure TvkuSurface.CreateHandle(const aCreateInfo: Pointer);
var err: TVkResult;
begin
- if Assigned(aAllocCallbacks) then begin
- new(fAllocCallbacks);
- fAllocCallbacks^ := aAllocCallbacks^;
- end;
{$IF DEFINED(VK_USE_PLATFORM_WIN32_KHR)}
if not Assigned(fInstanceCommands.vkCreateWin32SurfaceKHR) then
- raise TvkuException.Create('invalid function pointer: vkCreateWin32SurfaceKHR; did you enabled the VK_KHR_win32_surface extension?');
- err := fInstanceCommands.vkCreateWin32SurfaceKHR(fInstance, aCreateInfo, fAllocCallbacks, @fHandle);
+ raise TvkuInvalidFuncPtrException.Create('vkCreateWin32SurfaceKHR', 'VK_KHR_win32_surface');
+ err := fInstanceCommands.vkCreateWin32SurfaceKHR(fInstanceCommands.Instance, aCreateInfo, AllocCallbacks, @fHandle);
{$ENDIF}
if (err < VK_SUCCESS) then
raise TvkuErrorException.Create('unable to create surface', err);
@@ -68,37 +62,33 @@ end;
{$IF DEFINED(VK_USE_PLATFORM_WIN32_KHR)}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-constructor TvkuSurface.Create(const aInstance: VkInstance; const aCreateInfo: TVkWin32SurfaceCreateInfoKHR;
- const aInstanceCommands: TVkInstanceCommands);
+constructor TvkuSurface.Create(const aCreateInfo: TVkWin32SurfaceCreateInfoKHR;
+ const aInstanceCommands: TVkInstanceCommands; const aAllocCallbacks: PVkAllocationCallbacks);
begin
inherited Create;
- fInstance := aInstance;
fInstanceCommands := aInstanceCommands;
- CreateHandle(@aCreateInfo, nil);
+ SetAllocCallbacks(aAllocCallbacks);
+ CreateHandle(@aCreateInfo);
end;
+{$ENDIF}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-constructor TvkuSurface.Create(const aInstance: VkInstance; const aCreateInfo: TVkWin32SurfaceCreateInfoKHR;
- const aInstanceCommands: TVkInstanceCommands; const aAllocCallbacks: TVkAllocationCallbacks);
+constructor TvkuSurface.Create(const aHandle: VkSurfaceKHR; const aOwnsHandle: Boolean;
+ const aInstanceCommands: TVkInstanceCommands; const aAllocCallbacks: PVkAllocationCallbacks);
begin
inherited Create;
- fInstance := aInstance;
+ fHandle := aHandle;
fInstanceCommands := aInstanceCommands;
- CreateHandle(@aCreateInfo, @aAllocCallbacks);
+ OwnsHandle := aOwnsHandle;
+ SetAllocCallbacks(aAllocCallbacks);
end;
-{$ENDIF}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
destructor TvkuSurface.Destroy;
begin
- if (fHandle <> VK_INVALID_NDP_HANDLE) then begin
- fInstanceCommands.vkDestroySurfaceKHR(fInstance, fHandle, fAllocCallbacks);
- fHandle := VK_INVALID_NDP_HANDLE;
- end;
- if Assigned(fAllocCallbacks) then begin
- Dispose(fAllocCallbacks);
- fAllocCallbacks := nil;
- end;
+ if OwnsHandle and (fHandle <> VK_INVALID_NDP_HANDLE) then
+ fInstanceCommands.vkDestroySurfaceKHR(fInstanceCommands.Instance, fHandle, AllocCallbacks);
+ fHandle := VK_INVALID_NDP_HANDLE;
inherited Destroy;
end;
diff --git a/projects/utils/uvkuSurfaceFactory.pas b/projects/utils/uvkuSurfaceFactory.pas
index 6a3c6ad..e92b19d 100644
--- a/projects/utils/uvkuSurfaceFactory.pas
+++ b/projects/utils/uvkuSurfaceFactory.pas
@@ -34,20 +34,19 @@ type
private
fFlags: VkFlags;
fWinControl: TWinControl;
- fInstance: VkInstance;
fInstanceCommands: TVkInstanceCommands;
procedure SetWinControl(aValue: TWinControl);
public
property WinControl: TWinControl read fWinControl write SetWinControl;
property Flags: VkFlags read fFlags write fFlags;
- function CreateSurface: TvkuSurface;
+ function CreateSurface: TvkuSurfaceEx;
function CreateSurface(
const aAllocHandler: TvkuAllocationHandler;
- const aOwnsHandler: Boolean): TvkuSurface;
+ const aOwnsHandler: Boolean): TvkuSurfaceEx;
constructor Create(const aInstance: TvkuInstance);
- constructor Create(const aInstance: VkInstance; const aInstanceCommands: TVkInstanceCommands);
+ constructor Create(const aInstanceCommands: TVkInstanceCommands);
end;
implementation
@@ -154,13 +153,13 @@ begin
end;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-function TvkuSurfaceFactory.CreateSurface: TvkuSurface;
+function TvkuSurfaceFactory.CreateSurface: TvkuSurfaceEx;
begin
result := CreateSurface(nil, false);
end;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-function TvkuSurfaceFactory.CreateSurface(const aAllocHandler: TvkuAllocationHandler; const aOwnsHandler: Boolean): TvkuSurface;
+function TvkuSurfaceFactory.CreateSurface(const aAllocHandler: TvkuAllocationHandler; const aOwnsHandler: Boolean): TvkuSurfaceEx;
{$IF DEFINED(VK_USE_PLATFORM_XLIB_KHR)}
{$ERROR 'TODO: implement'}
{$ELSEIF DEFINED(VK_USE_PLATFORM_XCB_KHR)}
@@ -195,8 +194,8 @@ begin
CreateInfo.hwnd := fHwnd;
{$ENDIF}
if Assigned(aAllocHandler)
- then srf := TvkuSurfaceEx.Create(fInstance, CreateInfo, fInstanceCommands, aAllocHandler.GetAllocationCallbacks)
- else srf := TvkuSurfaceEx.Create(fInstance, CreateInfo, fInstanceCommands);
+ then srf := TvkuSurfaceEx.Create(CreateInfo, fInstanceCommands, aAllocHandler.GetAllocationCallbacksPtr)
+ else srf := TvkuSurfaceEx.Create(CreateInfo, fInstanceCommands);
try
srf.fAllocHandler := aAllocHandler;
srf.fOwnsHandler := aOwnsHandler;
@@ -209,11 +208,11 @@ end;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor TvkuSurfaceFactory.Create(const aInstance: TvkuInstance);
begin
- Create(aInstance.Handle, aInstance.InstanceCommands);
+ Create(aInstance.InstanceCommands);
end;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-constructor TvkuSurfaceFactory.Create(const aInstance: VkInstance; const aInstanceCommands: TVkInstanceCommands);
+constructor TvkuSurfaceFactory.Create(const aInstanceCommands: TVkInstanceCommands);
begin
inherited Create;
{$IF DEFINED(VK_USE_PLATFORM_XLIB_KHR)}
@@ -229,7 +228,6 @@ begin
{$ELSEIF DEFINED(VK_USE_PLATFORM_WIN32_KHR)}
fHInstance := Vulkan.HINSTANCE(GetModuleHandle(nil));
{$ENDIF}
- fInstance := aInstance;
fInstanceCommands := aInstanceCommands;
fFlags := 0;
end;
diff --git a/projects/utils/uvkuSwapChain.pas b/projects/utils/uvkuSwapChain.pas
index 71baa3a..78d0a71 100644
--- a/projects/utils/uvkuSwapChain.pas
+++ b/projects/utils/uvkuSwapChain.pas
@@ -6,38 +6,32 @@ interface
uses
Classes, SysUtils,
- Vulkan;
+ Vulkan, uvkuBase, uvkuTypes;
type
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- TvkuImageArr = array of VkImage;
- TvkuSwapChain = class(TObject)
+ TvkuSwapChain = class(TvkuAllocHandle)
private
fHandle: VkSwapchainKHR;
- fDevice: VkDevice;
- fAllocCallbacks: PVkAllocationCallbacks;
fDeviceCommands: TVkDeviceCommands;
- procedure CreateHandle(
- const aCreateInfo: PVkSwapchainCreateInfoKHR;
- const aAllocCallbacks: PVkAllocationCallbacks);
+ procedure CreateHandle(const aCreateInfo: PVkSwapchainCreateInfoKHR);
public
property Handle: VkSwapchainKHR read fHandle;
- property Device: VkDevice read fDevice;
property DeviceCommands: TVkDeviceCommands read fDeviceCommands;
function GetImages: TvkuImageArr;
function AcquireNextImage(const aTimeout: VkUint64; const aSemaphore: VkSemaphore; const aFence: VkFence): VkUint32;
constructor Create(
- const aDevice: VkDevice;
const aCreateInfo: TVkSwapchainCreateInfoKHR;
- const aDeviceCommands: TVkDeviceCommands);
+ const aDeviceCommands: TVkDeviceCommands;
+ const aAllocCallbacks: PVkAllocationCallbacks = nil); overload;
constructor Create(
- const aDevice: VkDevice;
- const aCreateInfo: TVkSwapchainCreateInfoKHR;
+ const aHandle: VkSwapchainKHR;
+ const aOwnsHandle: Boolean;
const aDeviceCommands: TVkDeviceCommands;
- const aAllocCallbacks: TVkAllocationCallbacks);
+ const aAllocCallbacks: PVkAllocationCallbacks = nil); overload;
destructor Destroy; override;
end;
@@ -49,18 +43,14 @@ uses
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TvkuSwapChain//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-procedure TvkuSwapChain.CreateHandle(const aCreateInfo: PVkSwapchainCreateInfoKHR; const aAllocCallbacks: PVkAllocationCallbacks);
+procedure TvkuSwapChain.CreateHandle(const aCreateInfo: PVkSwapchainCreateInfoKHR);
var err: TVkResult;
begin
- if Assigned(aAllocCallbacks) then begin
- new(fAllocCallbacks);
- fAllocCallbacks^ := aAllocCallbacks^;
- end;
if not Assigned(fDeviceCommands.vkCreateSwapchainKHR) then
raise TvkuException.Create('invalid function pointer: vkCreateSwapchainKHR; did you enabled the VK_KHR_swapchain extension?');
- err := fDeviceCommands.vkCreateSwapchainKHR(fDevice, aCreateInfo, fAllocCallbacks, @fHandle);
+ err := fDeviceCommands.vkCreateSwapchainKHR(fDeviceCommands.Device, aCreateInfo, AllocCallbacks, @fHandle);
if (err < VK_SUCCESS) then
- raise TvkuErrorException.Create('unable to create surface', err);
+ raise TvkuErrorException.Create('unable to create swap chain', err);
end;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -70,12 +60,12 @@ var
err: TVkResult;
begin
if not Assigned(fDeviceCommands.vkGetSwapchainImagesKHR) then
- raise TvkuException.Create('invalid function pointer: vkGetSwapchainImagesKHR; did you enabled the VK_KHR_swapchain extension?');
- err := fDeviceCommands.vkGetSwapchainImagesKHR(fDevice, fHandle, @c, nil);
+ raise TvkuInvalidFuncPtrException.Create('vkGetSwapchainImagesKHR', 'VK_KHR_swapchain');
+ err := fDeviceCommands.vkGetSwapchainImagesKHR(fDeviceCommands.Device, fHandle, @c, nil);
if (err < VK_SUCCESS) then
raise TvkuErrorException.Create('unable to get swap chain image count', err);
SetLength(result, c);
- err := fDeviceCommands.vkGetSwapchainImagesKHR(fDevice, fHandle, @c, @result[0]);
+ err := fDeviceCommands.vkGetSwapchainImagesKHR(fDeviceCommands.Device, fHandle, @c, @result[0]);
if (err < VK_SUCCESS) then
raise TvkuErrorException.Create('unable to get swap chain images', err);
end;
@@ -83,46 +73,42 @@ end;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuSwapChain.AcquireNextImage(const aTimeout: VkUint64; const aSemaphore: VkSemaphore; const aFence: VkFence): VkUint32;
var
- c: VkUint32;
err: TVkResult;
begin
if not Assigned(fDeviceCommands.vkAcquireNextImageKHR) then
- raise TvkuException.Create('invalid function pointer: vkAcquireNextImageKHR; did you enabled the VK_KHR_swapchain extension?');
- err := fDeviceCommands.vkAcquireNextImageKHR(fDevice, fHandle, aTimeout, aSemaphore, aFence, @result);
+ raise TvkuInvalidFuncPtrException.Create('vkAcquireNextImageKHR', 'VK_KHR_swapchain');
+ err := fDeviceCommands.vkAcquireNextImageKHR(fDeviceCommands.Device, fHandle, aTimeout, aSemaphore, aFence, @result);
if (err < VK_SUCCESS) then
raise TvkuErrorException.Create('unable to aquire next image', err);
end;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-constructor TvkuSwapChain.Create(const aDevice: VkDevice; const aCreateInfo: TVkSwapchainCreateInfoKHR; const aDeviceCommands: TVkDeviceCommands);
+constructor TvkuSwapChain.Create(const aCreateInfo: TVkSwapchainCreateInfoKHR; const aDeviceCommands: TVkDeviceCommands;
+ const aAllocCallbacks: PVkAllocationCallbacks);
begin
inherited Create;
- fDevice := aDevice;
fDeviceCommands := aDeviceCommands;
- CreateHandle(@aCreateInfo, nil);
+ SetAllocCallbacks(aAllocCallbacks);
+ CreateHandle(@aCreateInfo);
end;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-constructor TvkuSwapChain.Create(const aDevice: VkDevice; const aCreateInfo: TVkSwapchainCreateInfoKHR;
- const aDeviceCommands: TVkDeviceCommands; const aAllocCallbacks: TVkAllocationCallbacks);
+constructor TvkuSwapChain.Create(const aHandle: VkSwapchainKHR; const aOwnsHandle: Boolean;
+ const aDeviceCommands: TVkDeviceCommands; const aAllocCallbacks: PVkAllocationCallbacks);
begin
inherited Create;
- fDevice := aDevice;
+ fHandle := aHandle;
fDeviceCommands := aDeviceCommands;
- CreateHandle(@aCreateInfo, @aAllocCallbacks);
+ OwnsHandle := aOwnsHandle;
+ SetAllocCallbacks(aAllocCallbacks);
end;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
destructor TvkuSwapChain.Destroy;
begin
- if (fHandle <> VK_INVALID_NDP_HANDLE) then begin
- fDeviceCommands.vkDestroySwapchainKHR(fDevice, fHandle, fAllocCallbacks);
- fHandle := VK_INVALID_NDP_HANDLE;
- end;
- if Assigned(fAllocCallbacks) then begin
- Dispose(fAllocCallbacks);
- fAllocCallbacks := nil;
- end;
+ if OwnsHandle and (fHandle <> VK_INVALID_NDP_HANDLE) then
+ fDeviceCommands.vkDestroySwapchainKHR(fDeviceCommands.Device, fHandle, AllocCallbacks);
+ fHandle := VK_INVALID_NDP_HANDLE;
inherited Destroy;
end;
diff --git a/projects/utils/uvkuSwapChainFactory.pas b/projects/utils/uvkuSwapChainFactory.pas
index 3c3289f..03d1bb2 100644
--- a/projects/utils/uvkuSwapChainFactory.pas
+++ b/projects/utils/uvkuSwapChainFactory.pas
@@ -6,7 +6,7 @@ interface
uses
Classes, SysUtils,
- Vulkan, uvkuSwapChain, uvkuAllocationHandler, uvkuDevice;
+ Vulkan, uvkuSwapChain, uvkuTypes, uvkuAllocationHandler, uvkuDevice;
type
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -19,10 +19,8 @@ type
end;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- TvkuUint32Arr = array of VkUint32;
TvkuSwapChainFactory = class(TObject)
private
- fDevice: VkDevice;
fDeviceCommands: TVkDeviceCommands;
fFlags: VkSwapchainCreateFlagsKHR;
@@ -45,7 +43,6 @@ type
function GetQueueFamilyIndex(const aIndex: Integer): VkUint32;
procedure SetQueueFamilyIndex(const aIndex: Integer; aValue: VkUint32);
public
- property Device: VkDevice read fDevice;
property DeviceCommands: TVkDeviceCommands read fDeviceCommands;
property Flags: VkSwapchainCreateFlagsKHR read fFlags write fFlags;
@@ -73,7 +70,7 @@ type
const aOwnsHandler: Boolean): TvkuSwapChain;
constructor Create(const aDevice: TvkuDevice);
- constructor Create(const aDevice: VkDevice; const aDeviceCommands: TVkDeviceCommands);
+ constructor Create(const aDeviceCommands: TVkDeviceCommands);
end;
implementation
@@ -149,27 +146,27 @@ begin
else CreateInfo.clipped := VK_FALSE;
if Assigned(aAllocHandler)
- then result := TvkuSwapChainEx.Create(fDevice, CreateInfo, fDeviceCommands, aAllocHandler.GetAllocationCallbacks)
- else result := TvkuSwapChainEx.Create(fDevice, CreateInfo, fDeviceCommands);
+ then result := TvkuSwapChainEx.Create(CreateInfo, fDeviceCommands, aAllocHandler.GetAllocationCallbacksPtr)
+ else result := TvkuSwapChainEx.Create(CreateInfo, fDeviceCommands);
try
TvkuSwapChainEx(result).fAllocHandler := aAllocHandler;
TvkuSwapChainEx(result).fOwnsHandler := aOwnsHandler;
except
FreeAndNil(result);
+ raise;
end;
end;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor TvkuSwapChainFactory.Create(const aDevice: TvkuDevice);
begin
- Create(aDevice.Handle, aDevice.DeviceCommands);
+ Create(aDevice.DeviceCommands);
end;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-constructor TvkuSwapChainFactory.Create(const aDevice: VkDevice; const aDeviceCommands: TVkDeviceCommands);
+constructor TvkuSwapChainFactory.Create(const aDeviceCommands: TVkDeviceCommands);
begin
inherited Create;
- fDevice := aDevice;
fDeviceCommands := aDeviceCommands;
fPresentMode := VK_PRESENT_MODE_FIFO_KHR;
end;
diff --git a/projects/utils/uvkuTypes.pas b/projects/utils/uvkuTypes.pas
new file mode 100644
index 0000000..af9e9da
--- /dev/null
+++ b/projects/utils/uvkuTypes.pas
@@ -0,0 +1,45 @@
+unit uvkuTypes;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes, SysUtils,
+ Vulkan;
+
+type
+ TvkuFloatArr = array of VkFloat;
+ TvkuUint32Arr = array of VkUint32;
+ TvkuImageArr = array of VkImage;
+ TvkuPhysicalDeviceArr = array of VkPhysicalDevice;
+ TvkuQueueFamilyPropertiesArr = array of TVkQueueFamilyProperties;
+ TvkuSparseImageFormatPropertiesArr = array of TVkSparseImageFormatProperties;
+ TvkuSurfaceFormatArr = array of TVkSurfaceFormatKHR;
+ TvkuPresentModeArr = array of TVkPresentModeKHR;
+ TvkuDisplayPropertiesArr = array of TVkDisplayPropertiesKHR;
+ TvkuDisplayPlanePropertiesArr = array of TVkDisplayPlanePropertiesKHR;
+ TvkuDisplayArr = array of VkDisplayKHR;
+ TvkuDisplayModePropertiesArr = array of TVkDisplayModePropertiesKHR;
+ TvkuCommandBufferArr = array of VkCommandBuffer;
+
+ TvkuApplicationInfo = packed record
+ AppName: String;
+ AppVersion: VkVersion;
+ EngineName: String;
+ EngineVersion: VkVersion;
+ ApiVersion: VkVersion;
+ end;
+
+ TvkuQueueCreateInfo = packed record
+ Flags: VkDeviceQueueCreateFlags;
+ FamilyIndex: VkUint32;
+ Priorities: TvkuFloatArr;
+ end;
+ TvkuQueueCreateInfoArr = array of TvkuQueueCreateInfo;
+
+
+implementation
+
+end.
+
diff --git a/projects/utils/uvkuUtils.pas b/projects/utils/uvkuUtils.pas
index 40ecf56..f328b7f 100644
--- a/projects/utils/uvkuUtils.pas
+++ b/projects/utils/uvkuUtils.pas
@@ -11,6 +11,7 @@ uses
type
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TvkuException = class(Exception);
+
TvkuErrorException = class(TvkuException)
private
fError: TVkResult;
@@ -19,6 +20,18 @@ type
constructor Create(const msg: string; const aError: TVkResult);
end;
+ TvkuInvalidFuncPtrException = class(TvkuException)
+ private
+ fExtensionName: String;
+ fFunctionName: String;
+ fExtentionName: String;
+ public
+ property FunctionName: String read fFunctionName;
+ property ExtensionName: String read fExtensionName;
+
+ constructor Create(const aFunctionName: String; const aExtensionName: String = '');
+ end;
+
function vkuMakeString(const aFeatures: TVkPhysicalDeviceFeatures; const aSeperator: String = sLineBreak): String;
function vkuMakeString(const aProperties: TVkPhysicalDeviceProperties; const aPrintLimits, aPrintSparseProps: Boolean): String;
function vkuMakeString(const aMemoryProperties: TVkPhysicalDeviceMemoryProperties): String;
@@ -34,6 +47,20 @@ begin
fError := aError;
end;
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TvkuInvalidFuncPtrException////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TvkuInvalidFuncPtrException.Create(const aFunctionName: String; const aExtensionName: String);
+var s: String;
+begin
+ fFunctionName := aFunctionName;
+ fExtensionName := aExtensionName;
+ s := 'did you load the vulkan core commands?';
+ if (aExtensionName <> '') then
+ s := 'did you enabled/load the ' + fExtensionName + ' extension?';
+ inherited Create('invalid function pointer: ' + fFunctionName + '; ' + s);
+end;
+
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////