sample_mask_agx corresponds directly to the hardware's 2-source instruction, but
it's hard to use correctly and even harder to legalize after the fact, since
it's responsible for not only discard but also late depth/stencil testing. For
our various high-level lowering passes, it's easier to use a one-source discard
(where we don't have to worry about sample masks), which the compiler will
internally lower to the two-source instruction. Introduce such an instruction.
Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Reviewed-by: Asahi Lina <lina@asahilina.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23832>
shader->info.outputs_written |= BITFIELD64_BIT(FRAG_RESULT_SAMPLE_MASK);
break;
+ case nir_intrinsic_discard_agx:
+ shader->info.fs.uses_discard = true;
+ break;
+
case nir_intrinsic_launch_mesh_workgroups:
case nir_intrinsic_launch_mesh_workgroups_with_payload_deref: {
for (unsigned i = 0; i < 3; ++i) {
# documented elsewhere as they are too complicated for this comment.
intrinsic("sample_mask_agx", src_comp=[1, 1])
+# Discard a subset of samples given by a specified sample mask. This acts like a
+# per-sample discard, or an inverted accumulating gl_SampleMask write. The
+# compiler will lower to sample_mask_agx, but that lowering is nontrivial as
+# sample_mask_agx also triggers depth/stencil testing.
+intrinsic("discard_agx", src_comp=[1])
+
# The fixed-function sample mask specified in the API (e.g. glSampleMask)
system_value("api_sample_mask_agx", 1, bit_sizes=[16])