4
社区成员
发帖
与我相关
我的任务
分享
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!");
}
}
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!");
}
}
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
}
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;
}
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);
}
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;
}
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!");
}
}
}
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!");
}
}
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);
}
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!");
}
}
}
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!");
}
}
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!");
}
}
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!");
}
}
}