summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2010-12-15 12:10:03 -0800
committerEric Anholt <eric@anholt.net>2010-12-16 10:48:19 -0800
commit290a1141bc561cbd8fd2bbbb0a7c24d1b6abe0b4 (patch)
treec4da5621d0c2a94979566edbfb08c561d05fcde5
parentec03b316b4dc5d56b8510cc5aeb0f71a4fdada18 (diff)
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.
-rw-r--r--src/mesa/drivers/dri/intel/intel_blit.c80
-rw-r--r--src/mesa/drivers/dri/intel/intel_blit.h2
-rw-r--r--src/mesa/drivers/dri/intel/intel_tex_copy.c14
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 ede88de82f..a2822b11d9 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 0163146573..ff69e4f8f8 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 c4a3364ceb..c6bc3d962a 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;
}