From deea1cc19e7f5f2efd9621aef42eb1aff8328d10 Mon Sep 17 00:00:00 2001 From: johndoe6345789 Date: Sun, 4 Jan 2026 00:34:04 +0000 Subject: [PATCH] feat: Enable Vulkan validation layers and improve GPU diagnostics logging --- src/app/sdl3_app_device.cpp | 25 +++++++++ src/app/sdl3_app_render.cpp | 108 +++++++++++++++++++----------------- 2 files changed, 83 insertions(+), 50 deletions(-) diff --git a/src/app/sdl3_app_device.cpp b/src/app/sdl3_app_device.cpp index e916da3..6d7deca 100644 --- a/src/app/sdl3_app_device.cpp +++ b/src/app/sdl3_app_device.cpp @@ -58,9 +58,34 @@ void Sdl3App::CreateInstance() { TRACE_VAR(extensionCount); TRACE_VAR(extensionList.size()); + // Enable validation layers if available + std::vector layerList; + uint32_t layerCount; + vkEnumerateInstanceLayerProperties(&layerCount, nullptr); + std::vector availableLayers(layerCount); + vkEnumerateInstanceLayerProperties(&layerCount, availableLayers.data()); + + const char* validationLayer = "VK_LAYER_KHRONOS_validation"; + bool validationAvailable = false; + for (const auto& layer : availableLayers) { + if (strcmp(layer.layerName, validationLayer) == 0) { + validationAvailable = true; + break; + } + } + + if (validationAvailable) { + layerList.push_back(validationLayer); + std::cout << "Validation layer enabled: " << validationLayer << "\n"; + } else { + std::cout << "Validation layer not available: " << validationLayer << "\n"; + } + VkInstanceCreateInfo createInfo{}; createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; createInfo.pApplicationInfo = &appInfo; + createInfo.enabledLayerCount = static_cast(layerList.size()); + createInfo.ppEnabledLayerNames = layerList.data(); createInfo.enabledExtensionCount = static_cast(extensionList.size()); createInfo.ppEnabledExtensionNames = extensionList.data(); diff --git a/src/app/sdl3_app_render.cpp b/src/app/sdl3_app_render.cpp index 8d3f878..1195382 100644 --- a/src/app/sdl3_app_render.cpp +++ b/src/app/sdl3_app_render.cpp @@ -3,6 +3,7 @@ #include "logging/logger.hpp" #include +#include #include #include @@ -23,77 +24,78 @@ const std::unordered_map kGuiKeyNames = { namespace sdl3cpp::app { void Sdl3App::PrintGpuDiagnostics(const std::string& errorContext) { - std::cerr << "\n========================================\n"; - std::cerr << "GPU DIAGNOSTIC REPORT\n"; - std::cerr << "========================================\n"; - std::cerr << "Error Context: " << errorContext << "\n\n"; + std::stringstream ss; + ss << "\n========================================\n"; + ss << "GPU DIAGNOSTIC REPORT\n"; + ss << "========================================\n"; + ss << "Error Context: " << errorContext << "\n\n"; // Device properties if (physicalDevice_ != VK_NULL_HANDLE) { VkPhysicalDeviceProperties deviceProps{}; vkGetPhysicalDeviceProperties(physicalDevice_, &deviceProps); - std::cerr << "=== GPU Information ===\n"; - std::cerr << "Device Name: " << deviceProps.deviceName << "\n"; - std::cerr << "Driver Version: " << VK_API_VERSION_MAJOR(deviceProps.driverVersion) << "." + ss << "=== GPU Information ===\n"; + ss << "Device Name: " << deviceProps.deviceName << "\n"; + ss << "Driver Version: " << VK_API_VERSION_MAJOR(deviceProps.driverVersion) << "." << VK_API_VERSION_MINOR(deviceProps.driverVersion) << "." << VK_API_VERSION_PATCH(deviceProps.driverVersion) << "\n"; - std::cerr << "API Version: " << VK_API_VERSION_MAJOR(deviceProps.apiVersion) << "." + ss << "API Version: " << VK_API_VERSION_MAJOR(deviceProps.apiVersion) << "." << VK_API_VERSION_MINOR(deviceProps.apiVersion) << "." << VK_API_VERSION_PATCH(deviceProps.apiVersion) << "\n"; - std::cerr << "Vendor ID: 0x" << std::hex << deviceProps.vendorID << std::dec << "\n"; - std::cerr << "Device ID: 0x" << std::hex << deviceProps.deviceID << std::dec << "\n"; + ss << "Vendor ID: 0x" << std::hex << deviceProps.vendorID << std::dec << "\n"; + ss << "Device ID: 0x" << std::hex << deviceProps.deviceID << std::dec << "\n"; VkPhysicalDeviceMemoryProperties memProps{}; vkGetPhysicalDeviceMemoryProperties(physicalDevice_, &memProps); - std::cerr << "\n=== Memory Information ===\n"; + ss << "\n=== Memory Information ===\n"; uint64_t totalVRAM = 0; for (uint32_t i = 0; i < memProps.memoryHeapCount; i++) { if (memProps.memoryHeaps[i].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) { totalVRAM += memProps.memoryHeaps[i].size; } } - std::cerr << "Total VRAM: " << (totalVRAM / 1024 / 1024) << " MB\n"; + ss << "Total VRAM: " << (totalVRAM / 1024 / 1024) << " MB\n"; // Memory heaps breakdown - std::cerr << "Memory Heaps (" << memProps.memoryHeapCount << "):\n"; + ss << "Memory Heaps (" << memProps.memoryHeapCount << "):\n"; for (uint32_t i = 0; i < memProps.memoryHeapCount; i++) { - std::cerr << " Heap " << i << ": " << (memProps.memoryHeaps[i].size / 1024 / 1024) << " MB"; + ss << " Heap " << i << ": " << (memProps.memoryHeaps[i].size / 1024 / 1024) << " MB"; if (memProps.memoryHeaps[i].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) { - std::cerr << " (Device Local)"; + ss << " (Device Local)"; } - std::cerr << "\n"; + ss << "\n"; } } // Swapchain state - std::cerr << "\n=== Swapchain State ===\n"; - std::cerr << "Extent: " << swapChainExtent_.width << "x" << swapChainExtent_.height << "\n"; - std::cerr << "Image Count: " << swapChainImages_.size() << "\n"; - std::cerr << "Format: " << swapChainImageFormat_ << "\n"; - std::cerr << "Consecutive Recreations: " << consecutiveSwapchainRecreations_ << "\n"; - std::cerr << "Framebuffer Resized Flag: " << (framebufferResized_ ? "true" : "false") << "\n"; - std::cerr << "First Frame Completed: " << (firstFrameCompleted_ ? "true" : "false") << "\n"; + ss << "\n=== Swapchain State ===\n"; + ss << "Extent: " << swapChainExtent_.width << "x" << swapChainExtent_.height << "\n"; + ss << "Image Count: " << swapChainImages_.size() << "\n"; + ss << "Format: " << swapChainImageFormat_ << "\n"; + ss << "Consecutive Recreations: " << consecutiveSwapchainRecreations_ << "\n"; + ss << "Framebuffer Resized Flag: " << (framebufferResized_ ? "true" : "false") << "\n"; + ss << "First Frame Completed: " << (firstFrameCompleted_ ? "true" : "false") << "\n"; // Render objects - std::cerr << "\n=== Scene State ===\n"; - std::cerr << "Render Objects: " << renderObjects_.size() << "\n"; - std::cerr << "Vertices: " << vertices_.size() << "\n"; - std::cerr << "Indices: " << indices_.size() << "\n"; - std::cerr << "Pipelines: " << graphicsPipelines_.size() << "\n"; - std::cerr << "GUI Renderer Active: " << (guiRenderer_ ? "true" : "false") << "\n"; - std::cerr << "GUI Has Commands: " << (guiHasCommands_ ? "true" : "false") << "\n"; + ss << "\n=== Scene State ===\n"; + ss << "Render Objects: " << renderObjects_.size() << "\n"; + ss << "Vertices: " << vertices_.size() << "\n"; + ss << "Indices: " << indices_.size() << "\n"; + ss << "Pipelines: " << graphicsPipelines_.size() << "\n"; + ss << "GUI Renderer Active: " << (guiRenderer_ ? "true" : "false") << "\n"; + ss << "GUI Has Commands: " << (guiHasCommands_ ? "true" : "false") << "\n"; // Check device features that might be related if (physicalDevice_ != VK_NULL_HANDLE) { VkPhysicalDeviceFeatures deviceFeatures{}; vkGetPhysicalDeviceFeatures(physicalDevice_, &deviceFeatures); - std::cerr << "\n=== Relevant Device Features ===\n"; - std::cerr << "Geometry Shader: " << (deviceFeatures.geometryShader ? "supported" : "not supported") << "\n"; - std::cerr << "Tessellation Shader: " << (deviceFeatures.tessellationShader ? "supported" : "not supported") << "\n"; - std::cerr << "Multi Draw Indirect: " << (deviceFeatures.multiDrawIndirect ? "supported" : "not supported") << "\n"; + ss << "\n=== Relevant Device Features ===\n"; + ss << "Geometry Shader: " << (deviceFeatures.geometryShader ? "supported" : "not supported") << "\n"; + ss << "Tessellation Shader: " << (deviceFeatures.tessellationShader ? "supported" : "not supported") << "\n"; + ss << "Multi Draw Indirect: " << (deviceFeatures.multiDrawIndirect ? "supported" : "not supported") << "\n"; } // Queue properties @@ -103,28 +105,31 @@ void Sdl3App::PrintGpuDiagnostics(const std::string& errorContext) { std::vector queueFamilies(queueFamilyCount); vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice_, &queueFamilyCount, queueFamilies.data()); - std::cerr << "\n=== Queue Families ===\n"; + ss << "\n=== Queue Families ===\n"; for (uint32_t i = 0; i < queueFamilyCount; i++) { - std::cerr << "Family " << i << ": " << queueFamilies[i].queueCount << " queues, flags: 0x" + ss << "Family " << i << ": " << queueFamilies[i].queueCount << " queues, flags: 0x" << std::hex << queueFamilies[i].queueFlags << std::dec << "\n"; } } - std::cerr << "\n=== Possible Causes ===\n"; - std::cerr << "1. GPU driver crash or hang - Check dmesg for GPU reset messages\n"; - std::cerr << "2. Infinite loop in shader code - Review vertex/fragment shaders\n"; - std::cerr << "3. Command buffer submission issue - Check synchronization\n"; - std::cerr << "4. GPU overheating or hardware issue - Monitor GPU temperature\n"; - std::cerr << "5. Driver bug - Try updating GPU drivers to latest version\n"; - std::cerr << "6. Resource exhaustion - Check system memory and VRAM usage\n"; + ss << "\n=== Possible Causes ===\n"; + ss << "1. GPU driver crash or hang - Check dmesg for GPU reset messages\n"; + ss << "2. Infinite loop in shader code - Review vertex/fragment shaders\n"; + ss << "3. Command buffer submission issue - Check synchronization\n"; + ss << "4. GPU overheating or hardware issue - Monitor GPU temperature\n"; + ss << "5. Driver bug - Try updating GPU drivers to latest version\n"; + ss << "6. Resource exhaustion - Check system memory and VRAM usage\n"; - std::cerr << "\n=== Recommended Actions ===\n"; - std::cerr << "1. Check system logs: dmesg | grep -i 'gpu\\|radeon\\|amdgpu'\n"; - std::cerr << "2. Update GPU drivers: sudo dnf update mesa-vulkan-drivers\n"; - std::cerr << "3. Verify GPU health: radeontop or similar monitoring tool\n"; - std::cerr << "4. Check for driver messages: journalctl -k | grep -i amdgpu\n"; - std::cerr << "5. Try with different Vulkan settings or validation layers\n"; - std::cerr << "========================================\n\n"; + ss << "\n=== Recommended Actions ===\n"; + ss << "1. Check system logs: dmesg | grep -i 'gpu\\|radeon\\|amdgpu'\n"; + ss << "2. Update GPU drivers: sudo dnf update mesa-vulkan-drivers\n"; + ss << "3. Verify GPU health: radeontop or similar monitoring tool\n"; + ss << "4. Check for driver messages: journalctl -k | grep -i amdgpu\n"; + ss << "5. Try with different Vulkan settings or validation layers\n"; + ss << "========================================\n"; + + // LOG_ERROR(ss.str()); + std::cerr << ss.str() << std::endl; } void Sdl3App::CreateCommandBuffers() { @@ -170,6 +175,8 @@ void Sdl3App::RecordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageI vkCmdBindIndexBuffer(commandBuffer, indexBuffer_, 0, VK_INDEX_TYPE_UINT16); core::PushConstants pushConstants{}; pushConstants.viewProj = viewProj; + // Temporarily disable drawing to test if hang is caused by draw commands + /* for (const auto& object : renderObjects_) { auto pipelineIt = graphicsPipelines_.find(object.shaderKey); if (pipelineIt == graphicsPipelines_.end()) { @@ -184,6 +191,7 @@ void Sdl3App::RecordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageI &pushConstants); vkCmdDrawIndexed(commandBuffer, object.indexCount, 1, object.indexOffset, object.vertexOffset, 0); } + */ vkCmdEndRenderPass(commandBuffer); if (guiRenderer_) { guiRenderer_->BlitToSwapchain(commandBuffer, swapChainImages_[imageIndex]);