i915_render.c revision fa225cbc
1fa225cbcSrjs/*
2fa225cbcSrjs * Copyright © 2006 Intel Corporation
3fa225cbcSrjs *
4fa225cbcSrjs * Permission is hereby granted, free of charge, to any person obtaining a
5fa225cbcSrjs * copy of this software and associated documentation files (the "Software"),
6fa225cbcSrjs * to deal in the Software without restriction, including without limitation
7fa225cbcSrjs * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8fa225cbcSrjs * and/or sell copies of the Software, and to permit persons to whom the
9fa225cbcSrjs * Software is furnished to do so, subject to the following conditions:
10fa225cbcSrjs *
11fa225cbcSrjs * The above copyright notice and this permission notice (including the next
12fa225cbcSrjs * paragraph) shall be included in all copies or substantial portions of the
13fa225cbcSrjs * Software.
14fa225cbcSrjs *
15fa225cbcSrjs * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16fa225cbcSrjs * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17fa225cbcSrjs * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18fa225cbcSrjs * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19fa225cbcSrjs * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20fa225cbcSrjs * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21fa225cbcSrjs * SOFTWARE.
22fa225cbcSrjs *
23fa225cbcSrjs * Authors:
24fa225cbcSrjs *    Wang Zhenyu <zhenyu.z.wang@intel.com>
25fa225cbcSrjs *    Eric Anholt <eric@anholt.net>
26fa225cbcSrjs *
27fa225cbcSrjs */
28fa225cbcSrjs
29fa225cbcSrjs#ifdef HAVE_CONFIG_H
30fa225cbcSrjs#include "config.h"
31fa225cbcSrjs#endif
32fa225cbcSrjs
33fa225cbcSrjs#include "xf86.h"
34fa225cbcSrjs#include "i830.h"
35fa225cbcSrjs#include "i915_reg.h"
36fa225cbcSrjs#include "i915_3d.h"
37fa225cbcSrjs
38fa225cbcSrjsstruct formatinfo {
39fa225cbcSrjs    int fmt;
40fa225cbcSrjs    uint32_t card_fmt;
41fa225cbcSrjs};
42fa225cbcSrjs
43fa225cbcSrjsstruct blendinfo {
44fa225cbcSrjs    Bool dst_alpha;
45fa225cbcSrjs    Bool src_alpha;
46fa225cbcSrjs    uint32_t src_blend;
47fa225cbcSrjs    uint32_t dst_blend;
48fa225cbcSrjs};
49fa225cbcSrjs
50fa225cbcSrjsstatic struct blendinfo i915_blend_op[] = {
51fa225cbcSrjs    /* Clear */
52fa225cbcSrjs    {0, 0, BLENDFACT_ZERO,          BLENDFACT_ZERO},
53fa225cbcSrjs    /* Src */
54fa225cbcSrjs    {0, 0, BLENDFACT_ONE,           BLENDFACT_ZERO},
55fa225cbcSrjs    /* Dst */
56fa225cbcSrjs    {0, 0, BLENDFACT_ZERO,          BLENDFACT_ONE},
57fa225cbcSrjs    /* Over */
58fa225cbcSrjs    {0, 1, BLENDFACT_ONE,           BLENDFACT_INV_SRC_ALPHA},
59fa225cbcSrjs    /* OverReverse */
60fa225cbcSrjs    {1, 0, BLENDFACT_INV_DST_ALPHA, BLENDFACT_ONE},
61fa225cbcSrjs    /* In */
62fa225cbcSrjs    {1, 0, BLENDFACT_DST_ALPHA,     BLENDFACT_ZERO},
63fa225cbcSrjs    /* InReverse */
64fa225cbcSrjs    {0, 1, BLENDFACT_ZERO,          BLENDFACT_SRC_ALPHA},
65fa225cbcSrjs    /* Out */
66fa225cbcSrjs    {1, 0, BLENDFACT_INV_DST_ALPHA, BLENDFACT_ZERO},
67fa225cbcSrjs    /* OutReverse */
68fa225cbcSrjs    {0, 1, BLENDFACT_ZERO,          BLENDFACT_INV_SRC_ALPHA},
69fa225cbcSrjs    /* Atop */
70fa225cbcSrjs    {1, 1, BLENDFACT_DST_ALPHA,     BLENDFACT_INV_SRC_ALPHA},
71fa225cbcSrjs    /* AtopReverse */
72fa225cbcSrjs    {1, 1, BLENDFACT_INV_DST_ALPHA, BLENDFACT_SRC_ALPHA},
73fa225cbcSrjs    /* Xor */
74fa225cbcSrjs    {1, 1, BLENDFACT_INV_DST_ALPHA, BLENDFACT_INV_SRC_ALPHA},
75fa225cbcSrjs    /* Add */
76fa225cbcSrjs    {0, 0, BLENDFACT_ONE,           BLENDFACT_ONE},
77fa225cbcSrjs};
78fa225cbcSrjs
79fa225cbcSrjsstatic struct formatinfo i915_tex_formats[] = {
80fa225cbcSrjs    {PICT_a8r8g8b8, MAPSURF_32BIT | MT_32BIT_ARGB8888 },
81fa225cbcSrjs    {PICT_x8r8g8b8, MAPSURF_32BIT | MT_32BIT_XRGB8888 },
82fa225cbcSrjs    {PICT_a8b8g8r8, MAPSURF_32BIT | MT_32BIT_ABGR8888 },
83fa225cbcSrjs    {PICT_x8b8g8r8, MAPSURF_32BIT | MT_32BIT_XBGR8888 },
84fa225cbcSrjs    {PICT_r5g6b5,   MAPSURF_16BIT | MT_16BIT_RGB565   },
85fa225cbcSrjs    {PICT_a1r5g5b5, MAPSURF_16BIT | MT_16BIT_ARGB1555 },
86fa225cbcSrjs    {PICT_x1r5g5b5, MAPSURF_16BIT | MT_16BIT_ARGB1555 },
87fa225cbcSrjs    {PICT_a4r4g4b4, MAPSURF_16BIT | MT_16BIT_ARGB4444 },
88fa225cbcSrjs    {PICT_x4r4g4b4, MAPSURF_16BIT | MT_16BIT_ARGB4444 },
89fa225cbcSrjs    {PICT_a8,       MAPSURF_8BIT | MT_8BIT_A8 	  },
90fa225cbcSrjs};
91fa225cbcSrjs
92fa225cbcSrjsstatic uint32_t i915_get_blend_cntl(int op, PicturePtr pMask,
93fa225cbcSrjs				    uint32_t dst_format)
94fa225cbcSrjs{
95fa225cbcSrjs    uint32_t sblend, dblend;
96fa225cbcSrjs
97fa225cbcSrjs    sblend = i915_blend_op[op].src_blend;
98fa225cbcSrjs    dblend = i915_blend_op[op].dst_blend;
99fa225cbcSrjs
100fa225cbcSrjs    /* If there's no dst alpha channel, adjust the blend op so that we'll treat
101fa225cbcSrjs     * it as always 1.
102fa225cbcSrjs     */
103fa225cbcSrjs    if (PICT_FORMAT_A(dst_format) == 0 && i915_blend_op[op].dst_alpha) {
104fa225cbcSrjs        if (sblend == BLENDFACT_DST_ALPHA)
105fa225cbcSrjs            sblend = BLENDFACT_ONE;
106fa225cbcSrjs        else if (sblend == BLENDFACT_INV_DST_ALPHA)
107fa225cbcSrjs            sblend = BLENDFACT_ZERO;
108fa225cbcSrjs    }
109fa225cbcSrjs
110fa225cbcSrjs    /* i915 engine reads 8bit color buffer into green channel in cases
111fa225cbcSrjs       like color buffer blending .etc, and also writes back green channel.
112fa225cbcSrjs       So with dst_alpha blend we should use color factor. See spec on
113fa225cbcSrjs       "8-bit rendering" */
114fa225cbcSrjs    if ((dst_format == PICT_a8) && i915_blend_op[op].dst_alpha) {
115fa225cbcSrjs        if (sblend == BLENDFACT_DST_ALPHA)
116fa225cbcSrjs            sblend = BLENDFACT_DST_COLR;
117fa225cbcSrjs        else if (sblend == BLENDFACT_INV_DST_ALPHA)
118fa225cbcSrjs            sblend = BLENDFACT_INV_DST_COLR;
119fa225cbcSrjs    }
120fa225cbcSrjs
121fa225cbcSrjs    /* If the source alpha is being used, then we should only be in a case
122fa225cbcSrjs     * where the source blend factor is 0, and the source blend value is the
123fa225cbcSrjs     * mask channels multiplied by the source picture's alpha.
124fa225cbcSrjs     */
125fa225cbcSrjs    if (pMask && pMask->componentAlpha && PICT_FORMAT_RGB(pMask->format) &&
126fa225cbcSrjs	i915_blend_op[op].src_alpha)
127fa225cbcSrjs    {
128fa225cbcSrjs        if (dblend == BLENDFACT_SRC_ALPHA) {
129fa225cbcSrjs	    dblend = BLENDFACT_SRC_COLR;
130fa225cbcSrjs        } else if (dblend == BLENDFACT_INV_SRC_ALPHA) {
131fa225cbcSrjs	    dblend = BLENDFACT_INV_SRC_COLR;
132fa225cbcSrjs        }
133fa225cbcSrjs    }
134fa225cbcSrjs
135fa225cbcSrjs    return (sblend << S6_CBUF_SRC_BLEND_FACT_SHIFT) |
136fa225cbcSrjs	(dblend << S6_CBUF_DST_BLEND_FACT_SHIFT);
137fa225cbcSrjs}
138fa225cbcSrjs
139fa225cbcSrjsstatic Bool i915_get_dest_format(PicturePtr pDstPicture, uint32_t *dst_format)
140fa225cbcSrjs{
141fa225cbcSrjs    switch (pDstPicture->format) {
142fa225cbcSrjs    case PICT_a8r8g8b8:
143fa225cbcSrjs    case PICT_x8r8g8b8:
144fa225cbcSrjs        *dst_format = COLR_BUF_ARGB8888;
145fa225cbcSrjs        break;
146fa225cbcSrjs    case PICT_r5g6b5:
147fa225cbcSrjs        *dst_format = COLR_BUF_RGB565;
148fa225cbcSrjs        break;
149fa225cbcSrjs    case PICT_a1r5g5b5:
150fa225cbcSrjs    case PICT_x1r5g5b5:
151fa225cbcSrjs        *dst_format = COLR_BUF_ARGB1555;
152fa225cbcSrjs        break;
153fa225cbcSrjs    case PICT_a8:
154fa225cbcSrjs        *dst_format = COLR_BUF_8BIT;
155fa225cbcSrjs        break;
156fa225cbcSrjs    case PICT_a4r4g4b4:
157fa225cbcSrjs    case PICT_x4r4g4b4:
158fa225cbcSrjs	*dst_format = COLR_BUF_ARGB4444;
159fa225cbcSrjs	break;
160fa225cbcSrjs    default:
161fa225cbcSrjs	{
162fa225cbcSrjs	    ScrnInfoPtr pScrn;
163fa225cbcSrjs
164fa225cbcSrjs	    pScrn = xf86Screens[pDstPicture->pDrawable->pScreen->myNum];
165fa225cbcSrjs	    I830FALLBACK("Unsupported dest format 0x%x\n",
166fa225cbcSrjs			 (int)pDstPicture->format);
167fa225cbcSrjs	}
168fa225cbcSrjs    }
169fa225cbcSrjs    return TRUE;
170fa225cbcSrjs}
171fa225cbcSrjs
172fa225cbcSrjsstatic Bool i915_check_composite_texture(ScrnInfoPtr pScrn, PicturePtr pPict, int unit)
173fa225cbcSrjs{
174fa225cbcSrjs    if (pPict->repeatType > RepeatReflect)
175fa225cbcSrjs        I830FALLBACK("Unsupported picture repeat %d\n", pPict->repeatType);
176fa225cbcSrjs
177fa225cbcSrjs    if (pPict->filter != PictFilterNearest &&
178fa225cbcSrjs        pPict->filter != PictFilterBilinear)
179fa225cbcSrjs        I830FALLBACK("Unsupported filter 0x%x\n", pPict->filter);
180fa225cbcSrjs
181fa225cbcSrjs    if (pPict->pDrawable)
182fa225cbcSrjs    {
183fa225cbcSrjs	int w, h, i;
184fa225cbcSrjs
185fa225cbcSrjs	w = pPict->pDrawable->width;
186fa225cbcSrjs	h = pPict->pDrawable->height;
187fa225cbcSrjs	if ((w > 2048) || (h > 2048))
188fa225cbcSrjs	    I830FALLBACK("Picture w/h too large (%dx%d)\n", w, h);
189fa225cbcSrjs
190fa225cbcSrjs	for (i = 0; i < sizeof(i915_tex_formats) / sizeof(i915_tex_formats[0]);
191fa225cbcSrjs	     i++)
192fa225cbcSrjs	{
193fa225cbcSrjs	    if (i915_tex_formats[i].fmt == pPict->format)
194fa225cbcSrjs		break;
195fa225cbcSrjs	}
196fa225cbcSrjs	if (i == sizeof(i915_tex_formats) / sizeof(i915_tex_formats[0]))
197fa225cbcSrjs	    I830FALLBACK("Unsupported picture format 0x%x\n",
198fa225cbcSrjs			 (int)pPict->format);
199fa225cbcSrjs    }
200fa225cbcSrjs
201fa225cbcSrjs    return TRUE;
202fa225cbcSrjs}
203fa225cbcSrjs
204fa225cbcSrjsBool
205fa225cbcSrjsi915_check_composite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture,
206fa225cbcSrjs		     PicturePtr pDstPicture)
207fa225cbcSrjs{
208fa225cbcSrjs    ScrnInfoPtr pScrn = xf86Screens[pDstPicture->pDrawable->pScreen->myNum];
209fa225cbcSrjs    uint32_t tmp1;
210fa225cbcSrjs
211fa225cbcSrjs    /* Check for unsupported compositing operations. */
212fa225cbcSrjs    if (op >= sizeof(i915_blend_op) / sizeof(i915_blend_op[0]))
213fa225cbcSrjs        I830FALLBACK("Unsupported Composite op 0x%x\n", op);
214fa225cbcSrjs    if (pMaskPicture != NULL && pMaskPicture->componentAlpha &&
215fa225cbcSrjs	PICT_FORMAT_RGB(pMaskPicture->format))
216fa225cbcSrjs    {
217fa225cbcSrjs        /* Check if it's component alpha that relies on a source alpha and on
218fa225cbcSrjs         * the source value.  We can only get one of those into the single
219fa225cbcSrjs         * source value that we get to blend with.
220fa225cbcSrjs         */
221fa225cbcSrjs        if (i915_blend_op[op].src_alpha &&
222fa225cbcSrjs            (i915_blend_op[op].src_blend != BLENDFACT_ZERO))
223fa225cbcSrjs            	I830FALLBACK("Component alpha not supported with source "
224fa225cbcSrjs			     "alpha and source value blending.\n");
225fa225cbcSrjs    }
226fa225cbcSrjs
227fa225cbcSrjs    if (!i915_check_composite_texture(pScrn, pSrcPicture, 0))
228fa225cbcSrjs        I830FALLBACK("Check Src picture texture\n");
229fa225cbcSrjs    if (pMaskPicture != NULL && !i915_check_composite_texture(pScrn, pMaskPicture, 1))
230fa225cbcSrjs        I830FALLBACK("Check Mask picture texture\n");
231fa225cbcSrjs
232fa225cbcSrjs    if (!i915_get_dest_format(pDstPicture, &tmp1))
233fa225cbcSrjs	I830FALLBACK("Get Color buffer format\n");
234fa225cbcSrjs
235fa225cbcSrjs    return TRUE;
236fa225cbcSrjs}
237fa225cbcSrjs
238fa225cbcSrjsstatic Bool
239fa225cbcSrjsi915_texture_setup(PicturePtr pPict, PixmapPtr pPix, int unit)
240fa225cbcSrjs{
241fa225cbcSrjs    ScrnInfoPtr pScrn = xf86Screens[pPict->pDrawable->pScreen->myNum];
242fa225cbcSrjs    I830Ptr pI830 = I830PTR(pScrn);
243fa225cbcSrjs    uint32_t format, pitch, filter;
244fa225cbcSrjs    int w, h, i;
245fa225cbcSrjs    uint32_t wrap_mode;
246fa225cbcSrjs
247fa225cbcSrjs    pitch = intel_get_pixmap_pitch(pPix);
248fa225cbcSrjs    w = pPict->pDrawable->width;
249fa225cbcSrjs    h = pPict->pDrawable->height;
250fa225cbcSrjs    pI830->scale_units[unit][0] = pPix->drawable.width;
251fa225cbcSrjs    pI830->scale_units[unit][1] = pPix->drawable.height;
252fa225cbcSrjs
253fa225cbcSrjs    for (i = 0; i < sizeof(i915_tex_formats) / sizeof(i915_tex_formats[0]);
254fa225cbcSrjs	 i++)
255fa225cbcSrjs    {
256fa225cbcSrjs        if (i915_tex_formats[i].fmt == pPict->format)
257fa225cbcSrjs	    break;
258fa225cbcSrjs    }
259fa225cbcSrjs    if (i == sizeof(i915_tex_formats)/ sizeof(i915_tex_formats[0]))
260fa225cbcSrjs	I830FALLBACK("unknown texture format\n");
261fa225cbcSrjs    format = i915_tex_formats[i].card_fmt;
262fa225cbcSrjs
263fa225cbcSrjs    switch (pPict->repeatType) {
264fa225cbcSrjs    case RepeatNone:
265fa225cbcSrjs	wrap_mode = TEXCOORDMODE_CLAMP_BORDER;
266fa225cbcSrjs	break;
267fa225cbcSrjs    case RepeatNormal:
268fa225cbcSrjs	wrap_mode = TEXCOORDMODE_WRAP;
269fa225cbcSrjs	break;
270fa225cbcSrjs    case RepeatPad:
271fa225cbcSrjs	wrap_mode = TEXCOORDMODE_CLAMP_EDGE;
272fa225cbcSrjs	break;
273fa225cbcSrjs    case RepeatReflect:
274fa225cbcSrjs	wrap_mode = TEXCOORDMODE_MIRROR;
275fa225cbcSrjs	break;
276fa225cbcSrjs    default:
277fa225cbcSrjs	FatalError("Unknown repeat type %d\n", pPict->repeatType);
278fa225cbcSrjs    }
279fa225cbcSrjs
280fa225cbcSrjs    switch (pPict->filter) {
281fa225cbcSrjs    case PictFilterNearest:
282fa225cbcSrjs        filter = (FILTER_NEAREST << SS2_MAG_FILTER_SHIFT) |
283fa225cbcSrjs	    (FILTER_NEAREST << SS2_MIN_FILTER_SHIFT);
284fa225cbcSrjs        break;
285fa225cbcSrjs    case PictFilterBilinear:
286fa225cbcSrjs        filter = (FILTER_LINEAR << SS2_MAG_FILTER_SHIFT) |
287fa225cbcSrjs	    (FILTER_LINEAR << SS2_MIN_FILTER_SHIFT);
288fa225cbcSrjs        break;
289fa225cbcSrjs    default:
290fa225cbcSrjs	filter = 0;
291fa225cbcSrjs        I830FALLBACK("Bad filter 0x%x\n", pPict->filter);
292fa225cbcSrjs    }
293fa225cbcSrjs
294fa225cbcSrjs    pI830->mapstate[unit * 3 + 0] = 0; /* offset filled in at emit time */
295fa225cbcSrjs    pI830->mapstate[unit * 3 + 1] = format |
296fa225cbcSrjs	MS3_USE_FENCE_REGS |
297fa225cbcSrjs	((pPix->drawable.height - 1) << MS3_HEIGHT_SHIFT) |
298fa225cbcSrjs	((pPix->drawable.width - 1) << MS3_WIDTH_SHIFT);
299fa225cbcSrjs    pI830->mapstate[unit * 3 + 2] = ((pitch / 4) - 1) << MS4_PITCH_SHIFT;
300fa225cbcSrjs
301fa225cbcSrjs    pI830->samplerstate[unit * 3 + 0] = (MIPFILTER_NONE <<
302fa225cbcSrjs					 SS2_MIP_FILTER_SHIFT);
303fa225cbcSrjs    pI830->samplerstate[unit * 3 + 0] |= filter;
304fa225cbcSrjs    pI830->samplerstate[unit * 3 + 1] = SS3_NORMALIZED_COORDS;
305fa225cbcSrjs    pI830->samplerstate[unit * 3 + 1] |= wrap_mode << SS3_TCX_ADDR_MODE_SHIFT;
306fa225cbcSrjs    pI830->samplerstate[unit * 3 + 1] |= wrap_mode << SS3_TCY_ADDR_MODE_SHIFT;
307fa225cbcSrjs    pI830->samplerstate[unit * 3 + 1] |= unit << SS3_TEXTUREMAP_INDEX_SHIFT;
308fa225cbcSrjs    pI830->samplerstate[unit * 3 + 2] = 0x00000000; /* border color */
309fa225cbcSrjs
310fa225cbcSrjs    pI830->transform[unit] = pPict->transform;
311fa225cbcSrjs
312fa225cbcSrjs    return TRUE;
313fa225cbcSrjs}
314fa225cbcSrjs
315fa225cbcSrjsBool
316fa225cbcSrjsi915_prepare_composite(int op, PicturePtr pSrcPicture,
317fa225cbcSrjs		       PicturePtr pMaskPicture, PicturePtr pDstPicture,
318fa225cbcSrjs		       PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst)
319fa225cbcSrjs{
320fa225cbcSrjs    ScrnInfoPtr pScrn = xf86Screens[pSrcPicture->pDrawable->pScreen->myNum];
321fa225cbcSrjs    I830Ptr pI830 = I830PTR(pScrn);
322fa225cbcSrjs    drm_intel_bo *bo_table[] = {
323fa225cbcSrjs	NULL, /* batch_bo */
324fa225cbcSrjs	i830_get_pixmap_bo(pSrc),
325fa225cbcSrjs	pMask ? i830_get_pixmap_bo(pMask) : NULL,
326fa225cbcSrjs	i830_get_pixmap_bo(pDst),
327fa225cbcSrjs    };
328fa225cbcSrjs
329fa225cbcSrjs    pI830->render_src_picture = pSrcPicture;
330fa225cbcSrjs    pI830->render_src = pSrc;
331fa225cbcSrjs    pI830->render_mask_picture = pMaskPicture;
332fa225cbcSrjs    pI830->render_mask = pMask;
333fa225cbcSrjs    pI830->render_dst_picture = pDstPicture;
334fa225cbcSrjs    pI830->render_dst = pDst;
335fa225cbcSrjs
336fa225cbcSrjs    i830_exa_check_pitch_3d(pSrc);
337fa225cbcSrjs    if (pMask)
338fa225cbcSrjs	i830_exa_check_pitch_3d(pMask);
339fa225cbcSrjs    i830_exa_check_pitch_3d(pDst);
340fa225cbcSrjs
341fa225cbcSrjs    if (!i915_get_dest_format(pDstPicture,
342fa225cbcSrjs			      &pI830->i915_render_state.dst_format))
343fa225cbcSrjs	return FALSE;
344fa225cbcSrjs
345fa225cbcSrjs    if (!i830_get_aperture_space(pScrn, bo_table, ARRAY_SIZE(bo_table)))
346fa225cbcSrjs	return FALSE;
347fa225cbcSrjs
348fa225cbcSrjs    if (!i915_texture_setup(pSrcPicture, pSrc, 0))
349fa225cbcSrjs	I830FALLBACK("fail to setup src texture\n");
350fa225cbcSrjs
351fa225cbcSrjs    pI830->dst_coord_adjust = 0;
352fa225cbcSrjs    pI830->src_coord_adjust = 0;
353fa225cbcSrjs    pI830->mask_coord_adjust = 0;
354fa225cbcSrjs    if (pSrcPicture->filter == PictFilterNearest)
355fa225cbcSrjs	pI830->dst_coord_adjust = -0.125;
356fa225cbcSrjs    if (pMask != NULL) {
357fa225cbcSrjs	if (!i915_texture_setup(pMaskPicture, pMask, 1))
358fa225cbcSrjs	    I830FALLBACK("fail to setup mask texture\n");
359fa225cbcSrjs
360fa225cbcSrjs	if (pMaskPicture->filter == PictFilterNearest)
361fa225cbcSrjs	    pI830->dst_coord_adjust = -0.125;
362fa225cbcSrjs    } else {
363fa225cbcSrjs	pI830->transform[1] = NULL;
364fa225cbcSrjs	pI830->scale_units[1][0] = -1;
365fa225cbcSrjs	pI830->scale_units[1][1] = -1;
366fa225cbcSrjs    }
367fa225cbcSrjs
368fa225cbcSrjs    pI830->i915_render_state.op = op;
369fa225cbcSrjs    pI830->i915_render_state.needs_emit = TRUE;
370fa225cbcSrjs
371fa225cbcSrjs    return TRUE;
372fa225cbcSrjs}
373fa225cbcSrjs
374fa225cbcSrjsstatic void
375fa225cbcSrjsi915_emit_composite_setup(ScrnInfoPtr pScrn)
376fa225cbcSrjs{
377fa225cbcSrjs    I830Ptr pI830 = I830PTR(pScrn);
378fa225cbcSrjs    int op = pI830->i915_render_state.op;
379fa225cbcSrjs    PicturePtr pSrcPicture = pI830->render_src_picture;
380fa225cbcSrjs    PicturePtr pMaskPicture = pI830->render_mask_picture;
381fa225cbcSrjs    PicturePtr pDstPicture = pI830->render_dst_picture;
382fa225cbcSrjs    PixmapPtr pSrc = pI830->render_src;
383fa225cbcSrjs    PixmapPtr pMask = pI830->render_mask;
384fa225cbcSrjs    PixmapPtr pDst = pI830->render_dst;
385fa225cbcSrjs    uint32_t dst_format = pI830->i915_render_state.dst_format, dst_pitch;
386fa225cbcSrjs    uint32_t blendctl;
387fa225cbcSrjs    int out_reg = FS_OC;
388fa225cbcSrjs    FS_LOCALS(20);
389fa225cbcSrjs    Bool is_affine_src, is_affine_mask;
390fa225cbcSrjs
391fa225cbcSrjs    pI830->i915_render_state.needs_emit = FALSE;
392fa225cbcSrjs
393fa225cbcSrjs    IntelEmitInvarientState(pScrn);
394fa225cbcSrjs    pI830->last_3d = LAST_3D_RENDER;
395fa225cbcSrjs
396fa225cbcSrjs    dst_pitch = intel_get_pixmap_pitch(pDst);
397fa225cbcSrjs
398fa225cbcSrjs    is_affine_src = i830_transform_is_affine (pI830->transform[0]);
399fa225cbcSrjs    is_affine_mask = i830_transform_is_affine (pI830->transform[1]);
400fa225cbcSrjs
401fa225cbcSrjs    if (pMask == NULL) {
402fa225cbcSrjs	BEGIN_BATCH(10);
403fa225cbcSrjs	OUT_BATCH(_3DSTATE_MAP_STATE | 3);
404fa225cbcSrjs	OUT_BATCH(0x00000001); /* map 0 */
405fa225cbcSrjs	OUT_RELOC_PIXMAP(pSrc, I915_GEM_DOMAIN_SAMPLER, 0, 0);
406fa225cbcSrjs	OUT_BATCH(pI830->mapstate[1]);
407fa225cbcSrjs	OUT_BATCH(pI830->mapstate[2]);
408fa225cbcSrjs
409fa225cbcSrjs	OUT_BATCH(_3DSTATE_SAMPLER_STATE | 3);
410fa225cbcSrjs	OUT_BATCH(0x00000001); /* sampler 0 */
411fa225cbcSrjs	OUT_BATCH(pI830->samplerstate[0]);
412fa225cbcSrjs	OUT_BATCH(pI830->samplerstate[1]);
413fa225cbcSrjs	OUT_BATCH(pI830->samplerstate[2]);
414fa225cbcSrjs	ADVANCE_BATCH();
415fa225cbcSrjs    } else {
416fa225cbcSrjs	BEGIN_BATCH(16);
417fa225cbcSrjs	OUT_BATCH(_3DSTATE_MAP_STATE | 6);
418fa225cbcSrjs	OUT_BATCH(0x00000003); /* map 0,1 */
419fa225cbcSrjs	OUT_RELOC_PIXMAP(pSrc, I915_GEM_DOMAIN_SAMPLER, 0, 0);
420fa225cbcSrjs	OUT_BATCH(pI830->mapstate[1]);
421fa225cbcSrjs	OUT_BATCH(pI830->mapstate[2]);
422fa225cbcSrjs	OUT_RELOC_PIXMAP(pMask, I915_GEM_DOMAIN_SAMPLER, 0, 0);
423fa225cbcSrjs	OUT_BATCH(pI830->mapstate[4]);
424fa225cbcSrjs	OUT_BATCH(pI830->mapstate[5]);
425fa225cbcSrjs
426fa225cbcSrjs	OUT_BATCH(_3DSTATE_SAMPLER_STATE | 6);
427fa225cbcSrjs	OUT_BATCH(0x00000003); /* sampler 0,1 */
428fa225cbcSrjs	OUT_BATCH(pI830->samplerstate[0]);
429fa225cbcSrjs	OUT_BATCH(pI830->samplerstate[1]);
430fa225cbcSrjs	OUT_BATCH(pI830->samplerstate[2]);
431fa225cbcSrjs	OUT_BATCH(pI830->samplerstate[3]);
432fa225cbcSrjs	OUT_BATCH(pI830->samplerstate[4]);
433fa225cbcSrjs	OUT_BATCH(pI830->samplerstate[5]);
434fa225cbcSrjs	ADVANCE_BATCH();
435fa225cbcSrjs    }
436fa225cbcSrjs    {
437fa225cbcSrjs	uint32_t ss2;
438fa225cbcSrjs
439fa225cbcSrjs	BEGIN_BATCH(16);
440fa225cbcSrjs	OUT_BATCH(_3DSTATE_BUF_INFO_CMD);
441fa225cbcSrjs	OUT_BATCH(BUF_3D_ID_COLOR_BACK| BUF_3D_USE_FENCE|
442fa225cbcSrjs		  BUF_3D_PITCH(dst_pitch));
443fa225cbcSrjs	OUT_RELOC_PIXMAP(pDst, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0);
444fa225cbcSrjs
445fa225cbcSrjs	OUT_BATCH(_3DSTATE_DST_BUF_VARS_CMD);
446fa225cbcSrjs	OUT_BATCH(dst_format);
447fa225cbcSrjs
448fa225cbcSrjs	OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(2) |
449fa225cbcSrjs		  I1_LOAD_S(4) | I1_LOAD_S(5) | I1_LOAD_S(6) | 3);
450fa225cbcSrjs	ss2 = S2_TEXCOORD_FMT(0, is_affine_src ? TEXCOORDFMT_2D : TEXCOORDFMT_4D);
451fa225cbcSrjs	if (pMask)
452fa225cbcSrjs		ss2 |= S2_TEXCOORD_FMT(1, is_affine_mask ? TEXCOORDFMT_2D : TEXCOORDFMT_4D);
453fa225cbcSrjs	else
454fa225cbcSrjs		ss2 |= S2_TEXCOORD_FMT(1, TEXCOORDFMT_NOT_PRESENT);
455fa225cbcSrjs	ss2 |= S2_TEXCOORD_FMT(2, TEXCOORDFMT_NOT_PRESENT);
456fa225cbcSrjs	ss2 |= S2_TEXCOORD_FMT(3, TEXCOORDFMT_NOT_PRESENT);
457fa225cbcSrjs	ss2 |= S2_TEXCOORD_FMT(4, TEXCOORDFMT_NOT_PRESENT);
458fa225cbcSrjs	ss2 |= S2_TEXCOORD_FMT(5, TEXCOORDFMT_NOT_PRESENT);
459fa225cbcSrjs	ss2 |= S2_TEXCOORD_FMT(6, TEXCOORDFMT_NOT_PRESENT);
460fa225cbcSrjs	ss2 |= S2_TEXCOORD_FMT(7, TEXCOORDFMT_NOT_PRESENT);
461fa225cbcSrjs	OUT_BATCH(ss2);
462fa225cbcSrjs	OUT_BATCH((1 << S4_POINT_WIDTH_SHIFT) | S4_LINE_WIDTH_ONE |
463fa225cbcSrjs		  S4_CULLMODE_NONE| S4_VFMT_XY);
464fa225cbcSrjs	blendctl = i915_get_blend_cntl(op, pMaskPicture, pDstPicture->format);
465fa225cbcSrjs	OUT_BATCH(0x00000000); /* Disable stencil buffer */
466fa225cbcSrjs	OUT_BATCH(S6_CBUF_BLEND_ENABLE | S6_COLOR_WRITE_ENABLE |
467fa225cbcSrjs		  (BLENDFUNC_ADD << S6_CBUF_BLEND_FUNC_SHIFT) | blendctl);
468fa225cbcSrjs
469fa225cbcSrjs	/* draw rect is unconditional */
470fa225cbcSrjs	OUT_BATCH(_3DSTATE_DRAW_RECT_CMD);
471fa225cbcSrjs	OUT_BATCH(0x00000000);
472fa225cbcSrjs	OUT_BATCH(0x00000000);  /* ymin, xmin*/
473fa225cbcSrjs	OUT_BATCH(DRAW_YMAX(pDst->drawable.height - 1) |
474fa225cbcSrjs		  DRAW_XMAX(pDst->drawable.width - 1));
475fa225cbcSrjs	OUT_BATCH(0x00000000);  /* yorig, xorig (relate to color buffer?)*/
476fa225cbcSrjs	OUT_BATCH(MI_NOOP);
477fa225cbcSrjs	ADVANCE_BATCH();
478fa225cbcSrjs    }
479fa225cbcSrjs
480fa225cbcSrjs    if (dst_format == COLR_BUF_8BIT)
481fa225cbcSrjs	out_reg = FS_U0;
482fa225cbcSrjs
483fa225cbcSrjs    FS_BEGIN();
484fa225cbcSrjs
485fa225cbcSrjs    /* Declare the registers necessary for our program.  I don't think the
486fa225cbcSrjs     * S then T ordering is necessary.
487fa225cbcSrjs     */
488fa225cbcSrjs    i915_fs_dcl(FS_S0);
489fa225cbcSrjs    if (pMask)
490fa225cbcSrjs	i915_fs_dcl(FS_S1);
491fa225cbcSrjs    i915_fs_dcl(FS_T0);
492fa225cbcSrjs    if (pMask)
493fa225cbcSrjs	i915_fs_dcl(FS_T1);
494fa225cbcSrjs
495fa225cbcSrjs    /* Load the pSrcPicture texel */
496fa225cbcSrjs    if (is_affine_src) {
497fa225cbcSrjs	i915_fs_texld(FS_R0, FS_S0, FS_T0);
498fa225cbcSrjs    } else {
499fa225cbcSrjs	i915_fs_texldp(FS_R0, FS_S0, FS_T0);
500fa225cbcSrjs    }
501fa225cbcSrjs
502fa225cbcSrjs    /* If the texture lacks an alpha channel, force the alpha to 1. */
503fa225cbcSrjs    if (PICT_FORMAT_A(pSrcPicture->format) == 0)
504fa225cbcSrjs	i915_fs_mov_masked(FS_R0, MASK_W, i915_fs_operand_one());
505fa225cbcSrjs
506fa225cbcSrjs    if (!pMask) {
507fa225cbcSrjs	/* No mask, so move to output color */
508fa225cbcSrjs	i915_fs_mov(out_reg, i915_fs_operand_reg(FS_R0));
509fa225cbcSrjs    } else {
510fa225cbcSrjs	/* Load the pMaskPicture texel */
511fa225cbcSrjs	if (is_affine_mask) {
512fa225cbcSrjs	    i915_fs_texld(FS_R1, FS_S1, FS_T1);
513fa225cbcSrjs	} else {
514fa225cbcSrjs	    i915_fs_texldp(FS_R1, FS_S1, FS_T1);
515fa225cbcSrjs	}
516fa225cbcSrjs	/* If the texture lacks an alpha channel, force the alpha to 1. */
517fa225cbcSrjs	if (PICT_FORMAT_A(pMaskPicture->format) == 0)
518fa225cbcSrjs	    i915_fs_mov_masked(FS_R1, MASK_W, i915_fs_operand_one());
519fa225cbcSrjs
520fa225cbcSrjs	/* If component alpha is active in the mask and the blend operation
521fa225cbcSrjs	 * uses the source alpha, then we know we don't need the source
522fa225cbcSrjs	 * value (otherwise we would have hit a fallback earlier), so we
523fa225cbcSrjs	 * provide the source alpha (src.A * mask.X) as output color.
524fa225cbcSrjs	 * Conversely, if CA is set and we don't need the source alpha, then
525fa225cbcSrjs	 * we produce the source value (src.X * mask.X) and the source alpha
526fa225cbcSrjs	 * is unused..  Otherwise, we provide the non-CA source value
527fa225cbcSrjs	 * (src.X * mask.A).
528fa225cbcSrjs	 */
529fa225cbcSrjs	if (pMaskPicture->componentAlpha &&
530fa225cbcSrjs	    PICT_FORMAT_RGB(pMaskPicture->format))
531fa225cbcSrjs	{
532fa225cbcSrjs	    if (i915_blend_op[op].src_alpha) {
533fa225cbcSrjs		i915_fs_mul(out_reg, i915_fs_operand(FS_R0, W, W, W, W),
534fa225cbcSrjs			    i915_fs_operand_reg(FS_R1));
535fa225cbcSrjs	    } else {
536fa225cbcSrjs		i915_fs_mul(out_reg, i915_fs_operand_reg(FS_R0),
537fa225cbcSrjs			    i915_fs_operand_reg(FS_R1));
538fa225cbcSrjs	    }
539fa225cbcSrjs	} else {
540fa225cbcSrjs	    i915_fs_mul(out_reg, i915_fs_operand_reg(FS_R0),
541fa225cbcSrjs			i915_fs_operand(FS_R1, W, W, W, W));
542fa225cbcSrjs	}
543fa225cbcSrjs    }
544fa225cbcSrjs    if (dst_format == COLR_BUF_8BIT)
545fa225cbcSrjs	i915_fs_mov(FS_OC, i915_fs_operand(out_reg, W, W, W, W));
546fa225cbcSrjs
547fa225cbcSrjs    FS_END();
548fa225cbcSrjs}
549fa225cbcSrjs
550fa225cbcSrjs
551fa225cbcSrjs
552fa225cbcSrjs/* Emit the vertices for a single composite rectangle.
553fa225cbcSrjs *
554fa225cbcSrjs * This function is no longer shared between i830 and i915 generation code.
555fa225cbcSrjs */
556fa225cbcSrjsstatic void
557fa225cbcSrjsi915_emit_composite_primitive(PixmapPtr pDst,
558fa225cbcSrjs			      int srcX, int srcY,
559fa225cbcSrjs			      int maskX, int maskY,
560fa225cbcSrjs			      int dstX, int dstY,
561fa225cbcSrjs			      int w, int h)
562fa225cbcSrjs{
563fa225cbcSrjs    ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
564fa225cbcSrjs    I830Ptr pI830 = I830PTR(pScrn);
565fa225cbcSrjs    Bool is_affine_src, is_affine_mask = TRUE;
566fa225cbcSrjs    int per_vertex, num_floats;
567fa225cbcSrjs    float src_x[3], src_y[3], src_w[3], mask_x[3], mask_y[3], mask_w[3];
568fa225cbcSrjs
569fa225cbcSrjs    per_vertex = 2; /* dest x/y */
570fa225cbcSrjs
571fa225cbcSrjs    {
572fa225cbcSrjs	float x = srcX + pI830->src_coord_adjust;
573fa225cbcSrjs	float y = srcY + pI830->src_coord_adjust;
574fa225cbcSrjs
575fa225cbcSrjs	is_affine_src = i830_transform_is_affine (pI830->transform[0]);
576fa225cbcSrjs	if (is_affine_src) {
577fa225cbcSrjs	    if (!i830_get_transformed_coordinates(x, y,
578fa225cbcSrjs						  pI830->transform[0],
579fa225cbcSrjs						  &src_x[0], &src_y[0]))
580fa225cbcSrjs		return;
581fa225cbcSrjs
582fa225cbcSrjs	    if (!i830_get_transformed_coordinates(x, y + h,
583fa225cbcSrjs						  pI830->transform[0],
584fa225cbcSrjs						  &src_x[1], &src_y[1]))
585fa225cbcSrjs		return;
586fa225cbcSrjs
587fa225cbcSrjs	    if (!i830_get_transformed_coordinates(x + w, y + h,
588fa225cbcSrjs						  pI830->transform[0],
589fa225cbcSrjs						  &src_x[2], &src_y[2]))
590fa225cbcSrjs		return;
591fa225cbcSrjs
592fa225cbcSrjs	    per_vertex += 2;    /* src x/y */
593fa225cbcSrjs	} else {
594fa225cbcSrjs	    if (!i830_get_transformed_coordinates_3d(x, y,
595fa225cbcSrjs						     pI830->transform[0],
596fa225cbcSrjs						     &src_x[0],
597fa225cbcSrjs						     &src_y[0],
598fa225cbcSrjs						     &src_w[0]))
599fa225cbcSrjs		return;
600fa225cbcSrjs
601fa225cbcSrjs	    if (!i830_get_transformed_coordinates_3d(x, y + h,
602fa225cbcSrjs						     pI830->transform[0],
603fa225cbcSrjs						     &src_x[1],
604fa225cbcSrjs						     &src_y[1],
605fa225cbcSrjs						     &src_w[1]))
606fa225cbcSrjs		return;
607fa225cbcSrjs
608fa225cbcSrjs	    if (!i830_get_transformed_coordinates_3d(x + w, y + h,
609fa225cbcSrjs						     pI830->transform[0],
610fa225cbcSrjs						     &src_x[2],
611fa225cbcSrjs						     &src_y[2],
612fa225cbcSrjs						     &src_w[2]))
613fa225cbcSrjs		return;
614fa225cbcSrjs
615fa225cbcSrjs	    per_vertex += 4;    /* src x/y/z/w */
616fa225cbcSrjs	}
617fa225cbcSrjs    }
618fa225cbcSrjs
619fa225cbcSrjs    if (pI830->render_mask) {
620fa225cbcSrjs	float x = maskX + pI830->mask_coord_adjust;
621fa225cbcSrjs	float y = maskY + pI830->mask_coord_adjust;
622fa225cbcSrjs
623fa225cbcSrjs	is_affine_mask = i830_transform_is_affine (pI830->transform[1]);
624fa225cbcSrjs	if (is_affine_mask) {
625fa225cbcSrjs	    if (!i830_get_transformed_coordinates(x, y,
626fa225cbcSrjs						  pI830->transform[1],
627fa225cbcSrjs						  &mask_x[0], &mask_y[0]))
628fa225cbcSrjs		return;
629fa225cbcSrjs
630fa225cbcSrjs	    if (!i830_get_transformed_coordinates(x, y + h,
631fa225cbcSrjs						  pI830->transform[1],
632fa225cbcSrjs						  &mask_x[1], &mask_y[1]))
633fa225cbcSrjs		return;
634fa225cbcSrjs
635fa225cbcSrjs	    if (!i830_get_transformed_coordinates(x + w, y + h,
636fa225cbcSrjs						  pI830->transform[1],
637fa225cbcSrjs						  &mask_x[2], &mask_y[2]))
638fa225cbcSrjs		return;
639fa225cbcSrjs
640fa225cbcSrjs	    per_vertex += 2;	/* mask x/y */
641fa225cbcSrjs	} else {
642fa225cbcSrjs	    if (!i830_get_transformed_coordinates_3d(x, y,
643fa225cbcSrjs						     pI830->transform[1],
644fa225cbcSrjs						     &mask_x[0],
645fa225cbcSrjs						     &mask_y[0],
646fa225cbcSrjs						     &mask_w[0]))
647fa225cbcSrjs		return;
648fa225cbcSrjs
649fa225cbcSrjs	    if (!i830_get_transformed_coordinates_3d(x, y + h,
650fa225cbcSrjs						     pI830->transform[1],
651fa225cbcSrjs						     &mask_x[1],
652fa225cbcSrjs						     &mask_y[1],
653fa225cbcSrjs						     &mask_w[1]))
654fa225cbcSrjs		return;
655fa225cbcSrjs
656fa225cbcSrjs	    if (!i830_get_transformed_coordinates_3d(x + w, y + h,
657fa225cbcSrjs						     pI830->transform[1],
658fa225cbcSrjs						     &mask_x[2],
659fa225cbcSrjs						     &mask_y[2],
660fa225cbcSrjs						     &mask_w[2]))
661fa225cbcSrjs		return;
662fa225cbcSrjs
663fa225cbcSrjs	    per_vertex += 4;	/* mask x/y/z/w */
664fa225cbcSrjs	}
665fa225cbcSrjs    }
666fa225cbcSrjs
667fa225cbcSrjs    num_floats = 3 * per_vertex;
668fa225cbcSrjs
669fa225cbcSrjs    BEGIN_BATCH(1 + num_floats);
670fa225cbcSrjs
671fa225cbcSrjs    OUT_BATCH(PRIM3D_INLINE | PRIM3D_RECTLIST | (num_floats-1));
672fa225cbcSrjs    OUT_BATCH_F(pI830->dst_coord_adjust + dstX + w);
673fa225cbcSrjs    OUT_BATCH_F(pI830->dst_coord_adjust + dstY + h);
674fa225cbcSrjs    OUT_BATCH_F(src_x[2] / pI830->scale_units[0][0]);
675fa225cbcSrjs    OUT_BATCH_F(src_y[2] / pI830->scale_units[0][1]);
676fa225cbcSrjs    if (!is_affine_src) {
677fa225cbcSrjs	OUT_BATCH_F(0.0);
678fa225cbcSrjs	OUT_BATCH_F(src_w[2]);
679fa225cbcSrjs    }
680fa225cbcSrjs    if (pI830->render_mask) {
681fa225cbcSrjs	OUT_BATCH_F(mask_x[2] / pI830->scale_units[1][0]);
682fa225cbcSrjs	OUT_BATCH_F(mask_y[2] / pI830->scale_units[1][1]);
683fa225cbcSrjs	if (!is_affine_mask) {
684fa225cbcSrjs	    OUT_BATCH_F(0.0);
685fa225cbcSrjs	    OUT_BATCH_F(mask_w[2]);
686fa225cbcSrjs	}
687fa225cbcSrjs    }
688fa225cbcSrjs
689fa225cbcSrjs    OUT_BATCH_F(pI830->dst_coord_adjust + dstX);
690fa225cbcSrjs    OUT_BATCH_F(pI830->dst_coord_adjust + dstY + h);
691fa225cbcSrjs    OUT_BATCH_F(src_x[1] / pI830->scale_units[0][0]);
692fa225cbcSrjs    OUT_BATCH_F(src_y[1] / pI830->scale_units[0][1]);
693fa225cbcSrjs    if (!is_affine_src) {
694fa225cbcSrjs	OUT_BATCH_F(0.0);
695fa225cbcSrjs	OUT_BATCH_F(src_w[1]);
696fa225cbcSrjs    }
697fa225cbcSrjs    if (pI830->render_mask) {
698fa225cbcSrjs	OUT_BATCH_F(mask_x[1] / pI830->scale_units[1][0]);
699fa225cbcSrjs	OUT_BATCH_F(mask_y[1] / pI830->scale_units[1][1]);
700fa225cbcSrjs	if (!is_affine_mask) {
701fa225cbcSrjs	    OUT_BATCH_F(0.0);
702fa225cbcSrjs	    OUT_BATCH_F(mask_w[1]);
703fa225cbcSrjs	}
704fa225cbcSrjs    }
705fa225cbcSrjs
706fa225cbcSrjs    OUT_BATCH_F(pI830->dst_coord_adjust + dstX);
707fa225cbcSrjs    OUT_BATCH_F(pI830->dst_coord_adjust + dstY);
708fa225cbcSrjs    OUT_BATCH_F(src_x[0] / pI830->scale_units[0][0]);
709fa225cbcSrjs    OUT_BATCH_F(src_y[0] / pI830->scale_units[0][1]);
710fa225cbcSrjs    if (!is_affine_src) {
711fa225cbcSrjs	OUT_BATCH_F(0.0);
712fa225cbcSrjs	OUT_BATCH_F(src_w[0]);
713fa225cbcSrjs    }
714fa225cbcSrjs    if (pI830->render_mask) {
715fa225cbcSrjs	OUT_BATCH_F(mask_x[0] / pI830->scale_units[1][0]);
716fa225cbcSrjs	OUT_BATCH_F(mask_y[0] / pI830->scale_units[1][1]);
717fa225cbcSrjs	if (!is_affine_mask) {
718fa225cbcSrjs	    OUT_BATCH_F(0.0);
719fa225cbcSrjs	    OUT_BATCH_F(mask_w[0]);
720fa225cbcSrjs	}
721fa225cbcSrjs    }
722fa225cbcSrjs
723fa225cbcSrjs    ADVANCE_BATCH();
724fa225cbcSrjs}
725fa225cbcSrjs
726fa225cbcSrjsvoid
727fa225cbcSrjsi915_composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
728fa225cbcSrjs	       int dstX, int dstY, int w, int h)
729fa225cbcSrjs{
730fa225cbcSrjs    ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
731fa225cbcSrjs    I830Ptr pI830 = I830PTR(pScrn);
732fa225cbcSrjs
733fa225cbcSrjs    intel_batch_start_atomic(pScrn, 150);
734fa225cbcSrjs
735fa225cbcSrjs    if (pI830->i915_render_state.needs_emit)
736fa225cbcSrjs	i915_emit_composite_setup(pScrn);
737fa225cbcSrjs
738fa225cbcSrjs    i915_emit_composite_primitive(pDst, srcX, srcY, maskX, maskY, dstX, dstY,
739fa225cbcSrjs				  w, h);
740fa225cbcSrjs
741fa225cbcSrjs    intel_batch_end_atomic(pScrn);
742fa225cbcSrjs}
743fa225cbcSrjs
744fa225cbcSrjsvoid
745fa225cbcSrjsi915_batch_flush_notify(ScrnInfoPtr pScrn)
746fa225cbcSrjs{
747fa225cbcSrjs    I830Ptr pI830 = I830PTR(pScrn);
748fa225cbcSrjs
749fa225cbcSrjs    pI830->i915_render_state.needs_emit = TRUE;
750fa225cbcSrjs}
751