diff --git a/include/platform.h b/include/platform.h index e2fe497..d3b5cc4 100644 --- a/include/platform.h +++ b/include/platform.h @@ -4,4 +4,5 @@ namespace platform { std::vector getRequiredExtensions(); + uint32_t getTime(); } diff --git a/include/renderer.h b/include/renderer.h index fa0ff22..4d9ddc7 100644 --- a/include/renderer.h +++ b/include/renderer.h @@ -6,6 +6,12 @@ struct RenderTarget { VkSurfaceKHR surface = nullptr; VkSwapchainKHR swapchain = nullptr; + VkExtent2D extent = {}; + + VkImage* images = nullptr; + VkImageView* imageViews = nullptr; + VkFramebuffer* framebuffers = nullptr; + VkCommandBuffer* commandBuffers = nullptr; VkSemaphore imageAvailableSemaphore = nullptr; @@ -34,6 +40,7 @@ private: #endif void createLogicalDevice(); void createCommandPool(); + void createPresentationRenderPass(); VkInstance instance_ = nullptr; @@ -56,4 +63,6 @@ private: VkQueue graphicsQueue_ = nullptr; VkCommandPool commandPool_ = nullptr; + + VkRenderPass presentationRenderPass_ = nullptr; }; diff --git a/src/main.cpp b/src/main.cpp index 254d070..6113e46 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -16,6 +16,10 @@ std::vector platform::getRequiredExtensions() { return names; } +uint32_t platform::getTime() { + return SDL_GetTicks(); +} + int main(int, char*[]) { window = SDL_CreateWindow("Graph", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 640, 480, SDL_WINDOW_VULKAN); if(!window) diff --git a/src/renderer.cpp b/src/renderer.cpp index a7e4b9c..f026315 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include "platform.h" @@ -15,6 +16,7 @@ Renderer::Renderer() { #endif createLogicalDevice(); createCommandPool(); + createPresentationRenderPass(); } Renderer::~Renderer() { @@ -41,6 +43,23 @@ void Renderer::render(RenderTarget* target) { vkBeginCommandBuffer(commandBuffer, &beginInfo); + VkClearValue clearColor = {}; + clearColor.color.float32[0] = sin((platform::getTime() / 500.0f) * 0.2f) * 0.5f + 0.5f; + clearColor.color.float32[1] = sin((platform::getTime() / 500.0f) * 0.4f) * 0.5f + 0.5f; + clearColor.color.float32[2] = sin((platform::getTime() / 500.0f) * 0.8f) * 0.5f + 0.5f; + + VkRenderPassBeginInfo renderPassBeginInfo = {}; + renderPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; + renderPassBeginInfo.framebuffer = target->framebuffers[imageIndex]; + renderPassBeginInfo.renderPass = presentationRenderPass_; + renderPassBeginInfo.renderArea.extent = target->extent; + renderPassBeginInfo.clearValueCount = 1; + renderPassBeginInfo.pClearValues = &clearColor; + + vkCmdBeginRenderPass(commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); + + vkCmdEndRenderPass(commandBuffer); + vkEndCommandBuffer(commandBuffer); const VkPipelineStageFlags waitStage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; @@ -75,6 +94,8 @@ RenderTarget* Renderer::createSurfaceRenderTarget(VkSurfaceKHR surface) { VkSurfaceCapabilitiesKHR surfaceCapabilities = {}; vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice_, surface, &surfaceCapabilities); + target->extent = surfaceCapabilities.currentExtent; + uint32_t surfaceFormatCount = 0; vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice_, surface, &surfaceFormatCount, nullptr); @@ -113,9 +134,37 @@ RenderTarget* Renderer::createSurfaceRenderTarget(VkSurfaceKHR surface) { uint32_t swapchainImageCount = 0; vkGetSwapchainImagesKHR(device_, target->swapchain, &swapchainImageCount, nullptr); - VkImage* swapchainImages = new VkImage[swapchainImageCount]; - vkGetSwapchainImagesKHR(device_, target->swapchain, &swapchainImageCount, swapchainImages); + target->images = new VkImage[swapchainImageCount]; + vkGetSwapchainImagesKHR(device_, target->swapchain, &swapchainImageCount, target->images); + target->imageViews = new VkImageView[swapchainImageCount]; + for(uint32_t i = 0; i < swapchainImageCount; i++) { + VkImageViewCreateInfo createInfo = {}; + createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; + createInfo.image = target->images[i]; + createInfo.viewType = VK_IMAGE_VIEW_TYPE_2D; + createInfo.format = VK_FORMAT_B8G8R8A8_SRGB; + createInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + createInfo.subresourceRange.levelCount = 1; + createInfo.subresourceRange.layerCount = 1; + + vkCreateImageView(device_, &createInfo, nullptr, &target->imageViews[i]); + } + + target->framebuffers = new VkFramebuffer[swapchainImageCount]; + for(uint32_t i = 0; i < swapchainImageCount; i++) { + VkFramebufferCreateInfo framebufferInfo = {}; + framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; + framebufferInfo.renderPass = presentationRenderPass_; + framebufferInfo.attachmentCount = 1; + framebufferInfo.pAttachments = &target->imageViews[i]; + framebufferInfo.width = target->extent.width; + framebufferInfo.height = target->extent.height; + framebufferInfo.layers = 1; + + vkCreateFramebuffer(device_, &framebufferInfo, nullptr, &target->framebuffers[i]); + } + VkCommandBufferAllocateInfo allocateInfo = {}; allocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; allocateInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; @@ -281,6 +330,36 @@ void Renderer::createCommandPool() { VkCommandPoolCreateInfo poolCreateInfo = {}; poolCreateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; poolCreateInfo.queueFamilyIndex = queueIndices.graphics; + poolCreateInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; vkCreateCommandPool(device_, &poolCreateInfo, nullptr, &commandPool_); } + +void Renderer::createPresentationRenderPass() { + VkAttachmentDescription colorAttachment = {}; + colorAttachment.format = VK_FORMAT_B8G8R8A8_SRGB; + colorAttachment.samples = VK_SAMPLE_COUNT_1_BIT; + colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; + colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; + colorAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + colorAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; + colorAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + colorAttachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; + + VkAttachmentReference colorAttachmentRef = {}; + colorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + + VkSubpassDescription subpass = {}; + subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; + subpass.colorAttachmentCount = 1; + subpass.pColorAttachments = &colorAttachmentRef; + + VkRenderPassCreateInfo renderPassInfo = {}; + renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; + renderPassInfo.attachmentCount = 1; + renderPassInfo.pAttachments = &colorAttachment; + renderPassInfo.subpassCount = 1; + renderPassInfo.pSubpasses = &subpass; + + vkCreateRenderPass(device_, &renderPassInfo, nullptr, &presentationRenderPass_); +}