From e2809849ecac69615ece294a55ee355afaac33d3 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Thu, 2 Feb 2012 14:01:12 +0100 Subject: [PATCH] r600g: add a depth misc state which depends on occlusion queries 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 | 22 --------- src/gallium/drivers/r600/evergreen_state.c | 30 +++++++++--- src/gallium/drivers/r600/r600.h | 2 - src/gallium/drivers/r600/r600_hw_context.c | 23 +-------- src/gallium/drivers/r600/r600_hw_context_priv.h | 2 +- src/gallium/drivers/r600/r600_pipe.c | 4 +- src/gallium/drivers/r600/r600_pipe.h | 65 ++++++++++++++++++++++++- src/gallium/drivers/r600/r600_query.c | 23 +++++++++ src/gallium/drivers/r600/r600_state.c | 54 +++++++++++--------- src/gallium/drivers/r600/r600_state_common.c | 18 +++---- 10 files changed, 152 insertions(+), 91 deletions(-) diff --git a/src/gallium/drivers/r600/evergreen_hw_context.c b/src/gallium/drivers/r600/evergreen_hw_context.c index f3b207b..a7ba04d 100644 --- a/src/gallium/drivers/r600/evergreen_hw_context.c +++ b/src/gallium/drivers/r600/evergreen_hw_context.c @@ -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; diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c index 3667aba..94dc562 100644 --- a/src/gallium/drivers/r600/evergreen_state.c +++ b/src/gallium/drivers/r600/evergreen_state.c @@ -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; } diff --git a/src/gallium/drivers/r600/r600.h b/src/gallium/drivers/r600/r600.h index 1bb6c4b..a792e94 100644 --- a/src/gallium/drivers/r600/r600.h +++ b/src/gallium/drivers/r600/r600.h @@ -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); diff --git a/src/gallium/drivers/r600/r600_hw_context.c b/src/gallium/drivers/r600/r600_hw_context.c index 3632c6d..c59b853 100644 --- a/src/gallium/drivers/r600/r600_hw_context.c +++ b/src/gallium/drivers/r600/r600_hw_context.c @@ -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; diff --git a/src/gallium/drivers/r600/r600_hw_context_priv.h b/src/gallium/drivers/r600/r600_hw_context_priv.h index 1e57138..61009af 100644 --- a/src/gallium/drivers/r600/r600_hw_context_priv.h +++ b/src/gallium/drivers/r600/r600_hw_context_priv.h @@ -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) diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c index c8ee331..3d35ed2 100644 --- a/src/gallium/drivers/r600/r600_pipe.c +++ b/src/gallium/drivers/r600/r600_pipe.c @@ -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; diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h index e4c6df7..4d5b67a 100644 --- a/src/gallium/drivers/r600/r600_pipe.h +++ b/src/gallium/drivers/r600/r600_pipe.h @@ -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); @@ -554,6 +564,57 @@ void r600_init_command_buffer(struct r600_command_buffer *cb, unsigned num_dw, e 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 */ static INLINE uint32_t S_FIXED(float value, uint32_t frac_bits) diff --git a/src/gallium/drivers/r600/r600_query.c b/src/gallium/drivers/r600/r600_query.c index faec99c..f2e6d01 100644 --- a/src/gallium/drivers/r600/r600_query.c +++ b/src/gallium/drivers/r600/r600_query.c @@ -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, diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c index f8711b2..eab1983 100644 --- a/src/gallium/drivers/r600/r600_state.c +++ b/src/gallium/drivers/r600/r600_state.c @@ -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; } diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c index e2a2802..cadb079 100644 --- a/src/gallium/drivers/r600/r600_state_common.c +++ b/src/gallium/drivers/r600/r600_state_common.c @@ -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 ? -- 2.7.4