109 lines
3.8 KiB
C++
109 lines
3.8 KiB
C++
#include "detail/graphics.h"
|
|
|
|
namespace deerith {
|
|
namespace graphics {
|
|
void drawFrame();
|
|
} // namespace graphics
|
|
|
|
void graphics::vulkan_test_loop() {
|
|
while (!glfwWindowShouldClose(window)) {
|
|
glfwPollEvents();
|
|
drawFrame();
|
|
}
|
|
}
|
|
|
|
void graphics::create_vulkan_sync_objects() {
|
|
image_available_semaphores.resize(MAX_FRAMES_IN_FLIGHT);
|
|
render_finished_semaphores.resize(MAX_FRAMES_IN_FLIGHT);
|
|
in_flight_fences.resize(MAX_FRAMES_IN_FLIGHT);
|
|
|
|
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;
|
|
|
|
for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
|
|
if (vkCreateSemaphore(device, &semaphoreInfo, nullptr, &image_available_semaphores[i]) != VK_SUCCESS ||
|
|
vkCreateSemaphore(device, &semaphoreInfo, nullptr, &render_finished_semaphores[i]) != VK_SUCCESS ||
|
|
vkCreateFence(device, &fenceInfo, nullptr, &in_flight_fences[i]) != VK_SUCCESS) {
|
|
|
|
deerith_graphics_error("failed to create synchronization objects for a frame!");
|
|
}
|
|
}
|
|
}
|
|
|
|
void graphics::drawFrame() {
|
|
vkWaitForFences(device, 1, &in_flight_fences[current_frame], VK_TRUE, UINT64_MAX);
|
|
|
|
uint32_t image_index;
|
|
VkResult result = vkAcquireNextImageKHR(device, swap_chain, UINT64_MAX, image_available_semaphores[current_frame], VK_NULL_HANDLE, &image_index);
|
|
|
|
if (result == VK_ERROR_OUT_OF_DATE_KHR) {
|
|
frame_buffer_resize = false;
|
|
vulkan_recreate_swap_chain();
|
|
return;
|
|
} else if (result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR) {
|
|
deerith_graphics_error("failed to acquire swap chain image!");
|
|
}
|
|
|
|
vkResetFences(device, 1, &in_flight_fences[current_frame]);
|
|
|
|
vkResetCommandBuffer(command_buffers[current_frame], 0);
|
|
record_command_buffer(command_buffers[current_frame], image_index);
|
|
|
|
VkSubmitInfo submit_info{};
|
|
submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
|
|
|
VkSemaphore waitSemaphores[] = {image_available_semaphores[current_frame]};
|
|
VkPipelineStageFlags waitStages[] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT};
|
|
submit_info.waitSemaphoreCount = 1;
|
|
submit_info.pWaitSemaphores = waitSemaphores;
|
|
submit_info.pWaitDstStageMask = waitStages;
|
|
|
|
submit_info.commandBufferCount = 1;
|
|
submit_info.pCommandBuffers = &command_buffers[current_frame];
|
|
|
|
VkSemaphore signalSemaphores[] = {render_finished_semaphores[current_frame]};
|
|
submit_info.signalSemaphoreCount = 1;
|
|
submit_info.pSignalSemaphores = signalSemaphores;
|
|
|
|
if (vkQueueSubmit(graphics_queue, 1, &submit_info, in_flight_fences[current_frame]) != VK_SUCCESS) {
|
|
deerith_graphics_error("failed to submit draw command buffer!");
|
|
}
|
|
|
|
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;
|
|
|
|
VkPresentInfoKHR presentInfo{};
|
|
presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
|
|
|
|
presentInfo.waitSemaphoreCount = 1;
|
|
presentInfo.pWaitSemaphores = signalSemaphores;
|
|
|
|
VkSwapchainKHR swapChains[] = {swap_chain};
|
|
presentInfo.swapchainCount = 1;
|
|
presentInfo.pSwapchains = swapChains;
|
|
presentInfo.pImageIndices = &image_index;
|
|
presentInfo.pResults = nullptr;
|
|
|
|
result = vkQueuePresentKHR(pressent_queue, &presentInfo);
|
|
|
|
if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR || frame_buffer_resize) {
|
|
vulkan_recreate_swap_chain();
|
|
frame_buffer_resize = false;
|
|
} else if (result != VK_SUCCESS) {
|
|
deerith_graphics_error("failed to present swap chain image!");
|
|
}
|
|
|
|
current_frame = (current_frame + 1) % MAX_FRAMES_IN_FLIGHT;
|
|
}
|
|
} // namespace deerith
|