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.