summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers
diff options
context:
space:
mode:
authorAlyssa Rosenzweig <[email protected]>2019-02-26 23:51:34 +0000
committerAlyssa Rosenzweig <[email protected]>2019-03-04 04:58:55 +0000
commit40ffee4448835e04d139657aafdb5919aa5af941 (patch)
tree5ae2231dc0f0e66f1fcf80a8bf150a07fc400e6b /src/gallium/drivers
parent59c9623d0a75d5201ad48351af26aad1bc0b7073 (diff)
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 <[email protected]> Reviewed-by: Tomeu Vizoso <[email protected]>
Diffstat (limited to 'src/gallium/drivers')
-rw-r--r--src/gallium/drivers/panfrost/pan_context.c133
-rw-r--r--src/gallium/drivers/panfrost/pan_job.h8
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 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 */