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-09-28 18:22:11 -04:00
|
|
|
#include <cstring>
|
2018-09-27 22:47:56 -04:00
|
|
|
|
2018-09-29 21:03:06 -04:00
|
|
|
#include "platform.h"
|
|
|
|
|
2018-09-27 20:09:42 -04:00
|
|
|
Renderer::Renderer() {
|
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();
|
|
|
|
}
|
|
|
|
|
|
|
|
Renderer::~Renderer() {
|
2018-09-28 20:41:48 -04:00
|
|
|
#ifdef DEBUG
|
|
|
|
destroyMessenger_(instance_, messenger_, nullptr);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
vkDestroyDevice(device_, nullptr);
|
|
|
|
|
2018-09-27 20:33:45 -04:00
|
|
|
vkDestroyInstance(instance_, nullptr);
|
|
|
|
}
|
|
|
|
|
2018-09-29 21:03:06 -04:00
|
|
|
RenderTarget* Renderer::createSurfaceRenderTarget(VkSurfaceKHR surface) {
|
|
|
|
RenderTarget* target = new RenderTarget();
|
|
|
|
target->surface = surface;
|
|
|
|
|
|
|
|
VkSurfaceCapabilitiesKHR surfaceCapabilities = {};
|
|
|
|
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice_, surface, &surfaceCapabilities);
|
|
|
|
|
|
|
|
uint32_t surfaceFormatCount = 0;
|
|
|
|
vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice_, surface, &surfaceFormatCount, nullptr);
|
|
|
|
|
|
|
|
VkSurfaceFormatKHR* surfaceFormats = new VkSurfaceFormatKHR[surfaceFormatCount];
|
|
|
|
vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice_, surface, &surfaceFormatCount, surfaceFormats);
|
|
|
|
|
2018-09-29 21:28:15 -04:00
|
|
|
uint32_t chosenFormat = 0;
|
|
|
|
for(uint32_t i = 0; i < surfaceFormatCount; i++) {
|
|
|
|
if(surfaceFormats[i].colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR)
|
|
|
|
chosenFormat = i;
|
|
|
|
}
|
|
|
|
|
2018-09-29 21:03:06 -04:00
|
|
|
VkBool32 supported = false;
|
|
|
|
vkGetPhysicalDeviceSurfaceSupportKHR(physicalDevice_, queueIndices.presentation, surface, &supported);
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
vkCreateSwapchainKHR(device_, &swapchainCreateInfo, nullptr, &target->swapchain);
|
|
|
|
|
2018-09-29 21:53:24 -04:00
|
|
|
delete[] surfaceFormats;
|
|
|
|
|
2018-09-29 21:03:06 -04:00
|
|
|
return target;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Renderer::destroyRenderTarget(RenderTarget* target) {
|
|
|
|
vkDestroySwapchainKHR(device_, target->swapchain, nullptr);
|
|
|
|
vkDestroySurfaceKHR(instance_, target->surface, nullptr);
|
2018-09-29 21:53:24 -04:00
|
|
|
|
|
|
|
delete target;
|
2018-09-29 21:03:06 -04:00
|
|
|
}
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
VkLayerProperties* availableLayers = new VkLayerProperties[layerCount];
|
|
|
|
vkEnumerateInstanceLayerProperties(&layerCount, availableLayers);
|
|
|
|
|
|
|
|
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-09-28 18:10:33 -04:00
|
|
|
|
|
|
|
uint32_t extensionCount = 0;
|
|
|
|
vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, nullptr);
|
|
|
|
|
|
|
|
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-09-28 18:10:33 -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-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;
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
};
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
VkPhysicalDevice* physicalDevices = new VkPhysicalDevice[physicalDeviceCount];
|
|
|
|
vkEnumeratePhysicalDevices(instance_, &physicalDeviceCount, physicalDevices);
|
2018-09-29 21:03:06 -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-09-27 22:47:56 -04:00
|
|
|
|
2018-09-29 21:03:06 -04:00
|
|
|
physicalDevice_ = physicalDevices[i];
|
2018-09-27 20:33:45 -04:00
|
|
|
}
|
|
|
|
|
2018-09-28 20:41:48 -04:00
|
|
|
delete[] physicalDevices;
|
|
|
|
|
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-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-09-29 21:20:58 -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-09-28 20:41:48 -04:00
|
|
|
delete[] queueFamilyProperties;
|
|
|
|
|
2018-09-29 21:20:58 -04:00
|
|
|
queueIndices.presentation = queueIndices.graphics; //FIXME: this may not always be true!!
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
deviceQueueCreateInfos.push_back(queueCreateInfo);
|
|
|
|
}
|
|
|
|
|
2018-09-29 21:03:06 -04:00
|
|
|
const std::vector<const char*> enabledExtensions = {"VK_KHR_swapchain"};
|
|
|
|
|
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-09-27 20:33:45 -04:00
|
|
|
|
2018-09-29 21:03:06 -04:00
|
|
|
vkCreateDevice(physicalDevice_, &deviceCreateInfo, nullptr, &device_);
|
2018-09-27 22:47:56 -04:00
|
|
|
|
2018-09-29 21:20:58 -04:00
|
|
|
vkGetDeviceQueue(device_, queueIndices.graphics, 0, &graphicsQueue_);
|
2018-09-27 20:09:42 -04:00
|
|
|
}
|