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
これは、期待される結果を生成するという点で、うまく機能します。私が抱えている問題は、2 つの GPU を搭載した MacBook Pro で統合 GPU を使用していることであり、ディスクリート GPU を使用したいと考えています。MTLCreateSystemDefaultDevice()(ディスクリート GPU)の結果を に渡すと-[MPSImageAreaMin initWithDevice:...]、アサーション エラーが発生します。
-[MTLDebugComputeCommandEncoder setComputePipelineState:] 失敗したアサーション computePipelineState が別のデバイスに関連付けられています
これはおそらく、MTLComputeCommandEncoder実行を担当する機械が内部で使用する のインスタンスが-encodeToCommandBuffer:sourceTexture:destinationTexture:、統合 GPU を使用するように設定されているためです。これは物から引っ張られた結果だと思います。commandBufferCIImageProcessorOutput
私の質問: で使用する GPU を指定することは可能-encodeToCommandBuffer:sourceTexture:destinationTexture:ですか? おそらくそれには、出力/金属コマンド バッファのカスタマイズが含まれますが、それについてはわかりません。