From 954e2eee29c5903fc9a7ebee205414b95da0133e Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Thu, 25 May 2023 13:22:47 -0400 Subject: [PATCH] asahi: Plumb ppp_multisamplectl into shaders This lets us implement gl_SamplePositions in a cheap way with some ALU in the shader preamble. Signed-off-by: Alyssa Rosenzweig Part-of: --- src/gallium/drivers/asahi/agx_nir_lower_sysvals.c | 2 ++ src/gallium/drivers/asahi/agx_state.c | 24 +++++++++++++++++++++++ src/gallium/drivers/asahi/agx_state.h | 8 ++++++++ src/gallium/drivers/asahi/agx_uniforms.c | 1 + 4 files changed, 35 insertions(+) diff --git a/src/gallium/drivers/asahi/agx_nir_lower_sysvals.c b/src/gallium/drivers/asahi/agx_nir_lower_sysvals.c index 3884d42..19db492 100644 --- a/src/gallium/drivers/asahi/agx_nir_lower_sysvals.c +++ b/src/gallium/drivers/asahi/agx_nir_lower_sysvals.c @@ -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); diff --git a/src/gallium/drivers/asahi/agx_state.c b/src/gallium/drivers/asahi/agx_state.c index 94a1f91..bab3c5a 100644 --- a/src/gallium/drivers/asahi/agx_state.c +++ b/src/gallium/drivers/asahi/agx_state.c @@ -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 diff --git a/src/gallium/drivers/asahi/agx_state.h b/src/gallium/drivers/asahi/agx_state.h index 3e2936b..1e33fbc 100644 --- a/src/gallium/drivers/asahi/agx_state.h +++ b/src/gallium/drivers/asahi/agx_state.h @@ -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) */ diff --git a/src/gallium/drivers/asahi/agx_uniforms.c b/src/gallium/drivers/asahi/agx_uniforms.c index 9a8ac74..4f6d02c 100644 --- a/src/gallium/drivers/asahi/agx_uniforms.c +++ b/src/gallium/drivers/asahi/agx_uniforms.c @@ -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)); -- 2.7.4