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>
49 #define TB0C_LAST_STAGE (1 << 31)
50 #define TB0C_RESULT_SCALE_1X (0 << 29)
51 #define TB0C_RESULT_SCALE_2X (1 << 29)
52 #define TB0C_RESULT_SCALE_4X (2 << 29)
53 #define TB0C_OP_MODULE (3 << 25)
54 #define TB0C_OUTPUT_WRITE_CURRENT (0 << 24)
55 #define TB0C_OUTPUT_WRITE_ACCUM (1 << 24)
56 #define TB0C_ARG3_REPLICATE_ALPHA (1<<23)
57 #define TB0C_ARG3_INVERT (1<<22)
58 #define TB0C_ARG3_SEL_XXX
59 #define TB0C_ARG2_REPLICATE_ALPHA (1<<17)
60 #define TB0C_ARG2_INVERT (1<<16)
61 #define TB0C_ARG2_SEL_ONE (0 << 12)
62 #define TB0C_ARG2_SEL_FACTOR (1 << 12)
63 #define TB0C_ARG2_SEL_TEXEL0 (6 << 12)
64 #define TB0C_ARG2_SEL_TEXEL1 (7 << 12)
65 #define TB0C_ARG2_SEL_TEXEL2 (8 << 12)
66 #define TB0C_ARG2_SEL_TEXEL3 (9 << 12)
67 #define TB0C_ARG1_REPLICATE_ALPHA (1<<11)
68 #define TB0C_ARG1_INVERT (1<<10)
69 #define TB0C_ARG1_SEL_ONE (0 << 6)
70 #define TB0C_ARG1_SEL_TEXEL0 (6 << 6)
71 #define TB0C_ARG1_SEL_TEXEL1 (7 << 6)
72 #define TB0C_ARG1_SEL_TEXEL2 (8 << 6)
73 #define TB0C_ARG1_SEL_TEXEL3 (9 << 6)
74 #define TB0C_ARG0_REPLICATE_ALPHA (1<<5)
75 #define TB0C_ARG0_SEL_XXX
77 #define TB0A_CTR_STAGE_ENABLE (1<<31)
78 #define TB0A_RESULT_SCALE_1X (0 << 29)
79 #define TB0A_RESULT_SCALE_2X (1 << 29)
80 #define TB0A_RESULT_SCALE_4X (2 << 29)
81 #define TB0A_OP_MODULE (3 << 25)
82 #define TB0A_OUTPUT_WRITE_CURRENT (0<<24)
83 #define TB0A_OUTPUT_WRITE_ACCUM (1<<24)
84 #define TB0A_CTR_STAGE_SEL_BITS_XXX
85 #define TB0A_ARG3_SEL_XXX
86 #define TB0A_ARG3_INVERT (1<<17)
87 #define TB0A_ARG2_INVERT (1<<16)
88 #define TB0A_ARG2_SEL_ONE (0 << 12)
89 #define TB0A_ARG2_SEL_TEXEL0 (6 << 12)
90 #define TB0A_ARG2_SEL_TEXEL1 (7 << 12)
91 #define TB0A_ARG2_SEL_TEXEL2 (8 << 12)
92 #define TB0A_ARG2_SEL_TEXEL3 (9 << 12)
93 #define TB0A_ARG1_INVERT (1<<10)
94 #define TB0A_ARG1_SEL_ONE (0 << 6)
95 #define TB0A_ARG1_SEL_TEXEL0 (6 << 6)
96 #define TB0A_ARG1_SEL_TEXEL1 (7 << 6)
97 #define TB0A_ARG1_SEL_TEXEL2 (8 << 6)
98 #define TB0A_ARG1_SEL_TEXEL3 (9 << 6)
100 static struct blendinfo i830_blend_op[] = {
102 {0, 0, BLENDFACTOR_ZERO, BLENDFACTOR_ZERO},
104 {0, 0, BLENDFACTOR_ONE, BLENDFACTOR_ZERO},
106 {0, 0, BLENDFACTOR_ZERO, BLENDFACTOR_ONE},
108 {0, 1, BLENDFACTOR_ONE, BLENDFACTOR_INV_SRC_ALPHA},
110 {1, 0, BLENDFACTOR_INV_DST_ALPHA, BLENDFACTOR_ONE},
112 {1, 0, BLENDFACTOR_DST_ALPHA, BLENDFACTOR_ZERO},
114 {0, 1, BLENDFACTOR_ZERO, BLENDFACTOR_SRC_ALPHA},
116 {1, 0, BLENDFACTOR_INV_DST_ALPHA, BLENDFACTOR_ZERO},
118 {0, 1, BLENDFACTOR_ZERO, BLENDFACTOR_INV_SRC_ALPHA},
120 {1, 1, BLENDFACTOR_DST_ALPHA, BLENDFACTOR_INV_SRC_ALPHA},
122 {1, 1, BLENDFACTOR_INV_DST_ALPHA, BLENDFACTOR_SRC_ALPHA},
124 {1, 1, BLENDFACTOR_INV_DST_ALPHA, BLENDFACTOR_INV_SRC_ALPHA},
126 {0, 0, BLENDFACTOR_ONE, BLENDFACTOR_ONE},
129 static struct formatinfo i830_tex_formats[] = {
130 {PICT_a8, MAPSURF_8BIT | MT_8BIT_A8},
131 {PICT_a8r8g8b8, MAPSURF_32BIT | MT_32BIT_ARGB8888},
132 {PICT_a8b8g8r8, MAPSURF_32BIT | MT_32BIT_ABGR8888},
133 {PICT_r5g6b5, MAPSURF_16BIT | MT_16BIT_RGB565},
134 {PICT_a1r5g5b5, MAPSURF_16BIT | MT_16BIT_ARGB1555},
135 {PICT_a4r4g4b4, MAPSURF_16BIT | MT_16BIT_ARGB4444},
138 static struct formatinfo i855_tex_formats[] = {
139 {PICT_x8r8g8b8, MAPSURF_32BIT | MT_32BIT_XRGB8888},
140 {PICT_x8b8g8r8, MAPSURF_32BIT | MT_32BIT_XBGR8888},
143 static Bool i830_get_dest_format(PicturePtr dest_picture, uint32_t * dst_format)
147 switch (dest_picture->format) {
150 *dst_format = COLR_BUF_ARGB8888;
153 *dst_format = COLR_BUF_RGB565;
157 *dst_format = COLR_BUF_ARGB1555;
160 *dst_format = COLR_BUF_8BIT;
164 *dst_format = COLR_BUF_ARGB4444;
167 scrn = xf86Screens[dest_picture->pDrawable->pScreen->myNum];
168 intel_debug_fallback(scrn, "Unsupported dest format 0x%x\n",
169 (int)dest_picture->format);
172 *dst_format |= DSTORG_HORT_BIAS(0x8) | DSTORG_VERT_BIAS(0x8);
176 static Bool i830_get_blend_cntl(ScrnInfoPtr scrn, int op, PicturePtr mask,
177 uint32_t dst_format, uint32_t * blendctl)
179 uint32_t sblend, dblend;
181 sblend = i830_blend_op[op].src_blend;
182 dblend = i830_blend_op[op].dst_blend;
184 /* If there's no dst alpha channel, adjust the blend op so that we'll treat
187 if (PICT_FORMAT_A(dst_format) == 0 && i830_blend_op[op].dst_alpha) {
188 if (sblend == BLENDFACTOR_DST_ALPHA)
189 sblend = BLENDFACTOR_ONE;
190 else if (sblend == BLENDFACTOR_INV_DST_ALPHA)
191 sblend = BLENDFACTOR_ZERO;
194 /* For blending purposes, COLR_BUF_8BIT values show up in the green
195 * channel. So we can't use the alpha channel.
197 if (dst_format == PICT_a8 && ((sblend == BLENDFACTOR_DST_ALPHA ||
198 sblend == BLENDFACTOR_INV_DST_ALPHA))) {
199 intel_debug_fallback(scrn, "Can't do dst alpha blending with "
204 /* If the source alpha is being used, then we should only be in a case
205 * where the source blend factor is 0, and the source blend value is the
206 * mask channels multiplied by the source picture's alpha.
208 if (mask && mask->componentAlpha && PICT_FORMAT_RGB(mask->format)
209 && i830_blend_op[op].src_alpha) {
210 if (dblend == BLENDFACTOR_SRC_ALPHA) {
211 dblend = BLENDFACTOR_SRC_COLR;
212 } else if (dblend == BLENDFACTOR_INV_SRC_ALPHA) {
213 dblend = BLENDFACTOR_INV_SRC_COLR;
217 *blendctl = (sblend << S8_SRC_BLEND_FACTOR_SHIFT) |
218 (dblend << S8_DST_BLEND_FACTOR_SHIFT);
223 static uint32_t i8xx_get_card_format(intel_screen_private *intel,
228 for (i = 0; i < sizeof(i830_tex_formats) / sizeof(i830_tex_formats[0]);
230 if (i830_tex_formats[i].fmt == picture->format)
231 return i830_tex_formats[i].card_fmt;
234 if (!(IS_I830(intel) || IS_845G(intel))) {
235 for (i = 0; i < sizeof(i855_tex_formats) / sizeof(i855_tex_formats[0]);
237 if (i855_tex_formats[i].fmt == picture->format)
238 return i855_tex_formats[i].card_fmt;
245 static void i830_texture_setup(PicturePtr picture, PixmapPtr pixmap, int unit)
248 ScrnInfoPtr scrn = xf86Screens[picture->pDrawable->pScreen->myNum];
249 intel_screen_private *intel = intel_get_screen_private(scrn);
250 uint32_t format, tiling_bits, pitch, filter;
252 uint32_t texcoordtype;
254 pitch = intel_pixmap_pitch(pixmap);
255 intel->scale_units[unit][0] = pixmap->drawable.width;
256 intel->scale_units[unit][1] = pixmap->drawable.height;
257 intel->transform[unit] = picture->transform;
259 if (intel_transform_is_affine(intel->transform[unit]))
260 texcoordtype = TEXCOORDTYPE_CARTESIAN;
262 texcoordtype = TEXCOORDTYPE_HOMOGENEOUS;
264 switch (picture->repeatType) {
266 wrap_mode = TEXCOORDMODE_CLAMP_BORDER;
269 wrap_mode = TEXCOORDMODE_WRAP;
272 wrap_mode = TEXCOORDMODE_CLAMP;
275 wrap_mode = TEXCOORDMODE_MIRROR;
278 FatalError("Unknown repeat type %d\n", picture->repeatType);
281 switch (picture->filter) {
282 case PictFilterNearest:
283 filter = ((FILTER_NEAREST << TM0S3_MAG_FILTER_SHIFT) |
284 (FILTER_NEAREST << TM0S3_MIN_FILTER_SHIFT));
286 case PictFilterBilinear:
287 filter = ((FILTER_LINEAR << TM0S3_MAG_FILTER_SHIFT) |
288 (FILTER_LINEAR << TM0S3_MIN_FILTER_SHIFT));
291 FatalError("Bad filter 0x%x\n", picture->filter);
293 filter |= (MIPFILTER_NONE << TM0S3_MIP_FILTER_SHIFT);
295 if (intel_pixmap_tiled(pixmap)) {
296 tiling_bits = TM0S1_TILED_SURFACE;
297 if (intel_get_pixmap_private(pixmap)->tiling
299 tiling_bits |= TM0S1_TILE_WALK;
303 format = i8xx_get_card_format(intel, picture);
305 assert(intel->in_batch_atomic);
307 OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_2 |
308 LOAD_TEXTURE_MAP(unit) | 4);
309 OUT_RELOC_PIXMAP(pixmap, I915_GEM_DOMAIN_SAMPLER, 0, 0);
310 OUT_BATCH(((pixmap->drawable.height -
311 1) << TM0S1_HEIGHT_SHIFT) | ((pixmap->drawable.width -
314 format | tiling_bits);
315 OUT_BATCH((pitch / 4 - 1) << TM0S2_PITCH_SHIFT | TM0S2_MAP_2D);
317 OUT_BATCH(0); /* default color */
318 OUT_BATCH(_3DSTATE_MAP_COORD_SET_CMD | TEXCOORD_SET(unit) |
319 ENABLE_TEXCOORD_PARAMS | TEXCOORDS_ARE_NORMAL |
320 texcoordtype | ENABLE_ADDR_V_CNTL |
321 TEXCOORD_ADDR_V_MODE(wrap_mode) |
322 ENABLE_ADDR_U_CNTL | TEXCOORD_ADDR_U_MODE(wrap_mode));
323 /* map texel stream */
324 OUT_BATCH(_3DSTATE_MAP_COORD_SETBIND_CMD);
326 OUT_BATCH(TEXBIND_SET0(TEXCOORDSRC_VTXSET_0) |
327 TEXBIND_SET1(TEXCOORDSRC_KEEP) |
328 TEXBIND_SET2(TEXCOORDSRC_KEEP) |
329 TEXBIND_SET3(TEXCOORDSRC_KEEP));
331 OUT_BATCH(TEXBIND_SET0(TEXCOORDSRC_VTXSET_0) |
332 TEXBIND_SET1(TEXCOORDSRC_VTXSET_1) |
333 TEXBIND_SET2(TEXCOORDSRC_KEEP) |
334 TEXBIND_SET3(TEXCOORDSRC_KEEP));
335 OUT_BATCH(_3DSTATE_MAP_TEX_STREAM_CMD | (unit << 16) |
336 DISABLE_TEX_STREAM_BUMP |
337 ENABLE_TEX_STREAM_COORD_SET |
338 TEX_STREAM_COORD_SET(unit) |
339 ENABLE_TEX_STREAM_MAP_IDX | TEX_STREAM_MAP_IDX(unit));
343 i830_check_composite(int op,
344 PicturePtr source_picture,
345 PicturePtr mask_picture,
346 PicturePtr dest_picture,
347 int width, int height)
349 ScrnInfoPtr scrn = xf86Screens[dest_picture->pDrawable->pScreen->myNum];
352 /* Check for unsupported compositing operations. */
353 if (op >= sizeof(i830_blend_op) / sizeof(i830_blend_op[0])) {
354 intel_debug_fallback(scrn, "Unsupported Composite op 0x%x\n",
359 if (mask_picture != NULL && mask_picture->componentAlpha &&
360 PICT_FORMAT_RGB(mask_picture->format)) {
361 /* Check if it's component alpha that relies on a source alpha and on
362 * the source value. We can only get one of those into the single
363 * source value that we get to blend with.
365 if (i830_blend_op[op].src_alpha &&
366 (i830_blend_op[op].src_blend != BLENDFACTOR_ZERO)) {
367 intel_debug_fallback(scrn, "Component alpha not "
368 "supported with source alpha and "
369 "source value blending.\n");
374 if (!i830_get_dest_format(dest_picture, &tmp1)) {
375 intel_debug_fallback(scrn, "Get Color buffer format\n");
379 if (width > 2048 || height > 2048) {
380 intel_debug_fallback(scrn, "Operation is too large (%d, %d)\n", width, height);
388 i830_check_composite_target(PixmapPtr pixmap)
390 if (pixmap->drawable.width > 2048 || pixmap->drawable.height > 2048)
393 if(!intel_check_pitch_3d(pixmap))
400 i830_check_composite_texture(ScreenPtr screen, PicturePtr picture)
402 ScrnInfoPtr scrn = xf86Screens[screen->myNum];
403 intel_screen_private *intel = intel_get_screen_private(scrn);
405 if (picture->repeatType > RepeatReflect) {
406 intel_debug_fallback(scrn, "Unsupported picture repeat %d\n",
407 picture->repeatType);
411 if (picture->filter != PictFilterNearest &&
412 picture->filter != PictFilterBilinear) {
413 intel_debug_fallback(scrn, "Unsupported filter 0x%x\n",
418 if (picture->pDrawable) {
421 w = picture->pDrawable->width;
422 h = picture->pDrawable->height;
423 if ((w > 2048) || (h > 2048)) {
424 intel_debug_fallback(scrn,
425 "Picture w/h too large (%dx%d)\n",
430 /* XXX we can use the xrgb32 types if there the picture covers the clip */
431 if (!i8xx_get_card_format(intel, picture)) {
432 intel_debug_fallback(scrn, "Unsupported picture format "
434 (int)picture->format);
445 i830_prepare_composite(int op, PicturePtr source_picture,
446 PicturePtr mask_picture, PicturePtr dest_picture,
447 PixmapPtr source, PixmapPtr mask, PixmapPtr dest)
449 ScrnInfoPtr scrn = xf86Screens[dest_picture->pDrawable->pScreen->myNum];
450 intel_screen_private *intel = intel_get_screen_private(scrn);
451 drm_intel_bo *bo_table[] = {
453 intel_get_pixmap_bo(source),
454 mask ? intel_get_pixmap_bo(mask) : NULL,
455 intel_get_pixmap_bo(dest),
458 intel->render_source_picture = source_picture;
459 intel->render_source = source;
460 intel->render_mask_picture = mask_picture;
461 intel->render_mask = mask;
462 intel->render_dest_picture = dest_picture;
463 intel->render_dest = dest;
465 if (!intel_check_pitch_3d(source))
468 if (mask_picture->componentAlpha &&
469 PICT_FORMAT_RGB(mask_picture->format)) {
470 /* Check if it's component alpha that relies on a source alpha and on
471 * the source value. We can only get one of those into the single
472 * source value that we get to blend with.
474 if (i830_blend_op[op].src_alpha &&
475 (i830_blend_op[op].src_blend != BLENDFACTOR_ZERO)) {
476 intel_debug_fallback(scrn, "Component alpha not "
477 "supported with source alpha and "
478 "source value blending.\n");
482 if (!intel_check_pitch_3d(mask))
485 if (!intel_check_pitch_3d(dest))
488 if (!i830_get_dest_format(dest_picture, &intel->render_dest_format))
491 if (!intel_get_aperture_space(scrn, bo_table, ARRAY_SIZE(bo_table)))
495 intel->transform[1] = NULL;
496 intel->scale_units[1][0] = -1;
497 intel->scale_units[1][1] = -1;
501 uint32_t cblend, ablend, blendctl;
503 /* If component alpha is active in the mask and the blend operation
504 * uses the source alpha, then we know we don't need the source
505 * value (otherwise we would have hit a fallback earlier), so we
506 * provide the source alpha (src.A * mask.X) as output color.
507 * Conversely, if CA is set and we don't need the source alpha, then
508 * we produce the source value (src.X * mask.X) and the source alpha
509 * is unused.. Otherwise, we provide the non-CA source value
512 * The PICT_FORMAT_RGB(pict) == 0 fixups are not needed on 855+'s a8
513 * pictures, but we need to implement it for 830/845 and there's no
514 * harm done in leaving it in.
517 TB0C_LAST_STAGE | TB0C_RESULT_SCALE_1X | TB0C_OP_MODULE |
518 TB0C_OUTPUT_WRITE_CURRENT;
520 TB0A_RESULT_SCALE_1X | TB0A_OP_MODULE |
521 TB0A_OUTPUT_WRITE_CURRENT;
523 /* Get the source picture's channels into TBx_ARG1 */
524 if ((mask_picture != NULL &&
525 mask_picture->componentAlpha &&
526 PICT_FORMAT_RGB(mask_picture->format) &&
527 i830_blend_op[op].src_alpha)
528 || dest_picture->format == PICT_a8) {
529 /* Producing source alpha value, so the first set of channels
530 * is src.A instead of src.X. We also do this if the destination
531 * is a8, in which case src.G is what's written, and the other
532 * channels are ignored.
534 ablend |= TB0A_ARG1_SEL_TEXEL0;
535 cblend |= TB0C_ARG1_SEL_TEXEL0 | TB0C_ARG1_REPLICATE_ALPHA;
537 if (PICT_FORMAT_RGB(source_picture->format) != 0)
538 cblend |= TB0C_ARG1_SEL_TEXEL0;
540 cblend |= TB0C_ARG1_SEL_ONE | TB0C_ARG1_INVERT; /* 0.0 */
541 ablend |= TB0A_ARG1_SEL_TEXEL0;
545 cblend |= TB0C_ARG2_SEL_TEXEL1;
546 if (dest_picture->format == PICT_a8 ||
547 ! mask_picture->componentAlpha ||
548 ! PICT_FORMAT_RGB(mask_picture->format))
549 cblend |= TB0C_ARG2_REPLICATE_ALPHA;
550 ablend |= TB0A_ARG2_SEL_TEXEL1;
552 cblend |= TB0C_ARG2_SEL_ONE;
553 ablend |= TB0A_ARG2_SEL_ONE;
556 if (!i830_get_blend_cntl
557 (scrn, op, mask_picture, dest_picture->format, &blendctl)) {
561 intel->cblend = cblend;
562 intel->ablend = ablend;
563 intel->s8_blendctl = blendctl;
566 if(intel_pixmap_is_dirty(source) ||
567 (mask && intel_pixmap_is_dirty(mask)))
568 intel_batch_emit_flush(scrn);
570 intel->needs_render_state_emit = TRUE;
575 static void i830_emit_composite_state(ScrnInfoPtr scrn)
577 intel_screen_private *intel = intel_get_screen_private(scrn);
578 uint32_t vf2, tiling_bits;
579 uint32_t texcoordfmt = 0;
581 intel->needs_render_state_emit = FALSE;
583 IntelEmitInvarientState(scrn);
584 intel->last_3d = LAST_3D_RENDER;
586 assert(intel->in_batch_atomic);
588 if (intel_pixmap_tiled(intel->render_dest)) {
589 tiling_bits = BUF_3D_TILED_SURFACE;
590 if (intel_get_pixmap_private(intel->render_dest)->tiling
592 tiling_bits |= BUF_3D_TILE_WALK_Y;
596 OUT_BATCH(_3DSTATE_BUF_INFO_CMD);
597 OUT_BATCH(BUF_3D_ID_COLOR_BACK | tiling_bits |
598 BUF_3D_PITCH(intel_pixmap_pitch(intel->render_dest)));
599 OUT_RELOC_PIXMAP(intel->render_dest,
600 I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0);
602 OUT_BATCH(_3DSTATE_DST_BUF_VARS_CMD);
603 OUT_BATCH(intel->render_dest_format);
605 OUT_BATCH(_3DSTATE_DRAW_RECT_CMD);
607 OUT_BATCH(0); /* ymin, xmin */
608 OUT_BATCH(DRAW_YMAX(intel->render_dest->drawable.height - 1) |
609 DRAW_XMAX(intel->render_dest->drawable.width - 1));
610 OUT_BATCH(0); /* yorig, xorig */
612 OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 |
613 I1_LOAD_S(2) | I1_LOAD_S(3) | I1_LOAD_S(8) | 2);
614 if (intel->render_mask)
615 vf2 = 2 << 12; /* 2 texture coord sets */
618 OUT_BATCH(vf2); /* number of coordinate sets */
619 OUT_BATCH(S3_CULLMODE_NONE | S3_VERTEXHAS_XY);
620 OUT_BATCH(S8_ENABLE_COLOR_BLEND | S8_BLENDFUNC_ADD | intel->
621 s8_blendctl | S8_ENABLE_COLOR_BUFFER_WRITE);
623 OUT_BATCH(_3DSTATE_INDPT_ALPHA_BLEND_CMD | DISABLE_INDPT_ALPHA_BLEND);
625 OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_2 |
626 LOAD_TEXTURE_BLEND_STAGE(0) | 1);
627 OUT_BATCH(intel->cblend);
628 OUT_BATCH(intel->ablend);
630 OUT_BATCH(_3DSTATE_ENABLES_1_CMD | DISABLE_LOGIC_OP |
631 DISABLE_STENCIL_TEST | DISABLE_DEPTH_BIAS |
632 DISABLE_SPEC_ADD | DISABLE_FOG | DISABLE_ALPHA_TEST |
633 ENABLE_COLOR_BLEND | DISABLE_DEPTH_TEST);
634 /* We have to explicitly say we don't want write disabled */
635 OUT_BATCH(_3DSTATE_ENABLES_2_CMD | ENABLE_COLOR_MASK |
636 DISABLE_STENCIL_WRITE | ENABLE_TEX_CACHE |
637 DISABLE_DITHER | ENABLE_COLOR_WRITE | DISABLE_DEPTH_WRITE);
639 if (intel_transform_is_affine(intel->render_source_picture->transform))
640 texcoordfmt |= (TEXCOORDFMT_2D << 0);
642 texcoordfmt |= (TEXCOORDFMT_3D << 0);
643 if (intel->render_mask) {
644 if (intel_transform_is_affine
645 (intel->render_mask_picture->transform))
646 texcoordfmt |= (TEXCOORDFMT_2D << 2);
648 texcoordfmt |= (TEXCOORDFMT_3D << 2);
650 OUT_BATCH(_3DSTATE_VERTEX_FORMAT_2_CMD | texcoordfmt);
652 i830_texture_setup(intel->render_source_picture, intel->render_source, 0);
653 if (intel->render_mask) {
654 i830_texture_setup(intel->render_mask_picture,
655 intel->render_mask, 1);
659 /* Emit the vertices for a single composite rectangle.
661 * This function is no longer shared between i830 and i915 generation code.
664 i830_emit_composite_primitive(PixmapPtr dest,
666 int maskX, int maskY,
667 int dstX, int dstY, int w, int h)
669 ScrnInfoPtr scrn = xf86Screens[dest->drawable.pScreen->myNum];
670 intel_screen_private *intel = intel_get_screen_private(scrn);
671 Bool is_affine_src, is_affine_mask = TRUE;
673 float src_x[3], src_y[3], src_w[3], mask_x[3], mask_y[3], mask_w[3];
675 per_vertex = 2; /* dest x/y */
678 float x = srcX, y = srcY;
680 is_affine_src = intel_transform_is_affine(intel->transform[0]);
682 if (!intel_get_transformed_coordinates(x, y,
689 if (!intel_get_transformed_coordinates(x, y + h,
696 if (!intel_get_transformed_coordinates(x + w, y + h,
703 per_vertex += 2; /* src x/y */
705 if (!intel_get_transformed_coordinates_3d(x, y,
713 if (!intel_get_transformed_coordinates_3d(x, y + h,
721 if (!intel_get_transformed_coordinates_3d(x + w, y + h,
729 per_vertex += 3; /* src x/y/w */
733 if (intel->render_mask) {
734 float x = maskX, y = maskY;
736 is_affine_mask = intel_transform_is_affine(intel->transform[1]);
737 if (is_affine_mask) {
738 if (!intel_get_transformed_coordinates(x, y,
745 if (!intel_get_transformed_coordinates(x, y + h,
752 if (!intel_get_transformed_coordinates(x + w, y + h,
759 per_vertex += 2; /* mask x/y */
761 if (!intel_get_transformed_coordinates_3d(x, y,
769 if (!intel_get_transformed_coordinates_3d(x, y + h,
777 if (!intel_get_transformed_coordinates_3d(x + w, y + h,
785 per_vertex += 3; /* mask x/y/w */
789 if (intel->vertex_count == 0) {
790 intel->vertex_index = intel->batch_used;
791 OUT_BATCH(PRIM3D_INLINE | PRIM3D_RECTLIST);
793 OUT_BATCH_F(dstX + w);
794 OUT_BATCH_F(dstY + h);
795 OUT_BATCH_F(src_x[2] / intel->scale_units[0][0]);
796 OUT_BATCH_F(src_y[2] / intel->scale_units[0][1]);
797 if (!is_affine_src) {
798 OUT_BATCH_F(src_w[2]);
800 if (intel->render_mask) {
801 OUT_BATCH_F(mask_x[2] / intel->scale_units[1][0]);
802 OUT_BATCH_F(mask_y[2] / intel->scale_units[1][1]);
803 if (!is_affine_mask) {
804 OUT_BATCH_F(mask_w[2]);
809 OUT_BATCH_F(dstY + h);
810 OUT_BATCH_F(src_x[1] / intel->scale_units[0][0]);
811 OUT_BATCH_F(src_y[1] / intel->scale_units[0][1]);
812 if (!is_affine_src) {
813 OUT_BATCH_F(src_w[1]);
815 if (intel->render_mask) {
816 OUT_BATCH_F(mask_x[1] / intel->scale_units[1][0]);
817 OUT_BATCH_F(mask_y[1] / intel->scale_units[1][1]);
818 if (!is_affine_mask) {
819 OUT_BATCH_F(mask_w[1]);
825 OUT_BATCH_F(src_x[0] / intel->scale_units[0][0]);
826 OUT_BATCH_F(src_y[0] / intel->scale_units[0][1]);
827 if (!is_affine_src) {
828 OUT_BATCH_F(src_w[0]);
830 if (intel->render_mask) {
831 OUT_BATCH_F(mask_x[0] / intel->scale_units[1][0]);
832 OUT_BATCH_F(mask_y[0] / intel->scale_units[1][1]);
833 if (!is_affine_mask) {
834 OUT_BATCH_F(mask_w[0]);
838 intel->vertex_count += 3 * per_vertex;
842 void i830_vertex_flush(intel_screen_private *intel)
844 if (intel->vertex_count) {
845 intel->batch_ptr[intel->vertex_index] |= intel->vertex_count - 1;
846 intel->vertex_count = 0;
851 * Do a single rectangle composite operation.
854 i830_composite(PixmapPtr dest, int srcX, int srcY, int maskX, int maskY,
855 int dstX, int dstY, int w, int h)
857 ScrnInfoPtr scrn = xf86Screens[dest->drawable.pScreen->myNum];
858 intel_screen_private *intel = intel_get_screen_private(scrn);
860 intel_batch_start_atomic(scrn, 58 + /* invarient */
862 20 + /* 2 * setup_texture */
863 1 + 30 /* verts */ );
865 if (intel->needs_render_state_emit)
866 i830_emit_composite_state(scrn);
868 i830_emit_composite_primitive(dest, srcX, srcY, maskX, maskY, dstX,
871 intel_batch_end_atomic(scrn);
874 void i830_batch_commit_notify(intel_screen_private *intel)
876 intel->needs_render_state_emit = TRUE;