1fa225cbcSrjs/* 2fa225cbcSrjs * Copyright © 2008 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 * Author: 24fa225cbcSrjs * Zou Nan hai <nanhai.zou@intel.com> 25fa225cbcSrjs * 26fa225cbcSrjs */ 27fa225cbcSrjs#ifdef HAVE_CONFIG_H 28fa225cbcSrjs#include "config.h" 29fa225cbcSrjs#endif 30fa225cbcSrjs 31fa225cbcSrjs#include <X11/extensions/Xv.h> 32fa225cbcSrjs#include <X11/extensions/XvMC.h> 33fa225cbcSrjs#include <fourcc.h> 34fa225cbcSrjs#include <errno.h> 35fa225cbcSrjs 36fa225cbcSrjs#include "i830.h" 37fa225cbcSrjs#include "i830_dri.h" 38fa225cbcSrjs#define _INTEL_XVMC_SERVER_ 39fa225cbcSrjs#include "i830_hwmc.h" 40fa225cbcSrjs#include "i965_hwmc.h" 41fa225cbcSrjs#include "intel_bufmgr.h" 42fa225cbcSrjs 43fa225cbcSrjs#define STRIDE(w) (w) 44fa225cbcSrjs#define SIZE_YUV420(w, h) (h * (STRIDE(w) + STRIDE(w >> 1))) 45fa225cbcSrjs#define VLD_MAX_SLICE_LEN (32*1024) 46fa225cbcSrjs 47fa225cbcSrjs#ifndef XVMC_VLD 48fa225cbcSrjs#define XVMC_VLD 0x00020000 49fa225cbcSrjs#endif 50fa225cbcSrjs 51fa225cbcSrjsstatic PutImageFuncPtr XvPutImage; 52fa225cbcSrjs 53fa225cbcSrjs 54fa225cbcSrjsstatic int create_context(ScrnInfoPtr pScrn, 55fa225cbcSrjs XvMCContextPtr context, int *num_privates, CARD32 **private) 56fa225cbcSrjs{ 57fa225cbcSrjs struct i965_xvmc_context *private_context, *context_dup; 58fa225cbcSrjs I830Ptr I830 = I830PTR(pScrn); 59fa225cbcSrjs 60fa225cbcSrjs unsigned int blocknum = 61fa225cbcSrjs (((context->width + 15)/16)*((context->height+15)/16)); 62fa225cbcSrjs unsigned int blocksize = 6*blocknum*64*sizeof(short); 63fa225cbcSrjs blocksize = (blocksize + 4095)&(~4095); 64fa225cbcSrjs if ((private_context = Xcalloc(sizeof(*private_context))) == NULL) { 65fa225cbcSrjs ErrorF("XVMC Can not allocate private context\n"); 66fa225cbcSrjs return BadAlloc; 67fa225cbcSrjs } 68fa225cbcSrjs 69fa225cbcSrjs if ((context_dup = Xcalloc(sizeof(*private_context))) == NULL) { 70fa225cbcSrjs ErrorF("XVMC Can not allocate private context\n"); 71fa225cbcSrjs return BadAlloc; 72fa225cbcSrjs } 73fa225cbcSrjs 74fa225cbcSrjs private_context->is_g4x = IS_G4X(I830); 75fa225cbcSrjs private_context->is_965_q = IS_965_Q(I830); 76fa225cbcSrjs private_context->is_igdng = IS_IGDNG(I830); 77fa225cbcSrjs private_context->comm.kernel_exec_fencing = I830->kernel_exec_fencing; 78fa225cbcSrjs private_context->comm.type = xvmc_driver->flag; 79fa225cbcSrjs 80fa225cbcSrjs *num_privates = sizeof(*private_context)/sizeof(CARD32); 81fa225cbcSrjs *private = (CARD32 *)private_context; 82fa225cbcSrjs memcpy(context_dup, private_context, sizeof(*private_context)); 83fa225cbcSrjs context->driver_priv = context_dup; 84fa225cbcSrjs 85fa225cbcSrjs return Success; 86fa225cbcSrjs} 87fa225cbcSrjs 88fa225cbcSrjsstatic void destroy_context(ScrnInfoPtr pScrn, XvMCContextPtr context) 89fa225cbcSrjs{ 90fa225cbcSrjs struct i965_xvmc_context *private_context; 91fa225cbcSrjs private_context = context->driver_priv; 92fa225cbcSrjs Xfree(private_context); 93fa225cbcSrjs} 94fa225cbcSrjs 95fa225cbcSrjsstatic int create_surface(ScrnInfoPtr pScrn, XvMCSurfacePtr surface, 96fa225cbcSrjs int *num_priv, CARD32 **priv) 97fa225cbcSrjs{ 98fa225cbcSrjs XvMCContextPtr ctx = surface->context; 99fa225cbcSrjs 100fa225cbcSrjs struct i965_xvmc_surface *priv_surface, *surface_dup; 101fa225cbcSrjs struct i965_xvmc_context *priv_ctx = ctx->driver_priv; 102fa225cbcSrjs int i; 103fa225cbcSrjs for (i = 0 ; i < I965_MAX_SURFACES; i++) { 104fa225cbcSrjs if (priv_ctx->surfaces[i] == NULL) { 105fa225cbcSrjs priv_surface = Xcalloc(sizeof(*priv_surface)); 106fa225cbcSrjs if (priv_surface == NULL) 107fa225cbcSrjs return BadAlloc; 108fa225cbcSrjs surface_dup = Xcalloc(sizeof(*priv_surface)); 109fa225cbcSrjs if (surface_dup == NULL) 110fa225cbcSrjs return BadAlloc; 111fa225cbcSrjs 112fa225cbcSrjs priv_surface->no = i; 113fa225cbcSrjs priv_surface->handle = priv_surface; 114fa225cbcSrjs priv_surface->w = ctx->width; 115fa225cbcSrjs priv_surface->h = ctx->height; 116fa225cbcSrjs priv_ctx->surfaces[i] = surface->driver_priv 117fa225cbcSrjs = priv_surface; 118fa225cbcSrjs memcpy(surface_dup, priv_surface, sizeof(*priv_surface)); 119fa225cbcSrjs *num_priv = sizeof(*priv_surface)/sizeof(CARD32); 120fa225cbcSrjs *priv = (CARD32 *)surface_dup; 121fa225cbcSrjs break; 122fa225cbcSrjs } 123fa225cbcSrjs } 124fa225cbcSrjs 125fa225cbcSrjs if (i >= I965_MAX_SURFACES) { 126fa225cbcSrjs ErrorF("I965 XVMC too many surfaces in one context\n"); 127fa225cbcSrjs return BadAlloc; 128fa225cbcSrjs } 129fa225cbcSrjs 130fa225cbcSrjs return Success; 131fa225cbcSrjs} 132fa225cbcSrjs 133fa225cbcSrjsstatic void destory_surface(ScrnInfoPtr pScrn, XvMCSurfacePtr surface) 134fa225cbcSrjs{ 135fa225cbcSrjs XvMCContextPtr ctx = surface->context; 136fa225cbcSrjs struct i965_xvmc_surface *priv_surface = surface->driver_priv; 137fa225cbcSrjs struct i965_xvmc_context *priv_ctx = ctx->driver_priv; 138fa225cbcSrjs priv_ctx->surfaces[priv_surface->no] = NULL; 139fa225cbcSrjs Xfree(priv_surface); 140fa225cbcSrjs} 141fa225cbcSrjs 142fa225cbcSrjsstatic int create_subpicture(ScrnInfoPtr pScrn, XvMCSubpicturePtr subpicture, 143fa225cbcSrjs int *num_priv, CARD32 **priv) 144fa225cbcSrjs{ 145fa225cbcSrjs return Success; 146fa225cbcSrjs} 147fa225cbcSrjs 148fa225cbcSrjsstatic void destroy_subpicture(ScrnInfoPtr pScrn, XvMCSubpicturePtr subpicture) 149fa225cbcSrjs{ 150fa225cbcSrjs} 151fa225cbcSrjs 152fa225cbcSrjsstatic int put_image(ScrnInfoPtr pScrn, 153fa225cbcSrjs short src_x, short src_y, 154fa225cbcSrjs short drw_x, short drw_y, short src_w, 155fa225cbcSrjs short src_h, short drw_w, short drw_h, 156fa225cbcSrjs int id, unsigned char *buf, short width, 157fa225cbcSrjs short height, Bool sync, RegionPtr clipBoxes, pointer data, 158fa225cbcSrjs DrawablePtr pDraw) 159fa225cbcSrjs{ 160fa225cbcSrjs I830Ptr pI830 = I830PTR(pScrn); 161fa225cbcSrjs struct intel_xvmc_command *cmd = (struct intel_xvmc_command *)buf; 162fa225cbcSrjs dri_bo *bo; 163fa225cbcSrjs 164fa225cbcSrjs if (id == FOURCC_XVMC) { 165fa225cbcSrjs bo = intel_bo_gem_create_from_name(pI830->bufmgr, "surface", cmd->handle); 166fa225cbcSrjs dri_bo_pin(bo, 0x1000); 167fa225cbcSrjs buf = pI830->FbBase + bo->offset; 168fa225cbcSrjs } 169fa225cbcSrjs XvPutImage(pScrn, src_x, src_y, drw_x, drw_y, src_w, src_h, 170fa225cbcSrjs drw_w, drw_h, id, buf, width, height, sync, clipBoxes, 171fa225cbcSrjs data, pDraw); 172fa225cbcSrjs 173fa225cbcSrjs if (id == FOURCC_XVMC) { 174fa225cbcSrjs dri_bo_unpin(bo); 175fa225cbcSrjs dri_bo_unreference(bo); 176fa225cbcSrjs } 177fa225cbcSrjs 178fa225cbcSrjs return Success; 179fa225cbcSrjs} 180fa225cbcSrjs 181fa225cbcSrjsstatic Bool init(ScrnInfoPtr screen_info, XF86VideoAdaptorPtr adaptor) 182fa225cbcSrjs{ 183fa225cbcSrjs XvPutImage = adaptor->PutImage; 184fa225cbcSrjs adaptor->PutImage = put_image; 185fa225cbcSrjs 186fa225cbcSrjs return TRUE; 187fa225cbcSrjs} 188fa225cbcSrjs 189fa225cbcSrjsstatic void fini(ScrnInfoPtr screen_info) 190fa225cbcSrjs{ 191fa225cbcSrjs} 192fa225cbcSrjs 193fa225cbcSrjsstatic XF86MCSurfaceInfoRec yv12_mpeg2_vld_surface = 194fa225cbcSrjs{ 195fa225cbcSrjs FOURCC_YV12, 196fa225cbcSrjs XVMC_CHROMA_FORMAT_420, 197fa225cbcSrjs 0, 198fa225cbcSrjs 1936, 199fa225cbcSrjs 1096, 200fa225cbcSrjs 1920, 201fa225cbcSrjs 1080, 202fa225cbcSrjs XVMC_MPEG_2|XVMC_VLD, 203fa225cbcSrjs XVMC_INTRA_UNSIGNED, 204fa225cbcSrjs NULL 205fa225cbcSrjs}; 206fa225cbcSrjs 207fa225cbcSrjsstatic XF86MCSurfaceInfoRec yv12_mpeg2_surface = 208fa225cbcSrjs{ 209fa225cbcSrjs FOURCC_YV12, 210fa225cbcSrjs XVMC_CHROMA_FORMAT_420, 211fa225cbcSrjs 0, 212fa225cbcSrjs 1936, 213fa225cbcSrjs 1096, 214fa225cbcSrjs 1920, 215fa225cbcSrjs 1080, 216fa225cbcSrjs XVMC_MPEG_2|XVMC_MOCOMP, 217fa225cbcSrjs /* XVMC_OVERLAID_SURFACE | XVMC_SUBPICTURE_INDEPENDENT_SCALING,*/ 218fa225cbcSrjs XVMC_INTRA_UNSIGNED, 219fa225cbcSrjs /* &yv12_subpicture_list*/ 220fa225cbcSrjs NULL 221fa225cbcSrjs}; 222fa225cbcSrjs 223fa225cbcSrjsstatic XF86MCSurfaceInfoRec yv12_mpeg1_surface = 224fa225cbcSrjs{ 225fa225cbcSrjs FOURCC_YV12, 226fa225cbcSrjs XVMC_CHROMA_FORMAT_420, 227fa225cbcSrjs 0, 228fa225cbcSrjs 1920, 229fa225cbcSrjs 1080, 230fa225cbcSrjs 1920, 231fa225cbcSrjs 1080, 232fa225cbcSrjs XVMC_MPEG_1|XVMC_MOCOMP, 233fa225cbcSrjs /*XVMC_OVERLAID_SURFACE | XVMC_SUBPICTURE_INDEPENDENT_SCALING | 234fa225cbcSrjs XVMC_INTRA_UNSIGNED,*/ 235fa225cbcSrjs XVMC_INTRA_UNSIGNED, 236fa225cbcSrjs 237fa225cbcSrjs /*&yv12_subpicture_list*/ 238fa225cbcSrjs NULL 239fa225cbcSrjs}; 240fa225cbcSrjs 241fa225cbcSrjsstatic XF86MCSurfaceInfoPtr surface_info[] = { 242fa225cbcSrjs &yv12_mpeg2_surface, 243fa225cbcSrjs &yv12_mpeg1_surface 244fa225cbcSrjs}; 245fa225cbcSrjs 246fa225cbcSrjsstatic XF86MCSurfaceInfoPtr surface_info_vld[] = { 247fa225cbcSrjs &yv12_mpeg2_vld_surface, 248fa225cbcSrjs &yv12_mpeg2_surface, 249fa225cbcSrjs}; 250fa225cbcSrjs 251fa225cbcSrjsstatic XF86MCAdaptorRec adaptor_vld = { 252fa225cbcSrjs .name = "Intel(R) Textured Video", 253fa225cbcSrjs .num_surfaces = sizeof(surface_info_vld)/sizeof(surface_info_vld[0]), 254fa225cbcSrjs .surfaces = surface_info_vld, 255fa225cbcSrjs 256fa225cbcSrjs .CreateContext = create_context, 257fa225cbcSrjs .DestroyContext = destroy_context, 258fa225cbcSrjs .CreateSurface = create_surface, 259fa225cbcSrjs .DestroySurface = destory_surface, 260fa225cbcSrjs .CreateSubpicture = create_subpicture, 261fa225cbcSrjs .DestroySubpicture = destroy_subpicture 262fa225cbcSrjs}; 263fa225cbcSrjs 264fa225cbcSrjsstatic XF86MCAdaptorRec adaptor = { 265fa225cbcSrjs .name = "Intel(R) Textured Video", 266fa225cbcSrjs .num_surfaces = sizeof(surface_info)/sizeof(surface_info[0]), 267fa225cbcSrjs .surfaces = surface_info, 268fa225cbcSrjs 269fa225cbcSrjs .CreateContext = create_context, 270fa225cbcSrjs .DestroyContext = destroy_context, 271fa225cbcSrjs .CreateSurface = create_surface, 272fa225cbcSrjs .DestroySurface = destory_surface, 273fa225cbcSrjs .CreateSubpicture = create_subpicture, 274fa225cbcSrjs .DestroySubpicture = destroy_subpicture 275fa225cbcSrjs}; 276fa225cbcSrjs 277fa225cbcSrjsstruct intel_xvmc_driver i965_xvmc_driver = { 278fa225cbcSrjs .name = "i965_xvmc", 279fa225cbcSrjs .adaptor = &adaptor, 280fa225cbcSrjs .flag = XVMC_I965_MPEG2_MC, 281fa225cbcSrjs .init = init, 282fa225cbcSrjs .fini = fini 283fa225cbcSrjs}; 284fa225cbcSrjs 285fa225cbcSrjsstruct intel_xvmc_driver vld_xvmc_driver = { 286fa225cbcSrjs .name = "xvmc_vld", 287fa225cbcSrjs .adaptor = &adaptor_vld, 288fa225cbcSrjs .flag = XVMC_I965_MPEG2_VLD, 289fa225cbcSrjs .init = init, 290fa225cbcSrjs .fini = fini 291fa225cbcSrjs}; 292fa225cbcSrjs 293