static void vbuf_flush_indices( struct draw_stage *stage );
-static void vbuf_flush_vertices( struct draw_stage *stage,
+static void vbuf_flush_vertices( struct draw_stage *stage );
+static void vbuf_alloc_vertices( struct draw_stage *stage,
unsigned new_vertex_size );
static INLINE void
check_space( struct vbuf_stage *vbuf, unsigned nr )
{
- if (vbuf->nr_vertices + nr > vbuf->max_vertices )
- vbuf_flush_vertices(&vbuf->stage, vbuf->vertex_size );
+ if (vbuf->nr_vertices + nr > vbuf->max_vertices ) {
+ vbuf_flush_vertices(&vbuf->stage);
+ vbuf_alloc_vertices(&vbuf->stage, vbuf->vertex_size);
+ }
if (vbuf->nr_indices + nr > vbuf->max_indices )
vbuf_flush_indices(&vbuf->stage);
/**
- * Extract the needed fields from vertex_header and emit i915 dwords.
+ * 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.
+ * clip pos) that we ignore here. We only use the vertex->data[] fields.
*/
static INLINE void
emit_vertex( struct vbuf_stage *vbuf,
vertex->vertex_id = vbuf->nr_vertices++;
for (i = 0; i < vinfo->num_attribs; i++) {
- switch (vinfo->format[i]) {
- case FORMAT_OMIT:
+ uint j = vinfo->src_index[i];
+ switch (vinfo->emit[i]) {
+ case EMIT_OMIT:
/* no-op */
break;
- case FORMAT_1F:
- *vbuf->vertex_ptr++ = fui(vertex->data[i][0]);
+ case EMIT_ALL:
+ /* just copy the whole vertex as-is to the vbuf */
+ assert(i == 0);
+ memcpy(vbuf->vertex_ptr, vertex, vinfo->size * 4);
+ vbuf->vertex_ptr += vinfo->size;
+ return;
+ case EMIT_1F:
+ *vbuf->vertex_ptr++ = fui(vertex->data[j][0]);
+ count++;
+ break;
+ case EMIT_1F_PSIZE:
+ *vbuf->vertex_ptr++ = fui(vbuf->stage.draw->rasterizer->point_size);
count++;
break;
- case FORMAT_2F:
- *vbuf->vertex_ptr++ = fui(vertex->data[i][0]);
- *vbuf->vertex_ptr++ = fui(vertex->data[i][1]);
+ case EMIT_2F:
+ *vbuf->vertex_ptr++ = fui(vertex->data[j][0]);
+ *vbuf->vertex_ptr++ = fui(vertex->data[j][1]);
count += 2;
break;
- case FORMAT_3F:
- *vbuf->vertex_ptr++ = fui(vertex->data[i][0]);
- *vbuf->vertex_ptr++ = fui(vertex->data[i][1]);
- *vbuf->vertex_ptr++ = fui(vertex->data[i][2]);
+ case EMIT_3F:
+ *vbuf->vertex_ptr++ = fui(vertex->data[j][0]);
+ *vbuf->vertex_ptr++ = fui(vertex->data[j][1]);
+ *vbuf->vertex_ptr++ = fui(vertex->data[j][2]);
count += 3;
break;
- case FORMAT_4F:
- *vbuf->vertex_ptr++ = fui(vertex->data[i][0]);
- *vbuf->vertex_ptr++ = fui(vertex->data[i][1]);
- *vbuf->vertex_ptr++ = fui(vertex->data[i][2]);
- *vbuf->vertex_ptr++ = fui(vertex->data[i][3]);
+ case EMIT_4F:
+ *vbuf->vertex_ptr++ = fui(vertex->data[j][0]);
+ *vbuf->vertex_ptr++ = fui(vertex->data[j][1]);
+ *vbuf->vertex_ptr++ = fui(vertex->data[j][2]);
+ *vbuf->vertex_ptr++ = fui(vertex->data[j][3]);
count += 4;
break;
- case FORMAT_4UB:
- *vbuf->vertex_ptr++ = pack_ub4(float_to_ubyte( vertex->data[i][2] ),
- float_to_ubyte( vertex->data[i][1] ),
- float_to_ubyte( vertex->data[i][0] ),
- float_to_ubyte( vertex->data[i][3] ));
+ case EMIT_4UB:
+ *vbuf->vertex_ptr++ = pack_ub4(float_to_ubyte( vertex->data[j][2] ),
+ float_to_ubyte( vertex->data[j][1] ),
+ float_to_ubyte( vertex->data[j][0] ),
+ float_to_ubyte( vertex->data[j][3] ));
count += 1;
break;
default:
}
+/**
+ * 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.
+ */
+static void
+vbuf_set_prim( struct draw_stage *stage, uint newprim )
+{
+ struct vbuf_stage *vbuf = vbuf_stage(stage);
+ const struct vertex_info *vinfo;
+ unsigned vertex_size;
+
+ assert(newprim == PIPE_PRIM_POINTS ||
+ newprim == PIPE_PRIM_LINES ||
+ newprim == PIPE_PRIM_TRIANGLES);
+
+ vbuf->prim = newprim;
+ vbuf->render->set_primitive(vbuf->render, newprim);
+
+ vinfo = vbuf->render->get_vertex_info(vbuf->render);
+ vertex_size = vinfo->size * sizeof(float);
+
+ if (vertex_size != vbuf->vertex_size)
+ vbuf_flush_vertices(stage);
+
+ if (!vbuf->vertices)
+ vbuf_alloc_vertices(stage, vertex_size);
+}
+
+
static void
vbuf_first_tri( struct draw_stage *stage,
struct prim_header *prim )
{
- struct vbuf_stage *vbuf = vbuf_stage( stage );
-
vbuf_flush_indices( stage );
stage->tri = vbuf_tri;
+ vbuf_set_prim(stage, PIPE_PRIM_TRIANGLES);
stage->tri( stage, prim );
- vbuf->prim = PIPE_PRIM_TRIANGLES;
- vbuf->render->set_primitive(vbuf->render, PIPE_PRIM_TRIANGLES);
}
vbuf_first_line( struct draw_stage *stage,
struct prim_header *prim )
{
- struct vbuf_stage *vbuf = vbuf_stage( stage );
-
vbuf_flush_indices( stage );
stage->line = vbuf_line;
+ vbuf_set_prim(stage, PIPE_PRIM_LINES);
stage->line( stage, prim );
- vbuf->prim = PIPE_PRIM_LINES;
- vbuf->render->set_primitive(vbuf->render, PIPE_PRIM_LINES);
}
vbuf_first_point( struct draw_stage *stage,
struct prim_header *prim )
{
- struct vbuf_stage *vbuf = vbuf_stage( stage );
-
vbuf_flush_indices( stage );
stage->point = vbuf_point;
+ vbuf_set_prim(stage, PIPE_PRIM_POINTS);
stage->point( stage, prim );
- vbuf->prim = PIPE_PRIM_POINTS;
- vbuf->render->set_primitive(vbuf->render, PIPE_PRIM_POINTS);
}
if(!vbuf->nr_indices)
return;
- assert(vbuf->vertex_ptr - vbuf->vertices ==
+ assert((uint) (vbuf->vertex_ptr - vbuf->vertices) ==
vbuf->nr_vertices * vbuf->vertex_size / sizeof(unsigned));
switch(vbuf->prim) {
assert(0);
}
- vbuf->render->draw( vbuf->render,
- vbuf->prim,
- vbuf->indices,
- vbuf->nr_indices,
- vbuf->vertices,
- vbuf->nr_vertices,
- vbuf->vertex_size );
-
+ vbuf->render->draw(vbuf->render, vbuf->indices, vbuf->nr_indices);
+
vbuf->nr_indices = 0;
+
+ stage->point = vbuf_first_point;
+ stage->line = vbuf_first_line;
+ stage->tri = vbuf_first_tri;
}
* we flush.
*/
static void
-vbuf_flush_vertices( struct draw_stage *stage,
- unsigned new_vertex_size )
+vbuf_flush_vertices( struct draw_stage *stage )
{
struct vbuf_stage *vbuf = vbuf_stage( stage );
vbuf->vertex_ptr = vbuf->vertices = NULL;
}
+}
+
+static void
+vbuf_alloc_vertices( struct draw_stage *stage,
+ unsigned new_vertex_size )
+{
+ struct vbuf_stage *vbuf = vbuf_stage( stage );
+
assert(!vbuf->nr_indices);
+ assert(!vbuf->vertices);
/* Allocate a new vertex buffer */
vbuf->vertex_size = new_vertex_size;
vbuf->max_vertices = vbuf->render->max_vertex_buffer_bytes / vbuf->vertex_size;
- vbuf->vertices = vbuf->render->allocate_vertices(vbuf->render,
- vbuf->vertex_size,
- vbuf->max_vertices) ;
+ vbuf->vertices = (uint *) vbuf->render->allocate_vertices(vbuf->render,
+ (ushort) vbuf->vertex_size,
+ (ushort) vbuf->max_vertices);
vbuf->vertex_ptr = vbuf->vertices;
}
static void
vbuf_begin( struct draw_stage *stage )
{
- struct vbuf_stage *vbuf = vbuf_stage(stage);
- const struct vertex_info *vinfo = vbuf->render->get_vertex_info(vbuf->render);
- unsigned vertex_size = vinfo->size * sizeof(float);
-
- if(vbuf->vertex_size != vertex_size)
- vbuf_flush_vertices(&vbuf->stage, vertex_size);
+ /* no-op, vbuffer allocated by first point/line/tri */
}
static void
vbuf_end( struct draw_stage *stage )
{
+// vbuf_flush_indices( stage );
/* XXX: Overkill */
- vbuf_flush_indices( stage );
+ vbuf_flush_vertices( stage );
stage->point = vbuf_first_point;
stage->line = vbuf_first_line;
static void
vbuf_reset_stipple_counter( struct draw_stage *stage )
{
+ (void) stage;
}
assert(render->max_indices < UNDEFINED_VERTEX_ID);
vbuf->max_indices = render->max_indices;
- vbuf->indices = align_malloc( vbuf->max_indices, 16 );
+ vbuf->indices = (ushort *)
+ align_malloc( vbuf->max_indices * sizeof(vbuf->indices[0]), 16 );
vbuf->vertices = NULL;
vbuf->vertex_ptr = vbuf->vertices;
+
+ vbuf->prim = ~0;
return &vbuf->stage;
}