Kajetan Johannes Hammerle преди 3 месеца
родител
ревизия
dd67b81ccd
променени са 4 файла, в които са добавени 134 реда и са изтрити 71 реда
  1. 31 47
      src/VulkanUtils.c
  2. 8 3
      src/VulkanUtils.h
  3. 94 20
      src/VulkanWrapper.c
  4. 1 1
      test/modules/WindowManagerTests.c

+ 31 - 47
src/VulkanUtils.c

@@ -393,19 +393,6 @@ void destroyVulkanSwapchainImages(VulkanSwapchainImages* si, VkDevice d) {
     *si = (VulkanSwapchainImages){0};
 }
 
-bool initVulkanSemaphore(VkSemaphore* s, VkDevice d) {
-    VkSemaphoreCreateInfo info = {
-        .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO};
-    VK_ASSERT(vkCreateSemaphore(d, &info, nullptr, s));
-    return false;
-}
-
-void destroyVulkanSemaphore(VkSemaphore s, VkDevice d) {
-    if(d != VK_NULL_HANDLE) {
-        vkDestroySemaphore(d, s, nullptr);
-    }
-}
-
 static bool initShaderModule(FileContent* f, VkDevice d, VkShaderModule* sm) {
     if((f->length % 4) != 0) {
         LOG_ERROR("Shader size is not a multiple of 4");
@@ -482,43 +469,40 @@ void destroyVulkanFramebuffers(VkFramebuffer** f, u32 amount, VkDevice d) {
     }
 }
 
-/*static bool initCommandBuffers() {
-    vk.swapchain.commandsBuffers =
-        coreAllocate(sizeof(VkCommandBuffer) * vk.swapchain.amount);
-    VkCommandBufferAllocateInfo a = {
+bool initCommandVulkanBuffer(
+    VkCommandBuffer* cb, VkDevice d, VkCommandPool cp) {
+    VkCommandBufferAllocateInfo info = {
         .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
-        .commandPool = vk.swapchain.commandPool,
+        .commandPool = cp,
         .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
-        .commandBufferCount = vk.swapchain.amount};
-    VK_ASSERT(vkAllocateCommandBuffers(
-        vk.device.logical, &a, vk.swapchain.commandsBuffers));
+        .commandBufferCount = 1};
+    VK_ASSERT(vkAllocateCommandBuffers(d, &info, cb));
     return false;
 }
 
-static void destroyCommandBuffers() {
-    if(vk.swapchain.commandPool != VK_NULL_HANDLE && vk.swapchain.amount >
-0) { vkFreeCommandBuffers( vk.device.logical, vk.swapchain.commandPool,
-vk.swapchain.amount, vk.swapchain.commandsBuffers);
-    }
-    coreFree(vk.swapchain.commandsBuffers);
-}
-
-static bool fillCommandBuffer(u32 index) {
-    (void)index;
-    // VkCommandBufferBeginInfo info = {
-    //     .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
-    //     .flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT};
-    // VK_ASSERT(vkBeginCommandBuffer(vk.swapchain.commandsBuffers[index],
-    // &info)); VkClearValue v = {.color = {.int32 = {255, 0, 0, 0}}};
-    // VkRenderPassBeginInfo rInfo = {
-    //     .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
-    //     .renderPass = vk.renderPass,
-    //     .framebuffer = vk.swapchain.framebuffers[index],
-    //     .renderArea = {.offset = {0, 0}, .extent = {vk.width,
-vk.height}},
-    //     .clearValueCount = 1,
-    //     .pClearValues = &v};
-    // vkCmdBeginRenderPass(vk.swapchain.commandsBuffers[index], &rInfo,
-    //                      VK_SUBPASS_CONTENTS_INLINE);
+bool initVulkanSemaphore(VkSemaphore* s, VkDevice d) {
+    VkSemaphoreCreateInfo info = {
+        .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO};
+    VK_ASSERT(vkCreateSemaphore(d, &info, nullptr, s));
     return false;
-}*/
+}
+
+void destroyVulkanSemaphore(VkSemaphore s, VkDevice d) {
+    if(d != VK_NULL_HANDLE) {
+        vkDestroySemaphore(d, s, nullptr);
+    }
+}
+
+bool initVulkanFence(VkFence* f, VkDevice d) {
+    VkFenceCreateInfo info = {
+        .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
+        .flags = VK_FENCE_CREATE_SIGNALED_BIT};
+    VK_ASSERT(vkCreateFence(d, &info, nullptr, f));
+    return false;
+}
+
+void destroyVulkanFence(VkFence f, VkDevice d) {
+    if(d != VK_NULL_HANDLE) {
+        vkDestroyFence(d, f, nullptr);
+    }
+}

+ 8 - 3
src/VulkanUtils.h

@@ -77,9 +77,6 @@ bool initVulkanSwapchainImages(
     VulkanSwapchainImages* si, VkDevice d, VkSwapchainKHR sc, VkFormat format);
 void destroyVulkanSwapchainImages(VulkanSwapchainImages* si, VkDevice d);
 
-bool initVulkanSemaphore(VkSemaphore* s, VkDevice d);
-void destroyVulkanSemaphore(VkSemaphore s, VkDevice d);
-
 bool initVulkanShaderModule(VkShaderModule* sm, VkDevice d, const char* path);
 void destroyVulkanShaderModule(VkShaderModule sm, VkDevice d);
 
@@ -91,4 +88,12 @@ bool initVulkanFramebuffers(
     u32 width, u32 height);
 void destroyVulkanFramebuffers(VkFramebuffer** f, u32 amount, VkDevice d);
 
+bool initCommandVulkanBuffer(VkCommandBuffer* cb, VkDevice d, VkCommandPool cp);
+
+bool initVulkanSemaphore(VkSemaphore* s, VkDevice d);
+void destroyVulkanSemaphore(VkSemaphore s, VkDevice d);
+
+bool initVulkanFence(VkFence* f, VkDevice d);
+void destroyVulkanFence(VkFence f, VkDevice d);
+
 #endif

+ 94 - 20
src/VulkanWrapper.c

@@ -6,10 +6,6 @@
 #include "GLFW.h"
 #include "VulkanUtils.h"
 
-// VkCommandBuffer* commandsBuffers;
-// VkSemaphore semaphore;
-// VkSemaphore renderSemaphore;
-
 static VkPhysicalDevice physicalDevice;
 static u32 graphicsFamily = 0;
 static u32 presentFamily = 0;
@@ -25,9 +21,15 @@ static VkShaderModule vertexShaderModule;
 static VkShaderModule fragmentShaderModule;
 static VkPipelineLayout pipelineLayout;
 static VkRenderPass renderPass;
+static VkViewport viewport;
+static VkRect2D scissor;
 static VkPipeline pipeline;
 static VkFramebuffer* framebuffers;
 static VkCommandPool commandPool;
+static VkCommandBuffer commandBuffer;
+static VkSemaphore imageAvailableSemaphore;
+static VkSemaphore renderFinishedSemaphore;
+static VkFence inFlightFence;
 
 static int getSurfaceFormatPoints(const VkSurfaceFormatKHR* sf) {
     if(sf->format == VK_FORMAT_B8G8R8A8_UNORM &&
@@ -229,14 +231,13 @@ static bool initPipeline() {
         .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
         .primitiveRestartEnable = false};
 
-    VkViewport viewport = {
-        .x = 0.0f,
-        .y = 0.0f,
-        .width = (float)swapchainSize.width,
-        .height = (float)swapchainSize.height,
-        .minDepth = 0.0f,
-        .maxDepth = 1.0f};
-    VkRect2D scissor = {.offset = {0, 0}, .extent = swapchainSize};
+    viewport = (VkViewport){.x = 0.0f,
+                            .y = 0.0f,
+                            .width = (float)swapchainSize.width,
+                            .height = (float)swapchainSize.height,
+                            .minDepth = 0.0f,
+                            .maxDepth = 1.0f};
+    scissor = (VkRect2D){.offset = {0, 0}, .extent = swapchainSize};
     VkPipelineViewportStateCreateInfo viewportState = {
         .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
         .viewportCount = 1,
@@ -333,12 +334,22 @@ static bool initRenderPass() {
         .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
         .colorAttachmentCount = 1,
         .pColorAttachments = &ca};
+    VkSubpassDependency dependency = {
+        .srcSubpass = VK_SUBPASS_EXTERNAL,
+        .dstSubpass = 0,
+        .srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+        .dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+        .srcAccessMask = 0,
+        .dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
+    };
     VkRenderPassCreateInfo info = {
         .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
         .attachmentCount = 1,
         .pAttachments = &c,
         .subpassCount = 1,
-        .pSubpasses = &subpass};
+        .pSubpasses = &subpass,
+        .dependencyCount = 1,
+        .pDependencies = &dependency};
     VK_ASSERT(vkCreateRenderPass(device, &info, nullptr, &renderPass));
     return false;
 }
@@ -349,6 +360,28 @@ static bool initCommandPool() {
         .flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,
         .queueFamilyIndex = graphicsFamily};
     VK_ASSERT(vkCreateCommandPool(device, &info, nullptr, &commandPool));
+    return initCommandVulkanBuffer(&commandBuffer, device, commandPool);
+}
+
+static bool fillCommandBuffer(VkCommandBuffer cb, u32 index) {
+    VkCommandBufferBeginInfo info = {
+        .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO};
+    VK_ASSERT(vkBeginCommandBuffer(cb, &info));
+    VkClearValue v = {.color = {.float32 = {0.0f, 0.5f, 0.0f, 1.0f}}};
+    VkRenderPassBeginInfo rInfo = {
+        .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
+        .renderPass = renderPass,
+        .framebuffer = framebuffers[index],
+        .renderArea = {.offset = {0, 0}, .extent = swapchainSize},
+        .clearValueCount = 1,
+        .pClearValues = &v};
+    vkCmdBeginRenderPass(cb, &rInfo, VK_SUBPASS_CONTENTS_INLINE);
+    vkCmdBindPipeline(cb, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
+    vkCmdSetViewport(cb, 0, 1, &viewport);
+    vkCmdSetScissor(cb, 0, 1, &scissor);
+    vkCmdDraw(cb, 3, 1, 0, 0);
+    vkCmdEndRenderPass(cb);
+    VK_ASSERT(vkEndCommandBuffer(cb));
     return false;
 }
 
@@ -361,20 +394,61 @@ bool initVulkan() {
            initVulkanFramebuffers(
                &framebuffers, &images, device, renderPass, swapchainSize.width,
                swapchainSize.height) ||
-           initCommandPool();
-    /*  || initSemaphore(&vk.semaphore) ||
-       initSemaphore(&vk.renderSemaphore)
-     */
+           initCommandPool() ||
+           initVulkanSemaphore(&imageAvailableSemaphore, device) ||
+           initVulkanSemaphore(&renderFinishedSemaphore, device) ||
+           initVulkanFence(&inFlightFence, device);
+}
+
+static bool render() {
+    VK_ASSERT(vkWaitForFences(device, 1, &inFlightFence, true, UINT64_MAX));
+    VK_ASSERT(vkResetFences(device, 1, &inFlightFence));
+
+    uint32_t imageIndex = 0;
+    VK_ASSERT(vkAcquireNextImageKHR(
+        device, swapchain, UINT64_MAX, imageAvailableSemaphore, VK_NULL_HANDLE,
+        &imageIndex));
+
+    vkResetCommandBuffer(commandBuffer, 0);
+    fillCommandBuffer(commandBuffer, imageIndex);
+
+    VkSemaphore waitSemaphores[] = {imageAvailableSemaphore};
+    VkPipelineStageFlags waitStages[] = {
+        VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT};
+    VkSemaphore signalSemaphores[] = {renderFinishedSemaphore};
+    VkSubmitInfo info = {
+        .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
+        .waitSemaphoreCount = 1,
+        .pWaitSemaphores = waitSemaphores,
+        .pWaitDstStageMask = waitStages,
+        .commandBufferCount = 1,
+        .pCommandBuffers = &commandBuffer,
+        .signalSemaphoreCount = 1,
+        .pSignalSemaphores = signalSemaphores};
+    VK_ASSERT(vkQueueSubmit(graphicsQueue, 1, &info, inFlightFence));
+
+    VkPresentInfoKHR presentInfo = {
+        .sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
+        .waitSemaphoreCount = 1,
+        .pWaitSemaphores = signalSemaphores,
+        .swapchainCount = 1,
+        .pSwapchains = &swapchain,
+        .pImageIndices = &imageIndex};
+
+    VK_ASSERT(vkQueuePresentKHR(presentQueue, &presentInfo));
+    return false;
 }
 
 void renderVulkan() {
+    render();
 }
 
 void destroyVulkan(void) {
     if(device != VK_NULL_HANDLE) {
-        //     destroyCommandBuffers();
-        //     destroySemaphore(vk.semaphore);
-        //     destroySemaphore(vk.renderSemaphore);
+        vkDeviceWaitIdle(device);
+        destroyVulkanFence(inFlightFence, device);
+        destroyVulkanSemaphore(imageAvailableSemaphore, device);
+        destroyVulkanSemaphore(renderFinishedSemaphore, device);
         vkDestroyCommandPool(device, commandPool, nullptr);
         destroyVulkanFramebuffers(&framebuffers, images.amount, device);
         vkDestroyPipeline(device, pipeline, nullptr);

+ 1 - 1
test/modules/WindowManagerTests.c

@@ -11,7 +11,7 @@ static Button testButton = 0;
 static Button textButton = 0;
 
 static bool isRunning(void*) {
-    return !shouldWindowClose() && ticks > 0 && !isButtonDown(closeButton);
+    return !shouldWindowClose() && /*ticks > 0 &&*/ !isButtonDown(closeButton);
 }
 
 static void tick(void*) {