One less dependency on the TGSI_ATTRIB_x flags.
This requires setting the vertex_info->interp_mode[] values in the i915 driver and passing them to draw_set_vertex_attributes().
static INLINE void
-emit_vertex_attr(struct vertex_info *vinfo, uint vfAttr, uint format)
+emit_vertex_attr(struct vertex_info *vinfo, uint vfAttr, uint format, uint interp)
{
const uint n = vinfo->num_attribs;
vinfo->attr_mask |= (1 << vfAttr);
assert(vfAttr < Elements(vinfo->attrib_to_slot));
vinfo->attrib_to_slot[vfAttr] = n - 2;
}
- /*printf("Vertex slot %d = vfattrib %d\n", n, vfAttr);*/
- /*vinfo->interp_mode[n] = interpMode;*/
+ vinfo->interp_mode[n] = interp;
vinfo->format[n] = format;
vinfo->num_attribs++;
void
draw_set_vertex_attributes( struct draw_context *draw,
- const unsigned *slot_to_vf_attr,
+ const uint *slot_to_vf_attr,
+ const uint *interp_mode,
unsigned nr_attrs )
{
struct vertex_info *vinfo = &draw->vertex_info;
/*
* First three attribs are always the same: header, clip pos, winpos
*/
- emit_vertex_attr(vinfo, TGSI_ATTRIB_VERTEX_HEADER, FORMAT_1F);
- emit_vertex_attr(vinfo, TGSI_ATTRIB_CLIP_POS, FORMAT_4F);
- emit_vertex_attr(vinfo, TGSI_ATTRIB_POS, FORMAT_4F_VIEWPORT);
+ emit_vertex_attr(vinfo, TGSI_ATTRIB_VERTEX_HEADER, FORMAT_1F, INTERP_NONE);
+ emit_vertex_attr(vinfo, TGSI_ATTRIB_CLIP_POS, FORMAT_4F, INTERP_LINEAR);
+ emit_vertex_attr(vinfo, TGSI_ATTRIB_POS, FORMAT_4F_VIEWPORT, INTERP_LINEAR);
/*
* Remaining attribs (color, texcoords, etc)
*/
for (i = 1; i < nr_attrs; i++) {
- emit_vertex_attr(vinfo, slot_to_vf_attr[i], FORMAT_4F);
+ emit_vertex_attr(vinfo, slot_to_vf_attr[i], FORMAT_4F, interp_mode[i]);
}
compute_vertex_size(vinfo);
struct draw_stage *stage );
void draw_set_vertex_attributes( struct draw_context *draw,
- const unsigned *attrs,
+ const uint *attrs, const uint *interp_mode,
unsigned nr_attrs );
unsigned draw_prim_info( unsigned prim, unsigned *first, unsigned *incr );
#include "draw_private.h"
-struct flatshade_stage {
- struct draw_stage stage;
-
- const unsigned *lookup;
-};
-
-
-
-static INLINE struct flatshade_stage *flatshade_stage( struct draw_stage *stage )
-{
- return (struct flatshade_stage *)stage;
-}
-
-
static void flatshade_begin( struct draw_stage *stage )
{
stage->next->begin( stage->next );
struct vertex_header *dst,
const struct vertex_header *src )
{
- const struct flatshade_stage *flatshade = flatshade_stage(stage);
- const unsigned *lookup = flatshade->lookup;
-
- copy_attr( lookup[TGSI_ATTRIB_COLOR0], dst, src );
- copy_attr( lookup[TGSI_ATTRIB_COLOR1], dst, src );
- copy_attr( lookup[TGSI_ATTRIB_BFC0], dst, src );
- copy_attr( lookup[TGSI_ATTRIB_BFC1], dst, src );
+ const uint num_attribs = stage->draw->vertex_info.num_attribs;
+ const uint *interp_mode = stage->draw->vertex_info.interp_mode;
+ uint i;
+
+ /* Look for constant/flat attribs and duplicate from src to dst vertex */
+ for (i = 1; i < num_attribs - 2; i++) {
+ if (interp_mode[i + 2] == INTERP_CONSTANT) {
+ copy_attr( i, dst, src );
+ }
+ }
}
*/
struct draw_stage *draw_flatshade_stage( struct draw_context *draw )
{
- struct flatshade_stage *flatshade = CALLOC_STRUCT(flatshade_stage);
+ struct draw_stage *flatshade = CALLOC_STRUCT(draw_stage);
draw_alloc_tmps( &flatshade->stage, 2 );
- flatshade->stage.draw = draw;
- flatshade->stage.next = NULL;
- flatshade->stage.begin = flatshade_begin;
- flatshade->stage.point = flatshade_point;
- flatshade->stage.line = flatshade_line;
- flatshade->stage.tri = flatshade_tri;
- flatshade->stage.end = flatshade_end;
- flatshade->stage.reset_stipple_counter = flatshade_reset_stipple_counter;
-
- flatshade->lookup = draw->vertex_info.attrib_to_slot;
+ flatshade->draw = draw;
+ flatshade->next = NULL;
+ flatshade->begin = flatshade_begin;
+ flatshade->point = flatshade_point;
+ flatshade->line = flatshade_line;
+ flatshade->tri = flatshade_tri;
+ flatshade->end = flatshade_end;
+ flatshade->reset_stipple_counter = flatshade_reset_stipple_counter;
- return &flatshade->stage;
+ return flatshade;
}
#define FORMAT_4UB 5
+enum interp_mode {
+ INTERP_NONE, /**< never interpolate vertex header info */
+ INTERP_CONSTANT,
+ INTERP_LINEAR,
+ INTERP_PERSPECTIVE
+};
+
+
+
struct vertex_info
{
uint num_attribs;
static INLINE void
-emit_vertex_attr(struct vertex_info *vinfo, uint vfAttr, uint format)
+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->format[n] = format;
+ vinfo->interp_mode[n] = interp;
vinfo->num_attribs++;
}
static void calculate_vertex_layout( struct i915_context *i915 )
{
const unsigned inputsRead = i915->fs.inputs_read;
+ const uint colorInterp
+ = i915->setup.flatshade ? INTERP_CONSTANT : INTERP_LINEAR;
struct vertex_info *vinfo = &i915->current.vertex_info;
boolean needW = 0;
memset(vinfo, 0, sizeof(*vinfo));
/* pos */
- emit_vertex_attr(vinfo, TGSI_ATTRIB_POS, FORMAT_3F);
+ emit_vertex_attr(vinfo, TGSI_ATTRIB_POS, FORMAT_3F, INTERP_LINEAR);
/* Note: we'll set the S4_VFMT_XYZ[W] bits below */
/* color0 */
if (inputsRead & (1 << TGSI_ATTRIB_COLOR0)) {
- emit_vertex_attr(vinfo, TGSI_ATTRIB_COLOR0, FORMAT_4UB);
+ 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);
+ emit_vertex_attr(vinfo, TGSI_ATTRIB_COLOR1, FORMAT_4UB, colorInterp);
vinfo->hwfmt[0] |= S4_VFMT_SPEC_FOG;
}
for (i = TGSI_ATTRIB_TEX0; i <= TGSI_ATTRIB_TEX7; i++) {
uint hwtc;
if (inputsRead & (1 << i)) {
- emit_vertex_attr(vinfo, i, FORMAT_4F);
+ emit_vertex_attr(vinfo, i, FORMAT_4F, INTERP_PERSPECTIVE);
hwtc = TEXCOORDFMT_4D;
needW = TRUE;
}
*/
if (i915->setup.light_twoside) {
if (inputsRead & (1 << TGSI_ATTRIB_COLOR0)) {
- emit_vertex_attr(vinfo, TGSI_ATTRIB_BFC0, FORMAT_OMIT);
+ 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);
+ emit_vertex_attr(vinfo, TGSI_ATTRIB_BFC1, FORMAT_OMIT, colorInterp);
}
}
*/
draw_set_vertex_attributes( i915->draw,
vinfo->slot_to_attrib,
+ vinfo->interp_mode,
vinfo->num_attribs);
/* Need to set this flag so that the LIS2/4 registers get set.
struct draw_stage;
-enum interp_mode {
- INTERP_CONSTANT,
- INTERP_LINEAR,
- INTERP_PERSPECTIVE
-};
-
-
#define SP_NEW_VIEWPORT 0x1
#define SP_NEW_SETUP 0x2
#define SP_NEW_FS 0x4
for (j = 0; j < NUM_CHANNELS; j++)
tri_persp_coeff(setup, slot, j);
break;
+
+ default:
+ /* invalid interp mode */
+ assert(0);
}
}
}
/* If the attributes have changed, tell the draw module about
* the new vertex layout.
*/
- if (vinfo->attr_mask != softpipe->attr_mask) {
+ /* XXX we also need to do this when the shading mode (interp modes) change: */
+ if (1/*vinfo->attr_mask != softpipe->attr_mask*/) {
softpipe->attr_mask = vinfo->attr_mask;
draw_set_vertex_attributes( softpipe->draw,
vinfo->slot_to_attrib,
+ vinfo->interp_mode,
vinfo->num_attribs);
}
}