From 686f69bd13fd2aebaa40edeb7e25e4a49b12a2bd Mon Sep 17 00:00:00 2001 From: Corbin Simpson Date: Wed, 24 Feb 2010 20:02:59 -0800 Subject: [PATCH] r300g: Atomize vertex shader. --- src/gallium/drivers/r300/r300_blit.c | 2 +- src/gallium/drivers/r300/r300_context.c | 1 + src/gallium/drivers/r300/r300_context.h | 3 +- src/gallium/drivers/r300/r300_emit.c | 62 ++++++++++++--------------- src/gallium/drivers/r300/r300_emit.h | 3 +- src/gallium/drivers/r300/r300_state.c | 18 ++++---- src/gallium/drivers/r300/r300_state_derived.c | 25 ++++++----- src/gallium/drivers/r300/r300_vs.c | 4 +- 8 files changed, 58 insertions(+), 60 deletions(-) diff --git a/src/gallium/drivers/r300/r300_blit.c b/src/gallium/drivers/r300/r300_blit.c index eb9b0be..187b4bf 100644 --- a/src/gallium/drivers/r300/r300_blit.c +++ b/src/gallium/drivers/r300/r300_blit.c @@ -33,7 +33,7 @@ static void r300_blitter_save_states(struct r300_context* r300) util_blitter_save_stencil_ref(r300->blitter, &(r300->stencil_ref)); util_blitter_save_rasterizer(r300->blitter, r300->rs_state.state); util_blitter_save_fragment_shader(r300->blitter, r300->fs); - util_blitter_save_vertex_shader(r300->blitter, r300->vs); + util_blitter_save_vertex_shader(r300->blitter, r300->vs_state.state); } /* Clear currently bound buffers. */ diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c index 925873a..4788358 100644 --- a/src/gallium/drivers/r300/r300_context.c +++ b/src/gallium/drivers/r300/r300_context.c @@ -126,6 +126,7 @@ static void r300_setup_atoms(struct r300_context* r300) R300_INIT_ATOM(viewport, 9); R300_INIT_ATOM(rs_block, 21); R300_INIT_ATOM(vertex_format, 26); + R300_INIT_ATOM(vs, 1031); /* Some non-CSO atoms need explicit space to store the state locally. */ r300->blend_color_state.state = CALLOC_STRUCT(r300_blend_color_state); diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index 443af4e..3d4f652 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -155,7 +155,6 @@ struct r300_ztop_state { #define R300_ANY_NEW_SAMPLERS 0x0001fe00 #define R300_NEW_TEXTURE 0x00040000 #define R300_ANY_NEW_TEXTURES 0x03fc0000 -#define R300_NEW_VERTEX_SHADER 0x08000000 #define R300_NEW_VERTEX_SHADER_CONSTANTS 0x10000000 #define R300_NEW_QUERY 0x40000000 #define R300_NEW_KITCHEN_SINK 0x7fffffff @@ -315,7 +314,7 @@ struct r300_context { struct r300_texture* textures[8]; int texture_count; /* Vertex shader. */ - struct r300_vertex_shader* vs; + struct r300_atom vs_state; /* Viewport state. */ struct r300_atom viewport_state; /* ZTOP state. */ diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index 2d8801c..3037a38 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -843,21 +843,31 @@ void r300_emit_vertex_format_state(struct r300_context* r300, void* state) END_CS; } +static void r300_flush_pvs(struct r300_context* r300) +{ + CS_LOCALS(r300); + + BEGIN_CS(2); + OUT_CS_REG(R300_VAP_PVS_STATE_FLUSH_REG, 0x0); + END_CS; +} -void r300_emit_vertex_program_code(struct r300_context* r300, - struct r300_vertex_program_code* code) +void r300_emit_vs_state(struct r300_context* r300, void* state) { - int i; + struct r300_vertex_shader* vs = (struct r300_vertex_shader*)state; + struct r300_vertex_program_code* code = &vs->code; struct r300_screen* r300screen = r300_screen(r300->context.screen); unsigned instruction_count = code->length / 4; + unsigned i; + + unsigned vtx_mem_size = r300screen->caps->is_r500 ? 128 : 72; + unsigned input_count = MAX2(util_bitcount(code->InputsRead), 1); + unsigned output_count = MAX2(util_bitcount(code->OutputsWritten), 1); + unsigned temp_count = MAX2(code->num_temporaries, 1); - int vtx_mem_size = r300screen->caps->is_r500 ? 128 : 72; - int input_count = MAX2(util_bitcount(code->InputsRead), 1); - int output_count = MAX2(util_bitcount(code->OutputsWritten), 1); - int temp_count = MAX2(code->num_temporaries, 1); - int pvs_num_slots = MIN3(vtx_mem_size / input_count, - vtx_mem_size / output_count, 10); - int pvs_num_controllers = MIN2(vtx_mem_size / temp_count, 6); + unsigned pvs_num_slots = MIN3(vtx_mem_size / input_count, + vtx_mem_size / output_count, 10); + unsigned pvs_num_controllers = MIN2(vtx_mem_size / temp_count, 6); CS_LOCALS(r300); @@ -867,6 +877,8 @@ void r300_emit_vertex_program_code(struct r300_context* r300, return; } + r300_flush_pvs(r300); + BEGIN_CS(9 + code->length); /* R300_VAP_PVS_CODE_CNTL_0 * R300_VAP_PVS_CONST_CNTL @@ -881,8 +893,9 @@ void r300_emit_vertex_program_code(struct r300_context* r300, OUT_CS_REG(R300_VAP_PVS_VECTOR_INDX_REG, 0); OUT_CS_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, code->length); - for (i = 0; i < code->length; i++) + for (i = 0; i < code->length; i++) { OUT_CS(code->body.d[i]); + } OUT_CS_REG(R300_VAP_CNTL, R300_PVS_NUM_SLOTS(pvs_num_slots) | R300_PVS_NUM_CNTLRS(pvs_num_controllers) | @@ -892,12 +905,6 @@ void r300_emit_vertex_program_code(struct r300_context* r300, END_CS; } -void r300_emit_vertex_shader(struct r300_context* r300, - struct r300_vertex_shader* vs) -{ - r300_emit_vertex_program_code(r300, &vs->code); -} - void r300_emit_vs_constant_buffer(struct r300_context* r300, struct rc_constant_list* constants) { @@ -994,15 +1001,6 @@ void r300_flush_textures(struct r300_context* r300) END_CS; } -static void r300_flush_pvs(struct r300_context* r300) -{ - CS_LOCALS(r300); - - BEGIN_CS(2); - OUT_CS_REG(R300_VAP_PVS_STATE_FLUSH_REG, 0x0); - END_CS; -} - void r300_emit_buffer_validate(struct r300_context *r300) { struct pipe_framebuffer_state* fb = @@ -1088,7 +1086,7 @@ unsigned r300_get_num_dirty_dwords(struct r300_context *r300) } /* XXX This is the compensation for the non-atomized states. */ - dwords += 2048; + dwords += 1024; return dwords; } @@ -1160,17 +1158,13 @@ void r300_emit_dirty_state(struct r300_context* r300) r300_flush_textures(r300); } - if (r300->dirty_state & (R300_NEW_VERTEX_SHADER | R300_NEW_VERTEX_SHADER_CONSTANTS)) { + if (r300->dirty_state & R300_NEW_VERTEX_SHADER_CONSTANTS || r300->vs_state.dirty) { r300_flush_pvs(r300); } - if (r300->dirty_state & R300_NEW_VERTEX_SHADER) { - r300_emit_vertex_shader(r300, r300->vs); - r300->dirty_state &= ~R300_NEW_VERTEX_SHADER; - } - if (r300->dirty_state & R300_NEW_VERTEX_SHADER_CONSTANTS) { - r300_emit_vs_constant_buffer(r300, &r300->vs->code.constants); + struct r300_vertex_shader* vs = r300->vs_state.state; + r300_emit_vs_constant_buffer(r300, &vs->code.constants); r300->dirty_state &= ~R300_NEW_VERTEX_SHADER_CONSTANTS; } diff --git a/src/gallium/drivers/r300/r300_emit.h b/src/gallium/drivers/r300/r300_emit.h index ff709a0..f27cf5f 100644 --- a/src/gallium/drivers/r300/r300_emit.h +++ b/src/gallium/drivers/r300/r300_emit.h @@ -79,8 +79,7 @@ void r300_emit_vertex_program_code(struct r300_context* r300, void r300_emit_vs_constant_buffer(struct r300_context* r300, struct rc_constant_list* constants); -void r300_emit_vertex_shader(struct r300_context* r300, - struct r300_vertex_shader* vs); +void r300_emit_vs_state(struct r300_context* r300, void* state); void r300_emit_viewport_state(struct r300_context* r300, void* state); diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 34bf81c..0f14ccc 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -658,9 +658,7 @@ static void r300_bind_fs_state(struct pipe_context* pipe, void* shader) r300->fs = fs; r300_pick_fragment_shader(r300); - if (r300->vs && r300_vertex_shader_setup_wpos(r300)) { - r300->vertex_format_state.dirty = TRUE; - } + r300->vertex_format_state.dirty = TRUE; r300->dirty_state |= R300_NEW_FRAGMENT_SHADER | R300_NEW_FRAGMENT_SHADER_CONSTANTS; } @@ -1107,21 +1105,23 @@ static void r300_bind_vs_state(struct pipe_context* pipe, void* shader) struct r300_vertex_shader* vs = (struct r300_vertex_shader*)shader; if (vs == NULL) { - r300->vs = NULL; + r300->vs_state.state = NULL; return; } else if (!vs->translated) { r300_translate_vertex_shader(r300, vs); } - r300->vs = vs; + r300->vs_state.state = vs; + r300->vs_state.size = vs->code.length + 11; + r300->vs_state.dirty = TRUE; + + r300->vertex_format_state.dirty = TRUE; + if (r300->fs) { r300_vertex_shader_setup_wpos(r300); } - r300->vertex_format_state.dirty = TRUE; - - r300->dirty_state |= - R300_NEW_VERTEX_SHADER | R300_NEW_VERTEX_SHADER_CONSTANTS; + r300->dirty_state |= R300_NEW_VERTEX_SHADER_CONSTANTS; } else { draw_flush(r300->draw); draw_bind_vertex_shader(r300->draw, diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c index 2cbce92..b33d449 100644 --- a/src/gallium/drivers/r300/r300_state_derived.c +++ b/src/gallium/drivers/r300/r300_state_derived.c @@ -42,7 +42,8 @@ static void r300_draw_emit_attrib(struct r300_context* r300, enum interp_mode interp, int index) { - struct tgsi_shader_info* info = &r300->vs->info; + struct r300_vertex_shader* vs = r300->vs_state.state; + struct tgsi_shader_info* info = &vs->info; int output; output = draw_find_shader_output(r300->draw, @@ -55,7 +56,8 @@ static void r300_draw_emit_attrib(struct r300_context* r300, static void r300_draw_emit_all_attribs(struct r300_context* r300) { - struct r300_shader_semantics* vs_outputs = &r300->vs->outputs; + struct r300_vertex_shader* vs = r300->vs_state.state; + struct r300_shader_semantics* vs_outputs = &vs->outputs; int i, gen_count; /* Position. */ @@ -106,6 +108,7 @@ static void r300_draw_emit_all_attribs(struct r300_context* r300) /* Update the PSC tables. */ static void r300_vertex_psc(struct r300_context* r300) { + struct r300_vertex_shader* vs = r300->vs_state.state; struct r300_vertex_info *vformat = (struct r300_vertex_info*)r300->vertex_format_state.state; uint16_t type, swizzle; @@ -117,7 +120,7 @@ static void r300_vertex_psc(struct r300_context* r300) /* If TCL is bypassed, map vertex streams to equivalent VS output * locations. */ if (r300->tcl_bypass) { - stream_tab = r300->vs->stream_loc_notcl; + stream_tab = vs->stream_loc_notcl; } else { stream_tab = identity; } @@ -127,7 +130,7 @@ static void r300_vertex_psc(struct r300_context* r300) * and not on attrib information. */ DBG(r300, DBG_DRAW, "r300: vs expects %d attribs, routing %d elements" " in psc\n", - r300->vs->info.num_inputs, + vs->info.num_inputs, r300->vertex_element_count); for (i = 0; i < r300->vertex_element_count; i++) { @@ -159,13 +162,14 @@ static void r300_vertex_psc(struct r300_context* r300) /* Update the PSC tables for SW TCL, using Draw. */ static void r300_swtcl_vertex_psc(struct r300_context* r300) { + struct r300_vertex_shader* vs = r300->vs_state.state; struct r300_vertex_info *vformat = (struct r300_vertex_info*)r300->vertex_format_state.state; struct vertex_info* vinfo = &vformat->vinfo; uint16_t type, swizzle; enum pipe_format format; unsigned i, attrib_count; - int* vs_output_tab = r300->vs->stream_loc_notcl; + int* vs_output_tab = vs->stream_loc_notcl; /* For each Draw attribute, route it to the fragment shader according * to the vs_output_tab. */ @@ -424,6 +428,7 @@ static void r300_update_rs_block(struct r300_context* r300, /* Update the shader-dependant states. */ static void r300_update_derived_shader_state(struct r300_context* r300) { + struct r300_vertex_shader* vs = r300->vs_state.state; struct r300_screen* r300screen = r300_screen(r300->context.screen); struct r300_vertex_info *vformat = (struct r300_vertex_info*)r300->vertex_format_state.state; @@ -431,9 +436,9 @@ static void r300_update_derived_shader_state(struct r300_context* r300) /* Mmm, delicious hax */ memset(r300->vertex_format_state.state, 0, sizeof(struct r300_vertex_info)); - memcpy(vinfo->hwfmt, r300->vs->hwfmt, sizeof(uint)*4); + memcpy(vinfo->hwfmt, vs->hwfmt, sizeof(uint)*4); - r300_update_rs_block(r300, &r300->vs->outputs, &r300->fs->inputs); + r300_update_rs_block(r300, &vs->outputs, &r300->fs->inputs); if (r300screen->caps->has_tcl) { r300_vertex_psc(r300); @@ -519,9 +524,9 @@ static void r300_update_ztop(struct r300_context* r300) void r300_update_derived_state(struct r300_context* r300) { /* XXX */ - if (r300->dirty_state & - (R300_NEW_FRAGMENT_SHADER | R300_NEW_VERTEX_SHADER) || - r300->vertex_format_state.dirty || r300->rs_state.dirty) { + if (r300->dirty_state & R300_NEW_FRAGMENT_SHADER || + r300->vs_state.dirty || r300->vertex_format_state.dirty || + r300->rs_state.dirty) { r300_update_derived_shader_state(r300); } diff --git a/src/gallium/drivers/r300/r300_vs.c b/src/gallium/drivers/r300/r300_vs.c index a6786c3..60a04bb 100644 --- a/src/gallium/drivers/r300/r300_vs.c +++ b/src/gallium/drivers/r300/r300_vs.c @@ -368,8 +368,8 @@ void r300_translate_vertex_shader(struct r300_context* r300, boolean r300_vertex_shader_setup_wpos(struct r300_context* r300) { - struct r300_vertex_shader* vs = r300->vs; - int tex_output = r300->vs->wpos_tex_output; + struct r300_vertex_shader* vs = r300->vs_state.state; + int tex_output = vs->wpos_tex_output; uint32_t tex_fmt = R300_INPUT_CNTL_TC0 << tex_output; uint32_t* hwfmt = vs->hwfmt; -- 2.7.4