unit uvkuDescriptorPool; {$mode objfpc}{$H+} interface uses Classes, SysUtils, Vulkan, uvkuBase, uvkuTypes; type ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// TvkuDescriptorPool = class(TvkuAllocHandle) private fHandle: VkDescriptorPool; fDeviceCommands: TVkDeviceCommands; procedure CreateHandle(const aCreateInfo: TVkDescriptorPoolCreateInfo); public property Handle: VkDescriptorPool read fHandle; property DeviceCommands: TVkDeviceCommands read fDeviceCommands; function AllocateDescriptorSet( const aDescriptorSetLayout: VkDescriptorSetLayout): VkDescriptorSet; function AllocateDescriptorSets( const aDescriptorSetLayouts: array of VkDescriptorSetLayout): TVkDescriptorSetArr; procedure FreeDescriptorSet( const aDescriptorSet: VkDescriptorSet); procedure FreeDescriptorSets( const aDescriptorSets: TVkDescriptorSetArr); constructor Create( const aCreateInfo: TVkDescriptorPoolCreateInfo; const aDeviceCommands: TVkDeviceCommands; const aAllocCallbacks: PVkAllocationCallbacks = nil); constructor Create( const aHandle: VkDescriptorPool; const aOwnsHandle: Boolean; const aDeviceCommands: TVkDeviceCommands; const aAllocCallbacks: PVkAllocationCallbacks = nil); destructor Destroy; override; end; implementation uses uvkuUtils; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TvkuDescriptorPool///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TvkuDescriptorPool.CreateHandle(const aCreateInfo: TVkDescriptorPoolCreateInfo); var err: TVkResult; begin if not Assigned(fDeviceCommands.vkCreateDescriptorPool) then raise TvkuInvalidFuncPtrException.Create('vkCreateDescriptorPool'); err := fDeviceCommands.vkCreateDescriptorPool(fDeviceCommands.Device, @aCreateInfo, AllocCallbacks, @fHandle); if (err <> VK_SUCCESS) then raise TvkuErrorException.Create('unable to create descriptor pool', err); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TvkuDescriptorPool.AllocateDescriptorSet(const aDescriptorSetLayout: VkDescriptorSetLayout): VkDescriptorSet; begin result := AllocateDescriptorSets([ aDescriptorSetLayout ])[0]; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TvkuDescriptorPool.AllocateDescriptorSets(const aDescriptorSetLayouts: array of VkDescriptorSetLayout): TVkDescriptorSetArr; var AllocInfo: TVkDescriptorSetAllocateInfo; err: TVkResult; begin if not Assigned(fDeviceCommands.vkAllocateDescriptorSets) then raise TvkuInvalidFuncPtrException.Create('vkAllocateDescriptorSets'); FillByte(AllocInfo, SizeOf(AllocInfo), 0); AllocInfo.sType := VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; AllocInfo.pNext := nil; AllocInfo.descriptorPool := fHandle; AllocInfo.descriptorSetCount := Length(aDescriptorSetLayouts); AllocInfo.pSetLayouts := @aDescriptorSetLayouts[0]; SetLength(result, AllocInfo.descriptorSetCount); err := fDeviceCommands.vkAllocateDescriptorSets(fDeviceCommands.Device, @AllocInfo, @result[0]); if (err <> VK_SUCCESS) then raise TvkuErrorException.Create('unable to allocate descriptor sets', err); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TvkuDescriptorPool.FreeDescriptorSet(const aDescriptorSet: VkDescriptorSet); begin FreeDescriptorSets(TVkDescriptorSetArr.Create(aDescriptorSet)); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TvkuDescriptorPool.FreeDescriptorSets(const aDescriptorSets: TVkDescriptorSetArr); var err: TVkResult; begin if not Assigned(fDeviceCommands.vkFreeDescriptorSets) then raise TvkuInvalidFuncPtrException.Create('vkFreeDescriptorSets'); err := fDeviceCommands.vkFreeDescriptorSets(fDeviceCommands.Device, fHandle, Length(aDescriptorSets), @aDescriptorSets[0]); if (err <> VK_SUCCESS) then raise TvkuErrorException.Create('unable to free descriptor sets', err); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor TvkuDescriptorPool.Create(const aCreateInfo: TVkDescriptorPoolCreateInfo; const aDeviceCommands: TVkDeviceCommands; const aAllocCallbacks: PVkAllocationCallbacks); begin inherited Create; fDeviceCommands := aDeviceCommands; SetAllocCallbacks(aAllocCallbacks); CreateHandle(aCreateInfo); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor TvkuDescriptorPool.Create(const aHandle: VkDescriptorPool; const aOwnsHandle: Boolean; const aDeviceCommands: TVkDeviceCommands; const aAllocCallbacks: PVkAllocationCallbacks); begin inherited Create; fHandle := aHandle; fDeviceCommands := aDeviceCommands; OwnsHandle := aOwnsHandle; SetAllocCallbacks(aAllocCallbacks); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// destructor TvkuDescriptorPool.Destroy; begin if OwnsHandle and (fHandle <> VK_INVALID_NDP_HANDLE) then fDeviceCommands.vkDestroyDescriptorPool(fDeviceCommands.Device, fHandle, AllocCallbacks); fHandle := VK_INVALID_NDP_HANDLE; inherited Destroy; end; end.