From a852615946b98de2d832d4907f09649803577db7 Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Sun, 26 Sep 2010 12:06:46 -0400 Subject: [PATCH] r600g: disable early cull optimization when occlusion query running When occlusion query are running we want to have accurate fragment count thus disable any early culling optimization GPU has. Based on work from Bas Nieuwenhuizen Signed-off-by: Jerome Glisse --- src/gallium/drivers/r600/r600.h | 1 + src/gallium/winsys/r600/drm/evergreen_state.c | 13 ++++++++++++ src/gallium/winsys/r600/drm/r600_priv.h | 21 +++++++++++++++++++ src/gallium/winsys/r600/drm/r600_state2.c | 16 ++++++++++++++ src/gallium/winsys/r600/drm/r600d.h | 10 +++++++++ 5 files changed, 61 insertions(+) diff --git a/src/gallium/drivers/r600/r600.h b/src/gallium/drivers/r600/r600.h index 65b029b065f..17d34409dc4 100644 --- a/src/gallium/drivers/r600/r600.h +++ b/src/gallium/drivers/r600/r600.h @@ -246,6 +246,7 @@ struct r600_context { struct radeon_bo **bo; u32 *pm4; struct list_head query_list; + unsigned num_query_running; }; struct r600_draw { diff --git a/src/gallium/winsys/r600/drm/evergreen_state.c b/src/gallium/winsys/r600/drm/evergreen_state.c index f2038638d6b..860c836e858 100644 --- a/src/gallium/winsys/r600/drm/evergreen_state.c +++ b/src/gallium/winsys/r600/drm/evergreen_state.c @@ -75,6 +75,7 @@ static const struct r600_reg evergreen_reg_list[] = { {0, 0, R_009100_SPI_CONFIG_CNTL}, {0, 0, R_00913C_SPI_CONFIG_CNTL_1}, {0, 0, R_028000_DB_RENDER_CONTROL}, + {0, 0, R_028004_DB_COUNT_CONTROL}, {0, 0, R_028008_DB_DEPTH_VIEW}, {0, 0, R_02800C_DB_RENDER_OVERRIDE}, {0, 0, R_028010_DB_RENDER_OVERRIDE2}, @@ -589,6 +590,18 @@ void evergreen_context_draw(struct r600_context *ctx, const struct r600_draw *dr } } + /* queries need some special values */ + if (ctx->num_query_running) { + r600_context_reg(ctx, R600_GROUP_CONTEXT, + R_028004_DB_COUNT_CONTROL, + S_028004_PERFECT_ZPASS_COUNTS(1), + S_028004_PERFECT_ZPASS_COUNTS(1)); + r600_context_reg(ctx, R600_GROUP_CONTEXT, + R_02800C_DB_RENDER_OVERRIDE, + S_02800C_NOOP_CULL_DISABLE(1), + S_02800C_NOOP_CULL_DISABLE(1)); + } + if ((ctx->pm4_dirty_cdwords + ndwords + ctx->pm4_cdwords) > ctx->pm4_ndwords) { /* need to flush */ r600_context_flush(ctx); diff --git a/src/gallium/winsys/r600/drm/r600_priv.h b/src/gallium/winsys/r600/drm/r600_priv.h index 92b2eb1dff1..25a65c6a10f 100644 --- a/src/gallium/winsys/r600/drm/r600_priv.h +++ b/src/gallium/winsys/r600/drm/r600_priv.h @@ -54,4 +54,25 @@ struct r600_reg { /* radeon_pciid.c */ unsigned radeon_family_from_device(unsigned device); + +static void inline r600_context_reg(struct r600_context *ctx, unsigned group_id, + unsigned offset, unsigned value, + unsigned mask) +{ + struct r600_group *group = &ctx->groups[group_id]; + struct r600_group_block *block; + unsigned id; + + id = group->offset_block_id[(offset - group->start_offset) >> 2]; + block = &group->blocks[id]; + id = (offset - block->start_offset) >> 2; + block->pm4[id] &= ~mask; + block->pm4[id] |= value; + if (!(block->status & R600_BLOCK_STATUS_DIRTY)) { + ctx->pm4_dirty_cdwords += 2 + block->pm4_ndwords; + } + block->status |= R600_BLOCK_STATUS_ENABLED; + block->status |= R600_BLOCK_STATUS_DIRTY; +} + #endif diff --git a/src/gallium/winsys/r600/drm/r600_state2.c b/src/gallium/winsys/r600/drm/r600_state2.c index e1f32da91b0..d60c37fc90d 100644 --- a/src/gallium/winsys/r600/drm/r600_state2.c +++ b/src/gallium/winsys/r600/drm/r600_state2.c @@ -943,6 +943,20 @@ void r600_context_draw(struct r600_context *ctx, const struct r600_draw *draw) } } + /* queries need some special values */ + if (ctx->num_query_running) { + if (ctx->radeon->family >= CHIP_RV770) { + r600_context_reg(ctx, R600_GROUP_CONTEXT, + R_028D0C_DB_RENDER_CONTROL, + S_028D0C_R700_PERFECT_ZPASS_COUNTS(1), + S_028D0C_R700_PERFECT_ZPASS_COUNTS(1)); + } + r600_context_reg(ctx, R600_GROUP_CONTEXT, + R_028D10_DB_RENDER_OVERRIDE, + S_028D10_NOOP_CULL_DISABLE(1), + S_028D10_NOOP_CULL_DISABLE(1)); + } + if ((ctx->pm4_dirty_cdwords + ndwords + ctx->pm4_cdwords) > ctx->pm4_ndwords) { /* need to flush */ r600_context_flush(ctx); @@ -1181,6 +1195,7 @@ void r600_query_begin(struct r600_context *ctx, struct r600_query *query) query->state |= R600_QUERY_STATE_STARTED; query->state ^= R600_QUERY_STATE_ENDED; + ctx->num_query_running++; } void r600_query_end(struct r600_context *ctx, struct r600_query *query) @@ -1197,6 +1212,7 @@ void r600_query_end(struct r600_context *ctx, struct r600_query *query) query->num_results += 16; query->state ^= R600_QUERY_STATE_STARTED; query->state |= R600_QUERY_STATE_ENDED; + ctx->num_query_running--; } struct r600_query *r600_context_query_create(struct r600_context *ctx, unsigned query_type) diff --git a/src/gallium/winsys/r600/drm/r600d.h b/src/gallium/winsys/r600/drm/r600d.h index 3c60e5c11a7..fcce2934d39 100644 --- a/src/gallium/winsys/r600/drm/r600d.h +++ b/src/gallium/winsys/r600/drm/r600d.h @@ -839,6 +839,16 @@ #define R_028800_DB_DEPTH_CONTROL 0x028800 #define R_02880C_DB_SHADER_CONTROL 0x02880C #define R_028D0C_DB_RENDER_CONTROL 0x028D0C +#define S_028D0C_DEPTH_CLEAR_ENABLE(x) (((x) & 0x1) << 0) +#define S_028D0C_STENCIL_CLEAR_ENABLE(x) (((x) & 0x1) << 1) +#define S_028D0C_DEPTH_COPY_ENABLE(x) (((x) & 0x1) << 2) +#define S_028D0C_STENCIL_COPY_ENABLE(x) (((x) & 0x1) << 3) +#define S_028D0C_RESUMMARIZE_ENABLE(x) (((x) & 0x1) << 4) +#define S_028D0C_STENCIL_COMPRESS_DISABLE(x) (((x) & 0x1) << 5) +#define S_028D0C_DEPTH_COMPRESS_DISABLE(x) (((x) & 0x1) << 6) +#define S_028D0C_COPY_CENTROID(x) (((x) & 0x1) << 7) +#define S_028D0C_COPY_SAMPLE(x) (((x) & 0x1) << 8) +#define S_028D0C_R700_PERFECT_ZPASS_COUNTS(x) (((x) & 0x1) << 15) #define R_028D10_DB_RENDER_OVERRIDE 0x028D10 #define R_028D2C_DB_SRESULTS_COMPARE_STATE1 0x028D2C #define R_028D30_DB_PRELOAD_CONTROL 0x028D30 -- 2.30.2