aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvimene <vincent.menegaux@gmail.com>2025-12-20 00:24:06 +0100
committervimene <vincent.menegaux@gmail.com>2025-12-20 00:24:06 +0100
commit8024a6d59a4595f69f03466b66f4ea2eea87fcf9 (patch)
tree21f855eb92adfbe71bf13ebfdb76898b25e95464
parentc9d3b369a868dc54e4c5cc26a9354dddbe91db1b (diff)
downloadengine-8024a6d59a4595f69f03466b66f4ea2eea87fcf9.tar.gz
added rendering and presentation
-rw-r--r--src/engine.cpp247
1 files changed, 172 insertions, 75 deletions
diff --git a/src/engine.cpp b/src/engine.cpp
index 1ade915..31f72d0 100644
--- a/src/engine.cpp
+++ b/src/engine.cpp
@@ -784,6 +784,7 @@ static int main_graphical() {
VkPhysicalDeviceVulkan13Features device_vk13_features{};
device_vk13_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES;
+ device_vk13_features.synchronization2 = VK_TRUE;
device_vk13_features.dynamicRendering = VK_TRUE;
device_features.pNext = &device_vk13_features;
@@ -1166,89 +1167,185 @@ static int main_graphical() {
std::exit(EXIT_FAILURE);
}
+ // create sync objects
+ VkSemaphore sem_present_complete, sem_render_finished;
+ VkFence fence_draw;
+
+ // TODO: I don't know if I have to use 2 different VkSemaphoreCreateInfo, but for now, let's do
+ // this so we're sure it'll work
+ VkSemaphoreCreateInfo sem_present_complete_ci {
+ .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
+ .pNext = nullptr,
+ .flags = {},
+ };
+ if (VkResult res = vkCreateSemaphore(logical_device, &sem_present_complete_ci, nullptr, &sem_present_complete); res != VK_SUCCESS) {
+ std::cerr << "failed to create present complete semaphore, error code: " << string_VkResult(res) << std::endl;
+ std::exit(EXIT_FAILURE);
+ }
+ std::cout << "sem_present_complete: " << sem_present_complete << std::endl;
+ VkSemaphoreCreateInfo sem_render_finished_ci {
+ .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
+ .pNext = nullptr,
+ .flags = {},
+ };
+ if (VkResult res = vkCreateSemaphore(logical_device, &sem_render_finished_ci, nullptr, &sem_render_finished); res != VK_SUCCESS) {
+ std::cerr << "failed to create render finished semaphore, error code: " << string_VkResult(res) << std::endl;
+ std::exit(EXIT_FAILURE);
+ }
+ std::cout << "sem_render_finished: " << sem_render_finished << std::endl;
+
+ VkFenceCreateInfo fence_draw_ci {
+ .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
+ .pNext = nullptr,
+ .flags = VK_FENCE_CREATE_SIGNALED_BIT,
+ };
+ if (VkResult res = vkCreateFence(logical_device, &fence_draw_ci, nullptr, &fence_draw); res != VK_SUCCESS) {
+ std::cerr << "failed to create draw semaphore, error code: " << string_VkResult(res) << std::endl;
+ std::exit(EXIT_FAILURE);
+ }
+ std::cout << "fence_draw: " << fence_draw << std::endl;
+
// main loop
while (!glfwWindowShouldClose(window)) {
glfwPollEvents();
- // this shouldn't be a function, it has to be removed (but keep the inside) once it can run.
- // Keeping it like this gives the opportunity to check for simple errors while it can't run
- [&]() {
- uint32_t img_idx {}; // TODO: define properly
- VkCommandBufferBeginInfo cmd_buf_bi {
- .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
- .pNext = nullptr,
- .flags = {},
- .pInheritanceInfo = {},
- };
- if (VkResult res = vkBeginCommandBuffer(cmd_buf, &cmd_buf_bi); res != VK_SUCCESS) {
- std::cerr << "failed to begin command buffer, error code: " << string_VkResult(res) << std::endl;
- std::exit(EXIT_FAILURE);
- }
- transition_image_layout(cmd_buf, swapchain_imgs[img_idx],
- VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
- {}, VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT,
- VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT);
- VkClearValue clear_val { .color = { .float32 = { 0.f, 0.f, 0.f, 1.f } }, };
- VkRenderingAttachmentInfo attachment_info {
- .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
- .pNext = nullptr,
- .imageView = swapchain_img_views[img_idx],
- .imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
- .resolveMode = {},
- .resolveImageView = {},
- .resolveImageLayout = {},
- .loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
- .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
- .clearValue = clear_val,
- };
- VkRenderingInfo render_info {
- .sType = VK_STRUCTURE_TYPE_RENDERING_INFO,
- .pNext = nullptr,
- .flags = {},
- .renderArea = { .offset { 0, 0 }, .extent = swapchain_extent },
- .layerCount = 1,
- .viewMask = {},
- .colorAttachmentCount = 1,
- .pColorAttachments = &attachment_info,
- .pDepthAttachment = {},
- .pStencilAttachment = {},
- };
- vkCmdBeginRendering(cmd_buf, &render_info);
- vkCmdBindPipeline(cmd_buf, VK_PIPELINE_BIND_POINT_GRAPHICS, graphics_pl);
-
- VkViewport viewport {
- .x = 0.f,
- .y = 0.f,
- .width = static_cast<float>(swapchain_extent.width),
- .height = static_cast<float>(swapchain_extent.height),
- .minDepth = 0.f,
- .maxDepth = 1.f,
- };
- vkCmdSetViewport(cmd_buf, 0, 1, &viewport);
-
- VkRect2D scissor {
- .offset = { 0, 0 },
- .extent = swapchain_extent,
- };
- vkCmdSetScissor(cmd_buf, 0, 1, &scissor);
-
- vkCmdDraw(cmd_buf, 3, 1, 0, 0);
-
- vkCmdEndRendering(cmd_buf);
-
- transition_image_layout(cmd_buf, swapchain_imgs[img_idx],
- VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
- VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, {},
- VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT);
-
- if (VkResult res = vkEndCommandBuffer(cmd_buf); res != VK_SUCCESS) {
- std::cerr << "failed to end command buffer, error code: " << string_VkResult(res) << std::endl;
- std::exit(EXIT_FAILURE);
- }
+ if (VkResult res = vkQueueWaitIdle(graphics_queue); res != VK_SUCCESS) {
+ std::cerr << "failed to wait idle for graphics queue, error code: " << string_VkResult(res) << std::endl;
+ std::exit(EXIT_FAILURE);
+ }
+
+ uint32_t img_idx;
+ if (VkResult res = vkAcquireNextImageKHR(logical_device, swapchain,
+ std::numeric_limits<uint64_t>::max(), sem_present_complete, nullptr, &img_idx); res != VK_SUCCESS) {
+ std::cerr << "failed to acquire next image, error code: " << string_VkResult(res) << std::endl;
+ std::exit(EXIT_FAILURE);
+ }
+
+ // record command buffer
+ VkCommandBufferBeginInfo cmd_buf_bi {
+ .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
+ .pNext = nullptr,
+ .flags = {},
+ .pInheritanceInfo = {},
+ };
+ if (VkResult res = vkBeginCommandBuffer(cmd_buf, &cmd_buf_bi); res != VK_SUCCESS) {
+ std::cerr << "failed to begin command buffer, error code: " << string_VkResult(res) << std::endl;
+ std::exit(EXIT_FAILURE);
+ }
+ transition_image_layout(cmd_buf, swapchain_imgs[img_idx],
+ VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+ {}, VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT,
+ VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT);
+ VkClearValue clear_val { .color = { .float32 = { 0.f, 0.f, 0.f, 1.f } }, };
+ VkRenderingAttachmentInfo attachment_info {
+ .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
+ .pNext = nullptr,
+ .imageView = swapchain_img_views[img_idx],
+ .imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+ .resolveMode = {},
+ .resolveImageView = {},
+ .resolveImageLayout = {},
+ .loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
+ .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
+ .clearValue = clear_val,
+ };
+ VkRenderingInfo render_info {
+ .sType = VK_STRUCTURE_TYPE_RENDERING_INFO,
+ .pNext = nullptr,
+ .flags = {},
+ .renderArea = { .offset { 0, 0 }, .extent = swapchain_extent },
+ .layerCount = 1,
+ .viewMask = {},
+ .colorAttachmentCount = 1,
+ .pColorAttachments = &attachment_info,
+ .pDepthAttachment = {},
+ .pStencilAttachment = {},
};
+ vkCmdBeginRendering(cmd_buf, &render_info);
+ vkCmdBindPipeline(cmd_buf, VK_PIPELINE_BIND_POINT_GRAPHICS, graphics_pl);
+
+ VkViewport viewport {
+ .x = 0.f,
+ .y = 0.f,
+ .width = static_cast<float>(swapchain_extent.width),
+ .height = static_cast<float>(swapchain_extent.height),
+ .minDepth = 0.f,
+ .maxDepth = 1.f,
+ };
+ vkCmdSetViewport(cmd_buf, 0, 1, &viewport);
+
+ VkRect2D scissor {
+ .offset = { 0, 0 },
+ .extent = swapchain_extent,
+ };
+ vkCmdSetScissor(cmd_buf, 0, 1, &scissor);
+
+ vkCmdDraw(cmd_buf, 3, 1, 0, 0);
+
+ vkCmdEndRendering(cmd_buf);
+
+ transition_image_layout(cmd_buf, swapchain_imgs[img_idx],
+ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
+ VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, {},
+ VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT);
+
+ if (VkResult res = vkEndCommandBuffer(cmd_buf); res != VK_SUCCESS) {
+ std::cerr << "failed to end command buffer, error code: " << string_VkResult(res) << std::endl;
+ std::exit(EXIT_FAILURE);
+ }
+
+ if (VkResult res = vkResetFences(logical_device, 1, &fence_draw); res != VK_SUCCESS) {
+ std::cerr << "failed to reset draw fence, error code: " << string_VkResult(res) << std::endl;
+ std::exit(EXIT_FAILURE);
+ }
+
+ VkPipelineStageFlags pl_stage_flags = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
+ VkSubmitInfo submit_info {
+ .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
+ .pNext = nullptr,
+ .waitSemaphoreCount = 1,
+ .pWaitSemaphores = &sem_present_complete,
+ .pWaitDstStageMask = &pl_stage_flags,
+ .commandBufferCount = 1,
+ .pCommandBuffers = &cmd_buf,
+ .signalSemaphoreCount = 1,
+ .pSignalSemaphores = &sem_render_finished,
+ };
+ if (VkResult res = vkQueueSubmit(graphics_queue, 1, &submit_info, fence_draw); res != VK_SUCCESS) {
+ std::cerr << "failed to submit queue, error code: " << string_VkResult(res) << std::endl;
+ std::exit(EXIT_FAILURE);
+ }
+
+ if (VkResult res = vkWaitForFences(logical_device, 1, &fence_draw, VK_TRUE, std::numeric_limits<uint64_t>::max()); res != VK_SUCCESS) {
+ std::cerr << "failed to wait for draw fence, error code: " << string_VkResult(res) << std::endl;
+ std::exit(EXIT_FAILURE);
+ }
+
+ VkPresentInfoKHR present_info {
+ .sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
+ .pNext = nullptr,
+ .waitSemaphoreCount = 1,
+ .pWaitSemaphores = &sem_render_finished,
+ .swapchainCount = 1,
+ .pSwapchains = &swapchain,
+ .pImageIndices = &img_idx,
+ .pResults = nullptr,
+ };
+ if (VkResult res = vkQueuePresentKHR(presentation_queue, &present_info); res != VK_SUCCESS) {
+ std::cerr << "failed to present, error code: " << string_VkResult(res) << std::endl;
+ std::exit(EXIT_FAILURE);
+ }
+ }
+
+ if (VkResult res = vkDeviceWaitIdle(logical_device); res != VK_SUCCESS) {
+ std::cerr << "failed to wait idle for device, error code: " << string_VkResult(res) << std::endl;
+ std::exit(EXIT_FAILURE);
}
// cleanup
+ vkDestroyFence(logical_device, fence_draw, nullptr);
+ vkDestroySemaphore(logical_device, sem_render_finished, nullptr);
+ vkDestroySemaphore(logical_device, sem_present_complete, nullptr);
vkDestroyCommandPool(logical_device, cmd_pool, nullptr);
vkDestroyPipeline(logical_device, graphics_pl, nullptr);
vkDestroyPipelineLayout(logical_device, pl_layout, nullptr);