重构完成逻辑设备创建,surface创建

ink-soul 2024-04-02 12:08:46 +08:00
parent 77e93d01d1
commit 7063d9a0f9
5 changed files with 223 additions and 29 deletions

View File

@ -9,8 +9,8 @@
#include "VulkanExampleBase.h" #include "VulkanExampleBase.h"
std::vector<const char*> VulkanExampleBase::args;
/*
VKAPI_ATTR VkBool32 VKAPI_CALL debugMessageCallback(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject, size_t location, int32_t msgCode, const char * pLayerPrefix, const char * pMsg, void * pUserData) VKAPI_ATTR VkBool32 VKAPI_CALL debugMessageCallback(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject, size_t location, int32_t msgCode, const char * pLayerPrefix, const char * pMsg, void * pUserData)
{ {
std::string prefix(""); std::string prefix("");
@ -33,7 +33,7 @@ VKAPI_ATTR VkBool32 VKAPI_CALL debugMessageCallback(VkDebugReportFlagsEXT flags,
fflush(stdout); fflush(stdout);
return VK_FALSE; return VK_FALSE;
} }
*/
VkResult VulkanExampleBase::createInstance(bool enableValidation) VkResult VulkanExampleBase::createInstance(bool enableValidation)
{ {
setter.settings.validation = enableValidation; setter.settings.validation = enableValidation;
@ -591,7 +591,7 @@ void VulkanExampleBase::initVulkan()
/* /*
Validation layers Validation layers
*/
if (settings.validation) { if (settings.validation) {
vkCreateDebugReportCallback = reinterpret_cast<PFN_vkCreateDebugReportCallbackEXT>(vkGetInstanceProcAddr(instance, "vkCreateDebugReportCallbackEXT")); vkCreateDebugReportCallback = reinterpret_cast<PFN_vkCreateDebugReportCallbackEXT>(vkGetInstanceProcAddr(instance, "vkCreateDebugReportCallbackEXT"));
vkDestroyDebugReportCallback = reinterpret_cast<PFN_vkDestroyDebugReportCallbackEXT>(vkGetInstanceProcAddr(instance, "vkDestroyDebugReportCallbackEXT")); vkDestroyDebugReportCallback = reinterpret_cast<PFN_vkDestroyDebugReportCallbackEXT>(vkGetInstanceProcAddr(instance, "vkDestroyDebugReportCallbackEXT"));
@ -601,10 +601,10 @@ void VulkanExampleBase::initVulkan()
debugCreateInfo.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT; debugCreateInfo.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT;
VK_CHECK_RESULT(vkCreateDebugReportCallback(instance, &debugCreateInfo, nullptr, &debugReportCallback)); VK_CHECK_RESULT(vkCreateDebugReportCallback(instance, &debugCreateInfo, nullptr, &debugReportCallback));
} }
*/
/* /*
GPU selection GPU selection
*/
uint32_t gpuCount = 0; uint32_t gpuCount = 0;
VK_CHECK_RESULT(vkEnumeratePhysicalDevices(instance, &gpuCount, nullptr)); VK_CHECK_RESULT(vkEnumeratePhysicalDevices(instance, &gpuCount, nullptr));
assert(gpuCount > 0); assert(gpuCount > 0);
@ -620,7 +620,7 @@ void VulkanExampleBase::initVulkan()
vkGetPhysicalDeviceProperties(physicalDevice, &deviceProperties); vkGetPhysicalDeviceProperties(physicalDevice, &deviceProperties);
vkGetPhysicalDeviceFeatures(physicalDevice, &deviceFeatures); vkGetPhysicalDeviceFeatures(physicalDevice, &deviceFeatures);
vkGetPhysicalDeviceMemoryProperties(physicalDevice, &deviceMemoryProperties); vkGetPhysicalDeviceMemoryProperties(physicalDevice, &deviceMemoryProperties);
*/
/* /*
Device creation Device creation
*/ */

View File

@ -2270,9 +2270,11 @@ void PlumageRender::updateUIOverlay()
} }
// 完全重写避免OS specific // 完全重写避免OS specific
/*
PlumageRender* plumageRender; PlumageRender* plumageRender;
// OS specific macros for the example main entry points
#if defined(_WIN32) #if defined(_WIN32)
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{ {
@ -2299,3 +2301,17 @@ PlumageRender* plumageRender;
return 0; return 0;
} }
#endif #endif
*/
int main()
{
PlumageRender* plumageRender;
VulkanBackend::Setter setter;
if (!setter.settings.headless)
{
plumageRender->initWindow(setter.settings.width, setter.settings.height);
plumageRender->initVulkan();
}
return 0;
}

View File

@ -19,12 +19,15 @@
#include <vulkan/vulkan.h> #include <vulkan/vulkan.h>
#include "VulkanExampleBase.h" #include "VulkanExampleBase.h"
#include "glTFModel.h" #include "glTFModel.h"
#include "GLFW/glfw3.h"
#include <VulkanTexture.hpp> #include <VulkanTexture.hpp>
#include "VulkanDevice.hpp" #include "VulkanDevice.hpp"
#include "ui.hpp" #include "ui.hpp"
#include <VulkanUtils.hpp> #include <VulkanUtils.hpp>
#include "renderSetter.h" #include "renderSetter.h"
#include "GLFW/glfw3.h" #include "vulkanFoundation.h"
#define STB_IMAGE_WRITE_IMPLEMENTATION #define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb_image_write.h" #include "stb_image_write.h"
@ -296,6 +299,7 @@ public:
void initWindow(int width, int height); void initWindow(int width, int height);
static void framebufferResizeCallback(GLFWwindow* window, int width, int height); static void framebufferResizeCallback(GLFWwindow* window, int width, int height);
void renderNode(glTFModel::Node* node, uint32_t cbIndex, glTFModel::Material::AlphaMode alphaMode); void renderNode(glTFModel::Node* node, uint32_t cbIndex, glTFModel::Material::AlphaMode alphaMode);
void loadScene(std::string filename); void loadScene(std::string filename);

View File

@ -1,12 +1,27 @@
#include "vulkanFoundation.h" #include "vulkanFoundation.h"
VKAPI_ATTR VkBool32 VKAPI_CALL VulkanBackend::VulkanFondation::debugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageTypes, const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, void* pUserData)
{
std::cerr << "validation layer: " << pCallbackData->pMessage << std::endl;
return VK_FALSE; void VulkanBackend::VulkanFondation::initVulkan()
{
// 创建instance
createInstance();
// 设置校验层消息回调
setupDebugMessager();
// 选择主机显卡
pickPhysicalDevice();
// 实时显示结果的glfw surface
createSurface();
// 完成逻辑设备创建
createLogicalDevice();
} }
void VulkanBackend::VulkanFondation::createInstance() void VulkanBackend::VulkanFondation::createInstance()
{ {
// check validation layers // check validation layers
@ -106,6 +121,25 @@ std::vector<const char*> VulkanBackend::VulkanFondation::getRequiredExtensions()
return extensions; return extensions;
} }
void VulkanBackend::VulkanFondation::setupDebugMessager()
{
if (!setter.settings.validation)
{
return;
}
VkDebugUtilsMessengerCreateInfoEXT createInfo{};
populateDebugMessengerCreateInfo(createInfo);
if (CreateDebugUtilsMessengerEXT(instance, &createInfo, nullptr, &debugMessenger) != VK_SUCCESS)
{
throw std::runtime_error("failed to set up debug messenger in setupDebugMessenger");
}
}
void VulkanBackend::VulkanFondation::populateDebugMessengerCreateInfo(VkDebugUtilsMessengerCreateInfoEXT& debugCreateInfo) void VulkanBackend::VulkanFondation::populateDebugMessengerCreateInfo(VkDebugUtilsMessengerCreateInfoEXT& debugCreateInfo)
{ {
debugCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT; debugCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT;
@ -119,13 +153,49 @@ void VulkanBackend::VulkanFondation::populateDebugMessengerCreateInfo(VkDebugUti
debugCreateInfo.pfnUserCallback = &debugCallback; debugCreateInfo.pfnUserCallback = &debugCallback;
debugCreateInfo.pUserData = nullptr; debugCreateInfo.pUserData = nullptr;
} }
// debugCallback用于校验层
VKAPI_ATTR VkBool32 VKAPI_CALL VulkanBackend::VulkanFondation::debugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageTypes, const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, void* pUserData)
{
{
std::cerr << "validation layer: " << pCallbackData->pMessage << std::endl;
return VK_FALSE;
}
}
VkResult VulkanBackend::VulkanFondation::CreateDebugUtilsMessengerEXT(VkInstance instance, const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDebugUtilsMessengerEXT* pDebugMessenger)
{
auto func = (PFN_vkCreateDebugUtilsMessengerEXT)vkGetInstanceProcAddr(instance, "vkCreateDebugUtilsMessengerEXT");
if (func != nullptr)
{
return func(instance, pCreateInfo, pAllocator, pDebugMessenger);
}
else
{
return VK_ERROR_EXTENSION_NOT_PRESENT;
}
}
void VulkanBackend::VulkanFondation::createSurface() void VulkanBackend::VulkanFondation::createSurface()
{ {
if (setter.settings.headless)
{
return;
} }
inline void VulkanBackend::VulkanFondation::pickPhysicalDevice() if (glfwCreateWindowSurface(instance, window, nullptr, &surface) != VK_SUCCESS)
{
throw std::runtime_error("failed to create window surface in createSurface()");
}
}
void VulkanBackend::VulkanFondation::pickPhysicalDevice()
{ {
uint32_t deviceCount = 0; uint32_t deviceCount = 0;
@ -208,12 +278,13 @@ VulkanBackend::VulkanFondation::QueueFamilyIndices VulkanBackend::VulkanFondatio
VkBool32 presentSupport = false; VkBool32 presentSupport = false;
// 检查队列支持 // 检查显示队列支持
int i = 0; int i = 0;
if (!setter.settings.headless) if (!setter.settings.headless)
{ {
vkGetPhysicalDeviceSurfaceSupportKHR(device, i, surface, &presentSupport); vkGetPhysicalDeviceSurfaceSupportKHR(device, i, surface, &presentSupport);
} }
for (const auto& queueFamily : queueFamilies) for (const auto& queueFamily : queueFamilies)
{ {
if (queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT) { if (queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT) {
@ -238,9 +309,7 @@ VulkanBackend::VulkanFondation::QueueFamilyIndices VulkanBackend::VulkanFondatio
{ {
indices.presentFamily = i; indices.presentFamily = i;
} }
i++; i++;
} }
return indices; return indices;
@ -273,3 +342,83 @@ VulkanBackend::VulkanFondation::SwapChainSupportDetails VulkanBackend::VulkanFon
return details; return details;
} }
void VulkanBackend::VulkanFondation::createLogicalDevice()
{
QueueFamilyIndices indices = findQueueFamilies(physicalDevice);
std::vector<VkDeviceQueueCreateInfo> queueCreateInfos;
if (setter.settings.headless)
{
VkDeviceQueueCreateInfo queueCreateInfo{};
queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
queueCreateInfo.queueFamilyIndex = indices.graphicsFamily.value();
queueCreateInfo.queueCount = 1;
float queuePriority = 1.0f;
queueCreateInfo.pQueuePriorities = &queuePriority;
queueCreateInfos.push_back(queueCreateInfo);
}
else
{
std::set<uint32_t> uniqueQueueFamilies = { indices.graphicsFamily.value(),indices.presentFamily.value() };
float queuePriority = 1.0f;
for (uint32_t queueFamily : uniqueQueueFamilies)
{
VkDeviceQueueCreateInfo queueCreateInfo{};
queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
queueCreateInfo.queueFamilyIndex = queueFamily;
queueCreateInfo.queueCount = 1;
queueCreateInfo.pQueuePriorities = &queuePriority;
queueCreateInfos.push_back(queueCreateInfo);
}
}
VkPhysicalDeviceFeatures enableFeatures{};
if (deviceFeatures.samplerAnisotropy) {
enableFeatures.samplerAnisotropy = VK_TRUE;
}
std::vector<const char*> enabledExtensions{};
if (!setter.settings.headless)
{
for (auto swapchainExtension: swapchainExtensions)
{
enabledExtensions.push_back(swapchainExtension);
}
}
VkDeviceCreateInfo deviceCreateInfo{};
deviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
deviceCreateInfo.queueCreateInfoCount = static_cast<uint32_t>(queueCreateInfos.size());
deviceCreateInfo.pQueueCreateInfos = queueCreateInfos.data();
deviceCreateInfo.pEnabledFeatures = &enableFeatures;
deviceCreateInfo.enabledExtensionCount = static_cast<uint32_t>(enabledExtensions.size());
deviceCreateInfo.ppEnabledExtensionNames = enabledExtensions.data();
//新版本vulkan已不对实例和设备特定验证层做区分此处保证兼容性
if (setter.settings.validation)
{
deviceCreateInfo.enabledLayerCount = static_cast<uint32_t>(validationLayers.size());
deviceCreateInfo.ppEnabledLayerNames = validationLayers.data();
}
else
{
deviceCreateInfo.enabledLayerCount = 0;
}
if (vkCreateDevice(physicalDevice, &deviceCreateInfo, nullptr, &device) != VK_SUCCESS)
{
throw std::runtime_error("failed to create logical device");
}
vkGetDeviceQueue(device, indices.graphicsFamily.value(), 0, &graphicQueue);
if (setter.settings.headless)
{
vkGetDeviceQueue(device, indices.presentFamily.value(), 0, &presentQueue);
}
}

View File

@ -27,18 +27,18 @@ namespace VulkanBackend
//"VK_EXT_headless_surface" //"VK_EXT_headless_surface"
}; };
VulkanBackend::Setter setter; const int MAX_FRAME_IN_FLIGHT = 2;
void initVulkan();
private: private:
VulkanBackend::Setter setter;
VkInstance instance; VkInstance instance;
VkDebugUtilsMessengerEXT debugMessenger; VkDebugUtilsMessengerEXT debugMessenger;
VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
VkDevice device;
VkSurfaceKHR surface;
struct QueueFamilyIndices struct QueueFamilyIndices
{ {
std::optional<uint32_t> graphicsFamily; std::optional<uint32_t> graphicsFamily;
@ -61,23 +61,48 @@ namespace VulkanBackend
std::vector<VkPresentModeKHR> presentModes; std::vector<VkPresentModeKHR> presentModes;
}; };
VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
VkDevice device;
GLFWwindow* window;
VkSurfaceKHR surface;
VkPhysicalDeviceFeatures deviceFeatures;
VkQueue graphicQueue;
VkQueue presentQueue;
// 句柄创建,检查校验层支持和获取需要的扩展
void createInstance();
bool checkValidationLayerSupport();
std::vector<const char*> getRequiredExtensions();
// 实时显示结果使用的glfwSurface,受headless配置项控制
void createSurface();
// 设置校验层使用的消息回调
void setupDebugMessager();
void populateDebugMessengerCreateInfo(VkDebugUtilsMessengerCreateInfoEXT& debugCreateInfo);
static VKAPI_ATTR VkBool32 VKAPI_CALL debugCallback( static VKAPI_ATTR VkBool32 VKAPI_CALL debugCallback(
VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
VkDebugUtilsMessageTypeFlagsEXT messageTypes, VkDebugUtilsMessageTypeFlagsEXT messageTypes,
const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
void* pUserData); void* pUserData);
VkResult CreateDebugUtilsMessengerEXT(VkInstance instance, const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDebugUtilsMessengerEXT* pDebugMessenger);
void createInstance(); // 通过检查队列、交换链、扩展支持,选择合适的显卡
bool checkValidationLayerSupport();
std::vector<const char*> getRequiredExtensions();
void populateDebugMessengerCreateInfo(VkDebugUtilsMessengerCreateInfoEXT& debugCreateInfo);
void createSurface();
void pickPhysicalDevice(); void pickPhysicalDevice();
bool isDeviceSuitable(VkPhysicalDevice device); bool isDeviceSuitable(VkPhysicalDevice device);
bool checkDeviceExtensionSupport(VkPhysicalDevice device); bool checkDeviceExtensionSupport(VkPhysicalDevice device);
VulkanBackend::VulkanFondation::QueueFamilyIndices findQueueFamilies(VkPhysicalDevice device); VulkanBackend::VulkanFondation::QueueFamilyIndices findQueueFamilies(VkPhysicalDevice device);
VulkanBackend::VulkanFondation::SwapChainSupportDetails querySwapChainSupport(VkPhysicalDevice device); VulkanBackend::VulkanFondation::SwapChainSupportDetails querySwapChainSupport(VkPhysicalDevice device);
// 创建程序使用的逻辑显卡设备
void createLogicalDevice();
}; };
VulkanFondation::VulkanFondation() VulkanFondation::VulkanFondation()