Mercurial > games > semicongine
view src/semicongine/vulkan/instance.nim @ 553:592b28cf65f0
add: more stuff for the vulkan API wrappers
author | Sam <sam@basx.dev> |
---|---|
date | Tue, 28 Feb 2023 00:08:28 +0700 |
parents | 0d20af721f88 |
children | f036546f5ea2 |
line wrap: on
line source
import std/strformat import ./api import ./utils type Instance* = object vk*: VkInstance Debugger* = object instance: Instance messenger: VkDebugUtilsMessengerEXT DebugCallback* = proc ( messageSeverity: VkDebugUtilsMessageSeverityFlagBitsEXT, messageTypes: VkDebugUtilsMessageTypeFlagsEXT, pCallbackData: ptr VkDebugUtilsMessengerCallbackDataEXT, userData: pointer ): VkBool32 {.cdecl.} proc getInstanceExtensions*(): seq[string] = var extensionCount: uint32 checkVkResult vkEnumerateInstanceExtensionProperties(nil, addr(extensionCount), nil) if extensionCount > 0: var extensions = newSeq[VkExtensionProperties](extensionCount) checkVkResult vkEnumerateInstanceExtensionProperties(nil, addr(extensionCount), extensions.toCPointer) for extension in extensions: result.add(cleanString(extension.extensionName)) proc getLayers*(): seq[string] = var n_layers: uint32 checkVkResult vkEnumerateInstanceLayerProperties(addr(n_layers), nil) if n_layers > 0: var layers = newSeq[VkLayerProperties](n_layers) checkVkResult vkEnumerateInstanceLayerProperties(addr(n_layers), layers.toCPointer) for layer in layers: result.add(cleanString(layer.layerName)) proc createInstance*( vulkanVersion: uint32, instanceExtensions: openArray[string], layers: openArray[string], name = "defaultVulkanInstance", engine = "defaultEngine", ): Instance = for i in layers: assert i in getLayers() for i in instanceExtensions: assert i in getInstanceExtensions() var layersC = allocCStringArray(layers) instanceExtensionsC = allocCStringArray(instanceExtensions) appinfo = VkApplicationInfo( sType: VK_STRUCTURE_TYPE_APPLICATION_INFO, pApplicationName: name, pEngineName: engine, apiVersion: vulkanVersion, ) createinfo = VkInstanceCreateInfo( sType: VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, pApplicationInfo: addr(appinfo), enabledLayerCount: layers.len.uint32, ppEnabledLayerNames: layersC, enabledExtensionCount: instanceExtensions.len.uint32, ppEnabledExtensionNames: instanceExtensionsC ) checkVkResult vkCreateInstance(addr(createinfo), nil, addr(result.vk)) result.vk.loadVulkan() deallocCStringArray(layersC) deallocCStringArray(instanceExtensionsC) for extension in instanceExtensions: result.vk.loadExtension($extension) proc destroy*(instance: var Instance) = assert instance.vk.valid # needs to happen after window is trashed as the driver might have a hook registered for the window destruction instance.vk.vkDestroyInstance(nil) instance.vk.reset() proc defaultDebugCallback( messageSeverity: VkDebugUtilsMessageSeverityFlagBitsEXT, messageTypes: VkDebugUtilsMessageTypeFlagsEXT, pCallbackData: ptr VkDebugUtilsMessengerCallbackDataEXT, userData: pointer ): VkBool32 {.cdecl.} = echo &"{messageSeverity}: {toEnums messageTypes}: {pCallbackData.pMessage}" return false proc createDebugMessenger*( instance: Instance, severityLevels: openArray[VkDebugUtilsMessageSeverityFlagBitsEXT] = @[], types: openArray[VkDebugUtilsMessageTypeFlagBitsEXT] = @[], callback: DebugCallback=defaultDebugCallback ): Debugger = assert instance.vk.valid result.instance = instance var severityLevelBits = high(VkDebugUtilsMessageSeverityFlagsEXT) var typeBits = high(VkDebugUtilsMessageTypeFlagsEXT) if severityLevels.len > 0: severityLevelBits = toBits severityLevels if types.len > 0: typeBits = toBits types var createInfo = VkDebugUtilsMessengerCreateInfoEXT( sType: VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT, messageSeverity: severityLevelBits, messageType: typeBits, pfnUserCallback: callback, pUserData: nil, ) checkVkResult instance.vk.vkCreateDebugUtilsMessengerEXT(addr(createInfo), nil, addr(result.messenger)) proc destroy*(debugger: var Debugger) = assert debugger.messenger.valid assert debugger.instance.vk.valid debugger.instance.vk.vkDestroyDebugUtilsMessengerEXT(debugger.messenger, nil) debugger.messenger.reset()