[Mesa-dev] [PATCH 05/12] intel: Move separate-stencil s8 mapping logic to intel_miptree_map.

Eric Anholt eric at anholt.net
Mon Dec 5 11:42:29 PST 2011


We're going to want to reuse this logic in mapping of fake packed
miptrees wrapping separate depth/stencil miptrees.
---
 src/mesa/drivers/dri/intel/intel_fbo.c         |  139 +++++-------------------
 src/mesa/drivers/dri/intel/intel_mipmap_tree.c |   86 ++++++++++++++-
 2 files changed, 112 insertions(+), 113 deletions(-)

diff --git a/src/mesa/drivers/dri/intel/intel_fbo.c b/src/mesa/drivers/dri/intel/intel_fbo.c
index 3fa0661..de4abab 100644
--- a/src/mesa/drivers/dri/intel/intel_fbo.c
+++ b/src/mesa/drivers/dri/intel/intel_fbo.c
@@ -256,68 +256,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.
  *
  * A depthstencil renderbuffer, if using separate stencil, consists of a depth
@@ -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);
@@ -429,52 +391,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.
  *
  * \see intel_map_renderbuffer_separate_s8z24()
@@ -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) {
diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
index 8f2a433..4b6eeef 100644
--- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
+++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
@@ -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);
-- 
1.7.7.3



More information about the mesa-dev mailing list