Indirect Command Buffers on the GPU

iOS 12 / macOS Mojave introduce "indirect command buffers" with Metal, that can be encoded with both the CPU and GPU. The documentation for the CPU side seems decent, here under "Indirect Command Buffers": https://developer.apple.com/documentation/metal/advanced_command_setup?language=objc


However, for the GPU / metal side, documentation seems non-existant, and I am struggling. The only thing I have found is the "Basic Indirect Command Buffer" sample – https://developer.apple.com/documentation/metal/advanced_command_setup/basic_indirect_command_buffers?language=objc– which shows the following very simple Metal example:


cmd.set_vertex_buffer(args.vertex_buffers[cmd_idx], AAPLBufferIndexVertices);

cmd.draw_primitives(primitive_type::triangle_strip, 0, args.vertex_num[cmd_idx], 1, 0);

cmd.reset();


These map fairly logically to the "MTLIndirectRenderCommand" interface on the CPU – https://developer.apple.com/documentation/metal/mtlindirectrendercommand?language=objc– but yet do not appear in any Metal documentation I can find (neither https://developer.apple.com/metal/Metal-Shading-Language-Specification.pdf nor in any header I can find)


Further, when I try to do what I really want, which is create a command buffer to draw indexed primitives, the likely function of cmd.draw_indexed_primitives(...) (matching the CPU documentation) has a signature that the compiler won't give me any hints of, and doesn't seem to be quite that of the CPU side.


My attempt of cmd.draw_indexed_primitives(primitive_type::triangle, args.indexCount[meshIndex], index_type::uint32, args.index_buffers[meshIndex], 1, 0, 0); doesn't like "index_type", and trying to replace that with a straight value of "1" (as per MTLIndexTypeUInt32) gives an error of "no matching member function for call to 'draw_indexed_primitives'".


Further, other likely Metal functions from the CPU side, like cmd.set_render_pipeline_state(...) simply don't seem to exist.


So, the question: any tips as to where documentation for the GPU indirect command buffers lives? Any header I am missing digging into?


Thanks,


Russell

Accepted Reply

Right, so to answer my own question many months later:


  1. If anyone is looking for the Metal Indirect Command Buffer header, for Xcode 10.2.1 it's in /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/usr/lib/clang/902.3/include/metal/metal_command_buffer
  2. The render_command API for draw_indexed_primitives() is templated to take either a ushort* or uint* type for the index buffer, and so unlike the CPU-side API, it doesn't require the index_type parameter
  3. set_render_pipeline_state() is indeed in the CPU-side API only
  4. There is some limited documentation now added to the Metal Shading Language Specification, 6.14, "Encoding Commands for Indirect Command Buffers"


Replies

Right, so to answer my own question many months later:


  1. If anyone is looking for the Metal Indirect Command Buffer header, for Xcode 10.2.1 it's in /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/usr/lib/clang/902.3/include/metal/metal_command_buffer
  2. The render_command API for draw_indexed_primitives() is templated to take either a ushort* or uint* type for the index buffer, and so unlike the CPU-side API, it doesn't require the index_type parameter
  3. set_render_pipeline_state() is indeed in the CPU-side API only
  4. There is some limited documentation now added to the Metal Shading Language Specification, 6.14, "Encoding Commands for Indirect Command Buffers"