Go to the source code of this file.
Data Structures | |
struct | vbuf_stage |
Vertex buffer emit stage. More... | |
Functions | |
static struct vbuf_stage * | vbuf_stage (struct draw_stage *stage) |
Basically a cast wrapper. | |
static void | vbuf_flush_indices (struct vbuf_stage *vbuf) |
static void | vbuf_flush_vertices (struct vbuf_stage *vbuf) |
Flush existing vertex buffer and allocate a new one. | |
static void | vbuf_alloc_vertices (struct vbuf_stage *vbuf) |
static boolean | overflow (void *map, void *ptr, unsigned bytes, unsigned bufsz) |
static void | check_space (struct vbuf_stage *vbuf, unsigned nr) |
static ushort | emit_vertex (struct vbuf_stage *vbuf, struct vertex_header *vertex) |
Extract the needed fields from post-transformed vertex and emit a hardware(driver) vertex. | |
static void | vbuf_tri (struct draw_stage *stage, struct prim_header *prim) |
static void | vbuf_line (struct draw_stage *stage, struct prim_header *prim) |
static void | vbuf_point (struct draw_stage *stage, struct prim_header *prim) |
static void | vbuf_set_prim (struct vbuf_stage *vbuf, uint prim) |
Set the prim type for subsequent vertices. | |
static void | vbuf_first_tri (struct draw_stage *stage, struct prim_header *prim) |
static void | vbuf_first_line (struct draw_stage *stage, struct prim_header *prim) |
static void | vbuf_first_point (struct draw_stage *stage, struct prim_header *prim) |
static void | vbuf_flush (struct draw_stage *stage, unsigned flags) |
static void | vbuf_reset_stipple_counter (struct draw_stage *stage) |
static void | vbuf_destroy (struct draw_stage *stage) |
struct draw_stage * | draw_vbuf_stage (struct draw_context *draw, struct vbuf_render *render) |
Create a new primitive vbuf/render stage. |
Definition in file draw_pipe_vbuf.c.
static void check_space | ( | struct vbuf_stage * | vbuf, | |
unsigned | nr | |||
) | [static] |
Definition at line 110 of file draw_pipe_vbuf.c.
References vbuf_stage::max_indices, vbuf_stage::max_vertices, vbuf_stage::nr_indices, vbuf_stage::nr_vertices, vbuf_alloc_vertices(), vbuf_flush_indices(), and vbuf_flush_vertices().
00111 { 00112 if (vbuf->nr_vertices + nr > vbuf->max_vertices ) { 00113 vbuf_flush_vertices(vbuf); 00114 vbuf_alloc_vertices(vbuf); 00115 } 00116 00117 if (vbuf->nr_indices + nr > vbuf->max_indices ) 00118 vbuf_flush_indices(vbuf); 00119 }
struct draw_stage* draw_vbuf_stage | ( | struct draw_context * | draw, | |
struct vbuf_render * | render | |||
) | [read] |
Create a new primitive vbuf/render stage.
Definition at line 455 of file draw_pipe_vbuf.c.
References align_malloc(), vbuf_stage::cache, CALLOC_STRUCT, draw_stage::destroy, draw_stage::draw, draw_stage::flush, vbuf_stage::indices, draw_stage::line, MAX2, vbuf_render::max_indices, vbuf_stage::max_indices, draw_stage::point, vbuf_stage::render, draw_stage::reset_stipple_counter, vbuf_stage::stage, translate_cache_create(), draw_stage::tri, UNDEFINED_VERTEX_ID, vbuf_destroy(), vbuf_first_line(), vbuf_first_point(), vbuf_first_tri(), vbuf_flush(), vbuf_reset_stipple_counter(), vbuf_stage::vertex_ptr, and vbuf_stage::vertices.
00457 { 00458 struct vbuf_stage *vbuf = CALLOC_STRUCT(vbuf_stage); 00459 if (vbuf == NULL) 00460 goto fail; 00461 00462 vbuf->stage.draw = draw; 00463 vbuf->stage.point = vbuf_first_point; 00464 vbuf->stage.line = vbuf_first_line; 00465 vbuf->stage.tri = vbuf_first_tri; 00466 vbuf->stage.flush = vbuf_flush; 00467 vbuf->stage.reset_stipple_counter = vbuf_reset_stipple_counter; 00468 vbuf->stage.destroy = vbuf_destroy; 00469 00470 vbuf->render = render; 00471 vbuf->max_indices = MAX2(render->max_indices, UNDEFINED_VERTEX_ID-1); 00472 00473 vbuf->indices = (ushort *) align_malloc( vbuf->max_indices * 00474 sizeof(vbuf->indices[0]), 00475 16 ); 00476 if (!vbuf->indices) 00477 goto fail; 00478 00479 vbuf->cache = translate_cache_create(); 00480 if (!vbuf->cache) 00481 goto fail; 00482 00483 00484 vbuf->vertices = NULL; 00485 vbuf->vertex_ptr = vbuf->vertices; 00486 00487 return &vbuf->stage; 00488 00489 fail: 00490 if (vbuf) 00491 vbuf_destroy(&vbuf->stage); 00492 00493 return NULL; 00494 }
static ushort emit_vertex | ( | struct vbuf_stage * | vbuf, | |
struct vertex_header * | vertex | |||
) | [static] |
Extract the needed fields from post-transformed vertex and emit a hardware(driver) vertex.
Recall that the vertices are constructed by the 'draw' module and have a couple of slots at the beginning (1-dword header, 4-dword clip pos) that we ignore here. We only use the vertex->data[] fields.
Definition at line 132 of file draw_pipe_vbuf.c.
References vertex_header::data, draw_dump_emitted_vertex(), vbuf_stage::nr_vertices, translate::set_buffer, vbuf_stage::translate, UNDEFINED_VERTEX_ID, vertex_header::vertex_id, vbuf_stage::vertex_ptr, vbuf_stage::vertex_size, and vbuf_stage::vinfo.
00134 { 00135 if(vertex->vertex_id == UNDEFINED_VERTEX_ID) { 00136 /* Hmm - vertices are emitted one at a time - better make sure 00137 * set_buffer is efficient. Consider a special one-shot mode for 00138 * translate. 00139 */ 00140 /* Note: we really do want data[0] here, not data[pos]: 00141 */ 00142 vbuf->translate->set_buffer(vbuf->translate, 0, vertex->data[0], 0); 00143 vbuf->translate->run(vbuf->translate, 0, 1, vbuf->vertex_ptr); 00144 00145 if (0) draw_dump_emitted_vertex(vbuf->vinfo, (uint8_t *)vbuf->vertex_ptr); 00146 00147 vbuf->vertex_ptr += vbuf->vertex_size/4; 00148 vertex->vertex_id = vbuf->nr_vertices++; 00149 } 00150 00151 return (ushort)vertex->vertex_id; 00152 }
static boolean overflow | ( | void * | map, | |
void * | ptr, | |||
unsigned | bytes, | |||
unsigned | bufsz | |||
) | [static] |
Definition at line 102 of file draw_pipe_vbuf.c.
00103 { 00104 unsigned long used = (unsigned long) ((char *)ptr - (char *)map); 00105 return (used + bytes) > bufsz; 00106 }
static void vbuf_alloc_vertices | ( | struct vbuf_stage * | vbuf | ) | [static] |
Definition at line 386 of file draw_pipe_vbuf.c.
References vbuf_render::allocate_vertices, assert, vbuf_render::max_vertex_buffer_bytes, vbuf_stage::max_vertices, vbuf_stage::nr_indices, vbuf_stage::render, vbuf_stage::vertex_ptr, vbuf_stage::vertex_size, and vbuf_stage::vertices.
00387 { 00388 assert(!vbuf->nr_indices); 00389 assert(!vbuf->vertices); 00390 00391 /* Allocate a new vertex buffer */ 00392 vbuf->max_vertices = vbuf->render->max_vertex_buffer_bytes / vbuf->vertex_size; 00393 00394 /* even number */ 00395 vbuf->max_vertices = vbuf->max_vertices & ~1; 00396 00397 /* Must always succeed -- driver gives us a 00398 * 'max_vertex_buffer_bytes' which it guarantees it can allocate, 00399 * and it will flush itself if necessary to do so. If this does 00400 * fail, we are basically without usable hardware. 00401 */ 00402 vbuf->vertices = (uint *) vbuf->render->allocate_vertices(vbuf->render, 00403 (ushort) vbuf->vertex_size, 00404 (ushort) vbuf->max_vertices); 00405 vbuf->vertex_ptr = vbuf->vertices; 00406 }
static void vbuf_destroy | ( | struct draw_stage * | stage | ) | [static] |
Definition at line 435 of file draw_pipe_vbuf.c.
References align_free(), vbuf_stage::cache, vbuf_render::destroy, FREE, vbuf_stage::indices, vbuf_stage::render, translate_cache_destroy(), and vbuf_stage().
00436 { 00437 struct vbuf_stage *vbuf = vbuf_stage( stage ); 00438 00439 if(vbuf->indices) 00440 align_free( vbuf->indices ); 00441 00442 if (vbuf->render) 00443 vbuf->render->destroy( vbuf->render ); 00444 00445 if (vbuf->cache) 00446 translate_cache_destroy(vbuf->cache); 00447 00448 FREE( stage ); 00449 }
static void vbuf_first_line | ( | struct draw_stage * | stage, | |
struct prim_header * | prim | |||
) | [static] |
Definition at line 316 of file draw_pipe_vbuf.c.
References draw_stage::line, PIPE_PRIM_LINES, vbuf_flush_indices(), vbuf_line(), vbuf_set_prim(), and vbuf_stage().
00318 { 00319 struct vbuf_stage *vbuf = vbuf_stage( stage ); 00320 00321 vbuf_flush_indices( vbuf ); 00322 stage->line = vbuf_line; 00323 vbuf_set_prim(vbuf, PIPE_PRIM_LINES); 00324 stage->line( stage, prim ); 00325 }
static void vbuf_first_point | ( | struct draw_stage * | stage, | |
struct prim_header * | prim | |||
) | [static] |
Definition at line 329 of file draw_pipe_vbuf.c.
References PIPE_PRIM_POINTS, draw_stage::point, vbuf_flush_indices(), vbuf_point(), vbuf_set_prim(), and vbuf_stage().
00331 { 00332 struct vbuf_stage *vbuf = vbuf_stage( stage ); 00333 00334 vbuf_flush_indices( vbuf ); 00335 stage->point = vbuf_point; 00336 vbuf_set_prim(vbuf, PIPE_PRIM_POINTS); 00337 stage->point( stage, prim ); 00338 }
static void vbuf_first_tri | ( | struct draw_stage * | stage, | |
struct prim_header * | prim | |||
) | [static] |
Definition at line 303 of file draw_pipe_vbuf.c.
References PIPE_PRIM_TRIANGLES, draw_stage::tri, vbuf_flush_indices(), vbuf_set_prim(), vbuf_stage(), and vbuf_tri().
00305 { 00306 struct vbuf_stage *vbuf = vbuf_stage( stage ); 00307 00308 vbuf_flush_indices( vbuf ); 00309 stage->tri = vbuf_tri; 00310 vbuf_set_prim(vbuf, PIPE_PRIM_TRIANGLES); 00311 stage->tri( stage, prim ); 00312 }
static void vbuf_flush | ( | struct draw_stage * | stage, | |
unsigned | flags | |||
) | [static] |
Definition at line 411 of file draw_pipe_vbuf.c.
References DRAW_FLUSH_BACKEND, draw_stage::line, draw_stage::point, draw_stage::tri, vbuf_first_line(), vbuf_first_point(), vbuf_first_tri(), vbuf_flush_indices(), vbuf_flush_vertices(), and vbuf_stage().
00412 { 00413 struct vbuf_stage *vbuf = vbuf_stage( stage ); 00414 00415 vbuf_flush_indices( vbuf ); 00416 00417 stage->point = vbuf_first_point; 00418 stage->line = vbuf_first_line; 00419 stage->tri = vbuf_first_tri; 00420 00421 if (flags & DRAW_FLUSH_BACKEND) 00422 vbuf_flush_vertices( vbuf ); 00423 }
static void vbuf_flush_indices | ( | struct vbuf_stage * | vbuf | ) | [static] |
Definition at line 342 of file draw_pipe_vbuf.c.
References assert, vbuf_render::draw, vbuf_stage::indices, vbuf_stage::nr_indices, vbuf_stage::nr_vertices, vbuf_stage::render, vbuf_stage::vertex_ptr, vbuf_stage::vertex_size, and vbuf_stage::vertices.
00343 { 00344 if(!vbuf->nr_indices) 00345 return; 00346 00347 assert((uint) (vbuf->vertex_ptr - vbuf->vertices) == 00348 vbuf->nr_vertices * vbuf->vertex_size / sizeof(unsigned)); 00349 00350 vbuf->render->draw(vbuf->render, vbuf->indices, vbuf->nr_indices); 00351 00352 vbuf->nr_indices = 0; 00353 }
static void vbuf_flush_vertices | ( | struct vbuf_stage * | vbuf | ) | [static] |
Flush existing vertex buffer and allocate a new one.
XXX: We separate flush-on-index-full and flush-on-vb-full, but may raise issues uploading vertices if the hardware wants to flush when we flush.
Definition at line 364 of file draw_pipe_vbuf.c.
References draw_stage::draw, draw_reset_vertex_ids(), vbuf_stage::max_vertices, vbuf_stage::nr_vertices, vbuf_render::release_vertices, vbuf_stage::render, vbuf_stage::stage, vbuf_flush_indices(), vbuf_stage::vertex_ptr, vbuf_stage::vertex_size, and vbuf_stage::vertices.
00365 { 00366 if(vbuf->vertices) { 00367 vbuf_flush_indices(vbuf); 00368 00369 /* Reset temporary vertices ids */ 00370 if(vbuf->nr_vertices) 00371 draw_reset_vertex_ids( vbuf->stage.draw ); 00372 00373 /* Free the vertex buffer */ 00374 vbuf->render->release_vertices(vbuf->render, 00375 vbuf->vertices, 00376 vbuf->vertex_size, 00377 vbuf->nr_vertices); 00378 vbuf->max_vertices = vbuf->nr_vertices = 0; 00379 vbuf->vertex_ptr = vbuf->vertices = NULL; 00380 00381 } 00382 }
static void vbuf_line | ( | struct draw_stage * | stage, | |
struct prim_header * | prim | |||
) | [static] |
Definition at line 171 of file draw_pipe_vbuf.c.
References check_space(), emit_vertex(), vbuf_stage::indices, vbuf_stage::nr_indices, prim_header::v, and vbuf_stage().
00173 { 00174 struct vbuf_stage *vbuf = vbuf_stage( stage ); 00175 unsigned i; 00176 00177 check_space( vbuf, 2 ); 00178 00179 for (i = 0; i < 2; i++) { 00180 vbuf->indices[vbuf->nr_indices++] = emit_vertex( vbuf, prim->v[i] ); 00181 } 00182 }
static void vbuf_point | ( | struct draw_stage * | stage, | |
struct prim_header * | prim | |||
) | [static] |
Definition at line 186 of file draw_pipe_vbuf.c.
References check_space(), emit_vertex(), vbuf_stage::indices, vbuf_stage::nr_indices, prim_header::v, and vbuf_stage().
00188 { 00189 struct vbuf_stage *vbuf = vbuf_stage( stage ); 00190 00191 check_space( vbuf, 1 ); 00192 00193 vbuf->indices[vbuf->nr_indices++] = emit_vertex( vbuf, prim->v[0] ); 00194 }
static void vbuf_reset_stipple_counter | ( | struct draw_stage * | stage | ) | [static] |
Definition at line 427 of file draw_pipe_vbuf.c.
00428 { 00429 /* XXX: Need to do something here for hardware with linestipple. 00430 */ 00431 (void) stage; 00432 }
static void vbuf_set_prim | ( | struct vbuf_stage * | vbuf, | |
uint | prim | |||
) | [static] |
Set the prim type for subsequent vertices.
This may result in a new vertex size. The existing vbuffer (if any) will be flushed if needed and a new one allocated.
Definition at line 205 of file draw_pipe_vbuf.c.
References assert, vertex_info::attrib, vbuf_stage::cache, draw_stage::draw, translate_key::element, vertex_info::emit, EMIT_1F, EMIT_1F_PSIZE, EMIT_2F, EMIT_3F, EMIT_4F, EMIT_4UB, vbuf_render::get_vertex_info, translate_element::input_buffer, translate_element::input_format, translate_element::input_offset, translate::key, translate_key::nr_elements, vertex_info::num_attribs, translate_element::output_format, translate_element::output_offset, translate_key::output_stride, PIPE_FORMAT_B8G8R8A8_UNORM, PIPE_FORMAT_NONE, PIPE_FORMAT_R32_FLOAT, PIPE_FORMAT_R32G32_FLOAT, PIPE_FORMAT_R32G32B32_FLOAT, PIPE_FORMAT_R32G32B32A32_FLOAT, pipe_rasterizer_state::point_size, vbuf_stage::point_size, draw_context::rasterizer, vbuf_stage::render, translate::set_buffer, vbuf_render::set_primitive, vertex_info::size, vertex_info::src_index, vbuf_stage::stage, vbuf_stage::translate, translate_cache_find(), translate_key_compare(), translate_key_sanitize(), vbuf_alloc_vertices(), vbuf_flush_vertices(), vbuf_stage::vertex_size, vbuf_stage::vertices, and vbuf_stage::vinfo.
00206 { 00207 struct translate_key hw_key; 00208 unsigned dst_offset; 00209 unsigned i; 00210 00211 vbuf->render->set_primitive(vbuf->render, prim); 00212 00213 /* Must do this after set_primitive() above: 00214 * 00215 * XXX: need some state managment to track when this needs to be 00216 * recalculated. The driver should tell us whether there was a 00217 * state change. 00218 */ 00219 vbuf->vinfo = vbuf->render->get_vertex_info(vbuf->render); 00220 00221 if (vbuf->vertex_size != vbuf->vinfo->size * sizeof(float)) { 00222 vbuf_flush_vertices(vbuf); 00223 vbuf->vertex_size = vbuf->vinfo->size * sizeof(float); 00224 } 00225 00226 /* Translate from pipeline vertices to hw vertices. 00227 */ 00228 dst_offset = 0; 00229 00230 for (i = 0; i < vbuf->vinfo->num_attribs; i++) { 00231 unsigned emit_sz = 0; 00232 unsigned src_buffer = 0; 00233 unsigned output_format; 00234 unsigned src_offset = (vbuf->vinfo->attrib[i].src_index * 4 * sizeof(float) ); 00235 00236 switch (vbuf->vinfo->attrib[i].emit) { 00237 case EMIT_4F: 00238 output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; 00239 emit_sz = 4 * sizeof(float); 00240 break; 00241 case EMIT_3F: 00242 output_format = PIPE_FORMAT_R32G32B32_FLOAT; 00243 emit_sz = 3 * sizeof(float); 00244 break; 00245 case EMIT_2F: 00246 output_format = PIPE_FORMAT_R32G32_FLOAT; 00247 emit_sz = 2 * sizeof(float); 00248 break; 00249 case EMIT_1F: 00250 output_format = PIPE_FORMAT_R32_FLOAT; 00251 emit_sz = 1 * sizeof(float); 00252 break; 00253 case EMIT_1F_PSIZE: 00254 output_format = PIPE_FORMAT_R32_FLOAT; 00255 emit_sz = 1 * sizeof(float); 00256 src_buffer = 1; 00257 src_offset = 0; 00258 break; 00259 case EMIT_4UB: 00260 output_format = PIPE_FORMAT_B8G8R8A8_UNORM; 00261 emit_sz = 4 * sizeof(ubyte); 00262 break; 00263 default: 00264 assert(0); 00265 output_format = PIPE_FORMAT_NONE; 00266 emit_sz = 0; 00267 break; 00268 } 00269 00270 hw_key.element[i].input_format = PIPE_FORMAT_R32G32B32A32_FLOAT; 00271 hw_key.element[i].input_buffer = src_buffer; 00272 hw_key.element[i].input_offset = src_offset; 00273 hw_key.element[i].output_format = output_format; 00274 hw_key.element[i].output_offset = dst_offset; 00275 00276 dst_offset += emit_sz; 00277 } 00278 00279 hw_key.nr_elements = vbuf->vinfo->num_attribs; 00280 hw_key.output_stride = vbuf->vinfo->size * 4; 00281 00282 /* Don't bother with caching at this stage: 00283 */ 00284 if (!vbuf->translate || 00285 translate_key_compare(&vbuf->translate->key, &hw_key) != 0) 00286 { 00287 translate_key_sanitize(&hw_key); 00288 vbuf->translate = translate_cache_find(vbuf->cache, &hw_key); 00289 00290 vbuf->translate->set_buffer(vbuf->translate, 1, &vbuf->point_size, 0); 00291 } 00292 00293 vbuf->point_size = vbuf->stage.draw->rasterizer->point_size; 00294 00295 /* Allocate new buffer? 00296 */ 00297 if (!vbuf->vertices) 00298 vbuf_alloc_vertices(vbuf); 00299 }
static struct vbuf_stage* vbuf_stage | ( | struct draw_stage * | stage | ) | [static, read] |
Basically a cast wrapper.
Definition at line 89 of file draw_pipe_vbuf.c.
References assert.
00090 { 00091 assert(stage); 00092 return (struct vbuf_stage *)stage; 00093 }
static void vbuf_tri | ( | struct draw_stage * | stage, | |
struct prim_header * | prim | |||
) | [static] |
Definition at line 156 of file draw_pipe_vbuf.c.
References check_space(), emit_vertex(), vbuf_stage::indices, vbuf_stage::nr_indices, prim_header::v, and vbuf_stage().
00158 { 00159 struct vbuf_stage *vbuf = vbuf_stage( stage ); 00160 unsigned i; 00161 00162 check_space( vbuf, 3 ); 00163 00164 for (i = 0; i < 3; i++) { 00165 vbuf->indices[vbuf->nr_indices++] = emit_vertex( vbuf, prim->v[i] ); 00166 } 00167 }