llvmpipe: bin state-change commands
authorBrian Paul <brianp@vmware.com>
Fri, 4 Dec 2009 18:50:40 +0000 (11:50 -0700)
committerBrian Paul <brianp@vmware.com>
Fri, 4 Dec 2009 18:50:43 +0000 (11:50 -0700)
Previously, each triangle had a pointer to the state to use for shading.
Now we insert state-change commands into the bins.  When we execute one
of those commands we just update a 'current state' pointer and use that
pointer when calling the jit shader.

When inserting state-change commands into a bin we check if the previous
command was also a state-change command and simply replace it.  This
avoids accumulating useless/redundant state-change commands.

src/gallium/drivers/llvmpipe/lp_rast.c
src/gallium/drivers/llvmpipe/lp_rast.h
src/gallium/drivers/llvmpipe/lp_rast_priv.h
src/gallium/drivers/llvmpipe/lp_setup.c
src/gallium/drivers/llvmpipe/lp_setup_context.h
src/gallium/drivers/llvmpipe/lp_setup_tri.c

index d5fe6e936993b123cee6285161b2b6ec7284f8c1..8f37a28e8758dda5a90682915e148628b7f6117c 100644 (file)
@@ -237,9 +237,10 @@ void lp_rast_set_state( struct lp_rasterizer *rast,
 {
    const struct lp_rast_state *state = arg.set_state;
 
-   RAST_DEBUG("%s\n", __FUNCTION__);
+   RAST_DEBUG("%s %p\n", __FUNCTION__, (void *) state);
 
-   /* XXX to do */
+   /* just set the current state pointer for this rasterizer */
+   rast->current_state = state;
 }
 
 
@@ -279,7 +280,7 @@ void lp_rast_shade_quads( struct lp_rasterizer *rast,
                           unsigned mask)
 {
 #if 1
-   const struct lp_rast_state *state = inputs->state;
+   const struct lp_rast_state *state = rast->current_state;
    struct lp_rast_tile *tile = &rast->tile;
    void *color;
    void *depth;
@@ -287,6 +288,8 @@ void lp_rast_shade_quads( struct lp_rasterizer *rast,
    unsigned ix, iy;
    int block_offset;
 
+   assert(state);
+
    /* Sanity checks */
    assert(x % TILE_VECTOR_WIDTH == 0);
    assert(y % TILE_VECTOR_HEIGHT == 0);
index 435993d44d26551fd693a5ce92703cfdf660265d..e9a1fa49add58a12153422c3cab46dd3b0a4457a 100644 (file)
@@ -55,18 +55,13 @@ struct lp_rast_state {
 
 };
 
-/* Coefficients necessary to run the shader at a given location:
+
+/**
+ * Coefficients necessary to run the shader at a given location.
+ * First coefficient is position.
+ * These pointers point into the bin data buffer.
  */
 struct lp_rast_shader_inputs {
-
-   /* Current rasterizer state:
-    */
-   const struct lp_rast_state *state;
-
-   /* Attribute interpolation:
-    * First coefficient is position.
-    * These pointers point into the bin data buffer.
-    */
    float (*a0)[4];
    float (*dadx)[4];
    float (*dady)[4];
index 4c0dfe2282daa08d6187d83656442e312eaf66fe..98111edff7268609b1b6fa48f17f45ca22048ca6 100644 (file)
@@ -86,6 +86,8 @@ struct lp_rasterizer
       unsigned y;
       unsigned mask;
    } blocks[256];
+
+   const struct lp_rast_state *current_state;
 };
 
 
index fc7f4f6778edb48aa6cf7b40e1ce8aa347a25195..11a9fd2637c825d03de35078ddc2ab336bef4b6b 100644 (file)
@@ -155,6 +155,34 @@ static void reset_context( struct setup_context *setup )
 }
 
 
+/**
+ * Return last command in the bin
+ */
+static lp_rast_cmd
+lp_get_last_command( const struct cmd_bin *bin )
+{
+   const struct cmd_block *tail = bin->commands.tail;
+   const unsigned i = tail->count;
+   if (i > 0)
+      return tail->cmd[i - 1];
+   else
+      return NULL;
+}
+
+
+/**
+ * Replace the arg of the last command in the bin.
+ */
+static void
+lp_replace_last_command_arg( struct cmd_bin *bin,
+                             const union lp_rast_cmd_arg arg )
+{
+   struct cmd_block *tail = bin->commands.tail;
+   const unsigned i = tail->count;
+   assert(i > 0);
+   tail->arg[i - 1] = arg;
+}
+
 
 
 /* Add a command to all active bins.
@@ -170,6 +198,32 @@ static void bin_everywhere( struct setup_context *setup,
 }
 
 
+/**
+ * Put a state-change command into all bins.
+ * If we find that the last command in a bin was also a state-change
+ * command, we can simply replace that one with the new one.
+ */
+static void
+bin_state_command( struct setup_context *setup,
+                   lp_rast_cmd cmd,
+                   const union lp_rast_cmd_arg arg )
+{
+   unsigned i, j;
+   for (i = 0; i < setup->tiles_x; i++) {
+      for (j = 0; j < setup->tiles_y; j++) {
+         struct cmd_bin *bin = &setup->tile[i][j];
+         lp_rast_cmd last_cmd = lp_get_last_command(bin);
+         if (last_cmd == cmd) {
+            lp_replace_last_command_arg(bin, arg);
+         }
+         else {
+            bin_command( bin, cmd, arg );
+         }
+      }
+   }
+}
+
+
 /** Rasterize commands for a single bin */
 static void
 rasterize_bin( struct lp_rasterizer *rast,
@@ -234,31 +288,6 @@ begin_binning( struct setup_context *setup )
 {
    SETUP_DEBUG("%s\n", __FUNCTION__);
 
-   if (!setup->fb.cbuf && !setup->fb.zsbuf) {
-      setup->fb.width = 0;
-      setup->fb.height = 0;
-   }
-   else if (!setup->fb.zsbuf) {
-      setup->fb.width = setup->fb.cbuf->width;
-      setup->fb.height = setup->fb.cbuf->height;
-   }
-   else if (!setup->fb.cbuf) {
-      setup->fb.width = setup->fb.zsbuf->width;
-      setup->fb.height = setup->fb.zsbuf->height;
-   }
-   else {
-      /* XXX: not sure what we're really supposed to do for
-       * mis-matched color & depth buffer sizes.
-       */
-      setup->fb.width = MIN2(setup->fb.cbuf->width,
-                             setup->fb.zsbuf->width);
-      setup->fb.height = MIN2(setup->fb.cbuf->height,
-                              setup->fb.zsbuf->height);
-   }
-
-   setup->tiles_x = align(setup->fb.width, TILE_SIZE) / TILE_SIZE;
-   setup->tiles_y = align(setup->fb.height, TILE_SIZE) / TILE_SIZE;
-
    if (setup->fb.cbuf) {
       if (setup->clear.flags & PIPE_CLEAR_COLOR)
          bin_everywhere( setup, 
@@ -352,8 +381,34 @@ lp_setup_bind_framebuffer( struct setup_context *setup,
 
    pipe_surface_reference( &setup->fb.cbuf, color );
    pipe_surface_reference( &setup->fb.zsbuf, zstencil );
+
+   if (!setup->fb.cbuf && !setup->fb.zsbuf) {
+      setup->fb.width = 0;
+      setup->fb.height = 0;
+   }
+   else if (!setup->fb.zsbuf) {
+      setup->fb.width = setup->fb.cbuf->width;
+      setup->fb.height = setup->fb.cbuf->height;
+   }
+   else if (!setup->fb.cbuf) {
+      setup->fb.width = setup->fb.zsbuf->width;
+      setup->fb.height = setup->fb.zsbuf->height;
+   }
+   else {
+      /* XXX: not sure what we're really supposed to do for
+       * mis-matched color & depth buffer sizes.
+       */
+      setup->fb.width = MIN2(setup->fb.cbuf->width,
+                             setup->fb.zsbuf->width);
+      setup->fb.height = MIN2(setup->fb.cbuf->height,
+                              setup->fb.zsbuf->height);
+   }
+
+   setup->tiles_x = align(setup->fb.width, TILE_SIZE) / TILE_SIZE;
+   setup->tiles_y = align(setup->fb.height, TILE_SIZE) / TILE_SIZE;
 }
 
+
 void
 lp_setup_clear( struct setup_context *setup,
                 const float *color,
@@ -608,12 +663,10 @@ lp_setup_update_shader_state( struct setup_context *setup )
                    sizeof setup->fs.current);
             setup->fs.stored = stored;
 
-#if 0
             /* put the state-set command into all bins */
-            bin_everywhere( setup, 
-                            lp_rast_set_state, 
-                            *setup->fs.stored );
-#endif
+            bin_state_command( setup, 
+                               lp_rast_set_state, 
+                               lp_rast_arg_state(setup->fs.stored) );
          }
       }
    }
index 1715048f7602d25b222176f87247e613aa0dc6a7..7c7c34f3f7612e2ea6737ed01fd08279e7f6929d 100644 (file)
@@ -76,10 +76,14 @@ struct cmd_block_list {
  */
 struct cmd_bin {
    struct cmd_block_list commands;
-   struct lp_rast_state *curr_state;
 };
    
 
+/**
+ * This stores bulk data which is shared by all bins.
+ * Examples include triangle data and state data.  The commands in
+ * the per-tile bins will point to chunks of data in this structure.
+ */
 struct data_block_list {
    struct data_block *head;
    struct data_block *tail;
@@ -241,5 +245,4 @@ static INLINE void bin_command( struct cmd_bin *bin,
 }
 
 
-
 #endif
index 74ed0a9e8fb758511a17cf15fbea7dc22f6ddbf1..48733a599b74206781941e78908c1a79c937d381 100644 (file)
@@ -295,8 +295,6 @@ do_triangle_ccw(struct setup_context *setup,
       return;
    }
 
-   tri->inputs.state = setup->fs.stored;
-
    /* 
     */
    tri->oneoverarea = ((float)FIXED_ONE) / (float)area;