mirror of
https://github.com/cemu-project/Cemu.git
synced 2026-01-01 07:37:06 +00:00
rework gpu selection
This commit is contained in:
parent
ba9a9370fe
commit
d64e0c9b6f
7 changed files with 105 additions and 41 deletions
|
|
@ -20,6 +20,8 @@
|
|||
#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"
|
||||
|
||||
|
|
@ -36,10 +38,53 @@ float supportBufferData[512 * 4];
|
|||
// Defined in the OpenGL renderer
|
||||
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()
|
||||
{
|
||||
m_device = MTL::CreateSystemDefaultDevice();
|
||||
m_commandQueue = m_device->newCommandQueue();
|
||||
// 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();
|
||||
}
|
||||
|
||||
// Feature support
|
||||
m_isAppleGPU = m_device->supportsFamily(MTL::GPUFamilyApple1);
|
||||
|
|
@ -50,6 +95,9 @@ MetalRenderer::MetalRenderer()
|
|||
|
||||
CheckForPixelFormatSupport(m_pixelFormatSupport);
|
||||
|
||||
// Create command queue
|
||||
m_commandQueue = m_device->newCommandQueue();
|
||||
|
||||
// Synchronization resources
|
||||
m_event = m_device->newEvent();
|
||||
|
||||
|
|
@ -523,6 +571,7 @@ 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"));
|
||||
|
|
@ -636,6 +685,7 @@ 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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -155,6 +155,8 @@ public:
|
|||
static constexpr uint32 OCCLUSION_QUERY_POOL_SIZE = 1024;
|
||||
static constexpr uint32 TEXTURE_READBACK_SIZE = 32 * 1024 * 1024; // 32 MB
|
||||
|
||||
static std::vector<std::string> GetDevices();
|
||||
|
||||
MetalRenderer();
|
||||
~MetalRenderer() override;
|
||||
|
||||
|
|
@ -459,7 +461,7 @@ private:
|
|||
MetalPerformanceMonitor m_performanceMonitor;
|
||||
|
||||
// Metal objects
|
||||
MTL::Device* m_device;
|
||||
MTL::Device* m_device = nullptr;
|
||||
MTL::CommandQueue* m_commandQueue;
|
||||
|
||||
// Feature support
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ VKAPI_ATTR VkBool32 VKAPI_CALL DebugUtilsCallback(VkDebugUtilsMessageSeverityFla
|
|||
return VK_FALSE;
|
||||
}
|
||||
|
||||
std::vector<VulkanRenderer::DeviceInfo> VulkanRenderer::GetDevices()
|
||||
std::vector<std::string> VulkanRenderer::GetDevices()
|
||||
{
|
||||
if(!vkEnumerateInstanceVersion)
|
||||
{
|
||||
|
|
@ -105,7 +105,7 @@ std::vector<VulkanRenderer::DeviceInfo> VulkanRenderer::GetDevices()
|
|||
apiVersion = VK_API_VERSION_1_1;
|
||||
}
|
||||
|
||||
std::vector<DeviceInfo> result;
|
||||
std::vector<std::string> result;
|
||||
|
||||
std::vector<const char*> requiredExtensions;
|
||||
requiredExtensions.clear();
|
||||
|
|
@ -168,7 +168,7 @@ std::vector<VulkanRenderer::DeviceInfo> VulkanRenderer::GetDevices()
|
|||
physDeviceProps.pNext = &physDeviceIDProps;
|
||||
vkGetPhysicalDeviceProperties2(device, &physDeviceProps);
|
||||
|
||||
result.emplace_back(physDeviceProps.properties.deviceName, physDeviceIDProps.deviceUUID);
|
||||
result.emplace_back(physDeviceProps.properties.deviceName);
|
||||
}
|
||||
}
|
||||
vkDestroySurfaceKHR(instance, surface, nullptr);
|
||||
|
|
@ -181,7 +181,6 @@ std::vector<VulkanRenderer::DeviceInfo> VulkanRenderer::GetDevices()
|
|||
vkDestroyInstance(instance, nullptr);
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
void VulkanRenderer::DetermineVendor()
|
||||
|
|
@ -389,8 +388,7 @@ VulkanRenderer::VulkanRenderer()
|
|||
auto surface = CreateFramebufferSurface(m_instance, gui_getWindowInfo().window_main);
|
||||
|
||||
auto& config = GetConfig();
|
||||
decltype(config.graphic_device_uuid) zero{};
|
||||
const bool has_device_set = config.graphic_device_uuid != zero;
|
||||
const bool has_device_set = !config.graphic_device_name.empty();
|
||||
|
||||
VkPhysicalDevice fallbackDevice = VK_NULL_HANDLE;
|
||||
|
||||
|
|
@ -410,7 +408,7 @@ VulkanRenderer::VulkanRenderer()
|
|||
physDeviceProps.pNext = &physDeviceIDProps;
|
||||
vkGetPhysicalDeviceProperties2(device, &physDeviceProps);
|
||||
|
||||
if (memcmp(config.graphic_device_uuid.data(), physDeviceIDProps.deviceUUID, VK_UUID_SIZE) != 0)
|
||||
if (config.graphic_device_name != physDeviceProps.properties.deviceName)
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -423,7 +421,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_uuid = {}; // resetting device selection
|
||||
config.graphic_device_name = ""; // resetting device selection
|
||||
}
|
||||
else if (m_physicalDevice == VK_NULL_HANDLE)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -156,19 +156,7 @@ public:
|
|||
sint32 texelCountY;
|
||||
}FormatInfoVK;
|
||||
|
||||
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();
|
||||
static std::vector<std::string> GetDevices();
|
||||
VulkanRenderer();
|
||||
virtual ~VulkanRenderer();
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue