diff --git a/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp b/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp index 50c60523..a578948a 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp +++ b/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp @@ -20,8 +20,6 @@ #include "Cemu/Logging/CemuLogging.h" #include "Cafe/HW/Latte/Core/FetchShader.h" #include "Cafe/HW/Latte/Core/LatteConst.h" -#include "Foundation/NSString.hpp" -#include "Metal/MTLDevice.hpp" #include "config/CemuConfig.h" #include "gui/guiWrapper.h" @@ -38,53 +36,10 @@ float supportBufferData[512 * 4]; // Defined in the OpenGL renderer void LatteDraw_handleSpecialState8_clearAsDepth(); -std::vector MetalRenderer::GetDevices() -{ - auto devices = MTL::CopyAllDevices(); - std::vector result; - result.reserve(devices->count()); - for (uint32 i = 0; i < devices->count(); i++) - { - MTL::Device* device = static_cast(devices->object(i)); - result.push_back(std::string(device->name()->utf8String())); - } - - return result; -} - MetalRenderer::MetalRenderer() { - // Pick a device - auto& config = GetConfig(); - const bool hasDeviceSet = !config.graphic_device_name.empty(); - - // If a device is set, try to find it - if (hasDeviceSet) - { - auto devices = MTL::CopyAllDevices(); - for (uint32 i = 0; i < devices->count(); i++) - { - MTL::Device* device = static_cast(devices->object(i)); - std::string name = std::string(device->name()->utf8String()); - if (name == config.graphic_device_name) - { - m_device = device; - break; - } - } - } - - if (!m_device) - { - if (hasDeviceSet) - { - cemuLog_log(LogType::Force, "The selected GPU ({}) could not be found. Using the system default device.", config.graphic_device_name); - config.graphic_device_name = ""; - } - - // Use the system default device - m_device = MTL::CreateSystemDefaultDevice(); - } + m_device = MTL::CreateSystemDefaultDevice(); + m_commandQueue = m_device->newCommandQueue(); // Feature support m_isAppleGPU = m_device->supportsFamily(MTL::GPUFamilyApple1); @@ -95,9 +50,6 @@ MetalRenderer::MetalRenderer() CheckForPixelFormatSupport(m_pixelFormatSupport); - // Create command queue - m_commandQueue = m_device->newCommandQueue(); - // Synchronization resources m_event = m_device->newEvent(); @@ -571,7 +523,6 @@ void MetalRenderer::DeleteFontTextures() void MetalRenderer::AppendOverlayDebugInfo() { ImGui::Text("--- GPU info ---"); - ImGui::Text("GPU name %s", m_device->name()->utf8String()); ImGui::Text("Is Apple GPU %s", (m_isAppleGPU ? "yes" : "no")); ImGui::Text("Has unified memory %s", (m_hasUnifiedMemory ? "yes" : "no")); ImGui::Text("Supports Metal3 %s", (m_supportsMetal3 ? "yes" : "no")); @@ -685,7 +636,6 @@ void MetalRenderer::texture_clearColorSlice(LatteTexture* hostTexture, sint32 sl { if (!FormatIsRenderable(hostTexture->format)) { - // TODO: handle this somehow? cemuLog_logOnce(LogType::Force, "cannot clear color texture with format {}, because it's not renderable", hostTexture->format); return; } diff --git a/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.h b/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.h index cf4fc29f..6a5db69b 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.h +++ b/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.h @@ -155,8 +155,6 @@ public: static constexpr uint32 OCCLUSION_QUERY_POOL_SIZE = 1024; static constexpr uint32 TEXTURE_READBACK_SIZE = 32 * 1024 * 1024; // 32 MB - static std::vector GetDevices(); - MetalRenderer(); ~MetalRenderer() override; @@ -461,7 +459,7 @@ private: MetalPerformanceMonitor m_performanceMonitor; // Metal objects - MTL::Device* m_device = nullptr; + MTL::Device* m_device; MTL::CommandQueue* m_commandQueue; // Feature support diff --git a/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.cpp b/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.cpp index dea66bb4..a28eef4e 100644 --- a/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.cpp +++ b/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.cpp @@ -91,7 +91,7 @@ VKAPI_ATTR VkBool32 VKAPI_CALL DebugUtilsCallback(VkDebugUtilsMessageSeverityFla return VK_FALSE; } -std::vector VulkanRenderer::GetDevices() +std::vector VulkanRenderer::GetDevices() { if(!vkEnumerateInstanceVersion) { @@ -105,7 +105,7 @@ std::vector VulkanRenderer::GetDevices() apiVersion = VK_API_VERSION_1_1; } - std::vector result; + std::vector result; std::vector requiredExtensions; requiredExtensions.clear(); @@ -168,7 +168,7 @@ std::vector VulkanRenderer::GetDevices() physDeviceProps.pNext = &physDeviceIDProps; vkGetPhysicalDeviceProperties2(device, &physDeviceProps); - result.emplace_back(physDeviceProps.properties.deviceName); + result.emplace_back(physDeviceProps.properties.deviceName, physDeviceIDProps.deviceUUID); } } vkDestroySurfaceKHR(instance, surface, nullptr); @@ -181,6 +181,7 @@ std::vector VulkanRenderer::GetDevices() vkDestroyInstance(instance, nullptr); return result; + } void VulkanRenderer::DetermineVendor() @@ -388,7 +389,8 @@ VulkanRenderer::VulkanRenderer() auto surface = CreateFramebufferSurface(m_instance, gui_getWindowInfo().window_main); auto& config = GetConfig(); - const bool has_device_set = !config.graphic_device_name.empty(); + decltype(config.graphic_device_uuid) zero{}; + const bool has_device_set = config.graphic_device_uuid != zero; VkPhysicalDevice fallbackDevice = VK_NULL_HANDLE; @@ -408,7 +410,7 @@ VulkanRenderer::VulkanRenderer() physDeviceProps.pNext = &physDeviceIDProps; vkGetPhysicalDeviceProperties2(device, &physDeviceProps); - if (config.graphic_device_name != physDeviceProps.properties.deviceName) + if (memcmp(config.graphic_device_uuid.data(), physDeviceIDProps.deviceUUID, VK_UUID_SIZE) != 0) continue; } @@ -421,7 +423,7 @@ VulkanRenderer::VulkanRenderer() { cemuLog_log(LogType::Force, "The selected GPU could not be found or is not suitable. Falling back to first available device instead"); m_physicalDevice = fallbackDevice; - config.graphic_device_name = ""; // resetting device selection + config.graphic_device_uuid = {}; // resetting device selection } else if (m_physicalDevice == VK_NULL_HANDLE) { diff --git a/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.h b/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.h index 68309414..867647a3 100644 --- a/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.h +++ b/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.h @@ -156,7 +156,19 @@ public: sint32 texelCountY; }FormatInfoVK; - static std::vector GetDevices(); + struct DeviceInfo + { + DeviceInfo(const std::string name, uint8* uuid) + : name(name) + { + std::copy(uuid, uuid + VK_UUID_SIZE, this->uuid.data()); + } + + std::string name; + std::array uuid; + }; + + static std::vector GetDevices(); VulkanRenderer(); virtual ~VulkanRenderer(); diff --git a/src/config/CemuConfig.cpp b/src/config/CemuConfig.cpp index 701e6be5..0e39656b 100644 --- a/src/config/CemuConfig.cpp +++ b/src/config/CemuConfig.cpp @@ -212,7 +212,7 @@ void CemuConfig::Load(XMLConfigParser& parser) // graphics auto graphic = parser.get("Graphic"); graphic_api = graphic.get("api", kOpenGL); - graphic.get("device", graphic_device_name); + graphic.get("device", graphic_device_uuid); vsync = graphic.get("VSync", 0); gx2drawdone_sync = graphic.get("GX2DrawdoneSync", true); upscale_filter = graphic.get("UpscaleFilter", kBicubicHermiteFilter); @@ -468,7 +468,7 @@ void CemuConfig::Save(XMLConfigParser& parser) // graphics auto graphic = config.set("Graphic"); graphic.set("api", graphic_api); - graphic.set("device", graphic_device_name); + graphic.set("device", graphic_device_uuid); graphic.set("VSync", vsync); graphic.set("GX2DrawdoneSync", gx2drawdone_sync); //graphic.set("PrecompiledShaders", precompiled_shaders.GetValue()); diff --git a/src/config/CemuConfig.h b/src/config/CemuConfig.h index 0dc8cf2b..d1e5e214 100644 --- a/src/config/CemuConfig.h +++ b/src/config/CemuConfig.h @@ -462,7 +462,7 @@ struct CemuConfig // graphics ConfigValue graphic_api{ kVulkan }; - std::string graphic_device_name; + std::array graphic_device_uuid; ConfigValue vsync{ 0 }; // 0 = off, 1+ = on depending on render backend ConfigValue gx2drawdone_sync {true}; ConfigValue render_upside_down{ false }; diff --git a/src/gui/GeneralSettings2.cpp b/src/gui/GeneralSettings2.cpp index 7071c7e8..8b6e0ee1 100644 --- a/src/gui/GeneralSettings2.cpp +++ b/src/gui/GeneralSettings2.cpp @@ -1,5 +1,3 @@ -#include "Foundation/NSString.hpp" -#include "Metal/MTLDevice.hpp" #include "gui/wxgui.h" #include "gui/GeneralSettings2.h" #include "gui/CemuApp.h" @@ -29,9 +27,6 @@ #include "Cafe/HW/Latte/Renderer/Vulkan/VulkanAPI.h" #include "Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.h" -#if ENABLE_METAL -#include "Cafe/HW/Latte/Renderer/Metal/MetalRenderer.h" -#endif #include "Cafe/Account/Account.h" #include @@ -87,15 +82,15 @@ private: IAudioInputAPI::DeviceDescriptionPtr m_description; }; -class wxGraphicsDevice : public wxClientData +class wxVulkanUUID : public wxClientData { public: - wxGraphicsDevice(const std::string& name) - : m_name(name) {} - const std::string& GetName() const { return m_name; } + wxVulkanUUID(const VulkanRenderer::DeviceInfo& info) + : m_device_info(info) {} + const VulkanRenderer::DeviceInfo& GetDeviceInfo() const { return m_device_info; } private: - std::string m_name; + VulkanRenderer::DeviceInfo m_device_info; }; class wxAccountData : public wxClientData @@ -1030,14 +1025,14 @@ void GeneralSettings2::StoreConfig() selection = m_graphic_device->GetSelection(); if(selection != wxNOT_FOUND) { - const auto* info = (wxGraphicsDevice*)m_graphic_device->GetClientObject(selection); + const auto* info = (wxVulkanUUID*)m_graphic_device->GetClientObject(selection); if(info) - config.graphic_device_name = info->GetName(); + config.graphic_device_uuid = info->GetDeviceInfo().uuid; else - config.graphic_device_name = ""; + config.graphic_device_uuid = {}; } else - config.graphic_device_name = ""; + config.graphic_device_uuid = {}; config.vsync = m_vsync->GetSelection(); @@ -1543,14 +1538,14 @@ void GeneralSettings2::HandleGraphicsApiSelection() { for(const auto& device : devices) { - m_graphic_device->Append(device, new wxGraphicsDevice(device)); + m_graphic_device->Append(device.name, new wxVulkanUUID(device)); } m_graphic_device->SetSelection(0); const auto& config = GetConfig(); for(size_t i = 0; i < devices.size(); ++i) { - if(config.graphic_device_name == devices[i]) + if(config.graphic_device_uuid == devices[i].uuid) { m_graphic_device->SetSelection(i); break; @@ -1571,30 +1566,9 @@ void GeneralSettings2::HandleGraphicsApiSelection() m_vsync->Select(selection); - m_graphic_device->Enable(); - m_graphic_device->Clear(); - -#if ENABLE_METAL - auto devices = MetalRenderer::GetDevices(); - if (!devices.empty()) - { - for (const auto& device : devices) - { - m_graphic_device->Append(device, new wxGraphicsDevice(device)); - } - m_graphic_device->SetSelection(0); - - const auto& config = GetConfig(); - for (size_t i = 0; i < devices.size(); ++i) - { - if (config.graphic_device_name == devices[i]) - { - m_graphic_device->SetSelection(i); - break; - } - } - } -#endif + // TODO: add an option to select the graphic device + m_graphic_device->Clear(); + m_graphic_device->Disable(); } }