Mac OS 上 CLion 中的新 Vulkan 项目将不会创建 VkInstance
New Vulkan project in CLion on Mac OS will not create VkInstance
在我第一次成功尝试使用 Java 和 OpenGL (LWJGL3) 的 3D 引擎之后,我决定尝试使用 C++ 的 Vulkan。
我对 C/C++ 几乎没有任何经验,而且我知道 Vulkan 的陡峭学习曲线。不过这不是问题。
我决定按照本教程进行操作:https://vulkan-tutorial.com/Introduction
它向我展示了如何使用 XCode 使用 Vulkan 创建一个新项目(就像我在 Mac OS Mojave 上一样)。但是,我想使用 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)
我显示上述文件的原因将在问题中显而易见。
目前的'Program'如下:
#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。函数 returns VK_ERROR_INCOMPATIBLE_DRIVER。现在,我怀疑该驱动程序实际上是不兼容的,因为我有 运行 Vulkan SDK 随附的演示应用程序,而另一个我已经能够 运行 完全相同 'program' 在 XCode 中。当我进一步调查这个问题时,我注意到 glfwGetRequiredInstanceExtensions
函数 return 没有扩展,当程序在 CLion 中是 运行 像这样,但是 return 一个在XCode 等价物。
这一切让我相信我在链接 Cmake 文件中的 libraries/frameworks 时做错了什么,因为我知道 Mac 不直接支持 Vulkan OS,而是(以某种方式?)通过一层与 Metal 通信。
我是否需要指定程序通过 Metal 层传递其 Vulkan 功能的方式,这是在 XCode 中自动完成的,还是我的方法存在其他问题?
如有任何帮助,我们将不胜感激!
您可能想查看 LunarXchange website 和您的 SDK 中的 MacOS 入门指南。最后有一节展示了如何使用 CMake 构建 Vulkan 应用程序并 运行 它在 MacOS 上。您可能还想使用 FindVulkan CMake 模块,而不是手动设置包含目录和目标 link 库。
但我对您的具体问题的第一个猜测是您可能没有设置 VK_ICD_FILENAMES
环境变量。您的观察是正确的,即没有对 Vulkan 的直接支持。相反,支持由 MoltenVK 库提供,该库被视为 Vulkan 驱动程序。但是这个 "driver" 并没有被 SDK 安装在任何系统目录中。 SDK 只是解压缩到您的主目录结构中,因此您必须通过此环境变量告诉 Vulkan 加载程序在哪里可以找到它。
同样,入门指南末尾的 CMake 部分演示了此环境变量的使用。整个指南还详细介绍了各种 Vulkan 和 MoltenVK 组件的工作原理。
在我第一次成功尝试使用 Java 和 OpenGL (LWJGL3) 的 3D 引擎之后,我决定尝试使用 C++ 的 Vulkan。 我对 C/C++ 几乎没有任何经验,而且我知道 Vulkan 的陡峭学习曲线。不过这不是问题。
我决定按照本教程进行操作:https://vulkan-tutorial.com/Introduction
它向我展示了如何使用 XCode 使用 Vulkan 创建一个新项目(就像我在 Mac OS Mojave 上一样)。但是,我想使用 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)
我显示上述文件的原因将在问题中显而易见。
目前的'Program'如下:
#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。函数 returns VK_ERROR_INCOMPATIBLE_DRIVER。现在,我怀疑该驱动程序实际上是不兼容的,因为我有 运行 Vulkan SDK 随附的演示应用程序,而另一个我已经能够 运行 完全相同 'program' 在 XCode 中。当我进一步调查这个问题时,我注意到 glfwGetRequiredInstanceExtensions
函数 return 没有扩展,当程序在 CLion 中是 运行 像这样,但是 return 一个在XCode 等价物。
这一切让我相信我在链接 Cmake 文件中的 libraries/frameworks 时做错了什么,因为我知道 Mac 不直接支持 Vulkan OS,而是(以某种方式?)通过一层与 Metal 通信。
我是否需要指定程序通过 Metal 层传递其 Vulkan 功能的方式,这是在 XCode 中自动完成的,还是我的方法存在其他问题?
如有任何帮助,我们将不胜感激!
您可能想查看 LunarXchange website 和您的 SDK 中的 MacOS 入门指南。最后有一节展示了如何使用 CMake 构建 Vulkan 应用程序并 运行 它在 MacOS 上。您可能还想使用 FindVulkan CMake 模块,而不是手动设置包含目录和目标 link 库。
但我对您的具体问题的第一个猜测是您可能没有设置 VK_ICD_FILENAMES
环境变量。您的观察是正确的,即没有对 Vulkan 的直接支持。相反,支持由 MoltenVK 库提供,该库被视为 Vulkan 驱动程序。但是这个 "driver" 并没有被 SDK 安装在任何系统目录中。 SDK 只是解压缩到您的主目录结构中,因此您必须通过此环境变量告诉 Vulkan 加载程序在哪里可以找到它。
同样,入门指南末尾的 CMake 部分演示了此环境变量的使用。整个指南还详细介绍了各种 Vulkan 和 MoltenVK 组件的工作原理。