diff --git a/include/renderer.h b/include/renderer.h index 4b502d3..fa0ff22 100644 --- a/include/renderer.h +++ b/include/renderer.h @@ -5,6 +5,12 @@ struct RenderTarget { VkSurfaceKHR surface = nullptr; VkSwapchainKHR swapchain = nullptr; + + VkCommandBuffer* commandBuffers = nullptr; + + VkSemaphore imageAvailableSemaphore = nullptr; + VkSemaphore renderFinishedSemaphore = nullptr; + VkFence* fences = nullptr; }; class Renderer { @@ -12,6 +18,8 @@ public: Renderer(); ~Renderer(); + void render(RenderTarget* target); + RenderTarget* createSurfaceRenderTarget(VkSurfaceKHR surface); void destroyRenderTarget(RenderTarget* target); @@ -25,6 +33,7 @@ private: void createDebugMessenger(); #endif void createLogicalDevice(); + void createCommandPool(); VkInstance instance_ = nullptr; @@ -45,4 +54,6 @@ private: } queueIndices; VkQueue graphicsQueue_ = nullptr; + + VkCommandPool commandPool_ = nullptr; }; diff --git a/src/main.cpp b/src/main.cpp index a84dc31..254d070 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -35,6 +35,8 @@ int main(int, char*[]) { if(event.type == SDL_QUIT) running = false; } + + renderer->render(target); } renderer->destroyRenderTarget(target); diff --git a/src/renderer.cpp b/src/renderer.cpp index 3702384..a7e4b9c 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -14,6 +14,7 @@ Renderer::Renderer() { createDebugMessenger(); #endif createLogicalDevice(); + createCommandPool(); } Renderer::~Renderer() { @@ -26,6 +27,47 @@ Renderer::~Renderer() { vkDestroyInstance(instance_, nullptr); } +void Renderer::render(RenderTarget* target) { + uint32_t imageIndex = 0; + vkAcquireNextImageKHR(device_, target->swapchain, UINT64_MAX, target->imageAvailableSemaphore, nullptr, &imageIndex); + + vkWaitForFences(device_, 1, &target->fences[imageIndex], true, UINT64_MAX); + vkResetFences(device_, 1, &target->fences[imageIndex]); + + const VkCommandBuffer commandBuffer = target->commandBuffers[imageIndex]; + + VkCommandBufferBeginInfo beginInfo = {}; + beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + + vkBeginCommandBuffer(commandBuffer, &beginInfo); + + vkEndCommandBuffer(commandBuffer); + + const VkPipelineStageFlags waitStage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + + VkSubmitInfo submitInfo = {}; + submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + submitInfo.waitSemaphoreCount = 1; + submitInfo.pWaitSemaphores = &target->imageAvailableSemaphore; + submitInfo.pWaitDstStageMask = &waitStage; + submitInfo.commandBufferCount = 1; + submitInfo.pCommandBuffers = &commandBuffer; + submitInfo.signalSemaphoreCount = 1; + submitInfo.pSignalSemaphores = &target->renderFinishedSemaphore; + + vkQueueSubmit(graphicsQueue_, 1, &submitInfo, target->fences[imageIndex]); + + VkPresentInfoKHR presentInfo = {}; + presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; + presentInfo.waitSemaphoreCount = 1; + presentInfo.pWaitSemaphores = &target->renderFinishedSemaphore; + presentInfo.swapchainCount = 1; + presentInfo.pSwapchains = &target->swapchain; + presentInfo.pImageIndices = &imageIndex; + + vkQueuePresentKHR(graphicsQueue_, &presentInfo); +} + RenderTarget* Renderer::createSurfaceRenderTarget(VkSurfaceKHR surface) { RenderTarget* target = new RenderTarget(); target->surface = surface; @@ -68,6 +110,37 @@ RenderTarget* Renderer::createSurfaceRenderTarget(VkSurfaceKHR surface) { delete[] surfaceFormats; + uint32_t swapchainImageCount = 0; + vkGetSwapchainImagesKHR(device_, target->swapchain, &swapchainImageCount, nullptr); + + VkImage* swapchainImages = new VkImage[swapchainImageCount]; + vkGetSwapchainImagesKHR(device_, target->swapchain, &swapchainImageCount, swapchainImages); + + VkCommandBufferAllocateInfo allocateInfo = {}; + allocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; + allocateInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; + allocateInfo.commandPool = commandPool_; + allocateInfo.commandBufferCount = swapchainImageCount; + + target->commandBuffers = new VkCommandBuffer[swapchainImageCount]; + + vkAllocateCommandBuffers(device_, &allocateInfo, target->commandBuffers); + + VkSemaphoreCreateInfo semaphoreCreateInfo = {}; + semaphoreCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; + + vkCreateSemaphore(device_, &semaphoreCreateInfo, nullptr, &target->imageAvailableSemaphore); + vkCreateSemaphore(device_, &semaphoreCreateInfo, nullptr, &target->renderFinishedSemaphore); + + VkFenceCreateInfo fenceCreateInfo = {}; + fenceCreateInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; + fenceCreateInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT; + + target->fences = new VkFence[swapchainImageCount]; + + for(uint32_t i = 0; i < swapchainImageCount; i++) + vkCreateFence(device_, &fenceCreateInfo, nullptr, &target->fences[i]); + return target; } @@ -203,3 +276,11 @@ void Renderer::createLogicalDevice() { vkGetDeviceQueue(device_, queueIndices.graphics, 0, &graphicsQueue_); } + +void Renderer::createCommandPool() { + VkCommandPoolCreateInfo poolCreateInfo = {}; + poolCreateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; + poolCreateInfo.queueFamilyIndex = queueIndices.graphics; + + vkCreateCommandPool(device_, &poolCreateInfo, nullptr, &commandPool_); +}