unit uvkuPhysicalDevice; {$mode objfpc}{$H+} interface uses Classes, SysUtils, Vulkan, uvkuInstance; type ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// TvkuQueueFamilyPropertiesArr = array of TVkQueueFamilyProperties; TvkuSparseImageFormatPropertiesArr = array of TVkSparseImageFormatProperties; TvkuSurfaceFormatArr = array of TVkSurfaceFormatKHR; TvkuPresentModeArr = array of TVkPresentModeKHR; TvkuDisplayPropertiesArr = array of TVkDisplayPropertiesKHR; TvkuDisplayPlanePropertiesArr = array of TVkDisplayPlanePropertiesKHR; TvkuDisplayArr = array of VkDisplayKHR; TvkuDisplayModePropertiesArr = array of TVkDisplayModePropertiesKHR; TvkuPhysicalDevice = class(TObject) private fHandle: VkPhysicalDevice; fInstanceCommands: TVkInstanceCommands; public { VK_VERSION_1_0 } function GetFeatures: TVkPhysicalDeviceFeatures; function GetProperties: TVkPhysicalDeviceProperties; function GetMemoryProperties: TVkPhysicalDeviceMemoryProperties; function GetQueueFamilyProperties: TvkuQueueFamilyPropertiesArr; function GetFormatProperties(const aFormat: TVkFormat): TVkFormatProperties; function GetImageFormatProperties( const aFormat: TVkFormat; const aImageType: TVkImageType; const aTiling: TVkImageTiling; const aUsage: VkImageUsageFlags; const aFlags: VkImageCreateFlags): TVkImageFormatProperties; function GetSparseImageFormatProperties( const aFormat: TVkFormat; const aImageType: TVkImageType; const aSamples: TVkSampleCountFlagBits; const aUsage: VkImageUsageFlags; const aTiling: TVkImageTiling): TvkuSparseImageFormatPropertiesArr; public { VK_KHR_surface } function GetSurfaceSupport(const aQueueFamilyIndex: VkUint32; const aSurface: VkSurfaceKHR): Boolean; function GetSurfaceCapabilities(const aSurface: VkSurfaceKHR): TVkSurfaceCapabilitiesKHR; function GetSurfaceFormats(const aSurface: VkSurfaceKHR): TvkuSurfaceFormatArr; function GetSurfacePresentModes(const aSurface: VkSurfaceKHR): TvkuPresentModeArr; public { VK_KHR_display } function GetDisplayProperties: TvkuDisplayPropertiesArr; function GetDisplayPlaneProperties: TvkuDisplayPlanePropertiesArr; function GetDisplayPlaneSupportedDisplays(const aPlaneIndex: VkUint32): TvkuDisplayArr; function GetDisplayModeProperties(const aDisplay: VkDisplayKHR): TvkuDisplayModePropertiesArr; public property Handle: VkPhysicalDevice read fHandle; property InstanceCommands: TVkInstanceCommands read fInstanceCommands; constructor Create(const aHandle: VkPhysicalDevice; const aInstanceCommands: TVkInstanceCommands); end; implementation uses uvkuUtils; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TvkuPhysicalDevice///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TvkuPhysicalDevice.GetFeatures: TVkPhysicalDeviceFeatures; begin if not Assigned(fInstanceCommands.vkGetPhysicalDeviceFeatures) then raise TvkuException.Create('invalid function pointer: vkGetPhysicalDeviceFeatures; did you load the vulkan core commands?'); fInstanceCommands.vkGetPhysicalDeviceFeatures(fHandle, @result); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TvkuPhysicalDevice.GetProperties: TVkPhysicalDeviceProperties; begin if not Assigned(fInstanceCommands.vkGetPhysicalDeviceProperties) then raise TvkuException.Create('invalid function pointer: vkGetPhysicalDeviceProperties; did you load the vulkan core commands?'); fInstanceCommands.vkGetPhysicalDeviceProperties(fHandle, @result); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TvkuPhysicalDevice.GetMemoryProperties: TVkPhysicalDeviceMemoryProperties; begin if not Assigned(fInstanceCommands.vkGetPhysicalDeviceMemoryProperties) then raise TvkuException.Create('invalid function pointer: vkGetPhysicalDeviceMemoryProperties; did you load the vulkan core commands?'); fInstanceCommands.vkGetPhysicalDeviceMemoryProperties(fHandle, @result); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TvkuPhysicalDevice.GetQueueFamilyProperties: TvkuQueueFamilyPropertiesArr; var c: VkUint32; begin result := nil; if not Assigned(fInstanceCommands.vkGetPhysicalDeviceQueueFamilyProperties) then raise TvkuException.Create('invalid function pointer: vkGetPhysicalDeviceQueueFamilyProperties; did you load the vulkan core commands?'); fInstanceCommands.vkGetPhysicalDeviceQueueFamilyProperties(fHandle, @c, nil); SetLength(result, c); fInstanceCommands.vkGetPhysicalDeviceQueueFamilyProperties(fHandle, @c, @result[0]); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TvkuPhysicalDevice.GetFormatProperties(const aFormat: TVkFormat): TVkFormatProperties; begin if not Assigned(fInstanceCommands.vkGetPhysicalDeviceFormatProperties) then raise TvkuException.Create('invalid function pointer: vkGetPhysicalDeviceFormatProperties; did you load the vulkan core commands?'); fInstanceCommands.vkGetPhysicalDeviceFormatProperties(fHandle, aFormat, @result); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TvkuPhysicalDevice.GetImageFormatProperties(const aFormat: TVkFormat; const aImageType: TVkImageType; const aTiling: TVkImageTiling; const aUsage: VkImageUsageFlags; const aFlags: VkImageCreateFlags): TVkImageFormatProperties; var err: TVkResult; begin if not Assigned(fInstanceCommands.vkGetPhysicalDeviceImageFormatProperties) then raise TvkuException.Create('invalid function pointer: vkGetPhysicalDeviceImageFormatProperties; did you load the vulkan core commands?'); err := fInstanceCommands.vkGetPhysicalDeviceImageFormatProperties(fHandle, aFormat, aImageType, aTiling, aUsage, aFlags, @result); if (err < VK_SUCCESS) then raise TvkuErrorException.Create('unable to get physical device image format properties', err); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TvkuPhysicalDevice.GetSparseImageFormatProperties(const aFormat: TVkFormat; const aImageType: TVkImageType; const aSamples: TVkSampleCountFlagBits; const aUsage: VkImageUsageFlags; const aTiling: TVkImageTiling): TvkuSparseImageFormatPropertiesArr; var c: VkUint32; begin result := nil; if not Assigned(fInstanceCommands.vkGetPhysicalDeviceSparseImageFormatProperties) then raise TvkuException.Create('invalid function pointer: vkGetPhysicalDeviceSparseImageFormatProperties; did you load the vulkan core commands?'); fInstanceCommands.vkGetPhysicalDeviceSparseImageFormatProperties(fHandle, aFormat, aImageType, aSamples, aUsage, aTiling, @c, nil); SetLength(result, c); fInstanceCommands.vkGetPhysicalDeviceSparseImageFormatProperties(fHandle, aFormat, aImageType, aSamples, aUsage, aTiling, @c, @result[0]); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TvkuPhysicalDevice.GetSurfaceSupport(const aQueueFamilyIndex: VkUint32; const aSurface: VkSurfaceKHR): Boolean; var b: VkBool32; err: TVkResult; begin if not Assigned(fInstanceCommands.vkGetPhysicalDeviceSurfaceSupportKHR) then raise TvkuException.Create('invalid function pointer: vkGetPhysicalDeviceSurfaceSupportKHR; did you enabled the VK_KHR_surface extension?'); err := fInstanceCommands.vkGetPhysicalDeviceSurfaceSupportKHR(fHandle, aQueueFamilyIndex, aSurface, @b); if (err < VK_SUCCESS) then raise TvkuErrorException.Create('unable to get physical device surface support', err); result := (b <> 0); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TvkuPhysicalDevice.GetSurfaceCapabilities(const aSurface: VkSurfaceKHR): TVkSurfaceCapabilitiesKHR; var err: TVkResult; begin if not Assigned(fInstanceCommands.vkGetPhysicalDeviceSurfaceCapabilitiesKHR) then raise TvkuException.Create('invalid function pointer: vkGetPhysicalDeviceSurfaceCapabilitiesKHR; did you enabled the VK_KHR_surface extension?'); err := fInstanceCommands.vkGetPhysicalDeviceSurfaceCapabilitiesKHR(fHandle, aSurface, @result); if (err < VK_SUCCESS) then raise TvkuErrorException.Create('unable to get physical device surface capabilities', err); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TvkuPhysicalDevice.GetSurfaceFormats(const aSurface: VkSurfaceKHR): TvkuSurfaceFormatArr; var c: VkUint32; begin result := nil; if not Assigned(fInstanceCommands.vkGetPhysicalDeviceSurfaceFormatsKHR) then raise TvkuException.Create('invalid function pointer: vkGetPhysicalDeviceSurfaceFormatsKHR; did you enabled the VK_KHR_surface extension?'); fInstanceCommands.vkGetPhysicalDeviceSurfaceFormatsKHR(fHandle, aSurface, @c, nil); SetLength(result, c); fInstanceCommands.vkGetPhysicalDeviceSurfaceFormatsKHR(fHandle, aSurface, @c, @result[0]); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TvkuPhysicalDevice.GetSurfacePresentModes(const aSurface: VkSurfaceKHR): TvkuPresentModeArr; var c: VkUint32; err: TVkResult; begin result := nil; if not Assigned(fInstanceCommands.vkGetPhysicalDeviceSurfacePresentModesKHR) then raise TvkuException.Create('invalid function pointer: vkGetPhysicalDeviceSurfacePresentModesKHR; did you enabled the VK_KHR_surface extension?'); err := fInstanceCommands.vkGetPhysicalDeviceSurfacePresentModesKHR(fHandle, aSurface, @c, nil); if (err < VK_SUCCESS) then raise TvkuErrorException.Create('unable to get physical device surface present mode count', err); SetLength(result, c); err := fInstanceCommands.vkGetPhysicalDeviceSurfacePresentModesKHR(fHandle, aSurface, @c, @result[0]); if (err < VK_SUCCESS) then raise TvkuErrorException.Create('unable to get physical device surface present modes', err); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TvkuPhysicalDevice.GetDisplayProperties: TvkuDisplayPropertiesArr; var err: TVkResult; c: VkUint32; begin result := nil; if not Assigned(fInstanceCommands.vkGetPhysicalDeviceDisplayPropertiesKHR) then raise TvkuException.Create('invalid function pointer: vkGetPhysicalDeviceDisplayPropertiesKHR; did you enabled the VK_KHR_display extension?'); err := fInstanceCommands.vkGetPhysicalDeviceDisplayPropertiesKHR(fHandle, @c, nil); if (err < VK_SUCCESS) then raise TvkuErrorException.Create('unable to get physical device display property count', err); SetLength(result, c); err := fInstanceCommands.vkGetPhysicalDeviceDisplayPropertiesKHR(fHandle, @c, @result[0]); if (err < VK_SUCCESS) then raise TvkuErrorException.Create('unable to get physical device display properties', err); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TvkuPhysicalDevice.GetDisplayPlaneProperties: TvkuDisplayPlanePropertiesArr; var err: TVkResult; c: VkUint32; begin result := nil; if not Assigned(fInstanceCommands.vkGetPhysicalDeviceDisplayPlanePropertiesKHR) then raise TvkuException.Create('invalid function pointer: vkGetPhysicalDeviceDisplayPlanePropertiesKHR; did you enabled the VK_KHR_display extension?'); err := fInstanceCommands.vkGetPhysicalDeviceDisplayPlanePropertiesKHR(fHandle, @c, nil); if (err < VK_SUCCESS) then raise TvkuErrorException.Create('unable to get physical device display plane property count', err); SetLength(result, c); err := fInstanceCommands.vkGetPhysicalDeviceDisplayPlanePropertiesKHR(fHandle, @c, @result[0]); if (err < VK_SUCCESS) then raise TvkuErrorException.Create('unable to get physical device display plane properties', err); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TvkuPhysicalDevice.GetDisplayPlaneSupportedDisplays(const aPlaneIndex: VkUint32): TvkuDisplayArr; var err: TVkResult; c: VkUint32; begin result := nil; if not Assigned(fInstanceCommands.vkGetDisplayPlaneSupportedDisplaysKHR) then raise TvkuException.Create('invalid function pointer: vkGetDisplayPlaneSupportedDisplaysKHR; did you enabled the VK_KHR_display extension?'); err := fInstanceCommands.vkGetDisplayPlaneSupportedDisplaysKHR(fHandle, aPlaneIndex, @c, nil); if (err < VK_SUCCESS) then raise TvkuErrorException.Create('unable to get supported display plane count', err); SetLength(result, c); err := fInstanceCommands.vkGetDisplayPlaneSupportedDisplaysKHR(fHandle, aPlaneIndex, @c, @result[0]); if (err < VK_SUCCESS) then raise TvkuErrorException.Create('unable to get supported display planes', err); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TvkuPhysicalDevice.GetDisplayModeProperties(const aDisplay: VkDisplayKHR): TvkuDisplayModePropertiesArr; var err: TVkResult; c: VkUint32; begin result := nil; if not Assigned(fInstanceCommands.vkGetDisplayModePropertiesKHR) then raise TvkuException.Create('invalid function pointer: vkGetDisplayModePropertiesKHR; did you enabled the VK_KHR_display extension?'); err := fInstanceCommands.vkGetDisplayModePropertiesKHR(fHandle, aDisplay, @c, nil); if (err < VK_SUCCESS) then raise TvkuErrorException.Create('unable to get display mode property count', err); SetLength(result, c); err := fInstanceCommands.vkGetDisplayPlaneSupportedDisplaysKHR(fHandle, aDisplay, @c, @result[0]); if (err < VK_SUCCESS) then raise TvkuErrorException.Create('unable to get display mode properties', err); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor TvkuPhysicalDevice.Create(const aHandle: VkPhysicalDevice; const aInstanceCommands: TVkInstanceCommands); begin if (aHandle = VK_INVALID_HANDLE) then raise TvkuException.Create('invalid physical device handle'); if not Assigned(aInstanceCommands) then raise TvkuException.Create('invalid instance commands'); inherited Create; fHandle := aHandle; fInstanceCommands := aInstanceCommands; end; end.