我想通过 CMake 的 FetchContent 模块提供 Vulkan SDK。
# Vulkan SDK
set(VULKAN_SDK_VERSION 1.3.290.0)
# FetchContent_Declare() calls
FetchContent_Declare(VulkanHeaders
GIT_REPOSITORY https://github.com/KhronosGroup/Vulkan-Headers.git
GIT_TAG "vulkan-sdk-${VULKAN_SDK_VERSION}"
OVERRIDE_FIND_PACKAGE)
FetchContent_Declare(VulkanLoader
GIT_REPOSITORY https://github.com/KhronosGroup/Vulkan-Loader.git
GIT_TAG "vulkan-sdk-${VULKAN_SDK_VERSION}"
OVERRIDE_FIND_PACKAGE)
FetchContent_Declare(VulkanUtilityLibraries
GIT_REPOSITORY https://github.com/KhronosGroup/Vulkan-Utility-Libraries.git
GIT_TAG "vulkan-sdk-${VULKAN_SDK_VERSION}"
OVERRIDE_FIND_PACKAGE)
FetchContent_Declare(SPIRV-Headers
GIT_REPOSITORY https://github.com/KhronosGroup/SPIRV-Headers.git
GIT_TAG "vulkan-sdk-${VULKAN_SDK_VERSION}"
OVERRIDE_FIND_PACKAGE)
FetchContent_Declare(SPIRV-Tools
GIT_REPOSITORY https://github.com/KhronosGroup/SPIRV-Tools.git
GIT_TAG "vulkan-sdk-${VULKAN_SDK_VERSION}"
OVERRIDE_FIND_PACKAGE)
FetchContent_Declare(VulkanValidationLayers
GIT_REPOSITORY https://github.com/KhronosGroup/Vulkan-ValidationLayers.git
GIT_TAG "vulkan-sdk-${VULKAN_SDK_VERSION}"
OVERRIDE_FIND_PACKAGE)
# Build Settings
set(SPIRV_SKIP_TESTS ON CACHE BOOL "" FORCE)
set(USE_MIMALLOC OFF CACHE BOOL "" FORCE)
set(USE_ROBIN_HOOD_HASHING OFF CACHE BOOL "" FORCE)
# FetchContent_MakeAvailable() calls
FetchContent_MakeAvailable(VulkanHeaders)
FetchContent_MakeAvailable(VulkanLoader)
FetchContent_MakeAvailable(VulkanUtilityLibraries)
FetchContent_MakeAvailable(SPIRV-Headers)
FetchContent_MakeAvailable(SPIRV-Tools)
FetchContent_MakeAvailable(VulkanValidationLayers)
add_library(Vulkan::Vulkan INTERFACE IMPORTED GLOBAL)
target_link_libraries(Vulkan::Vulkan INTERFACE
Vulkan::Headers
Vulkan::Loader
Vulkan::LayerSettings
Vulkan::UtilityHeaders
Vulkan::SafeStruct
SPIRV-Headers
SPIRV-Tools
VkLayer_utils)
我链接到我的项目。
add_executable(${PROJECT_NAME} main.cpp)
target_link_libraries(${PROJECT_NAME} PRIVATE
glm::glm
glfw
Vulkan::Vulkan)
我有简单的 Vulkan Hello World 来检查验证层是否可用。
#define GLFW_INCLUDE_VULKAN
#include <GLFW/glfw3.h>
#include <iostream>
#include <stdexcept>
#include <vector>
const std::vector<const char*> validationLayers = {
"VK_LAYER_KHRONOS_validation"
};
#ifdef NDEBUG
const bool enableValidationLayers = false;
#else
const bool enableValidationLayers = true;
#endif
void checkValidationLayerSupport() {
uint32_t layerCount;
vkEnumerateInstanceLayerProperties(&layerCount, nullptr);
std::vector<VkLayerProperties> availableLayers(layerCount);
vkEnumerateInstanceLayerProperties(&layerCount, availableLayers.data());
for (const char* layerName : validationLayers) {
bool layerFound = false;
for (const auto& layerProperties : availableLayers) {
if (strcmp(layerName, layerProperties.layerName) == 0) {
layerFound = true;
break;
}
}
if (!layerFound) {
throw std::runtime_error("Required validation layer not found!");
}
}
}
VkInstance createInstance() {
if (enableValidationLayers) {
checkValidationLayerSupport();
}
VkInstance instance;
VkInstanceCreateInfo createInfo{};
createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
if (enableValidationLayers) {
createInfo.ppEnabledLayerNames = validationLayers.data();
createInfo.enabledLayerCount = static_cast<uint32_t>(validationLayers.size());
} else {
createInfo.enabledLayerCount = 0;
}
if (vkCreateInstance(&createInfo, nullptr, &instance) != VK_SUCCESS) {
throw std::runtime_error("Failed to create Vulkan instance!");
}
return instance;
}
int main() {
try {
// GLFW initialisieren
glfwInit();
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
// Vulkan Instanz erstellen
VkInstance instance = createInstance();
// Hier könnte dein Vulkan-Code fortgesetzt werden
vkDestroyInstance(instance, nullptr);
} catch (const std::runtime_error& e) {
std::cerr << e.what() << std::endl;
return EXIT_FAILURE;
}
glfwTerminate();
return EXIT_SUCCESS;
}
我在配置或构建阶段没有收到任何错误。当我运行该程序时,它指出没有可用的验证层。这不是正确的行为,因为当我使用安装的普通 VulkanSDK 并使用 find_package() 时,它会正确列出所有可用的验证层。
问题是您的 CMake 文件在构建树中的某个位置构建了验证层,而 Vulkan 加载程序无法找到它,因为您的构建树不是它查找层的标准位置之一。 解决此问题的一种方法是在启动应用程序之前设置
VK_LAYER_PATH
环境变量以包含验证层二进制文件和 JSON 文件最终位于构建树中的目录。 Loader GitHub 存储库应包含描述此行为的文档。