unit uvkuPhysicalDevice; {$mode objfpc}{$H+} interface uses Classes, SysUtils, Vulkan, uvkuInstance; type ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// TVkQueueFamilyPropertiesArr = array of TVkQueueFamilyProperties; TVkSparseImageFormatPropertiesArr = array of TVkSparseImageFormatProperties; TVkSurfaceFormatArr = array of TVkSurfaceFormatKHR; TVkPresentModeArr = array of TVkPresentModeKHR; TVkDisplayPropertiesArr = array of TVkDisplayPropertiesKHR; TVkDisplayPlanePropertiesArr = array of TVkDisplayPlanePropertiesKHR; TVkDisplayArr = array of VkDisplayKHR; TVkDisplayModePropertiesArr = 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: TVkQueueFamilyPropertiesArr; 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): TVkSparseImageFormatPropertiesArr; public { VK_KHR_surface } function GetSurfaceSupport(const aQueueFamilyIndex: VkUint32; const aSurface: VkSurfaceKHR): Boolean; function GetSurfaceCapabilities(const aSurface: VkSurfaceKHR): TVkSurfaceCapabilitiesKHR; function GetSurfaceFormats(const aSurface: VkSurfaceKHR): TVkSurfaceFormatArr; function GetSurfacePresentModes(const aSurface: VkSurfaceKHR): TVkPresentModeArr; public { VK_KHR_display } function GetDisplayProperties: TVkDisplayPropertiesArr; function GetDisplayPlaneProperties: TVkDisplayPlanePropertiesArr; function GetDisplayPlaneSupportedDisplays(const aPlaneIndex: VkUint32): TVkDisplayArr; function GetDisplayModeProperties(const aDisplay: VkDisplayKHR): TVkDisplayModePropertiesArr; 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: TVkQueueFamilyPropertiesArr; var c: VkUint32; begin 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): TVkSparseImageFormatPropertiesArr; var c: VkUint32; begin 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): TVkSurfaceFormatArr; var c: VkUint32; begin 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): TVkPresentModeArr; var c: VkUint32; err: TVkResult; begin 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: TVkDisplayPropertiesArr; var err: TVkResult; c: VkUint32; begin 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: TVkDisplayPlanePropertiesArr; var err: TVkResult; c: VkUint32; begin 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): TVkDisplayArr; var err: TVkResult; c: VkUint32; begin 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): TVkDisplayModePropertiesArr; var err: TVkResult; c: VkUint32; begin 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.