/** * Do setup for triangle rasterization, then render the triangle. */ void sp_setup_tri( struct setup_context *setup, const float (*v0)[4], const float (*v1)[4], const float (*v2)[4] ) { float det; #if DEBUG_VERTS debug_printf("Setup triangle:\n"); print_vertex(setup, v0); print_vertex(setup, v1); print_vertex(setup, v2); #endif if (setup->softpipe->no_rast) return; det = calc_det(v0, v1, v2); /* debug_printf("%s\n", __FUNCTION__ ); */ #if DEBUG_FRAGS setup->numFragsEmitted = 0; setup->numFragsWritten = 0; #endif if (cull_tri( setup, det )) return; if (!setup_sort_vertices( setup, det, v0, v1, v2 )) return; setup_tri_coefficients( setup ); setup_tri_edges( setup ); assert(setup->softpipe->reduced_prim == PIPE_PRIM_TRIANGLES); setup->span.y = 0; setup->span.right[0] = 0; setup->span.right[1] = 0; /* setup->span.z_mode = tri_z_mode( setup->ctx ); */ /* init_constant_attribs( setup ); */ if (setup->oneoverarea < 0.0) { /* emaj on left: */ subtriangle( setup, &setup->emaj, &setup->ebot, setup->ebot.lines ); subtriangle( setup, &setup->emaj, &setup->etop, setup->etop.lines ); } else { /* emaj on right: */ subtriangle( setup, &setup->ebot, &setup->emaj, setup->ebot.lines ); subtriangle( setup, &setup->etop, &setup->emaj, setup->etop.lines ); } flush_spans( setup ); #if DEBUG_FRAGS printf("Tri: %u frags emitted, %u written\n", setup->numFragsEmitted, setup->numFragsWritten); #endif }
/** * Render the upper or lower half of a triangle. * Scissoring/cliprect is applied here too. */ static void subtriangle(struct setup_context *setup, struct edge *eleft, struct edge *eright, int lines, unsigned viewport_index) { const struct pipe_scissor_state *cliprect = &setup->softpipe->cliprect[viewport_index]; const int minx = (int) cliprect->minx; const int maxx = (int) cliprect->maxx; const int miny = (int) cliprect->miny; const int maxy = (int) cliprect->maxy; int y, start_y, finish_y; int sy = (int)eleft->sy; assert((int)eleft->sy == (int) eright->sy); assert(lines >= 0); /* clip top/bottom */ start_y = sy; if (start_y < miny) start_y = miny; finish_y = sy + lines; if (finish_y > maxy) finish_y = maxy; start_y -= sy; finish_y -= sy; /* debug_printf("%s %d %d\n", __FUNCTION__, start_y, finish_y); */ for (y = start_y; y < finish_y; y++) { /* avoid accumulating adds as floats don't have the precision to * accurately iterate large triangle edges that way. luckily we * can just multiply these days. * * this is all drowned out by the attribute interpolation anyway. */ int left = (int)(eleft->sx + y * eleft->dxdy); int right = (int)(eright->sx + y * eright->dxdy); /* clip left/right */ if (left < minx) left = minx; if (right > maxx) right = maxx; if (left < right) { int _y = sy + y; if (block(_y) != setup->span.y) { flush_spans(setup); setup->span.y = block(_y); } setup->span.left[_y&1] = left; setup->span.right[_y&1] = right; } } /* save the values so that emaj can be restarted: */ eleft->sx += lines * eleft->dxdy; eright->sx += lines * eright->dxdy; eleft->sy += lines; eright->sy += lines; }
/** * Do setup for triangle rasterization, then render the triangle. */ void sp_setup_tri(struct setup_context *setup, const float (*v0)[4], const float (*v1)[4], const float (*v2)[4]) { float det; uint layer = 0; unsigned viewport_index = 0; #if DEBUG_VERTS debug_printf("Setup triangle:\n"); print_vertex(setup, v0); print_vertex(setup, v1); print_vertex(setup, v2); #endif if (setup->softpipe->no_rast || setup->softpipe->rasterizer->rasterizer_discard) return; det = calc_det(v0, v1, v2); /* debug_printf("%s\n", __FUNCTION__ ); */ #if DEBUG_FRAGS setup->numFragsEmitted = 0; setup->numFragsWritten = 0; #endif if (!setup_sort_vertices( setup, det, v0, v1, v2 )) return; setup_tri_coefficients( setup ); setup_tri_edges( setup ); assert(setup->softpipe->reduced_prim == PIPE_PRIM_TRIANGLES); setup->span.y = 0; setup->span.right[0] = 0; setup->span.right[1] = 0; /* setup->span.z_mode = tri_z_mode( setup->ctx ); */ if (setup->softpipe->layer_slot > 0) { layer = *(unsigned *)setup->vprovoke[setup->softpipe->layer_slot]; layer = MIN2(layer, setup->max_layer); } setup->quad[0].input.layer = layer; if (setup->softpipe->viewport_index_slot > 0) { unsigned *udata = (unsigned*)v0[setup->softpipe->viewport_index_slot]; viewport_index = sp_clamp_viewport_idx(*udata); } setup->quad[0].input.viewport_index = viewport_index; /* init_constant_attribs( setup ); */ if (setup->oneoverarea < 0.0) { /* emaj on left: */ subtriangle(setup, &setup->emaj, &setup->ebot, setup->ebot.lines, viewport_index); subtriangle(setup, &setup->emaj, &setup->etop, setup->etop.lines, viewport_index); } else { /* emaj on right: */ subtriangle(setup, &setup->ebot, &setup->emaj, setup->ebot.lines, viewport_index); subtriangle(setup, &setup->etop, &setup->emaj, setup->etop.lines, viewport_index); } flush_spans( setup ); if (setup->softpipe->active_statistics_queries) { setup->softpipe->pipeline_statistics.c_primitives++; } #if DEBUG_FRAGS printf("Tri: %u frags emitted, %u written\n", setup->numFragsEmitted, setup->numFragsWritten); #endif }