}
-static void vbuf_flush_indices( struct vbuf_stage *vbuf );
static void vbuf_flush_vertices( struct vbuf_stage *vbuf );
static void vbuf_alloc_vertices( struct vbuf_stage *vbuf );
static INLINE void
check_space( struct vbuf_stage *vbuf, unsigned nr )
{
- if (vbuf->nr_vertices + nr > vbuf->max_vertices ) {
- vbuf_flush_vertices(vbuf);
- vbuf_alloc_vertices(vbuf);
+ if (vbuf->nr_vertices + nr > vbuf->max_vertices ||
+ vbuf->nr_indices + nr > vbuf->max_indices)
+ {
+ vbuf_flush_vertices( vbuf );
+ vbuf_alloc_vertices( vbuf );
}
-
- if (vbuf->nr_indices + nr > vbuf->max_indices )
- vbuf_flush_indices(vbuf);
}
* will be flushed if needed and a new one allocated.
*/
static void
-vbuf_set_prim( struct vbuf_stage *vbuf, uint prim )
+vbuf_start_prim( struct vbuf_stage *vbuf, uint prim )
{
struct translate_key hw_key;
unsigned dst_offset;
* state change.
*/
vbuf->vinfo = vbuf->render->get_vertex_info(vbuf->render);
-
- if (vbuf->vertex_size != vbuf->vinfo->size * sizeof(float)) {
- vbuf_flush_vertices(vbuf);
- vbuf->vertex_size = vbuf->vinfo->size * sizeof(float);
- }
+ vbuf->vertex_size = vbuf->vinfo->size * sizeof(float);
/* Translate from pipeline vertices to hw vertices.
*/
/* Allocate new buffer?
*/
- if (!vbuf->vertices)
- vbuf_alloc_vertices(vbuf);
+ assert(vbuf->vertices == NULL);
+ vbuf_alloc_vertices(vbuf);
}
{
struct vbuf_stage *vbuf = vbuf_stage( stage );
- vbuf_flush_indices( vbuf );
+ vbuf_flush_vertices( vbuf );
+ vbuf_start_prim(vbuf, PIPE_PRIM_TRIANGLES);
stage->tri = vbuf_tri;
- vbuf_set_prim(vbuf, PIPE_PRIM_TRIANGLES);
stage->tri( stage, prim );
}
{
struct vbuf_stage *vbuf = vbuf_stage( stage );
- vbuf_flush_indices( vbuf );
+ vbuf_flush_vertices( vbuf );
+ vbuf_start_prim(vbuf, PIPE_PRIM_LINES);
stage->line = vbuf_line;
- vbuf_set_prim(vbuf, PIPE_PRIM_LINES);
stage->line( stage, prim );
}
{
struct vbuf_stage *vbuf = vbuf_stage( stage );
- vbuf_flush_indices( vbuf );
+ vbuf_flush_vertices(vbuf);
+ vbuf_start_prim(vbuf, PIPE_PRIM_POINTS);
stage->point = vbuf_point;
- vbuf_set_prim(vbuf, PIPE_PRIM_POINTS);
stage->point( stage, prim );
}
-static void
-vbuf_flush_indices( struct vbuf_stage *vbuf )
-{
- if(!vbuf->nr_indices)
- return;
-
- assert((uint) (vbuf->vertex_ptr - vbuf->vertices) ==
- vbuf->nr_vertices * vbuf->vertex_size / sizeof(unsigned));
-
- vbuf->render->draw(vbuf->render, vbuf->indices, vbuf->nr_indices);
-
- vbuf->nr_indices = 0;
-}
-
/**
* 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.
*/
static void
vbuf_flush_vertices( struct vbuf_stage *vbuf )
{
- if(vbuf->vertices) {
- vbuf_flush_indices(vbuf);
-
+ if(vbuf->vertices) {
+
+ vbuf->render->unmap_vertices( vbuf->render, 0, vbuf->nr_vertices );
+
+ if (vbuf->nr_indices)
+ {
+ vbuf->render->draw(vbuf->render,
+ vbuf->indices,
+ vbuf->nr_indices );
+
+ vbuf->nr_indices = 0;
+ }
+
/* Reset temporary vertices ids */
if(vbuf->nr_vertices)
draw_reset_vertex_ids( vbuf->stage.draw );
/* Free the vertex buffer */
- vbuf->render->release_vertices(vbuf->render,
- vbuf->vertices,
- vbuf->vertex_size,
- vbuf->nr_vertices);
+ vbuf->render->release_vertices( vbuf->render );
+
vbuf->max_vertices = vbuf->nr_vertices = 0;
vbuf->vertex_ptr = vbuf->vertices = NULL;
-
}
}
* and it will flush itself if necessary to do so. If this does
* fail, we are basically without usable hardware.
*/
- vbuf->vertices = (uint *) vbuf->render->allocate_vertices(vbuf->render,
- (ushort) vbuf->vertex_size,
- (ushort) vbuf->max_vertices);
+ vbuf->render->allocate_vertices(vbuf->render,
+ (ushort) vbuf->vertex_size,
+ (ushort) vbuf->max_vertices);
+
+ vbuf->vertices = (uint *) vbuf->render->map_vertices( vbuf->render );
+
vbuf->vertex_ptr = vbuf->vertices;
}
{
struct vbuf_stage *vbuf = vbuf_stage( stage );
- vbuf_flush_indices( vbuf );
+ vbuf_flush_vertices( vbuf );
stage->point = vbuf_first_point;
stage->line = vbuf_first_line;
stage->tri = vbuf_first_tri;
-
- if (flags & DRAW_FLUSH_BACKEND)
- vbuf_flush_vertices( vbuf );
}
void draw_pt_emit_linear( struct pt_emit *emit,
const float (*vertex_data)[4],
- unsigned vertex_count,
unsigned stride,
- unsigned start,
unsigned count );
void draw_pt_emit_destroy( struct pt_emit *emit );
return;
}
- hw_verts = render->allocate_vertices(render,
- (ushort)translate->key.output_stride,
- (ushort)vertex_count);
+ render->allocate_vertices(render,
+ (ushort)translate->key.output_stride,
+ (ushort)vertex_count);
+
+ hw_verts = render->map_vertices( render );
if (!hw_verts) {
assert(0);
return;
vertex_count,
hw_verts );
+ render->unmap_vertices( render,
+ 0,
+ vertex_count );
+
render->draw(render,
elts,
count);
- render->release_vertices(render,
- hw_verts,
- translate->key.output_stride,
- vertex_count);
+ render->release_vertices(render);
}
void draw_pt_emit_linear(struct pt_emit *emit,
const float (*vertex_data)[4],
- unsigned vertex_count,
unsigned stride,
- unsigned start,
unsigned count)
{
struct draw_context *draw = emit->draw;
*/
draw_do_flush( draw, DRAW_FLUSH_BACKEND );
- if (count >= UNDEFINED_VERTEX_ID) {
- assert(0);
- return;
- }
+ 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)) {
- assert(0);
- return;
- }
+ if (!draw->render->set_primitive(draw->render, emit->prim))
+ goto fail;
- hw_verts = render->allocate_vertices(render,
- (ushort)translate->key.output_stride,
- (ushort)count);
- if (!hw_verts) {
- assert(0);
- return;
- }
+ 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->run(translate,
0,
- vertex_count,
+ count,
hw_verts);
if (0) {
unsigned i;
- for (i = 0; i < vertex_count; 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 +
}
}
+ render->unmap_vertices( render, 0, count );
+
+ render->draw_arrays(render, 0, count);
+
+ render->release_vertices(render);
- render->draw_arrays(render, start, count);
+ return;
- render->release_vertices(render,
- hw_verts,
- translate->key.output_stride,
- vertex_count);
+fail:
+ assert(0);
+ return;
}
struct pt_emit *draw_pt_emit_create( struct draw_context *draw )
return;
}
- hw_verts = draw->render->allocate_vertices( draw->render,
- (ushort)feme->translate->key.output_stride,
- (ushort)fetch_count );
+ 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;
}
}
+ draw->render->unmap_vertices( draw->render,
+ 0,
+ (ushort)fetch_count );
+
/* XXX: Draw arrays path to avoid re-emitting index list again and
* again.
*/
/* Done -- that was easy, wasn't it:
*/
- draw->render->release_vertices( draw->render,
- hw_verts,
- feme->translate->key.output_stride,
- fetch_count );
+ draw->render->release_vertices( draw->render );
}
*/
draw_do_flush( draw, DRAW_FLUSH_BACKEND );
- if (count >= UNDEFINED_VERTEX_ID) {
- assert(0);
- return;
- }
+ if (count >= UNDEFINED_VERTEX_ID)
+ goto fail;
- hw_verts = draw->render->allocate_vertices( draw->render,
- (ushort)feme->translate->key.output_stride,
- (ushort)count );
- if (!hw_verts) {
- assert(0);
- return;
- }
+ 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.
*/
}
}
+ draw->render->unmap_vertices( draw->render, 0, count );
+
/* XXX: Draw arrays path to avoid re-emitting index list again and
* again.
*/
- draw->render->draw_arrays( draw->render,
- 0, /*start*/
- count );
+ draw->render->draw_arrays( draw->render, 0, count );
/* Done -- that was easy, wasn't it:
*/
- draw->render->release_vertices( draw->render,
- hw_verts,
- feme->translate->key.output_stride,
- count );
+ draw->render->release_vertices( draw->render );
+ return;
+fail:
+ assert(0);
+ return;
}
if (count >= UNDEFINED_VERTEX_ID)
return FALSE;
- hw_verts = draw->render->allocate_vertices( draw->render,
- (ushort)feme->translate->key.output_stride,
- (ushort)count );
+ if (!draw->render->allocate_vertices( draw->render,
+ (ushort)feme->translate->key.output_stride,
+ (ushort)count ))
+ return FALSE;
+
+ hw_verts = draw->render->map_vertices( draw->render );
if (!hw_verts)
return FALSE;
count,
hw_verts );
+ draw->render->unmap_vertices( draw->render, 0, (ushort)count );
+
/* XXX: Draw arrays path to avoid re-emitting index list again and
* again.
*/
/* Done -- that was easy, wasn't it:
*/
- draw->render->release_vertices( draw->render,
- hw_verts,
- feme->translate->key.output_stride,
- count );
+ draw->render->release_vertices( draw->render );
return TRUE;
}
*/
draw_do_flush( draw, DRAW_FLUSH_BACKEND );
- if (count >= UNDEFINED_VERTEX_ID) {
- assert(0);
- return;
- }
+ if (count >= UNDEFINED_VERTEX_ID)
+ goto fail;
- hw_verts = draw->render->allocate_vertices( draw->render,
- (ushort)fse->key.output_stride,
- (ushort)count );
+ if (!draw->render->allocate_vertices( draw->render,
+ (ushort)fse->key.output_stride,
+ (ushort)count ))
+ goto fail;
- if (!hw_verts) {
- assert(0);
- return;
- }
+ 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,
start, count,
hw_verts );
- /* Draw arrays path to avoid re-emitting index list again and
- * again.
- */
- draw->render->draw_arrays( draw->render,
- 0,
- count );
-
+
if (0) {
unsigned i;
for (i = 0; i < count; i++) {
(const uint8_t *)hw_verts + fse->key.output_stride * i );
}
}
+
+ draw->render->unmap_vertices( draw->render, 0, (ushort)count );
+ /* 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;
- draw->render->release_vertices( draw->render,
- hw_verts,
- fse->key.output_stride,
- count );
+fail:
+ assert(0);
+ return;
}
*/
draw_do_flush( draw, DRAW_FLUSH_BACKEND );
- if (fetch_count >= UNDEFINED_VERTEX_ID) {
- assert(0);
- return;
- }
+ if (fetch_count >= UNDEFINED_VERTEX_ID)
+ goto fail;
- hw_verts = draw->render->allocate_vertices( draw->render,
- (ushort)fse->key.output_stride,
- (ushort)fetch_count );
- if (!hw_verts) {
- assert(0);
- return;
- }
+ 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.
fetch_count,
hw_verts );
- draw->render->draw( draw->render,
- draw_elts,
- draw_count );
if (0) {
unsigned i;
}
}
+ draw->render->unmap_vertices( draw->render, 0, (ushort)fetch_count );
+
+ draw->render->draw( draw->render,
+ draw_elts,
+ draw_count );
+
- draw->render->release_vertices( draw->render,
- hw_verts,
- fse->key.output_stride,
- fetch_count );
+ draw->render->release_vertices( draw->render );
+ return;
+fail:
+ assert(0);
+ return;
}
if (count >= UNDEFINED_VERTEX_ID)
return FALSE;
- hw_verts = draw->render->allocate_vertices( draw->render,
- (ushort)fse->key.output_stride,
- (ushort)count );
+ if (!draw->render->allocate_vertices( draw->render,
+ (ushort)fse->key.output_stride,
+ (ushort)count ))
+ return FALSE;
- if (!hw_verts) {
+ hw_verts = draw->render->map_vertices( draw->render );
+ if (!hw_verts)
return FALSE;
- }
/* Single routine to fetch vertices, run shader and emit HW verts.
* Clipping is done elsewhere -- either by the API or on hardware,
draw_count );
+ draw->render->unmap_vertices( draw->render, 0, (ushort) count );
- draw->render->release_vertices( draw->render,
- hw_verts,
- fse->key.output_stride,
- count );
+ draw->render->release_vertices( draw->render );
return TRUE;
}
else {
draw_pt_emit_linear( fpme->emit,
(const float (*)[4])pipeline_verts->data,
- count,
fpme->vertex_size,
- 0, /*start*/
count );
}
* Hardware renderers will use ttm memory, others will just malloc
* something.
*/
- void *(*allocate_vertices)( struct vbuf_render *,
- ushort vertex_size,
- ushort nr_vertices );
+ boolean (*allocate_vertices)( struct vbuf_render *,
+ ushort vertex_size,
+ ushort nr_vertices );
+
+ void *(*map_vertices)( struct vbuf_render * );
+ void (*unmap_vertices)( struct vbuf_render *,
+ ushort min_index,
+ ushort max_index );
/**
* Notify the renderer of the current primitive when it changes.
/**
* Called when vbuf is done with this set of vertices:
*/
- void (*release_vertices)( struct vbuf_render *,
- void *vertices,
- unsigned vertex_size,
- unsigned vertices_used );
+ void (*release_vertices)( struct vbuf_render * );
void (*destroy)( struct vbuf_render * );
};