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);
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)
{
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
/* 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;
/* 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)
*/
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));