From 5650a719f0c69c00954e47bd7a7b3e9433cb551d Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Tue, 8 Mar 2011 08:20:31 +0100 Subject: r300g: decide whether a flush should be asynchronous when calling it Thread offloading is not sometimes desirable, e.g. when mapping a buffer. --- src/gallium/drivers/r300/r300_blit.c | 2 +- src/gallium/drivers/r300/r300_context.c | 6 +++--- src/gallium/drivers/r300/r300_context.h | 7 +++++-- src/gallium/drivers/r300/r300_emit.c | 2 +- src/gallium/drivers/r300/r300_flush.c | 25 +++++++++++++++---------- src/gallium/drivers/r300/r300_render.c | 2 +- src/gallium/drivers/r300/r300_transfer.c | 18 +++++++----------- src/gallium/drivers/r300/r300_winsys.h | 13 ++++--------- 8 files changed, 37 insertions(+), 38 deletions(-) (limited to 'src/gallium/drivers/r300') diff --git a/src/gallium/drivers/r300/r300_blit.c b/src/gallium/drivers/r300/r300_blit.c index 6391ea7f3b..6682b2bad4 100644 --- a/src/gallium/drivers/r300/r300_blit.c +++ b/src/gallium/drivers/r300/r300_blit.c @@ -263,7 +263,7 @@ static void r300_clear(struct pipe_context* pipe, /* Reserve CS space. */ if (dwords > (R300_MAX_CMDBUF_DWORDS - r300->cs->cdw)) { - r300->context.flush(&r300->context, 0, NULL); + r300_flush(&r300->context, R300_FLUSH_ASYNC, NULL); } /* Emit clear packets. */ diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c index 48a595981b..720d666d98 100644 --- a/src/gallium/drivers/r300/r300_context.c +++ b/src/gallium/drivers/r300/r300_context.c @@ -139,11 +139,11 @@ static void r300_destroy_context(struct pipe_context* context) FREE(r300); } -void r300_flush_cb(void *data) +static void r300_flush_callback(void *data, unsigned flags) { struct r300_context* const cs_context_copy = data; - cs_context_copy->context.flush(&cs_context_copy->context, 0, NULL); + r300_flush(&cs_context_copy->context, flags, NULL); } #define R300_INIT_ATOM(atomname, atomsize) \ @@ -453,7 +453,7 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen, r300_init_render_functions(r300); r300_init_states(&r300->context); - rws->cs_set_flush(r300->cs, r300_flush_cb, r300); + rws->cs_set_flush(r300->cs, r300_flush_callback, r300); /* The KIL opcode needs the first texture unit to be enabled * on r3xx-r4xx. In order to calm down the CS checker, we bind this diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index 1e28221326..76ea5ee251 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -665,8 +665,6 @@ static INLINE void r300_mark_atom_dirty(struct r300_context *r300, struct pipe_context* r300_create_context(struct pipe_screen* screen, void *priv); -void r300_flush_cb(void *data); - /* Context initialization. */ struct draw_stage* r300_draw_stage(struct r300_context* r300); void r300_init_blit_functions(struct r300_context *r300); @@ -681,6 +679,11 @@ void r300_decompress_zmask(struct r300_context *r300); void r300_decompress_zmask_locked_unsafe(struct r300_context *r300); void r300_decompress_zmask_locked(struct r300_context *r300); +/* r300_flush.c */ +void r300_flush(struct pipe_context *pipe, + unsigned flags, + struct pipe_fence_handle **fence); + /* r300_hyperz.c */ void r300_update_hyperz_state(struct r300_context* r300); diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index 60f8305856..b28be9367f 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -1218,7 +1218,7 @@ validate: if (flushed) return FALSE; - r300->context.flush(&r300->context, 0, NULL); + r300_flush(&r300->context, R300_FLUSH_ASYNC, NULL); flushed = TRUE; goto validate; } diff --git a/src/gallium/drivers/r300/r300_flush.c b/src/gallium/drivers/r300/r300_flush.c index 9c41a1383c..fa0926868b 100644 --- a/src/gallium/drivers/r300/r300_flush.c +++ b/src/gallium/drivers/r300/r300_flush.c @@ -31,9 +31,10 @@ #include "r300_cs.h" #include "r300_emit.h" -static void r300_flush(struct pipe_context* pipe, - unsigned flags, - struct pipe_fence_handle** fence) + +void r300_flush(struct pipe_context *pipe, + unsigned flags, + struct pipe_fence_handle **fence) { struct r300_context *r300 = r300_context(pipe); struct r300_atom *atom; @@ -61,7 +62,7 @@ static void r300_flush(struct pipe_context* pipe, r500_emit_index_bias(r300, 0); r300->flush_counter++; - r300->rws->cs_flush(r300->cs); + r300->rws->cs_flush(r300->cs, flags); r300->dirty_hw = 0; /* New kitchen sink, baby. */ @@ -83,20 +84,24 @@ static void r300_flush(struct pipe_context* pipe, * and we cannot emit an empty CS. We must write some regs then. */ CS_LOCALS(r300); OUT_CS_REG(RB3D_COLOR_CHANNEL_MASK, 0); - r300->rws->cs_flush(r300->cs); + r300->rws->cs_flush(r300->cs, flags); } else { /* Even if hw is not dirty, we should at least reset the CS in case * the space checking failed for the first draw operation. */ - r300->rws->cs_flush(r300->cs); + r300->rws->cs_flush(r300->cs, flags); } } +} - if (flags & PIPE_FLUSH_FRAME) { - r300->rws->cs_sync_flush(r300->cs); - } +static void r300_flush_wrapped(struct pipe_context *pipe, + unsigned flags, + struct pipe_fence_handle **fence) +{ + /* don't use the flags param, it means something else */ + r300_flush(pipe, 0, fence); } void r300_init_flush_functions(struct r300_context* r300) { - r300->context.flush = r300_flush; + r300->context.flush = r300_flush_wrapped; } diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index 300cb86acf..26594dabe4 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -219,7 +219,7 @@ static boolean r300_reserve_cs_dwords(struct r300_context *r300, /* Reserve requested CS space. */ if (cs_dwords > (R300_MAX_CMDBUF_DWORDS - r300->cs->cdw)) { - r300->context.flush(&r300->context, 0, NULL); + r300_flush(&r300->context, R300_FLUSH_ASYNC, NULL); flushed = TRUE; } diff --git a/src/gallium/drivers/r300/r300_transfer.c b/src/gallium/drivers/r300/r300_transfer.c index 0b73162abd..928c86be0c 100644 --- a/src/gallium/drivers/r300/r300_transfer.c +++ b/src/gallium/drivers/r300/r300_transfer.c @@ -72,6 +72,7 @@ static void r300_copy_into_tiled_texture(struct pipe_context *ctx, transfer->box.x, transfer->box.y, transfer->box.z, &r300transfer->linear_texture->b.b.b, 0, &src_box); + /* XXX remove this. */ ctx->flush(ctx, 0, NULL); } @@ -152,7 +153,7 @@ r300_texture_get_transfer(struct pipe_context *ctx, if (!trans->linear_texture) { /* Oh crap, the thing can't create the texture. * Let's flush and try again. */ - ctx->flush(ctx, 0, NULL); + r300_flush(ctx, 0, NULL); trans->linear_texture = r300_resource( ctx->screen->resource_create(ctx->screen, @@ -176,13 +177,7 @@ r300_texture_get_transfer(struct pipe_context *ctx, assert(!trans->linear_texture->tex.microtile && !trans->linear_texture->tex.macrotile[0]); - /* Set the stride. - * - * Even though we are using an internal texture for this, - * the transfer level, box and usage parameters still reflect - * the arguments received to get_transfer. We just do the - * right thing internally. - */ + /* Set the stride. */ trans->transfer.stride = trans->linear_texture->tex.stride_in_bytes[0]; @@ -192,7 +187,7 @@ r300_texture_get_transfer(struct pipe_context *ctx, r300_copy_from_tiled_texture(ctx, trans); /* Always referenced in the blit. */ - ctx->flush(ctx, 0, NULL); + r300_flush(ctx, 0, NULL); } return &trans->transfer; } @@ -202,8 +197,9 @@ r300_texture_get_transfer(struct pipe_context *ctx, trans->transfer.stride = tex->tex.stride_in_bytes[level]; trans->offset = r300_texture_get_offset(tex, level, box->z); - if (referenced_cs) - ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL); + if (referenced_cs && + !(usage & PIPE_TRANSFER_UNSYNCHRONIZED)) + r300_flush(ctx, 0, NULL); return &trans->transfer; } return NULL; diff --git a/src/gallium/drivers/r300/r300_winsys.h b/src/gallium/drivers/r300/r300_winsys.h index c0b66899f8..3a6798a542 100644 --- a/src/gallium/drivers/r300/r300_winsys.h +++ b/src/gallium/drivers/r300/r300_winsys.h @@ -35,6 +35,7 @@ #include "pipe/p_state.h" #define R300_MAX_CMDBUF_DWORDS (16 * 1024) +#define R300_FLUSH_ASYNC (1 << 0) struct winsys_handle; struct r300_winsys_screen; @@ -265,15 +266,9 @@ struct r300_winsys_screen { * Flush a command stream. * * \param cs A command stream to flush. + * \param flags, R300_FLUSH_ASYNC or 0. */ - void (*cs_flush)(struct r300_winsys_cs *cs); - - /** - * Wait until the last flush is completed. - * - * \param cs A command stream. - */ - void (*cs_sync_flush)(struct r300_winsys_cs *cs); + void (*cs_flush)(struct r300_winsys_cs *cs, unsigned flags); /** * Set a flush callback which is called from winsys when flush is @@ -284,7 +279,7 @@ struct r300_winsys_screen { * \param user A user pointer that will be passed to the flush callback. */ void (*cs_set_flush)(struct r300_winsys_cs *cs, - void (*flush)(void *), + void (*flush)(void *ctx, unsigned flags), void *user); /** -- cgit v1.2.3