From 079bd0f81e75918c3dca945021fdc573594bff1b Mon Sep 17 00:00:00 2001 From: InkSoul Date: Wed, 21 Feb 2024 20:23:59 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=E8=AE=BE=E5=A4=87=E5=88=9B?= =?UTF-8?q?=E5=BB=BA=E5=92=8C=E9=98=9F=E5=88=97=E5=88=9B=E5=BB=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- VulkanTutorial.cpp | 175 ++++++++++++++++++++++++++++++++++++++++++--- VulkanTutorial.h | 38 +++++++++- 2 files changed, 201 insertions(+), 12 deletions(-) diff --git a/VulkanTutorial.cpp b/VulkanTutorial.cpp index 3b6475c..74d7c95 100644 --- a/VulkanTutorial.cpp +++ b/VulkanTutorial.cpp @@ -84,17 +84,7 @@ void HelloTriangleApplication::createInstance() { throw std::runtime_error("failed to create instance"); } - // show available extensions - uint32_t availableExtensionCount = 0; - vkEnumerateInstanceExtensionProperties(nullptr, &availableExtensionCount, nullptr); - std::vector availableExtensions(availableExtensionCount); - vkEnumerateInstanceExtensionProperties(nullptr, &availableExtensionCount, availableExtensions.data()); - std::cout << "available extensions :" << std::endl; - for (const auto& extension : availableExtensions) - { - std::cout << "\t" << extension.extensionName << " ver:" << extension.specVersion << std::endl; - } } @@ -104,8 +94,15 @@ void HelloTriangleApplication::initVulkan() { createInstance(); + showAvailableExtension(); + setupDebugMessenger(); + createSurface(); + + pickPhysicalDevice(); + + createLogicalDevice(); } @@ -123,16 +120,22 @@ void HelloTriangleApplication::mainLoop(GLFWwindow* window){ void HelloTriangleApplication::cleanup(GLFWwindow* window) { + vkDestroyDevice(device, nullptr); + if (enableValidationLayers) { DestroyDebugUtilsMessengerEXT(instance, debugMessenger, nullptr); } + vkDestroySurfaceKHR(instance, surface, nullptr); + vkDestroyInstance(instance, nullptr); - + glfwDestroyWindow(window); glfwTerminate(); + + } std::vector HelloTriangleApplication::getRequiredExtensions() { @@ -152,6 +155,21 @@ std::vector HelloTriangleApplication::getRequiredExtensions() { } +void HelloTriangleApplication::showAvailableExtension() +{ + // show available extensions + + uint32_t availableExtensionCount = 0; + vkEnumerateInstanceExtensionProperties(nullptr, &availableExtensionCount, nullptr); + std::vector availableExtensions(availableExtensionCount); + vkEnumerateInstanceExtensionProperties(nullptr, &availableExtensionCount, availableExtensions.data()); + std::cout << "available extensions :" << std::endl; + for (const auto& extension : availableExtensions) + { + std::cout << "\t" << extension.extensionName << " ver:" << extension.specVersion << std::endl; + } +} + VKAPI_ATTR VkBool32 VKAPI_CALL HelloTriangleApplication::debugCallback( VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageTypes, @@ -196,6 +214,141 @@ void HelloTriangleApplication::populateDebugMessengerCreateInfo(VkDebugUtilsMess } +void HelloTriangleApplication::createSurface() +{ + if (glfwCreateWindowSurface(instance,window,nullptr,&surface) != VK_SUCCESS) + { + throw std::runtime_error("failed to create window surface in createSurface()"); + } +} + +void HelloTriangleApplication::pickPhysicalDevice() +{ + uint32_t deviceCount = 0; + vkEnumeratePhysicalDevices(instance, &deviceCount, nullptr); + if (deviceCount==0) + { + throw std::runtime_error("failed to find GPUs with Vulkan support"); + + } + + std::vector devices(deviceCount); + vkEnumeratePhysicalDevices(instance, &deviceCount, devices.data()); + + for (const auto& device : devices) + { + if (isDeviceSuitable(device)) + { + physicalDevice = device; + break; + } + + } + if (physicalDevice == VK_NULL_HANDLE) + { + throw std::runtime_error("failed to find a suitable GPU"); + } + +} + +bool HelloTriangleApplication::isDeviceSuitable(VkPhysicalDevice device) +{ + QueueFamilyIndices indices = findQueueFamilies(device); + + return indices.isComplete(); +} + +HelloTriangleApplication::QueueFamilyIndices HelloTriangleApplication::findQueueFamilies(VkPhysicalDevice device) +{ + QueueFamilyIndices indices; + + uint32_t queueFamilyCount = 0; + vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, nullptr); + + std::vector queueFamilies(queueFamilyCount); + vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, queueFamilies.data()); + + VkBool32 presentSupport = false; + + + int i = 0; + vkGetPhysicalDeviceSurfaceSupportKHR(device, i, surface, &presentSupport); + for (const auto& queueFamily : queueFamilies) + { + if (queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT) { + indices.graphicsFamily = i; + } + if (indices.isComplete()) + { + break; + } + if (presentSupport) + { + indices.presentFamily = i; + } + + i++; + + } + + return indices; + +} + +void HelloTriangleApplication::createLogicalDevice() +{ + QueueFamilyIndices indices = findQueueFamilies(physicalDevice); + + std::vector queueCreateInfos; + std::set 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); + + } + /* + 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; + */ + + VkDeviceCreateInfo deviceCreateInfo{}; + deviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; + deviceCreateInfo.queueCreateInfoCount = static_cast(queueCreateInfos.size()); + deviceCreateInfo.pQueueCreateInfos = queueCreateInfos.data(); + deviceCreateInfo.pEnabledFeatures = &deviceFeatures; + //新版本vulkan已不对实例和设备特定验证层做区分,此处保证兼容性 + deviceCreateInfo.enabledExtensionCount = 0; + if (enableValidationLayers) + { + deviceCreateInfo.enabledLayerCount = static_cast(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); + vkGetDeviceQueue(device, indices.presentFamily.value(), 0, &presentQueue); +} + + bool HelloTriangleApplication::checkValidationLayerSupport() { uint32_t layerCount; vkEnumerateInstanceLayerProperties(&layerCount, nullptr); diff --git a/VulkanTutorial.h b/VulkanTutorial.h index eb4bac2..2415eb9 100644 --- a/VulkanTutorial.h +++ b/VulkanTutorial.h @@ -3,14 +3,17 @@ #pragma once + #define GLFW_INCLUDE_VULKAN #include #include #include +#include #include #include #include +#include VkResult CreateDebugUtilsMessengerEXT(VkInstance instance, const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo,const VkAllocationCallbacks* pAllocator,VkDebugUtilsMessengerEXT* pDebugMessenger); @@ -36,6 +39,29 @@ private: VkDebugUtilsMessengerEXT debugMessenger; + VkPhysicalDevice physicalDevice = VK_NULL_HANDLE; + + VkDevice device; + + VkPhysicalDeviceFeatures deviceFeatures{}; + + VkQueue graphicQueue; + VkQueue presentQueue; + + VkSurfaceKHR surface; + + struct QueueFamilyIndices + { + std::optional graphicsFamily; + std::optional presentFamily; + + bool isComplete() { + return graphicsFamily.has_value() && presentFamily.has_value(); + } + }; + + + GLFWwindow* initWindow(int Width, int Height); void createInstance(); @@ -50,6 +76,8 @@ private: std::vector getRequiredExtensions(); + void showAvailableExtension(); + static VKAPI_ATTR VkBool32 VKAPI_CALL debugCallback( VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageTypes, @@ -57,9 +85,17 @@ private: void* pUserData); void setupDebugMessenger(); - void populateDebugMessengerCreateInfo(VkDebugUtilsMessengerCreateInfoEXT& createInfo); + void createSurface(); + + void pickPhysicalDevice(); + bool isDeviceSuitable(VkPhysicalDevice device); + + QueueFamilyIndices findQueueFamilies(VkPhysicalDevice device); + + void createLogicalDevice(); + }; HelloTriangleApplication::HelloTriangleApplication()