From f4a6260a5edf137161820daa6e1c4084b4859ff9 Mon Sep 17 00:00:00 2001 From: Piotr Krygier Date: Wed, 14 Dec 2022 15:44:57 +0100 Subject: [PATCH] Fix some TODOs and FIXMEs --- include/localeVulkan.hpp | 6 +++ include/logger.hpp | 11 ++-- src/logger.cpp | 9 ++-- src/main.cpp | 3 +- src/vulkanBase.cpp | 106 ++++++++++++++++++++++++++------------- 5 files changed, 90 insertions(+), 45 deletions(-) diff --git a/include/localeVulkan.hpp b/include/localeVulkan.hpp index 1733de00..b04fc08a 100644 --- a/include/localeVulkan.hpp +++ b/include/localeVulkan.hpp @@ -24,6 +24,8 @@ namespace rse::locale::vulkan enum Errors { + VULKAN_LAYER_NOT_SUPPORTED, + VULKAN_EXTENSION_NOT_SUPPORTED, VULKAN_INTANCE_INIT_FAILED, VULKAN_NO_PHYSICAL_DEVICES, VULKAN_NO_SUITABLE_PHYSICAL_DEVICES, @@ -50,6 +52,10 @@ enum Errors std::array, LAST_LANGUAGE> vulkanErrorMesssages_nolocale = { {/* EN_US */ + /* VULKAN_LAYER_NOT_SUPPORTED */ + "Selected layer is not supported: ", + /* VULKAN_EXTENSION_NOT_SUPPORTED */ + "Selected extension is not supported: ", /* VULKAN_INTANCE_INIT_FAILED */ "Vulkan instance initialization failed", /* VULKAN_NO_PHYSICAL_DEVICES */ diff --git a/include/logger.hpp b/include/logger.hpp index fbb7ea00..b623e243 100644 --- a/include/logger.hpp +++ b/include/logger.hpp @@ -14,7 +14,7 @@ #include #ifndef LOG_LEVEL -#define LOG_LEVEL LOGLEVEL_WARNING +#define LOG_LEVEL LOGLEVEL_DEBUG #endif #define LOGT rse::log::Logger(rse::log::LOGLEVEL_TRACE) @@ -25,12 +25,13 @@ #define LOGF rse::log::Logger(rse::log::LOGLEVEL_FATAL) + namespace rse::log { /** * @brief Log level. Is not an enum class, because level is being compared to enable prints - * + * */ typedef enum { @@ -48,12 +49,13 @@ typedef enum */ class Logger { private: + bool printMessage; std::stringstream mMessageBuffer; public: /** * @brief Construct a new Logger object - * + * */ Logger(LogLevel); ~Logger(); @@ -65,7 +67,8 @@ class Logger { template Logger& operator<<(T&& message) { - mMessageBuffer << message; + if (printMessage) + mMessageBuffer << message; return *this; } }; diff --git a/src/logger.cpp b/src/logger.cpp index bd315ceb..8322a928 100644 --- a/src/logger.cpp +++ b/src/logger.cpp @@ -16,13 +16,13 @@ namespace rse::log { -Logger::Logger(LogLevel level) +Logger::Logger(LogLevel level) : printMessage(false) { if (level < LOG_LEVEL) { return; } - + switch (level) { case LOGLEVEL_TRACE: @@ -43,11 +43,12 @@ Logger::Logger(LogLevel level) case LOGLEVEL_FATAL: mMessageBuffer << "[FATAL] "; break; - + default: break; } - + printMessage = true; + } Logger::~Logger() diff --git a/src/main.cpp b/src/main.cpp index 371089b3..888ca720 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -10,7 +10,8 @@ int main(int argc, char** argv) rse::graphics::window::windowInit(); - rse::graphics::vulkanbase::initVulkan(); + if (0 != rse::graphics::vulkanbase::initVulkan()) + return -1; rse::graphics::window::windowLoop(); diff --git a/src/vulkanBase.cpp b/src/vulkanBase.cpp index 16a907c1..aa0de27a 100644 --- a/src/vulkanBase.cpp +++ b/src/vulkanBase.cpp @@ -9,8 +9,9 @@ * */ -/* TODO: Replace with more dynamic include */ +#ifdef __linux__ #define VK_USE_PLATFORM_XCB_KHR +#endif #include "vulkanBase.hpp" @@ -57,10 +58,13 @@ using namespace locale::vulkan; #define APPLICATION_NAME "RedScarfEngine PoC" #define ENGINE_NAME "RedScarf Engine" #define SWAP_BUFFER_COUNT 2U +#define IMAGE_FORMAT VK_FORMAT_B8G8R8A8_SRGB enum VULKAN_ERROR { VULKAN_ERROR_NO_ERROR = 0x0U, + VULKAN_ERROR_LAYER_NOT_SUPPORTED, + VULKAN_ERROR_EXTENSION_NOT_SUPPORTED, VULKAN_ERROR_INSTANCE_INIT_FAILED, VULKAN_ERROR_NO_PHYSICAL_DEVICE_FOUND, VULKAN_ERROR_NO_SUITABLE_PHYSICAL_DEVICE_FOUND, @@ -151,10 +155,11 @@ const std::vector gEnabledInstanceLayersNames = {"VK_LAYER_KHRONOS_ std::vector gEnabledInstanceLayersNames = {}; #endif -/* Extensions required by GLFW. TODO: Check for extensions required on other platforms */ const std::vector gEnabledInstanceExtensionsNames = { "VK_KHR_surface", +#ifdef __linux__ "VK_KHR_xcb_surface", +#endif "VK_KHR_device_group_creation", #ifndef NDEBUG "VK_EXT_debug_utils", @@ -474,7 +479,6 @@ static uint8_t createInstance() std::vector layerProperties; std::vector extensionsProperties; - /* TODO: Remove or use later layer and extension properties */ vkEnumerateInstanceLayerProperties(&layersCount, nullptr); layerProperties.resize(layersCount); vkEnumerateInstanceLayerProperties(&layersCount, layerProperties.data()); @@ -483,14 +487,36 @@ static uint8_t createInstance() extensionsProperties.resize(extensionCount); vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, extensionsProperties.data()); - printf("Supported Layers: \n"); +#ifndef NDEBUG + LOGD << "Supported Layers"; for (size_t i = 0; i < layersCount; i++) { - printf("%s\n", layerProperties[i].layerName); + LOGD << layerProperties[i].layerName; } - printf("Supported Extensions: \n"); + LOGD << "Supported Extensions"; for (size_t i = 0; i < extensionCount; i++) { - printf("%s\n", extensionsProperties[i].extensionName); + LOGD << extensionsProperties[i].extensionName; + } +#endif + + /* Check if selected layers are supported*/ + for (auto &layer : gEnabledInstanceLayersNames) { + if(std::find_if(layerProperties.begin(), layerProperties.end(), [&layer](const VkLayerProperties& lp) { + return strcmp(lp.layerName, layer); + }) == std::end(layerProperties)) { + LOGF << vulkanErrorMesssages[VULKAN_LAYER_NOT_SUPPORTED] << layer; + return VULKAN_ERROR_LAYER_NOT_SUPPORTED; + } + } + + /* Check if selected extensions are supported*/ + for (auto &extension : gEnabledInstanceExtensionsNames) { + if(std::find_if(extensionsProperties.begin(), extensionsProperties.end(), [&extension](const VkExtensionProperties& ep) { + return strcmp(ep.extensionName, extension); + }) == std::end(extensionsProperties)) { + LOGF << vulkanErrorMesssages[VULKAN_EXTENSION_NOT_SUPPORTED] << extension; + return VULKAN_ERROR_EXTENSION_NOT_SUPPORTED; + } } applicationInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; @@ -551,7 +577,6 @@ static uint8_t pickPhysicalDevice() /* Check for suitability */ for (size_t physicalDeviceIdx = 0U; physicalDeviceIdx < physicalDeviceCount; ++physicalDeviceIdx) { - /* TODO: Check for support */ VkPhysicalDeviceProperties deviceProperties; VkPhysicalDeviceFeatures deviceFeatures; vkGetPhysicalDeviceProperties(pPhysicalDevices[physicalDeviceIdx], &deviceProperties); @@ -559,7 +584,10 @@ static uint8_t pickPhysicalDevice() /* Expect discrete graphics device type */ if (deviceProperties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) { - gPhysicalDevice = pPhysicalDevices[physicalDeviceIdx]; + /* Application MUST have geometry shader */ + if (deviceFeatures.geometryShader) { + gPhysicalDevice = pPhysicalDevices[physicalDeviceIdx]; + } } } @@ -575,12 +603,13 @@ static uint8_t pickPhysicalDevice() static uint8_t createDevice() { uint32_t queueFamiliesPropertyCount = 0U; - ssize_t supportingQueueFamilityIdx = -1; - ssize_t supportingSufraceFamilityIdx = -1; + ssize_t graphicsFamilyIdx = -1; + ssize_t presentationFamiliyIdx = -1; std::vector pQueueFamilyProperties; VkDeviceCreateInfo deviceCreateInfo; VkDeviceQueueCreateInfo deviceQueueCreateInfos[2]; /* TODO: Change when we want more queues */ - std::vector pQueuePriorities; + std::vector pGraphicsFamiliyQueuePriorities; + std::vector pPresentationFamiliyQueuePriorities; /* Get information about supported queue families */ vkGetPhysicalDeviceQueueFamilyProperties(gPhysicalDevice, &queueFamiliesPropertyCount, nullptr); @@ -594,7 +623,7 @@ static uint8_t createDevice() for (size_t familyIdx = 0; familyIdx < queueFamiliesPropertyCount; ++familyIdx) { if (pQueueFamilyProperties[familyIdx].queueFlags & VK_QUEUE_GRAPHICS_BIT) { if (pQueueFamilyProperties[familyIdx].queueCount > numberOfQueues) { - supportingQueueFamilityIdx = familyIdx; + graphicsFamilyIdx = familyIdx; numberOfQueues = pQueueFamilyProperties[familyIdx].queueCount; } } @@ -603,38 +632,48 @@ static uint8_t createDevice() vkGetPhysicalDeviceSurfaceSupportKHR(gPhysicalDevice, familyIdx, gSurface, &presentSupport); if (presentSupport) { - // FIXME: Search for best, not first one - supportingSufraceFamilityIdx = familyIdx; + presentationFamiliyIdx = familyIdx; + } + + if (graphicsFamilyIdx > 0 && presentationFamiliyIdx > 0) + { + break; } } } /* This is not magic number ;P. We want to support exact number of required queues flags */ - if (0 > supportingQueueFamilityIdx) { + if (0 > graphicsFamilyIdx) { LOGF << vulkanErrorMesssages[VULKAN_QUEUE_NOT_SUPPORTED]; return VULKAN_ERROR_QUEUE_NOT_SUPPORTED; } - gQueueFamilyIndices[0] = supportingQueueFamilityIdx; /* TODO: Change when more families are needed */ + gQueueFamilyIndices[0] = graphicsFamilyIdx; /* TODO: Change when more families are needed */ - pQueuePriorities.resize(pQueueFamilyProperties[supportingQueueFamilityIdx].queueCount); - for (size_t i = 0; i < pQueueFamilyProperties[supportingQueueFamilityIdx].queueCount; i++) { - pQueuePriorities[i] = 1.0f; /* TODO: When queues have different tasks, change this if needed */ + pGraphicsFamiliyQueuePriorities.resize(pQueueFamilyProperties[graphicsFamilyIdx].queueCount); + for (size_t i = 0; i < pQueueFamilyProperties[graphicsFamilyIdx].queueCount; i++) { + pGraphicsFamiliyQueuePriorities[i] = 1.0f; /* TODO: When queues have different tasks, change this if needed */ } + pPresentationFamiliyQueuePriorities.resize(pQueueFamilyProperties[presentationFamiliyIdx].queueCount); + for (size_t i = 0; i < pQueueFamilyProperties[presentationFamiliyIdx].queueCount; i++) { + pPresentationFamiliyQueuePriorities[i] = 1.0f; /* TODO: When queues have different tasks, change this if needed */ + } + + deviceQueueCreateInfos[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; deviceQueueCreateInfos[0].pNext = nullptr; deviceQueueCreateInfos[0].flags = 0; - deviceQueueCreateInfos[0].queueFamilyIndex = supportingQueueFamilityIdx; - deviceQueueCreateInfos[0].queueCount = pQueueFamilyProperties[supportingQueueFamilityIdx].queueCount; - deviceQueueCreateInfos[0].pQueuePriorities = pQueuePriorities.data(); + deviceQueueCreateInfos[0].queueFamilyIndex = graphicsFamilyIdx; + deviceQueueCreateInfos[0].queueCount = pQueueFamilyProperties[graphicsFamilyIdx].queueCount; + deviceQueueCreateInfos[0].pQueuePriorities = pGraphicsFamiliyQueuePriorities.data(); deviceQueueCreateInfos[1].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; deviceQueueCreateInfos[1].pNext = nullptr; deviceQueueCreateInfos[1].flags = 0; - deviceQueueCreateInfos[1].queueFamilyIndex = supportingSufraceFamilityIdx; - deviceQueueCreateInfos[1].queueCount = pQueueFamilyProperties[supportingSufraceFamilityIdx].queueCount; - deviceQueueCreateInfos[1].pQueuePriorities = pQueuePriorities.data(); //FIXME: This is wrong for this queue! + deviceQueueCreateInfos[1].queueFamilyIndex = presentationFamiliyIdx; + deviceQueueCreateInfos[1].queueCount = pQueueFamilyProperties[presentationFamiliyIdx].queueCount; + deviceQueueCreateInfos[1].pQueuePriorities = pPresentationFamiliyQueuePriorities.data(); deviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; deviceCreateInfo.pNext = nullptr; @@ -652,8 +691,8 @@ static uint8_t createDevice() return VULKAN_ERROR_DEVICE_CREATION_FAILED; } - vkGetDeviceQueue(gDevice, supportingQueueFamilityIdx, 0, &gGraphicsQueue); - vkGetDeviceQueue(gDevice, supportingSufraceFamilityIdx, 0, &gPresentQueue); + vkGetDeviceQueue(gDevice, graphicsFamilyIdx, 0, &gGraphicsQueue); + vkGetDeviceQueue(gDevice, presentationFamiliyIdx, 0, &gPresentQueue); return VULKAN_ERROR_NO_ERROR; @@ -706,7 +745,7 @@ static uint8_t createVertexBuffer() vertexBufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; vertexBufferInfo.pNext = nullptr; vertexBufferInfo.flags = 0U; - vertexBufferInfo.size = sizeof(vertices[0]) * vertices.size(); // FIXME: Harcoded for now + vertexBufferInfo.size = sizeof(vertices[0]) * vertices.size(); vertexBufferInfo.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; vertexBufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; vertexBufferInfo.queueFamilyIndexCount = 0U; @@ -784,7 +823,7 @@ static uint8_t createSwapchain() createInfo.flags = 0U; createInfo.surface = gSurface; createInfo.minImageCount = SWAP_BUFFER_COUNT + 1; - createInfo.imageFormat = VK_FORMAT_B8G8R8A8_SRGB; /* TODO: Check for supported formats */ + createInfo.imageFormat = IMAGE_FORMAT; /* TODO: Check for supported formats */ createInfo.imageColorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR; /* TODO: Check for supported color space */ createInfo.imageExtent = gSwapchainExtent; createInfo.imageArrayLayers = 1U; /* For non-stereoscopic-3D applications, this value is 1. */ @@ -1053,11 +1092,6 @@ static void fillMultisamplingInfo(VkPipelineMultisampleStateCreateInfo* multisam multisampling->alphaToOneEnable = VK_FALSE; } -// static void setDepthAndStencilTesting() -// { -// //TODO: Fill -// } - static void fillColorBlendInfo(VkPipelineColorBlendStateCreateInfo* colorBlending) { VkPipelineColorBlendAttachmentState colorBlendAttachment{}; @@ -1096,7 +1130,7 @@ static uint8_t createRenderPass() { VkAttachmentDescription colorAttachment{}; colorAttachment.flags = 0U; - colorAttachment.format = VK_FORMAT_B8G8R8A8_SRGB; //FIXME: This is from swapchain. Change, so it won't break when swapchain uses different format + colorAttachment.format = IMAGE_FORMAT; colorAttachment.samples = VK_SAMPLE_COUNT_1_BIT; colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;