#pragma once /** ****************************************************************************** * Xenia : Xbox 360 Emulator Research Project * ****************************************************************************** * Copyright 2025 Ben Vanik. All rights reserved. * * Released under the BSD license - see LICENSE in the root for more details. * ****************************************************************************** * * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime */ #include #include #include #include #include #include namespace rex { namespace ui { namespace vulkan { class VulkanInstance { public: static std::unique_ptr Create(bool with_surface, bool try_enable_validation); VulkanInstance(const VulkanInstance&) = delete; VulkanInstance& operator=(const VulkanInstance&) = delete; VulkanInstance(VulkanInstance&&) = delete; VulkanInstance& operator=(VulkanInstance&&) = delete; ~VulkanInstance(); // nullptr if RenderDoc is not connected. RenderDocAPI* renderdoc_api() const { return renderdoc_api_.get(); } struct Functions { // From the loader module. PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = nullptr; PFN_vkDestroyInstance vkDestroyInstance = nullptr; // From vkGetInstanceProcAddr for nullptr. PFN_vkCreateInstance vkCreateInstance = nullptr; PFN_vkEnumerateInstanceExtensionProperties vkEnumerateInstanceExtensionProperties = nullptr; PFN_vkEnumerateInstanceLayerProperties vkEnumerateInstanceLayerProperties = nullptr; // Vulkan 1.1. PFN_vkEnumerateInstanceVersion vkEnumerateInstanceVersion = nullptr; // From vkGetInstanceProcAddr for the instance. #define XE_UI_VULKAN_FUNCTION(name) PFN_##name name = nullptr; #define XE_UI_VULKAN_FUNCTION_PROMOTED(extension_name, core_name) \ PFN_##core_name core_name = nullptr; #include // VK_KHR_surface (#1) #include // VK_KHR_xcb_surface (#6) #ifdef VK_USE_PLATFORM_XCB_KHR #include #endif // VK_KHR_android_surface (#9) #ifdef VK_USE_PLATFORM_ANDROID_KHR #include #endif // VK_KHR_win32_surface (#10) #ifdef VK_USE_PLATFORM_WIN32_KHR #include #endif // VK_KHR_get_physical_device_properties2 (#60, promoted to 1.1) #include // VK_EXT_debug_utils (#129) #include #undef XE_UI_VULKAN_FUNCTION_PROMOTED #undef XE_UI_VULKAN_FUNCTION }; const Functions& functions() const { return functions_; } uint32_t api_version() const { return api_version_; } // Also set to true if the version of the Vulkan API they were promoted to it // supported (with the `ext_major_minor_` prefix rather than `ext_`). struct Extensions { bool ext_KHR_surface = false; // #1 #ifdef VK_USE_PLATFORM_XCB_KHR bool ext_KHR_xcb_surface = false; // #6 #endif #ifdef VK_USE_PLATFORM_ANDROID_KHR bool ext_KHR_android_surface = false; // #9 #endif #ifdef VK_USE_PLATFORM_WIN32_KHR bool ext_KHR_win32_surface = false; // #10 #endif bool ext_1_1_KHR_get_physical_device_properties2 = false; // #60 bool ext_EXT_debug_utils = false; // #129 bool ext_KHR_portability_enumeration = false; // #395 }; const Extensions& extensions() const { return extensions_; } VkInstance instance() const { return instance_; } void EnumeratePhysicalDevices(std::vector& physical_devices_out) const; private: explicit VulkanInstance() = default; std::unique_ptr renderdoc_api_; rex::platform::DynamicLibrary loader_; Functions functions_; uint32_t api_version_ = VK_MAKE_API_VERSION(0, 1, 0, 0); Extensions extensions_; VkInstance instance_ = nullptr; static VkBool32 DebugUtilsMessengerCallback( VkDebugUtilsMessageSeverityFlagBitsEXT message_severity, VkDebugUtilsMessageTypeFlagsEXT message_types, const VkDebugUtilsMessengerCallbackDataEXT* callback_data, void* user_data); VkDebugUtilsMessengerEXT debug_utils_messenger_ = VK_NULL_HANDLE; }; } // namespace vulkan } // namespace ui } // namespace rex