diff --git a/engine/src/engine/renderapi/window.h b/engine/src/engine/renderapi/window.h index 5da0485..0ec5609 100644 --- a/engine/src/engine/renderapi/window.h +++ b/engine/src/engine/renderapi/window.h @@ -1,3 +1,4 @@ +#pragma once #include namespace renderapi { class Window { diff --git a/engine/src/engine/vulkanapi/backend.cpp b/engine/src/engine/vulkanapi/backend.cpp index fafe7b4..b0b4c01 100644 --- a/engine/src/engine/vulkanapi/backend.cpp +++ b/engine/src/engine/vulkanapi/backend.cpp @@ -6,17 +6,15 @@ namespace vulkanapi { { auto instanceCreator = InstanceCreator(); mInstance = new Instance(instanceCreator); - std::vector available_devices; - mInstance->EnumerateAvailablePhysicalDevices(available_devices); - int device_count = available_devices.size(); - if (device_count <= deviceIndex) { - zlog::error("Could not get the number of available physical devices. out of boundry. {} > {}", deviceIndex, device_count); - if (device_count == 0) { - return; - } - deviceIndex = 0; - } - mDevice = new Device(mInstance->Ptr(), available_devices[deviceIndex]); + + auto deviceCreator = DeviceCreator(*mInstance); + deviceCreator.desiredPhysicalDeviceFeatures.geometryShader = VK_TRUE; + deviceCreator.AddQueue("TransferQueue", VkQueueFlagBits::VK_QUEUE_GRAPHICS_BIT, 1.0); + deviceCreator.AddQueue("RenderQueue", VkQueueFlagBits::VK_QUEUE_GRAPHICS_BIT, 1.0); + deviceCreator.AddQueue("ComputeQueue", VkQueueFlagBits::VK_QUEUE_GRAPHICS_BIT, 1.0); + deviceCreator.AddQueue("PresentQueue", VkQueueFlagBits::VK_QUEUE_GRAPHICS_BIT, 1.0); + mDevice = new Device(deviceCreator); + } Backend::~Backend() { diff --git a/engine/src/engine/vulkanapi/backend.h b/engine/src/engine/vulkanapi/backend.h index 1dd4087..0f71ba7 100644 --- a/engine/src/engine/vulkanapi/backend.h +++ b/engine/src/engine/vulkanapi/backend.h @@ -4,6 +4,7 @@ #include "wrapper/instance.h" #include "wrapper/instance_creator.h" #include "wrapper/device.h" +#include "wrapper/device_creator.h" namespace vulkanapi { class Backend{ protected: diff --git a/engine/src/engine/vulkanapi/vulkan.h b/engine/src/engine/vulkanapi/vulkan.h index 7097bc0..4f62902 100644 --- a/engine/src/engine/vulkanapi/vulkan.h +++ b/engine/src/engine/vulkanapi/vulkan.h @@ -1,4 +1,4 @@ -//#pragma once +#pragma once #include #include #include diff --git a/engine/src/engine/vulkanapi/wrapper/device.cpp b/engine/src/engine/vulkanapi/wrapper/device.cpp index ac53d65..786c5ef 100644 --- a/engine/src/engine/vulkanapi/wrapper/device.cpp +++ b/engine/src/engine/vulkanapi/wrapper/device.cpp @@ -1,40 +1,14 @@ #include "device.h" -#include "device_help.h" +#include "device_creator.h" namespace vulkanapi { - Device::Device(VkInstance instance, VkPhysicalDevice physDevice):mPhysical(physDevice) - { - std::vector queue_families; - CheckAvailableQueueFamiliesAndTheirProperties(physDevice, queue_families); + Device::Device(DeviceCreator& Creator) + { - std::vector queue_create_infos; - _QueueCreateInfos(queue_create_infos, queue_families); - std::vector desired_extensions = { - "VK_KHR_swapchain", - }; - - VkPhysicalDeviceFeatures device_features{}; - _EnabledFeatures(device_features); - VkDeviceCreateInfo device_create_info = { - VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, // VkStructureType sType - nullptr, // const void * pNext - 0, // VkDeviceCreateFlags flags - static_cast(queue_create_infos.size()), // uint32_t queueCreateInfoCount - queue_create_infos.data(), // const VkDeviceQueueCreateInfo * pQueueCreateInfos - 0, // uint32_t enabledLayerCount - nullptr, // const char * const * ppEnabledLayerNames - static_cast(desired_extensions.size()), // uint32_t enabledExtensionCount - desired_extensions.data(), // const char * const * ppEnabledExtensionNames - &device_features // const VkPhysicalDeviceFeatures * pEnabledFeatures - }; - VkResult result = vkCreateDevice(physDevice, &device_create_info, nullptr, &mPtr); - if((result != VK_SUCCESS) || (mPtr == VK_NULL_HANDLE)) { - zlog::error("Could not create logical device."); - } - } + } uint32_t Device::GetQueueFamilyIndex(VkQueueFlags flag) { std::vector queue_families; - CheckAvailableQueueFamiliesAndTheirProperties(mPhysical, queue_families); + // CheckAvailableQueueFamiliesAndTheirProperties(mPhysical, queue_families); for (uint32_t i = 0, l = queue_families.size(); i < l; i++) { if ((queue_families[i].queueFlags & flag) == flag) { return i; diff --git a/engine/src/engine/vulkanapi/wrapper/device.h b/engine/src/engine/vulkanapi/wrapper/device.h index 3626dd0..f8378c5 100644 --- a/engine/src/engine/vulkanapi/wrapper/device.h +++ b/engine/src/engine/vulkanapi/wrapper/device.h @@ -3,7 +3,9 @@ #include "../vulkan.h" namespace vulkanapi { + class DeviceCreator; class Device{ + friend class DeviceCreator; protected: VkDevice mPtr{ NULL }; VkPhysicalDevice mPhysical{NULL}; @@ -15,8 +17,7 @@ namespace vulkanapi { return mPhysical; } public: - Device(){}; - Device(VkInstance ptr, VkPhysicalDevice physDevice); + Device(DeviceCreator& Creator); uint32_t GetQueueFamilyIndex(VkQueueFlags flag); VkCommandPool CreateCommandPool(const VkCommandPoolCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator); diff --git a/engine/src/engine/vulkanapi/wrapper/device_creator.cpp b/engine/src/engine/vulkanapi/wrapper/device_creator.cpp new file mode 100644 index 0000000..5ddab33 --- /dev/null +++ b/engine/src/engine/vulkanapi/wrapper/device_creator.cpp @@ -0,0 +1,41 @@ +#pragma once +#include "device.h" +#include "device_creator.h" +#include "zlog.h" +namespace vulkanapi { + DeviceCreator::DeviceCreator(Instance& instance) + :instance(instance) + , desiredPhysicalDeviceType(VkPhysicalDeviceType::VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) + , desiredPhysicalDeviceFeatures() + { + + } + void DeviceCreator::AddQueue(std::string name, VkQueueFlags flag, float prioritie) + { + desiredQueues.emplace_back(name, flag, prioritie); + } + void DeviceCreator::AddWindowExtension() + { + AddExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME); + AddQueue("PresentQueue", VK_QUEUE_FLAG_BITS_MAX_ENUM, 1.0f); +#ifdef _USE_GRAPHIC_DEBUG + AddLayer("VK_LAYER_KHRONOS_validation"); + AddLayer("VK_LAYER_RENDERDOC_Capture"); +#endif + } + void DeviceCreator::QueueCreateInfos(std::vector& queue_create_infos, std::vector& queue_families) + { + std::vector availableLayers(); + + } + void DeviceCreator::AddExtension(std::string extensionName) + { + desiredExtensions.push_back(extensionName); + } +#ifdef _USE_GRAPHIC_DEBUG + void DeviceCreator::AddLayer(std::string layerName) + { + desiredLayers.push_back(layerName); + } +#endif +}; \ No newline at end of file diff --git a/engine/src/engine/vulkanapi/wrapper/device_creator.h b/engine/src/engine/vulkanapi/wrapper/device_creator.h new file mode 100644 index 0000000..c1cf944 --- /dev/null +++ b/engine/src/engine/vulkanapi/wrapper/device_creator.h @@ -0,0 +1,42 @@ +#pragma once +#include "../vulkan.h" +#include +#include + +namespace vulkanapi { + class Device; + class Instance; + class DeviceCreator { + friend class Device; + private: + class DesiredQueue final + { + public: + std::string name; + VkQueueFlags flag; + float prioritie; + DesiredQueue(std::string name, VkQueueFlags flag, float prioritie) + : name(name), flag(flag), prioritie(prioritie){} + }; + public: + VkPhysicalDeviceFeatures desiredPhysicalDeviceFeatures; + VkPhysicalDeviceType desiredPhysicalDeviceType; + std::vector desiredExtensions; + std::vector desiredQueues; + public: + Instance& instance; + + public: + DeviceCreator(Instance& instance); + void AddQueue(std::string name, VkQueueFlags flag, float prioritie); + void AddExtension(std::string extensionName); + void AddWindowExtension(); + void QueueCreateInfos(std::vector& queue_create_infos, std::vector& queue_families); +#ifdef _USE_GRAPHIC_DEBUG + public: + std::vector desiredLayers; + void AddLayer(std::string layerName); +#endif + private: + +}; \ No newline at end of file diff --git a/engine/src/engine/vulkanapi/wrapper/device_help.h b/engine/src/engine/vulkanapi/wrapper/device_help.h deleted file mode 100644 index aa7e545..0000000 --- a/engine/src/engine/vulkanapi/wrapper/device_help.h +++ /dev/null @@ -1,44 +0,0 @@ -#pragma once -#include "../vulkan.h" -#include -#include -#include -#include "zlog.h" -namespace vulkanapi { - constexpr float DEFAULT_QUEUE_PRIORITY = 1.0f; - bool CheckAvailableQueueFamiliesAndTheirProperties(VkPhysicalDevice physical_device,std::vector& queue_families) { - uint32_t queue_families_count = 0; - - vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &queue_families_count, nullptr); - if (queue_families_count == 0) { - zlog::error("Could not get the number of queue families."); - return false; - } - - queue_families.resize(queue_families_count); - vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &queue_families_count, queue_families.data()); - if (queue_families_count == 0) { - zlog::error("Could not acquire properties of queue families."); - return false; - } - - return true; - } - void _QueueCreateInfos(std::vector& queue_create_infos, std::vector& queue_families) { - for (uint32_t i = 0, l = queue_families.size(); i < l; i++) { - queue_create_infos.push_back({ - VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // VkStructureType sType - nullptr, // const void * pNext - 0, // VkDeviceQueueCreateFlags flags - i, // uint32_t queueFamilyIndex - 1, // uint32_t queueCount - &DEFAULT_QUEUE_PRIORITY // const float * pQueuePriorities - }); - } - } - void _EnabledFeatures(VkPhysicalDeviceFeatures& device_features) { - device_features.independentBlend = true; - device_features.depthClamp = true; - //device_features.protectedMemory = true; - } -} \ No newline at end of file diff --git a/engine/src/engine/vulkanapi/wrapper/instance.cpp b/engine/src/engine/vulkanapi/wrapper/instance.cpp index cc34a2e..dfa418d 100644 --- a/engine/src/engine/vulkanapi/wrapper/instance.cpp +++ b/engine/src/engine/vulkanapi/wrapper/instance.cpp @@ -22,9 +22,9 @@ namespace vulkanapi { Creator.apiVersion // uint32_t apiVersion }; #ifdef _USE_GRAPHIC_DEBUG - Creator._AddDebugExtension(); + Creator.AddDebugExtension(); #endif - Creator._AddWindowExtension(); + Creator.AddWindowExtension(); auto extensions = Creator.EnabledExtensionNames(); auto layers = Creator.EnabledLayerNames();; VkInstanceCreateInfo instance_create_info = { @@ -38,7 +38,7 @@ namespace vulkanapi { extensions.data() // const char * const * ppEnabledExtensionNames }; #ifdef _USE_GRAPHIC_DEBUG - VkDebugUtilsMessengerCreateInfoEXT debugInfo = Creator._DebugUtilsLayerNext(); + VkDebugUtilsMessengerCreateInfoEXT debugInfo = Creator.DebugUtilsLayerNext(); instance_create_info.pNext = &debugInfo; #endif VkResult result = vkCreateInstance(&instance_create_info, nullptr, &mPtr); diff --git a/engine/src/engine/vulkanapi/wrapper/instance_creator.cpp b/engine/src/engine/vulkanapi/wrapper/instance_creator.cpp index f361de9..11f7feb 100644 --- a/engine/src/engine/vulkanapi/wrapper/instance_creator.cpp +++ b/engine/src/engine/vulkanapi/wrapper/instance_creator.cpp @@ -1,9 +1,6 @@ #pragma once #include "instance.h" #include "instance_creator.h" -#include -#include -#include #include "zlog.h" namespace vulkanapi { InstanceCreator::InstanceCreator() @@ -28,14 +25,14 @@ namespace vulkanapi { { desiredLayers.push_back(layerName); } - void InstanceCreator::_AddWindowExtension() + void InstanceCreator::AddWindowExtension() { AddExtension("VK_KHR_win32_surface"); AddExtension(VK_KHR_SURFACE_EXTENSION_NAME); - AddExtension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); - AddExtension(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME); + //AddExtension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); + //AddExtension(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME); } - void InstanceCreator::_AddDebugExtension() + void InstanceCreator::AddDebugExtension() { AddLayer("VK_LAYER_KHRONOS_validation"); AddLayer("VK_LAYER_RENDERDOC_Capture"); @@ -79,7 +76,7 @@ namespace vulkanapi { } #ifdef _USE_GRAPHIC_DEBUG - VkDebugUtilsMessengerCreateInfoEXT InstanceCreator::_DebugUtilsLayerNext() + VkDebugUtilsMessengerCreateInfoEXT InstanceCreator::DebugUtilsLayerNext() { VkDebugUtilsMessengerCreateInfoEXT createInfo{}; createInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT; diff --git a/engine/src/engine/vulkanapi/wrapper/instance_creator.h b/engine/src/engine/vulkanapi/wrapper/instance_creator.h index 78ff947..ac376de 100644 --- a/engine/src/engine/vulkanapi/wrapper/instance_creator.h +++ b/engine/src/engine/vulkanapi/wrapper/instance_creator.h @@ -20,8 +20,8 @@ namespace vulkanapi { void AddExtension(std::string extensionName); void AddLayer(std::string layerName); - void _AddWindowExtension(); - void _AddDebugExtension(); + void AddWindowExtension(); + void AddDebugExtension(); std::vector EnabledExtensionNames(); std::vector EnabledLayerNames(); @@ -31,7 +31,7 @@ namespace vulkanapi { VkDebugUtilsMessageTypeFlagsEXT messageType; PFN_vkDebugUtilsMessengerCallbackEXT debugCallback; - VkDebugUtilsMessengerCreateInfoEXT _DebugUtilsLayerNext(); + VkDebugUtilsMessengerCreateInfoEXT DebugUtilsLayerNext(); #endif private: diff --git a/engine/src/engine/vulkanapi/wrapper/instance_help.h b/engine/src/engine/vulkanapi/wrapper/instance_help.h deleted file mode 100644 index af44378..0000000 --- a/engine/src/engine/vulkanapi/wrapper/instance_help.h +++ /dev/null @@ -1,186 +0,0 @@ -#pragma once -#include "../vulkan.h" -#include -#include -#include -#include "zlog.h" -namespace vulkanapi { - bool ConnectWithVulkanLoaderLibrary(LIBRARY_TYPE& vulkan_library) { -#if defined _WIN32 - vulkan_library = LoadLibrary("vulkan-1.dll"); -#elif defined __linux - vulkan_library = dlopen("libvulkan.so.1", RTLD_NOW); -#endif - if (vulkan_library == nullptr) { - zlog::error("Could not connect with a Vulkan Runtime library."); - return false; - } - return true; - } - bool LoadFunctionExportedFromVulkanLoaderLibrary(LIBRARY_TYPE const& vulkan_library) { -#if defined _WIN32 -#define LoadFunction GetProcAddress -#elif defined __linux -#define LoadFunction dlsym -#endif - -#define EXPORTED_VULKAN_FUNCTION( name ) \ - name = (PFN_##name)LoadFunction( vulkan_library, #name ); \ - if( name == nullptr ) { \ - zlog::error( "Could not load exported Vulkan function named:"#name);\ - return false; \ - } -#include "engine/vulkanapi/vulkan_function_list.inl" - return true; - } - - bool LoadGlobalLevelFunctions() { -#define GLOBAL_LEVEL_VULKAN_FUNCTION( name ) \ - name = (PFN_##name)vkGetInstanceProcAddr( nullptr, #name ); \ - if( name == nullptr ) { \ - zlog::error( "Could not load global level Vulkan function named:"#name);\ - return false; \ - } - -#include "engine/vulkanapi/vulkan_function_list.inl" - - return true; - } - bool LoadInstanceLevelFunctions(VkInstance instance, - std::vector const& enabled_extensions) { - // Load core Vulkan API instance-level functions -#define INSTANCE_LEVEL_VULKAN_FUNCTION( name ) \ - name = (PFN_##name)vkGetInstanceProcAddr( instance, #name ); \ - if( name == nullptr ) { \ - zlog::error( "Could not load instance-level Vulkan function named:"#name);\ - return false; \ - } - - // Load instance-level functions from enabled extensions -#define INSTANCE_LEVEL_VULKAN_FUNCTION_FROM_EXTENSION( name, extension ) \ - for( auto & enabled_extension : enabled_extensions ) { \ - if( std::string( enabled_extension ) == std::string( extension ) ) { \ - name = (PFN_##name)vkGetInstanceProcAddr( instance, #name ); \ - if( name == nullptr ) { \ - zlog::error( "Could not load instance-level Vulkan function named:"#name);\ - return false; \ - } \ - } \ - } - -#include "engine/vulkanapi/vulkan_function_list.inl" - - return true; - } - bool IsExtensionSupported(std::vector const& available_extensions, - char const* const extension) { - for (auto& available_extension : available_extensions) { - if (strstr(available_extension.extensionName, extension)) { - return true; - } - } - return false; - } - bool IsLayerSupported(std::vector const& available_layers, - char const* const layer) { - for (auto& available_layer : available_layers) { - if (strstr(available_layer.layerName, layer)) { - return true; - } - } - return false; - } - bool CheckAvailableInstanceLayers(std::vector& available_layers) { - uint32_t extensions_count = 0; - VkResult result = VK_SUCCESS; - - result = vkEnumerateInstanceLayerProperties(&extensions_count, nullptr); - if ((result != VK_SUCCESS) || - (extensions_count == 0)) { - zlog::error("Could not get the number of instance layers."); - return false; - } - - available_layers.resize(extensions_count); - result = vkEnumerateInstanceLayerProperties(&extensions_count, available_layers.data()); - if ((result != VK_SUCCESS) || - (extensions_count == 0)) { - zlog::error("Could not enumerate instance layers."); - return false; - } - - return true; - } - bool CheckAvailableInstanceExtensions(std::vector& available_extensions) { - uint32_t extensions_count = 0; - VkResult result = VK_SUCCESS; - - result = vkEnumerateInstanceExtensionProperties(nullptr, &extensions_count, nullptr); - if ((result != VK_SUCCESS) || - (extensions_count == 0)) { - zlog::error("Could not get the number of instance extensions."); - return false; - } - - available_extensions.resize(extensions_count); - result = vkEnumerateInstanceExtensionProperties(nullptr, &extensions_count, available_extensions.data()); - if ((result != VK_SUCCESS) || - (extensions_count == 0)) { - zlog::error("Could not enumerate instance extensions."); - return false; - } - - return true; - } - std::vector _EnabledExtensionNames(std::vector& extensions) { - std::vector available_extensions; - std::vector _extension; - if (!CheckAvailableInstanceExtensions(available_extensions)) { - return _extension; - } - for (int i = 0, l = extensions.size(); i < l; i++) { - if (IsExtensionSupported(available_extensions, extensions[i].c_str())) { - _extension.push_back(extensions[i].c_str()); - } - else { - zlog::error("cann't support extension: {}", extensions[i].c_str()); - } - } - return _extension; - } - std::vector _EnabledLayerNames(std::vector& layers) { - std::vector available_layers; - std::vector _layers; - if (!CheckAvailableInstanceLayers(available_layers)) { - return _layers; - } - for (int i = 0, l = layers.size(); i < l; i++) { - if (IsLayerSupported(available_layers, layers[i].c_str())) { - _layers.push_back(layers[i].c_str()); - } - else { - zlog::error("Could not load instance-level Vulkan function named: {}", layers[i].c_str()); - } - } - return _layers; - } - // debug callback - static VKAPI_ATTR VkBool32 VKAPI_CALL debugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT, - VkDebugUtilsMessageTypeFlagsEXT, - const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, - void*) - { - zlog::error("validation layer: {}", pCallbackData->pMessage); - return VK_FALSE; - } - VkDebugUtilsMessengerCreateInfoEXT _DebugUtilsLayerNext() { - VkDebugUtilsMessengerCreateInfoEXT createInfo{}; - createInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT; - createInfo.messageSeverity = - VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT; - createInfo.messageType = - VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT; - createInfo.pfnUserCallback = debugCallback; - return createInfo; - } -}; \ No newline at end of file diff --git a/engine/src/engine/vulkanapi/wrapper/swapchain_help.h b/engine/src/engine/vulkanapi/wrapper/swapchain_help.h index d462289..33e79a9 100644 --- a/engine/src/engine/vulkanapi/wrapper/swapchain_help.h +++ b/engine/src/engine/vulkanapi/wrapper/swapchain_help.h @@ -1,3 +1,4 @@ +#pragma once #include "instance.h" #include #include "zlog.h"