comparison src/vulkan_helpers.nim @ 5:4ed9cb098315

add: structure code for crossplatform, add some input handling + bugfixes
author Sam <sam@basx.dev>
date Thu, 22 Dec 2022 00:06:40 +0700
parents af9183acb173
children 0660ba9d1930
comparison
equal deleted inserted replaced
4:af9183acb173 5:4ed9cb098315
3 import std/strformat 3 import std/strformat
4 import std/logging 4 import std/logging
5 5
6 import ./glslang/glslang 6 import ./glslang/glslang
7 import ./vulkan 7 import ./vulkan
8 import ./window
8 9
9 when defined(release): 10 when defined(release):
10 const ENABLEVULKANVALIDATIONLAYERS* = false 11 const ENABLEVULKANVALIDATIONLAYERS* = false
11 else: 12 else:
12 const ENABLEVULKANVALIDATIONLAYERS* = true 13 const ENABLEVULKANVALIDATIONLAYERS* = true
19 debug(&"CALLING vulkan: {astToStr(call)}") 20 debug(&"CALLING vulkan: {astToStr(call)}")
20 let value = call 21 let value = call
21 if value != VK_SUCCESS: 22 if value != VK_SUCCESS:
22 raise newException(Exception, "Vulkan error: " & astToStr(call) & " returned " & $value) 23 raise newException(Exception, "Vulkan error: " & astToStr(call) & " returned " & $value)
23 24
25 func addrOrNil[T](obj: var openArray[T]): ptr T =
26 if obj.len > 0: addr(obj[0]) else: nil
24 27
25 proc VK_MAKE_API_VERSION*(variant: uint32, major: uint32, minor: uint32, patch: uint32): uint32 {.compileTime.} = 28 proc VK_MAKE_API_VERSION*(variant: uint32, major: uint32, minor: uint32, patch: uint32): uint32 {.compileTime.} =
26 (variant shl 29) or (major shl 22) or (minor shl 12) or patch 29 (variant shl 29) or (major shl 22) or (minor shl 12) or patch
27 30
28 31
46 49
47 proc getInstanceExtensions*(): seq[string] = 50 proc getInstanceExtensions*(): seq[string] =
48 var extensionCount: uint32 51 var extensionCount: uint32
49 checkVkResult vkEnumerateInstanceExtensionProperties(nil, addr(extensionCount), nil) 52 checkVkResult vkEnumerateInstanceExtensionProperties(nil, addr(extensionCount), nil)
50 var extensions = newSeq[VkExtensionProperties](extensionCount) 53 var extensions = newSeq[VkExtensionProperties](extensionCount)
51 checkVkResult vkEnumerateInstanceExtensionProperties(nil, addr(extensionCount), addr(extensions[0])) 54 checkVkResult vkEnumerateInstanceExtensionProperties(nil, addr(extensionCount), addrOrNil(extensions))
52 55
53 for extension in extensions: 56 for extension in extensions:
54 result.add(cleanString(extension.extensionName)) 57 result.add(cleanString(extension.extensionName))
55 58
56 59
57 proc getDeviceExtensions*(device: VkPhysicalDevice): seq[string] = 60 proc getDeviceExtensions*(device: VkPhysicalDevice): seq[string] =
58 var extensionCount: uint32 61 var extensionCount: uint32
59 checkVkResult vkEnumerateDeviceExtensionProperties(device, nil, addr(extensionCount), nil) 62 checkVkResult vkEnumerateDeviceExtensionProperties(device, nil, addr(extensionCount), nil)
60 var extensions = newSeq[VkExtensionProperties](extensionCount) 63 var extensions = newSeq[VkExtensionProperties](extensionCount)
61 checkVkResult vkEnumerateDeviceExtensionProperties(device, nil, addr(extensionCount), addr(extensions[0])) 64 checkVkResult vkEnumerateDeviceExtensionProperties(device, nil, addr(extensionCount), addrOrNil(extensions))
62 65
63 for extension in extensions: 66 for extension in extensions:
64 result.add(cleanString(extension.extensionName)) 67 result.add(cleanString(extension.extensionName))
65 68
66 69
67 proc getValidationLayers*(): seq[string] = 70 proc getValidationLayers*(): seq[string] =
68 var n_layers: uint32 71 var n_layers: uint32
69 checkVkResult vkEnumerateInstanceLayerProperties(addr(n_layers), nil) 72 checkVkResult vkEnumerateInstanceLayerProperties(addr(n_layers), nil)
70 var layers = newSeq[VkLayerProperties](n_layers) 73 var layers = newSeq[VkLayerProperties](n_layers)
71 checkVkResult vkEnumerateInstanceLayerProperties(addr(n_layers), addr(layers[0])) 74 checkVkResult vkEnumerateInstanceLayerProperties(addr(n_layers), addrOrNil(layers))
72 75
73 for layer in layers: 76 for layer in layers:
74 result.add(cleanString(layer.layerName)) 77 result.add(cleanString(layer.layerName))
75 78
76 79
77 proc getVulkanPhysicalDevices*(instance: VkInstance): seq[VkPhysicalDevice] = 80 proc getVulkanPhysicalDevices*(instance: VkInstance): seq[VkPhysicalDevice] =
78 var n_devices: uint32 81 var n_devices: uint32
79 checkVkResult vkEnumeratePhysicalDevices(instance, addr(n_devices), nil) 82 checkVkResult vkEnumeratePhysicalDevices(instance, addr(n_devices), nil)
80 result = newSeq[VkPhysicalDevice](n_devices) 83 result = newSeq[VkPhysicalDevice](n_devices)
81 checkVkResult vkEnumeratePhysicalDevices(instance, addr(n_devices), addr(result[0])) 84 checkVkResult vkEnumeratePhysicalDevices(instance, addr(n_devices), addrOrNil(result))
82 85
83 86
84 proc getQueueFamilies*(device: VkPhysicalDevice): seq[VkQueueFamilyProperties] = 87 proc getQueueFamilies*(device: VkPhysicalDevice): seq[VkQueueFamilyProperties] =
85 var n_queuefamilies: uint32 88 var n_queuefamilies: uint32
86 vkGetPhysicalDeviceQueueFamilyProperties(device, addr(n_queuefamilies), nil) 89 vkGetPhysicalDeviceQueueFamilyProperties(device, addr(n_queuefamilies), nil)
87 result = newSeq[VkQueueFamilyProperties](n_queuefamilies) 90 result = newSeq[VkQueueFamilyProperties](n_queuefamilies)
88 vkGetPhysicalDeviceQueueFamilyProperties(device, addr(n_queuefamilies), addr(result[0])) 91 vkGetPhysicalDeviceQueueFamilyProperties(device, addr(n_queuefamilies), addrOrNil(result))
89 92
90 93
91 proc getDeviceSurfaceFormats*(device: VkPhysicalDevice, surface: VkSurfaceKHR): seq[VkSurfaceFormatKHR] = 94 proc getDeviceSurfaceFormats*(device: VkPhysicalDevice, surface: VkSurfaceKHR): seq[VkSurfaceFormatKHR] =
92 var n_formats: uint32 95 var n_formats: uint32
93 checkVkResult vkGetPhysicalDeviceSurfaceFormatsKHR(device, surface, addr(n_formats), nil); 96 checkVkResult vkGetPhysicalDeviceSurfaceFormatsKHR(device, surface, addr(n_formats), nil);
94 result = newSeq[VkSurfaceFormatKHR](n_formats) 97 result = newSeq[VkSurfaceFormatKHR](n_formats)
95 checkVkResult vkGetPhysicalDeviceSurfaceFormatsKHR(device, surface, addr(n_formats), addr(result[0])) 98 checkVkResult vkGetPhysicalDeviceSurfaceFormatsKHR(device, surface, addr(n_formats), addrOrNil(result))
96 99
97 100
98 proc getDeviceSurfacePresentModes*(device: VkPhysicalDevice, surface: VkSurfaceKHR): seq[VkPresentModeKHR] = 101 proc getDeviceSurfacePresentModes*(device: VkPhysicalDevice, surface: VkSurfaceKHR): seq[VkPresentModeKHR] =
99 var n_modes: uint32 102 var n_modes: uint32
100 checkVkResult vkGetPhysicalDeviceSurfacePresentModesKHR(device, surface, addr(n_modes), nil); 103 checkVkResult vkGetPhysicalDeviceSurfacePresentModesKHR(device, surface, addr(n_modes), nil);
101 result = newSeq[VkPresentModeKHR](n_modes) 104 result = newSeq[VkPresentModeKHR](n_modes)
102 checkVkResult vkGetPhysicalDeviceSurfacePresentModesKHR(device, surface, addr(n_modes), addr(result[0])) 105 checkVkResult vkGetPhysicalDeviceSurfacePresentModesKHR(device, surface, addr(n_modes), addrOrNil(result))
103 106
104 107
105 proc getSwapChainImages*(device: VkDevice, swapChain: VkSwapchainKHR): seq[VkImage] = 108 proc getSwapChainImages*(device: VkDevice, swapChain: VkSwapchainKHR): seq[VkImage] =
106 var n_images: uint32 109 var n_images: uint32
107 checkVkResult vkGetSwapchainImagesKHR(device, swapChain, addr(n_images), nil); 110 checkVkResult vkGetSwapchainImagesKHR(device, swapChain, addr(n_images), nil);
108 result = newSeq[VkImage](n_images) 111 result = newSeq[VkImage](n_images)
109 checkVkResult vkGetSwapchainImagesKHR(device, swapChain, addr(n_images), addr(result[0])); 112 checkVkResult vkGetSwapchainImagesKHR(device, swapChain, addr(n_images), addrOrNil(result));
110 113
111 114
112 proc getPresentMode*(modes: seq[VkPresentModeKHR]): VkPresentModeKHR = 115 proc getPresentMode*(modes: seq[VkPresentModeKHR]): VkPresentModeKHR =
113 let preferredModes = [ 116 let preferredModes = [
114 VK_PRESENT_MODE_MAILBOX_KHR, # triple buffering 117 VK_PRESENT_MODE_MAILBOX_KHR, # triple buffering
159 ) 162 )
160 var createinfo = VkInstanceCreateInfo( 163 var createinfo = VkInstanceCreateInfo(
161 sType: VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, 164 sType: VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
162 pApplicationInfo: addr(appinfo), 165 pApplicationInfo: addr(appinfo),
163 enabledLayerCount: usableLayers.len.uint32, 166 enabledLayerCount: usableLayers.len.uint32,
164 ppEnabledLayerNames: cast[ptr UncheckedArray[cstring]](addr(usableLayers[0])), 167 ppEnabledLayerNames: cast[ptr UncheckedArray[cstring]](addrOrNil(usableLayers)),
165 enabledExtensionCount: requiredExtensions.len.uint32, 168 enabledExtensionCount: requiredExtensions.len.uint32,
166 ppEnabledExtensionNames: cast[ptr UncheckedArray[cstring]](addr(requiredExtensions)) 169 ppEnabledExtensionNames: cast[ptr UncheckedArray[cstring]](addr(requiredExtensions))
167 ) 170 )
168 checkVkResult vkCreateInstance(addr(createinfo), nil, addr(result)) 171 checkVkResult vkCreateInstance(addr(createinfo), nil, addr(result))
169 172
194 197
195 var requiredExtensions = ["VK_KHR_swapchain".cstring] 198 var requiredExtensions = ["VK_KHR_swapchain".cstring]
196 var deviceCreateInfo = VkDeviceCreateInfo( 199 var deviceCreateInfo = VkDeviceCreateInfo(
197 sType: VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, 200 sType: VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
198 queueCreateInfoCount: uint32(queueCreateInfo.len), 201 queueCreateInfoCount: uint32(queueCreateInfo.len),
199 pQueueCreateInfos: addr(queueCreateInfo[0]), 202 pQueueCreateInfos: addrOrNil(queueCreateInfo),
200 pEnabledFeatures: addr(features), 203 pEnabledFeatures: addr(features),
201 enabledExtensionCount: requiredExtensions.len.uint32, 204 enabledExtensionCount: requiredExtensions.len.uint32,
202 ppEnabledExtensionNames: cast[ptr UncheckedArray[cstring]](addr(requiredExtensions)) 205 ppEnabledExtensionNames: cast[ptr UncheckedArray[cstring]](addr(requiredExtensions))
203 ) 206 )
204 checkVkResult vkCreateDevice(physicalDevice, addr(deviceCreateInfo), nil, addr(result[0])) 207 checkVkResult vkCreateDevice(physicalDevice, addr(deviceCreateInfo), nil, addr(result[0]))
212 }.toTable() 215 }.toTable()
213 var code = compileGLSLToSPIRV(VK_GLSL_MAP[stage], shader, "<memory-shader>") 216 var code = compileGLSLToSPIRV(VK_GLSL_MAP[stage], shader, "<memory-shader>")
214 var createInfo = VkShaderModuleCreateInfo( 217 var createInfo = VkShaderModuleCreateInfo(
215 sType: VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, 218 sType: VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
216 codeSize: uint(code.len * sizeof(uint32)), 219 codeSize: uint(code.len * sizeof(uint32)),
217 pCode: addr(code[0]), 220 pCode: addrOrNil(code),
218 ) 221 )
219 var shaderModule: VkShaderModule 222 var shaderModule: VkShaderModule
220 checkVkResult vkCreateShaderModule(device, addr(createInfo), nil, addr(shaderModule)) 223 checkVkResult vkCreateShaderModule(device, addr(createInfo), nil, addr(shaderModule))
221 224
222 return VkPipelineShaderStageCreateInfo( 225 return VkPipelineShaderStageCreateInfo(
232 pCallbackData: VkDebugUtilsMessengerCallbackDataEXT, 235 pCallbackData: VkDebugUtilsMessengerCallbackDataEXT,
233 userData: pointer 236 userData: pointer
234 ): VkBool32 {.cdecl.} = 237 ): VkBool32 {.cdecl.} =
235 echo &"{messageSeverity}: {VkDebugUtilsMessageTypeFlagBitsEXT(messageTypes)}: {pCallbackData.pMessage}" 238 echo &"{messageSeverity}: {VkDebugUtilsMessageTypeFlagBitsEXT(messageTypes)}: {pCallbackData.pMessage}"
236 return VK_FALSE 239 return VK_FALSE
240
241 proc getSurfaceCapabilities*(device: VkPhysicalDevice, surface: VkSurfaceKHR): VkSurfaceCapabilitiesKHR =
242 checkVkResult device.vkGetPhysicalDeviceSurfaceCapabilitiesKHR(surface, addr(result))
243
244 when defined(linux):
245 proc createVulkanSurface*(instance: VkInstance, window: NativeWindow): VkSurfaceKHR =
246 var surfaceCreateInfo = VkXlibSurfaceCreateInfoKHR(
247 sType: VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR,
248 dpy: window.display,
249 window: window.window,
250 )
251 checkVkResult vkCreateXlibSurfaceKHR(instance, addr(surfaceCreateInfo), nil, addr(result))
252 when defined(windows):
253 proc createVulkanSurface*(instance: VkInstance, window: NativeWindow): VkSurfaceKHR =
254 var surfaceCreateInfo = VkWin32SurfaceCreateInfoKHR(
255 sType: VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR,
256 hinstance: window.hinstance,
257 hwnd: window.hwnd,
258 )
259 checkVkResult vkCreateWin32SurfaceKHR(instance, addr(surfaceCreateInfo), nil, addr(result))