diff --git a/.gitignore b/.gitignore index 3ac37b5..2b93107 100644 --- a/.gitignore +++ b/.gitignore @@ -54,3 +54,4 @@ __pycache__/ *.pyc *.pyo *.pyd +sdl3_app.log diff --git a/AGENTS.md b/AGENTS.md index e826661..02fef95 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -10,3 +10,5 @@ - Prefer `constexpr`, `inline`, and scoped enums over macros. - Keep APIs explicit and predictable; avoid implicit conversions. +## Logging +- When fixing a bug, add trace logging in the affected area to improve diagnostics. diff --git a/src/services/impl/vulkan_device_service.cpp b/src/services/impl/vulkan_device_service.cpp index a4b21a9..99644f7 100644 --- a/src/services/impl/vulkan_device_service.cpp +++ b/src/services/impl/vulkan_device_service.cpp @@ -31,6 +31,7 @@ void VulkanDeviceService::Initialize(const std::vector& deviceExten deviceExtensions_ = deviceExtensions; validationLayersEnabled_ = enableValidationLayers; + physicalDevice_ = VK_NULL_HANDLE; // Get required extensions from SDL uint32_t extensionCount = 0; @@ -42,7 +43,9 @@ void VulkanDeviceService::Initialize(const std::vector& deviceExten std::vector requiredExtensions(extensions, extensions + extensionCount); CreateInstance(requiredExtensions); - PickPhysicalDevice(); + logger_->Trace("VulkanDeviceService", "Initialize", + "instanceCreated=" + std::string(instance_ != VK_NULL_HANDLE ? "true" : "false") + + ", selectionDeferredUntilSurface=true"); } void VulkanDeviceService::CreateSurface(SDL_Window* window) { @@ -56,6 +59,8 @@ void VulkanDeviceService::CreateSurface(SDL_Window* window) { if (!SDL_Vulkan_CreateSurface(window, instance_, nullptr, &surface_)) { throw std::runtime_error("Failed to create Vulkan surface"); } + logger_->Trace("VulkanDeviceService", "CreateSurface", + "surfaceCreated=" + std::string(surface_ != VK_NULL_HANDLE ? "true" : "false")); } void VulkanDeviceService::CreateInstance(const std::vector& requiredExtensions) { @@ -159,6 +164,9 @@ void VulkanDeviceService::PickPhysicalDevice() { bool VulkanDeviceService::IsDeviceSuitable(VkPhysicalDevice device) const { logger_->Trace("VulkanDeviceService", "IsDeviceSuitable", "deviceIsNull=" + std::string(device == VK_NULL_HANDLE ? "true" : "false")); + if (surface_ == VK_NULL_HANDLE) { + throw std::runtime_error("Vulkan surface must be created before checking device suitability"); + } QueueFamilyIndices indices = FindQueueFamilies(device); bool extensionsSupported = CheckDeviceExtensionSupport(device); @@ -183,6 +191,9 @@ bool VulkanDeviceService::IsDeviceSuitable(VkPhysicalDevice device) const { QueueFamilyIndices VulkanDeviceService::FindQueueFamilies(VkPhysicalDevice device) const { logger_->Trace("VulkanDeviceService", "FindQueueFamilies", "deviceIsNull=" + std::string(device == VK_NULL_HANDLE ? "true" : "false")); + if (surface_ == VK_NULL_HANDLE) { + throw std::runtime_error("Vulkan surface must be created before querying queue families"); + } QueueFamilyIndices indices; uint32_t queueFamilyCount = 0; @@ -231,6 +242,18 @@ bool VulkanDeviceService::CheckDeviceExtensionSupport(VkPhysicalDevice device) c void VulkanDeviceService::CreateLogicalDevice() { logger_->Trace("VulkanDeviceService", "CreateLogicalDevice"); + if (surface_ == VK_NULL_HANDLE) { + logger_->Trace("VulkanDeviceService", "CreateLogicalDevice", "surfaceIsNull=true"); + throw std::runtime_error("Vulkan surface must be created before creating the logical device"); + } + + if (physicalDevice_ == VK_NULL_HANDLE) { + logger_->Trace("VulkanDeviceService", "CreateLogicalDevice", "physicalDeviceSelected=false"); + PickPhysicalDevice(); + } + logger_->Trace("VulkanDeviceService", "CreateLogicalDevice", + "physicalDeviceSelected=" + std::string(physicalDevice_ != VK_NULL_HANDLE ? "true" : "false")); + QueueFamilyIndices indices = FindQueueFamilies(physicalDevice_); std::vector queueCreateInfos; diff --git a/src/services/interfaces/i_vulkan_device_service.hpp b/src/services/interfaces/i_vulkan_device_service.hpp index 647b25e..c1b83ef 100644 --- a/src/services/interfaces/i_vulkan_device_service.hpp +++ b/src/services/interfaces/i_vulkan_device_service.hpp @@ -33,7 +33,7 @@ public: virtual ~IVulkanDeviceService() = default; /** - * @brief Initialize Vulkan instance and select physical device. + * @brief Initialize Vulkan instance and store required extensions. * * @param deviceExtensions Required device extensions * @param enableValidationLayers Whether to enable validation layers @@ -55,7 +55,7 @@ public: /** * @brief Create the logical device and retrieve queues. * - * Must be called after Initialize(). + * Must be called after CreateSurface(). This selects the physical device. * * @throws std::runtime_error if device creation fails */