|  | @@ -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);
 |