我有一个自定义的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:] 断言失败 computePipelineState 与不同的设备相关联
这大概是因为MTLComputeCommandEncoder
负责运行的机器内部使用的实例-encodeToCommandBuffer:sourceTexture:destinationTexture:
已经设置为使用集成 GPU。我认为这来自于从物体中commandBuffer
拉出。CIImageProcessorOutput
我的问题:是否可以指定要使用的 GPU -encodeToCommandBuffer:sourceTexture:destinationTexture:
?大概这涉及自定义输出/金属命令缓冲区,但我不确定。