1fa225cbcSrjs/* 2fa225cbcSrjs * Copyright © 2006 Intel Corporation 3fa225cbcSrjs * 4fa225cbcSrjs * Permission is hereby granted, free of charge, to any person obtaining a 5fa225cbcSrjs * copy of this software and associated documentation files (the "Software"), 6fa225cbcSrjs * to deal in the Software without restriction, including without limitation 7fa225cbcSrjs * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8fa225cbcSrjs * and/or sell copies of the Software, and to permit persons to whom the 9fa225cbcSrjs * Software is furnished to do so, subject to the following conditions: 10fa225cbcSrjs * 11fa225cbcSrjs * The above copyright notice and this permission notice (including the next 12fa225cbcSrjs * paragraph) shall be included in all copies or substantial portions of the 13fa225cbcSrjs * Software. 14fa225cbcSrjs * 15fa225cbcSrjs * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16fa225cbcSrjs * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17fa225cbcSrjs * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18fa225cbcSrjs * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19fa225cbcSrjs * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20fa225cbcSrjs * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21fa225cbcSrjs * SOFTWARE. 22fa225cbcSrjs * 23fa225cbcSrjs * Authors: 24fa225cbcSrjs * Wang Zhenyu <zhenyu.z.wang@intel.com> 25fa225cbcSrjs * Eric Anholt <eric@anholt.net> 26fa225cbcSrjs * 27fa225cbcSrjs */ 28fa225cbcSrjs 29fa225cbcSrjs#ifdef HAVE_CONFIG_H 30fa225cbcSrjs#include "config.h" 31fa225cbcSrjs#endif 32fa225cbcSrjs 33fa225cbcSrjs#include "xf86.h" 34fa225cbcSrjs#include "i830.h" 35fa225cbcSrjs#include "i830_reg.h" 36fa225cbcSrjs 37fa225cbcSrjsstruct blendinfo { 38fa225cbcSrjs Bool dst_alpha; 39fa225cbcSrjs Bool src_alpha; 40fa225cbcSrjs uint32_t src_blend; 41fa225cbcSrjs uint32_t dst_blend; 42fa225cbcSrjs}; 43fa225cbcSrjs 44fa225cbcSrjsstruct formatinfo { 45fa225cbcSrjs int fmt; 46fa225cbcSrjs uint32_t card_fmt; 47fa225cbcSrjs}; 48fa225cbcSrjs 49fa225cbcSrjs#define TB0C_LAST_STAGE (1 << 31) 50fa225cbcSrjs#define TB0C_RESULT_SCALE_1X (0 << 29) 51fa225cbcSrjs#define TB0C_RESULT_SCALE_2X (1 << 29) 52fa225cbcSrjs#define TB0C_RESULT_SCALE_4X (2 << 29) 53fa225cbcSrjs#define TB0C_OP_MODULE (3 << 25) 54fa225cbcSrjs#define TB0C_OUTPUT_WRITE_CURRENT (0 << 24) 55fa225cbcSrjs#define TB0C_OUTPUT_WRITE_ACCUM (1 << 24) 56fa225cbcSrjs#define TB0C_ARG3_REPLICATE_ALPHA (1<<23) 57fa225cbcSrjs#define TB0C_ARG3_INVERT (1<<22) 58fa225cbcSrjs#define TB0C_ARG3_SEL_XXX 59fa225cbcSrjs#define TB0C_ARG2_REPLICATE_ALPHA (1<<17) 60fa225cbcSrjs#define TB0C_ARG2_INVERT (1<<16) 61fa225cbcSrjs#define TB0C_ARG2_SEL_ONE (0 << 12) 62fa225cbcSrjs#define TB0C_ARG2_SEL_FACTOR (1 << 12) 63fa225cbcSrjs#define TB0C_ARG2_SEL_TEXEL0 (6 << 12) 64fa225cbcSrjs#define TB0C_ARG2_SEL_TEXEL1 (7 << 12) 65fa225cbcSrjs#define TB0C_ARG2_SEL_TEXEL2 (8 << 12) 66fa225cbcSrjs#define TB0C_ARG2_SEL_TEXEL3 (9 << 12) 67fa225cbcSrjs#define TB0C_ARG1_REPLICATE_ALPHA (1<<11) 68fa225cbcSrjs#define TB0C_ARG1_INVERT (1<<10) 69fa225cbcSrjs#define TB0C_ARG1_SEL_ONE (0 << 6) 70fa225cbcSrjs#define TB0C_ARG1_SEL_TEXEL0 (6 << 6) 71fa225cbcSrjs#define TB0C_ARG1_SEL_TEXEL1 (7 << 6) 72fa225cbcSrjs#define TB0C_ARG1_SEL_TEXEL2 (8 << 6) 73fa225cbcSrjs#define TB0C_ARG1_SEL_TEXEL3 (9 << 6) 74fa225cbcSrjs#define TB0C_ARG0_REPLICATE_ALPHA (1<<5) 75fa225cbcSrjs#define TB0C_ARG0_SEL_XXX 76fa225cbcSrjs 77fa225cbcSrjs#define TB0A_CTR_STAGE_ENABLE (1<<31) 78fa225cbcSrjs#define TB0A_RESULT_SCALE_1X (0 << 29) 79fa225cbcSrjs#define TB0A_RESULT_SCALE_2X (1 << 29) 80fa225cbcSrjs#define TB0A_RESULT_SCALE_4X (2 << 29) 81fa225cbcSrjs#define TB0A_OP_MODULE (3 << 25) 82fa225cbcSrjs#define TB0A_OUTPUT_WRITE_CURRENT (0<<24) 83fa225cbcSrjs#define TB0A_OUTPUT_WRITE_ACCUM (1<<24) 84fa225cbcSrjs#define TB0A_CTR_STAGE_SEL_BITS_XXX 85fa225cbcSrjs#define TB0A_ARG3_SEL_XXX 86fa225cbcSrjs#define TB0A_ARG3_INVERT (1<<17) 87fa225cbcSrjs#define TB0A_ARG2_INVERT (1<<16) 88fa225cbcSrjs#define TB0A_ARG2_SEL_ONE (0 << 12) 89fa225cbcSrjs#define TB0A_ARG2_SEL_TEXEL0 (6 << 12) 90fa225cbcSrjs#define TB0A_ARG2_SEL_TEXEL1 (7 << 12) 91fa225cbcSrjs#define TB0A_ARG2_SEL_TEXEL2 (8 << 12) 92fa225cbcSrjs#define TB0A_ARG2_SEL_TEXEL3 (9 << 12) 93fa225cbcSrjs#define TB0A_ARG1_INVERT (1<<10) 94fa225cbcSrjs#define TB0A_ARG1_SEL_ONE (0 << 6) 95fa225cbcSrjs#define TB0A_ARG1_SEL_TEXEL0 (6 << 6) 96fa225cbcSrjs#define TB0A_ARG1_SEL_TEXEL1 (7 << 6) 97fa225cbcSrjs#define TB0A_ARG1_SEL_TEXEL2 (8 << 6) 98fa225cbcSrjs#define TB0A_ARG1_SEL_TEXEL3 (9 << 6) 99fa225cbcSrjs 100fa225cbcSrjsstatic struct blendinfo i830_blend_op[] = { 101fa225cbcSrjs /* Clear */ 102fa225cbcSrjs {0, 0, BLENDFACTOR_ZERO, BLENDFACTOR_ZERO}, 103fa225cbcSrjs /* Src */ 104fa225cbcSrjs {0, 0, BLENDFACTOR_ONE, BLENDFACTOR_ZERO}, 105fa225cbcSrjs /* Dst */ 106fa225cbcSrjs {0, 0, BLENDFACTOR_ZERO, BLENDFACTOR_ONE}, 107fa225cbcSrjs /* Over */ 108fa225cbcSrjs {0, 1, BLENDFACTOR_ONE, BLENDFACTOR_INV_SRC_ALPHA}, 109fa225cbcSrjs /* OverReverse */ 110fa225cbcSrjs {1, 0, BLENDFACTOR_INV_DST_ALPHA, BLENDFACTOR_ONE}, 111fa225cbcSrjs /* In */ 112fa225cbcSrjs {1, 0, BLENDFACTOR_DST_ALPHA, BLENDFACTOR_ZERO}, 113fa225cbcSrjs /* InReverse */ 114fa225cbcSrjs {0, 1, BLENDFACTOR_ZERO, BLENDFACTOR_SRC_ALPHA}, 115fa225cbcSrjs /* Out */ 116fa225cbcSrjs {1, 0, BLENDFACTOR_INV_DST_ALPHA, BLENDFACTOR_ZERO}, 117fa225cbcSrjs /* OutReverse */ 118fa225cbcSrjs {0, 1, BLENDFACTOR_ZERO, BLENDFACTOR_INV_SRC_ALPHA}, 119fa225cbcSrjs /* Atop */ 120fa225cbcSrjs {1, 1, BLENDFACTOR_DST_ALPHA, BLENDFACTOR_INV_SRC_ALPHA}, 121fa225cbcSrjs /* AtopReverse */ 122fa225cbcSrjs {1, 1, BLENDFACTOR_INV_DST_ALPHA, BLENDFACTOR_SRC_ALPHA}, 123fa225cbcSrjs /* Xor */ 124fa225cbcSrjs {1, 1, BLENDFACTOR_INV_DST_ALPHA, BLENDFACTOR_INV_SRC_ALPHA}, 125fa225cbcSrjs /* Add */ 126fa225cbcSrjs {0, 0, BLENDFACTOR_ONE, BLENDFACTOR_ONE}, 127fa225cbcSrjs}; 128fa225cbcSrjs 129fa225cbcSrjs/* The x8* formats could use MT_32BIT_X* on 855+, but since we implement 130fa225cbcSrjs * workarounds for 830/845 anyway, we just rely on those whether the hardware 131fa225cbcSrjs * could handle it for us or not. 132fa225cbcSrjs */ 133fa225cbcSrjsstatic struct formatinfo i830_tex_formats[] = { 134fa225cbcSrjs {PICT_a8r8g8b8, MT_32BIT_ARGB8888 }, 135fa225cbcSrjs {PICT_x8r8g8b8, MT_32BIT_ARGB8888 }, 136fa225cbcSrjs {PICT_a8b8g8r8, MT_32BIT_ABGR8888 }, 137fa225cbcSrjs {PICT_x8b8g8r8, MT_32BIT_ABGR8888 }, 138fa225cbcSrjs {PICT_r5g6b5, MT_16BIT_RGB565 }, 139fa225cbcSrjs {PICT_a1r5g5b5, MT_16BIT_ARGB1555 }, 140fa225cbcSrjs {PICT_x1r5g5b5, MT_16BIT_ARGB1555 }, 141fa225cbcSrjs {PICT_a8, MT_8BIT_A8 }, 142fa225cbcSrjs}; 143fa225cbcSrjs 144fa225cbcSrjsstatic Bool i830_get_dest_format(PicturePtr pDstPicture, uint32_t *dst_format) 145fa225cbcSrjs{ 146fa225cbcSrjs switch (pDstPicture->format) { 147fa225cbcSrjs case PICT_a8r8g8b8: 148fa225cbcSrjs case PICT_x8r8g8b8: 149fa225cbcSrjs *dst_format = COLR_BUF_ARGB8888; 150fa225cbcSrjs break; 151fa225cbcSrjs case PICT_r5g6b5: 152fa225cbcSrjs *dst_format = COLR_BUF_RGB565; 153fa225cbcSrjs break; 154fa225cbcSrjs case PICT_a1r5g5b5: 155fa225cbcSrjs case PICT_x1r5g5b5: 156fa225cbcSrjs *dst_format = COLR_BUF_ARGB1555; 157fa225cbcSrjs break; 158fa225cbcSrjs case PICT_a8: 159fa225cbcSrjs *dst_format = COLR_BUF_8BIT; 160fa225cbcSrjs break; 161fa225cbcSrjs case PICT_a4r4g4b4: 162fa225cbcSrjs case PICT_x4r4g4b4: 163fa225cbcSrjs *dst_format = COLR_BUF_ARGB4444; 164fa225cbcSrjs break; 165fa225cbcSrjs default: 166fa225cbcSrjs { 167fa225cbcSrjs ScrnInfoPtr pScrn; 168fa225cbcSrjs 169fa225cbcSrjs pScrn = xf86Screens[pDstPicture->pDrawable->pScreen->myNum]; 170fa225cbcSrjs I830FALLBACK("Unsupported dest format 0x%x\n", 171fa225cbcSrjs (int)pDstPicture->format); 172fa225cbcSrjs } 173fa225cbcSrjs } 174fa225cbcSrjs *dst_format |= DSTORG_HORT_BIAS (0x8) | DSTORG_VERT_BIAS (0x8); 175fa225cbcSrjs return TRUE; 176fa225cbcSrjs} 177fa225cbcSrjs 178fa225cbcSrjs 179fa225cbcSrjsstatic Bool i830_get_blend_cntl(ScrnInfoPtr pScrn, int op, PicturePtr pMask, 180fa225cbcSrjs uint32_t dst_format, uint32_t *blendctl) 181fa225cbcSrjs{ 182fa225cbcSrjs uint32_t sblend, dblend; 183fa225cbcSrjs 184fa225cbcSrjs sblend = i830_blend_op[op].src_blend; 185fa225cbcSrjs dblend = i830_blend_op[op].dst_blend; 186fa225cbcSrjs 187fa225cbcSrjs /* If there's no dst alpha channel, adjust the blend op so that we'll treat 188fa225cbcSrjs * it as always 1. 189fa225cbcSrjs */ 190fa225cbcSrjs if (PICT_FORMAT_A(dst_format) == 0 && i830_blend_op[op].dst_alpha) { 191fa225cbcSrjs if (sblend == BLENDFACTOR_DST_ALPHA) 192fa225cbcSrjs sblend = BLENDFACTOR_ONE; 193fa225cbcSrjs else if (sblend == BLENDFACTOR_INV_DST_ALPHA) 194fa225cbcSrjs sblend = BLENDFACTOR_ZERO; 195fa225cbcSrjs } 196fa225cbcSrjs 197fa225cbcSrjs /* For blending purposes, COLR_BUF_8BIT values show up in the green 198fa225cbcSrjs * channel. So we can't use the alpha channel. 199fa225cbcSrjs */ 200fa225cbcSrjs if (dst_format == PICT_a8 && ((sblend == BLENDFACTOR_DST_ALPHA || 201fa225cbcSrjs sblend == BLENDFACTOR_INV_DST_ALPHA))) { 202fa225cbcSrjs I830FALLBACK("Can't do dst alpha blending with PICT_a8 dest.\n"); 203fa225cbcSrjs } 204fa225cbcSrjs 205fa225cbcSrjs /* If the source alpha is being used, then we should only be in a case 206fa225cbcSrjs * where the source blend factor is 0, and the source blend value is the 207fa225cbcSrjs * mask channels multiplied by the source picture's alpha. 208fa225cbcSrjs */ 209fa225cbcSrjs if (pMask && pMask->componentAlpha && PICT_FORMAT_RGB(pMask->format) 210fa225cbcSrjs && i830_blend_op[op].src_alpha) { 211fa225cbcSrjs if (dblend == BLENDFACTOR_SRC_ALPHA) { 212fa225cbcSrjs dblend = BLENDFACTOR_SRC_COLR; 213fa225cbcSrjs } else if (dblend == BLENDFACTOR_INV_SRC_ALPHA) { 214fa225cbcSrjs dblend = BLENDFACTOR_INV_SRC_COLR; 215fa225cbcSrjs } 216fa225cbcSrjs } 217fa225cbcSrjs 218fa225cbcSrjs *blendctl = (sblend << S8_SRC_BLEND_FACTOR_SHIFT) | 219fa225cbcSrjs (dblend << S8_DST_BLEND_FACTOR_SHIFT); 220fa225cbcSrjs 221fa225cbcSrjs return TRUE; 222fa225cbcSrjs} 223fa225cbcSrjs 224fa225cbcSrjsstatic Bool i830_check_composite_texture(ScrnInfoPtr pScrn, PicturePtr pPict, int unit) 225fa225cbcSrjs{ 226fa225cbcSrjs if (pPict->repeatType > RepeatReflect) 227fa225cbcSrjs I830FALLBACK("Unsupported picture repeat %d\n", pPict->repeatType); 228fa225cbcSrjs 229fa225cbcSrjs if (pPict->filter != PictFilterNearest && 230fa225cbcSrjs pPict->filter != PictFilterBilinear) 231fa225cbcSrjs { 232fa225cbcSrjs I830FALLBACK("Unsupported filter 0x%x\n", pPict->filter); 233fa225cbcSrjs } 234fa225cbcSrjs 235fa225cbcSrjs if (pPict->pDrawable) 236fa225cbcSrjs { 237fa225cbcSrjs int w, h, i; 238fa225cbcSrjs 239fa225cbcSrjs w = pPict->pDrawable->width; 240fa225cbcSrjs h = pPict->pDrawable->height; 241fa225cbcSrjs if ((w > 2048) || (h > 2048)) 242fa225cbcSrjs I830FALLBACK("Picture w/h too large (%dx%d)\n", w, h); 243fa225cbcSrjs 244fa225cbcSrjs for (i = 0; i < sizeof(i830_tex_formats) / sizeof(i830_tex_formats[0]); 245fa225cbcSrjs i++) 246fa225cbcSrjs { 247fa225cbcSrjs if (i830_tex_formats[i].fmt == pPict->format) 248fa225cbcSrjs break; 249fa225cbcSrjs } 250fa225cbcSrjs if (i == sizeof(i830_tex_formats) / sizeof(i830_tex_formats[0])) 251fa225cbcSrjs I830FALLBACK("Unsupported picture format 0x%x\n", 252fa225cbcSrjs (int)pPict->format); 253fa225cbcSrjs } 254fa225cbcSrjs 255fa225cbcSrjs return TRUE; 256fa225cbcSrjs} 257fa225cbcSrjs 258fa225cbcSrjsstatic uint32_t 259fa225cbcSrjsi8xx_get_card_format(PicturePtr pPict) 260fa225cbcSrjs{ 261fa225cbcSrjs int i; 262fa225cbcSrjs for (i = 0; i < sizeof(i830_tex_formats) / sizeof(i830_tex_formats[0]); 263fa225cbcSrjs i++) 264fa225cbcSrjs { 265fa225cbcSrjs if (i830_tex_formats[i].fmt == pPict->format) 266fa225cbcSrjs return i830_tex_formats[i].card_fmt; 267fa225cbcSrjs } 268fa225cbcSrjs FatalError("Unsupported format type %d\n", pPict->format); 269fa225cbcSrjs} 270fa225cbcSrjs 271fa225cbcSrjsstatic void 272fa225cbcSrjsi830_texture_setup(PicturePtr pPict, PixmapPtr pPix, int unit) 273fa225cbcSrjs{ 274fa225cbcSrjs 275fa225cbcSrjs ScrnInfoPtr pScrn = xf86Screens[pPict->pDrawable->pScreen->myNum]; 276fa225cbcSrjs I830Ptr pI830 = I830PTR(pScrn); 277fa225cbcSrjs uint32_t format, pitch, filter; 278fa225cbcSrjs uint32_t wrap_mode; 279fa225cbcSrjs uint32_t texcoordtype; 280fa225cbcSrjs 281fa225cbcSrjs pitch = intel_get_pixmap_pitch(pPix); 282fa225cbcSrjs pI830->scale_units[unit][0] = pPix->drawable.width; 283fa225cbcSrjs pI830->scale_units[unit][1] = pPix->drawable.height; 284fa225cbcSrjs pI830->transform[unit] = pPict->transform; 285fa225cbcSrjs 286fa225cbcSrjs if (i830_transform_is_affine(pI830->transform[unit])) 287fa225cbcSrjs texcoordtype = TEXCOORDTYPE_CARTESIAN; 288fa225cbcSrjs else 289fa225cbcSrjs texcoordtype = TEXCOORDTYPE_HOMOGENEOUS; 290fa225cbcSrjs 291fa225cbcSrjs format = i8xx_get_card_format(pPict); 292fa225cbcSrjs 293fa225cbcSrjs switch (pPict->repeatType) { 294fa225cbcSrjs case RepeatNone: 295fa225cbcSrjs wrap_mode = TEXCOORDMODE_CLAMP_BORDER; 296fa225cbcSrjs break; 297fa225cbcSrjs case RepeatNormal: 298fa225cbcSrjs wrap_mode = TEXCOORDMODE_WRAP; 299fa225cbcSrjs break; 300fa225cbcSrjs case RepeatPad: 301fa225cbcSrjs wrap_mode = TEXCOORDMODE_CLAMP; 302fa225cbcSrjs break; 303fa225cbcSrjs case RepeatReflect: 304fa225cbcSrjs wrap_mode = TEXCOORDMODE_MIRROR; 305fa225cbcSrjs break; 306fa225cbcSrjs default: 307fa225cbcSrjs FatalError("Unknown repeat type %d\n", pPict->repeatType); 308fa225cbcSrjs } 309fa225cbcSrjs 310fa225cbcSrjs switch (pPict->filter) { 311fa225cbcSrjs case PictFilterNearest: 312fa225cbcSrjs filter = ((FILTER_NEAREST<<TM0S3_MAG_FILTER_SHIFT) | 313fa225cbcSrjs (FILTER_NEAREST<<TM0S3_MIN_FILTER_SHIFT)); 314fa225cbcSrjs break; 315fa225cbcSrjs case PictFilterBilinear: 316fa225cbcSrjs filter = ((FILTER_LINEAR<<TM0S3_MAG_FILTER_SHIFT) | 317fa225cbcSrjs (FILTER_LINEAR<<TM0S3_MIN_FILTER_SHIFT)); 318fa225cbcSrjs break; 319fa225cbcSrjs default: 320fa225cbcSrjs filter = 0; 321fa225cbcSrjs FatalError("Bad filter 0x%x\n", pPict->filter); 322fa225cbcSrjs } 323fa225cbcSrjs filter |= (MIPFILTER_NONE << TM0S3_MIP_FILTER_SHIFT); 324fa225cbcSrjs 325fa225cbcSrjs { 326fa225cbcSrjs if (pPix->drawable.bitsPerPixel == 8) 327fa225cbcSrjs format |= MAPSURF_8BIT; 328fa225cbcSrjs else if (pPix->drawable.bitsPerPixel == 16) 329fa225cbcSrjs format |= MAPSURF_16BIT; 330fa225cbcSrjs else 331fa225cbcSrjs format |= MAPSURF_32BIT; 332fa225cbcSrjs 333fa225cbcSrjs BEGIN_BATCH(10); 334fa225cbcSrjs OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_2 | LOAD_TEXTURE_MAP(unit) | 4); 335fa225cbcSrjs OUT_RELOC_PIXMAP(pPix, I915_GEM_DOMAIN_SAMPLER, 0, TM0S0_USE_FENCE); 336fa225cbcSrjs OUT_BATCH(((pPix->drawable.height - 1) << TM0S1_HEIGHT_SHIFT) | 337fa225cbcSrjs ((pPix->drawable.width - 1) << TM0S1_WIDTH_SHIFT) | format); 338fa225cbcSrjs OUT_BATCH((pitch/4 - 1) << TM0S2_PITCH_SHIFT | TM0S2_MAP_2D); 339fa225cbcSrjs OUT_BATCH(filter); 340fa225cbcSrjs OUT_BATCH(0); /* default color */ 341fa225cbcSrjs OUT_BATCH(_3DSTATE_MAP_COORD_SET_CMD | TEXCOORD_SET(unit) | 342fa225cbcSrjs ENABLE_TEXCOORD_PARAMS | TEXCOORDS_ARE_NORMAL | 343fa225cbcSrjs texcoordtype | ENABLE_ADDR_V_CNTL | 344fa225cbcSrjs TEXCOORD_ADDR_V_MODE(wrap_mode) | 345fa225cbcSrjs ENABLE_ADDR_U_CNTL | TEXCOORD_ADDR_U_MODE(wrap_mode)); 346fa225cbcSrjs /* map texel stream */ 347fa225cbcSrjs OUT_BATCH(_3DSTATE_MAP_COORD_SETBIND_CMD); 348fa225cbcSrjs if (unit == 0) 349fa225cbcSrjs OUT_BATCH(TEXBIND_SET0(TEXCOORDSRC_VTXSET_0) | 350fa225cbcSrjs TEXBIND_SET1(TEXCOORDSRC_KEEP) | 351fa225cbcSrjs TEXBIND_SET2(TEXCOORDSRC_KEEP) | 352fa225cbcSrjs TEXBIND_SET3(TEXCOORDSRC_KEEP)); 353fa225cbcSrjs else 354fa225cbcSrjs OUT_BATCH(TEXBIND_SET0(TEXCOORDSRC_VTXSET_0) | 355fa225cbcSrjs TEXBIND_SET1(TEXCOORDSRC_VTXSET_1) | 356fa225cbcSrjs TEXBIND_SET2(TEXCOORDSRC_KEEP) | 357fa225cbcSrjs TEXBIND_SET3(TEXCOORDSRC_KEEP)); 358fa225cbcSrjs OUT_BATCH(_3DSTATE_MAP_TEX_STREAM_CMD | (unit << 16) | 359fa225cbcSrjs DISABLE_TEX_STREAM_BUMP | 360fa225cbcSrjs ENABLE_TEX_STREAM_COORD_SET | 361fa225cbcSrjs TEX_STREAM_COORD_SET(unit) | 362fa225cbcSrjs ENABLE_TEX_STREAM_MAP_IDX | 363fa225cbcSrjs TEX_STREAM_MAP_IDX(unit)); 364fa225cbcSrjs ADVANCE_BATCH(); 365fa225cbcSrjs } 366fa225cbcSrjs} 367fa225cbcSrjs 368fa225cbcSrjsBool 369fa225cbcSrjsi830_check_composite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, 370fa225cbcSrjs PicturePtr pDstPicture) 371fa225cbcSrjs{ 372fa225cbcSrjs ScrnInfoPtr pScrn = xf86Screens[pDstPicture->pDrawable->pScreen->myNum]; 373fa225cbcSrjs uint32_t tmp1; 374fa225cbcSrjs 375fa225cbcSrjs /* Check for unsupported compositing operations. */ 376fa225cbcSrjs if (op >= sizeof(i830_blend_op) / sizeof(i830_blend_op[0])) 377fa225cbcSrjs I830FALLBACK("Unsupported Composite op 0x%x\n", op); 378fa225cbcSrjs 379fa225cbcSrjs if (pMaskPicture != NULL && pMaskPicture->componentAlpha && 380fa225cbcSrjs PICT_FORMAT_RGB(pMaskPicture->format)) { 381fa225cbcSrjs /* Check if it's component alpha that relies on a source alpha and on 382fa225cbcSrjs * the source value. We can only get one of those into the single 383fa225cbcSrjs * source value that we get to blend with. 384fa225cbcSrjs */ 385fa225cbcSrjs if (i830_blend_op[op].src_alpha && 386fa225cbcSrjs (i830_blend_op[op].src_blend != BLENDFACTOR_ZERO)) 387fa225cbcSrjs I830FALLBACK("Component alpha not supported with source " 388fa225cbcSrjs "alpha and source value blending.\n"); 389fa225cbcSrjs } 390fa225cbcSrjs 391fa225cbcSrjs if (!i830_check_composite_texture(pScrn, pSrcPicture, 0)) 392fa225cbcSrjs I830FALLBACK("Check Src picture texture\n"); 393fa225cbcSrjs if (pMaskPicture != NULL && !i830_check_composite_texture(pScrn, pMaskPicture, 1)) 394fa225cbcSrjs I830FALLBACK("Check Mask picture texture\n"); 395fa225cbcSrjs 396fa225cbcSrjs if (!i830_get_dest_format(pDstPicture, &tmp1)) 397fa225cbcSrjs I830FALLBACK("Get Color buffer format\n"); 398fa225cbcSrjs 399fa225cbcSrjs return TRUE; 400fa225cbcSrjs} 401fa225cbcSrjs 402fa225cbcSrjsBool 403fa225cbcSrjsi830_prepare_composite(int op, PicturePtr pSrcPicture, 404fa225cbcSrjs PicturePtr pMaskPicture, PicturePtr pDstPicture, 405fa225cbcSrjs PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst) 406fa225cbcSrjs{ 407fa225cbcSrjs ScrnInfoPtr pScrn = xf86Screens[pDstPicture->pDrawable->pScreen->myNum]; 408fa225cbcSrjs I830Ptr pI830 = I830PTR(pScrn); 409fa225cbcSrjs 410fa225cbcSrjs pI830->render_src_picture = pSrcPicture; 411fa225cbcSrjs pI830->render_src = pSrc; 412fa225cbcSrjs pI830->render_mask_picture = pMaskPicture; 413fa225cbcSrjs pI830->render_mask = pMask; 414fa225cbcSrjs pI830->render_dst_picture = pDstPicture; 415fa225cbcSrjs pI830->render_dst = pDst; 416fa225cbcSrjs 417fa225cbcSrjs i830_exa_check_pitch_3d(pSrc); 418fa225cbcSrjs if (pMask) 419fa225cbcSrjs i830_exa_check_pitch_3d(pMask); 420fa225cbcSrjs i830_exa_check_pitch_3d(pDst); 421fa225cbcSrjs 422fa225cbcSrjs if (!i830_get_dest_format(pDstPicture, &pI830->render_dst_format)) 423fa225cbcSrjs return FALSE; 424fa225cbcSrjs 425fa225cbcSrjs pI830->dst_coord_adjust = 0; 426fa225cbcSrjs pI830->src_coord_adjust = 0; 427fa225cbcSrjs pI830->mask_coord_adjust = 0; 428fa225cbcSrjs if (pSrcPicture->filter == PictFilterNearest) 429fa225cbcSrjs pI830->src_coord_adjust = 0.375; 430fa225cbcSrjs if (pMask != NULL) { 431fa225cbcSrjs pI830->mask_coord_adjust = 0; 432fa225cbcSrjs if (pMaskPicture->filter == PictFilterNearest) 433fa225cbcSrjs pI830->mask_coord_adjust = 0.375; 434fa225cbcSrjs } else { 435fa225cbcSrjs pI830->transform[1] = NULL; 436fa225cbcSrjs pI830->scale_units[1][0] = -1; 437fa225cbcSrjs pI830->scale_units[1][1] = -1; 438fa225cbcSrjs } 439fa225cbcSrjs 440fa225cbcSrjs { 441fa225cbcSrjs uint32_t cblend, ablend, blendctl; 442fa225cbcSrjs 443fa225cbcSrjs /* If component alpha is active in the mask and the blend operation 444fa225cbcSrjs * uses the source alpha, then we know we don't need the source 445fa225cbcSrjs * value (otherwise we would have hit a fallback earlier), so we 446fa225cbcSrjs * provide the source alpha (src.A * mask.X) as output color. 447fa225cbcSrjs * Conversely, if CA is set and we don't need the source alpha, then 448fa225cbcSrjs * we produce the source value (src.X * mask.X) and the source alpha 449fa225cbcSrjs * is unused.. Otherwise, we provide the non-CA source value 450fa225cbcSrjs * (src.X * mask.A). 451fa225cbcSrjs * 452fa225cbcSrjs * The PICT_FORMAT_RGB(pict) == 0 fixups are not needed on 855+'s a8 453fa225cbcSrjs * pictures, but we need to implement it for 830/845 and there's no 454fa225cbcSrjs * harm done in leaving it in. 455fa225cbcSrjs */ 456fa225cbcSrjs cblend = TB0C_LAST_STAGE | TB0C_RESULT_SCALE_1X | TB0C_OP_MODULE | 457fa225cbcSrjs TB0C_OUTPUT_WRITE_CURRENT; 458fa225cbcSrjs ablend = TB0A_RESULT_SCALE_1X | TB0A_OP_MODULE | 459fa225cbcSrjs TB0A_OUTPUT_WRITE_CURRENT; 460fa225cbcSrjs 461fa225cbcSrjs /* Get the source picture's channels into TBx_ARG1 */ 462fa225cbcSrjs if ((pMaskPicture != NULL && 463fa225cbcSrjs pMaskPicture->componentAlpha && 464fa225cbcSrjs PICT_FORMAT_RGB(pMaskPicture->format) && 465fa225cbcSrjs i830_blend_op[op].src_alpha) || pDstPicture->format == PICT_a8) 466fa225cbcSrjs { 467fa225cbcSrjs /* Producing source alpha value, so the first set of channels 468fa225cbcSrjs * is src.A instead of src.X. We also do this if the destination 469fa225cbcSrjs * is a8, in which case src.G is what's written, and the other 470fa225cbcSrjs * channels are ignored. 471fa225cbcSrjs */ 472fa225cbcSrjs if (PICT_FORMAT_A(pSrcPicture->format) != 0) { 473fa225cbcSrjs ablend |= TB0A_ARG1_SEL_TEXEL0; 474fa225cbcSrjs cblend |= TB0C_ARG1_SEL_TEXEL0 | TB0C_ARG1_REPLICATE_ALPHA; 475fa225cbcSrjs } else { 476fa225cbcSrjs ablend |= TB0A_ARG1_SEL_ONE; 477fa225cbcSrjs cblend |= TB0C_ARG1_SEL_ONE; 478fa225cbcSrjs } 479fa225cbcSrjs } else { 480fa225cbcSrjs if (PICT_FORMAT_A(pSrcPicture->format) != 0) { 481fa225cbcSrjs ablend |= TB0A_ARG1_SEL_TEXEL0; 482fa225cbcSrjs } else { 483fa225cbcSrjs ablend |= TB0A_ARG1_SEL_ONE; 484fa225cbcSrjs } 485fa225cbcSrjs if (PICT_FORMAT_RGB(pSrcPicture->format) != 0) 486fa225cbcSrjs cblend |= TB0C_ARG1_SEL_TEXEL0; 487fa225cbcSrjs else 488fa225cbcSrjs cblend |= TB0C_ARG1_SEL_ONE | TB0C_ARG1_INVERT; /* 0.0 */ 489fa225cbcSrjs } 490fa225cbcSrjs 491fa225cbcSrjs if (pMask) { 492fa225cbcSrjs if (pDstPicture->format != PICT_a8 && 493fa225cbcSrjs (pMaskPicture->componentAlpha && 494fa225cbcSrjs PICT_FORMAT_RGB(pMaskPicture->format))) 495fa225cbcSrjs { 496fa225cbcSrjs cblend |= TB0C_ARG2_SEL_TEXEL1; 497fa225cbcSrjs } else { 498fa225cbcSrjs if (PICT_FORMAT_A(pMaskPicture->format) != 0) 499fa225cbcSrjs cblend |= TB0C_ARG2_SEL_TEXEL1 | 500fa225cbcSrjs TB0C_ARG2_REPLICATE_ALPHA; 501fa225cbcSrjs else 502fa225cbcSrjs cblend |= TB0C_ARG2_SEL_ONE; 503fa225cbcSrjs } 504fa225cbcSrjs if (PICT_FORMAT_A(pMaskPicture->format) != 0) 505fa225cbcSrjs ablend |= TB0A_ARG2_SEL_TEXEL1; 506fa225cbcSrjs else 507fa225cbcSrjs ablend |= TB0A_ARG2_SEL_ONE; 508fa225cbcSrjs } else { 509fa225cbcSrjs cblend |= TB0C_ARG2_SEL_ONE; 510fa225cbcSrjs ablend |= TB0A_ARG2_SEL_ONE; 511fa225cbcSrjs } 512fa225cbcSrjs 513fa225cbcSrjs if (!i830_get_blend_cntl(pScrn, op, pMaskPicture, pDstPicture->format, 514fa225cbcSrjs &blendctl)) { 515fa225cbcSrjs return FALSE; 516fa225cbcSrjs } 517fa225cbcSrjs 518fa225cbcSrjs pI830->cblend = cblend; 519fa225cbcSrjs pI830->ablend = ablend; 520fa225cbcSrjs pI830->s8_blendctl = blendctl; 521fa225cbcSrjs } 522fa225cbcSrjs 523fa225cbcSrjs i830_debug_sync(pScrn); 524fa225cbcSrjs 525fa225cbcSrjs pI830->needs_render_state_emit = TRUE; 526fa225cbcSrjs 527fa225cbcSrjs return TRUE; 528fa225cbcSrjs} 529fa225cbcSrjs 530fa225cbcSrjsstatic void 531fa225cbcSrjsi830_emit_composite_state(ScrnInfoPtr pScrn) 532fa225cbcSrjs{ 533fa225cbcSrjs I830Ptr pI830 = I830PTR(pScrn); 534fa225cbcSrjs uint32_t vf2; 535fa225cbcSrjs uint32_t texcoordfmt = 0; 536fa225cbcSrjs 537fa225cbcSrjs pI830->needs_render_state_emit = FALSE; 538fa225cbcSrjs 539fa225cbcSrjs IntelEmitInvarientState(pScrn); 540fa225cbcSrjs pI830->last_3d = LAST_3D_RENDER; 541fa225cbcSrjs 542fa225cbcSrjs BEGIN_BATCH(21); 543fa225cbcSrjs 544fa225cbcSrjs OUT_BATCH(_3DSTATE_BUF_INFO_CMD); 545fa225cbcSrjs OUT_BATCH(BUF_3D_ID_COLOR_BACK| BUF_3D_USE_FENCE | 546fa225cbcSrjs BUF_3D_PITCH(intel_get_pixmap_pitch(pI830->render_dst))); 547fa225cbcSrjs OUT_RELOC_PIXMAP(pI830->render_dst, 548fa225cbcSrjs I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); 549fa225cbcSrjs 550fa225cbcSrjs OUT_BATCH(_3DSTATE_DST_BUF_VARS_CMD); 551fa225cbcSrjs OUT_BATCH(pI830->render_dst_format); 552fa225cbcSrjs 553fa225cbcSrjs OUT_BATCH(_3DSTATE_DRAW_RECT_CMD); 554fa225cbcSrjs OUT_BATCH(0); 555fa225cbcSrjs OUT_BATCH(0); /* ymin, xmin */ 556fa225cbcSrjs OUT_BATCH(DRAW_YMAX(pI830->render_dst->drawable.height - 1) | 557fa225cbcSrjs DRAW_XMAX(pI830->render_dst->drawable.width - 1)); 558fa225cbcSrjs OUT_BATCH(0); /* yorig, xorig */ 559fa225cbcSrjs 560fa225cbcSrjs OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | 561fa225cbcSrjs I1_LOAD_S(2) | 562fa225cbcSrjs I1_LOAD_S(3) | 563fa225cbcSrjs I1_LOAD_S(8) | 564fa225cbcSrjs 2); 565fa225cbcSrjs if (pI830->render_mask) 566fa225cbcSrjs vf2 = 2 << 12; /* 2 texture coord sets */ 567fa225cbcSrjs else 568fa225cbcSrjs vf2 = 1 << 12; 569fa225cbcSrjs OUT_BATCH(vf2); /* number of coordinate sets */ 570fa225cbcSrjs OUT_BATCH(S3_CULLMODE_NONE | S3_VERTEXHAS_XY); 571fa225cbcSrjs OUT_BATCH(S8_ENABLE_COLOR_BLEND | S8_BLENDFUNC_ADD | pI830->s8_blendctl | 572fa225cbcSrjs S8_ENABLE_COLOR_BUFFER_WRITE); 573fa225cbcSrjs 574fa225cbcSrjs OUT_BATCH(_3DSTATE_INDPT_ALPHA_BLEND_CMD | DISABLE_INDPT_ALPHA_BLEND); 575fa225cbcSrjs 576fa225cbcSrjs OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_2 | 577fa225cbcSrjs LOAD_TEXTURE_BLEND_STAGE(0)|1); 578fa225cbcSrjs OUT_BATCH(pI830->cblend); 579fa225cbcSrjs OUT_BATCH(pI830->ablend); 580fa225cbcSrjs 581fa225cbcSrjs OUT_BATCH(_3DSTATE_ENABLES_1_CMD | DISABLE_LOGIC_OP | 582fa225cbcSrjs DISABLE_STENCIL_TEST | DISABLE_DEPTH_BIAS | 583fa225cbcSrjs DISABLE_SPEC_ADD | DISABLE_FOG | DISABLE_ALPHA_TEST | 584fa225cbcSrjs ENABLE_COLOR_BLEND | DISABLE_DEPTH_TEST); 585fa225cbcSrjs /* We have to explicitly say we don't want write disabled */ 586fa225cbcSrjs OUT_BATCH(_3DSTATE_ENABLES_2_CMD | ENABLE_COLOR_MASK | 587fa225cbcSrjs DISABLE_STENCIL_WRITE | ENABLE_TEX_CACHE | 588fa225cbcSrjs DISABLE_DITHER | ENABLE_COLOR_WRITE | 589fa225cbcSrjs DISABLE_DEPTH_WRITE); 590fa225cbcSrjs 591fa225cbcSrjs if (i830_transform_is_affine(pI830->render_src_picture->transform)) 592fa225cbcSrjs texcoordfmt |= (TEXCOORDFMT_2D << 0); 593fa225cbcSrjs else 594fa225cbcSrjs texcoordfmt |= (TEXCOORDFMT_3D << 0); 595fa225cbcSrjs if (pI830->render_mask) { 596fa225cbcSrjs if (i830_transform_is_affine(pI830->render_mask_picture->transform)) 597fa225cbcSrjs texcoordfmt |= (TEXCOORDFMT_2D << 2); 598fa225cbcSrjs else 599fa225cbcSrjs texcoordfmt |= (TEXCOORDFMT_3D << 2); 600fa225cbcSrjs } 601fa225cbcSrjs OUT_BATCH(_3DSTATE_VERTEX_FORMAT_2_CMD | texcoordfmt); 602fa225cbcSrjs 603fa225cbcSrjs ADVANCE_BATCH(); 604fa225cbcSrjs 605fa225cbcSrjs i830_texture_setup(pI830->render_src_picture, pI830->render_src, 0); 606fa225cbcSrjs if (pI830->render_mask) { 607fa225cbcSrjs i830_texture_setup(pI830->render_mask_picture, 608fa225cbcSrjs pI830->render_mask, 1); 609fa225cbcSrjs } 610fa225cbcSrjs} 611fa225cbcSrjs 612fa225cbcSrjs/* Emit the vertices for a single composite rectangle. 613fa225cbcSrjs * 614fa225cbcSrjs * This function is no longer shared between i830 and i915 generation code. 615fa225cbcSrjs */ 616fa225cbcSrjsstatic void 617fa225cbcSrjsi830_emit_composite_primitive(PixmapPtr pDst, 618fa225cbcSrjs int srcX, int srcY, 619fa225cbcSrjs int maskX, int maskY, 620fa225cbcSrjs int dstX, int dstY, 621fa225cbcSrjs int w, int h) 622fa225cbcSrjs{ 623fa225cbcSrjs ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; 624fa225cbcSrjs I830Ptr pI830 = I830PTR(pScrn); 625fa225cbcSrjs Bool is_affine_src, is_affine_mask = TRUE; 626fa225cbcSrjs int per_vertex, num_floats; 627fa225cbcSrjs float src_x[3], src_y[3], src_w[3], mask_x[3], mask_y[3], mask_w[3]; 628fa225cbcSrjs 629fa225cbcSrjs per_vertex = 2; /* dest x/y */ 630fa225cbcSrjs 631fa225cbcSrjs { 632fa225cbcSrjs float x = srcX + pI830->src_coord_adjust; 633fa225cbcSrjs float y = srcY + pI830->src_coord_adjust; 634fa225cbcSrjs 635fa225cbcSrjs is_affine_src = i830_transform_is_affine (pI830->transform[0]); 636fa225cbcSrjs if (is_affine_src) { 637fa225cbcSrjs if (!i830_get_transformed_coordinates(x, y, 638fa225cbcSrjs pI830->transform[0], 639fa225cbcSrjs &src_x[0], &src_y[0])) 640fa225cbcSrjs return; 641fa225cbcSrjs 642fa225cbcSrjs if (!i830_get_transformed_coordinates(x, y + h, 643fa225cbcSrjs pI830->transform[0], 644fa225cbcSrjs &src_x[1], &src_y[1])) 645fa225cbcSrjs return; 646fa225cbcSrjs 647fa225cbcSrjs if (!i830_get_transformed_coordinates(x + w, y + h, 648fa225cbcSrjs pI830->transform[0], 649fa225cbcSrjs &src_x[2], &src_y[2])) 650fa225cbcSrjs return; 651fa225cbcSrjs 652fa225cbcSrjs per_vertex += 2; /* src x/y */ 653fa225cbcSrjs } else { 654fa225cbcSrjs if (!i830_get_transformed_coordinates_3d(x, y, 655fa225cbcSrjs pI830->transform[0], 656fa225cbcSrjs &src_x[0], 657fa225cbcSrjs &src_y[0], 658fa225cbcSrjs &src_w[0])) 659fa225cbcSrjs return; 660fa225cbcSrjs 661fa225cbcSrjs if (!i830_get_transformed_coordinates_3d(x, y + h, 662fa225cbcSrjs pI830->transform[0], 663fa225cbcSrjs &src_x[1], 664fa225cbcSrjs &src_y[1], 665fa225cbcSrjs &src_w[1])) 666fa225cbcSrjs return; 667fa225cbcSrjs 668fa225cbcSrjs if (!i830_get_transformed_coordinates_3d(x + w, y + h, 669fa225cbcSrjs pI830->transform[0], 670fa225cbcSrjs &src_x[2], 671fa225cbcSrjs &src_y[2], 672fa225cbcSrjs &src_w[2])) 673fa225cbcSrjs return; 674fa225cbcSrjs 675fa225cbcSrjs per_vertex += 3; /* src x/y/w */ 676fa225cbcSrjs } 677fa225cbcSrjs } 678fa225cbcSrjs 679fa225cbcSrjs if (pI830->render_mask) { 680fa225cbcSrjs float x = maskX + pI830->mask_coord_adjust; 681fa225cbcSrjs float y = maskY + pI830->mask_coord_adjust; 682fa225cbcSrjs 683fa225cbcSrjs is_affine_mask = i830_transform_is_affine (pI830->transform[1]); 684fa225cbcSrjs if (is_affine_mask) { 685fa225cbcSrjs if (!i830_get_transformed_coordinates(x, y, 686fa225cbcSrjs pI830->transform[1], 687fa225cbcSrjs &mask_x[0], &mask_y[0])) 688fa225cbcSrjs return; 689fa225cbcSrjs 690fa225cbcSrjs if (!i830_get_transformed_coordinates(x, y + h, 691fa225cbcSrjs pI830->transform[1], 692fa225cbcSrjs &mask_x[1], &mask_y[1])) 693fa225cbcSrjs return; 694fa225cbcSrjs 695fa225cbcSrjs if (!i830_get_transformed_coordinates(x + w, y + h, 696fa225cbcSrjs pI830->transform[1], 697fa225cbcSrjs &mask_x[2], &mask_y[2])) 698fa225cbcSrjs return; 699fa225cbcSrjs 700fa225cbcSrjs per_vertex += 2; /* mask x/y */ 701fa225cbcSrjs } else { 702fa225cbcSrjs if (!i830_get_transformed_coordinates_3d(x, y, 703fa225cbcSrjs pI830->transform[1], 704fa225cbcSrjs &mask_x[0], 705fa225cbcSrjs &mask_y[0], 706fa225cbcSrjs &mask_w[0])) 707fa225cbcSrjs return; 708fa225cbcSrjs 709fa225cbcSrjs if (!i830_get_transformed_coordinates_3d(x, y + h, 710fa225cbcSrjs pI830->transform[1], 711fa225cbcSrjs &mask_x[1], 712fa225cbcSrjs &mask_y[1], 713fa225cbcSrjs &mask_w[1])) 714fa225cbcSrjs return; 715fa225cbcSrjs 716fa225cbcSrjs if (!i830_get_transformed_coordinates_3d(x + w, y + h, 717fa225cbcSrjs pI830->transform[1], 718fa225cbcSrjs &mask_x[2], 719fa225cbcSrjs &mask_y[2], 720fa225cbcSrjs &mask_w[2])) 721fa225cbcSrjs return; 722fa225cbcSrjs 723fa225cbcSrjs per_vertex += 3; /* mask x/y/w */ 724fa225cbcSrjs } 725fa225cbcSrjs } 726fa225cbcSrjs 727fa225cbcSrjs num_floats = 3 * per_vertex; 728fa225cbcSrjs 729fa225cbcSrjs BEGIN_BATCH(1 + num_floats); 730fa225cbcSrjs 731fa225cbcSrjs OUT_BATCH(PRIM3D_INLINE | PRIM3D_RECTLIST | (num_floats-1)); 732fa225cbcSrjs OUT_BATCH_F(pI830->dst_coord_adjust + dstX + w); 733fa225cbcSrjs OUT_BATCH_F(pI830->dst_coord_adjust + dstY + h); 734fa225cbcSrjs OUT_BATCH_F(src_x[2] / pI830->scale_units[0][0]); 735fa225cbcSrjs OUT_BATCH_F(src_y[2] / pI830->scale_units[0][1]); 736fa225cbcSrjs if (!is_affine_src) { 737fa225cbcSrjs OUT_BATCH_F(src_w[2]); 738fa225cbcSrjs } 739fa225cbcSrjs if (pI830->render_mask) { 740fa225cbcSrjs OUT_BATCH_F(mask_x[2] / pI830->scale_units[1][0]); 741fa225cbcSrjs OUT_BATCH_F(mask_y[2] / pI830->scale_units[1][1]); 742fa225cbcSrjs if (!is_affine_mask) { 743fa225cbcSrjs OUT_BATCH_F(mask_w[2]); 744fa225cbcSrjs } 745fa225cbcSrjs } 746fa225cbcSrjs 747fa225cbcSrjs OUT_BATCH_F(pI830->dst_coord_adjust + dstX); 748fa225cbcSrjs OUT_BATCH_F(pI830->dst_coord_adjust + dstY + h); 749fa225cbcSrjs OUT_BATCH_F(src_x[1] / pI830->scale_units[0][0]); 750fa225cbcSrjs OUT_BATCH_F(src_y[1] / pI830->scale_units[0][1]); 751fa225cbcSrjs if (!is_affine_src) { 752fa225cbcSrjs OUT_BATCH_F(src_w[1]); 753fa225cbcSrjs } 754fa225cbcSrjs if (pI830->render_mask) { 755fa225cbcSrjs OUT_BATCH_F(mask_x[1] / pI830->scale_units[1][0]); 756fa225cbcSrjs OUT_BATCH_F(mask_y[1] / pI830->scale_units[1][1]); 757fa225cbcSrjs if (!is_affine_mask) { 758fa225cbcSrjs OUT_BATCH_F(mask_w[1]); 759fa225cbcSrjs } 760fa225cbcSrjs } 761fa225cbcSrjs 762fa225cbcSrjs OUT_BATCH_F(pI830->dst_coord_adjust + dstX); 763fa225cbcSrjs OUT_BATCH_F(pI830->dst_coord_adjust + dstY); 764fa225cbcSrjs OUT_BATCH_F(src_x[0] / pI830->scale_units[0][0]); 765fa225cbcSrjs OUT_BATCH_F(src_y[0] / pI830->scale_units[0][1]); 766fa225cbcSrjs if (!is_affine_src) { 767fa225cbcSrjs OUT_BATCH_F(src_w[0]); 768fa225cbcSrjs } 769fa225cbcSrjs if (pI830->render_mask) { 770fa225cbcSrjs OUT_BATCH_F(mask_x[0] / pI830->scale_units[1][0]); 771fa225cbcSrjs OUT_BATCH_F(mask_y[0] / pI830->scale_units[1][1]); 772fa225cbcSrjs if (!is_affine_mask) { 773fa225cbcSrjs OUT_BATCH_F(mask_w[0]); 774fa225cbcSrjs } 775fa225cbcSrjs } 776fa225cbcSrjs 777fa225cbcSrjs ADVANCE_BATCH(); 778fa225cbcSrjs} 779fa225cbcSrjs 780fa225cbcSrjs 781fa225cbcSrjs/** 782fa225cbcSrjs * Do a single rectangle composite operation. 783fa225cbcSrjs */ 784fa225cbcSrjsvoid 785fa225cbcSrjsi830_composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, 786fa225cbcSrjs int dstX, int dstY, int w, int h) 787fa225cbcSrjs{ 788fa225cbcSrjs ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; 789fa225cbcSrjs I830Ptr pI830 = I830PTR(pScrn); 790fa225cbcSrjs 791fa225cbcSrjs intel_batch_start_atomic(pScrn, 792fa225cbcSrjs 58 + /* invarient */ 793fa225cbcSrjs 22 + /* setup */ 794fa225cbcSrjs 20 + /* 2 * setup_texture */ 795fa225cbcSrjs 1 + 30 /* verts */); 796fa225cbcSrjs 797fa225cbcSrjs if (pI830->needs_render_state_emit) 798fa225cbcSrjs i830_emit_composite_state(pScrn); 799fa225cbcSrjs 800fa225cbcSrjs i830_emit_composite_primitive(pDst, srcX, srcY, maskX, maskY, dstX, dstY, 801fa225cbcSrjs w, h); 802fa225cbcSrjs 803fa225cbcSrjs intel_batch_end_atomic(pScrn); 804fa225cbcSrjs 805fa225cbcSrjs i830_debug_sync(pScrn); 806fa225cbcSrjs} 807fa225cbcSrjs 808fa225cbcSrjsvoid 809fa225cbcSrjsi830_batch_flush_notify(ScrnInfoPtr scrn) 810fa225cbcSrjs{ 811fa225cbcSrjs I830Ptr i830 = I830PTR(scrn); 812fa225cbcSrjs 813fa225cbcSrjs i830->needs_render_state_emit = TRUE; 814fa225cbcSrjs} 815