// MobileGL - MobileGL/MG_Backend/DirectVulkan/VkIncludes.h // Copyright (c) 2025-2026 MobileGL-Dev // Licensed under the GNU Lesser General Public License v3.0: // https://www.gnu.org/licenses/gpl-3.0.txt // https://www.gnu.org/licenses/lgpl-3.0.txt // SPDX-License-Identifier: LGPL-3.0-only // End of Source File Header #pragma once #include "VulkanRendererConfig.h" #define ENUM_STR_CASE(c) case c: return #c; namespace MobileGL::MG_Backend::DirectVulkan { inline const char* VkResultToString(VkResult result) { switch (result) { ENUM_STR_CASE(VK_SUCCESS) ENUM_STR_CASE(VK_NOT_READY) ENUM_STR_CASE(VK_TIMEOUT) ENUM_STR_CASE(VK_EVENT_SET) ENUM_STR_CASE(VK_EVENT_RESET) ENUM_STR_CASE(VK_INCOMPLETE) ENUM_STR_CASE(VK_ERROR_OUT_OF_HOST_MEMORY) ENUM_STR_CASE(VK_ERROR_OUT_OF_DEVICE_MEMORY) ENUM_STR_CASE(VK_ERROR_INITIALIZATION_FAILED) ENUM_STR_CASE(VK_ERROR_DEVICE_LOST) ENUM_STR_CASE(VK_ERROR_MEMORY_MAP_FAILED) ENUM_STR_CASE(VK_ERROR_LAYER_NOT_PRESENT) ENUM_STR_CASE(VK_ERROR_EXTENSION_NOT_PRESENT) ENUM_STR_CASE(VK_ERROR_FEATURE_NOT_PRESENT) ENUM_STR_CASE(VK_ERROR_INCOMPATIBLE_DRIVER) ENUM_STR_CASE(VK_ERROR_TOO_MANY_OBJECTS) ENUM_STR_CASE(VK_ERROR_FORMAT_NOT_SUPPORTED) ENUM_STR_CASE(VK_ERROR_FRAGMENTED_POOL) ENUM_STR_CASE(VK_ERROR_UNKNOWN) ENUM_STR_CASE(VK_ERROR_OUT_OF_POOL_MEMORY) ENUM_STR_CASE(VK_ERROR_INVALID_EXTERNAL_HANDLE) ENUM_STR_CASE(VK_ERROR_FRAGMENTATION) ENUM_STR_CASE(VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS) ENUM_STR_CASE(VK_PIPELINE_COMPILE_REQUIRED) ENUM_STR_CASE(VK_ERROR_SURFACE_LOST_KHR) ENUM_STR_CASE(VK_ERROR_NATIVE_WINDOW_IN_USE_KHR) ENUM_STR_CASE(VK_SUBOPTIMAL_KHR) ENUM_STR_CASE(VK_ERROR_OUT_OF_DATE_KHR) ENUM_STR_CASE(VK_ERROR_INCOMPATIBLE_DISPLAY_KHR) ENUM_STR_CASE(VK_ERROR_VALIDATION_FAILED_EXT) ENUM_STR_CASE(VK_ERROR_INVALID_SHADER_NV) default: return "VK_RESULT_UNKNOWN"; } } } // namespace MobileGL::MG_Backend::DirectVulkan namespace MobileGL::MG_Backend::DirectVulkan { // GL renders into sRGB color attachments RAW while GL_FRAMEBUFFER_SRGB is disabled // (the core-profile default); Vulkan sRGB attachments always encode on write. The // attachment view (and render pass format) therefore drops to the UNORM twin // whenever the capability is off. Sampled views keep the sRGB format (decode on // sample is unconditional in GL). inline VkFormat ResolveSrgbAttachmentWriteFormat(VkFormat format, bool framebufferSrgbEnabled) { if (framebufferSrgbEnabled) return format; switch (format) { case VK_FORMAT_R8G8B8A8_SRGB: return VK_FORMAT_R8G8B8A8_UNORM; case VK_FORMAT_B8G8R8A8_SRGB: return VK_FORMAT_B8G8R8A8_UNORM; default: return format; } } } // namespace MobileGL::MG_Backend::DirectVulkan // The context line (__VA_ARGS__ = its own format string + args) must be a SEPARATE log // call: appending its format to the base format while its arguments precede the base // arguments makes every conversion read the wrong slot (a %s pulling an int crashes). // // MGLOG_F and deliberately NOT latched. VK_VERIFY is the invariant-check macro: a Vulkan call // MobileGL believes it has already made legal came back non-success, which is a // should-never-happen state, not an expected failure mode a user hits. Those fast-fail loudly // and keep saying so - the log-quietness rules that latch W/E cover expected failures (driver // capability gaps, app misuse), not broken internal invariants. MOBILEGL_ASSERT below traps in // a DEBUG build; MGLOG_F is what makes the same condition visible in an INFO test run, where // the assert is compiled out by contract. // // A soft, recoverable failure must therefore NOT be routed through VK_VERIFY. Check the // VkResult directly and report it with MGLOG_E_ONCE - see VkTextureManager::SyncTextureResource, // where a driver legitimately refuses an image the format pre-check accepted. #define VK_VERIFY(expr, ...) \ do { \ VkResult _vk_verify_result = (expr); \ if (_vk_verify_result != VK_SUCCESS) { \ __VA_OPT__(MGLOG_F(__VA_ARGS__);) \ MGLOG_F("Vulkan error %s (%d) at %s:%d", \ MobileGL::MG_Backend::DirectVulkan::VkResultToString(_vk_verify_result), \ _vk_verify_result, __FILE__, __LINE__); \ } \ MOBILEGL_ASSERT(_vk_verify_result == VK_SUCCESS, "Vulkan error %s (%d) at %s:%d", \ MobileGL::MG_Backend::DirectVulkan::VkResultToString(_vk_verify_result), \ _vk_verify_result, __FILE__, __LINE__); \ } while (0) #define XXHASH_VERIFY(expr, ...) \ do { \ XXH_errorcode _xxh_verify_result = (expr); \ if (_xxh_verify_result != XXH_OK) { \ __VA_OPT__(MGLOG_F(__VA_ARGS__);) \ } \ MOBILEGL_ASSERT(_xxh_verify_result == XXH_OK, "XXHash error %d at %s:%d", _xxh_verify_result, __FILE__, \ __LINE__); \ } while (0)