Go to the source code of this file.
Data Structures | |
struct | cell_vbuf_render |
Subclass of vbuf_render because we need a cell_context pointer in a few places. More... | |
Defines | |
#define | ALLOW_INLINE_VERTS 1 |
Vertex buffer code. | |
Functions | |
static struct cell_vbuf_render * | cell_vbuf_render (struct vbuf_render *vbr) |
cast wrapper | |
static struct vertex_info * | cell_vbuf_get_vertex_info (struct vbuf_render *vbr) |
static void * | cell_vbuf_allocate_vertices (struct vbuf_render *vbr, ushort vertex_size, ushort nr_vertices) |
static void | cell_vbuf_release_vertices (struct vbuf_render *vbr, void *vertices, unsigned vertex_size, unsigned vertices_used) |
static boolean | cell_vbuf_set_primitive (struct vbuf_render *vbr, unsigned prim) |
static void | cell_vbuf_draw (struct vbuf_render *vbr, const ushort *indices, uint nr_indices) |
static void | cell_vbuf_destroy (struct vbuf_render *vbr) |
void | cell_init_vbuf (struct cell_context *cell) |
Initialize the post-transform vertex buffer information for the given context. |
#define ALLOW_INLINE_VERTS 1 |
Vertex buffer code.
The draw module transforms vertices to window coords, etc. and emits the vertices into buffer supplied by this module. When a vertex buffer is full, or we flush, we'll send the vertex data to the SPUs.
Authors Brian Paul Allow vertex data to be inlined after RENDER command
Definition at line 49 of file cell_vbuf.c.
void cell_init_vbuf | ( | struct cell_context * | cell | ) |
Initialize the post-transform vertex buffer information for the given context.
Definition at line 272 of file cell_vbuf.c.
References vbuf_render::allocate_vertices, assert, cell_vbuf_render::base, CALLOC_STRUCT, cell_vbuf_render::cell, CELL_BUFFER_SIZE, cell_vbuf_allocate_vertices(), cell_vbuf_destroy(), cell_vbuf_draw(), cell_vbuf_get_vertex_info(), cell_vbuf_release_vertices(), cell_vbuf_set_primitive(), vbuf_render::destroy, vbuf_render::draw, cell_context::draw, draw_vbuf_stage(), vbuf_render::get_vertex_info, vbuf_render::max_indices, vbuf_render::max_vertex_buffer_bytes, vbuf_render::release_vertices, vbuf_render::set_primitive, cell_context::vbuf, cell_context::vbuf_render, and cell_vbuf_render::vertex_buf.
00273 { 00274 assert(cell->draw); 00275 00276 cell->vbuf_render = CALLOC_STRUCT(cell_vbuf_render); 00277 00278 /* The max number of indexes is what can fix into a batch buffer, 00279 * minus the render and release-verts commands. 00280 */ 00281 cell->vbuf_render->base.max_indices 00282 = (CELL_BUFFER_SIZE 00283 - sizeof(struct cell_command_render) 00284 - sizeof(struct cell_command_release_verts)) 00285 / sizeof(ushort); 00286 cell->vbuf_render->base.max_vertex_buffer_bytes = CELL_BUFFER_SIZE; 00287 00288 cell->vbuf_render->base.get_vertex_info = cell_vbuf_get_vertex_info; 00289 cell->vbuf_render->base.allocate_vertices = cell_vbuf_allocate_vertices; 00290 cell->vbuf_render->base.set_primitive = cell_vbuf_set_primitive; 00291 cell->vbuf_render->base.draw = cell_vbuf_draw; 00292 cell->vbuf_render->base.release_vertices = cell_vbuf_release_vertices; 00293 cell->vbuf_render->base.destroy = cell_vbuf_destroy; 00294 00295 cell->vbuf_render->cell = cell; 00296 #if 1 00297 cell->vbuf_render->vertex_buf = ~0; 00298 #endif 00299 00300 cell->vbuf = draw_vbuf_stage(cell->draw, &cell->vbuf_render->base); 00301 }
static void* cell_vbuf_allocate_vertices | ( | struct vbuf_render * | vbr, | |
ushort | vertex_size, | |||
ushort | nr_vertices | |||
) | [static] |
Definition at line 85 of file cell_vbuf.c.
References assert, cell_vbuf_render::cell, cell_get_empty_buffer(), cell_vbuf_render(), cell_vbuf_render::vertex_buf, cell_vbuf_render::vertex_buffer, and cell_vbuf_render::vertex_size.
00087 { 00088 struct cell_vbuf_render *cvbr = cell_vbuf_render(vbr); 00089 /*printf("Alloc verts %u * %u\n", vertex_size, nr_vertices);*/ 00090 00091 assert(cvbr->vertex_buf == ~0); 00092 cvbr->vertex_buf = cell_get_empty_buffer(cvbr->cell); 00093 cvbr->vertex_buffer = cvbr->cell->buffer[cvbr->vertex_buf]; 00094 cvbr->vertex_size = vertex_size; 00095 return cvbr->vertex_buffer; 00096 }
static void cell_vbuf_destroy | ( | struct vbuf_render * | vbr | ) | [static] |
Definition at line 259 of file cell_vbuf.c.
References cell_vbuf_render::cell, cell_vbuf_render(), FREE, and cell_context::vbuf_render.
00260 { 00261 struct cell_vbuf_render *cvbr = cell_vbuf_render(vbr); 00262 cvbr->cell->vbuf_render = NULL; 00263 FREE(cvbr); 00264 }
static void cell_vbuf_draw | ( | struct vbuf_render * | vbr, | |
const ushort * | indices, | |||
uint | nr_indices | |||
) | [static] |
Definition at line 140 of file cell_vbuf.c.
References ALLOW_INLINE_VERTS, ASSERT, cell_vbuf_render::cell, cell_batch_alloc(), cell_batch_alloc_aligned(), cell_batch_free_space(), CELL_CMD_RENDER, cell_flush_int(), CELL_FLUSH_WAIT, cell_vbuf_render(), FALSE, cell_command_render::inline_verts, cell_command_render::min_index, cell_command_render::num_indexes, cell_command_render::num_verts, cell_command_render::opcode, PIPE_PRIM_TRIANGLES, cell_vbuf_render::prim, cell_command_render::prim_type, ROUNDUP8, vertex_info::size, TRUE, cell_vbuf_render::vertex_buf, cell_command_render::vertex_buf, cell_vbuf_render::vertex_buffer, cell_context::vertex_info, cell_command_render::vertex_size, cell_vbuf_render::vertex_size, cell_command_render::xmax, cell_command_render::xmin, cell_command_render::ymax, and cell_command_render::ymin.
00143 { 00144 struct cell_vbuf_render *cvbr = cell_vbuf_render(vbr); 00145 struct cell_context *cell = cvbr->cell; 00146 float xmin, ymin, xmax, ymax; 00147 uint i; 00148 uint nr_vertices = 0, min_index = ~0; 00149 const void *vertices = cvbr->vertex_buffer; 00150 const uint vertex_size = cvbr->vertex_size; 00151 00152 for (i = 0; i < nr_indices; i++) { 00153 if (indices[i] > nr_vertices) 00154 nr_vertices = indices[i]; 00155 if (indices[i] < min_index) 00156 min_index = indices[i]; 00157 } 00158 nr_vertices++; 00159 00160 #if 0 00161 /*if (min_index > 0)*/ 00162 printf("%s min_index = %u\n", __FUNCTION__, min_index); 00163 #endif 00164 00165 #if 0 00166 printf("cell_vbuf_draw() nr_indices = %u nr_verts = %u\n", 00167 nr_indices, nr_vertices); 00168 printf(" "); 00169 for (i = 0; i < nr_indices; i += 3) { 00170 printf("%u %u %u, ", indices[i+0], indices[i+1], indices[i+2]); 00171 } 00172 printf("\n"); 00173 #elif 0 00174 printf("cell_vbuf_draw() nr_indices = %u nr_verts = %u indexes = [%u %u %u ...]\n", 00175 nr_indices, nr_vertices, 00176 indices[0], indices[1], indices[2]); 00177 printf("ind space = %u, vert space = %u, space = %u\n", 00178 nr_indices * 2, 00179 nr_vertices * 4 * cell->vertex_info.size, 00180 cell_batch_free_space(cell)); 00181 #endif 00182 00183 /* compute x/y bounding box */ 00184 xmin = ymin = 1e50; 00185 xmax = ymax = -1e50; 00186 for (i = min_index; i < nr_vertices; i++) { 00187 const float *v = (float *) ((ubyte *) vertices + i * vertex_size); 00188 if (v[0] < xmin) 00189 xmin = v[0]; 00190 if (v[0] > xmax) 00191 xmax = v[0]; 00192 if (v[1] < ymin) 00193 ymin = v[1]; 00194 if (v[1] > ymax) 00195 ymax = v[1]; 00196 } 00197 #if 0 00198 printf("PPU Bounds %g, %g .. %g, %g\n", xmin, ymin, xmax, ymax); 00199 fflush(stdout); 00200 #endif 00201 00202 if (cvbr->prim != PIPE_PRIM_TRIANGLES) 00203 return; /* only render tris for now */ 00204 00205 /* build/insert batch RENDER command */ 00206 { 00207 const uint index_bytes = ROUNDUP8(nr_indices * 2); 00208 const uint vertex_bytes = nr_vertices * 4 * cell->vertex_info.size; 00209 const uint batch_size = sizeof(struct cell_command_render) + index_bytes; 00210 00211 struct cell_command_render *render 00212 = (struct cell_command_render *) 00213 cell_batch_alloc(cell, batch_size); 00214 00215 render->opcode = CELL_CMD_RENDER; 00216 render->prim_type = cvbr->prim; 00217 00218 render->num_indexes = nr_indices; 00219 render->min_index = min_index; 00220 00221 /* append indices after render command */ 00222 memcpy(render + 1, indices, nr_indices * 2); 00223 00224 /* if there's room, append vertices after the indices, else leave 00225 * vertices in the original/separate buffer. 00226 */ 00227 render->vertex_size = 4 * cell->vertex_info.size; 00228 render->num_verts = nr_vertices; 00229 if (ALLOW_INLINE_VERTS && 00230 min_index == 0 && 00231 vertex_bytes + 16 <= cell_batch_free_space(cell)) { 00232 /* vertex data inlined, after indices, at 16-byte boundary */ 00233 void *dst = cell_batch_alloc_aligned(cell, vertex_bytes, 16); 00234 memcpy(dst, vertices, vertex_bytes); 00235 render->inline_verts = TRUE; 00236 render->vertex_buf = ~0; 00237 } 00238 else { 00239 /* vertex data in separate buffer */ 00240 render->inline_verts = FALSE; 00241 ASSERT(cvbr->vertex_buf >= 0); 00242 render->vertex_buf = cvbr->vertex_buf; 00243 } 00244 00245 render->xmin = xmin; 00246 render->ymin = ymin; 00247 render->xmax = xmax; 00248 render->ymax = ymax; 00249 } 00250 00251 #if 0 00252 /* helpful for debug */ 00253 cell_flush_int(cell, CELL_FLUSH_WAIT); 00254 #endif 00255 }
static struct vertex_info* cell_vbuf_get_vertex_info | ( | struct vbuf_render * | vbr | ) | [static, read] |
Definition at line 77 of file cell_vbuf.c.
References cell_vbuf_render::cell, cell_vbuf_render(), and cell_context::vertex_info.
00078 { 00079 struct cell_vbuf_render *cvbr = cell_vbuf_render(vbr); 00080 return &cvbr->cell->vertex_info; 00081 }
static void cell_vbuf_release_vertices | ( | struct vbuf_render * | vbr, | |
void * | vertices, | |||
unsigned | vertex_size, | |||
unsigned | vertices_used | |||
) | [static] |
Definition at line 100 of file cell_vbuf.c.
References assert, cell_vbuf_render::cell, cell_batch_alloc(), CELL_CMD_RELEASE_VERTS, cell_flush_int(), cell_vbuf_render(), cell_command_release_verts::opcode, cell_command_release_verts::vertex_buf, cell_vbuf_render::vertex_buf, and cell_vbuf_render::vertex_buffer.
00102 { 00103 struct cell_vbuf_render *cvbr = cell_vbuf_render(vbr); 00104 struct cell_context *cell = cvbr->cell; 00105 00106 /* 00107 printf("%s vertex_buf = %u count = %u\n", 00108 __FUNCTION__, cvbr->vertex_buf, vertices_used); 00109 */ 00110 00111 /* Tell SPUs they can release the vert buf */ 00112 if (cvbr->vertex_buf != ~0U) { 00113 struct cell_command_release_verts *release 00114 = (struct cell_command_release_verts *) 00115 cell_batch_alloc(cell, sizeof(struct cell_command_release_verts)); 00116 release->opcode = CELL_CMD_RELEASE_VERTS; 00117 release->vertex_buf = cvbr->vertex_buf; 00118 } 00119 00120 cvbr->vertex_buf = ~0; 00121 cell_flush_int(cell, 0x0); 00122 00123 assert(vertices == cvbr->vertex_buffer); 00124 cvbr->vertex_buffer = NULL; 00125 }
static struct cell_vbuf_render* cell_vbuf_render | ( | struct vbuf_render * | vbr | ) | [static, read] |
cast wrapper
Definition at line 69 of file cell_vbuf.c.
00070 { 00071 return (struct cell_vbuf_render *) vbr; 00072 }
static boolean cell_vbuf_set_primitive | ( | struct vbuf_render * | vbr, | |
unsigned | prim | |||
) | [static] |
Definition at line 130 of file cell_vbuf.c.
References cell_vbuf_render(), cell_vbuf_render::prim, and TRUE.
00131 { 00132 struct cell_vbuf_render *cvbr = cell_vbuf_render(vbr); 00133 cvbr->prim = prim; 00134 /*printf("cell_set_prim %u\n", prim);*/ 00135 return TRUE; 00136 }