From d34494602cd58cf91c103f2cc9933c6434c5d555 Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Mon, 16 Jun 2025 22:34:21 +0200 Subject: [PATCH] Sligthly rework validation layer logging to tet file --- base/VulkanDebug.cpp | 34 ++++++++++++++----- base/VulkanDebug.h | 2 ++ base/vulkanexamplebase.cpp | 13 +++---- .../computecullandlod/computecullandlod.cpp | 2 +- examples/imgui/main.cpp | 4 +-- examples/textoverlay/textoverlay.cpp | 4 +-- .../texturecubemaparray.cpp | 4 +-- examples/triangle/triangle.cpp | 2 +- .../trianglevulkan13/trianglevulkan13.cpp | 2 +- examples/vulkanscene/vulkanscene.cpp | 6 ++-- 10 files changed, 47 insertions(+), 26 deletions(-) diff --git a/base/VulkanDebug.cpp b/base/VulkanDebug.cpp index 03d04bd5..1d3a78e4 100644 --- a/base/VulkanDebug.cpp +++ b/base/VulkanDebug.cpp @@ -14,6 +14,7 @@ namespace vks namespace debug { bool logToFile{ false }; + std::string logFileName{ "validation_output.txt" }; PFN_vkCreateDebugUtilsMessengerEXT vkCreateDebugUtilsMessengerEXT; PFN_vkDestroyDebugUtilsMessengerEXT vkDestroyDebugUtilsMessengerEXT; @@ -31,25 +32,33 @@ namespace vks if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT) { prefix = "VERBOSE: "; #if defined(_WIN32) - prefix = "\033[32m" + prefix + "\033[0m"; + if (!logToFile) { + prefix = "\033[32m" + prefix + "\033[0m"; + } #endif } else if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT) { prefix = "INFO: "; #if defined(_WIN32) - prefix = "\033[36m" + prefix + "\033[0m"; + if (!logToFile) { + prefix = "\033[36m" + prefix + "\033[0m"; + } #endif } else if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT) { prefix = "WARNING: "; #if defined(_WIN32) - prefix = "\033[33m" + prefix + "\033[0m"; + if (!logToFile) { + prefix = "\033[33m" + prefix + "\033[0m"; + } #endif } else if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) { prefix = "ERROR: "; #if defined(_WIN32) - prefix = "\033[31m" + prefix + "\033[0m"; + if (!logToFile) { + prefix = "\033[31m" + prefix + "\033[0m"; + } #endif } @@ -76,10 +85,7 @@ namespace vks std::cout << debugMessage.str() << "\n\n"; } if (logToFile) { - std::ofstream logfile; - logfile.open("validation.txt", std::ios_base::app); - logfile << debugMessage.str() << std::endl; - logfile.close(); + log(debugMessage.str()); } fflush(stdout); #endif @@ -99,6 +105,18 @@ namespace vks debugUtilsMessengerCI.pfnUserCallback = debugUtilsMessageCallback; } + void log(std::string message) + { + if (logToFile) { + time_t timestamp; + time(×tamp); + std::ofstream logfile; + logfile.open(logFileName, std::ios_base::app); + logfile << strtok(ctime(×tamp), "\n") << ": " << message << std::endl; + logfile.close(); + } + } + void setupDebugging(VkInstance instance) { vkCreateDebugUtilsMessengerEXT = reinterpret_cast(vkGetInstanceProcAddr(instance, "vkCreateDebugUtilsMessengerEXT")); diff --git a/base/VulkanDebug.h b/base/VulkanDebug.h index 59801109..49e877df 100644 --- a/base/VulkanDebug.h +++ b/base/VulkanDebug.h @@ -35,6 +35,7 @@ namespace vks namespace debug { extern bool logToFile; + extern std::string logFileName; // Default debug callback VKAPI_ATTR VkBool32 VKAPI_CALL debugUtilsMessageCallback( @@ -49,6 +50,7 @@ namespace vks void freeDebugCallback(VkInstance instance); // Used to populate a VkDebugUtilsMessengerCreateInfoEXT with our example messenger function and desired flags void setupDebugingMessengerCreateInfo(VkDebugUtilsMessengerCreateInfoEXT& debugUtilsMessengerCI); + void log(std::string message); } // Wrapper for the VK_EXT_debug_utils extension diff --git a/base/vulkanexamplebase.cpp b/base/vulkanexamplebase.cpp index b4ad3a69..5a307847 100644 --- a/base/vulkanexamplebase.cpp +++ b/base/vulkanexamplebase.cpp @@ -802,7 +802,7 @@ VulkanExampleBase::VulkanExampleBase() // Command line arguments commandLineParser.add("help", { "--help" }, 0, "Show help"); commandLineParser.add("validation", { "-v", "--validation" }, 0, "Enable validation layers"); - commandLineParser.add("validationlog", { "-vl", "--validationlog" }, 0, "Log validation messages to a textfile (validation.txt)"); + commandLineParser.add("validationlogfile", { "-vl", "--validationlogfile" }, 0, "Log validation messages to a textfile"); commandLineParser.add("vsync", { "-vs", "--vsync" }, 0, "Enable V-Sync"); commandLineParser.add("fullscreen", { "-f", "--fullscreen" }, 0, "Start in fullscreen mode"); commandLineParser.add("width", { "-w", "--width" }, 1, "Set window width"); @@ -831,12 +831,8 @@ VulkanExampleBase::VulkanExampleBase() if (commandLineParser.isSet("validation")) { settings.validation = true; } - if (commandLineParser.isSet("validationlog")) { + if (commandLineParser.isSet("validationlogfile")) { vks::debug::logToFile = true; - std::ofstream logfile; - logfile.open("validation.txt", std::ios_base::app); - logfile << std::endl << "Sample: " << name << std::endl; - logfile.close(); } if (commandLineParser.isSet("vsync")) { settings.vsync = true; @@ -1034,6 +1030,11 @@ bool VulkanExampleBase::initVulkan() this->settings.validation = true; #endif + // Validation messages can be stored, e.g. to be used in external tools like CI/CD + if (commandLineParser.isSet("validationlogfile")) { + vks::debug::log("Sample: " + title); + } + // Create the instance VkResult result = createInstance(); if (result != VK_SUCCESS) { diff --git a/examples/computecullandlod/computecullandlod.cpp b/examples/computecullandlod/computecullandlod.cpp index adbd5b05..82a829e8 100644 --- a/examples/computecullandlod/computecullandlod.cpp +++ b/examples/computecullandlod/computecullandlod.cpp @@ -87,7 +87,7 @@ public: VulkanExample() : VulkanExampleBase() { - title = "Vulkan Example - Compute cull and lod"; + title = "Compute cull and lod"; camera.type = Camera::CameraType::firstperson; camera.setPerspective(60.0f, (float)width / (float)height, 0.1f, 512.0f); camera.setTranslation(glm::vec3(0.5f, 0.0f, 0.0f)); diff --git a/examples/imgui/main.cpp b/examples/imgui/main.cpp index 2029d708..3b612ad3 100644 --- a/examples/imgui/main.cpp +++ b/examples/imgui/main.cpp @@ -1,7 +1,7 @@ /* * Vulkan Example - imGui (https://github.com/ocornut/imgui) * -* Copyright (C) 2017-2024 by Sascha Willems - www.saschawillems.de +* Copyright (C) 2017-2025 by Sascha Willems - www.saschawillems.de * * This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) */ @@ -567,7 +567,7 @@ public: VulkanExample() : VulkanExampleBase() { - title = "Vulkan Example - ImGui"; + title = "User interfaces with ImGui"; camera.type = Camera::CameraType::lookat; camera.setPosition(glm::vec3(0.0f, 0.0f, -4.8f)); camera.setRotation(glm::vec3(4.5f, -380.0f, 0.0f)); diff --git a/examples/textoverlay/textoverlay.cpp b/examples/textoverlay/textoverlay.cpp index 3c3c91ba..648f3058 100644 --- a/examples/textoverlay/textoverlay.cpp +++ b/examples/textoverlay/textoverlay.cpp @@ -4,7 +4,7 @@ * This sample renders a basic text overlay on top of a 3D scene that can be used e.g. for debug purposes * For a more complete GUI sample see the ImGui sample * -* Copyright (C) 2016-2024 by Sascha Willems - www.saschawillems.de +* Copyright (C) 2016-2025 by Sascha Willems - www.saschawillems.de * * This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) */ @@ -462,7 +462,7 @@ public: VulkanExample() : VulkanExampleBase() { - title = "Vulkan Example - Text overlay"; + title = "Text overlay"; camera.type = Camera::CameraType::lookat; camera.setPosition(glm::vec3(0.0f, 0.0f, -2.5f)); camera.setRotation(glm::vec3(-25.0f, -0.0f, 0.0f)); diff --git a/examples/texturecubemaparray/texturecubemaparray.cpp b/examples/texturecubemaparray/texturecubemaparray.cpp index f5b62885..a8826d09 100644 --- a/examples/texturecubemaparray/texturecubemaparray.cpp +++ b/examples/texturecubemaparray/texturecubemaparray.cpp @@ -4,7 +4,7 @@ * This sample shows how load and render an cubemap array texture. A single image contains multiple cube maps. * The cubemap to be displayed is selected in the fragment shader * -* Copyright (C) 2020-2023 by Sascha Willems - www.saschawillems.de +* Copyright (C) 2020-2025 by Sascha Willems - www.saschawillems.de * * This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) */ @@ -50,7 +50,7 @@ public: VulkanExample() : VulkanExampleBase() { - title = "Cube map textures"; + title = "Cube map texture arrays"; camera.type = Camera::CameraType::lookat; camera.setPosition(glm::vec3(0.0f, 0.0f, -4.0f)); camera.setRotationSpeed(0.25f); diff --git a/examples/triangle/triangle.cpp b/examples/triangle/triangle.cpp index 57f11082..986aaae5 100644 --- a/examples/triangle/triangle.cpp +++ b/examples/triangle/triangle.cpp @@ -116,7 +116,7 @@ public: VulkanExample() : VulkanExampleBase() { - title = "Vulkan Example - Basic indexed triangle"; + title = "Basic indexed triangle"; // To keep things simple, we don't use the UI overlay from the framework settings.overlay = false; // Setup a default look-at camera diff --git a/examples/trianglevulkan13/trianglevulkan13.cpp b/examples/trianglevulkan13/trianglevulkan13.cpp index bc3a4164..66211714 100644 --- a/examples/trianglevulkan13/trianglevulkan13.cpp +++ b/examples/trianglevulkan13/trianglevulkan13.cpp @@ -103,7 +103,7 @@ public: VulkanExample() : VulkanExampleBase() { - title = "Vulkan Example - Basic indexed triangle using Vulkan 1.3"; + title = "Basic indexed triangle using Vulkan 1.3"; // To keep things simple, we don't use the UI overlay from the framework settings.overlay = false; // Setup a default look-at camera diff --git a/examples/vulkanscene/vulkanscene.cpp b/examples/vulkanscene/vulkanscene.cpp index 3ccd822f..a900f3c0 100644 --- a/examples/vulkanscene/vulkanscene.cpp +++ b/examples/vulkanscene/vulkanscene.cpp @@ -1,9 +1,9 @@ /* * Vulkan Demo Scene * -* Don't take this a an example, it's more of a personal playground +* Don't take this a an example, it's more of a playground * -* Copyright (C) 2016-2023 by Sascha Willems - www.saschawillems.de +* Copyright (C) 2016-2025 by Sascha Willems - www.saschawillems.de * * This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) */ @@ -44,7 +44,7 @@ public: VulkanExample() : VulkanExampleBase() { - title = "Vulkan Demo Scene (c) by Sascha Willems"; + title = "Vulkan Demo Scene"; camera.type = Camera::CameraType::lookat; //camera.flipY = true; camera.setPosition(glm::vec3(0.0f, 0.0f, -3.75f));