Finally a triangle

This commit is contained in:
Warwick 2025-01-16 17:01:06 +00:00
parent 41056d6026
commit df7f62ff8b

View file

@ -62,6 +62,10 @@ typedef struct Application {
uint32_t swapChainFramebufferCount; uint32_t swapChainFramebufferCount;
VkCommandPool commandPool; VkCommandPool commandPool;
VkCommandBuffer commandBuffer; VkCommandBuffer commandBuffer;
VkSemaphore imageAvailableSemaphore;
VkSemaphore renderFinishedSemaphore;
VkFence inFlightFence;
} Application; } Application;
typedef struct SwapChainSupportDetails { typedef struct SwapChainSupportDetails {
@ -846,12 +850,22 @@ void createRenderPass(Application *app) {
subpass.colorAttachmentCount = 1; subpass.colorAttachmentCount = 1;
subpass.pColorAttachments = &colorAttachmentRef; subpass.pColorAttachments = &colorAttachmentRef;
VkSubpassDependency dependency = {0};
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 = {0}; VkRenderPassCreateInfo renderPassInfo = {0};
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
renderPassInfo.attachmentCount = 1; renderPassInfo.attachmentCount = 1;
renderPassInfo.pAttachments = &colorAttachment; renderPassInfo.pAttachments = &colorAttachment;
renderPassInfo.subpassCount = 1; renderPassInfo.subpassCount = 1;
renderPassInfo.pSubpasses = &subpass; renderPassInfo.pSubpasses = &subpass;
renderPassInfo.dependencyCount = 1;
renderPassInfo.pDependencies = &dependency;
if (vkCreateRenderPass(app->device, &renderPassInfo, NULL, if (vkCreateRenderPass(app->device, &renderPassInfo, NULL,
&app->renderPass) != VK_SUCCESS) { &app->renderPass) != VK_SUCCESS) {
@ -971,6 +985,25 @@ void createCommandBuffer(Application *app) {
} }
} }
void createSyncObjects(Application *app) {
VkSemaphoreCreateInfo semaphoreInfo = {0};
semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
VkFenceCreateInfo fenceInfo = {0};
fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
if (vkCreateSemaphore(app->device, &semaphoreInfo, NULL,
&app->imageAvailableSemaphore) != VK_SUCCESS ||
vkCreateSemaphore(app->device, &semaphoreInfo, NULL,
&app->renderFinishedSemaphore) != VK_SUCCESS ||
vkCreateFence(app->device, &fenceInfo, NULL, &app->inFlightFence) !=
VK_SUCCESS) {
fprintf(stderr, "Failed to create semaphores!");
exit(EXIT_FAILURE);
}
}
void initVulkan(Application *app) { void initVulkan(Application *app) {
createInstance(app); createInstance(app);
setupDebugMessenger(app); setupDebugMessenger(app);
@ -984,15 +1017,67 @@ void initVulkan(Application *app) {
createFramebuffers(app); createFramebuffers(app);
CreateCommandPool(app); CreateCommandPool(app);
createCommandBuffer(app); createCommandBuffer(app);
createSyncObjects(app);
}
void drawFrame(Application *app) {
vkWaitForFences(app->device, 1, &app->inFlightFence, VK_TRUE, UINT64_MAX);
vkResetFences(app->device, 1, &app->inFlightFence);
uint32_t imageIndex;
vkAcquireNextImageKHR(app->device, app->swapChain, UINT64_MAX,
app->imageAvailableSemaphore, VK_NULL_HANDLE,
&imageIndex);
vkResetCommandBuffer(app->commandBuffer, 0);
recordCommandBuffer(app, app->commandBuffer, imageIndex);
VkSubmitInfo submitInfo = {0};
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
VkSemaphore waitSemaphores[] = {app->imageAvailableSemaphore};
VkPipelineStageFlags waitStages[] = {
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT};
submitInfo.waitSemaphoreCount = 1;
submitInfo.pWaitSemaphores = waitSemaphores;
submitInfo.pWaitDstStageMask = waitStages;
submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &app->commandBuffer;
VkSemaphore signalSemaphores[] = {app->renderFinishedSemaphore};
submitInfo.signalSemaphoreCount = 1;
submitInfo.pSignalSemaphores = signalSemaphores;
if (vkQueueSubmit(app->graphicsQueue, 1, &submitInfo, app->inFlightFence) !=
VK_SUCCESS) {
fprintf(stderr, "failed to submit draw command buffer!");
exit(EXIT_FAILURE);
}
VkPresentInfoKHR presentInfo = {0};
presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
presentInfo.waitSemaphoreCount = 1;
presentInfo.pWaitSemaphores = signalSemaphores;
VkSwapchainKHR swapChains[] = {app->swapChain};
presentInfo.swapchainCount = 1;
presentInfo.pSwapchains = swapChains;
presentInfo.pImageIndices = &imageIndex;
presentInfo.pResults = NULL; // Optional
vkQueuePresentKHR(app->presentQueue, &presentInfo);
} }
void mainLoop(Application *app) { void mainLoop(Application *app) {
while (!glfwWindowShouldClose(app->window)) { while (!glfwWindowShouldClose(app->window)) {
glfwPollEvents(); glfwPollEvents();
drawFrame(app);
} }
vkDeviceWaitIdle(app->device);
} }
void cleanup(Application *app) { void cleanup(Application *app) {
vkDestroySemaphore(app->device, app->imageAvailableSemaphore, NULL);
vkDestroySemaphore(app->device, app->renderFinishedSemaphore, NULL);
vkDestroyFence(app->device, app->inFlightFence, NULL);
vkDestroyCommandPool(app->device, app->commandPool, NULL); vkDestroyCommandPool(app->device, app->commandPool, NULL);
for (uint i = 0; i < app->swapChainFramebufferCount; i++) { for (uint i = 0; i < app->swapChainFramebufferCount; i++) {
vkDestroyFramebuffer(app->device, app->swapChainFramebuffers[i], NULL); vkDestroyFramebuffer(app->device, app->swapChainFramebuffers[i], NULL);