diff options
| -rw-r--r-- | src/mesa/pipe/softpipe/sp_clear.c | 4 | ||||
| -rw-r--r-- | src/mesa/pipe/softpipe/sp_state_surface.c | 8 | ||||
| -rw-r--r-- | src/mesa/pipe/softpipe/sp_tile_cache.c | 330 | ||||
| -rw-r--r-- | src/mesa/pipe/softpipe/sp_tile_cache.h | 12 | 
4 files changed, 206 insertions, 148 deletions
diff --git a/src/mesa/pipe/softpipe/sp_clear.c b/src/mesa/pipe/softpipe/sp_clear.c index 496b38fd5f..a4276362b9 100644 --- a/src/mesa/pipe/softpipe/sp_clear.c +++ b/src/mesa/pipe/softpipe/sp_clear.c @@ -50,12 +50,12 @@ softpipe_clear(struct pipe_context *pipe, struct pipe_surface *ps,     softpipe_update_derived(softpipe); /* not needed?? */ -   if (ps == sp_tile_cache_get_surface(softpipe, softpipe->zbuf_cache)) { +   if (ps == 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 (ps == sp_tile_cache_get_surface(softpipe, softpipe->cbuf_cache[0])) { +   else if (ps == sp_tile_cache_get_surface(softpipe->cbuf_cache[0])) {        float clear[4];        clear[0] = 0.2f; /* XXX hack */        clear[1] = 0.2f; /* XXX hack */ diff --git a/src/mesa/pipe/softpipe/sp_state_surface.c b/src/mesa/pipe/softpipe/sp_state_surface.c index 9470ef485f..30bedc74bc 100644 --- a/src/mesa/pipe/softpipe/sp_state_surface.c +++ b/src/mesa/pipe/softpipe/sp_state_surface.c @@ -66,7 +66,7 @@ softpipe_set_framebuffer_state(struct pipe_context *pipe,           sp->framebuffer.cbufs[i] = fb->cbufs[i];           /* update cache */ -         sp_tile_cache_set_surface(sp, sp->cbuf_cache[i], ps); +         sp_tile_cache_set_surface(sp->cbuf_cache[i], ps);        }     } @@ -92,7 +92,7 @@ softpipe_set_framebuffer_state(struct pipe_context *pipe,        sp->framebuffer.zbuf = fb->zbuf;        /* update cache */ -      sp_tile_cache_set_surface(sp, sp->zbuf_cache, ps); +      sp_tile_cache_set_surface(sp->zbuf_cache, ps);     }     /* XXX combined depth/stencil here */ @@ -116,12 +116,12 @@ softpipe_set_framebuffer_state(struct pipe_context *pipe,        if (fb->sbuf != fb->zbuf) {           /* separate stencil buf */           sp->sbuf_cache = sp->sbuf_cache_sep; -         sp_tile_cache_set_surface(sp, sp->sbuf_cache, ps); +         sp_tile_cache_set_surface(sp->sbuf_cache, ps);        }        else {           /* combined depth/stencil */           sp->sbuf_cache = sp->zbuf_cache; -         sp_tile_cache_set_surface(sp, sp->sbuf_cache, ps); +         sp_tile_cache_set_surface(sp->sbuf_cache, ps);        }     } diff --git a/src/mesa/pipe/softpipe/sp_tile_cache.c b/src/mesa/pipe/softpipe/sp_tile_cache.c index 08cd39cc55..92e43d63bc 100644 --- a/src/mesa/pipe/softpipe/sp_tile_cache.c +++ b/src/mesa/pipe/softpipe/sp_tile_cache.c @@ -38,9 +38,7 @@  #include "sp_surface.h"  #include "sp_tile_cache.h" -#define CLEAR_OPTIMIZATION 0 - -#define NUM_ENTRIES 20 +#define NUM_ENTRIES 30  /** XXX move these */ @@ -69,7 +67,7 @@ struct softpipe_tile_cache -static uint +static INLINE uint  is_clear_flag_set(const uint *bitvec, int x, int y)  {     int pos, bit; @@ -82,7 +80,7 @@ is_clear_flag_set(const uint *bitvec, int x, int y)  } -static void +static INLINE void  clear_clear_flag(uint *bitvec, int x, int y)  {     int pos; @@ -123,24 +121,22 @@ sp_destroy_tile_cache(struct softpipe_tile_cache *tc)  void -sp_tile_cache_set_surface(struct softpipe_context *sp, -			  struct softpipe_tile_cache *tc, +sp_tile_cache_set_surface(struct softpipe_tile_cache *tc,                            struct pipe_surface *ps)  {     if (tc->surface && tc->surface->map)        pipe_surface_unmap(tc->surface);     pipe_surface_reference(&tc->surface, ps); + +   if (!ps->map) +      pipe_surface_map(ps);  }  struct pipe_surface * -sp_tile_cache_get_surface(struct softpipe_context *sp, -			  struct softpipe_tile_cache *tc) +sp_tile_cache_get_surface(struct softpipe_tile_cache *tc)  { -   if (tc->surface && !tc->surface->map) -      pipe_surface_map(tc->surface); -     return tc->surface;  } @@ -161,46 +157,200 @@ sp_tile_cache_set_texture(struct softpipe_tile_cache *tc,  } +static INLINE boolean +is_depth_stencil_surface(struct pipe_surface *ps) +{ +   return (ps && +           (ps->format == PIPE_FORMAT_S8_Z24 || +            ps->format == PIPE_FORMAT_U_Z16 || +            ps->format == PIPE_FORMAT_U_Z32 || +            ps->format == PIPE_FORMAT_U_S8)); +} + + +/** + * Set pixels in a tile to the given clear color/value. + */ +static void +clear_tile(struct softpipe_cached_tile *tile, uint format, +           const float clear_value[4]) +{ +   uint i, j; + +   switch (format) { +   case PIPE_FORMAT_U_Z16: +      { +         ushort clear_val = (ushort) (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) (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) (clear_value[0] * 0xffffff); +         clear_val |= ((uint) 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) 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 */ +      if (clear_value[0] == 0.0 && +          clear_value[1] == 0.0 && +          clear_value[2] == 0.0 && +          clear_value[3] == 0.0) { +         memset(tile->data.color, 0, sizeof(tile->data.color)); +      } +      else { +         for (i = 0; i < TILE_SIZE; i++) { +            for (j = 0; j < TILE_SIZE; j++) { +               tile->data.color[i][j][0] = clear_value[0]; +               tile->data.color[i][j][1] = clear_value[1]; +               tile->data.color[i][j][2] = clear_value[2]; +               tile->data.color[i][j][3] = clear_value[3]; +            } +         } +      } +   } +} + + +static INLINE void +put_tile(struct pipe_context *pipe, +         struct pipe_surface *ps,  +         struct softpipe_cached_tile *tile) +{ +   assert(tile->x >= 0); +   assert(tile->x % TILE_SIZE == 0); +   assert(tile->y >= 0); +   assert(tile->y % TILE_SIZE == 0); + +   if (is_depth_stencil_surface(ps)) { +      pipe->put_tile(pipe, ps, +                     tile->x, tile->y, TILE_SIZE, TILE_SIZE, +                     tile->data.depth32, 0/*STRIDE*/); +   } +   else { +      pipe->put_tile_rgba(pipe, ps, +                          tile->x, tile->y, TILE_SIZE, TILE_SIZE, +                          (float *) tile->data.color); +   } +} + + +static INLINE void +get_tile(struct pipe_context *pipe, +         struct pipe_surface *ps,  +         struct softpipe_cached_tile *tile) +{ +   assert(tile->x >= 0); +   assert(tile->x % TILE_SIZE == 0); +   assert(tile->y >= 0); +   assert(tile->y % TILE_SIZE == 0); + +   if (is_depth_stencil_surface(ps)) { +      pipe->get_tile(pipe, ps, +                     tile->x, tile->y, TILE_SIZE, TILE_SIZE, +                     tile->data.depth32, 0/*STRIDE*/); +   } +   else { +      pipe->get_tile_rgba(pipe, ps, +                          tile->x, tile->y, TILE_SIZE, TILE_SIZE, +                          (float *) tile->data.color); +   } +} + +  void  sp_flush_tile_cache(struct softpipe_context *softpipe,                      struct softpipe_tile_cache *tc)  {     struct pipe_context *pipe = &softpipe->pipe;     struct pipe_surface *ps = tc->surface; -   boolean is_depth_stencil;     int inuse = 0, pos;     if (!ps || !ps->buffer)        return; -   is_depth_stencil = (ps->format == PIPE_FORMAT_S8_Z24 || -                       ps->format == PIPE_FORMAT_Z24_S8 || -                       ps->format == PIPE_FORMAT_U_Z16 || -                       ps->format == PIPE_FORMAT_U_Z32 || -                       ps->format == PIPE_FORMAT_U_S8); -     for (pos = 0; pos < NUM_ENTRIES; pos++) {        struct softpipe_cached_tile *tile = tc->entries + pos;        if (tile->x >= 0) { -         if (is_depth_stencil) { -            pipe->put_tile(pipe, ps, -                           tile->x, tile->y, TILE_SIZE, TILE_SIZE, -                           tile->data.depth32, 0/*STRIDE*/); -         } -         else { -            pipe->put_tile_rgba(pipe, ps, -                                tile->x, tile->y, TILE_SIZE, TILE_SIZE, -                                (float *) tile->data.color); -         } - +         put_tile(pipe, ps, tile);           tile->x = tile->y = -1;  /* mark as empty */           inuse++;        }     } -   /* +#if TILE_CLEAR_OPTIMIZATION +   sp_tile_cache_flush_clear(&softpipe->pipe, tc); +#endif +#if 0     printf("flushed tiles in use: %d\n", inuse); -   */ +#endif +} + + +/** + * Actually clear the tiles which were flagged as being cleared. + */ +void +sp_tile_cache_flush_clear(struct pipe_context *pipe, +                          struct softpipe_tile_cache *tc) +{ +   struct pipe_surface *ps = tc->surface; +   const uint w = tc->surface->width; +   const uint h = tc->surface->height; +   uint x, y; +   struct softpipe_cached_tile tile; +   uint numCleared = 0; + +   /* clear one tile to the clear value */ +   clear_tile(&tile, ps->format, tc->clear_value); + +   /* push the tile to all positions marked as clear */ +   for (y = 0; y < h; y += TILE_SIZE) { +      for (x = 0; x < w; x += TILE_SIZE) { +         if (is_clear_flag_set(tc->clear_flags, x, y)) { +            tile.x = x; +            tile.y = y; +            put_tile(pipe, ps, &tile); + +            /* do this? */ +            clear_clear_flag(tc->clear_flags, x, y); + +            numCleared++; +         } +      } +   } +#if 0 +   printf("num cleared: %u\n", numCleared); +#endif  } @@ -210,12 +360,6 @@ sp_get_cached_tile(struct softpipe_context *softpipe,  {     struct pipe_context *pipe = &softpipe->pipe;     struct pipe_surface *ps = tc->surface; -   boolean is_depth_stencil -      = (ps->format == PIPE_FORMAT_S8_Z24 || -         ps->format == PIPE_FORMAT_Z24_S8 || -         ps->format == PIPE_FORMAT_U_Z16 || -         ps->format == PIPE_FORMAT_U_Z32 || -         ps->format == PIPE_FORMAT_U_S8);     /* tile pos in framebuffer: */     const int tile_x = x & ~(TILE_SIZE - 1); @@ -230,104 +374,21 @@ sp_get_cached_tile(struct softpipe_context *softpipe,        if (tile->x != -1) {           /* put dirty tile back in framebuffer */ -         if (is_depth_stencil) { -            pipe->put_tile(pipe, ps, -                           tile->x, tile->y, TILE_SIZE, TILE_SIZE, -                           tile->data.depth32, 0 /*STRIDE*/); -         } -         else { -            pipe->put_tile_rgba(pipe, ps, -                                tile->x, tile->y, TILE_SIZE, TILE_SIZE, -                                (float *) tile->data.color); -         } +         put_tile(pipe, ps, tile);        } +      tile->x = tile_x; +      tile->y = tile_y; +        if (is_clear_flag_set(tc->clear_flags, x, y)) {           /* don't get tile from framebuffer, just clear it */ -         uint i, j; -         /* 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_Z24_S8: -            { -               uint clear_val = ((uint) (tc->clear_value[0] * 0xffffff)) << 8; -               clear_val |= ((uint) tc->clear_value[1]) & 0xff; -               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]; -               } -            } -         } +         clear_tile(tile, ps->format, tc->clear_value);           clear_clear_flag(tc->clear_flags, x, y);        }        else { -         /* get new tile from framebuffer */ -         if (is_depth_stencil) { -            pipe->get_tile(pipe, ps, -                           tile_x, tile_y, TILE_SIZE, TILE_SIZE, -                           tile->data.depth32, 0/*STRIDE*/); -         } -         else { -            pipe->get_tile_rgba(pipe, ps, -                                tile_x, tile_y, TILE_SIZE, TILE_SIZE, -                                (float *) tile->data.color); -         } +         /* get new tile data from surface */ +         get_tile(pipe, ps, tile);        } - -      tile->x = tile_x; -      tile->y = tile_y;     }     return tile; @@ -375,20 +436,13 @@ sp_get_cached_tile_tex(struct pipe_context *pipe,        struct pipe_surface *ps           = pipe->get_tex_surface(pipe, tc->texture, face, level, z); -      if (ps != tc->surface) { -	 if (tc->surface && tc->surface->map) -	    pipe_surface_unmap(tc->surface); - -	 pipe_surface_reference(&tc->surface, ps); - -	 if (!tc->surface->map) -	    pipe_surface_map(tc->surface); -      } +      pipe_surface_map(ps);        pipe->get_tile_rgba(pipe, ps,                            tile_x, tile_y, TILE_SIZE, TILE_SIZE,                            (float *) tile->data.color); +      pipe_surface_unmap(ps);        pipe_surface_reference(&ps, NULL);        tile->x = tile_x; @@ -415,7 +469,7 @@ sp_tile_cache_clear(struct softpipe_tile_cache *tc, const float value[4])     tc->clear_value[2] = value[2];     tc->clear_value[3] = value[3]; -#if CLEAR_OPTIMIZATION +#if TILE_CLEAR_OPTIMIZATION     memset(tc->clear_flags, 255, sizeof(tc->clear_flags));  #else     memset(tc->clear_flags, 0, sizeof(tc->clear_flags)); diff --git a/src/mesa/pipe/softpipe/sp_tile_cache.h b/src/mesa/pipe/softpipe/sp_tile_cache.h index de5ff2c498..b2a0e011e9 100644 --- a/src/mesa/pipe/softpipe/sp_tile_cache.h +++ b/src/mesa/pipe/softpipe/sp_tile_cache.h @@ -28,6 +28,8 @@  #ifndef SP_TILE_CACHE_H  #define SP_TILE_CACHE_H +#define TILE_CLEAR_OPTIMIZATION 0 +  #include "pipe/p_compiler.h" @@ -63,13 +65,11 @@ extern void  sp_destroy_tile_cache(struct softpipe_tile_cache *tc);  extern void -sp_tile_cache_set_surface(struct softpipe_context *sp, -			  struct softpipe_tile_cache *tc, +sp_tile_cache_set_surface(struct softpipe_tile_cache *tc,                            struct pipe_surface *sps);  extern struct pipe_surface * -sp_tile_cache_get_surface(struct softpipe_context *sp, -			  struct softpipe_tile_cache *tc); +sp_tile_cache_get_surface(struct softpipe_tile_cache *tc);  extern void  sp_tile_cache_set_texture(struct softpipe_tile_cache *tc, @@ -80,6 +80,10 @@ sp_flush_tile_cache(struct softpipe_context *softpipe,                      struct softpipe_tile_cache *tc);  extern void +sp_tile_cache_flush_clear(struct pipe_context *pipe, +                          struct softpipe_tile_cache *tc); + +extern void  sp_tile_cache_clear(struct softpipe_tile_cache *tc, const float value[4]);  extern struct softpipe_cached_tile *  | 
