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},
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},
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;
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) {
/* 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);
* 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;
}
}
}
+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;
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;
}
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);
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);
{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},
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);
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;
#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)
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);
return NULL;
}
- LIST_INITHEAD(&rctx->dirty_states);
-
r600_get_backend_mask(rctx); /* this emits commands and must be last */
return &rctx->context;
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,
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
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.
*/
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;
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);
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)
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);
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,
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) {
}
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);
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;
}
}
}
+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;
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 ||
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;
}
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;
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)
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 ?