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,