From 0673c571c79d00d05328bf41e9c6a52bfb0f7324 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 24 Jan 2008 16:41:03 -0700 Subject: Cell: rewrite compute_vertex_layout() --- src/mesa/pipe/cell/ppu/cell_state_derived.c | 149 +++++++++++----------------- 1 file changed, 60 insertions(+), 89 deletions(-) (limited to 'src') diff --git a/src/mesa/pipe/cell/ppu/cell_state_derived.c b/src/mesa/pipe/cell/ppu/cell_state_derived.c index f236224bce..f3b3ae8544 100644 --- a/src/mesa/pipe/cell/ppu/cell_state_derived.c +++ b/src/mesa/pipe/cell/ppu/cell_state_derived.c @@ -31,102 +31,93 @@ #include "pipe/draw/draw_vertex.h" #include "cell_context.h" #include "cell_state.h" +#include "cell_state_emit.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. - * Derived from: fs, setup states. + * 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. */ -static void calculate_vertex_layout( struct cell_context *cell ) +static void +calculate_vertex_layout( struct cell_context *cell ) { -#if 0 - const struct pipe_shader_state *vs = cell->vs->state; + const struct pipe_shader_state *vs = &cell->vs->shader; const struct pipe_shader_state *fs = &cell->fs->shader; const enum interp_mode colorInterp = cell->rasterizer->flatshade ? INTERP_CONSTANT : INTERP_LINEAR; struct vertex_info *vinfo = &cell->vertex_info; - boolean emitBack0 = FALSE, emitBack1 = FALSE, emitPsize = FALSE; - uint front0 = 0, back0 = 0, front1 = 0, back1 = 0; uint i; -#endif - const enum interp_mode colorInterp - = cell->rasterizer->flatshade ? INTERP_CONSTANT : INTERP_LINEAR; - struct vertex_info *vinfo = &cell->vertex_info; - uint front0; - uint src = 0; - - memset(vinfo, 0, sizeof(*vinfo)); + int src; #if 0 - if (fs->input_semantic_name[0] == TGSI_SEMANTIC_POSITION) { - /* Need Z if depth test is enabled or the fragment program uses the - * fragment position (XYZW). + if (cell->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 = &cell->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; } - - cell->psize_slot = -1; #endif - /* always emit vertex pos */ - draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_LINEAR, src++); + /* reset vinfo */ + vinfo->num_attribs = 0; -#if 1 - front0 = draw_emit_vertex_attr(vinfo, EMIT_4F, colorInterp, src++); -#endif + /* we always want to emit vertex pos */ + src = find_vs_output(vs, TGSI_SEMANTIC_POSITION, 0); + assert(src >= 0); + draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_POS, src); -#if 0 /* - * XXX I think we need to reconcile the vertex shader outputs with - * the fragment shader inputs here to make sure the slots line up. - * Might just be getting lucky so far. - * Or maybe do that in the state tracker? + * Loop over fragment shader inputs, searching for the matching output + * from the vertex shader. */ - - 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: - /* vertex programs always emit position, but might not be - * needed for fragment progs. - */ - /* no-op */ + /* already done above */ break; case TGSI_SEMANTIC_COLOR: - if (vs->output_semantic_index[i] == 0) { - front0 = draw_emit_vertex_attr(vinfo, EMIT_4F, colorInterp, src++); - } - else { - assert(vs->output_semantic_index[i] == 1); - front1 = draw_emit_vertex_attr(vinfo, EMIT_4F, colorInterp, src++); - } - break; - - case TGSI_SEMANTIC_BCOLOR: - if (vs->output_semantic_index[i] == 0) { - emitBack0 = TRUE; - } - else { - assert(vs->output_semantic_index[i] == 1); - emitBack1 = TRUE; - } + 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: - draw_emit_vertex_attr(vinfo, EMIT_1F, INTERP_PERSPECTIVE, src++); - break; - - case TGSI_SEMANTIC_PSIZE: - /* XXX only emit if drawing points or front/back polygon mode - * is point mode - */ - emitPsize = TRUE; + 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, EMIT_1F, INTERP_PERSPECTIVE, src); break; case TGSI_SEMANTIC_GENERIC: /* this includes texcoords and varying vars */ - draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src++); + 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: @@ -134,29 +125,6 @@ static void calculate_vertex_layout( struct cell_context *cell ) } } - cell->nr_frag_attrs = fs->num_inputs; - - /* We want these after all other attribs since they won't get passed - * to the fragment shader. All prior vertex output attribs should match - * up 1:1 with the fragment shader inputs. - */ - if (emitBack0) { - back0 = draw_emit_vertex_attr(vinfo, EMIT_4F, colorInterp, src++); - } - if (emitBack1) { - back1 = draw_emit_vertex_attr(vinfo, EMIT_4F, colorInterp, src++); - } - if (emitPsize) { - cell->psize_slot - = draw_emit_vertex_attr(vinfo, EMIT_1F, INTERP_CONSTANT, src++); - } - - /* If the attributes have changed, tell the draw module about - * the new vertex layout. - */ - /* XXX we also need to do this when the shading mode (interp modes) change: */ -#endif - draw_compute_vertex_size(vinfo); } @@ -198,9 +166,12 @@ compute_cliprect(struct cell_context *sp) #endif + void cell_update_derived( struct cell_context *cell ) { - if (cell->dirty & (CELL_NEW_RASTERIZER | CELL_NEW_FS)) + if (cell->dirty & (CELL_NEW_RASTERIZER | + CELL_NEW_FS | + CELL_NEW_VS)) calculate_vertex_layout( cell ); #if 0 -- cgit v1.2.3