Mercurial > games > semicongine
comparison src/vulkan_helpers.nim @ 17:b40466fa446a
add: vertex basics, some refactoring
author | Sam <sam@basx.dev> |
---|---|
date | Sun, 01 Jan 2023 01:00:50 +0700 |
parents | 9e5fe647ff91 |
children |
comparison
equal
deleted
inserted
replaced
16:617c6dcddbe2 | 17:b40466fa446a |
---|---|
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 |