From 290a1141bc561cbd8fd2bbbb0a7c24d1b6abe0b4 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 15 Dec 2010 12:10:03 -0800 Subject: [PATCH] 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 ede88de82f1..a2822b11d96 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 01631465735..ff69e4f8f8f 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 c4a3364ceba..c6bc3d962ab 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; } -- 2.30.2