iOS代码在运行时识别金属支持?
Posted
技术标签:
【中文标题】iOS代码在运行时识别金属支持?【英文标题】:iOS code to identify metal support in runtime? 【发布时间】:2015-06-29 16:53:09 【问题描述】:通常,我使用下面的代码来识别设备的 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
的值?
【问题讨论】:
【参考方案1】:很高兴您正在寻找特定于 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。
在模拟器中,当在 macOS 10.15 上运行时,从 iOS 13 / tvOS 13 开始支持 Metal。使用相同的策略:致电MTLCreateSystemDefaultDevice()
。如果它返回一个对象,那么您的模拟器代码正在模拟器硬件加速的环境中运行。如果它返回nil
,则说明您运行的是较旧的模拟器或 Metal 不可用的环境。
【讨论】:
不,这不是真的,我在某些 Mac 上看到 MTLCreateSystemDefaultDevice 返回一个设备,但此 Mac 不支持金属【参考方案2】:在 iOS 上,您只需检查 MTLCreateSystemDefaultDevice()
。如果它返回一个有效的设备,你就可以开始了。在 macOS 上,您需要小心;使用[MTLCopyAllDevices() count]
确定您是否有任何支持的金属设备可用。
您应该避免在 macOS 上使用 MTLCreateSystemDefaultDevice()
,因为这可能会强制多路复用器切换到独立 GPU(例如:如果您正在处理在独立显卡和集成显卡之间自动切换显卡的笔记本电脑)。
【讨论】:
MTLCopyAllDevices 仅在 macOS 中可用。 developer.apple.com/documentation/metal/… 啊,真的。谢谢。【参考方案3】: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);
使用子类型和类型变量来识别设备和其他信息。
【讨论】:
这意味着保留所有可以运行 Metal 的设备的列表......并在 Apple 发布新设备时更新它。如果您的应用是使用 iOS 8 或更高版本的 SDK 构建的,而您需要使用该 SDK 才能使用 Metal,那么您可以免费拨打MTLCreateSystemDefaultDevice
。【参考方案4】:
我认为最好的方法是尝试获得金属类之一。
Class metalDeviceClass = NSClassFromString(@"MTLDevice");
BOOL isMetalAvailable = metalDeviceClass != nil;
if (isMetalAvailable)
NSLog(@"Metal available");
else
NSLog(@"Metal not available");
【讨论】:
1.MTLDevice
不是一个类;它是一个协议,因此即使在支持 Metal 的设备上,此测试也会失败。 2. Metal 框架中的类仍然存在于不支持 Metal 的设备上(您只是无法对它们做任何事情),因此测试它们的存在不会告诉您是否可以使用 Metal 进行渲染。见my answer。
好的,谢谢指点。实际上我没有检查它是类还是协议。我的意思是检查其中一门课程的可用性。你的解决方案是正确的。以上是关于iOS代码在运行时识别金属支持?的主要内容,如果未能解决你的问题,请参考以下文章