Problems with argument buffers in macOS 10.13.1

Having varied results, depending upon the GPU, using argument buffers in a macOS application.


On a late 2012 MacBook Pro with a GeForce 650M GPU, I can get the argument buffer to work only if it's created with the 'MTLResourceStorageModeShared' option. If it's created with 'MTLResourceStorageModeManaged', then the primitives (a collection of patches) are never rendered.


On a 2013 MacBook Pro just an Intel HD 4000 GPU, the application hangs and then crashes if I try to use an argument buffer, no matter what storage mode I specify (the crash is specifically in a call to setRenderPipelineState()).


This is with the 'public beta' of 10.13.1. Anyone else had such experiences with argument buffers on macOS?


-- Alex

Replies

What Tier of Argument Buffers are you using? Some macOS GPUs and all iOS GPUs only support Tier1 which means you cannot encode an argument buffer on the GPU and limits the size of the pool of textures, buffers, and samples from which a shader can can access.

As far as I know, I am only trying to use 'tier 1' features: the argument buffer struct consists only of three pointers to ordinary buffers that were previously passed as function arguments, and I'm not trying to point one argument buffer to another argument buffer. The argument buffer is encoded on the CPU side with a MTLArgumentEncoder. The argument buffer is being passed to a tessellation vertex shader. Just before the application crashes, it logs the following:


Error occurred when creating pipeline: Error Domain=CompilerError Code=1 "Compiler encountered an internal error" UserInfo={NSLocalizedDescription=Compiler encountered an internal error}


I did also create a very simple program that just draws a single triangle using an argument buffer, & that works fine.

Okay, I think I've isolated this to the "internal compiler error" that occurs when I try to create a pipeline with a particular combination of a vertex function and a fragment function. Will make a bug report shortly.


-- Alex

I entered the following bug report:

https://bugreport.apple.com/web/?problemID=34911053

Thanks for the bug. I was able to reproduce the crash with your app and I've passed this onto the Intel GPU Driver team.


WRT to the problem you saw using Managed memory on Nvidia, a common developer mistake is to neglect calling didModifyRange on the buffer after modifying the memory. Just confirm that after you change your argument buffer, you call didModifyRange.

Ah, so even though I'm using the MTLArgumentEncoder to set the contents of the argument buffer, and not using a pointer, I'd still need to call 'didModifyRange'?

Correct.


In fact, It's actually the opposite of what you were thinking. If you use a pointer to encode the arguments (which you can only do in a shader / kernel), you don't need to use didModifyRange. If you use the MTLArgumentEncoder (and are thus using the CPU to encode the arguements), you must use didModifyRange.


AMD and nVidia GPUs are likely to have CPU/GPU mirror of each managed buffer since they have discrete memory (Intel and iOS GPUs share system memory with the CPU). Calling 'didModifyRange' tells the driver that it will need to syncronize a CPU copy of the managed buffer with the discrete memory copy. MTLArgumentEncoder without calling 'didModifyRange', only makes changes to the CPU copy. When you write to an argument buffer you only make changes to the GPU copy and so you don't need to call 'didModifyRange' since that copy is what the GPU acutally uses.