diff options
author | Corbin Simpson <[email protected]> | 2009-11-15 05:25:15 +0100 |
---|---|---|
committer | Corbin Simpson <[email protected]> | 2009-11-20 17:48:10 -0800 |
commit | 1c181a7eff96816b5d72ea5daab5818eef0ebc60 (patch) | |
tree | 760e188f80947c0bd4b1864b5c33ad645370f594 /src/gallium/drivers/r300/r300_state_derived.c | |
parent | 015e7e7724a64d3d9e02e57f6a8eb88a6441f596 (diff) |
r300g: Begin separating HW TCL and SW TCL state and setup.
This patch removes draw_context entirely from the HW TCL path and cleans up
a few other things along the way. Hopefully, nothing got broken.
Thanks to Marek Olšák for testing, review, and pointing out my bugs. :3
Diffstat (limited to 'src/gallium/drivers/r300/r300_state_derived.c')
-rw-r--r-- | src/gallium/drivers/r300/r300_state_derived.c | 192 |
1 files changed, 94 insertions, 98 deletions
diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c index b4d0eeaf8c5..5aa4166d939 100644 --- a/src/gallium/drivers/r300/r300_state_derived.c +++ b/src/gallium/drivers/r300/r300_state_derived.c @@ -65,84 +65,43 @@ int r300_shader_key_compare(void* key1, void* key2) { static void r300_vs_tab_routes(struct r300_context* r300, struct r300_vertex_info* vformat) { - struct r300_screen* r300screen = r300_screen(r300->context.screen); struct vertex_info* vinfo = &vformat->vinfo; int* tab = vformat->vs_tab; boolean pos = FALSE, psize = FALSE, fog = FALSE; int i, texs = 0, cols = 0; - struct tgsi_shader_info* info; - - if (r300screen->caps->has_tcl) { - /* Use vertex shader to determine required routes. */ - info = &r300->vs->info; - } else { - /* Use fragment shader to determine required routes. */ - info = &r300->fs->info; - } + struct tgsi_shader_info* info = &r300->fs->info; - assert(info->num_inputs <= 16); + /* XXX One day we should figure out how to handle a different number of + * VS outputs and FS inputs, as well as a different number of vertex streams + * and VS inputs. It's definitely one of the sources of hardlocks. */ - if (!r300screen->caps->has_tcl || !r300->rs_state->enable_vte) - { - for (i = 0; i < info->num_inputs; i++) { - switch (r300->vs->code.inputs[i]) { - case TGSI_SEMANTIC_POSITION: - pos = TRUE; - tab[i] = 0; - break; - case TGSI_SEMANTIC_COLOR: - tab[i] = 2 + cols; - cols++; - break; - case TGSI_SEMANTIC_PSIZE: - assert(psize == FALSE); - psize = TRUE; - tab[i] = 15; - break; - case TGSI_SEMANTIC_FOG: - assert(fog == FALSE); - fog = TRUE; - /* Fall through */ - case TGSI_SEMANTIC_GENERIC: - tab[i] = 6 + texs; - texs++; - break; - default: - debug_printf("r300: Unknown vertex input %d\n", - info->input_semantic_name[i]); - break; - } - } - } - else - { - /* Just copy vert attribs over as-is. */ - for (i = 0; i < info->num_inputs; i++) { - tab[i] = i; - } - - for (i = 0; i < info->num_outputs; i++) { - switch (info->output_semantic_name[i]) { - case TGSI_SEMANTIC_POSITION: - pos = TRUE; - break; - case TGSI_SEMANTIC_COLOR: - cols++; - break; - case TGSI_SEMANTIC_PSIZE: - psize = TRUE; - break; - case TGSI_SEMANTIC_FOG: - fog = TRUE; - /* Fall through */ - case TGSI_SEMANTIC_GENERIC: - texs++; - break; - default: - debug_printf("r300: Unknown vertex output %d\n", - info->output_semantic_name[i]); - break; - } + for (i = 0; i < info->num_inputs; i++) { + switch (info->input_semantic_name[i]) { + case TGSI_SEMANTIC_POSITION: + pos = TRUE; + tab[i] = 0; + break; + case TGSI_SEMANTIC_COLOR: + tab[i] = 2 + cols; + cols++; + break; + case TGSI_SEMANTIC_PSIZE: + assert(psize == FALSE); + psize = TRUE; + tab[i] = 15; + break; + case TGSI_SEMANTIC_FOG: + assert(fog == FALSE); + fog = TRUE; + /* Fall through */ + case TGSI_SEMANTIC_GENERIC: + tab[i] = 6 + texs; + texs++; + break; + default: + debug_printf("r300: Unknown vertex input %d\n", + info->input_semantic_name[i]); + break; } } @@ -161,8 +120,7 @@ static void r300_vs_tab_routes(struct r300_context* r300, /* We need to add vertex position attribute only for SW TCL case, * for HW TCL case it could be generated by vertex shader */ - if (!pos && !r300screen->caps->has_tcl) { - debug_printf("r300: Forcing vertex position attribute emit...\n"); + if (!pos) { /* Make room for the position attribute * at the beginning of the tab. */ for (i = 15; i > 0; i--) { @@ -230,31 +188,66 @@ static void r300_vs_tab_routes(struct r300_context* r300, static void r300_vertex_psc(struct r300_context* r300, struct r300_vertex_info* vformat) { - struct r300_screen* r300screen = r300_screen(r300->context.screen); - struct vertex_info* vinfo = &vformat->vinfo; - int* tab = vformat->vs_tab; uint16_t type, swizzle; enum pipe_format format; - unsigned i, attrib_count; + unsigned i; /* Vertex shaders have no semantics on their inputs, - * so PSC should just route stuff based on their info, + * so PSC should just route stuff based on the vertex elements, * and not on attrib information. */ - if (r300screen->caps->has_tcl) { - attrib_count = r300->vs->info.num_inputs; - DBG(r300, DBG_DRAW, "r300: routing %d attribs in psc for vs\n", - attrib_count); - } else { - attrib_count = vinfo->num_attribs; - DBG(r300, DBG_DRAW, "r300: attrib count: %d\n", attrib_count); - for (i = 0; i < attrib_count; i++) { - DBG(r300, DBG_DRAW, "r300: attrib: offset %d, interp %d, size %d," - " tab %d\n", vinfo->attrib[i].src_index, - vinfo->attrib[i].interp_mode, vinfo->attrib[i].emit, - tab[i]); + DBG(r300, DBG_DRAW, "r300: vs expects %d attribs, routing %d elements" + " in psc\n", + r300->vs->info.num_inputs, + r300->vertex_element_count); + + for (i = 0; i < r300->vertex_element_count; i++) { + format = r300->vertex_element[i].src_format; + + type = r300_translate_vertex_data_type(format) | + (i << R300_DST_VEC_LOC_SHIFT); + swizzle = r300_translate_vertex_data_swizzle(format); + + if (i % 2) { + vformat->vap_prog_stream_cntl[i >> 1] |= type << 16; + vformat->vap_prog_stream_cntl_ext[i >> 1] |= swizzle << 16; + } else { + vformat->vap_prog_stream_cntl[i >> 1] |= type; + vformat->vap_prog_stream_cntl_ext[i >> 1] |= swizzle; } } + + assert(i <= 15); + + /* Set the last vector in the PSC. */ + if (i) { + i -= 1; + } + vformat->vap_prog_stream_cntl[i >> 1] |= + (R300_LAST_VEC << (i & 1 ? 16 : 0)); +} + +/* Update the PSC tables for SW TCL, using Draw. */ +static void r300_swtcl_vertex_psc(struct r300_context* r300, + struct r300_vertex_info* vformat) +{ + struct vertex_info* vinfo = &vformat->vinfo; + int* tab = vformat->vs_tab; + uint16_t type, swizzle; + enum pipe_format format; + unsigned i, attrib_count; + + /* For each Draw attribute, route it to the fragment shader according + * to the tab. */ + attrib_count = vinfo->num_attribs; + DBG(r300, DBG_DRAW, "r300: attrib count: %d\n", attrib_count); + for (i = 0; i < attrib_count; i++) { + DBG(r300, DBG_DRAW, "r300: attrib: offset %d, interp %d, size %d," + " tab %d\n", vinfo->attrib[i].src_index, + vinfo->attrib[i].interp_mode, vinfo->attrib[i].emit, + tab[i]); + } + for (i = 0; i < attrib_count; i++) { /* Make sure we have a proper destination for our attribute. */ assert(tab[i] != -1); @@ -272,12 +265,10 @@ static void r300_vertex_psc(struct r300_context* r300, /* Add the attribute to the PSC table. */ if (i & 1) { vformat->vap_prog_stream_cntl[i >> 1] |= type << 16; - vformat->vap_prog_stream_cntl_ext[i >> 1] |= swizzle << 16; } else { - vformat->vap_prog_stream_cntl[i >> 1] |= type << 0; - - vformat->vap_prog_stream_cntl_ext[i >> 1] |= swizzle << 0; + vformat->vap_prog_stream_cntl[i >> 1] |= type; + vformat->vap_prog_stream_cntl_ext[i >> 1] |= swizzle; } } @@ -505,7 +496,13 @@ static void r300_update_derived_shader_state(struct r300_context* r300) } r300_vs_tab_routes(r300, vformat); - r300_vertex_psc(r300, vformat); + + if (r300screen->caps->has_tcl) { + r300_vertex_psc(r300, vformat); + } else { + r300_swtcl_vertex_psc(r300, vformat); + } + r300_update_fs_tab(r300, vformat); r300_update_rs_block(r300, rs_block); @@ -553,8 +550,7 @@ static void r300_update_ztop(struct r300_context* r300) void r300_update_derived_state(struct r300_context* r300) { - /* XXX */ - if (TRUE || r300->dirty_state & + if (r300->dirty_state & (R300_NEW_FRAGMENT_SHADER | R300_NEW_VERTEX_SHADER)) { r300_update_derived_shader_state(r300); } |