i915: Made vbuf work
authorJakob Bornecrantz <jakob@tungstengraphics.com>
Tue, 27 May 2008 11:18:25 +0000 (13:18 +0200)
committerJakob Bornecrantz <jakob@tungstengraphics.com>
Wed, 28 May 2008 11:44:36 +0000 (13:44 +0200)
src/gallium/drivers/i915simple/i915_prim_vbuf.c
src/gallium/winsys/dri/intel/intel_winsys_pipe.c

index 7fb2adbb53b8548c1763f01dd6ea7cdf9bb5770a..81293d0d1f86d1a55f5c1cce403f9ba737cc5b15 100644 (file)
@@ -62,8 +62,14 @@ struct i915_vbuf_render {
    /** Vertex size in bytes */
    unsigned vertex_size;
 
+   /** Software primitive */
+   unsigned prim;
+
    /** Hardware primitive */
    unsigned hwprim;
+
+   /** Genereate a vertex list */
+   unsigned fallback;
 };
 
 
@@ -95,8 +101,8 @@ i915_vbuf_render_get_vertex_info( struct vbuf_render *render )
 
 static void *
 i915_vbuf_render_allocate_vertices( struct vbuf_render *render,
-                                   ushort vertex_size,
-                                   ushort nr_vertices )
+                                    ushort vertex_size,
+                                    ushort nr_vertices )
 {
    struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
    struct i915_context *i915 = i915_render->i915;
@@ -107,9 +113,9 @@ i915_vbuf_render_allocate_vertices( struct vbuf_render *render,
    assert(!i915->vbo);
    i915->vbo = winsys->buffer_create(winsys, 64, I915_BUFFER_USAGE_LIT_VERTEX,
                                      size);
-   
+
    i915->dirty |= I915_NEW_VBO;
-   
+
    return winsys->buffer_map(winsys, 
                              i915->vbo, 
                              PIPE_BUFFER_USAGE_CPU_WRITE);
@@ -121,16 +127,36 @@ i915_vbuf_render_set_primitive( struct vbuf_render *render,
                                 unsigned prim )
 {
    struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
-   
+   i915_render->prim = prim;
+
    switch(prim) {
    case PIPE_PRIM_POINTS:
       i915_render->hwprim = PRIM3D_POINTLIST;
+      i915_render->fallback = 0;
       return TRUE;
    case PIPE_PRIM_LINES:
       i915_render->hwprim = PRIM3D_LINELIST;
+      i915_render->fallback = 0;
+      return TRUE;
+   case PIPE_PRIM_LINE_STRIP:
+      i915_render->hwprim = PRIM3D_LINESTRIP;
+      i915_render->fallback = 0;
       return TRUE;
    case PIPE_PRIM_TRIANGLES:
       i915_render->hwprim = PRIM3D_TRILIST;
+      i915_render->fallback = 0;
+      return TRUE;
+   case PIPE_PRIM_TRIANGLE_STRIP:
+      i915_render->hwprim = PRIM3D_TRISTRIP;
+      i915_render->fallback = 0;
+      return TRUE;
+   case PIPE_PRIM_QUADS:
+      i915_render->hwprim = PRIM3D_TRILIST;
+      i915_render->fallback = PIPE_PRIM_QUADS;
+      return TRUE;
+   case PIPE_PRIM_QUAD_STRIP:
+      i915_render->hwprim = PRIM3D_TRILIST;
+      i915_render->fallback = PIPE_PRIM_QUAD_STRIP;
       return TRUE;
    default:
       /* Actually, can handle a lot more just fine...  Fixme.
@@ -140,6 +166,179 @@ i915_vbuf_render_set_primitive( struct vbuf_render *render,
 }
 
 
+
+/**
+ * Used for fallbacks in draw_arrays
+ */
+static void
+draw_arrays_generate_indices( struct vbuf_render *render,
+                              unsigned start, uint nr,
+                              unsigned type )
+{
+   struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
+   struct i915_context *i915 = i915_render->i915;
+   unsigned i;
+   unsigned end = start + nr;
+   switch(type) {
+   case 0:
+      for (i = start; i+1 < end; i += 2)
+        OUT_BATCH( (i+0) | (i+1) << 16 );
+      if (i < end)
+        OUT_BATCH( i );
+      break;
+   case PIPE_PRIM_QUADS:
+      for (i = start; i + 3 < end; i += 4) {
+        OUT_BATCH( (i+0) | (i+1) << 16 );
+        OUT_BATCH( (i+3) | (i+1) << 16 );
+        OUT_BATCH( (i+2) | (i+3) << 16 );
+      }
+      break;
+   case PIPE_PRIM_QUAD_STRIP:
+      for (i = start; i + 3 < end; i += 2) {
+        OUT_BATCH( (i+0) | (i+1) << 16 );
+        OUT_BATCH( (i+3) | (i+2) << 16 );
+        OUT_BATCH( (i+0) | (i+3) << 16 );
+      }
+      break;
+   default:
+      assert(0);
+   }
+}
+
+static unsigned
+draw_arrays_calc_nr_indices( uint nr, unsigned type )
+{
+   switch (type) {
+   case 0:
+      return nr;
+   case PIPE_PRIM_QUADS:
+      return (nr / 4) * 6;
+   case PIPE_PRIM_QUAD_STRIP:
+      return ((nr - 2) / 2) * 6;
+   default:
+      assert(0);
+      return 0;
+   }
+}
+
+static void
+draw_arrays_fallback( struct vbuf_render *render,
+                      unsigned start,
+                      uint nr )
+{
+   struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
+   struct i915_context *i915 = i915_render->i915;
+   struct pipe_winsys *winsys = i915->pipe.winsys;
+   unsigned nr_indices;
+
+   winsys->buffer_unmap( winsys, i915->vbo );
+   if (i915->dirty)
+      i915_update_derived( i915 );
+
+   if (i915->hardware_dirty)
+      i915_emit_hardware_state( i915 );
+
+   nr_indices = draw_arrays_calc_nr_indices( nr, i915_render->fallback );
+
+   if (!BEGIN_BATCH( 1 + (nr_indices + 1)/2, 1 )) {
+      FLUSH_BATCH(NULL);
+
+      /* Make sure state is re-emitted after a flush:
+       */
+      i915_update_derived( i915 );
+      i915_emit_hardware_state( i915 );
+
+      if (!BEGIN_BATCH( 1 + (nr_indices + 1)/2, 1 )) {
+        assert(0);
+        goto out;
+      }
+   }
+   OUT_BATCH( _3DPRIMITIVE |
+             PRIM_INDIRECT |
+             i915_render->hwprim |
+             PRIM_INDIRECT_ELTS |
+             nr_indices );
+
+   draw_arrays_generate_indices( render, start, nr, i915_render->fallback );
+out:
+   winsys->buffer_map( winsys, i915->vbo, PIPE_BUFFER_USAGE_CPU_WRITE );
+}
+
+static void
+i915_vbuf_render_draw_arrays( struct vbuf_render *render,
+                              unsigned start,
+                              uint nr )
+{
+   struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
+
+   if (i915_render->fallback) {
+      draw_arrays_fallback( render, start, nr );
+      return;
+   }
+
+   /* JB: TODO submit direct cmds */
+   draw_arrays_fallback( render, start, nr );
+}
+
+/**
+ * Used for normal and fallback emitting of indices
+ * If type is zero normal operation assumed.
+ */
+static void
+draw_generate_indices( struct vbuf_render *render,
+                       const ushort *indices,
+                       uint nr_indices,
+                       unsigned type )
+{
+   struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
+   struct i915_context *i915 = i915_render->i915;
+   unsigned i;
+
+   switch(type) {
+   case 0:
+      for (i = 0; i + 1 < nr_indices; i += 2) {
+        OUT_BATCH( (indices[i] & 0x0FFF) | ((indices[i+1] & 0x0FFF) << 16) );
+      }
+      if (i < nr_indices) {
+        OUT_BATCH( indices[i] & 0x0FFF );
+      }
+      break;
+   case PIPE_PRIM_QUADS:
+      for (i = 0; i + 3 < nr_indices; i += 4) {
+        OUT_BATCH( (indices[i+0] & 0x0FFF) | (indices[i+1] & 0x0FFF) << 16 );
+        OUT_BATCH( (indices[i+3] & 0x0FFF) | (indices[i+1] & 0x0FFF) << 16 );
+        OUT_BATCH( (indices[i+2] & 0x0FFF) | (indices[i+3] & 0x0FFF) << 16 );
+      }
+      break;
+   case PIPE_PRIM_QUAD_STRIP:
+      for (i = 0; i + 3 < nr_indices; i += 2) {
+        OUT_BATCH( (indices[i+0] & 0x0FFF) | (indices[i+1] & 0x0FFF) << 16 );
+        OUT_BATCH( (indices[i+3] & 0x0FFF) | (indices[i+2] & 0x0FFF) << 16 );
+        OUT_BATCH( (indices[i+0] & 0x0FFF) | (indices[i+3] & 0x0FFF) << 16 );
+      }
+      break;
+   default:
+      assert(0);
+      break;
+   }
+}
+
+static unsigned
+draw_calc_nr_indices( uint nr_indices, unsigned type )
+{
+   switch (type) {
+   case 0:
+      return nr_indices;
+   case PIPE_PRIM_QUADS:
+      return (nr_indices / 4) * 6;
+   case PIPE_PRIM_QUAD_STRIP:
+      return ((nr_indices - 2) / 2) * 6;
+   default:
+      assert(0);
+      return 0;
+   }
+}
+
 static void 
 i915_vbuf_render_draw( struct vbuf_render *render,
                        const ushort *indices,
@@ -147,13 +346,15 @@ i915_vbuf_render_draw( struct vbuf_render *render,
 {
    struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
    struct i915_context *i915 = i915_render->i915;
-   unsigned i;
+   struct pipe_winsys *winsys = i915->pipe.winsys;
+   unsigned save_nr_indices;
+
+   save_nr_indices = nr_indices;
+   nr_indices = draw_calc_nr_indices( nr_indices, i915_render->fallback );
 
    assert(nr_indices);
+   winsys->buffer_unmap( winsys, i915->vbo );
 
-   /* this seems to be bogus, since we validate state right after this */
-   /*assert((i915->dirty & ~I915_NEW_VBO) == 0);*/
-   
    if (i915->dirty)
       i915_update_derived( i915 );
 
@@ -170,22 +371,23 @@ i915_vbuf_render_draw( struct vbuf_render *render,
 
       if (!BEGIN_BATCH( 1 + (nr_indices + 1)/2, 1 )) {
         assert(0);
-        return;
+     goto out;
       }
    }
 
    OUT_BATCH( _3DPRIMITIVE |
-              PRIM_INDIRECT |
-              i915_render->hwprim |
-             PRIM_INDIRECT_ELTS |
-             nr_indices );
-   for (i = 0; i + 1 < nr_indices; i += 2) {
-      OUT_BATCH( indices[i] |
-                 (indices[i + 1] << 16) );
-   }
-   if (i < nr_indices) {
-      OUT_BATCH( indices[i] );
-   }
+             PRIM_INDIRECT |
+             i915_render->hwprim |
+             PRIM_INDIRECT_ELTS |
+             nr_indices );
+   draw_generate_indices( render,
+                         indices,
+                         save_nr_indices,
+                         i915_render->fallback );
+
+out:
+   winsys->buffer_map( winsys, i915->vbo, PIPE_BUFFER_USAGE_CPU_WRITE );
+   return;
 }
 
 
@@ -234,6 +436,7 @@ i915_vbuf_render_create( struct i915_context *i915 )
    i915_render->base.allocate_vertices = i915_vbuf_render_allocate_vertices;
    i915_render->base.set_primitive = i915_vbuf_render_set_primitive;
    i915_render->base.draw = i915_vbuf_render_draw;
+   i915_render->base.draw_arrays = i915_vbuf_render_draw_arrays;
    i915_render->base.release_vertices = i915_vbuf_render_release_vertices;
    i915_render->base.destroy = i915_vbuf_render_destroy;
    
@@ -258,6 +461,7 @@ struct draw_stage *i915_draw_vbuf_stage( struct i915_context *i915 )
       render->destroy(render);
       return NULL;
    }
-    
+   draw_set_render(i915->draw, render);
+
    return stage;
 }
index 10e1a84cc1270f01d1f692f227a0da62580321df..059b16be3b141595e3ac6f2cb2e5f9f178601d8d 100644 (file)
@@ -328,8 +328,8 @@ intel_create_pipe_winsys( int fd, struct _DriFreeSlabManager *fMan )
                                        DRM_BO_FLAG_READ |
                                        DRM_BO_FLAG_WRITE |
                                        DRM_BO_FLAG_MEM_TT,
-                                       32 * 4096,
-                                       1, 40, 32 * 4096 * 2, 0,
+                                       128,
+                                       6, 120, 32 * 4096, 0,
                                        fMan);
    }