Archived
1
Fork 0
This repository has been archived on 2025-04-12. You can view files and clone it, but cannot push or open issues or pull requests.
graph/src/renderer.cpp

519 lines
20 KiB
C++
Raw Normal View History

#include "renderer.h"
2018-09-27 22:47:56 -04:00
#include <set>
#include <vector>
#include <iostream>
2018-10-15 19:52:16 -04:00
#include <fstream>
2018-09-28 18:22:11 -04:00
#include <cstring>
#include <cmath>
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-09-29 21:03:06 -04:00
Renderer::Renderer() {
2018-09-27 20:33:45 -04:00
createInstance();
#ifdef DEBUG
if(enableDebug)
createDebugMessenger();
#endif
2018-09-27 20:33:45 -04:00
createLogicalDevice();
2018-10-01 19:14:44 -04:00
createCommandPool();
createPresentationRenderPass();
2018-10-16 08:18:19 -04:00
2018-10-15 19:52:16 -04:00
worldPass_ = new WorldPass(*this);
2018-09-27 20:33:45 -04:00
}
Renderer::~Renderer() {
vkDeviceWaitIdle(device_);
2018-10-16 08:18:19 -04:00
2018-10-15 19:52:16 -04:00
delete worldPass_;
2018-10-16 08:18:19 -04:00
vkDestroyRenderPass(device_, presentationRenderPass_, nullptr);
2018-10-16 08:18:19 -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-16 08:49:25 -04:00
void Renderer::render(World& world, RenderTarget* target) {
2018-10-01 19:14:44 -04:00
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]);
2018-10-16 08:18:19 -04:00
2018-10-01 19:14:44 -04:00
const VkCommandBuffer commandBuffer = target->commandBuffers[imageIndex];
VkCommandBufferBeginInfo beginInfo = {};
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
vkBeginCommandBuffer(commandBuffer, &beginInfo);
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
VkClearValue clearColor = {};
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);
2018-10-16 08:18:19 -04:00
worldPass_->render(commandBuffer, world, target);
2018-10-16 08:18:19 -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;
vkQueueSubmit(graphicsQueue_, 1, &submitInfo, target->fences[imageIndex]);
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;
presentInfo.pImageIndices = &imageIndex;
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-09-29 21:03:06 -04:00
RenderTarget* target = new RenderTarget();
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
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-09-29 21:03:06 -04:00
VkSurfaceFormatKHR* surfaceFormats = new VkSurfaceFormatKHR[surfaceFormatCount];
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-09-29 21:03:06 -04:00
VkBool32 supported = false;
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;
swapchainCreateInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
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;
swapchainCreateInfo.clipped = true;
2018-10-01 21:02:27 -04:00
if(oldTarget)
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-01 21:02:27 -04:00
if(oldTarget)
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
target->numImages = swapchainImageCount;
2018-10-16 08:18:19 -04:00
target->images = new VkImage[swapchainImageCount];
vkGetSwapchainImagesKHR(device_, target->swapchain, &swapchainImageCount, target->images);
2018-10-16 08:18:19 -04:00
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]);
}
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) {
vkDeviceWaitIdle(device_);
2018-10-16 08:18:19 -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
delete[] target->fences;
2018-10-16 08:18:19 -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
delete[] target->commandBuffers;
2018-10-16 08:18:19 -04:00
for(uint32_t i = 0; i < target->numImages; i++) {
vkDestroyFramebuffer(device_, target->framebuffers[i], nullptr);
vkDestroyImageView(device_, target->imageViews[i], nullptr);
}
2018-10-16 08:18:19 -04:00
delete[] target->framebuffers;
delete[] target->imageViews;
delete[] target->images;
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-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;
}
uint32_t Renderer::findMemoryType(const uint32_t typeFilter, const VkMemoryPropertyFlags properties) {
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-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() {
uint32_t layerCount = 0;
vkEnumerateInstanceLayerProperties(&layerCount, nullptr);
2018-10-16 08:18:19 -04:00
VkLayerProperties* availableLayers = new VkLayerProperties[layerCount];
vkEnumerateInstanceLayerProperties(&layerCount, availableLayers);
2018-10-16 08:18:19 -04:00
std::vector<const char*> enabledLayers;
#ifdef DEBUG
for(uint32_t i = 0; i < layerCount; i++) {
if(!strcmp(availableLayers[i].layerName, "VK_LAYER_LUNARG_standard_validation"))
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
uint32_t extensionCount = 0;
vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, nullptr);
2018-10-16 08:18:19 -04:00
VkExtensionProperties* availableExtensions = new VkExtensionProperties[extensionCount];
vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, availableExtensions);
std::vector<const char*> enabledExtensions;
#ifdef DEBUG
for(uint32_t i = 0; i < extensionCount; i++) {
if(!strcmp(availableExtensions[i].extensionName, "VK_EXT_debug_utils")) {
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());
VkInstanceCreateInfo instanceCreateInfo = {};
instanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
instanceCreateInfo.enabledLayerCount = enabledLayers.size();
instanceCreateInfo.ppEnabledLayerNames = enabledLayers.data();
instanceCreateInfo.enabledExtensionCount = enabledExtensions.size();
instanceCreateInfo.ppEnabledExtensionNames = enabledExtensions.data();
2018-10-16 08:18:19 -04:00
vkCreateInstance(&instanceCreateInfo, nullptr, &instance_);
}
#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");
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
return VK_SUCCESS;
};
2018-10-16 08:18:19 -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-09-27 20:33:45 -04:00
VkPhysicalDevice* physicalDevices = new VkPhysicalDevice[physicalDeviceCount];
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
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-09-27 22:47:56 -04:00
VkQueueFamilyProperties* 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 = {};
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-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;
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_);
}
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_);
}