Mercurial > games > semicongine
diff src/vulkan_helpers.nim @ 2:213fdf8d31dd
did: hello world triangle, a bit of code organization
author | Sam <sam@basx.dev> |
---|---|
date | Mon, 19 Dec 2022 10:41:20 +0700 |
parents | bb2a7d3a7003 |
children | af9183acb173 |
line wrap: on
line diff
--- a/src/vulkan_helpers.nim Fri Dec 16 00:05:41 2022 +0700 +++ b/src/vulkan_helpers.nim Mon Dec 19 10:41:20 2022 +0700 @@ -1,26 +1,43 @@ import std/tables import std/strutils +import std/strformat +import std/logging import ./glslang/glslang import ./vulkan - when defined(release): - const ENABLEVULKANVALIDATIONLAYERS = false + const ENABLEVULKANVALIDATIONLAYERS* = false else: - const ENABLEVULKANVALIDATIONLAYERS = true + const ENABLEVULKANVALIDATIONLAYERS* = true template checkVkResult*(call: untyped) = - let value = call - if value != VK_SUCCESS: - raise newException(Exception, "Vulkan error: " & astToStr(call) & " returned " & $value) + when defined(release): + discard call + else: + let value = call + debug(&"CALLING vulkan: {astToStr(call)}") + if value != VK_SUCCESS: + raise newException(Exception, "Vulkan error: " & astToStr(call) & " returned " & $value) proc VK_MAKE_API_VERSION*(variant: uint32, major: uint32, minor: uint32, patch: uint32): uint32 {.compileTime.} = (variant shl 29) or (major shl 22) or (minor shl 12) or patch +proc filterForSurfaceFormat*(formats: seq[VkSurfaceFormatKHR]): seq[VkSurfaceFormatKHR] = + for format in formats: + if format.format == VK_FORMAT_B8G8R8A8_SRGB and format.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR: + result.add(format) + + +proc cleanString*(str: openArray[char]): string = + for i in 0 ..< len(str): + if str[i] == char(0): + result = join(str[0 ..< i]) + break + proc getInstanceExtensions*(): seq[string] = var extensionCount: uint32 checkVkResult vkEnumerateInstanceExtensionProperties(nil, addr(extensionCount), nil) @@ -28,7 +45,7 @@ checkVkResult vkEnumerateInstanceExtensionProperties(nil, addr(extensionCount), addr(extensions[0])) for extension in extensions: - result.add(join(extension.extensionName).strip(chars={char(0)})) + result.add(cleanString(extension.extensionName)) proc getDeviceExtensions*(device: VkPhysicalDevice): seq[string] = @@ -38,7 +55,7 @@ checkVkResult vkEnumerateDeviceExtensionProperties(device, nil, addr(extensionCount), addr(extensions[0])) for extension in extensions: - result.add(join(extension.extensionName).strip(chars={char(0)})) + result.add(cleanString(extension.extensionName)) proc getValidationLayers*(): seq[string] = @@ -48,7 +65,7 @@ checkVkResult vkEnumerateInstanceLayerProperties(addr(n_layers), addr(layers[0])) for layer in layers: - result.add(join(layer.layerName).strip(chars={char(0)})) + result.add(cleanString(layer.layerName)) proc getVulkanPhysicalDevices*(instance: VkInstance): seq[VkPhysicalDevice] = @@ -88,10 +105,10 @@ proc getPresentMode*(modes: seq[VkPresentModeKHR]): VkPresentModeKHR = let preferredModes = [ - VK_PRESENT_MODE_MAILBOX_KHR, - VK_PRESENT_MODE_FIFO_RELAXED_KHR, - VK_PRESENT_MODE_FIFO_KHR, - VK_PRESENT_MODE_IMMEDIATE_KHR, + VK_PRESENT_MODE_MAILBOX_KHR, # triple buffering + VK_PRESENT_MODE_FIFO_RELAXED_KHR, # double duffering + VK_PRESENT_MODE_FIFO_KHR, # double duffering + VK_PRESENT_MODE_IMMEDIATE_KHR, # single buffering ] for preferredMode in preferredModes: for mode in modes: @@ -108,6 +125,7 @@ "VK_KHR_display".cstring, "VK_KHR_surface".cstring, "VK_KHR_xlib_surface".cstring, + "VK_EXT_debug_utils".cstring, ] let availableExtensions = getInstanceExtensions() for extension in requiredExtensions: @@ -122,7 +140,9 @@ if $layer in availableLayers: usableLayers.add(layer) + echo "Available validation layers: ", availableLayers echo "Using validation layers: ", usableLayers + echo "Available extensions: ", availableExtensions echo "Using extensions: ", requiredExtensions var appinfo = VkApplicationInfo( @@ -144,33 +164,40 @@ loadVK_KHR_surface() loadVK_KHR_xlib_surface() loadVK_KHR_swapchain() + when ENABLEVULKANVALIDATIONLAYERS: + loadVK_EXT_debug_utils(result) proc getVulcanDevice*( physicalDevice: var VkPhysicalDevice, features: var VkPhysicalDeviceFeatures, - selectedQueueFamily: uint32, -): (VkDevice, VkQueue) = + graphicsQueueFamily: uint32, + presentationQueueFamily: uint32, +): (VkDevice, VkQueue, VkQueue) = # setup queue and device + # TODO: need check this, possibly wrong logic, see Vulkan tutorial var priority = 1.0'f32 - var queueCreateInfo = VkDeviceQueueCreateInfo( - sType: VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, - queueFamilyIndex: uint32(selectedQueueFamily), - queueCount: 1, - pQueuePriorities: addr(priority), - ) + var queueCreateInfo = [ + VkDeviceQueueCreateInfo( + sType: VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, + queueFamilyIndex: graphicsQueueFamily, + queueCount: 1, + pQueuePriorities: addr(priority), + ), + ] var requiredExtensions = ["VK_KHR_swapchain".cstring] var deviceCreateInfo = VkDeviceCreateInfo( sType: VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, - pQueueCreateInfos: addr(queueCreateInfo), - queueCreateInfoCount: 1, + queueCreateInfoCount: uint32(queueCreateInfo.len), + pQueueCreateInfos: addr(queueCreateInfo[0]), pEnabledFeatures: addr(features), enabledExtensionCount: requiredExtensions.len.uint32, ppEnabledExtensionNames: cast[ptr UncheckedArray[cstring]](addr(requiredExtensions)) ) checkVkResult vkCreateDevice(physicalDevice, addr(deviceCreateInfo), nil, addr(result[0])) - vkGetDeviceQueue(result[0], selectedQueueFamily, 0'u32, addr(result[1])); + vkGetDeviceQueue(result[0], graphicsQueueFamily, 0'u32, addr(result[1])); + vkGetDeviceQueue(result[0], presentationQueueFamily, 0'u32, addr(result[2])); proc createShaderStage*(device: VkDevice, stage: VkShaderStageFlagBits, shader: string): VkPipelineShaderStageCreateInfo = const VK_GLSL_MAP = { @@ -180,15 +207,24 @@ var code = compileGLSLToSPIRV(VK_GLSL_MAP[stage], shader, "<memory-shader>") var createInfo = VkShaderModuleCreateInfo( sType: VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, - codeSize: code.len.uint, + codeSize: uint(code.len * sizeof(uint32)), pCode: addr(code[0]), ) var shaderModule: VkShaderModule checkVkResult vkCreateShaderModule(device, addr(createInfo), nil, addr(shaderModule)) - var vertShaderStageInfo = VkPipelineShaderStageCreateInfo( + return VkPipelineShaderStageCreateInfo( sType: VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, stage: stage, module: shaderModule, pName: "main", # entry point for shader ) + +proc debugCallback*( + messageSeverity: VkDebugUtilsMessageSeverityFlagBitsEXT, + messageTypes: VkDebugUtilsMessageTypeFlagsEXT, + pCallbackData: VkDebugUtilsMessengerCallbackDataEXT, + userData: pointer +): VkBool32 {.cdecl.} = + echo &"{messageSeverity}: {VkDebugUtilsMessageTypeFlagBitsEXT(messageTypes)}: {pCallbackData.pMessage}" + return VK_FALSE