Vulkan各部分参数

OpenTK 2026-07-08 11:32:22

1. createInstance() - 创建Vulkan实例

void createInstance() {
    // ==================== 应用程序信息 ====================
    VkApplicationInfo appInfo{};
    appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;  // 结构体类型标识
    appInfo.pNext = nullptr;  // 扩展链指针,本例不使用
    
    // 应用名称 - 驱动可能用于性能优化或调试
    appInfo.pApplicationName = "My Vulkan Application";
    
    // 应用版本号 - 格式: 主版本.次版本.补丁版本
    appInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
    // 可以这样: VK_MAKE_VERSION(2, 5, 3) 表示 v2.5.3
    
    // 引擎名称 - 如果是使用引擎开发,这里填引擎名
    appInfo.pEngineName = "Custom Game Engine";
    
    // 引擎版本号
    appInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0);
    
    // Vulkan API版本 - 决定使用哪个版本的Vulkan功能
    appInfo.apiVersion = VK_API_VERSION_1_3;  // 可选: VK_API_VERSION_1_0, 1_1, 1_2, 1_3

    // ==================== 实例创建主信息 ====================
    VkInstanceCreateInfo createInfo{};
    createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
    createInfo.pNext = nullptr;  // 后面会通过pNext链附加调试信息
    
    // 实例创建标志 - 目前保留为0,未来可能用
    createInfo.flags = 0;
    
    // 绑定应用程序信息
    createInfo.pApplicationInfo = &appInfo;

    // ==================== 启用的扩展 ====================
    // 扩展是Vulkan的可选功能,必须显式启用
    std::vector<const char*> extensions = {
        // ---- 必需扩展 ----
        "VK_KHR_surface",              // 窗口表面基础扩展(必须)
        
        // ---- 平台特定表面扩展(根据操作系统选择) ----
        #ifdef _WIN32
        "VK_KHR_win32_surface",        // Windows平台表面扩展
        #elif defined(__linux__)
        "VK_KHR_xcb_surface",          // Linux XCB表面(或VK_KHR_xlib_surface)
        "VK_KHR_wayland_surface",      // Linux Wayland表面
        #elif defined(__APPLE__)
        "VK_MVK_macos_surface",        // macOS表面(MoltenVK)
        "VK_EXT_metal_surface",        // Metal表面
        #elif defined(__ANDROID__)
        "VK_KHR_android_surface",      // Android表面
        #endif
        
        // ---- 调试扩展(仅在调试版本启用) ----
        "VK_EXT_debug_utils",          // 调试工具扩展 - 用于验证层回调
        // "VK_EXT_validation_features", // 验证层特性控制 - 精细控制验证行为
        
        // ---- 性能扩展 ----
        // "VK_KHR_performance_query",   // 性能查询
        // "VK_KHR_pipeline_executable_properties", // 管线可执行属性
        
        // ---- 设备组扩展(多GPU) ----
        // "VK_KHR_device_group",        // 设备组支持
        // "VK_KHR_device_group_creation", // 设备组创建
        
        // ---- 显示扩展(无窗口系统) ----
        // "VK_KHR_display",             // 直接显示(不需要窗口系统)
        // "VK_KHR_display_swapchain",   // 显示交换链
        
        // ---- 其他有用扩展 ----
        // "VK_KHR_get_physical_device_properties2", // 获取设备属性2(Vulkan 1.1已包含)
        // "VK_KHR_external_memory_capabilities", // 外部内存能力
        // "VK_KHR_external_semaphore_capabilities", // 外部信号量能力
        // "VK_KHR_external_fence_capabilities", // 外部栅栏能力
    };
    
    createInfo.enabledExtensionCount = static_cast<uint32_t>(extensions.size());
    createInfo.ppEnabledExtensionNames = extensions.data();

    // ==================== 启用的验证层 ====================
    // 验证层在发布版本应该禁用,以提升性能
    std::vector<const char*> validationLayers = {
        "VK_LAYER_KHRONOS_validation",   // 标准验证层(包含所有验证)
        // "VK_LAYER_LUNARG_monitor",     // 性能监控层 - 显示GPU使用率
        // "VK_LAYER_LUNARG_screenshot",  // 截图层 - 截取渲染结果
        // "VK_LAYER_KHRONOS_synchronization2", // 同步验证层2 - 检测同步错误
        // "VK_LAYER_KHRONOS_profiles",   // 配置文件层 - 测试不同设备兼容性
        // "VK_LAYER_LUNARG_api_dump",    // API转储层 - 记录所有API调用
        // "VK_LAYER_LUNARG_core_validation", // 核心验证(旧版)
        // "VK_LAYER_LUNARG_parameter_validation", // 参数验证(旧版)
        // "VK_LAYER_LUNARG_object_tracker", // 对象跟踪(旧版)
        // "VK_LAYER_GOOGLE_threading",   // 线程安全验证
        // "VK_LAYER_GOOGLE_unique_objects", // 唯一对象验证
    };
    
    if (enableValidationLayers) {
        createInfo.enabledLayerCount = static_cast<uint32_t>(validationLayers.size());
        createInfo.ppEnabledLayerNames = validationLayers.data();
    } else {
        createInfo.enabledLayerCount = 0;
        createInfo.ppEnabledLayerNames = nullptr;
    }

    // ==================== pNext扩展链配置 ====================
    // 通过pNext链可以传递额外的配置信息
    
    // 1. 调试信使配置(用于实例创建时捕获早期错误)
    VkDebugUtilsMessengerCreateInfoEXT debugCreateInfo{};
    if (enableValidationLayers) {
        debugCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT;
        debugCreateInfo.pNext = nullptr;
        
        // 设置消息严重性级别 - 决定接收哪些级别的消息
        debugCreateInfo.messageSeverity = 
            VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT |  // 详细: 资源分配、对象创建等
            VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT |     // 信息: API调用、状态变化
            VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT |  // 警告: 潜在问题、使用不当
            VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;     // 错误: API违规、崩溃风险
        
        // 设置消息类型 - 决定接收哪些类型的消息
        debugCreateInfo.messageType =
            VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT |      // 通用: 性能和规范相关
            VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT |   // 验证: API使用错误
            VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT |  // 性能: 性能建议
            VK_DEBUG_UTILS_MESSAGE_TYPE_DEVICE_ADDRESS_BINDING_BIT_EXT; // 设备地址绑定
        
        debugCreateInfo.pfnUserCallback = debugCallback;  // 回调函数
        debugCreateInfo.pUserData = nullptr;  // 可传递自定义数据
        
        // 将调试信使链接到实例创建信息
        createInfo.pNext = &debugCreateInfo;
        
        // 2. 验证层特性控制(更精细的验证设置)
        VkValidationFeaturesEXT validationFeatures{};
        validationFeatures.sType = VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT;
        
        // 启用特定的验证功能
        std::vector<VkValidationFeatureEnableEXT> enableFeatures = {
            VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT,      // GPU辅助验证(检测着色器错误)
            VK_VALIDATION_FEATURE_ENABLE_DEBUG_PRINTF_EXT,      // 允许着色器使用debugPrintf
            // VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXT, // 同步验证
            // VK_VALIDATION_FEATURE_ENABLE_BEST_PRACTICES_EXT, // 最佳实践检查
        };
        validationFeatures.enabledValidationFeatureCount = enableFeatures.size();
        validationFeatures.pEnabledValidationFeatures = enableFeatures.data();
        
        // 禁用特定的验证功能
        std::vector<VkValidationFeatureDisableEXT> disableFeatures = {
            // VK_VALIDATION_FEATURE_DISABLE_THREAD_SAFETY_EXT,   // 禁用线程安全检查
            // VK_VALIDATION_FEATURE_DISABLE_API_PARAMETERS_EXT,  // 禁用API参数检查
            // VK_VALIDATION_FEATURE_DISABLE_OBJECT_LIFETIMES_EXT, // 禁用对象生命周期检查
            // VK_VALIDATION_FEATURE_DISABLE_CORE_CHECKS_EXT,     // 禁用核心检查
            // VK_VALIDATION_FEATURE_DISABLE_UNIQUE_HANDLES_EXT,  // 禁用唯一句柄检查
            // VK_VALIDATION_FEATURE_DISABLE_SHADER_VALIDATION_EXT, // 禁用着色器验证
        };
        validationFeatures.disabledValidationFeatureCount = disableFeatures.size();
        validationFeatures.pDisabledValidationFeatures = disableFeatures.data();
        
        // 将验证特性链接到调试信使(形成链: createInfo -> debugCreateInfo -> validationFeatures)
        debugCreateInfo.pNext = &validationFeatures;
    }

    // ==================== 创建实例 ====================
    if (vkCreateInstance(&createInfo, nullptr, &instance) != VK_SUCCESS) {
        throw std::runtime_error("failed to create instance!");
    }
}

2. setupDebugMessenger() - 调试信使

void setupDebugMessenger() {
    if (!enableValidationLayers) return;

    // ==================== 调试信使创建信息 ====================
    VkDebugUtilsMessengerCreateInfoEXT createInfo{};
    createInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT;
    createInfo.pNext = nullptr;
    createInfo.flags = 0;  // 保留,必须为0

    // ==================== 消息严重性过滤 ====================
    // 控制接收哪些级别的消息
    createInfo.messageSeverity = 
        VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT |  // 最详细: 每个API调用、资源创建
        VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT |     // 信息: 驱动信息、性能数据
        VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT |  // 警告: 不规范用法、潜在bug
        VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;     // 错误: API违规、致命问题
    
    // 也可以只接收警告和错误(减少输出)
    // 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_GENERAL_BIT_EXT |      // 通用: 性能和规范建议
        VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT |   // 验证: API使用错误
        VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT |  // 性能: 性能优化建议
        VK_DEBUG_UTILS_MESSAGE_TYPE_DEVICE_ADDRESS_BINDING_BIT_EXT; // 设备地址绑定

    // ==================== 回调函数设置 ====================
    createInfo.pfnUserCallback = debugCallback;  // 消息处理函数指针
    createInfo.pUserData = nullptr;  // 传递给回调的用户数据

    // ==================== 创建调试信使 ====================
    if (CreateDebugUtilsMessengerEXT(instance, &createInfo, nullptr, &debugMessenger) != VK_SUCCESS) {
        throw std::runtime_error("failed to set up debug messenger!");
    }
}

3. createSurface() - 窗口表面

void createSurface() {
    // ==================== GLFW方式(推荐,跨平台) ====================
    if (glfwCreateWindowSurface(instance, window, nullptr, &surface) != VK_SUCCESS) {
        throw std::runtime_error("failed to create window surface!");
    }
    
    // ==================== 手动创建(平台特定) ====================
    #ifdef _WIN32
    // Windows平台手动创建
    VkWin32SurfaceCreateInfoKHR win32CreateInfo{};
    win32CreateInfo.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
    win32CreateInfo.pNext = nullptr;
    win32CreateInfo.flags = 0;
    win32CreateInfo.hinstance = GetModuleHandle(nullptr);  // 当前实例句柄
    win32CreateInfo.hwnd = glfwGetWin32Window(window);     // 窗口句柄
    // vkCreateWin32SurfaceKHR(instance, &win32CreateInfo, nullptr, &surface);
    
    #elif defined(__linux__)
    // Linux XCB方式
    VkXcbSurfaceCreateInfoKHR xcbCreateInfo{};
    xcbCreateInfo.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR;
    xcbCreateInfo.pNext = nullptr;
    xcbCreateInfo.flags = 0;
    xcbCreateInfo.connection = xcbConnection;  // XCB连接
    xcbCreateInfo.window = xcbWindow;          // XCB窗口
    // vkCreateXcbSurfaceKHR(instance, &xcbCreateInfo, nullptr, &surface);
    
    // Linux Wayland方式
    VkWaylandSurfaceCreateInfoKHR waylandCreateInfo{};
    waylandCreateInfo.sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR;
    waylandCreateInfo.pNext = nullptr;
    waylandCreateInfo.flags = 0;
    waylandCreateInfo.display = waylandDisplay;  // Wayland显示
    waylandCreateInfo.surface = waylandSurface;  // Wayland表面
    // vkCreateWaylandSurfaceKHR(instance, &waylandCreateInfo, nullptr, &surface);
    
    #elif defined(__APPLE__)
    // macOS方式(使用MoltenVK)
    VkMacOSSurfaceCreateInfoMVK macosCreateInfo{};
    macosCreateInfo.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK;
    macosCreateInfo.pNext = nullptr;
    macosCreateInfo.flags = 0;
    macosCreateInfo.pView = metalView;  // Metal视图
    // vkCreateMacOSSurfaceMVK(instance, &macosCreateInfo, nullptr, &surface);
    
    #elif defined(__ANDROID__)
    // Android方式
    VkAndroidSurfaceCreateInfoKHR androidCreateInfo{};
    androidCreateInfo.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR;
    androidCreateInfo.pNext = nullptr;
    androidCreateInfo.flags = 0;
    androidCreateInfo.window = androidWindow;  // Android窗口
    // vkCreateAndroidSurfaceKHR(instance, &androidCreateInfo, nullptr, &surface);
    #endif
}

4. pickPhysicalDevice() - 物理设备选择

void 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<VkPhysicalDevice> devices(deviceCount);
    vkEnumeratePhysicalDevices(instance, &deviceCount, devices.data());

    // ==================== 设备评分系统 ====================
    // 为每个设备打分,选择分数最高的
    std::multimap<int, VkPhysicalDevice> rankedDevices;
    
    for (const auto& device : devices) {
        int score = rateDeviceSuitability(device);
        rankedDevices.insert(std::make_pair(score, device));
    }
    
    // 选择分数最高的设备
    if (rankedDevices.rbegin()->first > 0) {
        physicalDevice = rankedDevices.rbegin()->second;
    } else {
        throw std::runtime_error("failed to find a suitable GPU!");
    }
}

int rateDeviceSuitability(VkPhysicalDevice device) {
    int score = 0;
    
    // ==================== 获取设备属性 ====================
    VkPhysicalDeviceProperties properties;
    vkGetPhysicalDeviceProperties(device, &properties);
    
    // 设备名称
    // properties.deviceName = "NVIDIA GeForce RTX 3080"
    // properties.deviceName = "AMD Radeon RX 6800 XT"
    // properties.deviceName = "Intel UHD Graphics 630"
    
    // 设备类型 - 分数权重
    if (properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) {
        score += 1000;  // 独立显卡:最高分
    } else if (properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU) {
        score += 500;   // 集成显卡:中等
    } else if (properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU) {
        score += 200;   // 虚拟GPU
    } else if (properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_CPU) {
        score += 100;   // CPU渲染
    }
    
    // 设备限制
    // properties.limits.maxImageDimension2D = 16384  // 最大纹理尺寸
    // properties.limits.maxViewports = 16            // 最大视口数
    // properties.limits.maxPushConstantsSize = 128  // 推送常量大小
    // properties.limits.maxMemoryAllocationCount = 4096
    
    // 设备API版本
    // properties.apiVersion = VK_API_VERSION_1_3
    
    // 驱动版本
    // properties.driverVersion = 510.47.03

    // ==================== 获取设备特性 ====================
    VkPhysicalDeviceFeatures features;
    vkGetPhysicalDeviceFeatures(device, &features);
    
    // 检查需要的特性
    if (features.geometryShader) {
        score += 100;  // 支持几何着色器
    }
    if (features.tessellationShader) {
        score += 100;  // 支持细分着色器
    }
    if (features.samplerAnisotropy) {
        score += 50;   // 支持各向异性过滤
    }
    if (features.textureCompressionBC) {
        score += 50;   // 支持BC纹理压缩(DXT)
    }
    if (features.textureCompressionETC2) {
        score += 30;   // 支持ETC2压缩
    }
    if (features.textureCompressionASTC_LDR) {
        score += 30;   // 支持ASTC压缩
    }
    if (features.shaderFloat64) {
        score += 20;   // 支持双精度浮点
    }
    if (features.multiDrawIndirect) {
        score += 20;   // 支持间接多绘制
    }
    if (features.fragmentStoresAndAtomics) {
        score += 20;   // 支持片段存储和原子操作
    }
    if (features.vertexPipelineStoresAndAtomics) {
        score += 10;   // 支持顶点管线存储
    }
    if (features.fillModeNonSolid) {
        score += 10;   // 支持线框模式
    }
    
    // ==================== 获取Vulkan 1.1特性 ====================
    VkPhysicalDeviceVulkan11Features features11{};
    features11.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES;
    
    VkPhysicalDeviceFeatures2 features2{};
    features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
    features2.pNext = &features11;
    vkGetPhysicalDeviceFeatures2(device, &features2);
    
    if (features11.multiview) {
        score += 30;   // 支持多视图(VR)
    }
    if (features11.variablePointers) {
        score += 20;   // 支持可变指针
    }
    if (features11.storageBuffer16BitAccess) {
        score += 10;   // 支持16位存储缓冲
    }
    
    // ==================== 获取Vulkan 1.2特性 ====================
    VkPhysicalDeviceVulkan12Features features12{};
    features12.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES;
    features11.pNext = &features12;
    
    if (features12.descriptorIndexing) {
        score += 50;   // 支持描述符索引(大量纹理)
    }
    if (features12.shaderFloat16) {
        score += 20;   // 支持16位浮点着色器
    }
    if (features12.shaderInt8) {
        score += 10;   // 支持8位整数着色器
    }
    if (features12.timelineSemaphore) {
        score += 20;   // 支持时间线信号量
    }
    if (features12.bufferDeviceAddress) {
        score += 20;   // 支持缓冲设备地址
    }
    
    // ==================== 检查队列族 ====================
    QueueFamilyIndices indices = findQueueFamilies(device);
    if (!indices.isComplete()) {
        return 0;  // 缺少必要的队列族
    }
    
    // 检查扩展支持
    if (!checkDeviceExtensionSupport(device)) {
        return 0;  // 缺少必要的扩展
    }
    
    // 检查交换链支持
    SwapChainSupportDetails swapChainSupport = querySwapChainSupport(device);
    if (swapChainSupport.formats.empty() || swapChainSupport.presentModes.empty()) {
        return 0;  // 不支持交换链
    }
    
    // 附加分:交换链支持更多格式
    score += swapChainSupport.formats.size() > 5 ? 50 : 0;
    
    // 附加分:支持MAILBOX呈现模式(低延迟)
    for (auto mode : swapChainSupport.presentModes) {
        if (mode == VK_PRESENT_MODE_MAILBOX_KHR) {
            score += 100;
            break;
        }
    }
    
    // ==================== 获取设备内存属性 ====================
    VkPhysicalDeviceMemoryProperties memoryProperties;
    vkGetPhysicalDeviceMemoryProperties(device, &memoryProperties);
    
    // 检查是否有足够的内存类型
    // memoryProperties.memoryHeapCount  // 内存堆数量
    // memoryProperties.memoryTypeCount  // 内存类型数量
    
    // 检查内存大小(近似)
    for (uint32_t i = 0; i < memoryProperties.memoryHeapCount; i++) {
        if (memoryProperties.memoryHeaps[i].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) {
            VkDeviceSize heapSize = memoryProperties.memoryHeaps[i].size;
            if (heapSize > 4 * 1024 * 1024 * 1024ULL) {  // > 4GB
                score += 200;
            } else if (heapSize > 2 * 1024 * 1024 * 1024ULL) {  // > 2GB
                score += 100;
            } else if (heapSize > 1 * 1024 * 1024 * 1024ULL) {  // > 1GB
                score += 50;
            }
        }
    }
    
    return score;
}

5. createLogicalDevice() - 逻辑设备

void createLogicalDevice() {
    // ==================== 获取队列族索引 ====================
    QueueFamilyIndices indices = findQueueFamilies(physicalDevice);

    // ==================== 创建队列 ====================
    // 每个队列族可以创建多个队列
    std::vector<VkDeviceQueueCreateInfo> queueCreateInfos;
    
    // 使用set去重(如果图形和呈现在同一队列族)
    std::set<uint32_t> uniqueQueueFamilies = {
        indices.graphicsFamily.value(),
        indices.presentFamily.value()
    };

    // 队列优先级 - 范围0.0到1.0,1.0为最高优先级
    float queuePriority = 1.0f;
    float lowPriority = 0.5f;
    float mediumPriority = 0.7f;
    float highPriority = 1.0f;
    
    for (uint32_t queueFamily : uniqueQueueFamilies) {
        VkDeviceQueueCreateInfo queueCreateInfo{};
        queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
        queueCreateInfo.pNext = nullptr;
        queueCreateInfo.flags = 0;  // 保留
        
        queueCreateInfo.queueFamilyIndex = queueFamily;
        queueCreateInfo.queueCount = 1;  // 创建1个队列
        
        // 可以创建多个队列,每个有不同的优先级
        // std::vector<float> priorities = {1.0f, 0.8f, 0.5f};
        // queueCreateInfo.queueCount = 3;
        // queueCreateInfo.pQueuePriorities = priorities.data();
        
        queueCreateInfo.pQueuePriorities = &queuePriority;
        
        queueCreateInfos.push_back(queueCreateInfo);
    }

    // ==================== 设备特性 ====================
    VkPhysicalDeviceFeatures deviceFeatures{};
    
    // 启用需要的特性
    deviceFeatures.samplerAnisotropy = VK_TRUE;        // 各向异性过滤
    deviceFeatures.geometryShader = VK_FALSE;          // 几何着色器(不需要)
    deviceFeatures.tessellationShader = VK_FALSE;      // 细分着色器(不需要)
    deviceFeatures.textureCompressionBC = VK_FALSE;    // BC压缩(不需要)
    deviceFeatures.multiDrawIndirect = VK_FALSE;       // 间接绘制(不需要)
    deviceFeatures.fillModeNonSolid = VK_FALSE;        // 线框模式(不需要)
    deviceFeatures.wideLines = VK_FALSE;               // 宽线(不需要)
    deviceFeatures.largePoints = VK_FALSE;             // 大点(不需要)
    deviceFeatures.depthClamp = VK_FALSE;              // 深度钳制
    deviceFeatures.depthBiasClamp = VK_FALSE;          // 深度偏置钳制
    deviceFeatures.logicOp = VK_FALSE;                 // 逻辑操作
    deviceFeatures.occlusionQueryPrecise = VK_FALSE;   // 精确遮挡查询
    deviceFeatures.pipelineStatisticsQuery = VK_FALSE; // 管线统计查询
    deviceFeatures.shaderClipDistance = VK_FALSE;      // 着色器裁剪距离
    deviceFeatures.shaderCullDistance = VK_FALSE;      // 着色器剔除距离

    // ==================== 设备扩展 ====================
    std::vector<const char*> deviceExtensions = {
        VK_KHR_SWAPCHAIN_EXTENSION_NAME,           // 交换链(必须)
        // "VK_KHR_swapchain_mutable_format",      // 可变交换链格式
        // "VK_KHR_maintenance1",                   // 维护扩展1
        // "VK_KHR_maintenance2",                   // 维护扩展2
        // "VK_KHR_maintenance3",                   // 维护扩展3
        
        // 以下扩展按需启用
        // "VK_KHR_push_descriptor",                // 推送描述符(快速绑定)
        // "VK_EXT_descriptor_indexing",            // 描述符索引(大量纹理)
        // "VK_KHR_buffer_device_address",          // 缓冲设备地址
        // "VK_KHR_timeline_semaphore",             // 时间线信号量
        // "VK_KHR_shader_float16_int8",            // 16位浮点和8位整数
        // "VK_EXT_memory_budget",                  // 内存预算查询
        // "VK_EXT_memory_priority",                // 内存优先级
        // "VK_EXT_custom_border_color",            // 自定义边界颜色
        // "VK_EXT_filter_cubic",                   // 三次滤波
        // "VK_EXT_shader_viewport_index_layer",    // 视口索引层
        // "VK_EXT_sample_locations",               // 采样位置
        
        // 光线追踪扩展(需要硬件支持)
        // "VK_KHR_acceleration_structure",          // 加速结构
        // "VK_KHR_ray_tracing_pipeline",           // 光线追踪管线
        // "VK_KHR_ray_query",                      // 光线查询
    };

    // ==================== 创建逻辑设备 ====================
    VkDeviceCreateInfo createInfo{};
    createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
    createInfo.pNext = nullptr;
    createInfo.flags = 0;
    
    createInfo.queueCreateInfoCount = static_cast<uint32_t>(queueCreateInfos.size());
    createInfo.pQueueCreateInfos = queueCreateInfos.data();
    
    createInfo.pEnabledFeatures = &deviceFeatures;
    
    createInfo.enabledExtensionCount = static_cast<uint32_t>(deviceExtensions.size());
    createInfo.ppEnabledExtensionNames = deviceExtensions.data();
    
    // 注意:设备层已被弃用,不需要设置
    createInfo.enabledLayerCount = 0;
    createInfo.ppEnabledLayerNames = nullptr;

    // ==================== 创建设备 ====================
    if (vkCreateDevice(physicalDevice, &createInfo, nullptr, &device) != VK_SUCCESS) {
        throw std::runtime_error("failed to create logical device!");
    }

    // ==================== 获取队列句柄 ====================
    // 队列索引0表示该队列族中的第一个队列
    vkGetDeviceQueue(device, indices.graphicsFamily.value(), 0, &graphicsQueue);
    vkGetDeviceQueue(device, indices.presentFamily.value(), 0, &presentQueue);
    
    // 如果需要,可以获取同一队列族的其他队列
    // VkQueue computeQueue;
    // vkGetDeviceQueue(device, indices.computeFamily.value(), 0, &computeQueue);
    // VkQueue transferQueue;
    // vkGetDeviceQueue(device, indices.transferFamily.value(), 0, &transferQueue);
}

6. createSwapChain() - 交换链

void createSwapChain() {
    // ==================== 查询交换链支持 ====================
    SwapChainSupportDetails swapChainSupport = querySwapChainSupport(physicalDevice);

    // ==================== 选择表面格式 ====================
    VkSurfaceFormatKHR surfaceFormat = chooseSwapSurfaceFormat(swapChainSupport.formats);
    
    // 可用的格式示例:
    // VK_FORMAT_B8G8R8A8_SRGB        // BGRA 8位 SRGB(常用)
    // VK_FORMAT_R8G8B8A8_SRGB        // RGBA 8位 SRGB
    // VK_FORMAT_B8G8R8A8_UNORM       // BGRA 8位 线性
    // VK_FORMAT_R8G8B8A8_UNORM       // RGBA 8位 线性
    // VK_FORMAT_R16G16B16A16_SFLOAT  // 16位浮点(HDR)
    // VK_FORMAT_A2B10G10R10_UNORM_PACK32  // 10位色深
    // VK_FORMAT_R32G32B32A32_SFLOAT  // 32位浮点(HDR)

    // ==================== 选择呈现模式 ====================
    VkPresentModeKHR presentMode = chooseSwapPresentMode(swapChainSupport.presentModes);
    
    // 呈现模式说明:
    // VK_PRESENT_MODE_IMMEDIATE_KHR     // 立即显示(可能撕裂,延迟最低)
    // VK_PRESENT_MODE_FIFO_KHR          // 先进先出(垂直同步,延迟中等)
    // VK_PRESENT_MODE_FIFO_RELAXED_KHR  // 宽松FIFO(如果延迟了不等待)
    // VK_PRESENT_MODE_MAILBOX_KHR       // 邮箱(三重缓冲,延迟低,不撕裂)

    // ==================== 选择分辨率 ====================
    VkExtent2D extent = chooseSwapExtent(swapChainSupport.capabilities);
    
    // 分辨率示例:
    // extent.width = 1920, extent.height = 1080  // 1080p
    // extent.width = 2560, extent.height = 1440  // 1440p
    // extent.width = 3840, extent.height = 2160  // 4K

    // ==================== 计算图像数量 ====================
    // 通常使用minImageCount + 1 实现三重缓冲
    uint32_t imageCount = swapChainSupport.capabilities.minImageCount + 1;
    
    // 如果maxImageCount为0表示没有限制
    if (swapChainSupport.capabilities.maxImageCount > 0 && 
        imageCount > swapChainSupport.capabilities.maxImageCount) {
        imageCount = swapChainSupport.capabilities.maxImageCount;
    }
    
    // 一般推荐值:
    // 2 = 双缓冲(垂直同步)
    // 3 = 三缓冲(低延迟,常用)
    // 4+ = 更多缓冲(特殊用途)

    // ==================== 创建交换链 ====================
    VkSwapchainCreateInfoKHR createInfo{};
    createInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
    createInfo.pNext = nullptr;
    
    // 创建标志
    createInfo.flags = 0;
    // 可能的标志:
    // VK_SWAPCHAIN_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT_KHR  // 多GPU拆分
    
    createInfo.surface = surface;
    createInfo.minImageCount = imageCount;
    createInfo.imageFormat = surfaceFormat.format;
    createInfo.imageColorSpace = surfaceFormat.colorSpace;
    createInfo.imageExtent = extent;
    
    // 图像数组层数(1 = 非立体渲染,2 = 立体VR)
    createInfo.imageArrayLayers = 1;
    
    // 图像用途标志
    createInfo.imageUsage = 
        VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;  // 作为颜色附件(渲染目标)
    // 可以组合使用:
    // createInfo.imageUsage = 
    //     VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |  // 渲染目标
    //     VK_IMAGE_USAGE_TRANSFER_DST_BIT;       // 可以写入数据
    //     VK_IMAGE_USAGE_TRANSFER_SRC_BIT;       // 可以读取数据
    //     VK_IMAGE_USAGE_SAMPLED_BIT;            // 可以作为纹理采样

    // ==================== 共享模式 ====================
    QueueFamilyIndices indices = findQueueFamilies(physicalDevice);
    uint32_t queueFamilyIndices[] = {
        indices.graphicsFamily.value(),
        indices.presentFamily.value()
    };

    if (indices.graphicsFamily != indices.presentFamily) {
        // 并发共享模式:多个队列族可以同时访问图像
        createInfo.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
        createInfo.queueFamilyIndexCount = 2;
        createInfo.pQueueFamilyIndices = queueFamilyIndices;
    } else {
        // 独占模式:只有一个队列族访问(性能更好)
        createInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
        createInfo.queueFamilyIndexCount = 0;
        createInfo.pQueueFamilyIndices = nullptr;
    }

    // ==================== 变换和混合 ====================
    // 表面变换 - 处理屏幕旋转等
    createInfo.preTransform = swapChainSupport.capabilities.currentTransform;
    // 其他选项:
    // VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR           // 无变换
    // VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR          // 旋转90度
    // VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR         // 旋转180度
    // VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR         // 旋转270度
    // VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR  // 水平镜像
    
    // 透明度混合
    createInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
    // 其他选项:
    // VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR  // 预乘Alpha
    // VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR // 后乘Alpha
    // VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR         // 继承
    
    // 呈现模式
    createInfo.presentMode = presentMode;
    
    // 裁剪被遮挡的像素(提升性能)
    createInfo.clipped = VK_TRUE;
    
    // 重建交换链时的旧交换链句柄(首次创建时为VK_NULL_HANDLE)
    createInfo.oldSwapchain = VK_NULL_HANDLE;

    // ==================== 创建交换链 ====================
    if (vkCreateSwapchainKHR(device, &createInfo, nullptr, &swapChain) != VK_SUCCESS) {
        throw std::runtime_error("failed to create swap chain!");
    }

    // ==================== 获取交换链图像 ====================
    vkGetSwapchainImagesKHR(device, swapChain, &imageCount, nullptr);
    swapChainImages.resize(imageCount);
    vkGetSwapchainImagesKHR(device, swapChain, &imageCount, swapChainImages.data());

    swapChainImageFormat = surfaceFormat.format;
    swapChainExtent = extent;
}

7. createImageViews() - 图像视图

void createImageViews() {
    swapChainImageViews.resize(swapChainImages.size());

    for (size_t i = 0; i < swapChainImages.size(); i++) {
        VkImageViewCreateInfo createInfo{};
        createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
        createInfo.pNext = nullptr;
        createInfo.flags = 0;  // 保留

        // ==================== 图像和格式 ====================
        createInfo.image = swapChainImages[i];
        createInfo.format = swapChainImageFormat;

        // ==================== 视图类型 ====================
        createInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
        // 其他视图类型:
        // VK_IMAGE_VIEW_TYPE_1D            // 1D纹理
        // VK_IMAGE_VIEW_TYPE_2D            // 2D纹理(最常用)
        // VK_IMAGE_VIEW_TYPE_3D            // 3D体积纹理
        // VK_IMAGE_VIEW_TYPE_CUBE          // 立方体贴图
        // VK_IMAGE_VIEW_TYPE_1D_ARRAY      // 1D纹理数组
        // VK_IMAGE_VIEW_TYPE_2D_ARRAY      // 2D纹理数组
        // VK_IMAGE_VIEW_TYPE_CUBE_ARRAY    // 立方体贴图数组

        // ==================== 颜色通道映射 ====================
        // 可以交换或屏蔽颜色通道
        createInfo.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;  // R -> R
        createInfo.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;  // G -> G
        createInfo.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;  // B -> B
        createInfo.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;  // A -> A
        
        // 其他通道映射选项:
        // VK_COMPONENT_SWIZZLE_ZERO      // 设为0
        // VK_COMPONENT_SWIZZLE_ONE       // 设为1
        // VK_COMPONENT_SWIZZLE_R         // 使用R通道
        // VK_COMPONENT_SWIZZLE_G         // 使用G通道
        // VK_COMPONENT_SWIZZLE_B         // 使用B通道
        // VK_COMPONENT_SWIZZLE_A         // 使用A通道
        
        // 示例:将RGBA转换为RGB,A设为1
        // createInfo.components.a = VK_COMPONENT_SWIZZLE_ONE;
        
        // 示例:交换R和B通道(用于某些格式)
        // createInfo.components.r = VK_COMPONENT_SWIZZLE_B;
        // createInfo.components.b = VK_COMPONENT_SWIZZLE_R;

        // ==================== 子资源范围 ====================
        createInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
        // 其他方面:
        // VK_IMAGE_ASPECT_DEPTH_BIT          // 深度方面
        // VK_IMAGE_ASPECT_STENCIL_BIT        // 模板方面
        // VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT  // 深度+模板
        // VK_IMAGE_ASPECT_PLANE_0_BIT        // YUV平面0
        // VK_IMAGE_ASPECT_PLANE_1_BIT        // YUV平面1
        // VK_IMAGE_ASPECT_PLANE_2_BIT        // YUV平面2
        // VK_IMAGE_ASPECT_METADATA_BIT       // 元数据
        
        createInfo.subresourceRange.baseMipLevel = 0;  // 起始MIP级别
        createInfo.subresourceRange.levelCount = 1;     // 使用1级MIP
        // 如果有多级MIP:levelCount = VK_REMAINING_MIP_LEVELS
        
        createInfo.subresourceRange.baseArrayLayer = 0;  // 起始数组层
        createInfo.subresourceRange.layerCount = 1;       // 使用1层
        // 如果是立方体贴图:layerCount = 6
        // 如果使用所有层:layerCount = VK_REMAINING_ARRAY_LAYERS

        // ==================== 创建图像视图 ====================
        if (vkCreateImageView(device, &createInfo, nullptr, &swapChainImageViews[i]) != VK_SUCCESS) {
            throw std::runtime_error("failed to create image views!");
        }
    }
}

8. createRenderPass() - 渲染通道

void createRenderPass() {
    // ==================== 颜色附件描述 ====================
    VkAttachmentDescription colorAttachment{};
    colorAttachment.flags = 0;  // 保留
    colorAttachment.format = swapChainImageFormat;
    
    // 采样数 - 多重采样抗锯齿(MSAA)
    colorAttachment.samples = VK_SAMPLE_COUNT_1_BIT;  // 无抗锯齿
    // 其他采样数:
    // VK_SAMPLE_COUNT_2_BIT    // 2x MSAA
    // VK_SAMPLE_COUNT_4_BIT    // 4x MSAA(常用)
    // VK_SAMPLE_COUNT_8_BIT    // 8x MSAA
    // VK_SAMPLE_COUNT_16_BIT   // 16x MSAA
    // VK_SAMPLE_COUNT_32_BIT   // 32x MSAA
    // VK_SAMPLE_COUNT_64_BIT   // 64x MSAA

    // ==================== 加载/存储操作 ====================
    // 加载操作 - 渲染前如何处理附件内容
    colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;  // 清除为指定颜色
    // 其他加载操作:
    // VK_ATTACHMENT_LOAD_OP_LOAD     // 保留现有内容(用于多层渲染)
    // VK_ATTACHMENT_LOAD_OP_DONT_CARE // 不关心(可用于优化)
    
    // 存储操作 - 渲染后如何处理附件内容
    colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;  // 保存渲染结果
    // 其他存储操作:
    // VK_ATTACHMENT_STORE_OP_DONT_CARE // 不保存(用于临时附件)
    // VK_ATTACHMENT_STORE_OP_NONE      // 不操作(Vulkan 1.3+)

    // 模板操作的加载/存储(不使用模板)
    colorAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
    colorAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;

    // ==================== 图像布局 ====================
    // 初始布局 - 渲染前的图像布局
    colorAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;  // 不关心之前内容
    // 其他初始布局:
    // VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL  // 作为颜色附件(最佳)
    // VK_IMAGE_LAYOUT_PRESENT_SRC_KHR           // 用于呈现
    // VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL  // 只读着色器采样
    // VK_IMAGE_LAYOUT_GENERAL                   // 通用(最慢)
    
    // 最终布局 - 渲染后的图像布局
    colorAttachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;  // 用于呈现到屏幕
    // 其他最终布局:
    // VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL  // 作为颜色附件
    // VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL      // 用于传输读取
    // VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL      // 用于传输写入
    // VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL // 深度/模板附件

    // ==================== 附件引用 ====================
    VkAttachmentReference colorAttachmentRef{};
    colorAttachmentRef.attachment = 0;  // 附件数组中的索引
    // 在子通道中使用的布局
    colorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;

    // ==================== 子通道描述 ====================
    VkSubpassDescription subpass{};
    subpass.flags = 0;  // 保留
    subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;  // 图形管线
    // VK_PIPELINE_BIND_POINT_COMPUTE  // 计算管线(用于计算子通道)
    
    // 输入附件(用于子通道间读取)
    subpass.inputAttachmentCount = 0;
    subpass.pInputAttachments = nullptr;
    
    // 颜色附件
    subpass.colorAttachmentCount = 1;
    subpass.pColorAttachments = &colorAttachmentRef;
    
    // 解析附件 - 用于MSAA的颜色解析(将多重采样解析为单采样)
    subpass.pResolveAttachments = nullptr;
    // 如果有MSAA,设置为解析目标附件:
    // subpass.pResolveAttachments = &resolveAttachmentRef;
    
    // 深度/模板附件
    subpass.pDepthStencilAttachment = nullptr;
    // 如果使用深度测试,设置:
    // subpass.pDepthStencilAttachment = &depthAttachmentRef;
    
    // 保留附件 - 在子通道中保持不变
    subpass.preserveAttachmentCount = 0;
    subpass.pPreserveAttachments = nullptr;

    // ==================== 子通道依赖 ====================
    VkSubpassDependency dependency{};
    dependency.srcSubpass = VK_SUBPASS_EXTERNAL;  // 渲染通道之前的阶段
    dependency.dstSubpass = 0;                    // 子通道0
    
    // 源管线阶段 - 等待什么操作完成
    dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
    // 其他阶段:
    // VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT        // 管线开头
    // VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT      // 间接绘制
    // VK_PIPELINE_STAGE_VERTEX_INPUT_BIT       // 顶点输入
    // VK_PIPELINE_STAGE_VERTEX_SHADER_BIT      // 顶点着色器
    // VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT
    // VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT
    // VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT    // 几何着色器
    // VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT    // 片段着色器
    // VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
    // VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT
    // VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT  // 颜色输出
    // VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT    // 计算着色器
    // VK_PIPELINE_STAGE_TRANSFER_BIT          // 传输操作
    // VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT     // 管线末尾
    // VK_PIPELINE_STAGE_HOST_BIT              // 主机操作
    // VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT      // 所有图形阶段
    // VK_PIPELINE_STAGE_ALL_COMMANDS_BIT      // 所有命令
    
    // 目标管线阶段
    dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
    
    // 源访问类型
    dependency.srcAccessMask = 0;
    // 目标访问类型
    dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
    // 其他访问类型:
    // VK_ACCESS_INDIRECT_COMMAND_READ_BIT
    // VK_ACCESS_INDEX_READ_BIT
    // VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT
    // VK_ACCESS_UNIFORM_READ_BIT
    // VK_ACCESS_INPUT_ATTACHMENT_READ_BIT
    // VK_ACCESS_SHADER_READ_BIT
    // VK_ACCESS_SHADER_WRITE_BIT
    // VK_ACCESS_COLOR_ATTACHMENT_READ_BIT
    // VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
    // VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT
    // VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT
    // VK_ACCESS_TRANSFER_READ_BIT
    // VK_ACCESS_TRANSFER_WRITE_BIT
    // VK_ACCESS_HOST_READ_BIT
    // VK_ACCESS_HOST_WRITE_BIT
    // VK_ACCESS_MEMORY_READ_BIT
    // VK_ACCESS_MEMORY_WRITE_BIT
    
    // 依赖标志
    dependency.dependencyFlags = 0;
    // VK_DEPENDENCY_BY_REGION_BIT  // 仅区域内依赖(性能优化)

    // ==================== 创建渲染通道 ====================
    VkRenderPassCreateInfo renderPassInfo{};
    renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
    renderPassInfo.pNext = nullptr;
    renderPassInfo.flags = 0;
    
    renderPassInfo.attachmentCount = 1;
    renderPassInfo.pAttachments = &colorAttachment;
    renderPassInfo.subpassCount = 1;
    renderPassInfo.pSubpasses = &subpass;
    renderPassInfo.dependencyCount = 1;
    renderPassInfo.pDependencies = &dependency;

    if (vkCreateRenderPass(device, &renderPassInfo, nullptr, &renderPass) != VK_SUCCESS) {
        throw std::runtime_error("failed to create render pass!");
    }
}

9. createGraphicsPipeline() - 图形管线(部分关键部分)

void createGraphicsPipeline() {
    // ==================== 读取着色器 ====================
    auto vertShaderCode = readFile("shaders/vertex.spv");
    auto fragShaderCode = readFile("shaders/fragment.spv");
    
    VkShaderModule vertShaderModule = createShaderModule(vertShaderCode);
    VkShaderModule fragShaderModule = createShaderModule(fragShaderCode);

    // ==================== 着色器阶段 ====================
    VkPipelineShaderStageCreateInfo vertShaderStageInfo{};
    vertShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
    vertShaderStageInfo.pNext = nullptr;
    vertShaderStageInfo.flags = 0;
    vertShaderStageInfo.stage = VK_SHADER_STAGE_VERTEX_BIT;
    vertShaderStageInfo.module = vertShaderModule;
    vertShaderStageInfo.pName = "main";  // 入口点
    // 特化常量 - 编译时优化
    vertShaderStageInfo.pSpecializationInfo = nullptr;

    // 片段着色器阶段
    VkPipelineShaderStageCreateInfo fragShaderStageInfo{};
    fragShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
    fragShaderStageInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT;
    fragShaderStageInfo.module = fragShaderModule;
    fragShaderStageInfo.pName = "main";

    VkPipelineShaderStageCreateInfo shaderStages[] = {
        vertShaderStageInfo,
        fragShaderStageInfo
    };
    
    // 其他着色器阶段(如果需要):
    // VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT   // 细分控制
    // VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT // 细分评估
    // VK_SHADER_STAGE_GEOMETRY_BIT               // 几何着色器

    // ==================== 顶点输入状态 ====================
    VkPipelineVertexInputStateCreateInfo vertexInputInfo{};
    vertexInputInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
    vertexInputInfo.pNext = nullptr;
    vertexInputInfo.flags = 0;
    
    // 顶点绑定描述 - 描述顶点数据如何排列
    vertexInputInfo.vertexBindingDescriptionCount = 0;
    vertexInputInfo.pVertexBindingDescriptions = nullptr;
    // 如果有顶点数据:
    // VkVertexInputBindingDescription bindingDesc{};
    // bindingDesc.binding = 0;                   // 绑定索引
    // bindingDesc.stride = sizeof(Vertex);       // 顶点大小
    // bindingDesc.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;  // 每顶点
    // VK_VERTEX_INPUT_RATE_INSTANCE              // 每实例
    
    // 顶点属性描述 - 描述每个属性的格式
    vertexInputInfo.vertexAttributeDescriptionCount = 0;
    vertexInputInfo.pVertexAttributeDescriptions = nullptr;
    // 如果有属性:
    // VkVertexInputAttributeDescription attribDesc{};
    // attribDesc.location = 0;                   // 着色器位置
    // attribDesc.binding = 0;                    // 绑定索引
    // attribDesc.format = VK_FORMAT_R32G32B32_SFLOAT;  // 格式
    // attribDesc.offset = offsetof(Vertex, pos); // 偏移量

    // ==================== 输入装配状态 ====================
    VkPipelineInputAssemblyStateCreateInfo inputAssembly{};
    inputAssembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
    inputAssembly.pNext = nullptr;
    inputAssembly.flags = 0;
    
    // 图元拓扑
    inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
    // 其他拓扑:
    // VK_PRIMITIVE_TOPOLOGY_POINT_LIST              // 点列表
    // VK_PRIMITIVE_TOPOLOGY_LINE_LIST               // 线列表
    // VK_PRIMITIVE_TOPOLOGY_LINE_STRIP              // 线带
    // VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST           // 三角形列表(最常用)
    // VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP          // 三角形带
    // VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN            // 三角形扇
    // VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY    // 带邻接线列表
    // VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY   // 带邻接线带
    // VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY // 带邻接三角形列表
    // VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY // 带邻接三角形带
    // VK_PRIMITIVE_TOPOLOGY_PATCH_LIST              // 面片列表(细分)
    
    inputAssembly.primitiveRestartEnable = VK_FALSE;  // 不启用图元重启
    // VK_TRUE // 启用图元重启(用于条带拓扑)

    // ==================== 光栅化状态 ====================
    VkPipelineRasterizationStateCreateInfo rasterizer{};
    rasterizer.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
    rasterizer.pNext = nullptr;
    rasterizer.flags = 0;
    
    // 深度钳制 - 是否将深度值钳制到[0,1]
    rasterizer.depthClampEnable = VK_FALSE;
    // 丢弃所有光栅化结果(用于纯计算)
    rasterizer.rasterizerDiscardEnable = VK_FALSE;
    
    // 多边形填充模式
    rasterizer.polygonMode = VK_POLYGON_MODE_FILL;
    // 其他模式:
    // VK_POLYGON_MODE_LINE   // 线框模式
    // VK_POLYGON_MODE_POINT  // 点模式
    
    // 线宽(仅当polygonMode为LINE时有效)
    rasterizer.lineWidth = 1.0f;
    // 注意:宽线需要设备特性支持(wideLines)
    
    // 面剔除
    rasterizer.cullMode = VK_CULL_MODE_BACK_BIT;  // 剔除背面
    // 其他选项:
    // VK_CULL_MODE_NONE           // 不剔除
    // VK_CULL_MODE_FRONT_BIT      // 剔除正面
    // VK_CULL_MODE_FRONT_AND_BACK // 剔除所有(不绘制)
    
    // 正面朝向
    rasterizer.frontFace = VK_FRONT_FACE_CLOCKWISE;  // 顺时针为正面
    // VK_FRONT_FACE_COUNTER_CLOCKWISE  // 逆时针为正面
    
    // 深度偏置 - 用于阴影映射等
    rasterizer.depthBiasEnable = VK_FALSE;
    rasterizer.depthBiasConstantFactor = 0.0f;
    rasterizer.depthBiasClamp = 0.0f;
    rasterizer.depthBiasSlopeFactor = 0.0f;

    // ==================== 多重采样状态 ====================
    VkPipelineMultisampleStateCreateInfo multisampling{};
    multisampling.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
    multisampling.pNext = nullptr;
    multisampling.flags = 0;
    
    multisampling.sampleShadingEnable = VK_FALSE;  // 不启用采样着色
    multisampling.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;  // 1倍采样
    // 其他采样数:
    // VK_SAMPLE_COUNT_2_BIT, 4_BIT, 8_BIT, 16_BIT, 32_BIT, 64_BIT
    
    // 最小采样遮蔽
    multisampling.minSampleShading = 1.0f;
    multisampling.pSampleMask = nullptr;  // 采样掩码
    multisampling.alphaToCoverageEnable = VK_FALSE;  // Alpha覆盖
    multisampling.alphaToOneEnable = VK_FALSE;  // Alpha到一

    // ==================== 颜色混合状态 ====================
    VkPipelineColorBlendAttachmentState colorBlendAttachment{};
    // 颜色写入掩码
    colorBlendAttachment.colorWriteMask = 
        VK_COLOR_COMPONENT_R_BIT |
        VK_COLOR_COMPONENT_G_BIT |
        VK_COLOR_COMPONENT_B_BIT |
        VK_COLOR_COMPONENT_A_BIT;
    // 可以只写部分通道:
    // VK_COLOR_COMPONENT_R_BIT  // 只写红色通道
    
    // 启用混合
    colorBlendAttachment.blendEnable = VK_FALSE;  // 不混合(直接覆盖)
    // 如果启用混合,需要设置:
    // colorBlendAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
    // colorBlendAttachment.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
    // colorBlendAttachment.colorBlendOp = VK_BLEND_OP_ADD;
    // colorBlendAttachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
    // colorBlendAttachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
    // colorBlendAttachment.alphaBlendOp = VK_BLEND_OP_ADD;

    // 颜色混合全局状态
    VkPipelineColorBlendStateCreateInfo colorBlending{};
    colorBlending.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
    colorBlending.pNext = nullptr;
    colorBlending.flags = 0;
    
    colorBlending.logicOpEnable = VK_FALSE;  // 不启用逻辑操作
    colorBlending.logicOp = VK_LOGIC_OP_COPY;  // 逻辑操作类型(未使用)
    colorBlending.attachmentCount = 1;
    colorBlending.pAttachments = &colorBlendAttachment;
    colorBlending.blendConstants[0] = 0.0f;  // 混合常量R
    colorBlending.blendConstants[1] = 0.0f;  // 混合常量G
    colorBlending.blendConstants[2] = 0.0f;  // 混合常量B
    colorBlending.blendConstants[3] = 0.0f;  // 混合常量A

    // ==================== 动态状态 ====================
    // 这些状态可以在命令缓冲区中动态修改
    std::vector<VkDynamicState> dynamicStates = {
        VK_DYNAMIC_STATE_VIEWPORT,    // 视口
        VK_DYNAMIC_STATE_SCISSOR,     // 裁剪矩形
        // VK_DYNAMIC_STATE_LINE_WIDTH,  // 线宽
        // VK_DYNAMIC_STATE_DEPTH_BIAS,  // 深度偏置
        // VK_DYNAMIC_STATE_BLEND_CONSTANTS,  // 混合常量
        // VK_DYNAMIC_STATE_DEPTH_BOUNDS,  // 深度范围
        // VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK,  // 模板比较掩码
        // VK_DYNAMIC_STATE_STENCIL_WRITE_MASK,  // 模板写入掩码
        // VK_DYNAMIC_STATE_STENCIL_REFERENCE,  // 模板参考值
        // VK_DYNAMIC_STATE_CULL_MODE,  // 剔除模式
        // VK_DYNAMIC_STATE_FRONT_FACE,  // 正面朝向
        // VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY,  // 图元拓扑
        // VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT,  // 多视口
        // VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT,  // 多裁剪矩形
        // VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE,  // 顶点绑定步长
        // VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE,  // 深度测试启用
        // VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE,  // 深度写入启用
        // VK_DYNAMIC_STATE_DEPTH_COMPARE_OP,  // 深度比较操作
        // VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE,  // 模板测试启用
        // VK_DYNAMIC_STATE_STENCIL_OP,  // 模板操作
    };

    VkPipelineDynamicStateCreateInfo dynamicState{};
    dynamicState.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
    dynamicState.pNext = nullptr;
    dynamicState.flags = 0;
    dynamicState.dynamicStateCount = static_cast<uint32_t>(dynamicStates.size());
    dynamicState.pDynamicStates = dynamicStates.data();

    // ==================== 管线布局 ====================
    VkPipelineLayoutCreateInfo pipelineLayoutInfo{};
    pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
    pipelineLayoutInfo.pNext = nullptr;
    pipelineLayoutInfo.flags = 0;
    
    // 描述符集布局(Uniform、纹理等)
    pipelineLayoutInfo.setLayoutCount = 0;
    pipelineLayoutInfo.pSetLayouts = nullptr;
    // 如果有Uniform:
    // std::vector<VkDescriptorSetLayout> descriptorSetLayouts = { ... };
    // pipelineLayoutInfo.setLayoutCount = descriptorSetLayouts.size();
    // pipelineLayoutInfo.pSetLayouts = descriptorSetLayouts.data();
    
    // 推送常量(小量频繁更新的数据)
    pipelineLayoutInfo.pushConstantRangeCount = 0;
    pipelineLayoutInfo.pPushConstantRanges = nullptr;
    // 如果有推送常量:
    // VkPushConstantRange pushConstantRange{};
    // pushConstantRange.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
    // pushConstantRange.offset = 0;
    // pushConstantRange.size = sizeof(MVPData);

    // ==================== 创建管线布局和管线 ====================
    if (vkCreatePipelineLayout(device, &pipelineLayoutInfo, nullptr, &pipelineLayout) != VK_SUCCESS) {
        throw std::runtime_error("failed to create pipeline layout!");
    }

    VkGraphicsPipelineCreateInfo pipelineInfo{};
    pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
    pipelineInfo.pNext = nullptr;
    pipelineInfo.flags = 0;  // 可以设置派生管线标志
    // 管线创建标志:
    // VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT  // 禁用优化(调试)
    // VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT     // 允许派生
    // VK_PIPELINE_CREATE_DERIVATIVE_BIT            // 是派生管线
    
    pipelineInfo.stageCount = 2;
    pipelineInfo.pStages = shaderStages;
    pipelineInfo.pVertexInputState = &vertexInputInfo;
    pipelineInfo.pInputAssemblyState = &inputAssembly;
    pipelineInfo.pTessellationState = nullptr;  // 不用细分
    pipelineInfo.pViewportState = &viewportState;
    pipelineInfo.pRasterizationState = &rasterizer;
    pipelineInfo.pMultisampleState = &multisampling;
    pipelineInfo.pDepthStencilState = nullptr;  // 不用深度/模板
    pipelineInfo.pColorBlendState = &colorBlending;
    pipelineInfo.pDynamicState = &dynamicState;
    pipelineInfo.layout = pipelineLayout;
    pipelineInfo.renderPass = renderPass;
    pipelineInfo.subpass = 0;  // 在子通道0中使用
    
    // 管线派生
    pipelineInfo.basePipelineHandle = VK_NULL_HANDLE;
    pipelineInfo.basePipelineIndex = -1;

    if (vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, &graphicsPipeline) != VK_SUCCESS) {
        throw std::runtime_error("failed to create graphics pipeline!");
    }

    vkDestroyShaderModule(device, fragShaderModule, nullptr);
    vkDestroyShaderModule(device, vertShaderModule, nullptr);
}

10. createFramebuffers() - 帧缓冲

void createFramebuffers() {
    swapChainFramebuffers.resize(swapChainImageViews.size());

    for (size_t i = 0; i < swapChainImageViews.size(); i++) {
        // ==================== 附件数组 ====================
        std::vector<VkImageView> attachments = {
            swapChainImageViews[i]  // 颜色附件
            // 如果有深度附件:
            // depthImageView
            // 如果有解析附件(MSAA):
            // resolveImageView
        };

        VkFramebufferCreateInfo framebufferInfo{};
        framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
        framebufferInfo.pNext = nullptr;
        framebufferInfo.flags = 0;
        
        framebufferInfo.renderPass = renderPass;
        framebufferInfo.attachmentCount = static_cast<uint32_t>(attachments.size());
        framebufferInfo.pAttachments = attachments.data();
        
        // 帧缓冲尺寸必须与附件匹配
        framebufferInfo.width = swapChainExtent.width;
        framebufferInfo.height = swapChainExtent.height;
        framebufferInfo.layers = 1;  // 层数(1=非立体)
        // 如果是立体渲染:layers = 2

        if (vkCreateFramebuffer(device, &framebufferInfo, nullptr, &swapChainFramebuffers[i]) != VK_SUCCESS) {
            throw std::runtime_error("failed to create framebuffer!");
        }
    }
}

11. createCommandPool() - 命令池

void createCommandPool() {
    QueueFamilyIndices queueFamilyIndices = findQueueFamilies(physicalDevice);

    VkCommandPoolCreateInfo poolInfo{};
    poolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
    poolInfo.pNext = nullptr;
    
    // 命令池标志
    poolInfo.flags = 
        VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;  // 允许重置单个命令缓冲区
    // 其他标志:
    // VK_COMMAND_POOL_CREATE_TRANSIENT_BIT  // 命令缓冲区使用频繁(优化提示)
    // VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT  // 允许重置单个CB
    
    poolInfo.queueFamilyIndex = queueFamilyIndices.graphicsFamily.value();

    if (vkCreateCommandPool(device, &poolInfo, nullptr, &commandPool) != VK_SUCCESS) {
        throw std::runtime_error("failed to create command pool!");
    }
}

12. createCommandBuffers() - 命令缓冲区

void createCommandBuffers() {
    commandBuffers.resize(MAX_FRAMES_IN_FLIGHT);

    VkCommandBufferAllocateInfo allocInfo{};
    allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
    allocInfo.pNext = nullptr;
    
    allocInfo.commandPool = commandPool;
    
    // 命令缓冲区级别
    allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;  // 主命令缓冲区
    // VK_COMMAND_BUFFER_LEVEL_SECONDARY  // 次级命令缓冲区(可被主CB调用)
    
    allocInfo.commandBufferCount = static_cast<uint32_t>(commandBuffers.size());

    if (vkAllocateCommandBuffers(device, &allocInfo, commandBuffers.data()) != VK_SUCCESS) {
        throw std::runtime_error("failed to allocate command buffers!");
    }
}

13. createSyncObjects() - 同步对象

void createSyncObjects() {
    imageAvailableSemaphores.resize(MAX_FRAMES_IN_FLIGHT);
    renderFinishedSemaphores.resize(MAX_FRAMES_IN_FLIGHT);
    inFlightFences.resize(MAX_FRAMES_IN_FLIGHT);

    // ==================== 信号量创建信息 ====================
    VkSemaphoreCreateInfo semaphoreInfo{};
    semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
    semaphoreInfo.pNext = nullptr;
    semaphoreInfo.flags = 0;  // 目前保留
    
    // 对于Vulkan 1.2+,可以使用时间线信号量
    // VkSemaphoreTypeCreateInfo timelineInfo{};
    // timelineInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO;
    // timelineInfo.semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE;  // 时间线信号量
    // timelineInfo.initialValue = 0;
    // semaphoreInfo.pNext = &timelineInfo;

    // ==================== 栅栏创建信息 ====================
    VkFenceCreateInfo fenceInfo{};
    fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
    fenceInfo.pNext = nullptr;
    
    // 栅栏标志
    fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;  // 初始为已触发
    // 其他标志:
    // 0  // 初始为未触发(需要等待后才能使用)

    for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
        if (vkCreateSemaphore(device, &semaphoreInfo, nullptr, &imageAvailableSemaphores[i]) != VK_SUCCESS ||
            vkCreateSemaphore(device, &semaphoreInfo, nullptr, &renderFinishedSemaphores[i]) != VK_SUCCESS ||
            vkCreateFence(device, &fenceInfo, nullptr, &inFlightFences[i]) != VK_SUCCESS) {
            throw std::runtime_error("failed to create synchronization objects for a frame!");
        }
    }
}

 

...全文
196 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

4

社区成员

发帖
与我相关
我的任务
社区描述
openTK、OpenGL、WebGL技术学习交流
图形渲染c#程序人生 技术论坛(原bbs) 广东省·深圳市
社区管理员
  • 亿只小灿灿
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧