title: Using Metal discard_fragment() to discard individual samples in an MSAA attachment
body: <p>For an MSSA attachment, the following simple Metal fragment shader is meant to be run in multiple render passes, once per sample, to fill the stencil attachment with different reference values per sample. It does not work as expected, and effectively fills <strong><em>all</em></strong> stencil pixel samples with the reference value on each renderpass.</p>
  <pre><code>struct _10
  {
      int _m0;
  };
  
  struct main0_out
  {
      float gl_FragDepth [[depth(any)]];
  };
  
  fragment main0_out main0(constant _10&amp; _12 [[buffer(0)]], uint gl_SampleID [[sample_id]])
  {
      main0_out out = {};
      if (gl_SampleID != _12._m0)
      {
          discard_fragment();
      }
      out.gl_FragDepth = 0.5;
      return out;
  }
  </code></pre>
  <p>The problem seems to be using <code>discard_fragment()</code> on a per-sample basis. The intended operation of discarding one sample but writing another does not occur. Instead, the sample is never discarded, regardless of the comparison value passed in the buffer.</p>
  <p>In fact, from what I can tell from GPU capture shader tracing results, it appears that the entire if-discard clause is optimized away by the Metal compiler. My guess is that Metal probably recognizes the disconnect between per-sample invocations and <code>discard_fragment()</code>, and removes it, but I can't be sure.</p>
  <p>I can't find any Metal documentation on <code>discard_fragment()</code> and its use with MSAA, so I can't tell whether <code>discard_fragment()</code> is supposed to work with individual sample invocations in that environment, or whether it can only discard the entire fragment (which admittedly the function name implies, but what does that mean for per-sample invocations?).</p>
  <p>Does the logic and intention of this shader make sense? Is <code>discard_fragment()</code> supposed to work with individual sample invocations? And why would the Metal compiler possibly be removing the discard operation from my shader?</p>