Search code examples
c++windowsglfwvulkan

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


I'm trying to create a swapchain after surface creation. Currently my window is being created with GLFW like this:

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

I create my VkInstance like this:

    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!")

My VkDevice like this:

    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);

Then I'm giving the HWND and hInstance to the surface through:

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!")

After that as required by the validation layers I query for support and capabilities:

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

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

vkGetPhysicalDeviceSurfaceSupportKHR() returns VK_SUCCESS and that the surface is supported, but vkGetPhysicalDeviceSurfaceCapabilitiesKHR() returns VK_ERROR_SURFACE_LOST_KHR. I tried switching the order of these two functions and still the same happens.

Finally when I try to create a swapchain:

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;

It fails with this VK_RESULT: VK_ERROR_INITIALIZATION_FAILED, and the validation layers throw this warning:

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

Even though I believe I have checked for capabilities.

My Instance has this extensions enabled which are all that are required for GLFW to function:

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

My thought is that there is something wrong with Vulkan, since I can not see where this could go wrong. I was thinking of creating an issue but I wanted to check with you guys first.


Solution

  • Turns out I wasn't setting the HWND and HInstance variables properly but the surface creation didn't complain about it, neither did the validation layers. And for some reason one of the query capabilities function didn't fail while the other did.