static void fse_run_linear(struct draw_pt_middle_end *middle, unsigned start, unsigned count, unsigned prim_flags) { struct fetch_shade_emit *fse = (struct fetch_shade_emit *)middle; struct draw_context *draw = fse->draw; char *hw_verts; /* XXX: need to flush to get prim_vbuf.c to release its allocation?? */ draw_do_flush( draw, DRAW_FLUSH_BACKEND ); if (!draw->render->allocate_vertices( draw->render, (ushort)fse->key.output_stride, (ushort)count )) goto fail; hw_verts = draw->render->map_vertices( draw->render ); if (!hw_verts) goto fail; /* Single routine to fetch vertices, run shader and emit HW verts. * Clipping is done elsewhere -- either by the API or on hardware, * or for some other reason not required... */ fse->active->run_linear( fse->active, start, count, hw_verts ); if (0) { unsigned i; for (i = 0; i < count; i++) { debug_printf("\n\n%s vertex %d: (stride %d, offset %d)\n", __FUNCTION__, i, fse->key.output_stride, fse->key.output_stride * i); draw_dump_emitted_vertex( fse->vinfo, (const uint8_t *)hw_verts + fse->key.output_stride * i ); } } draw->render->unmap_vertices( draw->render, 0, (ushort)(count - 1) ); /* Draw arrays path to avoid re-emitting index list again and * again. */ draw->render->draw_arrays( draw->render, 0, count ); draw->render->release_vertices( draw->render ); return; fail: debug_warn_once("allocate or map of vertex buffer failed (out of memory?)"); return; }
static void fetch_emit_run( struct draw_pt_middle_end *middle, const unsigned *fetch_elts, unsigned fetch_count, const ushort *draw_elts, unsigned draw_count, unsigned prim_flags ) { struct fetch_emit_middle_end *feme = (struct fetch_emit_middle_end *)middle; struct draw_context *draw = feme->draw; void *hw_verts; /* XXX: need to flush to get prim_vbuf.c to release its allocation?? */ draw_do_flush( draw, DRAW_FLUSH_BACKEND ); draw->render->allocate_vertices( draw->render, (ushort)feme->translate->key.output_stride, (ushort)fetch_count ); hw_verts = draw->render->map_vertices( draw->render ); if (!hw_verts) { assert(0); return; } /* Single routine to fetch vertices and emit HW verts. */ feme->translate->run_elts( feme->translate, fetch_elts, fetch_count, draw->instance_id, hw_verts ); if (0) { unsigned i; for (i = 0; i < fetch_count; i++) { debug_printf("\n\nvertex %d:\n", i); draw_dump_emitted_vertex( feme->vinfo, (const uint8_t *)hw_verts + feme->vinfo->size * 4 * i ); } } draw->render->unmap_vertices( draw->render, 0, (ushort)(fetch_count - 1) ); /* XXX: Draw arrays path to avoid re-emitting index list again and * again. */ draw->render->draw_elements( draw->render, draw_elts, draw_count ); /* Done -- that was easy, wasn't it: */ draw->render->release_vertices( draw->render ); }
static void fse_run(struct draw_pt_middle_end *middle, const unsigned *fetch_elts, unsigned fetch_count, const ushort *draw_elts, unsigned draw_count, unsigned prim_flags ) { struct fetch_shade_emit *fse = (struct fetch_shade_emit *)middle; struct draw_context *draw = fse->draw; void *hw_verts; /* XXX: need to flush to get prim_vbuf.c to release its allocation?? */ draw_do_flush( draw, DRAW_FLUSH_BACKEND ); if (!draw->render->allocate_vertices( draw->render, (ushort)fse->key.output_stride, (ushort)fetch_count )) goto fail; hw_verts = draw->render->map_vertices( draw->render ); if (!hw_verts) goto fail; /* Single routine to fetch vertices, run shader and emit HW verts. */ fse->active->run_elts( fse->active, fetch_elts, fetch_count, hw_verts ); if (0) { unsigned i; for (i = 0; i < fetch_count; i++) { debug_printf("\n\n%s vertex %d:\n", __FUNCTION__, i); draw_dump_emitted_vertex( fse->vinfo, (const uint8_t *)hw_verts + fse->key.output_stride * i ); } } draw->render->unmap_vertices( draw->render, 0, (ushort)(fetch_count - 1) ); draw->render->draw_elements( draw->render, draw_elts, draw_count ); draw->render->release_vertices( draw->render ); return; fail: assert(0); return; }
static void fetch_emit_run_linear( struct draw_pt_middle_end *middle, unsigned start, unsigned count ) { struct fetch_emit_middle_end *feme = (struct fetch_emit_middle_end *)middle; struct draw_context *draw = feme->draw; void *hw_verts; /* XXX: need to flush to get prim_vbuf.c to release its allocation?? */ draw_do_flush( draw, DRAW_FLUSH_BACKEND ); if (count >= UNDEFINED_VERTEX_ID) goto fail; if (!draw->render->allocate_vertices( draw->render, (ushort)feme->translate->key.output_stride, (ushort)count )) goto fail; hw_verts = draw->render->map_vertices( draw->render ); if (!hw_verts) goto fail; /* Single routine to fetch vertices and emit HW verts. */ feme->translate->run( feme->translate, start, count, hw_verts ); if (0) { unsigned i; for (i = 0; i < count; i++) { debug_printf("\n\nvertex %d:\n", i); draw_dump_emitted_vertex( feme->vinfo, (const uint8_t *)hw_verts + feme->vinfo->size * 4 * i ); } } draw->render->unmap_vertices( draw->render, 0, count - 1 ); /* XXX: Draw arrays path to avoid re-emitting index list again and * again. */ draw->render->draw_arrays( draw->render, 0, count ); /* Done -- that was easy, wasn't it: */ draw->render->release_vertices( draw->render ); return; fail: assert(0); return; }
/** * 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. */ static INLINE ushort emit_vertex( struct vbuf_stage *vbuf, struct vertex_header *vertex ) { if(vertex->vertex_id == UNDEFINED_VERTEX_ID) { /* Hmm - vertices are emitted one at a time - better make sure * set_buffer is efficient. Consider a special one-shot mode for * translate. */ /* Note: we really do want data[0] here, not data[pos]: */ vbuf->translate->set_buffer(vbuf->translate, 0, vertex->data[0], 0); vbuf->translate->run(vbuf->translate, 0, 1, vbuf->vertex_ptr); if (0) draw_dump_emitted_vertex(vbuf->vinfo, (uint8_t *)vbuf->vertex_ptr); vbuf->vertex_ptr += vbuf->vertex_size/4; vertex->vertex_id = vbuf->nr_vertices++; } return (ushort)vertex->vertex_id; }
void draw_pt_emit_linear(struct pt_emit *emit, const struct draw_vertex_info *vert_info, const struct draw_prim_info *prim_info) { const float (*vertex_data)[4] = (const float (*)[4])vert_info->verts->data; unsigned stride = vert_info->stride; unsigned count = vert_info->count; struct draw_context *draw = emit->draw; struct translate *translate = emit->translate; struct vbuf_render *render = draw->render; void *hw_verts; unsigned start, i; #if 0 debug_printf("Linear emit\n"); #endif /* XXX: need to flush to get prim_vbuf.c to release its allocation?? */ draw_do_flush( draw, DRAW_FLUSH_BACKEND ); /* XXX: and work out some way to coordinate the render primitive * between vbuf.c and here... */ draw->render->set_primitive(draw->render, emit->prim); if (!render->allocate_vertices(render, (ushort)translate->key.output_stride, (ushort)count)) goto fail; hw_verts = render->map_vertices( render ); if (!hw_verts) goto fail; translate->set_buffer(translate, 0, vertex_data, stride, count - 1); translate->set_buffer(translate, 1, &draw->rasterizer->point_size, 0, ~0); translate->run(translate, 0, count, draw->start_instance, draw->instance_id, hw_verts); if (0) { unsigned i; for (i = 0; i < count; i++) { debug_printf("\n\n%s vertex %d:\n", __FUNCTION__, i); draw_dump_emitted_vertex( emit->vinfo, (const uint8_t *)hw_verts + translate->key.output_stride * i ); } } render->unmap_vertices( render, 0, count - 1 ); for (start = i = 0; i < prim_info->primitive_count; start += prim_info->primitive_lengths[i], i++) { render->draw_arrays(render, start, prim_info->primitive_lengths[i]); } render->release_vertices(render); return; fail: debug_warn_once("allocate or map of vertex buffer failed (out of memory?)"); return; }
void draw_pt_emit_linear(struct pt_emit *emit, const float (*vertex_data)[4], unsigned stride, unsigned count) { struct draw_context *draw = emit->draw; struct translate *translate = emit->translate; struct vbuf_render *render = draw->render; void *hw_verts; #if 0 debug_printf("Linear emit\n"); #endif /* XXX: need to flush to get prim_vbuf.c to release its allocation?? */ draw_do_flush( draw, DRAW_FLUSH_BACKEND ); if (count >= UNDEFINED_VERTEX_ID) goto fail; /* XXX: and work out some way to coordinate the render primitive * between vbuf.c and here... */ if (!draw->render->set_primitive(draw->render, emit->prim)) goto fail; if (!render->allocate_vertices(render, (ushort)translate->key.output_stride, (ushort)count)) goto fail; hw_verts = render->map_vertices( render ); if (!hw_verts) goto fail; translate->set_buffer(translate, 0, vertex_data, stride); translate->set_buffer(translate, 1, &draw->rasterizer->point_size, 0); translate->run(translate, 0, count, draw->instance_id, hw_verts); if (0) { unsigned i; for (i = 0; i < count; i++) { debug_printf("\n\n%s vertex %d:\n", __FUNCTION__, i); draw_dump_emitted_vertex( emit->vinfo, (const uint8_t *)hw_verts + translate->key.output_stride * i ); } } render->unmap_vertices( render, 0, count - 1 ); render->draw_arrays(render, 0, count); render->release_vertices(render); return; fail: assert(0); return; }