Initial code release
[adaptation/xorg-x11-drv-intel.git] / src / i915_render.c
1 /*
2  * Copyright © 2006 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21  * SOFTWARE.
22  *
23  * Authors:
24  *    Wang Zhenyu <zhenyu.z.wang@intel.com>
25  *    Eric Anholt <eric@anholt.net>
26  *
27  */
28
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32
33 #include "xf86.h"
34 #include "intel.h"
35 #include "i915_reg.h"
36 #include "i915_3d.h"
37
38 struct formatinfo {
39         int fmt;
40         uint32_t card_fmt;
41 };
42
43 struct blendinfo {
44         Bool dst_alpha;
45         Bool src_alpha;
46         uint32_t src_blend;
47         uint32_t dst_blend;
48 };
49
50 static struct blendinfo i915_blend_op[] = {
51         /* Clear */
52         {0, 0, BLENDFACT_ZERO, BLENDFACT_ZERO},
53         /* Src */
54         {0, 0, BLENDFACT_ONE, BLENDFACT_ZERO},
55         /* Dst */
56         {0, 0, BLENDFACT_ZERO, BLENDFACT_ONE},
57         /* Over */
58         {0, 1, BLENDFACT_ONE, BLENDFACT_INV_SRC_ALPHA},
59         /* OverReverse */
60         {1, 0, BLENDFACT_INV_DST_ALPHA, BLENDFACT_ONE},
61         /* In */
62         {1, 0, BLENDFACT_DST_ALPHA, BLENDFACT_ZERO},
63         /* InReverse */
64         {0, 1, BLENDFACT_ZERO, BLENDFACT_SRC_ALPHA},
65         /* Out */
66         {1, 0, BLENDFACT_INV_DST_ALPHA, BLENDFACT_ZERO},
67         /* OutReverse */
68         {0, 1, BLENDFACT_ZERO, BLENDFACT_INV_SRC_ALPHA},
69         /* Atop */
70         {1, 1, BLENDFACT_DST_ALPHA, BLENDFACT_INV_SRC_ALPHA},
71         /* AtopReverse */
72         {1, 1, BLENDFACT_INV_DST_ALPHA, BLENDFACT_SRC_ALPHA},
73         /* Xor */
74         {1, 1, BLENDFACT_INV_DST_ALPHA, BLENDFACT_INV_SRC_ALPHA},
75         /* Add */
76         {0, 0, BLENDFACT_ONE, BLENDFACT_ONE},
77 };
78
79 static struct formatinfo i915_tex_formats[] = {
80         {PICT_a8, MAPSURF_8BIT | MT_8BIT_A8},
81         {PICT_a8r8g8b8, MAPSURF_32BIT | MT_32BIT_ARGB8888},
82         {PICT_x8r8g8b8, MAPSURF_32BIT | MT_32BIT_XRGB8888},
83         {PICT_a8b8g8r8, MAPSURF_32BIT | MT_32BIT_ABGR8888},
84         {PICT_x8b8g8r8, MAPSURF_32BIT | MT_32BIT_XBGR8888},
85 #if XORG_VERSION_CURRENT >= 10699900
86         {PICT_a2r10g10b10, MAPSURF_32BIT | MT_32BIT_ARGB2101010},
87         {PICT_a2b10g10r10, MAPSURF_32BIT | MT_32BIT_ABGR2101010},
88 #endif
89         {PICT_r5g6b5, MAPSURF_16BIT | MT_16BIT_RGB565},
90         {PICT_a1r5g5b5, MAPSURF_16BIT | MT_16BIT_ARGB1555},
91         {PICT_a4r4g4b4, MAPSURF_16BIT | MT_16BIT_ARGB4444},
92 };
93
94 static uint32_t i915_get_blend_cntl(int op, PicturePtr mask,
95                                     uint32_t dst_format)
96 {
97         uint32_t sblend, dblend;
98
99         sblend = i915_blend_op[op].src_blend;
100         dblend = i915_blend_op[op].dst_blend;
101
102         /* If there's no dst alpha channel, adjust the blend op so that we'll
103          * treat it as always 1.
104          */
105         if (PICT_FORMAT_A(dst_format) == 0 && i915_blend_op[op].dst_alpha) {
106                 if (sblend == BLENDFACT_DST_ALPHA)
107                         sblend = BLENDFACT_ONE;
108                 else if (sblend == BLENDFACT_INV_DST_ALPHA)
109                         sblend = BLENDFACT_ZERO;
110         }
111
112         /* i915 engine reads 8bit color buffer into green channel in cases
113            like color buffer blending .etc, and also writes back green channel.
114            So with dst_alpha blend we should use color factor. See spec on
115            "8-bit rendering" */
116         if ((dst_format == PICT_a8) && i915_blend_op[op].dst_alpha) {
117                 if (sblend == BLENDFACT_DST_ALPHA)
118                         sblend = BLENDFACT_DST_COLR;
119                 else if (sblend == BLENDFACT_INV_DST_ALPHA)
120                         sblend = BLENDFACT_INV_DST_COLR;
121         }
122
123         /* If the source alpha is being used, then we should only be in a case
124          * where the source blend factor is 0, and the source blend value is the
125          * mask channels multiplied by the source picture's alpha.
126          */
127         if (mask && mask->componentAlpha && PICT_FORMAT_RGB(mask->format) &&
128             i915_blend_op[op].src_alpha) {
129                 if (dblend == BLENDFACT_SRC_ALPHA) {
130                         dblend = BLENDFACT_SRC_COLR;
131                 } else if (dblend == BLENDFACT_INV_SRC_ALPHA) {
132                         dblend = BLENDFACT_INV_SRC_COLR;
133                 }
134         }
135
136         return S6_CBUF_BLEND_ENABLE | S6_COLOR_WRITE_ENABLE |
137                 (BLENDFUNC_ADD << S6_CBUF_BLEND_FUNC_SHIFT) |
138                 (sblend << S6_CBUF_SRC_BLEND_FACT_SHIFT) |
139                 (dblend << S6_CBUF_DST_BLEND_FACT_SHIFT);
140 }
141
142 #define DSTORG_HORT_BIAS(x)             ((x)<<20)
143 #define DSTORG_VERT_BIAS(x)             ((x)<<16)
144
145 static Bool i915_get_dest_format(PicturePtr dest_picture, uint32_t * dst_format)
146 {
147         ScrnInfoPtr scrn;
148
149         switch (dest_picture->format) {
150         case PICT_a8r8g8b8:
151         case PICT_x8r8g8b8:
152                 *dst_format = COLR_BUF_ARGB8888;
153                 break;
154         case PICT_r5g6b5:
155                 *dst_format = COLR_BUF_RGB565;
156                 break;
157         case PICT_a1r5g5b5:
158         case PICT_x1r5g5b5:
159                 *dst_format = COLR_BUF_ARGB1555;
160                 break;
161 #if XORG_VERSION_CURRENT >= 10699900
162         case PICT_a2r10g10b10:
163         case PICT_x2r10g10b10:
164                 *dst_format = COLR_BUF_ARGB2AAA;
165                 break;
166 #endif
167         case PICT_a8:
168                 *dst_format = COLR_BUF_8BIT;
169                 break;
170         case PICT_a4r4g4b4:
171         case PICT_x4r4g4b4:
172                 *dst_format = COLR_BUF_ARGB4444;
173                 break;
174         default:
175                 scrn = xf86Screens[dest_picture->pDrawable->pScreen->myNum];
176                 intel_debug_fallback(scrn,
177                                      "Unsupported dest format 0x%x\n",
178                                      (int)dest_picture->format);
179                 return FALSE;
180         }
181         *dst_format |= DSTORG_HORT_BIAS(0x8) | DSTORG_VERT_BIAS(0x8);
182         return TRUE;
183 }
184
185 Bool
186 i915_check_composite(int op,
187                      PicturePtr source_picture,
188                      PicturePtr mask_picture,
189                      PicturePtr dest_picture,
190                      int width, int height)
191 {
192         ScrnInfoPtr scrn = xf86Screens[dest_picture->pDrawable->pScreen->myNum];
193         uint32_t tmp1;
194
195         /* Check for unsupported compositing operations. */
196         if (op >= sizeof(i915_blend_op) / sizeof(i915_blend_op[0])) {
197                 intel_debug_fallback(scrn, "Unsupported Composite op 0x%x\n",
198                                      op);
199                 return FALSE;
200         }
201         if (mask_picture != NULL && mask_picture->componentAlpha &&
202             PICT_FORMAT_RGB(mask_picture->format)) {
203                 /* Check if it's component alpha that relies on a source alpha
204                  * and on the source value.  We can only get one of those
205                  * into the single source value that we get to blend with.
206                  */
207                 if (i915_blend_op[op].src_alpha &&
208                     (i915_blend_op[op].src_blend != BLENDFACT_ZERO)) {
209                         if (op != PictOpOver) {
210                                 intel_debug_fallback(scrn,
211                                                      "Component alpha not supported "
212                                                      "with source alpha and source "
213                                                      "value blending.\n");
214                                 return FALSE;
215                         }
216                 }
217         }
218
219         if (!i915_get_dest_format(dest_picture, &tmp1)) {
220                 intel_debug_fallback(scrn, "Get Color buffer format\n");
221                 return FALSE;
222         }
223
224         if (width > 2048 || height > 2048)
225                 return FALSE;
226
227         return TRUE;
228 }
229
230 Bool
231 i915_check_composite_target(PixmapPtr pixmap)
232 {
233         if (pixmap->drawable.width > 2048 || pixmap->drawable.height > 2048)
234                 return FALSE;
235
236         if(!intel_check_pitch_3d(pixmap))
237                 return FALSE;
238
239         return TRUE;
240 }
241
242 Bool
243 i915_check_composite_texture(ScreenPtr screen, PicturePtr picture)
244 {
245         if (picture->repeatType > RepeatReflect) {
246                 ScrnInfoPtr scrn = xf86Screens[screen->myNum];
247                 intel_debug_fallback(scrn, "Unsupported picture repeat %d\n",
248                              picture->repeatType);
249                 return FALSE;
250         }
251
252         if (picture->filter != PictFilterNearest &&
253             picture->filter != PictFilterBilinear) {
254                 ScrnInfoPtr scrn = xf86Screens[screen->myNum];
255                 intel_debug_fallback(scrn, "Unsupported filter 0x%x\n",
256                                      picture->filter);
257                 return FALSE;
258         }
259
260         if (picture->pSourcePict) {
261                 SourcePict *source = picture->pSourcePict;
262                 if (source->type == SourcePictTypeSolidFill)
263                         return TRUE;
264         }
265
266         if (picture->pDrawable) {
267                 int w, h, i;
268
269                 w = picture->pDrawable->width;
270                 h = picture->pDrawable->height;
271                 if ((w > 2048) || (h > 2048)) {
272                         ScrnInfoPtr scrn = xf86Screens[screen->myNum];
273                         intel_debug_fallback(scrn,
274                                              "Picture w/h too large (%dx%d)\n",
275                                              w, h);
276                         return FALSE;
277                 }
278
279                 for (i = 0;
280                      i < sizeof(i915_tex_formats) / sizeof(i915_tex_formats[0]);
281                      i++) {
282                         if (i915_tex_formats[i].fmt == picture->format)
283                                 break;
284                 }
285                 if (i == sizeof(i915_tex_formats) / sizeof(i915_tex_formats[0]))
286                 {
287                         ScrnInfoPtr scrn = xf86Screens[screen->myNum];
288                         intel_debug_fallback(scrn, "Unsupported picture format "
289                                              "0x%x\n",
290                                              (int)picture->format);
291                         return FALSE;
292                 }
293
294                 return TRUE;
295         }
296
297         return FALSE;
298 }
299
300 static Bool i915_texture_setup(PicturePtr picture, PixmapPtr pixmap, int unit)
301 {
302         ScrnInfoPtr scrn = xf86Screens[picture->pDrawable->pScreen->myNum];
303         intel_screen_private *intel = intel_get_screen_private(scrn);
304         uint32_t format, pitch, filter;
305         uint32_t wrap_mode, tiling_bits;
306         int i;
307
308         pitch = intel_pixmap_pitch(pixmap);
309         intel->scale_units[unit][0] = 1. / pixmap->drawable.width;
310         intel->scale_units[unit][1] = 1. / pixmap->drawable.height;
311
312         for (i = 0; i < sizeof(i915_tex_formats) / sizeof(i915_tex_formats[0]);
313              i++) {
314                 if (i915_tex_formats[i].fmt == picture->format)
315                         break;
316         }
317         if (i == sizeof(i915_tex_formats) / sizeof(i915_tex_formats[0])) {
318                 intel_debug_fallback(scrn, "unknown texture format\n");
319                 return FALSE;
320         }
321         format = i915_tex_formats[i].card_fmt;
322
323         switch (picture->repeatType) {
324         case RepeatNone:
325                 wrap_mode = TEXCOORDMODE_CLAMP_BORDER;
326                 break;
327         case RepeatNormal:
328                 wrap_mode = TEXCOORDMODE_WRAP;
329                 break;
330         case RepeatPad:
331                 wrap_mode = TEXCOORDMODE_CLAMP_EDGE;
332                 break;
333         case RepeatReflect:
334                 wrap_mode = TEXCOORDMODE_MIRROR;
335                 break;
336         default:
337                 FatalError("Unknown repeat type %d\n", picture->repeatType);
338         }
339
340         switch (picture->filter) {
341         case PictFilterNearest:
342                 filter = (FILTER_NEAREST << SS2_MAG_FILTER_SHIFT) |
343                     (FILTER_NEAREST << SS2_MIN_FILTER_SHIFT);
344                 break;
345         case PictFilterBilinear:
346                 filter = (FILTER_LINEAR << SS2_MAG_FILTER_SHIFT) |
347                     (FILTER_LINEAR << SS2_MIN_FILTER_SHIFT);
348                 break;
349         default:
350                 filter = 0;
351                 intel_debug_fallback(scrn, "Bad filter 0x%x\n",
352                                      picture->filter);
353                 return FALSE;
354         }
355
356         /* offset filled in at emit time */
357         if (intel_pixmap_tiled(pixmap)) {
358                 tiling_bits = MS3_TILED_SURFACE;
359                 if (intel_get_pixmap_private(pixmap)->tiling
360                                 == I915_TILING_Y)
361                         tiling_bits |= MS3_TILE_WALK;
362         } else
363                 tiling_bits = 0;
364
365         intel->texture[unit] = pixmap;
366         intel->mapstate[unit * 3 + 0] = 0;
367         intel->mapstate[unit * 3 + 1] = format |
368             tiling_bits |
369             ((pixmap->drawable.height - 1) << MS3_HEIGHT_SHIFT) |
370             ((pixmap->drawable.width - 1) << MS3_WIDTH_SHIFT);
371         intel->mapstate[unit * 3 + 2] = ((pitch / 4) - 1) << MS4_PITCH_SHIFT;
372
373         intel->samplerstate[unit * 3 + 0] = (MIPFILTER_NONE <<
374                                              SS2_MIP_FILTER_SHIFT);
375         intel->samplerstate[unit * 3 + 0] |= filter;
376         intel->samplerstate[unit * 3 + 1] = SS3_NORMALIZED_COORDS;
377         intel->samplerstate[unit * 3 + 1] |=
378             wrap_mode << SS3_TCX_ADDR_MODE_SHIFT;
379         intel->samplerstate[unit * 3 + 1] |=
380             wrap_mode << SS3_TCY_ADDR_MODE_SHIFT;
381         intel->samplerstate[unit * 3 + 1] |= unit << SS3_TEXTUREMAP_INDEX_SHIFT;
382         intel->samplerstate[unit * 3 + 2] = 0x00000000; /* border color */
383
384         intel->transform[unit] = picture->transform;
385
386         return TRUE;
387 }
388
389 static void
390 i915_emit_composite_primitive_constant(intel_screen_private *intel,
391                                        int srcX, int srcY,
392                                        int maskX, int maskY,
393                                        int dstX, int dstY,
394                                        int w, int h)
395 {
396         OUT_VERTEX(dstX + w);
397         OUT_VERTEX(dstY + h);
398
399         OUT_VERTEX(dstX);
400         OUT_VERTEX(dstY + h);
401
402         OUT_VERTEX(dstX);
403         OUT_VERTEX(dstY);
404 }
405
406 static void
407 i915_emit_composite_primitive_identity_source(intel_screen_private *intel,
408                                               int srcX, int srcY,
409                                               int maskX, int maskY,
410                                               int dstX, int dstY,
411                                               int w, int h)
412 {
413         OUT_VERTEX(dstX + w);
414         OUT_VERTEX(dstY + h);
415         OUT_VERTEX((srcX + w) * intel->scale_units[0][0]);
416         OUT_VERTEX((srcY + h) * intel->scale_units[0][1]);
417
418         OUT_VERTEX(dstX);
419         OUT_VERTEX(dstY + h);
420         OUT_VERTEX(srcX * intel->scale_units[0][0]);
421         OUT_VERTEX((srcY + h) * intel->scale_units[0][1]);
422
423         OUT_VERTEX(dstX);
424         OUT_VERTEX(dstY);
425         OUT_VERTEX(srcX * intel->scale_units[0][0]);
426         OUT_VERTEX(srcY * intel->scale_units[0][1]);
427 }
428
429 static void
430 i915_emit_composite_primitive_affine_source(intel_screen_private *intel,
431                                             int srcX, int srcY,
432                                             int maskX, int maskY,
433                                             int dstX, int dstY,
434                                             int w, int h)
435 {
436         float src_x[3], src_y[3];
437
438         if (!intel_get_transformed_coordinates(srcX, srcY,
439                                               intel->transform[0],
440                                               &src_x[0],
441                                               &src_y[0]))
442                 return;
443
444         if (!intel_get_transformed_coordinates(srcX, srcY + h,
445                                               intel->transform[0],
446                                               &src_x[1],
447                                               &src_y[1]))
448                 return;
449
450         if (!intel_get_transformed_coordinates(srcX + w, srcY + h,
451                                               intel->transform[0],
452                                               &src_x[2],
453                                               &src_y[2]))
454                 return;
455
456         OUT_VERTEX(dstX + w);
457         OUT_VERTEX(dstY + h);
458         OUT_VERTEX(src_x[2] * intel->scale_units[0][0]);
459         OUT_VERTEX(src_y[2] * intel->scale_units[0][1]);
460
461         OUT_VERTEX(dstX);
462         OUT_VERTEX(dstY + h);
463         OUT_VERTEX(src_x[1] * intel->scale_units[0][0]);
464         OUT_VERTEX(src_y[1] * intel->scale_units[0][1]);
465
466         OUT_VERTEX(dstX);
467         OUT_VERTEX(dstY);
468         OUT_VERTEX(src_x[0] * intel->scale_units[0][0]);
469         OUT_VERTEX(src_y[0] * intel->scale_units[0][1]);
470 }
471
472 static void
473 i915_emit_composite_primitive_constant_identity_mask(intel_screen_private *intel,
474                                                      int srcX, int srcY,
475                                                      int maskX, int maskY,
476                                                      int dstX, int dstY,
477                                                      int w, int h)
478 {
479         OUT_VERTEX(dstX + w);
480         OUT_VERTEX(dstY + h);
481         OUT_VERTEX((maskX + w) * intel->scale_units[0][0]);
482         OUT_VERTEX((maskY + h) * intel->scale_units[0][1]);
483
484         OUT_VERTEX(dstX);
485         OUT_VERTEX(dstY + h);
486         OUT_VERTEX(maskX * intel->scale_units[0][0]);
487         OUT_VERTEX((maskY + h) * intel->scale_units[0][1]);
488
489         OUT_VERTEX(dstX);
490         OUT_VERTEX(dstY);
491         OUT_VERTEX(maskX * intel->scale_units[0][0]);
492         OUT_VERTEX(maskY * intel->scale_units[0][1]);
493 }
494
495 static void
496 i915_emit_composite_primitive_identity_source_mask(intel_screen_private *intel,
497                                                    int srcX, int srcY,
498                                                    int maskX, int maskY,
499                                                    int dstX, int dstY,
500                                                    int w, int h)
501 {
502         OUT_VERTEX(dstX + w);
503         OUT_VERTEX(dstY + h);
504         OUT_VERTEX((srcX + w) * intel->scale_units[0][0]);
505         OUT_VERTEX((srcY + h) * intel->scale_units[0][1]);
506         OUT_VERTEX((maskX + w) * intel->scale_units[1][0]);
507         OUT_VERTEX((maskY + h) * intel->scale_units[1][1]);
508
509         OUT_VERTEX(dstX);
510         OUT_VERTEX(dstY + h);
511         OUT_VERTEX(srcX * intel->scale_units[0][0]);
512         OUT_VERTEX((srcY + h) * intel->scale_units[0][1]);
513         OUT_VERTEX(maskX * intel->scale_units[1][0]);
514         OUT_VERTEX((maskY + h) * intel->scale_units[1][1]);
515
516         OUT_VERTEX(dstX);
517         OUT_VERTEX(dstY);
518         OUT_VERTEX(srcX * intel->scale_units[0][0]);
519         OUT_VERTEX(srcY * intel->scale_units[0][1]);
520         OUT_VERTEX(maskX * intel->scale_units[1][0]);
521         OUT_VERTEX(maskY * intel->scale_units[1][1]);
522 }
523
524 static void
525 i915_emit_composite_primitive(intel_screen_private *intel,
526                               int srcX, int srcY,
527                               int maskX, int maskY,
528                               int dstX, int dstY,
529                               int w, int h)
530 {
531         Bool is_affine_src = TRUE, is_affine_mask = TRUE;
532         int per_vertex;
533         int tex_unit = 0;
534         int src_unit = -1, mask_unit = -1;
535         float src_x[3], src_y[3], src_w[3], mask_x[3], mask_y[3], mask_w[3];
536
537         per_vertex = 2;         /* dest x/y */
538
539         if (! intel->render_source_is_solid) {
540                 src_unit = tex_unit++;
541
542                 is_affine_src = intel_transform_is_affine(intel->transform[src_unit]);
543                 if (is_affine_src) {
544                         if (!intel_get_transformed_coordinates(srcX, srcY,
545                                                               intel->
546                                                               transform[src_unit],
547                                                               &src_x[0],
548                                                               &src_y[0]))
549                                 return;
550
551                         if (!intel_get_transformed_coordinates(srcX, srcY + h,
552                                                               intel->
553                                                               transform[src_unit],
554                                                               &src_x[1],
555                                                               &src_y[1]))
556                                 return;
557
558                         if (!intel_get_transformed_coordinates(srcX + w, srcY + h,
559                                                               intel->
560                                                               transform[src_unit],
561                                                               &src_x[2],
562                                                               &src_y[2]))
563                                 return;
564
565                         per_vertex += 2;        /* src x/y */
566                 } else {
567                         if (!intel_get_transformed_coordinates_3d(srcX, srcY,
568                                                                  intel->
569                                                                  transform[src_unit],
570                                                                  &src_x[0],
571                                                                  &src_y[0],
572                                                                  &src_w[0]))
573                                 return;
574
575                         if (!intel_get_transformed_coordinates_3d(srcX, srcY + h,
576                                                                  intel->
577                                                                  transform[src_unit],
578                                                                  &src_x[1],
579                                                                  &src_y[1],
580                                                                  &src_w[1]))
581                                 return;
582
583                         if (!intel_get_transformed_coordinates_3d(srcX + w, srcY + h,
584                                                                  intel->
585                                                                  transform[src_unit],
586                                                                  &src_x[2],
587                                                                  &src_y[2],
588                                                                  &src_w[2]))
589                                 return;
590
591                         per_vertex += 4;        /* src x/y/z/w */
592                 }
593         }
594
595         if (intel->render_mask && ! intel->render_mask_is_solid) {
596                 mask_unit = tex_unit++;
597
598                 is_affine_mask = intel_transform_is_affine(intel->transform[mask_unit]);
599                 if (is_affine_mask) {
600                         if (!intel_get_transformed_coordinates(maskX, maskY,
601                                                               intel->
602                                                               transform[mask_unit],
603                                                               &mask_x[0],
604                                                               &mask_y[0]))
605                                 return;
606
607                         if (!intel_get_transformed_coordinates(maskX, maskY + h,
608                                                               intel->
609                                                               transform[mask_unit],
610                                                               &mask_x[1],
611                                                               &mask_y[1]))
612                                 return;
613
614                         if (!intel_get_transformed_coordinates(maskX + w, maskY + h,
615                                                               intel->
616                                                               transform[mask_unit],
617                                                               &mask_x[2],
618                                                               &mask_y[2]))
619                                 return;
620
621                         per_vertex += 2;        /* mask x/y */
622                 } else {
623                         if (!intel_get_transformed_coordinates_3d(maskX, maskY,
624                                                                  intel->
625                                                                  transform[mask_unit],
626                                                                  &mask_x[0],
627                                                                  &mask_y[0],
628                                                                  &mask_w[0]))
629                                 return;
630
631                         if (!intel_get_transformed_coordinates_3d(maskX, maskY + h,
632                                                                  intel->
633                                                                  transform[mask_unit],
634                                                                  &mask_x[1],
635                                                                  &mask_y[1],
636                                                                  &mask_w[1]))
637                                 return;
638
639                         if (!intel_get_transformed_coordinates_3d(maskX + w, maskY + h,
640                                                                  intel->
641                                                                  transform[mask_unit],
642                                                                  &mask_x[2],
643                                                                  &mask_y[2],
644                                                                  &mask_w[2]))
645                                 return;
646
647                         per_vertex += 4;        /* mask x/y/z/w */
648                 }
649         }
650
651         OUT_VERTEX(dstX + w);
652         OUT_VERTEX(dstY + h);
653         if (! intel->render_source_is_solid) {
654             OUT_VERTEX(src_x[2] * intel->scale_units[src_unit][0]);
655             OUT_VERTEX(src_y[2] * intel->scale_units[src_unit][1]);
656             if (!is_affine_src) {
657                 OUT_VERTEX(0.0);
658                 OUT_VERTEX(src_w[2]);
659             }
660         }
661         if (intel->render_mask && ! intel->render_mask_is_solid) {
662                 OUT_VERTEX(mask_x[2] * intel->scale_units[mask_unit][0]);
663                 OUT_VERTEX(mask_y[2] * intel->scale_units[mask_unit][1]);
664                 if (!is_affine_mask) {
665                         OUT_VERTEX(0.0);
666                         OUT_VERTEX(mask_w[2]);
667                 }
668         }
669
670         OUT_VERTEX(dstX);
671         OUT_VERTEX(dstY + h);
672         if (! intel->render_source_is_solid) {
673             OUT_VERTEX(src_x[1] * intel->scale_units[src_unit][0]);
674             OUT_VERTEX(src_y[1] * intel->scale_units[src_unit][1]);
675             if (!is_affine_src) {
676                 OUT_VERTEX(0.0);
677                 OUT_VERTEX(src_w[1]);
678             }
679         }
680         if (intel->render_mask && ! intel->render_mask_is_solid) {
681                 OUT_VERTEX(mask_x[1] * intel->scale_units[mask_unit][0]);
682                 OUT_VERTEX(mask_y[1] * intel->scale_units[mask_unit][1]);
683                 if (!is_affine_mask) {
684                         OUT_VERTEX(0.0);
685                         OUT_VERTEX(mask_w[1]);
686                 }
687         }
688
689         OUT_VERTEX(dstX);
690         OUT_VERTEX(dstY);
691         if (! intel->render_source_is_solid) {
692             OUT_VERTEX(src_x[0] * intel->scale_units[src_unit][0]);
693             OUT_VERTEX(src_y[0] * intel->scale_units[src_unit][1]);
694             if (!is_affine_src) {
695                 OUT_VERTEX(0.0);
696                 OUT_VERTEX(src_w[0]);
697             }
698         }
699         if (intel->render_mask && ! intel->render_mask_is_solid) {
700                 OUT_VERTEX(mask_x[0] * intel->scale_units[mask_unit][0]);
701                 OUT_VERTEX(mask_y[0] * intel->scale_units[mask_unit][1]);
702                 if (!is_affine_mask) {
703                         OUT_VERTEX(0.0);
704                         OUT_VERTEX(mask_w[0]);
705                 }
706         }
707 }
708
709 Bool
710 i915_prepare_composite(int op, PicturePtr source_picture,
711                        PicturePtr mask_picture, PicturePtr dest_picture,
712                        PixmapPtr source, PixmapPtr mask, PixmapPtr dest)
713 {
714         ScrnInfoPtr scrn = xf86Screens[dest_picture->pDrawable->pScreen->myNum];
715         intel_screen_private *intel = intel_get_screen_private(scrn);
716         drm_intel_bo *bo_table[] = {
717                 NULL,           /* batch_bo */
718                 intel_get_pixmap_bo(dest),
719                 source ? intel_get_pixmap_bo(source) : NULL,
720                 mask ? intel_get_pixmap_bo(mask) : NULL,
721         };
722         int tex_unit = 0;
723         int floats_per_vertex;
724
725         intel->render_source_picture = source_picture;
726         intel->render_source = source;
727         intel->render_mask_picture = mask_picture;
728         intel->render_mask = mask;
729         intel->render_dest_picture = dest_picture;
730         intel->render_dest = dest;
731
732         intel->render_source_is_solid = FALSE;
733         if (source_picture->pSourcePict) {
734                 SourcePict *source = source_picture->pSourcePict;
735                 if (source->type == SourcePictTypeSolidFill) {
736                         intel->render_source_is_solid = TRUE;
737                         intel->render_source_solid = source->solidFill.color;
738                 }
739         }
740         if (!intel->render_source_is_solid && !intel_check_pitch_3d(source))
741                 return FALSE;
742
743         intel->render_mask_is_solid = FALSE;
744         if (mask) {
745                 if (mask_picture->pSourcePict) {
746                         SourcePict *source = mask_picture->pSourcePict;
747                         if (source->type == SourcePictTypeSolidFill) {
748                                 intel->render_mask_is_solid = TRUE;
749                                 intel->render_mask_solid = source->solidFill.color;
750                         }
751                 }
752                 if (!intel->render_mask_is_solid && !intel_check_pitch_3d(mask))
753                         return FALSE;
754         }
755
756         if (!intel_check_pitch_3d(dest))
757                 return FALSE;
758
759         if (!i915_get_dest_format(dest_picture,
760                                   &intel->i915_render_state.dst_format))
761                 return FALSE;
762
763         if (!intel_get_aperture_space(scrn, bo_table, ARRAY_SIZE(bo_table)))
764                 return FALSE;
765
766         intel->needs_render_ca_pass = FALSE;
767         if (mask_picture != NULL && mask_picture->componentAlpha &&
768             PICT_FORMAT_RGB(mask_picture->format)) {
769                 /* Check if it's component alpha that relies on a source alpha
770                  * and on the source value.  We can only get one of those
771                  * into the single source value that we get to blend with.
772                  */
773                 if (i915_blend_op[op].src_alpha &&
774                     (i915_blend_op[op].src_blend != BLENDFACT_ZERO)) {
775                         if (op != PictOpOver)
776                                 return FALSE;
777
778                         intel->needs_render_ca_pass = TRUE;
779                 }
780         }
781
782         intel->transform[0] = NULL;
783         intel->scale_units[0][0] = -1;
784         intel->scale_units[0][1] = -1;
785         intel->transform[1] = NULL;
786         intel->scale_units[1][0] = -1;
787         intel->scale_units[1][1] = -1;
788
789         floats_per_vertex = 2;          /* dest x/y */
790         if (! intel->render_source_is_solid) {
791                 if (!i915_texture_setup(source_picture, source, tex_unit++)) {
792                         intel_debug_fallback(scrn, "fail to setup src texture\n");
793                         return FALSE;
794                 }
795
796                 if (intel_transform_is_affine(source_picture->transform))
797                         floats_per_vertex += 2; /* src x/y */
798                 else
799                         floats_per_vertex += 4; /* src x/y/z/w */
800         }
801
802         if (mask != NULL) {
803                 if (! intel->render_mask_is_solid) {
804                         if (!i915_texture_setup(mask_picture, mask, tex_unit++)) {
805                                 intel_debug_fallback(scrn,
806                                                 "fail to setup mask texture\n");
807                                 return FALSE;
808                         }
809
810                         if (intel_transform_is_affine(mask_picture->transform))
811                                 floats_per_vertex += 2; /* mask x/y */
812                         else
813                                 floats_per_vertex += 4; /* mask x/y/z/w */
814                 }
815         }
816
817         intel->i915_render_state.op = op;
818
819         /* BUF_INFO is an implicit flush */
820         if (dest != intel->render_current_dest)
821                 intel_batch_do_flush(scrn);
822         else if((source && intel_pixmap_is_dirty(source)) ||
823                 (mask && intel_pixmap_is_dirty(mask)))
824                 intel_batch_emit_flush(scrn);
825
826         intel->needs_render_state_emit = TRUE;
827
828         intel->prim_emit = i915_emit_composite_primitive;
829         if (!mask) {
830                 if (intel->render_source_is_solid)
831                         intel->prim_emit = i915_emit_composite_primitive_constant;
832                 else if (intel->transform[0] == NULL)
833                         intel->prim_emit = i915_emit_composite_primitive_identity_source;
834                 else if (intel_transform_is_affine(intel->transform[0]))
835                         intel->prim_emit = i915_emit_composite_primitive_affine_source;
836         } else {
837                 if (intel->transform[0] == NULL) {
838                         if (intel->render_source_is_solid)
839                                 intel->prim_emit = i915_emit_composite_primitive_constant_identity_mask;
840                         else if (intel->transform[1] == NULL)
841                                 intel->prim_emit = i915_emit_composite_primitive_identity_source_mask;
842                 }
843         }
844
845         if (floats_per_vertex != intel->floats_per_vertex) {
846                 intel->floats_per_vertex = floats_per_vertex;
847                 intel->needs_render_vertex_emit = TRUE;
848         }
849
850         return TRUE;
851 }
852
853 static void
854 i915_composite_emit_shader(intel_screen_private *intel, CARD8 op)
855 {
856         PicturePtr mask_picture = intel->render_mask_picture;
857         PixmapPtr mask = intel->render_mask;
858         int src_reg, mask_reg;
859         Bool is_solid_src, is_solid_mask;
860         Bool dest_is_alpha = PIXMAN_FORMAT_RGB(intel->render_dest_picture->format) == 0;
861         int tex_unit, t;
862         FS_LOCALS();
863
864         is_solid_src = intel->render_source_is_solid;
865         is_solid_mask = intel->render_mask_is_solid;
866
867         FS_BEGIN();
868
869         /* Declare the registers necessary for our program.  */
870         t = 0;
871         if (is_solid_src) {
872                 i915_fs_dcl(FS_T8);
873                 src_reg = FS_T8;
874         } else {
875                 i915_fs_dcl(FS_T0);
876                 i915_fs_dcl(FS_S0);
877                 t++;
878         }
879         if (!mask) {
880                 /* No mask, so load directly to output color */
881                 if (! is_solid_src) {
882                         if (dest_is_alpha)
883                                 src_reg = FS_R0;
884                         else
885                                 src_reg = FS_OC;
886
887                         if (intel_transform_is_affine(intel->transform[0]))
888                                 i915_fs_texld(src_reg, FS_S0, FS_T0);
889                         else
890                                 i915_fs_texldp(src_reg, FS_S0, FS_T0);
891                 }
892
893                 if (src_reg != FS_OC) {
894                         if (dest_is_alpha)
895                                 i915_fs_mov(FS_OC, i915_fs_operand(src_reg, W, W, W, W));
896                         else
897                                 i915_fs_mov(FS_OC, i915_fs_operand_reg(src_reg));
898                 }
899         } else {
900                 if (is_solid_mask) {
901                         i915_fs_dcl(FS_T9);
902                         mask_reg = FS_T9;
903                 } else {
904                         i915_fs_dcl(FS_T0 + t);
905                         i915_fs_dcl(FS_S0 + t);
906                 }
907
908                 tex_unit = 0;
909                 if (! is_solid_src) {
910                         /* Load the source_picture texel */
911                         if (intel_transform_is_affine(intel->transform[tex_unit]))
912                                 i915_fs_texld(FS_R0, FS_S0, FS_T0);
913                         else
914                                 i915_fs_texldp(FS_R0, FS_S0, FS_T0);
915
916                         src_reg = FS_R0;
917                         tex_unit++;
918                 }
919
920                 if (! is_solid_mask) {
921                         /* Load the mask_picture texel */
922                         if (intel_transform_is_affine(intel->transform[tex_unit]))
923                                 i915_fs_texld(FS_R1, FS_S0 + t, FS_T0 + t);
924                         else
925                                 i915_fs_texldp(FS_R1, FS_S0 + t, FS_T0 + t);
926
927                         mask_reg = FS_R1;
928                 }
929
930                 if (dest_is_alpha) {
931                         i915_fs_mul(FS_OC,
932                                     i915_fs_operand(src_reg, W, W, W, W),
933                                     i915_fs_operand(mask_reg, W, W, W, W));
934                 } else {
935                         /* If component alpha is active in the mask and the blend
936                          * operation uses the source alpha, then we know we don't
937                          * need the source value (otherwise we would have hit a
938                          * fallback earlier), so we provide the source alpha (src.A *
939                          * mask.X) as output color.
940                          * Conversely, if CA is set and we don't need the source alpha,
941                          * then we produce the source value (src.X * mask.X) and the
942                          * source alpha is unused.  Otherwise, we provide the non-CA
943                          * source value (src.X * mask.A).
944                          */
945                         if (mask_picture->componentAlpha &&
946                             PICT_FORMAT_RGB(mask_picture->format)) {
947                                 if (i915_blend_op[op].src_alpha) {
948                                         i915_fs_mul(FS_OC,
949                                                     i915_fs_operand(src_reg, W, W, W, W),
950                                                     i915_fs_operand_reg(mask_reg));
951                                 } else {
952                                         i915_fs_mul(FS_OC,
953                                                     i915_fs_operand_reg(src_reg),
954                                                     i915_fs_operand_reg(mask_reg));
955                                 }
956                         } else {
957                                 i915_fs_mul(FS_OC,
958                                             i915_fs_operand_reg(src_reg),
959                                             i915_fs_operand(mask_reg, W, W, W, W));
960                         }
961                 }
962         }
963
964         FS_END();
965 }
966
967 static void i915_emit_composite_setup(ScrnInfoPtr scrn)
968 {
969         intel_screen_private *intel = intel_get_screen_private(scrn);
970         int op = intel->i915_render_state.op;
971         PicturePtr mask_picture = intel->render_mask_picture;
972         PicturePtr dest_picture = intel->render_dest_picture;
973         PixmapPtr mask = intel->render_mask;
974         PixmapPtr dest = intel->render_dest;
975         Bool is_solid_src, is_solid_mask;
976         int tex_count, t;
977
978         intel->needs_render_state_emit = FALSE;
979
980         IntelEmitInvarientState(scrn);
981         intel->last_3d = LAST_3D_RENDER;
982
983         is_solid_src = intel->render_source_is_solid;
984         is_solid_mask = intel->render_mask_is_solid;
985
986         tex_count = 0;
987         tex_count += ! is_solid_src;
988         tex_count += mask && ! is_solid_mask;
989
990         assert(intel->in_batch_atomic);
991
992         if (tex_count != 0) {
993             OUT_BATCH(_3DSTATE_MAP_STATE | (3 * tex_count));
994             OUT_BATCH((1 << tex_count) - 1);
995             for (t = 0; t < tex_count; t++) {
996                 OUT_RELOC_PIXMAP(intel->texture[t], I915_GEM_DOMAIN_SAMPLER, 0, 0);
997                 OUT_BATCH(intel->mapstate[3*t + 1]);
998                 OUT_BATCH(intel->mapstate[3*t + 2]);
999             }
1000
1001             OUT_BATCH(_3DSTATE_SAMPLER_STATE | (3 * tex_count));
1002             OUT_BATCH((1 << tex_count) - 1);
1003             for (t = 0; t < tex_count; t++) {
1004                 OUT_BATCH(intel->samplerstate[3*t + 0]);
1005                 OUT_BATCH(intel->samplerstate[3*t + 1]);
1006                 OUT_BATCH(intel->samplerstate[3*t + 2]);
1007             }
1008         }
1009
1010         if (is_solid_src) {
1011             OUT_BATCH (_3DSTATE_DFLT_DIFFUSE_CMD);
1012             OUT_BATCH (intel->render_source_solid);
1013         }
1014         if (mask && is_solid_mask) {
1015             OUT_BATCH (_3DSTATE_DFLT_SPEC_CMD);
1016             OUT_BATCH (intel->render_mask_solid);
1017         }
1018
1019         /* BUF_INFO is an implicit flush, so avoid if the target has not changed.
1020          * XXX However for reasons unfathomed, correct rendering in KDE requires
1021          * at least a MI_FLUSH | INHIBIT_RENDER_CACHE_FLUSH here.
1022          */
1023         if (1 || dest != intel->render_current_dest) {
1024                 uint32_t tiling_bits;
1025
1026                 intel_batch_do_flush(scrn);
1027
1028                 if (intel_pixmap_tiled(dest)) {
1029                         tiling_bits = BUF_3D_TILED_SURFACE;
1030                         if (intel_get_pixmap_private(dest)->tiling
1031                             == I915_TILING_Y)
1032                                 tiling_bits |= BUF_3D_TILE_WALK_Y;
1033                 } else
1034                         tiling_bits = 0;
1035
1036                 OUT_BATCH(_3DSTATE_BUF_INFO_CMD);
1037                 OUT_BATCH(BUF_3D_ID_COLOR_BACK | tiling_bits |
1038                           BUF_3D_PITCH(intel_pixmap_pitch(dest)));
1039                 OUT_RELOC_PIXMAP(dest, I915_GEM_DOMAIN_RENDER,
1040                                  I915_GEM_DOMAIN_RENDER, 0);
1041
1042                 OUT_BATCH(_3DSTATE_DST_BUF_VARS_CMD);
1043                 OUT_BATCH(intel->i915_render_state.dst_format);
1044
1045                 /* draw rect is unconditional */
1046                 OUT_BATCH(_3DSTATE_DRAW_RECT_CMD);
1047                 OUT_BATCH(0x00000000);
1048                 OUT_BATCH(0x00000000);  /* ymin, xmin */
1049                 OUT_BATCH(DRAW_YMAX(dest->drawable.height - 1) |
1050                           DRAW_XMAX(dest->drawable.width - 1));
1051                 /* yorig, xorig (relate to color buffer?) */
1052                 OUT_BATCH(0x00000000);
1053
1054                 intel->render_current_dest = dest;
1055         }
1056
1057         {
1058                 uint32_t ss2;
1059
1060                 ss2 = ~0;
1061                 t = 0;
1062                 if (! is_solid_src) {
1063                     ss2 &= ~S2_TEXCOORD_FMT(t, TEXCOORDFMT_NOT_PRESENT);
1064                     ss2 |= S2_TEXCOORD_FMT(t,
1065                                            intel_transform_is_affine(intel->transform[t]) ?
1066                                            TEXCOORDFMT_2D : TEXCOORDFMT_4D);
1067                     t++;
1068                 }
1069                 if (mask && ! is_solid_mask) {
1070                     ss2 &= ~S2_TEXCOORD_FMT(t, TEXCOORDFMT_NOT_PRESENT);
1071                     ss2 |= S2_TEXCOORD_FMT(t,
1072                                            intel_transform_is_affine(intel->transform[t]) ?
1073                                            TEXCOORDFMT_2D : TEXCOORDFMT_4D);
1074                     t++;
1075                 }
1076
1077                 if (intel->needs_render_ca_pass) {
1078                         OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(2) | 0);
1079                         OUT_BATCH(ss2);
1080                 } else {
1081                         OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(2) | I1_LOAD_S(6) | 1);
1082                         OUT_BATCH(ss2);
1083                         OUT_BATCH(i915_get_blend_cntl(op, mask_picture, dest_picture->format));
1084                 }
1085         }
1086
1087         if (! intel->needs_render_ca_pass)
1088                 i915_composite_emit_shader(intel, op);
1089 }
1090
1091 void
1092 i915_composite(PixmapPtr dest, int srcX, int srcY, int maskX, int maskY,
1093                int dstX, int dstY, int w, int h)
1094 {
1095         ScrnInfoPtr scrn = xf86Screens[dest->drawable.pScreen->myNum];
1096         intel_screen_private *intel = intel_get_screen_private(scrn);
1097
1098         /* 28 + 16 + 10 + 20 + 32 + 16 */
1099         intel_batch_start_atomic(scrn, 150);
1100
1101         if (intel->needs_render_state_emit)
1102                 i915_emit_composite_setup(scrn);
1103
1104         if (intel->needs_render_vertex_emit ||
1105             intel_vertex_space(intel) < 3*4*intel->floats_per_vertex) {
1106                 i915_vertex_flush(intel);
1107
1108                 if (intel_vertex_space(intel) < 256) {
1109                         intel_next_vertex(intel);
1110
1111                         OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 |
1112                                   I1_LOAD_S(0) | I1_LOAD_S(1) | 1);
1113                         OUT_RELOC(intel->vertex_bo, I915_GEM_DOMAIN_VERTEX, 0, 0);
1114                         OUT_BATCH((intel->floats_per_vertex << S1_VERTEX_WIDTH_SHIFT) |
1115                                   (intel->floats_per_vertex << S1_VERTEX_PITCH_SHIFT));
1116                         intel->vertex_index = 0;
1117                 } else if (intel->floats_per_vertex != intel->last_floats_per_vertex){
1118                         OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 |
1119                                   I1_LOAD_S(1) | 0);
1120                         OUT_BATCH((intel->floats_per_vertex << S1_VERTEX_WIDTH_SHIFT) |
1121                                   (intel->floats_per_vertex << S1_VERTEX_PITCH_SHIFT));
1122
1123                         intel->vertex_index =
1124                                 (intel->vertex_used + intel->floats_per_vertex - 1) /  intel->floats_per_vertex;
1125                         intel->vertex_used = intel->vertex_index * intel->floats_per_vertex;
1126                 }
1127
1128                 intel->last_floats_per_vertex = intel->floats_per_vertex;
1129                 intel->needs_render_vertex_emit = FALSE;
1130         }
1131
1132         if (intel->prim_offset == 0) {
1133                 if (intel->needs_render_ca_pass) {
1134                         OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(6) | 0);
1135                         OUT_BATCH(i915_get_blend_cntl(PictOpOutReverse,
1136                                                       intel->render_mask_picture,
1137                                                       intel->render_dest_picture->format));
1138                         i915_composite_emit_shader(intel, PictOpOutReverse);
1139                 }
1140
1141                 intel->prim_offset = intel->batch_used;
1142                 OUT_BATCH(PRIM3D_RECTLIST | PRIM3D_INDIRECT_SEQUENTIAL);
1143                 OUT_BATCH(intel->vertex_index);
1144         }
1145         intel->vertex_count += 3;
1146
1147         intel->prim_emit(intel,
1148                          srcX, srcY,
1149                          maskX, maskY,
1150                          dstX, dstY,
1151                          w, h);
1152
1153         intel_batch_end_atomic(scrn);
1154 }
1155
1156 void
1157 i915_vertex_flush(intel_screen_private *intel)
1158 {
1159         if (intel->prim_offset == 0)
1160                 return;
1161
1162         intel->batch_ptr[intel->prim_offset] |= intel->vertex_count;
1163         intel->prim_offset = 0;
1164
1165         if (intel->needs_render_ca_pass) {
1166                 OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(6) | 0);
1167                 OUT_BATCH(i915_get_blend_cntl(PictOpAdd,
1168                                               intel->render_mask_picture,
1169                                               intel->render_dest_picture->format));
1170                 i915_composite_emit_shader(intel, PictOpAdd);
1171                 OUT_BATCH(PRIM3D_RECTLIST | PRIM3D_INDIRECT_SEQUENTIAL | intel->vertex_count);
1172                 OUT_BATCH(intel->vertex_index);
1173         }
1174
1175         intel->vertex_index += intel->vertex_count;
1176         intel->vertex_count = 0;
1177 }
1178
1179 void
1180 i915_batch_commit_notify(intel_screen_private *intel)
1181 {
1182         intel->needs_render_state_emit = TRUE;
1183         intel->render_current_dest = NULL;
1184         intel->last_floats_per_vertex = 0;
1185 }