[Mesa-dev] [PATCH 2/6] r600g: atomize vertex shader

Marek Olšák maraeo at gmail.com
Sun Mar 3 05:39:54 PST 2013


---
 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



More information about the mesa-dev mailing list