unit uvkuImageFactory; {$mode objfpc}{$H+} interface uses Classes, SysUtils, Vulkan, uvkuImage, uvkuDevice, uvkuAllocationHandler, uvkuTypes, uvkuFactoryBase; type ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// TvkuImageEx = class(TvkuImage) private fAllocHandler: TvkuAllocationHandler; fOwnsHandle: Boolean; public destructor Destroy; override; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// TvkuImageFactory = class(TvkuDeviceObjFactory) private 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 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; end; implementation uses uvkuUtils; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TvkuImageEx//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// destructor TvkuImageEx.Destroy; begin inherited Destroy; if fOwnsHandle then FreeAndNil(fAllocHandler); 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, DeviceCommands, aAllocHandler.GetAllocationCallbacksPtr) else result := TvkuImageEx.Create(CreateInfo, DeviceCommands); try TvkuImageEx(result).fAllocHandler := aAllocHandler; TvkuImageEx(result).fOwnsHandle := aOwnsHandler; except FreeAndNil(result); raise; end; end; end.