在Mac OS上的CLion中,新的Vulkan项目不会创建VkInstance

时间:2018-12-04 22:04:20

标签: c++ xcode cmake clion vulkan

在我首次成功尝试使用Java和OpenGL(LWJGL3)的3D引擎之后,我决定尝试使用C ++在Vulkan进行尝试。 我几乎没有C / C ++的经验,并且我知道Vulkan的学习曲线很陡。但是,这不是问题。

我决定遵循本教程:https://vulkan-tutorial.com/Introduction

它向我展示了如何使用XCode(与Mac OS Mojave一样)使用Vulkan创建新项目。但是,我想使用CLion继续本教程的其余部分,因为我将在多个操作系统之间进行切换。

我尽力创建一个CLion项目,并成功制作了我的第一个CMakeLists文件,但是似乎有些错误。该文件当前包含以下内容:

cmake_minimum_required(VERSION 3.12)
project(VulkanTesting)

set(CMAKE_CXX_STANDARD 14)

add_executable(VulkanTesting main.cpp)

include_directories(/usr/local/include)
include_directories(/Users/[username]/Documents/Vulkan/SDK/vulkansdk-macos-1.1.92.1/macOS/include)

target_link_libraries(VulkanTesting /usr/local/lib/libglfw.3.3.dylib)
target_link_libraries(VulkanTesting /Users/[username]/Documents/Vulkan/SDK/vulkansdk-macos-1.1.92.1/macOS/lib/libvulkan.1.dylib)
target_link_libraries(VulkanTesting /Users/[username]/Documents/Vulkan/SDK/vulkansdk-macos-1.1.92.1/macOS/lib/libvulkan.1.1.92.dylib)

# Don't know if I need the next two lines
link_directories(/usr/local/lib)
link_directories(/Users/[username]/Documents/Vulkan/SDK/vulkansdk-macos-1.1.92.1/macOS/lib)

我显示上述文件的原因在问题中显而易见。

到目前为止,“程序”如下:

#define GLFW_INCLUDE_VULKAN
#include <GLFW/glfw3.h>

#include <iostream>
#include <stdexcept>
#include <functional>
#include <cstdlib>
#include <vector>

const int WIDTH = 800;
const int HEIGHT = 600;

class HelloTriangleApplication {
public:
    void run() {
        initWindow();
        initVulkan();
        mainLoop();
        cleanup();
    }

private:
    GLFWwindow* window;
    VkInstance instance;

    void initWindow(){
        glfwInit();
        glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
        glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
        window = glfwCreateWindow(WIDTH, HEIGHT, "My first Vulkan window", nullptr, nullptr);
    }

    void initVulkan() {
        createInstance();
    }

    void createInstance(){
        // Instantiate Application Info
        VkApplicationInfo applicationInfo = {};
        applicationInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
        applicationInfo.pApplicationName = "Hello Triangle";
        applicationInfo.applicationVersion = VK_MAKE_VERSION(1,0,0);
        applicationInfo.pEngineName = "No Engine";
        applicationInfo.engineVersion = VK_MAKE_VERSION(1,0,0);
        applicationInfo.apiVersion = VK_API_VERSION_1_0;

        // Instantiate Instance Creation Info
        VkInstanceCreateInfo createInfo = {};
        createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
        createInfo.pApplicationInfo = &applicationInfo;

        // Get GLFW platform specific extensions
        uint32_t glfwExtensionCount = 0;
        const char** glfwExtensions;
        glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount);


        // Fill in required extensions in Instance Creation Info
        createInfo.enabledExtensionCount = glfwExtensionCount;
        createInfo.ppEnabledExtensionNames = glfwExtensions;

        // For validation layers, this is a later step in the tutorial.
        createInfo.enabledLayerCount = 0;

        // Create the Vulkan instance, and check if it was successful.
        VkResult result = vkCreateInstance(&createInfo, nullptr, &instance);
        if(result != VK_SUCCESS){
            std::cout << "glfwExtensionCount: " << glfwExtensionCount << "\n";
            std::cout << "glfwExtensionNames: " << &glfwExtensions << "\n";
            std::cout << "result: " << result << "\n";
            throw std::runtime_error("Failed to create Vulkan Instance");
        }

    }

    void mainLoop() {
        while(!glfwWindowShouldClose(window)){
            glfwPollEvents();
        }
    }

    void cleanup() {
        glfwDestroyWindow(window);
        glfwTerminate();
    }
};

int main() {
    HelloTriangleApplication app;

    try {
        app.run();
    } catch (const std::exception& e) {
        std::cerr << e.what() << std::endl;
        return EXIT_FAILURE;
    }

    return EXIT_SUCCESS;
}

我遇到的问题是,当我尝试运行该程序时,它不会创建VkInstance。该函数返回VK_ERROR_INCOMPATIBLE_DRIVER。现在,我怀疑该驱动程序实际上是不兼容的,因为我已经运行了Vulkan SDK随附的演示应用程序,而我又能够在XCode中运行完全相同的“程序”。当我进一步研究该问题时,我注意到glfwGetRequiredInstanceExtensions函数在像这样在CLion中运行该程序时不返回任何扩展名,但是在XCode等效项中返回一个扩展名。

所有这些使我相信,在Cmake文件中链接库/框架时,我做错了某些事情,因为我知道Mac OS并不直接支持Vulkan,而是(以某种方式?)穿过一层与Metal通信。

我需要为程序指定一种通过Metal层传递其Vulkan功能的方法吗,这是在XCode中自动完成的,还是我的方法有其他问题?

任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:1)

您可能希望在LunarXchange website和您的SDK中查看《 MacOS入门指南》。最后的一节显示了如何使用CMake构建Vulkan应用程序并在MacOS上运行它。您可能还想使用FindVulkan CMake模块,而不是手动设置包含目录和目标链接库。

但是我对您的特定问题的第一个猜测是您可能未设置VK_ICD_FILENAMES环境变量。您的观察是正确的,没有直接支持Vulkan。而是由MoltenVK库提供支持,该库被视为Vulkan驱动程序。但是,SDK并未将此“驱动程序”安装在任何系统目录中。该SDK仅在您的主目录结构中解压缩,因此您必须告诉Vulkan加载器通过此环境变量在哪里找到它。

同样,《入门指南》末尾的CMake部分演示了此环境变量的用法。整个指南进一步介绍了各种Vulkan和MoltenVK组件的工作方式。