diff options
author | José Fonseca <jfonseca@vmware.com> | 2010-04-18 10:34:01 +0200 |
---|---|---|
committer | José Fonseca <jfonseca@vmware.com> | 2010-04-18 10:36:28 +0200 |
commit | 4b148bcf5e6cf08fac31cd10b42ac5f5a5f43cd6 (patch) | |
tree | b5b3162a2b95df266148304712e97c4255e886eb | |
parent | 4272c01fbfd42833e4e0937bed84e45fe5da52b9 (diff) |
llvmpipe: Emit only the vertex attributes necessary for the FS, and ensure the first one is always position.
With this we correctly handle vertex shaders whose output position is not
in index zero.
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_state_derived.c | 135 |
1 files changed, 67 insertions, 68 deletions
diff --git a/src/gallium/drivers/llvmpipe/lp_state_derived.c b/src/gallium/drivers/llvmpipe/lp_state_derived.c index 777871638f..113d77ab78 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_derived.c +++ b/src/gallium/drivers/llvmpipe/lp_state_derived.c @@ -50,88 +50,87 @@ compute_vertex_info(struct llvmpipe_context *llvmpipe) { const struct lp_fragment_shader *lpfs = llvmpipe->fs; struct vertex_info *vinfo = &llvmpipe->vertex_info; - const uint num = draw_num_shader_outputs(llvmpipe->draw); + struct lp_shader_input inputs[1 + PIPE_MAX_SHADER_INPUTS]; + unsigned vs_index; uint i; - /* Tell setup to tell the draw module to simply emit the whole - * post-xform vertex as-is. - * - * Not really sure if this is the best approach. + /* + * Match FS inputs against VS outputs, emitting the necessary attributes. */ - vinfo->num_attribs = 0; - for (i = 0; i < num; i++) { - draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, i); - } - draw_compute_vertex_size(vinfo); - - - lp_setup_set_vertex_info(llvmpipe->setup, vinfo); -/* - llvmpipe->psize_slot = draw_find_vs_output(llvmpipe->draw, - TGSI_SEMANTIC_PSIZE, 0); -*/ - - /* Now match FS inputs against emitted vertex data. It's also - * entirely possible to just have a fixed layout for FS input, - * determined by the fragment shader itself, and adjust the draw - * outputs to match that. - */ - { - struct lp_shader_input inputs[PIPE_MAX_SHADER_INPUTS]; - - for (i = 0; i < lpfs->info.num_inputs; i++) { + vinfo->num_attribs = 0; - /* This can be precomputed, except for flatshade: + vs_index = draw_find_shader_output(llvmpipe->draw, + TGSI_SEMANTIC_POSITION, + 0); + + draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, vs_index); + + for (i = 0; i < lpfs->info.num_inputs; i++) { + /* + * Search for each input in current vs output: + */ + + vs_index = draw_find_shader_output(llvmpipe->draw, + lpfs->info.input_semantic_name[i], + lpfs->info.input_semantic_index[i]); + + /* This can be pre-computed, except for flatshade: + */ + switch (lpfs->info.input_semantic_name[i]) { + case TGSI_SEMANTIC_FACE: + inputs[i].interp = LP_INTERP_FACING; + break; + case TGSI_SEMANTIC_POSITION: + /* Position was already emitted above + */ + inputs[i].interp = LP_INTERP_POSITION; + inputs[i].src_index = 0; + continue; + case TGSI_SEMANTIC_COLOR: + /* Colors are linearly inputs[i].interpolated in the fragment shader + * even when flatshading is active. This just tells the + * setup module to use coefficients with ddx==0 and + * ddy==0. */ - switch (lpfs->info.input_semantic_name[i]) { - case TGSI_SEMANTIC_FACE: - inputs[i].interp = LP_INTERP_FACING; + if (llvmpipe->rasterizer->flatshade) + inputs[i].interp = LP_INTERP_CONSTANT; + else + inputs[i].interp = LP_INTERP_LINEAR; + break; + + default: + switch (lpfs->info.input_interpolate[i]) { + case TGSI_INTERPOLATE_CONSTANT: + inputs[i].interp = LP_INTERP_CONSTANT; break; - case TGSI_SEMANTIC_POSITION: - inputs[i].interp = LP_INTERP_POSITION; + case TGSI_INTERPOLATE_LINEAR: + inputs[i].interp = LP_INTERP_LINEAR; break; - case TGSI_SEMANTIC_COLOR: - /* Colors are linearly interpolated in the fragment shader - * even when flatshading is active. This just tells the - * setup module to use coefficients with ddx==0 and - * ddy==0. - */ - if (llvmpipe->rasterizer->flatshade) - inputs[i].interp = LP_INTERP_CONSTANT; - else - inputs[i].interp = LP_INTERP_LINEAR; + case TGSI_INTERPOLATE_PERSPECTIVE: + inputs[i].interp = LP_INTERP_PERSPECTIVE; break; - default: - switch (lpfs->info.input_interpolate[i]) { - case TGSI_INTERPOLATE_CONSTANT: - inputs[i].interp = LP_INTERP_CONSTANT; - break; - case TGSI_INTERPOLATE_LINEAR: - inputs[i].interp = LP_INTERP_LINEAR; - break; - case TGSI_INTERPOLATE_PERSPECTIVE: - inputs[i].interp = LP_INTERP_PERSPECTIVE; - break; - default: - assert(0); - break; - } + assert(0); + break; } - - /* Search for each input in current vs output: - */ - inputs[i].src_index = - draw_find_shader_output(llvmpipe->draw, - lpfs->info.input_semantic_name[i], - lpfs->info.input_semantic_index[i]); } - lp_setup_set_fs_inputs(llvmpipe->setup, - inputs, - lpfs->info.num_inputs); + /* + * Emit the requested fs attribute for all but position. + */ + + inputs[i].src_index = vinfo->num_attribs; + draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, vs_index); } + + draw_compute_vertex_size(vinfo); + + lp_setup_set_vertex_info(llvmpipe->setup, vinfo); + + lp_setup_set_fs_inputs(llvmpipe->setup, + inputs, + lpfs->info.num_inputs); } |