vkCreateSwapchainKHR():未为此物理设备检索表面功能

vkCreateSwapchainKHR(): surface capabilities not retrieved for this physical device

我正在尝试在表面创建后创建交换链。目前我的 window 正在使用 GLFW 创建,如下所示:

glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
GLFWWindow = glfwCreateWindow(Extent.Width, Extent.Height, _Name.c_str(), NULL, NULL);

我这样创建 VkInstance

    VkApplicationInfo AppInfo = { VK_STRUCTURE_TYPE_APPLICATION_INFO };
    AppInfo.apiVersion = VK_API_VERSION_1_1;    //Should check if version is available vi vkEnumerateInstanceVersion().
    AppInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
    AppInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0);
    AppInfo.pApplicationName = _AppName;
    AppInfo.pEngineName = "Game Studio";

#ifdef GS_DEBUG
    const char* InstanceLayers[] = { "VK_LAYER_LUNARG_standard_validation" };
#else
    const char* InstanceLayers[] = nullptr;
#endif // GS_DEBUG

    const char* Extensions[] = { VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_WIN32_SURFACE_EXTENSION_NAME };

    VkInstanceCreateInfo InstanceCreateInfo = { VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO };
    InstanceCreateInfo.pApplicationInfo = &AppInfo;
    InstanceCreateInfo.enabledLayerCount = 1;
    InstanceCreateInfo.ppEnabledLayerNames = InstanceLayers;
    InstanceCreateInfo.enabledExtensionCount = 2;
    InstanceCreateInfo.ppEnabledExtensionNames = Extensions;

    GS_VK_CHECK(vkCreateInstance(&InstanceCreateInfo, ALLOCATOR, &Instance), "Failed to create Instance!")

我的VkDevice是这样的:

    VkPhysicalDeviceFeatures deviceFeatures = {};   //COME BACK TO

    const char* DeviceExtensions[] = { VK_KHR_SWAPCHAIN_EXTENSION_NAME };

    PhysicalDevice = CreatePhysicalDevice(_Instance);

    QueueInfo GraphicsQueueInfo;
    QueueInfo ComputeQueueInfo;
    QueueInfo TransferQueueInfo;

    GraphicsQueueInfo.QueueFlag = VK_QUEUE_GRAPHICS_BIT;
    GraphicsQueueInfo.QueuePriority = 1.0f;
    ComputeQueueInfo.QueueFlag = VK_QUEUE_COMPUTE_BIT;
    ComputeQueueInfo.QueuePriority = 1.0f;
    TransferQueueInfo.QueueFlag = VK_QUEUE_TRANSFER_BIT;
    TransferQueueInfo.QueuePriority = 1.0f;

    QueueInfo QueueInfos[] = { GraphicsQueueInfo, ComputeQueueInfo, TransferQueueInfo };

    FVector<VkDeviceQueueCreateInfo> QueueCreateInfos = CreateQueueInfos(QueueInfos, 3, PhysicalDevice);

    VkDeviceCreateInfo DeviceCreateInfo = { VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO };
    DeviceCreateInfo.queueCreateInfoCount = QueueCreateInfos.length();
    DeviceCreateInfo.pQueueCreateInfos = QueueCreateInfos.data();
    DeviceCreateInfo.enabledExtensionCount = 1;
    DeviceCreateInfo.pEnabledFeatures = &deviceFeatures;
    DeviceCreateInfo.ppEnabledExtensionNames = DeviceExtensions;

    auto ff = vkCreateDevice(PhysicalDevice, &DeviceCreateInfo, ALLOCATOR, &Device);

    Vk_Queue* Queues[] = { &GraphicsQueue, &ComputeQueue, &TransferQueue };

    SetVk_Queues(Queues, QueueCreateInfos);

    vkGetPhysicalDeviceMemoryProperties(PhysicalDevice, &MemoryProperties);

然后我将 HWNDhInstance 传递给表面:

VkWin32SurfaceCreateInfoKHR WCreateInfo = { VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR };
WCreateInfo.hwnd = SCAST(WindowsWindow*, _Window)->GetWindowObject();
WCreateInfo.hinstance = SCAST(WindowsWindow*, _Window)->GetHInstance();

GS_VK_CHECK(vkCreateWin32SurfaceKHR(m_Instance, &WCreateInfo, ALLOCATOR, &Surface), "Failed to create Windows Surface!")

之后,根据验证层的要求,我查询支持和功能:

VkSurfaceCapabilitiesKHR Capabilities;
auto CapResult = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(_PD, Surface, &Capabilities);

VkBool32 Supports = 0;
auto SupResult = vkGetPhysicalDeviceSurfaceSupportKHR(_PD, _Device.GetGraphicsQueue().GetQueueIndex(), Surface, &Supports);

vkGetPhysicalDeviceSurfaceSupportKHR()returnsVK_SUCCESS而且表面是支持的,但是vkGetPhysicalDeviceSurfaceCapabilitiesKHR()returnsVK_ERROR_SURFACE_LOST_KHR。我试着调换这两个函数的顺序,还是一样。

最后,当我尝试创建交换链时:

VkSwapchainCreateInfoKHR SwapchainCreateInfo = { VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR };

SwapchainCreateInfo.surface = _Surface;
SwapchainCreateInfo.minImageCount = 3;
SwapchainCreateInfo.imageFormat = _SurfaceFormat;
SwapchainCreateInfo.imageColorSpace = _SurfaceColorSpace;
SwapchainCreateInfo.imageExtent = _SurfaceExtent;
SwapchainCreateInfo.imageArrayLayers = 1;
SwapchainCreateInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
SwapchainCreateInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
SwapchainCreateInfo.queueFamilyIndexCount = 1; // Optional
SwapchainCreateInfo.pQueueFamilyIndices = nullptr;
SwapchainCreateInfo.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
SwapchainCreateInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
SwapchainCreateInfo.presentMode = _PresentMode;
SwapchainCreateInfo.clipped = VK_TRUE;
SwapchainCreateInfo.oldSwapchain = _OldSwapchain;

失败并显示此 VK_RESULTVK_ERROR_INITIALIZATION_FAILED,并且验证层抛出此警告:

UNASSIGNED-CoreValidation-DrawState-SwapchainCreateBeforeQuery(ERROR / SPEC): msgNum: 0 - vkCreateSwapchainKHR(): surface capabilities not retrieved for this physical device
    Objects: 1
        [0] 0x1fddb809470, type: 2, name: NULL

即使我相信我已经检查了功能。

我的实例启用了此扩展,这是 GLFW 运行所需的全部:

const char* Extensions[] = { VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_WIN32_SURFACE_EXTENSION_NAME };

我的想法是 Vulkan 有问题,因为我看不出哪里会出错。我正在考虑创建一个问题,但我想先和你们确认一下。

您展示了 window 创建和表面创建,但不包括实例创建代码。创建实例时,您是否确保请求了 glfwGetRequiredInstanceExtensions 返回的扩展?请求的确切扩展集是什么?

如果您没有请求任何延期,特别是如果您缺少 VK_KHR_surfaceVK_KHR_win32_surface,那么预计部分或所有表面操作可能会失败。

此外,您如何填充 _SurfaceFormat

最后,这看起来不对:

SwapchainCreateInfo.queueFamilyIndexCount = 1; // Optional
SwapchainCreateInfo.pQueueFamilyIndices = nullptr;

如果 pQueueFamilyIndices 为空,则 queueFamilyIndexCount 应为零。

原来我没有正确设置 HWND 和 HInstance 变量,但是表面创建并没有抱怨它,验证层也没有。由于某种原因,其中一个查询功能函数没有失败,而另一个失败了。