vmwgfx_tex_video.c revision 3bfa90b6
13bfa90b6Smrg/* 23bfa90b6Smrg * Copyright 2009-2011 VMWare, Inc. 33bfa90b6Smrg * All Rights Reserved. 43bfa90b6Smrg * 53bfa90b6Smrg * Permission is hereby granted, free of charge, to any person obtaining a 63bfa90b6Smrg * copy of this software and associated documentation files (the 73bfa90b6Smrg * "Software"), to deal in the Software without restriction, including 83bfa90b6Smrg * without limitation the rights to use, copy, modify, merge, publish, 93bfa90b6Smrg * distribute, sub license, and/or sell copies of the Software, and to 103bfa90b6Smrg * permit persons to whom the Software is furnished to do so, subject to 113bfa90b6Smrg * the following conditions: 123bfa90b6Smrg * 133bfa90b6Smrg * The above copyright notice and this permission notice (including the 143bfa90b6Smrg * next paragraph) shall be included in all copies or substantial portions 153bfa90b6Smrg * of the Software. 163bfa90b6Smrg * 173bfa90b6Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 183bfa90b6Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 193bfa90b6Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 203bfa90b6Smrg * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 213bfa90b6Smrg * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 223bfa90b6Smrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 233bfa90b6Smrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 243bfa90b6Smrg * 253bfa90b6Smrg * Author: Thomas Hellstrom <thellstrom@vmware.com> 263bfa90b6Smrg * Author: Zack Rusin <zackr@vmware.com> 273bfa90b6Smrg */ 283bfa90b6Smrg 293bfa90b6Smrg#include "vmwgfx_driver.h" 303bfa90b6Smrg#include "vmwgfx_drmi.h" 313bfa90b6Smrg#include "vmwgfx_saa.h" 323bfa90b6Smrg 333bfa90b6Smrg#include <xf86xv.h> 343bfa90b6Smrg#include <X11/extensions/Xv.h> 353bfa90b6Smrg#include <fourcc.h> 363bfa90b6Smrg#include <xa_tracker.h> 373bfa90b6Smrg#include <xa_context.h> 383bfa90b6Smrg#include <math.h> 393bfa90b6Smrg 403bfa90b6Smrg/*XXX get these from pipe's texture limits */ 413bfa90b6Smrg#define IMAGE_MAX_WIDTH 2048 423bfa90b6Smrg#define IMAGE_MAX_HEIGHT 2048 433bfa90b6Smrg 443bfa90b6Smrg#define RES_720P_X 1280 453bfa90b6Smrg#define RES_720P_Y 720 463bfa90b6Smrg 473bfa90b6Smrg 483bfa90b6Smrg#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) 493bfa90b6Smrg 503bfa90b6Smrg/* 513bfa90b6Smrg * ITU-R BT.601, BT.709 transfer matrices. 523bfa90b6Smrg * [R', G', B'] values are in the range [0, 1], Y' is in the range [0,1] 533bfa90b6Smrg * and [Pb, Pr] components are in the range [-0.5, 0.5]. 543bfa90b6Smrg * 553bfa90b6Smrg * The matrices are transposed to fit the xa conversion matrix format. 563bfa90b6Smrg */ 573bfa90b6Smrg 583bfa90b6Smrgstatic const float bt_601[] = { 593bfa90b6Smrg 1.f, 1.f, 1.f, 0.f, 603bfa90b6Smrg 0.f, -0.344136f, 1.772f, 0.f, 613bfa90b6Smrg 1.402f, -0.714136f, 0.f, 0.f 623bfa90b6Smrg}; 633bfa90b6Smrg 643bfa90b6Smrgstatic const float bt_709[] = { 653bfa90b6Smrg 1.f, 1.f, 1.f, 0.f, 663bfa90b6Smrg 0.f, -0.187324f, 1.8556f, 0.f, 673bfa90b6Smrg 1.5748f, -0.468124f, 0.f, 0.f 683bfa90b6Smrg}; 693bfa90b6Smrg 703bfa90b6Smrgstatic Atom xvBrightness, xvContrast, xvSaturation, xvHue; 713bfa90b6Smrg 723bfa90b6Smrg#define NUM_TEXTURED_ATTRIBUTES 4 733bfa90b6Smrgstatic XF86AttributeRec TexturedAttributes[NUM_TEXTURED_ATTRIBUTES] = { 743bfa90b6Smrg {XvSettable | XvGettable, -1000, 1000, "XV_BRIGHTNESS"}, 753bfa90b6Smrg {XvSettable | XvGettable, -1000, 1000, "XV_CONTRAST"}, 763bfa90b6Smrg {XvSettable | XvGettable, -1000, 1000, "XV_SATURATION"}, 773bfa90b6Smrg {XvSettable | XvGettable, -1000, 1000, "XV_HUE"} 783bfa90b6Smrg}; 793bfa90b6Smrg 803bfa90b6Smrg#define NUM_FORMATS 3 813bfa90b6Smrgstatic XF86VideoFormatRec Formats[NUM_FORMATS] = { 823bfa90b6Smrg {15, TrueColor}, {16, TrueColor}, {24, TrueColor} 833bfa90b6Smrg}; 843bfa90b6Smrg 853bfa90b6Smrgstatic XF86VideoEncodingRec DummyEncoding[1] = { 863bfa90b6Smrg { 873bfa90b6Smrg 0, 883bfa90b6Smrg "XV_IMAGE", 893bfa90b6Smrg IMAGE_MAX_WIDTH, IMAGE_MAX_HEIGHT, 903bfa90b6Smrg {1, 1} 913bfa90b6Smrg } 923bfa90b6Smrg}; 933bfa90b6Smrg 943bfa90b6Smrg#define NUM_IMAGES 3 953bfa90b6Smrgstatic XF86ImageRec Images[NUM_IMAGES] = { 963bfa90b6Smrg XVIMAGE_UYVY, 973bfa90b6Smrg XVIMAGE_YUY2, 983bfa90b6Smrg XVIMAGE_YV12, 993bfa90b6Smrg}; 1003bfa90b6Smrg 1013bfa90b6Smrgstruct xorg_xv_port_priv { 1023bfa90b6Smrg struct xa_tracker *xat; 1033bfa90b6Smrg struct xa_context *r; 1043bfa90b6Smrg struct xa_fence *fence; 1053bfa90b6Smrg 1063bfa90b6Smrg RegionRec clip; 1073bfa90b6Smrg 1083bfa90b6Smrg int brightness; 1093bfa90b6Smrg int contrast; 1103bfa90b6Smrg int saturation; 1113bfa90b6Smrg int hue; 1123bfa90b6Smrg 1133bfa90b6Smrg int current_set; 1143bfa90b6Smrg struct vmwgfx_dmabuf *bounce[2][3]; 1153bfa90b6Smrg struct xa_surface *yuv[3]; 1163bfa90b6Smrg 1173bfa90b6Smrg int drm_fd; 1183bfa90b6Smrg 1193bfa90b6Smrg Bool hdtv; 1203bfa90b6Smrg float uv_offset; 1213bfa90b6Smrg float uv_scale; 1223bfa90b6Smrg float y_offset; 1233bfa90b6Smrg float y_scale; 1243bfa90b6Smrg float rgb_offset; 1253bfa90b6Smrg float rgb_scale; 1263bfa90b6Smrg float sinhue; 1273bfa90b6Smrg float coshue; 1283bfa90b6Smrg float cm[16]; 1293bfa90b6Smrg}; 1303bfa90b6Smrg 1313bfa90b6Smrg/* 1323bfa90b6Smrg * vmwgfx_update_conversion_matrix - Compute the effective color conversion 1333bfa90b6Smrg * matrix. 1343bfa90b6Smrg * 1353bfa90b6Smrg * Applies yuv- and resulting rgb scales and offsets to compute the correct 1363bfa90b6Smrg * color conversion matrix. These scales and offsets are properties of the 1373bfa90b6Smrg * video stream and can be adjusted using XV properties as well. 1383bfa90b6Smrg */ 1393bfa90b6Smrgstatic void 1403bfa90b6Smrgvmwgfx_update_conversion_matrix(struct xorg_xv_port_priv *priv) 1413bfa90b6Smrg{ 1423bfa90b6Smrg int i; 1433bfa90b6Smrg float *cm = priv->cm; 1443bfa90b6Smrg static const float *bt; 1453bfa90b6Smrg 1463bfa90b6Smrg bt = (priv->hdtv) ? bt_709 : bt_601; 1473bfa90b6Smrg 1483bfa90b6Smrg memcpy(cm, bt, sizeof(bt_601)); 1493bfa90b6Smrg 1503bfa90b6Smrg /* 1513bfa90b6Smrg * Apply hue rotation 1523bfa90b6Smrg */ 1533bfa90b6Smrg cm[4] = priv->coshue * bt[4] - priv->sinhue * bt[8]; 1543bfa90b6Smrg cm[8] = priv->sinhue * bt[4] + priv->coshue * bt[8]; 1553bfa90b6Smrg cm[5] = priv->coshue * bt[5] - priv->sinhue * bt[9]; 1563bfa90b6Smrg cm[9] = priv->sinhue * bt[5] + priv->coshue * bt[9]; 1573bfa90b6Smrg cm[6] = priv->coshue * bt[6] - priv->sinhue * bt[10]; 1583bfa90b6Smrg cm[10] = priv->sinhue * bt[6] + priv->coshue * bt[10]; 1593bfa90b6Smrg 1603bfa90b6Smrg /* 1613bfa90b6Smrg * Adjust for yuv scales in input and rgb scale in the converted output. 1623bfa90b6Smrg */ 1633bfa90b6Smrg for(i = 0; i < 3; ++i) { 1643bfa90b6Smrg cm[i] *= (priv->y_scale*priv->rgb_scale); 1653bfa90b6Smrg cm[i+4] *= (priv->uv_scale*priv->rgb_scale); 1663bfa90b6Smrg cm[i+8] *= (priv->uv_scale*priv->rgb_scale); 1673bfa90b6Smrg } 1683bfa90b6Smrg 1693bfa90b6Smrg /* 1703bfa90b6Smrg * Adjust for yuv offsets in input and rgb offset in the converted output. 1713bfa90b6Smrg */ 1723bfa90b6Smrg for (i = 0; i < 3; ++i) 1733bfa90b6Smrg cm[i+12] = -cm[i]*priv->y_offset - (cm[i+4] + cm[i+8])*priv->uv_offset 1743bfa90b6Smrg - priv->rgb_offset*priv->rgb_scale; 1753bfa90b6Smrg 1763bfa90b6Smrg /* 1773bfa90b6Smrg * Alpha is 1, unconditionally. 1783bfa90b6Smrg */ 1793bfa90b6Smrg cm[15] = 1.f; 1803bfa90b6Smrg} 1813bfa90b6Smrg 1823bfa90b6Smrg 1833bfa90b6Smrgstatic void 1843bfa90b6Smrgstop_video(ScrnInfoPtr pScrn, pointer data, Bool shutdown) 1853bfa90b6Smrg{ 1863bfa90b6Smrg struct xorg_xv_port_priv *priv = (struct xorg_xv_port_priv *)data; 1873bfa90b6Smrg int i, j; 1883bfa90b6Smrg 1893bfa90b6Smrg REGION_EMPTY(pScrn->pScreen, &priv->clip); 1903bfa90b6Smrg if (shutdown) { 1913bfa90b6Smrg 1923bfa90b6Smrg /* 1933bfa90b6Smrg * No need to destroy the xa context or xa tracker since 1943bfa90b6Smrg * they are copied from the screen resources. 1953bfa90b6Smrg */ 1963bfa90b6Smrg 1973bfa90b6Smrg xa_fence_destroy(priv->fence); 1983bfa90b6Smrg priv->fence = NULL; 1993bfa90b6Smrg 2003bfa90b6Smrg for (i=0; i<3; ++i) { 2013bfa90b6Smrg if (priv->yuv[i]) { 2023bfa90b6Smrg xa_surface_destroy(priv->yuv[i]); 2033bfa90b6Smrg priv->yuv[i] = NULL; 2043bfa90b6Smrg } 2053bfa90b6Smrg for (j=0; j<2; ++j) { 2063bfa90b6Smrg if (priv->bounce[j][i]) { 2073bfa90b6Smrg vmwgfx_dmabuf_destroy(priv->bounce[j][i]); 2083bfa90b6Smrg priv->bounce[0][i] = NULL; 2093bfa90b6Smrg } 2103bfa90b6Smrg } 2113bfa90b6Smrg } 2123bfa90b6Smrg } 2133bfa90b6Smrg} 2143bfa90b6Smrg 2153bfa90b6Smrgstatic int 2163bfa90b6Smrgset_port_attribute(ScrnInfoPtr pScrn, 2173bfa90b6Smrg Atom attribute, INT32 value, pointer data) 2183bfa90b6Smrg{ 2193bfa90b6Smrg struct xorg_xv_port_priv *priv = (struct xorg_xv_port_priv *)data; 2203bfa90b6Smrg 2213bfa90b6Smrg if (attribute == xvBrightness) { 2223bfa90b6Smrg if ((value < -1000) || (value > 1000)) 2233bfa90b6Smrg return BadValue; 2243bfa90b6Smrg 2253bfa90b6Smrg priv->brightness = value; 2263bfa90b6Smrg priv->y_offset = -((float) value)/1000.f; 2273bfa90b6Smrg 2283bfa90b6Smrg } else if (attribute == xvContrast) { 2293bfa90b6Smrg if ((value < -1000) || (value > 1000)) 2303bfa90b6Smrg return BadValue; 2313bfa90b6Smrg 2323bfa90b6Smrg priv->contrast = value; 2333bfa90b6Smrg priv->rgb_scale = ((float) value + 1000.f)/1000.f; 2343bfa90b6Smrg 2353bfa90b6Smrg } else if (attribute == xvSaturation) { 2363bfa90b6Smrg if ((value < -1000) || (value > 1000)) 2373bfa90b6Smrg return BadValue; 2383bfa90b6Smrg 2393bfa90b6Smrg priv->saturation = value; 2403bfa90b6Smrg priv->uv_scale = ((float) value + 1000.f)/1000.f; 2413bfa90b6Smrg 2423bfa90b6Smrg } else if (attribute == xvHue) { 2433bfa90b6Smrg double hue_angle; 2443bfa90b6Smrg 2453bfa90b6Smrg if ((value < -1000) || (value > 1000)) 2463bfa90b6Smrg return BadValue; 2473bfa90b6Smrg 2483bfa90b6Smrg priv->hue = value; 2493bfa90b6Smrg hue_angle = (double) value * M_PI / 1000.; 2503bfa90b6Smrg priv->sinhue = sin(hue_angle); 2513bfa90b6Smrg priv->coshue = cos(hue_angle); 2523bfa90b6Smrg 2533bfa90b6Smrg } else 2543bfa90b6Smrg return BadMatch; 2553bfa90b6Smrg 2563bfa90b6Smrg vmwgfx_update_conversion_matrix(priv); 2573bfa90b6Smrg return Success; 2583bfa90b6Smrg} 2593bfa90b6Smrg 2603bfa90b6Smrgstatic int 2613bfa90b6Smrgget_port_attribute(ScrnInfoPtr pScrn, 2623bfa90b6Smrg Atom attribute, INT32 * value, pointer data) 2633bfa90b6Smrg{ 2643bfa90b6Smrg struct xorg_xv_port_priv *priv = (struct xorg_xv_port_priv *)data; 2653bfa90b6Smrg 2663bfa90b6Smrg if (attribute == xvBrightness) 2673bfa90b6Smrg *value = priv->brightness; 2683bfa90b6Smrg else if (attribute == xvContrast) 2693bfa90b6Smrg *value = priv->contrast; 2703bfa90b6Smrg else if (attribute == xvSaturation) 2713bfa90b6Smrg *value = priv->saturation; 2723bfa90b6Smrg else if (attribute == xvHue) 2733bfa90b6Smrg *value = priv->hue; 2743bfa90b6Smrg else 2753bfa90b6Smrg return BadMatch; 2763bfa90b6Smrg 2773bfa90b6Smrg return Success; 2783bfa90b6Smrg} 2793bfa90b6Smrg 2803bfa90b6Smrgstatic void 2813bfa90b6Smrgquery_best_size(ScrnInfoPtr pScrn, 2823bfa90b6Smrg Bool motion, 2833bfa90b6Smrg short vid_w, short vid_h, 2843bfa90b6Smrg short drw_w, short drw_h, 2853bfa90b6Smrg unsigned int *p_w, unsigned int *p_h, pointer data) 2863bfa90b6Smrg{ 2873bfa90b6Smrg if (vid_w > (drw_w << 1)) 2883bfa90b6Smrg drw_w = vid_w >> 1; 2893bfa90b6Smrg if (vid_h > (drw_h << 1)) 2903bfa90b6Smrg drw_h = vid_h >> 1; 2913bfa90b6Smrg 2923bfa90b6Smrg *p_w = drw_w; 2933bfa90b6Smrg *p_h = drw_h; 2943bfa90b6Smrg} 2953bfa90b6Smrg 2963bfa90b6Smrgstatic int 2973bfa90b6Smrgcheck_yuv_surfaces(struct xorg_xv_port_priv *priv, int id, 2983bfa90b6Smrg int width, int height) 2993bfa90b6Smrg{ 3003bfa90b6Smrg struct xa_surface **yuv = priv->yuv; 3013bfa90b6Smrg struct vmwgfx_dmabuf **bounce = priv->bounce[priv->current_set]; 3023bfa90b6Smrg int ret = 0; 3033bfa90b6Smrg int i; 3043bfa90b6Smrg size_t size; 3053bfa90b6Smrg 3063bfa90b6Smrg for (i=0; i<3; ++i) { 3073bfa90b6Smrg 3083bfa90b6Smrg /* 3093bfa90b6Smrg * Adjust u,v texture size and DMA buffer to what's required by 3103bfa90b6Smrg * the format. 3113bfa90b6Smrg */ 3123bfa90b6Smrg if (i == 1) { 3133bfa90b6Smrg switch(id) { 3143bfa90b6Smrg case FOURCC_YV12: 3153bfa90b6Smrg height /= 2; 3163bfa90b6Smrg /* Fall through */ 3173bfa90b6Smrg case FOURCC_YUY2: 3183bfa90b6Smrg case FOURCC_UYVY: 3193bfa90b6Smrg width /= 2; 3203bfa90b6Smrg break; 3213bfa90b6Smrg default: 3223bfa90b6Smrg break; 3233bfa90b6Smrg } 3243bfa90b6Smrg } 3253bfa90b6Smrg 3263bfa90b6Smrg if (!yuv[i]) 3273bfa90b6Smrg yuv[i] = xa_surface_create(priv->xat, width, height, 8, 3283bfa90b6Smrg xa_type_yuv_component, 3293bfa90b6Smrg xa_format_unknown, 0); 3303bfa90b6Smrg else 3313bfa90b6Smrg ret = xa_surface_redefine(yuv[i], width, height, 8, 3323bfa90b6Smrg xa_type_yuv_component, 3333bfa90b6Smrg xa_format_unknown, 0, 0); 3343bfa90b6Smrg if (ret || !yuv[i]) 3353bfa90b6Smrg return BadAlloc; 3363bfa90b6Smrg 3373bfa90b6Smrg size = width * height; 3383bfa90b6Smrg 3393bfa90b6Smrg if (bounce[i] && (bounce[i]->size < size || 3403bfa90b6Smrg bounce[i]->size > 2*size)) { 3413bfa90b6Smrg vmwgfx_dmabuf_destroy(bounce[i]); 3423bfa90b6Smrg bounce[i] = NULL; 3433bfa90b6Smrg } 3443bfa90b6Smrg 3453bfa90b6Smrg if (!bounce[i]) { 3463bfa90b6Smrg bounce[i] = vmwgfx_dmabuf_alloc(priv->drm_fd, size); 3473bfa90b6Smrg if (!bounce[i]) 3483bfa90b6Smrg return BadAlloc; 3493bfa90b6Smrg } 3503bfa90b6Smrg } 3513bfa90b6Smrg return Success; 3523bfa90b6Smrg} 3533bfa90b6Smrg 3543bfa90b6Smrgstatic int 3553bfa90b6Smrgquery_image_attributes(ScrnInfoPtr pScrn, 3563bfa90b6Smrg int id, 3573bfa90b6Smrg unsigned short *w, unsigned short *h, 3583bfa90b6Smrg int *pitches, int *offsets) 3593bfa90b6Smrg{ 3603bfa90b6Smrg int size, tmp; 3613bfa90b6Smrg 3623bfa90b6Smrg if (*w > IMAGE_MAX_WIDTH) 3633bfa90b6Smrg *w = IMAGE_MAX_WIDTH; 3643bfa90b6Smrg if (*h > IMAGE_MAX_HEIGHT) 3653bfa90b6Smrg *h = IMAGE_MAX_HEIGHT; 3663bfa90b6Smrg 3673bfa90b6Smrg *w = (*w + 1) & ~1; 3683bfa90b6Smrg if (offsets) 3693bfa90b6Smrg offsets[0] = 0; 3703bfa90b6Smrg 3713bfa90b6Smrg switch (id) { 3723bfa90b6Smrg case FOURCC_YV12: 3733bfa90b6Smrg *h = (*h + 1) & ~1; 3743bfa90b6Smrg size = (*w + 3) & ~3; 3753bfa90b6Smrg if (pitches) { 3763bfa90b6Smrg pitches[0] = size; 3773bfa90b6Smrg } 3783bfa90b6Smrg size *= *h; 3793bfa90b6Smrg if (offsets) { 3803bfa90b6Smrg offsets[1] = size; 3813bfa90b6Smrg } 3823bfa90b6Smrg tmp = ((*w >> 1) + 3) & ~3; 3833bfa90b6Smrg if (pitches) { 3843bfa90b6Smrg pitches[1] = pitches[2] = tmp; 3853bfa90b6Smrg } 3863bfa90b6Smrg tmp *= (*h >> 1); 3873bfa90b6Smrg size += tmp; 3883bfa90b6Smrg if (offsets) { 3893bfa90b6Smrg offsets[2] = size; 3903bfa90b6Smrg } 3913bfa90b6Smrg size += tmp; 3923bfa90b6Smrg break; 3933bfa90b6Smrg case FOURCC_UYVY: 3943bfa90b6Smrg case FOURCC_YUY2: 3953bfa90b6Smrg default: 3963bfa90b6Smrg size = *w << 1; 3973bfa90b6Smrg if (pitches) 3983bfa90b6Smrg pitches[0] = size; 3993bfa90b6Smrg size *= *h; 4003bfa90b6Smrg break; 4013bfa90b6Smrg } 4023bfa90b6Smrg 4033bfa90b6Smrg return size; 4043bfa90b6Smrg} 4053bfa90b6Smrg 4063bfa90b6Smrgstatic int 4073bfa90b6Smrgcopy_packed_data(ScrnInfoPtr pScrn, 4083bfa90b6Smrg struct xorg_xv_port_priv *port, 4093bfa90b6Smrg int id, 4103bfa90b6Smrg unsigned char *buf, 4113bfa90b6Smrg int left, 4123bfa90b6Smrg int top, 4133bfa90b6Smrg unsigned short w, unsigned short h) 4143bfa90b6Smrg{ 4153bfa90b6Smrg int i; 4163bfa90b6Smrg struct vmwgfx_dmabuf **bounce = port->bounce[port->current_set]; 4173bfa90b6Smrg char *ymap, *vmap, *umap; 4183bfa90b6Smrg unsigned char y1, y2, u, v; 4193bfa90b6Smrg int yidx, uidx, vidx; 4203bfa90b6Smrg int y_array_size = w * h; 4213bfa90b6Smrg int ret = BadAlloc; 4223bfa90b6Smrg 4233bfa90b6Smrg /* 4243bfa90b6Smrg * Here, we could use xa_surface_[map|unmap], but given the size of 4253bfa90b6Smrg * the yuv textures, that could stress the xa tracker dma buffer pool, 4263bfa90b6Smrg * particularaly with multiple videos rendering simultaneously. 4273bfa90b6Smrg * 4283bfa90b6Smrg * Instead, cheat and allocate vmwgfx dma buffers directly. 4293bfa90b6Smrg */ 4303bfa90b6Smrg 4313bfa90b6Smrg ymap = (char *)vmwgfx_dmabuf_map(bounce[0]); 4323bfa90b6Smrg if (!ymap) 4333bfa90b6Smrg return BadAlloc; 4343bfa90b6Smrg umap = (char *)vmwgfx_dmabuf_map(bounce[1]); 4353bfa90b6Smrg if (!umap) 4363bfa90b6Smrg goto out_no_umap; 4373bfa90b6Smrg vmap = (char *)vmwgfx_dmabuf_map(bounce[2]); 4383bfa90b6Smrg if (!vmap) 4393bfa90b6Smrg goto out_no_vmap; 4403bfa90b6Smrg 4413bfa90b6Smrg 4423bfa90b6Smrg yidx = uidx = vidx = 0; 4433bfa90b6Smrg 4443bfa90b6Smrg switch (id) { 4453bfa90b6Smrg case FOURCC_YV12: { 4463bfa90b6Smrg int pitches[3], offsets[3]; 4473bfa90b6Smrg unsigned char *y, *u, *v; 4483bfa90b6Smrg query_image_attributes(pScrn, FOURCC_YV12, 4493bfa90b6Smrg &w, &h, pitches, offsets); 4503bfa90b6Smrg 4513bfa90b6Smrg y = buf + offsets[0]; 4523bfa90b6Smrg v = buf + offsets[1]; 4533bfa90b6Smrg u = buf + offsets[2]; 4543bfa90b6Smrg memcpy(ymap, y, w*h); 4553bfa90b6Smrg memcpy(vmap, v, w*h/4); 4563bfa90b6Smrg memcpy(umap, u, w*h/4); 4573bfa90b6Smrg break; 4583bfa90b6Smrg } 4593bfa90b6Smrg case FOURCC_UYVY: 4603bfa90b6Smrg for (i = 0; i < y_array_size; i +=2 ) { 4613bfa90b6Smrg /* extracting two pixels */ 4623bfa90b6Smrg u = buf[0]; 4633bfa90b6Smrg y1 = buf[1]; 4643bfa90b6Smrg v = buf[2]; 4653bfa90b6Smrg y2 = buf[3]; 4663bfa90b6Smrg buf += 4; 4673bfa90b6Smrg 4683bfa90b6Smrg ymap[yidx++] = y1; 4693bfa90b6Smrg ymap[yidx++] = y2; 4703bfa90b6Smrg umap[uidx++] = u; 4713bfa90b6Smrg vmap[vidx++] = v; 4723bfa90b6Smrg } 4733bfa90b6Smrg break; 4743bfa90b6Smrg case FOURCC_YUY2: 4753bfa90b6Smrg for (i = 0; i < y_array_size; i +=2 ) { 4763bfa90b6Smrg /* extracting two pixels */ 4773bfa90b6Smrg y1 = buf[0]; 4783bfa90b6Smrg u = buf[1]; 4793bfa90b6Smrg y2 = buf[2]; 4803bfa90b6Smrg v = buf[3]; 4813bfa90b6Smrg 4823bfa90b6Smrg buf += 4; 4833bfa90b6Smrg 4843bfa90b6Smrg ymap[yidx++] = y1; 4853bfa90b6Smrg ymap[yidx++] = y2; 4863bfa90b6Smrg umap[uidx++] = u; 4873bfa90b6Smrg vmap[vidx++] = v; 4883bfa90b6Smrg } 4893bfa90b6Smrg break; 4903bfa90b6Smrg default: 4913bfa90b6Smrg ret = BadAlloc; 4923bfa90b6Smrg break; 4933bfa90b6Smrg } 4943bfa90b6Smrg 4953bfa90b6Smrg ret = Success; 4963bfa90b6Smrg vmwgfx_dmabuf_unmap(bounce[2]); 4973bfa90b6Smrg out_no_vmap: 4983bfa90b6Smrg vmwgfx_dmabuf_unmap(bounce[1]); 4993bfa90b6Smrg out_no_umap: 5003bfa90b6Smrg vmwgfx_dmabuf_unmap(bounce[0]); 5013bfa90b6Smrg 5023bfa90b6Smrg if (ret == Success) { 5033bfa90b6Smrg struct xa_surface *srf; 5043bfa90b6Smrg struct vmwgfx_dmabuf *buf; 5053bfa90b6Smrg uint32_t handle; 5063bfa90b6Smrg unsigned int stride; 5073bfa90b6Smrg BoxRec box; 5083bfa90b6Smrg RegionRec reg; 5093bfa90b6Smrg 5103bfa90b6Smrg box.x1 = 0; 5113bfa90b6Smrg box.x2 = w; 5123bfa90b6Smrg box.y1 = 0; 5133bfa90b6Smrg box.y2 = h; 5143bfa90b6Smrg 5153bfa90b6Smrg REGION_INIT(pScrn->pScreen, ®, &box, 1); 5163bfa90b6Smrg 5173bfa90b6Smrg for (i=0; i<3; ++i) { 5183bfa90b6Smrg srf = port->yuv[i]; 5193bfa90b6Smrg buf = bounce[i]; 5203bfa90b6Smrg 5213bfa90b6Smrg if (i == 1) { 5223bfa90b6Smrg switch(id) { 5233bfa90b6Smrg case FOURCC_YV12: 5243bfa90b6Smrg h /= 2; 5253bfa90b6Smrg /* Fall through */ 5263bfa90b6Smrg case FOURCC_YUY2: 5273bfa90b6Smrg case FOURCC_UYVY: 5283bfa90b6Smrg w /= 2; 5293bfa90b6Smrg break; 5303bfa90b6Smrg default: 5313bfa90b6Smrg break; 5323bfa90b6Smrg } 5333bfa90b6Smrg 5343bfa90b6Smrg box.x1 = 0; 5353bfa90b6Smrg box.x2 = w; 5363bfa90b6Smrg box.y1 = 0; 5373bfa90b6Smrg box.y2 = h; 5383bfa90b6Smrg 5393bfa90b6Smrg REGION_RESET(pScrn->pScreen, ®, &box); 5403bfa90b6Smrg } 5413bfa90b6Smrg 5423bfa90b6Smrg if (xa_surface_handle(srf, &handle, &stride) != 0) { 5433bfa90b6Smrg ret = BadAlloc; 5443bfa90b6Smrg break; 5453bfa90b6Smrg } 5463bfa90b6Smrg 5473bfa90b6Smrg if (vmwgfx_dma(0, 0, ®, buf, w, handle, 1) != 0) { 5483bfa90b6Smrg ret = BadAlloc; 5493bfa90b6Smrg break; 5503bfa90b6Smrg } 5513bfa90b6Smrg } 5523bfa90b6Smrg REGION_UNINIT(pScrn->pScreen, ®); 5533bfa90b6Smrg } 5543bfa90b6Smrg 5553bfa90b6Smrg return ret; 5563bfa90b6Smrg} 5573bfa90b6Smrg 5583bfa90b6Smrg 5593bfa90b6Smrgstatic int 5603bfa90b6Smrgdisplay_video(ScreenPtr pScreen, struct xorg_xv_port_priv *pPriv, int id, 5613bfa90b6Smrg RegionPtr dstRegion, 5623bfa90b6Smrg int src_x, int src_y, int src_w, int src_h, 5633bfa90b6Smrg int dst_x, int dst_y, int dst_w, int dst_h, 5643bfa90b6Smrg PixmapPtr pPixmap) 5653bfa90b6Smrg{ 5663bfa90b6Smrg struct vmwgfx_saa_pixmap *vpix = vmwgfx_saa_pixmap(pPixmap); 5673bfa90b6Smrg Bool hdtv; 5683bfa90b6Smrg RegionRec reg; 5693bfa90b6Smrg int ret = BadAlloc; 5703bfa90b6Smrg int blit_ret; 5713bfa90b6Smrg 5723bfa90b6Smrg REGION_NULL(pScreen, ®); 5733bfa90b6Smrg 5743bfa90b6Smrg if (!vmwgfx_hw_accel_validate(pPixmap, 0, XA_FLAG_RENDER_TARGET, 0, ®)) 5753bfa90b6Smrg goto out_no_dst; 5763bfa90b6Smrg 5773bfa90b6Smrg hdtv = ((src_w >= RES_720P_X) && (src_h >= RES_720P_Y)); 5783bfa90b6Smrg if (hdtv != pPriv->hdtv) { 5793bfa90b6Smrg pPriv->hdtv = hdtv; 5803bfa90b6Smrg vmwgfx_update_conversion_matrix(pPriv); 5813bfa90b6Smrg } 5823bfa90b6Smrg 5833bfa90b6Smrg#ifdef COMPOSITE 5843bfa90b6Smrg 5853bfa90b6Smrg /* 5863bfa90b6Smrg * For redirected windows, we need to fix up the destination coordinates. 5873bfa90b6Smrg */ 5883bfa90b6Smrg 5893bfa90b6Smrg REGION_TRANSLATE(pScreen, dstRegion, -pPixmap->screen_x, 5903bfa90b6Smrg -pPixmap->screen_y); 5913bfa90b6Smrg dst_x -= pPixmap->screen_x; 5923bfa90b6Smrg dst_y -= pPixmap->screen_y; 5933bfa90b6Smrg#endif 5943bfa90b6Smrg 5953bfa90b6Smrg /* 5963bfa90b6Smrg * Throttle on previous blit. 5973bfa90b6Smrg */ 5983bfa90b6Smrg 5993bfa90b6Smrg if (pPriv->fence) { 6003bfa90b6Smrg (void) xa_fence_wait(pPriv->fence, 1000000000ULL); 6013bfa90b6Smrg xa_fence_destroy(pPriv->fence); 6023bfa90b6Smrg pPriv->fence = NULL; 6033bfa90b6Smrg } 6043bfa90b6Smrg 6053bfa90b6Smrg DamageRegionAppend(&pPixmap->drawable, dstRegion); 6063bfa90b6Smrg 6073bfa90b6Smrg blit_ret = xa_yuv_planar_blit(pPriv->r, src_x, src_y, src_w, src_h, 6083bfa90b6Smrg dst_x, dst_y, dst_w, dst_h, 6093bfa90b6Smrg (struct xa_box *)REGION_RECTS(dstRegion), 6103bfa90b6Smrg REGION_NUM_RECTS(dstRegion), 6113bfa90b6Smrg pPriv->cm, 6123bfa90b6Smrg vpix->hw, pPriv->yuv); 6133bfa90b6Smrg 6143bfa90b6Smrg saa_pixmap_dirty(pPixmap, TRUE, dstRegion); 6153bfa90b6Smrg DamageRegionProcessPending(&pPixmap->drawable); 6163bfa90b6Smrg ret = Success; 6173bfa90b6Smrg 6183bfa90b6Smrg if (!blit_ret) { 6193bfa90b6Smrg ret = Success; 6203bfa90b6Smrg pPriv->fence = xa_fence_get(pPriv->r); 6213bfa90b6Smrg } else 6223bfa90b6Smrg ret = BadAlloc; 6233bfa90b6Smrg 6243bfa90b6Smrg out_no_dst: 6253bfa90b6Smrg REGION_UNINIT(pScreen, ®); 6263bfa90b6Smrg return ret; 6273bfa90b6Smrg} 6283bfa90b6Smrg 6293bfa90b6Smrgstatic int 6303bfa90b6Smrgput_image(ScrnInfoPtr pScrn, 6313bfa90b6Smrg short src_x, short src_y, 6323bfa90b6Smrg short drw_x, short drw_y, 6333bfa90b6Smrg short src_w, short src_h, 6343bfa90b6Smrg short drw_w, short drw_h, 6353bfa90b6Smrg int id, unsigned char *buf, 6363bfa90b6Smrg short width, short height, 6373bfa90b6Smrg Bool sync, RegionPtr clipBoxes, pointer data, 6383bfa90b6Smrg DrawablePtr pDraw) 6393bfa90b6Smrg{ 6403bfa90b6Smrg struct xorg_xv_port_priv *pPriv = (struct xorg_xv_port_priv *) data; 6413bfa90b6Smrg ScreenPtr pScreen = xf86ScrnToScreen(pScrn); 6423bfa90b6Smrg PixmapPtr pPixmap; 6433bfa90b6Smrg INT32 x1, x2, y1, y2; 6443bfa90b6Smrg BoxRec dstBox; 6453bfa90b6Smrg int ret; 6463bfa90b6Smrg 6473bfa90b6Smrg /* Clip */ 6483bfa90b6Smrg x1 = src_x; 6493bfa90b6Smrg x2 = src_x + src_w; 6503bfa90b6Smrg y1 = src_y; 6513bfa90b6Smrg y2 = src_y + src_h; 6523bfa90b6Smrg 6533bfa90b6Smrg dstBox.x1 = drw_x; 6543bfa90b6Smrg dstBox.x2 = drw_x + drw_w; 6553bfa90b6Smrg dstBox.y1 = drw_y; 6563bfa90b6Smrg dstBox.y2 = drw_y + drw_h; 6573bfa90b6Smrg 6583bfa90b6Smrg if (!xf86XVClipVideoHelper(&dstBox, &x1, &x2, &y1, &y2, clipBoxes, 6593bfa90b6Smrg width, height)) 6603bfa90b6Smrg return Success; 6613bfa90b6Smrg 6623bfa90b6Smrg ret = check_yuv_surfaces(pPriv, id, width, height); 6633bfa90b6Smrg if (ret) 6643bfa90b6Smrg return ret; 6653bfa90b6Smrg 6663bfa90b6Smrg ret = copy_packed_data(pScrn, pPriv, id, buf, 6673bfa90b6Smrg src_x, src_y, width, height); 6683bfa90b6Smrg if (ret) 6693bfa90b6Smrg return ret; 6703bfa90b6Smrg 6713bfa90b6Smrg if (pDraw->type == DRAWABLE_WINDOW) { 6723bfa90b6Smrg pPixmap = (*pScreen->GetWindowPixmap)((WindowPtr)pDraw); 6733bfa90b6Smrg } else { 6743bfa90b6Smrg pPixmap = (PixmapPtr)pDraw; 6753bfa90b6Smrg } 6763bfa90b6Smrg 6773bfa90b6Smrg display_video(pScrn->pScreen, pPriv, id, clipBoxes, 6783bfa90b6Smrg src_x, src_y, src_w, src_h, 6793bfa90b6Smrg drw_x, drw_y, 6803bfa90b6Smrg drw_w, drw_h, pPixmap); 6813bfa90b6Smrg 6823bfa90b6Smrg pPriv->current_set = (pPriv->current_set + 1) & 1; 6833bfa90b6Smrg return Success; 6843bfa90b6Smrg} 6853bfa90b6Smrg 6863bfa90b6Smrgstatic struct xorg_xv_port_priv * 6873bfa90b6Smrgport_priv_create(struct xa_tracker *xat, struct xa_context *r, 6883bfa90b6Smrg int drm_fd) 6893bfa90b6Smrg{ 6903bfa90b6Smrg struct xorg_xv_port_priv *priv = NULL; 6913bfa90b6Smrg 6923bfa90b6Smrg priv = calloc(1, sizeof(struct xorg_xv_port_priv)); 6933bfa90b6Smrg 6943bfa90b6Smrg if (!priv) 6953bfa90b6Smrg return NULL; 6963bfa90b6Smrg 6973bfa90b6Smrg priv->r = r; 6983bfa90b6Smrg priv->xat = xat; 6993bfa90b6Smrg priv->drm_fd = drm_fd; 7003bfa90b6Smrg REGION_NULL(pScreen, &priv->clip); 7013bfa90b6Smrg priv->hdtv = FALSE; 7023bfa90b6Smrg priv->uv_offset = 0.5f; 7033bfa90b6Smrg priv->uv_scale = 1.f; 7043bfa90b6Smrg priv->y_offset = 0.f; 7053bfa90b6Smrg priv->y_scale = 1.f; 7063bfa90b6Smrg priv->rgb_offset = 0.f; 7073bfa90b6Smrg priv->rgb_scale = 1.f; 7083bfa90b6Smrg priv->sinhue = 0.f; 7093bfa90b6Smrg priv->coshue = 1.f; 7103bfa90b6Smrg 7113bfa90b6Smrg vmwgfx_update_conversion_matrix(priv); 7123bfa90b6Smrg 7133bfa90b6Smrg return priv; 7143bfa90b6Smrg} 7153bfa90b6Smrg 7163bfa90b6Smrgstatic void 7173bfa90b6Smrgvmwgfx_free_textured_adaptor(XF86VideoAdaptorPtr adaptor, Bool free_ports) 7183bfa90b6Smrg{ 7193bfa90b6Smrg if (free_ports) { 7203bfa90b6Smrg int i; 7213bfa90b6Smrg 7223bfa90b6Smrg for(i=0; i<adaptor->nPorts; ++i) { 7233bfa90b6Smrg free(adaptor->pPortPrivates[i].ptr); 7243bfa90b6Smrg } 7253bfa90b6Smrg } 7263bfa90b6Smrg 7273bfa90b6Smrg free(adaptor->pAttributes); 7283bfa90b6Smrg free(adaptor->pPortPrivates); 7293bfa90b6Smrg xf86XVFreeVideoAdaptorRec(adaptor); 7303bfa90b6Smrg} 7313bfa90b6Smrg 7323bfa90b6Smrgstatic XF86VideoAdaptorPtr 7333bfa90b6Smrgxorg_setup_textured_adapter(ScreenPtr pScreen) 7343bfa90b6Smrg{ 7353bfa90b6Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 7363bfa90b6Smrg modesettingPtr ms = modesettingPTR(pScrn); 7373bfa90b6Smrg XF86VideoAdaptorPtr adapt; 7383bfa90b6Smrg XF86AttributePtr attrs; 7393bfa90b6Smrg DevUnion *dev_unions; 7403bfa90b6Smrg int nports = 16, i; 7413bfa90b6Smrg int nattributes; 7423bfa90b6Smrg struct xa_context *xar; 7433bfa90b6Smrg 7443bfa90b6Smrg /* 7453bfa90b6Smrg * Use the XA default context since we don't expect the X server 7463bfa90b6Smrg * to render from multiple threads. 7473bfa90b6Smrg */ 7483bfa90b6Smrg 7493bfa90b6Smrg xar = xa_context_default(ms->xat); 7503bfa90b6Smrg nattributes = NUM_TEXTURED_ATTRIBUTES; 7513bfa90b6Smrg 7523bfa90b6Smrg adapt = calloc(1, sizeof(XF86VideoAdaptorRec)); 7533bfa90b6Smrg dev_unions = calloc(nports, sizeof(DevUnion)); 7543bfa90b6Smrg attrs = calloc(nattributes, sizeof(XF86AttributeRec)); 7553bfa90b6Smrg if (adapt == NULL || dev_unions == NULL || attrs == NULL) { 7563bfa90b6Smrg free(adapt); 7573bfa90b6Smrg free(dev_unions); 7583bfa90b6Smrg free(attrs); 7593bfa90b6Smrg return NULL; 7603bfa90b6Smrg } 7613bfa90b6Smrg 7623bfa90b6Smrg adapt->type = XvWindowMask | XvInputMask | XvImageMask; 7633bfa90b6Smrg adapt->flags = 0; 7643bfa90b6Smrg adapt->name = "XA G3D Textured Video"; 7653bfa90b6Smrg adapt->nEncodings = 1; 7663bfa90b6Smrg adapt->pEncodings = DummyEncoding; 7673bfa90b6Smrg adapt->nFormats = NUM_FORMATS; 7683bfa90b6Smrg adapt->pFormats = Formats; 7693bfa90b6Smrg adapt->nPorts = 0; 7703bfa90b6Smrg adapt->pPortPrivates = dev_unions; 7713bfa90b6Smrg adapt->nAttributes = nattributes; 7723bfa90b6Smrg adapt->pAttributes = attrs; 7733bfa90b6Smrg memcpy(attrs, TexturedAttributes, nattributes * sizeof(XF86AttributeRec)); 7743bfa90b6Smrg adapt->nImages = NUM_IMAGES; 7753bfa90b6Smrg adapt->pImages = Images; 7763bfa90b6Smrg adapt->PutVideo = NULL; 7773bfa90b6Smrg adapt->PutStill = NULL; 7783bfa90b6Smrg adapt->GetVideo = NULL; 7793bfa90b6Smrg adapt->GetStill = NULL; 7803bfa90b6Smrg adapt->StopVideo = stop_video; 7813bfa90b6Smrg adapt->SetPortAttribute = set_port_attribute; 7823bfa90b6Smrg adapt->GetPortAttribute = get_port_attribute; 7833bfa90b6Smrg adapt->QueryBestSize = query_best_size; 7843bfa90b6Smrg adapt->PutImage = put_image; 7853bfa90b6Smrg adapt->QueryImageAttributes = query_image_attributes; 7863bfa90b6Smrg 7873bfa90b6Smrg 7883bfa90b6Smrg for (i = 0; i < nports; i++) { 7893bfa90b6Smrg struct xorg_xv_port_priv *priv = 7903bfa90b6Smrg port_priv_create(ms->xat, xar, ms->fd); 7913bfa90b6Smrg 7923bfa90b6Smrg adapt->pPortPrivates[i].ptr = (pointer) (priv); 7933bfa90b6Smrg adapt->nPorts++; 7943bfa90b6Smrg } 7953bfa90b6Smrg 7963bfa90b6Smrg return adapt; 7973bfa90b6Smrg} 7983bfa90b6Smrg 7993bfa90b6Smrgvoid 8003bfa90b6Smrgxorg_xv_init(ScreenPtr pScreen) 8013bfa90b6Smrg{ 8023bfa90b6Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 8033bfa90b6Smrg modesettingPtr ms = modesettingPTR(pScrn); 8043bfa90b6Smrg XF86VideoAdaptorPtr *adaptors, *new_adaptors = NULL; 8053bfa90b6Smrg XF86VideoAdaptorPtr textured_adapter = NULL, overlay_adaptor = NULL; 8063bfa90b6Smrg int num_adaptors; 8073bfa90b6Smrg 8083bfa90b6Smrg num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors); 8093bfa90b6Smrg new_adaptors = malloc((num_adaptors + 2) * sizeof(XF86VideoAdaptorPtr *)); 8103bfa90b6Smrg if (new_adaptors == NULL) 8113bfa90b6Smrg return; 8123bfa90b6Smrg 8133bfa90b6Smrg memcpy(new_adaptors, adaptors, num_adaptors * sizeof(XF86VideoAdaptorPtr)); 8143bfa90b6Smrg adaptors = new_adaptors; 8153bfa90b6Smrg 8163bfa90b6Smrg /* Add the adaptors supported by our hardware. First, set up the atoms 8173bfa90b6Smrg * that will be used by both output adaptors. 8183bfa90b6Smrg */ 8193bfa90b6Smrg xvBrightness = MAKE_ATOM("XV_BRIGHTNESS"); 8203bfa90b6Smrg xvContrast = MAKE_ATOM("XV_CONTRAST"); 8213bfa90b6Smrg xvSaturation = MAKE_ATOM("XV_SATURATION"); 8223bfa90b6Smrg xvHue = MAKE_ATOM("XV_HUE"); 8233bfa90b6Smrg 8243bfa90b6Smrg if (ms->xat) { 8253bfa90b6Smrg textured_adapter = xorg_setup_textured_adapter(pScreen); 8263bfa90b6Smrg if (textured_adapter) 8273bfa90b6Smrg adaptors[num_adaptors++] = textured_adapter; 8283bfa90b6Smrg } else { 8293bfa90b6Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 8303bfa90b6Smrg "No 3D acceleration. Not setting up textured video.\n"); 8313bfa90b6Smrg } 8323bfa90b6Smrg 8333bfa90b6Smrg overlay_adaptor = vmw_video_init_adaptor(pScrn); 8343bfa90b6Smrg if (overlay_adaptor) 8353bfa90b6Smrg adaptors[num_adaptors++] = overlay_adaptor; 8363bfa90b6Smrg 8373bfa90b6Smrg if (num_adaptors) { 8383bfa90b6Smrg Bool ret; 8393bfa90b6Smrg ret = xf86XVScreenInit(pScreen, adaptors, num_adaptors); 8403bfa90b6Smrg if (textured_adapter) 8413bfa90b6Smrg vmwgfx_free_textured_adaptor(textured_adapter, !ret); 8423bfa90b6Smrg if (overlay_adaptor) 8433bfa90b6Smrg vmw_video_free_adaptor(overlay_adaptor, !ret); 8443bfa90b6Smrg if (!ret) 8453bfa90b6Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 8463bfa90b6Smrg "Failed to initialize Xv.\n"); 8473bfa90b6Smrg } else { 8483bfa90b6Smrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 8493bfa90b6Smrg "Disabling Xv because no adaptors could be initialized.\n"); 8503bfa90b6Smrg } 8513bfa90b6Smrg} 852