[Mesa-dev] [PATCH 2/3] panfrost: Decouple Gallium clear from FBD clear
Alyssa Rosenzweig
alyssa at rosenzweig.io
Wed Feb 27 00:56:42 UTC 2019
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 <alyssa at rosenzweig.io>
---
src/gallium/drivers/panfrost/pan_context.c | 133 +++++++++------------
src/gallium/drivers/panfrost/pan_job.h | 8 ++
2 files changed, 67 insertions(+), 74 deletions(-)
diff --git a/src/gallium/drivers/panfrost/pan_context.c b/src/gallium/drivers/panfrost/pan_context.c
index 112f777df80..b3bee2aa36d 100644
--- a/src/gallium/drivers/panfrost/pan_context.c
+++ b/src/gallium/drivers/panfrost/pan_context.c
@@ -413,42 +413,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;
}
@@ -457,14 +446,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;
}
@@ -472,36 +461,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;
@@ -516,40 +499,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
@@ -978,7 +953,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 */
--
2.20.1
More information about the mesa-dev
mailing list