intel: Consolidate texture validation copy code, and reuse it correctly.
authorEric Anholt <eric@anholt.net>
Wed, 28 Sep 2011 23:07:56 +0000 (16:07 -0700)
committerEric Anholt <eric@anholt.net>
Mon, 3 Oct 2011 20:29:38 +0000 (13:29 -0700)
The path for ->Data was failing to be called for the FBO draw offset
fallback, and also had mismatched compressed texture support code.

This drops the intel_prepare_render() in the blit path.  We aren't
copying to/from a GL_FRONT buffer, so it doesn't matter.

src/mesa/drivers/dri/intel/intel_fbo.c
src/mesa/drivers/dri/intel/intel_mipmap_tree.c
src/mesa/drivers/dri/intel/intel_mipmap_tree.h
src/mesa/drivers/dri/intel/intel_regions.c
src/mesa/drivers/dri/intel/intel_regions.h
src/mesa/drivers/dri/intel/intel_tex_validate.c

index c0fb8d8..d87dabb 100644 (file)
@@ -729,7 +729,6 @@ intel_render_texture(struct gl_context * ctx,
        * into that.
        */
       struct intel_context *intel = intel_context(ctx);
-      struct intel_mipmap_tree *old_mt = intel_image->mt;
       struct intel_mipmap_tree *new_mt;
 
       new_mt = intel_miptree_create(intel, image->TexObject->Target,
@@ -741,17 +740,11 @@ intel_render_texture(struct gl_context * ctx,
                                    intel_image->base.Base.Depth,
                                    GL_TRUE);
 
-      intel_miptree_image_copy(intel,
-                               new_mt,
-                              intel_image->base.Base.Face,
-                              intel_image->base.Base.Level,
-                              old_mt);
-
-      intel_miptree_release(&intel_image->mt);
-      intel_image->mt = new_mt;
+      intel_miptree_copy_teximage(intel, intel_image, new_mt);
       intel_renderbuffer_set_draw_offset(irb, intel_image, att->Zoffset);
 
       intel_region_reference(&irb->region, intel_image->mt->region);
+      intel_miptree_release(&new_mt);
    }
 #endif
    /* update drawing region, etc */
index c25df35..553a21e 100644 (file)
 #include "intel_regions.h"
 #include "intel_tex_layout.h"
 #include "intel_tex.h"
+#include "intel_blit.h"
 #include "main/enums.h"
 #include "main/formats.h"
+#include "main/teximage.h"
 
 #define FILE_DEBUG_FLAG DEBUG_MIPTREE
 
@@ -310,102 +312,107 @@ intel_miptree_get_image_offset(struct intel_mipmap_tree *mt,
 }
 
 /**
- * Upload data for a particular image.
+ * Copies the image's current data to the given miptree, and associates that
+ * miptree with the image.
  */
 void
-intel_miptree_image_data(struct intel_context *intel,
-                        struct intel_mipmap_tree *dst,
-                        GLuint face,
-                        GLuint level,
-                        void *src,
-                        GLuint src_row_pitch,
-                        GLuint src_image_pitch)
+intel_miptree_copy_teximage(struct intel_context *intel,
+                           struct intel_texture_image *intelImage,
+                           struct intel_mipmap_tree *dst_mt)
 {
-   const GLuint depth = dst->level[level].depth;
-   GLuint i;
-
-   for (i = 0; i < depth; i++) {
-      GLuint dst_x, dst_y, height, width;
-
-      intel_miptree_get_image_offset(dst, level, face, i, &dst_x, &dst_y);
-
-      height = dst->level[level].height;
-      width = dst->level[level].width;
-      if (dst->compressed) {
-        unsigned int align_w, align_h;
+   struct intel_mipmap_tree *src_mt = intelImage->mt;
+   int level = intelImage->base.Base.Level;
+   int face = intelImage->base.Base.Face;
+   GLuint width = src_mt->level[level].width;
+   GLuint height = src_mt->level[level].height;
+   GLuint depth = src_mt->level[level].depth;
+   int slice;
+   void *src, *dst;
+
+   if (dst_mt->compressed) {
+      unsigned int align_w, align_h;
+
+      intel_get_texture_alignment_unit(intelImage->base.Base.TexFormat,
+                                      &align_w, &align_h);
+      height = ALIGN(height, align_h) / align_h;
+      width = ALIGN(width, align_w);
+   }
 
-        intel_get_texture_alignment_unit(dst->format, &align_w, &align_h);
-        height = (height + align_h - 1) / align_h;
-        width = ALIGN(width, align_w);
+   for (slice = 0; slice < depth; slice++) {
+      unsigned int dst_x, dst_y, src_x, src_y;
+
+      intel_miptree_get_image_offset(dst_mt, level, face, slice,
+                                    &dst_x, &dst_y);
+
+      if (src_mt) {
+        /* Copy potentially with the blitter:
+         */
+        intel_miptree_get_image_offset(src_mt, level, face, slice,
+                                       &src_x, &src_y);
+
+        DBG("validate blit mt %p %d,%d/%d -> mt %p %d,%d/%d (%dx%d)\n",
+            src_mt, src_x, src_y, src_mt->region->pitch * src_mt->region->cpp,
+            dst_mt, dst_x, dst_y, dst_mt->region->pitch * dst_mt->region->cpp,
+            width, height);
+
+        if (!intelEmitCopyBlit(intel,
+                               dst_mt->region->cpp,
+                               src_mt->region->pitch, src_mt->region->bo,
+                               0, src_mt->region->tiling,
+                               dst_mt->region->pitch, dst_mt->region->bo,
+                               0, dst_mt->region->tiling,
+                               src_x, src_y,
+                               dst_x, dst_y,
+                               width, height,
+                               GL_COPY)) {
+
+           fallback_debug("miptree validate blit for %s failed\n",
+                          _mesa_get_format_name(intelImage->base.Base.TexFormat));
+           dst = intel_region_map(intel, dst_mt->region);
+           src = intel_region_map(intel, src_mt->region);
+
+           _mesa_copy_rect(dst,
+                           dst_mt->cpp,
+                           dst_mt->region->pitch,
+                           dst_x, dst_y,
+                           width, height,
+                           src, src_mt->region->pitch,
+                           src_x, src_y);
+
+           intel_region_unmap(intel, dst_mt->region);
+           intel_region_unmap(intel, src_mt->region);
+        }
+      } else {
+        dst = intel_region_map(intel, dst_mt->region);
+
+        DBG("validate upload mt %p -> mt %p %d,%d/%d (%dx%d)\n",
+            src,
+            dst_mt, dst_x, dst_y, dst_mt->region->pitch * dst_mt->region->cpp,
+            width, height);
+
+        src = intelImage->base.Base.Data;
+        src += (intelImage->base.Base.RowStride *
+                intelImage->base.Base.Height *
+                dst_mt->region->cpp *
+                slice);
+
+        _mesa_copy_rect(dst,
+                        dst_mt->region->cpp,
+                        dst_mt->region->pitch,
+                        dst_x, dst_y,
+                        width, height,
+                        src,
+                        intelImage->base.Base.RowStride,
+                        0, 0);
+
+        intel_region_unmap(intel, dst_mt->region);
       }
-
-      DBG("%s: %d/%d %p/%d -> (%d, %d)/%d (%d, %d)\n",
-         __FUNCTION__, face, level,
-         src, src_row_pitch * dst->cpp,
-         dst_x, dst_y, dst->region->pitch * dst->cpp,
-         width, height);
-
-      intel_region_data(intel,
-                       dst->region, 0, dst_x, dst_y,
-                       src,
-                       src_row_pitch,
-                       0, 0,                             /* source x, y */
-                       width, height);
-
-      src = (char *)src + src_image_pitch * dst->cpp;
    }
-}
 
-
-/**
- * Copy mipmap image between trees
- */
-void
-intel_miptree_image_copy(struct intel_context *intel,
-                         struct intel_mipmap_tree *dst,
-                         GLuint face, GLuint level,
-                         struct intel_mipmap_tree *src)
-{
-   GLuint width = src->level[level].width;
-   GLuint height = src->level[level].height;
-   GLuint depth = src->level[level].depth;
-   GLuint src_x, src_y, dst_x, dst_y;
-   GLuint i;
-   GLboolean success;
-
-   if (dst->compressed) {
-       GLuint align_w, align_h;
-
-       intel_get_texture_alignment_unit(dst->format, &align_w, &align_h);
-       height = (height + 3) / 4;
-       width = ALIGN(width, align_w);
+   if (!src_mt) {
+      _mesa_free_texmemory(intelImage->base.Base.Data);
+      intelImage->base.Base.Data = NULL;
    }
 
-   intel_prepare_render(intel);
-
-   for (i = 0; i < depth; i++) {
-      intel_miptree_get_image_offset(src, level, face, i, &src_x, &src_y);
-      intel_miptree_get_image_offset(dst, level, face, i, &dst_x, &dst_y);
-      success = intel_region_copy(intel,
-                                 dst->region, 0, dst_x, dst_y,
-                                 src->region, 0, src_x, src_y,
-                                 width, height, GL_FALSE,
-                                 GL_COPY);
-      if (!success) {
-        GLubyte *src_ptr, *dst_ptr;
-
-        src_ptr = intel_region_map(intel, src->region);
-        dst_ptr = intel_region_map(intel, dst->region);
-
-        _mesa_copy_rect(dst_ptr,
-                        dst->cpp,
-                        dst->region->pitch,
-                        dst_x, dst_y, width, height,
-                        src_ptr,
-                        src->region->pitch,
-                        src_x, src_y);
-        intel_region_unmap(intel, src->region);
-        intel_region_unmap(intel, dst->region);
-      }
-   }
+   intel_miptree_reference(&intelImage->mt, dst_mt);
 }
index 7ca24f9..7c0a3e3 100644 (file)
@@ -56,6 +56,7 @@
  * temporary system buffers.
  */
 
+struct intel_texture_image;
 
 /**
  * Describes the location of each texture image within a texture region.
@@ -180,21 +181,10 @@ void intel_miptree_set_image_offset(struct intel_mipmap_tree *mt,
                                     GLuint level,
                                     GLuint img, GLuint x, GLuint y);
 
-/* Upload an image into a tree
- */
-void intel_miptree_image_data(struct intel_context *intel,
-                              struct intel_mipmap_tree *dst,
-                              GLuint face,
-                              GLuint level,
-                              void *src,
-                              GLuint src_row_pitch, GLuint src_image_pitch);
-
-/* Copy an image between two trees
- */
-void intel_miptree_image_copy(struct intel_context *intel,
-                              struct intel_mipmap_tree *dst,
-                              GLuint face, GLuint level,
-                              struct intel_mipmap_tree *src);
+void
+intel_miptree_copy_teximage(struct intel_context *intel,
+                            struct intel_texture_image *intelImage,
+                            struct intel_mipmap_tree *dst_mt);
 
 /* i915_mipmap_tree.c:
  */
index 9cb1632..7faf4ca 100644 (file)
@@ -337,37 +337,6 @@ _mesa_copy_rect(GLubyte * dst,
    }
 }
 
-
-/* Upload data to a rectangular sub-region.  Lots of choices how to do this:
- *
- * - memcpy by span to current destination
- * - upload data as new buffer and blit
- *
- * Currently always memcpy.
- */
-void
-intel_region_data(struct intel_context *intel,
-                  struct intel_region *dst,
-                  GLuint dst_offset,
-                  GLuint dstx, GLuint dsty,
-                  const void *src, GLuint src_pitch,
-                  GLuint srcx, GLuint srcy, GLuint width, GLuint height)
-{
-   _DBG("%s\n", __FUNCTION__);
-
-   if (intel == NULL)
-      return;
-
-   intel_prepare_render(intel);
-
-   _mesa_copy_rect(intel_region_map(intel, dst) + dst_offset,
-                   dst->cpp,
-                   dst->pitch,
-                   dstx, dsty, width, height, src, src_pitch, srcx, srcy);
-
-   intel_region_unmap(intel, dst);
-}
-
 /* Copy rectangular sub-regions. Need better logic about when to
  * push buffers into AGP - will currently do so whenever possible.
  */
index 61a284a..e639895 100644 (file)
@@ -101,16 +101,6 @@ GLubyte *intel_region_map(struct intel_context *intel,
 
 void intel_region_unmap(struct intel_context *intel, struct intel_region *ib);
 
-
-/* Upload data to a rectangular sub-region
- */
-void intel_region_data(struct intel_context *intel,
-                       struct intel_region *dest,
-                       GLuint dest_offset,
-                       GLuint destx, GLuint desty,
-                       const void *src, GLuint src_stride,
-                       GLuint srcx, GLuint srcy, GLuint width, GLuint height);
-
 /* Copy rectangular sub-regions
  */
 GLboolean
index f227ab8..a2299ee 100644 (file)
@@ -4,7 +4,9 @@
 
 #include "intel_context.h"
 #include "intel_mipmap_tree.h"
+#include "intel_blit.h"
 #include "intel_tex.h"
+#include "intel_tex_layout.h"
 
 #define FILE_DEBUG_FLAG DEBUG_TEXTURE
 
@@ -27,44 +29,6 @@ intel_update_max_level(struct intel_texture_object *intelObj,
    }
 }
 
-/**
- * Copies the image's contents at its level into the object's miptree,
- * and updates the image to point at the object's miptree.
- */
-static void
-copy_image_data_to_tree(struct intel_context *intel,
-                        struct intel_texture_object *intelObj,
-                        struct intel_texture_image *intelImage)
-{
-   if (intelImage->mt) {
-      /* Copy potentially with the blitter:
-       */
-      intel_miptree_image_copy(intel,
-                               intelObj->mt,
-                               intelImage->base.Base.Face,
-                               intelImage->base.Base.Level, intelImage->mt);
-   }
-   else {
-      assert(intelImage->base.Base.Data != NULL);
-
-      /* More straightforward upload.  
-       */
-      intel_miptree_image_data(intel,
-                               intelObj->mt,
-                               intelImage->base.Base.Face,
-                               intelImage->base.Base.Level,
-                               intelImage->base.Base.Data,
-                               intelImage->base.Base.RowStride,
-                               intelImage->base.Base.RowStride *
-                               intelImage->base.Base.Height);
-      _mesa_align_free(intelImage->base.Base.Data);
-      intelImage->base.Base.Data = NULL;
-   }
-
-   intel_miptree_reference(&intelImage->mt, intelObj->mt);
-}
-
-
 /*  
  */
 GLuint
@@ -148,7 +112,7 @@ intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit)
           */
          if (intelObj->mt != intelImage->mt &&
             !intelImage->used_as_render_target) {
-            copy_image_data_to_tree(intel, intelObj, intelImage);
+            intel_miptree_copy_teximage(intel, intelImage, intelObj->mt);
          }
       }
    }