summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/r600
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2013-02-28 17:27:36 +0100
committerMarek Olšák <[email protected]>2013-03-11 13:43:36 +0100
commit63042af933eb97930077ad57b047ffa7abb0f6e0 (patch)
treec99e03c4b4027fe1616b21c8d28b909c0d7e3adf /src/gallium/drivers/r600
parent167263ecb17264fce3d17f516e6234fc87bd6029 (diff)
r600g: atomize vertex shader
Reviewed-by: Jerome Glisse <[email protected]>
Diffstat (limited to 'src/gallium/drivers/r600')
-rw-r--r--src/gallium/drivers/r600/evergreen_hw_context.c27
-rw-r--r--src/gallium/drivers/r600/evergreen_state.c171
-rw-r--r--src/gallium/drivers/r600/r600_hw_context.c17
-rw-r--r--src/gallium/drivers/r600/r600_pipe.h14
-rw-r--r--src/gallium/drivers/r600/r600_shader.c1
-rw-r--r--src/gallium/drivers/r600/r600_shader.h1
-rw-r--r--src/gallium/drivers/r600/r600_state.c166
-rw-r--r--src/gallium/drivers/r600/r600_state_common.c38
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 f81d7f3216b..730e51fbfc6 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 5c7cd40d1ef..c52e4c8f074 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 677c6fca4f4..a2eefa8199f 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 28c7de31da8..813012fd2de 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 7ecab7bbf4f..621db79095d 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 f55e002aea6..925dc44d83e 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 2ddd567043b..e8d7c8469ee 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 4566fc7df63..842d0d4aa47 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)
{