diff options
Diffstat (limited to 'src/mesa/pipe/softpipe/sp_state_derived.c')
-rw-r--r-- | src/mesa/pipe/softpipe/sp_state_derived.c | 174 |
1 files changed, 110 insertions, 64 deletions
diff --git a/src/mesa/pipe/softpipe/sp_state_derived.c b/src/mesa/pipe/softpipe/sp_state_derived.c index 39c3e1afe1..9e4c35e696 100644 --- a/src/mesa/pipe/softpipe/sp_state_derived.c +++ b/src/mesa/pipe/softpipe/sp_state_derived.c @@ -49,82 +49,128 @@ find_vs_output(const struct pipe_shader_state *vs, } +/** + * Mark the current vertex layout as "invalid". + * We'll validate the vertex layout later, when we start to actually + * render a point or line or tri. + */ +static void +invalidate_vertex_layout(struct softpipe_context *softpipe) +{ + softpipe->vertex_info.num_attribs = 0; +} + /** - * Determine how to map vertex program outputs to fragment program inputs. - * Basically, this will be used when computing the triangle interpolation - * coefficients from the post-transform vertex attributes. + * The vertex info describes how to convert the post-transformed vertices + * (simple float[][4]) used by the 'draw' module into vertices for + * rasterization. + * + * This function validates the vertex layout and returns a pointer to a + * vertex_info object. */ -static void calculate_vertex_layout( struct softpipe_context *softpipe ) +struct vertex_info * +softpipe_get_vertex_info(struct softpipe_context *softpipe) { - const struct pipe_shader_state *vs = &softpipe->vs->shader; - const struct pipe_shader_state *fs = &softpipe->fs->shader; - const enum interp_mode colorInterp - = softpipe->rasterizer->flatshade ? INTERP_CONSTANT : INTERP_LINEAR; struct vertex_info *vinfo = &softpipe->vertex_info; - uint i; - if (softpipe->vbuf) { - /* if using the post-transform vertex buffer, tell draw_vbuf to - * simply emit the whole post-xform vertex as-is: - */ - struct vertex_info *vinfo_vbuf = &softpipe->vertex_info_vbuf; - vinfo_vbuf->num_attribs = 0; - draw_emit_vertex_attr(vinfo_vbuf, EMIT_ALL, INTERP_NONE, 0); - vinfo_vbuf->size = 4 * vs->num_outputs + sizeof(struct vertex_header)/4; - } + if (vinfo->num_attribs == 0) { + /* compute vertex layout now */ + const struct pipe_shader_state *vs = &softpipe->vs->shader; + const struct pipe_shader_state *fs = &softpipe->fs->shader; + const enum interp_mode colorInterp + = softpipe->rasterizer->flatshade ? INTERP_CONSTANT : INTERP_LINEAR; + uint i; + + if (softpipe->vbuf) { + /* if using the post-transform vertex buffer, tell draw_vbuf to + * simply emit the whole post-xform vertex as-is: + */ + struct vertex_info *vinfo_vbuf = &softpipe->vertex_info_vbuf; + vinfo_vbuf->num_attribs = 0; + draw_emit_vertex_attr(vinfo_vbuf, EMIT_ALL, INTERP_NONE, 0); + vinfo_vbuf->size = 4 * vs->num_outputs + + sizeof(struct vertex_header) / 4; + } - /* - * Loop over fragment shader inputs, searching for the matching output - * from the vertex shader. - */ - vinfo->num_attribs = 0; - for (i = 0; i < fs->num_inputs; i++) { - int src; - switch (fs->input_semantic_name[i]) { - case TGSI_SEMANTIC_POSITION: - src = find_vs_output(vs, TGSI_SEMANTIC_POSITION, 0); - assert(src >= 0); - draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_POS, src); - break; - - case TGSI_SEMANTIC_COLOR: - src = find_vs_output(vs, TGSI_SEMANTIC_COLOR, - fs->input_semantic_index[i]); - assert(src >= 0); - draw_emit_vertex_attr(vinfo, EMIT_4F, colorInterp, src); - break; - - case TGSI_SEMANTIC_FOG: - src = find_vs_output(vs, TGSI_SEMANTIC_FOG, 0); + /* + * Loop over fragment shader inputs, searching for the matching output + * from the vertex shader. + */ + vinfo->num_attribs = 0; + for (i = 0; i < fs->num_inputs; i++) { + int src; + switch (fs->input_semantic_name[i]) { + case TGSI_SEMANTIC_POSITION: + src = find_vs_output(vs, TGSI_SEMANTIC_POSITION, 0); + assert(src >= 0); + draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_POS, src); + break; + + case TGSI_SEMANTIC_COLOR: + src = find_vs_output(vs, TGSI_SEMANTIC_COLOR, + fs->input_semantic_index[i]); + if (src < 0) + src = 0; + assert(src >= 0); + draw_emit_vertex_attr(vinfo, EMIT_4F, colorInterp, src); + break; + + case TGSI_SEMANTIC_FOG: + 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; + if (src < 0) /* XXX temp hack, try demos/fogcoord.c with this */ + src = 0; #endif - assert(src >= 0); - draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src); - break; - - case TGSI_SEMANTIC_GENERIC: - /* this includes texcoords and varying vars */ - src = find_vs_output(vs, TGSI_SEMANTIC_GENERIC, - fs->input_semantic_index[i]); - assert(src >= 0); - draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src); - break; - - default: - assert(0); + assert(src >= 0); + draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src); + break; + + case TGSI_SEMANTIC_GENERIC: + /* this includes texcoords and varying vars */ + src = find_vs_output(vs, TGSI_SEMANTIC_GENERIC, + fs->input_semantic_index[i]); + assert(src >= 0); + draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src); + break; + + default: + assert(0); + } } - } - softpipe->psize_slot = find_vs_output(vs, TGSI_SEMANTIC_PSIZE, 0); - if (softpipe->psize_slot >= 0) { - draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT, - softpipe->psize_slot); + softpipe->psize_slot = find_vs_output(vs, TGSI_SEMANTIC_PSIZE, 0); + if (softpipe->psize_slot >= 0) { + draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT, + softpipe->psize_slot); + } + + draw_compute_vertex_size(vinfo); } - draw_compute_vertex_size(vinfo); + return vinfo; +} + + +/** + * Called from vbuf module. + * + * Note that there's actually two different vertex layouts in softpipe. + * + * The normal one is computed in softpipe_get_vertex_info() above and is + * used by the point/line/tri "setup" code. + * + * The other one (this one) is only used by the vbuf module (which is + * not normally used by default but used in testing). For the vbuf module, + * we basically want to pass-through the draw module's vertex layout as-is. + * When the softpipe vbuf code begins drawing, the normal vertex layout + * will come into play again. + */ +struct vertex_info * +softpipe_get_vbuf_vertex_info(struct softpipe_context *softpipe) +{ + (void) softpipe_get_vertex_info(softpipe); + return &softpipe->vertex_info_vbuf; } @@ -171,7 +217,7 @@ void softpipe_update_derived( struct softpipe_context *softpipe ) if (softpipe->dirty & (SP_NEW_RASTERIZER | SP_NEW_FS | SP_NEW_VS)) - calculate_vertex_layout( softpipe ); + invalidate_vertex_layout( softpipe ); if (softpipe->dirty & (SP_NEW_SCISSOR | SP_NEW_DEPTH_STENCIL_ALPHA | |