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.
This commit is contained in:
Eric Anholt 2010-12-15 12:10:03 -08:00
parent ec03b316b4
commit 290a1141bc
3 changed files with 94 additions and 2 deletions

View file

@ -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);
}

View file

@ -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

View file

@ -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;
}