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)
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::vk-bootstrap ALIAS vk-bootstrap)
@ -33,10 +47,10 @@ target_include_directories(vk-bootstrap PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
$<INSTALL_INTERFACE:include>)
target_include_directories(vk-bootstrap PUBLIC src)
target_include_directories(vk-bootstrap PUBLIC ${Vulkan_INCLUDE_DIR})
target_link_libraries(vk-bootstrap
PRIVATE
vk-bootstrap-compiler-warnings
vk-boostrap-vulkan-headers
${CMAKE_DL_LIBS})
target_compile_features(vk-bootstrap PUBLIC cxx_std_14)

View File

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

View File

@ -10,10 +10,13 @@ const int MAX_FRAMES_IN_FLIGHT = 2;
struct Init {
GLFWwindow* window;
VulkanLibrary vk_lib;
vkb::Instance instance;
VkSurfaceKHR surface;
vkb::Device device;
vkb::Swapchain swapchain;
//convenience
VulkanLibrary* operator->(){ return &vk_lib; }
};
struct RenderData {
@ -49,6 +52,8 @@ int device_initialization (Init& init) {
}
init.instance = instance_ret.value ();
init.vk_lib.init(init.instance.instance);
init.surface = create_surface_glfw (init.instance.instance, init.window);
vkb::PhysicalDeviceSelector phys_device_selector (init.instance);
@ -66,6 +71,7 @@ int device_initialization (Init& init) {
return -1;
}
init.device = device_ret.value ();
init.vk_lib.init(init.device.device);
return 0;
}
@ -137,7 +143,7 @@ int create_render_pass (Init& init, RenderData& data) {
render_pass_info.dependencyCount = 1;
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";
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 ());
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
}
@ -266,7 +272,7 @@ int create_graphics_pipeline (Init& init, RenderData& data) {
pipeline_layout_info.setLayoutCount = 0;
pipeline_layout_info.pushConstantRangeCount = 0;
if (vkCreatePipelineLayout (
if (init->vkCreatePipelineLayout (
init.device.device, &pipeline_layout_info, nullptr, &data.pipeline_layout) != VK_SUCCESS) {
std::cout << "failed to create pipeline layout\n";
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.basePipelineHandle = VK_NULL_HANDLE;
if (vkCreateGraphicsPipelines (
if (init->vkCreateGraphicsPipelines (
init.device.device, VK_NULL_HANDLE, 1, &pipeline_info, nullptr, &data.graphics_pipeline) != VK_SUCCESS) {
std::cout << "failed to create pipline\n";
return -1; // failed to create graphics pipeline
}
vkDestroyShaderModule (init.device.device, frag_module, nullptr);
vkDestroyShaderModule (init.device.device, vert_module, nullptr);
init->vkDestroyShaderModule (init.device.device, frag_module, nullptr);
init->vkDestroyShaderModule (init.device.device, vert_module, nullptr);
return 0;
}
@ -324,7 +330,7 @@ int create_framebuffers (Init& init, RenderData& data) {
framebuffer_info.height = init.swapchain.extent.height;
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
}
}
@ -336,7 +342,7 @@ int create_command_pool (Init& init, RenderData& data) {
pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
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";
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.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;
}
@ -360,7 +366,7 @@ int create_command_buffers (Init& init, RenderData& data) {
VkCommandBufferBeginInfo 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
}
@ -386,18 +392,18 @@ int create_command_buffers (Init& init, RenderData& data) {
scissor.offset = { 0, 0 };
scissor.extent = init.swapchain.extent;
vkCmdSetViewport (data.command_buffers[i], 0, 1, &viewport);
vkCmdSetScissor (data.command_buffers[i], 0, 1, &scissor);
init->vkCmdSetViewport (data.command_buffers[i], 0, 1, &viewport);
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";
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;
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 ||
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) {
if (init->vkCreateSemaphore (init.device.device, &semaphore_info, nullptr, &data.available_semaphores[i]) != VK_SUCCESS ||
init->vkCreateSemaphore (init.device.device, &semaphore_info, nullptr, &data.finished_semaphore[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";
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) {
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) {
vkDestroyFramebuffer (init.device.device, framebuffer, nullptr);
init->vkDestroyFramebuffer (init.device.device, framebuffer, nullptr);
}
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) {
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;
VkResult result = vkAcquireNextImageKHR (init.device.device,
VkResult result = init->vkAcquireNextImageKHR (init.device.device,
init.swapchain.swapchain,
UINT64_MAX,
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) {
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];
@ -486,9 +492,9 @@ int draw_frame (Init& init, RenderData& data) {
submitInfo.signalSemaphoreCount = 1;
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";
return -1; //"failed to submit draw command buffer
}
@ -505,7 +511,7 @@ int draw_frame (Init& init, RenderData& data) {
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) {
return recreate_swapchain (init, data);
} else if (result != VK_SUCCESS) {
@ -519,26 +525,26 @@ int draw_frame (Init& init, RenderData& data) {
void cleanup (Init& init, RenderData& data) {
for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
vkDestroySemaphore (init.device.device, data.finished_semaphore[i], nullptr);
vkDestroySemaphore (init.device.device, data.available_semaphores[i], nullptr);
vkDestroyFence (init.device.device, data.in_flight_fences[i], nullptr);
init->vkDestroySemaphore (init.device.device, data.finished_semaphore[i], nullptr);
init->vkDestroySemaphore (init.device.device, data.available_semaphores[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) {
vkDestroyFramebuffer (init.device.device, framebuffer, nullptr);
init->vkDestroyFramebuffer (init.device.device, framebuffer, nullptr);
}
vkDestroyPipeline (init.device.device, data.graphics_pipeline, nullptr);
vkDestroyPipelineLayout (init.device.device, data.pipeline_layout, nullptr);
vkDestroyRenderPass (init.device.device, data.render_pass, nullptr);
init->vkDestroyPipeline (init.device.device, data.graphics_pipeline, nullptr);
init->vkDestroyPipelineLayout (init.device.device, data.pipeline_layout, nullptr);
init->vkDestroyRenderPass (init.device.device, data.render_pass, nullptr);
init.swapchain.destroy_image_views (data.swapchain_image_views);
vkb::destroy_swapchain (init.swapchain);
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);
destroy_window_glfw (init.window);
}
@ -565,7 +571,7 @@ int main () {
return -1;
}
}
vkDeviceWaitIdle (init.device.device);
init->vkDeviceWaitIdle (init.device.device);
cleanup (init, render_data);
return 0;

View File

@ -1,17 +1,13 @@
option(GLFW_BUILD_TESTS "" OFF)
option(GLFW_BUILD_DOCS "" OFF)
option(GLFW_INSTALL "" OFF)
option(GLFW_BUILD_EXAMPLES "" OFF)
#add_subdirectory(glfw)
option(CATCH_BUILD_TESTING "" OFF)
option(CATCH_ENABLE_WERROR "" OFF)
option(CATCH_INSTALL_DOCS "" OFF)
option(CATCH_INSTALL_HELPERS "" OFF)
set_property(GLOBAL PROPERTY CTEST_TARGETS_ADDED 1) #remove Catch2 target spam
#add_subdirectory(Catch2)
include(FetchContent)
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
PRIVATE
vk-bootstrap
vk-boostrap-vulkan-headers
vk-bootstrap-compiler-warnings
glfw
Catch2

View File

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

View File

@ -54,7 +54,6 @@ struct VulkanLibrary {
HMODULE library;
#endif
PFN_vkGetInstanceProcAddr ptr_vkGetInstanceProcAddr = VK_NULL_HANDLE;
VulkanLibrary() {
#if defined(__linux__)
@ -70,11 +69,11 @@ struct VulkanLibrary {
#endif
if (!library) return;
#if defined(__linux__) || defined(__APPLE__)
ptr_vkGetInstanceProcAddr =
vkGetInstanceProcAddr =
reinterpret_cast<PFN_vkGetInstanceProcAddr>(dlsym(library, "vkGetInstanceProcAddr"));
#elif defined(_WIN32)
ptr_vkGetInstanceProcAddr = reinterpret_cast<PFN_vkGetInstanceProcAddr> (
GetProcAddress (library, "vkGetInstanceProcAddr"));
vkGetInstanceProcAddr =
reinterpret_cast<PFN_vkGetInstanceProcAddr>(GetProcAddress(library, "vkGetInstanceProcAddr"));
#endif
}
@ -86,4 +85,83 @@ struct VulkanLibrary {
#endif
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;
};