2 * Copyright © 2006 Intel Corporation
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:
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
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
24 * Wang Zhenyu <zhenyu.z.wang@intel.com>
25 * Eric Anholt <eric@anholt.net>
50 static struct blendinfo i915_blend_op[] = {
52 {0, 0, BLENDFACT_ZERO, BLENDFACT_ZERO},
54 {0, 0, BLENDFACT_ONE, BLENDFACT_ZERO},
56 {0, 0, BLENDFACT_ZERO, BLENDFACT_ONE},
58 {0, 1, BLENDFACT_ONE, BLENDFACT_INV_SRC_ALPHA},
60 {1, 0, BLENDFACT_INV_DST_ALPHA, BLENDFACT_ONE},
62 {1, 0, BLENDFACT_DST_ALPHA, BLENDFACT_ZERO},
64 {0, 1, BLENDFACT_ZERO, BLENDFACT_SRC_ALPHA},
66 {1, 0, BLENDFACT_INV_DST_ALPHA, BLENDFACT_ZERO},
68 {0, 1, BLENDFACT_ZERO, BLENDFACT_INV_SRC_ALPHA},
70 {1, 1, BLENDFACT_DST_ALPHA, BLENDFACT_INV_SRC_ALPHA},
72 {1, 1, BLENDFACT_INV_DST_ALPHA, BLENDFACT_SRC_ALPHA},
74 {1, 1, BLENDFACT_INV_DST_ALPHA, BLENDFACT_INV_SRC_ALPHA},
76 {0, 0, BLENDFACT_ONE, BLENDFACT_ONE},
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},
89 {PICT_r5g6b5, MAPSURF_16BIT | MT_16BIT_RGB565},
90 {PICT_a1r5g5b5, MAPSURF_16BIT | MT_16BIT_ARGB1555},
91 {PICT_a4r4g4b4, MAPSURF_16BIT | MT_16BIT_ARGB4444},
94 static uint32_t i915_get_blend_cntl(int op, PicturePtr mask,
97 uint32_t sblend, dblend;
99 sblend = i915_blend_op[op].src_blend;
100 dblend = i915_blend_op[op].dst_blend;
102 /* If there's no dst alpha channel, adjust the blend op so that we'll
103 * treat it as always 1.
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;
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
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;
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.
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;
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);
142 #define DSTORG_HORT_BIAS(x) ((x)<<20)
143 #define DSTORG_VERT_BIAS(x) ((x)<<16)
145 static Bool i915_get_dest_format(PicturePtr dest_picture, uint32_t * dst_format)
149 switch (dest_picture->format) {
152 *dst_format = COLR_BUF_ARGB8888;
155 *dst_format = COLR_BUF_RGB565;
159 *dst_format = COLR_BUF_ARGB1555;
161 #if XORG_VERSION_CURRENT >= 10699900
162 case PICT_a2r10g10b10:
163 case PICT_x2r10g10b10:
164 *dst_format = COLR_BUF_ARGB2AAA;
168 *dst_format = COLR_BUF_8BIT;
172 *dst_format = COLR_BUF_ARGB4444;
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);
181 *dst_format |= DSTORG_HORT_BIAS(0x8) | DSTORG_VERT_BIAS(0x8);
186 i915_check_composite(int op,
187 PicturePtr source_picture,
188 PicturePtr mask_picture,
189 PicturePtr dest_picture,
190 int width, int height)
192 ScrnInfoPtr scrn = xf86Screens[dest_picture->pDrawable->pScreen->myNum];
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",
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.
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");
219 if (!i915_get_dest_format(dest_picture, &tmp1)) {
220 intel_debug_fallback(scrn, "Get Color buffer format\n");
224 if (width > 2048 || height > 2048)
231 i915_check_composite_target(PixmapPtr pixmap)
233 if (pixmap->drawable.width > 2048 || pixmap->drawable.height > 2048)
236 if(!intel_check_pitch_3d(pixmap))
243 i915_check_composite_texture(ScreenPtr screen, PicturePtr picture)
245 if (picture->repeatType > RepeatReflect) {
246 ScrnInfoPtr scrn = xf86Screens[screen->myNum];
247 intel_debug_fallback(scrn, "Unsupported picture repeat %d\n",
248 picture->repeatType);
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",
260 if (picture->pSourcePict) {
261 SourcePict *source = picture->pSourcePict;
262 if (source->type == SourcePictTypeSolidFill)
266 if (picture->pDrawable) {
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",
280 i < sizeof(i915_tex_formats) / sizeof(i915_tex_formats[0]);
282 if (i915_tex_formats[i].fmt == picture->format)
285 if (i == sizeof(i915_tex_formats) / sizeof(i915_tex_formats[0]))
287 ScrnInfoPtr scrn = xf86Screens[screen->myNum];
288 intel_debug_fallback(scrn, "Unsupported picture format "
290 (int)picture->format);
300 static Bool i915_texture_setup(PicturePtr picture, PixmapPtr pixmap, int unit)
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;
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;
312 for (i = 0; i < sizeof(i915_tex_formats) / sizeof(i915_tex_formats[0]);
314 if (i915_tex_formats[i].fmt == picture->format)
317 if (i == sizeof(i915_tex_formats) / sizeof(i915_tex_formats[0])) {
318 intel_debug_fallback(scrn, "unknown texture format\n");
321 format = i915_tex_formats[i].card_fmt;
323 switch (picture->repeatType) {
325 wrap_mode = TEXCOORDMODE_CLAMP_BORDER;
328 wrap_mode = TEXCOORDMODE_WRAP;
331 wrap_mode = TEXCOORDMODE_CLAMP_EDGE;
334 wrap_mode = TEXCOORDMODE_MIRROR;
337 FatalError("Unknown repeat type %d\n", picture->repeatType);
340 switch (picture->filter) {
341 case PictFilterNearest:
342 filter = (FILTER_NEAREST << SS2_MAG_FILTER_SHIFT) |
343 (FILTER_NEAREST << SS2_MIN_FILTER_SHIFT);
345 case PictFilterBilinear:
346 filter = (FILTER_LINEAR << SS2_MAG_FILTER_SHIFT) |
347 (FILTER_LINEAR << SS2_MIN_FILTER_SHIFT);
351 intel_debug_fallback(scrn, "Bad filter 0x%x\n",
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
361 tiling_bits |= MS3_TILE_WALK;
365 intel->texture[unit] = pixmap;
366 intel->mapstate[unit * 3 + 0] = 0;
367 intel->mapstate[unit * 3 + 1] = format |
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;
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 */
384 intel->transform[unit] = picture->transform;
390 i915_emit_composite_primitive_constant(intel_screen_private *intel,
392 int maskX, int maskY,
396 OUT_VERTEX(dstX + w);
397 OUT_VERTEX(dstY + h);
400 OUT_VERTEX(dstY + h);
407 i915_emit_composite_primitive_identity_source(intel_screen_private *intel,
409 int maskX, int maskY,
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]);
419 OUT_VERTEX(dstY + h);
420 OUT_VERTEX(srcX * intel->scale_units[0][0]);
421 OUT_VERTEX((srcY + h) * intel->scale_units[0][1]);
425 OUT_VERTEX(srcX * intel->scale_units[0][0]);
426 OUT_VERTEX(srcY * intel->scale_units[0][1]);
430 i915_emit_composite_primitive_affine_source(intel_screen_private *intel,
432 int maskX, int maskY,
436 float src_x[3], src_y[3];
438 if (!intel_get_transformed_coordinates(srcX, srcY,
444 if (!intel_get_transformed_coordinates(srcX, srcY + h,
450 if (!intel_get_transformed_coordinates(srcX + w, srcY + h,
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]);
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]);
468 OUT_VERTEX(src_x[0] * intel->scale_units[0][0]);
469 OUT_VERTEX(src_y[0] * intel->scale_units[0][1]);
473 i915_emit_composite_primitive_constant_identity_mask(intel_screen_private *intel,
475 int maskX, int maskY,
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]);
485 OUT_VERTEX(dstY + h);
486 OUT_VERTEX(maskX * intel->scale_units[0][0]);
487 OUT_VERTEX((maskY + h) * intel->scale_units[0][1]);
491 OUT_VERTEX(maskX * intel->scale_units[0][0]);
492 OUT_VERTEX(maskY * intel->scale_units[0][1]);
496 i915_emit_composite_primitive_identity_source_mask(intel_screen_private *intel,
498 int maskX, int maskY,
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]);
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]);
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]);
525 i915_emit_composite_primitive(intel_screen_private *intel,
527 int maskX, int maskY,
531 Bool is_affine_src = TRUE, is_affine_mask = TRUE;
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];
537 per_vertex = 2; /* dest x/y */
539 if (! intel->render_source_is_solid) {
540 src_unit = tex_unit++;
542 is_affine_src = intel_transform_is_affine(intel->transform[src_unit]);
544 if (!intel_get_transformed_coordinates(srcX, srcY,
551 if (!intel_get_transformed_coordinates(srcX, srcY + h,
558 if (!intel_get_transformed_coordinates(srcX + w, srcY + h,
565 per_vertex += 2; /* src x/y */
567 if (!intel_get_transformed_coordinates_3d(srcX, srcY,
575 if (!intel_get_transformed_coordinates_3d(srcX, srcY + h,
583 if (!intel_get_transformed_coordinates_3d(srcX + w, srcY + h,
591 per_vertex += 4; /* src x/y/z/w */
595 if (intel->render_mask && ! intel->render_mask_is_solid) {
596 mask_unit = tex_unit++;
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,
602 transform[mask_unit],
607 if (!intel_get_transformed_coordinates(maskX, maskY + h,
609 transform[mask_unit],
614 if (!intel_get_transformed_coordinates(maskX + w, maskY + h,
616 transform[mask_unit],
621 per_vertex += 2; /* mask x/y */
623 if (!intel_get_transformed_coordinates_3d(maskX, maskY,
625 transform[mask_unit],
631 if (!intel_get_transformed_coordinates_3d(maskX, maskY + h,
633 transform[mask_unit],
639 if (!intel_get_transformed_coordinates_3d(maskX + w, maskY + h,
641 transform[mask_unit],
647 per_vertex += 4; /* mask x/y/z/w */
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) {
658 OUT_VERTEX(src_w[2]);
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) {
666 OUT_VERTEX(mask_w[2]);
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) {
677 OUT_VERTEX(src_w[1]);
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) {
685 OUT_VERTEX(mask_w[1]);
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) {
696 OUT_VERTEX(src_w[0]);
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) {
704 OUT_VERTEX(mask_w[0]);
710 i915_prepare_composite(int op, PicturePtr source_picture,
711 PicturePtr mask_picture, PicturePtr dest_picture,
712 PixmapPtr source, PixmapPtr mask, PixmapPtr dest)
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[] = {
718 intel_get_pixmap_bo(dest),
719 source ? intel_get_pixmap_bo(source) : NULL,
720 mask ? intel_get_pixmap_bo(mask) : NULL,
723 int floats_per_vertex;
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;
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;
740 if (!intel->render_source_is_solid && !intel_check_pitch_3d(source))
743 intel->render_mask_is_solid = FALSE;
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;
752 if (!intel->render_mask_is_solid && !intel_check_pitch_3d(mask))
756 if (!intel_check_pitch_3d(dest))
759 if (!i915_get_dest_format(dest_picture,
760 &intel->i915_render_state.dst_format))
763 if (!intel_get_aperture_space(scrn, bo_table, ARRAY_SIZE(bo_table)))
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.
773 if (i915_blend_op[op].src_alpha &&
774 (i915_blend_op[op].src_blend != BLENDFACT_ZERO)) {
775 if (op != PictOpOver)
778 intel->needs_render_ca_pass = TRUE;
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;
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");
796 if (intel_transform_is_affine(source_picture->transform))
797 floats_per_vertex += 2; /* src x/y */
799 floats_per_vertex += 4; /* src x/y/z/w */
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");
810 if (intel_transform_is_affine(mask_picture->transform))
811 floats_per_vertex += 2; /* mask x/y */
813 floats_per_vertex += 4; /* mask x/y/z/w */
817 intel->i915_render_state.op = op;
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);
826 intel->needs_render_state_emit = TRUE;
828 intel->prim_emit = i915_emit_composite_primitive;
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;
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;
845 if (floats_per_vertex != intel->floats_per_vertex) {
846 intel->floats_per_vertex = floats_per_vertex;
847 intel->needs_render_vertex_emit = TRUE;
854 i915_composite_emit_shader(intel_screen_private *intel, CARD8 op)
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;
864 is_solid_src = intel->render_source_is_solid;
865 is_solid_mask = intel->render_mask_is_solid;
869 /* Declare the registers necessary for our program. */
880 /* No mask, so load directly to output color */
881 if (! is_solid_src) {
887 if (intel_transform_is_affine(intel->transform[0]))
888 i915_fs_texld(src_reg, FS_S0, FS_T0);
890 i915_fs_texldp(src_reg, FS_S0, FS_T0);
893 if (src_reg != FS_OC) {
895 i915_fs_mov(FS_OC, i915_fs_operand(src_reg, W, W, W, W));
897 i915_fs_mov(FS_OC, i915_fs_operand_reg(src_reg));
904 i915_fs_dcl(FS_T0 + t);
905 i915_fs_dcl(FS_S0 + t);
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);
914 i915_fs_texldp(FS_R0, FS_S0, FS_T0);
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);
925 i915_fs_texldp(FS_R1, FS_S0 + t, FS_T0 + t);
932 i915_fs_operand(src_reg, W, W, W, W),
933 i915_fs_operand(mask_reg, W, W, W, W));
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).
945 if (mask_picture->componentAlpha &&
946 PICT_FORMAT_RGB(mask_picture->format)) {
947 if (i915_blend_op[op].src_alpha) {
949 i915_fs_operand(src_reg, W, W, W, W),
950 i915_fs_operand_reg(mask_reg));
953 i915_fs_operand_reg(src_reg),
954 i915_fs_operand_reg(mask_reg));
958 i915_fs_operand_reg(src_reg),
959 i915_fs_operand(mask_reg, W, W, W, W));
967 static void i915_emit_composite_setup(ScrnInfoPtr scrn)
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;
978 intel->needs_render_state_emit = FALSE;
980 IntelEmitInvarientState(scrn);
981 intel->last_3d = LAST_3D_RENDER;
983 is_solid_src = intel->render_source_is_solid;
984 is_solid_mask = intel->render_mask_is_solid;
987 tex_count += ! is_solid_src;
988 tex_count += mask && ! is_solid_mask;
990 assert(intel->in_batch_atomic);
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]);
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]);
1011 OUT_BATCH (_3DSTATE_DFLT_DIFFUSE_CMD);
1012 OUT_BATCH (intel->render_source_solid);
1014 if (mask && is_solid_mask) {
1015 OUT_BATCH (_3DSTATE_DFLT_SPEC_CMD);
1016 OUT_BATCH (intel->render_mask_solid);
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.
1023 if (1 || dest != intel->render_current_dest) {
1024 uint32_t tiling_bits;
1026 intel_batch_do_flush(scrn);
1028 if (intel_pixmap_tiled(dest)) {
1029 tiling_bits = BUF_3D_TILED_SURFACE;
1030 if (intel_get_pixmap_private(dest)->tiling
1032 tiling_bits |= BUF_3D_TILE_WALK_Y;
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);
1042 OUT_BATCH(_3DSTATE_DST_BUF_VARS_CMD);
1043 OUT_BATCH(intel->i915_render_state.dst_format);
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);
1054 intel->render_current_dest = dest;
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);
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);
1077 if (intel->needs_render_ca_pass) {
1078 OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(2) | 0);
1081 OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(2) | I1_LOAD_S(6) | 1);
1083 OUT_BATCH(i915_get_blend_cntl(op, mask_picture, dest_picture->format));
1087 if (! intel->needs_render_ca_pass)
1088 i915_composite_emit_shader(intel, op);
1092 i915_composite(PixmapPtr dest, int srcX, int srcY, int maskX, int maskY,
1093 int dstX, int dstY, int w, int h)
1095 ScrnInfoPtr scrn = xf86Screens[dest->drawable.pScreen->myNum];
1096 intel_screen_private *intel = intel_get_screen_private(scrn);
1098 /* 28 + 16 + 10 + 20 + 32 + 16 */
1099 intel_batch_start_atomic(scrn, 150);
1101 if (intel->needs_render_state_emit)
1102 i915_emit_composite_setup(scrn);
1104 if (intel->needs_render_vertex_emit ||
1105 intel_vertex_space(intel) < 3*4*intel->floats_per_vertex) {
1106 i915_vertex_flush(intel);
1108 if (intel_vertex_space(intel) < 256) {
1109 intel_next_vertex(intel);
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 |
1120 OUT_BATCH((intel->floats_per_vertex << S1_VERTEX_WIDTH_SHIFT) |
1121 (intel->floats_per_vertex << S1_VERTEX_PITCH_SHIFT));
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;
1128 intel->last_floats_per_vertex = intel->floats_per_vertex;
1129 intel->needs_render_vertex_emit = FALSE;
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);
1141 intel->prim_offset = intel->batch_used;
1142 OUT_BATCH(PRIM3D_RECTLIST | PRIM3D_INDIRECT_SEQUENTIAL);
1143 OUT_BATCH(intel->vertex_index);
1145 intel->vertex_count += 3;
1147 intel->prim_emit(intel,
1153 intel_batch_end_atomic(scrn);
1157 i915_vertex_flush(intel_screen_private *intel)
1159 if (intel->prim_offset == 0)
1162 intel->batch_ptr[intel->prim_offset] |= intel->vertex_count;
1163 intel->prim_offset = 0;
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);
1175 intel->vertex_index += intel->vertex_count;
1176 intel->vertex_count = 0;
1180 i915_batch_commit_notify(intel_screen_private *intel)
1182 intel->needs_render_state_emit = TRUE;
1183 intel->render_current_dest = NULL;
1184 intel->last_floats_per_vertex = 0;