summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJerome Glisse <jglisse@redhat.com>2010-09-26 12:06:46 -0400
committerJerome Glisse <jglisse@redhat.com>2010-09-26 12:06:46 -0400
commita852615946b98de2d832d4907f09649803577db7 (patch)
tree2d5def85d8c6c573d9f839cbf28673e24783fb7a /src
parent6f16e497af9bf5938541d2088e91cc79f1641a19 (diff)
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 <bas@basnieuwenhuizen.nl> Signed-off-by: Jerome Glisse <jglisse@redhat.com>
Diffstat (limited to 'src')
-rw-r--r--src/gallium/drivers/r600/r600.h1
-rw-r--r--src/gallium/winsys/r600/drm/evergreen_state.c13
-rw-r--r--src/gallium/winsys/r600/drm/r600_priv.h21
-rw-r--r--src/gallium/winsys/r600/drm/r600_state2.c16
-rw-r--r--src/gallium/winsys/r600/drm/r600d.h10
5 files changed, 61 insertions, 0 deletions
diff --git a/src/gallium/drivers/r600/r600.h b/src/gallium/drivers/r600/r600.h
index 65b029b065..17d34409dc 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 f2038638d6..860c836e85 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 92b2eb1dff..25a65c6a10 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 e1f32da91b..d60c37fc90 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 3c60e5c11a..fcce2934d3 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