Mesa (master): intel: Support glCopyTexImage() from XRGB8888 to ARGB8888.

Eric Anholt anholt at kemper.freedesktop.org
Thu Dec 16 18:56:42 UTC 2010


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

Author: Eric Anholt <eric at anholt.net>
Date:   Wed Dec 15 12:10:03 2010 -0800

intel: Support glCopyTexImage() from XRGB8888 to ARGB8888.

The only mismatch between the two is that we have to clear the
destination's alpha to 1.0.  Fixes WOW performance on my Ironlake,
from a few frames a second to almost playable.

---

 src/mesa/drivers/dri/intel/intel_blit.c     |   80 +++++++++++++++++++++++++++
 src/mesa/drivers/dri/intel/intel_blit.h     |    2 +
 src/mesa/drivers/dri/intel/intel_tex_copy.c |   14 ++++-
 3 files changed, 94 insertions(+), 2 deletions(-)

diff --git a/src/mesa/drivers/dri/intel/intel_blit.c b/src/mesa/drivers/dri/intel/intel_blit.c
index ede88de..a2822b1 100644
--- a/src/mesa/drivers/dri/intel/intel_blit.c
+++ b/src/mesa/drivers/dri/intel/intel_blit.c
@@ -38,6 +38,8 @@
 #include "intel_reg.h"
 #include "intel_regions.h"
 #include "intel_batchbuffer.h"
+#include "intel_tex.h"
+#include "intel_mipmap_tree.h"
 
 #define FILE_DEBUG_FLAG DEBUG_BLIT
 
@@ -500,3 +502,81 @@ intel_emit_linear_blit(struct intel_context *intel,
       assert(ok);
    }
 }
+
+/**
+ * Used to initialize the alpha value of an ARGB8888 teximage after
+ * loading it from an XRGB8888 source.
+ *
+ * This is very common with glCopyTexImage2D().
+ */
+void
+intel_set_teximage_alpha_to_one(struct gl_context *ctx,
+				struct intel_texture_image *intel_image)
+{
+   struct intel_context *intel = intel_context(ctx);
+   unsigned int image_x, image_y;
+   uint32_t x1, y1, x2, y2;
+   uint32_t BR13, CMD;
+   int pitch, cpp;
+   drm_intel_bo *aper_array[2];
+   struct intel_region *region = intel_image->mt->region;
+   BATCH_LOCALS;
+
+   assert(intel_image->base.TexFormat == MESA_FORMAT_ARGB8888);
+
+   /* get dest x/y in destination texture */
+   intel_miptree_get_image_offset(intel_image->mt,
+				  intel_image->level,
+				  intel_image->face,
+				  0,
+				  &image_x, &image_y);
+
+   x1 = image_x;
+   y1 = image_y;
+   x2 = image_x + intel_image->base.Width;
+   y2 = image_y + intel_image->base.Height;
+
+   pitch = region->pitch;
+   cpp = region->cpp;
+
+   DBG("%s dst:buf(%p)/%d %d,%d sz:%dx%d\n",
+       __FUNCTION__,
+       intel_image->mt->region->buffer, (pitch * region->cpp),
+       x1, y1, x2 - x1, y2 - y1);
+
+   BR13 = br13_for_cpp(region->cpp) | 0xf0 << 16;
+   CMD = XY_COLOR_BLT_CMD;
+   CMD |= XY_BLT_WRITE_ALPHA;
+
+   assert(region->tiling != I915_TILING_Y);
+
+#ifndef I915
+   if (region->tiling != I915_TILING_NONE) {
+      CMD |= XY_DST_TILED;
+      pitch /= 4;
+   }
+#endif
+   BR13 |= (pitch * region->cpp);
+
+   /* do space check before going any further */
+   aper_array[0] = intel->batch->buf;
+   aper_array[1] = region->buffer;
+
+   if (drm_intel_bufmgr_check_aperture_space(aper_array,
+					     ARRAY_SIZE(aper_array)) != 0) {
+      intel_batchbuffer_flush(intel->batch);
+   }
+
+   BEGIN_BATCH_BLT(6);
+   OUT_BATCH(CMD);
+   OUT_BATCH(BR13);
+   OUT_BATCH((y1 << 16) | x1);
+   OUT_BATCH((y2 << 16) | x2);
+   OUT_RELOC_FENCED(region->buffer,
+		    I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
+		    0);
+   OUT_BATCH(0xffffffff); /* white, but only alpha gets written */
+   ADVANCE_BATCH();
+
+   intel_batchbuffer_emit_mi_flush(intel->batch);
+}
diff --git a/src/mesa/drivers/dri/intel/intel_blit.h b/src/mesa/drivers/dri/intel/intel_blit.h
index 0163146..ff69e4f 100644
--- a/src/mesa/drivers/dri/intel/intel_blit.h
+++ b/src/mesa/drivers/dri/intel/intel_blit.h
@@ -69,5 +69,7 @@ void intel_emit_linear_blit(struct intel_context *intel,
 			    drm_intel_bo *src_bo,
 			    unsigned int src_offset,
 			    unsigned int size);
+void intel_set_teximage_alpha_to_one(struct gl_context *ctx,
+				     struct intel_texture_image *intel_image);
 
 #endif
diff --git a/src/mesa/drivers/dri/intel/intel_tex_copy.c b/src/mesa/drivers/dri/intel/intel_tex_copy.c
index c4a3364..c6bc3d9 100644
--- a/src/mesa/drivers/dri/intel/intel_tex_copy.c
+++ b/src/mesa/drivers/dri/intel/intel_tex_copy.c
@@ -78,18 +78,25 @@ do_copy_texsubimage(struct intel_context *intel,
 {
    struct gl_context *ctx = &intel->ctx;
    struct intel_renderbuffer *irb;
+   bool copy_supported_with_alpha_override = false;
 
    intel_prepare_render(intel);
 
    irb = get_teximage_readbuffer(intel, internalFormat);
-   if (!intelImage->mt || !irb) {
+   if (!intelImage->mt || !irb || !irb->region) {
       if (unlikely(INTEL_DEBUG & DEBUG_FALLBACKS))
 	 fprintf(stderr, "%s fail %p %p (0x%08x)\n",
 		 __FUNCTION__, intelImage->mt, irb, internalFormat);
       return GL_FALSE;
    }
 
-   if (intelImage->base.TexFormat != irb->Base.Format) {
+   if (irb->Base.Format == MESA_FORMAT_XRGB8888 &&
+       intelImage->base.TexFormat == MESA_FORMAT_ARGB8888) {
+      copy_supported_with_alpha_override = true;
+   }
+
+   if (intelImage->base.TexFormat != irb->Base.Format &&
+       !copy_supported_with_alpha_override) {
       if (unlikely(INTEL_DEBUG & DEBUG_FALLBACKS))
 	 fprintf(stderr, "%s mismatched formats %s, %s\n",
 		 __FUNCTION__,
@@ -145,6 +152,9 @@ do_copy_texsubimage(struct intel_context *intel,
       }
    }
 
+   if (copy_supported_with_alpha_override)
+      intel_set_teximage_alpha_to_one(ctx, intelImage);
+
    return GL_TRUE;
 }
 




More information about the mesa-commit mailing list