Search code examples
iosmetal

How to use shared memory between GPU and CPU on iOS with Metal? (ideally with objective c)


I created a MTLTexture like this:

descTex=[MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatRGBA8Unorm width:texCamWidth height:texCamHeight mipmapped:NO];
descTex.usage = MTLTextureUsageShaderWrite | MTLTextureUsageShaderRead ;
[descTex setStorageMode:MTLStorageModeShared];
texOutRGB = [_device newTextureWithDescriptor:descTex];

Used a compute shader to fill the texture and render it to the screen. Results are as expected. Now I need to do a CPU hook to modify the texture data which can not be done with a shader. I expected that the MTLTexture.buffer contents would allow me to loop over the pixels but it appears it does not work like that. I see people using the getBytes and then replaceRegion to write it back but that does not look like using shared memory since a copy of the data is made. How to loop over the RGBA pixel data in the texture with the CPU?


Solution

  • If you created a simple 1D buffer instead, then just access the contents member as a pointer. If you need a RGBA buffer then create a CVPixelBuffer that contains BGRA pixels, you can then access the pixels by locking and then read/write to the base pointer for the buffer (take care to respect row widths), finally you can wrap the CVPixelBuffer as a metal texture to avoid the memcpy(). The 2D processing is not trivial, it is a lot easier to just use a 1D buffer.