sna_video_hwmc.c revision 03b705cf
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@sna.com> 25 * 26 */ 27#ifdef HAVE_CONFIG_H 28#include "config.h" 29#endif 30 31#define _SNA_XVMC_SERVER_ 32#include "sna.h" 33#include "sna_video_hwmc.h" 34 35#include <X11/extensions/Xv.h> 36#include <X11/extensions/XvMC.h> 37#include <fourcc.h> 38 39extern DevPrivateKey XF86XvScreenKey; 40 41static int create_subpicture(XvMCSubpicturePtr sub, int *size, CARD32 **priv) 42{ 43 return Success; 44} 45 46static void destroy_subpicture(XvMCSubpicturePtr sub) 47{ 48} 49 50static int create_surface(XvMCSurfacePtr surface, int *size, CARD32 **priv) 51{ 52 return Success; 53} 54 55static void destroy_surface(XvMCSurfacePtr surface) 56{ 57} 58 59static int create_context(XvPortPtr port, XvMCContextPtr ctx, 60 int *size, CARD32 **out) 61{ 62 struct sna *sna = to_sna_from_screen(ctx->pScreen); 63 struct intel_xvmc_hw_context { 64 unsigned int type; 65 union { 66 struct { 67 unsigned int use_phys_addr : 1; 68 } i915; 69 struct { 70 unsigned int is_g4x:1; 71 unsigned int is_965_q:1; 72 unsigned int is_igdng:1; 73 } i965; 74 }; 75 } *priv; 76 77 ctx->port_priv = port->devPriv.ptr; 78 79 priv = calloc(1, sizeof(*priv)); 80 if (priv == NULL) 81 return BadAlloc; 82 83 if (sna->kgem.gen >= 040) { 84 if (sna->kgem.gen >= 045) 85 priv->type = XVMC_I965_MPEG2_VLD; 86 else 87 priv->type = XVMC_I965_MPEG2_MC; 88 priv->i965.is_g4x = sna->kgem.gen == 045; 89 priv->i965.is_965_q = sna->PciInfo->device_id == PCI_CHIP_I965_Q; 90 priv->i965.is_igdng = sna->kgem.gen == 050; 91 } else 92 priv->type = XVMC_I915_MPEG2_MC; 93 94 *size = sizeof(*priv) >> 2; 95 *out = (CARD32 *)priv; 96 return Success; 97} 98 99static void destroy_context(XvMCContextPtr ctx) 100{ 101} 102 103/* i915 hwmc support */ 104static XvMCSurfaceInfoRec i915_YV12_mpg2_surface = { 105 FOURCC_YV12, 106 XVMC_CHROMA_FORMAT_420, 107 0, 108 720, 109 576, 110 720, 111 576, 112 XVMC_MPEG_2, 113 /* XVMC_OVERLAID_SURFACE | XVMC_SUBPICTURE_INDEPENDENT_SCALING, */ 114 0, 115 /* &yv12_subpicture_list */ 116 NULL, 117}; 118 119static XvMCSurfaceInfoRec i915_YV12_mpg1_surface = { 120 FOURCC_YV12, 121 XVMC_CHROMA_FORMAT_420, 122 0, 123 720, 124 576, 125 720, 126 576, 127 XVMC_MPEG_1, 128 /* XVMC_OVERLAID_SURFACE | XVMC_SUBPICTURE_INDEPENDENT_SCALING, */ 129 0, 130 NULL, 131}; 132 133static XvMCSurfaceInfoPtr surface_info_i915[2] = { 134 &i915_YV12_mpg2_surface, 135 &i915_YV12_mpg1_surface 136}; 137 138/* i965 and later hwmc support */ 139#ifndef XVMC_VLD 140#define XVMC_VLD 0x00020000 141#endif 142 143static XvMCSurfaceInfoRec yv12_mpeg2_vld_surface = { 144 FOURCC_YV12, 145 XVMC_CHROMA_FORMAT_420, 146 0, 147 1936, 148 1096, 149 1920, 150 1080, 151 XVMC_MPEG_2 | XVMC_VLD, 152 XVMC_INTRA_UNSIGNED, 153 NULL 154}; 155 156static XvMCSurfaceInfoRec yv12_mpeg2_i965_surface = { 157 FOURCC_YV12, 158 XVMC_CHROMA_FORMAT_420, 159 0, 160 1936, 161 1096, 162 1920, 163 1080, 164 XVMC_MPEG_2 | XVMC_MOCOMP, 165 /* XVMC_OVERLAID_SURFACE | XVMC_SUBPICTURE_INDEPENDENT_SCALING, */ 166 XVMC_INTRA_UNSIGNED, 167 /* &yv12_subpicture_list */ 168 NULL 169}; 170 171static XvMCSurfaceInfoRec yv12_mpeg1_i965_surface = { 172 FOURCC_YV12, 173 XVMC_CHROMA_FORMAT_420, 174 0, 175 1920, 176 1080, 177 1920, 178 1080, 179 XVMC_MPEG_1 | XVMC_MOCOMP, 180 /*XVMC_OVERLAID_SURFACE | XVMC_SUBPICTURE_INDEPENDENT_SCALING | 181 XVMC_INTRA_UNSIGNED, */ 182 XVMC_INTRA_UNSIGNED, 183 184 /*&yv12_subpicture_list */ 185 NULL 186}; 187 188static XvMCSurfaceInfoPtr surface_info_i965[] = { 189 &yv12_mpeg2_i965_surface, 190 &yv12_mpeg1_i965_surface 191}; 192 193static XvMCSurfaceInfoPtr surface_info_vld[] = { 194 &yv12_mpeg2_vld_surface, 195 &yv12_mpeg2_i965_surface, 196}; 197 198/* check chip type and load xvmc driver */ 199void sna_video_xvmc_setup(struct sna *sna, ScreenPtr screen) 200{ 201 XvMCAdaptorRec *adaptors; 202 const char *name; 203 char bus[64]; 204 int i; 205 206 if (!sna->xv.num_adaptors) 207 return; 208 209 if (!xf86LoaderCheckSymbol("XvMCScreenInit")) 210 return; 211 212 /* Needs KMS support. */ 213 if (sna->kgem.gen < 031) 214 return; 215 216 /* Not implemented */ 217 if (sna->kgem.gen >= 060) 218 return; 219 220 adaptors = calloc(sna->xv.num_adaptors, sizeof(XvMCAdaptorRec)); 221 if (adaptors == NULL) 222 return; 223 224 for (i = 0; i< sna->xv.num_adaptors; i++) { 225 adaptors[i].xv_adaptor = &sna->xv.adaptors[i]; 226 227 adaptors[i].num_subpictures = 0; 228 adaptors[i].subpictures = NULL; 229 adaptors[i].CreateContext = create_context; 230 adaptors[i].DestroyContext = destroy_context; 231 adaptors[i].CreateSurface = create_surface; 232 adaptors[i].DestroySurface = destroy_surface; 233 adaptors[i].CreateSubpicture = create_subpicture; 234 adaptors[i].DestroySubpicture = destroy_subpicture; 235 236 if (sna->kgem.gen >= 045) { 237 adaptors[i].num_surfaces = ARRAY_SIZE(surface_info_vld); 238 adaptors[i].surfaces = surface_info_vld; 239 } else if (sna->kgem.gen >= 040) { 240 adaptors[i].num_surfaces = ARRAY_SIZE(surface_info_i965); 241 adaptors[i].surfaces = surface_info_i965; 242 } else { 243 adaptors[i].num_surfaces = ARRAY_SIZE(surface_info_i915); 244 adaptors[i].surfaces = surface_info_i915; 245 } 246 } 247 248 if (XvMCScreenInit(screen, i, adaptors) != Success) { 249 xf86DrvMsg(sna->scrn->scrnIndex, X_INFO, 250 "[XvMC] Failed to initialize XvMC.\n"); 251 free(adaptors); 252 return; 253 } 254 255 sprintf(bus, "pci:%04x:%02x:%02x.%d", 256 sna->PciInfo->domain, 257 sna->PciInfo->bus, sna->PciInfo->dev, sna->PciInfo->func); 258 259 xf86XvMCRegisterDRInfo(screen, (char *)SNA_XVMC_LIBNAME, bus, 260 SNA_XVMC_MAJOR, SNA_XVMC_MINOR, 261 SNA_XVMC_PATCHLEVEL); 262 263 if (sna->kgem.gen >= 045) 264 name = "xvmc_vld"; 265 else if (sna->kgem.gen >= 040) 266 name = "i965_xvmc"; 267 else 268 name = "i915_xvmc"; 269 xf86DrvMsg(sna->scrn->scrnIndex, X_INFO, 270 "[XvMC] %s driver initialized.\n", 271 name); 272} 273