From a50edc8ed84c4c48c0dc8e1a079e8d5e8f1c3a0e Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Fri, 5 Oct 2012 04:02:22 +0200 Subject: [PATCH] r600g: atomize fetch shader The state object is actually a buffer, it's literally a buffer containing the shader code. Reviewed-by: Jerome Glisse --- .../drivers/r600/evergreen_hw_context.c | 2 - src/gallium/drivers/r600/evergreen_state.c | 25 ++++---- src/gallium/drivers/r600/r600_asm.c | 63 +++++++++---------- src/gallium/drivers/r600/r600_asm.h | 5 +- src/gallium/drivers/r600/r600_blit.c | 2 +- src/gallium/drivers/r600/r600_hw_context.c | 3 +- src/gallium/drivers/r600/r600_pipe.h | 20 +----- src/gallium/drivers/r600/r600_state.c | 26 ++++---- src/gallium/drivers/r600/r600_state_common.c | 42 +------------ 9 files changed, 67 insertions(+), 121 deletions(-) diff --git a/src/gallium/drivers/r600/evergreen_hw_context.c b/src/gallium/drivers/r600/evergreen_hw_context.c index 547f4f57d3e..57ebbb05bcb 100644 --- a/src/gallium/drivers/r600/evergreen_hw_context.c +++ b/src/gallium/drivers/r600/evergreen_hw_context.c @@ -103,7 +103,6 @@ static const struct r600_reg evergreen_context_reg_list[] = { {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}, - {R_0288A4_SQ_PGM_START_FS, REG_FLAG_NEED_BO, 0}, {R_0288EC_SQ_LDS_ALLOC_PS, 0, 0}, {R_028A00_PA_SU_POINT_SIZE, 0, 0}, {R_028A04_PA_SU_POINT_MINMAX, 0, 0}, @@ -190,7 +189,6 @@ static const struct r600_reg cayman_context_reg_list[] = { {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}, - {R_0288A4_SQ_PGM_START_FS, REG_FLAG_NEED_BO, 0}, {R_028900_SQ_ESGS_RING_ITEMSIZE, 0, 0}, {R_028904_SQ_GSVS_RING_ITEMSIZE, 0, 0}, {R_028908_SQ_ESTMP_RING_ITEMSIZE, 0, 0}, diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c index 9aef66bfc28..d2bbc5be94b 100644 --- a/src/gallium/drivers/r600/evergreen_state.c +++ b/src/gallium/drivers/r600/evergreen_state.c @@ -2309,6 +2309,18 @@ static void cayman_emit_sample_mask(struct r600_context *rctx, struct r600_atom r600_write_value(cs, mask | (mask << 16)); /* X0Y1_X1Y1 */ } +static void evergreen_emit_vertex_fetch_shader(struct r600_context *rctx, struct r600_atom *a) +{ + struct radeon_winsys_cs *cs = rctx->cs; + struct r600_cso_state *state = (struct r600_cso_state*)a; + struct r600_resource *shader = (struct r600_resource*)state->cso; + + r600_write_context_reg(cs, R_0288A4_SQ_PGM_START_FS, + r600_resource_va(rctx->context.screen, &shader->b.b) >> 8); + r600_write_value(cs, PKT3(PKT3_NOP, 0, 0)); + r600_write_value(cs, r600_context_bo_reloc(rctx, shader, RADEON_USAGE_READ)); +} + void evergreen_init_state_functions(struct r600_context *rctx) { unsigned id = 4; @@ -2360,6 +2372,7 @@ void evergreen_init_state_functions(struct r600_context *rctx) r600_init_atom(rctx, &rctx->db_misc_state.atom, id++, evergreen_emit_db_misc_state, 7); 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); rctx->context.create_blend_state = evergreen_create_blend_state; rctx->context.create_depth_stencil_alpha_state = evergreen_create_dsa_state; @@ -3323,18 +3336,6 @@ void evergreen_pipe_shader_vs(struct pipe_context *ctx, struct r600_pipe_shader S_02881C_USE_VTX_POINT_SIZE(rshader->vs_out_point_size); } -void evergreen_fetch_shader(struct pipe_context *ctx, - struct r600_vertex_element *ve) -{ - struct r600_context *rctx = (struct r600_context *)ctx; - struct r600_pipe_state *rstate = &ve->rstate; - rstate->id = R600_PIPE_STATE_FETCH_SHADER; - rstate->nregs = 0; - r600_pipe_state_add_reg_bo(rstate, R_0288A4_SQ_PGM_START_FS, - r600_resource_va(ctx->screen, (void *)ve->fetch_shader) >> 8, - ve->fetch_shader, RADEON_USAGE_READ); -} - void *evergreen_create_resolve_blend(struct r600_context *rctx) { struct pipe_blend_state blend; diff --git a/src/gallium/drivers/r600/r600_asm.c b/src/gallium/drivers/r600/r600_asm.c index 63bd8e9058b..37e8bf002d4 100644 --- a/src/gallium/drivers/r600/r600_asm.c +++ b/src/gallium/drivers/r600/r600_asm.c @@ -2747,23 +2747,27 @@ out_unknown: R600_ERR("unsupported vertex format %s\n", util_format_name(pformat)); } -int r600_vertex_elements_build_fetch_shader(struct r600_context *rctx, struct r600_vertex_element *ve) +void *r600_create_vertex_fetch_shader(struct pipe_context *ctx, + unsigned count, + const struct pipe_vertex_element *elements) { + struct r600_context *rctx = (struct r600_context *)ctx; static int dump_shaders = -1; - struct r600_bytecode bc; struct r600_bytecode_vtx vtx; - struct pipe_vertex_element *elements = ve->elements; const struct util_format_description *desc; unsigned fetch_resource_start = rctx->chip_class >= EVERGREEN ? 0 : 160; unsigned format, num_format, format_comp, endian; uint32_t *bytecode; - int i, j, r; + int i, j, r, fs_size; + struct r600_resource *fetch_shader; + + assert(count < 32); memset(&bc, 0, sizeof(bc)); r600_bytecode_init(&bc, rctx->chip_class, rctx->family); - for (i = 0; i < ve->count; i++) { + for (i = 0; i < count; i++) { if (elements[i].instance_divisor > 1) { if (rctx->chip_class == CAYMAN) { for (j = 0; j < 4; j++) { @@ -2780,7 +2784,7 @@ int r600_vertex_elements_build_fetch_shader(struct r600_context *rctx, struct r6 alu.last = j == 3; if ((r = r600_bytecode_add_alu(&bc, &alu))) { r600_bytecode_clear(&bc); - return r; + return NULL; } } } else { @@ -2797,27 +2801,27 @@ int r600_vertex_elements_build_fetch_shader(struct r600_context *rctx, struct r6 alu.last = 1; if ((r = r600_bytecode_add_alu(&bc, &alu))) { r600_bytecode_clear(&bc); - return r; + return NULL; } } } } - for (i = 0; i < ve->count; i++) { - r600_vertex_data_type(ve->elements[i].src_format, + for (i = 0; i < count; i++) { + r600_vertex_data_type(elements[i].src_format, &format, &num_format, &format_comp, &endian); - desc = util_format_description(ve->elements[i].src_format); + desc = util_format_description(elements[i].src_format); if (desc == NULL) { r600_bytecode_clear(&bc); - R600_ERR("unknown format %d\n", ve->elements[i].src_format); - return -EINVAL; + R600_ERR("unknown format %d\n", elements[i].src_format); + return NULL; } if (elements[i].src_offset > 65535) { r600_bytecode_clear(&bc); R600_ERR("too big src_offset: %u\n", elements[i].src_offset); - return -EINVAL; + return NULL; } memset(&vtx, 0, sizeof(vtx)); @@ -2840,7 +2844,7 @@ int r600_vertex_elements_build_fetch_shader(struct r600_context *rctx, struct r6 if ((r = r600_bytecode_add_vtx(&bc, &vtx))) { r600_bytecode_clear(&bc); - return r; + return NULL; } } @@ -2848,7 +2852,7 @@ int r600_vertex_elements_build_fetch_shader(struct r600_context *rctx, struct r6 if ((r = r600_bytecode_build(&bc))) { r600_bytecode_clear(&bc); - return r; + return NULL; } if (dump_shaders == -1) @@ -2860,41 +2864,36 @@ int r600_vertex_elements_build_fetch_shader(struct r600_context *rctx, struct r6 fprintf(stderr, "______________________________________________________________\n"); } - ve->fs_size = bc.ndw*4; + fs_size = bc.ndw*4; - ve->fetch_shader = (struct r600_resource*) + fetch_shader = (struct r600_resource*) pipe_buffer_create(rctx->context.screen, PIPE_BIND_CUSTOM, - PIPE_USAGE_IMMUTABLE, ve->fs_size); - if (ve->fetch_shader == NULL) { + PIPE_USAGE_IMMUTABLE, fs_size); + if (fetch_shader == NULL) { r600_bytecode_clear(&bc); - return -ENOMEM; + return NULL; } - bytecode = rctx->ws->buffer_map(ve->fetch_shader->cs_buf, rctx->cs, PIPE_TRANSFER_WRITE); + bytecode = rctx->ws->buffer_map(fetch_shader->cs_buf, rctx->cs, PIPE_TRANSFER_WRITE); if (bytecode == NULL) { r600_bytecode_clear(&bc); - pipe_resource_reference((struct pipe_resource**)&ve->fetch_shader, NULL); - return -ENOMEM; + pipe_resource_reference((struct pipe_resource**)&fetch_shader, NULL); + return NULL; } if (R600_BIG_ENDIAN) { - for (i = 0; i < ve->fs_size / 4; ++i) { + for (i = 0; i < fs_size / 4; ++i) { bytecode[i] = bswap_32(bc.bytecode[i]); } } else { - memcpy(bytecode, bc.bytecode, ve->fs_size); + memcpy(bytecode, bc.bytecode, fs_size); } - rctx->ws->buffer_unmap(ve->fetch_shader->cs_buf); + rctx->ws->buffer_unmap(fetch_shader->cs_buf); r600_bytecode_clear(&bc); - if (rctx->chip_class >= EVERGREEN) - evergreen_fetch_shader(&rctx->context, ve); - else - r600_fetch_shader(&rctx->context, ve); - - return 0; + return fetch_shader; } void r600_bytecode_alu_read(struct r600_bytecode_alu *alu, uint32_t word0, uint32_t word1) diff --git a/src/gallium/drivers/r600/r600_asm.h b/src/gallium/drivers/r600/r600_asm.h index 403365ba07b..d8f258fb10a 100644 --- a/src/gallium/drivers/r600/r600_asm.h +++ b/src/gallium/drivers/r600/r600_asm.h @@ -25,7 +25,6 @@ #include "r600.h" -struct r600_vertex_element; struct r600_context; struct r600_bytecode_alu_src { @@ -237,7 +236,9 @@ void r600_bytecode_alu_read(struct r600_bytecode_alu *alu, uint32_t word0, uint3 int cm_bytecode_add_cf_end(struct r600_bytecode *bc); -int r600_vertex_elements_build_fetch_shader(struct r600_context *rctx, struct r600_vertex_element *ve); +void *r600_create_vertex_fetch_shader(struct pipe_context *ctx, + unsigned count, + const struct pipe_vertex_element *elements); /* r700_asm.c */ void r700_bytecode_cf_vtx_build(uint32_t *bytecode, const struct r600_bytecode_cf *cf); diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c index a88cb5e4bba..0c41294e95f 100644 --- a/src/gallium/drivers/r600/r600_blit.c +++ b/src/gallium/drivers/r600/r600_blit.c @@ -58,7 +58,7 @@ static void r600_blitter_begin(struct pipe_context *ctx, enum r600_blitter_op op util_blitter_save_vertex_buffers(rctx->blitter, util_last_bit(rctx->vertex_buffer_state.enabled_mask), rctx->vertex_buffer_state.vb); - util_blitter_save_vertex_elements(rctx->blitter, rctx->vertex_elements); + util_blitter_save_vertex_elements(rctx->blitter, rctx->vertex_fetch_shader.cso); util_blitter_save_vertex_shader(rctx->blitter, rctx->vs_shader); util_blitter_save_so_targets(rctx->blitter, rctx->num_so_targets, (struct pipe_stream_output_target**)rctx->so_targets); diff --git a/src/gallium/drivers/r600/r600_hw_context.c b/src/gallium/drivers/r600/r600_hw_context.c index b3f0fbadf2d..2b260c8d94a 100644 --- a/src/gallium/drivers/r600/r600_hw_context.c +++ b/src/gallium/drivers/r600/r600_hw_context.c @@ -288,8 +288,6 @@ static const struct r600_reg r600_context_reg_list[] = { {GROUP_FORCE_NEW_BLOCK, 0, 0}, {R_028868_SQ_PGM_RESOURCES_VS, 0, 0}, {GROUP_FORCE_NEW_BLOCK, 0, 0}, - {R_028894_SQ_PGM_START_FS, REG_FLAG_NEED_BO, 0}, - {GROUP_FORCE_NEW_BLOCK, 0, 0}, {R_0288A4_SQ_PGM_RESOURCES_FS, 0, 0}, {R_0288DC_SQ_PGM_CF_OFFSET_FS, 0, 0}, {R_028644_SPI_PS_INPUT_CNTL_0, 0, 0}, @@ -873,6 +871,7 @@ void r600_begin_new_cs(struct r600_context *ctx) ctx->vgt2_state.atom.dirty = true; ctx->sample_mask.atom.dirty = true; ctx->stencil_ref.atom.dirty = true; + ctx->vertex_fetch_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 95f9ea15e83..a510baf93ad 100644 --- a/src/gallium/drivers/r600/r600_pipe.h +++ b/src/gallium/drivers/r600/r600_pipe.h @@ -35,7 +35,7 @@ #include "r600_resource.h" #include "evergreen_compute.h" -#define R600_NUM_ATOMS 30 +#define R600_NUM_ATOMS 31 #define R600_MAX_CONST_BUFFERS 2 #define R600_MAX_CONST_BUFFER_SIZE 4096 @@ -165,7 +165,6 @@ enum r600_pipe_state_id { R600_PIPE_STATE_RASTERIZER, R600_PIPE_STATE_DSA, R600_PIPE_STATE_POLYGON_OFFSET, - R600_PIPE_STATE_FETCH_SHADER, R600_PIPE_NSTATES }; @@ -240,15 +239,6 @@ struct r600_pipe_dsa { unsigned sx_alpha_test_control; }; -struct r600_vertex_element -{ - unsigned count; - struct pipe_vertex_element elements[PIPE_MAX_ATTRIBS]; - struct r600_resource *fetch_shader; - unsigned fs_size; - struct r600_pipe_state rstate; -}; - struct r600_pipe_shader; struct r600_pipe_shader_selector { @@ -277,8 +267,6 @@ struct r600_pipe_shader { struct r600_shader shader; struct r600_pipe_state rstate; struct r600_resource *bo; - struct r600_resource *bo_fetch; - struct r600_vertex_element vertex_elements; unsigned sprite_coord_enable; unsigned flatshade; unsigned pa_cl_vs_out_cntl; @@ -382,7 +370,6 @@ struct r600_context { struct r600_screen *screen; struct radeon_winsys *ws; struct r600_pipe_state *states[R600_PIPE_NSTATES]; - struct r600_vertex_element *vertex_elements; unsigned compute_cb_target_mask; unsigned db_shader_control; unsigned pa_sc_line_stipple; @@ -424,13 +411,14 @@ struct r600_context { struct r600_clip_state clip_state; struct r600_db_misc_state db_misc_state; struct r600_framebuffer framebuffer; + struct r600_sample_mask sample_mask; struct r600_seamless_cube_map seamless_cube_map; struct r600_stencil_ref_state stencil_ref; struct r600_vgt_state vgt_state; struct r600_vgt2_state vgt2_state; - struct r600_sample_mask sample_mask; struct r600_viewport_state viewport; /* Shaders and shader resources. */ + struct r600_cso_state vertex_fetch_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]; @@ -550,7 +538,6 @@ void evergreen_init_state_functions(struct r600_context *rctx); void evergreen_init_atom_start_cs(struct r600_context *rctx); void evergreen_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader *shader); void evergreen_pipe_shader_vs(struct pipe_context *ctx, struct r600_pipe_shader *shader); -void evergreen_fetch_shader(struct pipe_context *ctx, struct r600_vertex_element *ve); void *evergreen_create_db_flush_dsa(struct r600_context *rctx); void *evergreen_create_resolve_blend(struct r600_context *rctx); void *evergreen_create_decompress_blend(struct r600_context *rctx); @@ -627,7 +614,6 @@ void r600_init_state_functions(struct r600_context *rctx); void r600_init_atom_start_cs(struct r600_context *rctx); void r600_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader *shader); void r600_pipe_shader_vs(struct pipe_context *ctx, struct r600_pipe_shader *shader); -void r600_fetch_shader(struct pipe_context *ctx, struct r600_vertex_element *ve); void *r600_create_db_flush_dsa(struct r600_context *rctx); void *r600_create_resolve_blend(struct r600_context *rctx); void *r700_create_resolve_blend(struct r600_context *rctx); diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c index 98b45816d73..0881bae612d 100644 --- a/src/gallium/drivers/r600/r600_state.c +++ b/src/gallium/drivers/r600/r600_state.c @@ -2123,6 +2123,17 @@ static void r600_emit_sample_mask(struct r600_context *rctx, struct r600_atom *a mask | (mask << 8) | (mask << 16) | (mask << 24)); } +static void r600_emit_vertex_fetch_shader(struct r600_context *rctx, struct r600_atom *a) +{ + struct radeon_winsys_cs *cs = rctx->cs; + struct r600_cso_state *state = (struct r600_cso_state*)a; + struct r600_resource *shader = (struct r600_resource*)state->cso; + + r600_write_context_reg(cs, R_028894_SQ_PGM_START_FS, 0); + r600_write_value(cs, PKT3(PKT3_NOP, 0, 0)); + r600_write_value(cs, r600_context_bo_reloc(rctx, shader, RADEON_USAGE_READ)); +} + void r600_init_state_functions(struct r600_context *rctx) { unsigned id = 4; @@ -2172,6 +2183,7 @@ void r600_init_state_functions(struct r600_context *rctx) r600_init_atom(rctx, &rctx->db_misc_state.atom, id++, r600_emit_db_misc_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++, r600_emit_vertex_fetch_shader, 5); rctx->context.create_blend_state = r600_create_blend_state; rctx->context.create_depth_stencil_alpha_state = r600_create_dsa_state; @@ -2729,20 +2741,6 @@ void r600_pipe_shader_vs(struct pipe_context *ctx, struct r600_pipe_shader *shad S_02881C_USE_VTX_POINT_SIZE(rshader->vs_out_point_size); } -void r600_fetch_shader(struct pipe_context *ctx, - struct r600_vertex_element *ve) -{ - struct r600_pipe_state *rstate; - struct r600_context *rctx = (struct r600_context *)ctx; - - rstate = &ve->rstate; - rstate->id = R600_PIPE_STATE_FETCH_SHADER; - rstate->nregs = 0; - r600_pipe_state_add_reg_bo(rstate, R_028894_SQ_PGM_START_FS, - 0, - ve->fetch_shader, RADEON_USAGE_READ); -} - void *r600_create_resolve_blend(struct r600_context *rctx) { struct pipe_blend_state blend; diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c index c28f2f13c06..fe800f25a51 100644 --- a/src/gallium/drivers/r600/r600_state_common.c +++ b/src/gallium/drivers/r600/r600_state_common.c @@ -494,28 +494,13 @@ static void r600_delete_state(struct pipe_context *ctx, void *state) static void r600_bind_vertex_elements(struct pipe_context *ctx, void *state) { struct r600_context *rctx = (struct r600_context *)ctx; - struct r600_vertex_element *v = (struct r600_vertex_element*)state; - rctx->vertex_elements = v; - if (v) { - rctx->states[v->rstate.id] = &v->rstate; - r600_context_pipe_state_set(rctx, &v->rstate); - } + r600_set_cso_state(&rctx->vertex_fetch_shader, state); } static void r600_delete_vertex_elements(struct pipe_context *ctx, void *state) { - struct r600_context *rctx = (struct r600_context *)ctx; - struct r600_vertex_element *v = (struct r600_vertex_element*)state; - - if (rctx->states[v->rstate.id] == &v->rstate) { - rctx->states[v->rstate.id] = NULL; - } - if (rctx->vertex_elements == state) - rctx->vertex_elements = NULL; - - pipe_resource_reference((struct pipe_resource**)&v->fetch_shader, NULL); - FREE(state); + pipe_resource_reference((struct pipe_resource**)&state, NULL); } static void r600_set_index_buffer(struct pipe_context *ctx, @@ -713,27 +698,6 @@ void r600_emit_viewport_state(struct r600_context *rctx, struct r600_atom *atom) r600_write_value(cs, fui(state->translate[2])); /* R_028450_PA_CL_VPORT_ZOFFSET_0 */ } -static void *r600_create_vertex_elements(struct pipe_context *ctx, unsigned count, - const struct pipe_vertex_element *elements) -{ - struct r600_context *rctx = (struct r600_context *)ctx; - struct r600_vertex_element *v = CALLOC_STRUCT(r600_vertex_element); - - assert(count < 32); - if (!v) - return NULL; - - v->count = count; - memcpy(v->elements, elements, sizeof(struct pipe_vertex_element) * count); - - if (r600_vertex_elements_build_fetch_shader(rctx, v)) { - FREE(v); - return NULL; - } - - return v; -} - /* Compute the key for the hw shader variant */ static INLINE struct r600_shader_key r600_shader_selector_key(struct pipe_context * ctx, struct r600_pipe_shader_selector * sel) @@ -1566,7 +1530,7 @@ void r600_init_common_state_functions(struct r600_context *rctx) { rctx->context.create_fs_state = r600_create_ps_state; rctx->context.create_vs_state = r600_create_vs_state; - rctx->context.create_vertex_elements_state = r600_create_vertex_elements; + rctx->context.create_vertex_elements_state = r600_create_vertex_fetch_shader; rctx->context.bind_blend_state = r600_bind_blend_state; rctx->context.bind_depth_stencil_alpha_state = r600_bind_dsa_state; rctx->context.bind_fragment_sampler_states = r600_bind_ps_sampler_states; -- 2.30.2