From 65500b19dfea4eb5982256fc31e76155b347fdcf Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Sat, 2 Apr 2022 15:31:40 -0400 Subject: [PATCH] asahi: Implement polygon offset This is pretty simple now that the hardware is understood. The hardware interfaces parallels that of scissors, so the scissor path is reused with minor modifications to accommodate the new functionality. Signed-off-by: Alyssa Rosenzweig Part-of: --- src/gallium/drivers/asahi/agx_pipe.c | 3 ++ src/gallium/drivers/asahi/agx_state.c | 49 +++++++++++++++++++++------ src/gallium/drivers/asahi/agx_state.h | 8 ++--- src/gallium/drivers/asahi/magic.c | 3 +- src/gallium/drivers/asahi/magic.h | 1 + 5 files changed, 48 insertions(+), 16 deletions(-) diff --git a/src/gallium/drivers/asahi/agx_pipe.c b/src/gallium/drivers/asahi/agx_pipe.c index 39b187ee559..7de453b223b 100644 --- a/src/gallium/drivers/asahi/agx_pipe.c +++ b/src/gallium/drivers/asahi/agx_pipe.c @@ -502,6 +502,7 @@ agx_flush(struct pipe_context *pctx, agx_batch_add_bo(batch, batch->encoder); agx_batch_add_bo(batch, batch->scissor.bo); + agx_batch_add_bo(batch, batch->depth_bias.bo); agx_batch_add_bo(batch, dev->internal.bo); agx_batch_add_bo(batch, dev->reload.bo); @@ -552,6 +553,7 @@ agx_flush(struct pipe_context *pctx, ctx->batch->encoder->ptr.gpu, encoder_id, ctx->batch->scissor.bo->ptr.gpu, + ctx->batch->depth_bias.bo->ptr.gpu, pipeline_null.gpu, pipeline_clear, pipeline_store, @@ -629,6 +631,7 @@ agx_create_context(struct pipe_screen *screen, ctx->batch->encoder = agx_bo_create(agx_device(screen), 0x80000, AGX_MEMORY_TYPE_FRAMEBUFFER); ctx->batch->encoder_current = ctx->batch->encoder->ptr.cpu; ctx->batch->scissor.bo = agx_bo_create(agx_device(screen), 0x80000, AGX_MEMORY_TYPE_FRAMEBUFFER); + ctx->batch->depth_bias.bo = agx_bo_create(agx_device(screen), 0x80000, AGX_MEMORY_TYPE_FRAMEBUFFER); /* Upload fixed shaders (TODO: compile them?) */ diff --git a/src/gallium/drivers/asahi/agx_state.c b/src/gallium/drivers/asahi/agx_state.c index a26de9acfc5..117a8248cbe 100644 --- a/src/gallium/drivers/asahi/agx_state.c +++ b/src/gallium/drivers/asahi/agx_state.c @@ -288,16 +288,17 @@ agx_bind_rasterizer_state(struct pipe_context *pctx, void *cso) struct agx_context *ctx = agx_context(pctx); struct agx_rasterizer *so = cso; - /* Check if scissor state has changed, since scissor enable is part of the - * rasterizer state but everything else needed for scissors is part of - * viewport/scissor states */ - bool scissor_changed = (cso == NULL) || (ctx->rast == NULL) || - (ctx->rast->base.scissor != so->base.scissor); + /* Check if scissor or depth bias state has changed, since scissor/depth bias + * enable is part of the rasterizer state but everything else needed for + * scissors and depth bias is part of the scissor/depth bias arrays */ + bool scissor_zbias_changed = (cso == NULL) || (ctx->rast == NULL) || + (ctx->rast->base.scissor != so->base.scissor) || + (ctx->rast->base.offset_tri != so->base.offset_tri); ctx->rast = so; - if (scissor_changed) - ctx->dirty |= AGX_DIRTY_SCISSOR; + if (scissor_zbias_changed) + ctx->dirty |= AGX_DIRTY_SCISSOR_ZBIAS; } static enum agx_wrap @@ -606,7 +607,7 @@ agx_set_scissor_states(struct pipe_context *pctx, assert(num_scissors == 1 && "no geometry shaders"); ctx->scissor = *scissor; - ctx->dirty |= AGX_DIRTY_SCISSOR; + ctx->dirty |= AGX_DIRTY_SCISSOR_ZBIAS; } static void @@ -706,6 +707,22 @@ agx_upload_viewport_scissor(struct agx_pool *pool, }; } +static uint16_t +agx_upload_depth_bias(struct agx_batch *batch, + const struct pipe_rasterizer_state *rast) +{ + struct agx_depth_bias_packed *ptr = batch->depth_bias.bo->ptr.cpu; + unsigned index = (batch->depth_bias.count++); + + agx_pack(ptr + index, DEPTH_BIAS, cfg) { + cfg.depth_bias = rast->offset_units; + cfg.slope_scale = rast->offset_scale; + cfg.clamp = rast->offset_clamp; + } + + return index; +} + /* A framebuffer state can be reused across batches, so it doesn't make sense * to add surfaces to the BO list here. Instead we added them when flushing. */ @@ -1407,6 +1424,8 @@ demo_rasterizer(struct agx_context *ctx, struct agx_pool *pool, bool is_points) * optimize this out if the viewport is the default and the app does not * use the scissor test) */ cfg.scissor_enable = true; + + cfg.depth_bias_enable = rast->base.offset_tri; }; /* Words 2-3: front */ @@ -1450,12 +1469,13 @@ demo_unk12(struct agx_pool *pool) } static uint64_t -agx_set_index(struct agx_pool *pool, unsigned scissor) +agx_set_index(struct agx_pool *pool, uint16_t scissor, uint16_t zbias) { struct agx_ptr T = agx_pool_alloc_aligned(pool, AGX_SET_INDEX_LENGTH, 64); agx_pack(T.cpu, SET_INDEX, cfg) { cfg.scissor = scissor; + cfg.depth_bias = zbias; }; return T.gpu; @@ -1502,13 +1522,20 @@ agx_encode_state(struct agx_context *ctx, uint8_t *out, agx_push_record(&out, 7, demo_rasterizer(ctx, pool, is_points)); agx_push_record(&out, 5, demo_unk11(pool, is_lines, is_points, reads_tib, sample_mask_from_shader)); - if (ctx->dirty & (AGX_DIRTY_VIEWPORT | AGX_DIRTY_SCISSOR)) { + unsigned zbias = 0; + + if (ctx->rast->base.offset_tri) { + zbias = agx_upload_depth_bias(ctx->batch, &ctx->rast->base); + ctx->dirty |= AGX_DIRTY_SCISSOR_ZBIAS; + } + + if (ctx->dirty & (AGX_DIRTY_VIEWPORT | AGX_DIRTY_SCISSOR_ZBIAS)) { struct agx_viewport_scissor vps = agx_upload_viewport_scissor(pool, ctx->batch, &ctx->viewport, ctx->rast->base.scissor ? &ctx->scissor : NULL); agx_push_record(&out, 10, vps.viewport); - agx_push_record(&out, 2, agx_set_index(pool, vps.scissor)); + agx_push_record(&out, 2, agx_set_index(pool, vps.scissor, zbias)); } agx_push_record(&out, 3, demo_unk12(pool)); diff --git a/src/gallium/drivers/asahi/agx_state.h b/src/gallium/drivers/asahi/agx_state.h index 2de160bc329..35c11c13855 100644 --- a/src/gallium/drivers/asahi/agx_state.h +++ b/src/gallium/drivers/asahi/agx_state.h @@ -88,8 +88,8 @@ struct agx_stage { unsigned sampler_count, texture_count; }; -/* Uploaded scissor descriptors */ -struct agx_scissors { +/* Uploaded scissor or depth bias descriptors */ +struct agx_array { struct agx_bo *bo; unsigned count; }; @@ -114,7 +114,7 @@ struct agx_batch { struct agx_bo *encoder; uint8_t *encoder_current; - struct agx_scissors scissor; + struct agx_array scissor, depth_bias; }; struct agx_zsa { @@ -141,7 +141,7 @@ struct asahi_shader_key { enum agx_dirty { AGX_DIRTY_VERTEX = BITFIELD_BIT(0), AGX_DIRTY_VIEWPORT = BITFIELD_BIT(1), - AGX_DIRTY_SCISSOR = BITFIELD_BIT(2), + AGX_DIRTY_SCISSOR_ZBIAS = BITFIELD_BIT(2), }; struct agx_context { diff --git a/src/gallium/drivers/asahi/magic.c b/src/gallium/drivers/asahi/magic.c index a0d1cfb41b8..05f93bd09bb 100644 --- a/src/gallium/drivers/asahi/magic.c +++ b/src/gallium/drivers/asahi/magic.c @@ -162,6 +162,7 @@ demo_cmdbuf(uint64_t *buf, size_t size, uint64_t encoder_ptr, uint64_t encoder_id, uint64_t scissor_ptr, + uint64_t depth_bias_ptr, uint32_t pipeline_null, uint32_t pipeline_clear, uint32_t pipeline_store, @@ -187,7 +188,7 @@ demo_cmdbuf(uint64_t *buf, size_t size, cfg.store_pipeline_bind = 0x12; cfg.store_pipeline = pipeline_store; cfg.scissor_array = scissor_ptr; - cfg.depth_bias_array = demo_zero(pool, 0x1000); + cfg.depth_bias_array = depth_bias_ptr; if (framebuffer->zsbuf) { struct pipe_surface *zsbuf = framebuffer->zsbuf; diff --git a/src/gallium/drivers/asahi/magic.h b/src/gallium/drivers/asahi/magic.h index c405cbe51e5..a90595b8093 100644 --- a/src/gallium/drivers/asahi/magic.h +++ b/src/gallium/drivers/asahi/magic.h @@ -31,6 +31,7 @@ demo_cmdbuf(uint64_t *buf, size_t size, uint64_t encoder_ptr, uint64_t encoder_id, uint64_t scissor_ptr, + uint64_t depth_bias_ptr, uint32_t pipeline_null, uint32_t pipeline_clear, uint32_t pipeline_store,