From 63042af933eb97930077ad57b047ffa7abb0f6e0 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Thu, 28 Feb 2013 17:27:36 +0100 Subject: [PATCH] r600g: atomize vertex shader Reviewed-by: Jerome Glisse --- 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) { -- 2.7.4