Mercurial > games > semicongine
comparison src/zamikongine/engine.nim @ 493:680c4b8ca28a
add: working implementation of uniforms
| author | Sam <sam@basx.dev> |
|---|---|
| date | Sat, 14 Jan 2023 23:34:50 +0700 |
| parents | 54a1f8ee208e |
| children | 0c18638c7217 |
comparison
equal
deleted
inserted
replaced
| 492:d63d980fa3bb | 493:680c4b8ca28a |
|---|---|
| 22 var logger = newConsoleLogger() | 22 var logger = newConsoleLogger() |
| 23 addHandler(logger) | 23 addHandler(logger) |
| 24 | 24 |
| 25 | 25 |
| 26 const VULKAN_VERSION = VK_MAKE_API_VERSION(0'u32, 1'u32, 2'u32, 0'u32) | 26 const VULKAN_VERSION = VK_MAKE_API_VERSION(0'u32, 1'u32, 2'u32, 0'u32) |
| 27 const ENGINE_NAME = "zamkongine" | |
| 28 const ENGINE_VERSION = "0.1" | |
| 29 const BUILD_VERSION = ENGINE_VERSION & '-' & gorge("git log -1 --format=format:'%H'") | |
| 30 echo "Engine: " & ENGINE_NAME & " " & BUILD_VERSION | |
| 27 | 31 |
| 28 type | 32 type |
| 29 Device = object | 33 Device = object |
| 30 device: VkDevice | 34 device: VkDevice |
| 31 physicalDevice: PhysicalDevice | 35 physicalDevice: PhysicalDevice |
| 35 presentationQueue: VkQueue | 39 presentationQueue: VkQueue |
| 36 Swapchain = object | 40 Swapchain = object |
| 37 swapchain: VkSwapchainKHR | 41 swapchain: VkSwapchainKHR |
| 38 images: seq[VkImage] | 42 images: seq[VkImage] |
| 39 imageviews: seq[VkImageView] | 43 imageviews: seq[VkImageView] |
| 40 RenderPipeline[T] = object | 44 RenderPipeline*[VertexType, Uniforms] = object |
| 41 device*: VkDevice | 45 device*: VkDevice |
| 42 shaders*: seq[ShaderProgram[T]] | 46 shaders*: seq[ShaderProgram[VertexType, Uniforms]] |
| 43 layout*: VkPipelineLayout | 47 layout*: VkPipelineLayout |
| 44 pipeline*: VkPipeline | 48 pipeline*: VkPipeline |
| 45 uniformLayout*: VkDescriptorSetLayout | |
| 46 vertexBuffers*: seq[(seq[Buffer], uint32)] | 49 vertexBuffers*: seq[(seq[Buffer], uint32)] |
| 47 indexedVertexBuffers*: seq[(seq[Buffer], Buffer, uint32, VkIndexType)] | 50 indexedVertexBuffers*: seq[(seq[Buffer], Buffer, uint32, VkIndexType)] |
| 51 descriptorSetLayout*: VkDescriptorSetLayout | |
| 48 uniformBuffers*: array[MAX_FRAMES_IN_FLIGHT, Buffer] | 52 uniformBuffers*: array[MAX_FRAMES_IN_FLIGHT, Buffer] |
| 53 descriptorPool*: VkDescriptorPool | |
| 54 descriptors: array[MAX_FRAMES_IN_FLIGHT, VkDescriptorSet] | |
| 49 QueueFamily = object | 55 QueueFamily = object |
| 50 properties*: VkQueueFamilyProperties | 56 properties*: VkQueueFamilyProperties |
| 51 hasSurfaceSupport*: bool | 57 hasSurfaceSupport*: bool |
| 52 PhysicalDevice = object | 58 PhysicalDevice = object |
| 53 device*: VkPhysicalDevice | 59 device*: VkPhysicalDevice |
| 248 dependencyCount: 1, | 254 dependencyCount: 1, |
| 249 pDependencies: addr(dependency), | 255 pDependencies: addr(dependency), |
| 250 ) | 256 ) |
| 251 checkVkResult device.vkCreateRenderPass(addr(renderPassCreateInfo), nil, addr(result)) | 257 checkVkResult device.vkCreateRenderPass(addr(renderPassCreateInfo), nil, addr(result)) |
| 252 | 258 |
| 253 proc initRenderPipeline[VertextType, T](device: VkDevice, frameDimension: VkExtent2D, renderPass: VkRenderPass, vertexShader, fragmentShader: static string): RenderPipeline[T] = | 259 proc initRenderPipeline[VertexType, Uniforms](device: VkDevice, frameDimension: VkExtent2D, renderPass: VkRenderPass, vertexShader, fragmentShader: static string): RenderPipeline[VertexType, Uniforms] = |
| 254 # load shaders | 260 # load shaders |
| 255 result.device = device | 261 result.device = device |
| 256 result.shaders.add(initShaderProgram[T](device, VK_SHADER_STAGE_VERTEX_BIT, vertexShader)) | 262 result.shaders.add(initShaderProgram[VertexType, Uniforms](device, VK_SHADER_STAGE_VERTEX_BIT, vertexShader)) |
| 257 result.shaders.add(initShaderProgram[T](device, VK_SHADER_STAGE_FRAGMENT_BIT, fragmentShader)) | 263 result.shaders.add(initShaderProgram[VertexType, Uniforms](device, VK_SHADER_STAGE_FRAGMENT_BIT, fragmentShader)) |
| 258 | 264 |
| 259 var | 265 var |
| 260 # define which parts can be dynamic (pipeline is fixed after setup) | 266 # define which parts can be dynamic (pipeline is fixed after setup) |
| 261 dynamicStates = [VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR] | 267 dynamicStates = [VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR] |
| 262 dynamicState = VkPipelineDynamicStateCreateInfo( | 268 dynamicState = VkPipelineDynamicStateCreateInfo( |
| 263 sType: VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, | 269 sType: VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, |
| 264 dynamicStateCount: uint32(dynamicStates.len), | 270 dynamicStateCount: uint32(dynamicStates.len), |
| 265 pDynamicStates: addr(dynamicStates[0]), | 271 pDynamicStates: addr(dynamicStates[0]), |
| 266 ) | 272 ) |
| 267 vertexbindings = generateInputVertexBinding[VertextType]() | 273 vertexbindings = generateInputVertexBinding[VertexType]() |
| 268 attributebindings = generateInputAttributeBinding[VertextType]() | 274 attributebindings = generateInputAttributeBinding[VertexType]() |
| 269 | 275 |
| 270 # define input data format | 276 # define input data format |
| 271 vertexInputInfo = VkPipelineVertexInputStateCreateInfo( | 277 vertexInputInfo = VkPipelineVertexInputStateCreateInfo( |
| 272 sType: VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, | 278 sType: VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, |
| 273 vertexBindingDescriptionCount: uint32(vertexbindings.len), | 279 vertexBindingDescriptionCount: uint32(vertexbindings.len), |
| 334 attachmentCount: 1, | 340 attachmentCount: 1, |
| 335 pAttachments: addr(colorBlendAttachment), | 341 pAttachments: addr(colorBlendAttachment), |
| 336 blendConstants: [0.0'f, 0.0'f, 0.0'f, 0.0'f], | 342 blendConstants: [0.0'f, 0.0'f, 0.0'f, 0.0'f], |
| 337 ) | 343 ) |
| 338 | 344 |
| 339 result.uniformLayout = device.createUniformDescriptorLayout(VkShaderStageFlags(VK_SHADER_STAGE_VERTEX_BIT), 0) | 345 result.descriptorSetLayout = device.createUniformDescriptorLayout(VkShaderStageFlags(VK_SHADER_STAGE_VERTEX_BIT), 0) |
| 340 var | 346 var |
| 341 # "globals" that go into the shader, uniforms etc. | 347 # "globals" that go into the shader, uniforms etc. |
| 342 pipelineLayoutInfo = VkPipelineLayoutCreateInfo( | 348 pipelineLayoutInfo = VkPipelineLayoutCreateInfo( |
| 343 sType: VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, | 349 sType: VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, |
| 344 setLayoutCount: 1, | 350 setLayoutCount: 1, |
| 345 pSetLayouts: addr(result.uniformLayout), | 351 pSetLayouts: addr(result.descriptorSetLayout), |
| 346 pushConstantRangeCount: 0, | 352 pushConstantRangeCount: 0, |
| 347 pPushConstantRanges: nil, | 353 pPushConstantRanges: nil, |
| 348 ) | 354 ) |
| 349 checkVkResult vkCreatePipelineLayout(device, addr(pipelineLayoutInfo), nil, addr(result.layout)) | 355 checkVkResult vkCreatePipelineLayout(device, addr(pipelineLayoutInfo), nil, addr(result.layout)) |
| 350 | 356 |
| 493 result.vulkan.renderFinishedSemaphores, | 499 result.vulkan.renderFinishedSemaphores, |
| 494 result.vulkan.inFlightFences, | 500 result.vulkan.inFlightFences, |
| 495 ) = result.vulkan.device.device.setupSyncPrimitives() | 501 ) = result.vulkan.device.device.setupSyncPrimitives() |
| 496 | 502 |
| 497 | 503 |
| 498 proc setupPipeline*[VertexType, UniformType, T: object, IndexType: uint16|uint32](engine: var Engine, scenedata: ref Thing, vertexShader, fragmentShader: static string): RenderPipeline[T] = | 504 proc setupPipeline*[VertexType, UniformType: object, IndexType: uint16|uint32](engine: var Engine, scenedata: ref Thing, vertexShader, fragmentShader: static string): RenderPipeline[VertexType, UniformType] = |
| 499 engine.currentscenedata = scenedata | 505 engine.currentscenedata = scenedata |
| 500 result = initRenderPipeline[VertexType, T]( | 506 result = initRenderPipeline[VertexType, UniformType]( |
| 501 engine.vulkan.device.device, | 507 engine.vulkan.device.device, |
| 502 engine.vulkan.frameDimension, | 508 engine.vulkan.frameDimension, |
| 503 engine.vulkan.renderPass, | 509 engine.vulkan.renderPass, |
| 504 vertexShader, | 510 vertexShader, |
| 505 fragmentShader, | 511 fragmentShader, |
| 508 var allmeshes: seq[Mesh[VertexType]] | 514 var allmeshes: seq[Mesh[VertexType]] |
| 509 for mesh in partsOfType[ref Mesh[VertexType]](engine.currentscenedata): | 515 for mesh in partsOfType[ref Mesh[VertexType]](engine.currentscenedata): |
| 510 allmeshes.add(mesh[]) | 516 allmeshes.add(mesh[]) |
| 511 if allmeshes.len > 0: | 517 if allmeshes.len > 0: |
| 512 var ubermesh = createUberMesh(allmeshes) | 518 var ubermesh = createUberMesh(allmeshes) |
| 513 result.vertexBuffers.add createVertexBuffers(ubermesh, engine.vulkan.device.device, engine.vulkan.device.physicalDevice.device, engine.vulkan.commandPool, engine.vulkan.device.graphicsQueue) | 519 result.vertexBuffers.add createVertexBuffers(ubermesh, result.device, engine.vulkan.device.physicalDevice.device, engine.vulkan.commandPool, engine.vulkan.device.graphicsQueue) |
| 514 | 520 |
| 515 # vertex buffers with indexes | 521 # vertex buffers with indexes |
| 516 var allindexedmeshes: seq[IndexedMesh[VertexType, IndexType]] | 522 var allindexedmeshes: seq[IndexedMesh[VertexType, IndexType]] |
| 517 for mesh in partsOfType[ref IndexedMesh[VertexType, IndexType]](engine.currentscenedata): | 523 for mesh in partsOfType[ref IndexedMesh[VertexType, IndexType]](engine.currentscenedata): |
| 518 allindexedmeshes.add(mesh[]) | 524 allindexedmeshes.add(mesh[]) |
| 519 if allindexedmeshes.len > 0: | 525 if allindexedmeshes.len > 0: |
| 520 var indexedubermesh = createUberMesh(allindexedmeshes) | 526 var indexedubermesh = createUberMesh(allindexedmeshes) |
| 521 result.indexedVertexBuffers.add createIndexedVertexBuffers(indexedubermesh, engine.vulkan.device.device, engine.vulkan.device.physicalDevice.device, engine.vulkan.commandPool, engine.vulkan.device.graphicsQueue) | 527 result.indexedVertexBuffers.add createIndexedVertexBuffers(indexedubermesh, result.device, engine.vulkan.device.physicalDevice.device, engine.vulkan.commandPool, engine.vulkan.device.graphicsQueue) |
| 522 | 528 |
| 523 # uniform buffers | 529 # uniform buffers |
| 524 result.uniformBuffers = createUniformBuffers[MAX_FRAMES_IN_FLIGHT, UniformType]( | 530 result.uniformBuffers = createUniformBuffers[MAX_FRAMES_IN_FLIGHT, UniformType]( |
| 525 engine.vulkan.device.device, | 531 result.device, |
| 526 engine.vulkan.device.physicalDevice.device | 532 engine.vulkan.device.physicalDevice.device |
| 527 ) | 533 ) |
| 528 | 534 |
| 529 | 535 var |
| 530 proc runPipeline(commandBuffer: VkCommandBuffer, pipeline: RenderPipeline) = | 536 poolSize = VkDescriptorPoolSize( |
| 537 `type`: VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, | |
| 538 descriptorCount: uint32(MAX_FRAMES_IN_FLIGHT), | |
| 539 ) | |
| 540 poolInfo = VkDescriptorPoolCreateInfo( | |
| 541 sType: VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, | |
| 542 poolSizeCount: 1, | |
| 543 pPoolSizes: addr(poolSize), | |
| 544 maxSets: uint32(MAX_FRAMES_IN_FLIGHT), | |
| 545 ) | |
| 546 checkVkResult vkCreateDescriptorPool(result.device, addr(poolInfo), nil, addr(result.descriptorPool)) | |
| 547 | |
| 548 var layouts: array[MAX_FRAMES_IN_FLIGHT, VkDescriptorSetLayout] | |
| 549 for i in 0 ..< MAX_FRAMES_IN_FLIGHT: | |
| 550 layouts[i] = result.descriptorSetLayout | |
| 551 var allocInfo = VkDescriptorSetAllocateInfo( | |
| 552 sType: VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, | |
| 553 descriptorPool: result.descriptorPool, | |
| 554 descriptorSetCount: uint32(MAX_FRAMES_IN_FLIGHT), | |
| 555 pSetLayouts: addr(layouts[0]), | |
| 556 ) | |
| 557 | |
| 558 checkVkResult vkAllocateDescriptorSets(result.device, addr(allocInfo), addr(result.descriptors[0])) | |
| 559 | |
| 560 var bufferInfos: array[MAX_FRAMES_IN_FLIGHT, array[1, VkDescriptorBufferInfo]] # because we use only one Uniform atm | |
| 561 for i in 0 ..< MAX_FRAMES_IN_FLIGHT: | |
| 562 bufferInfos[i][0] = VkDescriptorBufferInfo( | |
| 563 buffer: result.uniformBuffers[i].vkBuffer, | |
| 564 offset: VkDeviceSize(0), | |
| 565 range: VkDeviceSize(sizeof(UniformType)), | |
| 566 ) | |
| 567 var descriptorWrite = VkWriteDescriptorSet( | |
| 568 sType: VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, | |
| 569 dstSet: result.descriptors[i], | |
| 570 dstBinding: 0, | |
| 571 dstArrayElement: 0, | |
| 572 descriptorType: VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, | |
| 573 descriptorCount: 1, | |
| 574 pBufferInfo: cast[ptr ptr VkDescriptorBufferInfo](addr(bufferInfos[i][0])), | |
| 575 ) | |
| 576 vkUpdateDescriptorSets(result.device, 1, addr(descriptorWrite), 0, nil) | |
| 577 | |
| 578 | |
| 579 proc runPipeline(commandBuffer: VkCommandBuffer, pipeline: var RenderPipeline, currentFrame: int) = | |
| 531 vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.pipeline) | 580 vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.pipeline) |
| 532 | 581 |
| 582 vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.layout, 0, 1, addr(pipeline.descriptors[currentFrame]), 0, nil) | |
| 533 for (vertexBufferSet, vertexCount) in pipeline.vertexBuffers: | 583 for (vertexBufferSet, vertexCount) in pipeline.vertexBuffers: |
| 534 var | 584 var |
| 535 vertexBuffers: seq[VkBuffer] | 585 vertexBuffers: seq[VkBuffer] |
| 536 offsets: seq[VkDeviceSize] | 586 offsets: seq[VkDeviceSize] |
| 537 for buffer in vertexBufferSet: | 587 for buffer in vertexBufferSet: |
| 548 for buffer in vertexBufferSet: | 598 for buffer in vertexBufferSet: |
| 549 vertexBuffers.add buffer.vkBuffer | 599 vertexBuffers.add buffer.vkBuffer |
| 550 offsets.add VkDeviceSize(0) | 600 offsets.add VkDeviceSize(0) |
| 551 | 601 |
| 552 vkCmdBindVertexBuffers(commandBuffer, firstBinding=0'u32, bindingCount=2'u32, pBuffers=addr(vertexBuffers[0]), pOffsets=addr(offsets[0])) | 602 vkCmdBindVertexBuffers(commandBuffer, firstBinding=0'u32, bindingCount=2'u32, pBuffers=addr(vertexBuffers[0]), pOffsets=addr(offsets[0])) |
| 553 vkCmdBindIndexBuffer(commandBuffer, indexBuffer.vkBuffer, VkDeviceSize(0), indexType); | 603 vkCmdBindIndexBuffer(commandBuffer, indexBuffer.vkBuffer, VkDeviceSize(0), indexType) |
| 554 vkCmdDrawIndexed(commandBuffer, indicesCount, 1, 0, 0, 0); | 604 vkCmdDrawIndexed(commandBuffer, indicesCount, 1, 0, 0, 0) |
| 555 | 605 |
| 556 proc recordCommandBuffer(renderPass: VkRenderPass, pipeline: RenderPipeline, commandBuffer: VkCommandBuffer, framebuffer: VkFramebuffer, frameDimension: VkExtent2D) = | 606 proc recordCommandBuffer(renderPass: VkRenderPass, pipeline: var RenderPipeline, commandBuffer: VkCommandBuffer, framebuffer: VkFramebuffer, frameDimension: VkExtent2D, currentFrame: int) = |
| 557 var | 607 var |
| 558 beginInfo = VkCommandBufferBeginInfo( | 608 beginInfo = VkCommandBufferBeginInfo( |
| 559 sType: VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, | 609 sType: VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, |
| 560 pInheritanceInfo: nil, | 610 pInheritanceInfo: nil, |
| 561 ) | 611 ) |
| 586 checkVkResult vkBeginCommandBuffer(commandBuffer, addr(beginInfo)) | 636 checkVkResult vkBeginCommandBuffer(commandBuffer, addr(beginInfo)) |
| 587 block: | 637 block: |
| 588 vkCmdBeginRenderPass(commandBuffer, addr(renderPassInfo), VK_SUBPASS_CONTENTS_INLINE) | 638 vkCmdBeginRenderPass(commandBuffer, addr(renderPassInfo), VK_SUBPASS_CONTENTS_INLINE) |
| 589 vkCmdSetViewport(commandBuffer, firstViewport=0, viewportCount=1, addr(viewport)) | 639 vkCmdSetViewport(commandBuffer, firstViewport=0, viewportCount=1, addr(viewport)) |
| 590 vkCmdSetScissor(commandBuffer, firstScissor=0, scissorCount=1, addr(scissor)) | 640 vkCmdSetScissor(commandBuffer, firstScissor=0, scissorCount=1, addr(scissor)) |
| 591 runPipeline(commandBuffer, pipeline) | 641 runPipeline(commandBuffer, pipeline, currentFrame) |
| 592 vkCmdEndRenderPass(commandBuffer) | 642 vkCmdEndRenderPass(commandBuffer) |
| 593 checkVkResult vkEndCommandBuffer(commandBuffer) | 643 checkVkResult vkEndCommandBuffer(commandBuffer) |
| 594 | 644 |
| 595 proc drawFrame(window: NativeWindow, vulkan: var Vulkan, currentFrame: int, resized: bool, pipeline: RenderPipeline) = | 645 proc drawFrame(window: NativeWindow, vulkan: var Vulkan, currentFrame: int, resized: bool, pipeline: var RenderPipeline) = |
| 596 checkVkResult vkWaitForFences(vulkan.device.device, 1, addr(vulkan.inFlightFences[currentFrame]), VK_TRUE, high(uint64)) | 646 checkVkResult vkWaitForFences(vulkan.device.device, 1, addr(vulkan.inFlightFences[currentFrame]), VK_TRUE, high(uint64)) |
| 597 var bufferImageIndex: uint32 | 647 var bufferImageIndex: uint32 |
| 598 let nextImageResult = vkAcquireNextImageKHR( | 648 let nextImageResult = vkAcquireNextImageKHR( |
| 599 vulkan.device.device, | 649 vulkan.device.device, |
| 600 vulkan.swapchain.swapchain, | 650 vulkan.swapchain.swapchain, |
| 609 elif not (nextImageResult in [VK_SUCCESS, VK_SUBOPTIMAL_KHR]): | 659 elif not (nextImageResult in [VK_SUCCESS, VK_SUBOPTIMAL_KHR]): |
| 610 raise newException(Exception, "Vulkan error: vkAcquireNextImageKHR returned " & $nextImageResult) | 660 raise newException(Exception, "Vulkan error: vkAcquireNextImageKHR returned " & $nextImageResult) |
| 611 checkVkResult vkResetFences(vulkan.device.device, 1, addr(vulkan.inFlightFences[currentFrame])) | 661 checkVkResult vkResetFences(vulkan.device.device, 1, addr(vulkan.inFlightFences[currentFrame])) |
| 612 | 662 |
| 613 checkVkResult vkResetCommandBuffer(vulkan.commandBuffers[currentFrame], VkCommandBufferResetFlags(0)) | 663 checkVkResult vkResetCommandBuffer(vulkan.commandBuffers[currentFrame], VkCommandBufferResetFlags(0)) |
| 614 vulkan.renderPass.recordCommandBuffer(pipeline, vulkan.commandBuffers[currentFrame], vulkan.framebuffers[bufferImageIndex], vulkan.frameDimension) | 664 vulkan.renderPass.recordCommandBuffer(pipeline, vulkan.commandBuffers[currentFrame], vulkan.framebuffers[bufferImageIndex], vulkan.frameDimension, currentFrame) |
| 615 var | 665 var |
| 616 waitSemaphores = [vulkan.imageAvailableSemaphores[currentFrame]] | 666 waitSemaphores = [vulkan.imageAvailableSemaphores[currentFrame]] |
| 617 waitStages = [VkPipelineStageFlags(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT)] | 667 waitStages = [VkPipelineStageFlags(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT)] |
| 618 signalSemaphores = [vulkan.renderFinishedSemaphores[currentFrame]] | 668 signalSemaphores = [vulkan.renderFinishedSemaphores[currentFrame]] |
| 619 submitInfo = VkSubmitInfo( | 669 submitInfo = VkSubmitInfo( |
| 642 if presentResult == VK_ERROR_OUT_OF_DATE_KHR or presentResult == VK_SUBOPTIMAL_KHR or resized: | 692 if presentResult == VK_ERROR_OUT_OF_DATE_KHR or presentResult == VK_SUBOPTIMAL_KHR or resized: |
| 643 vulkan.frameDimension = window.getFrameDimension(vulkan.device.physicalDevice.device, vulkan.surface) | 693 vulkan.frameDimension = window.getFrameDimension(vulkan.device.physicalDevice.device, vulkan.surface) |
| 644 (vulkan.swapchain, vulkan.framebuffers) = vulkan.recreateSwapchain() | 694 (vulkan.swapchain, vulkan.framebuffers) = vulkan.recreateSwapchain() |
| 645 | 695 |
| 646 | 696 |
| 647 proc run*(engine: var Engine, pipeline: RenderPipeline, globalUpdate: proc(engine: var Engine, dt: Duration)) = | 697 proc run*(engine: var Engine, pipeline: var RenderPipeline, globalUpdate: proc(engine: var Engine, dt: float32)) = |
| 648 var | 698 var |
| 649 killed = false | 699 killed = false |
| 650 currentFrame = 0 | 700 currentFrame = 0 |
| 651 resized = false | 701 resized = false |
| 652 lastUpdate = getTime() | 702 lastUpdate = getTime() |
| 668 discard | 718 discard |
| 669 | 719 |
| 670 # game logic update | 720 # game logic update |
| 671 let | 721 let |
| 672 now = getTime() | 722 now = getTime() |
| 673 dt = now - lastUpdate | 723 dt = float32(float64((now - lastUpdate).inNanoseconds) / 1_000_000_000'f64) |
| 674 lastUpdate = now | 724 lastUpdate = now |
| 675 engine.globalUpdate(dt) | 725 engine.globalUpdate(dt) |
| 676 for entity in allEntities(engine.currentscenedata): | 726 for entity in allEntities(engine.currentscenedata): |
| 677 entity.update(dt) | 727 entity.update(dt) |
| 678 | 728 |
| 679 # submit frame for drawing | 729 # submit frame for drawing |
| 680 engine.window.drawFrame(engine.vulkan, currentFrame, resized, pipeline) | 730 engine.window.drawFrame(engine.vulkan, currentFrame, resized, pipeline) |
| 681 resized = false | 731 resized = false |
| 682 currentFrame = (currentFrame + 1) mod MAX_FRAMES_IN_FLIGHT; | 732 currentFrame = (currentFrame + 1) mod MAX_FRAMES_IN_FLIGHT |
| 683 checkVkResult vkDeviceWaitIdle(engine.vulkan.device.device) | 733 checkVkResult vkDeviceWaitIdle(engine.vulkan.device.device) |
| 684 | 734 |
| 685 proc trash*(pipeline: var RenderPipeline) = | 735 proc trash*(pipeline: var RenderPipeline) = |
| 686 vkDestroyDescriptorSetLayout(pipeline.device, pipeline.uniformLayout, nil); | 736 vkDestroyDescriptorPool(pipeline.device, pipeline.descriptorPool, nil) |
| 737 vkDestroyDescriptorSetLayout(pipeline.device, pipeline.descriptorSetLayout, nil) | |
| 687 vkDestroyPipeline(pipeline.device, pipeline.pipeline, nil) | 738 vkDestroyPipeline(pipeline.device, pipeline.pipeline, nil) |
| 688 vkDestroyPipelineLayout(pipeline.device, pipeline.layout, nil) | 739 vkDestroyPipelineLayout(pipeline.device, pipeline.layout, nil) |
| 689 for shader in pipeline.shaders: | 740 for shader in pipeline.shaders: |
| 690 vkDestroyShaderModule(pipeline.device, shader.shader.module, nil) | 741 vkDestroyShaderModule(pipeline.device, shader.shader.module, nil) |
| 691 | 742 |
