sp_setup.h File Reference

This graph shows which files directly or indirectly include this file:

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_contextsetup_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)


Function Documentation

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  ) 

Definition at line 1529 of file sp_setup.c.

References FREE.

01531 {
01532    FREE( 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


Generated on Tue Sep 29 06:25:41 2009 for Gallium3D by  doxygen 1.5.4