如何在 CIImageProcessorKernel 子类中为 Metal Compute 指定设备?
How to specify device for Metal Compute in CIImageProcessorKernel subclass?
我有一个自定义 CIFilter
,使用 CIImageProcessorKernel
的子类实现。内核本身很简单:
@implementation ErosionFilterKernel
+ (BOOL)processWithInputs:(NSArray<id<CIImageProcessorInput>> *)inputs
arguments:(NSDictionary<NSString *,id> *)arguments
output:(id<CIImageProcessorOutput>)output
error:(NSError *__autoreleasing *)error
{
error = error ?: &(NSError * __autoreleasing){ nil };
id<MTLCommandBuffer> commandBuffer = output.metalCommandBuffer;
id<MTLTexture> sourceTexture = [inputs.firstObject metalTexture];
id<MTLTexture> destinationTexture = output.metalTexture;
NSInteger distance = [arguments[@"erosionDistance"] integerValue] ?: 1;
MPSImageAreaMin *erodeFilter = [[MPSImageAreaMin alloc] initWithDevice:commandBuffer.device
kernelWidth:distance
kernelHeight:distance];
[erodeFilter encodeToCommandBuffer:commandBuffer sourceTexture:sourceTexture destinationTexture:destinationTexture];
return YES;
}
@end
这很好用,因为它产生了预期的结果。 我遇到的问题 是它在具有两个 GPU 的 MacBook Pro 上使用集成 GPU,我希望它使用独立 GPU。如果我将 MTLCreateSystemDefaultDevice()
(离散 GPU)的结果传递给 -[MPSImageAreaMin initWithDevice:...]
,我会得到断言失败:
-[MTLDebugComputeCommandEncoder setComputePipelineState:] failed assertion computePipelineState is associated with a different device
这大概是因为负责运行-encodeToCommandBuffer:sourceTexture:destinationTexture:
的机器内部使用的MTLComputeCommandEncoder
实例已经设置为使用集成GPU。我认为这来自从CIImageProcessorOutput
对象中提取的commandBuffer
。
我的问题:
可以指定-encodeToCommandBuffer:sourceTexture:destinationTexture:
使用的GPU吗?据推测,这涉及自定义 output/metal 命令缓冲区,但我不确定。
使用哪个GPU应该由执行图像处理的CIContext
决定。您应该能够使用 [CIContext contextWithMTLDevice:]
初始值设定项指定设备。
顺便说一句,从 macOS 10.15 开始,还有一个内置的 CIMorphologyRectangleMinimum
filter that does the same. And there's also a circular version 从 10.13 开始可用。
我有一个自定义 CIFilter
,使用 CIImageProcessorKernel
的子类实现。内核本身很简单:
@implementation ErosionFilterKernel
+ (BOOL)processWithInputs:(NSArray<id<CIImageProcessorInput>> *)inputs
arguments:(NSDictionary<NSString *,id> *)arguments
output:(id<CIImageProcessorOutput>)output
error:(NSError *__autoreleasing *)error
{
error = error ?: &(NSError * __autoreleasing){ nil };
id<MTLCommandBuffer> commandBuffer = output.metalCommandBuffer;
id<MTLTexture> sourceTexture = [inputs.firstObject metalTexture];
id<MTLTexture> destinationTexture = output.metalTexture;
NSInteger distance = [arguments[@"erosionDistance"] integerValue] ?: 1;
MPSImageAreaMin *erodeFilter = [[MPSImageAreaMin alloc] initWithDevice:commandBuffer.device
kernelWidth:distance
kernelHeight:distance];
[erodeFilter encodeToCommandBuffer:commandBuffer sourceTexture:sourceTexture destinationTexture:destinationTexture];
return YES;
}
@end
这很好用,因为它产生了预期的结果。 我遇到的问题 是它在具有两个 GPU 的 MacBook Pro 上使用集成 GPU,我希望它使用独立 GPU。如果我将 MTLCreateSystemDefaultDevice()
(离散 GPU)的结果传递给 -[MPSImageAreaMin initWithDevice:...]
,我会得到断言失败:
-[MTLDebugComputeCommandEncoder setComputePipelineState:] failed assertion computePipelineState is associated with a different device
这大概是因为负责运行-encodeToCommandBuffer:sourceTexture:destinationTexture:
的机器内部使用的MTLComputeCommandEncoder
实例已经设置为使用集成GPU。我认为这来自从CIImageProcessorOutput
对象中提取的commandBuffer
。
我的问题:
可以指定-encodeToCommandBuffer:sourceTexture:destinationTexture:
使用的GPU吗?据推测,这涉及自定义 output/metal 命令缓冲区,但我不确定。
使用哪个GPU应该由执行图像处理的CIContext
决定。您应该能够使用 [CIContext contextWithMTLDevice:]
初始值设定项指定设备。
顺便说一句,从 macOS 10.15 开始,还有一个内置的 CIMorphologyRectangleMinimum
filter that does the same. And there's also a circular version 从 10.13 开始可用。