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 <alyssa@rosenzweig.io>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16512>
This commit is contained in:
Alyssa Rosenzweig 2022-04-02 15:31:40 -04:00
parent 666f307d41
commit 65500b19df
5 changed files with 48 additions and 16 deletions

View file

@ -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?) */

View file

@ -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));

View file

@ -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 {

View file

@ -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;

View file

@ -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,