Search code examples
iosobjective-cgpumetalmtlbuffer

MTLBuffer with MTLStorageModePrivate mode


I'm relatively new to the Metal, and I have a pretty straight-forward question. I simply can not init MTLBuffer with MTLStorageModePrivate option:

id<MTLBuffer> privateBuff = [device newBufferWithLength:dataLength options:MTLStorageModePrivate];

Compiler gives me an assert with that text:

-[MTLDebugDevice validateResourceOptions:isTexture:isIOSurface:]:437: failed assertion `options 0x2 conveys invalid cpuCacheMode of 0x2'

And it doesn't make much sense. I'm creating a buffer which can be accessed only from GPU, so I need no cpu cache modes whatsoever for this particular entity. I suppose I need to turn off that cpu cache mode, but how?

I looked through MTLCPUCacheMode, but it has nothing regarding turning cpu cache mode completely off.

Interesting note: I absolutely can create MTLHeap with MTLStorageModePrivate, but not MTLBuffer.

Any help would be appreciated. Thanks in advance!

UPDATE: I can create MTLBuffer with MTLStorageModePrivate by using MTLHeap. It looks something like this:

    MTLHeapDescriptor *heapDescriptor = [MTLHeapDescriptor new];
    heapDescriptor.storageMode = MTLStorageModePrivate;
    heapDescriptor.size = 0;

    MTLSizeAndAlign sizeAndAlign = [device heapBufferSizeAndAlignWithLength:lutSharedBuffer.length options:MTLResourceStorageModePrivate];
    sizeAndAlign.size += (sizeAndAlign.size & (sizeAndAlign.align - 1)) + sizeAndAlign.align;
    heapDescriptor.size += sizeAndAlign.size;

    privateHeap = [device newHeapWithDescriptor:heapDescriptor];

    privateBuff = [privateHeap newBufferWithLength:lutSharedBuffer.length options:MTLResourceStorageModePrivate]; //now it works!

But it's still not possible to do without the heap.


Solution

  • The issue here seems to be that you're using the incorrect enum to specify your resource options. In your first snippet, you use MTLStorageModePrivate, but you should be using MTLResourceStorageModePrivate, which contains a bit shift to place the storage mode in the correct bits.

    MTLResourceStorageModePrivate = MTLStorageModePrivate << MTLResourceStorageModeShift
    

    In Swift, this would have caused a compile-time error.