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.