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