a bit more work for optimizing clears in tile cache (not enabled yet)
authorBrian <brian.paul@tungstengraphics.com>
Wed, 24 Oct 2007 00:49:19 +0000 (18:49 -0600)
committerBrian <brian.paul@tungstengraphics.com>
Wed, 24 Oct 2007 18:32:42 +0000 (12:32 -0600)
src/mesa/drivers/x11/xm_surface.c
src/mesa/pipe/softpipe/sp_clear.c
src/mesa/pipe/softpipe/sp_tile_cache.c
src/mesa/pipe/softpipe/sp_tile_cache.h

index b2ef70ea90d4572052672eef9b0eb95b65ef19cc..f83c7917c4dc9bdfd1f27a8dacd0efb20d9391c7 100644 (file)
@@ -46,6 +46,7 @@
 #include "pipe/p_defines.h"
 #include "pipe/softpipe/sp_context.h"
 #include "pipe/softpipe/sp_clear.h"
+#include "pipe/softpipe/sp_tile_cache.h"
 #include "state_tracker/st_context.h"
 
 
@@ -219,6 +220,19 @@ xmesa_clear(struct pipe_context *pipe, struct pipe_surface *ps, GLuint value)
     */
    pipe->flush(pipe, 0);
 
+   {
+      struct softpipe_context *sp = softpipe_context(pipe);
+      struct softpipe_surface *sps = softpipe_surface(ps);
+      if (sps == sp_tile_cache_get_surface(sp->cbuf_cache[0])) {
+         float clear[4];
+         clear[0] = 0.2; /* XXX hack */
+         clear[1] = 0.2;
+         clear[2] = 0.2;
+         clear[3] = 0.2;
+         sp_tile_cache_clear(sp->cbuf_cache[0], clear);
+      }
+   }
+
    if (xrb && xrb->ximage) {
       /* clearing back color buffer */
       GET_CURRENT_CONTEXT(ctx);
index 96bca4b171b86b5ddbc35ce618c150b0515fdef3..08b87417aa4f6a510a7cac5c905b6be22a7bd8a4 100644 (file)
@@ -47,7 +47,7 @@ softpipe_clear(struct pipe_context *pipe, struct pipe_surface *ps,
                unsigned clearValue)
 {
    struct softpipe_context *softpipe = softpipe_context(pipe);
-   /*struct softpipe_surface *sps = softpipe_surface(ps);*/
+   struct softpipe_surface *sps = softpipe_surface(ps);
    unsigned x, y, w, h;
 
    softpipe_update_derived(softpipe); /* not needed?? */
@@ -66,9 +66,23 @@ softpipe_clear(struct pipe_context *pipe, struct pipe_surface *ps,
    assert(w <= ps->region->pitch);
    assert(h <= ps->region->height);
 
-   /* XXX skip this fill if we're using tile cache */
+   if (sps == sp_tile_cache_get_surface(softpipe->zbuf_cache)) {
+      float clear[4];
+      clear[0] = 1.0; /* XXX hack */
+      sp_tile_cache_clear(softpipe->zbuf_cache, clear);
+   }
+   else if (sps == sp_tile_cache_get_surface(softpipe->cbuf_cache[0])) {
+      float clear[4];
+      clear[0] = 0.2; /* XXX hack */
+      clear[1] = 0.2; /* XXX hack */
+      clear[2] = 0.2; /* XXX hack */
+      clear[3] = 0.2; /* XXX hack */
+      sp_tile_cache_clear(softpipe->cbuf_cache[0], clear);
+   }
+
    pipe->region_fill(pipe, ps->region, 0, x, y, w, h, clearValue);
 
+
 #if 0
    sp_clear_tile_cache(sps, clearValue);
 #endif
index 1e287c91a41ac81b068240f0d014d6473c508fb3..129785d26da39f8292dcb7e0f584edfcb64e81d4 100644 (file)
@@ -37,6 +37,7 @@
 #include "sp_surface.h"
 #include "sp_tile_cache.h"
 
+#define CLEAR_OPTIMIZATION 0
 
 #define NUM_ENTRIES 20
 
@@ -52,6 +53,7 @@ struct softpipe_tile_cache
    struct pipe_mipmap_tree *texture;  /**< if caching a texture */
    struct softpipe_cached_tile entries[NUM_ENTRIES];
    uint clear_flags[(MAX_WIDTH / TILE_SIZE) * (MAX_HEIGHT / TILE_SIZE) / 32];
+   float clear_value[4];
 };
 
 
@@ -73,6 +75,7 @@ is_clear_flag_set(const uint *bitvec, int x, int y)
    x /= TILE_SIZE;
    y /= TILE_SIZE;
    pos = y * (MAX_WIDTH / TILE_SIZE) + x;
+   assert(pos / 32 < (MAX_WIDTH / TILE_SIZE) * (MAX_HEIGHT / TILE_SIZE) / 32);
    bit = bitvec[pos / 32] & (1 << (pos & 31));
    return bit;
 }
@@ -85,6 +88,7 @@ clear_clear_flag(uint *bitvec, int x, int y)
    x /= TILE_SIZE;
    y /= TILE_SIZE;
    pos = y * (MAX_WIDTH / TILE_SIZE) + x;
+   assert(pos / 32 < (MAX_WIDTH / TILE_SIZE) * (MAX_HEIGHT / TILE_SIZE) / 32);
    bitvec[pos / 32] &= ~(1 << (pos & 31));
 }
    
@@ -125,6 +129,13 @@ sp_tile_cache_set_surface(struct softpipe_tile_cache *tc,
 }
 
 
+struct softpipe_surface *
+sp_tile_cache_get_surface(struct softpipe_tile_cache *tc)
+{
+   return tc->surface;
+}
+
+
 void
 sp_tile_cache_set_texture(struct softpipe_tile_cache *tc,
                           struct pipe_mipmap_tree *texture)
@@ -174,6 +185,7 @@ sp_flush_tile_cache(struct softpipe_tile_cache *tc)
          inuse++;
       }
    }
+
    /*
    printf("flushed tiles in use: %d\n", inuse);
    */
@@ -198,17 +210,9 @@ sp_get_cached_tile(struct softpipe_tile_cache *tc, int x, int y)
    const int pos = CACHE_POS(x, y);
    struct softpipe_cached_tile *tile = tc->entries + pos;
 
-   /*
-   printf("output %d, %d at pos %d\n", x, y, pos);
-   */
-
    if (tile_x != tile->x ||
        tile_y != tile->y) {
 
-      /*
-      printf("new tile at %d, %d, pos %d\n", tile_x, tile_y, pos);
-      */
-
       if (tile->x != -1) {
          /* put dirty tile back in framebuffer */
          if (is_depth_stencil) {
@@ -223,23 +227,63 @@ sp_get_cached_tile(struct softpipe_tile_cache *tc, int x, int y)
          }
       }
 
-      if (0/*is_clear_flag_set(tc->clear_flags, x, y)*/) {
+      if (is_clear_flag_set(tc->clear_flags, x, y)) {
          /* don't get tile from framebuffer, just clear it */
-#if 0
-         printf("clear tile\n");
          uint i, j;
-         for (i = 0; i < TILE_SIZE; i++) {
-            for (j = 0; j < TILE_SIZE; j++) {
-               tile->data.color[i][j][0] = 0.5;
-               tile->data.color[i][j][1] = 0.5;
-               tile->data.color[i][j][2] = 0.5;
-               tile->data.color[i][j][3] = 0.5;
+         /* XXX these loops could be optimized */
+         switch (ps->format) {
+         case PIPE_FORMAT_U_Z16:
+            {
+               ushort clear_val = (ushort) (tc->clear_value[0] * 0xffff);
+               for (i = 0; i < TILE_SIZE; i++) {
+                  for (j = 0; j < TILE_SIZE; j++) {
+                     tile->data.depth16[i][j] = clear_val;
+                  }
+               }
+            }
+            break;
+         case PIPE_FORMAT_U_Z32:
+            {
+               uint clear_val = (uint) (tc->clear_value[0] * 0xffffffff);
+               for (i = 0; i < TILE_SIZE; i++) {
+                  for (j = 0; j < TILE_SIZE; j++) {
+                     tile->data.depth32[i][j] = clear_val;
+                  }
+               }
+            }
+            break;
+         case PIPE_FORMAT_S8_Z24:
+            {
+               uint clear_val = (uint) (tc->clear_value[0] * 0xffffff);
+               clear_val |= ((uint) tc->clear_value[1]) << 24;
+               for (i = 0; i < TILE_SIZE; i++) {
+                  for (j = 0; j < TILE_SIZE; j++) {
+                     tile->data.depth32[i][j] = clear_val;
+                  }
+               }
+            }
+            break;
+         case PIPE_FORMAT_U_S8:
+            {
+               ubyte clear_val = (uint) tc->clear_value[0];
+               for (i = 0; i < TILE_SIZE; i++) {
+                  for (j = 0; j < TILE_SIZE; j++) {
+                     tile->data.stencil8[i][j] = clear_val;
+                  }
+               }
+            }
+            break;
+         default:
+            /* color */
+            for (i = 0; i < TILE_SIZE; i++) {
+               for (j = 0; j < TILE_SIZE; j++) {
+                  tile->data.color[i][j][0] = tc->clear_value[0];
+                  tile->data.color[i][j][1] = tc->clear_value[1];
+                  tile->data.color[i][j][2] = tc->clear_value[2];
+                  tile->data.color[i][j][3] = tc->clear_value[3];
+               }
             }
          }
-#else
-         (void) is_clear_flag_set;
-#endif
-         memset(tile->data.color, 0, sizeof(tile->data.color));
          clear_clear_flag(tc->clear_flags, x, y);
       }
       else {
@@ -322,10 +366,22 @@ sp_get_cached_tile_tex(struct pipe_context *pipe,
 }
 
 
-
+/**
+ * When a whole surface is being cleared to a value we can avoid
+ * fetching tiles above.
+ * Save the color and set a 'clearflag' for each tile of the screen.
+ */
 void
-sp_clear_tile_cache(struct softpipe_tile_cache *tc, unsigned clearval)
+sp_tile_cache_clear(struct softpipe_tile_cache *tc, const float value[4])
 {
-   (void) clearval; /* XXX use this */
+   tc->clear_value[0] = value[0];
+   tc->clear_value[1] = value[1];
+   tc->clear_value[2] = value[2];
+   tc->clear_value[3] = value[3];
+
+#if CLEAR_OPTIMIZATION
    memset(tc->clear_flags, 255, sizeof(tc->clear_flags));
+#else
+   memset(tc->clear_flags, 0, sizeof(tc->clear_flags));
+#endif
 }
index a1cc387a12d506298a5cb35c5f70c92812be2e3d..15245a2efba9e2f550e49a2d1578c319d2fef38a 100644 (file)
@@ -29,7 +29,7 @@
 #define SP_TILE_CACHE_H
 
 
-#include "p_compiler.h"
+#include "pipe/p_compiler.h"
 
 
 struct softpipe_context;
@@ -66,6 +66,9 @@ extern void
 sp_tile_cache_set_surface(struct softpipe_tile_cache *tc,
                           struct softpipe_surface *sps);
 
+extern struct softpipe_surface *
+sp_tile_cache_get_surface(struct softpipe_tile_cache *tc);
+
 extern void
 sp_tile_cache_set_texture(struct softpipe_tile_cache *tc,
                           struct pipe_mipmap_tree *texture);
@@ -74,7 +77,7 @@ extern void
 sp_flush_tile_cache(struct softpipe_tile_cache *tc);
 
 extern void
-sp_clear_tile_cache(struct softpipe_tile_cache *tc, unsigned clearval);
+sp_tile_cache_clear(struct softpipe_tile_cache *tc, const float value[4]);
 
 extern struct softpipe_cached_tile *
 sp_get_cached_tile(struct softpipe_tile_cache *tc, int x, int y);