重构完成逻辑设备创建,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"
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)
{
std::string prefix("");
@ -33,7 +33,7 @@ VKAPI_ATTR VkBool32 VKAPI_CALL debugMessageCallback(VkDebugReportFlagsEXT flags,
fflush(stdout);
return VK_FALSE;
}
*/
VkResult VulkanExampleBase::createInstance(bool enableValidation)
{
setter.settings.validation = enableValidation;
@ -591,7 +591,7 @@ void VulkanExampleBase::initVulkan()
/*
Validation layers
*/
if (settings.validation) {
vkCreateDebugReportCallback = reinterpret_cast<PFN_vkCreateDebugReportCallbackEXT>(vkGetInstanceProcAddr(instance, "vkCreateDebugReportCallbackEXT"));
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;
VK_CHECK_RESULT(vkCreateDebugReportCallback(instance, &debugCreateInfo, nullptr, &debugReportCallback));
}
*/
/*
GPU selection
*/
uint32_t gpuCount = 0;
VK_CHECK_RESULT(vkEnumeratePhysicalDevices(instance, &gpuCount, nullptr));
assert(gpuCount > 0);
@ -620,7 +620,7 @@ void VulkanExampleBase::initVulkan()
vkGetPhysicalDeviceProperties(physicalDevice, &deviceProperties);
vkGetPhysicalDeviceFeatures(physicalDevice, &deviceFeatures);
vkGetPhysicalDeviceMemoryProperties(physicalDevice, &deviceMemoryProperties);
*/
/*
Device creation
*/

View File

@ -2269,10 +2269,12 @@ void PlumageRender::updateUIOverlay()
}
// 完全重写避免OS specific
/*
PlumageRender* plumageRender;
// OS specific macros for the example main entry points
#if defined(_WIN32)
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
@ -2299,3 +2301,17 @@ PlumageRender* plumageRender;
return 0;
}
#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 "VulkanExampleBase.h"
#include "glTFModel.h"
#include "GLFW/glfw3.h"
#include <VulkanTexture.hpp>
#include "VulkanDevice.hpp"
#include "ui.hpp"
#include <VulkanUtils.hpp>
#include "renderSetter.h"
#include "GLFW/glfw3.h"
#include "vulkanFoundation.h"
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb_image_write.h"
@ -296,6 +299,7 @@ public:
void initWindow(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 loadScene(std::string filename);

View File

@ -1,12 +1,27 @@
#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()
{
// check validation layers
@ -106,6 +121,25 @@ std::vector<const char*> VulkanBackend::VulkanFondation::getRequiredExtensions()
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)
{
debugCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT;
@ -119,13 +153,49 @@ void VulkanBackend::VulkanFondation::populateDebugMessengerCreateInfo(VkDebugUti
debugCreateInfo.pfnUserCallback = &debugCallback;
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()
{
if (setter.settings.headless)
{
return;
}
if (glfwCreateWindowSurface(instance, window, nullptr, &surface) != VK_SUCCESS)
{
throw std::runtime_error("failed to create window surface in createSurface()");
}
}
inline void VulkanBackend::VulkanFondation::pickPhysicalDevice()
void VulkanBackend::VulkanFondation::pickPhysicalDevice()
{
uint32_t deviceCount = 0;
@ -208,12 +278,13 @@ VulkanBackend::VulkanFondation::QueueFamilyIndices VulkanBackend::VulkanFondatio
VkBool32 presentSupport = false;
// 检查队列支持
// 检查显示队列支持
int i = 0;
if (!setter.settings.headless)
{
vkGetPhysicalDeviceSurfaceSupportKHR(device, i, surface, &presentSupport);
}
for (const auto& queueFamily : queueFamilies)
{
if (queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT) {
@ -238,9 +309,7 @@ VulkanBackend::VulkanFondation::QueueFamilyIndices VulkanBackend::VulkanFondatio
{
indices.presentFamily = i;
}
i++;
}
return indices;
@ -273,3 +342,83 @@ VulkanBackend::VulkanFondation::SwapChainSupportDetails VulkanBackend::VulkanFon
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,24 +27,24 @@ namespace VulkanBackend
//"VK_EXT_headless_surface"
};
VulkanBackend::Setter setter;
const int MAX_FRAME_IN_FLIGHT = 2;
void initVulkan();
private:
VulkanBackend::Setter setter;
VkInstance instance;
VkDebugUtilsMessengerEXT debugMessenger;
VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
VkDevice device;
VkSurfaceKHR surface;
struct QueueFamilyIndices
{
std::optional<uint32_t> graphicsFamily;
std::optional<uint32_t> presentFamily;
bool isGraphicsFamilyComplete()
bool isGraphicsFamilyComplete()
{
return graphicsFamily.has_value();
}
@ -61,23 +61,48 @@ namespace VulkanBackend
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(
VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
VkDebugUtilsMessageTypeFlagsEXT messageTypes,
const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
void* pUserData);
void createInstance();
bool checkValidationLayerSupport();
std::vector<const char*> getRequiredExtensions();
void populateDebugMessengerCreateInfo(VkDebugUtilsMessengerCreateInfoEXT& debugCreateInfo);
VkResult CreateDebugUtilsMessengerEXT(VkInstance instance, const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDebugUtilsMessengerEXT* pDebugMessenger);
void createSurface();
// 通过检查队列、交换链、扩展支持,选择合适的显卡
void pickPhysicalDevice();
bool isDeviceSuitable(VkPhysicalDevice device);
bool checkDeviceExtensionSupport(VkPhysicalDevice device);
VulkanBackend::VulkanFondation::QueueFamilyIndices findQueueFamilies(VkPhysicalDevice device);
VulkanBackend::VulkanFondation::SwapChainSupportDetails querySwapChainSupport(VkPhysicalDevice device);
// 创建程序使用的逻辑显卡设备
void createLogicalDevice();
};
VulkanFondation::VulkanFondation()