summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJerome Glisse <jglisse@redhat.com>2012-09-05 15:18:24 -0400
committerJerome Glisse <jglisse@redhat.com>2012-09-06 15:09:17 -0400
commit5ceb87286f2e1b5b8527ba18a844abf450903175 (patch)
tree920771a74e03a839d0cd81c8f6449d786842994e
parent935a72944751e6bc0a5df779eef44766c7b52baa (diff)
r600g: order atom emission v3
To avoid GPU lockup registers must be emited in a specific order (no kidding ...). This patch rework atom emission so order in which atom are emited in respect to each other is always the same. We don't have any informations on what is the correct order so order will need to be infered from fglrx command stream. v2: add comment warning that atom order should not be taken lightly v3: rebase on top of alphatest atom fix Signed-off-by: Jerome Glisse <jglisse@redhat.com>
-rw-r--r--src/gallium/drivers/r600/evergreen_compute.c2
-rw-r--r--src/gallium/drivers/r600/evergreen_state.c63
-rw-r--r--src/gallium/drivers/r600/r600_hw_context.c10
-rw-r--r--src/gallium/drivers/r600/r600_pipe.c1
-rw-r--r--src/gallium/drivers/r600/r600_pipe.h33
-rw-r--r--src/gallium/drivers/r600/r600_state.c53
-rw-r--r--src/gallium/drivers/r600/r600_state_common.c36
7 files changed, 116 insertions, 82 deletions
diff --git a/src/gallium/drivers/r600/evergreen_compute.c b/src/gallium/drivers/r600/evergreen_compute.c
index acf91ba43f3..35333120654 100644
--- a/src/gallium/drivers/r600/evergreen_compute.c
+++ b/src/gallium/drivers/r600/evergreen_compute.c
@@ -583,7 +583,7 @@ void evergreen_init_atom_start_compute_cs(struct r600_context *ctx)
583 /* since all required registers are initialised in the 583 /* since all required registers are initialised in the
584 * start_compute_cs_cmd atom, we can EMIT_EARLY here. 584 * start_compute_cs_cmd atom, we can EMIT_EARLY here.
585 */ 585 */
586 r600_init_command_buffer(cb, 256, EMIT_EARLY); 586 r600_init_command_buffer(ctx, cb, 1, 256);
587 cb->pkt_flags = RADEON_CP_PACKET3_COMPUTE_MODE; 587 cb->pkt_flags = RADEON_CP_PACKET3_COMPUTE_MODE;
588 588
589 switch (ctx->family) { 589 switch (ctx->family) {
diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c
index bda8ed5dc2d..9a5183ec6be 100644
--- a/src/gallium/drivers/r600/evergreen_state.c
+++ b/src/gallium/drivers/r600/evergreen_state.c
@@ -2161,27 +2161,50 @@ static void cayman_emit_sample_mask(struct r600_context *rctx, struct r600_atom
2161 2161
2162void evergreen_init_state_functions(struct r600_context *rctx) 2162void evergreen_init_state_functions(struct r600_context *rctx)
2163{ 2163{
2164 r600_init_atom(&rctx->cb_misc_state.atom, evergreen_emit_cb_misc_state, 0, 0); 2164 unsigned id = 4;
2165 r600_atom_dirty(rctx, &rctx->cb_misc_state.atom); 2165
2166 r600_init_atom(&rctx->db_misc_state.atom, evergreen_emit_db_misc_state, 7, 0); 2166 /* !!!
2167 r600_atom_dirty(rctx, &rctx->db_misc_state.atom); 2167 * To avoid GPU lockup registers must be emited in a specific order
2168 r600_init_atom(&rctx->vertex_buffer_state.atom, evergreen_fs_emit_vertex_buffers, 0, 0); 2168 * (no kidding ...). The order below is important and have been
2169 r600_init_atom(&rctx->cs_vertex_buffer_state.atom, evergreen_cs_emit_vertex_buffers, 0, 0); 2169 * partialy infered from analyzing fglrx command stream.
2170 r600_init_atom(&rctx->vs_constbuf_state.atom, evergreen_emit_vs_constant_buffers, 0, 0); 2170 *
2171 r600_init_atom(&rctx->ps_constbuf_state.atom, evergreen_emit_ps_constant_buffers, 0, 0); 2171 * Don't reorder atom without carefully checking the effect (GPU lockup
2172 r600_init_atom(&rctx->vs_samplers.views.atom, evergreen_emit_vs_sampler_views, 0, 0); 2172 * or piglit regression).
2173 r600_init_atom(&rctx->ps_samplers.views.atom, evergreen_emit_ps_sampler_views, 0, 0); 2173 * !!!
2174 r600_init_atom(&rctx->cs_shader_state.atom, evergreen_emit_cs_shader, 0, 0); 2174 */
2175 r600_init_atom(&rctx->vs_samplers.atom_sampler, evergreen_emit_vs_sampler, 0, 0); 2175
2176 r600_init_atom(&rctx->ps_samplers.atom_sampler, evergreen_emit_ps_sampler, 0, 0); 2176 /* shader const */
2177 2177 r600_init_atom(rctx, &rctx->vs_constbuf_state.atom, id++, evergreen_emit_vs_constant_buffers, 0);
2178 if (rctx->chip_class == EVERGREEN) 2178 r600_init_atom(rctx, &rctx->ps_constbuf_state.atom, id++, evergreen_emit_ps_constant_buffers, 0);
2179 r600_init_atom(&rctx->sample_mask.atom, evergreen_emit_sample_mask, 3, 0); 2179 /* shader program */
2180 else 2180 r600_init_atom(rctx, &rctx->cs_shader_state.atom, id++, evergreen_emit_cs_shader, 0);
2181 r600_init_atom(&rctx->sample_mask.atom, cayman_emit_sample_mask, 4, 0); 2181 /* sampler */
2182 r600_init_atom(rctx, &rctx->vs_samplers.atom_sampler, id++, evergreen_emit_vs_sampler, 0);
2183 r600_init_atom(rctx, &rctx->ps_samplers.atom_sampler, id++, evergreen_emit_ps_sampler, 0);
2184 /* resources */
2185 r600_init_atom(rctx, &rctx->vertex_buffer_state.atom, id++, evergreen_fs_emit_vertex_buffers, 0);
2186 r600_init_atom(rctx, &rctx->cs_vertex_buffer_state.atom, id++, evergreen_cs_emit_vertex_buffers, 0);
2187 r600_init_atom(rctx, &rctx->vs_samplers.views.atom, id++, evergreen_emit_vs_sampler_views, 0);
2188 r600_init_atom(rctx, &rctx->ps_samplers.views.atom, id++, evergreen_emit_ps_sampler_views, 0);
2189
2190 if (rctx->chip_class == EVERGREEN) {
2191 r600_init_atom(rctx, &rctx->sample_mask.atom, id++, evergreen_emit_sample_mask, 3);
2192 } else {
2193 r600_init_atom(rctx, &rctx->sample_mask.atom, id++, cayman_emit_sample_mask, 4);
2194 }
2182 rctx->sample_mask.sample_mask = ~0; 2195 rctx->sample_mask.sample_mask = ~0;
2183 r600_atom_dirty(rctx, &rctx->sample_mask.atom); 2196 r600_atom_dirty(rctx, &rctx->sample_mask.atom);
2184 2197
2198 r600_init_atom(rctx, &rctx->cb_misc_state.atom, id++, evergreen_emit_cb_misc_state, 0);
2199 r600_atom_dirty(rctx, &rctx->cb_misc_state.atom);
2200
2201 r600_init_atom(rctx, &rctx->alphatest_state.atom, id++, r600_emit_alphatest_state, 6);
2202 r600_atom_dirty(rctx, &rctx->alphatest_state.atom);
2203
2204 r600_init_atom(rctx, &rctx->db_misc_state.atom, id++, evergreen_emit_db_misc_state, 7);
2205 r600_atom_dirty(rctx, &rctx->db_misc_state.atom);
2206
2207
2185 rctx->context.create_blend_state = evergreen_create_blend_state; 2208 rctx->context.create_blend_state = evergreen_create_blend_state;
2186 rctx->context.create_depth_stencil_alpha_state = evergreen_create_dsa_state; 2209 rctx->context.create_depth_stencil_alpha_state = evergreen_create_dsa_state;
2187 rctx->context.create_fs_state = r600_create_shader_state_ps; 2210 rctx->context.create_fs_state = r600_create_shader_state_ps;
@@ -2230,7 +2253,7 @@ static void cayman_init_atom_start_cs(struct r600_context *rctx)
2230{ 2253{
2231 struct r600_command_buffer *cb = &rctx->start_cs_cmd; 2254 struct r600_command_buffer *cb = &rctx->start_cs_cmd;
2232 2255
2233 r600_init_command_buffer(cb, 256, EMIT_EARLY); 2256 r600_init_command_buffer(rctx, cb, 0, 256);
2234 2257
2235 /* This must be first. */ 2258 /* This must be first. */
2236 r600_store_value(cb, PKT3(PKT3_CONTEXT_CONTROL, 1, 0)); 2259 r600_store_value(cb, PKT3(PKT3_CONTEXT_CONTROL, 1, 0));
@@ -2608,7 +2631,7 @@ void evergreen_init_atom_start_cs(struct r600_context *rctx)
2608 return; 2631 return;
2609 } 2632 }
2610 2633
2611 r600_init_command_buffer(cb, 256, EMIT_EARLY); 2634 r600_init_command_buffer(rctx, cb, 0, 256);
2612 2635
2613 /* This must be first. */ 2636 /* This must be first. */
2614 r600_store_value(cb, PKT3(PKT3_CONTEXT_CONTROL, 1, 0)); 2637 r600_store_value(cb, PKT3(PKT3_CONTEXT_CONTROL, 1, 0));
diff --git a/src/gallium/drivers/r600/r600_hw_context.c b/src/gallium/drivers/r600/r600_hw_context.c
index 7b7b6b1ffac..0ec13e5bade 100644
--- a/src/gallium/drivers/r600/r600_hw_context.c
+++ b/src/gallium/drivers/r600/r600_hw_context.c
@@ -633,15 +633,17 @@ out_err:
633void r600_need_cs_space(struct r600_context *ctx, unsigned num_dw, 633void r600_need_cs_space(struct r600_context *ctx, unsigned num_dw,
634 boolean count_draw_in) 634 boolean count_draw_in)
635{ 635{
636 struct r600_atom *state;
637
638 /* The number of dwords we already used in the CS so far. */ 636 /* The number of dwords we already used in the CS so far. */
639 num_dw += ctx->cs->cdw; 637 num_dw += ctx->cs->cdw;
640 638
641 if (count_draw_in) { 639 if (count_draw_in) {
640 unsigned i;
641
642 /* The number of dwords all the dirty states would take. */ 642 /* The number of dwords all the dirty states would take. */
643 LIST_FOR_EACH_ENTRY(state, &ctx->dirty_states, head) { 643 for (i = 0; i < R600_MAX_ATOM; i++) {
644 num_dw += state->num_dw; 644 if (ctx->atoms[i] && ctx->atoms[i]->dirty) {
645 num_dw += ctx->atoms[i]->num_dw;
646 }
645 } 647 }
646 648
647 num_dw += ctx->pm4_dirty_cdwords; 649 num_dw += ctx->pm4_dirty_cdwords;
diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c
index 286c676f85b..9e6c28d523b 100644
--- a/src/gallium/drivers/r600/r600_pipe.c
+++ b/src/gallium/drivers/r600/r600_pipe.c
@@ -224,7 +224,6 @@ static struct pipe_context *r600_create_context(struct pipe_screen *screen, void
224 rctx->family = rscreen->family; 224 rctx->family = rscreen->family;
225 rctx->chip_class = rscreen->chip_class; 225 rctx->chip_class = rscreen->chip_class;
226 226
227 LIST_INITHEAD(&rctx->dirty_states);
228 LIST_INITHEAD(&rctx->active_timer_queries); 227 LIST_INITHEAD(&rctx->active_timer_queries);
229 LIST_INITHEAD(&rctx->active_nontimer_queries); 228 LIST_INITHEAD(&rctx->active_nontimer_queries);
230 LIST_INITHEAD(&rctx->dirty); 229 LIST_INITHEAD(&rctx->dirty);
diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h
index 721334d1e84..ff720e95cfe 100644
--- a/src/gallium/drivers/r600/r600_pipe.h
+++ b/src/gallium/drivers/r600/r600_pipe.h
@@ -35,6 +35,8 @@
35#include "r600_resource.h" 35#include "r600_resource.h"
36#include "evergreen_compute.h" 36#include "evergreen_compute.h"
37 37
38#define R600_MAX_ATOM 17
39
38#define R600_MAX_CONST_BUFFERS 2 40#define R600_MAX_CONST_BUFFERS 2
39#define R600_MAX_CONST_BUFFER_SIZE 4096 41#define R600_MAX_CONST_BUFFER_SIZE 4096
40 42
@@ -44,23 +46,14 @@
44#define R600_BIG_ENDIAN 0 46#define R600_BIG_ENDIAN 0
45#endif 47#endif
46 48
47enum r600_atom_flags {
48 /* When set, atoms are added at the beginning of the dirty list
49 * instead of the end. */
50 EMIT_EARLY = (1 << 0)
51};
52
53/* This encapsulates a state or an operation which can emitted into the GPU 49/* This encapsulates a state or an operation which can emitted into the GPU
54 * command stream. It's not limited to states only, it can be used for anything 50 * command stream. It's not limited to states only, it can be used for anything
55 * that wants to write commands into the CS (e.g. cache flushes). */ 51 * that wants to write commands into the CS (e.g. cache flushes). */
56struct r600_atom { 52struct r600_atom {
57 void (*emit)(struct r600_context *ctx, struct r600_atom *state); 53 void (*emit)(struct r600_context *ctx, struct r600_atom *state);
58 54 unsigned id;
59 unsigned num_dw; 55 unsigned num_dw;
60 enum r600_atom_flags flags;
61 bool dirty; 56 bool dirty;
62
63 struct list_head head;
64}; 57};
65 58
66/* This is an atom containing GPU commands that never change. 59/* This is an atom containing GPU commands that never change.
@@ -372,8 +365,8 @@ struct r600_context {
372 unsigned default_ps_gprs, default_vs_gprs; 365 unsigned default_ps_gprs, default_vs_gprs;
373 366
374 /* States based on r600_atom. */ 367 /* States based on r600_atom. */
375 struct list_head dirty_states;
376 struct r600_command_buffer start_cs_cmd; /* invariant state mostly */ 368 struct r600_command_buffer start_cs_cmd; /* invariant state mostly */
369 struct r600_atom *atoms[R600_MAX_ATOM];
377 /** Compute specific registers initializations. The start_cs_cmd atom 370 /** Compute specific registers initializations. The start_cs_cmd atom
378 * must be emitted before start_compute_cs_cmd. */ 371 * must be emitted before start_compute_cs_cmd. */
379 struct r600_command_buffer start_compute_cs_cmd; 372 struct r600_command_buffer start_compute_cs_cmd;
@@ -464,20 +457,11 @@ static INLINE void r600_emit_atom(struct r600_context *rctx, struct r600_atom *a
464{ 457{
465 atom->emit(rctx, atom); 458 atom->emit(rctx, atom);
466 atom->dirty = false; 459 atom->dirty = false;
467 if (atom->head.next && atom->head.prev)
468 LIST_DELINIT(&atom->head);
469} 460}
470 461
471static INLINE void r600_atom_dirty(struct r600_context *rctx, struct r600_atom *state) 462static INLINE void r600_atom_dirty(struct r600_context *rctx, struct r600_atom *state)
472{ 463{
473 if (!state->dirty) { 464 state->dirty = true;
474 if (state->flags & EMIT_EARLY) {
475 LIST_ADD(&state->head, &rctx->dirty_states);
476 } else {
477 LIST_ADDTAIL(&state->head, &rctx->dirty_states);
478 }
479 state->dirty = true;
480 }
481} 465}
482 466
483/* evergreen_state.c */ 467/* evergreen_state.c */
@@ -587,9 +571,10 @@ void r600_translate_index_buffer(struct r600_context *r600,
587 unsigned count); 571 unsigned count);
588 572
589/* r600_state_common.c */ 573/* r600_state_common.c */
590void r600_init_atom(struct r600_atom *atom, 574void r600_emit_alphatest_state(struct r600_context *rctx, struct r600_atom *atom);
575void r600_init_atom(struct r600_context *rctx, struct r600_atom *atom, unsigned id,
591 void (*emit)(struct r600_context *ctx, struct r600_atom *state), 576 void (*emit)(struct r600_context *ctx, struct r600_atom *state),
592 unsigned num_dw, enum r600_atom_flags flags); 577 unsigned num_dw);
593void r600_init_common_atoms(struct r600_context *rctx); 578void r600_init_common_atoms(struct r600_context *rctx);
594unsigned r600_get_cb_flush_flags(struct r600_context *rctx); 579unsigned r600_get_cb_flush_flags(struct r600_context *rctx);
595void r600_texture_barrier(struct pipe_context *ctx); 580void r600_texture_barrier(struct pipe_context *ctx);
@@ -772,7 +757,7 @@ static INLINE void eg_store_loop_const(struct r600_command_buffer *cb, unsigned
772 r600_store_value(cb, value); 757 r600_store_value(cb, value);
773} 758}
774 759
775void r600_init_command_buffer(struct r600_command_buffer *cb, unsigned num_dw, enum r600_atom_flags flags); 760void r600_init_command_buffer(struct r600_context *rctx, struct r600_command_buffer *cb, unsigned id, unsigned num_dw);
776void r600_release_command_buffer(struct r600_command_buffer *cb); 761void r600_release_command_buffer(struct r600_command_buffer *cb);
777 762
778/* 763/*
diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c
index 53bbdd9da7d..ccafdc6733b 100644
--- a/src/gallium/drivers/r600/r600_state.c
+++ b/src/gallium/drivers/r600/r600_state.c
@@ -2031,27 +2031,48 @@ static void r600_emit_sample_mask(struct r600_context *rctx, struct r600_atom *a
2031 2031
2032void r600_init_state_functions(struct r600_context *rctx) 2032void r600_init_state_functions(struct r600_context *rctx)
2033{ 2033{
2034 r600_init_atom(&rctx->seamless_cube_map.atom, r600_emit_seamless_cube_map, 3, 0); 2034 unsigned id = 4;
2035 r600_atom_dirty(rctx, &rctx->seamless_cube_map.atom); 2035
2036 r600_init_atom(&rctx->cb_misc_state.atom, r600_emit_cb_misc_state, 0, 0); 2036 /* !!!
2037 r600_atom_dirty(rctx, &rctx->cb_misc_state.atom); 2037 * To avoid GPU lockup registers must be emited in a specific order
2038 r600_init_atom(&rctx->db_misc_state.atom, r600_emit_db_misc_state, 4, 0); 2038 * (no kidding ...). The order below is important and have been
2039 r600_atom_dirty(rctx, &rctx->db_misc_state.atom); 2039 * partialy infered from analyzing fglrx command stream.
2040 r600_init_atom(&rctx->vertex_buffer_state.atom, r600_emit_vertex_buffers, 0, 0); 2040 *
2041 r600_init_atom(&rctx->vs_constbuf_state.atom, r600_emit_vs_constant_buffers, 0, 0); 2041 * Don't reorder atom without carefully checking the effect (GPU lockup
2042 r600_init_atom(&rctx->ps_constbuf_state.atom, r600_emit_ps_constant_buffers, 0, 0); 2042 * or piglit regression).
2043 r600_init_atom(&rctx->vs_samplers.views.atom, r600_emit_vs_sampler_views, 0, 0); 2043 * !!!
2044 r600_init_atom(&rctx->ps_samplers.views.atom, r600_emit_ps_sampler_views, 0, 0); 2044 */
2045
2046 /* shader const */
2047 r600_init_atom(rctx, &rctx->vs_constbuf_state.atom, id++, r600_emit_vs_constant_buffers, 0);
2048 r600_init_atom(rctx, &rctx->ps_constbuf_state.atom, id++, r600_emit_ps_constant_buffers, 0);
2049
2045 /* sampler must be emited before TA_CNTL_AUX otherwise DISABLE_CUBE_WRAP change 2050 /* sampler must be emited before TA_CNTL_AUX otherwise DISABLE_CUBE_WRAP change
2046 * does not take effect 2051 * does not take effect (TA_CNTL_AUX emited by r600_emit_seamless_cube_map)
2047 */ 2052 */
2048 r600_init_atom(&rctx->vs_samplers.atom_sampler, r600_emit_vs_sampler, 0, EMIT_EARLY); 2053 r600_init_atom(rctx, &rctx->vs_samplers.atom_sampler, id++, r600_emit_vs_sampler, 0);
2049 r600_init_atom(&rctx->ps_samplers.atom_sampler, r600_emit_ps_sampler, 0, EMIT_EARLY); 2054 r600_init_atom(rctx, &rctx->ps_samplers.atom_sampler, id++, r600_emit_ps_sampler, 0);
2055 /* resource */
2056 r600_init_atom(rctx, &rctx->vs_samplers.views.atom, id++, r600_emit_vs_sampler_views, 0);
2057 r600_init_atom(rctx, &rctx->ps_samplers.views.atom, id++, r600_emit_ps_sampler_views, 0);
2058 r600_init_atom(rctx, &rctx->vertex_buffer_state.atom, id++, r600_emit_vertex_buffers, 0);
2059
2060 r600_init_atom(rctx, &rctx->seamless_cube_map.atom, id++, r600_emit_seamless_cube_map, 3);
2061 r600_atom_dirty(rctx, &rctx->seamless_cube_map.atom);
2050 2062
2051 r600_init_atom(&rctx->sample_mask.atom, r600_emit_sample_mask, 3, 0); 2063 r600_init_atom(rctx, &rctx->sample_mask.atom, id++, r600_emit_sample_mask, 3);
2052 rctx->sample_mask.sample_mask = ~0; 2064 rctx->sample_mask.sample_mask = ~0;
2053 r600_atom_dirty(rctx, &rctx->sample_mask.atom); 2065 r600_atom_dirty(rctx, &rctx->sample_mask.atom);
2054 2066
2067 r600_init_atom(rctx, &rctx->cb_misc_state.atom, id++, r600_emit_cb_misc_state, 0);
2068 r600_atom_dirty(rctx, &rctx->cb_misc_state.atom);
2069
2070 r600_init_atom(rctx, &rctx->alphatest_state.atom, id++, r600_emit_alphatest_state, 6);
2071 r600_atom_dirty(rctx, &rctx->alphatest_state.atom);
2072
2073 r600_init_atom(rctx, &rctx->db_misc_state.atom, id++, r600_emit_db_misc_state, 4);
2074 r600_atom_dirty(rctx, &rctx->db_misc_state.atom);
2075
2055 rctx->context.create_blend_state = r600_create_blend_state; 2076 rctx->context.create_blend_state = r600_create_blend_state;
2056 rctx->context.create_depth_stencil_alpha_state = r600_create_dsa_state; 2077 rctx->context.create_depth_stencil_alpha_state = r600_create_dsa_state;
2057 rctx->context.create_fs_state = r600_create_shader_state_ps; 2078 rctx->context.create_fs_state = r600_create_shader_state_ps;
@@ -2157,7 +2178,7 @@ void r600_init_atom_start_cs(struct r600_context *rctx)
2157 struct r600_command_buffer *cb = &rctx->start_cs_cmd; 2178 struct r600_command_buffer *cb = &rctx->start_cs_cmd;
2158 uint32_t tmp; 2179 uint32_t tmp;
2159 2180
2160 r600_init_command_buffer(cb, 256, EMIT_EARLY); 2181 r600_init_command_buffer(rctx, cb, 0, 256);
2161 2182
2162 /* R6xx requires this packet at the start of each command buffer */ 2183 /* R6xx requires this packet at the start of each command buffer */
2163 if (rctx->chip_class == R600) { 2184 if (rctx->chip_class == R600) {
diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c
index 26af6f609a5..e67eba8921c 100644
--- a/src/gallium/drivers/r600/r600_state_common.c
+++ b/src/gallium/drivers/r600/r600_state_common.c
@@ -44,11 +44,9 @@ static void r600_emit_command_buffer(struct r600_context *rctx, struct r600_atom
44 cs->cdw += cb->atom.num_dw; 44 cs->cdw += cb->atom.num_dw;
45} 45}
46 46
47void r600_init_command_buffer(struct r600_command_buffer *cb, unsigned num_dw, enum r600_atom_flags flags) 47void r600_init_command_buffer(struct r600_context *rctx, struct r600_command_buffer *cb, unsigned id, unsigned num_dw)
48{ 48{
49 cb->atom.emit = r600_emit_command_buffer; 49 r600_init_atom(rctx, &cb->atom, id, r600_emit_command_buffer, 0);
50 cb->atom.num_dw = 0;
51 cb->atom.flags = flags;
52 cb->buf = CALLOC(1, 4 * num_dw); 50 cb->buf = CALLOC(1, 4 * num_dw);
53 cb->max_num_dw = num_dw; 51 cb->max_num_dw = num_dw;
54} 52}
@@ -79,16 +77,22 @@ static void r600_emit_r6xx_flush_and_inv(struct r600_context *rctx, struct r600_
79 cs->buf[cs->cdw++] = EVENT_TYPE(EVENT_TYPE_CACHE_FLUSH_AND_INV_EVENT) | EVENT_INDEX(0); 77 cs->buf[cs->cdw++] = EVENT_TYPE(EVENT_TYPE_CACHE_FLUSH_AND_INV_EVENT) | EVENT_INDEX(0);
80} 78}
81 79
82void r600_init_atom(struct r600_atom *atom, 80void r600_init_atom(struct r600_context *rctx,
81 struct r600_atom *atom,
82 unsigned id,
83 void (*emit)(struct r600_context *ctx, struct r600_atom *state), 83 void (*emit)(struct r600_context *ctx, struct r600_atom *state),
84 unsigned num_dw, enum r600_atom_flags flags) 84 unsigned num_dw)
85{ 85{
86 assert(id < R600_MAX_ATOM);
87 assert(rctx->atoms[id] == NULL);
88 rctx->atoms[id] = atom;
89 atom->id = id;
86 atom->emit = emit; 90 atom->emit = emit;
87 atom->num_dw = num_dw; 91 atom->num_dw = num_dw;
88 atom->flags = flags; 92 atom->dirty = false;
89} 93}
90 94
91static void r600_emit_alphatest_state(struct r600_context *rctx, struct r600_atom *atom) 95void r600_emit_alphatest_state(struct r600_context *rctx, struct r600_atom *atom)
92{ 96{
93 struct radeon_winsys_cs *cs = rctx->cs; 97 struct radeon_winsys_cs *cs = rctx->cs;
94 struct r600_alphatest_state *a = (struct r600_alphatest_state*)atom; 98 struct r600_alphatest_state *a = (struct r600_alphatest_state*)atom;
@@ -106,10 +110,8 @@ static void r600_emit_alphatest_state(struct r600_context *rctx, struct r600_ato
106 110
107void r600_init_common_atoms(struct r600_context *rctx) 111void r600_init_common_atoms(struct r600_context *rctx)
108{ 112{
109 r600_init_atom(&rctx->surface_sync_cmd.atom, r600_emit_surface_sync, 5, EMIT_EARLY); 113 r600_init_atom(rctx, &rctx->r6xx_flush_and_inv_cmd, 2, r600_emit_r6xx_flush_and_inv, 2);
110 r600_init_atom(&rctx->r6xx_flush_and_inv_cmd, r600_emit_r6xx_flush_and_inv, 2, EMIT_EARLY); 114 r600_init_atom(rctx, &rctx->surface_sync_cmd.atom, 3, r600_emit_surface_sync, 5);
111 r600_init_atom(&rctx->alphatest_state.atom, r600_emit_alphatest_state, 6, 0);
112 r600_atom_dirty(rctx, &rctx->alphatest_state.atom);
113} 115}
114 116
115unsigned r600_get_cb_flush_flags(struct r600_context *rctx) 117unsigned r600_get_cb_flush_flags(struct r600_context *rctx)
@@ -1127,9 +1129,8 @@ void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *dinfo)
1127 struct r600_context *rctx = (struct r600_context *)ctx; 1129 struct r600_context *rctx = (struct r600_context *)ctx;
1128 struct pipe_draw_info info = *dinfo; 1130 struct pipe_draw_info info = *dinfo;
1129 struct pipe_index_buffer ib = {}; 1131 struct pipe_index_buffer ib = {};
1130 unsigned prim, ls_mask = 0; 1132 unsigned prim, ls_mask = 0, i;
1131 struct r600_block *dirty_block = NULL, *next_block = NULL; 1133 struct r600_block *dirty_block = NULL, *next_block = NULL;
1132 struct r600_atom *state = NULL, *next_state = NULL;
1133 struct radeon_winsys_cs *cs = rctx->cs; 1134 struct radeon_winsys_cs *cs = rctx->cs;
1134 uint64_t va; 1135 uint64_t va;
1135 uint8_t *ptr; 1136 uint8_t *ptr;
@@ -1221,8 +1222,11 @@ void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *dinfo)
1221 /* Emit states (the function expects that we emit at most 17 dwords here). */ 1222 /* Emit states (the function expects that we emit at most 17 dwords here). */
1222 r600_need_cs_space(rctx, 0, TRUE); 1223 r600_need_cs_space(rctx, 0, TRUE);
1223 1224
1224 LIST_FOR_EACH_ENTRY_SAFE(state, next_state, &rctx->dirty_states, head) { 1225 for (i = 0; i < R600_MAX_ATOM; i++) {
1225 r600_emit_atom(rctx, state); 1226 if (rctx->atoms[i] == NULL || !rctx->atoms[i]->dirty) {
1227 continue;
1228 }
1229 r600_emit_atom(rctx, rctx->atoms[i]);
1226 } 1230 }
1227 LIST_FOR_EACH_ENTRY_SAFE(dirty_block, next_block, &rctx->dirty,list) { 1231 LIST_FOR_EACH_ENTRY_SAFE(dirty_block, next_block, &rctx->dirty,list) {
1228 r600_context_block_emit_dirty(rctx, dirty_block, 0 /* pkt_flags */); 1232 r600_context_block_emit_dirty(rctx, dirty_block, 0 /* pkt_flags */);