Forráskód Böngészése

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.).
PCJohn 4 éve
szülő
commit
668ba68a7a

+ 5 - 0
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``.

+ 48 - 6
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()

+ 19 - 1
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=$<TARGET_FILE:Vulkan::glslangValidator>"
+    -P "${CMAKE_CURRENT_LIST_DIR}/Run-glslangValidator.cmake"
+    )
+endif()

+ 20 - 0
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")

+ 55 - 0
Tests/FindVulkan/Test/main-dynamicVulkanLoading.cpp

@@ -0,0 +1,55 @@
+#define VULKAN_HPP_DISPATCH_LOADER_DYNAMIC 1
+
+#include <iostream>
+
+#include <vulkan/vulkan.hpp>
+
+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<PFN_vkGetInstanceProcAddr>("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;
+}