103b705cfSriastradh/* 203b705cfSriastradh * Copyright © 2007 Intel Corporation 303b705cfSriastradh * 403b705cfSriastradh * Permission is hereby granted, free of charge, to any person obtaining a 503b705cfSriastradh * copy of this software and associated documentation files (the "Software"), 603b705cfSriastradh * to deal in the Software without restriction, including without limitation 703b705cfSriastradh * the rights to use, copy, modify, merge, publish, distribute, sublicense, 803b705cfSriastradh * and/or sell copies of the Software, and to permit persons to whom the 903b705cfSriastradh * Software is furnished to do so, subject to the following conditions: 1003b705cfSriastradh * 1103b705cfSriastradh * The above copyright notice and this permission notice (including the next 1203b705cfSriastradh * paragraph) shall be included in all copies or substantial portions of the 1303b705cfSriastradh * Software. 1403b705cfSriastradh * 1503b705cfSriastradh * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1603b705cfSriastradh * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1703b705cfSriastradh * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1803b705cfSriastradh * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 1903b705cfSriastradh * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 2003b705cfSriastradh * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 2103b705cfSriastradh * SOFTWARE. 2203b705cfSriastradh * 2303b705cfSriastradh * Authors: 2403b705cfSriastradh * Zhenyu Wang <zhenyu.z.wang@intel.com> 2503b705cfSriastradh * 2603b705cfSriastradh */ 2703b705cfSriastradh#ifdef HAVE_CONFIG_H 2803b705cfSriastradh#include "config.h" 2903b705cfSriastradh#endif 3003b705cfSriastradh 3103b705cfSriastradh#define _INTEL_XVMC_SERVER_ 3203b705cfSriastradh#include "intel.h" 3303b705cfSriastradh#include "intel_xvmc.h" 3403b705cfSriastradh 3503b705cfSriastradh#include <X11/extensions/Xv.h> 3603b705cfSriastradh#include <X11/extensions/XvMC.h> 3703b705cfSriastradh#include <fourcc.h> 3803b705cfSriastradh 3903b705cfSriastradhstatic int create_subpicture(ScrnInfoPtr scrn, XvMCSubpicturePtr subpicture, 4003b705cfSriastradh int *num_priv, CARD32 ** priv) 4103b705cfSriastradh{ 4203b705cfSriastradh return Success; 4303b705cfSriastradh} 4403b705cfSriastradh 4503b705cfSriastradhstatic void destroy_subpicture(ScrnInfoPtr scrn, XvMCSubpicturePtr subpicture) 4603b705cfSriastradh{ 4703b705cfSriastradh} 4803b705cfSriastradh 4903b705cfSriastradhstatic int create_surface(ScrnInfoPtr scrn, XvMCSurfacePtr surface, 5003b705cfSriastradh int *num_priv, CARD32 ** priv) 5103b705cfSriastradh{ 5203b705cfSriastradh return Success; 5303b705cfSriastradh} 5403b705cfSriastradh 5503b705cfSriastradhstatic void destroy_surface(ScrnInfoPtr scrn, XvMCSurfacePtr surface) 5603b705cfSriastradh{ 5703b705cfSriastradh} 5803b705cfSriastradh 5903b705cfSriastradhstatic int create_context(ScrnInfoPtr scrn, XvMCContextPtr pContext, 6003b705cfSriastradh int *num_priv, CARD32 **priv) 6103b705cfSriastradh{ 6203b705cfSriastradh intel_screen_private *intel = intel_get_screen_private(scrn); 6303b705cfSriastradh struct intel_xvmc_hw_context *contextRec; 6403b705cfSriastradh 6503b705cfSriastradh *priv = calloc(1, sizeof(struct intel_xvmc_hw_context)); 6603b705cfSriastradh contextRec = (struct intel_xvmc_hw_context *) *priv; 6703b705cfSriastradh if (!contextRec) { 6803b705cfSriastradh *num_priv = 0; 6903b705cfSriastradh return BadAlloc; 7003b705cfSriastradh } 7103b705cfSriastradh 7203b705cfSriastradh *num_priv = sizeof(struct intel_xvmc_hw_context) >> 2; 7303b705cfSriastradh 7403b705cfSriastradh if (IS_GEN3(intel)) { 7503b705cfSriastradh contextRec->type = XVMC_I915_MPEG2_MC; 7603b705cfSriastradh contextRec->i915.use_phys_addr = 0; 7703b705cfSriastradh } else { 7803b705cfSriastradh if (INTEL_INFO(intel)->gen >= 045) 7903b705cfSriastradh contextRec->type = XVMC_I965_MPEG2_VLD; 8003b705cfSriastradh else 8103b705cfSriastradh contextRec->type = XVMC_I965_MPEG2_MC; 8203b705cfSriastradh contextRec->i965.is_g4x = INTEL_INFO(intel)->gen == 045; 8303b705cfSriastradh contextRec->i965.is_965_q = IS_965_Q(intel); 8403b705cfSriastradh contextRec->i965.is_igdng = IS_GEN5(intel); 8503b705cfSriastradh } 8603b705cfSriastradh 8703b705cfSriastradh return Success; 8803b705cfSriastradh} 8903b705cfSriastradh 9003b705cfSriastradhstatic void destroy_context(ScrnInfoPtr scrn, XvMCContextPtr context) 9103b705cfSriastradh{ 9203b705cfSriastradh} 9303b705cfSriastradh 9403b705cfSriastradh/* i915 hwmc support */ 9503b705cfSriastradhstatic XF86MCSurfaceInfoRec i915_YV12_mpg2_surface = { 9603b705cfSriastradh FOURCC_YV12, 9703b705cfSriastradh XVMC_CHROMA_FORMAT_420, 9803b705cfSriastradh 0, 9903b705cfSriastradh 720, 10003b705cfSriastradh 576, 10103b705cfSriastradh 720, 10203b705cfSriastradh 576, 10303b705cfSriastradh XVMC_MPEG_2, 10403b705cfSriastradh /* XVMC_OVERLAID_SURFACE | XVMC_SUBPICTURE_INDEPENDENT_SCALING, */ 10503b705cfSriastradh 0, 10603b705cfSriastradh /* &yv12_subpicture_list */ 10703b705cfSriastradh NULL, 10803b705cfSriastradh}; 10903b705cfSriastradh 11003b705cfSriastradhstatic XF86MCSurfaceInfoRec i915_YV12_mpg1_surface = { 11103b705cfSriastradh FOURCC_YV12, 11203b705cfSriastradh XVMC_CHROMA_FORMAT_420, 11303b705cfSriastradh 0, 11403b705cfSriastradh 720, 11503b705cfSriastradh 576, 11603b705cfSriastradh 720, 11703b705cfSriastradh 576, 11803b705cfSriastradh XVMC_MPEG_1, 11903b705cfSriastradh /* XVMC_OVERLAID_SURFACE | XVMC_SUBPICTURE_INDEPENDENT_SCALING, */ 12003b705cfSriastradh 0, 12103b705cfSriastradh NULL, 12203b705cfSriastradh}; 12303b705cfSriastradh 12403b705cfSriastradhstatic XF86MCSurfaceInfoPtr surface_info_i915[2] = { 12503b705cfSriastradh (XF86MCSurfaceInfoPtr) & i915_YV12_mpg2_surface, 12603b705cfSriastradh (XF86MCSurfaceInfoPtr) & i915_YV12_mpg1_surface 12703b705cfSriastradh}; 12803b705cfSriastradh 12903b705cfSriastradh/* i965 and later hwmc support */ 13003b705cfSriastradh#ifndef XVMC_VLD 13103b705cfSriastradh#define XVMC_VLD 0x00020000 13203b705cfSriastradh#endif 13303b705cfSriastradh 13403b705cfSriastradhstatic XF86MCSurfaceInfoRec yv12_mpeg2_vld_surface = { 13503b705cfSriastradh FOURCC_YV12, 13603b705cfSriastradh XVMC_CHROMA_FORMAT_420, 13703b705cfSriastradh 0, 13803b705cfSriastradh 1936, 13903b705cfSriastradh 1096, 14003b705cfSriastradh 1920, 14103b705cfSriastradh 1080, 14203b705cfSriastradh XVMC_MPEG_2 | XVMC_VLD, 14303b705cfSriastradh XVMC_INTRA_UNSIGNED, 14403b705cfSriastradh NULL 14503b705cfSriastradh}; 14603b705cfSriastradh 14703b705cfSriastradhstatic XF86MCSurfaceInfoRec yv12_mpeg2_i965_surface = { 14803b705cfSriastradh FOURCC_YV12, 14903b705cfSriastradh XVMC_CHROMA_FORMAT_420, 15003b705cfSriastradh 0, 15103b705cfSriastradh 1936, 15203b705cfSriastradh 1096, 15303b705cfSriastradh 1920, 15403b705cfSriastradh 1080, 15503b705cfSriastradh XVMC_MPEG_2 | XVMC_MOCOMP, 15603b705cfSriastradh /* XVMC_OVERLAID_SURFACE | XVMC_SUBPICTURE_INDEPENDENT_SCALING, */ 15703b705cfSriastradh XVMC_INTRA_UNSIGNED, 15803b705cfSriastradh /* &yv12_subpicture_list */ 15903b705cfSriastradh NULL 16003b705cfSriastradh}; 16103b705cfSriastradh 16203b705cfSriastradhstatic XF86MCSurfaceInfoRec yv12_mpeg1_i965_surface = { 16303b705cfSriastradh FOURCC_YV12, 16403b705cfSriastradh XVMC_CHROMA_FORMAT_420, 16503b705cfSriastradh 0, 16603b705cfSriastradh 1920, 16703b705cfSriastradh 1080, 16803b705cfSriastradh 1920, 16903b705cfSriastradh 1080, 17003b705cfSriastradh XVMC_MPEG_1 | XVMC_MOCOMP, 17103b705cfSriastradh /*XVMC_OVERLAID_SURFACE | XVMC_SUBPICTURE_INDEPENDENT_SCALING | 17203b705cfSriastradh XVMC_INTRA_UNSIGNED, */ 17303b705cfSriastradh XVMC_INTRA_UNSIGNED, 17403b705cfSriastradh 17503b705cfSriastradh /*&yv12_subpicture_list */ 17603b705cfSriastradh NULL 17703b705cfSriastradh}; 17803b705cfSriastradh 17903b705cfSriastradhstatic XF86MCSurfaceInfoPtr surface_info_i965[] = { 18003b705cfSriastradh &yv12_mpeg2_i965_surface, 18103b705cfSriastradh &yv12_mpeg1_i965_surface 18203b705cfSriastradh}; 18303b705cfSriastradh 18403b705cfSriastradhstatic XF86MCSurfaceInfoPtr surface_info_vld[] = { 18503b705cfSriastradh &yv12_mpeg2_vld_surface, 18603b705cfSriastradh &yv12_mpeg2_i965_surface, 18703b705cfSriastradh}; 18803b705cfSriastradh 18903b705cfSriastradh/* check chip type and load xvmc driver */ 19003b705cfSriastradhBool intel_xvmc_adaptor_init(ScreenPtr pScreen) 19103b705cfSriastradh{ 19203b705cfSriastradh ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen); 19303b705cfSriastradh intel_screen_private *intel = intel_get_screen_private(scrn); 19413496ba1Ssnj struct pci_device *pci; 19503b705cfSriastradh static XF86MCAdaptorRec *pAdapt; 196fe8aea9eSmrg const char *name; 19703b705cfSriastradh char buf[64]; 19803b705cfSriastradh 19903b705cfSriastradh if (!intel->XvMCEnabled) 20003b705cfSriastradh return FALSE; 20103b705cfSriastradh 20203b705cfSriastradh /* Needs KMS support. */ 20303b705cfSriastradh if (IS_I915G(intel) || IS_I915GM(intel)) 20403b705cfSriastradh return FALSE; 20503b705cfSriastradh 20603b705cfSriastradh if (IS_GEN2(intel)) { 20703b705cfSriastradh ErrorF("Your chipset doesn't support XvMC.\n"); 20803b705cfSriastradh return FALSE; 20903b705cfSriastradh } 21003b705cfSriastradh 21113496ba1Ssnj pci = xf86GetPciInfoForEntity(intel->pEnt->index); 21213496ba1Ssnj if (pci == NULL) 21313496ba1Ssnj return FALSE; 21413496ba1Ssnj 21503b705cfSriastradh pAdapt = calloc(1, sizeof(XF86MCAdaptorRec)); 21603b705cfSriastradh if (!pAdapt) { 21703b705cfSriastradh ErrorF("Allocation error.\n"); 21803b705cfSriastradh return FALSE; 21903b705cfSriastradh } 22003b705cfSriastradh 22103b705cfSriastradh pAdapt->name = "Intel(R) Textured Video"; 22203b705cfSriastradh pAdapt->num_subpictures = 0; 22303b705cfSriastradh pAdapt->subpictures = NULL; 22403b705cfSriastradh pAdapt->CreateContext = create_context; 22503b705cfSriastradh pAdapt->DestroyContext = destroy_context; 22603b705cfSriastradh pAdapt->CreateSurface = create_surface; 22703b705cfSriastradh pAdapt->DestroySurface = destroy_surface; 22803b705cfSriastradh pAdapt->CreateSubpicture = create_subpicture; 22903b705cfSriastradh pAdapt->DestroySubpicture = destroy_subpicture; 23003b705cfSriastradh 23103b705cfSriastradh if (IS_GEN3(intel)) { 23203b705cfSriastradh name = "i915_xvmc", 23303b705cfSriastradh pAdapt->num_surfaces = ARRAY_SIZE(surface_info_i915); 23403b705cfSriastradh pAdapt->surfaces = surface_info_i915; 23503b705cfSriastradh } else if (INTEL_INFO(intel)->gen >= 045) { 23603b705cfSriastradh name = "xvmc_vld", 23703b705cfSriastradh pAdapt->num_surfaces = ARRAY_SIZE(surface_info_vld); 23803b705cfSriastradh pAdapt->surfaces = surface_info_vld; 23903b705cfSriastradh } else { 24003b705cfSriastradh name = "i965_xvmc", 24103b705cfSriastradh pAdapt->num_surfaces = ARRAY_SIZE(surface_info_i965); 24203b705cfSriastradh pAdapt->surfaces = surface_info_i965; 24303b705cfSriastradh } 24403b705cfSriastradh 24503b705cfSriastradh if (xf86XvMCScreenInit(pScreen, 1, &pAdapt)) { 24603b705cfSriastradh xf86DrvMsg(scrn->scrnIndex, X_INFO, 24703b705cfSriastradh "[XvMC] %s driver initialized.\n", 24803b705cfSriastradh name); 24903b705cfSriastradh } else { 25003b705cfSriastradh intel->XvMCEnabled = FALSE; 25103b705cfSriastradh xf86DrvMsg(scrn->scrnIndex, X_INFO, 25203b705cfSriastradh "[XvMC] Failed to initialize XvMC.\n"); 25303b705cfSriastradh return FALSE; 25403b705cfSriastradh } 25503b705cfSriastradh 25603b705cfSriastradh sprintf(buf, "pci:%04x:%02x:%02x.%d", 25713496ba1Ssnj pci->domain, pci->bus, pci->dev, pci->func); 25803b705cfSriastradh 25903b705cfSriastradh xf86XvMCRegisterDRInfo(pScreen, INTEL_XVMC_LIBNAME, 26003b705cfSriastradh buf, 26103b705cfSriastradh INTEL_XVMC_MAJOR, INTEL_XVMC_MINOR, 26203b705cfSriastradh INTEL_XVMC_PATCHLEVEL); 26303b705cfSriastradh return TRUE; 26403b705cfSriastradh} 265