summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJonathan Bradley <jcb@pikum.xyz>2023-08-24 10:18:00 -0400
committerJonathan Bradley <jcb@pikum.xyz>2023-08-24 10:18:00 -0400
commit91e15d7f97d24fec6ff5c299de8b9cd116778aae (patch)
treec838a9a9a7220421f0668e384ab2e1ebb38b44e5 /src
parent998ed84c26da259c5b19e228af245e58e0daa7d6 (diff)
add commandBuffer, semaphores, and fence - no binding yet
Diffstat (limited to 'src')
-rw-r--r--src/main.cpp5
-rw-r--r--src/window.cpp167
-rw-r--r--src/window.hpp2
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;