diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mesa/pipe/draw/draw_context.c | 41 | ||||
-rw-r--r-- | src/mesa/pipe/draw/draw_context.h | 4 | ||||
-rw-r--r-- | src/mesa/pipe/draw/draw_private.h | 3 | ||||
-rw-r--r-- | src/mesa/pipe/draw/draw_twoside.c | 26 | ||||
-rw-r--r-- | src/mesa/pipe/i915simple/i915_state_derived.c | 22 | ||||
-rw-r--r-- | src/mesa/pipe/softpipe/sp_state_derived.c | 25 |
6 files changed, 95 insertions, 26 deletions
diff --git a/src/mesa/pipe/draw/draw_context.c b/src/mesa/pipe/draw/draw_context.c index b14de34141..c15f7652a6 100644 --- a/src/mesa/pipe/draw/draw_context.c +++ b/src/mesa/pipe/draw/draw_context.c @@ -67,6 +67,11 @@ struct draw_context *draw_create( void ) draw->vcache.vertex[i] = (struct vertex_header *)(tmp + i * MAX_VERTEX_SIZE); } + draw->attrib_front0 = -1; + draw->attrib_back0 = -1; + draw->attrib_front1 = -1; + draw->attrib_back1 = -1; + return draw; } @@ -210,3 +215,39 @@ draw_set_vertex_shader(struct draw_context *draw, { draw->vertex_shader = *shader; } + + +/** + * This function is used to tell the draw module about attributes + * (like colors) that need to be selected based on front/back face + * orientation. + * + * The logic is: + * if (polygon is back-facing) { + * vertex->attrib[front0] = vertex->attrib[back0]; + * vertex->attrib[front1] = vertex->attrib[back1]; + * } + * + * \param front0 first attrib to replace if the polygon is back-facing + * \param back0 first attrib to copy if the polygon is back-facing + * \param front1 second attrib to replace if the polygon is back-facing + * \param back1 second attrib to copy if the polygon is back-facing + * + * Pass -1 to disable two-sided attributes. + */ +void +draw_set_twoside_attributes(struct draw_context *draw, + uint front0, uint back0, + uint front1, uint back1) +{ + /* XXX we could alternately pass an array of front/back attribs if there's + * ever need for more than two. One could imagine a shader extension + * that allows arbitrary attributes to be selected based on polygon + * orientation... + */ + draw->attrib_front0 = front0; + draw->attrib_back0 = back0; + draw->attrib_front1 = front1; + draw->attrib_back1 = back1; +} + diff --git a/src/mesa/pipe/draw/draw_context.h b/src/mesa/pipe/draw/draw_context.h index 4c9e64a12d..21ee18e7cf 100644 --- a/src/mesa/pipe/draw/draw_context.h +++ b/src/mesa/pipe/draw/draw_context.h @@ -92,6 +92,10 @@ void draw_set_vertex_attributes( struct draw_context *draw, const uint *attrs, const uint *interp_mode, unsigned nr_attrs ); +void draw_set_twoside_attributes(struct draw_context *draw, + uint front0, uint back0, + uint front1, uint back1); + unsigned draw_prim_info( unsigned prim, unsigned *first, unsigned *incr ); unsigned draw_trim( unsigned count, unsigned first, unsigned incr ); diff --git a/src/mesa/pipe/draw/draw_private.h b/src/mesa/pipe/draw/draw_private.h index e61f228d12..80c97ada32 100644 --- a/src/mesa/pipe/draw/draw_private.h +++ b/src/mesa/pipe/draw/draw_private.h @@ -158,6 +158,9 @@ struct draw_context /** Describes the layout of post-transformation vertices */ struct vertex_info vertex_info; + /** Two-sided attributes: */ + uint attrib_front0, attrib_back0; + uint attrib_front1, attrib_back1; unsigned nr_vertices; diff --git a/src/mesa/pipe/draw/draw_twoside.c b/src/mesa/pipe/draw/draw_twoside.c index a05eea41fc..98eb088035 100644 --- a/src/mesa/pipe/draw/draw_twoside.c +++ b/src/mesa/pipe/draw/draw_twoside.c @@ -61,15 +61,11 @@ static void twoside_begin( struct draw_stage *stage ) } -static INLINE void copy_color( unsigned attr_dst, +static INLINE void copy_attrib( unsigned attr_dst, unsigned attr_src, struct vertex_header *v ) { - if (attr_dst && attr_src) { - memcpy( v->data[attr_dst], - v->data[attr_src], - sizeof(v->data[0]) ); - } + COPY_4FV(v->data[attr_dst], v->data[attr_src]); } @@ -78,14 +74,16 @@ static struct vertex_header *copy_bfc( struct twoside_stage *twoside, unsigned idx ) { struct vertex_header *tmp = dup_vert( &twoside->stage, v, idx ); + const struct draw_context *draw = twoside->stage.draw; - copy_color( twoside->lookup[TGSI_ATTRIB_COLOR0], - twoside->lookup[TGSI_ATTRIB_BFC0], - tmp ); - - copy_color( twoside->lookup[TGSI_ATTRIB_COLOR1], - twoside->lookup[TGSI_ATTRIB_BFC1], - tmp ); + if (draw->attrib_front0) { + assert(draw->attrib_back0); + copy_attrib(draw->attrib_front0, draw->attrib_back0, tmp); + } + if (draw->attrib_front1) { + assert(draw->attrib_back1); + copy_attrib(draw->attrib_front1, draw->attrib_back1, tmp); + } return tmp; } @@ -104,7 +102,7 @@ static void twoside_tri( struct draw_stage *stage, tmp.det = header->det; tmp.edgeflags = header->edgeflags; - /* copy back colors to front color slots */ + /* copy back attribs to front attribs */ tmp.v[0] = copy_bfc(twoside, header->v[0], 0); tmp.v[1] = copy_bfc(twoside, header->v[1], 1); tmp.v[2] = copy_bfc(twoside, header->v[2], 2); diff --git a/src/mesa/pipe/i915simple/i915_state_derived.c b/src/mesa/pipe/i915simple/i915_state_derived.c index e156766a93..4b97223a6e 100644 --- a/src/mesa/pipe/i915simple/i915_state_derived.c +++ b/src/mesa/pipe/i915simple/i915_state_derived.c @@ -35,8 +35,9 @@ #include "i915_fpc.h" -static INLINE void -emit_vertex_attr(struct vertex_info *vinfo, uint vfAttr, uint format, uint interp) +static INLINE uint +emit_vertex_attr(struct vertex_info *vinfo, uint vfAttr, uint format, + uint interp) { const uint n = vinfo->num_attribs; vinfo->attr_mask |= (1 << vfAttr); @@ -44,6 +45,7 @@ emit_vertex_attr(struct vertex_info *vinfo, uint vfAttr, uint format, uint inter vinfo->format[n] = format; vinfo->interp_mode[n] = interp; vinfo->num_attribs++; + return n; } @@ -93,6 +95,7 @@ static void calculate_vertex_layout( struct i915_context *i915 ) const uint colorInterp = i915->setup.flatshade ? INTERP_CONSTANT : INTERP_LINEAR; struct vertex_info *vinfo = &i915->current.vertex_info; + uint front0 = 0, back0 = 0, front1 = 0, back1 = 0; boolean needW = 0; memset(vinfo, 0, sizeof(*vinfo)); @@ -103,14 +106,16 @@ static void calculate_vertex_layout( struct i915_context *i915 ) /* color0 */ if (inputsRead & (1 << TGSI_ATTRIB_COLOR0)) { - emit_vertex_attr(vinfo, TGSI_ATTRIB_COLOR0, FORMAT_4UB, colorInterp); + front0 = emit_vertex_attr(vinfo, TGSI_ATTRIB_COLOR0, + FORMAT_4UB, colorInterp); vinfo->hwfmt[0] |= S4_VFMT_COLOR; } /* color 1 */ if (inputsRead & (1 << TGSI_ATTRIB_COLOR1)) { assert(0); /* untested */ - emit_vertex_attr(vinfo, TGSI_ATTRIB_COLOR1, FORMAT_4UB, colorInterp); + front1 = emit_vertex_attr(vinfo, TGSI_ATTRIB_COLOR1, + FORMAT_4UB, colorInterp); vinfo->hwfmt[0] |= S4_VFMT_SPEC_FOG; } @@ -149,10 +154,12 @@ static void calculate_vertex_layout( struct i915_context *i915 ) */ if (i915->setup.light_twoside) { if (inputsRead & (1 << TGSI_ATTRIB_COLOR0)) { - emit_vertex_attr(vinfo, TGSI_ATTRIB_BFC0, FORMAT_OMIT, colorInterp); + back0 = emit_vertex_attr(vinfo, TGSI_ATTRIB_BFC0, + FORMAT_OMIT, colorInterp); } if (inputsRead & (1 << TGSI_ATTRIB_COLOR1)) { - emit_vertex_attr(vinfo, TGSI_ATTRIB_BFC1, FORMAT_OMIT, colorInterp); + back1 = emit_vertex_attr(vinfo, TGSI_ATTRIB_BFC1, + FORMAT_OMIT, colorInterp); } } @@ -166,6 +173,9 @@ static void calculate_vertex_layout( struct i915_context *i915 ) vinfo->interp_mode, vinfo->num_attribs); + draw_set_twoside_attributes(i915->draw, + front0, back0, front1, back1); + /* Need to set this flag so that the LIS2/4 registers get set. * It also means the i915_update_immediate() function must be called * after this one, in i915_update_derived(). diff --git a/src/mesa/pipe/softpipe/sp_state_derived.c b/src/mesa/pipe/softpipe/sp_state_derived.c index ff0a275fce..41b73405ae 100644 --- a/src/mesa/pipe/softpipe/sp_state_derived.c +++ b/src/mesa/pipe/softpipe/sp_state_derived.c @@ -37,16 +37,21 @@ -static void +/** + * Add another attribute to the given vertex_info object. + * \return slot in which the attribute was added + */ +static uint emit_vertex_attr(struct vertex_info *vinfo, uint vfAttr, uint format, uint interp) { const uint n = vinfo->num_attribs; vinfo->attr_mask |= (1 << vfAttr); vinfo->slot_to_attrib[n] = vfAttr; - vinfo->interp_mode[n] = interp; vinfo->format[n] = format; + vinfo->interp_mode[n] = interp; vinfo->num_attribs++; + return n; } @@ -62,6 +67,7 @@ static void calculate_vertex_layout( struct softpipe_context *softpipe ) const uint colorInterp = softpipe->setup.flatshade ? INTERP_CONSTANT : INTERP_LINEAR; struct vertex_info *vinfo = &softpipe->vertex_info; + uint front0 = 0, back0 = 0, front1 = 0, back1 = 0; uint i; memset(vinfo, 0, sizeof(*vinfo)); @@ -89,12 +95,14 @@ static void calculate_vertex_layout( struct softpipe_context *softpipe ) /* color0 */ if (inputsRead & (1 << TGSI_ATTRIB_COLOR0)) { - emit_vertex_attr(vinfo, TGSI_ATTRIB_COLOR0, FORMAT_4F, colorInterp); + front0 = emit_vertex_attr(vinfo, TGSI_ATTRIB_COLOR0, + FORMAT_4F, colorInterp); } /* color1 */ if (inputsRead & (1 << TGSI_ATTRIB_COLOR1)) { - emit_vertex_attr(vinfo, TGSI_ATTRIB_COLOR1, FORMAT_4F, colorInterp); + front1 = emit_vertex_attr(vinfo, TGSI_ATTRIB_COLOR1, + FORMAT_4F, colorInterp); } /* fog */ @@ -124,11 +132,13 @@ static void calculate_vertex_layout( struct softpipe_context *softpipe ) */ if (softpipe->setup.light_twoside) { if (inputsRead & (1 << TGSI_ATTRIB_COLOR0)) { - emit_vertex_attr(vinfo, TGSI_ATTRIB_BFC0, FORMAT_OMIT, INTERP_LINEAR); + back0 = emit_vertex_attr(vinfo, TGSI_ATTRIB_BFC0, + FORMAT_OMIT, colorInterp); } if (inputsRead & (1 << TGSI_ATTRIB_COLOR1)) { - emit_vertex_attr(vinfo, TGSI_ATTRIB_BFC1, FORMAT_OMIT, INTERP_LINEAR); + back1 = emit_vertex_attr(vinfo, TGSI_ATTRIB_BFC1, + FORMAT_OMIT, colorInterp); } } @@ -143,6 +153,9 @@ static void calculate_vertex_layout( struct softpipe_context *softpipe ) vinfo->slot_to_attrib, vinfo->interp_mode, vinfo->num_attribs); + + draw_set_twoside_attributes(softpipe->draw, + front0, back0, front1, back1); } } |