Vulkan API的设计核心是尽量最小化驱动程序的额外开销,所谓额外开销更多的是指向渲染以外的运算。其中一个具体的表现就是默认条件下,Vulkan API的错误检查的支持非常有限。即使遍历不正确的值或者将需要的参数传递为空指针,也不会有明确的处理逻辑,并且直接导致崩溃或者未定义的异常行为。之所以这样,是因为Vulkan要求每一个步骤定义都非常明确,导致很容易造成小错误,例如使用新的GPU功能,但是忘记了逻辑设备创建时请求它。
但是,这并不意味着这些检查不能添加到具体的API中。Vulkan推出了一个优化的系统,这个系统称之为Validation layers。Validation layers是可选组件,可以挂载到Vulkan函数中调用,以回调其他的操作。Validation layers的常见操作情景有:
- 根据规范检查参数数值,最终确认是否存与预期不符的情况
- 跟踪对象的创建和销毁,以查找是否存在资源的泄漏
- 跟踪线程的调用链,确认线程执行过程中的安全性
- 将每次函数调用所使用的参数记录到标准的输出中,进行初步的Vulkan概要分析
本节的代码主要是VulkanAPI的错误检查,应用好了可以大幅提升debug的效率。不过感觉这个使用过程有点复杂,实际使用还是需要更多的实践。
代码实例:代码要贴全了,便于大家理解,我本人是不太喜欢那种只贴一个片段的代码,出现了一个错误你就发现无从下手
#define GLFW_INCLUDE_VULKAN
#include <GLFW/glfw3.h>
#define GLM_FORCE_RADIANS
#define GLM_FORCE_DEPTH_ZERO_TO_ONE
#include <glm/glm.hpp>
#include <glm/mat4x4.hpp>
#include<vulkan/vulkan.h>
#include <iostream>
#include <stdexcept>
#include <vector>
#include<cstring>
const int WIDTH = 800;
const int HEIGHT = 600;
const std::vector<const char*> validationLayers = {
"VK_LAYER_LUNARG_standard_validation" };
#ifdef NDEBUG
const bool enableValidationLayers = false;
#else
const bool enableValidationLayers = true;
#endif
//代理函数
//该结构体应该传递给vkCreateDebugReportCallbackEXT函数创建VkDebugReportCallbackEXT对象。
//不幸的是,因为这个功能是一个扩展功能,它不会被自动加载。所以必须使用vkGetInstanceProcAddr查找函数地址。
VkResult CreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT* pCreateInfo, const
VkAllocationCallbacks* pAllocator, VkDebugReportCallbackEXT* pCallback) {
auto func = (PFN_vkCreateDebugReportCallbackEXT)vkG