cmake: Don't require vulkan in order to build

find_package is used to try to find the Vulkan-Headers, and if they aren't
present, it downloads them with fetch content. This way users don't need
vulkan 'installed' on their system, specifically for windows users.

It also changes the tests to load all the necessary function pointers, that
 way we don't need to find the vulkan loader to build the tests.
This commit is contained in:
Charles Giessen 2021-03-01 15:21:45 -07:00 committed by Charles Giessen
parent 15ae056542
commit 0c29d98362
7 changed files with 178 additions and 83 deletions

View File

@ -1,7 +1,21 @@
cmake_minimum_required(VERSION 3.10 FATAL_ERROR) cmake_minimum_required(VERSION 3.10 FATAL_ERROR)
project(VulkanBootstrap) project(VulkanBootstrap)
find_package(Vulkan REQUIRED) add_library(vk-boostrap-vulkan-headers INTERFACE)
find_package(Vulkan QUIET)
if(${Vulkan_INCLUDE_DIR} STREQUAL "Vulkan_INCLUDE_DIR-NOTFOUND")
include(FetchContent)
FetchContent_Declare(
VulkanHeaders
GIT_REPOSITORY https://github.com/KhronosGroup/Vulkan-Headers
GIT_TAG v1.2.171
)
FetchContent_MakeAvailable(VulkanHeaders)
target_link_libraries(vk-boostrap-vulkan-headers INTERFACE Vulkan::Headers)
else()
set_target_properties(vk-boostrap-vulkan-headers PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${Vulkan_INCLUDE_DIR})
endif()
add_library(vk-bootstrap src/VkBootstrap.h src/VkBootstrap.cpp) add_library(vk-bootstrap src/VkBootstrap.h src/VkBootstrap.cpp)
add_library(vk-bootstrap::vk-bootstrap ALIAS vk-bootstrap) add_library(vk-bootstrap::vk-bootstrap ALIAS vk-bootstrap)
@ -33,10 +47,10 @@ target_include_directories(vk-bootstrap PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src> $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
$<INSTALL_INTERFACE:include>) $<INSTALL_INTERFACE:include>)
target_include_directories(vk-bootstrap PUBLIC src) target_include_directories(vk-bootstrap PUBLIC src)
target_include_directories(vk-bootstrap PUBLIC ${Vulkan_INCLUDE_DIR})
target_link_libraries(vk-bootstrap target_link_libraries(vk-bootstrap
PRIVATE PRIVATE
vk-bootstrap-compiler-warnings vk-bootstrap-compiler-warnings
vk-boostrap-vulkan-headers
${CMAKE_DL_LIBS}) ${CMAKE_DL_LIBS})
target_compile_features(vk-bootstrap PUBLIC cxx_std_14) target_compile_features(vk-bootstrap PUBLIC cxx_std_14)

View File

@ -4,7 +4,7 @@ target_link_libraries(vk-bootstrap-triangle
glfw glfw
vk-bootstrap vk-bootstrap
vk-bootstrap-compiler-warnings vk-bootstrap-compiler-warnings
${Vulkan_LIBRARY}) vk-boostrap-vulkan-headers)
add_custom_command( add_custom_command(
TARGET vk-bootstrap-triangle TARGET vk-bootstrap-triangle

View File

@ -10,10 +10,13 @@ const int MAX_FRAMES_IN_FLIGHT = 2;
struct Init { struct Init {
GLFWwindow* window; GLFWwindow* window;
VulkanLibrary vk_lib;
vkb::Instance instance; vkb::Instance instance;
VkSurfaceKHR surface; VkSurfaceKHR surface;
vkb::Device device; vkb::Device device;
vkb::Swapchain swapchain; vkb::Swapchain swapchain;
//convenience
VulkanLibrary* operator->(){ return &vk_lib; }
}; };
struct RenderData { struct RenderData {
@ -49,6 +52,8 @@ int device_initialization (Init& init) {
} }
init.instance = instance_ret.value (); init.instance = instance_ret.value ();
init.vk_lib.init(init.instance.instance);
init.surface = create_surface_glfw (init.instance.instance, init.window); init.surface = create_surface_glfw (init.instance.instance, init.window);
vkb::PhysicalDeviceSelector phys_device_selector (init.instance); vkb::PhysicalDeviceSelector phys_device_selector (init.instance);
@ -66,6 +71,7 @@ int device_initialization (Init& init) {
return -1; return -1;
} }
init.device = device_ret.value (); init.device = device_ret.value ();
init.vk_lib.init(init.device.device);
return 0; return 0;
} }
@ -137,7 +143,7 @@ int create_render_pass (Init& init, RenderData& data) {
render_pass_info.dependencyCount = 1; render_pass_info.dependencyCount = 1;
render_pass_info.pDependencies = &dependency; render_pass_info.pDependencies = &dependency;
if (vkCreateRenderPass (init.device.device, &render_pass_info, nullptr, &data.render_pass) != VK_SUCCESS) { if (init->vkCreateRenderPass (init.device.device, &render_pass_info, nullptr, &data.render_pass) != VK_SUCCESS) {
std::cout << "failed to create render pass\n"; std::cout << "failed to create render pass\n";
return -1; // failed to create render pass! return -1; // failed to create render pass!
} }
@ -169,7 +175,7 @@ VkShaderModule createShaderModule (Init& init, const std::vector<char>& code) {
create_info.pCode = reinterpret_cast<const uint32_t*> (code.data ()); create_info.pCode = reinterpret_cast<const uint32_t*> (code.data ());
VkShaderModule shaderModule; VkShaderModule shaderModule;
if (vkCreateShaderModule (init.device.device, &create_info, nullptr, &shaderModule) != VK_SUCCESS) { if (init->vkCreateShaderModule (init.device.device, &create_info, nullptr, &shaderModule) != VK_SUCCESS) {
return VK_NULL_HANDLE; // failed to create shader module return VK_NULL_HANDLE; // failed to create shader module
} }
@ -266,7 +272,7 @@ int create_graphics_pipeline (Init& init, RenderData& data) {
pipeline_layout_info.setLayoutCount = 0; pipeline_layout_info.setLayoutCount = 0;
pipeline_layout_info.pushConstantRangeCount = 0; pipeline_layout_info.pushConstantRangeCount = 0;
if (vkCreatePipelineLayout ( if (init->vkCreatePipelineLayout (
init.device.device, &pipeline_layout_info, nullptr, &data.pipeline_layout) != VK_SUCCESS) { init.device.device, &pipeline_layout_info, nullptr, &data.pipeline_layout) != VK_SUCCESS) {
std::cout << "failed to create pipeline layout\n"; std::cout << "failed to create pipeline layout\n";
return -1; // failed to create pipeline layout return -1; // failed to create pipeline layout
@ -295,14 +301,14 @@ int create_graphics_pipeline (Init& init, RenderData& data) {
pipeline_info.subpass = 0; pipeline_info.subpass = 0;
pipeline_info.basePipelineHandle = VK_NULL_HANDLE; pipeline_info.basePipelineHandle = VK_NULL_HANDLE;
if (vkCreateGraphicsPipelines ( if (init->vkCreateGraphicsPipelines (
init.device.device, VK_NULL_HANDLE, 1, &pipeline_info, nullptr, &data.graphics_pipeline) != VK_SUCCESS) { init.device.device, VK_NULL_HANDLE, 1, &pipeline_info, nullptr, &data.graphics_pipeline) != VK_SUCCESS) {
std::cout << "failed to create pipline\n"; std::cout << "failed to create pipline\n";
return -1; // failed to create graphics pipeline return -1; // failed to create graphics pipeline
} }
vkDestroyShaderModule (init.device.device, frag_module, nullptr); init->vkDestroyShaderModule (init.device.device, frag_module, nullptr);
vkDestroyShaderModule (init.device.device, vert_module, nullptr); init->vkDestroyShaderModule (init.device.device, vert_module, nullptr);
return 0; return 0;
} }
@ -324,7 +330,7 @@ int create_framebuffers (Init& init, RenderData& data) {
framebuffer_info.height = init.swapchain.extent.height; framebuffer_info.height = init.swapchain.extent.height;
framebuffer_info.layers = 1; framebuffer_info.layers = 1;
if (vkCreateFramebuffer (init.device.device, &framebuffer_info, nullptr, &data.framebuffers[i]) != VK_SUCCESS) { if (init->vkCreateFramebuffer (init.device.device, &framebuffer_info, nullptr, &data.framebuffers[i]) != VK_SUCCESS) {
return -1; // failed to create framebuffer return -1; // failed to create framebuffer
} }
} }
@ -336,7 +342,7 @@ int create_command_pool (Init& init, RenderData& data) {
pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
pool_info.queueFamilyIndex = init.device.get_queue_index (vkb::QueueType::graphics).value (); pool_info.queueFamilyIndex = init.device.get_queue_index (vkb::QueueType::graphics).value ();
if (vkCreateCommandPool (init.device.device, &pool_info, nullptr, &data.command_pool) != VK_SUCCESS) { if (init->vkCreateCommandPool (init.device.device, &pool_info, nullptr, &data.command_pool) != VK_SUCCESS) {
std::cout << "failed to create command pool\n"; std::cout << "failed to create command pool\n";
return -1; // failed to create command pool return -1; // failed to create command pool
} }
@ -352,7 +358,7 @@ int create_command_buffers (Init& init, RenderData& data) {
allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
allocInfo.commandBufferCount = (uint32_t)data.command_buffers.size (); allocInfo.commandBufferCount = (uint32_t)data.command_buffers.size ();
if (vkAllocateCommandBuffers (init.device.device, &allocInfo, data.command_buffers.data ()) != VK_SUCCESS) { if (init->vkAllocateCommandBuffers (init.device.device, &allocInfo, data.command_buffers.data ()) != VK_SUCCESS) {
return -1; // failed to allocate command buffers; return -1; // failed to allocate command buffers;
} }
@ -360,7 +366,7 @@ int create_command_buffers (Init& init, RenderData& data) {
VkCommandBufferBeginInfo begin_info = {}; VkCommandBufferBeginInfo begin_info = {};
begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
if (vkBeginCommandBuffer (data.command_buffers[i], &begin_info) != VK_SUCCESS) { if (init->vkBeginCommandBuffer (data.command_buffers[i], &begin_info) != VK_SUCCESS) {
return -1; // failed to begin recording command buffer return -1; // failed to begin recording command buffer
} }
@ -386,18 +392,18 @@ int create_command_buffers (Init& init, RenderData& data) {
scissor.offset = { 0, 0 }; scissor.offset = { 0, 0 };
scissor.extent = init.swapchain.extent; scissor.extent = init.swapchain.extent;
vkCmdSetViewport (data.command_buffers[i], 0, 1, &viewport); init->vkCmdSetViewport (data.command_buffers[i], 0, 1, &viewport);
vkCmdSetScissor (data.command_buffers[i], 0, 1, &scissor); init->vkCmdSetScissor (data.command_buffers[i], 0, 1, &scissor);
vkCmdBeginRenderPass (data.command_buffers[i], &render_pass_info, VK_SUBPASS_CONTENTS_INLINE); init->vkCmdBeginRenderPass (data.command_buffers[i], &render_pass_info, VK_SUBPASS_CONTENTS_INLINE);
vkCmdBindPipeline (data.command_buffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, data.graphics_pipeline); init->vkCmdBindPipeline (data.command_buffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, data.graphics_pipeline);
vkCmdDraw (data.command_buffers[i], 3, 1, 0, 0); init->vkCmdDraw (data.command_buffers[i], 3, 1, 0, 0);
vkCmdEndRenderPass (data.command_buffers[i]); init->vkCmdEndRenderPass (data.command_buffers[i]);
if (vkEndCommandBuffer (data.command_buffers[i]) != VK_SUCCESS) { if (init->vkEndCommandBuffer (data.command_buffers[i]) != VK_SUCCESS) {
std::cout << "failed to record command buffer\n"; std::cout << "failed to record command buffer\n";
return -1; // failed to record command buffer! return -1; // failed to record command buffer!
} }
@ -419,9 +425,9 @@ int create_sync_objects (Init& init, RenderData& data) {
fence_info.flags = VK_FENCE_CREATE_SIGNALED_BIT; fence_info.flags = VK_FENCE_CREATE_SIGNALED_BIT;
for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) { for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
if (vkCreateSemaphore (init.device.device, &semaphore_info, nullptr, &data.available_semaphores[i]) != VK_SUCCESS || if (init->vkCreateSemaphore (init.device.device, &semaphore_info, nullptr, &data.available_semaphores[i]) != VK_SUCCESS ||
vkCreateSemaphore (init.device.device, &semaphore_info, nullptr, &data.finished_semaphore[i]) != VK_SUCCESS || init->vkCreateSemaphore (init.device.device, &semaphore_info, nullptr, &data.finished_semaphore[i]) != VK_SUCCESS ||
vkCreateFence (init.device.device, &fence_info, nullptr, &data.in_flight_fences[i]) != VK_SUCCESS) { init->vkCreateFence (init.device.device, &fence_info, nullptr, &data.in_flight_fences[i]) != VK_SUCCESS) {
std::cout << "failed to create sync objects\n"; std::cout << "failed to create sync objects\n";
return -1; // failed to create synchronization objects for a frame return -1; // failed to create synchronization objects for a frame
} }
@ -430,12 +436,12 @@ int create_sync_objects (Init& init, RenderData& data) {
} }
int recreate_swapchain (Init& init, RenderData& data) { int recreate_swapchain (Init& init, RenderData& data) {
vkDeviceWaitIdle (init.device.device); init->vkDeviceWaitIdle (init.device.device);
vkDestroyCommandPool (init.device.device, data.command_pool, nullptr); init->vkDestroyCommandPool (init.device.device, data.command_pool, nullptr);
for (auto framebuffer : data.framebuffers) { for (auto framebuffer : data.framebuffers) {
vkDestroyFramebuffer (init.device.device, framebuffer, nullptr); init->vkDestroyFramebuffer (init.device.device, framebuffer, nullptr);
} }
init.swapchain.destroy_image_views (data.swapchain_image_views); init.swapchain.destroy_image_views (data.swapchain_image_views);
@ -448,10 +454,10 @@ int recreate_swapchain (Init& init, RenderData& data) {
} }
int draw_frame (Init& init, RenderData& data) { int draw_frame (Init& init, RenderData& data) {
vkWaitForFences (init.device.device, 1, &data.in_flight_fences[data.current_frame], VK_TRUE, UINT64_MAX); init->vkWaitForFences (init.device.device, 1, &data.in_flight_fences[data.current_frame], VK_TRUE, UINT64_MAX);
uint32_t image_index = 0; uint32_t image_index = 0;
VkResult result = vkAcquireNextImageKHR (init.device.device, VkResult result = init->vkAcquireNextImageKHR (init.device.device,
init.swapchain.swapchain, init.swapchain.swapchain,
UINT64_MAX, UINT64_MAX,
data.available_semaphores[data.current_frame], data.available_semaphores[data.current_frame],
@ -466,7 +472,7 @@ int draw_frame (Init& init, RenderData& data) {
} }
if (data.image_in_flight[image_index] != VK_NULL_HANDLE) { if (data.image_in_flight[image_index] != VK_NULL_HANDLE) {
vkWaitForFences (init.device.device, 1, &data.image_in_flight[image_index], VK_TRUE, UINT64_MAX); init->vkWaitForFences (init.device.device, 1, &data.image_in_flight[image_index], VK_TRUE, UINT64_MAX);
} }
data.image_in_flight[image_index] = data.in_flight_fences[data.current_frame]; data.image_in_flight[image_index] = data.in_flight_fences[data.current_frame];
@ -486,9 +492,9 @@ int draw_frame (Init& init, RenderData& data) {
submitInfo.signalSemaphoreCount = 1; submitInfo.signalSemaphoreCount = 1;
submitInfo.pSignalSemaphores = signal_semaphores; submitInfo.pSignalSemaphores = signal_semaphores;
vkResetFences (init.device.device, 1, &data.in_flight_fences[data.current_frame]); init->vkResetFences (init.device.device, 1, &data.in_flight_fences[data.current_frame]);
if (vkQueueSubmit (data.graphics_queue, 1, &submitInfo, data.in_flight_fences[data.current_frame]) != VK_SUCCESS) { if (init->vkQueueSubmit (data.graphics_queue, 1, &submitInfo, data.in_flight_fences[data.current_frame]) != VK_SUCCESS) {
std::cout << "failed to submit draw command buffer\n"; std::cout << "failed to submit draw command buffer\n";
return -1; //"failed to submit draw command buffer return -1; //"failed to submit draw command buffer
} }
@ -505,7 +511,7 @@ int draw_frame (Init& init, RenderData& data) {
present_info.pImageIndices = &image_index; present_info.pImageIndices = &image_index;
result = vkQueuePresentKHR (data.present_queue, &present_info); result = init->vkQueuePresentKHR (data.present_queue, &present_info);
if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR) { if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR) {
return recreate_swapchain (init, data); return recreate_swapchain (init, data);
} else if (result != VK_SUCCESS) { } else if (result != VK_SUCCESS) {
@ -519,26 +525,26 @@ int draw_frame (Init& init, RenderData& data) {
void cleanup (Init& init, RenderData& data) { void cleanup (Init& init, RenderData& data) {
for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) { for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
vkDestroySemaphore (init.device.device, data.finished_semaphore[i], nullptr); init->vkDestroySemaphore (init.device.device, data.finished_semaphore[i], nullptr);
vkDestroySemaphore (init.device.device, data.available_semaphores[i], nullptr); init->vkDestroySemaphore (init.device.device, data.available_semaphores[i], nullptr);
vkDestroyFence (init.device.device, data.in_flight_fences[i], nullptr); init->vkDestroyFence (init.device.device, data.in_flight_fences[i], nullptr);
} }
vkDestroyCommandPool (init.device.device, data.command_pool, nullptr); init->vkDestroyCommandPool (init.device.device, data.command_pool, nullptr);
for (auto framebuffer : data.framebuffers) { for (auto framebuffer : data.framebuffers) {
vkDestroyFramebuffer (init.device.device, framebuffer, nullptr); init->vkDestroyFramebuffer (init.device.device, framebuffer, nullptr);
} }
vkDestroyPipeline (init.device.device, data.graphics_pipeline, nullptr); init->vkDestroyPipeline (init.device.device, data.graphics_pipeline, nullptr);
vkDestroyPipelineLayout (init.device.device, data.pipeline_layout, nullptr); init->vkDestroyPipelineLayout (init.device.device, data.pipeline_layout, nullptr);
vkDestroyRenderPass (init.device.device, data.render_pass, nullptr); init->vkDestroyRenderPass (init.device.device, data.render_pass, nullptr);
init.swapchain.destroy_image_views (data.swapchain_image_views); init.swapchain.destroy_image_views (data.swapchain_image_views);
vkb::destroy_swapchain (init.swapchain); vkb::destroy_swapchain (init.swapchain);
vkb::destroy_device (init.device); vkb::destroy_device (init.device);
vkDestroySurfaceKHR (init.instance.instance, init.surface, nullptr); init->vkDestroySurfaceKHR (init.instance.instance, init.surface, nullptr);
vkb::destroy_instance (init.instance); vkb::destroy_instance (init.instance);
destroy_window_glfw (init.window); destroy_window_glfw (init.window);
} }
@ -565,7 +571,7 @@ int main () {
return -1; return -1;
} }
} }
vkDeviceWaitIdle (init.device.device); init->vkDeviceWaitIdle (init.device.device);
cleanup (init, render_data); cleanup (init, render_data);
return 0; return 0;

View File

@ -1,17 +1,13 @@
option(GLFW_BUILD_TESTS "" OFF) option(GLFW_BUILD_TESTS "" OFF)
option(GLFW_BUILD_DOCS "" OFF) option(GLFW_BUILD_DOCS "" OFF)
option(GLFW_INSTALL "" OFF) option(GLFW_INSTALL "" OFF)
option(GLFW_BUILD_EXAMPLES "" OFF) option(GLFW_BUILD_EXAMPLES "" OFF)
#add_subdirectory(glfw)
option(CATCH_BUILD_TESTING "" OFF) option(CATCH_BUILD_TESTING "" OFF)
option(CATCH_ENABLE_WERROR "" OFF) option(CATCH_ENABLE_WERROR "" OFF)
option(CATCH_INSTALL_DOCS "" OFF) option(CATCH_INSTALL_DOCS "" OFF)
option(CATCH_INSTALL_HELPERS "" OFF) option(CATCH_INSTALL_HELPERS "" OFF)
set_property(GLOBAL PROPERTY CTEST_TARGETS_ADDED 1) #remove Catch2 target spam set_property(GLOBAL PROPERTY CTEST_TARGETS_ADDED 1) #remove Catch2 target spam
#add_subdirectory(Catch2)
include(FetchContent) include(FetchContent)
FetchContent_Declare( FetchContent_Declare(

View File

@ -2,6 +2,7 @@ add_executable(vk-bootstrap-test main.cpp bootstrap_tests.cpp error_code_tests.c
target_link_libraries(vk-bootstrap-test target_link_libraries(vk-bootstrap-test
PRIVATE PRIVATE
vk-bootstrap vk-bootstrap
vk-boostrap-vulkan-headers
vk-bootstrap-compiler-warnings vk-bootstrap-compiler-warnings
glfw glfw
Catch2 Catch2

View File

@ -357,8 +357,8 @@ TEST_CASE ("SystemInfo Loading Vulkan Automatically", "[VkBootstrap.loading]") {
TEST_CASE ("SystemInfo Loading Vulkan Manually", "[VkBootstrap.loading]") { TEST_CASE ("SystemInfo Loading Vulkan Manually", "[VkBootstrap.loading]") {
VulkanLibrary vk_lib; VulkanLibrary vk_lib;
REQUIRE (vk_lib.ptr_vkGetInstanceProcAddr != NULL); REQUIRE (vk_lib.vkGetInstanceProcAddr != NULL);
auto info_ret = vkb::SystemInfo::get_system_info (vk_lib.ptr_vkGetInstanceProcAddr); auto info_ret = vkb::SystemInfo::get_system_info (vk_lib.vkGetInstanceProcAddr);
REQUIRE (info_ret); REQUIRE (info_ret);
vkb::InstanceBuilder builder; vkb::InstanceBuilder builder;
auto ret = builder.build (); auto ret = builder.build ();
@ -374,8 +374,8 @@ TEST_CASE ("InstanceBuilder Loading Vulkan Automatically", "[VkBootstrap.loading
TEST_CASE ("InstanceBuilder Loading Vulkan Manually", "[VkBootstrap.loading]") { TEST_CASE ("InstanceBuilder Loading Vulkan Manually", "[VkBootstrap.loading]") {
VulkanLibrary vk_lib; VulkanLibrary vk_lib;
REQUIRE (vk_lib.ptr_vkGetInstanceProcAddr != NULL); REQUIRE (vk_lib.vkGetInstanceProcAddr != NULL);
vkb::InstanceBuilder builder{ vk_lib.ptr_vkGetInstanceProcAddr }; vkb::InstanceBuilder builder{ vk_lib.vkGetInstanceProcAddr };
auto ret = builder.build (); auto ret = builder.build ();
vk_lib.close (); vk_lib.close ();
} }
@ -395,16 +395,16 @@ TEST_CASE ("ReLoading Vulkan Automatically", "[VkBootstrap.loading]") {
TEST_CASE ("ReLoading Vulkan Manually", "[VkBootstrap.loading]") { TEST_CASE ("ReLoading Vulkan Manually", "[VkBootstrap.loading]") {
{ {
VulkanLibrary vk_lib; VulkanLibrary vk_lib;
REQUIRE (vk_lib.ptr_vkGetInstanceProcAddr != NULL); REQUIRE (vk_lib.vkGetInstanceProcAddr != NULL);
vkb::InstanceBuilder builder{ vk_lib.ptr_vkGetInstanceProcAddr }; vkb::InstanceBuilder builder{ vk_lib.vkGetInstanceProcAddr };
auto ret = builder.build (); auto ret = builder.build ();
REQUIRE (ret); REQUIRE (ret);
vk_lib.close (); vk_lib.close ();
} }
{ {
VulkanLibrary vk_lib; VulkanLibrary vk_lib;
REQUIRE (vk_lib.ptr_vkGetInstanceProcAddr != NULL); REQUIRE (vk_lib.vkGetInstanceProcAddr != NULL);
vkb::InstanceBuilder builder{ vk_lib.ptr_vkGetInstanceProcAddr }; vkb::InstanceBuilder builder{ vk_lib.vkGetInstanceProcAddr };
auto ret = builder.build (); auto ret = builder.build ();
REQUIRE (ret); REQUIRE (ret);
vk_lib.close (); vk_lib.close ();

View File

@ -54,7 +54,6 @@ struct VulkanLibrary {
HMODULE library; HMODULE library;
#endif #endif
PFN_vkGetInstanceProcAddr ptr_vkGetInstanceProcAddr = VK_NULL_HANDLE;
VulkanLibrary() { VulkanLibrary() {
#if defined(__linux__) #if defined(__linux__)
@ -70,11 +69,11 @@ struct VulkanLibrary {
#endif #endif
if (!library) return; if (!library) return;
#if defined(__linux__) || defined(__APPLE__) #if defined(__linux__) || defined(__APPLE__)
ptr_vkGetInstanceProcAddr = vkGetInstanceProcAddr =
reinterpret_cast<PFN_vkGetInstanceProcAddr>(dlsym(library, "vkGetInstanceProcAddr")); reinterpret_cast<PFN_vkGetInstanceProcAddr>(dlsym(library, "vkGetInstanceProcAddr"));
#elif defined(_WIN32) #elif defined(_WIN32)
ptr_vkGetInstanceProcAddr = reinterpret_cast<PFN_vkGetInstanceProcAddr> ( vkGetInstanceProcAddr =
GetProcAddress (library, "vkGetInstanceProcAddr")); reinterpret_cast<PFN_vkGetInstanceProcAddr>(GetProcAddress(library, "vkGetInstanceProcAddr"));
#endif #endif
} }
@ -86,4 +85,83 @@ struct VulkanLibrary {
#endif #endif
library = 0; library = 0;
} }
void init(VkInstance instance) {
vkGetDeviceProcAddr = (PFN_vkGetDeviceProcAddr)vkGetInstanceProcAddr(instance, "vkGetDeviceProcAddr");
}
void init(VkDevice device) {
vkCreateRenderPass = (PFN_vkCreateRenderPass)vkGetDeviceProcAddr(device, "vkCreateRenderPass");
vkCreateShaderModule = (PFN_vkCreateShaderModule)vkGetDeviceProcAddr(device, "vkCreateShaderModule");
vkCreatePipelineLayout =
(PFN_vkCreatePipelineLayout)vkGetDeviceProcAddr(device, "vkCreatePipelineLayout");
vkCreateGraphicsPipelines =
(PFN_vkCreateGraphicsPipelines)vkGetDeviceProcAddr(device, "vkCreateGraphicsPipelines");
vkDestroyShaderModule = (PFN_vkDestroyShaderModule)vkGetDeviceProcAddr(device, "vkDestroyShaderModule");
vkCreateFramebuffer = (PFN_vkCreateFramebuffer)vkGetDeviceProcAddr(device, "vkCreateFramebuffer");
vkCreateCommandPool = (PFN_vkCreateCommandPool)vkGetDeviceProcAddr(device, "vkCreateCommandPool");
vkAllocateCommandBuffers =
(PFN_vkAllocateCommandBuffers)vkGetDeviceProcAddr(device, "vkAllocateCommandBuffers");
vkBeginCommandBuffer = (PFN_vkBeginCommandBuffer)vkGetDeviceProcAddr(device, "vkBeginCommandBuffer");
vkEndCommandBuffer = (PFN_vkEndCommandBuffer)vkGetDeviceProcAddr(device, "vkEndCommandBuffer");
vkCmdSetViewport = (PFN_vkCmdSetViewport)vkGetDeviceProcAddr(device, "vkCmdSetViewport");
vkCmdSetScissor = (PFN_vkCmdSetScissor)vkGetDeviceProcAddr(device, "vkCmdSetScissor");
vkCmdBeginRenderPass = (PFN_vkCmdBeginRenderPass)vkGetDeviceProcAddr(device, "vkCmdBeginRenderPass");
vkCmdEndRenderPass = (PFN_vkCmdEndRenderPass)vkGetDeviceProcAddr(device, "vkCmdEndRenderPass");
vkCmdBindPipeline = (PFN_vkCmdBindPipeline)vkGetDeviceProcAddr(device, "vkCmdBindPipeline");
vkCmdDraw = (PFN_vkCmdDraw)vkGetDeviceProcAddr(device, "vkCmdDraw");
vkCreateSemaphore = (PFN_vkCreateSemaphore)vkGetDeviceProcAddr(device, "vkCreateSemaphore");
vkCreateFence = (PFN_vkCreateFence)vkGetDeviceProcAddr(device, "vkCreateFence");
vkDeviceWaitIdle = (PFN_vkDeviceWaitIdle)vkGetDeviceProcAddr(device, "vkDeviceWaitIdle");
vkDestroyCommandPool = (PFN_vkDestroyCommandPool)vkGetDeviceProcAddr(device, "vkDestroyCommandPool");
vkDestroyFramebuffer = (PFN_vkDestroyFramebuffer)vkGetDeviceProcAddr(device, "vkDestroyFramebuffer");
vkWaitForFences = (PFN_vkWaitForFences)vkGetDeviceProcAddr(device, "vkWaitForFences");
vkAcquireNextImageKHR = (PFN_vkAcquireNextImageKHR)vkGetDeviceProcAddr(device, "vkAcquireNextImageKHR");
vkResetFences = (PFN_vkResetFences)vkGetDeviceProcAddr(device, "vkResetFences");
vkQueueSubmit = (PFN_vkQueueSubmit)vkGetDeviceProcAddr(device, "vkQueueSubmit");
vkQueuePresentKHR = (PFN_vkQueuePresentKHR)vkGetDeviceProcAddr(device, "vkQueuePresentKHR");
vkDestroySemaphore = (PFN_vkDestroySemaphore)vkGetDeviceProcAddr(device, "vkDestroySemaphore");
vkDestroyFence = (PFN_vkDestroyFence)vkGetDeviceProcAddr(device, "vkDestroyFence");
vkDestroyPipeline = (PFN_vkDestroyPipeline)vkGetDeviceProcAddr(device, "vkDestroyPipeline");
vkDestroyPipelineLayout =
(PFN_vkDestroyPipelineLayout)vkGetDeviceProcAddr(device, "vkDestroyPipelineLayout");
vkDestroySurfaceKHR = (PFN_vkDestroySurfaceKHR)vkGetDeviceProcAddr(device, "vkDestroySurfaceKHR");
vkDestroyRenderPass = (PFN_vkDestroyRenderPass)vkGetDeviceProcAddr(device, "vkDestroyRenderPass");
}
PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = VK_NULL_HANDLE;
PFN_vkGetDeviceProcAddr vkGetDeviceProcAddr = VK_NULL_HANDLE;
PFN_vkCreateRenderPass vkCreateRenderPass = VK_NULL_HANDLE;
PFN_vkCreateShaderModule vkCreateShaderModule = VK_NULL_HANDLE;
PFN_vkCreatePipelineLayout vkCreatePipelineLayout = VK_NULL_HANDLE;
PFN_vkCreateGraphicsPipelines vkCreateGraphicsPipelines = VK_NULL_HANDLE;
PFN_vkDestroyShaderModule vkDestroyShaderModule = VK_NULL_HANDLE;
PFN_vkCreateFramebuffer vkCreateFramebuffer = VK_NULL_HANDLE;
PFN_vkCreateCommandPool vkCreateCommandPool = VK_NULL_HANDLE;
PFN_vkAllocateCommandBuffers vkAllocateCommandBuffers = VK_NULL_HANDLE;
PFN_vkBeginCommandBuffer vkBeginCommandBuffer = VK_NULL_HANDLE;
PFN_vkEndCommandBuffer vkEndCommandBuffer = VK_NULL_HANDLE;
PFN_vkCmdSetViewport vkCmdSetViewport = VK_NULL_HANDLE;
PFN_vkCmdSetScissor vkCmdSetScissor = VK_NULL_HANDLE;
PFN_vkCmdBeginRenderPass vkCmdBeginRenderPass = VK_NULL_HANDLE;
PFN_vkCmdEndRenderPass vkCmdEndRenderPass = VK_NULL_HANDLE;
PFN_vkCmdBindPipeline vkCmdBindPipeline = VK_NULL_HANDLE;
PFN_vkCmdDraw vkCmdDraw = VK_NULL_HANDLE;
PFN_vkCreateSemaphore vkCreateSemaphore = VK_NULL_HANDLE;
PFN_vkCreateFence vkCreateFence = VK_NULL_HANDLE;
PFN_vkDeviceWaitIdle vkDeviceWaitIdle = VK_NULL_HANDLE;
PFN_vkDestroyCommandPool vkDestroyCommandPool = VK_NULL_HANDLE;
PFN_vkDestroyFramebuffer vkDestroyFramebuffer = VK_NULL_HANDLE;
PFN_vkWaitForFences vkWaitForFences = VK_NULL_HANDLE;
PFN_vkAcquireNextImageKHR vkAcquireNextImageKHR = VK_NULL_HANDLE;
PFN_vkResetFences vkResetFences = VK_NULL_HANDLE;
PFN_vkQueueSubmit vkQueueSubmit = VK_NULL_HANDLE;
PFN_vkQueuePresentKHR vkQueuePresentKHR = VK_NULL_HANDLE;
PFN_vkDestroySemaphore vkDestroySemaphore = VK_NULL_HANDLE;
PFN_vkDestroyFence vkDestroyFence = VK_NULL_HANDLE;
PFN_vkDestroyPipeline vkDestroyPipeline = VK_NULL_HANDLE;
PFN_vkDestroyPipelineLayout vkDestroyPipelineLayout = VK_NULL_HANDLE;
PFN_vkDestroySurfaceKHR vkDestroySurfaceKHR = VK_NULL_HANDLE;
PFN_vkDestroyRenderPass vkDestroyRenderPass = VK_NULL_HANDLE;
}; };