r600g: add a depth misc state which depends on occlusion queries
authorMarek Olšák <maraeo@gmail.com>
Thu, 2 Feb 2012 13:01:12 +0000 (14:01 +0100)
committerMarek Olšák <maraeo@gmail.com>
Tue, 21 Feb 2012 20:42:27 +0000 (21:42 +0100)
This is a state which is derived from other states and is actually the first
state which doesn't correspond to any gallium state.

There are two state flags:
  bool occlusion_query_enabled
  bool flush_depthstencil_enabled

Additional flags can be added later if needed, e.g. bool hiz_enabled.
The emit function will have to figure out the register values by itself.

It basically just emits the registers when the state changes.
This commit also adds a few helper functions for writing registers directly
into a command stream.

src/gallium/drivers/r600/evergreen_hw_context.c
src/gallium/drivers/r600/evergreen_state.c
src/gallium/drivers/r600/r600.h
src/gallium/drivers/r600/r600_hw_context.c
src/gallium/drivers/r600/r600_hw_context_priv.h
src/gallium/drivers/r600/r600_pipe.c
src/gallium/drivers/r600/r600_pipe.h
src/gallium/drivers/r600/r600_query.c
src/gallium/drivers/r600/r600_state.c
src/gallium/drivers/r600/r600_state_common.c

index f3b207bb75b244a94c0481e45299a103e955d0f5..a7ba04d44c41649d5c7629754deed2a3bf9baa4e 100644 (file)
@@ -49,9 +49,7 @@ static const struct r600_reg evergreen_ctl_const_list[] = {
 
 static const struct r600_reg evergreen_context_reg_list[] = {
        {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, 0, 0},
        {GROUP_FORCE_NEW_BLOCK, 0, 0},
        {R_028014_DB_HTILE_DATA_BASE, REG_FLAG_NEED_BO, 0},
@@ -356,9 +354,7 @@ static const struct r600_reg evergreen_context_reg_list[] = {
 
 static const struct r600_reg cayman_context_reg_list[] = {
        {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, 0, 0},
        {GROUP_FORCE_NEW_BLOCK, 0, 0},
        {R_028014_DB_HTILE_DATA_BASE, REG_FLAG_NEED_BO, 0},
@@ -981,24 +977,6 @@ void evergreen_context_pipe_state_set_vs_sampler(struct r600_context *ctx, struc
        evergreen_context_pipe_state_set_sampler_border(ctx, state, R_00A414_TD_VS_SAMPLER0_BORDER_INDEX, id);
 }
 
-/* XXX make a proper state object (atom or pipe_state) out of this */
-void evergreen_context_draw_prepare(struct r600_context *ctx)
-{
-       struct r600_pipe_dsa *dsa = (struct r600_pipe_dsa*)ctx->states[R600_PIPE_STATE_DSA];
-       struct radeon_winsys_cs *cs = ctx->cs;
-
-       /* queries need some special values
-        * (this is non-zero if any query is active) */
-       if (ctx->num_cs_dw_queries_suspend) {
-               cs->buf[cs->cdw++] = PKT3(PKT3_SET_CONTEXT_REG, 1, 0);
-               cs->buf[cs->cdw++] = (R_028004_DB_COUNT_CONTROL - EVERGREEN_CONTEXT_REG_OFFSET) >> 2;
-               cs->buf[cs->cdw++] = S_028004_PERFECT_ZPASS_COUNTS(1);
-               cs->buf[cs->cdw++] = PKT3(PKT3_SET_CONTEXT_REG, 1, 0);
-               cs->buf[cs->cdw++] = (R_02800C_DB_RENDER_OVERRIDE - EVERGREEN_CONTEXT_REG_OFFSET) >> 2;
-               cs->buf[cs->cdw++] = dsa->db_render_override | S_02800C_NOOP_CULL_DISABLE(1);
-       }
-}
-
 void evergreen_flush_vgt_streamout(struct r600_context *ctx)
 {
        struct radeon_winsys_cs *cs = ctx->cs;
index 3667aba5af898d9de6939eb5581144c68b7a9841..94dc562069e46a6401aa7e5cf4f0dadb810edb6d 100644 (file)
@@ -716,7 +716,7 @@ static void *evergreen_create_dsa_state(struct pipe_context *ctx,
        struct r600_context *rctx = (struct r600_context *)ctx;
        struct r600_pipe_dsa *dsa = CALLOC_STRUCT(r600_pipe_dsa);
        unsigned db_depth_control, alpha_test_control, alpha_ref;
-       unsigned db_render_override, db_render_control;
+       unsigned db_render_control;
        struct r600_pipe_state *rstate;
 
        if (dsa == NULL) {
@@ -764,9 +764,6 @@ static void *evergreen_create_dsa_state(struct pipe_context *ctx,
 
        /* misc */
        db_render_control = 0;
-       db_render_override = S_02800C_FORCE_HIZ_ENABLE(V_02800C_FORCE_DISABLE) |
-               S_02800C_FORCE_HIS_ENABLE0(V_02800C_FORCE_DISABLE) |
-               S_02800C_FORCE_HIS_ENABLE1(V_02800C_FORCE_DISABLE);
        /* TODO db_render_override depends on query */
        r600_pipe_state_add_reg(rstate, R_028028_DB_STENCIL_CLEAR, 0x00000000, NULL, 0);
        r600_pipe_state_add_reg(rstate, R_02802C_DB_DEPTH_CLEAR, 0x3F800000, NULL, 0);
@@ -777,13 +774,10 @@ static void *evergreen_create_dsa_state(struct pipe_context *ctx,
         * STENCIL_EXPORT_ENABLE and KILL_ENABLE are controlled by
         * evergreen_pipe_shader_ps().*/
        r600_pipe_state_add_reg(rstate, R_028000_DB_RENDER_CONTROL, db_render_control, NULL, 0);
-       r600_pipe_state_add_reg(rstate, R_02800C_DB_RENDER_OVERRIDE, db_render_override, NULL, 0);
        r600_pipe_state_add_reg(rstate, R_028AC0_DB_SRESULTS_COMPARE_STATE0, 0x0, NULL, 0);
        r600_pipe_state_add_reg(rstate, R_028AC4_DB_SRESULTS_COMPARE_STATE1, 0x0, NULL, 0);
        r600_pipe_state_add_reg(rstate, R_028AC8_DB_PRELOAD_CONTROL, 0x0, NULL, 0);
        r600_pipe_state_add_reg(rstate, R_028B70_DB_ALPHA_TO_MASK, 0x0000AA00, NULL, 0);
-       dsa->db_render_override = db_render_override;
-
        return rstate;
 }
 
@@ -1757,8 +1751,29 @@ static void evergreen_set_framebuffer_state(struct pipe_context *ctx,
        }
 }
 
+static void evergreen_emit_db_misc_state(struct r600_context *rctx, struct r600_atom *atom)
+{
+       struct radeon_winsys_cs *cs = rctx->cs;
+       struct r600_atom_db_misc_state *a = (struct r600_atom_db_misc_state*)atom;
+       unsigned db_count_control = 0;
+       unsigned db_render_override =
+               S_02800C_FORCE_HIZ_ENABLE(V_02800C_FORCE_DISABLE) |
+               S_02800C_FORCE_HIS_ENABLE0(V_02800C_FORCE_DISABLE) |
+               S_02800C_FORCE_HIS_ENABLE1(V_02800C_FORCE_DISABLE);
+
+       if (a->occlusion_query_enabled) {
+               db_count_control |= S_028004_PERFECT_ZPASS_COUNTS(1);
+               db_render_override |= S_02800C_NOOP_CULL_DISABLE(1);
+       }
+
+       r600_write_context_reg(cs, R_028004_DB_COUNT_CONTROL, db_count_control);
+       r600_write_context_reg(cs, R_02800C_DB_RENDER_OVERRIDE, db_render_override);
+}
+
 void evergreen_init_state_functions(struct r600_context *rctx)
 {
+       r600_init_atom(&rctx->atom_db_misc_state.atom, evergreen_emit_db_misc_state, 6, 0);
+
        rctx->context.create_blend_state = evergreen_create_blend_state;
        rctx->context.create_depth_stencil_alpha_state = evergreen_create_dsa_state;
        rctx->context.create_fs_state = r600_create_shader_state;
@@ -2631,6 +2646,7 @@ void *evergreen_create_db_flush_dsa(struct r600_context *rctx)
                                S_028000_STENCIL_COPY_ENABLE(1) |
                                S_028000_COPY_CENTROID(1),
                                NULL, 0);
+       /* Don't set the 'is_flush' flag in r600_pipe_dsa, evergreen doesn't need it. */
        return rstate;
 }
 
index 1bb6c4bdee40858c83b51592c66216793cf8c561..a792e94b06ba65107d17b4ae0051cc1c12b1ea87 100644 (file)
@@ -208,7 +208,6 @@ void r600_context_pipe_state_set_fs_resource(struct r600_context *ctx, struct r6
 void r600_context_pipe_state_set_ps_sampler(struct r600_context *ctx, struct r600_pipe_state *state, unsigned id);
 void r600_context_pipe_state_set_vs_sampler(struct r600_context *ctx, struct r600_pipe_state *state, unsigned id);
 void r600_context_flush(struct r600_context *ctx, unsigned flags);
-void r600_context_draw_prepare(struct r600_context *ctx);
 
 struct r600_query *r600_context_query_create(struct r600_context *ctx, unsigned query_type);
 void r600_context_query_destroy(struct r600_context *ctx, struct r600_query *query);
@@ -236,7 +235,6 @@ void r600_context_block_emit_dirty(struct r600_context *ctx, struct r600_block *
 void r600_context_block_resource_emit_dirty(struct r600_context *ctx, struct r600_block *block);
 
 int evergreen_context_init(struct r600_context *ctx);
-void evergreen_context_draw_prepare(struct r600_context *ctx);
 void evergreen_context_pipe_state_set_ps_resource(struct r600_context *ctx, struct r600_pipe_resource_state *state, unsigned rid);
 void evergreen_context_pipe_state_set_vs_resource(struct r600_context *ctx, struct r600_pipe_resource_state *state, unsigned rid);
 void evergreen_context_pipe_state_set_fs_resource(struct r600_context *ctx, struct r600_pipe_resource_state *state, unsigned rid);
index 3632c6d14c2951d705a93938e42c480960789132..c59b853637abedd2e8089ae6159c27bbed6df411 100644 (file)
@@ -397,8 +397,6 @@ static const struct r600_reg r600_context_reg_list[] = {
        {R_028004_DB_DEPTH_VIEW, 0, 0},
        {GROUP_FORCE_NEW_BLOCK, 0, 0},
        {R_028010_DB_DEPTH_INFO, REG_FLAG_NEED_BO, 0},
-       {R_028D0C_DB_RENDER_CONTROL, 0, 0},
-       {R_028D10_DB_RENDER_OVERRIDE, 0, 0},
        {R_028D24_DB_HTILE_SURFACE, 0, 0},
        {R_028D30_DB_PRELOAD_CONTROL, 0, 0},
        {R_028D34_DB_PREFETCH_LIMIT, 0, 0},
@@ -1233,26 +1231,6 @@ void r600_context_block_resource_emit_dirty(struct r600_context *ctx, struct r60
        LIST_DELINIT(&block->list);
 }
 
-/* XXX make a proper state object (atom or pipe_state) out of this */
-void r600_context_draw_prepare(struct r600_context *ctx)
-{
-       struct r600_pipe_dsa *dsa = (struct r600_pipe_dsa*)ctx->states[R600_PIPE_STATE_DSA];
-       struct radeon_winsys_cs *cs = ctx->cs;
-
-       /* queries need some special values
-        * (this is non-zero if any query is active) */
-       if (ctx->num_cs_dw_queries_suspend) {
-               if (ctx->family >= CHIP_RV770) {
-                       cs->buf[cs->cdw++] = PKT3(PKT3_SET_CONTEXT_REG, 1, 0);
-                       cs->buf[cs->cdw++] = (R_028D0C_DB_RENDER_CONTROL - R600_CONTEXT_REG_OFFSET) >> 2;
-                       cs->buf[cs->cdw++] = dsa->db_render_control | S_028D0C_R700_PERFECT_ZPASS_COUNTS(1);
-               }
-               cs->buf[cs->cdw++] = PKT3(PKT3_SET_CONTEXT_REG, 1, 0);
-               cs->buf[cs->cdw++] = (R_028D10_DB_RENDER_OVERRIDE - R600_CONTEXT_REG_OFFSET) >> 2;
-               cs->buf[cs->cdw++] = dsa->db_render_override | S_028D10_NOOP_CULL_DISABLE(1);
-       }
-}
-
 void r600_inval_shader_cache(struct r600_context *ctx)
 {
        ctx->atom_surface_sync.flush_flags |= S_0085F0_SH_ACTION_ENA(1);
@@ -1350,6 +1328,7 @@ void r600_context_flush(struct r600_context *ctx, unsigned flags)
        ctx->flags = 0;
 
        r600_emit_atom(ctx, &ctx->atom_start_cs.atom);
+       r600_atom_dirty(ctx, &ctx->atom_db_misc_state.atom);
 
        if (streamout_suspended) {
                ctx->streamout_start = TRUE;
index 1e5713873d9206fc5385d2647e0b9c5e4ff21627..61009af1ab2ae6ea9cc6bcc1a8efc24205eaadbc 100644 (file)
@@ -30,7 +30,7 @@
 #include "util/u_hash_table.h"
 #include "os/os_thread.h"
 
-#define R600_MAX_DRAW_CS_DWORDS 17
+#define R600_MAX_DRAW_CS_DWORDS 11
 
 #define PKT_COUNT_C                     0xC000FFFF
 #define PKT_COUNT_S(x)                  (((x) & 0x3FFF) << 16)
index c8ee331789bb887f3a425e484fd5599e21a7dfbe..3d35ed289ce0a38a48b791325830df213ff47fe2 100644 (file)
@@ -232,6 +232,8 @@ static struct pipe_context *r600_create_context(struct pipe_screen *screen, void
        rctx->family = rscreen->family;
        rctx->chip_class = rscreen->chip_class;
 
+       LIST_INITHEAD(&rctx->dirty_states);
+
        r600_init_blit_functions(rctx);
        r600_init_query_functions(rctx);
        r600_init_context_resource_functions(rctx);
@@ -293,8 +295,6 @@ static struct pipe_context *r600_create_context(struct pipe_screen *screen, void
                return NULL;
        }
 
-       LIST_INITHEAD(&rctx->dirty_states);
-
        r600_get_backend_mask(rctx); /* this emits commands and must be last */
 
        return &rctx->context;
index e4c6df7d772edd2b6da2cbdff7197e5c368ff061..4d5b67aa1f69432360c5d6f64768c9c1505d2e73 100644 (file)
@@ -80,6 +80,12 @@ struct r600_atom_surface_sync {
        unsigned flush_flags; /* CP_COHER_CNTL */
 };
 
+struct r600_atom_db_misc_state {
+       struct r600_atom atom;
+       bool occlusion_query_enabled;
+       bool flush_depthstencil_enabled;
+};
+
 enum r600_pipe_state_id {
        R600_PIPE_STATE_BLEND = 0,
        R600_PIPE_STATE_BLEND_COLOR,
@@ -157,10 +163,9 @@ struct r600_pipe_blend {
 struct r600_pipe_dsa {
        struct r600_pipe_state          rstate;
        unsigned                        alpha_ref;
-       unsigned                        db_render_override;
-       unsigned                        db_render_control;
        ubyte                           valuemask[2];
        ubyte                           writemask[2];
+       bool                            is_flush;
 };
 
 struct r600_vertex_element
@@ -287,6 +292,7 @@ struct r600_context {
        struct r600_command_buffer      atom_start_cs; /* invariant state mostly */
        struct r600_atom_surface_sync   atom_surface_sync;
        struct r600_atom                atom_r6xx_flush_and_inv;
+       struct r600_atom_db_misc_state  atom_db_misc_state;
 
        /* Below are variables from the old r600_context.
         */
@@ -302,6 +308,7 @@ struct r600_context {
        unsigned                ctx_pm4_ndwords;
 
        /* The list of active queries. Only one query of each type can be active. */
+       int                     num_occlusion_queries;
        struct list_head        active_query_list;
        unsigned                num_cs_dw_queries_suspend;
        unsigned                num_cs_dw_streamout_end;
@@ -435,6 +442,9 @@ void r600_translate_index_buffer(struct r600_context *r600,
                                 unsigned count);
 
 /* r600_state_common.c */
+void r600_init_atom(struct r600_atom *atom,
+                   void (*emit)(struct r600_context *ctx, struct r600_atom *state),
+                   unsigned num_dw, enum r600_atom_flags flags);
 void r600_init_common_atoms(struct r600_context *rctx);
 unsigned r600_get_cb_flush_flags(struct r600_context *rctx);
 void r600_texture_barrier(struct pipe_context *ctx);
@@ -553,6 +563,57 @@ static INLINE void r600_store_ctl_const(struct r600_command_buffer *cb, unsigned
 void r600_init_command_buffer(struct r600_command_buffer *cb, unsigned num_dw, enum r600_atom_flags flags);
 void r600_release_command_buffer(struct r600_command_buffer *cb);
 
+/*
+ * Helpers for emitting state into a command stream directly.
+ */
+
+static INLINE void r600_write_value(struct radeon_winsys_cs *cs, unsigned value)
+{
+       cs->buf[cs->cdw++] = value;
+}
+
+static INLINE void r600_write_config_reg_seq(struct radeon_winsys_cs *cs, unsigned reg, unsigned num)
+{
+       assert(reg < R600_CONTEXT_REG_OFFSET);
+       assert(cs->cdw+2+num <= RADEON_MAX_CMDBUF_DWORDS);
+       cs->buf[cs->cdw++] = PKT3(PKT3_SET_CONFIG_REG, num, 0);
+       cs->buf[cs->cdw++] = (reg - R600_CONFIG_REG_OFFSET) >> 2;
+}
+
+static INLINE void r600_write_context_reg_seq(struct radeon_winsys_cs *cs, unsigned reg, unsigned num)
+{
+       assert(reg >= R600_CONTEXT_REG_OFFSET && reg < R600_CTL_CONST_OFFSET);
+       assert(cs->cdw+2+num <= RADEON_MAX_CMDBUF_DWORDS);
+       cs->buf[cs->cdw++] = PKT3(PKT3_SET_CONTEXT_REG, num, 0);
+       cs->buf[cs->cdw++] = (reg - R600_CONTEXT_REG_OFFSET) >> 2;
+}
+
+static INLINE void r600_write_ctl_const_seq(struct radeon_winsys_cs *cs, unsigned reg, unsigned num)
+{
+       assert(reg >= R600_CTL_CONST_OFFSET);
+       assert(cs->cdw+2+num <= RADEON_MAX_CMDBUF_DWORDS);
+       cs->buf[cs->cdw++] = PKT3(PKT3_SET_CTL_CONST, num, 0);
+       cs->buf[cs->cdw++] = (reg - R600_CTL_CONST_OFFSET) >> 2;
+}
+
+static INLINE void r600_write_config_reg(struct radeon_winsys_cs *cs, unsigned reg, unsigned value)
+{
+       r600_write_config_reg_seq(cs, reg, 1);
+       r600_write_value(cs, value);
+}
+
+static INLINE void r600_write_context_reg(struct radeon_winsys_cs *cs, unsigned reg, unsigned value)
+{
+       r600_write_context_reg_seq(cs, reg, 1);
+       r600_write_value(cs, value);
+}
+
+static INLINE void r600_write_ctl_const(struct radeon_winsys_cs *cs, unsigned reg, unsigned value)
+{
+       r600_write_ctl_const_seq(cs, reg, 1);
+       r600_write_value(cs, value);
+}
+
 /*
  * common helpers
  */
index faec99c6a808e80fc7f915e3ef57c01eecbdb65a..f2e6d01065935cd6a2947eee689082cbf4680a94 100644 (file)
@@ -37,11 +37,32 @@ static void r600_destroy_query(struct pipe_context *ctx, struct pipe_query *quer
        r600_context_query_destroy(rctx, (struct r600_query *)query);
 }
 
+static void r600_update_occlusion_query_state(struct r600_context *rctx,
+                                             unsigned type, int diff)
+{
+       if (type == PIPE_QUERY_OCCLUSION_COUNTER ||
+           type == PIPE_QUERY_OCCLUSION_PREDICATE) {
+               bool enable;
+
+               rctx->num_occlusion_queries += diff;
+               assert(rctx->num_occlusion_queries >= 0);
+
+               enable = rctx->num_occlusion_queries != 0;
+
+               if (rctx->atom_db_misc_state.occlusion_query_enabled != enable) {
+                       rctx->atom_db_misc_state.occlusion_query_enabled = enable;
+                       r600_atom_dirty(rctx, &rctx->atom_db_misc_state.atom);
+               }
+       }
+}
+
 static void r600_begin_query(struct pipe_context *ctx, struct pipe_query *query)
 {
        struct r600_context *rctx = (struct r600_context *)ctx;
        struct r600_query *rquery = (struct r600_query *)query;
 
+       r600_update_occlusion_query_state(rctx, rquery->type, 1);
+
        memset(&rquery->result, 0, sizeof(rquery->result));
        rquery->results_start = rquery->results_end;
        r600_query_begin(rctx, (struct r600_query *)query);
@@ -55,6 +76,8 @@ static void r600_end_query(struct pipe_context *ctx, struct pipe_query *query)
 
        r600_query_end(rctx, rquery);
        LIST_DELINIT(&rquery->list);
+
+       r600_update_occlusion_query_state(rctx, rquery->type, -1);
 }
 
 static boolean r600_get_query_result(struct pipe_context *ctx,
index f8711b227519380b33a0b2fc6a2a849c660cf766..eab1983a337b5351763eafdc73617ef214af16a5 100644 (file)
@@ -717,7 +717,6 @@ static void *r600_create_dsa_state(struct pipe_context *ctx,
        struct r600_context *rctx = (struct r600_context *)ctx;
        struct r600_pipe_dsa *dsa = CALLOC_STRUCT(r600_pipe_dsa);
        unsigned db_depth_control, alpha_test_control, alpha_ref;
-       unsigned db_render_override, db_render_control;
        struct r600_pipe_state *rstate;
 
        if (dsa == NULL) {
@@ -763,12 +762,6 @@ static void *r600_create_dsa_state(struct pipe_context *ctx,
        }
        dsa->alpha_ref = alpha_ref;
 
-       /* misc */
-       db_render_control = 0;
-       db_render_override = S_028D10_FORCE_HIZ_ENABLE(V_028D10_FORCE_DISABLE) |
-               S_028D10_FORCE_HIS_ENABLE0(V_028D10_FORCE_DISABLE) |
-               S_028D10_FORCE_HIS_ENABLE1(V_028D10_FORCE_DISABLE);
-       /* TODO db_render_override depends on query */
        r600_pipe_state_add_reg(rstate, R_028028_DB_STENCIL_CLEAR, 0x00000000, NULL, 0);
        r600_pipe_state_add_reg(rstate, R_02802C_DB_DEPTH_CLEAR, 0x3F800000, NULL, 0);
        r600_pipe_state_add_reg(rstate, R_028410_SX_ALPHA_TEST_CONTROL, alpha_test_control, NULL, 0);
@@ -776,15 +769,10 @@ static void *r600_create_dsa_state(struct pipe_context *ctx,
        r600_pipe_state_add_reg(rstate, R_0286E4_SPI_FOG_FUNC_BIAS, 0x00000000, NULL, 0);
        r600_pipe_state_add_reg(rstate, R_0286DC_SPI_FOG_CNTL, 0x00000000, NULL, 0);
        r600_pipe_state_add_reg(rstate, R_028800_DB_DEPTH_CONTROL, db_depth_control, NULL, 0);
-       r600_pipe_state_add_reg(rstate, R_028D0C_DB_RENDER_CONTROL, db_render_control, NULL, 0);
-       r600_pipe_state_add_reg(rstate, R_028D10_DB_RENDER_OVERRIDE, db_render_override, NULL, 0);
        r600_pipe_state_add_reg(rstate, R_028D2C_DB_SRESULTS_COMPARE_STATE1, 0x00000000, NULL, 0);
        r600_pipe_state_add_reg(rstate, R_028D30_DB_PRELOAD_CONTROL, 0x00000000, NULL, 0);
        r600_pipe_state_add_reg(rstate, R_028D44_DB_ALPHA_TO_MASK, 0x0000AA00, NULL, 0);
 
-       dsa->db_render_override = db_render_override;
-       dsa->db_render_control = db_render_control;
-
        return rstate;
 }
 
@@ -1703,8 +1691,38 @@ static void r600_set_framebuffer_state(struct pipe_context *ctx,
        }
 }
 
+static void r600_emit_db_misc_state(struct r600_context *rctx, struct r600_atom *atom)
+{
+       struct radeon_winsys_cs *cs = rctx->cs;
+       struct r600_atom_db_misc_state *a = (struct r600_atom_db_misc_state*)atom;
+       unsigned db_render_control = 0;
+       unsigned db_render_override =
+               S_028D10_FORCE_HIZ_ENABLE(V_028D10_FORCE_DISABLE) |
+               S_028D10_FORCE_HIS_ENABLE0(V_028D10_FORCE_DISABLE) |
+               S_028D10_FORCE_HIS_ENABLE1(V_028D10_FORCE_DISABLE);
+
+       if (a->occlusion_query_enabled) {
+               if (rctx->chip_class >= R700) {
+                       db_render_control |= S_028D0C_R700_PERFECT_ZPASS_COUNTS(1);
+               }
+               db_render_override |= S_028D10_NOOP_CULL_DISABLE(1);
+       }
+       if (a->flush_depthstencil_enabled) {
+               db_render_control |= S_028D0C_DEPTH_COPY_ENABLE(1) |
+                                    S_028D0C_STENCIL_COPY_ENABLE(1) |
+                                    S_028D0C_COPY_CENTROID(1);
+       }
+
+       r600_write_context_reg_seq(cs, R_028D0C_DB_RENDER_CONTROL, 2);
+       r600_write_value(cs, db_render_control); /* R_028D0C_DB_RENDER_CONTROL */
+       r600_write_value(cs, db_render_override); /* R_028D10_DB_RENDER_OVERRIDE */
+}
+
 void r600_init_state_functions(struct r600_context *rctx)
 {
+       r600_init_atom(&rctx->atom_db_misc_state.atom, r600_emit_db_misc_state, 4, 0);
+       r600_atom_dirty(rctx, &rctx->atom_db_misc_state.atom);
+
        rctx->context.create_blend_state = r600_create_blend_state;
        rctx->context.create_depth_stencil_alpha_state = r600_create_dsa_state;
        rctx->context.create_fs_state = r600_create_shader_state;
@@ -2255,7 +2273,6 @@ void *r600_create_db_flush_dsa(struct r600_context *rctx)
        struct pipe_depth_stencil_alpha_state dsa;
        struct r600_pipe_state *rstate;
        struct r600_pipe_dsa *dsa_state;
-       unsigned db_render_control;
        boolean quirk = false;
 
        if (rctx->family == CHIP_RV610 || rctx->family == CHIP_RV630 ||
@@ -2276,16 +2293,7 @@ void *r600_create_db_flush_dsa(struct r600_context *rctx)
 
        rstate = rctx->context.create_depth_stencil_alpha_state(&rctx->context, &dsa);
        dsa_state = (struct r600_pipe_dsa*)rstate;
-
-       db_render_control =
-               S_028D0C_DEPTH_COPY_ENABLE(1) |
-               S_028D0C_STENCIL_COPY_ENABLE(1) |
-               S_028D0C_COPY_CENTROID(1);
-
-       r600_pipe_state_add_reg(rstate, R_028D0C_DB_RENDER_CONTROL, db_render_control, NULL, 0);
-
-       dsa_state->db_render_control = db_render_control;
-
+       dsa_state->is_flush = true;
        return rstate;
 }
 
index e2a28020cd4d9faab6c7651bcd7025f912e09155..cadb07943c42b8dac1f831c29f03ae1dcc3482b0 100644 (file)
@@ -80,10 +80,9 @@ static void r600_emit_r6xx_flush_and_inv(struct r600_context *rctx, struct r600_
        cs->buf[cs->cdw++] = EVENT_TYPE(EVENT_TYPE_CACHE_FLUSH_AND_INV_EVENT) | EVENT_INDEX(0);
 }
 
-static void r600_init_atom(struct r600_atom *atom,
-                          void (*emit)(struct r600_context *ctx, struct r600_atom *state),
-                          unsigned num_dw,
-                          enum r600_atom_flags flags)
+void r600_init_atom(struct r600_atom *atom,
+                   void (*emit)(struct r600_context *ctx, struct r600_atom *state),
+                   unsigned num_dw, enum r600_atom_flags flags)
 {
        atom->emit = emit;
        atom->num_dw = num_dw;
@@ -263,6 +262,11 @@ void r600_bind_dsa_state(struct pipe_context *ctx, void *state)
        ref.writemask[1] = dsa->writemask[1];
 
        r600_set_stencil_ref(ctx, &ref);
+
+       if (rctx->atom_db_misc_state.flush_depthstencil_enabled != dsa->is_flush) {
+               rctx->atom_db_misc_state.flush_depthstencil_enabled = dsa->is_flush;
+               r600_atom_dirty(rctx, &rctx->atom_db_misc_state.atom);
+       }
 }
 
 void r600_bind_rs_state(struct pipe_context *ctx, void *state)
@@ -885,12 +889,6 @@ void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *dinfo)
                rctx->streamout_start = FALSE;
        }
 
-       if (rctx->chip_class >= EVERGREEN) {
-               evergreen_context_draw_prepare(rctx);
-       } else {
-               r600_context_draw_prepare(rctx);
-       }
-
        /* draw packet */
        cs->buf[cs->cdw++] = PKT3(PKT3_INDEX_TYPE, 0, rctx->predicate_drawing);
        cs->buf[cs->cdw++] = ib.index_size == 4 ?