iOS代码在运行时识别金属支持?

时间:2015-04-22 07:30:03

标签: ios objective-c metal

通常,我使用以下代码来识别设备的iOS版本。

if ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0)

以类似的方式,我正在尝试为设备找到Metal支持。使用A7(或更好)GPU和iOS 8.0的Apple设备支持Metal。

这是我期望我的代码工作的方式:

if (MetalSupported == true) {
  // metal programming
} else {
  // opengles2 programming
}

如何获取布尔变量MetalSupported的值?

4 个答案:

答案 0 :(得分:10)

您正在寻找特定于Metal的内容,这很好 - 通常,iOS版本检查和硬件名称检查都很脆弱,因为它们依赖于您的应用程序,了解所有可能的操作系统版本和设备永远跑了。如果Apple要回去发布一个增加了Metal支持的iOS 7.x版本(好吧,似乎不太可能),或者支持Metal的设备,但不是你正在寻找的硬件名称之一(似乎更有可能),你不得不追踪所有这些事情,并更新你的应用程序来管理它们。

无论如何,检查您正在运行的设备是否足够金属以获得令人敬畏的图形代码的最佳方法是什么?只是尝试获取MTLDevice对象:

id<MTLDevice> device = MTLCreateSystemDefaultDevice();
if (device) {
    // ready to rock 
} else {
    // back to OpenGL
}

请注意,仅测试Metal框架类的存在并不会有帮助 - 这些类在任何运行iOS 8的设备上(一直回到iPhone 4s和iPad 2),无论是否存在设备具有支持金属的GPU。

另请注意,iOS模拟器中没有Metal框架,因此如果您要进行模拟器测试,则需要在此模块和任何其他Metal代码周围添加一些#if。你的应用程序不使用GPU API,因为即使对于GL,模拟器也不是设备GPU性能的模仿者。

答案 1 :(得分:6)

在iOS上,您应该只检查MTLCreateSystemDefaultDevice()。如果它返回一个有效的设备,你很高兴。在macOS上,你需要小心;使用[MTLCopyAllDevices() count]确定您是否有任何支持的金属设备可用。

你应该避免在macOS上使用MTLCreateSystemDefaultDevice(),因为这会强制多路复用开关切换到独立GPU(例如:如果你正在处理一台笔记本电脑,在分立和集成图形之间进行自动图形切换)。

答案 2 :(得分:0)

Ricster清楚地解释了在运行时识别支持金属的设备的所有方法。如果你不能通过包含金属库在你的类中使用MTLCreateSystemDefaultDevice(),请使用设备信息(iOS版本,gpu / cpu架构),但是在使用设备信息时需要考虑Ricster解释的所有情况。

void deviceConfigurations(){
        size_t size;
        cpu_type_t type;
        cpu_subtype_t subtype;
        size = sizeof(type);
        sysctlbyname("hw.cputype", &type, &size, NULL, 0);

        size = sizeof(subtype);
        sysctlbyname("hw.cpusubtype", &subtype, &size, NULL, 0);
}

使用子类型和类型变量来识别设备和其他信息。

答案 3 :(得分:-2)

我认为最好的方法是尝试获得其中一个金属类。

Class metalDeviceClass = NSClassFromString(@"MTLDevice");
BOOL isMetalAvailable = metalDeviceClass != nil;
if (isMetalAvailable) {
    NSLog(@"Metal available");
} else {
    NSLog(@"Metal not available");
}