0

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:ですか? おそらくそれには、出力/金属コマンド バッファのカスタマイズが含まれますが、それについてはわかりません。

4

1 に答える 1