Mercurial > games > semicongine
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 |
