Mercurial > games > semicongine
comparison src/vulkan_helpers.nim @ 478:871ee602bf95
add: vertex basics, some refactoring
| author | Sam <sam@basx.dev> |
|---|---|
| date | Sun, 01 Jan 2023 01:00:50 +0700 |
| parents | 04b8471bdab4 |
| children |
comparison
equal
deleted
inserted
replaced
| 477:f226c99b5043 | 478:871ee602bf95 |
|---|---|
| 2 import std/strutils | 2 import std/strutils |
| 3 import std/strformat | 3 import std/strformat |
| 4 import std/logging | 4 import std/logging |
| 5 import std/macros | 5 import std/macros |
| 6 | 6 |
| 7 import ./glslang/glslang | |
| 8 import ./vulkan | 7 import ./vulkan |
| 9 import ./window | 8 import ./window |
| 10 | 9 |
| 11 | 10 |
| 12 const ENABLEVULKANVALIDATIONLAYERS* = not defined(release) | 11 const ENABLEVULKANVALIDATIONLAYERS* = not defined(release) |
| 14 | 13 |
| 15 template checkVkResult*(call: untyped) = | 14 template checkVkResult*(call: untyped) = |
| 16 when defined(release): | 15 when defined(release): |
| 17 discard call | 16 discard call |
| 18 else: | 17 else: |
| 19 debug "CALLING vulkan: ", astToStr(call) | 18 # yes, a bit cheap, but this is only for nice debug output |
| 19 var callstr = astToStr(call).replace("\n", "") | |
| 20 while callstr.find(" ") >= 0: | |
| 21 callstr = callstr.replace(" ", " ") | |
| 22 debug "CALLING vulkan: ", callstr | |
| 20 let value = call | 23 let value = call |
| 21 if value != VK_SUCCESS: | 24 if value != VK_SUCCESS: |
| 22 error "Vulkan error: ", astToStr(call), " returned ", $value | 25 error "Vulkan error: ", astToStr(call), " returned ", $value |
| 23 raise newException(Exception, "Vulkan error: " & astToStr(call) & " returned " & $value) | 26 raise newException(Exception, "Vulkan error: " & astToStr(call) & " returned " & $value) |
| 24 | 27 |
| 25 func addrOrNil[T](obj: var openArray[T]): ptr T = | 28 func addrOrNil[T](obj: var openArray[T]): ptr T = |
| 26 if obj.len > 0: addr(obj[0]) else: nil | 29 if obj.len > 0: addr(obj[0]) else: nil |
| 27 | 30 |
| 28 proc VK_MAKE_API_VERSION*(variant: uint32, major: uint32, minor: uint32, patch: uint32): uint32 {.compileTime.} = | 31 func VK_MAKE_API_VERSION*(variant: uint32, major: uint32, minor: uint32, patch: uint32): uint32 {.compileTime.} = |
| 29 (variant shl 29) or (major shl 22) or (minor shl 12) or patch | 32 (variant shl 29) or (major shl 22) or (minor shl 12) or patch |
| 30 | 33 |
| 31 | 34 |
| 32 proc filterForSurfaceFormat*(formats: seq[VkSurfaceFormatKHR]): seq[VkSurfaceFormatKHR] = | 35 func filterForSurfaceFormat*(formats: seq[VkSurfaceFormatKHR]): seq[VkSurfaceFormatKHR] = |
| 33 for format in formats: | 36 for format in formats: |
| 34 if format.format == VK_FORMAT_B8G8R8A8_SRGB and format.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR: | 37 if format.format == VK_FORMAT_B8G8R8A8_SRGB and format.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR: |
| 35 result.add(format) | 38 result.add(format) |
| 36 | 39 |
| 37 proc getSuitableSurfaceFormat*(formats: seq[VkSurfaceFormatKHR]): VkSurfaceFormatKHR = | 40 func getSuitableSurfaceFormat*(formats: seq[VkSurfaceFormatKHR]): VkSurfaceFormatKHR = |
| 38 let usableSurfaceFormats = filterForSurfaceFormat(formats) | 41 let usableSurfaceFormats = filterForSurfaceFormat(formats) |
| 39 if len(usableSurfaceFormats) == 0: | 42 if len(usableSurfaceFormats) == 0: |
| 40 raise newException(Exception, "No suitable surface formats found") | 43 raise newException(Exception, "No suitable surface formats found") |
| 41 return usableSurfaceFormats[0] | 44 return usableSurfaceFormats[0] |
| 42 | 45 |
| 43 | 46 |
| 44 proc cleanString*(str: openArray[char]): string = | 47 func cleanString*(str: openArray[char]): string = |
| 45 for i in 0 ..< len(str): | 48 for i in 0 ..< len(str): |
| 46 if str[i] == char(0): | 49 if str[i] == char(0): |
| 47 result = join(str[0 ..< i]) | 50 result = join(str[0 ..< i]) |
| 48 break | 51 break |
| 49 | 52 |
| 110 checkVkResult vkGetSwapchainImagesKHR(device, swapChain, addr(n_images), nil); | 113 checkVkResult vkGetSwapchainImagesKHR(device, swapChain, addr(n_images), nil); |
| 111 result = newSeq[VkImage](n_images) | 114 result = newSeq[VkImage](n_images) |
| 112 checkVkResult vkGetSwapchainImagesKHR(device, swapChain, addr(n_images), addrOrNil(result)); | 115 checkVkResult vkGetSwapchainImagesKHR(device, swapChain, addr(n_images), addrOrNil(result)); |
| 113 | 116 |
| 114 | 117 |
| 115 proc getPresentMode*(modes: seq[VkPresentModeKHR]): VkPresentModeKHR = | 118 func getPresentMode*(modes: seq[VkPresentModeKHR]): VkPresentModeKHR = |
| 116 let preferredModes = [ | 119 let preferredModes = [ |
| 117 VK_PRESENT_MODE_MAILBOX_KHR, # triple buffering | 120 VK_PRESENT_MODE_MAILBOX_KHR, # triple buffering |
| 118 VK_PRESENT_MODE_FIFO_RELAXED_KHR, # double duffering | 121 VK_PRESENT_MODE_FIFO_RELAXED_KHR, # double duffering |
| 119 VK_PRESENT_MODE_FIFO_KHR, # double duffering | 122 VK_PRESENT_MODE_FIFO_KHR, # double duffering |
| 120 VK_PRESENT_MODE_IMMEDIATE_KHR, # single buffering | 123 VK_PRESENT_MODE_IMMEDIATE_KHR, # single buffering |
| 210 ) | 213 ) |
| 211 checkVkResult vkCreateDevice(physicalDevice, addr(deviceCreateInfo), nil, addr(result[0])) | 214 checkVkResult vkCreateDevice(physicalDevice, addr(deviceCreateInfo), nil, addr(result[0])) |
| 212 vkGetDeviceQueue(result[0], graphicsQueueFamily, 0'u32, addr(result[1])); | 215 vkGetDeviceQueue(result[0], graphicsQueueFamily, 0'u32, addr(result[1])); |
| 213 vkGetDeviceQueue(result[0], presentationQueueFamily, 0'u32, addr(result[2])); | 216 vkGetDeviceQueue(result[0], presentationQueueFamily, 0'u32, addr(result[2])); |
| 214 | 217 |
| 215 proc createShaderStage*(device: VkDevice, stage: VkShaderStageFlagBits, shader: string): VkPipelineShaderStageCreateInfo = | |
| 216 const VK_GLSL_MAP = { | |
| 217 VK_SHADER_STAGE_VERTEX_BIT: GLSLANG_STAGE_VERTEX, | |
| 218 VK_SHADER_STAGE_FRAGMENT_BIT: GLSLANG_STAGE_FRAGMENT, | |
| 219 }.toTable() | |
| 220 var code = compileGLSLToSPIRV(VK_GLSL_MAP[stage], shader, "<memory-shader>") | |
| 221 var createInfo = VkShaderModuleCreateInfo( | |
| 222 sType: VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, | |
| 223 codeSize: uint(code.len * sizeof(uint32)), | |
| 224 pCode: addrOrNil(code), | |
| 225 ) | |
| 226 var shaderModule: VkShaderModule | |
| 227 checkVkResult vkCreateShaderModule(device, addr(createInfo), nil, addr(shaderModule)) | |
| 228 | |
| 229 return VkPipelineShaderStageCreateInfo( | |
| 230 sType: VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, | |
| 231 stage: stage, | |
| 232 module: shaderModule, | |
| 233 pName: "main", # entry point for shader | |
| 234 ) | |
| 235 | |
| 236 proc debugCallback*( | 218 proc debugCallback*( |
| 237 messageSeverity: VkDebugUtilsMessageSeverityFlagBitsEXT, | 219 messageSeverity: VkDebugUtilsMessageSeverityFlagBitsEXT, |
| 238 messageTypes: VkDebugUtilsMessageTypeFlagsEXT, | 220 messageTypes: VkDebugUtilsMessageTypeFlagsEXT, |
| 239 pCallbackData: VkDebugUtilsMessengerCallbackDataEXT, | 221 pCallbackData: VkDebugUtilsMessengerCallbackDataEXT, |
| 240 userData: pointer | 222 userData: pointer |
