intel: Move separate-stencil s8 mapping logic to intel_miptree_map.
authorEric Anholt <eric@anholt.net>
Tue, 29 Nov 2011 00:08:46 +0000 (16:08 -0800)
committerEric Anholt <eric@anholt.net>
Wed, 7 Dec 2011 21:36:57 +0000 (13:36 -0800)
We're going to want to reuse this logic in mapping of fake packed
miptrees wrapping separate depth/stencil miptrees.

Reviewed-by: Chad Versace <chad.versace@linux.intel.com>
src/mesa/drivers/dri/intel/intel_fbo.c
src/mesa/drivers/dri/intel/intel_mipmap_tree.c

index 3fa0661ab32e701aa1d77445904a1a184878afa1..de4abab748899011526cb94bf33ff175056d480f 100644 (file)
@@ -255,68 +255,6 @@ intel_map_renderbuffer_blit(struct gl_context *ctx,
    }
 }
 
-/**
- * \brief Map a stencil renderbuffer.
- *
- * Stencil buffers are W-tiled. Since the GTT has no W fence, we must detile
- * the buffer in software.
- *
- * This function allocates a temporary malloc'd buffer at
- * intel_renderbuffer::map_buffer, detiles the stencil buffer into it, then
- * returns the temporary buffer as the map.
- *
- * \see intel_renderbuffer::map_buffer
- * \see intel_map_renderbuffer()
- * \see intel_unmap_renderbuffer_s8()
- */
-static void
-intel_map_renderbuffer_s8(struct gl_context *ctx,
-                         struct gl_renderbuffer *rb,
-                         GLuint x, GLuint y, GLuint w, GLuint h,
-                         GLbitfield mode,
-                         GLubyte **out_map,
-                         GLint *out_stride)
-{
-   struct intel_context *intel = intel_context(ctx);
-   struct intel_renderbuffer *irb = intel_renderbuffer(rb);
-   uint8_t *tiled_s8_map;
-   uint8_t *untiled_s8_map;
-
-   assert(rb->Format == MESA_FORMAT_S8);
-   assert(irb->mt);
-
-   irb->map_mode = mode;
-   irb->map_x = x;
-   irb->map_y = y;
-   irb->map_w = w;
-   irb->map_h = h;
-
-   /* Flip the Y axis for the default framebuffer. */
-   int y_flip = (rb->Name == 0) ? -1 : 1;
-   int y_bias = (rb->Name == 0) ? (rb->Height - 1) : 0;
-
-   irb->map_buffer = malloc(w * h);
-   untiled_s8_map = irb->map_buffer;
-   tiled_s8_map = intel_region_map(intel, irb->mt->region, mode);
-
-   for (uint32_t pix_y = 0; pix_y < h; pix_y++) {
-      for (uint32_t pix_x = 0; pix_x < w; pix_x++) {
-        uint32_t flipped_y = y_flip * (int32_t)(y + pix_y) + y_bias;
-        ptrdiff_t offset = intel_offset_S8(irb->mt->region->pitch,
-                                           x + pix_x,
-                                           flipped_y);
-        untiled_s8_map[pix_y * w + pix_x] = tiled_s8_map[offset];
-      }
-   }
-
-   *out_map = untiled_s8_map;
-   *out_stride = w;
-
-   DBG("%s: rb %d (%s) s8 detiled mapped: (%d, %d) (%dx%d) -> %p/%d\n",
-       __FUNCTION__, rb->Name, _mesa_get_format_name(rb->Format),
-       x, y, w, h, *out_map, *out_stride);
-}
-
 /**
  * \brief Map a depthstencil buffer with separate stencil.
  *
@@ -412,8 +350,32 @@ intel_map_renderbuffer(struct gl_context *ctx,
    }
 
    if (rb->Format == MESA_FORMAT_S8) {
-      intel_map_renderbuffer_s8(ctx, rb, x, y, w, h, mode,
-                               out_map, out_stride);
+      void *map;
+      int stride;
+
+      /* For a window-system renderbuffer, we need to flip the mapping we
+       * receive upside-down.  So we need to ask for a rectangle on flipped
+       * vertically, and we then return a pointer to the bottom of it with a
+       * negative stride.
+       */
+      if (rb->Name == 0) {
+        y = rb->Height - y - h;
+      }
+
+      intel_miptree_map(intel, irb->mt, irb->mt_level, irb->mt_layer,
+                       x, y, w, h, mode, &map, &stride);
+
+      if (rb->Name == 0) {
+        map += (h - 1) * stride;
+        stride = -stride;
+      }
+
+      DBG("%s: rb %d (%s) mt mapped: (%d, %d) (%dx%d) -> %p/%d\n",
+         __FUNCTION__, rb->Name, _mesa_get_format_name(rb->Format),
+         x, y, w, h, *out_map, *out_stride);
+
+      *out_map = map;
+      *out_stride = stride;
    } else if (irb->wrapped_depth) {
       intel_map_renderbuffer_separate_s8z24(ctx, rb, x, y, w, h, mode,
                                            out_map, out_stride);
@@ -428,52 +390,6 @@ intel_map_renderbuffer(struct gl_context *ctx,
    }
 }
 
-/**
- * \see intel_map_renderbuffer_s8()
- */
-static void
-intel_unmap_renderbuffer_s8(struct gl_context *ctx,
-                           struct gl_renderbuffer *rb)
-{
-   struct intel_context *intel = intel_context(ctx);
-   struct intel_renderbuffer *irb = intel_renderbuffer(rb);
-
-   DBG("%s: rb %d (%s)\n", __FUNCTION__,
-       rb->Name, _mesa_get_format_name(rb->Format));
-
-   assert(rb->Format == MESA_FORMAT_S8);
-
-   if (!irb->map_buffer)
-      return;
-
-   if (irb->map_mode & GL_MAP_WRITE_BIT) {
-      /* The temporary buffer was written to, so we must copy its pixels into
-       * the real buffer.
-       */
-      uint8_t *untiled_s8_map = irb->map_buffer;
-      uint8_t *tiled_s8_map = irb->mt->region->bo->virtual;
-
-      /* Flip the Y axis for the default framebuffer. */
-      int y_flip = (rb->Name == 0) ? -1 : 1;
-      int y_bias = (rb->Name == 0) ? (rb->Height - 1) : 0;
-
-      for (uint32_t pix_y = 0; pix_y < irb->map_h; pix_y++) {
-        for (uint32_t pix_x = 0; pix_x < irb->map_w; pix_x++) {
-           uint32_t flipped_y = y_flip * (int32_t)(pix_y + irb->map_y) + y_bias;
-           ptrdiff_t offset = intel_offset_S8(irb->mt->region->pitch,
-                                              pix_x + irb->map_x,
-                                              flipped_y);
-           tiled_s8_map[offset] =
-              untiled_s8_map[pix_y * irb->map_w + pix_x];
-        }
-      }
-   }
-
-   intel_region_unmap(intel, irb->mt->region);
-   free(irb->map_buffer);
-   irb->map_buffer = NULL;
-}
-
 /**
  * \brief Unmap a depthstencil renderbuffer with separate stencil.
  *
@@ -539,13 +455,14 @@ static void
 intel_unmap_renderbuffer(struct gl_context *ctx,
                         struct gl_renderbuffer *rb)
 {
+   struct intel_context *intel = intel_context(ctx);
    struct intel_renderbuffer *irb = intel_renderbuffer(rb);
 
    DBG("%s: rb %d (%s)\n", __FUNCTION__,
        rb->Name, _mesa_get_format_name(rb->Format));
 
    if (rb->Format == MESA_FORMAT_S8) {
-      intel_unmap_renderbuffer_s8(ctx, rb);
+      intel_miptree_unmap(intel, irb->mt, irb->mt_level, irb->mt_layer);
    } else if (irb->wrapped_depth) {
       intel_unmap_renderbuffer_separate_s8z24(ctx, rb);
    } else if (irb->map_bo) {
index 8f2a433e75a9ffe3b7fc175911c20639ff5dbddc..4b6eeef925ec0a6ec7547c52740715aec1a34c89 100644 (file)
@@ -801,6 +801,80 @@ intel_miptree_unmap_gtt(struct intel_context *intel,
    }
 }
 
+static void
+intel_miptree_map_s8(struct intel_context *intel,
+                    struct intel_mipmap_tree *mt,
+                    struct intel_miptree_map *map,
+                    unsigned int level, unsigned int slice)
+{
+   map->stride = map->w;
+   map->buffer = map->ptr = malloc(map->stride * map->h);
+   if (!map->buffer)
+      return;
+
+   /* One of either READ_BIT or WRITE_BIT or both is set.  READ_BIT implies no
+    * INVALIDATE_RANGE_BIT.  WRITE_BIT needs the original values read in unless
+    * invalidate is set, since we'll be writing the whole rectangle from our
+    * temporary buffer back out.
+    */
+   if (!(map->mode & GL_MAP_INVALIDATE_RANGE_BIT)) {
+      uint8_t *untiled_s8_map = map->ptr;
+      uint8_t *tiled_s8_map = intel_region_map(intel, mt->region,
+                                              GL_MAP_READ_BIT);
+      unsigned int image_x, image_y;
+
+      intel_miptree_get_image_offset(mt, level, 0, slice, &image_x, &image_y);
+
+      for (uint32_t y = 0; y < map->h; y++) {
+        for (uint32_t x = 0; x < map->w; x++) {
+           ptrdiff_t offset = intel_offset_S8(mt->region->pitch,
+                                              x + image_x + map->x,
+                                              y + image_y + map->y);
+           untiled_s8_map[y * map->w + x] = tiled_s8_map[offset];
+        }
+      }
+
+      intel_region_unmap(intel, mt->region);
+
+      DBG("%s: %d,%d %dx%d from mt %p %d,%d = %p/%d\n", __FUNCTION__,
+         map->x, map->y, map->w, map->h,
+         mt, map->x + image_x, map->y + image_y, map->ptr, map->stride);
+   } else {
+      DBG("%s: %d,%d %dx%d from mt %p = %p/%d\n", __FUNCTION__,
+         map->x, map->y, map->w, map->h,
+         mt, map->ptr, map->stride);
+   }
+}
+
+static void
+intel_miptree_unmap_s8(struct intel_context *intel,
+                      struct intel_mipmap_tree *mt,
+                      struct intel_miptree_map *map,
+                      unsigned int level,
+                      unsigned int slice)
+{
+   if (map->mode & GL_MAP_WRITE_BIT) {
+      unsigned int image_x, image_y;
+      uint8_t *untiled_s8_map = map->ptr;
+      uint8_t *tiled_s8_map = intel_region_map(intel, mt->region, map->mode);
+
+      intel_miptree_get_image_offset(mt, level, 0, slice, &image_x, &image_y);
+
+      for (uint32_t y = 0; y < map->h; y++) {
+        for (uint32_t x = 0; x < map->w; x++) {
+           ptrdiff_t offset = intel_offset_S8(mt->region->pitch,
+                                              x + map->x,
+                                              y + map->y);
+           tiled_s8_map[offset] = untiled_s8_map[y * map->w + x];
+        }
+      }
+
+      intel_region_unmap(intel, mt->region);
+   }
+
+   free(map->buffer);
+}
+
 void
 intel_miptree_map(struct intel_context *intel,
                  struct intel_mipmap_tree *mt,
@@ -836,7 +910,11 @@ intel_miptree_map(struct intel_context *intel,
       intel_miptree_slice_set_needs_hiz_resolve(mt, level, slice);
    }
 
-   intel_miptree_map_gtt(intel, mt, map, level, slice);
+   if (mt->format == MESA_FORMAT_S8) {
+      intel_miptree_map_s8(intel, mt, map, level, slice);
+   } else {
+      intel_miptree_map_gtt(intel, mt, map, level, slice);
+   }
 
    *out_ptr = map->ptr;
    *out_stride = map->stride;
@@ -856,7 +934,11 @@ intel_miptree_unmap(struct intel_context *intel,
    DBG("%s: mt %p (%s) level %d slice %d\n", __FUNCTION__,
        mt, _mesa_get_format_name(mt->format), level, slice);
 
-   intel_miptree_unmap_gtt(intel, mt, map, level, slice);
+   if (mt->format == MESA_FORMAT_S8) {
+      intel_miptree_unmap_s8(intel, mt, map, level, slice);
+   } else {
+      intel_miptree_unmap_gtt(intel, mt, map, level, slice);
+   }
 
    mt->level[level].slice[slice].map = NULL;
    free(map);