From: Alyssa Rosenzweig Date: Tue, 26 Feb 2019 23:51:34 +0000 (+0000) Subject: panfrost: Decouple Gallium clear from FBD clear X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=40ffee4448835e04d139657aafdb5919aa5af941;p=mesa.git panfrost: Decouple Gallium clear from FBD clear The operations of gallium->clear() and the hardware callbacks are fundamentally independent. This routine decouples them by routing shared information via panfrost_job, allowing the hardware half to be deferred to the fragment job generation. Signed-off-by: Alyssa Rosenzweig Reviewed-by: Tomeu Vizoso --- diff --git a/src/gallium/drivers/panfrost/pan_context.c b/src/gallium/drivers/panfrost/pan_context.c index 257482f9006..d05863d35a0 100644 --- a/src/gallium/drivers/panfrost/pan_context.c +++ b/src/gallium/drivers/panfrost/pan_context.c @@ -412,42 +412,31 @@ normalised_float_to_u8(float f) } static void -panfrost_clear_sfbd(struct panfrost_context *ctx, - bool clear_color, - bool clear_depth, - bool clear_stencil, - uint32_t packed_color, - double depth, unsigned stencil - ) +panfrost_clear_sfbd(struct panfrost_job *job) { + struct panfrost_context *ctx = job->ctx; struct mali_single_framebuffer *sfbd = &ctx->fragment_sfbd; - if (clear_color) { - sfbd->clear_color_1 = packed_color; - sfbd->clear_color_2 = packed_color; - sfbd->clear_color_3 = packed_color; - sfbd->clear_color_4 = packed_color; + if (job->clear & PIPE_CLEAR_COLOR) { + sfbd->clear_color_1 = job->clear_color; + sfbd->clear_color_2 = job->clear_color; + sfbd->clear_color_3 = job->clear_color; + sfbd->clear_color_4 = job->clear_color; } - if (clear_depth) { - sfbd->clear_depth_1 = depth; - sfbd->clear_depth_2 = depth; - sfbd->clear_depth_3 = depth; - sfbd->clear_depth_4 = depth; - } - - if (clear_stencil) { - sfbd->clear_stencil = stencil; - } + if (job->clear & PIPE_CLEAR_DEPTH) { + sfbd->clear_depth_1 = job->clear_depth; + sfbd->clear_depth_2 = job->clear_depth; + sfbd->clear_depth_3 = job->clear_depth; + sfbd->clear_depth_4 = job->clear_depth; - /* Setup buffers */ - - if (clear_depth) { sfbd->depth_buffer = ctx->depth_stencil_buffer.gpu; sfbd->depth_buffer_enable = MALI_DEPTH_STENCIL_ENABLE; } - if (clear_stencil) { + if (job->clear & PIPE_CLEAR_STENCIL) { + sfbd->clear_stencil = job->clear_stencil; + sfbd->stencil_buffer = ctx->depth_stencil_buffer.gpu; sfbd->stencil_buffer_enable = MALI_DEPTH_STENCIL_ENABLE; } @@ -456,14 +445,14 @@ panfrost_clear_sfbd(struct panfrost_context *ctx, /* XXX: What do these flags mean? */ int clear_flags = 0x101100; - if (clear_color && clear_depth && clear_stencil) { + if (!(job->clear & ~(PIPE_CLEAR_COLOR | PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL))) { /* On a tiler like this, it's fastest to clear all three buffers at once */ clear_flags |= MALI_CLEAR_FAST; } else { clear_flags |= MALI_CLEAR_SLOW; - if (clear_stencil) + if (job->clear & PIPE_CLEAR_STENCIL) clear_flags |= MALI_CLEAR_SLOW_STENCIL; } @@ -471,36 +460,30 @@ panfrost_clear_sfbd(struct panfrost_context *ctx, } static void -panfrost_clear_mfbd(struct panfrost_context *ctx, - bool clear_color, - bool clear_depth, - bool clear_stencil, - uint32_t packed_color, - double depth, unsigned stencil - ) +panfrost_clear_mfbd(struct panfrost_job *job) { + struct panfrost_context *ctx = job->ctx; struct bifrost_render_target *buffer_color = &ctx->fragment_rts[0]; struct bifrost_framebuffer *buffer_ds = &ctx->fragment_mfbd; - if (clear_color) { - buffer_color->clear_color_1 = packed_color; - buffer_color->clear_color_2 = packed_color; - buffer_color->clear_color_3 = packed_color; - buffer_color->clear_color_4 = packed_color; + if (job->clear & PIPE_CLEAR_COLOR) { + buffer_color->clear_color_1 = job->clear_color; + buffer_color->clear_color_2 = job->clear_color; + buffer_color->clear_color_3 = job->clear_color; + buffer_color->clear_color_4 = job->clear_color; } - if (clear_depth) { - buffer_ds->clear_depth = depth; + if (job->clear & PIPE_CLEAR_DEPTH) { + buffer_ds->clear_depth = job->clear_depth; } - if (clear_stencil) { - buffer_ds->clear_stencil = stencil; + if (job->clear & PIPE_CLEAR_STENCIL) { + buffer_ds->clear_stencil = job->clear_stencil; } - if (clear_depth || clear_stencil) { + if (job->clear & (PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL)) { /* Setup combined 24/8 depth/stencil */ ctx->fragment_mfbd.unk3 |= MALI_MFBD_EXTRA; - //ctx->fragment_extra.unk = /*0x405*/0x404; ctx->fragment_extra.unk = 0x405; ctx->fragment_extra.ds_linear.depth = ctx->depth_stencil_buffer.gpu; ctx->fragment_extra.ds_linear.depth_stride = ctx->pipe_framebuffer.width * 4; @@ -515,40 +498,32 @@ panfrost_clear( double depth, unsigned stencil) { struct panfrost_context *ctx = pan_context(pipe); + struct panfrost_job *job = panfrost_get_job_for_fbo(ctx); - if (!color) { - printf("Warning: clear color null?\n"); - return; - } - - /* Save settings for FBO switch */ - ctx->last_clear.buffers = buffers; - ctx->last_clear.color = color; - ctx->last_clear.depth = depth; - ctx->last_clear.depth = depth; + if (buffers & PIPE_CLEAR_COLOR) { + /* Alpha clear only meaningful without alpha channel, TODO less ad hoc */ + bool has_alpha = util_format_has_alpha(ctx->pipe_framebuffer.cbufs[0]->format); + float clear_alpha = has_alpha ? color->f[3] : 1.0f; - bool clear_color = buffers & PIPE_CLEAR_COLOR; - bool clear_depth = buffers & PIPE_CLEAR_DEPTH; - bool clear_stencil = buffers & PIPE_CLEAR_STENCIL; + uint32_t packed_color = + (normalised_float_to_u8(clear_alpha) << 24) | + (normalised_float_to_u8(color->f[2]) << 16) | + (normalised_float_to_u8(color->f[1]) << 8) | + (normalised_float_to_u8(color->f[0]) << 0); - /* Remember that we've done something */ - ctx->frame_cleared = true; + job->clear_color = packed_color; - /* Alpha clear only meaningful without alpha channel */ - bool has_alpha = ctx->pipe_framebuffer.nr_cbufs && util_format_has_alpha(ctx->pipe_framebuffer.cbufs[0]->format); - float clear_alpha = has_alpha ? color->f[3] : 1.0f; + } - uint32_t packed_color = - (normalised_float_to_u8(clear_alpha) << 24) | - (normalised_float_to_u8(color->f[2]) << 16) | - (normalised_float_to_u8(color->f[1]) << 8) | - (normalised_float_to_u8(color->f[0]) << 0); + if (buffers & PIPE_CLEAR_DEPTH) { + job->clear_depth = depth; + } - if (require_sfbd) { - panfrost_clear_sfbd(ctx, clear_color, clear_depth, clear_stencil, packed_color, depth, stencil); - } else { - panfrost_clear_mfbd(ctx, clear_color, clear_depth, clear_stencil, packed_color, depth, stencil); + if (buffers & PIPE_CLEAR_STENCIL) { + job->clear_stencil = stencil; } + + job->clear |= buffers; } static mali_ptr @@ -977,7 +952,17 @@ panfrost_set_value_job(struct panfrost_context *ctx) mali_ptr panfrost_fragment_job(struct panfrost_context *ctx) { - /* Update fragment FBD */ + struct panfrost_job *job = panfrost_get_job_for_fbo(ctx); + + /* Actualize the clear late; TODO: Fix order dependency between clear + * and afbc */ + + if (require_sfbd) { + panfrost_clear_sfbd(job); + } else { + panfrost_clear_mfbd(job); + } + panfrost_set_fragment_afbc(ctx); if (ctx->pipe_framebuffer.nr_cbufs == 1) { diff --git a/src/gallium/drivers/panfrost/pan_job.h b/src/gallium/drivers/panfrost/pan_job.h index 2e6062112b3..0eb729a5b69 100644 --- a/src/gallium/drivers/panfrost/pan_job.h +++ b/src/gallium/drivers/panfrost/pan_job.h @@ -39,6 +39,14 @@ struct panfrost_job_key { struct panfrost_job { struct panfrost_context *ctx; struct panfrost_job_key key; + + /* Buffers cleared (PIPE_CLEAR_* bitmask) */ + unsigned clear; + + /* Packed clear values */ + uint32_t clear_color; + float clear_depth; + unsigned clear_stencil; }; /* Functions for managing the above */