Reputation: 21373
I've got a custom CIFilter
, implemented using a subclass of CIImageProcessorKernel
. The kernel itself is very simple:
@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
This works fine, in that it produces the expected result. The problem I'm having is that it uses the integrated GPU on a MacBook Pro with two GPUs, and I'd like it to use the discrete GPU. If I pass the result of MTLCreateSystemDefaultDevice()
(the discrete GPU) into -[MPSImageAreaMin initWithDevice:...]
, I get an assertion failure:
-[MTLDebugComputeCommandEncoder setComputePipelineState:] failed assertion computePipelineState is associated with a different device
This is presumably because the instance of MTLComputeCommandEncoder
used internally by the machinery responsible for running -encodeToCommandBuffer:sourceTexture:destinationTexture:
has already been set up to use the integrated GPU. I think this comes from the commandBuffer
pulled from the CIImageProcessorOutput
object.
My question:
Is it possible to specify the GPU to be used by -encodeToCommandBuffer:sourceTexture:destinationTexture:
? Presumably that involves customizing the output/metal command buffer, but I'm not sure about that.
Upvotes: 0
Views: 423
Reputation: 10383
Which GPU is used should be determined by the CIContext
that performs the image processing. You should be able to specify the device by using the [CIContext contextWithMTLDevice:]
initializer.
By the way, since macOS 10.15 there's also a built-in CIMorphologyRectangleMinimum
filter that does the same. And there's also a circular version that's available since 10.13.
Upvotes: 2