summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/gallium/drivers/r600/r600.h1
-rw-r--r--src/gallium/winsys/r600/drm/r600_hw_context.c36
2 files changed, 28 insertions, 9 deletions
diff --git a/src/gallium/drivers/r600/r600.h b/src/gallium/drivers/r600/r600.h
index 0b0df9d019b..33aa45088a8 100644
--- a/src/gallium/drivers/r600/r600.h
+++ b/src/gallium/drivers/r600/r600.h
@@ -235,6 +235,7 @@ struct r600_query {
#define R600_CONTEXT_DRAW_PENDING (1 << 0)
#define R600_CONTEXT_DST_CACHES_DIRTY (1 << 1)
+#define R600_CONTEXT_CHECK_EVENT_FLUSH (1 << 2)
struct r600_context {
struct radeon *radeon;
diff --git a/src/gallium/winsys/r600/drm/r600_hw_context.c b/src/gallium/winsys/r600/drm/r600_hw_context.c
index 150485d3fe1..b8a8108fb12 100644
--- a/src/gallium/winsys/r600/drm/r600_hw_context.c
+++ b/src/gallium/winsys/r600/drm/r600_hw_context.c
@@ -797,19 +797,33 @@ void r600_context_bo_flush(struct r600_context *ctx, unsigned flush_flags,
unsigned flush_mask, struct r600_bo *rbo)
{
struct radeon_bo *bo;
+ boolean use_event_flush = FALSE;
+
bo = rbo->bo;
/* if bo has already been flushed */
if (!(~bo->last_flush & flush_flags)) {
bo->last_flush &= flush_mask;
return;
}
- ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_SURFACE_SYNC, 3, ctx->predicate_drawing);
- ctx->pm4[ctx->pm4_cdwords++] = flush_flags;
- ctx->pm4[ctx->pm4_cdwords++] = (bo->size + 255) >> 8;
- ctx->pm4[ctx->pm4_cdwords++] = 0x00000000;
- ctx->pm4[ctx->pm4_cdwords++] = 0x0000000A;
- ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_NOP, 0, ctx->predicate_drawing);
- ctx->pm4[ctx->pm4_cdwords++] = bo->reloc_id;
+
+ if ((ctx->radeon->family < CHIP_RV770) &&
+ (G_0085F0_CB_ACTION_ENA(flush_flags) ||
+ G_0085F0_DB_ACTION_ENA(flush_flags)))
+ use_event_flush = TRUE;
+
+ if (use_event_flush && (ctx->flags & R600_CONTEXT_CHECK_EVENT_FLUSH)) {
+ ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_EVENT_WRITE, 0, ctx->predicate_drawing);
+ ctx->pm4[ctx->pm4_cdwords++] = EVENT_TYPE(EVENT_TYPE_CACHE_FLUSH_AND_INV_EVENT) | EVENT_INDEX(0);
+ ctx->flags &= ~R600_CONTEXT_CHECK_EVENT_FLUSH;
+ } else {
+ ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_SURFACE_SYNC, 3, ctx->predicate_drawing);
+ ctx->pm4[ctx->pm4_cdwords++] = flush_flags;
+ ctx->pm4[ctx->pm4_cdwords++] = (bo->size + 255) >> 8;
+ ctx->pm4[ctx->pm4_cdwords++] = 0x00000000;
+ ctx->pm4[ctx->pm4_cdwords++] = 0x0000000A;
+ ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_NOP, 0, ctx->predicate_drawing);
+ ctx->pm4[ctx->pm4_cdwords++] = bo->reloc_id;
+ }
bo->last_flush = (bo->last_flush | flush_flags) & flush_mask;
}
@@ -1119,6 +1133,7 @@ void r600_context_block_emit_dirty(struct r600_context *ctx, struct r600_block *
goto out;
}
+ ctx->flags |= R600_CONTEXT_CHECK_EVENT_FLUSH;
for (int j = 0; j < block->nreg; j++) {
if (block->pm4_bo_index[j]) {
/* find relocation */
@@ -1132,6 +1147,7 @@ void r600_context_block_emit_dirty(struct r600_context *ctx, struct r600_block *
block->reloc[id].bo);
}
}
+ ctx->flags &= ~R600_CONTEXT_CHECK_EVENT_FLUSH;
memcpy(&ctx->pm4[ctx->pm4_cdwords], block->pm4, block->pm4_ndwords * 4);
ctx->pm4_cdwords += block->pm4_ndwords;
@@ -1155,6 +1171,7 @@ void r600_context_flush_dest_caches(struct r600_context *ctx)
{
struct r600_bo *cb[8];
struct r600_bo *db;
+ int i;
if (!(ctx->flags & R600_CONTEXT_DST_CACHES_DIRTY))
return;
@@ -1169,8 +1186,9 @@ void r600_context_flush_dest_caches(struct r600_context *ctx)
cb[6] = r600_context_reg_bo(ctx, R_028058_CB_COLOR6_BASE);
cb[7] = r600_context_reg_bo(ctx, R_02805C_CB_COLOR7_BASE);
+ ctx->flags |= R600_CONTEXT_CHECK_EVENT_FLUSH;
/* flush the color buffers */
- for (int i = 0; i < 8; i++) {
+ for (i = 0; i < 8; i++) {
if (!cb[i])
continue;
@@ -1182,7 +1200,7 @@ void r600_context_flush_dest_caches(struct r600_context *ctx)
if (db) {
r600_context_bo_flush(ctx, S_0085F0_DB_ACTION_ENA(1), 0, db);
}
-
+ ctx->flags &= ~R600_CONTEXT_CHECK_EVENT_FLUSH;
ctx->flags &= ~R600_CONTEXT_DST_CACHES_DIRTY;
}