MacOS上有一个例外

发布于 2025-02-12 06:34:24 字数 5869 浏览 2 评论 0原文

我正在通过 this 教程。我已经使用GLFW和初始化的Vulkan实例创建了窗口,没有错误。但是,当我在macOS上调用glfwCreateWIndowSurface时,我得到了一个例外,这崩溃了该过程:

EXC_BAD_ACCESS(code=1, address=0x260000000020)

此函数在Win32和WSL2 Ubuntu上很好地

Thread 0 Crashed::  Dispatch queue: com.apple.main-thread
0   libobjc.A.dylib                     0x7ff81a9e8293 objc_retain + 35
1   Foundation                          0x7ff81ba213d5 +[NSBundle mainBundle] + 42
2   QuartzCore                          0x7ff821ccf655 +[CALayer defaultValueForKey:] + 866
3   QuartzCore                          0x7ff821cd5c2b +[CAMetalLayer defaultValueForKey:] + 323
4   QuartzCore                          0x7ff821cceaa5 classDescription_locked(objc_class*) + 3493
5   QuartzCore                          0x7ff821ccd9ad classDescription(objc_class*) + 221
6   QuartzCore                          0x7ff821ccd51e CA::Layer::class_state(objc_class*) + 72
7   QuartzCore                          0x7ff821ccd3ee -[CALayer init] + 99
8   QuartzCore                          0x7ff821cd5376 -[CAMetalLayer init] + 70
9   QuartzCore                          0x7ff821ccd319 +[CALayer layer] + 9
10  LearnVulkan                            0x10468768f _glfwPlatformCreateWindowSurface + 159
11  LearnVulkan                            0x10467955c glfwCreateWindowSurface + 428 (vulkan.c:332)
12  LearnVulkan                            0x104666359 LearnVulkan::Application::createWindowSurface() + 41 (Application.cpp:431)
13  LearnVulkan                            0x104665dd9 LearnVulkan::Application::initVulkan() + 73 (Application.cpp:89)
14  LearnVulkan                            0x104665b1a LearnVulkan::Application::initialize() + 106 (Application.cpp:28)
15  LearnVulkan                            0x1046658ab main + 107 (LearnVulkan.cpp:13)
16  dyld                                   0x11260851e start + 462

奏效:

int Application::initialize()
{
    mbQuit = false;
    initWindow();
    if (!mWindow)
    {
        std::cerr << "Failed to create GLFW window" << std::endl;
        glfwTerminate();
        return EXIT_FAILURE;
    }
    initVulkan();
    return EXIT_SUCCESS;
}

void Application::initWindow()
{
    // glfw: initialize and configure
    // ------------------------------
    glfwInit();
    // Because GLFW was originally designed to create an OpenGL context
    // we need to tell it to not create an OpenGL context with a subsequent call
    glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);

    // disable window resize
    glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);

    // create window
    mWindow = glfwCreateWindow(mConfig.windowWidth, mConfig.windowHeight, mConfig.windowTitle, nullptr, nullptr);
}

void Application::initVulkan()
{
    if (!checkExtensionSupport())
    {
        mbQuit = true;
        return;
    }
    createVulkanInstance();
#ifdef DEBUG
    setupDebugMessenger();
#endif
    createWindowSurface();
    pickPysicalDevice();
    createLogicalDevice();
}

void Application::createVulkanInstance()
{
#ifdef DEBUG
    if (!checkValidationLayerSupport())
    {
        mbQuit = true;
        std::cerr << "Validation layers requested, but not available!" << std::endl;
        return;
    }
#endif
    VkApplicationInfo appInfo {};
    appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
    appInfo.pApplicationName = mConfig.windowTitle;
    appInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
    appInfo.pEngineName = "Test";
    appInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0);
    appInfo.apiVersion = VK_API_VERSION_1_0;

    VkInstanceCreateInfo createInfo {};
    createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
    createInfo.pApplicationInfo = &appInfo;
    std::vector<const char*> extensions = getRequiredExtensions();
    createInfo.enabledExtensionCount = static_cast<uint32_t>(extensions.size());
    createInfo.ppEnabledExtensionNames = extensions.data();
#ifdef DEBUG
    createInfo.enabledLayerCount = static_cast<uint32_t>(VALIDATION_LAYERS.size());
    createInfo.ppEnabledLayerNames = VALIDATION_LAYERS.data();

    VkDebugUtilsMessengerCreateInfoEXT debugCreateInfo {};
    populateDebugMessengerCreateInfo(debugCreateInfo);
    createInfo.pNext = &debugCreateInfo;
#else
    createInfo.enabledLayerCount = 0;
    createInfo.pNext = nullptr;
#endif

#ifdef OS_MACOS
    createInfo.flags = VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
#endif

    if (vkCreateInstance(&createInfo, nullptr, &mVulkanInstance) != VK_SUCCESS)
    {
        mbQuit = true;
        std::cerr << "Failed to create Vulkan instance!" << std::endl;
    }
}

void Application::createWindowSurface()
{
    if (glfwCreateWindowSurface(mVulkanInstance, mWindow, nullptr, &mWindowSurface) != VK_SUCCESS)
    {
        std::cerr << "Failed to create window surface!" << std::endl;
        mbQuit = true;
    }
}

不知道发生了什么事,有人可以帮助我吗?

版本信息:

  • MACOS版本:MACOS Monterey版本12.4
  • Xcode版本:13.4.1
  • VulkansDK版本:1.3.216.0
  • GLFW:3.3稳定的

GLFW是从源构建的,这是.git> .gitmodules file> file>文件:

[submodule "ThirdParty/glfw"]
    path = ThirdParty/glfw
    url = [email protected]:glfw/glfw.git
    branch = 3.3-stable
[submodule "ThirdParty/glm"]
    path = ThirdParty/glm
    url = [email protected]:g-truc/glm.git
    branch = cmake3

I am learning Vulkan via this tutorial. I have created window with GLFW and initialized Vulkan instance without errors. But when I invoke glfwCreateWindowSurface on MacOS, I got an exception which crashed the process:

EXC_BAD_ACCESS(code=1, address=0x260000000020)

This function works well on Win32 and WSL2 Ubuntu, except MacOS.

Here's the stack:

Thread 0 Crashed::  Dispatch queue: com.apple.main-thread
0   libobjc.A.dylib                     0x7ff81a9e8293 objc_retain + 35
1   Foundation                          0x7ff81ba213d5 +[NSBundle mainBundle] + 42
2   QuartzCore                          0x7ff821ccf655 +[CALayer defaultValueForKey:] + 866
3   QuartzCore                          0x7ff821cd5c2b +[CAMetalLayer defaultValueForKey:] + 323
4   QuartzCore                          0x7ff821cceaa5 classDescription_locked(objc_class*) + 3493
5   QuartzCore                          0x7ff821ccd9ad classDescription(objc_class*) + 221
6   QuartzCore                          0x7ff821ccd51e CA::Layer::class_state(objc_class*) + 72
7   QuartzCore                          0x7ff821ccd3ee -[CALayer init] + 99
8   QuartzCore                          0x7ff821cd5376 -[CAMetalLayer init] + 70
9   QuartzCore                          0x7ff821ccd319 +[CALayer layer] + 9
10  LearnVulkan                            0x10468768f _glfwPlatformCreateWindowSurface + 159
11  LearnVulkan                            0x10467955c glfwCreateWindowSurface + 428 (vulkan.c:332)
12  LearnVulkan                            0x104666359 LearnVulkan::Application::createWindowSurface() + 41 (Application.cpp:431)
13  LearnVulkan                            0x104665dd9 LearnVulkan::Application::initVulkan() + 73 (Application.cpp:89)
14  LearnVulkan                            0x104665b1a LearnVulkan::Application::initialize() + 106 (Application.cpp:28)
15  LearnVulkan                            0x1046658ab main + 107 (LearnVulkan.cpp:13)
16  dyld                                   0x11260851e start + 462

My code:

int Application::initialize()
{
    mbQuit = false;
    initWindow();
    if (!mWindow)
    {
        std::cerr << "Failed to create GLFW window" << std::endl;
        glfwTerminate();
        return EXIT_FAILURE;
    }
    initVulkan();
    return EXIT_SUCCESS;
}

void Application::initWindow()
{
    // glfw: initialize and configure
    // ------------------------------
    glfwInit();
    // Because GLFW was originally designed to create an OpenGL context
    // we need to tell it to not create an OpenGL context with a subsequent call
    glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);

    // disable window resize
    glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);

    // create window
    mWindow = glfwCreateWindow(mConfig.windowWidth, mConfig.windowHeight, mConfig.windowTitle, nullptr, nullptr);
}

void Application::initVulkan()
{
    if (!checkExtensionSupport())
    {
        mbQuit = true;
        return;
    }
    createVulkanInstance();
#ifdef DEBUG
    setupDebugMessenger();
#endif
    createWindowSurface();
    pickPysicalDevice();
    createLogicalDevice();
}

void Application::createVulkanInstance()
{
#ifdef DEBUG
    if (!checkValidationLayerSupport())
    {
        mbQuit = true;
        std::cerr << "Validation layers requested, but not available!" << std::endl;
        return;
    }
#endif
    VkApplicationInfo appInfo {};
    appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
    appInfo.pApplicationName = mConfig.windowTitle;
    appInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
    appInfo.pEngineName = "Test";
    appInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0);
    appInfo.apiVersion = VK_API_VERSION_1_0;

    VkInstanceCreateInfo createInfo {};
    createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
    createInfo.pApplicationInfo = &appInfo;
    std::vector<const char*> extensions = getRequiredExtensions();
    createInfo.enabledExtensionCount = static_cast<uint32_t>(extensions.size());
    createInfo.ppEnabledExtensionNames = extensions.data();
#ifdef DEBUG
    createInfo.enabledLayerCount = static_cast<uint32_t>(VALIDATION_LAYERS.size());
    createInfo.ppEnabledLayerNames = VALIDATION_LAYERS.data();

    VkDebugUtilsMessengerCreateInfoEXT debugCreateInfo {};
    populateDebugMessengerCreateInfo(debugCreateInfo);
    createInfo.pNext = &debugCreateInfo;
#else
    createInfo.enabledLayerCount = 0;
    createInfo.pNext = nullptr;
#endif

#ifdef OS_MACOS
    createInfo.flags = VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
#endif

    if (vkCreateInstance(&createInfo, nullptr, &mVulkanInstance) != VK_SUCCESS)
    {
        mbQuit = true;
        std::cerr << "Failed to create Vulkan instance!" << std::endl;
    }
}

void Application::createWindowSurface()
{
    if (glfwCreateWindowSurface(mVulkanInstance, mWindow, nullptr, &mWindowSurface) != VK_SUCCESS)
    {
        std::cerr << "Failed to create window surface!" << std::endl;
        mbQuit = true;
    }
}

No idea what's going on, can anybody help me?

version info:

  • MacOS version: macOS Monterey Version 12.4
  • Xcode version: 13.4.1
  • VulkanSDK version: 1.3.216.0
  • glfw: 3.3-stable

glfw is built from source, here's the .gitmodules file:

[submodule "ThirdParty/glfw"]
    path = ThirdParty/glfw
    url = [email protected]:glfw/glfw.git
    branch = 3.3-stable
[submodule "ThirdParty/glm"]
    path = ThirdParty/glm
    url = [email protected]:g-truc/glm.git
    branch = cmake3

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

所谓喜欢 2025-02-19 06:34:25

我有完全相同的问题。 这个问题的直接原因是

#else
    createInfo.enabledLayerCount = 0;
    createInfo.pNext = nullptr;
#endif

vkcreateinstance()的设置中, 。显然,如果createInfo.enabledlayerCount为零,glfwcreatewindowsurface() 即使vkcreateinstance()返回vk_success

同样的事情会导致Lunarg Vulkan教程关闭验证层(使用#Define Ndebug)。除了设置非零验证层(这也给我带来麻烦)或可能使用其他功能创建表面之外,我不知道如何修复它?

I have the exact same issue. The proximate cause is this

#else
    createInfo.enabledLayerCount = 0;
    createInfo.pNext = nullptr;
#endif

in your setup for vkCreateInstance(). Apparently if createInfo.enabledLayerCount is zero, glfwCreateWindowSurface() crashes even though vkCreateInstance() returns VK_SUCCESS.

Same thing causes the LunarG Vulkan tutorials to crash if you turn off the validation layers (with #define NDEBUG). I don't know how to fix it, other than setting up non-zero validation layers (which are causing trouble for me too) or maybe creating a surface with another function?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文