创建Vulkan Surface时提示‘Unknown sensor type’错误的排查求助
尝试用SDL搭建基础Vulkan应用,创建Vulkan Surface时遇到错误,日志提示:Unknown sensor type。
创建Surface的代码
VkSurfaceKHR surface; SDL_SysWMinfo wmInfo; SDL_VERSION(&wmInfo.version); SDL_GetWindowWMInfo(window, &wmInfo); VkWin32SurfaceCreateInfoKHR createInfo{}; createInfo.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR; createInfo.hwnd = wmInfo.info.win.window; createInfo.hinstance = wmInfo.info.win.hinstance; if (vkCreateWin32SurfaceKHR(instance, &createInfo, nullptr, &surface) != VK_SUCCESS) { std::cerr << "Error creating surface: " << SDL_GetError() << std::endl; exit(EXIT_FAILURE); }
创建SDL窗口的代码
window = SDL_CreateWindow("Test", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 800, 600, SDL_WINDOW_VULKAN | SDL_WINDOW_SHOWN);
错误出现在上述的if判断语句中。
补充信息
尝试使用SDL_Vulkan_CreateSurface时,执行vkCreateInstance(&createInfo, nullptr, &instance)会触发‘Access violation’异常。如果移除向createInfo添加扩展的代码,实例能正常创建,但会收到Surface报错:VK_KHR_win32_surface extension is not enabled in the Vulkan instance(符合预期,因为移除了必要扩展)。以下是包含扩展的实例创建代码:
appInfo = {}; appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; appInfo.pApplicationName = "Test"; appInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0); appInfo.pEngineName = "Test Engine"; appInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0); appInfo.apiVersion = VK_API_VERSION_1_0; createInfo = {}; createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; createInfo.pApplicationInfo = &appInfo; std::vector<const char*> extensions = { VK_KHR_WIN32_SURFACE_EXTENSION_NAME, }; createInfo.enabledExtensionCount = static_cast<uint32_t>(extensions.size()); createInfo.ppEnabledExtensionNames = extensions.data(); VkInstance instance = NULL; if (vkCreateInstance(&createInfo, nullptr, &instance) != VK_SUCCESS) { std::cerr << "Error creating instance: " << SDL_GetError() << std::endl; exit(EXIT_FAILURE); }
针对Unknown sensor type错误
这个提示是SDL_GetError()返回的误导性信息,问题核心和传感器无关,根源在以下两点:
- Vulkan实例未正确启用必要扩展
- 手动调用平台Surface创建函数时未正确加载函数指针
用SDL获取所有必需的Vulkan扩展
不要手动指定扩展,SDL提供了SDL_Vulkan_GetInstanceExtensions函数,可以自动获取与当前窗口适配的所有Vulkan扩展,确保无遗漏:uint32_t extensionCount = 0; SDL_Vulkan_GetInstanceExtensions(window, &extensionCount, nullptr); std::vector<const char*> extensions(extensionCount); SDL_Vulkan_GetInstanceExtensions(window, &extensionCount, extensions.data());之后将这个扩展列表传入实例创建的
createInfo即可。改用SDL封装的Surface创建函数
手动调用vkCreateWin32SurfaceKHR需要自行处理函数指针加载和平台适配,容易出错。直接使用SDL_Vulkan_CreateSurface可以规避这些问题:VkSurfaceKHR surface; if (!SDL_Vulkan_CreateSurface(window, instance, nullptr, &surface)) { std::cerr << "Surface creation failed: " << SDL_GetError() << std::endl; exit(EXIT_FAILURE); }
针对vkCreateInstance的访问违例异常
这个问题通常和内存管理或结构体初始化有关:
确保结构体完全初始化
虽然使用了{}初始化,但部分编译器可能不会将所有成员置零,建议显式保证结构体初始化为空:VkApplicationInfo appInfo{}; VkInstanceCreateInfo createInfo{};验证窗口指针有效性
调用SDL_Vulkan_GetInstanceExtensions前,确认window是通过SDL_CreateWindow成功创建的有效指针,空指针会导致扩展列表获取失败,进而引发内存访问错误。启用Vulkan调试层获取准确错误
SDL_GetError()无法捕获Vulkan自身的错误,建议添加VK_EXT_debug_utils扩展,创建调试回调,获取更详细的错误信息,精准定位访问违例的原因。
内容的提问来源于stack exchange,提问作者GenesysRTA

