VkSurfaceKHR does not to update when resizing xcb window
Asked Answered
A

1

5

I have followed the tutorial at https://vulkan-tutorial.com... I created it without using the GLFW etension. So far I'm up to "Swap chain Recreation", and all is setup and rendering correctly.

However, I can't seem to get resizing working correctly!

I've hooked into the XCB_RESIZE_REQUEST and am setting my info struct w/h like so:

if (resize->width > 0) { info.width = resize->width; }
if (resize->height > 0) { info.height = resize->height; }
info.framebufferResized = true;

Which causes (in the next drawFrame() call) recreateSwapchain() to be called:

if (res == VK_ERROR_OUT_OF_DATE_KHR || res == VK_SUBOPTIMAL_KHR || info.framebufferResized) {
    info.framebufferResized = false;
    recreateSwapchain();
} else  if (res != VK_SUCCESS) {
    throw runtime_error("failed to present swap chain image!");
}

recreateSwapchain() {
    vkDeviceWaitIdle(info.device);

    cleanupSwapchain();

    querySwapchainSupport(info.physicalDevice);
    createSwapchain();
    createImageViews();
    createRenderPass();
    createGraphicsPipeline();
    createFramebuffers();
    createCommandBuffers();
}

I've done some debugging, and have found that the swapchainSupport.capabilities.minImageExtent.width (and height) do not change from the initial values!.. That is, this call

querySwapchainSupport(VkPhysicalDevice physicalDevice) {
    VkResult res = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(
        physicalDevice, info.surface, &info.swapchainSupport.capabilities);
    assert(res == VK_SUCCESS);

Does not update the info.swapchainSupport.capabilities with new window size.

Any help, or comments would be greatly appreciated.

Example Screenshot:

after resize

Armorer answered 28/10, 2018 at 1:12 Comment(3)
I'd rather not resort to using a library such as GLFW.. as I'll most likely want to target mobile at some point;Armorer
Why are you looking at minImageExtent instead of currentExtent?Monterrey
current, min, and max all stay the same: 800x600Armorer
W
7

I'm not sure if XCB_RESIZE_REQUEST is the right event to wait for. In my examples I use XCB_CONFIGURE_NOTIFY to check for window resize events, and querying the surface capabilities after that event gives me the new window size as the surface capabilities extents as expected:

case XCB_CONFIGURE_NOTIFY:
{
    const xcb_configure_notify_event_t *cfgEvent = (const xcb_configure_notify_event_t *)event;
    if (((cfgEvent->width != width) || (cfgEvent->height != height)))
    {
            destWidth = cfgEvent->width;
            destHeight = cfgEvent->height;
            if ((destWidth > 0) && (destHeight > 0))
            {
                // Swap chain recreation ins done in this function              
                windowResize();                 
            }
    }
}

You also need to add the accompanying flag at XCB window creation time:

uint32_t value_list[32];
value_list[1] = ... | XCB_EVENT_MASK_STRUCTURE_NOTIFY...

xcb_create_window(connection,
    ...     
    value_list);

This has been tested to work on many different Linux implementations and platforms.

If you need some help getting XCB up and running you may want to take a look at my Vulkan samples. The interesting parts are in the example base class and the swapchain header.

Wycliffite answered 28/10, 2018 at 8:6 Comment(2)
Yup, the same is performed in the "API without Secrets" series of Intel's Vulkan tutorials. Have a look here.Hundredfold
That Worked! Very Good! Does this have something to do with adding to XCB_EVENT_MASK_STRUCTURE_NOTIFY to the value_list?Armorer

© 2022 - 2024 — McMap. All rights reserved.