diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..24a8e87 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +*.png filter=lfs diff=lfs merge=lfs -text diff --git a/FirstTriangle.png b/FirstTriangle.png new file mode 100644 index 0000000..f726f17 --- /dev/null +++ b/FirstTriangle.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5f79029a0081980191bc7b034102abcabf1d81946b63c417505f7c220b3d67ef +size 46488 diff --git a/Hello_triangle/main.cpp b/Hello_triangle/main.cpp index a12a2c1..cd4b247 100644 --- a/Hello_triangle/main.cpp +++ b/Hello_triangle/main.cpp @@ -1,6 +1,6 @@ /* Following the vulkan tutorial on : - https://vulkan-tutorial.com/en/Drawing_a_triangle/Presentation/Swap_chain + https://vulkan-tutorial.com/en/Drawing_a_triangle/Drawing/Frames_in_flight */ #define GLFW_INCLUDE_VULKAN @@ -66,6 +66,9 @@ const std::vector deviceExtensions = { std::vector swapchainFrameBuffers; VkCommandPool commandPool; VkCommandBuffer commandBuffer; + VkSemaphore imageAvailableSemaphore; + VkSemaphore renderFinishedSemaphore; + VkFence inFlightFence; @@ -98,6 +101,25 @@ const std::vector deviceExtensions = { createFramebuffers(); createCommandPool(); createCommandBuffer(); + createSyncObjects(); + } + + void createSyncObjects() { + VkSemaphoreCreateInfo semaphoreInfo{}; + semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; + + VkFenceCreateInfo fenceInfo{}; + fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; + fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT; + + if (vkCreateSemaphore(device, &semaphoreInfo, nullptr, &imageAvailableSemaphore) != VK_SUCCESS || + vkCreateSemaphore(device, &semaphoreInfo, nullptr, &renderFinishedSemaphore) != VK_SUCCESS || + vkCreateFence(device, &fenceInfo, nullptr, &inFlightFence) != VK_SUCCESS) { + throw std::runtime_error("failed to create semaphores!"); + } + + + } void recordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageIndex) { @@ -324,12 +346,26 @@ const std::vector deviceExtensions = { subpass.colorAttachmentCount = 1; subpass.pColorAttachments = &colorAttachementRef; + VkSubpassDependency dependency{}; + dependency.srcSubpass = VK_SUBPASS_EXTERNAL; + dependency.dstSubpass = 0; + + dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + dependency.srcAccessMask = 0; + + dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + VkRenderPassCreateInfo renderPassInfo{}; renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; renderPassInfo.attachmentCount = 1; renderPassInfo.pAttachments = &colorAttachment; renderPassInfo.subpassCount = 1; renderPassInfo.pSubpasses = &subpass; + renderPassInfo.dependencyCount = 1; + renderPassInfo.pDependencies = &dependency; + + if (vkCreateRenderPass(device, &renderPassInfo, nullptr, &renderPass) != VK_SUCCESS) { throw std::runtime_error("Failed to create render pass!"); @@ -815,10 +851,68 @@ const std::vector deviceExtensions = { void mainLoop(){ while (!glfwWindowShouldClose(window)){ glfwPollEvents(); + drawFrame(); } + + vkDeviceWaitIdle(device); } + + void drawFrame() { + vkWaitForFences(device, 1, &inFlightFence, VK_TRUE, UINT64_MAX); + vkResetFences(device, 1, &inFlightFence); + + uint32_t imageIndex; + vkAcquireNextImageKHR(device, swapChain, UINT64_MAX, imageAvailableSemaphore, VK_NULL_HANDLE, &imageIndex); + + vkResetCommandBuffer(commandBuffer, 0); + recordCommandBuffer(commandBuffer, imageIndex); + + VkSubmitInfo submitInfo{}; + submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + + VkSemaphore waitSemaphores[] = { imageAvailableSemaphore }; + VkPipelineStageFlags waitstages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT }; + submitInfo.waitSemaphoreCount = 1; + submitInfo.pWaitSemaphores = waitSemaphores; + submitInfo.pWaitDstStageMask = waitstages; + + submitInfo.commandBufferCount = 1; + submitInfo.pCommandBuffers = &commandBuffer; + + VkSemaphore signalSemaphore[] = { renderFinishedSemaphore }; + submitInfo.signalSemaphoreCount = 1; + submitInfo.pSignalSemaphores = signalSemaphore; + + if (vkQueueSubmit(graphicsQueue,1, &submitInfo, inFlightFence) != VK_SUCCESS) { + throw std::runtime_error("failed to submit draw command buffer"); + } + + VkPresentInfoKHR presentInfo{}; + presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; + + presentInfo.waitSemaphoreCount = 1; + presentInfo.pWaitSemaphores = signalSemaphore; + + VkSwapchainKHR swapChains[] = { swapChain }; + presentInfo.swapchainCount = 1; + presentInfo.pSwapchains = swapChains; + presentInfo.pImageIndices = &imageIndex; + + vkQueuePresentKHR(presentQueue, &presentInfo); + + + + + } + + void cleanup(){ + + vkDestroySemaphore(device, imageAvailableSemaphore, nullptr); + vkDestroySemaphore(device, renderFinishedSemaphore, nullptr); + vkDestroyFence(device, inFlightFence, nullptr); + vkDestroyCommandPool(device, commandPool, nullptr); for (auto framebuffer : swapchainFrameBuffers) { diff --git a/readme.md b/readme.md index 636d4dc..d3594b7 100644 --- a/readme.md +++ b/readme.md @@ -1,3 +1,8 @@ # Vulkan API demo's -![Vulkan](https://www.vulkan.org/user/pages/01.home/Vulkan-Wide.png) \ No newline at end of file +![Vulkan](https://www.vulkan.org/user/pages/01.home/Vulkan-Wide.png) + + + + +![Rendering of first Triangle using vulkan](FirstTriangle.png) \ No newline at end of file