From a392206f96789fda85fe79edc4b2a76406259d51 Mon Sep 17 00:00:00 2001 From: Xiang Silian Date: Fri, 17 Oct 2025 15:20:23 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8A=BD=E8=B1=A1vulkan=20=E5=9F=BA=E7=B1=BB?= =?UTF-8?q?=EF=BC=8C=E6=A2=B3=E7=90=86=E4=BB=A3=E7=A0=81=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- vulkan/AppBase.cpp | 248 +++++++++++++++++++++++++++++++++++++ vulkan/AppBase.h | 67 ++++++++++ vulkan/Application.cpp | 271 ++++++----------------------------------- vulkan/Application.h | 99 ++------------- 4 files changed, 362 insertions(+), 323 deletions(-) create mode 100644 vulkan/AppBase.cpp create mode 100644 vulkan/AppBase.h diff --git a/vulkan/AppBase.cpp b/vulkan/AppBase.cpp new file mode 100644 index 0000000..cf0f496 --- /dev/null +++ b/vulkan/AppBase.cpp @@ -0,0 +1,248 @@ +#include "AppBase.h" + +std::vector AppBase::readFile(const std::string& enginePath) +{ + std::ifstream file{ enginePath, std::ios::ate | std::ios::binary }; + + if (!file.is_open()) + { + throw std::runtime_error("failed to open file: " + enginePath); + } + + size_t fileSize = static_cast(file.tellg()); + std::vector buffer(fileSize); + + file.seekg(0); + file.read(buffer.data(), fileSize); + file.close(); + return buffer; +} +VkShaderModule AppBase::createShaderModule(VkDevice& device, const std::vector& code) +{ + VkShaderModuleCreateInfo createInfo{}; + createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; + createInfo.codeSize = code.size(); + createInfo.pCode = reinterpret_cast(code.data()); + + VkShaderModule shaderModule; + if (vkCreateShaderModule(device, &createInfo, nullptr, &shaderModule) != VK_SUCCESS) + { + throw std::runtime_error("failed to create shader module!"); + } + + return shaderModule; +} + +bool AppBase::checkValidationLayerSupport() { + uint32_t layerCount; + vkEnumerateInstanceLayerProperties(&layerCount, nullptr); + + std::vector availableLayers(layerCount); + vkEnumerateInstanceLayerProperties(&layerCount, availableLayers.data()); + for (const char* layerName : validationLayers) { + bool layerFound = false; + + for (const auto& layerProperties : availableLayers) { + if (strcmp(layerName, layerProperties.layerName) == 0) { + layerFound = true; + break; + } + } + if (!layerFound) { + return false; + } + } + return true; +} + + +void AppBase::createInstance() +{ + if (enableValidationLayers && !checkValidationLayerSupport()) { + throw std::runtime_error("validation layers requested, but not available!"); + } + + VkApplicationInfo appInfo{}; + appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; + appInfo.pApplicationName = "Sample"; + appInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0); + appInfo.pEngineName = "No Engine"; + appInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0); + appInfo.apiVersion = VK_API_VERSION_1_0; + + VkInstanceCreateInfo createInfo{}; + createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; + createInfo.pApplicationInfo = &appInfo; + std::vector extensions; +#ifdef _WIN32 + // 获取 GLFW 所需的扩展 + uint32_t glfwExtensionCount = 0; + const char** glfwExtensions; + glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount); + + // 添加调试扩展 + for(int i = 0; i < glfwExtensionCount; i++) { + extensions.push_back(glfwExtensions[i]); + } + +#endif + + if (enableValidationLayers) { + extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); + } + + createInfo.enabledExtensionCount = static_cast(extensions.size()); + createInfo.ppEnabledExtensionNames = extensions.data(); + + if (enableValidationLayers) { + createInfo.enabledLayerCount = static_cast(validationLayers.size()); + createInfo.ppEnabledLayerNames = validationLayers.data(); + } + else { + createInfo.enabledLayerCount = 0; + } + + if (vkCreateInstance(&createInfo, nullptr, &instance) != VK_SUCCESS) { + throw std::runtime_error("failed to create instance!"); + } +} + +static VKAPI_ATTR VkBool32 VKAPI_CALL debugCallback( + VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, + VkDebugUtilsMessageTypeFlagsEXT messageType, + const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, + void* pUserData) { + + std::cerr << "validation layer: " << pCallbackData->pMessage << std::endl; + + return VK_FALSE; +} + +VkResult 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 AppBase::setupDebugMessenger() { + if (!enableValidationLayers) + return; + + VkDebugUtilsMessengerCreateInfoEXT createInfo{}; + createInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT; + createInfo.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT; + createInfo.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT; + createInfo.pfnUserCallback = debugCallback; + createInfo.pUserData = nullptr; // Optional + + if (CreateDebugUtilsMessengerEXT(instance, &createInfo, nullptr, &debugMessenger) != VK_SUCCESS) { + throw std::runtime_error("failed to set up debug messenger!"); + } +} + + +QueueFamilyIndices AppBase::findQueueFamilies(VkPhysicalDevice device, VkSurfaceKHR& surface) { + QueueFamilyIndices indices; + + uint32_t queueFamilyCount = 0; + vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, nullptr); + + std::vector queueFamilies(queueFamilyCount); + vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, queueFamilies.data()); + + int i = 0; + for (const auto& queueFamily : queueFamilies) { + if (queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT) { + indices.graphicsFamily = i; + } + VkBool32 presentSupport = false; + vkGetPhysicalDeviceSurfaceSupportKHR(device, i, surface, &presentSupport); + if (presentSupport) { + indices.presentFamily = i; + } + if (indices.isComplete()) { + break; + } + i++; + } + return indices; +} + +bool AppBase::checkSwapChainSupport(VkPhysicalDevice device, VkSurfaceKHR& surface) { + uint32_t formatCount; + vkGetPhysicalDeviceSurfaceFormatsKHR(device, surface, &formatCount, nullptr); + + uint32_t presentModeCount; + vkGetPhysicalDeviceSurfacePresentModesKHR(device, surface, &presentModeCount, nullptr); + + return formatCount > 0 && presentModeCount > 0; +} + +bool AppBase::checkDeviceExtensionSupport(VkPhysicalDevice device) { + // 获取设备支持的扩展数量 + uint32_t extensionCount; + vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount, nullptr); + + // 获取设备支持的扩展列表 + std::vector availableExtensions(extensionCount); + vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount, availableExtensions.data()); + + // 定义需要的扩展 + const std::vector requiredExtensions = { + VK_KHR_SWAPCHAIN_EXTENSION_NAME + }; + + // 检查所有需要的扩展是否都支持 + for (const char* requiredExtension : requiredExtensions) { + bool extensionFound = false; + for (const auto& extension : availableExtensions) { + if (strcmp(requiredExtension, extension.extensionName) == 0) { + extensionFound = true; + break; + } + } + + if (!extensionFound) { + return false; // 如果有一个扩展不支持,返回 false + } + } + + return true; // 所有扩展都支持 +} + + +bool AppBase::isDeviceSuitable(VkPhysicalDevice device, VkSurfaceKHR& surface) { + QueueFamilyIndices indices = findQueueFamilies(device, surface); + bool extensionsSupported = checkDeviceExtensionSupport(device); + bool swapChainAdequate = false; + if (extensionsSupported) { + swapChainAdequate = checkSwapChainSupport(device, surface); + } + return indices.isComplete() && extensionsSupported && swapChainAdequate; +} + +void AppBase::pickPhysicalDevice(VkPhysicalDevice& physicalDevice, VkSurfaceKHR& surface) +{ + 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, surface)) { + physicalDevice = device; + break; + } + } + + if (physicalDevice == VK_NULL_HANDLE) { + throw std::runtime_error("failed to find a suitable GPU!"); + } +} \ No newline at end of file diff --git a/vulkan/AppBase.h b/vulkan/AppBase.h new file mode 100644 index 0000000..7eb9ff0 --- /dev/null +++ b/vulkan/AppBase.h @@ -0,0 +1,67 @@ +#ifndef VULKAN_UTILS_H +#define VULKAN_UTILS_H + +#define VK_CHECK(x) \ + do \ + { \ + VkResult err = x; \ + if (err) \ + { \ + assert(false); \ + } \ + } while (0) + +#ifdef _WIN32 + #define logOut std::cout + #define GLFW_INCLUDE_VULKAN + #include +#else + #define logOut aout + #include +#endif + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct QueueFamilyIndices { + std::optional graphicsFamily; + std::optional presentFamily; + + bool isComplete() { + return graphicsFamily.has_value() && presentFamily.has_value(); + } +}; + +class AppBase +{ +public: + std::vector readFile(const std::string& enginePath); + VkShaderModule createShaderModule(VkDevice& device, const std::vector& code); + const std::vector validationLayers = {"VK_LAYER_KHRONOS_validation"}; +protected: + VkInstance instance; + void createInstance(); + bool checkValidationLayerSupport(); + void setupDebugMessenger(); + bool checkSwapChainSupport(VkPhysicalDevice device, VkSurfaceKHR& surface); + bool checkDeviceExtensionSupport(VkPhysicalDevice device); + QueueFamilyIndices findQueueFamilies(VkPhysicalDevice device, VkSurfaceKHR& surface); + bool isDeviceSuitable(VkPhysicalDevice device, VkSurfaceKHR& surface); + void pickPhysicalDevice(VkPhysicalDevice& physicalDevice, VkSurfaceKHR& surface); +#ifdef _WIN32 + GLFWwindow *window; +#endif + + bool enableValidationLayers = true; + VkDebugUtilsMessengerEXT debugMessenger; +}; + +#endif // VULKAN_UTILS_H \ No newline at end of file diff --git a/vulkan/Application.cpp b/vulkan/Application.cpp index b46554d..2849407 100644 --- a/vulkan/Application.cpp +++ b/vulkan/Application.cpp @@ -9,54 +9,7 @@ #include "../app/src/main/cpp/AndroidOut.h" #endif -bool enableValidationLayers = true; -void Application::createInstance() -{ - if (enableValidationLayers && !checkValidationLayerSupport()) { - throw std::runtime_error("validation layers requested, but not available!"); - } - - VkApplicationInfo appInfo{}; - appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; - appInfo.pApplicationName = "Sample"; - appInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0); - appInfo.pEngineName = "No Engine"; - appInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0); - appInfo.apiVersion = VK_API_VERSION_1_0; - - VkInstanceCreateInfo createInfo{}; - createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; - createInfo.pApplicationInfo = &appInfo; - -#ifdef _WIN32 - // 获取 GLFW 所需的扩展 - uint32_t glfwExtensionCount = 0; - const char** glfwExtensions; - glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount); - - // 添加调试扩展 - std::vector extensions(glfwExtensions, glfwExtensions + glfwExtensionCount); - if (enableValidationLayers) { - extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); - } - - createInfo.enabledExtensionCount = static_cast(extensions.size()); - createInfo.ppEnabledExtensionNames = extensions.data(); -#endif - - if (enableValidationLayers) { - createInfo.enabledLayerCount = static_cast(validationLayers.size()); - createInfo.ppEnabledLayerNames = validationLayers.data(); - } - else { - createInfo.enabledLayerCount = 0; - } - - if (vkCreateInstance(&createInfo, nullptr, &instance) != VK_SUCCESS) { - throw std::runtime_error("failed to create instance!"); - } -} void Application::initWindow() { @@ -66,7 +19,7 @@ void Application::initWindow() glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE); - window = glfwCreateWindow(kWidth, kHeight, "Vulkan", nullptr, nullptr); + window = glfwCreateWindow(480, 480, "Vulkan", nullptr, nullptr); #else #endif @@ -74,7 +27,6 @@ void Application::initWindow() void Application::run() { - initWindow(); initVulkan(); mainLoop(); cleanup(); @@ -102,49 +54,15 @@ void Application::createSurface() { #endif } -static VKAPI_ATTR VkBool32 VKAPI_CALL debugCallback( - VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, - VkDebugUtilsMessageTypeFlagsEXT messageType, - const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, - void* pUserData) { - std::cerr << "validation layer: " << pCallbackData->pMessage << std::endl; - - return VK_FALSE; -} - -VkResult 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 Application::setupDebugMessenger() { - if (!enableValidationLayers) - return; - - VkDebugUtilsMessengerCreateInfoEXT createInfo{}; - createInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT; - createInfo.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT; - createInfo.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT; - createInfo.pfnUserCallback = debugCallback; - createInfo.pUserData = nullptr; // Optional - - if (CreateDebugUtilsMessengerEXT(instance, &createInfo, nullptr, &debugMessenger) != VK_SUCCESS) { - throw std::runtime_error("failed to set up debug messenger!"); - } -} void Application::initVulkan() { + initWindow(); createInstance(); // 创建 Vulkan 实例 - setupDebugMessenger(); // 在这里调用 + setupDebugMessenger(); // 在这里调用 createSurface(); // 创建窗口表面 - pickPhysicalDevice(); // 选择物理设备 + pickPhysicalDevice(physicalDevice, surface); // 选择物理设备 createLogicalDevice(); // 创建逻辑设备 createSwapChain(); // 创建交换链 createImageViews(); // 创建交换链图像视图 @@ -207,7 +125,7 @@ void Application::createFramebuffers() { } void Application::createCommandPool() { - QueueFamilyIndices queueFamilyIndices = findQueueFamilies(physicalDevice); + QueueFamilyIndices queueFamilyIndices = findQueueFamilies(physicalDevice, surface); VkCommandPoolCreateInfo poolInfo{}; poolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; @@ -246,109 +164,9 @@ void Application::mainLoop() } -void Application::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!"); - } -} - - -QueueFamilyIndices Application::findQueueFamilies(VkPhysicalDevice device) { - QueueFamilyIndices indices; - - uint32_t queueFamilyCount = 0; - vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, nullptr); - - std::vector queueFamilies(queueFamilyCount); - vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, queueFamilies.data()); - - int i = 0; - for (const auto& queueFamily : queueFamilies) { - if (queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT) { - indices.graphicsFamily = i; - } - VkBool32 presentSupport = false; - vkGetPhysicalDeviceSurfaceSupportKHR(device, i, surface, &presentSupport); - if (presentSupport) { - indices.presentFamily = i; - } - if (indices.isComplete()) { - break; - } - i++; - } - return indices; -} - -bool Application::checkDeviceExtensionSupport(VkPhysicalDevice device) { - // 获取设备支持的扩展数量 - uint32_t extensionCount; - vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount, nullptr); - - // 获取设备支持的扩展列表 - std::vector availableExtensions(extensionCount); - vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount, availableExtensions.data()); - - // 定义需要的扩展 - const std::vector requiredExtensions = { - VK_KHR_SWAPCHAIN_EXTENSION_NAME - }; - - // 检查所有需要的扩展是否都支持 - for (const char* requiredExtension : requiredExtensions) { - bool extensionFound = false; - for (const auto& extension : availableExtensions) { - if (strcmp(requiredExtension, extension.extensionName) == 0) { - extensionFound = true; - break; - } - } - - if (!extensionFound) { - return false; // 如果有一个扩展不支持,返回 false - } - } - - return true; // 所有扩展都支持 -} - -bool Application::checkSwapChainSupport(VkPhysicalDevice device) { - uint32_t formatCount; - vkGetPhysicalDeviceSurfaceFormatsKHR(device, surface, &formatCount, nullptr); - - uint32_t presentModeCount; - vkGetPhysicalDeviceSurfacePresentModesKHR(device, surface, &presentModeCount, nullptr); - - return formatCount > 0 && presentModeCount > 0; -} - -bool Application::isDeviceSuitable(VkPhysicalDevice device) { - QueueFamilyIndices indices = findQueueFamilies(device); - bool extensionsSupported = checkDeviceExtensionSupport(device); - bool swapChainAdequate = false; - if (extensionsSupported) { - swapChainAdequate = checkSwapChainSupport(device); - } - return indices.isComplete() && extensionsSupported && swapChainAdequate; -} void Application::createLogicalDevice() { - QueueFamilyIndices indices = findQueueFamilies(physicalDevice); + QueueFamilyIndices indices = findQueueFamilies(physicalDevice, surface); std::vector queueCreateInfos; std::set uniqueQueueFamilies = { indices.graphicsFamily.value(), indices.presentFamily.value() }; @@ -386,26 +204,31 @@ void Application::createLogicalDevice() { vkGetDeviceQueue(device, indices.presentFamily.value(), 0, &presentQueue); } -//vk::Extent2D choose_extent(vk::Extent2D request_extent, -// const vk::Extent2D& min_image_extent, -// const vk::Extent2D& max_image_extent, -// const vk::Extent2D& current_extent) -//{ -// if (current_extent.width == 0xFFFFFFFF) -// { -// return request_extent; -// } -// -// if (request_extent.width < 1 || request_extent.height < 1) -// { -// return current_extent; -// } -// -// request_extent.width = clamp(request_extent.width, min_image_extent.width, max_image_extent.width); -// request_extent.height = clamp(request_extent.height, min_image_extent.height, max_image_extent.height); -// -// return request_extent; -//} +inline VkExtent2D choose_extent( + VkExtent2D request_extent, + const VkExtent2D &min_image_extent, + const VkExtent2D &max_image_extent, + const VkExtent2D ¤t_extent) +{ + if (current_extent.width == 0xFFFFFFFF) + { + return request_extent; + } + + if (request_extent.width < 1 || request_extent.height < 1) + { + logOut << "(Swapchain) Image extent ("<< request_extent.width << ", " << request_extent.height << ") not supported. Selecting ("<< current_extent.width << ", " << current_extent.height << ")." << std::endl; + return current_extent; + } + + request_extent.width = std::max(request_extent.width, min_image_extent.width); + request_extent.width = std::min(request_extent.width, max_image_extent.width); + + request_extent.height = std::max(request_extent.height, min_image_extent.height); + request_extent.height = std::min(request_extent.height, max_image_extent.height); + + return request_extent; +} void Application::createSwapChain() { // 选择交换链格式、颜色空间和分辨率 @@ -413,6 +236,10 @@ void Application::createSwapChain() { VkPresentModeKHR presentMode = VK_PRESENT_MODE_FIFO_KHR; VkExtent2D extent = { 0, 0 }; + VkSurfaceCapabilitiesKHR surface_capabilities{}; + vkGetPhysicalDeviceSurfaceCapabilitiesKHR(this->physicalDevice, this->surface, &surface_capabilities); + + extent = choose_extent(extent, surface_capabilities.minImageExtent, surface_capabilities.maxImageExtent, surface_capabilities.currentExtent); // 创建交换链 VkSwapchainCreateInfoKHR createInfo{}; createInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; @@ -420,11 +247,11 @@ void Application::createSwapChain() { createInfo.minImageCount = 2; // 双缓冲 createInfo.imageFormat = surfaceFormat.format; createInfo.imageColorSpace = surfaceFormat.colorSpace; - //createInfo.imageExtent = choose_extent(extent, surface_capabilities.minImageExtent, surface_capabilities.maxImageExtent, surface_capabilities.currentExtent);; + createInfo.imageExtent = extent; createInfo.imageArrayLayers = 1; createInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; - QueueFamilyIndices indices = findQueueFamilies(physicalDevice); + QueueFamilyIndices indices = findQueueFamilies(physicalDevice, surface); uint32_t queueFamilyIndices[] = { indices.graphicsFamily.value(), indices.presentFamily.value() }; if (indices.graphicsFamily != indices.presentFamily) { @@ -477,8 +304,8 @@ void Application::createGraphicsPipeline() { auto fragShaderCode = readFile("shaders/simple_shader.frag.spv"); // 创建着色器模块 - VkShaderModule vertShaderModule = createShaderModule(vertShaderCode); - VkShaderModule fragShaderModule = createShaderModule(fragShaderCode); + VkShaderModule vertShaderModule = createShaderModule(this->device, vertShaderCode); + VkShaderModule fragShaderModule = createShaderModule(this->device, fragShaderCode); // 定义着色器阶段 VkPipelineShaderStageCreateInfo vertShaderStageInfo{}; @@ -613,27 +440,7 @@ void Application::createRenderPass() { } } -bool Application::checkValidationLayerSupport() { - uint32_t layerCount; - vkEnumerateInstanceLayerProperties(&layerCount, nullptr); - std::vector availableLayers(layerCount); - vkEnumerateInstanceLayerProperties(&layerCount, availableLayers.data()); - for (const char* layerName : validationLayers) { - bool layerFound = false; - - for (const auto& layerProperties : availableLayers) { - if (strcmp(layerName, layerProperties.layerName) == 0) { - layerFound = true; - break; - } - } - if (!layerFound) { - return false; - } - } - return true; -} void Application::recordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageIndex) { VkCommandBufferBeginInfo beginInfo{}; diff --git a/vulkan/Application.h b/vulkan/Application.h index 547d4d0..751cdd1 100644 --- a/vulkan/Application.h +++ b/vulkan/Application.h @@ -1,106 +1,28 @@  #pragma once -#ifdef _WIN32 - #define GLFW_INCLUDE_VULKAN - #include -#else - #include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define VK_CHECK(x) \ - do \ - { \ - VkResult err = x; \ - if (err) \ - { \ - assert(false); \ - } \ - } while (0) - -struct QueueFamilyIndices { - std::optional graphicsFamily; - std::optional presentFamily; - - bool isComplete() { - return graphicsFamily.has_value() && presentFamily.has_value(); - } -}; +#include "AppBase.h" -class Application + +class Application : public AppBase { -private: - std::vector readFile(const std::string &enginePath) - { - std::ifstream file{enginePath, std::ios::ate | std::ios::binary}; - - if (!file.is_open()) - { - throw std::runtime_error("failed to open file: " + enginePath); - } - - size_t fileSize = static_cast(file.tellg()); - std::vector buffer(fileSize); - - file.seekg(0); - file.read(buffer.data(), fileSize); - file.close(); - return buffer; - } - VkShaderModule createShaderModule(const std::vector &code) - { - VkShaderModuleCreateInfo createInfo{}; - createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; - createInfo.codeSize = code.size(); - createInfo.pCode = reinterpret_cast(code.data()); - - VkShaderModule shaderModule; - if (vkCreateShaderModule(device, &createInfo, nullptr, &shaderModule) != VK_SUCCESS) - { - throw std::runtime_error("failed to create shader module!"); - } - - return shaderModule; - } - public: void run(); -private: -#ifdef _WIN32 - GLFWwindow *window; -#endif - VkInstance instance; - +protected: + void initVulkan(); void initWindow(); void createSurface(); - void initVulkan(); void mainLoop(); void cleanup(); - void createInstance(); + void createImageViews(); void createFramebuffers(); void createCommandPool(); void createCommandBuffer(); - void setupDebugMessenger(); - void pickPhysicalDevice(); - QueueFamilyIndices findQueueFamilies(VkPhysicalDevice device); - bool isDeviceSuitable(VkPhysicalDevice device); - bool checkSwapChainSupport(VkPhysicalDevice device); - bool checkDeviceExtensionSupport(VkPhysicalDevice device); - bool checkValidationLayerSupport(); + void createLogicalDevice(); void createSwapChain(); void createPipelineLayout(); @@ -129,10 +51,5 @@ private: VkSemaphore renderFinishedSemaphore; // 渲染完成信号量 VkFence inFlightFence; // 同步栅栏 VkQueue presentQueue; // 呈现队列 - VkDebugUtilsMessengerEXT debugMessenger; - const std::vector validationLayers = { - "VK_LAYER_KHRONOS_validation" - }; - const uint32_t kWidth = 480; - const uint32_t kHeight = 480; + }; \ No newline at end of file