r600g: disable early cull optimization when occlusion query running
authorJerome Glisse <jglisse@redhat.com>
Sun, 26 Sep 2010 16:06:46 +0000 (12:06 -0400)
committerJerome Glisse <jglisse@redhat.com>
Sun, 26 Sep 2010 16:06:46 +0000 (12:06 -0400)
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>
src/gallium/drivers/r600/r600.h
src/gallium/winsys/r600/drm/evergreen_state.c
src/gallium/winsys/r600/drm/r600_priv.h
src/gallium/winsys/r600/drm/r600_state2.c
src/gallium/winsys/r600/drm/r600d.h

index 65b029b..17d3440 100644 (file)
@@ -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 {
index f203863..860c836 100644 (file)
@@ -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);
index 92b2eb1..25a65c6 100644 (file)
@@ -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
index e1f32da..d60c37f 100644 (file)
@@ -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)
index 3c60e5c..fcce293 100644 (file)
 #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