asahi: Plumb ppp_multisamplectl into shaders
authorAlyssa Rosenzweig <alyssa@rosenzweig.io>
Thu, 25 May 2023 17:22:47 +0000 (13:22 -0400)
committerMarge Bot <emma+marge@anholt.net>
Wed, 7 Jun 2023 03:21:49 +0000 (03:21 +0000)
This lets us implement gl_SamplePositions in a cheap way with some ALU in the
shader preamble.

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

src/gallium/drivers/asahi/agx_nir_lower_sysvals.c
src/gallium/drivers/asahi/agx_state.c
src/gallium/drivers/asahi/agx_state.h
src/gallium/drivers/asahi/agx_uniforms.c

index 3884d42..19db492 100644 (file)
@@ -105,6 +105,8 @@ lower_intrinsic(nir_builder *b, nir_intrinsic_instr *intr)
       return load_sysval_root(b, 1, 32, &u->fs.blend_constant[3]);
    case nir_intrinsic_load_api_sample_mask_agx:
       return load_sysval_root(b, 1, 16, &u->fs.sample_mask);
+   case nir_intrinsic_load_sample_positions_agx:
+      return load_sysval_root(b, 1, 32, &u->fs.ppp_multisamplectl);
    case nir_intrinsic_load_ssbo_address:
       return load_sysval_indirect(b, 1, 64, AGX_SYSVAL_TABLE_ROOT,
                                   &u->ssbo_base, intr->src[0].ssa);
index 94a1f91..bab3c5a 100644 (file)
@@ -2071,6 +2071,26 @@ agx_build_meta(struct agx_batch *batch, bool store, bool partial_render)
    return agx_usc_fini(&b);
 }
 
+/*
+ * Return the standard sample positions, packed into a 32-bit word with fixed
+ * point nibbles for each x/y component of the (at most 4) samples. This is
+ * suitable for programming the PPP_MULTISAMPLECTL control register.
+ */
+static uint32_t
+agx_default_sample_positions(unsigned nr_samples)
+{
+   switch (nr_samples) {
+   case 1:
+      return 0x88;
+   case 2:
+      return 0x44cc;
+   case 4:
+      return 0xeaa26e26;
+   default:
+      unreachable("Invalid sample count");
+   }
+}
+
 void
 agx_batch_init_state(struct agx_batch *batch)
 {
@@ -2133,6 +2153,10 @@ agx_batch_init_state(struct agx_batch *batch)
       if (batch->key.cbufs[i])
          agx_batch_writes(batch, agx_resource(batch->key.cbufs[i]->texture));
    }
+
+   /* Set up standard sample positions */
+   batch->ppp_multisamplectl =
+      agx_default_sample_positions(batch->tilebuffer_layout.nr_samples);
 }
 
 static enum agx_object_type
index 3e2936b..1e33fbc 100644 (file)
@@ -124,6 +124,9 @@ struct PACKED agx_draw_uniforms {
          /* Blend constant if any */
          float blend_constant[4];
 
+         /* Value of the ppp_multisamplectl control register */
+         uint32_t ppp_multisamplectl;
+
          /* glSampleMask */
          uint16_t sample_mask;
       } fs;
@@ -227,6 +230,11 @@ struct agx_batch {
    /* Current varyings linkage structures */
    uint32_t varyings;
 
+   /* Value of the multisample control register, containing sample positions in
+    * each byte (x in low nibble, y in high nibble).
+    */
+   uint32_t ppp_multisamplectl;
+
    /* Resource list requirements, represented as a bit set indexed by BO
     * handles (GEM handles on Linux, or IOGPU's equivalent on macOS)
     */
index 9a8ac74..4f6d02c 100644 (file)
@@ -102,6 +102,7 @@ agx_upload_uniforms(struct agx_batch *batch, uint64_t textures,
              sizeof(ctx->blend_color));
 
       uniforms.fs.sample_mask = ctx->sample_mask;
+      uniforms.fs.ppp_multisamplectl = batch->ppp_multisamplectl;
    }
 
    memcpy(root_ptr.cpu, &uniforms, sizeof(uniforms));