summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2008-11-21 17:09:47 +0800
committerEric Anholt <eric@anholt.net>2008-11-21 17:35:33 +0800
commit3e0164aabb48a99fce58964cad99fd3978ee84f6 (patch)
tree351bf921dd35ee641a601ee67cfdc5b4183f2bc1
parenta6aa926e3f0b6237679db0d3331690d2a96adbc2 (diff)
i965: Add support for accelerated CopyTexSubImage.
There were hacks in EmitCopyBlit before to adjust offsets so that y=0 after the offsets had been adjusted for a negative pitch. It appears that those hacks were due to an unclear and surprising aspect of the hardware: inverting the pitch results in the blit into the specified rectangle being inverted, without the user needing to adjust y and base offset. Tested with piglit copytexsubimage test on 915GM and GM965. Should fix serious performance issues with ETQW and other applications.
-rw-r--r--src/mesa/drivers/dri/intel/intel_blit.c64
-rw-r--r--src/mesa/drivers/dri/intel/intel_tex.c7
-rw-r--r--src/mesa/drivers/dri/intel/intel_tex_copy.c38
3 files changed, 41 insertions, 68 deletions
diff --git a/src/mesa/drivers/dri/intel/intel_blit.c b/src/mesa/drivers/dri/intel/intel_blit.c
index e1046f4a5d..ab12aae6c7 100644
--- a/src/mesa/drivers/dri/intel/intel_blit.c
+++ b/src/mesa/drivers/dri/intel/intel_blit.c
@@ -40,6 +40,7 @@
#include "intel_reg.h"
#include "intel_regions.h"
#include "intel_batchbuffer.h"
+#include "intel_chipset.h"
#define FILE_DEBUG_FLAG DEBUG_BLIT
@@ -359,51 +360,24 @@ intelEmitCopyBlit(struct intel_context *intel,
return;
}
- /* Initial y values don't seem to work with negative pitches. If
- * we adjust the offsets manually (below), it seems to work fine.
- *
- * On the other hand, if we always adjust, the hardware doesn't
- * know which blit directions to use, so overlapping copypixels get
- * the wrong result.
- */
- if (dst_pitch > 0 && src_pitch > 0) {
- assert(dst_x < dst_x2);
- assert(dst_y < dst_y2);
-
- BEGIN_BATCH(8, NO_LOOP_CLIPRECTS);
- OUT_BATCH(CMD);
- OUT_BATCH(BR13 | dst_pitch);
- OUT_BATCH((dst_y << 16) | dst_x);
- OUT_BATCH((dst_y2 << 16) | dst_x2);
- OUT_RELOC(dst_buffer,
- I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
- dst_offset);
- OUT_BATCH((src_y << 16) | src_x);
- OUT_BATCH(src_pitch);
- OUT_RELOC(src_buffer,
- I915_GEM_DOMAIN_RENDER, 0,
- src_offset);
- ADVANCE_BATCH();
- }
- else {
- assert(dst_x < dst_x2);
- assert(h > 0);
-
- BEGIN_BATCH(8, NO_LOOP_CLIPRECTS);
- OUT_BATCH(CMD);
- OUT_BATCH(BR13 | ((uint16_t)dst_pitch));
- OUT_BATCH((0 << 16) | dst_x);
- OUT_BATCH((h << 16) | dst_x2);
- OUT_RELOC(dst_buffer,
- I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
- dst_offset + dst_y * dst_pitch);
- OUT_BATCH((0 << 16) | src_x);
- OUT_BATCH(src_pitch);
- OUT_RELOC(src_buffer,
- I915_GEM_DOMAIN_RENDER, 0,
- src_offset + src_y * src_pitch);
- ADVANCE_BATCH();
- }
+ assert(dst_x < dst_x2);
+ assert(dst_y < dst_y2);
+
+ BEGIN_BATCH(8, NO_LOOP_CLIPRECTS);
+ OUT_BATCH(CMD);
+ OUT_BATCH(BR13 | (uint16_t)dst_pitch);
+ OUT_BATCH((dst_y << 16) | dst_x);
+ OUT_BATCH((dst_y2 << 16) | dst_x2);
+ OUT_RELOC(dst_buffer,
+ I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
+ dst_offset);
+ OUT_BATCH((src_y << 16) | src_x);
+ OUT_BATCH((uint16_t)src_pitch);
+ OUT_RELOC(src_buffer,
+ I915_GEM_DOMAIN_RENDER, 0,
+ src_offset);
+ ADVANCE_BATCH();
+
intel_batchbuffer_emit_mi_flush(intel->batch);
}
diff --git a/src/mesa/drivers/dri/intel/intel_tex.c b/src/mesa/drivers/dri/intel/intel_tex.c
index 23455a4c74..82f8b87009 100644
--- a/src/mesa/drivers/dri/intel/intel_tex.c
+++ b/src/mesa/drivers/dri/intel/intel_tex.c
@@ -222,17 +222,10 @@ intelInitTextureFuncs(struct dd_function_table *functions)
functions->TexSubImage1D = intelTexSubImage1D;
functions->TexSubImage2D = intelTexSubImage2D;
functions->TexSubImage3D = intelTexSubImage3D;
-#ifdef I915
functions->CopyTexImage1D = intelCopyTexImage1D;
functions->CopyTexImage2D = intelCopyTexImage2D;
functions->CopyTexSubImage1D = intelCopyTexSubImage1D;
functions->CopyTexSubImage2D = intelCopyTexSubImage2D;
-#else
- functions->CopyTexImage1D = _swrast_copy_teximage1d;
- functions->CopyTexImage2D = _swrast_copy_teximage2d;
- functions->CopyTexSubImage1D = _swrast_copy_texsubimage1d;
- functions->CopyTexSubImage2D = _swrast_copy_texsubimage2d;
-#endif
functions->GetTexImage = intelGetTexImage;
functions->GenerateMipmap = intelGenerateMipmap;
diff --git a/src/mesa/drivers/dri/intel/intel_tex_copy.c b/src/mesa/drivers/dri/intel/intel_tex_copy.c
index f4cb4a781c..36446efde7 100644
--- a/src/mesa/drivers/dri/intel/intel_tex_copy.c
+++ b/src/mesa/drivers/dri/intel/intel_tex_copy.c
@@ -114,43 +114,49 @@ do_copy_texsubimage(struct intel_context *intel,
if (_mesa_clip_to_region(fb->_Xmin, fb->_Ymin, fb->_Xmax, fb->_Ymax,
&x, &y, &width, &height)) {
+ GLshort src_pitch;
+
/* Update dst for clipped src. Need to also clip the source rect.
*/
dstx += x - orig_x;
dsty += y - orig_y;
+ /* image_offset may be non-page-aligned, but that's illegal for tiling.
+ */
+ assert(intelImage->mt->region->tiling == I915_TILING_NONE);
+
if (ctx->ReadBuffer->Name == 0) {
/* reading from a window, adjust x, y */
__DRIdrawablePrivate *dPriv = intel->driDrawable;
- GLuint window_y;
- /* window_y = position of window on screen if y=0=bottom */
- window_y = intel->intelScreen->height - (dPriv->y + dPriv->h);
- y = window_y + y;
+ y = dPriv->y + (dPriv->h - (y + height));
x += dPriv->x;
+
+ /* Invert the data coming from the source rectangle due to GL
+ * and hardware disagreeing on where y=0 is.
+ *
+ * It appears that our offsets and pitches get mangled
+ * appropriately by the hardware, and we don't need to adjust them
+ * on our own.
+ */
+ src_pitch = -src->pitch;
}
else {
- /* reading from a FBO */
- /* invert Y */
- y = ctx->ReadBuffer->Height - y - 1;
+ /* reading from a FBO, y is already oriented the way we like */
+ src_pitch = src->pitch;
}
-
- /* A bit of fiddling to get the blitter to work with -ve
- * pitches. But we get a nice inverted blit this way, so it's
- * worth it:
- */
intelEmitCopyBlit(intel,
intelImage->mt->cpp,
- -src->pitch,
+ src_pitch,
src->buffer,
- src->height * src->pitch * src->cpp,
+ 0,
src->tiling,
intelImage->mt->pitch,
intelImage->mt->region->buffer,
image_offset,
intelImage->mt->region->tiling,
- x, y + height, dstx, dsty, width, height,
- GL_COPY); /* ? */
+ x, y, dstx, dsty, width, height,
+ GL_COPY);
}
}