spu_render.h File Reference

Include dependency graph for spu_render.h:

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

Go to the source code of this file.

Functions

void cmd_render (const struct cell_command_render *render, uint *pos_incr)
 Render primitives.


Function Documentation

void cmd_render ( const struct cell_command_render render,
uint pos_incr 
)

Render primitives.

Parameters:
pos_incr returns value indicating how may words to skip after this command in the batch buffer

find tiles which intersect the prim bounding box

loop over tiles, rendering tris

Definition at line 168 of file spu_render.c.

References ALIGN16_ATTRIB, align_pointer(), ASSERT, ASSERT_ALIGN16, cell_init_info::buffers, CELL_BUFFER_SIZE, spu_global::cur_ctile_status, spu_global::cur_ztile_status, Debug, spu_global::fb, get_cz_tiles(), spu_framebuffer::height_tiles, cell_init_info::id, spu_global::init, cell_command_render::inline_verts, cell_command_render::min_index, my_tile(), cell_command_render::num_indexes, cell_command_render::num_verts, PIPE_PRIM_TRIANGLES, cell_command_render::prim_type, put_cz_tiles(), ROUNDUP8, spu, TAG_SURFACE_CLEAR, TAG_VERTEX_BUFFER, tile_bounding_box(), tri_draw(), cell_command_render::vertex_buf, cell_command_render::vertex_size, wait_on_mask(), wait_put_cz_tiles(), and spu_framebuffer::width_tiles.

00169 {
00170    /* we'll DMA into these buffers */
00171    ubyte vertex_data[CELL_BUFFER_SIZE] ALIGN16_ATTRIB;
00172    const uint vertex_size = render->vertex_size; /* in bytes */
00173    /*const*/ uint total_vertex_bytes = render->num_verts * vertex_size;
00174    uint index_bytes;
00175    const ubyte *vertices;
00176    const ushort *indexes;
00177    uint i, j;
00178 
00179 
00180    if (Debug) {
00181       printf("SPU %u: RENDER prim %u, num_vert=%u  num_ind=%u  "
00182              "inline_vert=%u\n",
00183              spu.init.id,
00184              render->prim_type,
00185              render->num_verts,
00186              render->num_indexes,
00187              render->inline_verts);
00188 
00189       /*
00190       printf("       bound: %g, %g .. %g, %g\n",
00191              render->xmin, render->ymin, render->xmax, render->ymax);
00192       */
00193    }
00194 
00195    ASSERT(sizeof(*render) % 4 == 0);
00196    ASSERT(total_vertex_bytes % 16 == 0);
00197    ASSERT(render->prim_type == PIPE_PRIM_TRIANGLES);
00198    ASSERT(render->num_indexes % 3 == 0);
00199 
00200 
00201    /* indexes are right after the render command in the batch buffer */
00202    indexes = (const ushort *) (render + 1);
00203    index_bytes = ROUNDUP8(render->num_indexes * 2);
00204    *pos_incr = index_bytes / 8 + sizeof(*render) / 8;
00205 
00206 
00207    if (render->inline_verts) {
00208       /* Vertices are after indexes in batch buffer at next 16-byte addr */
00209       vertices = (const ubyte *) render + (*pos_incr * 8);
00210       vertices = (const ubyte *) align_pointer((void *) vertices, 16);
00211       ASSERT_ALIGN16(vertices);
00212       *pos_incr = ((vertices + total_vertex_bytes) - (ubyte *) render) / 8;
00213    }
00214    else {
00215       /* Begin DMA fetch of vertex buffer */
00216       ubyte *src = spu.init.buffers[render->vertex_buf];
00217       ubyte *dest = vertex_data;
00218 
00219       /* skip vertex data we won't use */
00220 #if 01
00221       src += render->min_index * vertex_size;
00222       dest += render->min_index * vertex_size;
00223       total_vertex_bytes -= render->min_index * vertex_size;
00224 #endif
00225       ASSERT(total_vertex_bytes % 16 == 0);
00226       ASSERT_ALIGN16(dest);
00227       ASSERT_ALIGN16(src);
00228 
00229       mfc_get(dest,   /* in vertex_data[] array */
00230               (unsigned int) src,  /* src in main memory */
00231               total_vertex_bytes,  /* size */
00232               TAG_VERTEX_BUFFER,
00233               0, /* tid */
00234               0  /* rid */);
00235 
00236       vertices = vertex_data;
00237 
00238       wait_on_mask(1 << TAG_VERTEX_BUFFER);
00239    }
00240 
00241 
00245    uint txmin, tymin, box_width_tiles, box_num_tiles;
00246    tile_bounding_box(render, &txmin, &tymin,
00247                      &box_num_tiles, &box_width_tiles);
00248 
00249 
00250    /* make sure any pending clears have completed */
00251    wait_on_mask(1 << TAG_SURFACE_CLEAR); /* XXX temporary */
00252 
00253 
00257    for (i = 0; i < box_num_tiles; i++) {
00258       const uint tx = txmin + i % box_width_tiles;
00259       const uint ty = tymin + i / box_width_tiles;
00260 
00261       ASSERT(tx < spu.fb.width_tiles);
00262       ASSERT(ty < spu.fb.height_tiles);
00263 
00264       if (!my_tile(tx, ty))
00265          continue;
00266 
00267       spu.cur_ctile_status = spu.ctile_status[ty][tx];
00268       spu.cur_ztile_status = spu.ztile_status[ty][tx];
00269 
00270       get_cz_tiles(tx, ty);
00271 
00272       uint drawn = 0;
00273 
00274       /* loop over tris */
00275       for (j = 0; j < render->num_indexes; j += 3) {
00276          const float *v0, *v1, *v2;
00277 
00278          v0 = (const float *) (vertices + indexes[j+0] * vertex_size);
00279          v1 = (const float *) (vertices + indexes[j+1] * vertex_size);
00280          v2 = (const float *) (vertices + indexes[j+2] * vertex_size);
00281 
00282          drawn += tri_draw(v0, v1, v2, tx, ty);
00283       }
00284 
00285       //printf("SPU %u: drew %u of %u\n", spu.init.id, drawn, render->num_indexes/3);
00286 
00287       /* write color/z tiles back to main framebuffer, if dirtied */
00288       put_cz_tiles(tx, ty);
00289 
00290       wait_put_cz_tiles(); /* XXX seems unnecessary... */
00291 
00292       spu.ctile_status[ty][tx] = spu.cur_ctile_status;
00293       spu.ztile_status[ty][tx] = spu.cur_ztile_status;
00294    }
00295 
00296    if (Debug)
00297       printf("SPU %u: RENDER done\n",
00298              spu.init.id);
00299 }


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