2018-09-27 20:09:42 -04:00
|
|
|
#include "renderer.h"
|
|
|
|
|
2018-09-27 22:47:56 -04:00
|
|
|
#include <set>
|
|
|
|
#include <vector>
|
2018-09-28 18:10:33 -04:00
|
|
|
#include <iostream>
|
2018-10-15 19:52:16 -04:00
|
|
|
#include <fstream>
|
2018-09-28 18:22:11 -04:00
|
|
|
#include <cstring>
|
2018-10-01 19:39:26 -04:00
|
|
|
#include <cmath>
|
2018-10-18 21:46:48 -04:00
|
|
|
#include <array>
|
2018-11-06 09:08:55 -05:00
|
|
|
#include <stb_image.h>
|
2018-09-27 22:47:56 -04:00
|
|
|
|
2018-09-29 21:03:06 -04:00
|
|
|
#include "platform.h"
|
2018-10-16 08:49:25 -04:00
|
|
|
#include "mesh.h"
|
2018-10-25 08:57:36 -04:00
|
|
|
#include "camera.h"
|
2018-11-06 09:08:55 -05:00
|
|
|
#include "material.h"
|
2018-09-29 21:03:06 -04:00
|
|
|
|
2018-11-08 12:51:32 -05:00
|
|
|
Renderer::Renderer(GraphicsConfig config) : config_(config) {
|
2018-09-27 20:33:45 -04:00
|
|
|
createInstance();
|
2018-09-28 18:10:33 -04:00
|
|
|
#ifdef DEBUG
|
|
|
|
if(enableDebug)
|
|
|
|
createDebugMessenger();
|
|
|
|
#endif
|
2018-09-27 20:33:45 -04:00
|
|
|
createLogicalDevice();
|
2018-10-01 19:14:44 -04:00
|
|
|
createCommandPool();
|
2018-10-01 19:39:26 -04:00
|
|
|
createPresentationRenderPass();
|
2018-10-17 10:06:38 -04:00
|
|
|
createDescriptorPool();
|
2018-11-06 09:08:55 -05:00
|
|
|
createMaterialSetLayout();
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-11-08 08:57:41 -05:00
|
|
|
shadowPass_ = new ShadowPass(*this);
|
2018-10-15 19:52:16 -04:00
|
|
|
worldPass_ = new WorldPass(*this);
|
2018-10-17 10:06:38 -04:00
|
|
|
postPass_ = new PostPass(*this);
|
2018-11-03 07:24:32 -04:00
|
|
|
dofPass_ = new DoFPass(*this);
|
2018-11-05 20:51:23 -05:00
|
|
|
imguiPass_ = new ImGuiPass(*this);
|
2018-11-07 07:20:52 -05:00
|
|
|
skyPass_ = new SkyPass(*this);
|
2018-09-27 20:33:45 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
Renderer::~Renderer() {
|
2018-10-01 20:20:16 -04:00
|
|
|
vkDeviceWaitIdle(device_);
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-11-07 07:20:52 -05:00
|
|
|
delete skyPass_;
|
2018-11-05 20:51:23 -05:00
|
|
|
delete imguiPass_;
|
2018-11-03 07:24:32 -04:00
|
|
|
delete dofPass_;
|
2018-10-17 10:12:34 -04:00
|
|
|
delete postPass_;
|
2018-10-15 19:52:16 -04:00
|
|
|
delete worldPass_;
|
2018-11-08 08:57:41 -05:00
|
|
|
delete shadowPass_;
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-11-06 09:08:55 -05:00
|
|
|
vkDestroyDescriptorSetLayout(device_, materialSetLayout_, nullptr);
|
|
|
|
|
2018-10-17 10:12:34 -04:00
|
|
|
vkDestroyDescriptorPool(device_, descriptorPool_, nullptr);
|
|
|
|
|
2018-10-01 20:20:16 -04:00
|
|
|
vkDestroyRenderPass(device_, presentationRenderPass_, nullptr);
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-10-01 20:20:16 -04:00
|
|
|
vkDestroyCommandPool(device_, commandPool_, nullptr);
|
|
|
|
|
2018-09-28 20:41:48 -04:00
|
|
|
#ifdef DEBUG
|
|
|
|
destroyMessenger_(instance_, messenger_, nullptr);
|
|
|
|
#endif
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-09-28 20:41:48 -04:00
|
|
|
vkDestroyDevice(device_, nullptr);
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-09-27 20:33:45 -04:00
|
|
|
vkDestroyInstance(instance_, nullptr);
|
|
|
|
}
|
|
|
|
|
2018-10-25 08:57:36 -04:00
|
|
|
void Renderer::render(World& world, Camera& camera, RenderTarget* target) {
|
2018-11-05 21:34:50 -05:00
|
|
|
vkAcquireNextImageKHR(device_, target->swapchain, UINT64_MAX, target->imageAvailableSemaphore, nullptr, &target->imageIndex);
|
2018-10-01 19:14:44 -04:00
|
|
|
|
2018-11-05 21:34:50 -05:00
|
|
|
target->currentResource = (target->imageIndex + 1) % numFrameResources;
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-11-05 21:34:50 -05:00
|
|
|
vkWaitForFences(device_, 1, &target->fences[target->currentResource], VK_TRUE, UINT64_MAX);
|
|
|
|
vkResetFences(device_, 1, &target->fences[target->currentResource]);
|
2018-10-25 08:57:36 -04:00
|
|
|
|
2018-11-05 21:34:50 -05:00
|
|
|
VkCommandBuffer commandBuffer = target->commandBuffers[target->currentResource];
|
2018-10-01 19:14:44 -04:00
|
|
|
|
|
|
|
VkCommandBufferBeginInfo beginInfo = {};
|
|
|
|
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
|
|
|
|
|
|
|
vkBeginCommandBuffer(commandBuffer, &beginInfo);
|
|
|
|
|
2018-11-08 08:57:41 -05:00
|
|
|
shadowPass_->render(commandBuffer, world);
|
|
|
|
|
2018-10-15 19:52:16 -04:00
|
|
|
VkViewport viewport = {};
|
|
|
|
viewport.width = target->extent.width;
|
|
|
|
viewport.height = target->extent.height;
|
|
|
|
viewport.maxDepth = 1.0f;
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-10-15 19:52:16 -04:00
|
|
|
vkCmdSetViewport(commandBuffer, 0, 1, &viewport);
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-10-15 19:52:16 -04:00
|
|
|
VkRect2D scissor = {};
|
|
|
|
scissor.extent = target->extent;
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-10-15 19:52:16 -04:00
|
|
|
vkCmdSetScissor(commandBuffer, 0, 1, &scissor);
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-11-07 07:20:52 -05:00
|
|
|
std::array<VkClearValue, 2> clearColor = {};
|
|
|
|
clearColor[1].depthStencil.depth = 1.0f;
|
|
|
|
|
|
|
|
VkRenderPassBeginInfo renderPassBeginInfo = {};
|
|
|
|
renderPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
|
|
|
|
renderPassBeginInfo.framebuffer = target->offscreenFramebuffers[target->currentResource];
|
|
|
|
renderPassBeginInfo.renderPass = worldPass_->getRenderPass();
|
|
|
|
renderPassBeginInfo.renderArea.extent = target->extent;
|
|
|
|
renderPassBeginInfo.clearValueCount = clearColor.size();
|
|
|
|
renderPassBeginInfo.pClearValues = clearColor.data();
|
|
|
|
|
|
|
|
vkCmdBeginRenderPass(commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
|
|
|
|
|
2018-10-25 08:57:36 -04:00
|
|
|
worldPass_->render(commandBuffer, world, camera, target);
|
2018-11-07 07:20:52 -05:00
|
|
|
skyPass_->render(commandBuffer);
|
|
|
|
|
|
|
|
vkCmdEndRenderPass(commandBuffer);
|
|
|
|
|
2018-11-05 21:06:12 -05:00
|
|
|
dofPass_->render(commandBuffer, camera, target);
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-11-03 07:24:32 -04:00
|
|
|
// reset after dof pass
|
|
|
|
vkCmdSetViewport(commandBuffer, 0, 1, &viewport);
|
|
|
|
vkCmdSetScissor(commandBuffer, 0, 1, &scissor);
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-11-07 07:20:52 -05:00
|
|
|
clearColor = {};
|
2018-10-01 19:39:26 -04:00
|
|
|
|
2018-11-07 07:20:52 -05:00
|
|
|
renderPassBeginInfo = {};
|
2018-10-01 19:39:26 -04:00
|
|
|
renderPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
|
2018-11-05 21:34:50 -05:00
|
|
|
renderPassBeginInfo.framebuffer = target->swapchainFramebuffers[target->currentResource];
|
2018-10-01 19:39:26 -04:00
|
|
|
renderPassBeginInfo.renderPass = presentationRenderPass_;
|
|
|
|
renderPassBeginInfo.renderArea.extent = target->extent;
|
|
|
|
renderPassBeginInfo.clearValueCount = 1;
|
2018-11-07 07:20:52 -05:00
|
|
|
renderPassBeginInfo.pClearValues = &clearColor[0];
|
2018-10-01 19:39:26 -04:00
|
|
|
|
|
|
|
vkCmdBeginRenderPass(commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-10-17 10:06:38 -04:00
|
|
|
postPass_->render(commandBuffer, target);
|
2018-11-05 20:51:23 -05:00
|
|
|
imguiPass_->render(commandBuffer, target);
|
2018-10-17 10:06:38 -04:00
|
|
|
|
2018-10-01 19:39:26 -04:00
|
|
|
vkCmdEndRenderPass(commandBuffer);
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-10-01 19:14:44 -04:00
|
|
|
vkEndCommandBuffer(commandBuffer);
|
|
|
|
|
|
|
|
const VkPipelineStageFlags waitStage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-10-01 19:14:44 -04:00
|
|
|
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;
|
|
|
|
|
2018-11-05 21:34:50 -05:00
|
|
|
vkQueueSubmit(graphicsQueue_, 1, &submitInfo, target->fences[target->currentResource]);
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-10-01 19:14:44 -04:00
|
|
|
VkPresentInfoKHR presentInfo = {};
|
|
|
|
presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
|
|
|
|
presentInfo.waitSemaphoreCount = 1;
|
|
|
|
presentInfo.pWaitSemaphores = &target->renderFinishedSemaphore;
|
|
|
|
presentInfo.swapchainCount = 1;
|
|
|
|
presentInfo.pSwapchains = &target->swapchain;
|
2018-11-05 21:34:50 -05:00
|
|
|
presentInfo.pImageIndices = &target->imageIndex;
|
2018-10-01 19:14:44 -04:00
|
|
|
|
|
|
|
vkQueuePresentKHR(graphicsQueue_, &presentInfo);
|
|
|
|
}
|
|
|
|
|
2018-10-01 21:02:27 -04:00
|
|
|
RenderTarget* Renderer::createSurfaceRenderTarget(VkSurfaceKHR surface, RenderTarget* oldTarget) {
|
|
|
|
vkDeviceWaitIdle(device_);
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-10-26 20:56:06 -04:00
|
|
|
auto target = new RenderTarget();
|
2018-09-29 21:03:06 -04:00
|
|
|
target->surface = surface;
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-09-29 21:03:06 -04:00
|
|
|
VkSurfaceCapabilitiesKHR surfaceCapabilities = {};
|
|
|
|
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice_, surface, &surfaceCapabilities);
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-10-01 19:39:26 -04:00
|
|
|
target->extent = surfaceCapabilities.currentExtent;
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-09-29 21:03:06 -04:00
|
|
|
uint32_t surfaceFormatCount = 0;
|
|
|
|
vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice_, surface, &surfaceFormatCount, nullptr);
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-10-26 20:56:06 -04:00
|
|
|
auto surfaceFormats = new VkSurfaceFormatKHR[surfaceFormatCount];
|
2018-09-29 21:03:06 -04:00
|
|
|
vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice_, surface, &surfaceFormatCount, surfaceFormats);
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-09-29 21:28:15 -04:00
|
|
|
uint32_t chosenFormat = 0;
|
|
|
|
for(uint32_t i = 0; i < surfaceFormatCount; i++) {
|
2018-10-16 12:52:50 -04:00
|
|
|
if(surfaceFormats[i].format == VK_FORMAT_B8G8R8A8_SRGB)
|
2018-09-29 21:28:15 -04:00
|
|
|
chosenFormat = i;
|
|
|
|
}
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-10-26 20:56:06 -04:00
|
|
|
VkBool32 supported = VK_FALSE;
|
2018-09-29 21:03:06 -04:00
|
|
|
vkGetPhysicalDeviceSurfaceSupportKHR(physicalDevice_, queueIndices.presentation, surface, &supported);
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-09-29 21:03:06 -04:00
|
|
|
VkSwapchainCreateInfoKHR swapchainCreateInfo = {};
|
|
|
|
swapchainCreateInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
|
|
|
|
swapchainCreateInfo.surface = surface;
|
|
|
|
swapchainCreateInfo.minImageCount = surfaceCapabilities.minImageCount;
|
2018-09-29 21:28:15 -04:00
|
|
|
swapchainCreateInfo.imageColorSpace = surfaceFormats[chosenFormat].colorSpace;
|
|
|
|
swapchainCreateInfo.imageFormat = surfaceFormats[chosenFormat].format;
|
2018-09-29 21:03:06 -04:00
|
|
|
swapchainCreateInfo.imageExtent = surfaceCapabilities.currentExtent;
|
|
|
|
swapchainCreateInfo.imageArrayLayers = 1;
|
2018-10-24 21:13:55 -04:00
|
|
|
swapchainCreateInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
|
2018-09-29 21:03:06 -04:00
|
|
|
swapchainCreateInfo.queueFamilyIndexCount = 1;
|
|
|
|
swapchainCreateInfo.pQueueFamilyIndices = &queueIndices.presentation;
|
|
|
|
swapchainCreateInfo.preTransform = surfaceCapabilities.currentTransform;
|
|
|
|
swapchainCreateInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
|
|
|
|
swapchainCreateInfo.presentMode = VK_PRESENT_MODE_FIFO_KHR;
|
2018-10-26 20:56:06 -04:00
|
|
|
swapchainCreateInfo.clipped = VK_TRUE;
|
2018-10-01 21:02:27 -04:00
|
|
|
|
2018-10-26 20:56:06 -04:00
|
|
|
if(oldTarget != nullptr)
|
2018-10-01 21:02:27 -04:00
|
|
|
swapchainCreateInfo.oldSwapchain = oldTarget->swapchain;
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-09-29 21:03:06 -04:00
|
|
|
vkCreateSwapchainKHR(device_, &swapchainCreateInfo, nullptr, &target->swapchain);
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-10-26 20:56:06 -04:00
|
|
|
if(oldTarget != nullptr)
|
2018-10-01 21:02:27 -04:00
|
|
|
destroyRenderTarget(oldTarget);
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-09-29 21:53:24 -04:00
|
|
|
delete[] surfaceFormats;
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-10-01 19:14:44 -04:00
|
|
|
uint32_t swapchainImageCount = 0;
|
|
|
|
vkGetSwapchainImagesKHR(device_, target->swapchain, &swapchainImageCount, nullptr);
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-10-01 20:20:16 -04:00
|
|
|
target->numImages = swapchainImageCount;
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-10-17 09:28:47 -04:00
|
|
|
target->swapchainImages = new VkImage[swapchainImageCount];
|
|
|
|
vkGetSwapchainImagesKHR(device_, target->swapchain, &swapchainImageCount, target->swapchainImages);
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-10-17 09:28:47 -04:00
|
|
|
// create frame resources
|
|
|
|
target->swapchainImageViews = new VkImageView[swapchainImageCount];
|
|
|
|
target->swapchainFramebuffers = new VkFramebuffer[swapchainImageCount];
|
2018-10-24 19:20:23 -04:00
|
|
|
target->offscreenColorImages = new VkImage[swapchainImageCount];
|
|
|
|
target->offscreenColorMemory = new VkDeviceMemory[swapchainImageCount];
|
|
|
|
target->offscreenColorImageViews = new VkImageView[swapchainImageCount];
|
|
|
|
target->offscreenDepthImages = new VkImage[swapchainImageCount];
|
|
|
|
target->offscreenDepthMemory = new VkDeviceMemory[swapchainImageCount];
|
|
|
|
target->offscreenDepthImageViews = new VkImageView[swapchainImageCount];
|
2018-10-17 09:28:47 -04:00
|
|
|
target->offscreenFramebuffers = new VkFramebuffer[swapchainImageCount];
|
2018-11-03 07:24:32 -04:00
|
|
|
target->nearFieldImages = new VkImage[swapchainImageCount];
|
|
|
|
target->nearFieldMemory = new VkDeviceMemory[swapchainImageCount];
|
|
|
|
target->nearFieldImageViews = new VkImageView[swapchainImageCount];
|
|
|
|
target->nearFieldFramebuffers = new VkFramebuffer[swapchainImageCount];
|
|
|
|
target->farFieldImages = new VkImage[swapchainImageCount];
|
|
|
|
target->farFieldMemory = new VkDeviceMemory[swapchainImageCount];
|
|
|
|
target->farFieldImageViews = new VkImageView[swapchainImageCount];
|
|
|
|
target->farFieldFramebuffers = new VkFramebuffer[swapchainImageCount];
|
2018-11-05 20:51:23 -05:00
|
|
|
target->imguiVertexBuffers = new VkBuffer[swapchainImageCount];
|
|
|
|
target->imguiVertexMemorys = new VkDeviceMemory[swapchainImageCount];
|
|
|
|
target->imguiVertexBufferSizes = new size_t[swapchainImageCount];
|
|
|
|
target->imguiIndexBuffers = new VkBuffer[swapchainImageCount];
|
|
|
|
target->imguiIndexMemorys = new VkDeviceMemory[swapchainImageCount];
|
|
|
|
target->imguiIndexBufferSizes = new size_t[swapchainImageCount];
|
2018-10-01 19:39:26 -04:00
|
|
|
for(uint32_t i = 0; i < swapchainImageCount; i++) {
|
2018-10-17 09:28:47 -04:00
|
|
|
// swapchain image view
|
|
|
|
{
|
|
|
|
VkImageViewCreateInfo createInfo = {};
|
|
|
|
createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
|
|
|
createInfo.image = target->swapchainImages[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->swapchainImageViews[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
// swapchain framebuffer
|
|
|
|
{
|
|
|
|
VkFramebufferCreateInfo framebufferInfo = {};
|
|
|
|
framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
|
|
|
|
framebufferInfo.renderPass = presentationRenderPass_;
|
|
|
|
framebufferInfo.attachmentCount = 1;
|
|
|
|
framebufferInfo.pAttachments = &target->swapchainImageViews[i];
|
|
|
|
framebufferInfo.width = target->extent.width;
|
|
|
|
framebufferInfo.height = target->extent.height;
|
|
|
|
framebufferInfo.layers = 1;
|
|
|
|
|
|
|
|
vkCreateFramebuffer(device_, &framebufferInfo, nullptr, &target->swapchainFramebuffers[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
// offscreen image
|
|
|
|
{
|
|
|
|
VkImageCreateInfo imageCreateInfo = {};
|
|
|
|
imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
|
|
|
imageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
|
|
|
|
imageCreateInfo.format = VK_FORMAT_R32G32B32A32_SFLOAT;
|
|
|
|
imageCreateInfo.extent.width = target->extent.width;
|
|
|
|
imageCreateInfo.extent.height = target->extent.height;
|
|
|
|
imageCreateInfo.extent.depth = 1;
|
|
|
|
imageCreateInfo.mipLevels = 1;
|
|
|
|
imageCreateInfo.arrayLayers = 1;
|
|
|
|
imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
|
|
|
|
imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
|
|
|
|
imageCreateInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
|
|
|
|
|
2018-10-24 19:20:23 -04:00
|
|
|
vkCreateImage(device_, &imageCreateInfo, nullptr, &target->offscreenColorImages[i]);
|
2018-10-17 09:28:47 -04:00
|
|
|
|
|
|
|
VkMemoryRequirements memoryRequirements = {};
|
2018-10-24 19:20:23 -04:00
|
|
|
vkGetImageMemoryRequirements(device_, target->offscreenColorImages[i], &memoryRequirements);
|
2018-10-17 09:28:47 -04:00
|
|
|
|
|
|
|
VkMemoryAllocateInfo allocateInfo = {};
|
|
|
|
allocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
|
|
|
allocateInfo.allocationSize = memoryRequirements.size;
|
|
|
|
allocateInfo.memoryTypeIndex = findMemoryType(memoryRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
|
|
|
|
|
2018-10-24 19:20:23 -04:00
|
|
|
vkAllocateMemory(device_, &allocateInfo, nullptr, &target->offscreenColorMemory[i]);
|
|
|
|
vkBindImageMemory(device_, target->offscreenColorImages[i], target->offscreenColorMemory[i], 0);
|
2018-10-17 09:28:47 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
// offscreen image view
|
|
|
|
{
|
|
|
|
VkImageViewCreateInfo createInfo = {};
|
|
|
|
createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
2018-10-24 19:20:23 -04:00
|
|
|
createInfo.image = target->offscreenColorImages[i];
|
2018-10-17 09:28:47 -04:00
|
|
|
createInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
|
|
|
createInfo.format = VK_FORMAT_R32G32B32A32_SFLOAT;
|
|
|
|
createInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
|
|
|
createInfo.subresourceRange.levelCount = 1;
|
|
|
|
createInfo.subresourceRange.layerCount = 1;
|
|
|
|
|
2018-10-24 19:20:23 -04:00
|
|
|
vkCreateImageView(device_, &createInfo, nullptr, &target->offscreenColorImageViews[i]);
|
|
|
|
}
|
2018-10-25 08:57:36 -04:00
|
|
|
|
2018-10-24 19:20:23 -04:00
|
|
|
// offscreen depth image
|
|
|
|
{
|
|
|
|
VkImageCreateInfo imageCreateInfo = {};
|
|
|
|
imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
|
|
|
imageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
|
|
|
|
imageCreateInfo.format = VK_FORMAT_D32_SFLOAT;
|
|
|
|
imageCreateInfo.extent.width = target->extent.width;
|
|
|
|
imageCreateInfo.extent.height = target->extent.height;
|
|
|
|
imageCreateInfo.extent.depth = 1;
|
|
|
|
imageCreateInfo.mipLevels = 1;
|
|
|
|
imageCreateInfo.arrayLayers = 1;
|
|
|
|
imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
|
|
|
|
imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
|
2018-11-03 07:24:32 -04:00
|
|
|
imageCreateInfo.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
|
2018-10-25 08:57:36 -04:00
|
|
|
|
2018-10-24 19:20:23 -04:00
|
|
|
vkCreateImage(device_, &imageCreateInfo, nullptr, &target->offscreenDepthImages[i]);
|
2018-10-25 08:57:36 -04:00
|
|
|
|
2018-10-24 19:20:23 -04:00
|
|
|
VkMemoryRequirements memoryRequirements = {};
|
|
|
|
vkGetImageMemoryRequirements(device_, target->offscreenDepthImages[i], &memoryRequirements);
|
2018-10-25 08:57:36 -04:00
|
|
|
|
2018-10-24 19:20:23 -04:00
|
|
|
VkMemoryAllocateInfo allocateInfo = {};
|
|
|
|
allocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
|
|
|
allocateInfo.allocationSize = memoryRequirements.size;
|
|
|
|
allocateInfo.memoryTypeIndex = findMemoryType(memoryRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
|
2018-10-25 08:57:36 -04:00
|
|
|
|
2018-10-24 19:20:23 -04:00
|
|
|
vkAllocateMemory(device_, &allocateInfo, nullptr, &target->offscreenDepthMemory[i]);
|
|
|
|
vkBindImageMemory(device_, target->offscreenDepthImages[i], target->offscreenDepthMemory[i], 0);
|
|
|
|
}
|
2018-10-25 08:57:36 -04:00
|
|
|
|
2018-10-24 19:20:23 -04:00
|
|
|
// offscreen depth image view
|
|
|
|
{
|
|
|
|
VkImageViewCreateInfo createInfo = {};
|
|
|
|
createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
|
|
|
createInfo.image = target->offscreenDepthImages[i];
|
|
|
|
createInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
|
|
|
createInfo.format = VK_FORMAT_D32_SFLOAT;
|
|
|
|
createInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
|
|
|
|
createInfo.subresourceRange.levelCount = 1;
|
|
|
|
createInfo.subresourceRange.layerCount = 1;
|
2018-10-25 08:57:36 -04:00
|
|
|
|
2018-10-24 19:20:23 -04:00
|
|
|
vkCreateImageView(device_, &createInfo, nullptr, &target->offscreenDepthImageViews[i]);
|
2018-10-17 09:28:47 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
// offscreen framebuffer
|
|
|
|
{
|
2018-10-24 19:20:23 -04:00
|
|
|
const std::array<VkImageView, 2> attachments = {
|
|
|
|
target->offscreenColorImageViews[i],
|
|
|
|
target->offscreenDepthImageViews[i]
|
|
|
|
};
|
2018-10-25 08:57:36 -04:00
|
|
|
|
2018-10-17 09:28:47 -04:00
|
|
|
VkFramebufferCreateInfo framebufferInfo = {};
|
|
|
|
framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
|
|
|
|
framebufferInfo.renderPass = worldPass_->getRenderPass();
|
2018-10-24 19:20:23 -04:00
|
|
|
framebufferInfo.attachmentCount = attachments.size();
|
|
|
|
framebufferInfo.pAttachments = attachments.data();
|
2018-10-17 09:28:47 -04:00
|
|
|
framebufferInfo.width = target->extent.width;
|
|
|
|
framebufferInfo.height = target->extent.height;
|
|
|
|
framebufferInfo.layers = 1;
|
|
|
|
|
|
|
|
vkCreateFramebuffer(device_, &framebufferInfo, nullptr, &target->offscreenFramebuffers[i]);
|
|
|
|
}
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-11-03 07:24:32 -04:00
|
|
|
// near field color
|
|
|
|
{
|
|
|
|
VkImageCreateInfo imageCreateInfo = {};
|
|
|
|
imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
|
|
|
imageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
|
|
|
|
imageCreateInfo.format = VK_FORMAT_R32G32B32A32_SFLOAT;
|
2018-11-05 21:26:39 -05:00
|
|
|
imageCreateInfo.extent.width = target->extent.width / dofFramebufferDownscaleFactor;
|
|
|
|
imageCreateInfo.extent.height = target->extent.height / dofFramebufferDownscaleFactor;
|
2018-11-03 07:24:32 -04:00
|
|
|
imageCreateInfo.extent.depth = 1;
|
|
|
|
imageCreateInfo.mipLevels = 1;
|
|
|
|
imageCreateInfo.arrayLayers = 1;
|
|
|
|
imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
|
|
|
|
imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
|
|
|
|
imageCreateInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-11-03 07:24:32 -04:00
|
|
|
vkCreateImage(device_, &imageCreateInfo, nullptr, &target->nearFieldImages[i]);
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-11-03 07:24:32 -04:00
|
|
|
VkMemoryRequirements memoryRequirements = {};
|
|
|
|
vkGetImageMemoryRequirements(device_, target->nearFieldImages[i], &memoryRequirements);
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-11-03 07:24:32 -04:00
|
|
|
VkMemoryAllocateInfo allocateInfo = {};
|
|
|
|
allocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
|
|
|
allocateInfo.allocationSize = memoryRequirements.size;
|
|
|
|
allocateInfo.memoryTypeIndex = findMemoryType(memoryRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-11-03 07:24:32 -04:00
|
|
|
vkAllocateMemory(device_, &allocateInfo, nullptr, &target->nearFieldMemory[i]);
|
|
|
|
vkBindImageMemory(device_, target->nearFieldImages[i], target->nearFieldMemory[i], 0);
|
|
|
|
}
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-11-03 07:24:32 -04:00
|
|
|
// near field image view
|
|
|
|
{
|
|
|
|
VkImageViewCreateInfo createInfo = {};
|
|
|
|
createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
|
|
|
createInfo.image = target->nearFieldImages[i];
|
|
|
|
createInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
|
|
|
createInfo.format = VK_FORMAT_R32G32B32A32_SFLOAT;
|
|
|
|
createInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
|
|
|
createInfo.subresourceRange.levelCount = 1;
|
|
|
|
createInfo.subresourceRange.layerCount = 1;
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-11-03 07:24:32 -04:00
|
|
|
vkCreateImageView(device_, &createInfo, nullptr, &target->nearFieldImageViews[i]);
|
|
|
|
}
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-11-03 07:24:32 -04:00
|
|
|
// near field framebuffer
|
2018-11-06 09:08:55 -05:00
|
|
|
{
|
2018-11-03 07:24:32 -04:00
|
|
|
VkFramebufferCreateInfo framebufferInfo = {};
|
|
|
|
framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
|
|
|
|
framebufferInfo.renderPass = dofPass_->getRenderPass();
|
|
|
|
framebufferInfo.attachmentCount = 1;
|
|
|
|
framebufferInfo.pAttachments = &target->nearFieldImageViews[i];
|
2018-11-05 21:26:39 -05:00
|
|
|
framebufferInfo.width = target->extent.width / dofFramebufferDownscaleFactor;
|
|
|
|
framebufferInfo.height = target->extent.height / dofFramebufferDownscaleFactor;
|
2018-11-03 07:24:32 -04:00
|
|
|
framebufferInfo.layers = 1;
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-11-03 07:24:32 -04:00
|
|
|
vkCreateFramebuffer(device_, &framebufferInfo, nullptr, &target->nearFieldFramebuffers[i]);
|
|
|
|
}
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-11-03 07:24:32 -04:00
|
|
|
// far field color
|
|
|
|
{
|
|
|
|
VkImageCreateInfo imageCreateInfo = {};
|
|
|
|
imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
|
|
|
imageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
|
|
|
|
imageCreateInfo.format = VK_FORMAT_R32G32B32A32_SFLOAT;
|
2018-11-05 21:26:39 -05:00
|
|
|
imageCreateInfo.extent.width = target->extent.width / dofFramebufferDownscaleFactor;
|
|
|
|
imageCreateInfo.extent.height = target->extent.height / dofFramebufferDownscaleFactor;
|
2018-11-03 07:24:32 -04:00
|
|
|
imageCreateInfo.extent.depth = 1;
|
|
|
|
imageCreateInfo.mipLevels = 1;
|
|
|
|
imageCreateInfo.arrayLayers = 1;
|
|
|
|
imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
|
|
|
|
imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
|
|
|
|
imageCreateInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-11-03 07:24:32 -04:00
|
|
|
vkCreateImage(device_, &imageCreateInfo, nullptr, &target->farFieldImages[i]);
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-11-03 07:24:32 -04:00
|
|
|
VkMemoryRequirements memoryRequirements = {};
|
|
|
|
vkGetImageMemoryRequirements(device_, target->farFieldImages[i], &memoryRequirements);
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-11-03 07:24:32 -04:00
|
|
|
VkMemoryAllocateInfo allocateInfo = {};
|
|
|
|
allocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
|
|
|
allocateInfo.allocationSize = memoryRequirements.size;
|
|
|
|
allocateInfo.memoryTypeIndex = findMemoryType(memoryRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-11-03 07:24:32 -04:00
|
|
|
vkAllocateMemory(device_, &allocateInfo, nullptr, &target->farFieldMemory[i]);
|
|
|
|
vkBindImageMemory(device_, target->farFieldImages[i], target->farFieldMemory[i], 0);
|
|
|
|
}
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-11-03 07:24:32 -04:00
|
|
|
// far field image view
|
|
|
|
{
|
|
|
|
VkImageViewCreateInfo createInfo = {};
|
|
|
|
createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
|
|
|
createInfo.image = target->farFieldImages[i];
|
|
|
|
createInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
|
|
|
createInfo.format = VK_FORMAT_R32G32B32A32_SFLOAT;
|
|
|
|
createInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
|
|
|
createInfo.subresourceRange.levelCount = 1;
|
|
|
|
createInfo.subresourceRange.layerCount = 1;
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-11-03 07:24:32 -04:00
|
|
|
vkCreateImageView(device_, &createInfo, nullptr, &target->farFieldImageViews[i]);
|
|
|
|
}
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-11-03 07:24:32 -04:00
|
|
|
// far field framebuffer
|
2018-11-06 09:08:55 -05:00
|
|
|
{
|
2018-11-03 07:24:32 -04:00
|
|
|
VkFramebufferCreateInfo framebufferInfo = {};
|
|
|
|
framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
|
|
|
|
framebufferInfo.renderPass = dofPass_->getRenderPass();
|
|
|
|
framebufferInfo.attachmentCount = 1;
|
|
|
|
framebufferInfo.pAttachments = &target->farFieldImageViews[i];
|
2018-11-05 21:26:39 -05:00
|
|
|
framebufferInfo.width = target->extent.width / dofFramebufferDownscaleFactor;
|
|
|
|
framebufferInfo.height = target->extent.height / dofFramebufferDownscaleFactor;
|
2018-11-03 07:24:32 -04:00
|
|
|
framebufferInfo.layers = 1;
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-11-03 07:24:32 -04:00
|
|
|
vkCreateFramebuffer(device_, &framebufferInfo, nullptr, &target->farFieldFramebuffers[i]);
|
|
|
|
}
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-11-05 20:51:23 -05:00
|
|
|
// imgui
|
|
|
|
{
|
|
|
|
target->imguiVertexBuffers[i] = nullptr;
|
|
|
|
target->imguiVertexMemorys[i] = nullptr;
|
|
|
|
target->imguiVertexBufferSizes[i] = 0;
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-11-05 20:51:23 -05:00
|
|
|
target->imguiIndexBuffers[i] = nullptr;
|
|
|
|
target->imguiIndexMemorys[i] = nullptr;
|
|
|
|
target->imguiIndexBufferSizes[i] = 0;
|
|
|
|
}
|
2018-10-01 19:39:26 -04:00
|
|
|
}
|
|
|
|
|
2018-10-17 10:06:38 -04:00
|
|
|
postPass_->createDescriptorSet(target);
|
2018-11-03 07:24:32 -04:00
|
|
|
dofPass_->createDescriptorSet(target);
|
2018-10-17 10:06:38 -04:00
|
|
|
|
2018-10-01 19:14:44 -04:00
|
|
|
VkCommandBufferAllocateInfo allocateInfo = {};
|
|
|
|
allocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
|
|
|
allocateInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
|
|
|
allocateInfo.commandPool = commandPool_;
|
|
|
|
allocateInfo.commandBufferCount = swapchainImageCount;
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-10-01 19:14:44 -04:00
|
|
|
target->commandBuffers = new VkCommandBuffer[swapchainImageCount];
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-10-01 19:14:44 -04:00
|
|
|
vkAllocateCommandBuffers(device_, &allocateInfo, target->commandBuffers);
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-10-01 19:14:44 -04:00
|
|
|
VkSemaphoreCreateInfo semaphoreCreateInfo = {};
|
|
|
|
semaphoreCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-10-01 19:14:44 -04:00
|
|
|
vkCreateSemaphore(device_, &semaphoreCreateInfo, nullptr, &target->imageAvailableSemaphore);
|
|
|
|
vkCreateSemaphore(device_, &semaphoreCreateInfo, nullptr, &target->renderFinishedSemaphore);
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-10-01 19:14:44 -04:00
|
|
|
VkFenceCreateInfo fenceCreateInfo = {};
|
|
|
|
fenceCreateInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
|
|
|
|
fenceCreateInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
|
|
|
|
|
|
|
|
target->fences = new VkFence[swapchainImageCount];
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-10-01 19:14:44 -04:00
|
|
|
for(uint32_t i = 0; i < swapchainImageCount; i++)
|
|
|
|
vkCreateFence(device_, &fenceCreateInfo, nullptr, &target->fences[i]);
|
|
|
|
|
2018-09-29 21:03:06 -04:00
|
|
|
return target;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Renderer::destroyRenderTarget(RenderTarget* target) {
|
2018-10-01 20:20:16 -04:00
|
|
|
vkDeviceWaitIdle(device_);
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-10-01 20:20:16 -04:00
|
|
|
for(uint32_t i = 0; i < target->numImages; i++)
|
|
|
|
vkDestroyFence(device_, target->fences[i], nullptr);
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-10-01 20:20:16 -04:00
|
|
|
delete[] target->fences;
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-10-01 20:20:16 -04:00
|
|
|
vkDestroySemaphore(device_, target->renderFinishedSemaphore, nullptr);
|
|
|
|
vkDestroySemaphore(device_, target->imageAvailableSemaphore, nullptr);
|
|
|
|
|
|
|
|
vkFreeCommandBuffers(device_, commandPool_, target->numImages, target->commandBuffers);
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-10-01 20:20:16 -04:00
|
|
|
delete[] target->commandBuffers;
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-11-05 21:28:39 -05:00
|
|
|
vkFreeDescriptorSets(device_, descriptorPool_, target->numImages, target->dofSets);
|
2018-10-17 10:12:34 -04:00
|
|
|
vkFreeDescriptorSets(device_, descriptorPool_, target->numImages, target->postSets);
|
|
|
|
|
2018-10-01 20:20:16 -04:00
|
|
|
for(uint32_t i = 0; i < target->numImages; i++) {
|
2018-11-05 20:51:23 -05:00
|
|
|
vkFreeMemory(device_, target->imguiIndexMemorys[i], nullptr);
|
|
|
|
vkDestroyBuffer(device_, target->imguiIndexBuffers[i], nullptr);
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-11-05 20:51:23 -05:00
|
|
|
vkFreeMemory(device_, target->imguiVertexMemorys[i], nullptr);
|
|
|
|
vkDestroyBuffer(device_, target->imguiVertexBuffers[i], nullptr);
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-11-03 07:24:32 -04:00
|
|
|
vkDestroyFramebuffer(device_, target->nearFieldFramebuffers[i], nullptr);
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-11-03 07:24:32 -04:00
|
|
|
vkDestroyImageView(device_, target->nearFieldImageViews[i], nullptr);
|
|
|
|
vkFreeMemory(device_, target->nearFieldMemory[i], nullptr);
|
|
|
|
vkDestroyImage(device_, target->nearFieldImages[i], nullptr);
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-11-03 07:24:32 -04:00
|
|
|
vkDestroyFramebuffer(device_, target->farFieldFramebuffers[i], nullptr);
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-11-03 07:24:32 -04:00
|
|
|
vkDestroyImageView(device_, target->farFieldImageViews[i], nullptr);
|
|
|
|
vkFreeMemory(device_, target->farFieldMemory[i], nullptr);
|
|
|
|
vkDestroyImage(device_, target->farFieldImages[i], nullptr);
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-10-17 10:12:34 -04:00
|
|
|
vkDestroyFramebuffer(device_, target->offscreenFramebuffers[i], nullptr);
|
2018-10-25 08:57:36 -04:00
|
|
|
|
2018-10-24 19:20:23 -04:00
|
|
|
vkDestroyImageView(device_, target->offscreenDepthImageViews[i], nullptr);
|
|
|
|
vkFreeMemory(device_, target->offscreenDepthMemory[i], nullptr);
|
|
|
|
vkDestroyImage(device_, target->offscreenDepthImages[i], nullptr);
|
2018-10-25 08:57:36 -04:00
|
|
|
|
2018-10-24 19:20:23 -04:00
|
|
|
vkDestroyImageView(device_, target->offscreenColorImageViews[i], nullptr);
|
|
|
|
vkFreeMemory(device_, target->offscreenColorMemory[i], nullptr);
|
|
|
|
vkDestroyImage(device_, target->offscreenColorImages[i], nullptr);
|
2018-10-17 10:12:34 -04:00
|
|
|
|
2018-10-17 09:28:47 -04:00
|
|
|
vkDestroyFramebuffer(device_, target->swapchainFramebuffers[i], nullptr);
|
|
|
|
vkDestroyImageView(device_, target->swapchainImageViews[i], nullptr);
|
2018-10-01 20:20:16 -04:00
|
|
|
}
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-11-05 20:51:23 -05:00
|
|
|
delete[] target->imguiIndexBufferSizes;
|
|
|
|
delete[] target->imguiIndexMemorys;
|
|
|
|
delete[] target->imguiIndexBuffers;
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-11-05 20:51:23 -05:00
|
|
|
delete[] target->imguiVertexBufferSizes;
|
|
|
|
delete[] target->imguiVertexMemorys;
|
|
|
|
delete[] target->imguiVertexBuffers;
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-11-03 07:24:32 -04:00
|
|
|
delete[] target->nearFieldFramebuffers;
|
|
|
|
delete[] target->nearFieldImageViews;
|
|
|
|
delete[] target->nearFieldMemory;
|
|
|
|
delete[] target->nearFieldImages;
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-11-03 07:24:32 -04:00
|
|
|
delete[] target->farFieldFramebuffers;
|
|
|
|
delete[] target->farFieldImageViews;
|
|
|
|
delete[] target->farFieldMemory;
|
|
|
|
delete[] target->farFieldImages;
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-10-24 19:29:44 -04:00
|
|
|
delete[] target->offscreenFramebuffers;
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-10-24 19:29:44 -04:00
|
|
|
delete[] target->offscreenDepthImageViews;
|
|
|
|
delete[] target->offscreenDepthMemory;
|
|
|
|
delete[] target->offscreenDepthImages;
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-10-24 19:29:44 -04:00
|
|
|
delete[] target->offscreenColorImageViews;
|
|
|
|
delete[] target->offscreenColorMemory;
|
|
|
|
delete[] target->offscreenColorImages;
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-10-17 09:28:47 -04:00
|
|
|
delete[] target->swapchainFramebuffers;
|
|
|
|
delete[] target->swapchainImageViews;
|
|
|
|
delete[] target->swapchainImages;
|
2018-10-25 08:57:36 -04:00
|
|
|
|
2018-11-03 07:24:32 -04:00
|
|
|
delete[] target->dofSets;
|
2018-10-24 19:29:44 -04:00
|
|
|
delete[] target->postSets;
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-09-29 21:03:06 -04:00
|
|
|
vkDestroySwapchainKHR(device_, target->swapchain, nullptr);
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-09-29 21:53:24 -04:00
|
|
|
delete target;
|
2018-09-29 21:03:06 -04:00
|
|
|
}
|
|
|
|
|
2018-10-30 21:13:36 -04:00
|
|
|
void Renderer::takeScreenshot(const char* path, RenderTarget* target) {
|
2018-10-24 21:13:55 -04:00
|
|
|
VkImageCreateInfo imageCreateInfo = {};
|
|
|
|
imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
|
|
|
imageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
|
|
|
|
imageCreateInfo.format = VK_FORMAT_R8G8B8A8_UNORM;
|
|
|
|
imageCreateInfo.extent.width = target->extent.width;
|
|
|
|
imageCreateInfo.extent.height = target->extent.height;
|
|
|
|
imageCreateInfo.extent.depth = 1;
|
|
|
|
imageCreateInfo.mipLevels = 1;
|
|
|
|
imageCreateInfo.arrayLayers = 1;
|
|
|
|
imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
|
|
|
|
imageCreateInfo.tiling = VK_IMAGE_TILING_LINEAR;
|
|
|
|
imageCreateInfo.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
|
2018-10-25 08:57:36 -04:00
|
|
|
|
2018-10-24 21:13:55 -04:00
|
|
|
VkImage image = nullptr;
|
|
|
|
vkCreateImage(device_, &imageCreateInfo, nullptr, &image);
|
2018-10-25 08:57:36 -04:00
|
|
|
|
2018-10-24 21:13:55 -04:00
|
|
|
VkMemoryRequirements memoryRequirements = {};
|
|
|
|
vkGetImageMemoryRequirements(device_, image, &memoryRequirements);
|
2018-10-25 08:57:36 -04:00
|
|
|
|
2018-10-24 21:13:55 -04:00
|
|
|
VkMemoryAllocateInfo allocateInfo = {};
|
|
|
|
allocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
|
|
|
allocateInfo.allocationSize = memoryRequirements.size;
|
|
|
|
allocateInfo.memoryTypeIndex = findMemoryType(memoryRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
|
2018-10-25 08:57:36 -04:00
|
|
|
|
2018-10-24 21:13:55 -04:00
|
|
|
VkDeviceMemory imageMemory = nullptr;
|
|
|
|
vkAllocateMemory(device_, &allocateInfo, nullptr, &imageMemory);
|
|
|
|
vkBindImageMemory(device_, image, imageMemory, 0);
|
2018-10-25 08:57:36 -04:00
|
|
|
|
2018-10-24 21:13:55 -04:00
|
|
|
VkCommandBufferAllocateInfo bufferAllocateInfo = {};
|
|
|
|
bufferAllocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
|
|
|
bufferAllocateInfo.commandPool = commandPool_;
|
|
|
|
bufferAllocateInfo.commandBufferCount = 1;
|
2018-10-25 08:57:36 -04:00
|
|
|
|
2018-10-24 21:13:55 -04:00
|
|
|
VkCommandBuffer commandBuffer = nullptr;
|
|
|
|
vkAllocateCommandBuffers(device_, &bufferAllocateInfo, &commandBuffer);
|
2018-10-25 08:57:36 -04:00
|
|
|
|
2018-10-24 21:13:55 -04:00
|
|
|
VkCommandBufferBeginInfo beginInfo = {};
|
|
|
|
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
2018-10-25 08:57:36 -04:00
|
|
|
|
2018-10-24 21:13:55 -04:00
|
|
|
vkBeginCommandBuffer(commandBuffer, &beginInfo);
|
2018-10-25 08:57:36 -04:00
|
|
|
|
2018-10-24 21:13:55 -04:00
|
|
|
// change screenshot image to transfer dst layout
|
|
|
|
{
|
|
|
|
VkImageMemoryBarrier imageMemoryBarrier = {};
|
|
|
|
imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
|
|
|
|
imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
|
|
|
imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
|
|
|
|
imageMemoryBarrier.image = image;
|
|
|
|
imageMemoryBarrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
|
|
|
imageMemoryBarrier.subresourceRange.layerCount = 1;
|
|
|
|
imageMemoryBarrier.subresourceRange.levelCount = 1;
|
2018-10-25 08:57:36 -04:00
|
|
|
|
2018-10-24 21:13:55 -04:00
|
|
|
vkCmdPipelineBarrier(
|
|
|
|
commandBuffer,
|
|
|
|
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
|
|
|
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
|
|
|
0,
|
|
|
|
0, nullptr,
|
|
|
|
0, nullptr,
|
|
|
|
1, &imageMemoryBarrier);
|
|
|
|
}
|
2018-10-25 08:57:36 -04:00
|
|
|
|
2018-10-26 20:56:06 -04:00
|
|
|
VkImage srcImage = target->swapchainImages[0]; // FIXME: use previous image
|
2018-10-25 08:57:36 -04:00
|
|
|
|
2018-10-24 21:13:55 -04:00
|
|
|
// change offscreen image to transfer src layout
|
|
|
|
{
|
|
|
|
VkImageMemoryBarrier imageMemoryBarrier = {};
|
|
|
|
imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
|
|
|
|
imageMemoryBarrier.srcAccessMask = VK_ACCESS_MEMORY_READ_BIT;
|
|
|
|
imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
|
|
|
|
imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
|
|
|
imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
|
|
|
|
imageMemoryBarrier.image = srcImage;
|
|
|
|
imageMemoryBarrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
|
|
|
imageMemoryBarrier.subresourceRange.layerCount = 1;
|
|
|
|
imageMemoryBarrier.subresourceRange.levelCount = 1;
|
2018-10-25 08:57:36 -04:00
|
|
|
|
2018-10-24 21:13:55 -04:00
|
|
|
vkCmdPipelineBarrier(
|
|
|
|
commandBuffer,
|
|
|
|
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
|
|
|
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
|
|
|
0,
|
|
|
|
0, nullptr,
|
|
|
|
0, nullptr,
|
|
|
|
1, &imageMemoryBarrier);
|
|
|
|
}
|
2018-10-25 08:57:36 -04:00
|
|
|
|
2018-10-24 21:13:55 -04:00
|
|
|
VkImageCopy imageCopy = {};
|
|
|
|
imageCopy.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
|
|
|
imageCopy.srcSubresource.layerCount = 1;
|
|
|
|
imageCopy.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
|
|
|
imageCopy.dstSubresource.layerCount = 1;
|
|
|
|
imageCopy.extent.width = target->extent.width;
|
|
|
|
imageCopy.extent.height = target->extent.height;
|
|
|
|
imageCopy.extent.depth = 1;
|
2018-10-25 08:57:36 -04:00
|
|
|
|
2018-10-24 21:13:55 -04:00
|
|
|
// Issue the copy command
|
|
|
|
vkCmdCopyImage(
|
|
|
|
commandBuffer,
|
|
|
|
srcImage,
|
|
|
|
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
|
|
|
image,
|
|
|
|
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
|
|
|
1,
|
|
|
|
&imageCopy);
|
2018-10-25 08:57:36 -04:00
|
|
|
|
2018-10-24 21:13:55 -04:00
|
|
|
// change screenshot image from transfer dst to general (for mapping memory)
|
|
|
|
{
|
|
|
|
VkImageMemoryBarrier imageMemoryBarrier = {};
|
|
|
|
imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
|
|
|
|
imageMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
|
|
|
imageMemoryBarrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
|
|
|
|
imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
|
|
|
|
imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
|
|
|
|
imageMemoryBarrier.image = image;
|
|
|
|
imageMemoryBarrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
|
|
|
imageMemoryBarrier.subresourceRange.layerCount = 1;
|
|
|
|
imageMemoryBarrier.subresourceRange.levelCount = 1;
|
2018-10-25 08:57:36 -04:00
|
|
|
|
2018-10-24 21:13:55 -04:00
|
|
|
vkCmdPipelineBarrier(
|
|
|
|
commandBuffer,
|
|
|
|
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
|
|
|
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
|
|
|
0,
|
|
|
|
0, nullptr,
|
|
|
|
0, nullptr,
|
|
|
|
1, &imageMemoryBarrier);
|
|
|
|
}
|
2018-10-25 08:57:36 -04:00
|
|
|
|
2018-10-24 21:13:55 -04:00
|
|
|
// change offscreen image layout back to normal
|
|
|
|
{
|
|
|
|
VkImageMemoryBarrier imageMemoryBarrier = {};
|
|
|
|
imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
|
|
|
|
imageMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
|
|
|
|
imageMemoryBarrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
|
|
|
|
imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
|
2018-10-30 21:13:36 -04:00
|
|
|
imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
2018-10-24 21:13:55 -04:00
|
|
|
imageMemoryBarrier.image = srcImage;
|
|
|
|
imageMemoryBarrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
|
|
|
imageMemoryBarrier.subresourceRange.layerCount = 1;
|
|
|
|
imageMemoryBarrier.subresourceRange.levelCount = 1;
|
2018-10-25 08:57:36 -04:00
|
|
|
|
2018-10-24 21:13:55 -04:00
|
|
|
vkCmdPipelineBarrier(
|
|
|
|
commandBuffer,
|
|
|
|
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
|
|
|
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
|
|
|
0,
|
|
|
|
0, nullptr,
|
|
|
|
0, nullptr,
|
|
|
|
1, &imageMemoryBarrier);
|
|
|
|
}
|
2018-10-25 08:57:36 -04:00
|
|
|
|
2018-10-24 21:13:55 -04:00
|
|
|
vkEndCommandBuffer(commandBuffer);
|
2018-10-25 08:57:36 -04:00
|
|
|
|
2018-10-24 21:13:55 -04:00
|
|
|
VkSubmitInfo submitInfo = {};
|
|
|
|
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
|
|
|
submitInfo.commandBufferCount = 1;
|
|
|
|
submitInfo.pCommandBuffers = &commandBuffer;
|
2018-10-25 08:57:36 -04:00
|
|
|
|
2018-10-24 21:13:55 -04:00
|
|
|
VkFenceCreateInfo fenceCreateInfo = {};
|
|
|
|
fenceCreateInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
|
2018-10-25 08:57:36 -04:00
|
|
|
|
2018-10-24 21:13:55 -04:00
|
|
|
VkFence fence = nullptr;
|
|
|
|
vkCreateFence(device_, &fenceCreateInfo, nullptr, &fence);
|
2018-10-25 08:57:36 -04:00
|
|
|
|
2018-10-24 21:13:55 -04:00
|
|
|
vkQueueSubmit(graphicsQueue_, 1, &submitInfo, fence);
|
2018-10-25 08:57:36 -04:00
|
|
|
|
2018-10-26 20:56:06 -04:00
|
|
|
vkWaitForFences(device_, 1, &fence, VK_TRUE, -1);
|
2018-10-24 21:13:55 -04:00
|
|
|
vkDestroyFence(device_, fence, nullptr);
|
2018-10-25 08:57:36 -04:00
|
|
|
|
2018-10-24 21:13:55 -04:00
|
|
|
vkFreeCommandBuffers(device_, commandPool_, 1, &commandBuffer);
|
2018-10-25 08:57:36 -04:00
|
|
|
|
2018-10-24 21:13:55 -04:00
|
|
|
VkImageSubresource subResource = {};
|
|
|
|
subResource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
2018-10-25 08:57:36 -04:00
|
|
|
|
2018-10-24 21:13:55 -04:00
|
|
|
VkSubresourceLayout subResourceLayout = {};
|
|
|
|
vkGetImageSubresourceLayout(device_, image, &subResource, &subResourceLayout);
|
2018-10-25 08:57:36 -04:00
|
|
|
|
2018-10-24 21:13:55 -04:00
|
|
|
const char* data = nullptr;
|
|
|
|
vkMapMemory(device_, imageMemory, 0, VK_WHOLE_SIZE, 0, (void**)&data);
|
|
|
|
data += subResourceLayout.offset;
|
2018-10-25 08:57:36 -04:00
|
|
|
|
2018-10-30 21:13:36 -04:00
|
|
|
std::ofstream file(path, std::ios::out | std::ios::binary);
|
2018-10-24 21:13:55 -04:00
|
|
|
file << "P6\n" << target->extent.width << "\n" << target->extent.height << "\n" << 255 << "\n";
|
2018-10-25 08:57:36 -04:00
|
|
|
|
2018-10-24 21:13:55 -04:00
|
|
|
for(uint32_t y = 0; y < target->extent.height; y++) {
|
2018-10-26 20:56:06 -04:00
|
|
|
auto row = reinterpret_cast<const unsigned int*>(data);
|
2018-10-24 21:13:55 -04:00
|
|
|
for(uint32_t x = 0; x < target->extent.width; x++) {
|
|
|
|
file.write(reinterpret_cast<const char*>(row), 3);
|
|
|
|
row++;
|
|
|
|
}
|
2018-10-25 08:57:36 -04:00
|
|
|
|
2018-10-24 21:13:55 -04:00
|
|
|
data += subResourceLayout.rowPitch;
|
|
|
|
}
|
2018-10-25 08:57:36 -04:00
|
|
|
|
2018-10-24 21:13:55 -04:00
|
|
|
file.close();
|
2018-10-25 08:57:36 -04:00
|
|
|
|
2018-10-24 21:13:55 -04:00
|
|
|
vkUnmapMemory(device_, imageMemory);
|
2018-10-25 08:57:36 -04:00
|
|
|
|
2018-10-24 21:13:55 -04:00
|
|
|
vkFreeMemory(device_, imageMemory, nullptr);
|
|
|
|
vkDestroyImage(device_, image, nullptr);
|
|
|
|
}
|
|
|
|
|
2018-10-15 19:52:16 -04:00
|
|
|
VkShaderModule Renderer::createShader(const char* path) {
|
|
|
|
std::ifstream file(path, std::ios::ate | std::ios::binary);
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-10-15 19:52:16 -04:00
|
|
|
size_t fileSize = (size_t) file.tellg();
|
|
|
|
std::vector<char> buffer(fileSize);
|
|
|
|
file.seekg(0);
|
|
|
|
file.read(buffer.data(), fileSize);
|
|
|
|
file.close();
|
|
|
|
|
|
|
|
VkShaderModuleCreateInfo createInfo = {};
|
|
|
|
createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
|
|
|
|
createInfo.codeSize = buffer.size();
|
|
|
|
createInfo.pCode = reinterpret_cast<const uint32_t*>(buffer.data());
|
|
|
|
|
|
|
|
VkShaderModule shaderModule;
|
|
|
|
vkCreateShaderModule(device_, &createInfo, nullptr, &shaderModule);
|
|
|
|
|
|
|
|
return shaderModule;
|
|
|
|
}
|
|
|
|
|
2018-11-05 20:51:23 -05:00
|
|
|
void Renderer::uploadImageData(VkImage image, int width, int height, VkDeviceSize size, void* src) {
|
|
|
|
VkBuffer stagingBuffer;
|
|
|
|
VkDeviceMemory stagingMemory;
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-11-05 20:51:23 -05:00
|
|
|
VkBufferCreateInfo bufferInfo = {};
|
|
|
|
bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
|
|
|
|
bufferInfo.size = size;
|
|
|
|
bufferInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
|
|
|
|
bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-11-05 20:51:23 -05:00
|
|
|
vkCreateBuffer(device_, &bufferInfo, nullptr, &stagingBuffer);
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-11-05 20:51:23 -05:00
|
|
|
VkMemoryRequirements memRequirements = {};
|
|
|
|
vkGetBufferMemoryRequirements(device_, stagingBuffer, &memRequirements);
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-11-05 20:51:23 -05:00
|
|
|
VkMemoryAllocateInfo allocInfo = {};
|
|
|
|
allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
|
|
|
allocInfo.allocationSize = memRequirements.size;
|
|
|
|
allocInfo.memoryTypeIndex = findMemoryType(memRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-11-05 20:51:23 -05:00
|
|
|
vkAllocateMemory(device_, &allocInfo, nullptr, &stagingMemory);
|
|
|
|
vkBindBufferMemory(device_, stagingBuffer, stagingMemory, 0);
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-11-05 20:51:23 -05:00
|
|
|
void* data;
|
|
|
|
vkMapMemory(device_, stagingMemory, 0, size, 0, &data);
|
|
|
|
memcpy(data, src, size);
|
|
|
|
vkUnmapMemory(device_, stagingMemory);
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-11-05 20:51:23 -05:00
|
|
|
VkCommandBufferAllocateInfo bufferAllocateInfo = {};
|
|
|
|
bufferAllocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
|
|
|
bufferAllocateInfo.commandPool = commandPool_;
|
|
|
|
bufferAllocateInfo.commandBufferCount = 1;
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-11-05 20:51:23 -05:00
|
|
|
VkCommandBuffer commandBuffer = nullptr;
|
|
|
|
vkAllocateCommandBuffers(device_, &bufferAllocateInfo, &commandBuffer);
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-11-05 20:51:23 -05:00
|
|
|
VkCommandBufferBeginInfo beginInfo = {};
|
|
|
|
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-11-05 20:51:23 -05:00
|
|
|
vkBeginCommandBuffer(commandBuffer, &beginInfo);
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-11-05 20:51:23 -05:00
|
|
|
// change layout to transfer dst
|
|
|
|
{
|
|
|
|
VkImageMemoryBarrier imageMemoryBarrier = {};
|
|
|
|
imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
|
|
|
|
imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
|
|
|
imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
|
|
|
|
imageMemoryBarrier.image = image;
|
|
|
|
imageMemoryBarrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
|
|
|
imageMemoryBarrier.subresourceRange.layerCount = 1;
|
|
|
|
imageMemoryBarrier.subresourceRange.levelCount = 1;
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-11-05 20:51:23 -05:00
|
|
|
vkCmdPipelineBarrier(
|
|
|
|
commandBuffer,
|
|
|
|
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
|
|
|
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
|
|
|
0,
|
|
|
|
0, nullptr,
|
|
|
|
0, nullptr,
|
|
|
|
1, &imageMemoryBarrier);
|
|
|
|
}
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-11-05 20:51:23 -05:00
|
|
|
VkBufferImageCopy region = {};
|
|
|
|
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
|
|
|
region.imageSubresource.layerCount = 1;
|
|
|
|
region.imageExtent.width = width;
|
|
|
|
region.imageExtent.height = height;
|
|
|
|
region.imageExtent.depth = 1;
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-11-05 20:51:23 -05:00
|
|
|
vkCmdCopyBufferToImage(
|
|
|
|
commandBuffer,
|
|
|
|
stagingBuffer,
|
|
|
|
image,
|
|
|
|
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
|
|
|
1,
|
|
|
|
®ion
|
|
|
|
);
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-11-05 20:51:23 -05:00
|
|
|
// change layout to shader read only
|
|
|
|
{
|
|
|
|
VkImageMemoryBarrier imageMemoryBarrier = {};
|
|
|
|
imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
|
|
|
|
imageMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
|
|
|
imageMemoryBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
|
|
|
|
imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
|
|
|
|
imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
|
|
|
imageMemoryBarrier.image = image;
|
|
|
|
imageMemoryBarrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
|
|
|
imageMemoryBarrier.subresourceRange.layerCount = 1;
|
|
|
|
imageMemoryBarrier.subresourceRange.levelCount = 1;
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-11-05 20:51:23 -05:00
|
|
|
vkCmdPipelineBarrier(
|
|
|
|
commandBuffer,
|
|
|
|
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
|
|
|
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
|
|
|
|
0,
|
|
|
|
0, nullptr,
|
|
|
|
0, nullptr,
|
|
|
|
1, &imageMemoryBarrier);
|
|
|
|
}
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-11-05 20:51:23 -05:00
|
|
|
vkEndCommandBuffer(commandBuffer);
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-11-05 20:51:23 -05:00
|
|
|
VkSubmitInfo submitInfo = {};
|
|
|
|
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
|
|
|
submitInfo.commandBufferCount = 1;
|
|
|
|
submitInfo.pCommandBuffers = &commandBuffer;
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-11-05 20:51:23 -05:00
|
|
|
VkFenceCreateInfo fenceCreateInfo = {};
|
|
|
|
fenceCreateInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-11-05 20:51:23 -05:00
|
|
|
VkFence fence = nullptr;
|
|
|
|
vkCreateFence(device_, &fenceCreateInfo, nullptr, &fence);
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-11-05 20:51:23 -05:00
|
|
|
vkQueueSubmit(graphicsQueue_, 1, &submitInfo, fence);
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-11-05 20:51:23 -05:00
|
|
|
vkWaitForFences(device_, 1, &fence, VK_TRUE, -1);
|
|
|
|
vkDestroyFence(device_, fence, nullptr);
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-11-05 20:51:23 -05:00
|
|
|
vkFreeCommandBuffers(device_, commandPool_, 1, &commandBuffer);
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-11-05 20:51:23 -05:00
|
|
|
vkFreeMemory(device_, stagingMemory, nullptr);
|
|
|
|
vkDestroyBuffer(device_, stagingBuffer, nullptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-10-16 09:04:57 -04:00
|
|
|
uint32_t Renderer::findMemoryType(const uint32_t typeFilter, const VkMemoryPropertyFlags properties) {
|
2018-10-26 20:56:06 -04:00
|
|
|
for(uint32_t i = 0; i < deviceMemoryProperties_.memoryTypeCount; i++) {
|
|
|
|
if((typeFilter & (1 << i)) && (deviceMemoryProperties_.memoryTypes[i].propertyFlags & properties) == properties) {
|
2018-10-16 08:49:25 -04:00
|
|
|
return i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Renderer::fillMeshBuffers(Mesh* mesh) {
|
|
|
|
// vertex
|
|
|
|
{
|
|
|
|
VkBufferCreateInfo bufferInfo = {};
|
|
|
|
bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
|
|
|
|
bufferInfo.size = sizeof(Vertex) * mesh->vertices.size();
|
|
|
|
bufferInfo.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
|
|
|
|
bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
|
|
|
|
|
|
|
vkCreateBuffer(device_, &bufferInfo, nullptr, &mesh->vertexBuffer);
|
|
|
|
|
|
|
|
VkMemoryRequirements memRequirements;
|
|
|
|
vkGetBufferMemoryRequirements(device_, mesh->vertexBuffer, &memRequirements);
|
|
|
|
|
|
|
|
VkMemoryAllocateInfo allocInfo = {};
|
|
|
|
allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
|
|
|
allocInfo.allocationSize = memRequirements.size;
|
|
|
|
allocInfo.memoryTypeIndex = findMemoryType(memRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
|
|
|
|
|
|
|
|
vkAllocateMemory(device_, &allocInfo, nullptr, &mesh->vertexMemory);
|
|
|
|
vkBindBufferMemory(device_, mesh->vertexBuffer, mesh->vertexMemory, 0);
|
|
|
|
|
|
|
|
void* data;
|
|
|
|
vkMapMemory(device_, mesh->vertexMemory, 0, bufferInfo.size, 0, &data);
|
|
|
|
memcpy(data, mesh->vertices.data(), bufferInfo.size);
|
|
|
|
vkUnmapMemory(device_, mesh->vertexMemory);
|
|
|
|
}
|
|
|
|
|
|
|
|
// index
|
|
|
|
{
|
|
|
|
VkBufferCreateInfo bufferInfo = {};
|
|
|
|
bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
|
|
|
|
bufferInfo.size = sizeof(uint32_t) * mesh->indices.size();
|
|
|
|
bufferInfo.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
|
|
|
|
bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
|
|
|
|
|
|
|
vkCreateBuffer(device_, &bufferInfo, nullptr, &mesh->indexBuffer);
|
|
|
|
|
|
|
|
VkMemoryRequirements memRequirements;
|
|
|
|
vkGetBufferMemoryRequirements(device_, mesh->indexBuffer, &memRequirements);
|
|
|
|
|
|
|
|
VkMemoryAllocateInfo allocInfo = {};
|
|
|
|
allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
|
|
|
allocInfo.allocationSize = memRequirements.size;
|
|
|
|
allocInfo.memoryTypeIndex = findMemoryType(memRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
|
|
|
|
|
|
|
|
vkAllocateMemory(device_, &allocInfo, nullptr, &mesh->indexMemory);
|
|
|
|
vkBindBufferMemory(device_, mesh->indexBuffer, mesh->indexMemory, 0);
|
|
|
|
|
|
|
|
void* data;
|
|
|
|
vkMapMemory(device_, mesh->indexMemory, 0, bufferInfo.size, 0, &data);
|
|
|
|
memcpy(data, mesh->indices.data(), bufferInfo.size);
|
|
|
|
vkUnmapMemory(device_, mesh->indexMemory);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-11-06 09:08:55 -05:00
|
|
|
void Renderer::fillMaterialBuffers(Material* material) {
|
|
|
|
int width = 0, height = 0, channels = 0;
|
|
|
|
stbi_uc* pixels = stbi_load(material->albedoTexturePath.c_str(), &width, &height, &channels, STBI_rgb_alpha);
|
|
|
|
if(pixels == nullptr)
|
|
|
|
return; // haha what
|
|
|
|
|
|
|
|
VkImageCreateInfo imageCreateInfo = {};
|
|
|
|
imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
|
|
|
imageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
|
|
|
|
imageCreateInfo.extent.width = width;
|
|
|
|
imageCreateInfo.extent.height = height;
|
|
|
|
imageCreateInfo.extent.depth = 1;
|
|
|
|
imageCreateInfo.mipLevels = 1;
|
|
|
|
imageCreateInfo.arrayLayers = 1;
|
|
|
|
imageCreateInfo.format = VK_FORMAT_R8G8B8A8_UNORM;
|
|
|
|
imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
|
|
|
|
imageCreateInfo.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
|
|
|
|
imageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
|
|
|
imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
|
|
|
|
|
|
|
|
vkCreateImage(device_, &imageCreateInfo, nullptr, &material->albedoImage);
|
|
|
|
|
|
|
|
VkMemoryRequirements memRequirements;
|
|
|
|
vkGetImageMemoryRequirements(device_, material->albedoImage, &memRequirements);
|
|
|
|
|
|
|
|
VkMemoryAllocateInfo allocInfo = {};
|
|
|
|
allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
|
|
|
allocInfo.allocationSize = memRequirements.size;
|
|
|
|
allocInfo.memoryTypeIndex = findMemoryType(memRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
|
|
|
|
|
|
|
|
vkAllocateMemory(device_, &allocInfo, nullptr, &material->albedoMemory);
|
|
|
|
vkBindImageMemory(device_, material->albedoImage, material->albedoMemory, 0);
|
|
|
|
|
|
|
|
uploadImageData(
|
|
|
|
material->albedoImage,
|
|
|
|
width,
|
|
|
|
height,
|
|
|
|
width * height * 4,
|
|
|
|
pixels
|
|
|
|
);
|
|
|
|
|
|
|
|
stbi_image_free(pixels);
|
|
|
|
|
|
|
|
VkImageViewCreateInfo createInfo = {};
|
|
|
|
createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
|
|
|
createInfo.image = material->albedoImage;
|
|
|
|
createInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
|
|
|
createInfo.format = VK_FORMAT_R8G8B8A8_UNORM;
|
|
|
|
createInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
|
|
|
createInfo.subresourceRange.levelCount = 1;
|
|
|
|
createInfo.subresourceRange.layerCount = 1;
|
|
|
|
|
|
|
|
vkCreateImageView(device_, &createInfo, nullptr, &material->albedoImageView);
|
|
|
|
|
|
|
|
VkSamplerCreateInfo samplerInfo = {};
|
|
|
|
samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
|
|
|
|
samplerInfo.magFilter = VK_FILTER_LINEAR;
|
|
|
|
samplerInfo.minFilter = VK_FILTER_LINEAR;
|
|
|
|
samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
|
|
|
|
samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
|
|
|
|
samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
|
|
|
|
samplerInfo.borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK;
|
|
|
|
samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
|
|
|
|
|
|
|
|
vkCreateSampler(device_, &samplerInfo, nullptr, &material->albedoSampler);
|
|
|
|
|
|
|
|
VkDescriptorSetAllocateInfo setAllocInfo = {};
|
|
|
|
setAllocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
|
|
|
|
setAllocInfo.descriptorPool = descriptorPool_;
|
|
|
|
setAllocInfo.descriptorSetCount = 1;
|
|
|
|
setAllocInfo.pSetLayouts = &materialSetLayout_;
|
|
|
|
|
|
|
|
vkAllocateDescriptorSets(device_, &setAllocInfo, &material->set);
|
|
|
|
|
|
|
|
VkDescriptorImageInfo albedoImageInfo = {};
|
|
|
|
albedoImageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
|
|
|
albedoImageInfo.imageView = material->albedoImageView;
|
|
|
|
albedoImageInfo.sampler = material->albedoSampler;
|
|
|
|
|
|
|
|
VkWriteDescriptorSet albedoDescriptorWrite = {};
|
|
|
|
albedoDescriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
|
|
|
albedoDescriptorWrite.descriptorCount = 1;
|
|
|
|
albedoDescriptorWrite.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
|
|
|
albedoDescriptorWrite.dstSet = material->set;
|
|
|
|
albedoDescriptorWrite.pImageInfo = &albedoImageInfo;
|
|
|
|
|
|
|
|
vkUpdateDescriptorSets(device_, 1, &albedoDescriptorWrite, 0, nullptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Renderer::destroyMaterialBuffers(Material* material) {
|
|
|
|
vkDeviceWaitIdle(device_);
|
|
|
|
|
|
|
|
vkFreeDescriptorSets(device_, descriptorPool_, 1, &material->set);
|
|
|
|
|
|
|
|
vkDestroySampler(device_, material->albedoSampler, nullptr);
|
|
|
|
vkDestroyImageView(device_, material->albedoImageView, nullptr);
|
|
|
|
vkFreeMemory(device_, material->albedoMemory, nullptr);
|
|
|
|
vkDestroyImage(device_, material->albedoImage, nullptr);
|
|
|
|
}
|
|
|
|
|
2018-10-16 09:01:14 -04:00
|
|
|
void Renderer::destroyMeshBuffers(Mesh* mesh) {
|
|
|
|
vkDeviceWaitIdle(device_);
|
|
|
|
|
|
|
|
vkFreeMemory(device_, mesh->indexMemory, nullptr);
|
|
|
|
vkDestroyBuffer(device_, mesh->indexBuffer, nullptr);
|
|
|
|
|
|
|
|
vkFreeMemory(device_, mesh->vertexMemory, nullptr);
|
|
|
|
vkDestroyBuffer(device_, mesh->vertexBuffer, nullptr);
|
|
|
|
}
|
|
|
|
|
2018-09-27 20:33:45 -04:00
|
|
|
void Renderer::createInstance() {
|
2018-09-28 18:10:33 -04:00
|
|
|
uint32_t layerCount = 0;
|
|
|
|
vkEnumerateInstanceLayerProperties(&layerCount, nullptr);
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-10-26 20:56:06 -04:00
|
|
|
auto availableLayers = new VkLayerProperties[layerCount];
|
2018-09-28 18:10:33 -04:00
|
|
|
vkEnumerateInstanceLayerProperties(&layerCount, availableLayers);
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-09-28 18:10:33 -04:00
|
|
|
std::vector<const char*> enabledLayers;
|
|
|
|
#ifdef DEBUG
|
|
|
|
for(uint32_t i = 0; i < layerCount; i++) {
|
2018-10-26 20:56:06 -04:00
|
|
|
if(strcmp(availableLayers[i].layerName, "VK_LAYER_LUNARG_standard_validation") == 0)
|
2018-09-28 18:10:33 -04:00
|
|
|
enabledLayers.push_back("VK_LAYER_LUNARG_standard_validation");
|
|
|
|
}
|
|
|
|
#endif
|
2018-09-28 20:41:48 -04:00
|
|
|
|
|
|
|
delete[] availableLayers;
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-09-28 18:10:33 -04:00
|
|
|
uint32_t extensionCount = 0;
|
|
|
|
vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, nullptr);
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-10-26 20:56:06 -04:00
|
|
|
auto availableExtensions = new VkExtensionProperties[extensionCount];
|
2018-09-28 18:10:33 -04:00
|
|
|
vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, availableExtensions);
|
|
|
|
|
|
|
|
std::vector<const char*> enabledExtensions;
|
|
|
|
#ifdef DEBUG
|
|
|
|
for(uint32_t i = 0; i < extensionCount; i++) {
|
2018-10-26 20:56:06 -04:00
|
|
|
if(strcmp(availableExtensions[i].extensionName, "VK_EXT_debug_utils") == 0) {
|
2018-09-28 18:10:33 -04:00
|
|
|
enabledExtensions.push_back("VK_EXT_debug_utils");
|
|
|
|
enableDebug = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
2018-09-28 20:41:48 -04:00
|
|
|
|
|
|
|
delete[] availableExtensions;
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-09-29 21:03:06 -04:00
|
|
|
auto requiredExtensions = platform::getRequiredExtensions();
|
|
|
|
enabledExtensions.insert(enabledExtensions.end(), requiredExtensions.begin(), requiredExtensions.end());
|
|
|
|
|
2018-09-27 20:09:42 -04:00
|
|
|
VkInstanceCreateInfo instanceCreateInfo = {};
|
|
|
|
instanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
|
2018-09-28 18:10:33 -04:00
|
|
|
instanceCreateInfo.enabledLayerCount = enabledLayers.size();
|
|
|
|
instanceCreateInfo.ppEnabledLayerNames = enabledLayers.data();
|
|
|
|
instanceCreateInfo.enabledExtensionCount = enabledExtensions.size();
|
|
|
|
instanceCreateInfo.ppEnabledExtensionNames = enabledExtensions.data();
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-09-27 20:09:42 -04:00
|
|
|
vkCreateInstance(&instanceCreateInfo, nullptr, &instance_);
|
|
|
|
}
|
|
|
|
|
2018-09-28 18:10:33 -04:00
|
|
|
#ifdef DEBUG
|
|
|
|
void Renderer::createDebugMessenger() {
|
|
|
|
createMessenger_ = (PFN_vkCreateDebugUtilsMessengerEXT)vkGetInstanceProcAddr(instance_, "vkCreateDebugUtilsMessengerEXT");
|
2018-09-28 20:41:48 -04:00
|
|
|
destroyMessenger_ = (PFN_vkDestroyDebugUtilsMessengerEXT)vkGetInstanceProcAddr(instance_, "vkDestroyDebugUtilsMessengerEXT");
|
|
|
|
|
2018-09-28 18:10:33 -04:00
|
|
|
VkDebugUtilsMessengerCreateInfoEXT messengerCreateInfo = {};
|
|
|
|
messengerCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT;
|
|
|
|
messengerCreateInfo.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT;
|
|
|
|
messengerCreateInfo.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT;
|
|
|
|
messengerCreateInfo.pfnUserCallback = [](VkDebugUtilsMessageSeverityFlagBitsEXT, unsigned int, const VkDebugUtilsMessengerCallbackDataEXT* callback, void*) -> unsigned int {
|
|
|
|
std::cout << callback->pMessage << std::endl;
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-09-28 18:10:33 -04:00
|
|
|
return VK_SUCCESS;
|
|
|
|
};
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-09-28 18:10:33 -04:00
|
|
|
createMessenger_(instance_, &messengerCreateInfo, nullptr, &messenger_);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2018-09-27 20:33:45 -04:00
|
|
|
void Renderer::createLogicalDevice() {
|
|
|
|
uint32_t physicalDeviceCount = 0;
|
|
|
|
vkEnumeratePhysicalDevices(instance_, &physicalDeviceCount, nullptr);
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-10-26 20:56:06 -04:00
|
|
|
auto physicalDevices = new VkPhysicalDevice[physicalDeviceCount];
|
2018-09-27 20:33:45 -04:00
|
|
|
vkEnumeratePhysicalDevices(instance_, &physicalDeviceCount, physicalDevices);
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-09-27 20:33:45 -04:00
|
|
|
for(uint32_t i = 0; i < physicalDeviceCount; i++) {
|
|
|
|
VkPhysicalDeviceProperties properties = {};
|
|
|
|
vkGetPhysicalDeviceProperties(physicalDevices[i], &properties);
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-09-29 21:03:06 -04:00
|
|
|
physicalDevice_ = physicalDevices[i];
|
2018-09-27 20:33:45 -04:00
|
|
|
}
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-09-28 20:41:48 -04:00
|
|
|
delete[] physicalDevices;
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-10-16 09:04:57 -04:00
|
|
|
vkGetPhysicalDeviceMemoryProperties(physicalDevice_, &deviceMemoryProperties_);
|
|
|
|
|
2018-09-27 22:47:56 -04:00
|
|
|
uint32_t queueFamilyPropertiesCount = 0;
|
2018-09-29 21:03:06 -04:00
|
|
|
vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice_, &queueFamilyPropertiesCount, nullptr);
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-10-26 20:56:06 -04:00
|
|
|
auto queueFamilyProperties = new VkQueueFamilyProperties[queueFamilyPropertiesCount];
|
2018-09-29 21:03:06 -04:00
|
|
|
vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice_, &queueFamilyPropertiesCount, queueFamilyProperties);
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-09-27 22:47:56 -04:00
|
|
|
for(uint32_t i = 0; i < queueFamilyPropertiesCount; i++) {
|
|
|
|
if(queueFamilyProperties[i].queueFlags & VK_QUEUE_GRAPHICS_BIT)
|
2018-09-29 21:20:58 -04:00
|
|
|
queueIndices.graphics = i;
|
2018-09-27 22:47:56 -04:00
|
|
|
}
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-09-28 20:41:48 -04:00
|
|
|
delete[] queueFamilyProperties;
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-09-29 21:20:58 -04:00
|
|
|
queueIndices.presentation = queueIndices.graphics; //FIXME: this may not always be true!!
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-09-29 21:20:58 -04:00
|
|
|
const std::set<uint32_t> queueFamilyIndices = {queueIndices.graphics};
|
2018-09-27 22:47:56 -04:00
|
|
|
std::vector<VkDeviceQueueCreateInfo> deviceQueueCreateInfos;
|
|
|
|
for(auto queueFamilyIndex : queueFamilyIndices) {
|
|
|
|
const float priority = 1.0f;
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-09-27 22:47:56 -04:00
|
|
|
VkDeviceQueueCreateInfo queueCreateInfo = {};
|
2018-09-28 18:22:57 -04:00
|
|
|
queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
|
2018-09-27 22:47:56 -04:00
|
|
|
queueCreateInfo.queueFamilyIndex = queueFamilyIndex;
|
|
|
|
queueCreateInfo.queueCount = 1;
|
|
|
|
queueCreateInfo.pQueuePriorities = &priority;
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-09-27 22:47:56 -04:00
|
|
|
deviceQueueCreateInfos.push_back(queueCreateInfo);
|
|
|
|
}
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-09-29 21:03:06 -04:00
|
|
|
const std::vector<const char*> enabledExtensions = {"VK_KHR_swapchain"};
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-09-27 20:33:45 -04:00
|
|
|
VkDeviceCreateInfo deviceCreateInfo = {};
|
|
|
|
deviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
|
2018-09-27 22:47:56 -04:00
|
|
|
deviceCreateInfo.queueCreateInfoCount = deviceQueueCreateInfos.size();
|
|
|
|
deviceCreateInfo.pQueueCreateInfos = deviceQueueCreateInfos.data();
|
2018-09-29 21:03:06 -04:00
|
|
|
deviceCreateInfo.enabledExtensionCount = enabledExtensions.size();
|
|
|
|
deviceCreateInfo.ppEnabledExtensionNames = enabledExtensions.data();
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-09-29 21:03:06 -04:00
|
|
|
vkCreateDevice(physicalDevice_, &deviceCreateInfo, nullptr, &device_);
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-09-29 21:20:58 -04:00
|
|
|
vkGetDeviceQueue(device_, queueIndices.graphics, 0, &graphicsQueue_);
|
2018-09-27 20:09:42 -04:00
|
|
|
}
|
2018-10-01 19:14:44 -04:00
|
|
|
|
|
|
|
void Renderer::createCommandPool() {
|
|
|
|
VkCommandPoolCreateInfo poolCreateInfo = {};
|
|
|
|
poolCreateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
|
|
|
|
poolCreateInfo.queueFamilyIndex = queueIndices.graphics;
|
2018-10-01 19:39:26 -04:00
|
|
|
poolCreateInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
|
2018-10-16 08:18:19 -04:00
|
|
|
|
2018-10-01 19:14:44 -04:00
|
|
|
vkCreateCommandPool(device_, &poolCreateInfo, nullptr, &commandPool_);
|
|
|
|
}
|
2018-10-01 19:39:26 -04:00
|
|
|
|
|
|
|
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;
|
|
|
|
|
2018-11-06 13:47:33 -05:00
|
|
|
std::array<VkSubpassDependency, 1> dependencies;
|
|
|
|
dependencies[0].srcSubpass = VK_SUBPASS_EXTERNAL;
|
|
|
|
dependencies[0].dstSubpass = 0;
|
|
|
|
dependencies[0].srcStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
|
|
|
|
dependencies[0].dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
|
|
|
dependencies[0].srcAccessMask = VK_ACCESS_MEMORY_READ_BIT;
|
|
|
|
dependencies[0].dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
|
|
|
dependencies[0].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
|
|
|
|
|
2018-10-01 19:39:26 -04:00
|
|
|
VkRenderPassCreateInfo renderPassInfo = {};
|
|
|
|
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
|
|
|
|
renderPassInfo.attachmentCount = 1;
|
|
|
|
renderPassInfo.pAttachments = &colorAttachment;
|
|
|
|
renderPassInfo.subpassCount = 1;
|
|
|
|
renderPassInfo.pSubpasses = &subpass;
|
2018-11-06 13:47:33 -05:00
|
|
|
renderPassInfo.dependencyCount = dependencies.size();
|
|
|
|
renderPassInfo.pDependencies = dependencies.data();
|
2018-10-01 19:39:26 -04:00
|
|
|
|
|
|
|
vkCreateRenderPass(device_, &renderPassInfo, nullptr, &presentationRenderPass_);
|
|
|
|
}
|
2018-10-17 10:06:38 -04:00
|
|
|
|
|
|
|
void Renderer::createDescriptorPool() {
|
2018-10-18 21:46:48 -04:00
|
|
|
const std::array<VkDescriptorPoolSize, 2> poolSizes = {
|
2018-11-03 07:24:32 -04:00
|
|
|
VkDescriptorPoolSize{VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 25},
|
|
|
|
VkDescriptorPoolSize{VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 25}
|
2018-10-18 21:46:48 -04:00
|
|
|
};
|
2018-10-17 10:06:38 -04:00
|
|
|
|
|
|
|
VkDescriptorPoolCreateInfo poolInfo = {};
|
|
|
|
poolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
|
2018-10-17 10:12:34 -04:00
|
|
|
poolInfo.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
|
2018-10-18 21:46:48 -04:00
|
|
|
poolInfo.poolSizeCount = poolSizes.size();
|
|
|
|
poolInfo.pPoolSizes = poolSizes.data();
|
2018-11-03 07:24:32 -04:00
|
|
|
poolInfo.maxSets = 25;
|
2018-10-17 10:06:38 -04:00
|
|
|
|
|
|
|
vkCreateDescriptorPool(device_, &poolInfo, nullptr, &descriptorPool_);
|
|
|
|
}
|
2018-11-06 09:08:55 -05:00
|
|
|
|
|
|
|
void Renderer::createMaterialSetLayout() {
|
|
|
|
VkDescriptorSetLayoutBinding albedoSamplerBinding = {};
|
|
|
|
albedoSamplerBinding.descriptorCount = 1;
|
|
|
|
albedoSamplerBinding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
|
|
|
albedoSamplerBinding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
|
|
|
|
|
|
|
|
VkDescriptorSetLayoutCreateInfo createInfo = {};
|
|
|
|
createInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
|
|
|
|
createInfo.bindingCount = 1;
|
|
|
|
createInfo.pBindings = &albedoSamplerBinding;
|
|
|
|
|
|
|
|
vkCreateDescriptorSetLayout(device_, &createInfo, nullptr, &materialSetLayout_);
|
|
|
|
}
|