Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Calling vkCreateSwapchainKHR on non-main thread cause stuck #2357

Open
XieYHccc opened this issue Sep 29, 2024 · 2 comments
Open

Calling vkCreateSwapchainKHR on non-main thread cause stuck #2357

XieYHccc opened this issue Sep 29, 2024 · 2 comments

Comments

@XieYHccc
Copy link

Hi everyone,

I'm using a Job system to split the initialization of my engine into different jobs. The problem is that calling vkCreateSwapchainKHR on a non-main thread mysteriously hangs with no validation errors(The same code works on Windows, see below).
However, when I move the initialization of Vulkan to main thread, it works.

So, Is there any thing I missed? or should we must call vkCreateSwapchainKHR on main thread on Macos?

Application::Application(const ApplicationSpecification& specs) 
{
    s_Instance = this;

    Logger::Init();

    // Init Job System
    m_JobSystem = CreateScope<JobSystem>();

    // Init Event Manager
    EventManager::CreateSingleton();

    // Init Input System
    Input::CreateSingleton();
    Input::Get()->Init();

    // Create Window
    {
        WindowSpecification windowSpec;
        windowSpec.width = specs.width;
        windowSpec.height = specs.height;
        windowSpec.title = specs.title;
        windowSpec.is_fullscreen = specs.isFullScreen;

#if defined(QK_PLATFORM_WINDOWS) || defined(QK_PLATFORM_MACOS)
        m_Window = CreateScope<WindowGLFW>(windowSpec);
        m_Window->Init();
#endif
        NFD::Init();

        QK_CORE_LOGI_TAG("Core", "Window created");
    }

    // Init Graphic Device and Renderer
    JobSystem::Counter counter;
    m_JobSystem->Execute([this]()
    {
#ifdef USE_VULKAN_DRIVER
        m_GraphicDevice = CreateScope<graphic::Device_Vulkan>();
        m_GraphicDevice->Init();
#endif
        GpuResourceManager::CreateSingleton();
        GpuResourceManager::Get().Init();
    }, &counter);

    // Init Asset system
    m_JobSystem->Execute([this, &counter]() 
    {
        m_JobSystem->Wait(&counter, 1);
        AssetManager::CreateSingleton(); 
    });

    // Init UI system
    m_JobSystem->Execute([this, &specs, &counter]() 
    {
        m_JobSystem->Wait(&counter, 1);
        UI::CreateSingleton();
        UI::Get()->Init(m_GraphicDevice.get(), specs.uiSpecs);
    });

    m_JobSystem->Wait(&counter, 1);

    // Register application callback functions
    EventManager::Get().Subscribe<WindowCloseEvent>([this](const WindowCloseEvent& event) { OnWindowClose(event);});
    EventManager::Get().Subscribe<WindowResizeEvent>([this](const WindowResizeEvent& event) { OnWindowResize(event); });
}
@AlexanderDevaikinEnscape

AFAIK it's because macOS requires interacting with UI only on main thread, and swapchain creation in MoltenVK is UI surface interaction on the Metal/OS level.

@billhollings
Copy link
Contributor

AFAIK it's because macOS requires interacting with UI only on main thread, and swapchain creation in MoltenVK is UI surface interaction on the Metal/OS level.

Yes. In the Apple APIs, access to the main UI components, such as screens or views, which MoltenVK may need to do during swapchain creation, must be done on the main thread.

If swapchain creation is done from a secondary thread, MoltenVK dispatches any necessary UI calls to the main thread, and waits for them to complete. If the app is also waiting on the main thread for the swapchain to be created, this can cause a deadlock.

@XieYHccc

Are you able to generate a call stack trace of the hang, so we can see where it is hanging?

If you're running the app from Xcode, you can pause the app and screenshot the call stacks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants