1

i follow the tutorial on https://vulkan-tutorial.com/ for trying to draw a simple triangle with Vulkan, but i get about 70 fps. (With a similar scene like drawing triangle with directx11 i am getting 10000 fps, and opengl:9000fps)

i've done some profiling and i find out that vkAcquireNextImageKHR takes so long.

the reason propably is that my graphics card doesnt support VK_PRESENT_MODE_MAILBOX_KHR, and according to tutorial i am choosing VK_PRESENT_MODE_FIFO_KHR

( my graphics card supports only 2 modes for PresentMode: VK_PRESENT_MODE_IMMEDIATE_KHR, VK_PRESENT_MODE_FIFO_KHR )

yes only thing i can think of this tutorial designed for VK_PRESENT_MODE_MAILBOX_KHR but i am using VK_PRESENT_MODE_FIFO_KHR mode.

also if i switch to VK_PRESENT_MODE_IMMEDIATE_KHR mode, i get 4000 fps (still direct3D11 and opengl faster than vulkan)

i copy-paste almost everything from vulkan-tutorial.com, and the code is: https://vulkan-tutorial.com/code/16_swap_chain_recreation.cpp

only different part i am doing is, in the tutorial, he uses glfw library for window creation and i create my own.. these are the differen parts (i didnt copy-paste the rest of the code since everything is same with the link above, the problem vkAcquireNextImageKHR call is in the drawFrame method, please check it from the link above)

void Graphics_Vulkan::recreateSwapChain()
{
    uint w = 0, h = 0;
    while (!MainWindow->GetClientSize(w, h) || w == 0 || h == 0) 
        ProcessMessageForAllWindows();

    vkDeviceWaitIdle(device);

    cleanupSwapChain();

    createSwapChain();
    createImageViews();
    createRenderPass();
    createGraphicsPipeline();
    createFramebuffers();
    createCommandBuffers();

    imagesInFlight.resize(swapChainImages.size(), VK_NULL_HANDLE);
}

void Graphics_Vulkan::createSurface()
{
    VkWin32SurfaceCreateInfoKHR createInfo{};
    createInfo.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
    createInfo.hwnd = MainWindow->hwnd;
    createInfo.hinstance = hInstance;

    if (vkCreateWin32SurfaceKHR(instance, &createInfo, nullptr, &surface) != VK_SUCCESS)
        throw std::runtime_error("failed to create window surface!");
}

VkExtent2D Graphics_Vulkan::chooseSwapExtent(const VkSurfaceCapabilitiesKHR & capabilities)
{
    if (capabilities.currentExtent.width != UINT32_MAX) {
        return capabilities.currentExtent;
    }
    else {

        uint width = 0, height = 0;
        MainWindow->GetClientSize(width, height);

        VkExtent2D actualExtent = {
            static_cast<uint32_t>(width),
            static_cast<uint32_t>(height)
        };

        actualExtent.width = max(capabilities.minImageExtent.width, min(capabilities.maxImageExtent.width, actualExtent.width));
        actualExtent.height = max(capabilities.minImageExtent.height, min(capabilities.maxImageExtent.height, actualExtent.height));

        return actualExtent;
    }
}

std::vector<const char*> Graphics_Vulkan::getRequiredExtensions()
{
    std::vector<const char*> enabledExtensions = { VK_KHR_SURFACE_EXTENSION_NAME };

#if defined(OSWINDOWS)
    enabledExtensions.push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
#elif defined(__ANDROID__)
    enabledExtensions.push_back(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME);
#elif defined(__linux__)
    enabledExtensions.push_back(VK_KHR_XCB_SURFACE_EXTENSION_NAME);
#endif

    enabledExtensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);

    /*on my pc, there were 2 more extensions. i wasnt sure to add those to in the list:
    VK_KHR_get_physical_device_properties2
    VK_EXT_debug_report
    */

    return enabledExtensions;
}

there is another person also having this issue, but couldnt get any answer on that page https://community.khronos.org/t/tearing-with-present-mode-fifo-enabled-vulkan-tutorial/106298

EDIT: i thought would help if i share values below after 64bit release test:

64bit release mode:

Vulkan 74fps (with VK_PRESENT_MODE_FIFO_KHR) Vulkan 9930fps (with VK_PRESENT_MODE_IMMEDIATE_KHR) Direct3D11 13100fps OpenGL 9600fps

4

1 回答 1

1

你所描述的一切本质上都是应该发生的。

如果您超过显示引擎(即:渲染内容比显示速度快),则有两种选择。您可以减慢渲染速度,也可以强制显示引擎在显示不同图像的过程中显示图像(通常会导致撕裂)。

在 Vulkan 中,这两个选项拼写为PRESENT_MODE_FIFOPRESENT_MODE_IMMEDIATE. 因此,FIFO 会导致您的代码与显示引擎同步,而 IMMEDIATE 不会,这是完全正常的。这实际上是您所要求的

于 2021-03-26T16:54:02.320 回答