Track hardware vertex buffer state changes.
authorJosé Fonseca <jrfonseca@tungstengraphics.com>
Tue, 6 Nov 2007 19:16:40 +0000 (19:16 +0000)
committerJosé Fonseca <jrfonseca@tungstengraphics.com>
Wed, 7 Nov 2007 13:40:35 +0000 (13:40 +0000)
src/mesa/pipe/i915simple/i915_context.h
src/mesa/pipe/i915simple/i915_prim_vbuf.c
src/mesa/pipe/i915simple/i915_state_emit.c
src/mesa/pipe/i915simple/i915_state_immediate.c

index 5c748ea..ee430eb 100644 (file)
@@ -109,7 +109,7 @@ struct i915_state
 
    /** Describes the current hardware vertex layout */
    struct vertex_info vertex_info;
-
+   
    unsigned id;                        /* track lost context events */
 };
 
@@ -185,6 +185,9 @@ struct i915_context
 
    unsigned *batch_start;
 
+   /** Vertex buffer */
+   struct pipe_buffer_handle *vbo;
+
    struct i915_state current;
    unsigned hardware_dirty;
    
@@ -211,6 +214,7 @@ struct i915_context
 #define I915_NEW_SAMPLER       0x400
 #define I915_NEW_TEXTURE       0x800
 #define I915_NEW_CONSTANTS     0x1000
+#define I915_NEW_VBO           0x2000
 
 
 /* Driver's internally generated state flags:
index 5499315..caae6c6 100644 (file)
@@ -82,8 +82,6 @@ struct vbuf_stage {
    ushort *element_map;
    unsigned nr_elements;
 
-   struct pipe_buffer_handle *buf; 
-   
    unsigned prim;
 
    struct i915_context *i915;   
@@ -279,7 +277,6 @@ static void vbuf_draw( struct draw_stage *stage )
    unsigned vertex_size = i915->current.vertex_info.size * 4; /* in bytes */
    unsigned hwprim;
    unsigned i;
-   unsigned *ptr;
    
    switch(vbuf->prim) {
    case PIPE_PRIM_POINTS:
@@ -304,7 +301,7 @@ static void vbuf_draw( struct draw_stage *stage )
    if (i915->hardware_dirty)
       i915_emit_hardware_state( i915 );
 
-   if (!BEGIN_BATCH( 4 + (nr + 1)/2, 1 )) {
+   if (!BEGIN_BATCH( 1 + (nr + 1)/2, 1 )) {
       FLUSH_BATCH();
 
       /* Make sure state is re-emitted after a flush: 
@@ -312,20 +309,12 @@ static void vbuf_draw( struct draw_stage *stage )
       i915_update_derived( i915 );
       i915_emit_hardware_state( i915 );
 
-      if (!BEGIN_BATCH( 4 + (nr + 1)/2, 1 )) {
+      if (!BEGIN_BATCH( 1 + (nr + 1)/2, 1 )) {
         assert(0);
         return;
       }
    }
 
-   /* FIXME: don't do this every time */
-   OUT_BATCH( _3DSTATE_LOAD_STATE_IMMEDIATE_1 | 
-             I1_LOAD_S(0) |
-             I1_LOAD_S(1) |
-             (1));
-   OUT_RELOC( vbuf->buf, I915_BUFFER_ACCESS_READ, 0 );
-   OUT_BATCH( ((vertex_size/4) << 24) |  /* vertex size in dwords */
-              ((vertex_size/4) << 16) ); /* vertex pitch in dwords */
    OUT_BATCH( _3DPRIMITIVE |
               PRIM_INDIRECT |
              hwprim |
@@ -361,7 +350,7 @@ static void vbuf_flush_elements( struct draw_stage *stage )
       
       vbuf->nr_elements = 0;
 
-      winsys->buffer_unmap(winsys, vbuf->buf);
+      winsys->buffer_unmap(winsys, i915->vbo);
 
       vbuf->nr_vertices = 0;
 
@@ -375,13 +364,16 @@ static void vbuf_flush_elements( struct draw_stage *stage )
    }
 
    /* FIXME: handle failure */
-   if(!vbuf->buf)
-      vbuf->buf = winsys->buffer_create(winsys, 64);
-   winsys->buffer_data( winsys, vbuf->buf
+   if(!i915->vbo)
+      i915->vbo = winsys->buffer_create(winsys, 64);
+   winsys->buffer_data( winsys, i915->vbo
                         VBUF_SIZE, NULL, 
                         I915_BUFFER_USAGE_LIT_VERTEX );
+   
+   i915->dirty |= I915_NEW_VBO;
+   
    vbuf->vertex_map = winsys->buffer_map(winsys, 
-                                         vbuf->buf
+                                         i915->vbo
                                          PIPE_BUFFER_FLAG_WRITE );
    vbuf->vertex_ptr = vbuf->vertex_map;
 
@@ -394,7 +386,9 @@ static void vbuf_flush_elements( struct draw_stage *stage )
 static void vbuf_begin( struct draw_stage *stage )
 {
    struct vbuf_stage *vbuf = vbuf_stage(stage);
+   struct i915_context *i915 = vbuf->i915;
 
+   assert(!i915->dirty);
    vbuf->vertex_size = vbuf->i915->current.vertex_info.size * 4;
 }
 
index 29fe9d9..ee44e52 100644 (file)
@@ -62,7 +62,7 @@ i915_emit_hardware_state(struct i915_context *i915 )
 {
    /* XXX: there must be an easier way */
    const unsigned dwords = ( 14 + 
-                             5 + 
+                             7 + 
                              I915_MAX_DYNAMIC + 
                              8 + 
                              2 + I915_TEX_UNITS*3 + 
@@ -72,7 +72,7 @@ i915_emit_hardware_state(struct i915_context *i915 )
                              6 
                            ) * 3/2; /* plus 50% margin */
    const unsigned relocs = ( I915_TEX_UNITS +
-                            2
+                            3
                            ) * 3/2; /* plus 50% margin */
 
 #if 0
@@ -134,16 +134,26 @@ i915_emit_hardware_state(struct i915_context *i915 )
       OUT_BATCH(0);
    }
    
-   /* 5 dwords, 0 relocs */
+   /* 7 dwords, 1 relocs */
    if (i915->hardware_dirty & I915_HW_IMMEDIATE)
    {
       OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | 
+               I1_LOAD_S(0) |
+               I1_LOAD_S(1) |
                I1_LOAD_S(2) |
                I1_LOAD_S(4) |
                I1_LOAD_S(5) |
                I1_LOAD_S(6) | 
-               (3));
+               (5));
       
+      if(i915->vbo)
+         OUT_RELOC(i915->vbo,
+                   I915_BUFFER_ACCESS_READ,
+                   i915->current.immediate[I915_IMMEDIATE_S0]);
+      else
+        /* FIXME: we should not do this */
+        OUT_BATCH(0);
+      OUT_BATCH(i915->current.immediate[I915_IMMEDIATE_S1]);
       OUT_BATCH(i915->current.immediate[I915_IMMEDIATE_S2]);
       OUT_BATCH(i915->current.immediate[I915_IMMEDIATE_S4]);
       OUT_BATCH(i915->current.immediate[I915_IMMEDIATE_S5]);
index 479d72a..d830bb7 100644 (file)
 
 
 /***********************************************************************
+ * S0,S1: Vertex buffer state.  
+ */
+static void upload_S0S1(struct i915_context *i915)
+{
+   unsigned LIS0, LIS1;
+
+   /* INTEL_NEW_VBO */
+   /* TODO: re-use vertex buffers here? */
+   LIS0 = 0;
+
+   /* INTEL_NEW_VERTEX_SIZE -- do this where the vertex size is calculated! 
+    */
+   {
+      unsigned vertex_size = i915->current.vertex_info.size;
+
+      LIS1 = ((vertex_size << 24) |
+             (vertex_size << 16));
+   }
+
+   /* INTEL_NEW_VBO */
+   /* TODO: use a vertex generation number to track vbo changes */
+   if (1 ||
+       i915->current.immediate[I915_IMMEDIATE_S0] != LIS0 ||
+       i915->current.immediate[I915_IMMEDIATE_S1] != LIS1) 
+   {
+      i915->current.immediate[I915_IMMEDIATE_S0] = LIS0;
+      i915->current.immediate[I915_IMMEDIATE_S1] = LIS1;
+      i915->hardware_dirty |= I915_HW_IMMEDIATE;
+   }
+}
+
+const struct i915_tracked_state i915_upload_S0S1 = {
+   .dirty = I915_NEW_VBO | I915_NEW_VERTEX_FORMAT,
+   .update = upload_S0S1
+};
+
+
+
+
+/***********************************************************************
  * S4: Vertex format, rasterization state
  */
 static void upload_S2S4(struct i915_context *i915)
@@ -166,6 +206,7 @@ const struct i915_tracked_state i915_upload_S7 = {
 
 
 static const struct i915_tracked_state *atoms[] = {
+   &i915_upload_S0S1,
    &i915_upload_S2S4,
    &i915_upload_S5,
    &i915_upload_S6,