struct quad_header quad;
struct {
- GLint left[2];
+ GLint left[2]; /**< [0] = row0, [1] = row1 */
GLint right[2];
GLint y;
GLuint y_flags;
- GLuint mask;
+ GLuint mask; /**< mask of MASK_BOTTOM/TOP_LEFT/RIGHT bits */
} span;
};
-
+/**
+ * Basically a cast wrapper.
+ */
static inline struct setup_stage *setup_stage( struct prim_stage *stage )
{
return (struct setup_stage *)stage;
}
-
-static inline GLint _min(GLint x, GLint y)
-{
- return x < y ? x : y;
-}
-
-static inline GLint _max(GLint x, GLint y)
-{
- return x > y ? x : y;
-}
-
+/**
+ * Given an X or Y coordinate, return the block/quad coordinate that it
+ * belongs to.
+ */
static inline GLint block( GLint x )
{
return x & ~1;
}
-
+/**
+ * Run shader on a quad/block.
+ */
static void run_shader_block( struct setup_stage *setup,
GLint x, GLint y, GLuint mask )
{
}
-/* this is pretty nasty... may need to rework flush_spans again to
+/**
+ * Compute mask which indicates which pixels in the 2x2 quad are actually inside
+ * the triangle's bounds.
+ *
+ * this is pretty nasty... may need to rework flush_spans again to
* fix it, if possible.
*/
static GLuint calculate_mask( struct setup_stage *setup,
}
+/**
+ * Render a horizontal span of quads
+ */
static void flush_spans( struct setup_stage *setup )
{
GLint minleft, maxright;
switch (setup->span.y_flags) {
case 3:
- minleft = _min(setup->span.left[0],
- setup->span.left[1]);
- maxright = _max(setup->span.right[0],
- setup->span.right[1]);
+ minleft = MIN2(setup->span.left[0], setup->span.left[1]);
+ maxright = MAX2(setup->span.right[0], setup->span.right[1]);
break;
case 1:
setup->span.right[1] = 0;
}
-
+/**
+ * Do setup for point rasterization, then render the point.
+ */
static void
setup_point( struct prim_stage *stage,
struct prim_header *header )
}
+/**
+ * Do setup for line rasterization, then render the line.
+ */
static void
setup_line( struct prim_stage *stage,
struct prim_header *header )
}
-
-
-
-
static GLboolean setup_sort_vertices( struct setup_stage *setup,
const struct prim_header *prim )
{
setup->oneoverarea = 1.0 / area;
}
+ /* XXX need to know if this is a front or back-facing triangle:
+ * - the GLSL gl_FrontFacing fragment attribute (bool)
+ * - two-sided stencil test
+ */
+ setup->quad.facing = 0;
_mesa_printf("%s one-over-area %f\n", __FUNCTION__, setup->oneoverarea );
}
+/**
+ * Compute a0 for a constant-valued coefficient (GL_FLAT shading).
+ */
static void const_coeff( struct setup_stage *setup,
GLuint slot,
GLuint i )
}
+/**
+ * Compute a0, dadx and dady for a linearly interpolated coefficient.
+ */
static void linear_coeff( struct setup_stage *setup,
GLuint slot,
GLuint i)
}
+/**
+ * Compute a0, dadx and dady for a perspective-corrected interpolant.
+ */
static void persp_coeff( struct setup_stage *setup,
GLuint slot,
GLuint i )
}
-
-
-
-
+/**
+ * Render the upper or lower half of a triangle.
+ * Scissoring is applied here too.
+ */
static void subtriangle( struct setup_stage *setup,
struct edge *eleft,
struct edge *eright,
}
+/**
+ * Do setup for triangle rasterization, then render the triangle.
+ */
static void setup_tri( struct prim_stage *stage,
struct prim_header *prim )
{
};
+/**
+ * Compute quad's attributes values, as constants (GL_FLAT shading).
+ */
static void INLINE cinterp( struct exec_machine *exec,
GLuint attrib,
GLuint i )
}
-/* Push into the fp:
+/**
+ * Compute quad's attribute values by linear interpolation.
+ *
+ * Push into the fp:
*
* INPUT[attr] = MAD COEF_A0[attr], COEF_DADX[attr], INPUT_WPOS.xxxx
* INPUT[attr] = MAD INPUT[attr], COEF_DADY[attr], INPUT_WPOS.yyyy
GLuint j;
for (j = 0; j < QUAD_SIZE; j++) {
+ const GLfloat x = exec->attr[FRAG_ATTRIB_WPOS][0][j];
+ const GLfloat y = exec->attr[FRAG_ATTRIB_WPOS][1][j];
exec->attr[attrib][i][j] = (exec->coef[attrib].a0[i] +
- exec->coef[attrib].dadx[i] * exec->attr[0][0][j] +
- exec->coef[attrib].dady[i] * exec->attr[0][1][j]);
+ exec->coef[attrib].dadx[i] * x +
+ exec->coef[attrib].dady[i] * y);
}
}
-/* Push into the fp:
+/**
+ * Compute quad's attribute values by linear interpolation with
+ * perspective correction.
+ *
+ * Push into the fp:
*
* INPUT[attr] = MAD COEF_A0[attr], COEF_DADX[attr], INPUT_WPOS.xxxx
* INPUT[attr] = MAD INPUT[attr], COEF_DADY[attr], INPUT_WPOS.yyyy
GLuint j;
for (j = 0; j < QUAD_SIZE; j++) {
+ const GLfloat x = exec->attr[FRAG_ATTRIB_WPOS][0][j];
+ const GLfloat y = exec->attr[FRAG_ATTRIB_WPOS][1][j];
+ const GLfloat invW = exec->attr[FRAG_ATTRIB_WPOS][3][j];
exec->attr[attrib][i][j] = ((exec->coef[attrib].a0[i] +
- exec->coef[attrib].dadx[i] * exec->attr[0][0][j] +
- exec->coef[attrib].dady[i] * exec->attr[0][1][j]) *
- exec->attr[0][3][j]);
+ exec->coef[attrib].dadx[i] * x +
+ exec->coef[attrib].dady[i] * y) * invW);
}
}
exec.attr[FRAG_ATTRIB_WPOS][1][3] = fy + 1.0;
/* Z and W are done by linear interpolation:
+ * XXX we'll probably have to use integers for Z
*/
if (generic->need_z) {
linterp(&exec, 0, 2);