Chain vertex buffers into the batch buffer.
authorJosé Fonseca <jrfonseca@tungstengraphics.com>
Wed, 31 Oct 2007 13:20:01 +0000 (13:20 +0000)
committerJosé Fonseca <jrfonseca@tungstengraphics.com>
Wed, 31 Oct 2007 13:20:01 +0000 (13:20 +0000)
src/mesa/pipe/i915simple/i915_prim_vbuf.c
src/mesa/pipe/i915simple/i915_reg.h

index 0adf987..8b5a08a 100644 (file)
@@ -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);
 }
 
 
index f4070ef..04620fe 100644 (file)
 #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