Go to the source code of this file.
Functions | |
void | setup_tri (struct setup_context *setup, const float(*v0)[4], const float(*v1)[4], const float(*v2)[4]) |
Do setup for triangle rasterization, then render the triangle. | |
void | setup_line (struct setup_context *setup, const float(*v0)[4], const float(*v1)[4]) |
Do setup for line rasterization, then render the line. | |
void | setup_point (struct setup_context *setup, const float(*v0)[4]) |
Do setup for point rasterization, then render the point. | |
struct setup_context * | setup_create_context (struct softpipe_context *softpipe) |
Create a new primitive setup/render stage. | |
void | setup_prepare (struct setup_context *setup) |
void | setup_destroy_context (struct setup_context *setup) |
struct setup_context* setup_create_context | ( | struct softpipe_context * | softpipe | ) | [read] |
Create a new primitive setup/render stage.
Definition at line 1538 of file sp_setup.c.
01540 { 01541 struct setup_context *setup = CALLOC_STRUCT(setup_context); 01542 #if SP_NUM_QUAD_THREADS > 1 01543 uint i; 01544 #endif 01545 01546 setup->softpipe = softpipe; 01547 01548 setup->quad.coef = setup->coef; 01549 setup->quad.posCoef = &setup->posCoef; 01550 01551 #if SP_NUM_QUAD_THREADS > 1 01552 setup->que.first = 0; 01553 setup->que.last = 0; 01554 pipe_mutex_init( setup->que.que_mutex ); 01555 pipe_condvar_init( setup->que.que_notfull_condvar ); 01556 pipe_condvar_init( setup->que.que_notempty_condvar ); 01557 setup->que.jobs_added = 0; 01558 setup->que.jobs_done = 0; 01559 pipe_condvar_init( setup->que.que_done_condvar ); 01560 for (i = 0; i < SP_NUM_QUAD_THREADS; i++) { 01561 setup->threads[i].setup = setup; 01562 setup->threads[i].id = i; 01563 setup->threads[i].handle = pipe_thread_create( quad_thread, &setup->threads[i] ); 01564 } 01565 #endif 01566 01567 return setup;
void setup_destroy_context | ( | struct setup_context * | setup | ) |
void setup_line | ( | struct setup_context * | setup, | |
const float * | v0[4], | |||
const float * | v1[4] | |||
) |
Do setup for line rasterization, then render the line.
Single-pixel width, no stipple, etc. We rely on the 'draw' module to handle stippling and wide lines.
Definition at line 1155 of file sp_setup.c.
References assert, CLIP_EMIT_QUAD, quad_header_input::coverage, debug_printf(), quad_header::inout, quad_header::input, quad_header_inout::mask, softpipe_context::no_rast, plot(), quad_header_input::prim, PRIM_LINE, setup_context::quad, setup_line_coefficients(), setup_context::softpipe, WAIT_FOR_COMPLETION, quad_header_input::x0, and quad_header_input::y0.
01159 { 01160 int x0 = (int) v0[0][0]; 01161 int x1 = (int) v1[0][0]; 01162 int y0 = (int) v0[0][1]; 01163 int y1 = (int) v1[0][1]; 01164 int dx = x1 - x0; 01165 int dy = y1 - y0; 01166 int xstep, ystep; 01167 01168 #if DEBUG_VERTS 01169 debug_printf("Setup line:\n"); 01170 print_vertex(setup, v0); 01171 print_vertex(setup, v1); 01172 #endif 01173 01174 if (setup->softpipe->no_rast) 01175 return; 01176 01177 if (dx == 0 && dy == 0) 01178 return; 01179 01180 if (!setup_line_coefficients(setup, v0, v1)) 01181 return; 01182 01183 assert(v0[0][0] < 1.0e9); 01184 assert(v0[0][1] < 1.0e9); 01185 assert(v1[0][0] < 1.0e9); 01186 assert(v1[0][1] < 1.0e9); 01187 01188 if (dx < 0) { 01189 dx = -dx; /* make positive */ 01190 xstep = -1; 01191 } 01192 else { 01193 xstep = 1; 01194 } 01195 01196 if (dy < 0) { 01197 dy = -dy; /* make positive */ 01198 ystep = -1; 01199 } 01200 else { 01201 ystep = 1; 01202 } 01203 01204 assert(dx >= 0); 01205 assert(dy >= 0); 01206 01207 setup->quad.input.x0 = setup->quad.input.y0 = -1; 01208 setup->quad.inout.mask = 0x0; 01209 setup->quad.input.prim = PRIM_LINE; 01210 /* XXX temporary: set coverage to 1.0 so the line appears 01211 * if AA mode happens to be enabled. 01212 */ 01213 setup->quad.input.coverage[0] = 01214 setup->quad.input.coverage[1] = 01215 setup->quad.input.coverage[2] = 01216 setup->quad.input.coverage[3] = 1.0; 01217 01218 if (dx > dy) { 01219 /*** X-major line ***/ 01220 int i; 01221 const int errorInc = dy + dy; 01222 int error = errorInc - dx; 01223 const int errorDec = error - dx; 01224 01225 for (i = 0; i < dx; i++) { 01226 plot(setup, x0, y0); 01227 01228 x0 += xstep; 01229 if (error < 0) { 01230 error += errorInc; 01231 } 01232 else { 01233 error += errorDec; 01234 y0 += ystep; 01235 } 01236 } 01237 } 01238 else { 01239 /*** Y-major line ***/ 01240 int i; 01241 const int errorInc = dx + dx; 01242 int error = errorInc - dy; 01243 const int errorDec = error - dy; 01244 01245 for (i = 0; i < dy; i++) { 01246 plot(setup, x0, y0); 01247 01248 y0 += ystep; 01249 if (error < 0) { 01250 error += errorInc; 01251 } 01252 else { 01253 error += errorDec; 01254 x0 += xstep; 01255 } 01256 } 01257 } 01258 01259 /* draw final quad */ 01260 if (setup->quad.inout.mask) { 01261 CLIP_EMIT_QUAD(setup); 01262 } 01263 01264 WAIT_FOR_COMPLETION(setup);
void setup_point | ( | struct setup_context * | setup, | |
const float * | v0[4] | |||
) |
Do setup for point rasterization, then render the point.
Round or square points... XXX could optimize a lot for 1-pixel points.
Definition at line 1286 of file sp_setup.c.
References tgsi_interp_coef::a0, assert, vertex_info::attrib, block(), CLIP_EMIT_QUAD, setup_context::coef, const_coeff(), quad_header_input::coverage, tgsi_interp_coef::dadx, tgsi_interp_coef::dady, debug_printf(), quad_header_input::facing, softpipe_context::fs, sp_fragment_shader::info, quad_header::inout, quad_header::input, tgsi_shader_info::input_semantic_name, INTERP_CONSTANT, INTERP_LINEAR, vertex_info::interp_mode, INTERP_PERSPECTIVE, INTERP_POS, quad_header_inout::mask, MASK_BOTTOM_LEFT, MASK_BOTTOM_RIGHT, MASK_TOP_LEFT, MASK_TOP_RIGHT, MAX2, MIN2, softpipe_context::no_rast, tgsi_shader_info::num_inputs, point_persp_coeff(), pipe_rasterizer_state::point_size, pipe_rasterizer_state::point_smooth, setup_context::posCoef, quad_header_input::prim, PRIM_POINT, softpipe_context::psize_slot, setup_context::quad, QUAD_BOTTOM_LEFT, QUAD_BOTTOM_RIGHT, QUAD_TOP_LEFT, QUAD_TOP_RIGHT, softpipe_context::rasterizer, setup_fragcoord_coeff(), setup_context::softpipe, softpipe_get_vertex_info(), vertex_info::src_index, TGSI_SEMANTIC_FOG, setup_context::vprovoke, WAIT_FOR_COMPLETION, quad_header_input::x0, and quad_header_input::y0.
01289 { 01290 struct softpipe_context *softpipe = setup->softpipe; 01291 const struct sp_fragment_shader *spfs = softpipe->fs; 01292 const int sizeAttr = setup->softpipe->psize_slot; 01293 const float size 01294 = sizeAttr > 0 ? v0[sizeAttr][0] 01295 : setup->softpipe->rasterizer->point_size; 01296 const float halfSize = 0.5F * size; 01297 const boolean round = (boolean) setup->softpipe->rasterizer->point_smooth; 01298 const float x = v0[0][0]; /* Note: data[0] is always position */ 01299 const float y = v0[0][1]; 01300 const struct vertex_info *vinfo = softpipe_get_vertex_info(softpipe); 01301 uint fragSlot; 01302 01303 #if DEBUG_VERTS 01304 debug_printf("Setup point:\n"); 01305 print_vertex(setup, v0); 01306 #endif 01307 01308 if (softpipe->no_rast) 01309 return; 01310 01311 /* For points, all interpolants are constant-valued. 01312 * However, for point sprites, we'll need to setup texcoords appropriately. 01313 * XXX: which coefficients are the texcoords??? 01314 * We may do point sprites as textured quads... 01315 * 01316 * KW: We don't know which coefficients are texcoords - ultimately 01317 * the choice of what interpolation mode to use for each attribute 01318 * should be determined by the fragment program, using 01319 * per-attribute declaration statements that include interpolation 01320 * mode as a parameter. So either the fragment program will have 01321 * to be adjusted for pointsprite vs normal point behaviour, or 01322 * otherwise a special interpolation mode will have to be defined 01323 * which matches the required behaviour for point sprites. But - 01324 * the latter is not a feature of normal hardware, and as such 01325 * probably should be ruled out on that basis. 01326 */ 01327 setup->vprovoke = v0; 01328 01329 /* setup Z, W */ 01330 const_coeff(setup, &setup->posCoef, 0, 2); 01331 const_coeff(setup, &setup->posCoef, 0, 3); 01332 01333 for (fragSlot = 0; fragSlot < spfs->info.num_inputs; fragSlot++) { 01334 const uint vertSlot = vinfo->attrib[fragSlot].src_index; 01335 uint j; 01336 01337 switch (vinfo->attrib[fragSlot].interp_mode) { 01338 case INTERP_CONSTANT: 01339 /* fall-through */ 01340 case INTERP_LINEAR: 01341 for (j = 0; j < NUM_CHANNELS; j++) 01342 const_coeff(setup, &setup->coef[fragSlot], vertSlot, j); 01343 break; 01344 case INTERP_PERSPECTIVE: 01345 for (j = 0; j < NUM_CHANNELS; j++) 01346 point_persp_coeff(setup, setup->vprovoke, 01347 &setup->coef[fragSlot], vertSlot, j); 01348 break; 01349 case INTERP_POS: 01350 setup_fragcoord_coeff(setup, fragSlot); 01351 break; 01352 default: 01353 assert(0); 01354 } 01355 01356 if (spfs->info.input_semantic_name[fragSlot] == TGSI_SEMANTIC_FOG) { 01357 /* FOG.y = front/back facing XXX fix this */ 01358 setup->coef[fragSlot].a0[1] = 1.0f - setup->quad.input.facing; 01359 setup->coef[fragSlot].dadx[1] = 0.0; 01360 setup->coef[fragSlot].dady[1] = 0.0; 01361 } 01362 } 01363 01364 setup->quad.input.prim = PRIM_POINT; 01365 01366 if (halfSize <= 0.5 && !round) { 01367 /* special case for 1-pixel points */ 01368 const int ix = ((int) x) & 1; 01369 const int iy = ((int) y) & 1; 01370 setup->quad.input.x0 = (int) x - ix; 01371 setup->quad.input.y0 = (int) y - iy; 01372 setup->quad.inout.mask = (1 << ix) << (2 * iy); 01373 CLIP_EMIT_QUAD(setup); 01374 } 01375 else { 01376 if (round) { 01377 /* rounded points */ 01378 const int ixmin = block((int) (x - halfSize)); 01379 const int ixmax = block((int) (x + halfSize)); 01380 const int iymin = block((int) (y - halfSize)); 01381 const int iymax = block((int) (y + halfSize)); 01382 const float rmin = halfSize - 0.7071F; /* 0.7071 = sqrt(2)/2 */ 01383 const float rmax = halfSize + 0.7071F; 01384 const float rmin2 = MAX2(0.0F, rmin * rmin); 01385 const float rmax2 = rmax * rmax; 01386 const float cscale = 1.0F / (rmax2 - rmin2); 01387 int ix, iy; 01388 01389 for (iy = iymin; iy <= iymax; iy += 2) { 01390 for (ix = ixmin; ix <= ixmax; ix += 2) { 01391 float dx, dy, dist2, cover; 01392 01393 setup->quad.inout.mask = 0x0; 01394 01395 dx = (ix + 0.5f) - x; 01396 dy = (iy + 0.5f) - y; 01397 dist2 = dx * dx + dy * dy; 01398 if (dist2 <= rmax2) { 01399 cover = 1.0F - (dist2 - rmin2) * cscale; 01400 setup->quad.input.coverage[QUAD_TOP_LEFT] = MIN2(cover, 1.0f); 01401 setup->quad.inout.mask |= MASK_TOP_LEFT; 01402 } 01403 01404 dx = (ix + 1.5f) - x; 01405 dy = (iy + 0.5f) - y; 01406 dist2 = dx * dx + dy * dy; 01407 if (dist2 <= rmax2) { 01408 cover = 1.0F - (dist2 - rmin2) * cscale; 01409 setup->quad.input.coverage[QUAD_TOP_RIGHT] = MIN2(cover, 1.0f); 01410 setup->quad.inout.mask |= MASK_TOP_RIGHT; 01411 } 01412 01413 dx = (ix + 0.5f) - x; 01414 dy = (iy + 1.5f) - y; 01415 dist2 = dx * dx + dy * dy; 01416 if (dist2 <= rmax2) { 01417 cover = 1.0F - (dist2 - rmin2) * cscale; 01418 setup->quad.input.coverage[QUAD_BOTTOM_LEFT] = MIN2(cover, 1.0f); 01419 setup->quad.inout.mask |= MASK_BOTTOM_LEFT; 01420 } 01421 01422 dx = (ix + 1.5f) - x; 01423 dy = (iy + 1.5f) - y; 01424 dist2 = dx * dx + dy * dy; 01425 if (dist2 <= rmax2) { 01426 cover = 1.0F - (dist2 - rmin2) * cscale; 01427 setup->quad.input.coverage[QUAD_BOTTOM_RIGHT] = MIN2(cover, 1.0f); 01428 setup->quad.inout.mask |= MASK_BOTTOM_RIGHT; 01429 } 01430 01431 if (setup->quad.inout.mask) { 01432 setup->quad.input.x0 = ix; 01433 setup->quad.input.y0 = iy; 01434 CLIP_EMIT_QUAD(setup); 01435 } 01436 } 01437 } 01438 } 01439 else { 01440 /* square points */ 01441 const int xmin = (int) (x + 0.75 - halfSize); 01442 const int ymin = (int) (y + 0.25 - halfSize); 01443 const int xmax = xmin + (int) size; 01444 const int ymax = ymin + (int) size; 01445 /* XXX could apply scissor to xmin,ymin,xmax,ymax now */ 01446 const int ixmin = block(xmin); 01447 const int ixmax = block(xmax - 1); 01448 const int iymin = block(ymin); 01449 const int iymax = block(ymax - 1); 01450 int ix, iy; 01451 01452 /* 01453 debug_printf("(%f, %f) -> X:%d..%d Y:%d..%d\n", x, y, xmin, xmax,ymin,ymax); 01454 */ 01455 for (iy = iymin; iy <= iymax; iy += 2) { 01456 uint rowMask = 0xf; 01457 if (iy < ymin) { 01458 /* above the top edge */ 01459 rowMask &= (MASK_BOTTOM_LEFT | MASK_BOTTOM_RIGHT); 01460 } 01461 if (iy + 1 >= ymax) { 01462 /* below the bottom edge */ 01463 rowMask &= (MASK_TOP_LEFT | MASK_TOP_RIGHT); 01464 } 01465 01466 for (ix = ixmin; ix <= ixmax; ix += 2) { 01467 uint mask = rowMask; 01468 01469 if (ix < xmin) { 01470 /* fragment is past left edge of point, turn off left bits */ 01471 mask &= (MASK_BOTTOM_RIGHT | MASK_TOP_RIGHT); 01472 } 01473 if (ix + 1 >= xmax) { 01474 /* past the right edge */ 01475 mask &= (MASK_BOTTOM_LEFT | MASK_TOP_LEFT); 01476 } 01477 01478 setup->quad.inout.mask = mask; 01479 setup->quad.input.x0 = ix; 01480 setup->quad.input.y0 = iy; 01481 CLIP_EMIT_QUAD(setup); 01482 } 01483 } 01484 } 01485 } 01486 01487 WAIT_FOR_COMPLETION(setup);
void setup_prepare | ( | struct setup_context * | setup | ) |
Definition at line 1489 of file sp_setup.c.
References quad_stage::begin, pipe_framebuffer_state::cbufs, pipe_rasterizer_state::cull_mode, softpipe_context::dirty, softpipe_context::draw, draw_num_vs_outputs(), pipe_rasterizer_state::fill_ccw, pipe_rasterizer_state::fill_cw, softpipe_context::first, softpipe_context::framebuffer, quad_header::nr_attrs, pipe_framebuffer_state::num_cbufs, PIPE_POLYGON_MODE_FILL, PIPE_PRIM_TRIANGLES, PIPE_SURFACE_STATUS_DEFINED, PIPE_WINDING_NONE, softpipe_context::quad, setup_context::quad, softpipe_context::rasterizer, softpipe_context::reduced_api_prim, setup_context::softpipe, softpipe_update_derived(), SP_NUM_QUAD_THREADS, pipe_surface::status, setup_context::winding, and pipe_framebuffer_state::zsbuf.
01491 { 01492 struct softpipe_context *sp = setup->softpipe; 01493 unsigned i; 01494 01495 if (sp->dirty) { 01496 softpipe_update_derived(sp); 01497 } 01498 01499 /* Mark surfaces as defined now */ 01500 for (i = 0; i < sp->framebuffer.num_cbufs; i++){ 01501 if (sp->framebuffer.cbufs[i]) { 01502 sp->framebuffer.cbufs[i]->status = PIPE_SURFACE_STATUS_DEFINED; 01503 } 01504 } 01505 if (sp->framebuffer.zsbuf) { 01506 sp->framebuffer.zsbuf->status = PIPE_SURFACE_STATUS_DEFINED; 01507 } 01508 01509 /* Note: nr_attrs is only used for debugging (vertex printing) */ 01510 setup->quad.nr_attrs = draw_num_vs_outputs(sp->draw); 01511 01512 for (i = 0; i < SP_NUM_QUAD_THREADS; i++) { 01513 sp->quad[i].first->begin( sp->quad[i].first ); 01514 } 01515 01516 if (sp->reduced_api_prim == PIPE_PRIM_TRIANGLES && 01517 sp->rasterizer->fill_cw == PIPE_POLYGON_MODE_FILL && 01518 sp->rasterizer->fill_ccw == PIPE_POLYGON_MODE_FILL) { 01519 /* we'll do culling */ 01520 setup->winding = sp->rasterizer->cull_mode; 01521 } 01522 else { 01523 /* 'draw' will do culling */ 01524 setup->winding = PIPE_WINDING_NONE; 01525 }
void setup_tri | ( | struct setup_context * | setup, | |
const float * | v0[4], | |||
const float * | v1[4], | |||
const float * | v2[4] | |||
) |
Do setup for triangle rasterization, then render the triangle.
Definition at line 935 of file sp_setup.c.
00940 { 00941 float det; 00942 00943 #if DEBUG_VERTS 00944 debug_printf("Setup triangle:\n"); 00945 print_vertex(setup, v0); 00946 print_vertex(setup, v1); 00947 print_vertex(setup, v2); 00948 #endif 00949 00950 if (setup->softpipe->no_rast) 00951 return; 00952 00953 det = calc_det(v0, v1, v2); 00954 /* 00955 debug_printf("%s\n", __FUNCTION__ ); 00956 */ 00957 00958 #if DEBUG_FRAGS 00959 setup->numFragsEmitted = 0; 00960 setup->numFragsWritten = 0; 00961 #endif 00962 00963 if (cull_tri( setup, det )) 00964 return; 00965 00966 if (!setup_sort_vertices( setup, det, v0, v1, v2 )) 00967 return; 00968 setup_tri_coefficients( setup ); 00969 setup_tri_edges( setup ); 00970 00971 setup->quad.input.prim = PRIM_TRI; 00972 00973 setup->span.y = 0; 00974 setup->span.y_flags = 0; 00975 setup->span.right[0] = 0; 00976 setup->span.right[1] = 0; 00977 /* setup->span.z_mode = tri_z_mode( setup->ctx ); */ 00978 00979 /* init_constant_attribs( setup ); */ 00980 00981 if (setup->oneoverarea < 0.0) { 00982 /* emaj on left: 00983 */ 00984 subtriangle( setup, &setup->emaj, &setup->ebot, setup->ebot.lines ); 00985 subtriangle( setup, &setup->emaj, &setup->etop, setup->etop.lines ); 00986 } 00987 else { 00988 /* emaj on right: 00989 */ 00990 subtriangle( setup, &setup->ebot, &setup->emaj, setup->ebot.lines ); 00991 subtriangle( setup, &setup->etop, &setup->emaj, setup->etop.lines ); 00992 } 00993 00994 flush_spans( setup ); 00995 00996 WAIT_FOR_COMPLETION(setup); 00997 00998 #if DEBUG_FRAGS 00999 printf("Tri: %u frags emitted, %u written\n", 01000 setup->numFragsEmitted, 01001 setup->numFragsWritten); 01002 #endif