diff options
| author | Jonathan Bradley <jcb@pikum.xyz> | 2023-08-24 10:18:00 -0400 |
|---|---|---|
| committer | Jonathan Bradley <jcb@pikum.xyz> | 2023-08-24 10:18:00 -0400 |
| commit | 91e15d7f97d24fec6ff5c299de8b9cd116778aae (patch) | |
| tree | c838a9a9a7220421f0668e384ab2e1ebb38b44e5 /src | |
| parent | 998ed84c26da259c5b19e228af245e58e0daa7d6 (diff) | |
add commandBuffer, semaphores, and fence - no binding yet
Diffstat (limited to 'src')
| -rw-r--r-- | src/main.cpp | 5 | ||||
| -rw-r--r-- | src/window.cpp | 167 | ||||
| -rw-r--r-- | src/window.hpp | 2 |
3 files changed, 166 insertions, 8 deletions
diff --git a/src/main.cpp b/src/main.cpp index 07ac831..d221f50 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -39,6 +39,8 @@ int main() { while (pkeSettings.isGameRunning) { + glfwPollEvents(); + if (nsAhead > 0) { std::this_thread::sleep_until(lastTimePoint + GameTimeDuration(nsAhead + 1)); nsAhead = 0; @@ -79,8 +81,11 @@ int main() { tickCount = 0; } + pkeSettings.isGameRunning = !glfwWindowShouldClose(window); } + vkDeviceWaitIdle(vkDevice); + } catch (const std::exception &exc) { printf("EXCEPTION: %s\n", exc.what()); } catch (const char *err) { diff --git a/src/window.cpp b/src/window.cpp index be4dec9..a56ae9b 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -20,6 +20,8 @@ GLFWwindow *window = nullptr; VkInstance vkInstance = nullptr; VkPhysicalDevice vkPhysicalDevice = nullptr; VkDevice vkDevice = nullptr; +VkQueue graphicsQueue = nullptr; +VkQueue presentQueue = nullptr; VkSurfaceKHR vkSurfaceKHR = nullptr; VkDebugReportCallbackEXT vkDebugReport = nullptr; VkAllocationCallbacks vkAllocatorStruct = {}; @@ -34,7 +36,7 @@ unsigned int CURRENT_FRAME = 0; unsigned int selectedSurfaceIndex = -1u; unsigned int selectedPresentIndex = -1u; unsigned int swapchainLength = 0u; -VkSwapchainKHR vkSwapchainKHR = nullptr; +VkSwapchainKHR vkSwapchainKHR = VK_NULL_HANDLE; VkSurfaceFormatKHR vkSurfaceFormatKHR; VkPresentModeKHR vkPresentModeKHR; VkExtent2D extent; @@ -46,6 +48,10 @@ VkPipelineLayout pipelineLayout; VkPipeline graphicsPipeline; VkFramebuffer *swapchainFramebuffers = nullptr; VkCommandPool vkCommandPool; +VkCommandBuffer commandBuffer; +VkSemaphore imageAvailableSemaphore; +VkSemaphore renderFinishedSemaphore; +VkFence inFlightFence; const std::vector<const char *> REQUIRED_EXTENSIONS = std::vector<const char *> { VK_KHR_SWAPCHAIN_EXTENSION_NAME @@ -337,6 +343,12 @@ void InitVulkan() { throw result; } } + + // queues + { + vkGetDeviceQueue(vkDevice, graphicsFamilyIndex, 0, &graphicsQueue); + vkGetDeviceQueue(vkDevice, presentFamilyIndex, 0, &presentQueue); + } } void CreateSwapchain() { @@ -404,7 +416,8 @@ void CreateSwapchain() { vkSwapchainCreateInfo.compositeAlpha = VkCompositeAlphaFlagBitsKHR::VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; vkSwapchainCreateInfo.presentMode = vkPresentModeKHR; vkSwapchainCreateInfo.clipped = VK_TRUE; - vkSwapchainCreateInfo.oldSwapchain = vkSwapchainKHR; + // vkSwapchainCreateInfo.oldSwapchain = vkSwapchainKHR; + vkSwapchainCreateInfo.oldSwapchain = VK_NULL_HANDLE; vkSwapchainCreateInfo.surface = vkSurfaceKHR; unsigned int qfi[2] = { graphicsFamilyIndex, presentFamilyIndex }; @@ -469,12 +482,22 @@ void CreateRenderPass() { subpass.colorAttachmentCount = 1; subpass.pColorAttachments = &colorAttachmentRef; + 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(vkDevice, &renderPassInfo, vkAllocator, &renderPass) != VK_SUCCESS) { throw "failed to create render pass!"; @@ -686,8 +709,88 @@ void CreateCommandPool() { } } +void CreateCommandBuffer() { + VkCommandBufferAllocateInfo allocInfo{}; + allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; + allocInfo.commandPool = vkCommandPool; + allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; + allocInfo.commandBufferCount = 1; + + auto result = vkAllocateCommandBuffers(vkDevice, &allocInfo, &commandBuffer); + if (result != VK_SUCCESS) { + throw "failed to allocate command buffer"; + } +} + +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; + + auto result1 = vkCreateSemaphore(vkDevice, &semaphoreInfo, vkAllocator, &imageAvailableSemaphore); + auto result2 = vkCreateSemaphore(vkDevice, &semaphoreInfo, vkAllocator, &renderFinishedSemaphore); + auto result3 = vkCreateFence(vkDevice, &fenceInfo, vkAllocator, &inFlightFence); + auto result = result1 == result2 && result2 == result3 && result3 == VK_SUCCESS; + if (!result) { + throw "failed to create sync objects"; + } +} + +void RecordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageIndex) { + VkCommandBufferBeginInfo beginInfo {}; + beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + beginInfo.flags = 0; + beginInfo.pInheritanceInfo = nullptr; + + auto result = vkBeginCommandBuffer(commandBuffer, &beginInfo); + if (result != VK_SUCCESS) { + throw "failed to begin recording command buffer"; + } + + VkClearValue clearColor = {{{0.0f, 0.0f, 0.0f, 1.0f}}}; + + VkRenderPassBeginInfo renderPassInfo{}; + renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; + renderPassInfo.renderPass = renderPass; + renderPassInfo.framebuffer = swapchainFramebuffers[imageIndex]; + renderPassInfo.renderArea.offset = {0, 0}; + renderPassInfo.renderArea.extent = extent; + renderPassInfo.clearValueCount = 1; + renderPassInfo.pClearValues = &clearColor; + + vkCmdBeginRenderPass(commandBuffer, &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE); + vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline); + + VkViewport viewport{}; + viewport.x = 0.0f; + viewport.y = 0.0f; + viewport.width = (float)extent.width; + viewport.height = (float)extent.height; + viewport.minDepth = 0.0f; + viewport.maxDepth = 1.0f; + + VkRect2D scissor{}; + scissor.offset = {0, 0}; + scissor.extent = extent; + + vkCmdSetViewport(commandBuffer, 0, 1, &viewport); + vkCmdSetScissor(commandBuffer, 0, 1, &scissor); + + // reminder that present.vert is a triangle + vkCmdDraw(commandBuffer, 3, 1, 0, 0); + + vkCmdEndRenderPass(commandBuffer); + + result = vkEndCommandBuffer(commandBuffer); + if (result != VK_SUCCESS) { + throw "failed to record command buffer!"; + } +} + void DestroySwapchain() { - vkDestroyCommandPool(vkDevice, vkCommandPool, vkAllocator); if (swapchainFramebuffers != nullptr && swapchainFramebuffers != CAFE_BABE(VkFramebuffer)) { for (long i = 0; i < swapchainLength; ++i) { vkDestroyFramebuffer(vkDevice, swapchainFramebuffers[i], vkAllocator); @@ -715,6 +818,7 @@ void FramebufferResizeCallback(GLFWwindow *window, int width, int height) { extent.width = width; extent.height = height; CreateSwapchain(); + CreateFramebuffers(); } void CreateWindow(PKEWindowProperties *wp) { @@ -729,14 +833,17 @@ void CreateWindow(PKEWindowProperties *wp) { CreateGraphicsPipeline(); CreateFramebuffers(); CreateCommandPool(); + CreateCommandBuffer(); + CreateSyncObjects(); } void DestroyWindow() { if (vkInstance == nullptr) return; - if (VULKAN_DEBUG_REPORT) { - auto vkDestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(vkInstance, "vkDestroyDebugReportCallbackEXT"); - vkDestroyDebugReportCallbackEXT(vkInstance, vkDebugReport, vkAllocator); - } + DestroySwapchain(); + vkDestroySemaphore(vkDevice, imageAvailableSemaphore, vkAllocator); + vkDestroySemaphore(vkDevice, renderFinishedSemaphore, vkAllocator); + vkDestroyFence(vkDevice, inFlightFence, vkAllocator); + vkDestroyCommandPool(vkDevice, vkCommandPool, vkAllocator); vkDestroyPipeline(vkDevice, graphicsPipeline, vkAllocator); vkDestroyPipelineLayout(vkDevice, pipelineLayout, vkAllocator); vkDestroyDescriptorSetLayout(vkDevice, vkDescriptorSetLayout, vkAllocator); @@ -744,6 +851,10 @@ void DestroyWindow() { DestroySwapchain(); vkDestroySurfaceKHR(vkInstance, vkSurfaceKHR, vkAllocator); vkDestroyDevice(vkDevice, vkAllocator); + if (VULKAN_DEBUG_REPORT) { + auto vkDestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(vkInstance, "vkDestroyDebugReportCallbackEXT"); + vkDestroyDebugReportCallbackEXT(vkInstance, vkDebugReport, vkAllocator); + } vkDestroyInstance(vkInstance, vkAllocator); glfwDestroyWindow(window); glfwTerminate(); @@ -767,6 +878,48 @@ VkShaderModule UploadShader(AssetHandle handle) { void PreRender() {} void Render() { + vkWaitForFences(vkDevice, 1, &inFlightFence, VK_TRUE, UINT64_MAX); + + uint32_t imageIndex; + vkAcquireNextImageKHR(vkDevice, vkSwapchainKHR, UINT64_MAX, imageAvailableSemaphore, VK_NULL_HANDLE, &imageIndex); + + vkResetFences(vkDevice, 1, &inFlightFence); + + vkResetCommandBuffer(commandBuffer, 0); + RecordCommandBuffer(commandBuffer, imageIndex); + + VkSemaphore waitSemaphores[] = {imageAvailableSemaphore}; + VkSemaphore signalSemaphores[] = {renderFinishedSemaphore}; + VkPipelineStageFlags waitStages[] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT}; + + VkSubmitInfo submitInfo{}; + submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + submitInfo.waitSemaphoreCount = 1; + submitInfo.pWaitSemaphores = waitSemaphores; + submitInfo.pWaitDstStageMask = waitStages; + submitInfo.commandBufferCount = 1; + submitInfo.pCommandBuffers = &commandBuffer; + submitInfo.signalSemaphoreCount = 1; + submitInfo.pSignalSemaphores = signalSemaphores; + + auto result = vkQueueSubmit(graphicsQueue, 1, &submitInfo, inFlightFence); + if (result != VK_SUCCESS) { + throw "failed to submit queue"; + } + + VkSwapchainKHR swapchains[] = {vkSwapchainKHR}; + + VkPresentInfoKHR presentInfo{}; + presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; + presentInfo.waitSemaphoreCount = 1; + presentInfo.pWaitSemaphores = signalSemaphores; + presentInfo.swapchainCount = 1; + presentInfo.pSwapchains = swapchains; + presentInfo.pImageIndices = &imageIndex; + presentInfo.pResults = nullptr; + + vkQueuePresentKHR(presentQueue, &presentInfo); + CURRENT_FRAME = (CURRENT_FRAME + 1) % swapchainLength; } diff --git a/src/window.hpp b/src/window.hpp index 117e67a..b7a4e05 100644 --- a/src/window.hpp +++ b/src/window.hpp @@ -9,7 +9,7 @@ const unsigned int MAX_FRAMES_IN_FLIGHT = 3; -extern GLFWwindow *glfwWindow; +extern GLFWwindow *window; extern VkInstance vkInstance; extern VkPhysicalDevice vkPhysicalDevice; extern VkSurfaceKHR vkSurfaceKHR; |
