一、下载并安装Vulkan驱动程序
1、在Vulkan官方网站上下载适合自己操作系统的驱动程序 (https://www.khronos.org/vulkan/),并解压缩到本地文件夹。
wget https://sdk.lunarg.com/sdk/download/1.2.131.2/linux/VulkanSDK-1.2.131.2.tar.gz
tar -xzvf VulkanSDK-1.2.131.2.tar.gz
2、进入解压后的文件夹,执行安装命令,安装成功后重启计算机。
cd VulkanSDK-1.2.131.2
./vulkansdk-linux-x86_64-1.2.131.2.run
3、在终端中运行以下命令,查看Vulkan是否正常安装。
vulkaninfo
二、集成Vulkan SDK到开发环境
1、将Vulkan SDK的头文件和库文件添加到编译器搜索路径中。
例如,如果您正在使用gcc编译器,请运行以下命令,将Vulkan SDK的头文件路径添加到gcc搜索路径中。
export C_INCLUDE_PATH=$C_INCLUDE_PATH:/path/to/VulkanSDK/include
2、将Vulkan SDK的库文件路径添加到环境变量中。
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/path/to/VulkanSDK/lib
三、创建窗口和Vulkan实例
1、使用Vulkan提供的库,在代码中创建窗口。
// include GLFW library
#include
// create window
GLFWwindow* window;
glfwInit();
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
window = glfwCreateWindow(width, height, title, nullptr, nullptr);
2、使用Vulkan创建实例。
// include Vulkan headers
#include
// create instance
VkInstance instance;
VkInstanceCreateInfo createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
// set application name and version
createInfo.pApplicationInfo = &appInfo;
// set the validation layers
createInfo.enabledLayerCount = static_cast(validationLayers.size());
createInfo.ppEnabledLayerNames = validationLayers.data();
// set the required extensions
createInfo.enabledExtensionCount = static_cast(requiredExtensions.size());
createInfo.ppEnabledExtensionNames = requiredExtensions.data();
// create the Vulkan instance
if (vkCreateInstance(&createInfo, nullptr, &instance) != VK_SUCCESS) {
throw std::runtime_error("failed to create instance!");
}
四、创建逻辑设备和交换链
1、检查支持的物理设备,并选择一个可用的物理设备。
// get the list of physical devices
uint32_t deviceCount = 0;
vkEnumeratePhysicalDevices(instance, &deviceCount, nullptr);
std::vector devices(deviceCount);
vkEnumeratePhysicalDevices(instance, &deviceCount, devices.data());
// choose a suitable device
for (const auto& device : devices) {
if (isDeviceSuitable(device)) {
physicalDevice = device;
break;
}
}
2、创建逻辑设备。
// create a logical device
VkDevice device;
VkDeviceCreateInfo createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
// set the queue family indices
createInfo.queueCreateInfoCount = static_cast(queueCreateInfos.size());
createInfo.pQueueCreateInfos = queueCreateInfos.data();
// set the required extensions
createInfo.enabledExtensionCount = static_cast(requiredDeviceExtensions.size());
createInfo.ppEnabledExtensionNames = requiredDeviceExtensions.data();
// create the logical device
if (vkCreateDevice(physicalDevice, &createInfo, nullptr, &device) != VK_SUCCESS) {
throw std::runtime_error("failed to create logical device!");
}
3、创建交换链。
// query and choose the surface format, presentation mode and extent
SwapChainSupportDetails swapChainSupport = querySwapChainSupport(physicalDevice);
VkSurfaceFormatKHR surfaceFormat = chooseSwapSurfaceFormat(swapChainSupport.formats);
VkPresentModeKHR presentMode = chooseSwapPresentMode(swapChainSupport.presentModes);
VkExtent2D extent = chooseSwapExtent(swapChainSupport.capabilities, windowWidth, windowHeight);
// create the swap chain
VkSwapchainCreateInfoKHR createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
createInfo.surface = surface;
createInfo.minImageCount = imageCount;
createInfo.imageFormat = surfaceFormat.format;
createInfo.imageColorSpace = surfaceFormat.colorSpace;
createInfo.imageExtent = extent;
createInfo.imageArrayLayers = 1;
createInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
createInfo.preTransform = swapChainSupport.capabilities.currentTransform;
createInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
createInfo.presentMode = presentMode;
createInfo.clipped = VK_TRUE;
createInfo.oldSwapchain = VK_NULL_HANDLE;
// create the swap chain
if (vkCreateSwapchainKHR(device, &createInfo, nullptr, &swapChain) != VK_SUCCESS) {
throw std::runtime_error("failed to create swap chain!");
}
五、创建图形管线和渲染过程
1、创建着色器模块。
// read the shader code from file
std::ifstream file("shader.spv", std::ios::ate | std::ios::binary);
if (!file.is_open()) {
throw std::runtime_error("failed to open file!");
}
size_t fileSize = (size_t)file.tellg();
std::vector code(fileSize);
file.seekg(0);
file.read(code.data(), fileSize);
file.close();
// create the shader module
VkShaderModuleCreateInfo createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
createInfo.codeSize = code.size();
createInfo.pCode = reinterpret_cast(code.data());
if (vkCreateShaderModule(device, &createInfo, nullptr, &shaderModule) != VK_SUCCESS) {
throw std::runtime_error("failed to create shader module!");
}
2、创建顶点缓冲区和索引缓冲区。
// create the vertex buffer and index buffer
VkBuffer vertexBuffer;
VkDeviceMemory vertexBufferMemory;
VkBuffer indexBuffer;
VkDeviceMemory indexBufferMemory;
createVertexBuffer(vertexBuffer, vertexBufferMemory);
createIndexBuffer(indexBuffer, indexBufferMemory);
3、创建图形管线。
// create the graphics pipeline
VkPipelineLayout pipelineLayout;
VkPipeline graphicsPipeline;
createPipelineLayout(pipelineLayout);
createGraphicsPipeline(graphicsPipeline, pipelineLayout);
4、创建帧缓冲和渲染过程,以及渲染命令缓冲。
// create the frame buffers and command buffers
std::vector swapChainFramebuffers;
std::vector commandBuffers;
createFramebuffers(swapChainFramebuffers);
createCommandBuffers(commandBuffers);