comparison src/semicongine/engine.nim @ 522:f2c97bdbb0b3

did: rename and update older demos to work with new APIs
author Sam <sam@basx.dev>
date Tue, 24 Jan 2023 10:22:38 +0700
parents a25325bec7f2
children 311ee4e58032
comparison
equal deleted inserted replaced
521:a25325bec7f2 522:f2c97bdbb0b3
93 vulkan*: Vulkan 93 vulkan*: Vulkan
94 window*: NativeWindow 94 window*: NativeWindow
95 currentscenedata*: Thing 95 currentscenedata*: Thing
96 input*: Input 96 input*: Input
97 97
98 proc getAllPhysicalDevices(instance: VkInstance, surface: VkSurfaceKHR): seq[PhysicalDevice] = 98 proc getAllPhysicalDevices(instance: VkInstance, surface: VkSurfaceKHR): seq[
99 PhysicalDevice] =
99 for vulkanPhysicalDevice in getVulkanPhysicalDevices(instance): 100 for vulkanPhysicalDevice in getVulkanPhysicalDevices(instance):
100 var device = PhysicalDevice(device: vulkanPhysicalDevice, extensions: getDeviceExtensions(vulkanPhysicalDevice)) 101 var device = PhysicalDevice(device: vulkanPhysicalDevice,
102 extensions: getDeviceExtensions(vulkanPhysicalDevice))
101 vkGetPhysicalDeviceProperties(vulkanPhysicalDevice, addr(device.properties)) 103 vkGetPhysicalDeviceProperties(vulkanPhysicalDevice, addr(device.properties))
102 vkGetPhysicalDeviceFeatures(vulkanPhysicalDevice, addr(device.features)) 104 vkGetPhysicalDeviceFeatures(vulkanPhysicalDevice, addr(device.features))
103 device.formats = vulkanPhysicalDevice.getDeviceSurfaceFormats(surface) 105 device.formats = vulkanPhysicalDevice.getDeviceSurfaceFormats(surface)
104 device.presentModes = vulkanPhysicalDevice.getDeviceSurfacePresentModes(surface) 106 device.presentModes = vulkanPhysicalDevice.getDeviceSurfacePresentModes(surface)
105 107
106 debug(&"Physical device nr {int(vulkanPhysicalDevice)} {cleanString(device.properties.deviceName)}") 108 debug(&"Physical device nr {int(vulkanPhysicalDevice)} {cleanString(device.properties.deviceName)}")
107 for i, queueFamilyProperty in enumerate(getQueueFamilies(vulkanPhysicalDevice)): 109 for i, queueFamilyProperty in enumerate(getQueueFamilies(
110 vulkanPhysicalDevice)):
108 var hasSurfaceSupport: VkBool32 = VK_FALSE 111 var hasSurfaceSupport: VkBool32 = VK_FALSE
109 checkVkResult vkGetPhysicalDeviceSurfaceSupportKHR(vulkanPhysicalDevice, uint32(i), surface, addr(hasSurfaceSupport)) 112 checkVkResult vkGetPhysicalDeviceSurfaceSupportKHR(vulkanPhysicalDevice,
110 device.queueFamilies.add(QueueFamily(properties: queueFamilyProperty, hasSurfaceSupport: bool(hasSurfaceSupport))) 113 uint32(i), surface, addr(hasSurfaceSupport))
114 device.queueFamilies.add(QueueFamily(properties: queueFamilyProperty,
115 hasSurfaceSupport: bool(hasSurfaceSupport)))
111 debug(&" Queue family {i} {queueFamilyProperty}") 116 debug(&" Queue family {i} {queueFamilyProperty}")
112 117
113 result.add(device) 118 result.add(device)
114 119
115 proc filterForDevice(devices: seq[PhysicalDevice]): seq[(PhysicalDevice, uint32, uint32)] = 120 proc filterForDevice(devices: seq[PhysicalDevice]): seq[(PhysicalDevice, uint32, uint32)] =
116 for device in devices: 121 for device in devices:
117 if not (device.formats.len > 0 and device.presentModes.len > 0 and "VK_KHR_swapchain" in device.extensions): 122 if not (device.formats.len > 0 and device.presentModes.len > 0 and
123 "VK_KHR_swapchain" in device.extensions):
118 continue 124 continue
119 var graphicsQueueFamily = high(uint32) 125 var graphicsQueueFamily = high(uint32)
120 var presentationQueueFamily = high(uint32) 126 var presentationQueueFamily = high(uint32)
121 for i, queueFamily in enumerate(device.queueFamilies): 127 for i, queueFamily in enumerate(device.queueFamilies):
122 if queueFamily.hasSurfaceSupport: 128 if queueFamily.hasSurfaceSupport:
123 presentationQueueFamily = uint32(i) 129 presentationQueueFamily = uint32(i)
124 if bool(uint32(queueFamily.properties.queueFlags) and ord(VK_QUEUE_GRAPHICS_BIT)): 130 if bool(uint32(queueFamily.properties.queueFlags) and ord(
131 VK_QUEUE_GRAPHICS_BIT)):
125 graphicsQueueFamily = uint32(i) 132 graphicsQueueFamily = uint32(i)
126 if graphicsQueueFamily != high(uint32) and presentationQueueFamily != high(uint32): 133 if graphicsQueueFamily != high(uint32) and presentationQueueFamily != high(uint32):
127 result.add((device, graphicsQueueFamily, presentationQueueFamily)) 134 result.add((device, graphicsQueueFamily, presentationQueueFamily))
128 135
129 for (device, graphicsQueueFamily, presentationQueueFamily) in result: 136 for (device, graphicsQueueFamily, presentationQueueFamily) in result:
130 debug(&"Viable device: {cleanString(device.properties.deviceName)} (graphics queue family {graphicsQueueFamily}, presentation queue family {presentationQueueFamily})") 137 debug(&"Viable device: {cleanString(device.properties.deviceName)} (graphics queue family {graphicsQueueFamily}, presentation queue family {presentationQueueFamily})")
131 138
132 139
133 proc getFrameDimension(window: NativeWindow, device: VkPhysicalDevice, surface: VkSurfaceKHR): TVec2[uint32] = 140 proc getFrameDimension(window: NativeWindow, device: VkPhysicalDevice,
141 surface: VkSurfaceKHR): TVec2[uint32] =
134 let capabilities = device.getSurfaceCapabilities(surface) 142 let capabilities = device.getSurfaceCapabilities(surface)
135 if capabilities.currentExtent.width != high(uint32): 143 if capabilities.currentExtent.width != high(uint32):
136 return TVec2[uint32]([capabilities.currentExtent.width, capabilities.currentExtent.height]) 144 return TVec2[uint32]([capabilities.currentExtent.width,
145 capabilities.currentExtent.height])
137 else: 146 else:
138 let (width, height) = window.size() 147 let (width, height) = window.size()
139 return TVec2[uint32]([ 148 return TVec2[uint32]([
140 min(max(uint32(width), capabilities.minImageExtent.width), capabilities.maxImageExtent.width), 149 min(max(uint32(width), capabilities.minImageExtent.width),
141 min(max(uint32(height), capabilities.minImageExtent.height), capabilities.maxImageExtent.height), 150 capabilities.maxImageExtent.width),
151 min(max(uint32(height), capabilities.minImageExtent.height),
152 capabilities.maxImageExtent.height),
142 ]) 153 ])
143 154
144 when DEBUG_LOG: 155 when DEBUG_LOG:
145 proc setupDebugLog(instance: VkInstance): VkDebugUtilsMessengerEXT = 156 proc setupDebugLog(instance: VkInstance): VkDebugUtilsMessengerEXT =
146 var createInfo = VkDebugUtilsMessengerCreateInfoEXT( 157 var createInfo = VkDebugUtilsMessengerCreateInfoEXT(
156 ord(VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT) 167 ord(VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT)
157 ), 168 ),
158 pfnUserCallback: debugCallback, 169 pfnUserCallback: debugCallback,
159 pUserData: nil, 170 pUserData: nil,
160 ) 171 )
161 checkVkResult instance.vkCreateDebugUtilsMessengerEXT(addr(createInfo), nil, addr(result)) 172 checkVkResult instance.vkCreateDebugUtilsMessengerEXT(addr(createInfo), nil,
162 173 addr(result))
163 proc setupVulkanDeviceAndQueues(instance: VkInstance, surface: VkSurfaceKHR): Device = 174
175 proc setupVulkanDeviceAndQueues(instance: VkInstance,
176 surface: VkSurfaceKHR): Device =
164 let usableDevices = instance.getAllPhysicalDevices(surface).filterForDevice() 177 let usableDevices = instance.getAllPhysicalDevices(surface).filterForDevice()
165 if len(usableDevices) == 0: 178 if len(usableDevices) == 0:
166 raise newException(Exception, "No suitable graphics device found") 179 raise newException(Exception, "No suitable graphics device found")
167 result.physicalDevice = usableDevices[0][0] 180 result.physicalDevice = usableDevices[0][0]
168 result.graphicsQueueFamily = usableDevices[0][1] 181 result.graphicsQueueFamily = usableDevices[0][1]
169 result.presentationQueueFamily = usableDevices[0][2] 182 result.presentationQueueFamily = usableDevices[0][2]
170 183
171 debug(&"Chose device {cleanString(result.physicalDevice.properties.deviceName)}") 184 debug(&"Chose device {cleanString(result.physicalDevice.properties.deviceName)}")
172 185
173 (result.device, result.graphicsQueue, result.presentationQueue) = getVulcanDevice( 186 (result.device, result.graphicsQueue, result.presentationQueue) = getVulcanDevice(
174 result.physicalDevice.device, 187 result.physicalDevice.device,
175 result.physicalDevice.features, 188 result.physicalDevice.features,
176 result.graphicsQueueFamily, 189 result.graphicsQueueFamily,
177 result.presentationQueueFamily, 190 result.presentationQueueFamily,
178 ) 191 )
179 192
180 proc setupSwapChain(device: VkDevice, physicalDevice: PhysicalDevice, surface: VkSurfaceKHR, dimension: TVec2[uint32], surfaceFormat: VkSurfaceFormatKHR): Swapchain = 193 proc setupSwapChain(device: VkDevice, physicalDevice: PhysicalDevice,
194 surface: VkSurfaceKHR, dimension: TVec2[uint32],
195 surfaceFormat: VkSurfaceFormatKHR): Swapchain =
181 196
182 let capabilities = physicalDevice.device.getSurfaceCapabilities(surface) 197 let capabilities = physicalDevice.device.getSurfaceCapabilities(surface)
183 var selectedPresentationMode = getPresentMode(physicalDevice.presentModes) 198 var selectedPresentationMode = getPresentMode(physicalDevice.presentModes)
184 var imageCount = capabilities.minImageCount + 1 199 var imageCount = capabilities.minImageCount + 1
185 if capabilities.maxImageCount > 0: 200 if capabilities.maxImageCount > 0:
200 compositeAlpha: VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR, 215 compositeAlpha: VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
201 presentMode: selectedPresentationMode, 216 presentMode: selectedPresentationMode,
202 clipped: VK_TRUE, 217 clipped: VK_TRUE,
203 oldSwapchain: VkSwapchainKHR(0), 218 oldSwapchain: VkSwapchainKHR(0),
204 ) 219 )
205 checkVkResult device.vkCreateSwapchainKHR(addr(swapchainCreateInfo), nil, addr(result.swapchain)) 220 checkVkResult device.vkCreateSwapchainKHR(addr(swapchainCreateInfo), nil,
221 addr(result.swapchain))
206 result.images = device.getSwapChainImages(result.swapchain) 222 result.images = device.getSwapChainImages(result.swapchain)
207 223
208 # setup swapchian image views 224 # setup swapchian image views
209 225
210 result.imageviews = newSeq[VkImageView](result.images.len) 226 result.imageviews = newSeq[VkImageView](result.images.len)
226 levelCount: 1, 242 levelCount: 1,
227 baseArrayLayer: 0, 243 baseArrayLayer: 0,
228 layerCount: 1, 244 layerCount: 1,
229 ), 245 ),
230 ) 246 )
231 checkVkResult device.vkCreateImageView(addr(imageViewCreateInfo), nil, addr(result.imageviews[i])) 247 checkVkResult device.vkCreateImageView(addr(imageViewCreateInfo), nil, addr(
248 result.imageviews[i]))
232 249
233 proc setupRenderPass(device: VkDevice, format: VkFormat): VkRenderPass = 250 proc setupRenderPass(device: VkDevice, format: VkFormat): VkRenderPass =
234 var 251 var
235 colorAttachment = VkAttachmentDescription( 252 colorAttachment = VkAttachmentDescription(
236 format: format, 253 format: format,
252 pColorAttachments: addr(colorAttachmentRef) 269 pColorAttachments: addr(colorAttachmentRef)
253 ) 270 )
254 dependency = VkSubpassDependency( 271 dependency = VkSubpassDependency(
255 srcSubpass: VK_SUBPASS_EXTERNAL, 272 srcSubpass: VK_SUBPASS_EXTERNAL,
256 dstSubpass: 0, 273 dstSubpass: 0,
257 srcStageMask: VkPipelineStageFlags(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT), 274 srcStageMask: VkPipelineStageFlags(
275 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT),
258 srcAccessMask: VkAccessFlags(0), 276 srcAccessMask: VkAccessFlags(0),
259 dstStageMask: VkPipelineStageFlags(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT), 277 dstStageMask: VkPipelineStageFlags(
278 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT),
260 dstAccessMask: VkAccessFlags(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT), 279 dstAccessMask: VkAccessFlags(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT),
261 ) 280 )
262 renderPassCreateInfo = VkRenderPassCreateInfo( 281 renderPassCreateInfo = VkRenderPassCreateInfo(
263 sType: VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, 282 sType: VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
264 attachmentCount: 1, 283 attachmentCount: 1,
268 dependencyCount: 1, 287 dependencyCount: 1,
269 pDependencies: addr(dependency), 288 pDependencies: addr(dependency),
270 ) 289 )
271 checkVkResult device.vkCreateRenderPass(addr(renderPassCreateInfo), nil, addr(result)) 290 checkVkResult device.vkCreateRenderPass(addr(renderPassCreateInfo), nil, addr(result))
272 291
273 proc initRenderPipeline[VertexType, Uniforms](device: VkDevice, frameSize: TVec2[uint32], renderPass: VkRenderPass, vertexShader, fragmentShader: static string): RenderPipeline[VertexType, Uniforms] = 292 proc initRenderPipeline[VertexType, Uniforms](device: VkDevice,
293 frameSize: TVec2[uint32], renderPass: VkRenderPass, vertexShader,
294 fragmentShader: static string): RenderPipeline[VertexType, Uniforms] =
274 # load shaders 295 # load shaders
275 result.device = device 296 result.device = device
276 result.shaders.add(initShaderProgram[VertexType, Uniforms](device, VK_SHADER_STAGE_VERTEX_BIT, vertexShader)) 297 result.shaders.add(initShaderProgram[VertexType, Uniforms](device,
277 result.shaders.add(initShaderProgram[VertexType, Uniforms](device, VK_SHADER_STAGE_FRAGMENT_BIT, fragmentShader)) 298 VK_SHADER_STAGE_VERTEX_BIT, vertexShader))
299 result.shaders.add(initShaderProgram[VertexType, Uniforms](device,
300 VK_SHADER_STAGE_FRAGMENT_BIT, fragmentShader))
278 301
279 var 302 var
280 # define which parts can be dynamic (pipeline is fixed after setup) 303 # define which parts can be dynamic (pipeline is fixed after setup)
281 dynamicStates = [VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR] 304 dynamicStates = [VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR]
282 dynamicState = VkPipelineDynamicStateCreateInfo( 305 dynamicState = VkPipelineDynamicStateCreateInfo(
354 attachmentCount: 1, 377 attachmentCount: 1,
355 pAttachments: addr(colorBlendAttachment), 378 pAttachments: addr(colorBlendAttachment),
356 blendConstants: [0.0'f, 0.0'f, 0.0'f, 0.0'f], 379 blendConstants: [0.0'f, 0.0'f, 0.0'f, 0.0'f],
357 ) 380 )
358 381
359 result.descriptorSetLayout = device.createUniformDescriptorLayout(VkShaderStageFlags(VK_SHADER_STAGE_VERTEX_BIT), 0) 382 result.descriptorSetLayout = device.createUniformDescriptorLayout(
360 var 383 VkShaderStageFlags(VK_SHADER_STAGE_VERTEX_BIT), 0)
384 var
361 # "globals" that go into the shader, uniforms etc. 385 # "globals" that go into the shader, uniforms etc.
362 pipelineLayoutInfo = VkPipelineLayoutCreateInfo( 386 pipelineLayoutInfo = VkPipelineLayoutCreateInfo(
363 sType: VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, 387 sType: VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
364 setLayoutCount: 1, 388 setLayoutCount: 1,
365 pSetLayouts: addr(result.descriptorSetLayout), 389 pSetLayouts: addr(result.descriptorSetLayout),
366 pushConstantRangeCount: 0, 390 pushConstantRangeCount: 0,
367 pPushConstantRanges: nil, 391 pPushConstantRanges: nil,
368 ) 392 )
369 checkVkResult vkCreatePipelineLayout(device, addr(pipelineLayoutInfo), nil, addr(result.layout)) 393 checkVkResult vkCreatePipelineLayout(device, addr(pipelineLayoutInfo), nil,
394 addr(result.layout))
370 395
371 var stages: seq[VkPipelineShaderStageCreateInfo] 396 var stages: seq[VkPipelineShaderStageCreateInfo]
372 for shader in result.shaders: 397 for shader in result.shaders:
373 stages.add(shader.shader) 398 stages.add(shader.shader)
374 var pipelineInfo = VkGraphicsPipelineCreateInfo( 399 var pipelineInfo = VkGraphicsPipelineCreateInfo(
396 addr(pipelineInfo), 421 addr(pipelineInfo),
397 nil, 422 nil,
398 addr(result.pipeline) 423 addr(result.pipeline)
399 ) 424 )
400 425
401 proc setupFramebuffers(device: VkDevice, swapchain: var Swapchain, renderPass: VkRenderPass, dimension: TVec2[uint32]): seq[VkFramebuffer] = 426 proc setupFramebuffers(device: VkDevice, swapchain: var Swapchain,
427 renderPass: VkRenderPass, dimension: TVec2[uint32]): seq[VkFramebuffer] =
402 result = newSeq[VkFramebuffer](swapchain.images.len) 428 result = newSeq[VkFramebuffer](swapchain.images.len)
403 for i, imageview in enumerate(swapchain.imageviews): 429 for i, imageview in enumerate(swapchain.imageviews):
404 var framebufferInfo = VkFramebufferCreateInfo( 430 var framebufferInfo = VkFramebufferCreateInfo(
405 sType: VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, 431 sType: VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
406 renderPass: renderPass, 432 renderPass: renderPass,
408 pAttachments: addr(swapchain.imageviews[i]), 434 pAttachments: addr(swapchain.imageviews[i]),
409 width: dimension[0], 435 width: dimension[0],
410 height: dimension[1], 436 height: dimension[1],
411 layers: 1, 437 layers: 1,
412 ) 438 )
413 checkVkResult device.vkCreateFramebuffer(addr(framebufferInfo), nil, addr(result[i])) 439 checkVkResult device.vkCreateFramebuffer(addr(framebufferInfo), nil, addr(
414 440 result[i]))
415 proc trash(device: VkDevice, swapchain: Swapchain, framebuffers: seq[VkFramebuffer]) = 441
442 proc trash(device: VkDevice, swapchain: Swapchain, framebuffers: seq[
443 VkFramebuffer]) =
416 for framebuffer in framebuffers: 444 for framebuffer in framebuffers:
417 device.vkDestroyFramebuffer(framebuffer, nil) 445 device.vkDestroyFramebuffer(framebuffer, nil)
418 for imageview in swapchain.imageviews: 446 for imageview in swapchain.imageviews:
419 device.vkDestroyImageView(imageview, nil) 447 device.vkDestroyImageView(imageview, nil)
420 device.vkDestroySwapchainKHR(swapchain.swapchain, nil) 448 device.vkDestroySwapchainKHR(swapchain.swapchain, nil)
438 vulkan.renderPass, 466 vulkan.renderPass,
439 vulkan.frameSize 467 vulkan.frameSize
440 ) 468 )
441 469
442 470
443 proc setupCommandBuffers(device: VkDevice, graphicsQueueFamily: uint32): (VkCommandPool, array[MAX_FRAMES_IN_FLIGHT, VkCommandBuffer]) = 471 proc setupCommandBuffers(device: VkDevice, graphicsQueueFamily: uint32): (
472 VkCommandPool, array[MAX_FRAMES_IN_FLIGHT, VkCommandBuffer]) =
444 # set up command buffer 473 # set up command buffer
445 var poolInfo = VkCommandPoolCreateInfo( 474 var poolInfo = VkCommandPoolCreateInfo(
446 sType: VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, 475 sType: VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
447 flags: VkCommandPoolCreateFlags(VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT), 476 flags: VkCommandPoolCreateFlags(VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT),
448 queueFamilyIndex: graphicsQueueFamily, 477 queueFamilyIndex: graphicsQueueFamily,
460 proc setupSyncPrimitives(device: VkDevice): ( 489 proc setupSyncPrimitives(device: VkDevice): (
461 array[MAX_FRAMES_IN_FLIGHT, VkSemaphore], 490 array[MAX_FRAMES_IN_FLIGHT, VkSemaphore],
462 array[MAX_FRAMES_IN_FLIGHT, VkSemaphore], 491 array[MAX_FRAMES_IN_FLIGHT, VkSemaphore],
463 array[MAX_FRAMES_IN_FLIGHT, VkFence], 492 array[MAX_FRAMES_IN_FLIGHT, VkFence],
464 ) = 493 ) =
465 var semaphoreInfo = VkSemaphoreCreateInfo(sType: VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO) 494 var semaphoreInfo = VkSemaphoreCreateInfo(
495 sType: VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO)
466 var fenceInfo = VkFenceCreateInfo( 496 var fenceInfo = VkFenceCreateInfo(
467 sType: VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, 497 sType: VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
468 flags: VkFenceCreateFlags(VK_FENCE_CREATE_SIGNALED_BIT) 498 flags: VkFenceCreateFlags(VK_FENCE_CREATE_SIGNALED_BIT)
469 ) 499 )
470 for i in 0 ..< MAX_FRAMES_IN_FLIGHT: 500 for i in 0 ..< MAX_FRAMES_IN_FLIGHT:
471 checkVkResult device.vkCreateSemaphore(addr(semaphoreInfo), nil, addr(result[0][i])) 501 checkVkResult device.vkCreateSemaphore(addr(semaphoreInfo), nil, addr(
472 checkVkResult device.vkCreateSemaphore(addr(semaphoreInfo), nil, addr(result[1][i])) 502 result[0][i]))
503 checkVkResult device.vkCreateSemaphore(addr(semaphoreInfo), nil, addr(
504 result[1][i]))
473 checkVkResult device.vkCreateFence(addr(fenceInfo), nil, addr(result[2][i])) 505 checkVkResult device.vkCreateFence(addr(fenceInfo), nil, addr(result[2][i]))
474 506
475 proc igniteEngine*(windowTitle: string): Engine = 507 proc igniteEngine*(windowTitle: string): Engine =
476 508
477 result.window = createWindow(windowTitle) 509 result.window = createWindow(windowTitle)
487 # create vulkan instance 519 # create vulkan instance
488 result.vulkan.instance = createVulkanInstance(VULKAN_VERSION) 520 result.vulkan.instance = createVulkanInstance(VULKAN_VERSION)
489 when DEBUG_LOG: 521 when DEBUG_LOG:
490 result.vulkan.debugMessenger = result.vulkan.instance.setupDebugLog() 522 result.vulkan.debugMessenger = result.vulkan.instance.setupDebugLog()
491 result.vulkan.surface = result.vulkan.instance.createVulkanSurface(result.window) 523 result.vulkan.surface = result.vulkan.instance.createVulkanSurface(result.window)
492 result.vulkan.device = result.vulkan.instance.setupVulkanDeviceAndQueues(result.vulkan.surface) 524 result.vulkan.device = result.vulkan.instance.setupVulkanDeviceAndQueues(
525 result.vulkan.surface)
493 526
494 # get basic frame information 527 # get basic frame information
495 result.vulkan.surfaceFormat = result.vulkan.device.physicalDevice.formats.getSuitableSurfaceFormat() 528 result.vulkan.surfaceFormat = result.vulkan.device.physicalDevice.formats.getSuitableSurfaceFormat()
496 result.vulkan.frameSize = result.window.getFrameDimension(result.vulkan.device.physicalDevice.device, result.vulkan.surface) 529 result.vulkan.frameSize = result.window.getFrameDimension(
530 result.vulkan.device.physicalDevice.device, result.vulkan.surface)
497 531
498 # setup swapchain and render pipeline 532 # setup swapchain and render pipeline
499 result.vulkan.swapchain = result.vulkan.device.device.setupSwapChain( 533 result.vulkan.swapchain = result.vulkan.device.device.setupSwapChain(
500 result.vulkan.device.physicalDevice, 534 result.vulkan.device.physicalDevice,
501 result.vulkan.surface, 535 result.vulkan.surface,
502 result.vulkan.frameSize, 536 result.vulkan.frameSize,
503 result.vulkan.surfaceFormat 537 result.vulkan.surfaceFormat
504 ) 538 )
505 result.vulkan.renderPass = result.vulkan.device.device.setupRenderPass(result.vulkan.surfaceFormat.format) 539 result.vulkan.renderPass = result.vulkan.device.device.setupRenderPass(
540 result.vulkan.surfaceFormat.format)
506 result.vulkan.framebuffers = result.vulkan.device.device.setupFramebuffers( 541 result.vulkan.framebuffers = result.vulkan.device.device.setupFramebuffers(
507 result.vulkan.swapchain, 542 result.vulkan.swapchain,
508 result.vulkan.renderPass, 543 result.vulkan.renderPass,
509 result.vulkan.frameSize 544 result.vulkan.frameSize
510 ) 545 )
511 ( 546 (
512 result.vulkan.device.commandPool, 547 result.vulkan.device.commandPool,
513 result.vulkan.device.commandBuffers, 548 result.vulkan.device.commandBuffers,
514 ) = result.vulkan.device.device.setupCommandBuffers(result.vulkan.device.graphicsQueueFamily) 549 ) = result.vulkan.device.device.setupCommandBuffers(
550 result.vulkan.device.graphicsQueueFamily)
515 551
516 ( 552 (
517 result.vulkan.imageAvailableSemaphores, 553 result.vulkan.imageAvailableSemaphores,
518 result.vulkan.renderFinishedSemaphores, 554 result.vulkan.renderFinishedSemaphores,
519 result.vulkan.inFlightFences, 555 result.vulkan.inFlightFences,
520 ) = result.vulkan.device.device.setupSyncPrimitives() 556 ) = result.vulkan.device.device.setupSyncPrimitives()
521 557
522 558
523 proc setupPipeline*[VertexType; UniformType; IndexType: uint16|uint32](engine: var Engine, scenedata: Thing, vertexShader, fragmentShader: static string): RenderPipeline[VertexType, UniformType] = 559 proc setupPipeline*[VertexType; UniformType; IndexType: uint16|uint32](
560 engine: var Engine, scenedata: Thing, vertexShader,
561 fragmentShader: static string): RenderPipeline[VertexType, UniformType] =
524 engine.currentscenedata = scenedata 562 engine.currentscenedata = scenedata
525 result = initRenderPipeline[VertexType, UniformType]( 563 result = initRenderPipeline[VertexType, UniformType](
526 engine.vulkan.device.device, 564 engine.vulkan.device.device,
527 engine.vulkan.frameSize, 565 engine.vulkan.frameSize,
528 engine.vulkan.renderPass, 566 engine.vulkan.renderPass,
530 fragmentShader, 568 fragmentShader,
531 ) 569 )
532 570
533 # vertex buffers 571 # vertex buffers
534 for mesh in allPartsOfType[Mesh[VertexType]](engine.currentscenedata): 572 for mesh in allPartsOfType[Mesh[VertexType]](engine.currentscenedata):
535 result.vertexBuffers.add createVertexBuffers(mesh, result.device, engine.vulkan.device.physicalDevice.device, engine.vulkan.device.commandPool, engine.vulkan.device.graphicsQueue) 573 result.vertexBuffers.add createVertexBuffers(mesh, result.device,
574 engine.vulkan.device.physicalDevice.device,
575 engine.vulkan.device.commandPool, engine.vulkan.device.graphicsQueue)
536 576
537 # vertex buffers with indexes 577 # vertex buffers with indexes
538 when not (IndexType is void): 578 when not (IndexType is void):
539 for mesh in allPartsOfType[IndexedMesh[VertexType, IndexType]](engine.currentscenedata): 579 for mesh in allPartsOfType[IndexedMesh[VertexType, IndexType]](
540 result.indexedVertexBuffers.add createIndexedVertexBuffers(mesh, result.device, engine.vulkan.device.physicalDevice.device, engine.vulkan.device.commandPool, engine.vulkan.device.graphicsQueue) 580 engine.currentscenedata):
581 result.indexedVertexBuffers.add createIndexedVertexBuffers(mesh,
582 result.device, engine.vulkan.device.physicalDevice.device,
583 engine.vulkan.device.commandPool, engine.vulkan.device.graphicsQueue)
541 584
542 # uniform buffers 585 # uniform buffers
543 when not (UniformType is void): 586 when not (UniformType is void):
544 result.uniformBuffers = createUniformBuffers[MAX_FRAMES_IN_FLIGHT, UniformType]( 587 result.uniformBuffers = createUniformBuffers[MAX_FRAMES_IN_FLIGHT,
588 UniformType](
545 result.device, 589 result.device,
546 engine.vulkan.device.physicalDevice.device 590 engine.vulkan.device.physicalDevice.device
547 ) 591 )
548 592
549 var 593 var
555 sType: VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, 599 sType: VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
556 poolSizeCount: 1, 600 poolSizeCount: 1,
557 pPoolSizes: addr(poolSize), 601 pPoolSizes: addr(poolSize),
558 maxSets: uint32(MAX_FRAMES_IN_FLIGHT), 602 maxSets: uint32(MAX_FRAMES_IN_FLIGHT),
559 ) 603 )
560 checkVkResult vkCreateDescriptorPool(result.device, addr(poolInfo), nil, addr(result.descriptorPool)) 604 checkVkResult vkCreateDescriptorPool(result.device, addr(poolInfo), nil, addr(
605 result.descriptorPool))
561 606
562 var layouts: array[MAX_FRAMES_IN_FLIGHT, VkDescriptorSetLayout] 607 var layouts: array[MAX_FRAMES_IN_FLIGHT, VkDescriptorSetLayout]
563 for i in 0 ..< MAX_FRAMES_IN_FLIGHT: 608 for i in 0 ..< MAX_FRAMES_IN_FLIGHT:
564 layouts[i] = result.descriptorSetLayout 609 layouts[i] = result.descriptorSetLayout
565 var allocInfo = VkDescriptorSetAllocateInfo( 610 var allocInfo = VkDescriptorSetAllocateInfo(
567 descriptorPool: result.descriptorPool, 612 descriptorPool: result.descriptorPool,
568 descriptorSetCount: uint32(MAX_FRAMES_IN_FLIGHT), 613 descriptorSetCount: uint32(MAX_FRAMES_IN_FLIGHT),
569 pSetLayouts: addr(layouts[0]), 614 pSetLayouts: addr(layouts[0]),
570 ) 615 )
571 616
572 checkVkResult vkAllocateDescriptorSets(result.device, addr(allocInfo), addr(result.descriptors[0])) 617 checkVkResult vkAllocateDescriptorSets(result.device, addr(allocInfo), addr(
618 result.descriptors[0]))
573 619
574 when not (UniformType is void): 620 when not (UniformType is void):
575 var bufferInfos: array[MAX_FRAMES_IN_FLIGHT, array[1, VkDescriptorBufferInfo]] # because we use only one Uniform atm 621 var bufferInfos: array[MAX_FRAMES_IN_FLIGHT, array[1,
622 VkDescriptorBufferInfo]] # because we use only one Uniform atm
576 for i in 0 ..< MAX_FRAMES_IN_FLIGHT: 623 for i in 0 ..< MAX_FRAMES_IN_FLIGHT:
577 bufferInfos[i][0] = VkDescriptorBufferInfo( 624 bufferInfos[i][0] = VkDescriptorBufferInfo(
578 buffer: result.uniformBuffers[i].vkBuffer, 625 buffer: result.uniformBuffers[i].vkBuffer,
579 offset: VkDeviceSize(0), 626 offset: VkDeviceSize(0),
580 range: VkDeviceSize(sizeof(UniformType)), 627 range: VkDeviceSize(sizeof(UniformType)),
584 dstSet: result.descriptors[i], 631 dstSet: result.descriptors[i],
585 dstBinding: 0, 632 dstBinding: 0,
586 dstArrayElement: 0, 633 dstArrayElement: 0,
587 descriptorType: VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 634 descriptorType: VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
588 descriptorCount: 1, 635 descriptorCount: 1,
589 pBufferInfo: cast[ptr ptr VkDescriptorBufferInfo](addr(bufferInfos[i][0])), 636 pBufferInfo: cast[ptr ptr VkDescriptorBufferInfo](addr(bufferInfos[i][
637 0])),
590 ) 638 )
591 vkUpdateDescriptorSets(result.device, 1, addr(descriptorWrite), 0, nil) 639 vkUpdateDescriptorSets(result.device, 1, addr(descriptorWrite), 0, nil)
592 640
593 proc updateBufferData*[T](device: Device, buffer: Buffer, data: var T) = 641 proc updateBufferData*[T](device: Device, buffer: Buffer, data: var T) =
594 when stripGenericParams(T) is seq: # seq needs special treatment for automated data uploading 642 when stripGenericParams(T) is seq: # seq needs special treatment for automated data uploading
599 let size = sizeof(data) 647 let size = sizeof(data)
600 let dataptr = addr(data) 648 let dataptr = addr(data)
601 if not (HostVisible in buffer.memoryProperties): 649 if not (HostVisible in buffer.memoryProperties):
602 if not (TransferDst in buffer.bufferTypes): 650 if not (TransferDst in buffer.bufferTypes):
603 raise newException(Exception, "Buffer cannot be updated") 651 raise newException(Exception, "Buffer cannot be updated")
604 var stagingBuffer = device.device.InitBuffer(device.physicalDevice.device, uint64(size), {TransferSrc}, {HostVisible, HostCoherent}) 652 var stagingBuffer = device.device.InitBuffer(device.physicalDevice.device,
653 uint64(size), {TransferSrc}, {HostVisible, HostCoherent})
605 copyMem(stagingBuffer.data, dataptr, size) 654 copyMem(stagingBuffer.data, dataptr, size)
606 transferBuffer(device.commandPool, device.graphicsQueue, stagingBuffer, buffer, uint64(size)) 655 transferBuffer(device.commandPool, device.graphicsQueue, stagingBuffer,
656 buffer, uint64(size))
607 stagingBuffer.trash() 657 stagingBuffer.trash()
608 else: 658 else:
609 copyMem(buffer.data, dataptr, size) 659 copyMem(buffer.data, dataptr, size)
610 660
611 proc updateVertexData*[T: VertexAttribute](device: Device, vertexAttribute: var T) = 661 proc updateVertexData*[T: VertexAttribute](device: Device,
662 vertexAttribute: var T) =
612 device.updateBufferData(vertexAttribute.buffer, vertexAttribute.data) 663 device.updateBufferData(vertexAttribute.buffer, vertexAttribute.data)
613 664
614 proc updateUniformData*[VertexType, Uniforms](device: Device, pipeline: RenderPipeline[VertexType, Uniforms], data: var Uniforms) = 665 proc updateUniformData*[VertexType, Uniforms](device: Device,
666 pipeline: RenderPipeline[VertexType, Uniforms], data: var Uniforms) =
615 for buffer in pipeline.uniformBuffers: 667 for buffer in pipeline.uniformBuffers:
616 device.updateBufferData(buffer, data) 668 device.updateBufferData(buffer, data)
617 669
618 670
619 proc runPipeline[VertexType; Uniforms](commandBuffer: VkCommandBuffer, pipeline: var RenderPipeline[VertexType, Uniforms], currentFrame: int) = 671 proc runPipeline[VertexType; Uniforms](commandBuffer: VkCommandBuffer,
620 vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.pipeline) 672 pipeline: var RenderPipeline[VertexType, Uniforms], currentFrame: int) =
621 673 vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
622 vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.layout, 0, 1, addr(pipeline.descriptors[currentFrame]), 0, nil) 674 pipeline.pipeline)
675
676 vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
677 pipeline.layout, 0, 1, addr(pipeline.descriptors[currentFrame]), 0, nil)
623 for (vertexBufferSet, vertexCount) in pipeline.vertexBuffers: 678 for (vertexBufferSet, vertexCount) in pipeline.vertexBuffers:
624 var 679 var
625 vertexBuffers: seq[VkBuffer] 680 vertexBuffers: seq[VkBuffer]
626 offsets: seq[VkDeviceSize] 681 offsets: seq[VkDeviceSize]
627 for buffer in vertexBufferSet: 682 for buffer in vertexBufferSet:
628 vertexBuffers.add buffer.vkBuffer 683 vertexBuffers.add buffer.vkBuffer
629 offsets.add VkDeviceSize(0) 684 offsets.add VkDeviceSize(0)
630 685
631 vkCmdBindVertexBuffers(commandBuffer, firstBinding=0'u32, bindingCount=uint32(vertexBuffers.len), pBuffers=addr(vertexBuffers[0]), pOffsets=addr(offsets[0])) 686 vkCmdBindVertexBuffers(commandBuffer, firstBinding = 0'u32,
632 vkCmdDraw(commandBuffer, vertexCount=vertexCount, instanceCount=1'u32, firstVertex=0'u32, firstInstance=0'u32) 687 bindingCount = uint32(vertexBuffers.len), pBuffers = addr(vertexBuffers[
633 688 0]), pOffsets = addr(offsets[0]))
634 for (vertexBufferSet, indexBuffer, indicesCount, indexType) in pipeline.indexedVertexBuffers: 689 vkCmdDraw(commandBuffer, vertexCount = vertexCount, instanceCount = 1'u32,
690 firstVertex = 0'u32, firstInstance = 0'u32)
691
692 for (vertexBufferSet, indexBuffer, indicesCount, indexType) in
693 pipeline.indexedVertexBuffers:
635 var 694 var
636 vertexBuffers: seq[VkBuffer] 695 vertexBuffers: seq[VkBuffer]
637 offsets: seq[VkDeviceSize] 696 offsets: seq[VkDeviceSize]
638 for buffer in vertexBufferSet: 697 for buffer in vertexBufferSet:
639 vertexBuffers.add buffer.vkBuffer 698 vertexBuffers.add buffer.vkBuffer
640 offsets.add VkDeviceSize(0) 699 offsets.add VkDeviceSize(0)
641 700
642 vkCmdBindVertexBuffers(commandBuffer, firstBinding=0'u32, bindingCount=uint32(vertexBuffers.len), pBuffers=addr(vertexBuffers[0]), pOffsets=addr(offsets[0])) 701 vkCmdBindVertexBuffers(commandBuffer, firstBinding = 0'u32,
702 bindingCount = uint32(vertexBuffers.len), pBuffers = addr(vertexBuffers[
703 0]), pOffsets = addr(offsets[0]))
643 vkCmdBindIndexBuffer(commandBuffer, indexBuffer.vkBuffer, VkDeviceSize(0), indexType) 704 vkCmdBindIndexBuffer(commandBuffer, indexBuffer.vkBuffer, VkDeviceSize(0), indexType)
644 vkCmdDrawIndexed(commandBuffer, indicesCount, 1, 0, 0, 0) 705 vkCmdDrawIndexed(commandBuffer, indicesCount, 1, 0, 0, 0)
645 706
646 proc recordCommandBuffer(renderPass: VkRenderPass, pipeline: var RenderPipeline, commandBuffer: VkCommandBuffer, framebuffer: VkFramebuffer, frameSize: TVec2[uint32], currentFrame: int) = 707 proc recordCommandBuffer(renderPass: VkRenderPass, pipeline: var RenderPipeline,
708 commandBuffer: VkCommandBuffer, framebuffer: VkFramebuffer,
709 frameSize: TVec2[uint32], currentFrame: int) =
647 var 710 var
648 beginInfo = VkCommandBufferBeginInfo( 711 beginInfo = VkCommandBufferBeginInfo(
649 sType: VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, 712 sType: VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
650 pInheritanceInfo: nil, 713 pInheritanceInfo: nil,
651 ) 714 )
652 clearColor = VkClearValue(color: VkClearColorValue(float32: [0.2'f, 0.2'f, 0.2'f, 1.0'f])) 715 clearColor = VkClearValue(color: VkClearColorValue(float32: [0.2'f, 0.2'f,
716 0.2'f, 1.0'f]))
653 renderPassInfo = VkRenderPassBeginInfo( 717 renderPassInfo = VkRenderPassBeginInfo(
654 sType: VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, 718 sType: VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
655 renderPass: renderPass, 719 renderPass: renderPass,
656 framebuffer: framebuffer, 720 framebuffer: framebuffer,
657 renderArea: VkRect2D( 721 renderArea: VkRect2D(
662 pClearValues: addr(clearColor), 726 pClearValues: addr(clearColor),
663 ) 727 )
664 viewport = VkViewport( 728 viewport = VkViewport(
665 x: 0.0, 729 x: 0.0,
666 y: 0.0, 730 y: 0.0,
667 width: (float) frameSize.x, 731 width: (float)frameSize.x,
668 height: (float) frameSize.y, 732 height: (float)frameSize.y,
669 minDepth: 0.0, 733 minDepth: 0.0,
670 maxDepth: 1.0, 734 maxDepth: 1.0,
671 ) 735 )
672 scissor = VkRect2D( 736 scissor = VkRect2D(
673 offset: VkOffset2D(x: 0, y: 0), 737 offset: VkOffset2D(x: 0, y: 0),
674 extent: VkExtent2D(width: frameSize.x, height: frameSize.y) 738 extent: VkExtent2D(width: frameSize.x, height: frameSize.y)
675 ) 739 )
676 checkVkResult vkBeginCommandBuffer(commandBuffer, addr(beginInfo)) 740 checkVkResult vkBeginCommandBuffer(commandBuffer, addr(beginInfo))
677 block: 741 block:
678 vkCmdBeginRenderPass(commandBuffer, addr(renderPassInfo), VK_SUBPASS_CONTENTS_INLINE) 742 vkCmdBeginRenderPass(commandBuffer, addr(renderPassInfo), VK_SUBPASS_CONTENTS_INLINE)
679 vkCmdSetViewport(commandBuffer, firstViewport=0, viewportCount=1, addr(viewport)) 743 vkCmdSetViewport(commandBuffer, firstViewport = 0, viewportCount = 1, addr(viewport))
680 vkCmdSetScissor(commandBuffer, firstScissor=0, scissorCount=1, addr(scissor)) 744 vkCmdSetScissor(commandBuffer, firstScissor = 0, scissorCount = 1, addr(scissor))
681 runPipeline(commandBuffer, pipeline, currentFrame) 745 runPipeline(commandBuffer, pipeline, currentFrame)
682 vkCmdEndRenderPass(commandBuffer) 746 vkCmdEndRenderPass(commandBuffer)
683 checkVkResult vkEndCommandBuffer(commandBuffer) 747 checkVkResult vkEndCommandBuffer(commandBuffer)
684 748
685 proc drawFrame(window: NativeWindow, vulkan: var Vulkan, currentFrame: int, resized: bool, pipeline: var RenderPipeline) = 749 proc drawFrame(window: NativeWindow, vulkan: var Vulkan, currentFrame: int,
686 checkVkResult vkWaitForFences(vulkan.device.device, 1, addr(vulkan.inFlightFences[currentFrame]), VK_TRUE, high(uint64)) 750 resized: bool, pipeline: var RenderPipeline) =
751 checkVkResult vkWaitForFences(vulkan.device.device, 1, addr(
752 vulkan.inFlightFences[currentFrame]), VK_TRUE, high(uint64))
687 var bufferImageIndex: uint32 753 var bufferImageIndex: uint32
688 let nextImageResult = vkAcquireNextImageKHR( 754 let nextImageResult = vkAcquireNextImageKHR(
689 vulkan.device.device, 755 vulkan.device.device,
690 vulkan.swapchain.swapchain, 756 vulkan.swapchain.swapchain,
691 high(uint64), 757 high(uint64),
692 vulkan.imageAvailableSemaphores[currentFrame], 758 vulkan.imageAvailableSemaphores[currentFrame],
693 VkFence(0), 759 VkFence(0),
694 addr(bufferImageIndex) 760 addr(bufferImageIndex)
695 ) 761 )
696 if nextImageResult == VK_ERROR_OUT_OF_DATE_KHR: 762 if nextImageResult == VK_ERROR_OUT_OF_DATE_KHR:
697 vulkan.frameSize = window.getFrameDimension(vulkan.device.physicalDevice.device, vulkan.surface) 763 vulkan.frameSize = window.getFrameDimension(
764 vulkan.device.physicalDevice.device, vulkan.surface)
698 (vulkan.swapchain, vulkan.framebuffers) = vulkan.recreateSwapchain() 765 (vulkan.swapchain, vulkan.framebuffers) = vulkan.recreateSwapchain()
699 elif not (nextImageResult in [VK_SUCCESS, VK_SUBOPTIMAL_KHR]): 766 elif not (nextImageResult in [VK_SUCCESS, VK_SUBOPTIMAL_KHR]):
700 raise newException(Exception, "Vulkan error: vkAcquireNextImageKHR returned " & $nextImageResult) 767 raise newException(Exception, "Vulkan error: vkAcquireNextImageKHR returned " &
701 checkVkResult vkResetFences(vulkan.device.device, 1, addr(vulkan.inFlightFences[currentFrame])) 768 $nextImageResult)
702 769 checkVkResult vkResetFences(vulkan.device.device, 1, addr(
703 checkVkResult vkResetCommandBuffer(vulkan.device.commandBuffers[currentFrame], VkCommandBufferResetFlags(0)) 770 vulkan.inFlightFences[currentFrame]))
704 vulkan.renderPass.recordCommandBuffer(pipeline, vulkan.device.commandBuffers[currentFrame], vulkan.framebuffers[bufferImageIndex], vulkan.frameSize, currentFrame) 771
772 checkVkResult vkResetCommandBuffer(vulkan.device.commandBuffers[currentFrame],
773 VkCommandBufferResetFlags(0))
774 vulkan.renderPass.recordCommandBuffer(pipeline, vulkan.device.commandBuffers[
775 currentFrame], vulkan.framebuffers[bufferImageIndex], vulkan.frameSize, currentFrame)
705 var 776 var
706 waitSemaphores = [vulkan.imageAvailableSemaphores[currentFrame]] 777 waitSemaphores = [vulkan.imageAvailableSemaphores[currentFrame]]
707 waitStages = [VkPipelineStageFlags(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT)] 778 waitStages = [VkPipelineStageFlags(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT)]
708 signalSemaphores = [vulkan.renderFinishedSemaphores[currentFrame]] 779 signalSemaphores = [vulkan.renderFinishedSemaphores[currentFrame]]
709 submitInfo = VkSubmitInfo( 780 submitInfo = VkSubmitInfo(
714 commandBufferCount: 1, 785 commandBufferCount: 1,
715 pCommandBuffers: addr(vulkan.device.commandBuffers[currentFrame]), 786 pCommandBuffers: addr(vulkan.device.commandBuffers[currentFrame]),
716 signalSemaphoreCount: 1, 787 signalSemaphoreCount: 1,
717 pSignalSemaphores: addr(signalSemaphores[0]), 788 pSignalSemaphores: addr(signalSemaphores[0]),
718 ) 789 )
719 checkVkResult vkQueueSubmit(vulkan.device.graphicsQueue, 1, addr(submitInfo), vulkan.inFlightFences[currentFrame]) 790 checkVkResult vkQueueSubmit(vulkan.device.graphicsQueue, 1, addr(submitInfo),
791 vulkan.inFlightFences[currentFrame])
720 792
721 var presentInfo = VkPresentInfoKHR( 793 var presentInfo = VkPresentInfoKHR(
722 sType: VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, 794 sType: VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
723 waitSemaphoreCount: 1, 795 waitSemaphoreCount: 1,
724 pWaitSemaphores: addr(signalSemaphores[0]), 796 pWaitSemaphores: addr(signalSemaphores[0]),
727 pImageIndices: addr(bufferImageIndex), 799 pImageIndices: addr(bufferImageIndex),
728 pResults: nil, 800 pResults: nil,
729 ) 801 )
730 let presentResult = vkQueuePresentKHR(vulkan.device.presentationQueue, addr(presentInfo)) 802 let presentResult = vkQueuePresentKHR(vulkan.device.presentationQueue, addr(presentInfo))
731 803
732 if presentResult == VK_ERROR_OUT_OF_DATE_KHR or presentResult == VK_SUBOPTIMAL_KHR or resized: 804 if presentResult == VK_ERROR_OUT_OF_DATE_KHR or presentResult ==
733 vulkan.frameSize = window.getFrameDimension(vulkan.device.physicalDevice.device, vulkan.surface) 805 VK_SUBOPTIMAL_KHR or resized:
806 vulkan.frameSize = window.getFrameDimension(
807 vulkan.device.physicalDevice.device, vulkan.surface)
734 (vulkan.swapchain, vulkan.framebuffers) = vulkan.recreateSwapchain() 808 (vulkan.swapchain, vulkan.framebuffers) = vulkan.recreateSwapchain()
735 809
736 810
737 proc run*(engine: var Engine, pipeline: var RenderPipeline, globalUpdate: proc(engine: var Engine, dt: float32)) = 811 proc run*(engine: var Engine, pipeline: var RenderPipeline, globalUpdate: proc(
812 engine: var Engine, dt: float32)) =
738 var 813 var
739 currentFrame = 0 814 currentFrame = 0
740 resized = false 815 resized = false
741 lastUpdate = getTime() 816 lastUpdate = getTime()
742 817
805 for buffer in pipeline.uniformBuffers.mitems: 880 for buffer in pipeline.uniformBuffers.mitems:
806 buffer.trash() 881 buffer.trash()
807 882
808 proc trash*(engine: var Engine) = 883 proc trash*(engine: var Engine) =
809 checkVkResult vkDeviceWaitIdle(engine.vulkan.device.device) 884 checkVkResult vkDeviceWaitIdle(engine.vulkan.device.device)
810 engine.vulkan.device.device.trash(engine.vulkan.swapchain, engine.vulkan.framebuffers) 885 engine.vulkan.device.device.trash(engine.vulkan.swapchain,
886 engine.vulkan.framebuffers)
811 887
812 for i in 0 ..< MAX_FRAMES_IN_FLIGHT: 888 for i in 0 ..< MAX_FRAMES_IN_FLIGHT:
813 engine.vulkan.device.device.vkDestroySemaphore(engine.vulkan.imageAvailableSemaphores[i], nil) 889 engine.vulkan.device.device.vkDestroySemaphore(
814 engine.vulkan.device.device.vkDestroySemaphore(engine.vulkan.renderFinishedSemaphores[i], nil) 890 engine.vulkan.imageAvailableSemaphores[i], nil)
891 engine.vulkan.device.device.vkDestroySemaphore(
892 engine.vulkan.renderFinishedSemaphores[i], nil)
815 engine.vulkan.device.device.vkDestroyFence(engine.vulkan.inFlightFences[i], nil) 893 engine.vulkan.device.device.vkDestroyFence(engine.vulkan.inFlightFences[i], nil)
816 894
817 engine.vulkan.device.device.vkDestroyRenderPass(engine.vulkan.renderPass, nil) 895 engine.vulkan.device.device.vkDestroyRenderPass(engine.vulkan.renderPass, nil)
818 engine.vulkan.device.device.vkDestroyCommandPool(engine.vulkan.device.commandPool, nil) 896 engine.vulkan.device.device.vkDestroyCommandPool(
897 engine.vulkan.device.commandPool, nil)
819 898
820 engine.vulkan.instance.vkDestroySurfaceKHR(engine.vulkan.surface, nil) 899 engine.vulkan.instance.vkDestroySurfaceKHR(engine.vulkan.surface, nil)
821 engine.vulkan.device.device.vkDestroyDevice(nil) 900 engine.vulkan.device.device.vkDestroyDevice(nil)
822 when DEBUG_LOG: 901 when DEBUG_LOG:
823 engine.vulkan.instance.vkDestroyDebugUtilsMessengerEXT(engine.vulkan.debugMessenger, nil) 902 engine.vulkan.instance.vkDestroyDebugUtilsMessengerEXT(
903 engine.vulkan.debugMessenger, nil)
824 engine.window.trash() 904 engine.window.trash()
825 engine.vulkan.instance.vkDestroyInstance(nil) # needs to happen after window is trashed as the driver might have a hook registered for the window destruction 905 engine.vulkan.instance.vkDestroyInstance(
906 nil) # needs to happen after window is trashed as the driver might have a hook registered for the window destruction