aboutsummaryrefslogtreecommitdiff
path: root/src/engine.cpp
diff options
context:
space:
mode:
authorvimene <vincent.menegaux@gmail.com>2025-06-26 01:12:08 +0200
committervimene <vincent.menegaux@gmail.com>2025-06-26 01:12:08 +0200
commit625d18a6053e28762c77efd3dd0d79fc01b0b0ef (patch)
treebd7bd31a40b9d8061c32c9953d78412e2cf90a48 /src/engine.cpp
parentfc8e5fc191822c244f51335e49d44f5a047b128e (diff)
downloadengine-vulkan.tar.gz
added validation layers to vulkanvulkan
Diffstat (limited to 'src/engine.cpp')
-rw-r--r--src/engine.cpp128
1 files changed, 119 insertions, 9 deletions
diff --git a/src/engine.cpp b/src/engine.cpp
index d276d70..da28f75 100644
--- a/src/engine.cpp
+++ b/src/engine.cpp
@@ -292,6 +292,63 @@ static int main_term() {
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
+const std::vector<const char*> validation_layers = {
+ "VK_LAYER_KHRONOS_validation"
+};
+
+#ifdef NDEBUG
+const bool enable_validation_layers = false;
+#else
+const bool enable_validation_layers = true;
+#endif
+
+static bool check_validation_layer_support() {
+ uint32_t layer_count;
+ vkEnumerateInstanceLayerProperties(&layer_count, nullptr);
+
+ std::vector<VkLayerProperties> available_layers(layer_count);
+ vkEnumerateInstanceLayerProperties(&layer_count, available_layers.data());
+
+ for (const char* layer_name : validation_layers) {
+ bool layer_found = false;
+
+ for (const auto& layer_properties : available_layers) {
+ if (strcmp(layer_name, layer_properties.layerName) == 0) {
+ layer_found = true;
+ break;
+ }
+ }
+
+ if (!layer_found) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+static VKAPI_ATTR VkBool32 VKAPI_CALL debug_callback(
+ VkDebugUtilsMessageSeverityFlagBitsEXT message_severity,
+ VkDebugUtilsMessageTypeFlagsEXT message_type,
+ const VkDebugUtilsMessengerCallbackDataEXT* callback_data,
+ void* user_data) {
+ std::cerr << "validation layer: " << callback_data->pMessage << std::endl;
+ return VK_FALSE;
+}
+
+static void populate_msger_create_info(VkDebugUtilsMessengerCreateInfoEXT& msger_create_info) {
+ msger_create_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT;
+ msger_create_info.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT
+ | VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT
+ | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT
+ | VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
+ msger_create_info.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT
+ | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT
+ | VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT;
+ msger_create_info.pfnUserCallback = debug_callback;
+ msger_create_info.pUserData = nullptr;
+}
+
static int main_graphical() {
// init window
glfwInit();
@@ -301,6 +358,11 @@ static int main_graphical() {
// init Vulkan
// init Vulkan - create instance
+ if (enable_validation_layers && !check_validation_layer_support()) {
+ std::cerr << "validation layers requested, but not available!" << std::endl;
+ std::exit(EXIT_FAILURE);
+ }
+
VkApplicationInfo app_info{};
app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
app_info.pApplicationName = "engine - test";
@@ -309,26 +371,52 @@ static int main_graphical() {
app_info.engineVersion = VK_MAKE_VERSION(1, 0, 0);
app_info.apiVersion = VK_API_VERSION_1_0;
- uint32_t glfw_extension_count;
- const char** glfw_extensions;
- glfw_extensions = glfwGetRequiredInstanceExtensions(&glfw_extension_count);
+ std::vector<const char*> extensions;
+
+ {
+ uint32_t glfw_extension_count;
+ const char** glfw_extensions;
+ glfw_extensions = glfwGetRequiredInstanceExtensions(&glfw_extension_count);
+ extensions.insert(extensions.end(), glfw_extensions, glfw_extensions + glfw_extension_count);
+ }
+
+ if (enable_validation_layers) {
+ extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
+ }
uint32_t extension_count;
vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, nullptr);
- std::vector<VkExtensionProperties> extensions(extension_count);
- vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, extensions.data());
+ std::vector<VkExtensionProperties> available_extensions(extension_count);
+ vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, available_extensions.data());
std::cout << "vulkan extensions:\n";
- for (const auto& extension : extensions)
+ for (const auto& extension : available_extensions)
std::cout << " " << extension.extensionName << "\n";
+ std::cout << "\n";
+
+ std::cout << "required extensions:\n";
+ for (const auto& extension_name : extensions)
+ std::cout << " " << extension_name << "\n";
+
VkInstanceCreateInfo create_info{};
create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
create_info.pApplicationInfo = &app_info;
- create_info.enabledExtensionCount = glfw_extension_count;
- create_info.ppEnabledExtensionNames = glfw_extensions;
- create_info.enabledLayerCount = 0;
+ create_info.enabledExtensionCount = static_cast<uint32_t>(extensions.size());
+ create_info.ppEnabledExtensionNames = extensions.data();
+
+ VkDebugUtilsMessengerCreateInfoEXT inst_msger_create_info{};
+ if (enable_validation_layers) {
+ create_info.enabledLayerCount = static_cast<uint32_t>(validation_layers.size());
+ create_info.ppEnabledLayerNames = validation_layers.data();
+
+ populate_msger_create_info(inst_msger_create_info);
+ create_info.pNext = (VkDebugUtilsMessengerCreateInfoEXT*) &inst_msger_create_info;
+ } else {
+ create_info.enabledLayerCount = 0;
+ create_info.pNext = nullptr;
+ }
VkInstance instance;
if (VkResult res = vkCreateInstance(&create_info, nullptr, &instance); res != VK_SUCCESS) {
@@ -336,12 +424,34 @@ static int main_graphical() {
std::exit(EXIT_FAILURE);
}
+ VkDebugUtilsMessengerEXT debug_messenger;
+ if (enable_validation_layers) {
+ VkDebugUtilsMessengerCreateInfoEXT msger_create_info{};
+ populate_msger_create_info(msger_create_info);
+
+ auto create_debug_messenger = (PFN_vkCreateDebugUtilsMessengerEXT) vkGetInstanceProcAddr(instance, "vkCreateDebugUtilsMessengerEXT");
+ if (!create_debug_messenger) {
+ std::cerr << "failed to set up debug messenger!" << std::endl;
+ std::exit(EXIT_FAILURE);
+ }
+ create_debug_messenger(instance, &msger_create_info, nullptr, &debug_messenger);
+ }
+
// main loop
while (!glfwWindowShouldClose(window)) {
glfwPollEvents();
}
// cleanup
+ if (enable_validation_layers) {
+ auto destroy_debug_messenger = (PFN_vkDestroyDebugUtilsMessengerEXT) vkGetInstanceProcAddr(instance, "vkDestroyDebugUtilsMessengerEXT");
+ if (!destroy_debug_messenger) {
+ std::cerr << "failed to destroy debug messenger!" << std::endl;
+ std::exit(EXIT_FAILURE);
+ }
+ destroy_debug_messenger(instance, debug_messenger, nullptr);
+ }
+
vkDestroyInstance(instance, nullptr);
glfwDestroyWindow(window);
glfwTerminate();