#define NUM_CHANNELS 4
+struct lp_line_info {
+
+ float dx;
+ float dy;
+ float oneoverarea;
+
+ const float (*v1)[4];
+ const float (*v2)[4];
+};
/**
*/
static void linear_coef( struct lp_setup_context *setup,
struct lp_rast_triangle *tri,
- float oneoverarea,
+ struct lp_line_info *info,
unsigned slot,
- const float (*v1)[4],
- const float (*v2)[4],
unsigned vert_attr,
unsigned i)
{
- float a1 = v1[vert_attr][i];
- float a2 = v2[vert_attr][i];
+ float a1 = info->v1[vert_attr][i];
+ float a2 = info->v2[vert_attr][i];
float da21 = a1 - a2;
- float dadx = da21 * tri->dx * oneoverarea;
- float dady = da21 * tri->dy * oneoverarea;
+ float dadx = da21 * info->dx * info->oneoverarea;
+ float dady = da21 * info->dy * info->oneoverarea;
tri->inputs.dadx[slot][i] = dadx;
tri->inputs.dady[slot][i] = dady;
tri->inputs.a0[slot][i] = (a1 -
- (dadx * (v1[0][0] - setup->pixel_offset) +
- dady * (v1[0][1] - setup->pixel_offset)));
+ (dadx * (info->v1[0][0] - setup->pixel_offset) +
+ dady * (info->v1[0][1] - setup->pixel_offset)));
}
*/
static void perspective_coef( struct lp_setup_context *setup,
struct lp_rast_triangle *tri,
- float oneoverarea,
+ struct lp_line_info *info,
unsigned slot,
- const float (*v1)[4],
- const float (*v2)[4],
unsigned vert_attr,
unsigned i)
{
/* premultiply by 1/w (v[0][3] is always 1/w):
*/
- float a1 = v1[vert_attr][i] * v1[0][3];
- float a2 = v2[vert_attr][i] * v2[0][3];
+ float a1 = info->v1[vert_attr][i] * info->v1[0][3];
+ float a2 = info->v2[vert_attr][i] * info->v2[0][3];
float da21 = a1 - a2;
- float dadx = da21 * tri->dx * oneoverarea;
- float dady = da21 * tri->dy * oneoverarea;
+ float dadx = da21 * info->dx * info->oneoverarea;
+ float dady = da21 * info->dy * info->oneoverarea;
tri->inputs.dadx[slot][i] = dadx;
tri->inputs.dady[slot][i] = dady;
tri->inputs.a0[slot][i] = (a1 -
- (dadx * (v1[0][0] - setup->pixel_offset) +
- dady * (v1[0][1] - setup->pixel_offset)));
+ (dadx * (info->v1[0][0] - setup->pixel_offset) +
+ dady * (info->v1[0][1] - setup->pixel_offset)));
}
static void
setup_fragcoord_coef( struct lp_setup_context *setup,
struct lp_rast_triangle *tri,
- float oneoverarea,
+ struct lp_line_info *info,
unsigned slot,
- const float (*v1)[4],
- const float (*v2)[4],
unsigned usage_mask)
{
/*X*/
/*Z*/
if (usage_mask & TGSI_WRITEMASK_Z) {
- linear_coef(setup, tri, oneoverarea, slot, v1, v2, 0, 2);
+ linear_coef(setup, tri, info, slot, 0, 2);
}
/*W*/
if (usage_mask & TGSI_WRITEMASK_W) {
- linear_coef(setup, tri, oneoverarea, slot, v1, v2, 0, 3);
+ linear_coef(setup, tri, info, slot, 0, 3);
}
}
*/
static void setup_line_coefficients( struct lp_setup_context *setup,
struct lp_rast_triangle *tri,
- float oneoverarea,
- const float (*v1)[4],
- const float (*v2)[4])
+ struct lp_line_info *info)
{
unsigned fragcoord_usage_mask = TGSI_WRITEMASK_XYZ;
unsigned slot;
if (setup->flatshade_first) {
for (i = 0; i < NUM_CHANNELS; i++)
if (usage_mask & (1 << i))
- constant_coef(setup, tri, slot+1, v1[vert_attr][i], i);
+ constant_coef(setup, tri, slot+1, info->v1[vert_attr][i], i);
}
else {
for (i = 0; i < NUM_CHANNELS; i++)
if (usage_mask & (1 << i))
- constant_coef(setup, tri, slot+1, v2[vert_attr][i], i);
+ constant_coef(setup, tri, slot+1, info->v2[vert_attr][i], i);
}
break;
case LP_INTERP_LINEAR:
for (i = 0; i < NUM_CHANNELS; i++)
if (usage_mask & (1 << i))
- linear_coef(setup, tri, oneoverarea, slot+1, v1, v2, vert_attr, i);
+ linear_coef(setup, tri, info, slot+1, vert_attr, i);
break;
case LP_INTERP_PERSPECTIVE:
for (i = 0; i < NUM_CHANNELS; i++)
if (usage_mask & (1 << i))
- perspective_coef(setup, tri, oneoverarea, slot+1, v1, v2, vert_attr, i);
+ perspective_coef(setup, tri, info, slot+1, vert_attr, i);
fragcoord_usage_mask |= TGSI_WRITEMASK_W;
break;
fragcoord_usage_mask |= usage_mask;
break;
+ case LP_INTERP_FACING:
+ for (i = 0; i < NUM_CHANNELS; i++)
+ if (usage_mask & (1 << i))
+ constant_coef(setup, tri, slot+1, 1.0, i);
+ break;
+
default:
assert(0);
}
/* The internal position input is in slot zero:
*/
- setup_fragcoord_coef(setup, tri, oneoverarea, 0, v1, v2,
+ setup_fragcoord_coef(setup, tri, info, 0,
fragcoord_usage_mask);
}
-static void
-lp_setup_line( struct lp_setup_context *setup,
+static boolean
+try_setup_line( struct lp_setup_context *setup,
const float (*v1)[4],
const float (*v2)[4])
{
- struct lp_scene *scene = lp_setup_get_current_scene(setup);
+ struct lp_scene *scene = setup->scene;
struct lp_rast_triangle *line;
- float oneoverarea;
+ struct lp_line_info info;
float width = MAX2(1.0, setup->line_width);
struct u_rect bbox;
unsigned tri_bytes;
int nr_planes = 4;
/* linewidth should be interpreted as integer */
- int fixed_width = subpixel_snap(round(width));
+ int fixed_width = util_iround(width) * FIXED_ONE;
float x_offset=0;
float y_offset=0;
float x2diff;
float y2diff;
float dx, dy;
+ float area;
boolean draw_start;
boolean draw_end;
dx = v1[0][0] - v2[0][0];
dy = v1[0][1] - v2[0][1];
+ area = (dx * dx + dy * dy);
+ if (area == 0) {
+ LP_COUNT(nr_culled_tris);
+ return TRUE;
+ }
+
+ info.oneoverarea = 1.0f / area;
+ info.dx = dx;
+ info.dy = dy;
+ info.v1 = v1;
+ info.v2 = v2;
+
/* X-MAJOR LINE */
if (fabsf(dx) >= fabsf(dy)) {
else {
/* do intersection test */
float xintersect = fracf(v2[0][0]) + y2diff * dxdy;
- draw_end = (xintersect < 1.0 && xintersect > 0.0);
+ draw_end = (xintersect < 1.0 && xintersect >= 0.0);
}
/* Are we already drawing start/end?
x_offset_end = y_offset_end * dxdy;
}
}
-
+
/* x/y positions in fixed point */
x[0] = subpixel_snap(v1[0][0] + x_offset - setup->pixel_offset) - fixed_width/2;
x[1] = subpixel_snap(v2[0][0] + x_offset_end - setup->pixel_offset) - fixed_width/2;
bbox.y1 < bbox.y0) {
if (0) debug_printf("empty bounding box\n");
LP_COUNT(nr_culled_tris);
- return;
+ return TRUE;
}
if (!u_rect_test_intersection(&setup->draw_region, &bbox)) {
if (0) debug_printf("offscreen\n");
LP_COUNT(nr_culled_tris);
- return;
+ return TRUE;
}
u_rect_find_intersection(&setup->draw_region, &bbox);
nr_planes,
&tri_bytes);
if (!line)
- return;
+ return FALSE;
#ifdef DEBUG
line->v[0][0] = v1[0][0];
line->v[1][1] = v2[0][1];
#endif
- line->dx = dx;
- line->dy = dy;
-
/* calculate the deltas */
line->plane[0].dcdy = x[0] - x[1];
line->plane[1].dcdy = x[1] - x[2];
line->plane[3].dcdx = y[3] - y[0];
- oneoverarea = 1.0f / (dx * dx + dy * dy);
-
/* Setup parameter interpolants:
*/
- setup_line_coefficients( setup, line, oneoverarea, v1, v2);
+ setup_line_coefficients( setup, line, &info);
line->inputs.facing = 1.0F;
- line->inputs.state = setup->fs.stored;
+ line->inputs.disable = FALSE;
+ line->inputs.opaque = FALSE;
for (i = 0; i < 4; i++) {
struct lp_rast_plane *plane = &line->plane[i];
line->plane[7].eo = 0;
}
- lp_setup_bin_triangle(setup, line, &bbox, nr_planes);
+ return lp_setup_bin_triangle(setup, line, &bbox, nr_planes);
}
-
+
+
+static void lp_setup_line( struct lp_setup_context *setup,
+ const float (*v0)[4],
+ const float (*v1)[4] )
+{
+ if (!try_setup_line( setup, v0, v1 ))
+ {
+ if (!lp_setup_flush_and_restart(setup))
+ return;
+
+ if (!try_setup_line( setup, v0, v1 ))
+ return;
+ }
+}
+
void lp_setup_choose_line( struct lp_setup_context *setup )
{