summaryrefslogtreecommitdiffstats
path: root/src/mesa
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa')
-rw-r--r--src/mesa/pipe/draw/draw_context.c41
-rw-r--r--src/mesa/pipe/draw/draw_context.h4
-rw-r--r--src/mesa/pipe/draw/draw_private.h3
-rw-r--r--src/mesa/pipe/draw/draw_twoside.c26
-rw-r--r--src/mesa/pipe/i915simple/i915_state_derived.c22
-rw-r--r--src/mesa/pipe/softpipe/sp_state_derived.c25
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 b14de341410..c15f7652a6f 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 4c9e64a12d2..21ee18e7cf6 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 e61f228d12c..80c97ada329 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 a05eea41fc2..98eb088035a 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 e156766a934..4b97223a6e9 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 ff0a275fcea..41b73405ae5 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);
}
}