Finish unifying the surface and texture tile caches.
authorBrian <brian.paul@tungstengraphics.com>
Mon, 22 Oct 2007 15:37:26 +0000 (09:37 -0600)
committerBrian <brian.paul@tungstengraphics.com>
Mon, 22 Oct 2007 15:37:26 +0000 (09:37 -0600)
src/mesa/pipe/softpipe/sp_context.c
src/mesa/pipe/softpipe/sp_context.h
src/mesa/pipe/softpipe/sp_quad_fs.c
src/mesa/pipe/softpipe/sp_state_sampler.c
src/mesa/pipe/softpipe/sp_tex_sample.c
src/mesa/pipe/softpipe/sp_tile_cache.c
src/mesa/pipe/softpipe/sp_tile_cache.h
src/mesa/pipe/tgsi/exec/tgsi_exec.h

index 10c53a257bd1e9294dbc314ccda0f6f4ce9c705a..bf61019f624b39113494124a44486412bd3519ab 100644 (file)
@@ -343,6 +343,20 @@ struct pipe_context *softpipe_create( struct pipe_winsys *pipe_winsys,
    softpipe->pipe.mipmap_tree_layout = softpipe_mipmap_tree_layout;
    softpipe->pipe.get_tex_surface = softpipe_get_tex_surface;
 
+   /*
+    * Alloc caches for accessing drawing surfaces and textures.
+    * Must be before quad stage setup!
+    */
+   for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++)
+      softpipe->cbuf_cache[i] = sp_create_tile_cache();
+   softpipe->zbuf_cache = sp_create_tile_cache();
+   softpipe->sbuf_cache_sep = sp_create_tile_cache();
+   softpipe->sbuf_cache = softpipe->sbuf_cache_sep; /* initial value */
+
+   for (i = 0; i < PIPE_MAX_SAMPLERS; i++)
+      softpipe->tex_cache[i] = sp_create_tile_cache();
+
+
    /* setup quad rendering stages */
    softpipe->quad.polygon_stipple = sp_quad_polygon_stipple_stage(softpipe);
    softpipe->quad.shade = sp_quad_shade_stage(softpipe);
@@ -380,11 +394,5 @@ struct pipe_context *softpipe_create( struct pipe_winsys *pipe_winsys,
    sp_init_region_functions(softpipe);
    sp_init_surface_functions(softpipe);
 
-   for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++)
-      softpipe->cbuf_cache[i] = sp_create_tile_cache();
-   softpipe->zbuf_cache = sp_create_tile_cache();
-   softpipe->sbuf_cache_sep = sp_create_tile_cache();
-   softpipe->sbuf_cache = softpipe->sbuf_cache_sep; /* initial value */
-
    return &softpipe->pipe;
 }
index ea05f80d59ab22cf248a812e8b00aa2233398cdd..3e77bd6b8561e541dee3b0ef9ecf34dd3c2c74e5 100644 (file)
@@ -163,6 +163,8 @@ struct softpipe_context {
    /** This either points to zbuf_cache or sbuf_cache_sep */
    struct softpipe_tile_cache *sbuf_cache;
 
+   struct softpipe_tile_cache *tex_cache[PIPE_MAX_SAMPLERS];
+
    int use_sse : 1;
 };
 
index c850f08c57556f64816c066641cbb870085c3c25..674e02d0f430a06d015528b783448bfab62f165b 100644 (file)
@@ -153,19 +153,10 @@ static void shade_begin(struct quad_stage *qs)
    struct softpipe_context *softpipe = qs->softpipe;
    unsigned i, entry;
 
+   /* set TGSI sampler state that varies */
    for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
       qss->samplers[i].state = softpipe->sampler[i];
       qss->samplers[i].texture = softpipe->texture[i];
-      qss->samplers[i].get_samples = sp_get_samples;
-      qss->samplers[i].pipe = &softpipe->pipe;
-      /* init cache info here */
-      for (entry = 0; entry < TEX_CACHE_NUM_ENTRIES; entry++) {
-         qss->samplers[i].cache[entry].x = -1;
-         qss->samplers[i].cache[entry].y = -1;
-         qss->samplers[i].cache[entry].level = -1;
-         qss->samplers[i].cache[entry].face = -1;
-         qss->samplers[i].cache[entry].zslice = -1;
-      }
    }
 
    /* XXX only do this if the fragment shader changes... */
@@ -196,6 +187,7 @@ static void shade_begin(struct quad_stage *qs)
 struct quad_stage *sp_quad_shade_stage( struct softpipe_context *softpipe )
 {
    struct quad_shade_stage *qss = CALLOC_STRUCT(quad_shade_stage);
+   uint i;
 
    /* allocate storage for program inputs/outputs, aligned to 16 bytes */
    qss->inputs = malloc(PIPE_ATTRIB_MAX * sizeof(*qss->inputs) + 16);
@@ -207,5 +199,13 @@ struct quad_stage *sp_quad_shade_stage( struct softpipe_context *softpipe )
    qss->stage.begin = shade_begin;
    qss->stage.run = shade_quad;
 
+   /* set TGSI sampler state that's constant */
+   for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
+      assert(softpipe->tex_cache[i]);
+      qss->samplers[i].get_samples = sp_get_samples;
+      qss->samplers[i].pipe = &softpipe->pipe;
+      qss->samplers[i].cache = softpipe->tex_cache[i];
+   }
+
    return &qss->stage;
 }
index 4084e9163f3a51df6ef6e146a56c69964bd5877c..c00e815f2d4e92b5db25389a9f1ce98dc8021c5c 100644 (file)
@@ -31,6 +31,8 @@
 
 #include "sp_context.h"
 #include "sp_state.h"
+#include "sp_tile_cache.h"
+
 
 void *
 softpipe_create_sampler_state(struct pipe_context *pipe,
@@ -72,5 +74,7 @@ softpipe_set_texture_state(struct pipe_context *pipe,
    assert(unit < PIPE_MAX_SAMPLERS);
    softpipe->texture[unit] = texture;  /* ptr, not struct */
 
+   sp_tile_cache_set_texture(softpipe->tex_cache[unit], texture);
+
    softpipe->dirty |= SP_NEW_TEXTURE;
 }
index 64cb94d94419f00a1e34b1e639dc1fbb3624f809..385b8042c323b4d98c8ddc7570a2ee5dfa84c41b 100644 (file)
@@ -36,6 +36,7 @@
 #include "sp_context.h"
 #include "sp_surface.h"
 #include "sp_tex_sample.h"
+#include "sp_tile_cache.h"
 #include "pipe/p_context.h"
 #include "pipe/p_defines.h"
 #include "pipe/p_util.h"
@@ -522,28 +523,6 @@ choose_mipmap_levels(struct tgsi_sampler *sampler,
 }
 
 
-
-/**
- * Given the texture face, level, zslice, x and y values, compute
- * the cache entry position/index where we'd hope to find the
- * cached texture tile.
- * This is basically a direct-map cache.
- * XXX There's probably lots of ways in which we can improve
- * texture caching....
- */
-static unsigned
-compute_cache_pos(unsigned face, unsigned level, unsigned zslice,
-                  int tx, int ty)
-{
-#if 01
-   unsigned entry = tx + ty * 2 + zslice * 4 + face + level;
-   return entry % TEX_CACHE_NUM_ENTRIES;
-#else
-   return 0;
-#endif
-}
-
-
 /**
  * Get a texel from a texture, using the texture tile cache.
  *
@@ -551,74 +530,27 @@ compute_cache_pos(unsigned face, unsigned level, unsigned zslice,
  * \param level  the mipmap level
  * \param x  the x coord of texel within 2D image
  * \param y  the y coord of texel within 2D image
- * \param zslice  which slice of a 3D texture
+ * \param z  which slice of a 3D texture
  * \param rgba  the quad to put the texel/color into
  * \param j  which element of the rgba quad to write to
+ *
+ * XXX maybe move this into sp_tile_cache.c and merge with the
+ * sp_get_cached_tile_tex() function.  Also, get 4 texels instead of 1...
  */
 static void
 get_texel(struct tgsi_sampler *sampler,
-          unsigned face, unsigned level, int x, int y, unsigned zslice,
+          unsigned face, unsigned level, int x, int y, int z,
           float rgba[NUM_CHANNELS][QUAD_SIZE], unsigned j)
 {
-   int tx = x / TEX_CACHE_TILE_SIZE;
-   int ty = y / TEX_CACHE_TILE_SIZE;
-   unsigned entry = compute_cache_pos(face, level, zslice, tx, ty);
-
-   if (tx != sampler->cache[entry].x ||
-       ty != sampler->cache[entry].y ||
-       face != sampler->cache[entry].face ||
-       level != sampler->cache[entry].level ||
-       zslice != sampler->cache[entry].zslice) {
-      /* entry is not what's expected */
-      struct pipe_context *pipe = (struct pipe_context *) sampler->pipe;
-      struct pipe_surface *ps
-         = pipe->get_tex_surface(pipe, sampler->texture, face, level, zslice);
-
-      /*
-      printf("cache miss (%d, %d) face %u\n", tx, ty, face);
-      */
-
-      assert(ps->width == sampler->texture->level[level].width);
-      assert(ps->height == sampler->texture->level[level].height);
-      sampler->cache[entry].x = tx;
-      sampler->cache[entry].y = ty;
-      sampler->cache[entry].level = level;
-      sampler->cache[entry].face = face;
-      sampler->cache[entry].zslice = zslice;
-      ps->get_tile(ps,
-                   tx * TEX_CACHE_TILE_SIZE,
-                   ty * TEX_CACHE_TILE_SIZE,
-                   TEX_CACHE_TILE_SIZE, TEX_CACHE_TILE_SIZE,
-                   (float *) sampler->cache[entry].data);
-
-      pipe_surface_reference(&ps, NULL);
-   }
-   else {
-      /*
-      printf("cache hit (%d, %d)\n", x, y);
-      */
-   }
-
-   /* get the texel from cache entry */
-   tx = x % TEX_CACHE_TILE_SIZE;
-   ty = y % TEX_CACHE_TILE_SIZE;
-   if (sampler->texture->format == PIPE_FORMAT_U_Z16 ||
-       sampler->texture->format == PIPE_FORMAT_U_Z32 ||
-       sampler->texture->format == PIPE_FORMAT_S8_Z24) {
-      /* get_tile() returned one float per texel */
-      float *src = (float *) sampler->cache[entry].data;
-      rgba[0][j] =
-      rgba[1][j] =
-      rgba[2][j] =
-      rgba[3][j] = src[ty * TEX_CACHE_TILE_SIZE + tx];
-   }
-   else {
-      /* get_tile() returned four floats per texel */
-      rgba[0][j] = sampler->cache[entry].data[ty][tx][0];
-      rgba[1][j] = sampler->cache[entry].data[ty][tx][1];
-      rgba[2][j] = sampler->cache[entry].data[ty][tx][2];
-      rgba[3][j] = sampler->cache[entry].data[ty][tx][3];
-   }
+   const int tx = x % TILE_SIZE;
+   const int ty = y % TILE_SIZE;
+   const struct softpipe_cached_tile *tile
+      = sp_get_cached_tile_tex(sampler->pipe, sampler->cache,
+                               x, y, z, face, level);
+   rgba[0][j] = tile->data.color[ty][tx][0];
+   rgba[1][j] = tile->data.color[ty][tx][1];
+   rgba[2][j] = tile->data.color[ty][tx][2];
+   rgba[3][j] = tile->data.color[ty][tx][3];
 }
 
 
index d88bce46190e02ccf9dc4bb08dd0add0c91f78cc..1e287c91a41ac81b068240f0d014d6473c508fb3 100644 (file)
@@ -129,7 +129,15 @@ void
 sp_tile_cache_set_texture(struct softpipe_tile_cache *tc,
                           struct pipe_mipmap_tree *texture)
 {
+   uint i;
+
    tc->texture = texture;
+
+   /* mark as entries as invalid/empty */
+   /* XXX we should try to avoid this when the teximage hasn't changed */
+   for (i = 0; i < NUM_ENTRIES; i++) {
+      tc->entries[i].x = -1;
+   }
 }
 
 
@@ -263,10 +271,10 @@ sp_get_cached_tile(struct softpipe_tile_cache *tc, int x, int y)
  * This is basically a direct-map cache.
  * XXX There's probably lots of ways in which we can improve this.
  */
-static uint
+static INLINE uint
 tex_cache_pos(int x, int y, int z, int face, int level)
 {
-   uint entry = x + y * 2 + z * 4 + face + level;
+   uint entry = x + y * 5 + z * 4 + face + level;
    return entry % NUM_ENTRIES;
 }
 
@@ -275,19 +283,17 @@ tex_cache_pos(int x, int y, int z, int face, int level)
  * Similar to sp_get_cached_tile() but for textures.
  * Tiles are read-only and indexed with more params.
  */
-struct softpipe_cached_tile *
-sp_get_cached_tile_tex(struct softpipe_tile_cache *tc, int x, int y, int z,
+const struct softpipe_cached_tile *
+sp_get_cached_tile_tex(struct pipe_context *pipe,
+                       struct softpipe_tile_cache *tc, int x, int y, int z,
                        int face, int level)
 {
-   struct pipe_context *pipe; /* XXX need this */
-
    /* tile pos in framebuffer: */
    const int tile_x = x & ~(TILE_SIZE - 1);
    const int tile_y = y & ~(TILE_SIZE - 1);
-
    /* cache pos/entry: */
-   const int pos = tex_cache_pos(x / TILE_SIZE, y / TILE_SIZE,
-                                 z, face, level);
+   const uint pos = tex_cache_pos(x / TILE_SIZE, y / TILE_SIZE, z,
+                                  face, level);
    struct softpipe_cached_tile *tile = tc->entries + pos;
 
    if (tile_x != tile->x ||
@@ -295,6 +301,7 @@ sp_get_cached_tile_tex(struct softpipe_tile_cache *tc, int x, int y, int z,
        z != tile->z ||
        face != tile->face ||
        level != tile->level) {
+      /* XXX this call is a bit heavier than we'd like: */
       struct pipe_surface *ps
          = pipe->get_tex_surface(pipe, tc->texture, face, level, z);
 
@@ -303,6 +310,12 @@ sp_get_cached_tile_tex(struct softpipe_tile_cache *tc, int x, int y, int z,
                    (float *) tile->data.color);
 
       pipe_surface_reference(&ps, NULL);
+
+      tile->x = tile_x;
+      tile->y = tile_y;
+      tile->z = z;
+      tile->face = face;
+      tile->level = level;
    }
 
    return tile;
index 9879b1821ce313cec54ca7b7e35dd6a47c569dd8..a1cc387a12d506298a5cb35c5f70c92812be2e3d 100644 (file)
@@ -79,8 +79,9 @@ sp_clear_tile_cache(struct softpipe_tile_cache *tc, unsigned clearval);
 extern struct softpipe_cached_tile *
 sp_get_cached_tile(struct softpipe_tile_cache *tc, int x, int y);
 
-extern struct softpipe_cached_tile *
-sp_get_cached_tile_tex(struct softpipe_tile_cache *tc, int x, int y, int z,
+extern const struct softpipe_cached_tile *
+sp_get_cached_tile_tex(struct pipe_context *pipe,
+                       struct softpipe_tile_cache *tc, int x, int y, int z,
                        int face, int level);
 
 
index 20647e72e23e2344bf2c61a65b8dc09587a7be55..978c2d574e2024abb6b0bcde9165fe6aed3007ff 100644 (file)
@@ -29,14 +29,8 @@ struct tgsi_interp_coef
    float dady[NUM_CHANNELS];
 };
 
-#define TEX_CACHE_TILE_SIZE 8
-#define TEX_CACHE_NUM_ENTRIES 8
 
-struct tgsi_texture_cache_entry
-{
-   int x, y, face, level, zslice;
-   float data[TEX_CACHE_TILE_SIZE][TEX_CACHE_TILE_SIZE][4];
-};
+struct softpipe_tile_cache;  /**< Opaque to TGSI */
 
 struct tgsi_sampler
 {
@@ -50,7 +44,7 @@ struct tgsi_sampler
                        float lodbias,
                        float rgba[NUM_CHANNELS][QUAD_SIZE]);
    void *pipe; /*XXX temporary*/
-   struct tgsi_texture_cache_entry cache[TEX_CACHE_NUM_ENTRIES];
+   struct softpipe_tile_cache *cache;
 };
 
 struct tgsi_exec_labels