---
 src/gallium/drivers/r600/evergreen_hw_context.c |   27 ----
 src/gallium/drivers/r600/evergreen_state.c      |  171 +++++++++++------------
 src/gallium/drivers/r600/r600_hw_context.c      |   17 +--
 src/gallium/drivers/r600/r600_pipe.h            |   14 +-
 src/gallium/drivers/r600/r600_shader.c          |    1 +
 src/gallium/drivers/r600/r600_shader.h          |    1 +
 src/gallium/drivers/r600/r600_state.c           |  166 +++++++++++-----------
 src/gallium/drivers/r600/r600_state_common.c    |   38 +++--
 8 files changed, 203 insertions(+), 232 deletions(-)

diff --git a/src/gallium/drivers/r600/evergreen_hw_context.c 
b/src/gallium/drivers/r600/evergreen_hw_context.c
index f81d7f3..730e51f 100644
--- a/src/gallium/drivers/r600/evergreen_hw_context.c
+++ b/src/gallium/drivers/r600/evergreen_hw_context.c
@@ -29,17 +29,6 @@
 #include "util/u_math.h"
 
 static const struct r600_reg evergreen_context_reg_list[] = {
-       {R_02861C_SPI_VS_OUT_ID_0, 0, 0},
-       {R_028620_SPI_VS_OUT_ID_1, 0, 0},
-       {R_028624_SPI_VS_OUT_ID_2, 0, 0},
-       {R_028628_SPI_VS_OUT_ID_3, 0, 0},
-       {R_02862C_SPI_VS_OUT_ID_4, 0, 0},
-       {R_028630_SPI_VS_OUT_ID_5, 0, 0},
-       {R_028634_SPI_VS_OUT_ID_6, 0, 0},
-       {R_028638_SPI_VS_OUT_ID_7, 0, 0},
-       {R_02863C_SPI_VS_OUT_ID_8, 0, 0},
-       {R_028640_SPI_VS_OUT_ID_9, 0, 0},
-       {GROUP_FORCE_NEW_BLOCK, 0, 0},
        {R_028644_SPI_PS_INPUT_CNTL_0, 0, 0},
        {R_028648_SPI_PS_INPUT_CNTL_1, 0, 0},
        {R_02864C_SPI_PS_INPUT_CNTL_2, 0, 0},
@@ -73,7 +62,6 @@ static const struct r600_reg evergreen_context_reg_list[] = {
        {R_0286BC_SPI_PS_INPUT_CNTL_30, 0, 0},
        {R_0286C0_SPI_PS_INPUT_CNTL_31, 0, 0},
        {GROUP_FORCE_NEW_BLOCK, 0, 0},
-       {R_0286C4_SPI_VS_OUT_CONFIG, 0, 0},
        {R_0286CC_SPI_PS_IN_CONTROL_0, 0, 0},
        {R_0286D0_SPI_PS_IN_CONTROL_1, 0, 0},
        {R_0286D8_SPI_INPUT_Z, 0, 0},
@@ -82,21 +70,9 @@ static const struct r600_reg evergreen_context_reg_list[] = {
        {R_028840_SQ_PGM_START_PS, REG_FLAG_NEED_BO, 0},
        {R_028844_SQ_PGM_RESOURCES_PS, 0, 0},
        {R_02884C_SQ_PGM_EXPORTS_PS, 0, 0},
-       {R_02885C_SQ_PGM_START_VS, REG_FLAG_NEED_BO, 0},
-       {R_028860_SQ_PGM_RESOURCES_VS, 0, 0},
 };
 
 static const struct r600_reg cayman_context_reg_list[] = {
-       {R_02861C_SPI_VS_OUT_ID_0, 0, 0},
-       {R_028620_SPI_VS_OUT_ID_1, 0, 0},
-       {R_028624_SPI_VS_OUT_ID_2, 0, 0},
-       {R_028628_SPI_VS_OUT_ID_3, 0, 0},
-       {R_02862C_SPI_VS_OUT_ID_4, 0, 0},
-       {R_028630_SPI_VS_OUT_ID_5, 0, 0},
-       {R_028634_SPI_VS_OUT_ID_6, 0, 0},
-       {R_028638_SPI_VS_OUT_ID_7, 0, 0},
-       {R_02863C_SPI_VS_OUT_ID_8, 0, 0},
-       {R_028640_SPI_VS_OUT_ID_9, 0, 0},
        {R_028644_SPI_PS_INPUT_CNTL_0, 0, 0},
        {R_028648_SPI_PS_INPUT_CNTL_1, 0, 0},
        {R_02864C_SPI_PS_INPUT_CNTL_2, 0, 0},
@@ -129,7 +105,6 @@ static const struct r600_reg cayman_context_reg_list[] = {
        {R_0286B8_SPI_PS_INPUT_CNTL_29, 0, 0},
        {R_0286BC_SPI_PS_INPUT_CNTL_30, 0, 0},
        {R_0286C0_SPI_PS_INPUT_CNTL_31, 0, 0},
-       {R_0286C4_SPI_VS_OUT_CONFIG, 0, 0},
        {R_0286CC_SPI_PS_IN_CONTROL_0, 0, 0},
        {R_0286D0_SPI_PS_IN_CONTROL_1, 0, 0},
        {R_0286D8_SPI_INPUT_Z, 0, 0},
@@ -138,8 +113,6 @@ static const struct r600_reg cayman_context_reg_list[] = {
        {R_028840_SQ_PGM_START_PS, REG_FLAG_NEED_BO, 0},
        {R_028844_SQ_PGM_RESOURCES_PS, 0, 0},
        {R_02884C_SQ_PGM_EXPORTS_PS, 0, 0},
-       {R_02885C_SQ_PGM_START_VS, REG_FLAG_NEED_BO, 0},
-       {R_028860_SQ_PGM_RESOURCES_VS, 0, 0},
 };
 
 int evergreen_context_init(struct r600_context *ctx)
diff --git a/src/gallium/drivers/r600/evergreen_state.c 
b/src/gallium/drivers/r600/evergreen_state.c
index 5c7cd40..c52e4c8 100644
--- a/src/gallium/drivers/r600/evergreen_state.c
+++ b/src/gallium/drivers/r600/evergreen_state.c
@@ -2595,75 +2595,6 @@ static void evergreen_emit_vertex_fetch_shader(struct 
r600_context *rctx, struct
        r600_write_value(cs, r600_context_bo_reloc(rctx, &rctx->rings.gfx, 
shader->buffer, RADEON_USAGE_READ));
 }
 
-void evergreen_init_state_functions(struct r600_context *rctx)
-{
-       unsigned id = 4;
-
-       /* !!!
-        *  To avoid GPU lockup registers must be emited in a specific order
-        * (no kidding ...). The order below is important and have been
-        * partialy infered from analyzing fglrx command stream.
-        *
-        * Don't reorder atom without carefully checking the effect (GPU lockup
-        * or piglit regression).
-        * !!!
-        */
-
-       r600_init_atom(rctx, &rctx->framebuffer.atom, id++, 
evergreen_emit_framebuffer_state, 0);
-       /* shader const */
-       r600_init_atom(rctx, &rctx->constbuf_state[PIPE_SHADER_VERTEX].atom, 
id++, evergreen_emit_vs_constant_buffers, 0);
-       r600_init_atom(rctx, &rctx->constbuf_state[PIPE_SHADER_GEOMETRY].atom, 
id++, evergreen_emit_gs_constant_buffers, 0);
-       r600_init_atom(rctx, &rctx->constbuf_state[PIPE_SHADER_FRAGMENT].atom, 
id++, evergreen_emit_ps_constant_buffers, 0);
-       /* shader program */
-       r600_init_atom(rctx, &rctx->cs_shader_state.atom, id++, 
evergreen_emit_cs_shader, 0);
-       /* sampler */
-       r600_init_atom(rctx, &rctx->samplers[PIPE_SHADER_VERTEX].states.atom, 
id++, evergreen_emit_vs_sampler_states, 0);
-       r600_init_atom(rctx, &rctx->samplers[PIPE_SHADER_GEOMETRY].states.atom, 
id++, evergreen_emit_gs_sampler_states, 0);
-       r600_init_atom(rctx, &rctx->samplers[PIPE_SHADER_FRAGMENT].states.atom, 
id++, evergreen_emit_ps_sampler_states, 0);
-       /* resources */
-       r600_init_atom(rctx, &rctx->vertex_buffer_state.atom, id++, 
evergreen_fs_emit_vertex_buffers, 0);
-       r600_init_atom(rctx, &rctx->cs_vertex_buffer_state.atom, id++, 
evergreen_cs_emit_vertex_buffers, 0);
-       r600_init_atom(rctx, &rctx->samplers[PIPE_SHADER_VERTEX].views.atom, 
id++, evergreen_emit_vs_sampler_views, 0);
-       r600_init_atom(rctx, &rctx->samplers[PIPE_SHADER_GEOMETRY].views.atom, 
id++, evergreen_emit_gs_sampler_views, 0);
-       r600_init_atom(rctx, &rctx->samplers[PIPE_SHADER_FRAGMENT].views.atom, 
id++, evergreen_emit_ps_sampler_views, 0);
-
-       r600_init_atom(rctx, &rctx->vgt_state.atom, id++, r600_emit_vgt_state, 
7);
-
-       if (rctx->chip_class == EVERGREEN) {
-               r600_init_atom(rctx, &rctx->sample_mask.atom, id++, 
evergreen_emit_sample_mask, 3);
-       } else {
-               r600_init_atom(rctx, &rctx->sample_mask.atom, id++, 
cayman_emit_sample_mask, 4);
-       }
-       rctx->sample_mask.sample_mask = ~0;
-
-       r600_init_atom(rctx, &rctx->alphatest_state.atom, id++, 
r600_emit_alphatest_state, 6);
-       r600_init_atom(rctx, &rctx->blend_color.atom, id++, 
r600_emit_blend_color, 6);
-       r600_init_atom(rctx, &rctx->blend_state.atom, id++, 
r600_emit_cso_state, 0);
-       r600_init_atom(rctx, &rctx->cb_misc_state.atom, id++, 
evergreen_emit_cb_misc_state, 4);
-       r600_init_atom(rctx, &rctx->clip_misc_state.atom, id++, 
r600_emit_clip_misc_state, 6);
-       r600_init_atom(rctx, &rctx->clip_state.atom, id++, 
evergreen_emit_clip_state, 26);
-       r600_init_atom(rctx, &rctx->db_misc_state.atom, id++, 
evergreen_emit_db_misc_state, 10);
-       r600_init_atom(rctx, &rctx->db_state.atom, id++, 
evergreen_emit_db_state, 14);
-       r600_init_atom(rctx, &rctx->dsa_state.atom, id++, r600_emit_cso_state, 
0);
-       r600_init_atom(rctx, &rctx->poly_offset_state.atom, id++, 
evergreen_emit_polygon_offset, 6);
-       r600_init_atom(rctx, &rctx->rasterizer_state.atom, id++, 
r600_emit_cso_state, 0);
-       r600_init_atom(rctx, &rctx->scissor.atom, id++, 
evergreen_emit_scissor_state, 4);
-       r600_init_atom(rctx, &rctx->stencil_ref.atom, id++, 
r600_emit_stencil_ref, 4);
-       r600_init_atom(rctx, &rctx->viewport.atom, id++, 
r600_emit_viewport_state, 8);
-       r600_init_atom(rctx, &rctx->vertex_fetch_shader.atom, id++, 
evergreen_emit_vertex_fetch_shader, 5);
-       r600_init_atom(rctx, &rctx->streamout.begin_atom, id++, 
r600_emit_streamout_begin, 0);
-
-       rctx->context.create_blend_state = evergreen_create_blend_state;
-       rctx->context.create_depth_stencil_alpha_state = 
evergreen_create_dsa_state;
-       rctx->context.create_rasterizer_state = evergreen_create_rs_state;
-       rctx->context.create_sampler_state = evergreen_create_sampler_state;
-       rctx->context.create_sampler_view = evergreen_create_sampler_view;
-       rctx->context.set_framebuffer_state = evergreen_set_framebuffer_state;
-       rctx->context.set_polygon_stipple = evergreen_set_polygon_stipple;
-       rctx->context.set_scissor_state = evergreen_set_scissor_state;
-       evergreen_init_compute_state_functions(rctx);
-}
-
 void cayman_init_common_regs(struct r600_command_buffer *cb,
                             enum chip_class ctx_chip_class,
                             enum radeon_family ctx_family,
@@ -3462,15 +3393,11 @@ void evergreen_update_ps_state(struct pipe_context 
*ctx, struct r600_pipe_shader
 
 void evergreen_update_vs_state(struct pipe_context *ctx, struct 
r600_pipe_shader *shader)
 {
-       struct r600_context *rctx = (struct r600_context *)ctx;
-       struct r600_pipe_state *rstate = &shader->rstate;
+       struct r600_command_buffer *cb = &shader->command_buffer;
        struct r600_shader *rshader = &shader->shader;
        unsigned spi_vs_out_id[10] = {};
        unsigned i, tmp, nparams = 0;
 
-       /* clear previous register */
-       rstate->nregs = 0;
-
        for (i = 0; i < rshader->noutput; i++) {
                if (rshader->output[i].spi_sid) {
                        tmp = rshader->output[i].spi_sid << ((nparams & 3) * 8);
@@ -3479,10 +3406,11 @@ void evergreen_update_vs_state(struct pipe_context 
*ctx, struct r600_pipe_shader
                }
        }
 
+       r600_init_command_buffer(cb, 32);
+
+       r600_store_context_reg_seq(cb, R_02861C_SPI_VS_OUT_ID_0, 10);
        for (i = 0; i < 10; i++) {
-               r600_pipe_state_add_reg(rstate,
-                                       R_02861C_SPI_VS_OUT_ID_0 + i * 4,
-                                       spi_vs_out_id[i]);
+               r600_store_value(cb, spi_vs_out_id[i]);
        }
 
        /* Certain attributes (position, psize, etc.) don't count as params.
@@ -3492,17 +3420,14 @@ void evergreen_update_vs_state(struct pipe_context 
*ctx, struct r600_pipe_shader
        if (nparams < 1)
                nparams = 1;
 
-       r600_pipe_state_add_reg(rstate,
-                       R_0286C4_SPI_VS_OUT_CONFIG,
-                       S_0286C4_VS_EXPORT_COUNT(nparams - 1));
-       r600_pipe_state_add_reg(rstate,
-                       R_028860_SQ_PGM_RESOURCES_VS,
-                       S_028860_NUM_GPRS(rshader->bc.ngpr) |
-                       S_028860_STACK_SIZE(rshader->bc.nstack));
-       r600_pipe_state_add_reg_bo(rstate,
-                       R_02885C_SQ_PGM_START_VS,
-                       r600_resource_va(ctx->screen, (void *)shader->bo) >> 8,
-                       shader->bo, RADEON_USAGE_READ);
+       r600_store_context_reg(cb, R_0286C4_SPI_VS_OUT_CONFIG,
+                              S_0286C4_VS_EXPORT_COUNT(nparams - 1));
+       r600_store_context_reg(cb, R_028860_SQ_PGM_RESOURCES_VS,
+                              S_028860_NUM_GPRS(rshader->bc.ngpr) |
+                              S_028860_STACK_SIZE(rshader->bc.nstack));
+       r600_store_context_reg(cb, R_02885C_SQ_PGM_START_VS,
+                              r600_resource_va(ctx->screen, (void 
*)shader->bo) >> 8);
+       /* After that, the NOP relocation packet must be emitted (shader->bo, 
RADEON_USAGE_READ). */
 
        shader->pa_cl_vs_out_cntl =
                S_02881C_VS_OUT_CCDIST0_VEC_ENA((rshader->clip_dist_write & 
0x0F) != 0) |
@@ -3771,3 +3696,73 @@ boolean evergreen_dma_blit(struct pipe_context *ctx,
        }
        return TRUE;
 }
+
+void evergreen_init_state_functions(struct r600_context *rctx)
+{
+       unsigned id = 4;
+
+       /* !!!
+        *  To avoid GPU lockup registers must be emited in a specific order
+        * (no kidding ...). The order below is important and have been
+        * partialy infered from analyzing fglrx command stream.
+        *
+        * Don't reorder atom without carefully checking the effect (GPU lockup
+        * or piglit regression).
+        * !!!
+        */
+
+       r600_init_atom(rctx, &rctx->framebuffer.atom, id++, 
evergreen_emit_framebuffer_state, 0);
+       /* shader const */
+       r600_init_atom(rctx, &rctx->constbuf_state[PIPE_SHADER_VERTEX].atom, 
id++, evergreen_emit_vs_constant_buffers, 0);
+       r600_init_atom(rctx, &rctx->constbuf_state[PIPE_SHADER_GEOMETRY].atom, 
id++, evergreen_emit_gs_constant_buffers, 0);
+       r600_init_atom(rctx, &rctx->constbuf_state[PIPE_SHADER_FRAGMENT].atom, 
id++, evergreen_emit_ps_constant_buffers, 0);
+       /* shader program */
+       r600_init_atom(rctx, &rctx->cs_shader_state.atom, id++, 
evergreen_emit_cs_shader, 0);
+       /* sampler */
+       r600_init_atom(rctx, &rctx->samplers[PIPE_SHADER_VERTEX].states.atom, 
id++, evergreen_emit_vs_sampler_states, 0);
+       r600_init_atom(rctx, &rctx->samplers[PIPE_SHADER_GEOMETRY].states.atom, 
id++, evergreen_emit_gs_sampler_states, 0);
+       r600_init_atom(rctx, &rctx->samplers[PIPE_SHADER_FRAGMENT].states.atom, 
id++, evergreen_emit_ps_sampler_states, 0);
+       /* resources */
+       r600_init_atom(rctx, &rctx->vertex_buffer_state.atom, id++, 
evergreen_fs_emit_vertex_buffers, 0);
+       r600_init_atom(rctx, &rctx->cs_vertex_buffer_state.atom, id++, 
evergreen_cs_emit_vertex_buffers, 0);
+       r600_init_atom(rctx, &rctx->samplers[PIPE_SHADER_VERTEX].views.atom, 
id++, evergreen_emit_vs_sampler_views, 0);
+       r600_init_atom(rctx, &rctx->samplers[PIPE_SHADER_GEOMETRY].views.atom, 
id++, evergreen_emit_gs_sampler_views, 0);
+       r600_init_atom(rctx, &rctx->samplers[PIPE_SHADER_FRAGMENT].views.atom, 
id++, evergreen_emit_ps_sampler_views, 0);
+
+       r600_init_atom(rctx, &rctx->vgt_state.atom, id++, r600_emit_vgt_state, 
7);
+
+       if (rctx->chip_class == EVERGREEN) {
+               r600_init_atom(rctx, &rctx->sample_mask.atom, id++, 
evergreen_emit_sample_mask, 3);
+       } else {
+               r600_init_atom(rctx, &rctx->sample_mask.atom, id++, 
cayman_emit_sample_mask, 4);
+       }
+       rctx->sample_mask.sample_mask = ~0;
+
+       r600_init_atom(rctx, &rctx->alphatest_state.atom, id++, 
r600_emit_alphatest_state, 6);
+       r600_init_atom(rctx, &rctx->blend_color.atom, id++, 
r600_emit_blend_color, 6);
+       r600_init_atom(rctx, &rctx->blend_state.atom, id++, 
r600_emit_cso_state, 0);
+       r600_init_atom(rctx, &rctx->cb_misc_state.atom, id++, 
evergreen_emit_cb_misc_state, 4);
+       r600_init_atom(rctx, &rctx->clip_misc_state.atom, id++, 
r600_emit_clip_misc_state, 6);
+       r600_init_atom(rctx, &rctx->clip_state.atom, id++, 
evergreen_emit_clip_state, 26);
+       r600_init_atom(rctx, &rctx->db_misc_state.atom, id++, 
evergreen_emit_db_misc_state, 10);
+       r600_init_atom(rctx, &rctx->db_state.atom, id++, 
evergreen_emit_db_state, 14);
+       r600_init_atom(rctx, &rctx->dsa_state.atom, id++, r600_emit_cso_state, 
0);
+       r600_init_atom(rctx, &rctx->poly_offset_state.atom, id++, 
evergreen_emit_polygon_offset, 6);
+       r600_init_atom(rctx, &rctx->rasterizer_state.atom, id++, 
r600_emit_cso_state, 0);
+       r600_init_atom(rctx, &rctx->scissor.atom, id++, 
evergreen_emit_scissor_state, 4);
+       r600_init_atom(rctx, &rctx->stencil_ref.atom, id++, 
r600_emit_stencil_ref, 4);
+       r600_init_atom(rctx, &rctx->viewport.atom, id++, 
r600_emit_viewport_state, 8);
+       r600_init_atom(rctx, &rctx->vertex_fetch_shader.atom, id++, 
evergreen_emit_vertex_fetch_shader, 5);
+       r600_init_atom(rctx, &rctx->streamout.begin_atom, id++, 
r600_emit_streamout_begin, 0);
+       r600_init_atom(rctx, &rctx->vertex_shader.atom, id++, r600_emit_shader, 
23);
+
+       rctx->context.create_blend_state = evergreen_create_blend_state;
+       rctx->context.create_depth_stencil_alpha_state = 
evergreen_create_dsa_state;
+       rctx->context.create_rasterizer_state = evergreen_create_rs_state;
+       rctx->context.create_sampler_state = evergreen_create_sampler_state;
+       rctx->context.create_sampler_view = evergreen_create_sampler_view;
+       rctx->context.set_framebuffer_state = evergreen_set_framebuffer_state;
+       rctx->context.set_polygon_stipple = evergreen_set_polygon_stipple;
+       rctx->context.set_scissor_state = evergreen_set_scissor_state;
+       evergreen_init_compute_state_functions(rctx);
+}
diff --git a/src/gallium/drivers/r600/r600_hw_context.c 
b/src/gallium/drivers/r600/r600_hw_context.c
index 677c6fc..a2eefa8 100644
--- a/src/gallium/drivers/r600/r600_hw_context.c
+++ b/src/gallium/drivers/r600/r600_hw_context.c
@@ -216,22 +216,6 @@ int r600_context_add_block(struct r600_context *ctx, const 
struct r600_reg *reg,
 }
 
 static const struct r600_reg r600_context_reg_list[] = {
-       {R_028614_SPI_VS_OUT_ID_0, 0, 0},
-       {R_028618_SPI_VS_OUT_ID_1, 0, 0},
-       {R_02861C_SPI_VS_OUT_ID_2, 0, 0},
-       {R_028620_SPI_VS_OUT_ID_3, 0, 0},
-       {R_028624_SPI_VS_OUT_ID_4, 0, 0},
-       {R_028628_SPI_VS_OUT_ID_5, 0, 0},
-       {R_02862C_SPI_VS_OUT_ID_6, 0, 0},
-       {R_028630_SPI_VS_OUT_ID_7, 0, 0},
-       {R_028634_SPI_VS_OUT_ID_8, 0, 0},
-       {R_028638_SPI_VS_OUT_ID_9, 0, 0},
-       {R_0286C4_SPI_VS_OUT_CONFIG, 0, 0},
-       {GROUP_FORCE_NEW_BLOCK, 0, 0},
-       {R_028858_SQ_PGM_START_VS, REG_FLAG_NEED_BO, 0},
-       {GROUP_FORCE_NEW_BLOCK, 0, 0},
-       {R_028868_SQ_PGM_RESOURCES_VS, 0, 0},
-       {GROUP_FORCE_NEW_BLOCK, 0, 0},
        {R_028644_SPI_PS_INPUT_CNTL_0, 0, 0},
        {R_028648_SPI_PS_INPUT_CNTL_1, 0, 0},
        {R_02864C_SPI_PS_INPUT_CNTL_2, 0, 0},
@@ -829,6 +813,7 @@ void r600_begin_new_cs(struct r600_context *ctx)
        ctx->config_state.atom.dirty = true;
        ctx->stencil_ref.atom.dirty = true;
        ctx->vertex_fetch_shader.atom.dirty = true;
+       ctx->vertex_shader.atom.dirty = true;
        ctx->viewport.atom.dirty = true;
 
        if (ctx->blend_state.cso)
diff --git a/src/gallium/drivers/r600/r600_pipe.h 
b/src/gallium/drivers/r600/r600_pipe.h
index 28c7de3..813012f 100644
--- a/src/gallium/drivers/r600/r600_pipe.h
+++ b/src/gallium/drivers/r600/r600_pipe.h
@@ -34,7 +34,7 @@
 #include "r600_public.h"
 #include "r600_resource.h"
 
-#define R600_NUM_ATOMS 38
+#define R600_NUM_ATOMS 39
 
 #define R600_TRACE_CS 0
 
@@ -425,6 +425,11 @@ struct r600_fetch_shader {
        unsigned                        offset;
 };
 
+struct r600_shader_state {
+       struct r600_atom                atom;
+       struct r600_pipe_shader_selector *shader;
+};
+
 struct r600_streamout {
        struct r600_atom                begin_atom;
        bool                            begin_emitted;
@@ -518,6 +523,8 @@ struct r600_context {
        struct r600_viewport_state      viewport;
        /* Shaders and shader resources. */
        struct r600_cso_state           vertex_fetch_shader;
+       struct r600_shader_state        vertex_shader;
+       struct r600_shader_state        pixel_shader;
        struct r600_cs_shader_state     cs_shader_state;
        struct r600_constbuf_state      constbuf_state[PIPE_SHADER_TYPES];
        struct r600_textures_info       samplers[PIPE_SHADER_TYPES];
@@ -530,8 +537,8 @@ struct r600_context {
        /* Additional context states. */
        unsigned                        flags;
        unsigned                        compute_cb_target_mask;
-       struct r600_pipe_shader_selector        *ps_shader;
-       struct r600_pipe_shader_selector        *vs_shader;
+       struct r600_pipe_shader_selector *ps_shader;
+       struct r600_pipe_shader_selector *vs_shader;
        struct r600_rasterizer_state    *rasterizer;
        bool                            alpha_to_one;
        bool                            force_blend_disable;
@@ -745,6 +752,7 @@ void r600_emit_vgt_state(struct r600_context *rctx, struct 
r600_atom *atom);
 void r600_emit_clip_misc_state(struct r600_context *rctx, struct r600_atom 
*atom);
 void r600_emit_stencil_ref(struct r600_context *rctx, struct r600_atom *atom);
 void r600_emit_viewport_state(struct r600_context *rctx, struct r600_atom 
*atom);
+void r600_emit_shader(struct r600_context *rctx, struct r600_atom *a);
 void r600_init_atom(struct r600_context *rctx, struct r600_atom *atom, 
unsigned id,
                    void (*emit)(struct r600_context *ctx, struct r600_atom 
*state),
                    unsigned num_dw);
diff --git a/src/gallium/drivers/r600/r600_shader.c 
b/src/gallium/drivers/r600/r600_shader.c
index 7ecab7b..621db79 100644
--- a/src/gallium/drivers/r600/r600_shader.c
+++ b/src/gallium/drivers/r600/r600_shader.c
@@ -190,6 +190,7 @@ void r600_pipe_shader_destroy(struct pipe_context *ctx, 
struct r600_pipe_shader
 {
        pipe_resource_reference((struct pipe_resource**)&shader->bo, NULL);
        r600_bytecode_clear(&shader->shader.bc);
+       r600_release_command_buffer(&shader->command_buffer);
 }
 
 /*
diff --git a/src/gallium/drivers/r600/r600_shader.h 
b/src/gallium/drivers/r600/r600_shader.h
index f55e002..925dc44 100644
--- a/src/gallium/drivers/r600/r600_shader.h
+++ b/src/gallium/drivers/r600/r600_shader.h
@@ -75,6 +75,7 @@ struct r600_pipe_shader {
        struct r600_pipe_shader_selector *selector;
        struct r600_pipe_shader *next_variant;
        struct r600_shader      shader;
+       struct r600_command_buffer command_buffer; /* register writes */
        struct r600_pipe_state  rstate;
        struct r600_resource    *bo;
        unsigned                sprite_coord_enable;
diff --git a/src/gallium/drivers/r600/r600_state.c 
b/src/gallium/drivers/r600/r600_state.c
index 2ddd567..e8d7c84 100644
--- a/src/gallium/drivers/r600/r600_state.c
+++ b/src/gallium/drivers/r600/r600_state.c
@@ -2280,73 +2280,6 @@ static void r600_emit_vertex_fetch_shader(struct 
r600_context *rctx, struct r600
        r600_write_value(cs, r600_context_bo_reloc(rctx, &rctx->rings.gfx, 
shader->buffer, RADEON_USAGE_READ));
 }
 
-void r600_init_state_functions(struct r600_context *rctx)
-{
-       unsigned id = 4;
-
-       /* !!!
-        *  To avoid GPU lockup registers must be emited in a specific order
-        * (no kidding ...). The order below is important and have been
-        * partialy infered from analyzing fglrx command stream.
-        *
-        * Don't reorder atom without carefully checking the effect (GPU lockup
-        * or piglit regression).
-        * !!!
-        */
-
-       r600_init_atom(rctx, &rctx->framebuffer.atom, id++, 
r600_emit_framebuffer_state, 0);
-
-       /* shader const */
-       r600_init_atom(rctx, &rctx->constbuf_state[PIPE_SHADER_VERTEX].atom, 
id++, r600_emit_vs_constant_buffers, 0);
-       r600_init_atom(rctx, &rctx->constbuf_state[PIPE_SHADER_GEOMETRY].atom, 
id++, r600_emit_gs_constant_buffers, 0);
-       r600_init_atom(rctx, &rctx->constbuf_state[PIPE_SHADER_FRAGMENT].atom, 
id++, r600_emit_ps_constant_buffers, 0);
-
-       /* sampler must be emited before TA_CNTL_AUX otherwise 
DISABLE_CUBE_WRAP change
-        * does not take effect (TA_CNTL_AUX emited by 
r600_emit_seamless_cube_map)
-        */
-       r600_init_atom(rctx, &rctx->samplers[PIPE_SHADER_VERTEX].states.atom, 
id++, r600_emit_vs_sampler_states, 0);
-       r600_init_atom(rctx, &rctx->samplers[PIPE_SHADER_GEOMETRY].states.atom, 
id++, r600_emit_gs_sampler_states, 0);
-       r600_init_atom(rctx, &rctx->samplers[PIPE_SHADER_FRAGMENT].states.atom, 
id++, r600_emit_ps_sampler_states, 0);
-       /* resource */
-       r600_init_atom(rctx, &rctx->samplers[PIPE_SHADER_VERTEX].views.atom, 
id++, r600_emit_vs_sampler_views, 0);
-       r600_init_atom(rctx, &rctx->samplers[PIPE_SHADER_GEOMETRY].views.atom, 
id++, r600_emit_gs_sampler_views, 0);
-       r600_init_atom(rctx, &rctx->samplers[PIPE_SHADER_FRAGMENT].views.atom, 
id++, r600_emit_ps_sampler_views, 0);
-       r600_init_atom(rctx, &rctx->vertex_buffer_state.atom, id++, 
r600_emit_vertex_buffers, 0);
-
-       r600_init_atom(rctx, &rctx->vgt_state.atom, id++, r600_emit_vgt_state, 
7);
-
-       r600_init_atom(rctx, &rctx->seamless_cube_map.atom, id++, 
r600_emit_seamless_cube_map, 3);
-       r600_init_atom(rctx, &rctx->sample_mask.atom, id++, 
r600_emit_sample_mask, 3);
-       rctx->sample_mask.sample_mask = ~0;
-
-       r600_init_atom(rctx, &rctx->alphatest_state.atom, id++, 
r600_emit_alphatest_state, 6);
-       r600_init_atom(rctx, &rctx->blend_color.atom, id++, 
r600_emit_blend_color, 6);
-       r600_init_atom(rctx, &rctx->blend_state.atom, id++, 
r600_emit_cso_state, 0);
-       r600_init_atom(rctx, &rctx->cb_misc_state.atom, id++, 
r600_emit_cb_misc_state, 7);
-       r600_init_atom(rctx, &rctx->clip_misc_state.atom, id++, 
r600_emit_clip_misc_state, 6);
-       r600_init_atom(rctx, &rctx->clip_state.atom, id++, 
r600_emit_clip_state, 26);
-       r600_init_atom(rctx, &rctx->db_misc_state.atom, id++, 
r600_emit_db_misc_state, 7);
-       r600_init_atom(rctx, &rctx->db_state.atom, id++, r600_emit_db_state, 
11);
-       r600_init_atom(rctx, &rctx->dsa_state.atom, id++, r600_emit_cso_state, 
0);
-       r600_init_atom(rctx, &rctx->poly_offset_state.atom, id++, 
r600_emit_polygon_offset, 6);
-       r600_init_atom(rctx, &rctx->rasterizer_state.atom, id++, 
r600_emit_cso_state, 0);
-       r600_init_atom(rctx, &rctx->scissor.atom, id++, 
r600_emit_scissor_state, 4);
-       r600_init_atom(rctx, &rctx->config_state.atom, id++, 
r600_emit_config_state, 3);
-       r600_init_atom(rctx, &rctx->stencil_ref.atom, id++, 
r600_emit_stencil_ref, 4);
-       r600_init_atom(rctx, &rctx->viewport.atom, id++, 
r600_emit_viewport_state, 8);
-       r600_init_atom(rctx, &rctx->vertex_fetch_shader.atom, id++, 
r600_emit_vertex_fetch_shader, 5);
-       r600_init_atom(rctx, &rctx->streamout.begin_atom, id++, 
r600_emit_streamout_begin, 0);
-
-       rctx->context.create_blend_state = r600_create_blend_state;
-       rctx->context.create_depth_stencil_alpha_state = r600_create_dsa_state;
-       rctx->context.create_rasterizer_state = r600_create_rs_state;
-       rctx->context.create_sampler_state = r600_create_sampler_state;
-       rctx->context.create_sampler_view = r600_create_sampler_view;
-       rctx->context.set_framebuffer_state = r600_set_framebuffer_state;
-       rctx->context.set_polygon_stipple = r600_set_polygon_stipple;
-       rctx->context.set_scissor_state = r600_set_scissor_state;
-}
-
 /* Adjust GPR allocation on R6xx/R7xx */
 bool r600_adjust_gprs(struct r600_context *rctx)
 {
@@ -2876,15 +2809,11 @@ void r600_update_ps_state(struct pipe_context *ctx, 
struct r600_pipe_shader *sha
 
 void r600_update_vs_state(struct pipe_context *ctx, struct r600_pipe_shader 
*shader)
 {
-       struct r600_context *rctx = (struct r600_context *)ctx;
-       struct r600_pipe_state *rstate = &shader->rstate;
+       struct r600_command_buffer *cb = &shader->command_buffer;
        struct r600_shader *rshader = &shader->shader;
        unsigned spi_vs_out_id[10] = {};
        unsigned i, tmp, nparams = 0;
 
-       /* clear previous register */
-       rstate->nregs = 0;
-
        for (i = 0; i < rshader->noutput; i++) {
                if (rshader->output[i].spi_sid) {
                        tmp = rshader->output[i].spi_sid << ((nparams & 3) * 8);
@@ -2893,10 +2822,11 @@ void r600_update_vs_state(struct pipe_context *ctx, 
struct r600_pipe_shader *sha
                }
        }
 
+       r600_init_command_buffer(cb, 32);
+
+       r600_store_context_reg_seq(cb, R_028614_SPI_VS_OUT_ID_0, 10);
        for (i = 0; i < 10; i++) {
-               r600_pipe_state_add_reg(rstate,
-                                       R_028614_SPI_VS_OUT_ID_0 + i * 4,
-                                       spi_vs_out_id[i]);
+               r600_store_value(cb, spi_vs_out_id[i]);
        }
 
        /* Certain attributes (position, psize, etc.) don't count as params.
@@ -2906,16 +2836,13 @@ void r600_update_vs_state(struct pipe_context *ctx, 
struct r600_pipe_shader *sha
        if (nparams < 1)
                nparams = 1;
 
-       r600_pipe_state_add_reg(rstate,
-                               R_0286C4_SPI_VS_OUT_CONFIG,
-                               S_0286C4_VS_EXPORT_COUNT(nparams - 1));
-       r600_pipe_state_add_reg(rstate,
-                               R_028868_SQ_PGM_RESOURCES_VS,
-                               S_028868_NUM_GPRS(rshader->bc.ngpr) |
-                               S_028868_STACK_SIZE(rshader->bc.nstack));
-       r600_pipe_state_add_reg_bo(rstate,
-                       R_028858_SQ_PGM_START_VS,
-                       0, shader->bo, RADEON_USAGE_READ);
+       r600_store_context_reg(cb, R_0286C4_SPI_VS_OUT_CONFIG,
+                              S_0286C4_VS_EXPORT_COUNT(nparams - 1));
+       r600_store_context_reg(cb, R_028868_SQ_PGM_RESOURCES_VS,
+                              S_028868_NUM_GPRS(rshader->bc.ngpr) |
+                              S_028868_STACK_SIZE(rshader->bc.nstack));
+       r600_store_context_reg(cb, R_028858_SQ_PGM_START_VS, 0);
+       /* After that, the NOP relocation packet must be emitted (shader->bo, 
RADEON_USAGE_READ). */
 
        shader->pa_cl_vs_out_cntl =
                S_02881C_VS_OUT_CCDIST0_VEC_ENA((rshader->clip_dist_write & 
0x0F) != 0) |
@@ -3207,3 +3134,72 @@ boolean r600_dma_blit(struct pipe_context *ctx,
        }
        return TRUE;
 }
+
+void r600_init_state_functions(struct r600_context *rctx)
+{
+       unsigned id = 4;
+
+       /* !!!
+        *  To avoid GPU lockup registers must be emited in a specific order
+        * (no kidding ...). The order below is important and have been
+        * partialy infered from analyzing fglrx command stream.
+        *
+        * Don't reorder atom without carefully checking the effect (GPU lockup
+        * or piglit regression).
+        * !!!
+        */
+
+       r600_init_atom(rctx, &rctx->framebuffer.atom, id++, 
r600_emit_framebuffer_state, 0);
+
+       /* shader const */
+       r600_init_atom(rctx, &rctx->constbuf_state[PIPE_SHADER_VERTEX].atom, 
id++, r600_emit_vs_constant_buffers, 0);
+       r600_init_atom(rctx, &rctx->constbuf_state[PIPE_SHADER_GEOMETRY].atom, 
id++, r600_emit_gs_constant_buffers, 0);
+       r600_init_atom(rctx, &rctx->constbuf_state[PIPE_SHADER_FRAGMENT].atom, 
id++, r600_emit_ps_constant_buffers, 0);
+
+       /* sampler must be emited before TA_CNTL_AUX otherwise 
DISABLE_CUBE_WRAP change
+        * does not take effect (TA_CNTL_AUX emited by 
r600_emit_seamless_cube_map)
+        */
+       r600_init_atom(rctx, &rctx->samplers[PIPE_SHADER_VERTEX].states.atom, 
id++, r600_emit_vs_sampler_states, 0);
+       r600_init_atom(rctx, &rctx->samplers[PIPE_SHADER_GEOMETRY].states.atom, 
id++, r600_emit_gs_sampler_states, 0);
+       r600_init_atom(rctx, &rctx->samplers[PIPE_SHADER_FRAGMENT].states.atom, 
id++, r600_emit_ps_sampler_states, 0);
+       /* resource */
+       r600_init_atom(rctx, &rctx->samplers[PIPE_SHADER_VERTEX].views.atom, 
id++, r600_emit_vs_sampler_views, 0);
+       r600_init_atom(rctx, &rctx->samplers[PIPE_SHADER_GEOMETRY].views.atom, 
id++, r600_emit_gs_sampler_views, 0);
+       r600_init_atom(rctx, &rctx->samplers[PIPE_SHADER_FRAGMENT].views.atom, 
id++, r600_emit_ps_sampler_views, 0);
+       r600_init_atom(rctx, &rctx->vertex_buffer_state.atom, id++, 
r600_emit_vertex_buffers, 0);
+
+       r600_init_atom(rctx, &rctx->vgt_state.atom, id++, r600_emit_vgt_state, 
7);
+
+       r600_init_atom(rctx, &rctx->seamless_cube_map.atom, id++, 
r600_emit_seamless_cube_map, 3);
+       r600_init_atom(rctx, &rctx->sample_mask.atom, id++, 
r600_emit_sample_mask, 3);
+       rctx->sample_mask.sample_mask = ~0;
+
+       r600_init_atom(rctx, &rctx->alphatest_state.atom, id++, 
r600_emit_alphatest_state, 6);
+       r600_init_atom(rctx, &rctx->blend_color.atom, id++, 
r600_emit_blend_color, 6);
+       r600_init_atom(rctx, &rctx->blend_state.atom, id++, 
r600_emit_cso_state, 0);
+       r600_init_atom(rctx, &rctx->cb_misc_state.atom, id++, 
r600_emit_cb_misc_state, 7);
+       r600_init_atom(rctx, &rctx->clip_misc_state.atom, id++, 
r600_emit_clip_misc_state, 6);
+       r600_init_atom(rctx, &rctx->clip_state.atom, id++, 
r600_emit_clip_state, 26);
+       r600_init_atom(rctx, &rctx->db_misc_state.atom, id++, 
r600_emit_db_misc_state, 7);
+       r600_init_atom(rctx, &rctx->db_state.atom, id++, r600_emit_db_state, 
11);
+       r600_init_atom(rctx, &rctx->dsa_state.atom, id++, r600_emit_cso_state, 
0);
+       r600_init_atom(rctx, &rctx->poly_offset_state.atom, id++, 
r600_emit_polygon_offset, 6);
+       r600_init_atom(rctx, &rctx->rasterizer_state.atom, id++, 
r600_emit_cso_state, 0);
+       r600_init_atom(rctx, &rctx->scissor.atom, id++, 
r600_emit_scissor_state, 4);
+       r600_init_atom(rctx, &rctx->config_state.atom, id++, 
r600_emit_config_state, 3);
+       r600_init_atom(rctx, &rctx->stencil_ref.atom, id++, 
r600_emit_stencil_ref, 4);
+       r600_init_atom(rctx, &rctx->viewport.atom, id++, 
r600_emit_viewport_state, 8);
+       r600_init_atom(rctx, &rctx->vertex_fetch_shader.atom, id++, 
r600_emit_vertex_fetch_shader, 5);
+       r600_init_atom(rctx, &rctx->streamout.begin_atom, id++, 
r600_emit_streamout_begin, 0);
+       r600_init_atom(rctx, &rctx->vertex_shader.atom, id++, r600_emit_shader, 
23);
+
+       rctx->context.create_blend_state = r600_create_blend_state;
+       rctx->context.create_depth_stencil_alpha_state = r600_create_dsa_state;
+       rctx->context.create_rasterizer_state = r600_create_rs_state;
+       rctx->context.create_sampler_state = r600_create_sampler_state;
+       rctx->context.create_sampler_view = r600_create_sampler_view;
+       rctx->context.set_framebuffer_state = r600_set_framebuffer_state;
+       rctx->context.set_polygon_stipple = r600_set_polygon_stipple;
+       rctx->context.set_scissor_state = r600_set_scissor_state;
+}
+/* this function must be last */
diff --git a/src/gallium/drivers/r600/r600_state_common.c 
b/src/gallium/drivers/r600/r600_state_common.c
index 4566fc7..842d0d4 100644
--- a/src/gallium/drivers/r600/r600_state_common.c
+++ b/src/gallium/drivers/r600/r600_state_common.c
@@ -846,19 +846,20 @@ static void r600_bind_vs_state(struct pipe_context *ctx, 
void *state)
 {
        struct r600_context *rctx = (struct r600_context *)ctx;
 
-       rctx->vs_shader = (struct r600_pipe_shader_selector *)state;
-       if (state) {
-               r600_context_pipe_state_set(rctx, 
&rctx->vs_shader->current->rstate);
-
-               r600_context_add_resource_size(ctx, (struct pipe_resource 
*)rctx->vs_shader->current->bo);
-
-               /* Update clip misc state. */
-               if (rctx->vs_shader->current->pa_cl_vs_out_cntl != 
rctx->clip_misc_state.pa_cl_vs_out_cntl ||
-                   rctx->vs_shader->current->shader.clip_dist_write != 
rctx->clip_misc_state.clip_dist_write) {
-                       rctx->clip_misc_state.pa_cl_vs_out_cntl = 
rctx->vs_shader->current->pa_cl_vs_out_cntl;
-                       rctx->clip_misc_state.clip_dist_write = 
rctx->vs_shader->current->shader.clip_dist_write;
-                       rctx->clip_misc_state.atom.dirty = true;
-               }
+       if (!state)
+               return;
+
+       rctx->vertex_shader.shader = rctx->vs_shader = (struct 
r600_pipe_shader_selector *)state;
+       rctx->vertex_shader.atom.dirty = true;
+
+       r600_context_add_resource_size(ctx, (struct pipe_resource 
*)rctx->vs_shader->current->bo);
+
+       /* Update clip misc state. */
+       if (rctx->vs_shader->current->pa_cl_vs_out_cntl != 
rctx->clip_misc_state.pa_cl_vs_out_cntl ||
+           rctx->vs_shader->current->shader.clip_dist_write != 
rctx->clip_misc_state.clip_dist_write) {
+               rctx->clip_misc_state.pa_cl_vs_out_cntl = 
rctx->vs_shader->current->pa_cl_vs_out_cntl;
+               rctx->clip_misc_state.clip_dist_write = 
rctx->vs_shader->current->shader.clip_dist_write;
+               rctx->clip_misc_state.atom.dirty = true;
        }
 }
 
@@ -1748,6 +1749,17 @@ bool sampler_state_needs_border_color(const struct 
pipe_sampler_state *state)
                wrap_mode_uses_border_color(state->wrap_r, linear_filter));
 }
 
+void r600_emit_shader(struct r600_context *rctx, struct r600_atom *a)
+{
+       struct radeon_winsys_cs *cs = rctx->rings.gfx.cs;
+       struct r600_pipe_shader *shader = ((struct 
r600_shader_state*)a)->shader->current;
+
+       r600_emit_command_buffer(cs, &shader->command_buffer);
+
+       r600_write_value(cs, PKT3(PKT3_NOP, 0, 0));
+       r600_write_value(cs, r600_context_bo_reloc(rctx, &rctx->rings.gfx, 
shader->bo, RADEON_USAGE_READ));
+}
+
 /* keep this at the end of this file, please */
 void r600_init_common_state_functions(struct r600_context *rctx)
 {
-- 
1.7.10.4

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to