Facundo Villa
Facundo Villa

Reputation: 111

vkCreateSwapchainKHR: internal drawable creation failed

I had my Vulkan application working but for some reason it stopped working(I don't believe I touched anything that could have broken it, besides making my engine project a .lib instead of a .dll) and started giving the "vkCreateSwapchainKHR: internal drawable creation failed" error in the validation layers. vkCreateSwapchainKHR returns VK_ERROR_VALIDATION_FAILED_EXT.

I already checked this answer: Wat does the "vkCreateSwapchainKHR:internal drawable creation failed." means, but it was not my problem, (as I said, it was working until it wasn't). Here's all the code I believe is relevant, if you need something else just comment:

Window Creation:

/* Initialize the library */
if (!glfwInit())

    /* Create a windowed mode window and its OpenGL context */
    glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
    glfwWindowHint(GLFW_DECORATED, _WCI.IsDecorated);
    GLFWWindow = glfwCreateWindow(Extent.Width, Extent.Height, _WCI.Name.c_str(), nullptr, nullptr);

    if (!GLFWWindow) glfwTerminate();

    //glfwMakeContextCurrent(GLFWWindow);

    uint32 Count = 0;
    auto ff = glfwGetRequiredInstanceExtensions(&Count);

    GS_BASIC_LOG_MESSAGE("GLFW required extensions:")
    for (uint8 i = 0; i < Count; ++i)
    {
        GS_BASIC_LOG_MESSAGE("%d: %s", i, ff[i]);
    }

    WindowObject = glfwGetWin32Window(GLFWWindow);
    WindowInstance = GetModuleHandle(nullptr);

I'm using the correct instance extensions:

const char* Extensions[] = { VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_WIN32_SURFACE_EXTENSION_NAME, VK_EXT_DEBUG_UTILS_EXTENSION_NAME };
VKSwapchainCreator VulkanRenderContext::CreateSwapchain(VKDevice* _Device, VkSwapchainKHR _OldSwapchain) const
{
    VkSwapchainCreateInfoKHR SwapchainCreateInfo = { VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR };

    SwapchainCreateInfo.surface = Surface.GetHandle();
    SwapchainCreateInfo.minImageCount = 3;
    SwapchainCreateInfo.imageFormat = Format.format;
    SwapchainCreateInfo.imageColorSpace = Format.colorSpace;
    SwapchainCreateInfo.imageExtent = Extent2DToVkExtent2D(RenderExtent);
    //The imageArrayLayers specifies the amount of layers each image consists of. This is always 1 unless you are developing a stereoscopic 3D application.
    SwapchainCreateInfo.imageArrayLayers = 1;
    SwapchainCreateInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
    SwapchainCreateInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
    SwapchainCreateInfo.queueFamilyIndexCount = 0;
    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;

    return VKSwapchainCreator(_Device, &SwapchainCreateInfo);
}

Both VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR and VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR are supported by my GPU.

    VkBool32 Supports = 0;
    vkGetPhysicalDeviceSurfaceSupportKHR(_PD, PresentationQueue.GetQueueIndex(), _Surface, &Supports);

    VkSurfaceCapabilitiesKHR SurfaceCapabilities = {};
    vkGetPhysicalDeviceSurfaceCapabilitiesKHR(_PD, _Surface, &SurfaceCapabilities);

    VkBool32 Supported = 0;
    vkGetPhysicalDeviceSurfaceSupportKHR(_PD, PresentationQueue.GetQueueIndex(), _Surface, &Supported);

    auto bb = vkGetPhysicalDeviceWin32PresentationSupportKHR(_PD, PresentationQueue.GetQueueIndex());

Everything here returns true, although it seemed suspicious to me that VkSurfaceCapabilitiesKHR returned the same extent for currentExtent, minImageExtent and maxImageExtent.

Upvotes: 2

Views: 1314

Answers (2)

krOoze
krOoze

Reputation: 13276

/* Initialize the library */
if (!glfwInit())

    /* Create a windowed mode window and its OpenGL context */
    glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
    glfwWindowHint(GLFW_DECORATED, _WCI.IsDecorated);

If this is your actual code, it means "if glfwInit() succeeds skip glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);". And as we know not calling the hint causes the error.

The if should perhaps not have negation inside. And (this not being Python) it should have scope {} to cover all the init code.

Upvotes: 1

Facundo Villa
Facundo Villa

Reputation: 111

The solution was to remove the glfwInit call from inside the if and place it outside.

if (!glfwInit()) -> glfwInit()

No idea why, if someone knows why this could've have caused the problem I would love to know.

Upvotes: 1

Related Questions