unit uvkuSwapChainFactory; {$mode objfpc}{$H+} interface uses Classes, SysUtils, Vulkan, uvkuSwapChain, uvkuTypes, uvkuAllocationHandler, uvkuDevice, uvkuFactoryBase; type ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// TvkuSwapChainEx = class(TvkuSwapChain) private fAllocHandler: TvkuAllocationHandler; fOwnsHandler: Boolean; public destructor Destroy; override; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// TvkuSwapChainFactory = class(TvkuDeviceObjFactory) private fFlags: VkSwapchainCreateFlagsKHR; fSurface: VkSurfaceKHR; fMinImageCount: VkUint32; fImageFormat: TVkFormat; fImageColorSpace: TVkColorSpaceKHR; fImageExtent: TVkExtent2D; fImageArrayLayers: VkUint32; fImageUsage: VkImageUsageFlags; fImageSharingMode: TVkSharingMode; fQueueFamilyIndices: TvkuUint32Arr; fPreTransform: TVkSurfaceTransformFlagBitsKHR; fComposideAlpha: TVkCompositeAlphaFlagBitsKHR; fPresentMode: TVkPresentModeKHR; fClipped: Boolean; fOldSwapChain: VkSwapchainKHR; function GetQueueFamilyIndexCount: Integer; function GetQueueFamilyIndex(const aIndex: Integer): VkUint32; procedure SetQueueFamilyIndex(const aIndex: Integer; aValue: VkUint32); public property Flags: VkSwapchainCreateFlagsKHR read fFlags write fFlags; property Surface: VkSurfaceKHR read fSurface write fSurface; property MinImageCount: VkUint32 read fMinImageCount write fMinImageCount; property ImageFormat: TVkFormat read fImageFormat write fImageFormat; property ImageColorSpace: TVkColorSpaceKHR read fImageColorSpace write fImageColorSpace; property ImageExtent: TVkExtent2D read fImageExtent write fImageExtent; property ImageArrayLayers: VkUint32 read fImageArrayLayers write fImageArrayLayers; property ImageUsage: VkImageUsageFlags read fImageUsage write fImageUsage; property ImageSharingMode: TVkSharingMode read fImageSharingMode write fImageSharingMode; property PreTransform: TVkSurfaceTransformFlagBitsKHR read fPreTransform write fPreTransform; property ComposideAlpha: TVkCompositeAlphaFlagBitsKHR read fComposideAlpha write fComposideAlpha; property PresentMode: TVkPresentModeKHR read fPresentMode write fPresentMode; property Clipped: Boolean read fClipped write fClipped; property OldSwapChain: VkSwapchainKHR read fOldSwapChain write fOldSwapChain; property QueueFamilyIndices: TvkuUint32Arr read fQueueFamilyIndices write fQueueFamilyIndices; property QueueFamilyIndexCount: Integer read GetQueueFamilyIndexCount; property QueueFamilyIndex[const aIndex: Integer]: VkUint32 read GetQueueFamilyIndex write SetQueueFamilyIndex; function CreateSwapchain: TvkuSwapChain; function CreateSwapchain( const aAllocHandler: TvkuAllocationHandler; const aOwnsHandler: Boolean): TvkuSwapChain; procedure AfterConstruction; override; end; implementation uses uvkuUtils; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TvkuSwapChainEx//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// destructor TvkuSwapChainEx.Destroy; begin inherited Destroy; if fOwnsHandler then FreeAndNil(fAllocHandler); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TvkuSwapChainFactory/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TvkuSwapChainFactory.GetQueueFamilyIndexCount: Integer; begin result := Length(fQueueFamilyIndices); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TvkuSwapChainFactory.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; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TvkuSwapChainFactory.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 TvkuSwapChainFactory.CreateSwapchain: TvkuSwapChain; begin result := CreateSwapchain(nil, false); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TvkuSwapChainFactory.CreateSwapchain(const aAllocHandler: TvkuAllocationHandler; const aOwnsHandler: Boolean): TvkuSwapChain; var CreateInfo: TVkSwapchainCreateInfoKHR; begin FillByte(CreateInfo, SizeOf(CreateInfo), 0); CreateInfo.sType := VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; CreateInfo.pNext := nil; CreateInfo.flags := fFlags; CreateInfo.surface := fSurface; CreateInfo.minImageCount := fMinImageCount; CreateInfo.imageFormat := fImageFormat; CreateInfo.imageColorSpace := fImageColorSpace; CreateInfo.imageExtent := fImageExtent; CreateInfo.imageArrayLayers := fImageArrayLayers; CreateInfo.imageUsage := fImageUsage; CreateInfo.imageSharingMode := fImageSharingMode; CreateInfo.queueFamilyIndexCount := Length(fQueueFamilyIndices); CreateInfo.pQueueFamilyIndices := @fQueueFamilyIndices[0]; CreateInfo.preTransform := fPreTransform; CreateInfo.compositeAlpha := fComposideAlpha; CreateInfo.presentMode := fPresentMode; CreateInfo.oldSwapchain := fOldSwapChain; if fClipped then CreateInfo.clipped := VK_TRUE else CreateInfo.clipped := VK_FALSE; if Assigned(aAllocHandler) then result := TvkuSwapChainEx.Create(CreateInfo, DeviceCommands, aAllocHandler.GetAllocationCallbacksPtr) else result := TvkuSwapChainEx.Create(CreateInfo, DeviceCommands); try TvkuSwapChainEx(result).fAllocHandler := aAllocHandler; TvkuSwapChainEx(result).fOwnsHandler := aOwnsHandler; except FreeAndNil(result); raise; end; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TvkuSwapChainFactory.AfterConstruction; begin inherited AfterConstruction; fPresentMode := VK_PRESENT_MODE_FIFO_KHR; end; end.