unit uvkuInstance; {$mode objfpc}{$H+} interface uses Classes, SysUtils, Vulkan, uvkuBase, uvkuTypes; type ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// TvkuInstance = class(TvkuAllocHandle) private fHandle: VkInstance; fPhysicalDevices: TVkPhysicalDeviceArr; fInstanceCommands: TVkInstanceCommands; procedure UpdatePhysicalDevices; protected procedure CreateHandle(const aCreateInfo: PVkInstanceCreateInfo); public property Handle: VkInstance read fHandle; property InstanceCommands: TVkInstanceCommands read fInstanceCommands; function GetPhysicalDevices: TVkPhysicalDeviceArr; constructor Create( const aCreateInfo: TVkInstanceCreateInfo; const aAllocCallbacks: PVkAllocationCallbacks = nil); constructor Create( const aHandle: VkInstance; const aOwnsHandle: Boolean; const aAllocCallbacks: PVkAllocationCallbacks = nil); destructor Destroy; override; end; implementation uses uvkuUtils; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TvkuInstance/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TvkuInstance.UpdatePhysicalDevices; var c: VkUint32; err: TVkResult; begin if (fPhysicalDevices <> nil) then exit; err := InstanceCommands.vkEnumeratePhysicalDevices(fHandle, @c, nil); if (err < VK_SUCCESS) then raise TvkuErrorException.Create('unable to get physical device number', err); SetLength(fPhysicalDevices, c); err := InstanceCommands.vkEnumeratePhysicalDevices(fHandle, @c, @fPhysicalDevices[0]); if (err < VK_SUCCESS) then raise TvkuErrorException.Create('unable to get physical devices', err); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TvkuInstance.CreateHandle(const aCreateInfo: PVkInstanceCreateInfo); var e: TVkResult; begin e := vkCreateInstance(aCreateInfo, AllocCallbacks, @fHandle); if (e < VK_SUCCESS) then raise TvkuErrorException.Create('unable to create vulkan instance', e); fInstanceCommands := LoadInstanceCommands(fHandle); if not Assigned(InstanceCommands) then raise TvkuException.Create('unable to load instance commands'); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TvkuInstance.GetPhysicalDevices: TVkPhysicalDeviceArr; begin UpdatePhysicalDevices; result := fPhysicalDevices; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor TvkuInstance.Create(const aCreateInfo: TVkInstanceCreateInfo; const aAllocCallbacks: PVkAllocationCallbacks); begin inherited Create; fHandle := VK_INVALID_HANDLE; SetAllocCallbacks(aAllocCallbacks); CreateHandle(@aCreateInfo); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor TvkuInstance.Create(const aHandle: VkInstance; const aOwnsHandle: Boolean; const aAllocCallbacks: PVkAllocationCallbacks); begin inherited Create; fHandle := aHandle; OwnsHandle := aOwnsHandle; SetAllocCallbacks(aAllocCallbacks); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// destructor TvkuInstance.Destroy; begin if OwnsHandle and (fHandle <> VK_INVALID_HANDLE) then InstanceCommands.vkDestroyInstance(fHandle, AllocCallbacks); fHandle := VK_INVALID_HANDLE; FreeAndNil(fInstanceCommands); inherited Destroy; end; end.