failover: queiten compiler warnings
[mesa.git] / src / gallium / drivers / i915simple / i915_prim_vbuf.c
index 81293d0d1f86d1a55f5c1cce403f9ba737cc5b15..a8e97e7c306ed5d69c001c89c566d2ae0e71dc2f 100644 (file)
  */
 
 
+#include "draw/draw_context.h"
 #include "draw/draw_vbuf.h"
 #include "pipe/p_debug.h"
-#include "pipe/p_util.h"
 #include "pipe/p_inlines.h"
 #include "pipe/p_winsys.h"
+#include "util/u_math.h"
+#include "util/u_memory.h"
 
 #include "i915_context.h"
 #include "i915_reg.h"
@@ -70,6 +72,13 @@ struct i915_vbuf_render {
 
    /** Genereate a vertex list */
    unsigned fallback;
+
+   /* Stuff for the vbo */
+   struct pipe_buffer *vbo;
+   size_t vbo_size;
+   size_t vbo_offset;
+   void *vbo_ptr;
+   size_t vbo_alloc_size;
 };
 
 
@@ -106,19 +115,36 @@ i915_vbuf_render_allocate_vertices( struct vbuf_render *render,
 {
    struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
    struct i915_context *i915 = i915_render->i915;
-   struct pipe_winsys *winsys = i915->pipe.winsys;
+   struct pipe_screen *screen = i915->pipe.screen;
    size_t size = (size_t)vertex_size * (size_t)nr_vertices;
 
    /* FIXME: handle failure */
    assert(!i915->vbo);
-   i915->vbo = winsys->buffer_create(winsys, 64, I915_BUFFER_USAGE_LIT_VERTEX,
-                                     size);
 
+   if (i915_render->vbo_size > size + i915_render->vbo_offset && !i915->vbo_flushed) {
+   } else {
+      i915->vbo_flushed = 0;
+      pipe_buffer_reference(screen, &i915_render->vbo, NULL);
+   }
+
+   if (!i915_render->vbo) {
+      i915_render->vbo_size = MAX2(size, i915_render->vbo_alloc_size);
+      i915_render->vbo_offset = 0;
+      i915_render->vbo = pipe_buffer_create(screen,
+                                            64,
+                                            I915_BUFFER_USAGE_LIT_VERTEX,
+                                            i915_render->vbo_size);
+      i915_render->vbo_ptr = pipe_buffer_map(screen,
+                                             i915_render->vbo,
+                                             PIPE_BUFFER_USAGE_CPU_WRITE);
+      pipe_buffer_unmap(screen, i915_render->vbo);
+   }
+
+   i915->vbo = i915_render->vbo;
+   i915->vbo_offset = i915_render->vbo_offset;
    i915->dirty |= I915_NEW_VBO;
 
-   return winsys->buffer_map(winsys, 
-                             i915->vbo, 
-                             PIPE_BUFFER_USAGE_CPU_WRITE);
+   return (unsigned char *)i915_render->vbo_ptr + i915->vbo_offset;
 }
 
 
@@ -138,6 +164,10 @@ i915_vbuf_render_set_primitive( struct vbuf_render *render,
       i915_render->hwprim = PRIM3D_LINELIST;
       i915_render->fallback = 0;
       return TRUE;
+   case PIPE_PRIM_LINE_LOOP:
+      i915_render->hwprim = PRIM3D_LINELIST;
+      i915_render->fallback = PIPE_PRIM_LINE_LOOP;
+      return TRUE;
    case PIPE_PRIM_LINE_STRIP:
       i915_render->hwprim = PRIM3D_LINESTRIP;
       i915_render->fallback = 0;
@@ -150,6 +180,10 @@ i915_vbuf_render_set_primitive( struct vbuf_render *render,
       i915_render->hwprim = PRIM3D_TRISTRIP;
       i915_render->fallback = 0;
       return TRUE;
+   case PIPE_PRIM_TRIANGLE_FAN:
+      i915_render->hwprim = PRIM3D_TRIFAN;
+      i915_render->fallback = 0;
+      return TRUE;
    case PIPE_PRIM_QUADS:
       i915_render->hwprim = PRIM3D_TRILIST;
       i915_render->fallback = PIPE_PRIM_QUADS;
@@ -158,9 +192,12 @@ i915_vbuf_render_set_primitive( struct vbuf_render *render,
       i915_render->hwprim = PRIM3D_TRILIST;
       i915_render->fallback = PIPE_PRIM_QUAD_STRIP;
       return TRUE;
+   case PIPE_PRIM_POLYGON:
+      i915_render->hwprim = PRIM3D_POLY;
+      i915_render->fallback = 0;
+      return TRUE;
    default:
-      /* Actually, can handle a lot more just fine...  Fixme.
-       */
+      /* FIXME: Actually, can handle a lot more just fine... */
       return FALSE;
    }
 }
@@ -186,6 +223,13 @@ draw_arrays_generate_indices( struct vbuf_render *render,
       if (i < end)
         OUT_BATCH( i );
       break;
+   case PIPE_PRIM_LINE_LOOP:
+      if (nr >= 2) {
+        for (i = start + 1; i < end; i++)
+           OUT_BATCH( (i-0) | (i+0) << 16 );
+        OUT_BATCH( (i-0) | (  start) << 16 );
+      }
+      break;
    case PIPE_PRIM_QUADS:
       for (i = start; i + 3 < end; i += 4) {
         OUT_BATCH( (i+0) | (i+1) << 16 );
@@ -211,6 +255,11 @@ draw_arrays_calc_nr_indices( uint nr, unsigned type )
    switch (type) {
    case 0:
       return nr;
+   case PIPE_PRIM_LINE_LOOP:
+      if (nr >= 2)
+        return nr * 2;
+      else
+        return 0;
    case PIPE_PRIM_QUADS:
       return (nr / 4) * 6;
    case PIPE_PRIM_QUAD_STRIP:
@@ -228,10 +277,8 @@ draw_arrays_fallback( struct vbuf_render *render,
 {
    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 );
 
@@ -239,6 +286,8 @@ draw_arrays_fallback( struct vbuf_render *render,
       i915_emit_hardware_state( i915 );
 
    nr_indices = draw_arrays_calc_nr_indices( nr, i915_render->fallback );
+   if (!nr_indices)
+      return;
 
    if (!BEGIN_BATCH( 1 + (nr_indices + 1)/2, 1 )) {
       FLUSH_BATCH(NULL);
@@ -247,6 +296,7 @@ draw_arrays_fallback( struct vbuf_render *render,
        */
       i915_update_derived( i915 );
       i915_emit_hardware_state( i915 );
+      i915->vbo_flushed = 1;
 
       if (!BEGIN_BATCH( 1 + (nr_indices + 1)/2, 1 )) {
         assert(0);
@@ -260,8 +310,9 @@ draw_arrays_fallback( struct vbuf_render *render,
              nr_indices );
 
    draw_arrays_generate_indices( render, start, nr, i915_render->fallback );
+
 out:
-   winsys->buffer_map( winsys, i915->vbo, PIPE_BUFFER_USAGE_CPU_WRITE );
+   return;
 }
 
 static void
@@ -297,24 +348,31 @@ draw_generate_indices( struct vbuf_render *render,
    switch(type) {
    case 0:
       for (i = 0; i + 1 < nr_indices; i += 2) {
-        OUT_BATCH( (indices[i] & 0x0FFF) | ((indices[i+1] & 0x0FFF) << 16) );
+        OUT_BATCH( indices[i] | indices[i+1] << 16 );
       }
       if (i < nr_indices) {
-        OUT_BATCH( indices[i] & 0x0FFF );
+        OUT_BATCH( indices[i] );
+      }
+      break;
+   case PIPE_PRIM_LINE_LOOP:
+      if (nr_indices >= 2) {
+        for (i = 1; i < nr_indices; i++)
+           OUT_BATCH( indices[i-1] | indices[i] << 16 );
+        OUT_BATCH( indices[i-1] | indices[0] << 16 );
       }
       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 );
+        OUT_BATCH( indices[i+0] | indices[i+1] << 16 );
+        OUT_BATCH( indices[i+3] | indices[i+1] << 16 );
+        OUT_BATCH( indices[i+2] | indices[i+3] << 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 );
+        OUT_BATCH( indices[i+0] | indices[i+1] << 16 );
+        OUT_BATCH( indices[i+3] | indices[i+2] << 16 );
+        OUT_BATCH( indices[i+0] | indices[i+3] << 16 );
       }
       break;
    default:
@@ -329,6 +387,11 @@ draw_calc_nr_indices( uint nr_indices, unsigned type )
    switch (type) {
    case 0:
       return nr_indices;
+   case PIPE_PRIM_LINE_LOOP:
+      if (nr_indices >= 2)
+        return nr_indices * 2;
+      else
+        return 0;
    case PIPE_PRIM_QUADS:
       return (nr_indices / 4) * 6;
    case PIPE_PRIM_QUAD_STRIP:
@@ -346,14 +409,13 @@ 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;
-   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 );
+   nr_indices = draw_calc_nr_indices( nr_indices, i915_render->fallback );
+   if (!nr_indices)
+      return;
 
    if (i915->dirty)
       i915_update_derived( i915 );
@@ -368,6 +430,7 @@ i915_vbuf_render_draw( struct vbuf_render *render,
        */
       i915_update_derived( i915 );
       i915_emit_hardware_state( i915 );
+      i915->vbo_flushed = 1;
 
       if (!BEGIN_BATCH( 1 + (nr_indices + 1)/2, 1 )) {
         assert(0);
@@ -386,7 +449,6 @@ i915_vbuf_render_draw( struct vbuf_render *render,
                          i915_render->fallback );
 
 out:
-   winsys->buffer_map( winsys, i915->vbo, PIPE_BUFFER_USAGE_CPU_WRITE );
    return;
 }
 
@@ -399,11 +461,13 @@ i915_vbuf_render_release_vertices( struct vbuf_render *render,
 {
    struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
    struct i915_context *i915 = i915_render->i915;
-   struct pipe_winsys *winsys = i915->pipe.winsys;
+   size_t size = (size_t)vertex_size * (size_t)vertices_used;
 
    assert(i915->vbo);
-   winsys->buffer_unmap(winsys, i915->vbo);
-   pipe_buffer_reference(winsys, &i915->vbo, NULL);
+
+   i915_render->vbo_offset += size;
+   i915->vbo = NULL;
+   i915->dirty |= I915_NEW_VBO;
 }
 
 
@@ -422,6 +486,7 @@ static struct vbuf_render *
 i915_vbuf_render_create( struct i915_context *i915 )
 {
    struct i915_vbuf_render *i915_render = CALLOC_STRUCT(i915_vbuf_render);
+   struct pipe_screen *screen = i915->pipe.screen;
 
    i915_render->i915 = i915;
    
@@ -431,7 +496,7 @@ i915_vbuf_render_create( struct i915_context *i915 )
     * batch buffer.
     */
    i915_render->base.max_indices = 16*1024;
-   
+
    i915_render->base.get_vertex_info = i915_vbuf_render_get_vertex_info;
    i915_render->base.allocate_vertices = i915_vbuf_render_allocate_vertices;
    i915_render->base.set_primitive = i915_vbuf_render_set_primitive;
@@ -439,7 +504,19 @@ i915_vbuf_render_create( struct i915_context *i915 )
    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;
-   
+
+   i915_render->vbo_alloc_size = 128 * 4096;
+   i915_render->vbo_size = i915_render->vbo_alloc_size;
+   i915_render->vbo_offset = 0;
+   i915_render->vbo = pipe_buffer_create(screen,
+                                         64,
+                                         I915_BUFFER_USAGE_LIT_VERTEX,
+                                         i915_render->vbo_size);
+   i915_render->vbo_ptr = pipe_buffer_map(screen,
+                                          i915_render->vbo,
+                                          PIPE_BUFFER_USAGE_CPU_WRITE);
+   pipe_buffer_unmap(screen, i915_render->vbo);
+
    return &i915_render->base;
 }
 
@@ -461,6 +538,7 @@ struct draw_stage *i915_draw_vbuf_stage( struct i915_context *i915 )
       render->destroy(render);
       return NULL;
    }
+   /** TODO JB: this shouldn't be here */
    draw_set_render(i915->draw, render);
 
    return stage;