Revert "rework gpu selection"

This reverts commit d64e0c9b6f.
This commit is contained in:
Samuliak 2024-12-18 19:30:12 +01:00
parent fa004a33c6
commit 770d6cfda7
No known key found for this signature in database
7 changed files with 41 additions and 105 deletions

View file

@ -20,8 +20,6 @@
#include "Cemu/Logging/CemuLogging.h" #include "Cemu/Logging/CemuLogging.h"
#include "Cafe/HW/Latte/Core/FetchShader.h" #include "Cafe/HW/Latte/Core/FetchShader.h"
#include "Cafe/HW/Latte/Core/LatteConst.h" #include "Cafe/HW/Latte/Core/LatteConst.h"
#include "Foundation/NSString.hpp"
#include "Metal/MTLDevice.hpp"
#include "config/CemuConfig.h" #include "config/CemuConfig.h"
#include "gui/guiWrapper.h" #include "gui/guiWrapper.h"
@ -38,53 +36,10 @@ float supportBufferData[512 * 4];
// Defined in the OpenGL renderer // Defined in the OpenGL renderer
void LatteDraw_handleSpecialState8_clearAsDepth(); void LatteDraw_handleSpecialState8_clearAsDepth();
std::vector<std::string> MetalRenderer::GetDevices()
{
auto devices = MTL::CopyAllDevices();
std::vector<std::string> result;
result.reserve(devices->count());
for (uint32 i = 0; i < devices->count(); i++)
{
MTL::Device* device = static_cast<MTL::Device*>(devices->object(i));
result.push_back(std::string(device->name()->utf8String()));
}
return result;
}
MetalRenderer::MetalRenderer() 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<MTL::Device*>(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 // Feature support
m_isAppleGPU = m_device->supportsFamily(MTL::GPUFamilyApple1); m_isAppleGPU = m_device->supportsFamily(MTL::GPUFamilyApple1);
@ -95,9 +50,6 @@ MetalRenderer::MetalRenderer()
CheckForPixelFormatSupport(m_pixelFormatSupport); CheckForPixelFormatSupport(m_pixelFormatSupport);
// Create command queue
m_commandQueue = m_device->newCommandQueue();
// Synchronization resources // Synchronization resources
m_event = m_device->newEvent(); m_event = m_device->newEvent();
@ -571,7 +523,6 @@ void MetalRenderer::DeleteFontTextures()
void MetalRenderer::AppendOverlayDebugInfo() void MetalRenderer::AppendOverlayDebugInfo()
{ {
ImGui::Text("--- GPU info ---"); 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("Is Apple GPU %s", (m_isAppleGPU ? "yes" : "no"));
ImGui::Text("Has unified memory %s", (m_hasUnifiedMemory ? "yes" : "no")); ImGui::Text("Has unified memory %s", (m_hasUnifiedMemory ? "yes" : "no"));
ImGui::Text("Supports Metal3 %s", (m_supportsMetal3 ? "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)) 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); cemuLog_logOnce(LogType::Force, "cannot clear color texture with format {}, because it's not renderable", hostTexture->format);
return; return;
} }

View file

@ -155,8 +155,6 @@ public:
static constexpr uint32 OCCLUSION_QUERY_POOL_SIZE = 1024; static constexpr uint32 OCCLUSION_QUERY_POOL_SIZE = 1024;
static constexpr uint32 TEXTURE_READBACK_SIZE = 32 * 1024 * 1024; // 32 MB static constexpr uint32 TEXTURE_READBACK_SIZE = 32 * 1024 * 1024; // 32 MB
static std::vector<std::string> GetDevices();
MetalRenderer(); MetalRenderer();
~MetalRenderer() override; ~MetalRenderer() override;
@ -461,7 +459,7 @@ private:
MetalPerformanceMonitor m_performanceMonitor; MetalPerformanceMonitor m_performanceMonitor;
// Metal objects // Metal objects
MTL::Device* m_device = nullptr; MTL::Device* m_device;
MTL::CommandQueue* m_commandQueue; MTL::CommandQueue* m_commandQueue;
// Feature support // Feature support

View file

@ -91,7 +91,7 @@ VKAPI_ATTR VkBool32 VKAPI_CALL DebugUtilsCallback(VkDebugUtilsMessageSeverityFla
return VK_FALSE; return VK_FALSE;
} }
std::vector<std::string> VulkanRenderer::GetDevices() std::vector<VulkanRenderer::DeviceInfo> VulkanRenderer::GetDevices()
{ {
if(!vkEnumerateInstanceVersion) if(!vkEnumerateInstanceVersion)
{ {
@ -105,7 +105,7 @@ std::vector<std::string> VulkanRenderer::GetDevices()
apiVersion = VK_API_VERSION_1_1; apiVersion = VK_API_VERSION_1_1;
} }
std::vector<std::string> result; std::vector<DeviceInfo> result;
std::vector<const char*> requiredExtensions; std::vector<const char*> requiredExtensions;
requiredExtensions.clear(); requiredExtensions.clear();
@ -168,7 +168,7 @@ std::vector<std::string> VulkanRenderer::GetDevices()
physDeviceProps.pNext = &physDeviceIDProps; physDeviceProps.pNext = &physDeviceIDProps;
vkGetPhysicalDeviceProperties2(device, &physDeviceProps); vkGetPhysicalDeviceProperties2(device, &physDeviceProps);
result.emplace_back(physDeviceProps.properties.deviceName); result.emplace_back(physDeviceProps.properties.deviceName, physDeviceIDProps.deviceUUID);
} }
} }
vkDestroySurfaceKHR(instance, surface, nullptr); vkDestroySurfaceKHR(instance, surface, nullptr);
@ -181,6 +181,7 @@ std::vector<std::string> VulkanRenderer::GetDevices()
vkDestroyInstance(instance, nullptr); vkDestroyInstance(instance, nullptr);
return result; return result;
} }
void VulkanRenderer::DetermineVendor() void VulkanRenderer::DetermineVendor()
@ -388,7 +389,8 @@ VulkanRenderer::VulkanRenderer()
auto surface = CreateFramebufferSurface(m_instance, gui_getWindowInfo().window_main); auto surface = CreateFramebufferSurface(m_instance, gui_getWindowInfo().window_main);
auto& config = GetConfig(); 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; VkPhysicalDevice fallbackDevice = VK_NULL_HANDLE;
@ -408,7 +410,7 @@ VulkanRenderer::VulkanRenderer()
physDeviceProps.pNext = &physDeviceIDProps; physDeviceProps.pNext = &physDeviceIDProps;
vkGetPhysicalDeviceProperties2(device, &physDeviceProps); 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; 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"); 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; m_physicalDevice = fallbackDevice;
config.graphic_device_name = ""; // resetting device selection config.graphic_device_uuid = {}; // resetting device selection
} }
else if (m_physicalDevice == VK_NULL_HANDLE) else if (m_physicalDevice == VK_NULL_HANDLE)
{ {

View file

@ -156,7 +156,19 @@ public:
sint32 texelCountY; sint32 texelCountY;
}FormatInfoVK; }FormatInfoVK;
static std::vector<std::string> 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<uint8, VK_UUID_SIZE> uuid;
};
static std::vector<DeviceInfo> GetDevices();
VulkanRenderer(); VulkanRenderer();
virtual ~VulkanRenderer(); virtual ~VulkanRenderer();

View file

@ -212,7 +212,7 @@ void CemuConfig::Load(XMLConfigParser& parser)
// graphics // graphics
auto graphic = parser.get("Graphic"); auto graphic = parser.get("Graphic");
graphic_api = graphic.get("api", kOpenGL); graphic_api = graphic.get("api", kOpenGL);
graphic.get("device", graphic_device_name); graphic.get("device", graphic_device_uuid);
vsync = graphic.get("VSync", 0); vsync = graphic.get("VSync", 0);
gx2drawdone_sync = graphic.get("GX2DrawdoneSync", true); gx2drawdone_sync = graphic.get("GX2DrawdoneSync", true);
upscale_filter = graphic.get("UpscaleFilter", kBicubicHermiteFilter); upscale_filter = graphic.get("UpscaleFilter", kBicubicHermiteFilter);
@ -468,7 +468,7 @@ void CemuConfig::Save(XMLConfigParser& parser)
// graphics // graphics
auto graphic = config.set("Graphic"); auto graphic = config.set("Graphic");
graphic.set("api", graphic_api); graphic.set("api", graphic_api);
graphic.set("device", graphic_device_name); graphic.set("device", graphic_device_uuid);
graphic.set("VSync", vsync); graphic.set("VSync", vsync);
graphic.set("GX2DrawdoneSync", gx2drawdone_sync); graphic.set("GX2DrawdoneSync", gx2drawdone_sync);
//graphic.set("PrecompiledShaders", precompiled_shaders.GetValue()); //graphic.set("PrecompiledShaders", precompiled_shaders.GetValue());

View file

@ -462,7 +462,7 @@ struct CemuConfig
// graphics // graphics
ConfigValue<GraphicAPI> graphic_api{ kVulkan }; ConfigValue<GraphicAPI> graphic_api{ kVulkan };
std::string graphic_device_name; std::array<uint8, 16> graphic_device_uuid;
ConfigValue<int> vsync{ 0 }; // 0 = off, 1+ = on depending on render backend ConfigValue<int> vsync{ 0 }; // 0 = off, 1+ = on depending on render backend
ConfigValue<bool> gx2drawdone_sync {true}; ConfigValue<bool> gx2drawdone_sync {true};
ConfigValue<bool> render_upside_down{ false }; ConfigValue<bool> render_upside_down{ false };

View file

@ -1,5 +1,3 @@
#include "Foundation/NSString.hpp"
#include "Metal/MTLDevice.hpp"
#include "gui/wxgui.h" #include "gui/wxgui.h"
#include "gui/GeneralSettings2.h" #include "gui/GeneralSettings2.h"
#include "gui/CemuApp.h" #include "gui/CemuApp.h"
@ -29,9 +27,6 @@
#include "Cafe/HW/Latte/Renderer/Vulkan/VulkanAPI.h" #include "Cafe/HW/Latte/Renderer/Vulkan/VulkanAPI.h"
#include "Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.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 "Cafe/Account/Account.h"
#include <boost/tokenizer.hpp> #include <boost/tokenizer.hpp>
@ -87,15 +82,15 @@ private:
IAudioInputAPI::DeviceDescriptionPtr m_description; IAudioInputAPI::DeviceDescriptionPtr m_description;
}; };
class wxGraphicsDevice : public wxClientData class wxVulkanUUID : public wxClientData
{ {
public: public:
wxGraphicsDevice(const std::string& name) wxVulkanUUID(const VulkanRenderer::DeviceInfo& info)
: m_name(name) {} : m_device_info(info) {}
const std::string& GetName() const { return m_name; } const VulkanRenderer::DeviceInfo& GetDeviceInfo() const { return m_device_info; }
private: private:
std::string m_name; VulkanRenderer::DeviceInfo m_device_info;
}; };
class wxAccountData : public wxClientData class wxAccountData : public wxClientData
@ -1030,14 +1025,14 @@ void GeneralSettings2::StoreConfig()
selection = m_graphic_device->GetSelection(); selection = m_graphic_device->GetSelection();
if(selection != wxNOT_FOUND) if(selection != wxNOT_FOUND)
{ {
const auto* info = (wxGraphicsDevice*)m_graphic_device->GetClientObject(selection); const auto* info = (wxVulkanUUID*)m_graphic_device->GetClientObject(selection);
if(info) if(info)
config.graphic_device_name = info->GetName(); config.graphic_device_uuid = info->GetDeviceInfo().uuid;
else else
config.graphic_device_name = ""; config.graphic_device_uuid = {};
} }
else else
config.graphic_device_name = ""; config.graphic_device_uuid = {};
config.vsync = m_vsync->GetSelection(); config.vsync = m_vsync->GetSelection();
@ -1543,14 +1538,14 @@ void GeneralSettings2::HandleGraphicsApiSelection()
{ {
for(const auto& device : devices) 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); m_graphic_device->SetSelection(0);
const auto& config = GetConfig(); const auto& config = GetConfig();
for(size_t i = 0; i < devices.size(); ++i) 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); m_graphic_device->SetSelection(i);
break; break;
@ -1571,30 +1566,9 @@ void GeneralSettings2::HandleGraphicsApiSelection()
m_vsync->Select(selection); m_vsync->Select(selection);
m_graphic_device->Enable(); // TODO: add an option to select the graphic device
m_graphic_device->Clear(); m_graphic_device->Clear();
m_graphic_device->Disable();
#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
} }
} }