Merge commit 'origin/master' into gallium-0.2
[mesa.git] / src / gallium / drivers / softpipe / sp_tile_cache.c
index da30dd6c4847f8ebbf2c901cf0fe995b08ff327f..78b0efa46d27c879d74d15c67df909b4c32bc240 100644 (file)
  *    Brian Paul
  */
 
-#include "pipe/p_util.h"
 #include "pipe/p_inlines.h"
-#include "util/p_tile.h"
+#include "util/u_memory.h"
+#include "util/u_tile.h"
 #include "sp_context.h"
 #include "sp_surface.h"
+#include "sp_texture.h"
 #include "sp_tile_cache.h"
 
-#define NUM_ENTRIES 30
+#define NUM_ENTRIES 32
 
 
 /** XXX move these */
@@ -49,6 +50,7 @@
 
 struct softpipe_tile_cache
 {
+   struct pipe_screen *screen;
    struct pipe_surface *surface;  /**< the surface we're caching */
    void *surface_map;
    struct pipe_texture *texture;  /**< if caching a texture */
@@ -109,13 +111,14 @@ clear_clear_flag(uint *bitvec, int x, int y)
    
 
 struct softpipe_tile_cache *
-sp_create_tile_cache(void)
+sp_create_tile_cache( struct pipe_screen *screen )
 {
    struct softpipe_tile_cache *tc;
    uint pos;
 
    tc = CALLOC_STRUCT( softpipe_tile_cache );
    if (tc) {
+      tc->screen = screen;
       for (pos = 0; pos < NUM_ENTRIES; pos++) {
          tc->entries[pos].x =
          tc->entries[pos].y = -1;
@@ -131,7 +134,7 @@ sp_destroy_tile_cache(struct softpipe_tile_cache *tc)
    uint pos;
 
    for (pos = 0; pos < NUM_ENTRIES; pos++) {
-      //assert(tc->entries[pos].x < 0);
+      /*assert(tc->entries[pos].x < 0);*/
    }
    if (tc->surface) {
       pipe_surface_reference(&tc->surface, NULL);
@@ -154,20 +157,25 @@ sp_tile_cache_set_surface(struct softpipe_tile_cache *tc,
    assert(!tc->texture);
 
    if (tc->surface_map) {
-      /*assert(tc->surface != ps);*/
-      pipe_surface_unmap(tc->surface);
+      tc->screen->surface_unmap(tc->screen, tc->surface);
+      tc->surface_map = NULL;
    }
 
    pipe_surface_reference(&tc->surface, ps);
 
-   if (ps) {
-      if (tc->surface_map)
-        tc->surface_map = pipe_surface_map(ps);
+   if (tc->surface) {
+      if (tc->surface_map) /* XXX: this is always NULL!? */
+        tc->surface_map = tc->screen->surface_map(tc->screen, tc->surface,
+                                                   PIPE_BUFFER_USAGE_CPU_READ | 
+                                                   PIPE_BUFFER_USAGE_CPU_WRITE);
 
       tc->depth_stencil = (ps->format == PIPE_FORMAT_S8Z24_UNORM ||
+                           ps->format == PIPE_FORMAT_X8Z24_UNORM ||
+                           ps->format == PIPE_FORMAT_Z24S8_UNORM ||
+                           ps->format == PIPE_FORMAT_Z24X8_UNORM ||
                            ps->format == PIPE_FORMAT_Z16_UNORM ||
                            ps->format == PIPE_FORMAT_Z32_UNORM ||
-                           ps->format == PIPE_FORMAT_U_S8);
+                           ps->format == PIPE_FORMAT_S8_UNORM);
    }
 }
 
@@ -186,10 +194,13 @@ void
 sp_tile_cache_map_surfaces(struct softpipe_tile_cache *tc)
 {
    if (tc->surface && !tc->surface_map)
-      tc->surface_map = pipe_surface_map(tc->surface);
+      tc->surface_map = tc->screen->surface_map(tc->screen, tc->surface,
+                                                PIPE_BUFFER_USAGE_CPU_WRITE |
+                                                PIPE_BUFFER_USAGE_CPU_READ);
 
    if (tc->tex_surf && !tc->tex_surf_map)
-      tc->tex_surf_map = pipe_surface_map(tc->tex_surf);
+      tc->tex_surf_map = tc->screen->surface_map(tc->screen, tc->tex_surf,
+                                                 PIPE_BUFFER_USAGE_CPU_READ);
 }
 
 
@@ -197,12 +208,12 @@ void
 sp_tile_cache_unmap_surfaces(struct softpipe_tile_cache *tc)
 {
    if (tc->surface_map) {
-      pipe_surface_unmap(tc->surface);
+      tc->screen->surface_unmap(tc->screen, tc->surface);
       tc->surface_map = NULL;
    }
 
    if (tc->tex_surf_map) {
-      pipe_surface_unmap(tc->tex_surf);
+      tc->screen->surface_unmap(tc->screen, tc->tex_surf);
       tc->tex_surf_map = NULL;
    }
 }
@@ -220,10 +231,10 @@ sp_tile_cache_set_texture(struct pipe_context *pipe,
 
    assert(!tc->surface);
 
-   pipe_texture_reference(pipe, &tc->texture, texture);
+   pipe_texture_reference(&tc->texture, texture);
 
    if (tc->tex_surf_map) {
-      pipe_surface_unmap(tc->tex_surf);
+      tc->screen->surface_unmap(tc->screen, tc->tex_surf);
       tc->tex_surf_map = NULL;
    }
    pipe_surface_reference(&tc->tex_surf, NULL);
@@ -330,9 +341,9 @@ sp_tile_cache_flush_clear(struct pipe_context *pipe,
    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)) {
-            pipe_put_tile_raw(pipe, ps,
-                           x, y, TILE_SIZE, TILE_SIZE,
-                           tc->tile.data.color32, 0/*STRIDE*/);
+            pipe_put_tile_raw(ps,
+                              x, y, TILE_SIZE, TILE_SIZE,
+                              tc->tile.data.color32, 0/*STRIDE*/);
 
             /* do this? */
             clear_clear_flag(tc->clear_flags, x, y);
@@ -355,7 +366,6 @@ 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;
    int inuse = 0, pos;
 
@@ -365,12 +375,12 @@ sp_flush_tile_cache(struct softpipe_context *softpipe,
          struct softpipe_cached_tile *tile = tc->entries + pos;
          if (tile->x >= 0) {
             if (tc->depth_stencil) {
-               pipe_put_tile_raw(pipe, ps,
-                              tile->x, tile->y, TILE_SIZE, TILE_SIZE,
-                              tile->data.depth32, 0/*STRIDE*/);
+               pipe_put_tile_raw(ps,
+                                 tile->x, tile->y, TILE_SIZE, TILE_SIZE,
+                                 tile->data.depth32, 0/*STRIDE*/);
             }
             else {
-               pipe_put_tile_rgba(pipe, ps,
+               pipe_put_tile_rgba(ps,
                                   tile->x, tile->y, TILE_SIZE, TILE_SIZE,
                                   (float *) tile->data.color);
             }
@@ -384,7 +394,7 @@ sp_flush_tile_cache(struct softpipe_context *softpipe,
 #endif
    }
    else if (tc->texture) {
-      /* caching a texture, mark all entries as embpy */
+      /* caching a texture, mark all entries as empty */
       for (pos = 0; pos < NUM_ENTRIES; pos++) {
          tc->entries[pos].x = -1;
       }
@@ -405,7 +415,6 @@ struct softpipe_cached_tile *
 sp_get_cached_tile(struct softpipe_context *softpipe,
                    struct softpipe_tile_cache *tc, int x, int y)
 {
-   struct pipe_context *pipe = &softpipe->pipe;
    struct pipe_surface *ps = tc->surface;
 
    /* tile pos in framebuffer: */
@@ -422,12 +431,12 @@ sp_get_cached_tile(struct softpipe_context *softpipe,
       if (tile->x != -1) {
          /* put dirty tile back in framebuffer */
          if (tc->depth_stencil) {
-            pipe_put_tile_raw(pipe, ps,
+            pipe_put_tile_raw(ps,
                               tile->x, tile->y, TILE_SIZE, TILE_SIZE,
                               tile->data.depth32, 0/*STRIDE*/);
          }
          else {
-            pipe_put_tile_rgba(pipe, ps,
+            pipe_put_tile_rgba(ps,
                                tile->x, tile->y, TILE_SIZE, TILE_SIZE,
                                (float *) tile->data.color);
          }
@@ -449,12 +458,12 @@ sp_get_cached_tile(struct softpipe_context *softpipe,
       else {
          /* get new tile data from surface */
          if (tc->depth_stencil) {
-            pipe_get_tile_raw(pipe, ps,
+            pipe_get_tile_raw(ps,
                               tile->x, tile->y, TILE_SIZE, TILE_SIZE,
                               tile->data.depth32, 0/*STRIDE*/);
          }
          else {
-            pipe_get_tile_rgba(pipe, ps,
+            pipe_get_tile_rgba(ps,
                                tile->x, tile->y, TILE_SIZE, TILE_SIZE,
                                (float *) tile->data.color);
          }
@@ -485,10 +494,11 @@ tex_cache_pos(int x, int y, int z, int face, int level)
  * Tiles are read-only and indexed with more params.
  */
 const struct softpipe_cached_tile *
-sp_get_cached_tile_tex(struct pipe_context *pipe,
+sp_get_cached_tile_tex(struct softpipe_context *sp,
                        struct softpipe_tile_cache *tc, int x, int y, int z,
                        int face, int level)
 {
+   struct pipe_screen *screen = sp->pipe.screen;
    /* tile pos in framebuffer: */
    const int tile_x = x & ~(TILE_SIZE - 1);
    const int tile_y = y & ~(TILE_SIZE - 1);
@@ -497,6 +507,15 @@ sp_get_cached_tile_tex(struct pipe_context *pipe,
                                   face, level);
    struct softpipe_cached_tile *tile = tc->entries + pos;
 
+   if (tc->texture) {
+      struct softpipe_texture *spt = softpipe_texture(tc->texture);
+      if (spt->modified) {
+         /* texture was modified, force a cache reload */
+         tile->x = -1;
+         spt->modified = FALSE;
+      }
+   }
+
    if (tile_x != tile->x ||
        tile_y != tile->y ||
        z != tile->z ||
@@ -512,10 +531,12 @@ sp_get_cached_tile_tex(struct pipe_context *pipe,
          /* get new surface (view into texture) */
 
         if (tc->tex_surf_map)
-            pipe_surface_unmap(tc->tex_surf);
+            tc->screen->surface_unmap(tc->screen, tc->tex_surf);
 
-         tc->tex_surf = pipe->get_tex_surface(pipe, tc->texture, face, level, z);
-         tc->tex_surf_map = pipe_surface_map(tc->tex_surf);
+         tc->tex_surf = screen->get_tex_surface(screen, tc->texture, face, level, z, 
+                                                PIPE_BUFFER_USAGE_CPU_READ);
+         tc->tex_surf_map = screen->surface_map(screen, tc->tex_surf,
+                                                PIPE_BUFFER_USAGE_CPU_READ);
 
          tc->tex_face = face;
          tc->tex_level = level;
@@ -523,7 +544,7 @@ sp_get_cached_tile_tex(struct pipe_context *pipe,
       }
 
       /* get tile from the surface (view into texture) */
-      pipe_get_tile_rgba(pipe, tc->tex_surf,
+      pipe_get_tile_rgba(tc->tex_surf,
                          tile_x, tile_y, TILE_SIZE, TILE_SIZE,
                          (float *) tile->data.color);
       tile->x = tile_x;