title: How to use Metal argument buffer?
body: <p>I am trying to use Metal argument buffers to access data in a Metal compute kernel.
  The buffer has an entry when I print out the value CPU-side, but the Xcode debugger shows my argument buffer as empty on the GPU.</p>
  <p>I can see my buffer with the sentinel value as an indirect resource in the debugger but no pointer to it in the argument buffer.</p>
  <p>Here is the Swift code:</p>
  <pre class="lang-swift prettyprint-override"><code>import MetalKit
  
  do {
      let device = MTLCreateSystemDefaultDevice()!
      let capture_manager = MTLCaptureManager.shared()
      let capture_desc = MTLCaptureDescriptor()
      capture_desc.captureObject = device
      try capture_manager.startCapture(with: capture_desc)
      
      let argument_desc = MTLArgumentDescriptor()
      argument_desc.dataType = MTLDataType.pointer
      argument_desc.index = 0
      argument_desc.arrayLength = 1024
      
      let argument_encoder = device.makeArgumentEncoder(arguments: [argument_desc])!
      
      let argument_buffer = device.makeBuffer(length: argument_encoder.encodedLength, options: MTLResourceOptions())
      argument_encoder.setArgumentBuffer(argument_buffer, offset: 0)
      
      var sentinel: UInt32 = 12345
      let ptr = UnsafeRawPointer.init(&amp;sentinel)
      
      let buffer = device.makeBuffer(bytes: ptr, length: 4, options: MTLResourceOptions.storageModeShared)!
      argument_encoder.setBuffer(buffer, offset: 0, index: 0)
      
      let source = try String(contentsOf: URL.init(fileURLWithPath: &quot;/path/to/kernel.metal&quot;))
      let library = try device.makeLibrary(source: source, options: MTLCompileOptions())
      let function = library.makeFunction(name: &quot;main0&quot;)!
      
      let pipeline = try device.makeComputePipelineState(function: function)
      
      let queue = device.makeCommandQueue()!
      let encoder = queue.makeCommandBuffer()!
      
      let compute_encoder = encoder.makeComputeCommandEncoder()!
      
      compute_encoder.setComputePipelineState(pipeline)
      compute_encoder.setBuffer(argument_buffer, offset: 0, index: 0)
      compute_encoder.useResource(buffer, usage: MTLResourceUsage.read)
      compute_encoder.dispatchThreads(MTLSize.init(width: 1, height: 1, depth: 1), threadsPerThreadgroup: MTLSize.init(width: 1, height: 1, depth: 1))
      
      compute_encoder.endEncoding()
      
      encoder.commit()
      encoder.waitUntilCompleted()
  
      capture_manager.stopCapture()
  } catch {
      print(error)
      exit(1)
  }
  
  </code></pre>
  <p>And the compute kernel:</p>
  <pre><code>#include &lt;metal_stdlib&gt;
  #include &lt;simd/simd.h&gt;
  
  using namespace metal;
  
  struct Argument {
      constant uint32_t *ptr [[id(0)]];
  };
  
  kernel void main0(
      constant Argument *bufferArray [[buffer(0)]]
  ) {
      constant uint32_t *ptr = bufferArray[0].ptr;
      uint32_t y = *ptr;
  }
  
  </code></pre>
  <p>If anyone has any ideas, I'd greatly appreciate it!</p>