Reputation: 3960
I'm converting a ObjC tutorial (Apple's Selecting Device Objects for Compute Processing tutorial, in particular) to Swift.
I am doing it in increments, so I have to interface to some code still written in ObjC. I'm getting this error:
Cannot convert value of type
UnsafeRawPointer
to specified typeUnsafeMutableRawPointer
How can I fix this error without changing the parameter type passed into the func? My snippet of Swift code is:
func providePositionData(_inout data: NSData) {
// Synchronize since positions buffer will be used on another thread
objc_sync_enter(self)
let rawPtr: UnsafeMutableRawPointer = data.bytes
/* error here: Cannot convert value of type 'UnsafeRawPointer' to specified type 'UnsafeMutableRawPointer' */
let positionsBuffer = device.makeBuffer(
bytesNoCopy: rawPtr,
length: data.count,
options: .storageModeManaged,
deallocator: nil)
positionsBuffer!.label = "Provided Positions"
positionsBuffer?.__didModifyRange(NSRange(location: 0, length: data.count))
self.positionsBuffer = positionsBuffer
objc_sync_exit(self)
}
The working ObjC code is:
/// Called to provide positions data to be rendered on the next frame
- (void)providePositionData:(NSData *)data
{
// Synchronize since positions buffer will be used on another thread
@synchronized(self)
{
// Cast from 'const void *' to 'void *' which is okay in this case since updateData was
// created with -[NSData initWithBytesNoCopy:length:deallocator:] and underlying memory was
// allocated with vm_allocate
void *vmAllocatedAddress = (void *)data.bytes;
// Create a MTLBuffer with out copying the data
id<MTLBuffer> positionsBuffer = [_device newBufferWithBytesNoCopy:vmAllocatedAddress
length:data.length
options:MTLResourceStorageModeManaged
deallocator:nil];
positionsBuffer.label = @"Provided Positions";
[positionsBuffer didModifyRange:NSMakeRange(0, data.length)];
_positionsBuffer = positionsBuffer;
}
}
The NSData
that is sent in come from ObjC code that wraps the MTLBuffer
in NSData
to allow the app to perform memory management. Here is the working snippet:
// Wrap the memory allocated with vm_allocate with a NSData object which will allow the app to
// rely on ObjC ARC (or even MMR) to manage the memory's lifetime. Initialize NSData object
// with a deallocation block to free the vm_allocated memory when the object has been
// deallocated
{
// Block to dealloc memory created with vm_allocate
void (^deallocProvidedAddress)(void *bytes, NSUInteger length) =
^(void *bytes, NSUInteger length)
{
vm_deallocate((vm_map_t)mach_task_self(),
(vm_address_t)bytes,
length);
};
NSData *positionData = [[NSData alloc] initWithBytesNoCopy:positionDataAddress
length:positionDataSize
deallocator:deallocProvidedAddress];
NSData *velocityData = [[NSData alloc] initWithBytesNoCopy:velocityDataAddress
length:velocityDataSize
deallocator:deallocProvidedAddress];
dataProvider(positionData, velocityData, time);
}
Upvotes: 2
Views: 259