diff --git a/data/vulkan.tpl b/data/vulkan.tpl index 1e1ed7b..2f110be 100644 --- a/data/vulkan.tpl +++ b/data/vulkan.tpl @@ -89,12 +89,12 @@ type {%INTERFACE%} type - TVkInstanceCommands = packed record + TVkInstanceCommands = class Instance: VkInstance; {%INSTANCE_COMMANDS.INTERFACE%} end; - TVkDeviceCommands = packed record + TVkDeviceCommands = class Device: VkDevice; {%DEVICE_COMMANDS.INTERFACE%} end; @@ -111,12 +111,15 @@ function vkGetVersionMinor(const aVersion: VkVersion): Integer; inline; function vkGetVersionPatch(const aVersion: VkVersion): Integer; inline; function InitializeVulkan(const aLibName: String = VULKAN_LIBNAME): Boolean; -function LoadInstanceCommands(const aInstance: VkInstance; out aCommands: TVkInstanceCommands): Boolean; -function LoadDeviceCommands(const aInstance: VkInstance; const aDevice: VkDevice; out aCommands: TVkDeviceCommands): Boolean; +function LoadInstanceCommands(const aInstance: VkInstance): TVkInstanceCommands; +function LoadDeviceCommands(const aInstance: VkInstance; const aDevice: VkDevice): TVkDeviceCommands; procedure FinalizeVulkan; implementation +uses + SysUtils; + type {$IF DEFINED(VK_WIN)} TvkLibHandle = TLibHandle; @@ -210,46 +213,47 @@ begin result := success; end; -function LoadInstanceCommands(const aInstance: VkInstance; out aCommands: TVkInstanceCommands): Boolean; -var - success: Boolean; +function LoadInstanceCommands(const aInstance: VkInstance): TVkInstanceCommands; function GetProcAddress(const aName: String): TvkVoidFunction; begin result := vkGetInstanceProcAddr(aInstance, PVkChar(aName)); - if not Assigned(result) then - success := false; end; begin - FillByte(aCommands, SizeOf(aCommands), 0); - success := true; - with aCommands do begin - {%INSTANCE_COMMANDS.IMPLEMENTATION%} + result := TVkInstanceCommands.Create; + try + result.Instance := aInstance; + with result do begin + {%INSTANCE_COMMANDS.IMPLEMENTATION%} + end; + except + FreeAndNil(result); + raise; end; - result := success; end; -function LoadDeviceCommands(const aInstance: VkInstance; const aDevice: VkDevice; out aCommands: TVkDeviceCommands): Boolean; +function LoadDeviceCommands(const aInstance: VkInstance; const aDevice: VkDevice): TVkDeviceCommands; var vkGetDeviceProcAddr: TvkGetDeviceProcAddr; - success: Boolean; function GetProcAddress(const aName: String): TvkVoidFunction; begin result := vkGetDeviceProcAddr(aDevice, PVkChar(aName)); - if not Assigned(result) then - success := false; end; begin - FillByte(aCommands, SizeOf(aCommands), 0); vkGetDeviceProcAddr := TvkGetDeviceProcAddr(vkGetInstanceProcAddr(aInstance, 'vkGetDeviceProcAddr')); - success := true; - with aCommands do begin - {%DEVICE_COMMANDS.IMPLEMENTATION%} + result := TVkDeviceCommands.Create; + try + result.Device := aDevice; + with result do begin + {%DEVICE_COMMANDS.IMPLEMENTATION%} + end; + except + FreeAndNil(result); + raise; end; - result := success; end; procedure FinalizeVulkan; diff --git a/projects/Vulkan.pas b/projects/Vulkan.pas index b094574..8eab3e0 100644 --- a/projects/Vulkan.pas +++ b/projects/Vulkan.pas @@ -4227,7 +4227,7 @@ var vkEnumerateInstanceLayerProperties: TvkEnumerateInstanceLayerProperties; type - TVkInstanceCommands = packed record + TVkInstanceCommands = class Instance: VkInstance; { ========================================== VK_VERSION_1_0 ========================================== } @@ -4303,7 +4303,7 @@ type end; - TVkDeviceCommands = packed record + TVkDeviceCommands = class Device: VkDevice; { ========================================== VK_VERSION_1_0 ========================================== } @@ -4452,12 +4452,15 @@ function vkGetVersionMinor(const aVersion: VkVersion): Integer; inline; function vkGetVersionPatch(const aVersion: VkVersion): Integer; inline; function InitializeVulkan(const aLibName: String = VULKAN_LIBNAME): Boolean; -function LoadInstanceCommands(const aInstance: VkInstance; out aCommands: TVkInstanceCommands): Boolean; -function LoadDeviceCommands(const aInstance: VkInstance; const aDevice: VkDevice; out aCommands: TVkDeviceCommands): Boolean; +function LoadInstanceCommands(const aInstance: VkInstance): TVkInstanceCommands; +function LoadDeviceCommands(const aInstance: VkInstance; const aDevice: VkDevice): TVkDeviceCommands; procedure FinalizeVulkan; implementation +uses + SysUtils; + type {$IF DEFINED(VK_WIN)} TvkLibHandle = TLibHandle; @@ -4554,249 +4557,250 @@ begin result := success; end; -function LoadInstanceCommands(const aInstance: VkInstance; out aCommands: TVkInstanceCommands): Boolean; -var - success: Boolean; +function LoadInstanceCommands(const aInstance: VkInstance): TVkInstanceCommands; function GetProcAddress(const aName: String): TvkVoidFunction; begin result := vkGetInstanceProcAddr(aInstance, PVkChar(aName)); - if not Assigned(result) then - success := false; end; begin - FillByte(aCommands, SizeOf(aCommands), 0); - success := true; - with aCommands do begin - - { ========================================== VK_VERSION_1_0 ========================================== } - vkDestroyInstance := TvkDestroyInstance (GetProcAddress('vkDestroyInstance')); - vkEnumeratePhysicalDevices := TvkEnumeratePhysicalDevices (GetProcAddress('vkEnumeratePhysicalDevices')); - vkGetPhysicalDeviceFeatures := TvkGetPhysicalDeviceFeatures (GetProcAddress('vkGetPhysicalDeviceFeatures')); - vkGetPhysicalDeviceFormatProperties := TvkGetPhysicalDeviceFormatProperties (GetProcAddress('vkGetPhysicalDeviceFormatProperties')); - vkGetPhysicalDeviceImageFormatProperties := TvkGetPhysicalDeviceImageFormatProperties (GetProcAddress('vkGetPhysicalDeviceImageFormatProperties')); - vkGetPhysicalDeviceProperties := TvkGetPhysicalDeviceProperties (GetProcAddress('vkGetPhysicalDeviceProperties')); - vkGetPhysicalDeviceQueueFamilyProperties := TvkGetPhysicalDeviceQueueFamilyProperties (GetProcAddress('vkGetPhysicalDeviceQueueFamilyProperties')); - vkGetPhysicalDeviceMemoryProperties := TvkGetPhysicalDeviceMemoryProperties (GetProcAddress('vkGetPhysicalDeviceMemoryProperties')); - vkGetDeviceProcAddr := TvkGetDeviceProcAddr (GetProcAddress('vkGetDeviceProcAddr')); - vkCreateDevice := TvkCreateDevice (GetProcAddress('vkCreateDevice')); - vkEnumerateDeviceExtensionProperties := TvkEnumerateDeviceExtensionProperties (GetProcAddress('vkEnumerateDeviceExtensionProperties')); - vkEnumerateDeviceLayerProperties := TvkEnumerateDeviceLayerProperties (GetProcAddress('vkEnumerateDeviceLayerProperties')); - vkGetPhysicalDeviceSparseImageFormatProperties := TvkGetPhysicalDeviceSparseImageFormatProperties (GetProcAddress('vkGetPhysicalDeviceSparseImageFormatProperties')); - - { ========================================== VK_KHR_surface ========================================== } - vkDestroySurfaceKHR := TvkDestroySurfaceKHR (GetProcAddress('vkDestroySurfaceKHR')); - vkGetPhysicalDeviceSurfaceSupportKHR := TvkGetPhysicalDeviceSurfaceSupportKHR (GetProcAddress('vkGetPhysicalDeviceSurfaceSupportKHR')); - vkGetPhysicalDeviceSurfaceCapabilitiesKHR := TvkGetPhysicalDeviceSurfaceCapabilitiesKHR (GetProcAddress('vkGetPhysicalDeviceSurfaceCapabilitiesKHR')); - vkGetPhysicalDeviceSurfaceFormatsKHR := TvkGetPhysicalDeviceSurfaceFormatsKHR (GetProcAddress('vkGetPhysicalDeviceSurfaceFormatsKHR')); - vkGetPhysicalDeviceSurfacePresentModesKHR := TvkGetPhysicalDeviceSurfacePresentModesKHR (GetProcAddress('vkGetPhysicalDeviceSurfacePresentModesKHR')); - - { ========================================== VK_KHR_display ========================================== } - vkGetPhysicalDeviceDisplayPropertiesKHR := TvkGetPhysicalDeviceDisplayPropertiesKHR (GetProcAddress('vkGetPhysicalDeviceDisplayPropertiesKHR')); - vkGetPhysicalDeviceDisplayPlanePropertiesKHR := TvkGetPhysicalDeviceDisplayPlanePropertiesKHR (GetProcAddress('vkGetPhysicalDeviceDisplayPlanePropertiesKHR')); - vkGetDisplayPlaneSupportedDisplaysKHR := TvkGetDisplayPlaneSupportedDisplaysKHR (GetProcAddress('vkGetDisplayPlaneSupportedDisplaysKHR')); - vkGetDisplayModePropertiesKHR := TvkGetDisplayModePropertiesKHR (GetProcAddress('vkGetDisplayModePropertiesKHR')); - vkCreateDisplayModeKHR := TvkCreateDisplayModeKHR (GetProcAddress('vkCreateDisplayModeKHR')); - vkGetDisplayPlaneCapabilitiesKHR := TvkGetDisplayPlaneCapabilitiesKHR (GetProcAddress('vkGetDisplayPlaneCapabilitiesKHR')); - vkCreateDisplayPlaneSurfaceKHR := TvkCreateDisplayPlaneSurfaceKHR (GetProcAddress('vkCreateDisplayPlaneSurfaceKHR')); - - { ======================================= VK_KHR_xlib_surface ======================================== } - {$IFDEF VK_USE_PLATFORM_XLIB_KHR} - vkCreateXlibSurfaceKHR := TvkCreateXlibSurfaceKHR (GetProcAddress('vkCreateXlibSurfaceKHR')); - vkGetPhysicalDeviceXlibPresentationSupportKHR := TvkGetPhysicalDeviceXlibPresentationSupportKHR (GetProcAddress('vkGetPhysicalDeviceXlibPresentationSupportKHR')); - {$ENDIF} - - { ======================================== VK_KHR_xcb_surface ======================================== } - {$IFDEF VK_USE_PLATFORM_XCB_KHR} - vkCreateXcbSurfaceKHR := TvkCreateXcbSurfaceKHR (GetProcAddress('vkCreateXcbSurfaceKHR')); - vkGetPhysicalDeviceXcbPresentationSupportKHR := TvkGetPhysicalDeviceXcbPresentationSupportKHR (GetProcAddress('vkGetPhysicalDeviceXcbPresentationSupportKHR')); - {$ENDIF} - - { ====================================== VK_KHR_wayland_surface ====================================== } - {$IFDEF VK_USE_PLATFORM_WAYLAND_KHR} - vkCreateWaylandSurfaceKHR := TvkCreateWaylandSurfaceKHR (GetProcAddress('vkCreateWaylandSurfaceKHR')); - vkGetPhysicalDeviceWaylandPresentationSupportKHR := TvkGetPhysicalDeviceWaylandPresentationSupportKHR (GetProcAddress('vkGetPhysicalDeviceWaylandPresentationSupportKHR')); - {$ENDIF} - - { ======================================== VK_KHR_mir_surface ======================================== } - {$IFDEF VK_USE_PLATFORM_MIR_KHR} - vkCreateMirSurfaceKHR := TvkCreateMirSurfaceKHR (GetProcAddress('vkCreateMirSurfaceKHR')); - vkGetPhysicalDeviceMirPresentationSupportKHR := TvkGetPhysicalDeviceMirPresentationSupportKHR (GetProcAddress('vkGetPhysicalDeviceMirPresentationSupportKHR')); - {$ENDIF} - - { ====================================== VK_KHR_android_surface ====================================== } - {$IFDEF VK_USE_PLATFORM_ANDROID_KHR} - vkCreateAndroidSurfaceKHR := TvkCreateAndroidSurfaceKHR (GetProcAddress('vkCreateAndroidSurfaceKHR')); - {$ENDIF} - - { ======================================= VK_KHR_win32_surface ======================================= } - {$IFDEF VK_USE_PLATFORM_WIN32_KHR} - vkCreateWin32SurfaceKHR := TvkCreateWin32SurfaceKHR (GetProcAddress('vkCreateWin32SurfaceKHR')); - vkGetPhysicalDeviceWin32PresentationSupportKHR := TvkGetPhysicalDeviceWin32PresentationSupportKHR (GetProcAddress('vkGetPhysicalDeviceWin32PresentationSupportKHR')); - {$ENDIF} - - { ======================================= VK_EXT_debug_report ======================================== } - vkCreateDebugReportCallbackEXT := TvkCreateDebugReportCallbackEXT (GetProcAddress('vkCreateDebugReportCallbackEXT')); - vkDestroyDebugReportCallbackEXT := TvkDestroyDebugReportCallbackEXT (GetProcAddress('vkDestroyDebugReportCallbackEXT')); - vkDebugReportMessageEXT := TvkDebugReportMessageEXT (GetProcAddress('vkDebugReportMessageEXT')); - + result := TVkInstanceCommands.Create; + try + result.Instance := aInstance; + with result do begin + + { ========================================== VK_VERSION_1_0 ========================================== } + vkDestroyInstance := TvkDestroyInstance (GetProcAddress('vkDestroyInstance')); + vkEnumeratePhysicalDevices := TvkEnumeratePhysicalDevices (GetProcAddress('vkEnumeratePhysicalDevices')); + vkGetPhysicalDeviceFeatures := TvkGetPhysicalDeviceFeatures (GetProcAddress('vkGetPhysicalDeviceFeatures')); + vkGetPhysicalDeviceFormatProperties := TvkGetPhysicalDeviceFormatProperties (GetProcAddress('vkGetPhysicalDeviceFormatProperties')); + vkGetPhysicalDeviceImageFormatProperties := TvkGetPhysicalDeviceImageFormatProperties (GetProcAddress('vkGetPhysicalDeviceImageFormatProperties')); + vkGetPhysicalDeviceProperties := TvkGetPhysicalDeviceProperties (GetProcAddress('vkGetPhysicalDeviceProperties')); + vkGetPhysicalDeviceQueueFamilyProperties := TvkGetPhysicalDeviceQueueFamilyProperties (GetProcAddress('vkGetPhysicalDeviceQueueFamilyProperties')); + vkGetPhysicalDeviceMemoryProperties := TvkGetPhysicalDeviceMemoryProperties (GetProcAddress('vkGetPhysicalDeviceMemoryProperties')); + vkGetDeviceProcAddr := TvkGetDeviceProcAddr (GetProcAddress('vkGetDeviceProcAddr')); + vkCreateDevice := TvkCreateDevice (GetProcAddress('vkCreateDevice')); + vkEnumerateDeviceExtensionProperties := TvkEnumerateDeviceExtensionProperties (GetProcAddress('vkEnumerateDeviceExtensionProperties')); + vkEnumerateDeviceLayerProperties := TvkEnumerateDeviceLayerProperties (GetProcAddress('vkEnumerateDeviceLayerProperties')); + vkGetPhysicalDeviceSparseImageFormatProperties := TvkGetPhysicalDeviceSparseImageFormatProperties (GetProcAddress('vkGetPhysicalDeviceSparseImageFormatProperties')); + + { ========================================== VK_KHR_surface ========================================== } + vkDestroySurfaceKHR := TvkDestroySurfaceKHR (GetProcAddress('vkDestroySurfaceKHR')); + vkGetPhysicalDeviceSurfaceSupportKHR := TvkGetPhysicalDeviceSurfaceSupportKHR (GetProcAddress('vkGetPhysicalDeviceSurfaceSupportKHR')); + vkGetPhysicalDeviceSurfaceCapabilitiesKHR := TvkGetPhysicalDeviceSurfaceCapabilitiesKHR (GetProcAddress('vkGetPhysicalDeviceSurfaceCapabilitiesKHR')); + vkGetPhysicalDeviceSurfaceFormatsKHR := TvkGetPhysicalDeviceSurfaceFormatsKHR (GetProcAddress('vkGetPhysicalDeviceSurfaceFormatsKHR')); + vkGetPhysicalDeviceSurfacePresentModesKHR := TvkGetPhysicalDeviceSurfacePresentModesKHR (GetProcAddress('vkGetPhysicalDeviceSurfacePresentModesKHR')); + + { ========================================== VK_KHR_display ========================================== } + vkGetPhysicalDeviceDisplayPropertiesKHR := TvkGetPhysicalDeviceDisplayPropertiesKHR (GetProcAddress('vkGetPhysicalDeviceDisplayPropertiesKHR')); + vkGetPhysicalDeviceDisplayPlanePropertiesKHR := TvkGetPhysicalDeviceDisplayPlanePropertiesKHR (GetProcAddress('vkGetPhysicalDeviceDisplayPlanePropertiesKHR')); + vkGetDisplayPlaneSupportedDisplaysKHR := TvkGetDisplayPlaneSupportedDisplaysKHR (GetProcAddress('vkGetDisplayPlaneSupportedDisplaysKHR')); + vkGetDisplayModePropertiesKHR := TvkGetDisplayModePropertiesKHR (GetProcAddress('vkGetDisplayModePropertiesKHR')); + vkCreateDisplayModeKHR := TvkCreateDisplayModeKHR (GetProcAddress('vkCreateDisplayModeKHR')); + vkGetDisplayPlaneCapabilitiesKHR := TvkGetDisplayPlaneCapabilitiesKHR (GetProcAddress('vkGetDisplayPlaneCapabilitiesKHR')); + vkCreateDisplayPlaneSurfaceKHR := TvkCreateDisplayPlaneSurfaceKHR (GetProcAddress('vkCreateDisplayPlaneSurfaceKHR')); + + { ======================================= VK_KHR_xlib_surface ======================================== } + {$IFDEF VK_USE_PLATFORM_XLIB_KHR} + vkCreateXlibSurfaceKHR := TvkCreateXlibSurfaceKHR (GetProcAddress('vkCreateXlibSurfaceKHR')); + vkGetPhysicalDeviceXlibPresentationSupportKHR := TvkGetPhysicalDeviceXlibPresentationSupportKHR (GetProcAddress('vkGetPhysicalDeviceXlibPresentationSupportKHR')); + {$ENDIF} + + { ======================================== VK_KHR_xcb_surface ======================================== } + {$IFDEF VK_USE_PLATFORM_XCB_KHR} + vkCreateXcbSurfaceKHR := TvkCreateXcbSurfaceKHR (GetProcAddress('vkCreateXcbSurfaceKHR')); + vkGetPhysicalDeviceXcbPresentationSupportKHR := TvkGetPhysicalDeviceXcbPresentationSupportKHR (GetProcAddress('vkGetPhysicalDeviceXcbPresentationSupportKHR')); + {$ENDIF} + + { ====================================== VK_KHR_wayland_surface ====================================== } + {$IFDEF VK_USE_PLATFORM_WAYLAND_KHR} + vkCreateWaylandSurfaceKHR := TvkCreateWaylandSurfaceKHR (GetProcAddress('vkCreateWaylandSurfaceKHR')); + vkGetPhysicalDeviceWaylandPresentationSupportKHR := TvkGetPhysicalDeviceWaylandPresentationSupportKHR (GetProcAddress('vkGetPhysicalDeviceWaylandPresentationSupportKHR')); + {$ENDIF} + + { ======================================== VK_KHR_mir_surface ======================================== } + {$IFDEF VK_USE_PLATFORM_MIR_KHR} + vkCreateMirSurfaceKHR := TvkCreateMirSurfaceKHR (GetProcAddress('vkCreateMirSurfaceKHR')); + vkGetPhysicalDeviceMirPresentationSupportKHR := TvkGetPhysicalDeviceMirPresentationSupportKHR (GetProcAddress('vkGetPhysicalDeviceMirPresentationSupportKHR')); + {$ENDIF} + + { ====================================== VK_KHR_android_surface ====================================== } + {$IFDEF VK_USE_PLATFORM_ANDROID_KHR} + vkCreateAndroidSurfaceKHR := TvkCreateAndroidSurfaceKHR (GetProcAddress('vkCreateAndroidSurfaceKHR')); + {$ENDIF} + + { ======================================= VK_KHR_win32_surface ======================================= } + {$IFDEF VK_USE_PLATFORM_WIN32_KHR} + vkCreateWin32SurfaceKHR := TvkCreateWin32SurfaceKHR (GetProcAddress('vkCreateWin32SurfaceKHR')); + vkGetPhysicalDeviceWin32PresentationSupportKHR := TvkGetPhysicalDeviceWin32PresentationSupportKHR (GetProcAddress('vkGetPhysicalDeviceWin32PresentationSupportKHR')); + {$ENDIF} + + { ======================================= VK_EXT_debug_report ======================================== } + vkCreateDebugReportCallbackEXT := TvkCreateDebugReportCallbackEXT (GetProcAddress('vkCreateDebugReportCallbackEXT')); + vkDestroyDebugReportCallbackEXT := TvkDestroyDebugReportCallbackEXT (GetProcAddress('vkDestroyDebugReportCallbackEXT')); + vkDebugReportMessageEXT := TvkDebugReportMessageEXT (GetProcAddress('vkDebugReportMessageEXT')); + + end; + except + FreeAndNil(result); + raise; end; - result := success; end; -function LoadDeviceCommands(const aInstance: VkInstance; const aDevice: VkDevice; out aCommands: TVkDeviceCommands): Boolean; +function LoadDeviceCommands(const aInstance: VkInstance; const aDevice: VkDevice): TVkDeviceCommands; var vkGetDeviceProcAddr: TvkGetDeviceProcAddr; - success: Boolean; function GetProcAddress(const aName: String): TvkVoidFunction; begin result := vkGetDeviceProcAddr(aDevice, PVkChar(aName)); - if not Assigned(result) then - success := false; end; begin - FillByte(aCommands, SizeOf(aCommands), 0); vkGetDeviceProcAddr := TvkGetDeviceProcAddr(vkGetInstanceProcAddr(aInstance, 'vkGetDeviceProcAddr')); - success := true; - with aCommands do begin - - { ========================================== VK_VERSION_1_0 ========================================== } - vkDestroyDevice := TvkDestroyDevice (GetProcAddress('vkDestroyDevice')); - vkGetDeviceQueue := TvkGetDeviceQueue (GetProcAddress('vkGetDeviceQueue')); - vkQueueSubmit := TvkQueueSubmit (GetProcAddress('vkQueueSubmit')); - vkQueueWaitIdle := TvkQueueWaitIdle (GetProcAddress('vkQueueWaitIdle')); - vkDeviceWaitIdle := TvkDeviceWaitIdle (GetProcAddress('vkDeviceWaitIdle')); - vkAllocateMemory := TvkAllocateMemory (GetProcAddress('vkAllocateMemory')); - vkFreeMemory := TvkFreeMemory (GetProcAddress('vkFreeMemory')); - vkMapMemory := TvkMapMemory (GetProcAddress('vkMapMemory')); - vkUnmapMemory := TvkUnmapMemory (GetProcAddress('vkUnmapMemory')); - vkFlushMappedMemoryRanges := TvkFlushMappedMemoryRanges (GetProcAddress('vkFlushMappedMemoryRanges')); - vkInvalidateMappedMemoryRanges := TvkInvalidateMappedMemoryRanges (GetProcAddress('vkInvalidateMappedMemoryRanges')); - vkGetDeviceMemoryCommitment := TvkGetDeviceMemoryCommitment (GetProcAddress('vkGetDeviceMemoryCommitment')); - vkBindBufferMemory := TvkBindBufferMemory (GetProcAddress('vkBindBufferMemory')); - vkBindImageMemory := TvkBindImageMemory (GetProcAddress('vkBindImageMemory')); - vkGetBufferMemoryRequirements := TvkGetBufferMemoryRequirements (GetProcAddress('vkGetBufferMemoryRequirements')); - vkGetImageMemoryRequirements := TvkGetImageMemoryRequirements (GetProcAddress('vkGetImageMemoryRequirements')); - vkGetImageSparseMemoryRequirements := TvkGetImageSparseMemoryRequirements (GetProcAddress('vkGetImageSparseMemoryRequirements')); - vkQueueBindSparse := TvkQueueBindSparse (GetProcAddress('vkQueueBindSparse')); - vkCreateFence := TvkCreateFence (GetProcAddress('vkCreateFence')); - vkDestroyFence := TvkDestroyFence (GetProcAddress('vkDestroyFence')); - vkResetFences := TvkResetFences (GetProcAddress('vkResetFences')); - vkGetFenceStatus := TvkGetFenceStatus (GetProcAddress('vkGetFenceStatus')); - vkWaitForFences := TvkWaitForFences (GetProcAddress('vkWaitForFences')); - vkCreateSemaphore := TvkCreateSemaphore (GetProcAddress('vkCreateSemaphore')); - vkDestroySemaphore := TvkDestroySemaphore (GetProcAddress('vkDestroySemaphore')); - vkCreateEvent := TvkCreateEvent (GetProcAddress('vkCreateEvent')); - vkDestroyEvent := TvkDestroyEvent (GetProcAddress('vkDestroyEvent')); - vkGetEventStatus := TvkGetEventStatus (GetProcAddress('vkGetEventStatus')); - vkSetEvent := TvkSetEvent (GetProcAddress('vkSetEvent')); - vkResetEvent := TvkResetEvent (GetProcAddress('vkResetEvent')); - vkCreateQueryPool := TvkCreateQueryPool (GetProcAddress('vkCreateQueryPool')); - vkDestroyQueryPool := TvkDestroyQueryPool (GetProcAddress('vkDestroyQueryPool')); - vkGetQueryPoolResults := TvkGetQueryPoolResults (GetProcAddress('vkGetQueryPoolResults')); - vkCreateBuffer := TvkCreateBuffer (GetProcAddress('vkCreateBuffer')); - vkDestroyBuffer := TvkDestroyBuffer (GetProcAddress('vkDestroyBuffer')); - vkCreateBufferView := TvkCreateBufferView (GetProcAddress('vkCreateBufferView')); - vkDestroyBufferView := TvkDestroyBufferView (GetProcAddress('vkDestroyBufferView')); - vkCreateImage := TvkCreateImage (GetProcAddress('vkCreateImage')); - vkDestroyImage := TvkDestroyImage (GetProcAddress('vkDestroyImage')); - vkGetImageSubresourceLayout := TvkGetImageSubresourceLayout (GetProcAddress('vkGetImageSubresourceLayout')); - vkCreateImageView := TvkCreateImageView (GetProcAddress('vkCreateImageView')); - vkDestroyImageView := TvkDestroyImageView (GetProcAddress('vkDestroyImageView')); - vkCreateShaderModule := TvkCreateShaderModule (GetProcAddress('vkCreateShaderModule')); - vkDestroyShaderModule := TvkDestroyShaderModule (GetProcAddress('vkDestroyShaderModule')); - vkCreatePipelineCache := TvkCreatePipelineCache (GetProcAddress('vkCreatePipelineCache')); - vkDestroyPipelineCache := TvkDestroyPipelineCache (GetProcAddress('vkDestroyPipelineCache')); - vkGetPipelineCacheData := TvkGetPipelineCacheData (GetProcAddress('vkGetPipelineCacheData')); - vkMergePipelineCaches := TvkMergePipelineCaches (GetProcAddress('vkMergePipelineCaches')); - vkCreateGraphicsPipelines := TvkCreateGraphicsPipelines (GetProcAddress('vkCreateGraphicsPipelines')); - vkCreateComputePipelines := TvkCreateComputePipelines (GetProcAddress('vkCreateComputePipelines')); - vkDestroyPipeline := TvkDestroyPipeline (GetProcAddress('vkDestroyPipeline')); - vkCreatePipelineLayout := TvkCreatePipelineLayout (GetProcAddress('vkCreatePipelineLayout')); - vkDestroyPipelineLayout := TvkDestroyPipelineLayout (GetProcAddress('vkDestroyPipelineLayout')); - vkCreateSampler := TvkCreateSampler (GetProcAddress('vkCreateSampler')); - vkDestroySampler := TvkDestroySampler (GetProcAddress('vkDestroySampler')); - vkCreateDescriptorSetLayout := TvkCreateDescriptorSetLayout (GetProcAddress('vkCreateDescriptorSetLayout')); - vkDestroyDescriptorSetLayout := TvkDestroyDescriptorSetLayout (GetProcAddress('vkDestroyDescriptorSetLayout')); - vkCreateDescriptorPool := TvkCreateDescriptorPool (GetProcAddress('vkCreateDescriptorPool')); - vkDestroyDescriptorPool := TvkDestroyDescriptorPool (GetProcAddress('vkDestroyDescriptorPool')); - vkResetDescriptorPool := TvkResetDescriptorPool (GetProcAddress('vkResetDescriptorPool')); - vkAllocateDescriptorSets := TvkAllocateDescriptorSets (GetProcAddress('vkAllocateDescriptorSets')); - vkFreeDescriptorSets := TvkFreeDescriptorSets (GetProcAddress('vkFreeDescriptorSets')); - vkUpdateDescriptorSets := TvkUpdateDescriptorSets (GetProcAddress('vkUpdateDescriptorSets')); - vkCreateFramebuffer := TvkCreateFramebuffer (GetProcAddress('vkCreateFramebuffer')); - vkDestroyFramebuffer := TvkDestroyFramebuffer (GetProcAddress('vkDestroyFramebuffer')); - vkCreateRenderPass := TvkCreateRenderPass (GetProcAddress('vkCreateRenderPass')); - vkDestroyRenderPass := TvkDestroyRenderPass (GetProcAddress('vkDestroyRenderPass')); - vkGetRenderAreaGranularity := TvkGetRenderAreaGranularity (GetProcAddress('vkGetRenderAreaGranularity')); - vkCreateCommandPool := TvkCreateCommandPool (GetProcAddress('vkCreateCommandPool')); - vkDestroyCommandPool := TvkDestroyCommandPool (GetProcAddress('vkDestroyCommandPool')); - vkResetCommandPool := TvkResetCommandPool (GetProcAddress('vkResetCommandPool')); - vkAllocateCommandBuffers := TvkAllocateCommandBuffers (GetProcAddress('vkAllocateCommandBuffers')); - vkFreeCommandBuffers := TvkFreeCommandBuffers (GetProcAddress('vkFreeCommandBuffers')); - vkBeginCommandBuffer := TvkBeginCommandBuffer (GetProcAddress('vkBeginCommandBuffer')); - vkEndCommandBuffer := TvkEndCommandBuffer (GetProcAddress('vkEndCommandBuffer')); - vkResetCommandBuffer := TvkResetCommandBuffer (GetProcAddress('vkResetCommandBuffer')); - vkCmdBindPipeline := TvkCmdBindPipeline (GetProcAddress('vkCmdBindPipeline')); - vkCmdSetViewport := TvkCmdSetViewport (GetProcAddress('vkCmdSetViewport')); - vkCmdSetScissor := TvkCmdSetScissor (GetProcAddress('vkCmdSetScissor')); - vkCmdSetLineWidth := TvkCmdSetLineWidth (GetProcAddress('vkCmdSetLineWidth')); - vkCmdSetDepthBias := TvkCmdSetDepthBias (GetProcAddress('vkCmdSetDepthBias')); - vkCmdSetBlendConstants := TvkCmdSetBlendConstants (GetProcAddress('vkCmdSetBlendConstants')); - vkCmdSetDepthBounds := TvkCmdSetDepthBounds (GetProcAddress('vkCmdSetDepthBounds')); - vkCmdSetStencilCompareMask := TvkCmdSetStencilCompareMask (GetProcAddress('vkCmdSetStencilCompareMask')); - vkCmdSetStencilWriteMask := TvkCmdSetStencilWriteMask (GetProcAddress('vkCmdSetStencilWriteMask')); - vkCmdSetStencilReference := TvkCmdSetStencilReference (GetProcAddress('vkCmdSetStencilReference')); - vkCmdBindDescriptorSets := TvkCmdBindDescriptorSets (GetProcAddress('vkCmdBindDescriptorSets')); - vkCmdBindIndexBuffer := TvkCmdBindIndexBuffer (GetProcAddress('vkCmdBindIndexBuffer')); - vkCmdBindVertexBuffers := TvkCmdBindVertexBuffers (GetProcAddress('vkCmdBindVertexBuffers')); - vkCmdDraw := TvkCmdDraw (GetProcAddress('vkCmdDraw')); - vkCmdDrawIndexed := TvkCmdDrawIndexed (GetProcAddress('vkCmdDrawIndexed')); - vkCmdDrawIndirect := TvkCmdDrawIndirect (GetProcAddress('vkCmdDrawIndirect')); - vkCmdDrawIndexedIndirect := TvkCmdDrawIndexedIndirect (GetProcAddress('vkCmdDrawIndexedIndirect')); - vkCmdDispatch := TvkCmdDispatch (GetProcAddress('vkCmdDispatch')); - vkCmdDispatchIndirect := TvkCmdDispatchIndirect (GetProcAddress('vkCmdDispatchIndirect')); - vkCmdCopyBuffer := TvkCmdCopyBuffer (GetProcAddress('vkCmdCopyBuffer')); - vkCmdCopyImage := TvkCmdCopyImage (GetProcAddress('vkCmdCopyImage')); - vkCmdBlitImage := TvkCmdBlitImage (GetProcAddress('vkCmdBlitImage')); - vkCmdCopyBufferToImage := TvkCmdCopyBufferToImage (GetProcAddress('vkCmdCopyBufferToImage')); - vkCmdCopyImageToBuffer := TvkCmdCopyImageToBuffer (GetProcAddress('vkCmdCopyImageToBuffer')); - vkCmdUpdateBuffer := TvkCmdUpdateBuffer (GetProcAddress('vkCmdUpdateBuffer')); - vkCmdFillBuffer := TvkCmdFillBuffer (GetProcAddress('vkCmdFillBuffer')); - vkCmdClearColorImage := TvkCmdClearColorImage (GetProcAddress('vkCmdClearColorImage')); - vkCmdClearDepthStencilImage := TvkCmdClearDepthStencilImage (GetProcAddress('vkCmdClearDepthStencilImage')); - vkCmdClearAttachments := TvkCmdClearAttachments (GetProcAddress('vkCmdClearAttachments')); - vkCmdResolveImage := TvkCmdResolveImage (GetProcAddress('vkCmdResolveImage')); - vkCmdSetEvent := TvkCmdSetEvent (GetProcAddress('vkCmdSetEvent')); - vkCmdResetEvent := TvkCmdResetEvent (GetProcAddress('vkCmdResetEvent')); - vkCmdWaitEvents := TvkCmdWaitEvents (GetProcAddress('vkCmdWaitEvents')); - vkCmdPipelineBarrier := TvkCmdPipelineBarrier (GetProcAddress('vkCmdPipelineBarrier')); - vkCmdBeginQuery := TvkCmdBeginQuery (GetProcAddress('vkCmdBeginQuery')); - vkCmdEndQuery := TvkCmdEndQuery (GetProcAddress('vkCmdEndQuery')); - vkCmdResetQueryPool := TvkCmdResetQueryPool (GetProcAddress('vkCmdResetQueryPool')); - vkCmdWriteTimestamp := TvkCmdWriteTimestamp (GetProcAddress('vkCmdWriteTimestamp')); - vkCmdCopyQueryPoolResults := TvkCmdCopyQueryPoolResults (GetProcAddress('vkCmdCopyQueryPoolResults')); - vkCmdPushConstants := TvkCmdPushConstants (GetProcAddress('vkCmdPushConstants')); - vkCmdBeginRenderPass := TvkCmdBeginRenderPass (GetProcAddress('vkCmdBeginRenderPass')); - vkCmdNextSubpass := TvkCmdNextSubpass (GetProcAddress('vkCmdNextSubpass')); - vkCmdEndRenderPass := TvkCmdEndRenderPass (GetProcAddress('vkCmdEndRenderPass')); - vkCmdExecuteCommands := TvkCmdExecuteCommands (GetProcAddress('vkCmdExecuteCommands')); - - { ========================================= VK_KHR_swapchain ========================================= } - vkCreateSwapchainKHR := TvkCreateSwapchainKHR (GetProcAddress('vkCreateSwapchainKHR')); - vkDestroySwapchainKHR := TvkDestroySwapchainKHR (GetProcAddress('vkDestroySwapchainKHR')); - vkGetSwapchainImagesKHR := TvkGetSwapchainImagesKHR (GetProcAddress('vkGetSwapchainImagesKHR')); - vkAcquireNextImageKHR := TvkAcquireNextImageKHR (GetProcAddress('vkAcquireNextImageKHR')); - vkQueuePresentKHR := TvkQueuePresentKHR (GetProcAddress('vkQueuePresentKHR')); - - { ===================================== VK_KHR_display_swapchain ===================================== } - vkCreateSharedSwapchainsKHR := TvkCreateSharedSwapchainsKHR (GetProcAddress('vkCreateSharedSwapchainsKHR')); - + result := TVkDeviceCommands.Create; + try + result.Device := aDevice; + with result do begin + + { ========================================== VK_VERSION_1_0 ========================================== } + vkDestroyDevice := TvkDestroyDevice (GetProcAddress('vkDestroyDevice')); + vkGetDeviceQueue := TvkGetDeviceQueue (GetProcAddress('vkGetDeviceQueue')); + vkQueueSubmit := TvkQueueSubmit (GetProcAddress('vkQueueSubmit')); + vkQueueWaitIdle := TvkQueueWaitIdle (GetProcAddress('vkQueueWaitIdle')); + vkDeviceWaitIdle := TvkDeviceWaitIdle (GetProcAddress('vkDeviceWaitIdle')); + vkAllocateMemory := TvkAllocateMemory (GetProcAddress('vkAllocateMemory')); + vkFreeMemory := TvkFreeMemory (GetProcAddress('vkFreeMemory')); + vkMapMemory := TvkMapMemory (GetProcAddress('vkMapMemory')); + vkUnmapMemory := TvkUnmapMemory (GetProcAddress('vkUnmapMemory')); + vkFlushMappedMemoryRanges := TvkFlushMappedMemoryRanges (GetProcAddress('vkFlushMappedMemoryRanges')); + vkInvalidateMappedMemoryRanges := TvkInvalidateMappedMemoryRanges (GetProcAddress('vkInvalidateMappedMemoryRanges')); + vkGetDeviceMemoryCommitment := TvkGetDeviceMemoryCommitment (GetProcAddress('vkGetDeviceMemoryCommitment')); + vkBindBufferMemory := TvkBindBufferMemory (GetProcAddress('vkBindBufferMemory')); + vkBindImageMemory := TvkBindImageMemory (GetProcAddress('vkBindImageMemory')); + vkGetBufferMemoryRequirements := TvkGetBufferMemoryRequirements (GetProcAddress('vkGetBufferMemoryRequirements')); + vkGetImageMemoryRequirements := TvkGetImageMemoryRequirements (GetProcAddress('vkGetImageMemoryRequirements')); + vkGetImageSparseMemoryRequirements := TvkGetImageSparseMemoryRequirements (GetProcAddress('vkGetImageSparseMemoryRequirements')); + vkQueueBindSparse := TvkQueueBindSparse (GetProcAddress('vkQueueBindSparse')); + vkCreateFence := TvkCreateFence (GetProcAddress('vkCreateFence')); + vkDestroyFence := TvkDestroyFence (GetProcAddress('vkDestroyFence')); + vkResetFences := TvkResetFences (GetProcAddress('vkResetFences')); + vkGetFenceStatus := TvkGetFenceStatus (GetProcAddress('vkGetFenceStatus')); + vkWaitForFences := TvkWaitForFences (GetProcAddress('vkWaitForFences')); + vkCreateSemaphore := TvkCreateSemaphore (GetProcAddress('vkCreateSemaphore')); + vkDestroySemaphore := TvkDestroySemaphore (GetProcAddress('vkDestroySemaphore')); + vkCreateEvent := TvkCreateEvent (GetProcAddress('vkCreateEvent')); + vkDestroyEvent := TvkDestroyEvent (GetProcAddress('vkDestroyEvent')); + vkGetEventStatus := TvkGetEventStatus (GetProcAddress('vkGetEventStatus')); + vkSetEvent := TvkSetEvent (GetProcAddress('vkSetEvent')); + vkResetEvent := TvkResetEvent (GetProcAddress('vkResetEvent')); + vkCreateQueryPool := TvkCreateQueryPool (GetProcAddress('vkCreateQueryPool')); + vkDestroyQueryPool := TvkDestroyQueryPool (GetProcAddress('vkDestroyQueryPool')); + vkGetQueryPoolResults := TvkGetQueryPoolResults (GetProcAddress('vkGetQueryPoolResults')); + vkCreateBuffer := TvkCreateBuffer (GetProcAddress('vkCreateBuffer')); + vkDestroyBuffer := TvkDestroyBuffer (GetProcAddress('vkDestroyBuffer')); + vkCreateBufferView := TvkCreateBufferView (GetProcAddress('vkCreateBufferView')); + vkDestroyBufferView := TvkDestroyBufferView (GetProcAddress('vkDestroyBufferView')); + vkCreateImage := TvkCreateImage (GetProcAddress('vkCreateImage')); + vkDestroyImage := TvkDestroyImage (GetProcAddress('vkDestroyImage')); + vkGetImageSubresourceLayout := TvkGetImageSubresourceLayout (GetProcAddress('vkGetImageSubresourceLayout')); + vkCreateImageView := TvkCreateImageView (GetProcAddress('vkCreateImageView')); + vkDestroyImageView := TvkDestroyImageView (GetProcAddress('vkDestroyImageView')); + vkCreateShaderModule := TvkCreateShaderModule (GetProcAddress('vkCreateShaderModule')); + vkDestroyShaderModule := TvkDestroyShaderModule (GetProcAddress('vkDestroyShaderModule')); + vkCreatePipelineCache := TvkCreatePipelineCache (GetProcAddress('vkCreatePipelineCache')); + vkDestroyPipelineCache := TvkDestroyPipelineCache (GetProcAddress('vkDestroyPipelineCache')); + vkGetPipelineCacheData := TvkGetPipelineCacheData (GetProcAddress('vkGetPipelineCacheData')); + vkMergePipelineCaches := TvkMergePipelineCaches (GetProcAddress('vkMergePipelineCaches')); + vkCreateGraphicsPipelines := TvkCreateGraphicsPipelines (GetProcAddress('vkCreateGraphicsPipelines')); + vkCreateComputePipelines := TvkCreateComputePipelines (GetProcAddress('vkCreateComputePipelines')); + vkDestroyPipeline := TvkDestroyPipeline (GetProcAddress('vkDestroyPipeline')); + vkCreatePipelineLayout := TvkCreatePipelineLayout (GetProcAddress('vkCreatePipelineLayout')); + vkDestroyPipelineLayout := TvkDestroyPipelineLayout (GetProcAddress('vkDestroyPipelineLayout')); + vkCreateSampler := TvkCreateSampler (GetProcAddress('vkCreateSampler')); + vkDestroySampler := TvkDestroySampler (GetProcAddress('vkDestroySampler')); + vkCreateDescriptorSetLayout := TvkCreateDescriptorSetLayout (GetProcAddress('vkCreateDescriptorSetLayout')); + vkDestroyDescriptorSetLayout := TvkDestroyDescriptorSetLayout (GetProcAddress('vkDestroyDescriptorSetLayout')); + vkCreateDescriptorPool := TvkCreateDescriptorPool (GetProcAddress('vkCreateDescriptorPool')); + vkDestroyDescriptorPool := TvkDestroyDescriptorPool (GetProcAddress('vkDestroyDescriptorPool')); + vkResetDescriptorPool := TvkResetDescriptorPool (GetProcAddress('vkResetDescriptorPool')); + vkAllocateDescriptorSets := TvkAllocateDescriptorSets (GetProcAddress('vkAllocateDescriptorSets')); + vkFreeDescriptorSets := TvkFreeDescriptorSets (GetProcAddress('vkFreeDescriptorSets')); + vkUpdateDescriptorSets := TvkUpdateDescriptorSets (GetProcAddress('vkUpdateDescriptorSets')); + vkCreateFramebuffer := TvkCreateFramebuffer (GetProcAddress('vkCreateFramebuffer')); + vkDestroyFramebuffer := TvkDestroyFramebuffer (GetProcAddress('vkDestroyFramebuffer')); + vkCreateRenderPass := TvkCreateRenderPass (GetProcAddress('vkCreateRenderPass')); + vkDestroyRenderPass := TvkDestroyRenderPass (GetProcAddress('vkDestroyRenderPass')); + vkGetRenderAreaGranularity := TvkGetRenderAreaGranularity (GetProcAddress('vkGetRenderAreaGranularity')); + vkCreateCommandPool := TvkCreateCommandPool (GetProcAddress('vkCreateCommandPool')); + vkDestroyCommandPool := TvkDestroyCommandPool (GetProcAddress('vkDestroyCommandPool')); + vkResetCommandPool := TvkResetCommandPool (GetProcAddress('vkResetCommandPool')); + vkAllocateCommandBuffers := TvkAllocateCommandBuffers (GetProcAddress('vkAllocateCommandBuffers')); + vkFreeCommandBuffers := TvkFreeCommandBuffers (GetProcAddress('vkFreeCommandBuffers')); + vkBeginCommandBuffer := TvkBeginCommandBuffer (GetProcAddress('vkBeginCommandBuffer')); + vkEndCommandBuffer := TvkEndCommandBuffer (GetProcAddress('vkEndCommandBuffer')); + vkResetCommandBuffer := TvkResetCommandBuffer (GetProcAddress('vkResetCommandBuffer')); + vkCmdBindPipeline := TvkCmdBindPipeline (GetProcAddress('vkCmdBindPipeline')); + vkCmdSetViewport := TvkCmdSetViewport (GetProcAddress('vkCmdSetViewport')); + vkCmdSetScissor := TvkCmdSetScissor (GetProcAddress('vkCmdSetScissor')); + vkCmdSetLineWidth := TvkCmdSetLineWidth (GetProcAddress('vkCmdSetLineWidth')); + vkCmdSetDepthBias := TvkCmdSetDepthBias (GetProcAddress('vkCmdSetDepthBias')); + vkCmdSetBlendConstants := TvkCmdSetBlendConstants (GetProcAddress('vkCmdSetBlendConstants')); + vkCmdSetDepthBounds := TvkCmdSetDepthBounds (GetProcAddress('vkCmdSetDepthBounds')); + vkCmdSetStencilCompareMask := TvkCmdSetStencilCompareMask (GetProcAddress('vkCmdSetStencilCompareMask')); + vkCmdSetStencilWriteMask := TvkCmdSetStencilWriteMask (GetProcAddress('vkCmdSetStencilWriteMask')); + vkCmdSetStencilReference := TvkCmdSetStencilReference (GetProcAddress('vkCmdSetStencilReference')); + vkCmdBindDescriptorSets := TvkCmdBindDescriptorSets (GetProcAddress('vkCmdBindDescriptorSets')); + vkCmdBindIndexBuffer := TvkCmdBindIndexBuffer (GetProcAddress('vkCmdBindIndexBuffer')); + vkCmdBindVertexBuffers := TvkCmdBindVertexBuffers (GetProcAddress('vkCmdBindVertexBuffers')); + vkCmdDraw := TvkCmdDraw (GetProcAddress('vkCmdDraw')); + vkCmdDrawIndexed := TvkCmdDrawIndexed (GetProcAddress('vkCmdDrawIndexed')); + vkCmdDrawIndirect := TvkCmdDrawIndirect (GetProcAddress('vkCmdDrawIndirect')); + vkCmdDrawIndexedIndirect := TvkCmdDrawIndexedIndirect (GetProcAddress('vkCmdDrawIndexedIndirect')); + vkCmdDispatch := TvkCmdDispatch (GetProcAddress('vkCmdDispatch')); + vkCmdDispatchIndirect := TvkCmdDispatchIndirect (GetProcAddress('vkCmdDispatchIndirect')); + vkCmdCopyBuffer := TvkCmdCopyBuffer (GetProcAddress('vkCmdCopyBuffer')); + vkCmdCopyImage := TvkCmdCopyImage (GetProcAddress('vkCmdCopyImage')); + vkCmdBlitImage := TvkCmdBlitImage (GetProcAddress('vkCmdBlitImage')); + vkCmdCopyBufferToImage := TvkCmdCopyBufferToImage (GetProcAddress('vkCmdCopyBufferToImage')); + vkCmdCopyImageToBuffer := TvkCmdCopyImageToBuffer (GetProcAddress('vkCmdCopyImageToBuffer')); + vkCmdUpdateBuffer := TvkCmdUpdateBuffer (GetProcAddress('vkCmdUpdateBuffer')); + vkCmdFillBuffer := TvkCmdFillBuffer (GetProcAddress('vkCmdFillBuffer')); + vkCmdClearColorImage := TvkCmdClearColorImage (GetProcAddress('vkCmdClearColorImage')); + vkCmdClearDepthStencilImage := TvkCmdClearDepthStencilImage (GetProcAddress('vkCmdClearDepthStencilImage')); + vkCmdClearAttachments := TvkCmdClearAttachments (GetProcAddress('vkCmdClearAttachments')); + vkCmdResolveImage := TvkCmdResolveImage (GetProcAddress('vkCmdResolveImage')); + vkCmdSetEvent := TvkCmdSetEvent (GetProcAddress('vkCmdSetEvent')); + vkCmdResetEvent := TvkCmdResetEvent (GetProcAddress('vkCmdResetEvent')); + vkCmdWaitEvents := TvkCmdWaitEvents (GetProcAddress('vkCmdWaitEvents')); + vkCmdPipelineBarrier := TvkCmdPipelineBarrier (GetProcAddress('vkCmdPipelineBarrier')); + vkCmdBeginQuery := TvkCmdBeginQuery (GetProcAddress('vkCmdBeginQuery')); + vkCmdEndQuery := TvkCmdEndQuery (GetProcAddress('vkCmdEndQuery')); + vkCmdResetQueryPool := TvkCmdResetQueryPool (GetProcAddress('vkCmdResetQueryPool')); + vkCmdWriteTimestamp := TvkCmdWriteTimestamp (GetProcAddress('vkCmdWriteTimestamp')); + vkCmdCopyQueryPoolResults := TvkCmdCopyQueryPoolResults (GetProcAddress('vkCmdCopyQueryPoolResults')); + vkCmdPushConstants := TvkCmdPushConstants (GetProcAddress('vkCmdPushConstants')); + vkCmdBeginRenderPass := TvkCmdBeginRenderPass (GetProcAddress('vkCmdBeginRenderPass')); + vkCmdNextSubpass := TvkCmdNextSubpass (GetProcAddress('vkCmdNextSubpass')); + vkCmdEndRenderPass := TvkCmdEndRenderPass (GetProcAddress('vkCmdEndRenderPass')); + vkCmdExecuteCommands := TvkCmdExecuteCommands (GetProcAddress('vkCmdExecuteCommands')); + + { ========================================= VK_KHR_swapchain ========================================= } + vkCreateSwapchainKHR := TvkCreateSwapchainKHR (GetProcAddress('vkCreateSwapchainKHR')); + vkDestroySwapchainKHR := TvkDestroySwapchainKHR (GetProcAddress('vkDestroySwapchainKHR')); + vkGetSwapchainImagesKHR := TvkGetSwapchainImagesKHR (GetProcAddress('vkGetSwapchainImagesKHR')); + vkAcquireNextImageKHR := TvkAcquireNextImageKHR (GetProcAddress('vkAcquireNextImageKHR')); + vkQueuePresentKHR := TvkQueuePresentKHR (GetProcAddress('vkQueuePresentKHR')); + + { ===================================== VK_KHR_display_swapchain ===================================== } + vkCreateSharedSwapchainsKHR := TvkCreateSharedSwapchainsKHR (GetProcAddress('vkCreateSharedSwapchainsKHR')); + + end; + except + FreeAndNil(result); + raise; end; - result := success; end; procedure FinalizeVulkan; diff --git a/projects/generator/generate.bat b/projects/generator/generate.bat new file mode 100644 index 0000000..26ee4f9 --- /dev/null +++ b/projects/generator/generate.bat @@ -0,0 +1 @@ +generator-i386-win32.exe -i ..\..\data\vk.xml -t ..\..\data\vulkan.tpl -o ..\Vulkan.pas \ No newline at end of file diff --git a/projects/generator/generator.lps b/projects/generator/generator.lps index 81d1b40..d1e8b54 100644 --- a/projects/generator/generator.lps +++ b/projects/generator/generator.lps @@ -15,6 +15,7 @@ + @@ -29,9 +30,8 @@ - - + diff --git a/projects/triangle/triangle.lpi b/projects/triangle/triangle.lpi index 56617af..4ed1ed1 100644 --- a/projects/triangle/triangle.lpi +++ b/projects/triangle/triangle.lpi @@ -33,7 +33,7 @@ - + @@ -54,15 +54,15 @@ - + - + - + @@ -78,9 +78,13 @@ - + + + + + @@ -105,6 +109,11 @@ + + + + + diff --git a/projects/triangle/triangle.lpr b/projects/triangle/triangle.lpr index 9f61de6..67b4cef 100644 --- a/projects/triangle/triangle.lpr +++ b/projects/triangle/triangle.lpr @@ -7,8 +7,7 @@ uses {$IFDEF UNIX}{$IFDEF UseCThreads} cthreads, {$ENDIF}{$ENDIF} - Interfaces, Dialogs, Forms, uMainForm, Vulkan, uvkuDevice, uvkuDeviceFactory, uvkuPhysicalDeviceFactory, -uvkuAllocationHandler; + Interfaces, Dialogs, Forms, uMainForm, Vulkan, uvkuDevice, uvkuDeviceFactory; {$R *.res} diff --git a/projects/triangle/triangle.lps b/projects/triangle/triangle.lps index 83dcd1f..29e0e73 100644 --- a/projects/triangle/triangle.lps +++ b/projects/triangle/triangle.lps @@ -4,13 +4,14 @@ - + - - - + + + + @@ -18,253 +19,353 @@ - - - - + + + + + + - - - - + + + + + + + + + + - - - - + + + + - + - - - - + + + + - + - - - - + + + + + - + - - - - - + + + + - - + - - + - + - - - - + + + + + - + - - - + + + + + - + - - - - + + + + + + + + + + + + + + + + + + + + + - - + + - - - - - + + + + + - - + + - - + + - - + + - - + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - + - - + - - + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/projects/triangle/uMainForm.lfm b/projects/triangle/uMainForm.lfm index 7410eee..17e7600 100644 --- a/projects/triangle/uMainForm.lfm +++ b/projects/triangle/uMainForm.lfm @@ -4,7 +4,18 @@ object MainForm: TMainForm Top = 263 Width = 320 Caption = 'Triangle' + ClientHeight = 240 + ClientWidth = 320 OnCreate = FormCreate OnDestroy = FormDestroy LCLVersion = '1.7' + object RenderPanel: TPanel + Left = 0 + Height = 240 + Top = 0 + Width = 320 + Align = alClient + BevelOuter = bvNone + TabOrder = 0 + end end diff --git a/projects/triangle/uMainForm.pas b/projects/triangle/uMainForm.pas index 4a16e78..ef6c4f4 100644 --- a/projects/triangle/uMainForm.pas +++ b/projects/triangle/uMainForm.pas @@ -5,8 +5,11 @@ unit uMainForm; interface uses - Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, - Vulkan, uvkuInstance, uvkuInstanceFactory, uvkuPhysicalDevice, uvkuUtils, uvkuAllocationHandler, uvkuDevice, uvkuDeviceFactory; + Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls, + Vulkan, uvkuAllocationHandler, + uvkuInstance, uvkuInstanceFactory, + uvkuSurface, uvkuSurfaceFactory, + uvkuDevice, uvkuDeviceFactory; type ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -19,12 +22,14 @@ type ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// TMainForm = class(TForm) + RenderPanel: TPanel; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); private fAllocHandler: TCustomAllocHandler; fInstance: TvkuInstance; fDevice: TvkuDevice; + fSurface: TvkuSurface; public { public declarations } end; @@ -35,6 +40,7 @@ var implementation {$R *.lfm} +{$I Vulkan.inc} ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TCustomAllocHandler//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -67,9 +73,9 @@ end; procedure TMainForm.FormCreate(Sender: TObject); var PhyDevices: TvkuPhysicalDeviceArr; - QueueFamProps: TVkQueueFamilyPropertiesArr; iFactory: TvkuInstanceFactory; dFactory: TvkuDeviceFactory; + sFactory: TvkuSurfaceFactory; qci: TvkuQueueCreateInfo; begin fAllocHandler := TCustomAllocHandler.Create; @@ -77,6 +83,8 @@ begin WriteLn('create vulkan instance'); iFactory := TvkuInstanceFactory.Create; try + iFactory.Extensions.Add(VK_KHR_SURFACE_EXTENSION_NAME); + iFactory.Extensions.Add(TvkuInstanceFactory.GetPlatformSurfaceExtensionName); fInstance := iFactory.CreateInstance(fAllocHandler, false); finally FreeAndNil(iFactory); @@ -86,8 +94,17 @@ begin if (Length(PhyDevices) <= 0) then raise Exception.Create('unable to get physical device'); + WriteLn('create vulkan surface'); + sFactory := TvkuSurfaceFactory.Create(fInstance); + try + sFactory.WinControl := RenderPanel; + fSurface := sFactory.CreateSurface(fAllocHandler, false); + finally + FreeAndNil(sFactory); + end; + WriteLn('create vulkan device'); - dFactory := TvkuDeviceFactory.Create; + dFactory := TvkuDeviceFactory.Create(fInstance); try SetLength(qci.Priorities, 1); qci.Priorities[0] := 1.0; @@ -107,6 +124,7 @@ end; procedure TMainForm.FormDestroy(Sender: TObject); begin FreeAndNil(fDevice); + FreeAndNil(fSurface); FreeAndNil(fInstance); FreeAndNil(fAllocHandler); end; diff --git a/projects/utils/uvkuAllocationHandler.pas b/projects/utils/uvkuAllocationHandler.pas index e4b5a07..8dea193 100644 --- a/projects/utils/uvkuAllocationHandler.pas +++ b/projects/utils/uvkuAllocationHandler.pas @@ -90,7 +90,7 @@ end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TvkuAllocationHandler.GetAllocationCallbacks: TVkAllocationCallbacks; begin - FillByte(result, SizeOf(result), 0); + FillByte(result{%H-}, SizeOf(result), 0); result.pUserData := self; result.pfnAllocation := @AllocateMemoryCallback; result.pfnReallocation := @ReallocateMemoryCallback; diff --git a/projects/utils/uvkuDevice.pas b/projects/utils/uvkuDevice.pas index 21f9cf9..796442d 100644 --- a/projects/utils/uvkuDevice.pas +++ b/projects/utils/uvkuDevice.pas @@ -15,6 +15,8 @@ type fHandle: VkDevice; fPhysicalDevice: VkPhysicalDevice; fAllocCallbacks: PVkAllocationCallbacks; + fInstanceCommands: TVkInstanceCommands; + fDeviceCommands: TVkDeviceCommands; procedure CreateHandle( const aCreateInfo: PVkDeviceCreateInfo; @@ -25,10 +27,12 @@ type constructor Create( const aPhysicalDevice: VkPhysicalDevice; - const aCreateInfo: TVkDeviceCreateInfo); + const aCreateInfo: TVkDeviceCreateInfo; + const aInstanceCommands: TVkInstanceCommands); constructor Create( const aPhysicalDevice: VkPhysicalDevice; const aCreateInfo: TVkDeviceCreateInfo; + const aInstanceCommands: TVkInstanceCommands; const aAllocCallbacks: TVkAllocationCallbacks); destructor Destroy; override; end; @@ -44,44 +48,54 @@ uses procedure TvkuDevice.CreateHandle(const aCreateInfo: PVkDeviceCreateInfo; const aAllocCallbacks: PVkAllocationCallbacks); var err: TVkResult; begin + if not Assigned(fInstanceCommands.vkCreateDevice) then + raise TvkuException.Create('invalid function pointer: vkCreateDevice; did you load the vulkan core commands?'); if Assigned(aAllocCallbacks) then begin new(fAllocCallbacks); fAllocCallbacks^ := aAllocCallbacks^; end; - err := vkCreateDevice(fPhysicalDevice, aCreateInfo, fAllocCallbacks, @fHandle); + err := fInstanceCommands.vkCreateDevice(fPhysicalDevice, aCreateInfo, fAllocCallbacks, @fHandle); if (err < VK_SUCCESS) then raise TvkuErrorException.Create('unable to create device', err); + fDeviceCommands := LoadDeviceCommands(fInstanceCommands.Instance, fHandle); + if not Assigned(fDeviceCommands) then + raise TvkuException.Create('unable to load device commands'); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -constructor TvkuDevice.Create(const aPhysicalDevice: VkPhysicalDevice; const aCreateInfo: TVkDeviceCreateInfo); +constructor TvkuDevice.Create(const aPhysicalDevice: VkPhysicalDevice; const aCreateInfo: TVkDeviceCreateInfo; + const aInstanceCommands: TVkInstanceCommands); begin inherited Create; - fHandle := nil; - fPhysicalDevice := aPhysicalDevice; + fHandle := nil; + fPhysicalDevice := aPhysicalDevice; + fInstanceCommands := aInstanceCommands; CreateHandle(@aCreateInfo, nil); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -constructor TvkuDevice.Create(const aPhysicalDevice: VkPhysicalDevice; const aCreateInfo: TVkDeviceCreateInfo; const aAllocCallbacks: TVkAllocationCallbacks); +constructor TvkuDevice.Create(const aPhysicalDevice: VkPhysicalDevice; const aCreateInfo: TVkDeviceCreateInfo; + const aInstanceCommands: TVkInstanceCommands; const aAllocCallbacks: TVkAllocationCallbacks); begin inherited Create; - fHandle := nil; - fPhysicalDevice := aPhysicalDevice; + fHandle := nil; + fPhysicalDevice := aPhysicalDevice; + fInstanceCommands := aInstanceCommands; CreateHandle(@aCreateInfo, @aAllocCallbacks); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// destructor TvkuDevice.Destroy; begin - if Assigned(fHandle) then begin - vkDestroyDevice(fHandle, fAllocCallbacks); + if (fHandle <> VK_INVALID_HANDLE) then begin + fDeviceCommands.vkDestroyDevice(fHandle, fAllocCallbacks); fHandle := nil; end; if Assigned(fAllocCallbacks) then begin Dispose(fAllocCallbacks); fAllocCallbacks := nil; end; + FreeAndNil(fDeviceCommands); inherited Destroy; end; diff --git a/projects/utils/uvkuDeviceFactory.pas b/projects/utils/uvkuDeviceFactory.pas index 6ab935f..0a5df66 100644 --- a/projects/utils/uvkuDeviceFactory.pas +++ b/projects/utils/uvkuDeviceFactory.pas @@ -6,7 +6,7 @@ interface uses Classes, SysUtils, - Vulkan, uvkuDevice, uvkuAllocationHandler; + Vulkan, uvkuInstance, uvkuDevice, uvkuAllocationHandler; type ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -24,20 +24,13 @@ type fAllocHandler: TvkuAllocationHandler; fOwnsHandler: Boolean; public - constructor Create( - const aPhysicalDevice: VkPhysicalDevice; - const aCreateInfo: TVkDeviceCreateInfo); - constructor Create( - const aPhysicalDevice: VkPhysicalDevice; - const aCreateInfo: TVkDeviceCreateInfo; - const aAllocHandler: TvkuAllocationHandler; - const aOwnsHandler: Boolean); destructor Destroy; override; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// TvkuDeviceFactory = class(TObject) private + fInstance: TvkuInstance; fFeatures: TVkPhysicalDeviceFeatures; fFlags: VkDeviceCreateFlags; fLayers: TStringList; @@ -71,7 +64,7 @@ type const aAllocHandler: TvkuAllocationHandler; const aOwnsHandler: Boolean): TvkuDevice; - constructor Create; + constructor Create(const aInstance: TvkuInstance); destructor Destroy; override; end; @@ -82,25 +75,6 @@ uses ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TvkuDeviceEx/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -constructor TvkuDeviceEx.Create(const aPhysicalDevice: VkPhysicalDevice; const aCreateInfo: TVkDeviceCreateInfo); -begin - inherited Create(aPhysicalDevice, aCreateInfo); - fAllocHandler := nil; - fOwnsHandler := false; -end; - -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -constructor TvkuDeviceEx.Create(const aPhysicalDevice: VkPhysicalDevice; const aCreateInfo: TVkDeviceCreateInfo; - const aAllocHandler: TvkuAllocationHandler; const aOwnsHandler: Boolean); -begin - fAllocHandler := aAllocHandler; - fOwnsHandler := aOwnsHandler; - if Assigned(fAllocHandler) - then inherited Create(aPhysicalDevice, aCreateInfo, fAllocHandler.GetAllocationCallbacks) - else inherited Create(aPhysicalDevice, aCreateInfo); -end; - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// destructor TvkuDeviceEx.Destroy; begin @@ -172,7 +146,8 @@ begin end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -function TvkuDeviceFactory.CreateDevice(const aPhysicalDevice: VkPhysicalDevice; const aAllocHandler: TvkuAllocationHandler; const aOwnsHandler: Boolean): TvkuDevice; +function TvkuDeviceFactory.CreateDevice(const aPhysicalDevice: VkPhysicalDevice; + const aAllocHandler: TvkuAllocationHandler; const aOwnsHandler: Boolean): TvkuDevice; var CreateInfo: TVkDeviceCreateInfo; QueueInfos: array of TVkDeviceQueueCreateInfo; @@ -218,14 +193,24 @@ begin CreateInfo.ppEnabledExtensionNames := @ext[0]; CreateInfo.pEnabledFeatures := @fFeatures; - result := TvkuDeviceEx.Create(aPhysicalDevice, CreateInfo, aAllocHandler, aOwnsHandler); + if Assigned(aAllocHandler) + then result := TvkuDeviceEx.Create(aPhysicalDevice, CreateInfo, fInstance.InstanceCommands, aAllocHandler.GetAllocationCallbacks) + else result := TvkuDeviceEx.Create(aPhysicalDevice, CreateInfo, fInstance.InstanceCommands); + try + TvkuDeviceEx(result).fAllocHandler := aAllocHandler; + TvkuDeviceEx(result).fOwnsHandler := aOwnsHandler; + except + FreeAndNil(result); + raise; + end; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -constructor TvkuDeviceFactory.Create; +constructor TvkuDeviceFactory.Create(const aInstance: TvkuInstance); begin inherited Create; FillByte(fFeatures, SizeOf(fFeatures), 0); + fInstance := aInstance; fLayers := TStringList.Create; fExtensions := TStringList.Create; end; diff --git a/projects/utils/uvkuInstance.pas b/projects/utils/uvkuInstance.pas index 78f9e4f..c3dc2f3 100644 --- a/projects/utils/uvkuInstance.pas +++ b/projects/utils/uvkuInstance.pas @@ -6,32 +6,35 @@ interface uses Classes, SysUtils, - Vulkan, uvkuPhysicalDevice; + Vulkan; type ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// TvkuPhysicalDeviceArr = array of VkPhysicalDevice; TvkuInstance = class(TObject) private - fHandle: VkInstance; - fAllocCallbacks: PVkAllocationCallbacks; - fPhysicalDevices: TvkuPhysicalDeviceArr; + fHandle: VkInstance; + fAllocCallbacks: PVkAllocationCallbacks; + fPhysicalDevices: TvkuPhysicalDeviceArr; + fInstanceCommands: TVkInstanceCommands; - function GetPhysicalDeviceCount: Integer; - function GetPhysicalDevice(const aIndex: Integer): VkPhysicalDevice; procedure UpdatePhysicalDevices; protected procedure CreateHandle(const aCreateInfo: PVkInstanceCreateInfo; const aAllocCallbacks: PVkAllocationCallbacks); - constructor Create; + {%H-}constructor Create; public - property Handle: VkInstance read fHandle; - property PhysicalDeviceCount: Integer read GetPhysicalDeviceCount; - property PhysicalDevices[const aIndex: Integer]: VkPhysicalDevice read GetPhysicalDevice; + property Handle: VkInstance read fHandle; + property InstanceCommands: TVkInstanceCommands read fInstanceCommands; function GetPhysicalDevices: TvkuPhysicalDeviceArr; - constructor Create(const aCreateInfo: TVkInstanceCreateInfo); - constructor Create(const aCreateInfo: TVkInstanceCreateInfo; const aAllocCallbacks: TVkAllocationCallbacks); + constructor Create( + const aCreateInfo: TVkInstanceCreateInfo); + + constructor Create( + const aCreateInfo: TVkInstanceCreateInfo; + const aAllocCallbacks: TVkAllocationCallbacks); + destructor Destroy; override; end; @@ -42,22 +45,6 @@ uses ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TvkuInstance/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -function TvkuInstance.GetPhysicalDeviceCount: Integer; -begin - UpdatePhysicalDevices; - result := Length(fPhysicalDevices); -end; - -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -function TvkuInstance.GetPhysicalDevice(const aIndex: Integer): VkPhysicalDevice; -begin - UpdatePhysicalDevices; - if (aIndex < Low(fPhysicalDevices)) or (aIndex > High(fPhysicalDevices)) then - raise TvkuException.CreateFmt('index (%d) out of range (%d : %d)', [aIndex, Low(fPhysicalDevices), High(fPhysicalDevices)]); - result := fPhysicalDevices[aIndex]; -end; - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TvkuInstance.UpdatePhysicalDevices; var @@ -67,23 +54,16 @@ begin if (Length(fPhysicalDevices) > 0) then exit; - err := vkEnumeratePhysicalDevices(fHandle, @c, nil); + 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 := vkEnumeratePhysicalDevices(fHandle, @c, @fPhysicalDevices[0]); + err := InstanceCommands.vkEnumeratePhysicalDevices(fHandle, @c, @fPhysicalDevices[0]); if (err < VK_SUCCESS) then raise TvkuErrorException.Create('unable to get physical devices', err); end; -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -function TvkuInstance.GetPhysicalDevices: TvkuPhysicalDeviceArr; -begin - UpdatePhysicalDevices; - result := fPhysicalDevices; -end; - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TvkuInstance.CreateHandle(const aCreateInfo: PVkInstanceCreateInfo; const aAllocCallbacks: PVkAllocationCallbacks); var e: TVkResult; @@ -95,7 +75,9 @@ begin e := vkCreateInstance(aCreateInfo, fAllocCallbacks, @fHandle); if (e < VK_SUCCESS) then raise TvkuErrorException.Create('unable to create vulkan instance', e); - LoadVulkanCommands(fHandle); + fInstanceCommands := LoadInstanceCommands(fHandle); + if not Assigned(InstanceCommands) then + raise TvkuException.Create('unable to load instance commands'); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -106,6 +88,13 @@ begin fAllocCallbacks := nil; end; +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function TvkuInstance.GetPhysicalDevices: TvkuPhysicalDeviceArr; +begin + UpdatePhysicalDevices; + result := fPhysicalDevices; +end; + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor TvkuInstance.Create(const aCreateInfo: TVkInstanceCreateInfo); begin @@ -123,14 +112,15 @@ end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// destructor TvkuInstance.Destroy; begin - if Assigned(fHandle) then begin - vkDestroyInstance(fHandle, fAllocCallbacks); + if (fHandle <> VK_INVALID_HANDLE) then begin + InstanceCommands.vkDestroyInstance(fHandle, fAllocCallbacks); fHandle := nil; end; if Assigned(fAllocCallbacks) then begin Dispose(fAllocCallbacks); fAllocCallbacks := nil; end; + FreeAndNil(fInstanceCommands); inherited Destroy; end; diff --git a/projects/utils/uvkuInstanceFactory.pas b/projects/utils/uvkuInstanceFactory.pas index 325e88d..d79c2c6 100644 --- a/projects/utils/uvkuInstanceFactory.pas +++ b/projects/utils/uvkuInstanceFactory.pas @@ -1,6 +1,7 @@ unit uvkuInstanceFactory; {$mode objfpc}{$H+} +{$I Vulkan.inc} interface @@ -24,10 +25,6 @@ type fAllocHandler: TvkuAllocationHandler; fOwnsHandler: Boolean; public - constructor Create( - const aCreateInfo: TVkInstanceCreateInfo; - const aAllocHandler: TvkuAllocationHandler; - const aOwnsHandler: Boolean); destructor Destroy; override; end; @@ -49,10 +46,14 @@ type property Extensions: TStrings read GetExtensions; function CreateInstance: TvkuInstance; - function CreateInstance(const aAllocHandler: TvkuAllocationHandler; const aOwnsHandler: Boolean): TvkuInstance; + function CreateInstance( + const aAllocHandler: TvkuAllocationHandler; + const aOwnsHandler: Boolean): TvkuInstance; constructor Create; destructor Destroy; override; + public + class function GetPlatformSurfaceExtensionName: String; end; function vkuApplicationInfo: TvkuApplicationInfo; @@ -78,7 +79,7 @@ end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function vkuApplicationInfo(aAppName: String; aAppVersion: VkVersion; aEngineName: String; aEngineVersion: VkVersion; aApiVersion: VkVersion): TvkuApplicationInfo; begin - result := vkuApplicationInfo; + result := vkuApplicationInfo(); result.AppName := aAppName; result.AppVersion := aAppVersion; result.EngineName := aEngineName; @@ -88,16 +89,6 @@ end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TvkuInstanceEx///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -constructor TvkuInstanceEx.Create(const aCreateInfo: TVkInstanceCreateInfo; const aAllocHandler: TvkuAllocationHandler; const aOwnsHandler: Boolean); -begin - fOwnsHandler := aOwnsHandler; - fAllocHandler := aAllocHandler; - if Assigned(fAllocHandler) - then inherited Create(aCreateInfo, fAllocHandler.GetAllocationCallbacks) - else inherited Create(aCreateInfo); -end; - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// destructor TvkuInstanceEx.Destroy; begin @@ -135,7 +126,7 @@ var lay: array of PVkChar; ext: array of PVkChar; begin - FillByte(AppInfo, SizeOf(AppInfo), 0); + FillByte(AppInfo{%H-}, SizeOf(AppInfo), 0); AppInfo.sType := VK_STRUCTURE_TYPE_APPLICATION_INFO; AppInfo.pNext := nil; AppInfo.pApplicationName := PVkChar(fApplicationInfo.AppName); @@ -152,7 +143,7 @@ begin for i := 0 to fExtensions.Count-1 do ext[i] := PVkChar(fExtensions[i]); - FillByte(CreateInfo, SizeOf(CreateInfo), 0); + FillByte(CreateInfo{%H-}, SizeOf(CreateInfo), 0); CreateInfo.sType := VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; CreateInfo.pNext := nil; CreateInfo.flags := fFlags; @@ -162,7 +153,16 @@ begin CreateInfo.enabledExtensionCount := Length(ext); CreateInfo.ppEnabledExtensionNames := @ext[0]; - result := TvkuInstanceEx.Create(CreateInfo, aAllocHandler, aOwnsHandler); + if Assigned(aAllocHandler) + then result := TvkuInstanceEx.Create(CreateInfo, aAllocHandler.GetAllocationCallbacks) + else result := TvkuInstanceEx.Create(CreateInfo); + try + TvkuInstanceEx(result).fAllocHandler := aAllocHandler; + TvkuInstanceEx(result).fOwnsHandler := aOwnsHandler; + except + FreeAndNil(result); + raise; + end; end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -183,5 +183,25 @@ begin inherited Destroy; end; +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +class function TvkuInstanceFactory.GetPlatformSurfaceExtensionName: String; +begin +{$IF DEFINED(VK_USE_PLATFORM_XLIB_KHR)} + result := VK_KHR_XLIB_SURFACE_EXTENSION_NAME; +{$ELSEIF DEFINED(VK_USE_PLATFORM_XCB_KHR)} + result := VK_KHR_XCB_SURFACE_EXTENSION_NAME; +{$ELSEIF DEFINED(VK_USE_PLATFORM_WAYLAND_KHR)} + result := VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME; +{$ELSEIF DEFINED(VK_USE_PLATFORM_MIR_KHR)} + result := VK_KHR_MIR_SURFACE_EXTENSION_NAME; +{$ELSEIF DEFINED(VK_USE_PLATFORM_ANDROID_KHR)} + result := VK_KHR_ANDROID_SURFACE_EXTENSION_NAME; +{$ELSEIF DEFINED(VK_USE_PLATFORM_WIN32_KHR)} + result := VK_KHR_WIN32_SURFACE_EXTENSION_NAME; +{$ELSE} + {$ERROR 'unknown or unsupportet platform'} +{$ENDIF} +end; + end. diff --git a/projects/utils/uvkuPhysicalDevice.pas b/projects/utils/uvkuPhysicalDevice.pas index cf86195..5a1b3ca 100644 --- a/projects/utils/uvkuPhysicalDevice.pas +++ b/projects/utils/uvkuPhysicalDevice.pas @@ -6,18 +6,25 @@ interface uses Classes, SysUtils, - Vulkan; + 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; - function GetQueueFamilyProperties(const aIndex: Integer): TVkQueueFamilyProperties; - function GetQueueFamilyPropertyCount: Integer; - public + fInstanceCommands: TVkInstanceCommands; + + public { VK_VERSION_1_0 } function GetFeatures: TVkPhysicalDeviceFeatures; function GetProperties: TVkPhysicalDeviceProperties; function GetMemoryProperties: TVkPhysicalDeviceMemoryProperties; @@ -35,18 +42,24 @@ type const aSamples: TVkSampleCountFlagBits; const aUsage: VkImageUsageFlags; const aTiling: TVkImageTiling): TVkSparseImageFormatPropertiesArr; - public - property Handle: VkPhysicalDevice read fHandle; - property Features: TVkPhysicalDeviceFeatures read GetFeatures; - property Properties: TVkPhysicalDeviceProperties read GetProperties; - property MemoryProperties: TVkPhysicalDeviceMemoryProperties read GetMemoryProperties; - property QueueFamilyPropertyCount: Integer read GetQueueFamilyPropertyCount; - property QueueFamilyProperties[const aIndex: Integer]: TVkQueueFamilyProperties read GetQueueFamilyProperties; + 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; - property FormatProperties[const aFormat: TVkFormat]: TVkFormatProperties read GetFormatProperties; + public { VK_KHR_display } + function GetDisplayProperties: TVkDisplayPropertiesArr; + function GetDisplayPlaneProperties: TVkDisplayPlanePropertiesArr; + function GetDisplayPlaneSupportedDisplays(const aPlaneIndex: VkUint32): TVkDisplayArr; + function GetDisplayModeProperties(const aDisplay: VkDisplayKHR): TVkDisplayModePropertiesArr; - constructor Create(const aHandle: VkPhysicalDevice); + public + property Handle: VkPhysicalDevice read fHandle; + property InstanceCommands: TVkInstanceCommands read fInstanceCommands; + + constructor Create(const aHandle: VkPhysicalDevice; const aInstanceCommands: TVkInstanceCommands); end; implementation @@ -56,53 +69,47 @@ uses ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TvkuPhysicalDevice///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -function TvkuPhysicalDevice.GetQueueFamilyProperties(const aIndex: Integer): TVkQueueFamilyProperties; -var arr: TVkQueueFamilyPropertiesArr; -begin - arr := GetQueueFamilyProperties(); - if (aIndex < Low(arr)) or (aIndex > High(arr)) then - raise TvkuException.CreateFmt('index (%) out of range (%d : %d)', [aIndex, Low(arr), High(arr)]); - result := arr[aIndex]; -end; - -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -function TvkuPhysicalDevice.GetQueueFamilyPropertyCount: Integer; -begin - result := Length(GetQueueFamilyProperties); -end; - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TvkuPhysicalDevice.GetFeatures: TVkPhysicalDeviceFeatures; begin - vkGetPhysicalDeviceFeatures(fHandle, @result); + 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 - vkGetPhysicalDeviceProperties(fHandle, @result); + 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 - vkGetPhysicalDeviceMemoryProperties(fHandle, @result); + 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 - vkGetPhysicalDeviceQueueFamilyProperties(fHandle, @c, 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); - vkGetPhysicalDeviceQueueFamilyProperties(fHandle, @c, @result[0]); + fInstanceCommands.vkGetPhysicalDeviceQueueFamilyProperties(fHandle, @c, @result[0]); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TvkuPhysicalDevice.GetFormatProperties(const aFormat: TVkFormat): TVkFormatProperties; begin - vkGetPhysicalDeviceFormatProperties(fHandle, aFormat, @result); + 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; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -110,7 +117,9 @@ function TvkuPhysicalDevice.GetImageFormatProperties(const aFormat: TVkFormat; c const aTiling: TVkImageTiling; const aUsage: VkImageUsageFlags; const aFlags: VkImageCreateFlags): TVkImageFormatProperties; var err: TVkResult; begin - err := vkGetPhysicalDeviceImageFormatProperties(fHandle, aFormat, aImageType, aTiling, aUsage, aFlags, @result); + 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; @@ -120,18 +129,145 @@ function TvkuPhysicalDevice.GetSparseImageFormatProperties(const aFormat: TVkFor const aSamples: TVkSampleCountFlagBits; const aUsage: VkImageUsageFlags; const aTiling: TVkImageTiling): TVkSparseImageFormatPropertiesArr; var c: VkUint32; begin - vkGetPhysicalDeviceSparseImageFormatProperties(fHandle, aFormat, aImageType, aSamples, aUsage, aTiling, @c, 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): 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); - vkGetPhysicalDeviceSparseImageFormatProperties(fHandle, aFormat, aImageType, aSamples, aUsage, aTiling, @c, @result[0]); + 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); +constructor TvkuPhysicalDevice.Create(const aHandle: VkPhysicalDevice; const aInstanceCommands: TVkInstanceCommands); begin - if not Assigned(aHandle) then + 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; + fHandle := aHandle; + fInstanceCommands := aInstanceCommands; end; end. diff --git a/projects/utils/uvkuPhysicalDeviceFactory.pas b/projects/utils/uvkuPhysicalDeviceFactory.pas index 879889e..89923f4 100644 --- a/projects/utils/uvkuPhysicalDeviceFactory.pas +++ b/projects/utils/uvkuPhysicalDeviceFactory.pas @@ -6,13 +6,18 @@ interface uses Classes, SysUtils, - Vulkan, uvkuPhysicalDevice; + Vulkan, uvkuInstance, uvkuPhysicalDevice; type ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// TvkuPhysicalDeviceFactory = class(TObject) + private + fInstance: TvkuInstance; public - function CreatePhysicalDevice(const aHandle: VkPhysicalDevice): TvkuPhysicalDevice; + function CreatePhysicalDevice( + const aHandle: VkPhysicalDevice): TvkuPhysicalDevice; + + constructor Create(const aInstance: TvkuInstance); end; implementation @@ -22,7 +27,14 @@ implementation ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TvkuPhysicalDeviceFactory.CreatePhysicalDevice(const aHandle: VkPhysicalDevice): TvkuPhysicalDevice; begin - result := TvkuPhysicalDevice.Create(aHandle); + result := TvkuPhysicalDevice.Create(aHandle, fInstance.InstanceCommands); +end; + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +constructor TvkuPhysicalDeviceFactory.Create(const aInstance: TvkuInstance); +begin + inherited Create; + fInstance := aInstance; end; end. diff --git a/projects/utils/uvkuSurface.pas b/projects/utils/uvkuSurface.pas new file mode 100644 index 0000000..a6448ce --- /dev/null +++ b/projects/utils/uvkuSurface.pas @@ -0,0 +1,104 @@ +unit uvkuSurface; + +{$mode objfpc}{$H+} +{$I Vulkan.inc} + +interface + +uses + Classes, SysUtils, + Vulkan; + +type +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + TvkuSurface = class(TObject) + private + fHandle: VkSurfaceKHR; + fInstance: VkInstance; + fAllocCallbacks: PVkAllocationCallbacks; + fInstanceCommands: TVkInstanceCommands; + + procedure CreateHandle(const aCreateInfo: Pointer; const aAllocCallbacks: PVkAllocationCallbacks); + public + property Handle: VkSurfaceKHR read fHandle; + property Instance: VkInstance read fInstance; + property InstanceCommands: TVkInstanceCommands read fInstanceCommands; + + {$IF DEFINED(VK_USE_PLATFORM_WIN32_KHR)} + constructor Create( + const aInstance: VkInstance; + const aCreateInfo: TVkWin32SurfaceCreateInfoKHR; + const aInstanceCommands: TVkInstanceCommands); + constructor Create( + const aInstance: VkInstance; + const aCreateInfo: TVkWin32SurfaceCreateInfoKHR; + const aInstanceCommands: TVkInstanceCommands; + const aAllocCallbacks: TVkAllocationCallbacks); + {$ELSE} + {$ERROR 'unknown or unsupportet platform'} + {$ENDIF} + destructor Destroy; override; + end; + +implementation + +uses + uvkuUtils; + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//TvkuSurface//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +procedure TvkuSurface.CreateHandle(const aCreateInfo: Pointer; const aAllocCallbacks: PVkAllocationCallbacks); +var err: TVkResult; +begin + if Assigned(aAllocCallbacks) then begin + new(fAllocCallbacks); + fAllocCallbacks^ := aAllocCallbacks^; + end; +{$IF DEFINED(VK_USE_PLATFORM_WIN32_KHR)} + if not Assigned(fInstanceCommands.vkCreateWin32SurfaceKHR) then + raise TvkuException.Create('invalid function pointer: vkCreateWin32SurfaceKHR; did you enabled the VK_KHR_win32_surface extension?'); + err := fInstanceCommands.vkCreateWin32SurfaceKHR(fInstance, aCreateInfo, fAllocCallbacks, @fHandle); +{$ENDIF} + if (err < VK_SUCCESS) then + raise TvkuErrorException.Create('unable to create surface', err); +end; + +{$IF DEFINED(VK_USE_PLATFORM_WIN32_KHR)} +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +constructor TvkuSurface.Create(const aInstance: VkInstance; const aCreateInfo: TVkWin32SurfaceCreateInfoKHR; + const aInstanceCommands: TVkInstanceCommands); +begin + inherited Create; + fInstance := aInstance; + fInstanceCommands := aInstanceCommands; + CreateHandle(@aCreateInfo, nil); +end; + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +constructor TvkuSurface.Create(const aInstance: VkInstance; const aCreateInfo: TVkWin32SurfaceCreateInfoKHR; + const aInstanceCommands: TVkInstanceCommands; const aAllocCallbacks: TVkAllocationCallbacks); +begin + inherited Create; + fInstance := aInstance; + fInstanceCommands := aInstanceCommands; + CreateHandle(@aCreateInfo, @aAllocCallbacks); +end; +{$ENDIF} + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +destructor TvkuSurface.Destroy; +begin + if (fHandle <> VK_INVALID_NDP_HANDLE) then begin + fInstanceCommands.vkDestroySurfaceKHR(fInstance, fHandle, fAllocCallbacks); + fHandle := 0; + end; + if Assigned(fAllocCallbacks) then begin + Dispose(fAllocCallbacks); + fAllocCallbacks := nil; + end; + inherited Destroy; +end; + +end. + diff --git a/projects/utils/uvkuSurfaceFactory.pas b/projects/utils/uvkuSurfaceFactory.pas new file mode 100644 index 0000000..5e5250c --- /dev/null +++ b/projects/utils/uvkuSurfaceFactory.pas @@ -0,0 +1,230 @@ +unit uvkuSurfaceFactory; + +{$mode objfpc}{$H+} +{$I Vulkan.inc} + +interface + +uses + Classes, SysUtils, Controls, + Vulkan, uvkuInstance, uvkuSurface, uvkuAllocationHandler; + +type +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + TvkuSurfaceEx = class(TvkuSurface) + private + fAllocHandler: TvkuAllocationHandler; + fOwnsHandler: Boolean; + public + destructor Destroy; override; + end; + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + TvkuSurfaceFactory = class(TObject) + {$IF DEFINED(VK_USE_PLATFORM_WIN32_KHR)} + private + fHInstance: Vulkan.HINSTANCE; + fHwnd: Vulkan.HWND; + procedure SetHwnd(const aValue: Vulkan.HWND); + public + property HInstance: Vulkan.HINSTANCE read fHInstance write fHInstance; + property Hwnd: Vulkan.HWND read fHwnd write SetHwnd; + {$ENDIF} + + private + fFlags: VkFlags; + fWinControl: TWinControl; + fInstance: TvkuInstance; + procedure SetWinControl(aValue: TWinControl); + public + property WinControl: TWinControl read fWinControl write SetWinControl; + property Flags: VkFlags read fFlags write fFlags; + + function CreateSurface: TvkuSurface; + function CreateSurface( + const aAllocHandler: TvkuAllocationHandler; + const aOwnsHandler: Boolean): TvkuSurface; + + constructor Create(const aInstance: TvkuInstance); + end; + +implementation + +{$IF DEFINED(VK_USE_PLATFORM_WIN32_KHR)} +uses Windows; +{$ENDIF} + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//TvkuSurfaceEx////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +destructor TvkuSurfaceEx.Destroy; +begin + inherited Destroy; + if fOwnsHandler then + FreeAndNil(fAllocHandler); +end; + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//TvkuSurfaceFactory///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +{$IF DEFINED(VK_USE_PLATFORM_XLIB_KHR)} +{$ERROR 'TODO: implement'} +procedure TvkuSurfaceFactory.SetDisplay(const aValue: TDisplay); +begin +end; + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +procedure TvkuSurfaceFactory.SetWindow(const aValue: TWindow); +begin +end; + +{$ELSEIF DEFINED(VK_USE_PLATFORM_XCB_KHR)} +{$ERROR 'TODO: implement'} +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +procedure TvkuSurfaceFactory.SetConnection(const aValue: xcb_connection_t); +begin +end; + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +procedure TvkuSurfaceFactory.SetWindow(const aValue: xcb_window_t); +begin +end; + +{$ELSEIF DEFINED(VK_USE_PLATFORM_WAYLAND_KHR)} +{$ERROR 'TODO: implement'} +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +procedure TvkuSurfaceFactory.SetDisplay(const aValue: wl_display); +begin +end; + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +procedure TvkuSurfaceFactory.SetSurface(const aValue: wl_surface); +begin +end; + +{$ELSEIF DEFINED(VK_USE_PLATFORM_MIR_KHR)} +{$ERROR 'TODO: implement'} +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +procedure TvkuSurfaceFactory.SetConnection(const aValue: MirConnection); +begin +end; + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +procedure TvkuSurfaceFactory.SetSurface(const aValue: MirSurface); +begin +end; + +{$ELSEIF DEFINED(VK_USE_PLATFORM_ANDROID_KHR)} +{$ERROR 'TODO: implement'} +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +procedure TvkuSurfaceFactory.SetWindow(const aValue: ANativeWindow); +begin +end; + +{$ELSEIF DEFINED(VK_USE_PLATFORM_WIN32_KHR)} +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +procedure TvkuSurfaceFactory.SetHwnd(const aValue: Vulkan.HWND); +begin + SetWinControl(nil); + fHwnd := aValue; +end; +{$ENDIF} + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +procedure TvkuSurfaceFactory.SetWinControl(aValue: TWinControl); +begin + if fWinControl = aValue then + exit; + fWinControl := aValue; + {$IF DEFINED(VK_USE_PLATFORM_XLIB_KHR)} + {$ERROR 'TODO: implement'} + {$ELSEIF DEFINED(VK_USE_PLATFORM_XCB_KHR)} + {$ERROR 'TODO: implement'} + {$ELSEIF DEFINED(VK_USE_PLATFORM_WAYLAND_KHR)} + {$ERROR 'TODO: implement'} + {$ELSEIF DEFINED(VK_USE_PLATFORM_MIR_KHR)} + {$ERROR 'TODO: implement'} + {$ELSEIF DEFINED(VK_USE_PLATFORM_ANDROID_KHR)} + {$ERROR 'TODO: implement'} + {$ELSEIF DEFINED(VK_USE_PLATFORM_WIN32_KHR)} + fHwnd := Vulkan.HWND(fWinControl.Handle); + {$ENDIF} +end; + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function TvkuSurfaceFactory.CreateSurface: TvkuSurface; +begin + result := CreateSurface(nil, false); +end; + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function TvkuSurfaceFactory.CreateSurface(const aAllocHandler: TvkuAllocationHandler; const aOwnsHandler: Boolean): TvkuSurface; +{$IF DEFINED(VK_USE_PLATFORM_XLIB_KHR)} + {$ERROR 'TODO: implement'} +{$ELSEIF DEFINED(VK_USE_PLATFORM_XCB_KHR)} + {$ERROR 'TODO: implement'} +{$ELSEIF DEFINED(VK_USE_PLATFORM_WAYLAND_KHR)} + {$ERROR 'TODO: implement'} +{$ELSEIF DEFINED(VK_USE_PLATFORM_MIR_KHR)} + {$ERROR 'TODO: implement'} +{$ELSEIF DEFINED(VK_USE_PLATFORM_ANDROID_KHR)} + {$ERROR 'TODO: implement'} +{$ELSEIF DEFINED(VK_USE_PLATFORM_WIN32_KHR)} +var CreateInfo: TVkWin32SurfaceCreateInfoKHR; +{$ENDIF} +var srf: TvkuSurfaceEx; +begin + {$IF DEFINED(VK_USE_PLATFORM_XLIB_KHR)} + {$ERROR 'TODO: implement'} + {$ELSEIF DEFINED(VK_USE_PLATFORM_XCB_KHR)} + {$ERROR 'TODO: implement'} + {$ELSEIF DEFINED(VK_USE_PLATFORM_WAYLAND_KHR)} + {$ERROR 'TODO: implement'} + {$ELSEIF DEFINED(VK_USE_PLATFORM_MIR_KHR)} + {$ERROR 'TODO: implement'} + {$ELSEIF DEFINED(VK_USE_PLATFORM_ANDROID_KHR)} + {$ERROR 'TODO: implement'} + {$ELSEIF DEFINED(VK_USE_PLATFORM_WIN32_KHR)} + FillByte(CreateInfo, SizeOf(CreateInfo), 0); + CreateInfo.sType := VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR; + CreateInfo.pNext := nil; + CreateInfo.flags := fFlags; + CreateInfo.hinstance := fHInstance; + CreateInfo.hwnd := fHwnd; + {$ENDIF} + if Assigned(aAllocHandler) + then srf := TvkuSurfaceEx.Create(fInstance.Handle, CreateInfo, fInstance.InstanceCommands, aAllocHandler.GetAllocationCallbacks) + else srf := TvkuSurfaceEx.Create(fInstance.Handle, CreateInfo, fInstance.InstanceCommands); + try + srf.fAllocHandler := aAllocHandler; + srf.fOwnsHandler := aOwnsHandler; + except + FreeAndNil(srf); + end; + result := srf; +end; + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +constructor TvkuSurfaceFactory.Create(const aInstance: TvkuInstance); +begin + inherited Create; + {$IF DEFINED(VK_USE_PLATFORM_XLIB_KHR)} + {$ERROR 'TODO: implement'} + {$ELSEIF DEFINED(VK_USE_PLATFORM_XCB_KHR)} + {$ERROR 'TODO: implement'} + {$ELSEIF DEFINED(VK_USE_PLATFORM_WAYLAND_KHR)} + {$ERROR 'TODO: implement'} + {$ELSEIF DEFINED(VK_USE_PLATFORM_MIR_KHR)} + {$ERROR 'TODO: implement'} + {$ELSEIF DEFINED(VK_USE_PLATFORM_ANDROID_KHR)} + {$ERROR 'TODO: implement'} + {$ELSEIF DEFINED(VK_USE_PLATFORM_WIN32_KHR)} + fHInstance := Vulkan.HINSTANCE(GetModuleHandle(nil)); + {$ENDIF} + fInstance := aInstance; + fFlags := 0; +end; + +end. + +