1/* 2 * Copyright © 2007 Intel Corporation 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 * SOFTWARE. 22 * 23 * Authors: 24 * Zhenyu Wang <zhenyu.z.wang@intel.com> 25 * 26 */ 27#ifdef HAVE_CONFIG_H 28#include "config.h" 29#endif 30 31#define _INTEL_XVMC_SERVER_ 32#include "intel.h" 33#include "intel_xvmc.h" 34 35#include <X11/extensions/Xv.h> 36#include <X11/extensions/XvMC.h> 37#include <fourcc.h> 38 39static int create_subpicture(ScrnInfoPtr scrn, XvMCSubpicturePtr subpicture, 40 int *num_priv, CARD32 ** priv) 41{ 42 return Success; 43} 44 45static void destroy_subpicture(ScrnInfoPtr scrn, XvMCSubpicturePtr subpicture) 46{ 47} 48 49static int create_surface(ScrnInfoPtr scrn, XvMCSurfacePtr surface, 50 int *num_priv, CARD32 ** priv) 51{ 52 return Success; 53} 54 55static void destroy_surface(ScrnInfoPtr scrn, XvMCSurfacePtr surface) 56{ 57} 58 59static int create_context(ScrnInfoPtr scrn, XvMCContextPtr pContext, 60 int *num_priv, CARD32 **priv) 61{ 62 intel_screen_private *intel = intel_get_screen_private(scrn); 63 struct intel_xvmc_hw_context *contextRec; 64 65 *priv = calloc(1, sizeof(struct intel_xvmc_hw_context)); 66 contextRec = (struct intel_xvmc_hw_context *) *priv; 67 if (!contextRec) { 68 *num_priv = 0; 69 return BadAlloc; 70 } 71 72 *num_priv = sizeof(struct intel_xvmc_hw_context) >> 2; 73 74 if (IS_GEN3(intel)) { 75 contextRec->type = XVMC_I915_MPEG2_MC; 76 contextRec->i915.use_phys_addr = 0; 77 } else { 78 if (INTEL_INFO(intel)->gen >= 045) 79 contextRec->type = XVMC_I965_MPEG2_VLD; 80 else 81 contextRec->type = XVMC_I965_MPEG2_MC; 82 contextRec->i965.is_g4x = INTEL_INFO(intel)->gen == 045; 83 contextRec->i965.is_965_q = IS_965_Q(intel); 84 contextRec->i965.is_igdng = IS_GEN5(intel); 85 } 86 87 return Success; 88} 89 90static void destroy_context(ScrnInfoPtr scrn, XvMCContextPtr context) 91{ 92} 93 94/* i915 hwmc support */ 95static XF86MCSurfaceInfoRec i915_YV12_mpg2_surface = { 96 FOURCC_YV12, 97 XVMC_CHROMA_FORMAT_420, 98 0, 99 720, 100 576, 101 720, 102 576, 103 XVMC_MPEG_2, 104 /* XVMC_OVERLAID_SURFACE | XVMC_SUBPICTURE_INDEPENDENT_SCALING, */ 105 0, 106 /* &yv12_subpicture_list */ 107 NULL, 108}; 109 110static XF86MCSurfaceInfoRec i915_YV12_mpg1_surface = { 111 FOURCC_YV12, 112 XVMC_CHROMA_FORMAT_420, 113 0, 114 720, 115 576, 116 720, 117 576, 118 XVMC_MPEG_1, 119 /* XVMC_OVERLAID_SURFACE | XVMC_SUBPICTURE_INDEPENDENT_SCALING, */ 120 0, 121 NULL, 122}; 123 124static XF86MCSurfaceInfoPtr surface_info_i915[2] = { 125 (XF86MCSurfaceInfoPtr) & i915_YV12_mpg2_surface, 126 (XF86MCSurfaceInfoPtr) & i915_YV12_mpg1_surface 127}; 128 129/* i965 and later hwmc support */ 130#ifndef XVMC_VLD 131#define XVMC_VLD 0x00020000 132#endif 133 134static XF86MCSurfaceInfoRec yv12_mpeg2_vld_surface = { 135 FOURCC_YV12, 136 XVMC_CHROMA_FORMAT_420, 137 0, 138 1936, 139 1096, 140 1920, 141 1080, 142 XVMC_MPEG_2 | XVMC_VLD, 143 XVMC_INTRA_UNSIGNED, 144 NULL 145}; 146 147static XF86MCSurfaceInfoRec yv12_mpeg2_i965_surface = { 148 FOURCC_YV12, 149 XVMC_CHROMA_FORMAT_420, 150 0, 151 1936, 152 1096, 153 1920, 154 1080, 155 XVMC_MPEG_2 | XVMC_MOCOMP, 156 /* XVMC_OVERLAID_SURFACE | XVMC_SUBPICTURE_INDEPENDENT_SCALING, */ 157 XVMC_INTRA_UNSIGNED, 158 /* &yv12_subpicture_list */ 159 NULL 160}; 161 162static XF86MCSurfaceInfoRec yv12_mpeg1_i965_surface = { 163 FOURCC_YV12, 164 XVMC_CHROMA_FORMAT_420, 165 0, 166 1920, 167 1080, 168 1920, 169 1080, 170 XVMC_MPEG_1 | XVMC_MOCOMP, 171 /*XVMC_OVERLAID_SURFACE | XVMC_SUBPICTURE_INDEPENDENT_SCALING | 172 XVMC_INTRA_UNSIGNED, */ 173 XVMC_INTRA_UNSIGNED, 174 175 /*&yv12_subpicture_list */ 176 NULL 177}; 178 179static XF86MCSurfaceInfoPtr surface_info_i965[] = { 180 &yv12_mpeg2_i965_surface, 181 &yv12_mpeg1_i965_surface 182}; 183 184static XF86MCSurfaceInfoPtr surface_info_vld[] = { 185 &yv12_mpeg2_vld_surface, 186 &yv12_mpeg2_i965_surface, 187}; 188 189/* check chip type and load xvmc driver */ 190Bool intel_xvmc_adaptor_init(ScreenPtr pScreen) 191{ 192 ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen); 193 intel_screen_private *intel = intel_get_screen_private(scrn); 194 struct pci_device *pci; 195 static XF86MCAdaptorRec *pAdapt; 196 const char *name; 197 char buf[64]; 198 199 if (!intel->XvMCEnabled) 200 return FALSE; 201 202 /* Needs KMS support. */ 203 if (IS_I915G(intel) || IS_I915GM(intel)) 204 return FALSE; 205 206 if (IS_GEN2(intel)) { 207 ErrorF("Your chipset doesn't support XvMC.\n"); 208 return FALSE; 209 } 210 211 pci = xf86GetPciInfoForEntity(intel->pEnt->index); 212 if (pci == NULL) 213 return FALSE; 214 215 pAdapt = calloc(1, sizeof(XF86MCAdaptorRec)); 216 if (!pAdapt) { 217 ErrorF("Allocation error.\n"); 218 return FALSE; 219 } 220 221 pAdapt->name = "Intel(R) Textured Video"; 222 pAdapt->num_subpictures = 0; 223 pAdapt->subpictures = NULL; 224 pAdapt->CreateContext = create_context; 225 pAdapt->DestroyContext = destroy_context; 226 pAdapt->CreateSurface = create_surface; 227 pAdapt->DestroySurface = destroy_surface; 228 pAdapt->CreateSubpicture = create_subpicture; 229 pAdapt->DestroySubpicture = destroy_subpicture; 230 231 if (IS_GEN3(intel)) { 232 name = "i915_xvmc", 233 pAdapt->num_surfaces = ARRAY_SIZE(surface_info_i915); 234 pAdapt->surfaces = surface_info_i915; 235 } else if (INTEL_INFO(intel)->gen >= 045) { 236 name = "xvmc_vld", 237 pAdapt->num_surfaces = ARRAY_SIZE(surface_info_vld); 238 pAdapt->surfaces = surface_info_vld; 239 } else { 240 name = "i965_xvmc", 241 pAdapt->num_surfaces = ARRAY_SIZE(surface_info_i965); 242 pAdapt->surfaces = surface_info_i965; 243 } 244 245 if (xf86XvMCScreenInit(pScreen, 1, &pAdapt)) { 246 xf86DrvMsg(scrn->scrnIndex, X_INFO, 247 "[XvMC] %s driver initialized.\n", 248 name); 249 } else { 250 intel->XvMCEnabled = FALSE; 251 xf86DrvMsg(scrn->scrnIndex, X_INFO, 252 "[XvMC] Failed to initialize XvMC.\n"); 253 return FALSE; 254 } 255 256 sprintf(buf, "pci:%04x:%02x:%02x.%d", 257 pci->domain, pci->bus, pci->dev, pci->func); 258 259 xf86XvMCRegisterDRInfo(pScreen, INTEL_XVMC_LIBNAME, 260 buf, 261 INTEL_XVMC_MAJOR, INTEL_XVMC_MINOR, 262 INTEL_XVMC_PATCHLEVEL); 263 return TRUE; 264} 265