summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2010-05-31 12:14:23 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2010-05-31 12:23:29 +0100
commitd31abccd41c417338aac7c681e8bc6bd187b1843 (patch)
tree1f7d428d29245e765fae2ae68ad97c50ff9bc501
parent2cfd5bc134f0dd86ea714594d61f6d5eb29019ce (diff)
i915: Support textured video on an extended desktop.
Handle rendering textured video onto an extended desktop (>2048) by using a temporary pixmap. Note that we still cannot handle rendering to a greater than 2048 destination region, for that we will need to tile. Hmm, time to request a 2560x1600, 10bpc monitor... Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--src/i915_video.c111
1 files changed, 76 insertions, 35 deletions
diff --git a/src/i915_video.c b/src/i915_video.c
index bbac610b..8ce07d35 100644
--- a/src/i915_video.c
+++ b/src/i915_video.c
@@ -49,17 +49,47 @@ I915DisplayVideoTextured(ScrnInfoPtr scrn,
PixmapPtr pixmap)
{
intel_screen_private *intel = intel_get_screen_private(scrn);
- uint32_t format, ms3, s5;
+ uint32_t format, ms3, s5, tiling;
BoxPtr pbox = REGION_RECTS(dstRegion);
int nbox_total = REGION_NUM_RECTS(dstRegion);
int nbox_this_time;
int dxo, dyo, pix_xoff, pix_yoff;
+ PixmapPtr target;
#if 0
ErrorF("I915DisplayVideo: %dx%d (pitch %d)\n", width, height,
video_pitch);
#endif
+ dxo = dstRegion->extents.x1;
+ dyo = dstRegion->extents.y1;
+
+ if (pixmap->drawable.width > 2048 || pixmap->drawable.height > 2048 ||
+ !intel_check_pitch_3d(pixmap)) {
+ ScreenPtr screen = pixmap->drawable.pScreen;
+
+ target = screen->CreatePixmap(screen,
+ drw_w, drw_h,
+ pixmap->drawable.depth,
+ CREATE_PIXMAP_USAGE_SCRATCH);
+
+ pix_xoff = -dxo;
+ pix_yoff = -dyo;
+ } else {
+ target = pixmap;
+
+ /* Set up the offset for translating from the given region
+ * (in screen coordinates) to the backing pixmap.
+ */
+#ifdef COMPOSITE
+ pix_xoff = -target->screen_x + target->drawable.x;
+ pix_yoff = -target->screen_y + target->drawable.y;
+#else
+ pix_xoff = 0;
+ pix_yoff = 0;
+#endif
+ }
+
#define BYTES_FOR_BOXES(n) ((200 + (n) * 20) * 4)
#define BOXES_IN_BYTES(s) ((((s)/4) - 200) / 20)
#define BATCH_BYTES(p) ((p)->batch_bo->size - 16)
@@ -75,24 +105,18 @@ I915DisplayVideoTextured(ScrnInfoPtr scrn,
IntelEmitInvarientState(scrn);
intel->last_3d = LAST_3D_VIDEO;
- /* flush map & render cache */
- OUT_BATCH(MI_FLUSH | MI_WRITE_DIRTY_STATE |
- MI_INVALIDATE_MAP_CACHE);
- OUT_BATCH(0x00000000);
-
/* draw rect -- just clipping */
OUT_BATCH(_3DSTATE_DRAW_RECT_CMD);
OUT_BATCH(DRAW_DITHER_OFS_X(pixmap->drawable.x & 3) |
DRAW_DITHER_OFS_Y(pixmap->drawable.y & 3));
OUT_BATCH(0x00000000); /* ymin, xmin */
/* ymax, xmax */
- OUT_BATCH((pixmap->drawable.width - 1) |
- (pixmap->drawable.height - 1) << 16);
+ OUT_BATCH((target->drawable.width - 1) |
+ (target->drawable.height - 1) << 16);
OUT_BATCH(0x00000000); /* yorigin, xorigin */
- OUT_BATCH(MI_NOOP);
OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(2) |
- I1_LOAD_S(4) | I1_LOAD_S(5) | I1_LOAD_S(6) | 3);
+ I1_LOAD_S(5) | I1_LOAD_S(6) | 2);
OUT_BATCH(S2_TEXCOORD_FMT(0, TEXCOORDFMT_2D) |
S2_TEXCOORD_FMT(1, TEXCOORDFMT_NOT_PRESENT) |
S2_TEXCOORD_FMT(2, TEXCOORDFMT_NOT_PRESENT) |
@@ -101,8 +125,6 @@ I915DisplayVideoTextured(ScrnInfoPtr scrn,
S2_TEXCOORD_FMT(5, TEXCOORDFMT_NOT_PRESENT) |
S2_TEXCOORD_FMT(6, TEXCOORDFMT_NOT_PRESENT) |
S2_TEXCOORD_FMT(7, TEXCOORDFMT_NOT_PRESENT));
- OUT_BATCH((1 << S4_POINT_WIDTH_SHIFT) | S4_LINE_WIDTH_ONE |
- S4_CULLMODE_NONE | S4_VFMT_XY);
s5 = 0x0;
if (intel->cpp == 2)
s5 |= S5_COLOR_DITHER_ENABLE;
@@ -127,10 +149,16 @@ I915DisplayVideoTextured(ScrnInfoPtr scrn,
DSTORG_VERT_BIAS(0x8) | format);
/* front buffer, pitch, offset */
+ if (i830_pixmap_tiled(target)) {
+ tiling = BUF_3D_TILED_SURFACE;
+ if (i830_get_pixmap_intel(target)->tiling == I915_TILING_Y)
+ tiling |= BUF_3D_TILE_WALK_Y;
+ } else
+ tiling = 0;
OUT_BATCH(_3DSTATE_BUF_INFO_CMD);
- OUT_BATCH(BUF_3D_ID_COLOR_BACK | BUF_3D_USE_FENCE |
- BUF_3D_PITCH(intel_get_pixmap_pitch(pixmap)));
- OUT_RELOC_PIXMAP(pixmap, I915_GEM_DOMAIN_RENDER,
+ OUT_BATCH(BUF_3D_ID_COLOR_BACK | tiling |
+ BUF_3D_PITCH(intel_get_pixmap_pitch(target)));
+ OUT_RELOC_PIXMAP(target, I915_GEM_DOMAIN_RENDER,
I915_GEM_DOMAIN_RENDER, 0);
if (!is_planar_fourcc(id)) {
@@ -166,7 +194,7 @@ I915DisplayVideoTextured(ScrnInfoPtr scrn,
else
OUT_BATCH(adaptor_priv->YBufOffset);
- ms3 = MAPSURF_422 | MS3_USE_FENCE_REGS;
+ ms3 = MAPSURF_422;
switch (id) {
case FOURCC_YUY2:
ms3 |= MT_422_YCRCB_NORMAL;
@@ -285,7 +313,7 @@ I915DisplayVideoTextured(ScrnInfoPtr scrn,
else
OUT_BATCH(adaptor_priv->YBufOffset);
- ms3 = MAPSURF_8BIT | MT_8BIT_I8 | MS3_USE_FENCE_REGS;
+ ms3 = MAPSURF_8BIT | MT_8BIT_I8;
ms3 |= (height - 1) << MS3_HEIGHT_SHIFT;
ms3 |= (width - 1) << MS3_WIDTH_SHIFT;
OUT_BATCH(ms3);
@@ -307,7 +335,7 @@ I915DisplayVideoTextured(ScrnInfoPtr scrn,
else
OUT_BATCH(adaptor_priv->UBufOffset);
- ms3 = MAPSURF_8BIT | MT_8BIT_I8 | MS3_USE_FENCE_REGS;
+ ms3 = MAPSURF_8BIT | MT_8BIT_I8;
ms3 |= (height / 2 - 1) << MS3_HEIGHT_SHIFT;
ms3 |= (width / 2 - 1) << MS3_WIDTH_SHIFT;
OUT_BATCH(ms3);
@@ -320,7 +348,7 @@ I915DisplayVideoTextured(ScrnInfoPtr scrn,
else
OUT_BATCH(adaptor_priv->VBufOffset);
- ms3 = MAPSURF_8BIT | MT_8BIT_I8 | MS3_USE_FENCE_REGS;
+ ms3 = MAPSURF_8BIT | MT_8BIT_I8;
ms3 |= (height / 2 - 1) << MS3_HEIGHT_SHIFT;
ms3 |= (width / 2 - 1) << MS3_WIDTH_SHIFT;
OUT_BATCH(ms3);
@@ -381,22 +409,6 @@ I915DisplayVideoTextured(ScrnInfoPtr scrn,
FS_END();
}
- OUT_BATCH(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE);
-
- /* Set up the offset for translating from the given region
- * (in screen coordinates) to the backing pixmap.
- */
-#ifdef COMPOSITE
- pix_xoff = -pixmap->screen_x + pixmap->drawable.x;
- pix_yoff = -pixmap->screen_y + pixmap->drawable.y;
-#else
- pix_xoff = 0;
- pix_yoff = 0;
-#endif
-
- dxo = dstRegion->extents.x1;
- dyo = dstRegion->extents.y1;
-
OUT_BATCH(PRIM3D_RECTLIST | (12 * nbox_this_time - 1));
while (nbox_this_time--) {
int box_x1 = pbox->x1;
@@ -436,5 +448,34 @@ I915DisplayVideoTextured(ScrnInfoPtr scrn,
intel_batch_end_atomic(scrn);
}
+ if (target != pixmap) {
+ GCPtr gc;
+
+ gc = GetScratchGC(pixmap->drawable.depth,
+ pixmap->drawable.pScreen);
+ if (gc) {
+ RegionPtr tmp;
+
+ ValidateGC(&pixmap->drawable, gc);
+
+ if (REGION_NUM_RECTS(dstRegion) > 1) {
+ tmp = REGION_CREATE(pixmap->drawable.pScreen, NULL, 0);
+ if (tmp) {
+ REGION_COPY(pixmap->drawable.pScreen, tmp, dstRegion);
+ gc->funcs->ChangeClip(gc, CT_REGION, tmp, 0);
+ }
+ }
+
+ gc->ops->CopyArea(&target->drawable, &pixmap->drawable, gc,
+ 0, 0,
+ target->drawable.width,
+ target->drawable.height,
+ -pix_xoff, -pix_yoff);
+ FreeScratchGC(gc);
+ }
+
+ target->drawable.pScreen->DestroyPixmap(target);
+ }
+
i830_debug_flush(scrn);
}