i915_video.c revision 03b705cf
103b705cfSriastradh/*
203b705cfSriastradh * Copyright © 2006 Intel Corporation
303b705cfSriastradh *
403b705cfSriastradh * Permission is hereby granted, free of charge, to any person obtaining a
503b705cfSriastradh * copy of this software and associated documentation files (the "Software"),
603b705cfSriastradh * to deal in the Software without restriction, including without limitation
703b705cfSriastradh * the rights to use, copy, modify, merge, publish, distribute, sublicense,
803b705cfSriastradh * and/or sell copies of the Software, and to permit persons to whom the
903b705cfSriastradh * Software is furnished to do so, subject to the following conditions:
1003b705cfSriastradh *
1103b705cfSriastradh * The above copyright notice and this permission notice (including the next
1203b705cfSriastradh * paragraph) shall be included in all copies or substantial portions of the
1303b705cfSriastradh * Software.
1403b705cfSriastradh *
1503b705cfSriastradh * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1603b705cfSriastradh * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1703b705cfSriastradh * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1803b705cfSriastradh * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1903b705cfSriastradh * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2003b705cfSriastradh * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2103b705cfSriastradh * SOFTWARE.
2203b705cfSriastradh *
2303b705cfSriastradh * Authors:
2403b705cfSriastradh *    Eric Anholt <eric@anholt.net>
2503b705cfSriastradh *
2603b705cfSriastradh */
2703b705cfSriastradh
2803b705cfSriastradh#ifdef HAVE_CONFIG_H
2903b705cfSriastradh#include "config.h"
3003b705cfSriastradh#endif
3103b705cfSriastradh
3203b705cfSriastradh#include "xf86.h"
3303b705cfSriastradh#include "xf86_OSproc.h"
3403b705cfSriastradh#include "xf86xv.h"
3503b705cfSriastradh#include "fourcc.h"
3603b705cfSriastradh#include "gcstruct.h"
3703b705cfSriastradh
3803b705cfSriastradh#include "intel.h"
3903b705cfSriastradh#include "intel_video.h"
4003b705cfSriastradh#include "i915_reg.h"
4103b705cfSriastradh#include "i915_3d.h"
4203b705cfSriastradh
4303b705cfSriastradhvoid
4403b705cfSriastradhI915DisplayVideoTextured(ScrnInfoPtr scrn,
4503b705cfSriastradh			 intel_adaptor_private *adaptor_priv, int id,
4603b705cfSriastradh			 RegionPtr dstRegion,
4703b705cfSriastradh			 short width, short height, int video_pitch,
4803b705cfSriastradh			 int video_pitch2,
4903b705cfSriastradh			 short src_w, short src_h, short drw_w, short drw_h,
5003b705cfSriastradh			 PixmapPtr pixmap)
5103b705cfSriastradh{
5203b705cfSriastradh	intel_screen_private *intel = intel_get_screen_private(scrn);
5303b705cfSriastradh	uint32_t format, ms3, s5, tiling;
5403b705cfSriastradh	BoxPtr pbox = REGION_RECTS(dstRegion);
5503b705cfSriastradh	int nbox_total = REGION_NUM_RECTS(dstRegion);
5603b705cfSriastradh	int nbox_this_time;
5703b705cfSriastradh	int dxo, dyo, pix_xoff, pix_yoff;
5803b705cfSriastradh	PixmapPtr target;
5903b705cfSriastradh
6003b705cfSriastradh#if 0
6103b705cfSriastradh	ErrorF("I915DisplayVideo: %dx%d (pitch %d)\n", width, height,
6203b705cfSriastradh	       video_pitch);
6303b705cfSriastradh#endif
6403b705cfSriastradh
6503b705cfSriastradh	dxo = dstRegion->extents.x1;
6603b705cfSriastradh	dyo = dstRegion->extents.y1;
6703b705cfSriastradh
6803b705cfSriastradh	if (pixmap->drawable.width > 2048 || pixmap->drawable.height > 2048 ||
6903b705cfSriastradh	    !intel_check_pitch_3d(pixmap)) {
7003b705cfSriastradh		ScreenPtr screen = pixmap->drawable.pScreen;
7103b705cfSriastradh
7203b705cfSriastradh		target = screen->CreatePixmap(screen,
7303b705cfSriastradh					      dstRegion->extents.x2 - dxo,
7403b705cfSriastradh					      dstRegion->extents.y2 - dyo,
7503b705cfSriastradh					      pixmap->drawable.depth,
7603b705cfSriastradh					      CREATE_PIXMAP_USAGE_SCRATCH);
7703b705cfSriastradh		if (target == NULL)
7803b705cfSriastradh			return;
7903b705cfSriastradh
8003b705cfSriastradh		pix_xoff = -dxo;
8103b705cfSriastradh		pix_yoff = -dyo;
8203b705cfSriastradh	} else {
8303b705cfSriastradh		target = pixmap;
8403b705cfSriastradh
8503b705cfSriastradh		/* Set up the offset for translating from the given region
8603b705cfSriastradh		 * (in screen coordinates) to the backing pixmap.
8703b705cfSriastradh		 */
8803b705cfSriastradh#ifdef COMPOSITE
8903b705cfSriastradh		pix_xoff = -target->screen_x + target->drawable.x;
9003b705cfSriastradh		pix_yoff = -target->screen_y + target->drawable.y;
9103b705cfSriastradh#else
9203b705cfSriastradh		pix_xoff = 0;
9303b705cfSriastradh		pix_yoff = 0;
9403b705cfSriastradh#endif
9503b705cfSriastradh	}
9603b705cfSriastradh
9703b705cfSriastradh#define BYTES_FOR_BOXES(n)	((200 + (n) * 20) * 4)
9803b705cfSriastradh#define BOXES_IN_BYTES(s)	((((s)/4) - 200) / 20)
9903b705cfSriastradh#define BATCH_BYTES(p)		((p)->batch_bo->size - 16)
10003b705cfSriastradh
10103b705cfSriastradh	while (nbox_total) {
10203b705cfSriastradh		nbox_this_time = nbox_total;
10303b705cfSriastradh		if (BYTES_FOR_BOXES(nbox_this_time) > BATCH_BYTES(intel))
10403b705cfSriastradh			nbox_this_time = BOXES_IN_BYTES(BATCH_BYTES(intel));
10503b705cfSriastradh		nbox_total -= nbox_this_time;
10603b705cfSriastradh
10703b705cfSriastradh		intel_batch_start_atomic(scrn, 200 + 20 * nbox_this_time);
10803b705cfSriastradh
10903b705cfSriastradh		IntelEmitInvarientState(scrn);
11003b705cfSriastradh		intel->last_3d = LAST_3D_VIDEO;
11103b705cfSriastradh
11203b705cfSriastradh		/* draw rect -- just clipping */
11303b705cfSriastradh		OUT_BATCH(_3DSTATE_DRAW_RECT_CMD);
11403b705cfSriastradh		OUT_BATCH(DRAW_DITHER_OFS_X(pixmap->drawable.x & 3) |
11503b705cfSriastradh			  DRAW_DITHER_OFS_Y(pixmap->drawable.y & 3));
11603b705cfSriastradh		OUT_BATCH(0x00000000);	/* ymin, xmin */
11703b705cfSriastradh		/* ymax, xmax */
11803b705cfSriastradh		OUT_BATCH((target->drawable.width - 1) |
11903b705cfSriastradh			  (target->drawable.height - 1) << 16);
12003b705cfSriastradh		OUT_BATCH(0x00000000);	/* yorigin, xorigin */
12103b705cfSriastradh
12203b705cfSriastradh		OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(2) |
12303b705cfSriastradh			  I1_LOAD_S(5) | I1_LOAD_S(6) | 2);
12403b705cfSriastradh		OUT_BATCH(S2_TEXCOORD_FMT(0, TEXCOORDFMT_2D) |
12503b705cfSriastradh			  S2_TEXCOORD_FMT(1, TEXCOORDFMT_NOT_PRESENT) |
12603b705cfSriastradh			  S2_TEXCOORD_FMT(2, TEXCOORDFMT_NOT_PRESENT) |
12703b705cfSriastradh			  S2_TEXCOORD_FMT(3, TEXCOORDFMT_NOT_PRESENT) |
12803b705cfSriastradh			  S2_TEXCOORD_FMT(4, TEXCOORDFMT_NOT_PRESENT) |
12903b705cfSriastradh			  S2_TEXCOORD_FMT(5, TEXCOORDFMT_NOT_PRESENT) |
13003b705cfSriastradh			  S2_TEXCOORD_FMT(6, TEXCOORDFMT_NOT_PRESENT) |
13103b705cfSriastradh			  S2_TEXCOORD_FMT(7, TEXCOORDFMT_NOT_PRESENT));
13203b705cfSriastradh		s5 = 0x0;
13303b705cfSriastradh		if (intel->cpp == 2)
13403b705cfSriastradh			s5 |= S5_COLOR_DITHER_ENABLE;
13503b705cfSriastradh		OUT_BATCH(s5);	/* S5 - enable bits */
13603b705cfSriastradh		OUT_BATCH((2 << S6_DEPTH_TEST_FUNC_SHIFT) |
13703b705cfSriastradh			  (2 << S6_CBUF_SRC_BLEND_FACT_SHIFT) |
13803b705cfSriastradh			  (1 << S6_CBUF_DST_BLEND_FACT_SHIFT) |
13903b705cfSriastradh			  S6_COLOR_WRITE_ENABLE | (2 << S6_TRISTRIP_PV_SHIFT));
14003b705cfSriastradh
14103b705cfSriastradh		OUT_BATCH(_3DSTATE_CONST_BLEND_COLOR_CMD);
14203b705cfSriastradh		OUT_BATCH(0x00000000);
14303b705cfSriastradh
14403b705cfSriastradh		OUT_BATCH(_3DSTATE_DST_BUF_VARS_CMD);
14503b705cfSriastradh		if (intel->cpp == 2)
14603b705cfSriastradh			format = COLR_BUF_RGB565;
14703b705cfSriastradh		else
14803b705cfSriastradh			format =
14903b705cfSriastradh			    COLR_BUF_ARGB8888 | DEPTH_FRMT_24_FIXED_8_OTHER;
15003b705cfSriastradh
15103b705cfSriastradh		OUT_BATCH(LOD_PRECLAMP_OGL |
15203b705cfSriastradh			  DSTORG_HORT_BIAS(0x8) |
15303b705cfSriastradh			  DSTORG_VERT_BIAS(0x8) | format);
15403b705cfSriastradh
15503b705cfSriastradh		/* front buffer, pitch, offset */
15603b705cfSriastradh		if (intel_pixmap_tiled(target)) {
15703b705cfSriastradh			tiling = BUF_3D_TILED_SURFACE;
15803b705cfSriastradh			if (intel_get_pixmap_private(target)->tiling == I915_TILING_Y)
15903b705cfSriastradh				tiling |= BUF_3D_TILE_WALK_Y;
16003b705cfSriastradh		} else
16103b705cfSriastradh			tiling = 0;
16203b705cfSriastradh		OUT_BATCH(_3DSTATE_BUF_INFO_CMD);
16303b705cfSriastradh		OUT_BATCH(BUF_3D_ID_COLOR_BACK | tiling |
16403b705cfSriastradh			  BUF_3D_PITCH(intel_pixmap_pitch(target)));
16503b705cfSriastradh		OUT_RELOC_PIXMAP(target, I915_GEM_DOMAIN_RENDER,
16603b705cfSriastradh				 I915_GEM_DOMAIN_RENDER, 0);
16703b705cfSriastradh
16803b705cfSriastradh		if (!is_planar_fourcc(id)) {
16903b705cfSriastradh			FS_LOCALS();
17003b705cfSriastradh
17103b705cfSriastradh			OUT_BATCH(_3DSTATE_PIXEL_SHADER_CONSTANTS | 4);
17203b705cfSriastradh			OUT_BATCH(0x0000001);	/* constant 0 */
17303b705cfSriastradh			/* constant 0: brightness/contrast */
17403b705cfSriastradh			OUT_BATCH_F(adaptor_priv->brightness / 128.0);
17503b705cfSriastradh			OUT_BATCH_F(adaptor_priv->contrast / 255.0);
17603b705cfSriastradh			OUT_BATCH_F(0.0);
17703b705cfSriastradh			OUT_BATCH_F(0.0);
17803b705cfSriastradh
17903b705cfSriastradh			OUT_BATCH(_3DSTATE_SAMPLER_STATE | 3);
18003b705cfSriastradh			OUT_BATCH(0x00000001);
18103b705cfSriastradh			OUT_BATCH(SS2_COLORSPACE_CONVERSION |
18203b705cfSriastradh				  (FILTER_LINEAR << SS2_MAG_FILTER_SHIFT) |
18303b705cfSriastradh				  (FILTER_LINEAR << SS2_MIN_FILTER_SHIFT));
18403b705cfSriastradh			OUT_BATCH((TEXCOORDMODE_CLAMP_EDGE <<
18503b705cfSriastradh				   SS3_TCX_ADDR_MODE_SHIFT) |
18603b705cfSriastradh				  (TEXCOORDMODE_CLAMP_EDGE <<
18703b705cfSriastradh				   SS3_TCY_ADDR_MODE_SHIFT) |
18803b705cfSriastradh				  (0 << SS3_TEXTUREMAP_INDEX_SHIFT) |
18903b705cfSriastradh				  SS3_NORMALIZED_COORDS);
19003b705cfSriastradh			OUT_BATCH(0x00000000);
19103b705cfSriastradh
19203b705cfSriastradh			OUT_BATCH(_3DSTATE_MAP_STATE | 3);
19303b705cfSriastradh			OUT_BATCH(0x00000001);	/* texture map #1 */
19403b705cfSriastradh			if (adaptor_priv->buf)
19503b705cfSriastradh				OUT_RELOC(adaptor_priv->buf,
19603b705cfSriastradh					  I915_GEM_DOMAIN_SAMPLER, 0,
19703b705cfSriastradh					  adaptor_priv->YBufOffset);
19803b705cfSriastradh			else
19903b705cfSriastradh				OUT_BATCH(adaptor_priv->YBufOffset);
20003b705cfSriastradh
20103b705cfSriastradh			ms3 = MAPSURF_422;
20203b705cfSriastradh			switch (id) {
20303b705cfSriastradh			case FOURCC_YUY2:
20403b705cfSriastradh				ms3 |= MT_422_YCRCB_NORMAL;
20503b705cfSriastradh				break;
20603b705cfSriastradh			case FOURCC_UYVY:
20703b705cfSriastradh				ms3 |= MT_422_YCRCB_SWAPY;
20803b705cfSriastradh				break;
20903b705cfSriastradh			}
21003b705cfSriastradh			ms3 |= (height - 1) << MS3_HEIGHT_SHIFT;
21103b705cfSriastradh			ms3 |= (width - 1) << MS3_WIDTH_SHIFT;
21203b705cfSriastradh			OUT_BATCH(ms3);
21303b705cfSriastradh			OUT_BATCH(((video_pitch / 4) - 1) << MS4_PITCH_SHIFT);
21403b705cfSriastradh
21503b705cfSriastradh			FS_BEGIN();
21603b705cfSriastradh			i915_fs_dcl(FS_S0);
21703b705cfSriastradh			i915_fs_dcl(FS_T0);
21803b705cfSriastradh			i915_fs_texld(FS_OC, FS_S0, FS_T0);
21903b705cfSriastradh			if (adaptor_priv->brightness != 0) {
22003b705cfSriastradh				i915_fs_add(FS_OC,
22103b705cfSriastradh					    i915_fs_operand_reg(FS_OC),
22203b705cfSriastradh					    i915_fs_operand(FS_C0, X, X, X,
22303b705cfSriastradh							    ZERO));
22403b705cfSriastradh			}
22503b705cfSriastradh			FS_END();
22603b705cfSriastradh		} else {
22703b705cfSriastradh			FS_LOCALS();
22803b705cfSriastradh
22903b705cfSriastradh			/* For the planar formats, we set up three samplers --
23003b705cfSriastradh			 * one for each plane, in a Y8 format.  Because I
23103b705cfSriastradh			 * couldn't get the special PLANAR_TO_PACKED
23203b705cfSriastradh			 * shader setup to work, I did the manual pixel shader:
23303b705cfSriastradh			 *
23403b705cfSriastradh			 * y' = y - .0625
23503b705cfSriastradh			 * u' = u - .5
23603b705cfSriastradh			 * v' = v - .5;
23703b705cfSriastradh			 *
23803b705cfSriastradh			 * r = 1.1643 * y' + 0.0     * u' + 1.5958  * v'
23903b705cfSriastradh			 * g = 1.1643 * y' - 0.39173 * u' - 0.81290 * v'
24003b705cfSriastradh			 * b = 1.1643 * y' + 2.017   * u' + 0.0     * v'
24103b705cfSriastradh			 *
24203b705cfSriastradh			 * register assignment:
24303b705cfSriastradh			 * r0 = (y',u',v',0)
24403b705cfSriastradh			 * r1 = (y,y,y,y)
24503b705cfSriastradh			 * r2 = (u,u,u,u)
24603b705cfSriastradh			 * r3 = (v,v,v,v)
24703b705cfSriastradh			 * OC = (r,g,b,1)
24803b705cfSriastradh			 */
24903b705cfSriastradh			OUT_BATCH(_3DSTATE_PIXEL_SHADER_CONSTANTS | (22 - 2));
25003b705cfSriastradh			OUT_BATCH(0x000001f);	/* constants 0-4 */
25103b705cfSriastradh			/* constant 0: normalization offsets */
25203b705cfSriastradh			OUT_BATCH_F(-0.0625);
25303b705cfSriastradh			OUT_BATCH_F(-0.5);
25403b705cfSriastradh			OUT_BATCH_F(-0.5);
25503b705cfSriastradh			OUT_BATCH_F(0.0);
25603b705cfSriastradh			/* constant 1: r coefficients */
25703b705cfSriastradh			OUT_BATCH_F(1.1643);
25803b705cfSriastradh			OUT_BATCH_F(0.0);
25903b705cfSriastradh			OUT_BATCH_F(1.5958);
26003b705cfSriastradh			OUT_BATCH_F(0.0);
26103b705cfSriastradh			/* constant 2: g coefficients */
26203b705cfSriastradh			OUT_BATCH_F(1.1643);
26303b705cfSriastradh			OUT_BATCH_F(-0.39173);
26403b705cfSriastradh			OUT_BATCH_F(-0.81290);
26503b705cfSriastradh			OUT_BATCH_F(0.0);
26603b705cfSriastradh			/* constant 3: b coefficients */
26703b705cfSriastradh			OUT_BATCH_F(1.1643);
26803b705cfSriastradh			OUT_BATCH_F(2.017);
26903b705cfSriastradh			OUT_BATCH_F(0.0);
27003b705cfSriastradh			OUT_BATCH_F(0.0);
27103b705cfSriastradh			/* constant 4: brightness/contrast */
27203b705cfSriastradh			OUT_BATCH_F(adaptor_priv->brightness / 128.0);
27303b705cfSriastradh			OUT_BATCH_F(adaptor_priv->contrast / 255.0);
27403b705cfSriastradh			OUT_BATCH_F(0.0);
27503b705cfSriastradh			OUT_BATCH_F(0.0);
27603b705cfSriastradh
27703b705cfSriastradh			OUT_BATCH(_3DSTATE_SAMPLER_STATE | 9);
27803b705cfSriastradh			OUT_BATCH(0x00000007);
27903b705cfSriastradh			/* sampler 0 */
28003b705cfSriastradh			OUT_BATCH((FILTER_LINEAR << SS2_MAG_FILTER_SHIFT) |
28103b705cfSriastradh				  (FILTER_LINEAR << SS2_MIN_FILTER_SHIFT));
28203b705cfSriastradh			OUT_BATCH((TEXCOORDMODE_CLAMP_EDGE <<
28303b705cfSriastradh				   SS3_TCX_ADDR_MODE_SHIFT) |
28403b705cfSriastradh				  (TEXCOORDMODE_CLAMP_EDGE <<
28503b705cfSriastradh				   SS3_TCY_ADDR_MODE_SHIFT) |
28603b705cfSriastradh				  (0 << SS3_TEXTUREMAP_INDEX_SHIFT) |
28703b705cfSriastradh				  SS3_NORMALIZED_COORDS);
28803b705cfSriastradh			OUT_BATCH(0x00000000);
28903b705cfSriastradh			/* sampler 1 */
29003b705cfSriastradh			OUT_BATCH((FILTER_LINEAR << SS2_MAG_FILTER_SHIFT) |
29103b705cfSriastradh				  (FILTER_LINEAR << SS2_MIN_FILTER_SHIFT));
29203b705cfSriastradh			OUT_BATCH((TEXCOORDMODE_CLAMP_EDGE <<
29303b705cfSriastradh				   SS3_TCX_ADDR_MODE_SHIFT) |
29403b705cfSriastradh				  (TEXCOORDMODE_CLAMP_EDGE <<
29503b705cfSriastradh				   SS3_TCY_ADDR_MODE_SHIFT) |
29603b705cfSriastradh				  (1 << SS3_TEXTUREMAP_INDEX_SHIFT) |
29703b705cfSriastradh				  SS3_NORMALIZED_COORDS);
29803b705cfSriastradh			OUT_BATCH(0x00000000);
29903b705cfSriastradh			/* sampler 2 */
30003b705cfSriastradh			OUT_BATCH((FILTER_LINEAR << SS2_MAG_FILTER_SHIFT) |
30103b705cfSriastradh				  (FILTER_LINEAR << SS2_MIN_FILTER_SHIFT));
30203b705cfSriastradh			OUT_BATCH((TEXCOORDMODE_CLAMP_EDGE <<
30303b705cfSriastradh				   SS3_TCX_ADDR_MODE_SHIFT) |
30403b705cfSriastradh				  (TEXCOORDMODE_CLAMP_EDGE <<
30503b705cfSriastradh				   SS3_TCY_ADDR_MODE_SHIFT) |
30603b705cfSriastradh				  (2 << SS3_TEXTUREMAP_INDEX_SHIFT) |
30703b705cfSriastradh				  SS3_NORMALIZED_COORDS);
30803b705cfSriastradh			OUT_BATCH(0x00000000);
30903b705cfSriastradh
31003b705cfSriastradh			OUT_BATCH(_3DSTATE_MAP_STATE | 9);
31103b705cfSriastradh			OUT_BATCH(0x00000007);
31203b705cfSriastradh
31303b705cfSriastradh			if (adaptor_priv->buf)
31403b705cfSriastradh				OUT_RELOC(adaptor_priv->buf,
31503b705cfSriastradh					  I915_GEM_DOMAIN_SAMPLER, 0,
31603b705cfSriastradh					  adaptor_priv->YBufOffset);
31703b705cfSriastradh			else
31803b705cfSriastradh				OUT_BATCH(adaptor_priv->YBufOffset);
31903b705cfSriastradh
32003b705cfSriastradh			ms3 = MAPSURF_8BIT | MT_8BIT_I8;
32103b705cfSriastradh			ms3 |= (height - 1) << MS3_HEIGHT_SHIFT;
32203b705cfSriastradh			ms3 |= (width - 1) << MS3_WIDTH_SHIFT;
32303b705cfSriastradh			OUT_BATCH(ms3);
32403b705cfSriastradh			/* check to see if Y has special pitch than normal
32503b705cfSriastradh			 * double u/v pitch, e.g i915 XvMC hw requires at
32603b705cfSriastradh			 * least 1K alignment, so Y pitch might
32703b705cfSriastradh			 * be same as U/V's.*/
32803b705cfSriastradh			if (video_pitch2)
32903b705cfSriastradh				OUT_BATCH(((video_pitch2 / 4) -
33003b705cfSriastradh					   1) << MS4_PITCH_SHIFT);
33103b705cfSriastradh			else
33203b705cfSriastradh				OUT_BATCH(((video_pitch * 2 / 4) -
33303b705cfSriastradh					   1) << MS4_PITCH_SHIFT);
33403b705cfSriastradh
33503b705cfSriastradh			if (adaptor_priv->buf)
33603b705cfSriastradh				OUT_RELOC(adaptor_priv->buf,
33703b705cfSriastradh					  I915_GEM_DOMAIN_SAMPLER, 0,
33803b705cfSriastradh					  adaptor_priv->UBufOffset);
33903b705cfSriastradh			else
34003b705cfSriastradh				OUT_BATCH(adaptor_priv->UBufOffset);
34103b705cfSriastradh
34203b705cfSriastradh			ms3 = MAPSURF_8BIT | MT_8BIT_I8;
34303b705cfSriastradh			ms3 |= (height / 2 - 1) << MS3_HEIGHT_SHIFT;
34403b705cfSriastradh			ms3 |= (width / 2 - 1) << MS3_WIDTH_SHIFT;
34503b705cfSriastradh			OUT_BATCH(ms3);
34603b705cfSriastradh			OUT_BATCH(((video_pitch / 4) - 1) << MS4_PITCH_SHIFT);
34703b705cfSriastradh
34803b705cfSriastradh			if (adaptor_priv->buf)
34903b705cfSriastradh				OUT_RELOC(adaptor_priv->buf,
35003b705cfSriastradh					  I915_GEM_DOMAIN_SAMPLER, 0,
35103b705cfSriastradh					  adaptor_priv->VBufOffset);
35203b705cfSriastradh			else
35303b705cfSriastradh				OUT_BATCH(adaptor_priv->VBufOffset);
35403b705cfSriastradh
35503b705cfSriastradh			ms3 = MAPSURF_8BIT | MT_8BIT_I8;
35603b705cfSriastradh			ms3 |= (height / 2 - 1) << MS3_HEIGHT_SHIFT;
35703b705cfSriastradh			ms3 |= (width / 2 - 1) << MS3_WIDTH_SHIFT;
35803b705cfSriastradh			OUT_BATCH(ms3);
35903b705cfSriastradh			OUT_BATCH(((video_pitch / 4) - 1) << MS4_PITCH_SHIFT);
36003b705cfSriastradh
36103b705cfSriastradh			FS_BEGIN();
36203b705cfSriastradh			/* Declare samplers */
36303b705cfSriastradh			i915_fs_dcl(FS_S0);	/* Y */
36403b705cfSriastradh			i915_fs_dcl(FS_S1);	/* U */
36503b705cfSriastradh			i915_fs_dcl(FS_S2);	/* V */
36603b705cfSriastradh			i915_fs_dcl(FS_T0);	/* normalized coords */
36703b705cfSriastradh
36803b705cfSriastradh			/* Load samplers to temporaries. */
36903b705cfSriastradh			i915_fs_texld(FS_R1, FS_S0, FS_T0);
37003b705cfSriastradh			i915_fs_texld(FS_R2, FS_S1, FS_T0);
37103b705cfSriastradh			i915_fs_texld(FS_R3, FS_S2, FS_T0);
37203b705cfSriastradh
37303b705cfSriastradh			/* Move the sampled YUV data in R[123] to the first
37403b705cfSriastradh			 * 3 channels of R0.
37503b705cfSriastradh			 */
37603b705cfSriastradh			i915_fs_mov_masked(FS_R0, MASK_X,
37703b705cfSriastradh					   i915_fs_operand_reg(FS_R1));
37803b705cfSriastradh			i915_fs_mov_masked(FS_R0, MASK_Y,
37903b705cfSriastradh					   i915_fs_operand_reg(FS_R2));
38003b705cfSriastradh			i915_fs_mov_masked(FS_R0, MASK_Z,
38103b705cfSriastradh					   i915_fs_operand_reg(FS_R3));
38203b705cfSriastradh
38303b705cfSriastradh			/* Normalize the YUV data */
38403b705cfSriastradh			i915_fs_add(FS_R0, i915_fs_operand_reg(FS_R0),
38503b705cfSriastradh				    i915_fs_operand_reg(FS_C0));
38603b705cfSriastradh			/* dot-product the YUV data in R0 by the vectors of
38703b705cfSriastradh			 * coefficients for calculating R, G, and B, storing
38803b705cfSriastradh			 * the results in the R, G, or B channels of the output
38903b705cfSriastradh			 * color.  The OC results are implicitly clamped
39003b705cfSriastradh			 * at the end of the program.
39103b705cfSriastradh			 */
39203b705cfSriastradh			i915_fs_dp3(FS_OC, MASK_X,
39303b705cfSriastradh				    i915_fs_operand_reg(FS_R0),
39403b705cfSriastradh				    i915_fs_operand_reg(FS_C1));
39503b705cfSriastradh			i915_fs_dp3(FS_OC, MASK_Y,
39603b705cfSriastradh				    i915_fs_operand_reg(FS_R0),
39703b705cfSriastradh				    i915_fs_operand_reg(FS_C2));
39803b705cfSriastradh			i915_fs_dp3(FS_OC, MASK_Z,
39903b705cfSriastradh				    i915_fs_operand_reg(FS_R0),
40003b705cfSriastradh				    i915_fs_operand_reg(FS_C3));
40103b705cfSriastradh			/* Set alpha of the output to 1.0, by wiring W to 1
40203b705cfSriastradh			 * and not actually using the source.
40303b705cfSriastradh			 */
40403b705cfSriastradh			i915_fs_mov_masked(FS_OC, MASK_W,
40503b705cfSriastradh					   i915_fs_operand_one());
40603b705cfSriastradh
40703b705cfSriastradh			if (adaptor_priv->brightness != 0) {
40803b705cfSriastradh				i915_fs_add(FS_OC,
40903b705cfSriastradh					    i915_fs_operand_reg(FS_OC),
41003b705cfSriastradh					    i915_fs_operand(FS_C4, X, X, X,
41103b705cfSriastradh							    ZERO));
41203b705cfSriastradh			}
41303b705cfSriastradh			FS_END();
41403b705cfSriastradh		}
41503b705cfSriastradh
41603b705cfSriastradh		OUT_BATCH(PRIM3D_RECTLIST | (12 * nbox_this_time - 1));
41703b705cfSriastradh		while (nbox_this_time--) {
41803b705cfSriastradh			int box_x1 = pbox->x1;
41903b705cfSriastradh			int box_y1 = pbox->y1;
42003b705cfSriastradh			int box_x2 = pbox->x2;
42103b705cfSriastradh			int box_y2 = pbox->y2;
42203b705cfSriastradh			float src_scale_x, src_scale_y;
42303b705cfSriastradh
42403b705cfSriastradh			pbox++;
42503b705cfSriastradh
42603b705cfSriastradh			src_scale_x = ((float)src_w / width) / drw_w;
42703b705cfSriastradh			src_scale_y = ((float)src_h / height) / drw_h;
42803b705cfSriastradh
42903b705cfSriastradh			/* vertex data - rect list consists of bottom right,
43003b705cfSriastradh			 * bottom left, and top left vertices.
43103b705cfSriastradh			 */
43203b705cfSriastradh
43303b705cfSriastradh			/* bottom right */
43403b705cfSriastradh			OUT_BATCH_F(box_x2 + pix_xoff);
43503b705cfSriastradh			OUT_BATCH_F(box_y2 + pix_yoff);
43603b705cfSriastradh			OUT_BATCH_F((box_x2 - dxo) * src_scale_x);
43703b705cfSriastradh			OUT_BATCH_F((box_y2 - dyo) * src_scale_y);
43803b705cfSriastradh
43903b705cfSriastradh			/* bottom left */
44003b705cfSriastradh			OUT_BATCH_F(box_x1 + pix_xoff);
44103b705cfSriastradh			OUT_BATCH_F(box_y2 + pix_yoff);
44203b705cfSriastradh			OUT_BATCH_F((box_x1 - dxo) * src_scale_x);
44303b705cfSriastradh			OUT_BATCH_F((box_y2 - dyo) * src_scale_y);
44403b705cfSriastradh
44503b705cfSriastradh			/* top left */
44603b705cfSriastradh			OUT_BATCH_F(box_x1 + pix_xoff);
44703b705cfSriastradh			OUT_BATCH_F(box_y1 + pix_yoff);
44803b705cfSriastradh			OUT_BATCH_F((box_x1 - dxo) * src_scale_x);
44903b705cfSriastradh			OUT_BATCH_F((box_y1 - dyo) * src_scale_y);
45003b705cfSriastradh		}
45103b705cfSriastradh
45203b705cfSriastradh		intel_batch_end_atomic(scrn);
45303b705cfSriastradh	}
45403b705cfSriastradh
45503b705cfSriastradh	if (target != pixmap) {
45603b705cfSriastradh		GCPtr gc;
45703b705cfSriastradh
45803b705cfSriastradh		gc = GetScratchGC(pixmap->drawable.depth,
45903b705cfSriastradh				  pixmap->drawable.pScreen);
46003b705cfSriastradh		if (gc) {
46103b705cfSriastradh			gc->subWindowMode = ClipByChildren;
46203b705cfSriastradh
46303b705cfSriastradh			if (REGION_NUM_RECTS(dstRegion) > 1) {
46403b705cfSriastradh				RegionPtr tmp;
46503b705cfSriastradh
46603b705cfSriastradh				tmp = REGION_CREATE(pixmap->drawable.pScreen, NULL, 0);
46703b705cfSriastradh				if (tmp) {
46803b705cfSriastradh					REGION_COPY(pixmap->drawable.pScreen, tmp, dstRegion);
46903b705cfSriastradh					gc->funcs->ChangeClip(gc, CT_REGION, tmp, 0);
47003b705cfSriastradh				}
47103b705cfSriastradh			}
47203b705cfSriastradh
47303b705cfSriastradh			ValidateGC(&pixmap->drawable, gc);
47403b705cfSriastradh			gc->ops->CopyArea(&target->drawable, &pixmap->drawable, gc,
47503b705cfSriastradh					  0, 0,
47603b705cfSriastradh					  target->drawable.width,
47703b705cfSriastradh					  target->drawable.height,
47803b705cfSriastradh					  -pix_xoff, -pix_yoff);
47903b705cfSriastradh			FreeScratchGC(gc);
48003b705cfSriastradh		}
48103b705cfSriastradh
48203b705cfSriastradh		target->drawable.pScreen->DestroyPixmap(target);
48303b705cfSriastradh	}
48403b705cfSriastradh
48503b705cfSriastradh	intel_debug_flush(scrn);
48603b705cfSriastradh}
487