diff options
-rw-r--r-- | src/mesa/pipe/i915simple/i915_prim_vbuf.c | 72 | ||||
-rw-r--r-- | src/mesa/pipe/i915simple/i915_reg.h | 4 |
2 files changed, 52 insertions, 24 deletions
diff --git a/src/mesa/pipe/i915simple/i915_prim_vbuf.c b/src/mesa/pipe/i915simple/i915_prim_vbuf.c index 0adf987721d..8b5a08a3bb3 100644 --- a/src/mesa/pipe/i915simple/i915_prim_vbuf.c +++ b/src/mesa/pipe/i915simple/i915_prim_vbuf.c @@ -67,19 +67,17 @@ static void vbuf_flush_elements( struct draw_stage *stage ); struct vbuf_stage { struct draw_stage stage; /**< This must be first (base class) */ + /** Vertex size in bytes */ + unsigned vertex_size; + /* FIXME: we have no guarantee that 'unsigned' is 32bit */ - - /* Vertices are passed in as an array of floats making up each - * attribute in turn. Will eventually convert to hardware format - * in this stage. - */ + + /** Vertices in hardware format */ unsigned *vertex_map; unsigned *vertex_ptr; - unsigned vertex_size; - unsigned nr_vertices; - unsigned max_vertices; - + unsigned nr_vertices; + ushort *element_map; unsigned nr_elements; @@ -274,11 +272,13 @@ static void vbuf_draw( struct draw_stage *stage ) { struct vbuf_stage *vbuf = vbuf_stage( stage ); struct i915_context *i915 = vbuf->i915; + struct pipe_winsys *winsys = i915->pipe.winsys; unsigned nr = vbuf->nr_elements; unsigned vertex_size = i915->current.vertex_info.size * 4; /* in bytes */ unsigned hwprim; - unsigned *ptr; - unsigned i, j; + unsigned i; + char *ptr; + struct pipe_buffer_handle *buf; switch(vbuf->prim) { case PIPE_PRIM_POINTS: @@ -295,15 +295,37 @@ static void vbuf_draw( struct draw_stage *stage ) return; } + assert(vbuf->vertex_ptr - vbuf->vertex_map == vbuf->nr_vertices * vertex_size / 4); + + /* FIXME: handle failure */ + buf = winsys->buffer_create(winsys, 64); + winsys->buffer_data(winsys, buf, 8 + nr * vertex_size, NULL); + ptr = winsys->buffer_map(winsys, buf, PIPE_BUFFER_FLAG_WRITE); + *(unsigned *)ptr = _3DPRIMITIVE | + hwprim | + ((4 + vertex_size * nr)/4 - 2); + ptr += 4; + for (i = 0; i < nr; i++) { + memcpy(ptr, + (char*)vbuf->vertex_map + vbuf->element_map[i]*vertex_size, + vertex_size ); + ptr += vertex_size; + } + *(unsigned *)ptr = MI_BATCH_BUFFER_END; + ptr += 4; + winsys->buffer_unmap(winsys, buf); + if (i915->dirty) i915_update_derived( i915 ); if (i915->hardware_dirty) i915_emit_hardware_state( i915 ); - assert(vbuf->vertex_ptr - vbuf->vertex_map == vbuf->nr_vertices * vertex_size / 4); - - ptr = BEGIN_BATCH( 1 + nr * vertex_size / 4, 0 ); + ptr = BEGIN_BATCH( 2, 1 ); +#if 1 + assert(ptr); +#else + /* XXX: below is bogues as ptr always nonzero except in fatal errors */ if (ptr == 0) { FLUSH_BATCH(); @@ -312,21 +334,23 @@ static void vbuf_draw( struct draw_stage *stage ) i915_update_derived( i915 ); i915_emit_hardware_state( i915 ); - ptr = BEGIN_BATCH( 1 + nr * vertex_size / 4, 0 ); + ptr = BEGIN_BATCH( 2, 1 ); if (ptr == 0) { assert(0); return; } } - - /* TODO: Fire a DMA buffer */ - OUT_BATCH(_3DPRIMITIVE | - hwprim | - ((4 + vertex_size * nr)/4 - 2)); - - for (i = 0; i < nr; i++) - for (j = 0; j < vertex_size / 4; j++) - OUT_BATCH(vbuf->vertex_map[vbuf->element_map[i]*vertex_size/4 + j]); +#endif + + /* chain the vertex buffer in the batch buffer */ + OUT_BATCH(MI_BATCH_BUFFER_START + | (2 << 6) /* GTT-mapped memory */); + OUT_RELOC( buf, I915_BUFFER_ACCESS_READ, 0 ); + /* FIXME: we need to flush here since control after chained buffers returns + * directly to the ring buffer */ + FLUSH_BATCH(); + + winsys->buffer_reference(winsys, &buf, NULL); } diff --git a/src/mesa/pipe/i915simple/i915_reg.h b/src/mesa/pipe/i915simple/i915_reg.h index f4070ef93e8..04620fec681 100644 --- a/src/mesa/pipe/i915simple/i915_reg.h +++ b/src/mesa/pipe/i915simple/i915_reg.h @@ -907,6 +907,10 @@ #define MI_WAIT_FOR_PLANE_B_FLIP (1<<6) #define MI_WAIT_FOR_PLANE_A_FLIP (1<<2) +#define MI_BATCH_BUFFER (0x30<<23) +#define MI_BATCH_BUFFER_START (0x31<<23) +#define MI_BATCH_BUFFER_END (0xa<<23) + #define COMPAREFUNC_ALWAYS 0 |