MacOS Metal:无法从命令行应用程序捕获 GPU 帧
MacOS Metal: Failing to capture GPU Frame from command line app
我正在尝试在命令行应用程序中使用 MTLCaptureManager
以编程方式捕获 GPU 帧。
到目前为止,捕获管理器无法支持 MTLCaptureDestinationGPUTraceDocument
目的地。
我尝试使用 XCode 创建一个非常小的重现案例:
#import <Foundation/Foundation.h>
#import <Metal/Metal.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
id<MTLDevice> device = MTLCreateSystemDefaultDevice();
MTLCaptureManager* captureManager = [MTLCaptureManager sharedCaptureManager];
if (![captureManager supportsDestination:MTLCaptureDestinationGPUTraceDocument])
{
NSLog(@"********** captureManager does not support MTLCaptureDestinationGPUTraceDocument ************");
}
else
{
NSLog(@"captureManager support is fine");
}
}
return 0;
}
当运行和XCode时,似乎愿意工作:输出是:
2020-09-02 16:25:59.712217+0200 testMetalCapture[20095:416447] Metal GPU Frame Capture Enabled
2020-09-02 16:25:59.712503+0200 testMetalCapture[20095:416447] Metal API Validation Enabled
2020-09-02 16:26:00.669092+0200 testMetalCapture[20095:416447] captureManager support is fine
Program ended with exit code: 0
但是当我从终端存档构建结果并运行时,它失败了:
2020-09-02 16:32:57.607 testMetalCapture[20126:419837] ********** captureManager does not support MTLCaptureDestinationGPUTraceDocument ************
是否有任何 运行 时间环境我可以在终端中重现以使 MTLCaptureManager
正常工作?
(环境是 XCode 11.6 + MacOS 10.15 Catalina)
据我了解(我找不到任何官方文档):
MTLCaptureManager
需要 Info.plist
的授权:MetalCaptureEnabled
应设置为 YES
。
- 正确的方法是将命令行应用程序与这样的plist捆绑在一起
- 这很复杂,参见示例 Building OSX App Bundle
我偶然发现,如果在与命令行应用程序相同的目录中有一个 Info.plist
,MTLCaptureManager
也可以工作。
这个Info.plist几乎可以是空的,像这样:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>MetalCaptureEnabled</key>
<true/>
</dict>
</plist>
通过这个简单的设置,我可以 运行 我的测试程序(以及我的真实程序)
% ./testMetalCapture
2020-10-02 15:53:08.507 testMetalCapture[28559:686864] Metal GPU Frame Capture Enabled
2020-10-02 15:53:08.523 testMetalCapture[28559:686864] captureManager support is fine
(我目前使用的是MacOSX 10.15.6,以后可能会坏掉)
@rotoglup 的技巧对我有用,直到它不再起作用:一些缓冲区充满了零,并且没有图像出现在金属调试器内的 'screenshots' 中。我不知道这是因为 OS 或 XCode 或其他原因的更新。
正如@rotoglup 建议的那样,我仍然需要 Info.plist 包含此内容:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>MetalCaptureEnabled</key>
<true/>
</dict>
</plist>
但我还需要在启动命令行应用程序的终端中将 METAL_DEVICE_WRAPPER_TYPE 环境变量设置为 1:
export METAL_DEVICE_WRAPPER_TYPE=1
有了这个,缓冲区就被正确填满了,我得到了 non-empty 个屏幕截图。
我正在尝试在命令行应用程序中使用 MTLCaptureManager
以编程方式捕获 GPU 帧。
到目前为止,捕获管理器无法支持 MTLCaptureDestinationGPUTraceDocument
目的地。
我尝试使用 XCode 创建一个非常小的重现案例:
#import <Foundation/Foundation.h>
#import <Metal/Metal.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
id<MTLDevice> device = MTLCreateSystemDefaultDevice();
MTLCaptureManager* captureManager = [MTLCaptureManager sharedCaptureManager];
if (![captureManager supportsDestination:MTLCaptureDestinationGPUTraceDocument])
{
NSLog(@"********** captureManager does not support MTLCaptureDestinationGPUTraceDocument ************");
}
else
{
NSLog(@"captureManager support is fine");
}
}
return 0;
}
当运行和XCode时,似乎愿意工作:输出是:
2020-09-02 16:25:59.712217+0200 testMetalCapture[20095:416447] Metal GPU Frame Capture Enabled
2020-09-02 16:25:59.712503+0200 testMetalCapture[20095:416447] Metal API Validation Enabled
2020-09-02 16:26:00.669092+0200 testMetalCapture[20095:416447] captureManager support is fine
Program ended with exit code: 0
但是当我从终端存档构建结果并运行时,它失败了:
2020-09-02 16:32:57.607 testMetalCapture[20126:419837] ********** captureManager does not support MTLCaptureDestinationGPUTraceDocument ************
是否有任何 运行 时间环境我可以在终端中重现以使 MTLCaptureManager
正常工作?
(环境是 XCode 11.6 + MacOS 10.15 Catalina)
据我了解(我找不到任何官方文档):
MTLCaptureManager
需要Info.plist
的授权:MetalCaptureEnabled
应设置为YES
。- 正确的方法是将命令行应用程序与这样的plist捆绑在一起
- 这很复杂,参见示例 Building OSX App Bundle
我偶然发现,如果在与命令行应用程序相同的目录中有一个 Info.plist
,MTLCaptureManager
也可以工作。
这个Info.plist几乎可以是空的,像这样:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>MetalCaptureEnabled</key>
<true/>
</dict>
</plist>
通过这个简单的设置,我可以 运行 我的测试程序(以及我的真实程序)
% ./testMetalCapture
2020-10-02 15:53:08.507 testMetalCapture[28559:686864] Metal GPU Frame Capture Enabled
2020-10-02 15:53:08.523 testMetalCapture[28559:686864] captureManager support is fine
(我目前使用的是MacOSX 10.15.6,以后可能会坏掉)
@rotoglup 的技巧对我有用,直到它不再起作用:一些缓冲区充满了零,并且没有图像出现在金属调试器内的 'screenshots' 中。我不知道这是因为 OS 或 XCode 或其他原因的更新。
正如@rotoglup 建议的那样,我仍然需要 Info.plist 包含此内容:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>MetalCaptureEnabled</key>
<true/>
</dict>
</plist>
但我还需要在启动命令行应用程序的终端中将 METAL_DEVICE_WRAPPER_TYPE 环境变量设置为 1:
export METAL_DEVICE_WRAPPER_TYPE=1
有了这个,缓冲区就被正确填满了,我得到了 non-empty 个屏幕截图。