VkSurfaceKHR не обновляется при изменении размера окна xcb

Я следил за учебником на https://vulkan-tutorial.com ... Я создал его без использования GLFW etension. Пока я занимаюсь «Восстановлением цепочки подкачки», и все настроено и отрисовывается правильно.

Однако мне кажется, что изменение размера не работает правильно!

Я подключился к XCB_RESIZE_REQUEST и устанавливаю свою информационную структуру w / h следующим образом:

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

Что вызывает (в следующем drawFrame() вызове) recreateSwapchain():

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

Я провел некоторую отладку и обнаружил, что swapchainSupport.capabilities.minImageExtent.width (и высота) не меняются по сравнению с начальными значениями! .. То есть этот вызов

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

Не обновляет info.swapchainSupport.capabilities с новым размером окна.

Любая помощь или комментарии будут очень благодарны.

Пример снимка экрана:

после изменения размера


person coffeesaga    schedule 28.10.2018    source источник
comment
Я бы предпочел не прибегать к использованию такой библиотеки, как GLFW ... так как я, скорее всего, в какой-то момент захочу настроить таргетинг на мобильные устройства;   -  person coffeesaga    schedule 28.10.2018
comment
Почему вы смотрите на minImageExtent вместо currentExtent?   -  person Jherico    schedule 28.10.2018
comment
текущие, минимальные и максимальные значения остаются неизменными: 800x600   -  person coffeesaga    schedule 28.10.2018


Ответы (1)


Я не уверен, что XCB_RESIZE_REQUEST - подходящее событие, которого стоит ждать. В своих примерах я использую XCB_CONFIGURE_NOTIFY для проверки событий изменения размера окна, и запрос возможностей поверхности после этого события дает мне новый размер окна, поскольку возможности поверхности увеличиваются, как и ожидалось:

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

Вам также необходимо добавить соответствующий флаг во время создания окна XCB:

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

xcb_create_window(connection,
    ...     
    value_list);

Это было протестировано для работы на многих различных реализациях и платформах Linux.

Если вам нужна помощь в настройке и запуске XCB, вы можете взглянуть на мои образцы Vulkan. Интересные части находятся в примере базового класса и заголовок цепочки обмена.

person Sascha Willems    schedule 28.10.2018
comment
Да, то же самое выполняется в API без серии руководств Intel по Vulkan "Секреты". Взгляните здесь. - person Ekzuzy; 28.10.2018
comment
Это сработало! Очень хороший! Связано ли это с добавлением XCB_EVENT_MASK_STRUCTURE_NOTIFY в список значений? - person coffeesaga; 29.10.2018