agx: Extract texture write mask handling
authorAlyssa Rosenzweig <alyssa@rosenzweig.io>
Thu, 8 Jun 2023 16:15:01 +0000 (12:15 -0400)
committerMarge Bot <emma+marge@anholt.net>
Thu, 20 Jul 2023 15:33:28 +0000 (15:33 +0000)
image_load will share the logic.

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24258>

src/asahi/compiler/agx_compile.c

index f2cc501..b6aa2a6 100644 (file)
@@ -791,6 +791,32 @@ agx_txf_sampler(agx_context *ctx)
    return agx_immediate(ctx->out->txf_sampler);
 }
 
+static unsigned
+agx_expand_tex_to(agx_builder *b, nir_dest *dest, agx_index src, bool masked)
+{
+   unsigned nr_channels = nir_dest_num_components(*dest);
+   nir_component_mask_t mask = nir_ssa_def_components_read(&dest->ssa);
+
+   if (!masked)
+      mask = (nir_component_mask_t)BITFIELD_MASK(nr_channels);
+
+   agx_index packed_channels[4] = {agx_null()};
+   agx_index unpacked_channels[4] = {agx_null()};
+
+   /* Hardware writes the masked components contiguously, expand out for NIR */
+   agx_emit_split(b, packed_channels, src, 4 /* XXX: why not nr_channels */);
+
+   for (unsigned i = 0; i < nr_channels; ++i) {
+      unpacked_channels[i] =
+         (mask & BITFIELD_BIT(i))
+            ? packed_channels[util_bitcount(mask & BITFIELD_MASK(i))]
+            : agx_undef(src.size);
+   }
+
+   agx_emit_collect_to(b, agx_dest_index(dest), nr_channels, unpacked_channels);
+   return mask;
+}
+
 static agx_instr *
 agx_emit_image_store(agx_builder *b, nir_intrinsic_instr *instr)
 {
@@ -1528,41 +1554,22 @@ agx_emit_tex(agx_builder *b, nir_tex_instr *instr)
    else if (!agx_is_null(compare))
       compare_offset = compare;
 
-   unsigned nr_channels = nir_dest_num_components(instr->dest);
-   nir_component_mask_t mask = nir_ssa_def_components_read(&instr->dest.ssa);
-
-   /* Destination masking doesn't seem to work properly for gathers (because
-    * it's mostly pointless), but it does show up in the lowering of
-    * textureGatherOffsets. Don't try to mask the destination for gathers.
-    */
-   if (instr->op == nir_texop_tg4)
-      mask = BITFIELD_MASK(nr_channels);
-
    agx_index tmp = agx_temp(b->shader, dst.size);
-
    agx_instr *I = agx_texture_sample_to(
       b, tmp, coords, lod, bindless, texture, sampler, compare_offset,
       agx_tex_dim(instr->sampler_dim, instr->is_array),
-      agx_lod_mode_for_nir(instr->op), mask, 0, !agx_is_null(packed_offset),
+      agx_lod_mode_for_nir(instr->op), 0, 0, !agx_is_null(packed_offset),
       !agx_is_null(compare), agx_gather_for_nir(instr));
 
    if (txf)
       I->op = AGX_OPCODE_TEXTURE_LOAD;
 
-   agx_index packed_channels[4] = {agx_null()};
-   agx_index unpacked_channels[4] = {agx_null()};
-
-   /* Hardware writes the masked components contiguously, expand out for NIR */
-   agx_emit_split(b, packed_channels, tmp, 4 /* XXX: why not nr_channels */);
-
-   for (unsigned i = 0; i < nr_channels; ++i) {
-      unpacked_channels[i] =
-         (mask & BITFIELD_BIT(i))
-            ? packed_channels[util_bitcount(mask & BITFIELD_MASK(i))]
-            : agx_undef(tmp.size);
-   }
-
-   agx_emit_collect_to(b, dst, nr_channels, unpacked_channels);
+   /* Destination masking doesn't seem to work properly for gathers (because
+    * it's mostly pointless), but it does show up in the lowering of
+    * textureGatherOffsets. Don't try to mask the destination for gathers.
+    */
+   bool masked = (instr->op != nir_texop_tg4);
+   I->mask = agx_expand_tex_to(b, &instr->dest, tmp, masked);
 }
 
 /*