mirror of
https://github.com/charles-lunarg/vk-bootstrap.git
synced 2024-11-25 16:24:35 +00:00
Renamed many InstanceBuilder functions, added SystemInfo struct.
SystemInfo will be the way for users to know what is and isn't available on their system. Currently, it only has booleans for if validation layers and debug messenger are available, but more could be added in the future.
This commit is contained in:
parent
6933882f63
commit
a4ab8e099d
@ -16,26 +16,26 @@ option(VK_BOOTSTRAP_TEST "Test Vk-Bootstrap with glfw and Catch2" OFF)
|
|||||||
|
|
||||||
if (VK_BOOTSTRAP_TEST)
|
if (VK_BOOTSTRAP_TEST)
|
||||||
|
|
||||||
set(GLFW_BUILD_TESTS OFF CACHE BOOL "" FORCE)
|
set(GLFW_BUILD_TESTS OFF CACHE BOOL "" FORCE)
|
||||||
set(GLFW_BUILD_DOCS OFF CACHE BOOL "" FORCE)
|
set(GLFW_BUILD_DOCS OFF CACHE BOOL "" FORCE)
|
||||||
set(GLFW_INSTALL OFF CACHE BOOL "" FORCE)
|
set(GLFW_INSTALL OFF CACHE BOOL "" FORCE)
|
||||||
set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
|
set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
|
||||||
add_subdirectory(ext/glfw)
|
add_subdirectory(ext/glfw)
|
||||||
add_subdirectory(ext/Catch2)
|
add_subdirectory(ext/Catch2)
|
||||||
|
|
||||||
add_executable(vk-bootstrap-test tests/run_tests.cpp)
|
add_executable(vk-bootstrap-test tests/run_tests.cpp)
|
||||||
|
|
||||||
target_link_libraries(vk-bootstrap-test vk-bootstrap)
|
target_link_libraries(vk-bootstrap-test vk-bootstrap)
|
||||||
target_link_libraries(vk-bootstrap-test glfw)
|
target_link_libraries(vk-bootstrap-test glfw)
|
||||||
target_link_libraries(vk-bootstrap-test Catch2)
|
target_link_libraries(vk-bootstrap-test Catch2)
|
||||||
|
|
||||||
add_executable(vk-bootstrap-triangle example/triangle.cpp)
|
add_executable(vk-bootstrap-triangle example/triangle.cpp)
|
||||||
target_link_libraries(vk-bootstrap-triangle vk-bootstrap)
|
target_link_libraries(vk-bootstrap-triangle vk-bootstrap)
|
||||||
target_link_libraries(vk-bootstrap-triangle glfw)
|
target_link_libraries(vk-bootstrap-triangle glfw)
|
||||||
|
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
TARGET vk-bootstrap-triangle POST_BUILD
|
TARGET vk-bootstrap-triangle POST_BUILD
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/example/shaders ${CMAKE_CURRENT_BINARY_DIR}
|
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/example/shaders ${CMAKE_CURRENT_BINARY_DIR}
|
||||||
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}
|
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
@ -42,8 +42,7 @@ int device_initialization (Init& init) {
|
|||||||
init.window = create_window_glfw (false);
|
init.window = create_window_glfw (false);
|
||||||
|
|
||||||
vkb::InstanceBuilder instance_builder;
|
vkb::InstanceBuilder instance_builder;
|
||||||
auto instance_ret =
|
auto instance_ret = instance_builder.use_default_debug_messenger ().request_validation_layers ().build ();
|
||||||
instance_builder.set_default_debug_messenger ().check_and_setup_validation_layers ().build ();
|
|
||||||
if (!instance_ret) {
|
if (!instance_ret) {
|
||||||
std::cout << static_cast<uint32_t> (instance_ret.error ().type) << "\n";
|
std::cout << static_cast<uint32_t> (instance_ret.error ().type) << "\n";
|
||||||
}
|
}
|
||||||
|
@ -158,6 +158,31 @@ const char* validation_layer_name = "VK_LAYER_KHRONOS_validation";
|
|||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
|
SystemInfo::SystemInfo () {
|
||||||
|
auto available_extensions =
|
||||||
|
detail::get_vector<VkExtensionProperties> (vkEnumerateInstanceExtensionProperties, nullptr);
|
||||||
|
if (available_extensions.has_value ()) {
|
||||||
|
this->available_extensions = available_extensions.value ();
|
||||||
|
}
|
||||||
|
for (auto& ext : this->available_extensions)
|
||||||
|
if (ext.extensionName == VK_EXT_DEBUG_UTILS_EXTENSION_NAME)
|
||||||
|
debug_messenger_available = true;
|
||||||
|
|
||||||
|
auto available_layers = detail::get_vector<VkLayerProperties> (vkEnumerateInstanceLayerProperties);
|
||||||
|
if (available_layers.has_value ()) {
|
||||||
|
available_layers = available_layers.value ();
|
||||||
|
}
|
||||||
|
for (auto& layer : this->available_layers)
|
||||||
|
if (layer.layerName == detail::validation_layer_name) validation_layers_available = true;
|
||||||
|
}
|
||||||
|
bool SystemInfo::is_extension_available (const char* extension_name) {
|
||||||
|
if (!extension_name) return false;
|
||||||
|
return detail::check_extension_supported (available_extensions, extension_name);
|
||||||
|
}
|
||||||
|
bool SystemInfo::is_layer_available (const char* layer_name) {
|
||||||
|
if (!layer_name) return false;
|
||||||
|
return detail::check_layer_supported (available_layers, layer_name);
|
||||||
|
}
|
||||||
void destroy_instance (Instance instance) {
|
void destroy_instance (Instance instance) {
|
||||||
if (instance.instance != VK_NULL_HANDLE) {
|
if (instance.instance != VK_NULL_HANDLE) {
|
||||||
if (instance.debug_messenger != nullptr)
|
if (instance.debug_messenger != nullptr)
|
||||||
@ -165,17 +190,8 @@ void destroy_instance (Instance instance) {
|
|||||||
vkDestroyInstance (instance.instance, nullptr);
|
vkDestroyInstance (instance.instance, nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
InstanceBuilder::InstanceBuilder () {
|
|
||||||
auto available_extensions =
|
SystemInfo InstanceBuilder::get_system_info () { return system; }
|
||||||
detail::get_vector<VkExtensionProperties> (vkEnumerateInstanceExtensionProperties, nullptr);
|
|
||||||
if (available_extensions.has_value ()) {
|
|
||||||
system.available_extensions = available_extensions.value ();
|
|
||||||
}
|
|
||||||
auto available_layers = detail::get_vector<VkLayerProperties> (vkEnumerateInstanceLayerProperties);
|
|
||||||
if (available_layers.has_value ()) {
|
|
||||||
system.available_layers = available_layers.value ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
detail::Expected<Instance, detail::Error<InstanceError>> InstanceBuilder::build () {
|
detail::Expected<Instance, detail::Error<InstanceError>> InstanceBuilder::build () {
|
||||||
|
|
||||||
@ -317,18 +333,18 @@ InstanceBuilder& InstanceBuilder::must_enable_layer (const char* layer_name) {
|
|||||||
info.layers.push_back (layer_name);
|
info.layers.push_back (layer_name);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
InstanceBuilder& InstanceBuilder::must_enable_extension (const char* extension_name) {
|
InstanceBuilder& InstanceBuilder::request_layer (const char* layer_name) {
|
||||||
if (!extension_name) return *this;
|
|
||||||
info.extensions.push_back (extension_name);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
InstanceBuilder& InstanceBuilder::check_and_add_layer (const char* layer_name) {
|
|
||||||
if (!layer_name) return *this;
|
if (!layer_name) return *this;
|
||||||
if (detail::check_layer_supported (system.available_layers, layer_name))
|
if (detail::check_layer_supported (system.available_layers, layer_name))
|
||||||
info.layers.push_back (layer_name);
|
info.layers.push_back (layer_name);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
InstanceBuilder& InstanceBuilder::check_and_add_extension (const char* extension_name) {
|
InstanceBuilder& InstanceBuilder::must_enable_extension (const char* extension_name) {
|
||||||
|
if (!extension_name) return *this;
|
||||||
|
info.extensions.push_back (extension_name);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
InstanceBuilder& InstanceBuilder::request_extension (const char* extension_name) {
|
||||||
if (!extension_name) return *this;
|
if (!extension_name) return *this;
|
||||||
if (detail::check_extension_supported (system.available_extensions, extension_name))
|
if (detail::check_extension_supported (system.available_extensions, extension_name))
|
||||||
info.extensions.push_back (extension_name);
|
info.extensions.push_back (extension_name);
|
||||||
@ -338,14 +354,14 @@ InstanceBuilder& InstanceBuilder::must_enable_validation_layers (bool enable_val
|
|||||||
info.enable_validation_layers = enable_validation;
|
info.enable_validation_layers = enable_validation;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
InstanceBuilder& InstanceBuilder::check_and_setup_validation_layers (bool enable_validation) {
|
InstanceBuilder& InstanceBuilder::request_validation_layers (bool enable_validation) {
|
||||||
bool available =
|
info.enable_validation_layers =
|
||||||
|
enable_validation &&
|
||||||
detail::check_extension_supported (system.available_extensions, detail::validation_layer_name);
|
detail::check_extension_supported (system.available_extensions, detail::validation_layer_name);
|
||||||
info.enable_validation_layers = available;
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
InstanceBuilder& InstanceBuilder::set_default_debug_messenger () {
|
InstanceBuilder& InstanceBuilder::use_default_debug_messenger () {
|
||||||
info.use_debug_messenger = true;
|
info.use_debug_messenger = true;
|
||||||
info.debug_callback = default_debug_callback;
|
info.debug_callback = default_debug_callback;
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -97,6 +97,20 @@ template <typename E, typename U> class Expected {
|
|||||||
/* TODO implement operator == and operator != as friend or global */
|
/* TODO implement operator == and operator != as friend or global */
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
|
|
||||||
|
struct SystemInfo {
|
||||||
|
SystemInfo ();
|
||||||
|
// Returns true if a layer is available
|
||||||
|
bool is_layer_available (const char* layer_name);
|
||||||
|
// Returns true if an extension is available
|
||||||
|
bool is_extension_available (const char* extension_name);
|
||||||
|
|
||||||
|
std::vector<VkLayerProperties> available_layers;
|
||||||
|
std::vector<VkExtensionProperties> available_extensions;
|
||||||
|
bool validation_layers_available = false;
|
||||||
|
bool debug_messenger_available = false;
|
||||||
|
};
|
||||||
|
|
||||||
enum class InstanceError {
|
enum class InstanceError {
|
||||||
failed_create_instance,
|
failed_create_instance,
|
||||||
failed_create_debug_messenger,
|
failed_create_debug_messenger,
|
||||||
@ -124,8 +138,10 @@ void destroy_instance (Instance instance); // release instance resources
|
|||||||
|
|
||||||
class InstanceBuilder {
|
class InstanceBuilder {
|
||||||
public:
|
public:
|
||||||
InstanceBuilder (); // automatically gets available layers and extensions.
|
// contains useful information about the available vulkan capabilities, like layers and instance extensions.
|
||||||
|
SystemInfo get_system_info ();
|
||||||
|
|
||||||
|
// Create a VkInstance. Return an error if it failed.
|
||||||
detail::Expected<Instance, detail::Error<InstanceError>> build ();
|
detail::Expected<Instance, detail::Error<InstanceError>> build ();
|
||||||
|
|
||||||
// Sets the name of the application. Defaults to "" if none is provided.
|
// Sets the name of the application. Defaults to "" if none is provided.
|
||||||
@ -141,23 +157,25 @@ class InstanceBuilder {
|
|||||||
|
|
||||||
|
|
||||||
// Loads the specified layer if it is available.
|
// Loads the specified layer if it is available.
|
||||||
InstanceBuilder& check_and_add_layer (const char* layer_name);
|
InstanceBuilder& request_layer (const char* layer_name);
|
||||||
// Adds a layer to be enabled. Will fail to create an instance if the layer isn't available.
|
// Adds a layer to be enabled. Will fail to create an instance if the layer isn't available.
|
||||||
InstanceBuilder& must_enable_layer (const char* layer_name);
|
InstanceBuilder& must_enable_layer (const char* layer_name);
|
||||||
|
|
||||||
// Enables the specified extension if it is available.
|
// Enables the specified extension if it is available.
|
||||||
InstanceBuilder& check_and_add_extension (const char* extension_name);
|
InstanceBuilder& request_extension (const char* extension_name);
|
||||||
// Adds an extension to be enabled. Will fail to create an instance if the extension isn't available.
|
// Adds an extension to be enabled. Will fail to create an instance if the extension isn't available.
|
||||||
InstanceBuilder& must_enable_extension (const char* extension_name);
|
InstanceBuilder& must_enable_extension (const char* extension_name);
|
||||||
|
|
||||||
// Headless Mode does not load the required extensions for presentation. Defaults to false.
|
// Headless Mode does not load the required extensions for presentation. Defaults to false.
|
||||||
InstanceBuilder& set_headless (bool headless = false);
|
InstanceBuilder& set_headless (bool headless = false);
|
||||||
// Checks if the validation layers are available and loads them if they are.
|
|
||||||
InstanceBuilder& check_and_setup_validation_layers (bool enable_validation = true);
|
|
||||||
// Enables the validation layers. Will fail to create an instance if the validation layers aren't available.
|
// Enables the validation layers. Will fail to create an instance if the validation layers aren't available.
|
||||||
InstanceBuilder& must_enable_validation_layers (bool enable_validation = true);
|
InstanceBuilder& must_enable_validation_layers (bool require_validation = true);
|
||||||
|
// Checks if the validation layers are available and loads them if they are.
|
||||||
|
InstanceBuilder& request_validation_layers (bool enable_validation = true);
|
||||||
|
|
||||||
// Use a default debug callback that prints to standard out.
|
// Use a default debug callback that prints to standard out.
|
||||||
InstanceBuilder& set_default_debug_messenger ();
|
InstanceBuilder& use_default_debug_messenger ();
|
||||||
// Provide a user defined debug callback.
|
// Provide a user defined debug callback.
|
||||||
InstanceBuilder& set_debug_callback (PFN_vkDebugUtilsMessengerCallbackEXT callback);
|
InstanceBuilder& set_debug_callback (PFN_vkDebugUtilsMessengerCallbackEXT callback);
|
||||||
// Set what message severity is needed to trigger the callback.
|
// Set what message severity is needed to trigger the callback.
|
||||||
@ -216,10 +234,7 @@ class InstanceBuilder {
|
|||||||
bool headless_context = false;
|
bool headless_context = false;
|
||||||
} info;
|
} info;
|
||||||
|
|
||||||
struct SystemInfo {
|
SystemInfo system;
|
||||||
std::vector<VkLayerProperties> available_layers;
|
|
||||||
std::vector<VkExtensionProperties> available_extensions;
|
|
||||||
} system;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const char* to_string_message_severity (VkDebugUtilsMessageSeverityFlagBitsEXT s);
|
const char* to_string_message_severity (VkDebugUtilsMessageSeverityFlagBitsEXT s);
|
||||||
|
@ -6,7 +6,7 @@ int test_happy_path () {
|
|||||||
auto window = create_window_glfw ();
|
auto window = create_window_glfw ();
|
||||||
|
|
||||||
vkb::InstanceBuilder instance_builder;
|
vkb::InstanceBuilder instance_builder;
|
||||||
auto instance_ret = instance_builder.set_default_debug_messenger ().build ();
|
auto instance_ret = instance_builder.use_default_debug_messenger ().build ();
|
||||||
if (!instance_ret) {
|
if (!instance_ret) {
|
||||||
std::cout << static_cast<uint32_t> (instance_ret.error ().type) << "\n";
|
std::cout << static_cast<uint32_t> (instance_ret.error ().type) << "\n";
|
||||||
return -1; // couldn't make instance
|
return -1; // couldn't make instance
|
||||||
@ -44,7 +44,7 @@ int test_instance_basic () {
|
|||||||
vkb::InstanceBuilder builder;
|
vkb::InstanceBuilder builder;
|
||||||
|
|
||||||
auto instance_ret =
|
auto instance_ret =
|
||||||
builder.check_and_setup_validation_layers ()
|
builder.request_validation_layers ()
|
||||||
.set_app_name ("test")
|
.set_app_name ("test")
|
||||||
.set_debug_callback ([] (VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
|
.set_debug_callback ([] (VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
|
||||||
VkDebugUtilsMessageTypeFlagsEXT messageType,
|
VkDebugUtilsMessageTypeFlagsEXT messageType,
|
||||||
@ -71,13 +71,13 @@ int test_instance_headless () {
|
|||||||
vkb::InstanceBuilder builder;
|
vkb::InstanceBuilder builder;
|
||||||
|
|
||||||
auto instance_ret =
|
auto instance_ret =
|
||||||
builder.check_and_setup_validation_layers ()
|
builder.request_validation_layers ()
|
||||||
.set_headless ()
|
.set_headless ()
|
||||||
.set_app_version (4, 5, 6)
|
.set_app_version (4, 5, 6)
|
||||||
.set_app_name ("headless")
|
.set_app_name ("headless")
|
||||||
.set_engine_name ("nick")
|
.set_engine_name ("nick")
|
||||||
.set_api_version (1, 0, 34)
|
.set_api_version (1, 0, 34)
|
||||||
.set_default_debug_messenger ()
|
.use_default_debug_messenger ()
|
||||||
.add_validation_feature_enable (VkValidationFeatureEnableEXT::VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT)
|
.add_validation_feature_enable (VkValidationFeatureEnableEXT::VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT)
|
||||||
.add_validation_feature_disable (VkValidationFeatureDisableEXT::VK_VALIDATION_FEATURE_DISABLE_OBJECT_LIFETIMES_EXT)
|
.add_validation_feature_disable (VkValidationFeatureDisableEXT::VK_VALIDATION_FEATURE_DISABLE_OBJECT_LIFETIMES_EXT)
|
||||||
.add_validation_disable (VkValidationCheckEXT::VK_VALIDATION_CHECK_SHADERS_EXT)
|
.add_validation_disable (VkValidationCheckEXT::VK_VALIDATION_CHECK_SHADERS_EXT)
|
||||||
@ -93,7 +93,7 @@ int test_physical_device_selection () {
|
|||||||
printf ("\nphysical device selection\n");
|
printf ("\nphysical device selection\n");
|
||||||
|
|
||||||
vkb::InstanceBuilder instance_builder;
|
vkb::InstanceBuilder instance_builder;
|
||||||
auto instance_ret = instance_builder.set_default_debug_messenger ().build ();
|
auto instance_ret = instance_builder.use_default_debug_messenger ().build ();
|
||||||
auto instance = instance_ret.value ();
|
auto instance = instance_ret.value ();
|
||||||
auto window = create_window_glfw ();
|
auto window = create_window_glfw ();
|
||||||
auto surface = create_surface_glfw (instance.instance, window);
|
auto surface = create_surface_glfw (instance.instance, window);
|
||||||
@ -117,7 +117,7 @@ int test_physical_device_selection () {
|
|||||||
int test_device_creation () {
|
int test_device_creation () {
|
||||||
printf ("\ndevice creation\n");
|
printf ("\ndevice creation\n");
|
||||||
vkb::InstanceBuilder instance_builder;
|
vkb::InstanceBuilder instance_builder;
|
||||||
auto instance_ret = instance_builder.set_default_debug_messenger ().build ();
|
auto instance_ret = instance_builder.use_default_debug_messenger ().build ();
|
||||||
if (!instance_ret.has_value ()) {
|
if (!instance_ret.has_value ()) {
|
||||||
printf ("couldn't create instance %i\n", static_cast<uint32_t> (instance_ret.error ().type));
|
printf ("couldn't create instance %i\n", static_cast<uint32_t> (instance_ret.error ().type));
|
||||||
return -1;
|
return -1;
|
||||||
|
Loading…
Reference in New Issue
Block a user