comparison semiconginev2/old/vulkan/instance.nim @ 1218:56781cc0fc7c compiletime-tests

did: renamge main package
author sam <sam@basx.dev>
date Wed, 17 Jul 2024 21:01:37 +0700
parents semicongine/old/vulkan/instance.nim@a3eb305bcac2
children
comparison
equal deleted inserted replaced
1217:f819a874058f 1218:56781cc0fc7c
1 import std/strformat
2 import std/tables
3 import std/sequtils
4 import std/logging
5
6 import ../core
7
8 import ../platform/vulkanExtensions
9 import ../platform/window
10 import ../platform/surface
11
12 type
13 Instance* = object
14 vk*: VkInstance
15 window*: NativeWindow
16 surface*: VkSurfaceKHR
17 Debugger* = object
18 instance*: Instance
19 messenger*: VkDebugUtilsMessengerEXT
20 DebugCallback* = proc (
21 messageSeverity: VkDebugUtilsMessageSeverityFlagBitsEXT,
22 messageTypes: VkDebugUtilsMessageTypeFlagsEXT,
23 pCallbackData: ptr VkDebugUtilsMessengerCallbackDataEXT,
24 userData: pointer
25 ): VkBool32 {.cdecl.}
26
27 proc GetInstanceExtensions*(): seq[string] =
28 var extensionCount: uint32
29 checkVkResult vkEnumerateInstanceExtensionProperties(nil, addr(extensionCount), nil)
30 if extensionCount > 0:
31 var extensions = newSeq[VkExtensionProperties](extensionCount)
32 checkVkResult vkEnumerateInstanceExtensionProperties(nil, addr(extensionCount), extensions.ToCPointer)
33 for extension in extensions:
34 result.add(CleanString(extension.extensionName))
35
36 proc GetLayers*(): seq[string] =
37 var n_layers: uint32
38 checkVkResult vkEnumerateInstanceLayerProperties(addr(n_layers), nil)
39 if n_layers > 0:
40 var layers = newSeq[VkLayerProperties](n_layers)
41 checkVkResult vkEnumerateInstanceLayerProperties(addr(n_layers), layers.ToCPointer)
42 for layer in layers:
43 result.add(CleanString(layer.layerName))
44
45 proc CreateInstance*(
46 window: NativeWindow,
47 vulkanVersion: uint32,
48 instanceExtensions: seq[string],
49 layers: seq[string],
50 name = "defaultVulkanInstance",
51 engine = "defaultEngine",
52 ): Instance =
53
54 let requiredExtensions = REQUIRED_PLATFORM_EXTENSIONS & @["VK_KHR_surface"] & instanceExtensions
55 for i in requiredExtensions:
56 assert i in GetInstanceExtensions(), $i
57 var availableLayers: seq[string]
58 for i in layers:
59 if i in GetLayers():
60 availableLayers.add i
61 debug "Enabled layers: " & $availableLayers
62 var
63 layersC = allocCStringArray(availableLayers)
64 instanceExtensionsC = allocCStringArray(requiredExtensions)
65 appinfo = VkApplicationInfo(
66 sType: VK_STRUCTURE_TYPE_APPLICATION_INFO,
67 pApplicationName: name,
68 pEngineName: engine,
69 apiVersion: vulkanVersion,
70 )
71 createinfo = VkInstanceCreateInfo(
72 sType: VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
73 pApplicationInfo: addr(appinfo),
74 enabledLayerCount: availableLayers.len.uint32,
75 ppEnabledLayerNames: layersC,
76 enabledExtensionCount: requiredExtensions.len.uint32,
77 ppEnabledExtensionNames: instanceExtensionsC
78 )
79 checkVkResult vkCreateInstance(addr(createinfo), nil, addr(result.vk))
80 result.vk.loadVulkan()
81 deallocCStringArray(layersC)
82 deallocCStringArray(instanceExtensionsC)
83 for extension in requiredExtensions:
84 result.vk.loadExtension($extension)
85 result.surface = result.vk.CreateNativeSurface(window)
86
87 proc Destroy*(instance: var Instance) =
88 assert instance.vk.Valid
89 assert instance.surface.Valid
90 # needs to happen after window is trashed as the driver might have a hook registered for the window destruction
91 instance.vk.vkDestroySurfaceKHR(instance.surface, nil)
92 instance.surface.Reset()
93 instance.vk.vkDestroyInstance(nil)
94 instance.vk.Reset()
95
96 const LEVEL_MAPPING = {
97 VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT: lvlDebug,
98 VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT: lvlInfo,
99 VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT: lvlWarn,
100 VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT: lvlError,
101 }.toTable
102
103 proc defaultDebugCallback(
104 messageSeverity: VkDebugUtilsMessageSeverityFlagBitsEXT,
105 messageTypes: VkDebugUtilsMessageTypeFlagsEXT,
106 pCallbackData: ptr VkDebugUtilsMessengerCallbackDataEXT,
107 userData: pointer
108 ): VkBool32 {.cdecl.} =
109
110 log LEVEL_MAPPING[messageSeverity], &"{toEnums messageTypes}: {pCallbackData.pMessage}"
111 if messageSeverity == VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT:
112 let errorMsg = getStackTrace() & &"\n{toEnums messageTypes}: {pCallbackData.pMessage}"
113 raise newException(Exception, errorMsg)
114 return false
115
116 proc CreateDebugMessenger*(
117 instance: Instance,
118 severityLevels: openArray[VkDebugUtilsMessageSeverityFlagBitsEXT] = @[],
119 types: openArray[VkDebugUtilsMessageTypeFlagBitsEXT] = @[],
120 callback: DebugCallback = defaultDebugCallback
121 ): Debugger =
122 assert instance.vk.Valid
123 result.instance = instance
124 var severityLevelBits = VkDebugUtilsMessageSeverityFlagBitsEXT.items.toSeq.toBits
125 var typeBits = VkDebugUtilsMessageTypeFlagBitsEXT.items.toSeq.toBits
126 if severityLevels.len > 0:
127 severityLevelBits = toBits severityLevels
128 if types.len > 0:
129 typeBits = toBits types
130 var createInfo = VkDebugUtilsMessengerCreateInfoEXT(
131 sType: VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT,
132 messageSeverity: severityLevelBits,
133 messageType: typeBits,
134 pfnUserCallback: callback,
135 pUserData: nil,
136 )
137 checkVkResult instance.vk.vkCreateDebugUtilsMessengerEXT(addr(createInfo), nil, addr(result.messenger))
138
139 proc Destroy*(debugger: var Debugger) =
140 assert debugger.messenger.Valid
141 assert debugger.instance.vk.Valid
142 debugger.instance.vk.vkDestroyDebugUtilsMessengerEXT(debugger.messenger, nil)
143 debugger.messenger.Reset()