diff options
author | Brian <[email protected]> | 2008-01-23 14:23:49 -0700 |
---|---|---|
committer | Brian <[email protected]> | 2008-01-23 14:23:49 -0700 |
commit | 336e2cb9ec52e5cf8b2fac3142d5a67e3dcd55c4 (patch) | |
tree | e21808468828fac5902d9326a0e01cad35e22b27 | |
parent | 2d37e78e636e5e1e7d5d00230e50a00f7a71e868 (diff) |
gallium: rework compute_vertex_layout() to intelligently map vs outputs to fs inputs
Some follow-on simplification in prim setup is possible...
-rw-r--r-- | src/mesa/pipe/softpipe/sp_prim_setup.c | 13 | ||||
-rw-r--r-- | src/mesa/pipe/softpipe/sp_prim_vbuf.c | 1 | ||||
-rw-r--r-- | src/mesa/pipe/softpipe/sp_state_derived.c | 73 |
3 files changed, 60 insertions, 27 deletions
diff --git a/src/mesa/pipe/softpipe/sp_prim_setup.c b/src/mesa/pipe/softpipe/sp_prim_setup.c index 9b2f10bbbb1..4b6b7a0fd12 100644 --- a/src/mesa/pipe/softpipe/sp_prim_setup.c +++ b/src/mesa/pipe/softpipe/sp_prim_setup.c @@ -515,13 +515,22 @@ setup_fragcoord_coeff(struct setup_stage *setup) */ static void setup_tri_coefficients( struct setup_stage *setup ) { - const enum interp_mode *interp = setup->softpipe->vertex_info.interp_mode; + const enum interp_mode *interp; #define USE_INPUT_MAP 01 #if USE_INPUT_MAP const struct pipe_shader_state *fs = &setup->softpipe->fs->shader; #endif uint fragSlot; + if (setup->softpipe->vertex_info.format[0] == FORMAT_HEADER) { + /* skip header, pos slots */ + interp = setup->softpipe->vertex_info.interp_mode + 2; + } + else { + /* skip pos slot */ + interp = setup->softpipe->vertex_info.interp_mode + 1; + } + /* z and w are done by linear interpolation: */ tri_linear_coeff(setup, &setup->posCoef, 0, 2); @@ -557,7 +566,7 @@ static void setup_tri_coefficients( struct setup_stage *setup ) else { #endif uint j; - switch (interp[vertSlot]) { + switch (interp[fragSlot]) { case INTERP_CONSTANT: for (j = 0; j < NUM_CHANNELS; j++) const_coeff(setup, &setup->coef[fragSlot], vertSlot, j); diff --git a/src/mesa/pipe/softpipe/sp_prim_vbuf.c b/src/mesa/pipe/softpipe/sp_prim_vbuf.c index b76405f1792..0ab8a55d7d4 100644 --- a/src/mesa/pipe/softpipe/sp_prim_vbuf.c +++ b/src/mesa/pipe/softpipe/sp_prim_vbuf.c @@ -74,6 +74,7 @@ sp_vbuf_get_vertex_info(struct vbuf_render *vbr) { struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr); /* XXX check for state changes? */ + assert(!cvbr->softpipe->dirty ); return &cvbr->softpipe->vertex_info; } diff --git a/src/mesa/pipe/softpipe/sp_state_derived.c b/src/mesa/pipe/softpipe/sp_state_derived.c index 74d34c50a85..d399868f244 100644 --- a/src/mesa/pipe/softpipe/sp_state_derived.c +++ b/src/mesa/pipe/softpipe/sp_state_derived.c @@ -33,6 +33,22 @@ #include "sp_state.h" +static int +find_vs_output(const struct pipe_shader_state *vs, + uint semantic_name, + uint semantic_index) +{ + uint i; + for (i = 0; i < vs->num_outputs; i++) { + if (vs->output_semantic_name[i] == semantic_name && + vs->output_semantic_index[i] == semantic_index) + return i; + } + return -1; +} + + + /** * Determine which post-transform / pre-rasterization vertex attributes * we need. @@ -46,6 +62,7 @@ static void calculate_vertex_layout( struct softpipe_context *softpipe ) = softpipe->rasterizer->flatshade ? INTERP_CONSTANT : INTERP_LINEAR; struct vertex_info *vinfo = &softpipe->vertex_info; uint i; + int src; memset(vinfo, 0, sizeof(*vinfo)); @@ -56,6 +73,11 @@ static void calculate_vertex_layout( struct softpipe_context *softpipe ) draw_emit_vertex_attr(vinfo, FORMAT_HEADER, INTERP_LINEAR, 0); } + /* always emit pos for softpipe rasterization */ + src = find_vs_output(vs, TGSI_SEMANTIC_POSITION, 0); + assert(src >= 0); + draw_emit_vertex_attr(vinfo, FORMAT_4F, INTERP_LINEAR, src); + /* * XXX I think we need to reconcile the vertex shader outputs with * the fragment shader inputs here to make sure the slots line up. @@ -63,42 +85,36 @@ static void calculate_vertex_layout( struct softpipe_context *softpipe ) * Or maybe do that in the state tracker? */ - for (i = 0; i < vs->num_outputs; i++) { - switch (vs->output_semantic_name[i]) { + for (i = 0; i < fs->num_inputs; i++) { + switch (fs->input_semantic_name[i]) { case TGSI_SEMANTIC_POSITION: - draw_emit_vertex_attr(vinfo, FORMAT_4F, INTERP_LINEAR, i); + /* handled above */ break; case TGSI_SEMANTIC_COLOR: - if (vs->output_semantic_index[i] == 0) { - draw_emit_vertex_attr(vinfo, FORMAT_4F, colorInterp, i); - } - else { - assert(vs->output_semantic_index[i] == 1); - draw_emit_vertex_attr(vinfo, FORMAT_4F, colorInterp, i); - } - break; - - case TGSI_SEMANTIC_BCOLOR: - /* no-op */ + src = find_vs_output(vs, TGSI_SEMANTIC_COLOR, + fs->input_semantic_index[i]); + assert(src >= 0); + draw_emit_vertex_attr(vinfo, FORMAT_4F, colorInterp, src); break; case TGSI_SEMANTIC_FOG: - draw_emit_vertex_attr(vinfo, FORMAT_1F, INTERP_PERSPECTIVE, i); - break; - - case TGSI_SEMANTIC_PSIZE: - /* XXX only emit if drawing points or front/back polygon mode - * is point mode - */ - softpipe->psize_slot - = draw_emit_vertex_attr(vinfo, FORMAT_1F, INTERP_CONSTANT, i); + src = find_vs_output(vs, TGSI_SEMANTIC_FOG, 0); +#if 1 + if (src < 0) /* XXX temp hack, try demos/fogcoord.c with this */ + src = 0; +#endif + assert(src >= 0); + draw_emit_vertex_attr(vinfo, FORMAT_4F, INTERP_PERSPECTIVE, src); break; case TGSI_SEMANTIC_GENERIC: /* this includes texcoords and varying vars */ - draw_emit_vertex_attr(vinfo, FORMAT_4F, INTERP_PERSPECTIVE, i); + src = find_vs_output(vs, TGSI_SEMANTIC_GENERIC, + fs->input_semantic_index[i]); + assert(src >= 0); + draw_emit_vertex_attr(vinfo, FORMAT_4F, INTERP_PERSPECTIVE, src); break; default: @@ -106,6 +122,13 @@ static void calculate_vertex_layout( struct softpipe_context *softpipe ) } } + src = find_vs_output(vs, TGSI_SEMANTIC_PSIZE, 0); + if (src >= 0) { + softpipe->psize_slot = src; + draw_emit_vertex_attr(vinfo, FORMAT_4F, INTERP_CONSTANT, src); + } + + draw_compute_vertex_size(vinfo); softpipe->nr_frag_attrs = fs->num_inputs; @@ -152,7 +175,7 @@ compute_cliprect(struct softpipe_context *sp) */ void softpipe_update_derived( struct softpipe_context *softpipe ) { - if (softpipe->dirty & (SP_NEW_RASTERIZER | SP_NEW_FS)) + if (softpipe->dirty & (SP_NEW_RASTERIZER | SP_NEW_FS | SP_NEW_VS)) calculate_vertex_layout( softpipe ); if (softpipe->dirty & (SP_NEW_SCISSOR | |