Mesa (master): intel: Use the blitter to upload TexSubImage data to busy textures.

Eric Anholt anholt at kemper.freedesktop.org
Wed Jun 9 20:34:04 UTC 2010


Module: Mesa
Branch: master
Commit: 94731797c671d6e46e3e0c94c1a0cec5071c0ac3
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=94731797c671d6e46e3e0c94c1a0cec5071c0ac3

Author: Eric Anholt <eric at anholt.net>
Date:   Wed Jun  9 13:54:24 2010 -0700

intel: Use the blitter to upload TexSubImage data to busy textures.

This avoids many pipeline stalls in cairo-gl.
[ # ]  backend                         test   min(s) median(s) stddev. count
Before:
[  0]       gl            firefox-talos-gfx   36.799   36.851   2.34%    3/3
[  0]       gl            firefox-talos-svg   33.429   35.360   3.46%    3/3
After:
[  0]       gl            firefox-talos-gfx   35.895   36.250   0.48%    3/3
[  0]       gl            firefox-talos-svg   26.669   29.888   5.34%    3/3

This doesn't avoid all the pipeline stalls because the kernel reports
!busy for buffers on the flushing list.  That should be fixed in .36.

---

 src/mesa/drivers/dri/intel/intel_tex_subimage.c |   77 ++++++++++++++++++++---
 1 files changed, 67 insertions(+), 10 deletions(-)

diff --git a/src/mesa/drivers/dri/intel/intel_tex_subimage.c b/src/mesa/drivers/dri/intel/intel_tex_subimage.c
index 4f5c26a..af20573 100644
--- a/src/mesa/drivers/dri/intel/intel_tex_subimage.c
+++ b/src/mesa/drivers/dri/intel/intel_tex_subimage.c
@@ -35,6 +35,8 @@
 #include "intel_context.h"
 #include "intel_tex.h"
 #include "intel_mipmap_tree.h"
+#include "intel_batchbuffer.h"
+#include "intel_blit.h"
 
 #define FILE_DEBUG_FLAG DEBUG_TEXTURE
 
@@ -54,7 +56,9 @@ intelTexSubimage(GLcontext * ctx,
    struct intel_context *intel = intel_context(ctx);
    struct intel_texture_image *intelImage = intel_texture_image(texImage);
    GLuint dstRowStride = 0;
-   
+   drm_intel_bo *temp_bo = NULL, *dst_bo = NULL;
+   unsigned int blit_x = 0, blit_y = 0;
+
    DBG("%s target %s level %d offset %d,%d %dx%d\n", __FUNCTION__,
        _mesa_lookup_enum_by_nr(target),
        level, xoffset, yoffset, width, height);
@@ -77,14 +81,45 @@ intelTexSubimage(GLcontext * ctx,
    /* Map buffer if necessary.  Need to lock to prevent other contexts
     * from uploading the buffer under us.
     */
-   if (intelImage->mt) 
-      texImage->Data = intel_miptree_image_map(intel,
-                                               intelImage->mt,
-                                               intelImage->face,
-                                               intelImage->level,
-                                               &dstRowStride,
-                                               texImage->ImageOffsets);
-   else {
+   if (intelImage->mt) {
+      dst_bo = intel_region_buffer(intel, intelImage->mt->region,
+				   INTEL_WRITE_PART);
+
+      if (!compressed &&
+	  intelImage->mt->region->tiling != I915_TILING_Y &&
+	  intel->gen < 6 && target == GL_TEXTURE_2D &&
+	  drm_intel_bo_busy(dst_bo))
+      {
+	 unsigned long pitch;
+	 uint32_t tiling_mode = I915_TILING_NONE;
+	 temp_bo = drm_intel_bo_alloc_tiled(intel->bufmgr,
+					    "subimage blit bo",
+					    width, height,
+					    intelImage->mt->cpp,
+					    &tiling_mode,
+					    &pitch,
+					    0);
+	 drm_intel_gem_bo_map_gtt(temp_bo);
+	 texImage->Data = temp_bo->virtual;
+	 texImage->ImageOffsets[0] = 0;
+	 dstRowStride = pitch;
+
+	 intel_miptree_get_image_offset(intelImage->mt, level,
+					intelImage->face, 0,
+					&blit_x, &blit_y);
+	 blit_x += xoffset;
+	 blit_y += yoffset;
+	 xoffset = 0;
+	 yoffset = 0;
+      } else {
+	 texImage->Data = intel_miptree_image_map(intel,
+						  intelImage->mt,
+						  intelImage->face,
+						  intelImage->level,
+						  &dstRowStride,
+						  texImage->ImageOffsets);
+      }
+   } else {
       if (_mesa_is_format_compressed(texImage->TexFormat)) {
          dstRowStride =
             _mesa_format_row_stride(texImage->TexFormat, width);
@@ -121,11 +156,33 @@ intelTexSubimage(GLcontext * ctx,
                           format, type, pixels, packing)) {
          _mesa_error(ctx, GL_OUT_OF_MEMORY, "intelTexSubImage");
       }
+
+      if (temp_bo) {
+	 GLboolean ret;
+	 unsigned int dst_pitch = intelImage->mt->region->pitch *
+	    intelImage->mt->cpp;
+
+	 drm_intel_gem_bo_unmap_gtt(temp_bo);
+	 texImage->Data = NULL;
+
+	 ret = intelEmitCopyBlit(intel,
+				 intelImage->mt->cpp,
+				 dstRowStride / intelImage->mt->cpp,
+				 temp_bo, 0, GL_FALSE,
+				 dst_pitch / intelImage->mt->cpp, dst_bo, 0,
+				 intelImage->mt->region->tiling,
+				 0, 0, blit_x, blit_y, width, height,
+				 GL_COPY);
+	 assert(ret);
+      }
    }
 
    _mesa_unmap_teximage_pbo(ctx, packing);
 
-   if (intelImage->mt) {
+   if (temp_bo) {
+      drm_intel_bo_unreference(temp_bo);
+      temp_bo = NULL;
+   } else if (intelImage->mt) {
       intel_miptree_image_unmap(intel, intelImage->mt);
       texImage->Data = NULL;
    }




More information about the mesa-commit mailing list