diff --git a/projects/triangle/triangle.lpi b/projects/triangle/triangle.lpi
index e9167b6..de857d3 100644
--- a/projects/triangle/triangle.lpi
+++ b/projects/triangle/triangle.lpi
@@ -33,7 +33,7 @@
-
+
@@ -154,17 +154,29 @@
-
+
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/projects/triangle/triangle.lpr b/projects/triangle/triangle.lpr
index 6fd4e85..98de8fc 100644
--- a/projects/triangle/triangle.lpr
+++ b/projects/triangle/triangle.lpr
@@ -7,7 +7,8 @@ uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
- Interfaces, Dialogs, Forms, uMainForm, Vulkan, uvkuRenderPass, uvkuRenderPassFactory, uvkuFactoryBase;
+ Interfaces, Dialogs, Forms, uMainForm, Vulkan, uvkuRenderPass, uvkuRenderPassFactory, uvkuFactoryBase,
+uvkuFrameBuffer, uvkuFrameBufferFactory, uvkuUtils;
{$R *.res}
diff --git a/projects/triangle/triangle.lps b/projects/triangle/triangle.lps
index 9d7d521..42b924c 100644
--- a/projects/triangle/triangle.lps
+++ b/projects/triangle/triangle.lps
@@ -4,13 +4,13 @@
-
+
-
+
@@ -21,21 +21,21 @@
-
+
-
-
-
+
+
+
-
+
@@ -43,7 +43,7 @@
-
+
@@ -51,7 +51,7 @@
-
+
@@ -59,7 +59,7 @@
-
+
@@ -67,7 +67,7 @@
-
+
@@ -75,15 +75,15 @@
-
+
-
+
-
+
@@ -92,7 +92,7 @@
-
+
@@ -100,7 +100,7 @@
-
+
@@ -108,7 +108,7 @@
-
+
@@ -116,7 +116,7 @@
-
+
@@ -124,7 +124,7 @@
-
+
@@ -132,7 +132,7 @@
-
+
@@ -140,7 +140,7 @@
-
+
@@ -148,7 +148,7 @@
-
+
@@ -156,7 +156,7 @@
-
+
@@ -164,7 +164,7 @@
-
+
@@ -172,15 +172,15 @@
-
+
-
-
-
-
+
+
+
+
@@ -189,7 +189,7 @@
-
+
@@ -197,7 +197,7 @@
-
+
@@ -205,7 +205,7 @@
-
+
@@ -213,7 +213,7 @@
-
+
@@ -221,14 +221,14 @@
-
+
-
+
@@ -236,14 +236,17 @@
-
+
-
-
-
+
+
+
+
+
+
@@ -254,10 +257,11 @@
-
-
-
+
+
+
+
@@ -384,19 +388,18 @@
-
-
-
-
+
+
+
-
-
-
+
+
+
@@ -404,10 +407,28 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
@@ -468,6 +489,50 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/projects/utils/VulkanUtils.pas b/projects/utils/VulkanUtils.pas
index 121c44e..997d7ab 100644
--- a/projects/utils/VulkanUtils.pas
+++ b/projects/utils/VulkanUtils.pas
@@ -14,7 +14,8 @@ uses
uvkuImage, uvkuImageFactory, uvkuImageView, uvkuImageViewFactory,
uvkuBuffer, uvkuBufferFactory, uvkuBufferView, uvkuBufferViewFactory,
uvkuCommandPool, uvkuCommandPoolFactory, uvkuCommandBuffer,
- uvkuRenderPass, uvkuRenderPassFactory;
+ uvkuRenderPass, uvkuRenderPassFactory, uvkuFrameBuffer, uvkuFrameBufferFactory,
+ uvkuUtils;
type
{ Types }
@@ -86,6 +87,14 @@ type
TvkuRenderPass = uvkuRenderPass.TvkuRenderPass;
TvkuRenderPassEx = uvkuRenderPassFactory.TvkuRenderPassEx;
TvkuRenderPassFactory = uvkuRenderPassFactory.TvkuRenderPassFactory;
+ TvkuFrameBuffer = uvkuFrameBuffer.TvkuFrameBuffer;
+ TvkuFrameBufferEx = uvkuFrameBufferFactory.TvkuFrameBufferEx;
+ TvkuFrameBufferFactory = uvkuFrameBufferFactory.TvkuFrameBufferFactory;
+
+ { Utils }
+ TvkuException = uvkuUtils.TvkuException;
+ TvkuErrorException = uvkuUtils.TvkuErrorException;
+ TvkuInvalidFuncPtrException = uvkuUtils.TvkuInvalidFuncPtrException;
implementation
diff --git a/projects/utils/uvkuFrameBuffer.pas b/projects/utils/uvkuFrameBuffer.pas
new file mode 100644
index 0000000..3dde8b6
--- /dev/null
+++ b/projects/utils/uvkuFrameBuffer.pas
@@ -0,0 +1,84 @@
+unit uvkuFrameBuffer;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes, SysUtils,
+ Vulkan, uvkuBase;
+
+type
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ TvkuFrameBuffer = class(TvkuAllocHandle)
+ private
+ fHandle: VkFramebuffer;
+ fDeviceCommands: TVkDeviceCommands;
+
+ procedure CreateHandle(const aCreateInfo: TVkFramebufferCreateInfo);
+ public
+ property Handle: VkFramebuffer read fHandle;
+ property DeviceCommands: TVkDeviceCommands read fDeviceCommands;
+
+ constructor Create(
+ const aCreateInfo: TVkFramebufferCreateInfo;
+ const aDeviceCommands: TVkDeviceCommands;
+ const aAllocCallbacks: PVkAllocationCallbacks = nil);
+ constructor Create(
+ const aHandle: VkFramebuffer;
+ const aOwnsHandle: Boolean;
+ const aDeviceCommands: TVkDeviceCommands;
+ const aAllocCallbacks: PVkAllocationCallbacks = nil);
+ destructor Destroy; override;
+ end;
+
+implementation
+
+uses
+ uvkuUtils;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TvkuFrameBuffer////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TvkuFrameBuffer.CreateHandle(const aCreateInfo: TVkFramebufferCreateInfo);
+var err: TVkResult;
+begin
+ if not Assigned(fDeviceCommands.vkCreateFramebuffer) then
+ raise TvkuInvalidFuncPtrException.Create('vkCreateFramebuffer');
+ err := fDeviceCommands.vkCreateFramebuffer(fDeviceCommands.Device, @aCreateInfo, AllocCallbacks, @fHandle);
+ if (err < VK_SUCCESS) then
+ raise TvkuErrorException.Create('unable to create frame buffer', err);
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TvkuFrameBuffer.Create(const aCreateInfo: TVkFramebufferCreateInfo;
+ const aDeviceCommands: TVkDeviceCommands; const aAllocCallbacks: PVkAllocationCallbacks);
+begin
+ inherited Create;
+ fDeviceCommands := aDeviceCommands;
+ SetAllocCallbacks(aAllocCallbacks);
+ CreateHandle(aCreateInfo);
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TvkuFrameBuffer.Create(const aHandle: VkFramebuffer; const aOwnsHandle: Boolean;
+ const aDeviceCommands: TVkDeviceCommands; const aAllocCallbacks: PVkAllocationCallbacks);
+begin
+ inherited Create;
+ fHandle := aHandle;
+ fDeviceCommands := aDeviceCommands;
+ OwnsHandle := aOwnsHandle;
+ SetAllocCallbacks(aAllocCallbacks);
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+destructor TvkuFrameBuffer.Destroy;
+begin
+ if OwnsHandle and (fHandle <> VK_INVALID_NDP_HANDLE) then
+ fDeviceCommands.vkDestroyFramebuffer(fDeviceCommands.Device, fHandle, AllocCallbacks);
+ fHandle := VK_INVALID_NDP_HANDLE;
+ inherited Destroy;
+end;
+
+end.
+
diff --git a/projects/utils/uvkuFrameBufferFactory.pas b/projects/utils/uvkuFrameBufferFactory.pas
new file mode 100644
index 0000000..f5a2883
--- /dev/null
+++ b/projects/utils/uvkuFrameBufferFactory.pas
@@ -0,0 +1,131 @@
+unit uvkuFrameBufferFactory;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes, SysUtils,
+ Vulkan, uvkuFrameBuffer, uvkuFactoryBase, uvkuAllocationHandler, uvkuTypes;
+
+type
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ TvkuFrameBufferEx = class(TvkuFrameBuffer)
+ private
+ fAllocHandler: TvkuAllocationHandler;
+ fOwnsHandler: Boolean;
+ public
+ destructor Destroy; override;
+ end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ TvkuFrameBufferFactory = class(TvkuDeviceObjFactory)
+ private
+ fFlags: VkFramebufferCreateFlags;
+ fWidth: VkUint32;
+ fHeight: VkUint32;
+ fLayers: VkUint32;
+ fAttachments: TvkuImageViewArr;
+ function GetAttachment(const aIndex: Integer): VkImageView;
+ function GetAttachmentCount: Integer;
+ procedure SetAttachment(const aIndex: Integer; aValue: VkImageView);
+ procedure SetAttachmentCount(aValue: Integer);
+ public
+ property Flags: VkFramebufferCreateFlags read fFlags write fFlags;
+ property Width: VkUint32 read fWidth write fWidth;
+ property Height: VkUint32 read fHeight write fHeight;
+ property Layers: VkUint32 read fLayers write fLayers;
+
+ property Attachments: TvkuImageViewArr read fAttachments write fAttachments;
+ property AttachmentCount: Integer read GetAttachmentCount write SetAttachmentCount;
+ property Attachment[const aIndex: Integer]: VkImageView read GetAttachment write SetAttachment;
+
+ function CreateFrameBuffer(
+ const aRenderPass: VkRenderPass): TvkuFrameBufferEx;
+ function CreateFrameBuffer(
+ const aRenderPass: VkRenderPass;
+ const aAllocHandler: TvkuAllocationHandler;
+ const aOwnsHandler: Boolean): TvkuFrameBufferEx;
+ end;
+
+implementation
+
+uses
+ uvkuUtils;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TvkuFrameBufferEx//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+destructor TvkuFrameBufferEx.Destroy;
+begin
+ inherited Destroy;
+ if fOwnsHandler then
+ FreeAndNil(fAllocHandler);
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TvkuFrameBufferFactory/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TvkuFrameBufferFactory.GetAttachment(const aIndex: Integer): VkImageView;
+begin
+ if (aIndex < low(fAttachments)) or (aIndex > high(fAttachments)) then
+ raise TvkuException.CreateFmt('index (%d) out of range (%d : %d)', [aIndex, Low(fAttachments), High(fAttachments)]);
+ result := fAttachments[aIndex];
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TvkuFrameBufferFactory.GetAttachmentCount: Integer;
+begin
+ result := Length(fAttachments);
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TvkuFrameBufferFactory.SetAttachment(const aIndex: Integer; aValue: VkImageView);
+begin
+ if (aIndex < low(fAttachments)) or (aIndex > high(fAttachments)) then
+ raise TvkuException.CreateFmt('index (%d) out of range (%d : %d)', [aIndex, Low(fAttachments), High(fAttachments)]);
+ fAttachments[aIndex] := aValue;
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TvkuFrameBufferFactory.SetAttachmentCount(aValue: Integer);
+begin
+ SetLength(fAttachments, aValue);
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TvkuFrameBufferFactory.CreateFrameBuffer(const aRenderPass: VkRenderPass): TvkuFrameBufferEx;
+begin
+ result := CreateFrameBuffer(aRenderPass, nil, false);
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TvkuFrameBufferFactory.CreateFrameBuffer(const aRenderPass: VkRenderPass;
+ const aAllocHandler: TvkuAllocationHandler; const aOwnsHandler: Boolean): TvkuFrameBufferEx;
+var
+ CreateInfo: TVkFramebufferCreateInfo;
+begin
+ FillByte(CreateInfo, SizeOf(CreateInfo), 0);
+ CreateInfo.sType := VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
+ CreateInfo.pNext := nil;
+ CreateInfo.flags := fFlags;
+ CreateInfo.renderPass := aRenderPass;
+ CreateInfo.attachmentCount := Length(fAttachments);
+ CreateInfo.pAttachments := @fAttachments[0];
+ CreateInfo.width := fWidth;
+ CreateInfo.height := fHeight;
+ CreateInfo.layers := fLayers;
+ if Assigned(aAllocHandler)
+ then result := TvkuFrameBufferEx.Create(CreateInfo, DeviceCommands, aAllocHandler.GetAllocationCallbacksPtr)
+ else result := TvkuFrameBufferEx.Create(CreateInfo, DeviceCommands);
+ try
+ TvkuFrameBufferEx(result).fAllocHandler := aAllocHandler;
+ TvkuFrameBufferEx(result).fOwnsHandler := aOwnsHandler;
+ except
+ FreeAndNil(result);
+ raise;
+ end;
+end;
+
+end.
+
diff --git a/projects/utils/uvkuTypes.pas b/projects/utils/uvkuTypes.pas
index 12c8e98..da96ea3 100644
--- a/projects/utils/uvkuTypes.pas
+++ b/projects/utils/uvkuTypes.pas
@@ -25,6 +25,7 @@ type
TvkuAttachmentDescriptionArr = array of TVkAttachmentDescription;
TvkuSubpassDescriptionArr = array of TVkSubpassDescription;
TvkuSubpassDependencyArr = array of TVkSubpassDependency;
+ TvkuImageViewArr = array of VkImageView;
TvkuApplicationInfo = packed record
AppName: String;
@@ -41,7 +42,6 @@ type
end;
TvkuQueueCreateInfoArr = array of TvkuQueueCreateInfo;
-
implementation
end.