From 668ba68a7af9e7511e0e6c988ccfe297956a42b6 Mon Sep 17 00:00:00 2001 From: PCJohn Date: Sat, 22 May 2021 15:34:17 +0200 Subject: FindVulkan: add Vulkan::Headers and Vulkan::glslangValidator targets The `Vulkan::Headers` target complements existing Vulkan::Vulkan target. It is the same except it omits the Vulkan library which supports applications that loads the Vulkan library in at runtime. The `Vulkan::glslangValidator` target provides the glslangValidator executable which is the tool for converting between shader languages (GLSL, SPIR-V, etc.). --- ...Vulkan-add-Headers-glslangValidator-targets.rst | 5 ++ Modules/FindVulkan.cmake | 54 ++++++++++++++++++--- Tests/FindVulkan/Test/CMakeLists.txt | 20 +++++++- Tests/FindVulkan/Test/Run-glslangValidator.cmake | 20 ++++++++ .../FindVulkan/Test/main-dynamicVulkanLoading.cpp | 55 ++++++++++++++++++++++ 5 files changed, 147 insertions(+), 7 deletions(-) create mode 100644 Help/release/dev/FindVulkan-add-Headers-glslangValidator-targets.rst create mode 100644 Tests/FindVulkan/Test/Run-glslangValidator.cmake create mode 100644 Tests/FindVulkan/Test/main-dynamicVulkanLoading.cpp diff --git a/Help/release/dev/FindVulkan-add-Headers-glslangValidator-targets.rst b/Help/release/dev/FindVulkan-add-Headers-glslangValidator-targets.rst new file mode 100644 index 0000000..4f224cc --- /dev/null +++ b/Help/release/dev/FindVulkan-add-Headers-glslangValidator-targets.rst @@ -0,0 +1,5 @@ +FindVulkan-add-Headers-glslangValidator-targets +----------------------------------------------- + +* The :module:`FindVulkan` module gained imported targets + ``Vulkan::Headers`` and ``Vulkan::glslangValidator``. diff --git a/Modules/FindVulkan.cmake b/Modules/FindVulkan.cmake index ceb1921..4f48e13 100644 --- a/Modules/FindVulkan.cmake +++ b/Modules/FindVulkan.cmake @@ -13,12 +13,28 @@ and computing API. IMPORTED Targets ^^^^^^^^^^^^^^^^ -This module defines :prop_tgt:`IMPORTED` target ``Vulkan::Vulkan``, if -Vulkan has been found. +This module defines :prop_tgt:`IMPORTED` targets if Vulkan has been found: -.. versionadded:: 3.19 - This module defines :prop_tgt:`IMPORTED` target ``Vulkan::glslc``, if - Vulkan and the GLSLC SPIR-V compiler has been found. +``Vulkan::Vulkan`` + The main Vulkan library. + +``Vulkan::glslc`` + .. versionadded:: 3.19 + + The GLSLC SPIR-V compiler, if it has been found. + +``Vulkan::Headers`` + .. versionadded:: 3.21 + + Provides just Vulkan headers include paths, if found. No library is + included in this target. This can be useful for applications that + load Vulkan library dynamically. + +``Vulkan::glslangValidator`` + .. versionadded:: 3.21 + + The glslangValidator tool, if found. It is used to compile GLSL and + HLSL shaders into SPIR-V. Result Variables ^^^^^^^^^^^^^^^^ @@ -34,6 +50,7 @@ The module will also define three cache variables:: Vulkan_INCLUDE_DIR - the Vulkan include directory Vulkan_LIBRARY - the path to the Vulkan library Vulkan_GLSLC_EXECUTABLE - the path to the GLSL SPIR-V compiler + Vulkan_GLSLANG_VALIDATOR_EXECUTABLE - the path to the glslangValidator tool Hints ^^^^^ @@ -67,6 +84,11 @@ if(WIN32) HINTS "$ENV{VULKAN_SDK}/Bin" ) + find_program(Vulkan_GLSLANG_VALIDATOR_EXECUTABLE + NAMES glslangValidator + HINTS + "$ENV{VULKAN_SDK}/Bin" + ) elseif(CMAKE_SIZEOF_VOID_P EQUAL 4) find_library(Vulkan_LIBRARY NAMES vulkan-1 @@ -79,6 +101,11 @@ if(WIN32) HINTS "$ENV{VULKAN_SDK}/Bin32" ) + find_program(Vulkan_GLSLANG_VALIDATOR_EXECUTABLE + NAMES glslangValidator + HINTS + "$ENV{VULKAN_SDK}/Bin32" + ) endif() else() find_path(Vulkan_INCLUDE_DIR @@ -90,6 +117,9 @@ else() find_program(Vulkan_GLSLC_EXECUTABLE NAMES glslc HINTS "$ENV{VULKAN_SDK}/bin") + find_program(Vulkan_GLSLANG_VALIDATOR_EXECUTABLE + NAMES glslangValidator + HINTS "$ENV{VULKAN_SDK}/bin") endif() set(Vulkan_LIBRARIES ${Vulkan_LIBRARY}) @@ -100,7 +130,8 @@ find_package_handle_standard_args(Vulkan DEFAULT_MSG Vulkan_LIBRARY Vulkan_INCLUDE_DIR) -mark_as_advanced(Vulkan_INCLUDE_DIR Vulkan_LIBRARY Vulkan_GLSLC_EXECUTABLE) +mark_as_advanced(Vulkan_INCLUDE_DIR Vulkan_LIBRARY Vulkan_GLSLC_EXECUTABLE + Vulkan_GLSLANG_VALIDATOR_EXECUTABLE) if(Vulkan_FOUND AND NOT TARGET Vulkan::Vulkan) add_library(Vulkan::Vulkan UNKNOWN IMPORTED) @@ -109,7 +140,18 @@ if(Vulkan_FOUND AND NOT TARGET Vulkan::Vulkan) INTERFACE_INCLUDE_DIRECTORIES "${Vulkan_INCLUDE_DIRS}") endif() +if(Vulkan_FOUND AND NOT TARGET Vulkan::Headers) + add_library(Vulkan::Headers INTERFACE IMPORTED) + set_target_properties(Vulkan::Headers PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${Vulkan_INCLUDE_DIRS}") +endif() + if(Vulkan_FOUND AND Vulkan_GLSLC_EXECUTABLE AND NOT TARGET Vulkan::glslc) add_executable(Vulkan::glslc IMPORTED) set_property(TARGET Vulkan::glslc PROPERTY IMPORTED_LOCATION "${Vulkan_GLSLC_EXECUTABLE}") endif() + +if(Vulkan_FOUND AND Vulkan_GLSLANG_VALIDATOR_EXECUTABLE AND NOT TARGET Vulkan::glslangValidator) + add_executable(Vulkan::glslangValidator IMPORTED) + set_property(TARGET Vulkan::glslangValidator PROPERTY IMPORTED_LOCATION "${Vulkan_GLSLANG_VALIDATOR_EXECUTABLE}") +endif() diff --git a/Tests/FindVulkan/Test/CMakeLists.txt b/Tests/FindVulkan/Test/CMakeLists.txt index 9d36a0d..7ae8a11 100644 --- a/Tests/FindVulkan/Test/CMakeLists.txt +++ b/Tests/FindVulkan/Test/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.4) -project(TestFindVulkan C) +project(TestFindVulkan C CXX) include(CTest) SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/../../) @@ -14,6 +14,15 @@ target_include_directories(test_var PRIVATE ${Vulkan_INCLUDE_DIRS}) target_link_libraries(test_var PRIVATE ${Vulkan_LIBRARIES}) add_test(NAME test_var COMMAND test_var) +add_executable(test_tgt_dl main-dynamicVulkanLoading.cpp) +target_link_libraries(test_tgt_dl Vulkan::Headers ${CMAKE_DL_LIBS}) +add_test(NAME test_tgt_dl COMMAND test_tgt_dl) + +add_executable(test_var_dl main-dynamicVulkanLoading.cpp) +target_include_directories(test_var_dl PRIVATE ${Vulkan_INCLUDE_DIRS}) +target_link_libraries(test_var_dl ${CMAKE_DL_LIBS}) +add_test(NAME test_var_dl COMMAND test_var_dl) + if(Vulkan_GLSLC_EXECUTABLE) add_test(NAME test_glslc COMMAND ${CMAKE_COMMAND} @@ -22,3 +31,12 @@ if(Vulkan_GLSLC_EXECUTABLE) -P "${CMAKE_CURRENT_LIST_DIR}/Run-glslc.cmake" ) endif() + +if(Vulkan_GLSLANG_VALIDATOR_EXECUTABLE) + add_test(NAME test_glslangValidator + COMMAND ${CMAKE_COMMAND} + "-DVULKAN_GLSLANG_VALIDATOR_EXECUTABLE=${Vulkan_GLSLANG_VALIDATOR_EXECUTABLE}" + "-DVULKAN_GLSLANG_VALIDATOR_EXECUTABLE_TARGET=$" + -P "${CMAKE_CURRENT_LIST_DIR}/Run-glslangValidator.cmake" + ) +endif() diff --git a/Tests/FindVulkan/Test/Run-glslangValidator.cmake b/Tests/FindVulkan/Test/Run-glslangValidator.cmake new file mode 100644 index 0000000..27fd950 --- /dev/null +++ b/Tests/FindVulkan/Test/Run-glslangValidator.cmake @@ -0,0 +1,20 @@ +cmake_minimum_required(VERSION 3.12) + +function(run_glslangValidator exe exe_display) + execute_process(COMMAND ${exe} --help + OUTPUT_VARIABLE output + OUTPUT_STRIP_TRAILING_WHITESPACE + RESULT_VARIABLE result + ) + + if(NOT result EQUAL 1) + message(SEND_ERROR "Result of ${exe_display} --help is ${result}, should be 1") + endif() + + if(NOT output MATCHES "^Usage: glslangValidator") + message(SEND_ERROR "Output of ${exe_display} --help is \"${output}\", should begin with \"Usage: glslangValidator\"") + endif() +endfunction() + +run_glslangValidator("${VULKAN_GLSLANG_VALIDATOR_EXECUTABLE}" "\${VULKAN_GLSLANG_VALIDATOR_EXECUTABLE}") +run_glslangValidator("${VULKAN_GLSLANG_VALIDATOR_EXECUTABLE_TARGET}" "Vulkan::glslangValidator") diff --git a/Tests/FindVulkan/Test/main-dynamicVulkanLoading.cpp b/Tests/FindVulkan/Test/main-dynamicVulkanLoading.cpp new file mode 100644 index 0000000..f6f909f --- /dev/null +++ b/Tests/FindVulkan/Test/main-dynamicVulkanLoading.cpp @@ -0,0 +1,55 @@ +#define VULKAN_HPP_DISPATCH_LOADER_DYNAMIC 1 + +#include + +#include + +using namespace std; + +VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE + +int main() +{ + // catch exceptions + // (vulkan.hpp functions throws if they fail) + try { + + // initialize dynamic dispatcher + vk::DynamicLoader dl; + PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = + dl.getProcAddress("vkGetInstanceProcAddr"); + VULKAN_HPP_DEFAULT_DISPATCHER.init(vkGetInstanceProcAddr); + + // Vulkan instance + vk::UniqueInstance instance = + vk::createInstanceUnique(vk::InstanceCreateInfo{ + vk::InstanceCreateFlags(), // flags + &(const vk::ApplicationInfo&)vk::ApplicationInfo{ + "CMake Test application", // application name + VK_MAKE_VERSION(0, 0, 0), // application version + "CMake Test Engine", // engine name + VK_MAKE_VERSION(0, 0, 0), // engine version + VK_API_VERSION_1_0, // api version + }, + 0, // enabled layer count + nullptr, // enabled layer names + 0, // enabled extension count + nullptr, // enabled extension names + }); + VULKAN_HPP_DEFAULT_DISPATCHER.init(instance.get()); + + // catch exceptions + } catch (vk::Error& e) { + cout << "Failed because of Vulkan exception: " << e.what() << endl; + } catch (exception& e) { + cout << "Failed because of exception: " << e.what() << endl; + } catch (...) { + cout << "Failed because of unspecified exception." << endl; + } + + // We can't assert in this code because in general vk::createInstanceUnique + // might throw if no driver is found - but if we get here, FindVulkan is + // working + + return 0; +} -- cgit v0.12