1fa225cbcSrjs/* 2fa225cbcSrjs * Copyright © 2006 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 * Authors: 24fa225cbcSrjs * Xiang Haihao <haihao.xiang@intel.com> 25fa225cbcSrjs * 26fa225cbcSrjs */ 27fa225cbcSrjs#ifdef HAVE_CONFIG_H 28fa225cbcSrjs#include "config.h" 29fa225cbcSrjs#endif 30fa225cbcSrjs 31fa225cbcSrjs#include <string.h> 32fa225cbcSrjs 33fa225cbcSrjs#include "xf86.h" 34fa225cbcSrjs#include "xf86_OSproc.h" 35fa225cbcSrjs#include "compiler.h" 36fa225cbcSrjs#include "xf86PciInfo.h" 37fa225cbcSrjs#include "xf86Pci.h" 38fa225cbcSrjs#include "xf86fbman.h" 39fa225cbcSrjs#include "regionstr.h" 40fa225cbcSrjs 41fa225cbcSrjs#include "i830.h" 42fa225cbcSrjs#include "i830_dri.h" 43fa225cbcSrjs#include "i830_video.h" 44fa225cbcSrjs#include "xf86xv.h" 45fa225cbcSrjs#include "xf86xvmc.h" 46fa225cbcSrjs#include <X11/extensions/Xv.h> 47fa225cbcSrjs#include <X11/extensions/XvMC.h> 48fa225cbcSrjs#include "xaa.h" 49fa225cbcSrjs#include "xaalocal.h" 50fa225cbcSrjs#include "dixstruct.h" 51fa225cbcSrjs#include "fourcc.h" 52fa225cbcSrjs 53fa225cbcSrjs#if defined(X_NEED_XVPRIV_H) || defined (_XF86_FOURCC_H_) 54fa225cbcSrjs#include "xf86xvpriv.h" 55fa225cbcSrjs#endif 56fa225cbcSrjs 57fa225cbcSrjs#define _INTEL_XVMC_SERVER_ 58fa225cbcSrjs#include "i915_hwmc.h" 59fa225cbcSrjs 60fa225cbcSrjs#define I915_XVMC_MAX_BUFFERS 2 61fa225cbcSrjs#define I915_XVMC_MAX_CONTEXTS 4 62fa225cbcSrjs#define I915_XVMC_MAX_SURFACES 20 63fa225cbcSrjs 64fa225cbcSrjstypedef struct _I915XvMCSurfacePriv 65fa225cbcSrjs{ 66fa225cbcSrjs i830_memory *surface; 67fa225cbcSrjs unsigned long offsets[I915_XVMC_MAX_BUFFERS]; 68fa225cbcSrjs drm_handle_t surface_handle; 69fa225cbcSrjs} I915XvMCSurfacePriv; 70fa225cbcSrjs 71fa225cbcSrjstypedef struct _I915XvMCContextPriv 72fa225cbcSrjs{ 73fa225cbcSrjs i830_memory *mcStaticIndirectState; 74fa225cbcSrjs drm_handle_t sis_handle; 75fa225cbcSrjs i830_memory *mcSamplerState; 76fa225cbcSrjs drm_handle_t ssb_handle; 77fa225cbcSrjs i830_memory *mcMapState; 78fa225cbcSrjs drm_handle_t msb_handle; 79fa225cbcSrjs i830_memory *mcPixelShaderProgram; 80fa225cbcSrjs drm_handle_t psp_handle; 81fa225cbcSrjs i830_memory *mcPixelShaderConstants; 82fa225cbcSrjs drm_handle_t psc_handle; 83fa225cbcSrjs i830_memory *mcCorrdata; 84fa225cbcSrjs drm_handle_t corrdata_handle; 85fa225cbcSrjs} I915XvMCContextPriv; 86fa225cbcSrjs 87fa225cbcSrjstypedef struct _I915XvMC 88fa225cbcSrjs{ 89fa225cbcSrjs XID contexts[I915_XVMC_MAX_CONTEXTS]; 90fa225cbcSrjs XID surfaces[I915_XVMC_MAX_SURFACES]; 91fa225cbcSrjs I915XvMCSurfacePriv *sfprivs[I915_XVMC_MAX_SURFACES]; 92fa225cbcSrjs I915XvMCContextPriv *ctxprivs[I915_XVMC_MAX_CONTEXTS]; 93fa225cbcSrjs int ncontexts,nsurfaces; 94fa225cbcSrjs PutImageFuncPtr savePutImage; 95fa225cbcSrjs} I915XvMC, *I915XvMCPtr; 96fa225cbcSrjs 97fa225cbcSrjs/* 98fa225cbcSrjsstatic int yv12_subpicture_index_list[2] = 99fa225cbcSrjs{ 100fa225cbcSrjs FOURCC_IA44, 101fa225cbcSrjs FOURCC_AI44 102fa225cbcSrjs}; 103fa225cbcSrjs 104fa225cbcSrjsstatic XF86MCImageIDList yv12_subpicture_list = 105fa225cbcSrjs{ 106fa225cbcSrjs ARRARY_SIZE(yv12_subpicture_index_list), 107fa225cbcSrjs yv12_subpicture_index_list 108fa225cbcSrjs}; 109fa225cbcSrjs */ 110fa225cbcSrjs 111fa225cbcSrjsstatic XF86MCSurfaceInfoRec i915_YV12_mpg2_surface = 112fa225cbcSrjs{ 113fa225cbcSrjs SURFACE_TYPE_MPEG2_MPML, 114fa225cbcSrjs XVMC_CHROMA_FORMAT_420, 115fa225cbcSrjs 0, 116fa225cbcSrjs 720, 117fa225cbcSrjs 576, 118fa225cbcSrjs 720, 119fa225cbcSrjs 576, 120fa225cbcSrjs XVMC_MPEG_2, 121fa225cbcSrjs /* XVMC_OVERLAID_SURFACE | XVMC_SUBPICTURE_INDEPENDENT_SCALING,*/ 122fa225cbcSrjs 0, 123fa225cbcSrjs /* &yv12_subpicture_list*/ 124fa225cbcSrjs NULL, 125fa225cbcSrjs}; 126fa225cbcSrjs 127fa225cbcSrjsstatic XF86MCSurfaceInfoRec i915_YV12_mpg1_surface = 128fa225cbcSrjs{ 129fa225cbcSrjs SURFACE_TYPE_MPEG1_MPML, 130fa225cbcSrjs XVMC_CHROMA_FORMAT_420, 131fa225cbcSrjs 0, 132fa225cbcSrjs 720, 133fa225cbcSrjs 576, 134fa225cbcSrjs 720, 135fa225cbcSrjs 576, 136fa225cbcSrjs XVMC_MPEG_1, 137fa225cbcSrjs /* XVMC_OVERLAID_SURFACE | XVMC_SUBPICTURE_INDEPENDENT_SCALING,*/ 138fa225cbcSrjs 0, 139fa225cbcSrjs /* &yv12_subpicture_list*/ 140fa225cbcSrjs NULL, 141fa225cbcSrjs}; 142fa225cbcSrjs 143fa225cbcSrjsstatic XF86MCSurfaceInfoPtr ppSI[2] = 144fa225cbcSrjs{ 145fa225cbcSrjs (XF86MCSurfaceInfoPtr)&i915_YV12_mpg2_surface, 146fa225cbcSrjs (XF86MCSurfaceInfoPtr)&i915_YV12_mpg1_surface 147fa225cbcSrjs}; 148fa225cbcSrjs 149fa225cbcSrjs#if 0 150fa225cbcSrjs/* List of subpicture types that we support */ 151fa225cbcSrjsstatic XF86ImageRec ia44_subpicture = XVIMAGE_IA44; 152fa225cbcSrjsstatic XF86ImageRec ai44_subpicture = XVIMAGE_AI44; 153fa225cbcSrjs 154fa225cbcSrjsstatic XF86ImagePtr i915_subpicture_list[2] = 155fa225cbcSrjs{ 156fa225cbcSrjs (XF86ImagePtr)&ia44_subpicture, 157fa225cbcSrjs (XF86ImagePtr)&ai44_subpicture 158fa225cbcSrjs}; 159fa225cbcSrjs#endif 160fa225cbcSrjs 161fa225cbcSrjs/* Check context size not exceed surface type max */ 162fa225cbcSrjsstatic void 163fa225cbcSrjsi915_check_context_size(XvMCContextPtr ctx) 164fa225cbcSrjs{ 165fa225cbcSrjs int i; 166fa225cbcSrjs 167fa225cbcSrjs for (i = 0; i < ARRAY_SIZE(ppSI); i++) { 168fa225cbcSrjs if (ctx->surface_type_id == ppSI[i]->surface_type_id) { 169fa225cbcSrjs if (ctx->width > ppSI[i]->max_width) 170fa225cbcSrjs ctx->width = ppSI[i]->max_width; 171fa225cbcSrjs if (ctx->height > ppSI[i]->max_height) 172fa225cbcSrjs ctx->height = ppSI[i]->max_height; 173fa225cbcSrjs } 174fa225cbcSrjs } 175fa225cbcSrjs} 176fa225cbcSrjs 177fa225cbcSrjs/* 178fa225cbcSrjs * Init and clean up the screen private parts of XvMC. 179fa225cbcSrjs */ 180fa225cbcSrjsstatic void initI915XvMC(I915XvMCPtr xvmc) 181fa225cbcSrjs{ 182fa225cbcSrjs unsigned int i; 183fa225cbcSrjs 184fa225cbcSrjs for (i = 0; i < I915_XVMC_MAX_CONTEXTS; i++) { 185fa225cbcSrjs xvmc->contexts[i] = 0; 186fa225cbcSrjs xvmc->ctxprivs[i] = NULL; 187fa225cbcSrjs } 188fa225cbcSrjs 189fa225cbcSrjs for (i = 0; i < I915_XVMC_MAX_SURFACES; i++) { 190fa225cbcSrjs xvmc->surfaces[i] = 0; 191fa225cbcSrjs xvmc->sfprivs[i] = NULL; 192fa225cbcSrjs } 193fa225cbcSrjs xvmc->ncontexts = 0; 194fa225cbcSrjs xvmc->nsurfaces = 0; 195fa225cbcSrjs} 196fa225cbcSrjs 197fa225cbcSrjsstatic void cleanupI915XvMC(I915XvMCPtr xvmc) 198fa225cbcSrjs{ 199fa225cbcSrjs int i; 200fa225cbcSrjs 201fa225cbcSrjs for (i = 0; i < I915_XVMC_MAX_CONTEXTS; i++) { 202fa225cbcSrjs xvmc->contexts[i] = 0; 203fa225cbcSrjs if (xvmc->ctxprivs[i]) { 204fa225cbcSrjs xfree(xvmc->ctxprivs[i]); 205fa225cbcSrjs xvmc->ctxprivs[i] = NULL; 206fa225cbcSrjs } 207fa225cbcSrjs } 208fa225cbcSrjs 209fa225cbcSrjs for (i = 0; i < I915_XVMC_MAX_SURFACES; i++) { 210fa225cbcSrjs xvmc->surfaces[i] = 0; 211fa225cbcSrjs if (xvmc->sfprivs[i]) { 212fa225cbcSrjs xfree(xvmc->sfprivs[i]); 213fa225cbcSrjs xvmc->sfprivs[i] = NULL; 214fa225cbcSrjs } 215fa225cbcSrjs } 216fa225cbcSrjs} 217fa225cbcSrjs 218fa225cbcSrjsstatic Bool i915_map_xvmc_buffers(ScrnInfoPtr pScrn, I915XvMCContextPriv *ctxpriv) 219fa225cbcSrjs{ 220fa225cbcSrjs I830Ptr pI830 = I830PTR(pScrn); 221fa225cbcSrjs 222fa225cbcSrjs if (drmAddMap(pI830->drmSubFD, 223fa225cbcSrjs (drm_handle_t)(ctxpriv->mcStaticIndirectState->offset + pI830->LinearAddr), 224fa225cbcSrjs ctxpriv->mcStaticIndirectState->size, DRM_AGP, 0, 225fa225cbcSrjs (drmAddress)&ctxpriv->sis_handle) < 0) { 226fa225cbcSrjs xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 227fa225cbcSrjs "[drm] drmAddMap(sis_handle) failed!\n"); 228fa225cbcSrjs return FALSE; 229fa225cbcSrjs } 230fa225cbcSrjs 231fa225cbcSrjs if (drmAddMap(pI830->drmSubFD, 232fa225cbcSrjs (drm_handle_t)(ctxpriv->mcSamplerState->offset + pI830->LinearAddr), 233fa225cbcSrjs ctxpriv->mcSamplerState->size, DRM_AGP, 0, 234fa225cbcSrjs (drmAddress)&ctxpriv->ssb_handle) < 0) { 235fa225cbcSrjs xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 236fa225cbcSrjs "[drm] drmAddMap(ssb_handle) failed!\n"); 237fa225cbcSrjs return FALSE; 238fa225cbcSrjs } 239fa225cbcSrjs 240fa225cbcSrjs if (drmAddMap(pI830->drmSubFD, 241fa225cbcSrjs (drm_handle_t)(ctxpriv->mcMapState->offset + pI830->LinearAddr), 242fa225cbcSrjs ctxpriv->mcMapState->size, DRM_AGP, 0, 243fa225cbcSrjs (drmAddress)&ctxpriv->msb_handle) < 0) { 244fa225cbcSrjs xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 245fa225cbcSrjs "[drm] drmAddMap(msb_handle) failed!\n"); 246fa225cbcSrjs return FALSE; 247fa225cbcSrjs } 248fa225cbcSrjs 249fa225cbcSrjs if (drmAddMap(pI830->drmSubFD, 250fa225cbcSrjs (drm_handle_t)(ctxpriv->mcPixelShaderProgram->offset + pI830->LinearAddr), 251fa225cbcSrjs ctxpriv->mcPixelShaderProgram->size, DRM_AGP, 0, 252fa225cbcSrjs (drmAddress)&ctxpriv->psp_handle) < 0) { 253fa225cbcSrjs xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 254fa225cbcSrjs "[drm] drmAddMap(psp_handle) failed!\n"); 255fa225cbcSrjs return FALSE; 256fa225cbcSrjs } 257fa225cbcSrjs 258fa225cbcSrjs if (drmAddMap(pI830->drmSubFD, 259fa225cbcSrjs (drm_handle_t)(ctxpriv->mcPixelShaderConstants->offset + pI830->LinearAddr), 260fa225cbcSrjs ctxpriv->mcPixelShaderConstants->size, DRM_AGP, 0, 261fa225cbcSrjs (drmAddress)&ctxpriv->psc_handle) < 0) { 262fa225cbcSrjs xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 263fa225cbcSrjs "[drm] drmAddMap(psc_handle) failed!\n"); 264fa225cbcSrjs return FALSE; 265fa225cbcSrjs } 266fa225cbcSrjs 267fa225cbcSrjs if (drmAddMap(pI830->drmSubFD, 268fa225cbcSrjs (drm_handle_t)(ctxpriv->mcCorrdata->offset + pI830->LinearAddr), 269fa225cbcSrjs ctxpriv->mcCorrdata->size, DRM_AGP, 0, 270fa225cbcSrjs (drmAddress)&ctxpriv->corrdata_handle) < 0) { 271fa225cbcSrjs xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 272fa225cbcSrjs "[drm] drmAddMap(corrdata_handle) failed!\n"); 273fa225cbcSrjs return FALSE; 274fa225cbcSrjs } 275fa225cbcSrjs 276fa225cbcSrjs 277fa225cbcSrjs return TRUE; 278fa225cbcSrjs} 279fa225cbcSrjs 280fa225cbcSrjsstatic void i915_unmap_xvmc_buffers(ScrnInfoPtr pScrn, I915XvMCContextPriv *ctxpriv) 281fa225cbcSrjs{ 282fa225cbcSrjs I830Ptr pI830 = I830PTR(pScrn); 283fa225cbcSrjs 284fa225cbcSrjs if (ctxpriv->sis_handle) { 285fa225cbcSrjs drmRmMap(pI830->drmSubFD, ctxpriv->sis_handle); 286fa225cbcSrjs ctxpriv->sis_handle = 0; 287fa225cbcSrjs } 288fa225cbcSrjs 289fa225cbcSrjs if (ctxpriv->ssb_handle) { 290fa225cbcSrjs drmRmMap(pI830->drmSubFD, ctxpriv->ssb_handle); 291fa225cbcSrjs ctxpriv->ssb_handle = 0; 292fa225cbcSrjs } 293fa225cbcSrjs 294fa225cbcSrjs if (ctxpriv->msb_handle) { 295fa225cbcSrjs drmRmMap(pI830->drmSubFD, ctxpriv->msb_handle); 296fa225cbcSrjs ctxpriv->msb_handle = 0; 297fa225cbcSrjs } 298fa225cbcSrjs 299fa225cbcSrjs if (ctxpriv->psp_handle) { 300fa225cbcSrjs drmRmMap(pI830->drmSubFD, ctxpriv->psp_handle); 301fa225cbcSrjs ctxpriv->psp_handle = 0; 302fa225cbcSrjs } 303fa225cbcSrjs 304fa225cbcSrjs if (ctxpriv->psc_handle) { 305fa225cbcSrjs drmRmMap(pI830->drmSubFD, ctxpriv->psc_handle); 306fa225cbcSrjs ctxpriv->psc_handle = 0; 307fa225cbcSrjs } 308fa225cbcSrjs 309fa225cbcSrjs if (ctxpriv->corrdata_handle) { 310fa225cbcSrjs drmRmMap(pI830->drmSubFD, ctxpriv->corrdata_handle); 311fa225cbcSrjs ctxpriv->corrdata_handle = 0; 312fa225cbcSrjs } 313fa225cbcSrjs 314fa225cbcSrjs} 315fa225cbcSrjs 316fa225cbcSrjsstatic Bool i915_allocate_xvmc_buffers(ScrnInfoPtr pScrn, I915XvMCContextPriv *ctxpriv) 317fa225cbcSrjs{ 318fa225cbcSrjs I830Ptr pI830 = I830PTR(pScrn); 319fa225cbcSrjs int flags = ALIGN_BOTH_ENDS; 320fa225cbcSrjs 321fa225cbcSrjs /* on 915G/GM, load indirect can only use physical address...sigh */ 322fa225cbcSrjs if (IS_I915G(pI830) || IS_I915GM(pI830)) 323fa225cbcSrjs flags |= NEED_PHYSICAL_ADDR; 324fa225cbcSrjs 325fa225cbcSrjs if (!i830_allocate_xvmc_buffer(pScrn, "[XvMC]Static Indirect State", 326fa225cbcSrjs &(ctxpriv->mcStaticIndirectState), 4 * 1024, 327fa225cbcSrjs flags)) { 328fa225cbcSrjs return FALSE; 329fa225cbcSrjs } 330fa225cbcSrjs 331fa225cbcSrjs if (!i830_allocate_xvmc_buffer(pScrn, "[XvMC]Sampler State", 332fa225cbcSrjs &(ctxpriv->mcSamplerState), 4 * 1024, 333fa225cbcSrjs flags)) { 334fa225cbcSrjs return FALSE; 335fa225cbcSrjs } 336fa225cbcSrjs 337fa225cbcSrjs if (!i830_allocate_xvmc_buffer(pScrn, "[XvMC]Map State", 338fa225cbcSrjs &(ctxpriv->mcMapState), 4 * 1024, 339fa225cbcSrjs flags)) { 340fa225cbcSrjs return FALSE; 341fa225cbcSrjs } 342fa225cbcSrjs 343fa225cbcSrjs if (!i830_allocate_xvmc_buffer(pScrn, "[XvMC]Pixel Shader Program", 344fa225cbcSrjs &(ctxpriv->mcPixelShaderProgram), 4 * 1024, 345fa225cbcSrjs flags)) { 346fa225cbcSrjs return FALSE; 347fa225cbcSrjs } 348fa225cbcSrjs 349fa225cbcSrjs if (!i830_allocate_xvmc_buffer(pScrn, "[XvMC]Pixel Shader Constants", 350fa225cbcSrjs &(ctxpriv->mcPixelShaderConstants), 4 * 1024, 351fa225cbcSrjs flags)) { 352fa225cbcSrjs return FALSE; 353fa225cbcSrjs } 354fa225cbcSrjs 355fa225cbcSrjs if (!i830_allocate_xvmc_buffer(pScrn, "[XvMC]Correction Data Buffer", 356fa225cbcSrjs &(ctxpriv->mcCorrdata), 512 * 1024, 357fa225cbcSrjs ALIGN_BOTH_ENDS)) { 358fa225cbcSrjs return FALSE; 359fa225cbcSrjs } 360fa225cbcSrjs 361fa225cbcSrjs if (1) 362fa225cbcSrjs i830_describe_allocations(pScrn, 1, "i915_mc: "); 363fa225cbcSrjs 364fa225cbcSrjs return TRUE; 365fa225cbcSrjs} 366fa225cbcSrjs 367fa225cbcSrjsstatic void i915_free_xvmc_buffers(ScrnInfoPtr pScrn, I915XvMCContextPriv *ctxpriv) 368fa225cbcSrjs{ 369fa225cbcSrjs if (ctxpriv->mcStaticIndirectState) { 370fa225cbcSrjs i830_free_xvmc_buffer(pScrn, ctxpriv->mcStaticIndirectState); 371fa225cbcSrjs ctxpriv->mcStaticIndirectState = NULL; 372fa225cbcSrjs } 373fa225cbcSrjs 374fa225cbcSrjs if (ctxpriv->mcSamplerState) { 375fa225cbcSrjs i830_free_xvmc_buffer(pScrn, ctxpriv->mcSamplerState); 376fa225cbcSrjs ctxpriv->mcSamplerState = NULL; 377fa225cbcSrjs } 378fa225cbcSrjs 379fa225cbcSrjs if (ctxpriv->mcMapState) { 380fa225cbcSrjs i830_free_xvmc_buffer(pScrn, ctxpriv->mcMapState); 381fa225cbcSrjs ctxpriv->mcMapState = NULL; 382fa225cbcSrjs } 383fa225cbcSrjs 384fa225cbcSrjs if (ctxpriv->mcPixelShaderProgram) { 385fa225cbcSrjs i830_free_xvmc_buffer(pScrn, ctxpriv->mcPixelShaderProgram); 386fa225cbcSrjs ctxpriv->mcPixelShaderProgram = NULL; 387fa225cbcSrjs } 388fa225cbcSrjs 389fa225cbcSrjs if (ctxpriv->mcPixelShaderConstants) { 390fa225cbcSrjs i830_free_xvmc_buffer(pScrn, ctxpriv->mcPixelShaderConstants); 391fa225cbcSrjs ctxpriv->mcPixelShaderConstants = NULL; 392fa225cbcSrjs } 393fa225cbcSrjs 394fa225cbcSrjs if (ctxpriv->mcCorrdata) { 395fa225cbcSrjs i830_free_xvmc_buffer(pScrn, ctxpriv->mcCorrdata); 396fa225cbcSrjs ctxpriv->mcCorrdata = NULL; 397fa225cbcSrjs } 398fa225cbcSrjs 399fa225cbcSrjs} 400fa225cbcSrjs 401fa225cbcSrjs/* 402fa225cbcSrjs * i915_xvmc_create_context 403fa225cbcSrjs * 404fa225cbcSrjs * Some info about the private data: 405fa225cbcSrjs * 406fa225cbcSrjs * Set *num_priv to the number of 32bit words that make up the size of 407fa225cbcSrjs * of the data that priv will point to. 408fa225cbcSrjs * 409fa225cbcSrjs * *priv = (long *) xcalloc (elements, sizeof(element)) 410fa225cbcSrjs * *num_priv = (elements * sizeof(element)) >> 2; 411fa225cbcSrjs * 412fa225cbcSrjs **************************************************************************/ 413fa225cbcSrjs 414fa225cbcSrjsstatic int i915_xvmc_create_context (ScrnInfoPtr pScrn, XvMCContextPtr pContext, 415fa225cbcSrjs int *num_priv, long **priv ) 416fa225cbcSrjs{ 417fa225cbcSrjs I830Ptr pI830 = I830PTR(pScrn); 418fa225cbcSrjs I915XvMCCreateContextRec *contextRec = NULL; 419fa225cbcSrjs I915XvMCPtr pXvMC = (I915XvMCPtr)xvmc_driver->devPrivate; 420fa225cbcSrjs I915XvMCContextPriv *ctxpriv = NULL; 421fa225cbcSrjs int i; 422fa225cbcSrjs 423fa225cbcSrjs *priv = NULL; 424fa225cbcSrjs *num_priv = 0; 425fa225cbcSrjs 426fa225cbcSrjs if (!pI830->XvMCEnabled) { 427fa225cbcSrjs xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 428fa225cbcSrjs "[XvMC] i915: XvMC disabled!\n"); 429fa225cbcSrjs return BadAlloc; 430fa225cbcSrjs } 431fa225cbcSrjs 432fa225cbcSrjs for (i = 0; i < I915_XVMC_MAX_CONTEXTS; i++) { 433fa225cbcSrjs if (!pXvMC->contexts[i]) 434fa225cbcSrjs break; 435fa225cbcSrjs } 436fa225cbcSrjs 437fa225cbcSrjs if (i == I915_XVMC_MAX_CONTEXTS || 438fa225cbcSrjs pXvMC->ncontexts >= I915_XVMC_MAX_CONTEXTS) { 439fa225cbcSrjs xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 440fa225cbcSrjs "[XvMC] i915: Out of contexts.\n"); 441fa225cbcSrjs return BadAlloc; 442fa225cbcSrjs } 443fa225cbcSrjs 444fa225cbcSrjs i915_check_context_size(pContext); 445fa225cbcSrjs 446fa225cbcSrjs *priv = xcalloc(1, sizeof(I915XvMCCreateContextRec)); 447fa225cbcSrjs contextRec = (I915XvMCCreateContextRec *)*priv; 448fa225cbcSrjs 449fa225cbcSrjs if (!*priv) { 450fa225cbcSrjs *num_priv = 0; 451fa225cbcSrjs return BadAlloc; 452fa225cbcSrjs } 453fa225cbcSrjs 454fa225cbcSrjs *num_priv = sizeof(I915XvMCCreateContextRec) >> 2; 455fa225cbcSrjs 456fa225cbcSrjs ctxpriv = (I915XvMCContextPriv *)xcalloc(1, sizeof(I915XvMCContextPriv)); 457fa225cbcSrjs 458fa225cbcSrjs if (!ctxpriv) { 459fa225cbcSrjs xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 460fa225cbcSrjs "[XvMC] i915: Unable to allocate memory!\n"); 461fa225cbcSrjs xfree(*priv); 462fa225cbcSrjs *priv = NULL; 463fa225cbcSrjs *num_priv = 0; 464fa225cbcSrjs return BadAlloc; 465fa225cbcSrjs } 466fa225cbcSrjs 467fa225cbcSrjs if (!i915_allocate_xvmc_buffers(pScrn, ctxpriv)) { 468fa225cbcSrjs i915_free_xvmc_buffers(pScrn, ctxpriv); 469fa225cbcSrjs xfree(ctxpriv); 470fa225cbcSrjs ctxpriv = NULL; 471fa225cbcSrjs xfree(*priv); 472fa225cbcSrjs *priv = NULL; 473fa225cbcSrjs *num_priv = 0; 474fa225cbcSrjs return BadAlloc; 475fa225cbcSrjs } 476fa225cbcSrjs 477fa225cbcSrjs if (!i915_map_xvmc_buffers(pScrn, ctxpriv)) { 478fa225cbcSrjs i915_unmap_xvmc_buffers(pScrn, ctxpriv); 479fa225cbcSrjs i915_free_xvmc_buffers(pScrn, ctxpriv); 480fa225cbcSrjs xfree(ctxpriv); 481fa225cbcSrjs ctxpriv = NULL; 482fa225cbcSrjs xfree(*priv); 483fa225cbcSrjs *priv = NULL; 484fa225cbcSrjs *num_priv = 0; 485fa225cbcSrjs return BadAlloc; 486fa225cbcSrjs } 487fa225cbcSrjs 488fa225cbcSrjs /* common context items */ 489fa225cbcSrjs contextRec->comm.type = xvmc_driver->flag; 490fa225cbcSrjs contextRec->comm.batchbuffer.offset = xvmc_driver->batch->offset; 491fa225cbcSrjs contextRec->comm.batchbuffer.size = xvmc_driver->batch->size; 492fa225cbcSrjs contextRec->comm.batchbuffer.handle = xvmc_driver->batch_handle; 493fa225cbcSrjs 494fa225cbcSrjs /* i915 private context */ 495fa225cbcSrjs contextRec->ctxno = i; 496fa225cbcSrjs contextRec->sis.handle = ctxpriv->sis_handle; 497fa225cbcSrjs contextRec->sis.offset = ctxpriv->mcStaticIndirectState->offset; 498fa225cbcSrjs contextRec->sis.size = ctxpriv->mcStaticIndirectState->size; 499fa225cbcSrjs contextRec->ssb.handle = ctxpriv->ssb_handle; 500fa225cbcSrjs contextRec->ssb.offset = ctxpriv->mcSamplerState->offset; 501fa225cbcSrjs contextRec->ssb.size = ctxpriv->mcSamplerState->size; 502fa225cbcSrjs contextRec->msb.handle = ctxpriv->msb_handle; 503fa225cbcSrjs contextRec->msb.offset = ctxpriv->mcMapState->offset; 504fa225cbcSrjs contextRec->msb.size = ctxpriv->mcMapState->size; 505fa225cbcSrjs contextRec->psp.handle = ctxpriv->psp_handle; 506fa225cbcSrjs contextRec->psp.offset = ctxpriv->mcPixelShaderProgram->offset; 507fa225cbcSrjs contextRec->psp.size = ctxpriv->mcPixelShaderProgram->size; 508fa225cbcSrjs contextRec->psc.handle = ctxpriv->psc_handle; 509fa225cbcSrjs contextRec->psc.offset = ctxpriv->mcPixelShaderConstants->offset; 510fa225cbcSrjs contextRec->psc.size = ctxpriv->mcPixelShaderConstants->size; 511fa225cbcSrjs contextRec->corrdata.handle = ctxpriv->corrdata_handle; 512fa225cbcSrjs contextRec->corrdata.offset = ctxpriv->mcCorrdata->offset; 513fa225cbcSrjs contextRec->corrdata.size = ctxpriv->mcCorrdata->size; 514fa225cbcSrjs contextRec->deviceID = DEVICE_ID(pI830->PciInfo); 515fa225cbcSrjs 516fa225cbcSrjs if (IS_I915G(pI830) || IS_I915GM(pI830)) { 517fa225cbcSrjs contextRec->sis.bus_addr = ctxpriv->mcStaticIndirectState->bus_addr; 518fa225cbcSrjs contextRec->ssb.bus_addr = ctxpriv->mcSamplerState->bus_addr; 519fa225cbcSrjs contextRec->msb.bus_addr = ctxpriv->mcMapState->bus_addr; 520fa225cbcSrjs contextRec->psp.bus_addr = ctxpriv->mcPixelShaderProgram->bus_addr; 521fa225cbcSrjs contextRec->psc.bus_addr = ctxpriv->mcPixelShaderConstants->bus_addr; 522fa225cbcSrjs } 523fa225cbcSrjs 524fa225cbcSrjs pXvMC->ncontexts++; 525fa225cbcSrjs pXvMC->contexts[i] = pContext->context_id; 526fa225cbcSrjs pXvMC->ctxprivs[i] = ctxpriv; 527fa225cbcSrjs 528fa225cbcSrjs return Success; 529fa225cbcSrjs} 530fa225cbcSrjs 531fa225cbcSrjsstatic int i915_xvmc_create_surface (ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf, 532fa225cbcSrjs int *num_priv, long **priv ) 533fa225cbcSrjs{ 534fa225cbcSrjs I830Ptr pI830 = I830PTR(pScrn); 535fa225cbcSrjs I915XvMCPtr pXvMC = (I915XvMCPtr)xvmc_driver->devPrivate; 536fa225cbcSrjs I915XvMCSurfacePriv *sfpriv = NULL; 537fa225cbcSrjs I915XvMCCreateSurfaceRec *surfaceRec = NULL; 538fa225cbcSrjs XvMCContextPtr ctx = NULL; 539fa225cbcSrjs unsigned int srfno; 540fa225cbcSrjs unsigned long bufsize; 541fa225cbcSrjs 542fa225cbcSrjs if (!pI830->XvMCEnabled) { 543fa225cbcSrjs xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 544fa225cbcSrjs "[XvMC] i915: XvMC disabled!\n"); 545fa225cbcSrjs return BadAlloc; 546fa225cbcSrjs } 547fa225cbcSrjs 548fa225cbcSrjs *priv = NULL; 549fa225cbcSrjs *num_priv = 0; 550fa225cbcSrjs 551fa225cbcSrjs for (srfno = 0; srfno < I915_XVMC_MAX_SURFACES; ++srfno) { 552fa225cbcSrjs if (!pXvMC->surfaces[srfno]) 553fa225cbcSrjs break; 554fa225cbcSrjs } 555fa225cbcSrjs 556fa225cbcSrjs if (srfno == I915_XVMC_MAX_SURFACES || 557fa225cbcSrjs pXvMC->nsurfaces >= I915_XVMC_MAX_SURFACES) { 558fa225cbcSrjs xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 559fa225cbcSrjs "[XvMC] i915: Too many surfaces !\n"); 560fa225cbcSrjs return BadAlloc; 561fa225cbcSrjs } 562fa225cbcSrjs 563fa225cbcSrjs *priv = xcalloc(1, sizeof(I915XvMCCreateSurfaceRec)); 564fa225cbcSrjs surfaceRec = (I915XvMCCreateSurfaceRec *)*priv; 565fa225cbcSrjs 566fa225cbcSrjs if (!*priv) { 567fa225cbcSrjs xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 568fa225cbcSrjs "[XvMC] i915:Unable to allocate surface priv ret memory!\n"); 569fa225cbcSrjs return BadAlloc; 570fa225cbcSrjs } 571fa225cbcSrjs 572fa225cbcSrjs *num_priv = sizeof(I915XvMCCreateSurfaceRec) >> 2; 573fa225cbcSrjs sfpriv = (I915XvMCSurfacePriv *)xcalloc(1, sizeof(I915XvMCSurfacePriv)); 574fa225cbcSrjs 575fa225cbcSrjs if (!sfpriv) { 576fa225cbcSrjs xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 577fa225cbcSrjs "[XvMC] i915: Unable to allocate surface priv memory!\n"); 578fa225cbcSrjs xfree(*priv); 579fa225cbcSrjs *priv = NULL; 580fa225cbcSrjs *num_priv = 0; 581fa225cbcSrjs return BadAlloc; 582fa225cbcSrjs } 583fa225cbcSrjs 584fa225cbcSrjs ctx = pSurf->context; 585fa225cbcSrjs bufsize = SIZE_YUV420(ctx->width, ctx->height); 586fa225cbcSrjs 587fa225cbcSrjs if (!i830_allocate_xvmc_buffer(pScrn, "XvMC surface", 588fa225cbcSrjs &(sfpriv->surface), bufsize, 589fa225cbcSrjs ALIGN_BOTH_ENDS)) { 590fa225cbcSrjs xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 591fa225cbcSrjs "[XvMC] i915 : Failed to allocate XvMC surface space!\n"); 592fa225cbcSrjs xfree(sfpriv); 593fa225cbcSrjs xfree(*priv); 594fa225cbcSrjs *priv = NULL; 595fa225cbcSrjs *num_priv = 0; 596fa225cbcSrjs return BadAlloc; 597fa225cbcSrjs } 598fa225cbcSrjs 599fa225cbcSrjs if (0) 600fa225cbcSrjs i830_describe_allocations(pScrn, 1, ""); 601fa225cbcSrjs 602fa225cbcSrjs if (drmAddMap(pI830->drmSubFD, 603fa225cbcSrjs (drm_handle_t)(sfpriv->surface->offset + pI830->LinearAddr), 604fa225cbcSrjs sfpriv->surface->size, DRM_AGP, 0, 605fa225cbcSrjs (drmAddress)&sfpriv->surface_handle) < 0) { 606fa225cbcSrjs xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 607fa225cbcSrjs "[drm] drmAddMap(surface_handle) failed!\n"); 608fa225cbcSrjs i830_free_xvmc_buffer(pScrn, sfpriv->surface); 609fa225cbcSrjs xfree(sfpriv); 610fa225cbcSrjs xfree(*priv); 611fa225cbcSrjs *priv = NULL; 612fa225cbcSrjs *num_priv = 0; 613fa225cbcSrjs return BadAlloc; 614fa225cbcSrjs } 615fa225cbcSrjs 616fa225cbcSrjs surfaceRec->srfno = srfno; 617fa225cbcSrjs surfaceRec->srf.handle = sfpriv->surface_handle; 618fa225cbcSrjs surfaceRec->srf.offset = sfpriv->surface->offset; 619fa225cbcSrjs surfaceRec->srf.size = sfpriv->surface->size; 620fa225cbcSrjs 621fa225cbcSrjs pXvMC->surfaces[srfno] = pSurf->surface_id; 622fa225cbcSrjs pXvMC->sfprivs[srfno]= sfpriv; 623fa225cbcSrjs pXvMC->nsurfaces++; 624fa225cbcSrjs 625fa225cbcSrjs return Success; 626fa225cbcSrjs} 627fa225cbcSrjs 628fa225cbcSrjsstatic int i915_xvmc_create_subpict(ScrnInfoPtr pScrn, XvMCSubpicturePtr pSubp, 629fa225cbcSrjs int *num_priv, long **priv ) 630fa225cbcSrjs{ 631fa225cbcSrjs I830Ptr pI830 = I830PTR(pScrn); 632fa225cbcSrjs I915XvMCPtr pXvMC = (I915XvMCPtr)xvmc_driver->devPrivate; 633fa225cbcSrjs I915XvMCSurfacePriv *sfpriv = NULL; 634fa225cbcSrjs I915XvMCCreateSurfaceRec *surfaceRec = NULL; 635fa225cbcSrjs XvMCContextPtr ctx = NULL; 636fa225cbcSrjs unsigned int srfno; 637fa225cbcSrjs unsigned int bufsize; 638fa225cbcSrjs 639fa225cbcSrjs *priv = NULL; 640fa225cbcSrjs *num_priv = 0; 641fa225cbcSrjs 642fa225cbcSrjs for (srfno = 0; srfno < I915_XVMC_MAX_SURFACES; ++srfno) { 643fa225cbcSrjs if (!pXvMC->surfaces[srfno]) 644fa225cbcSrjs break; 645fa225cbcSrjs } 646fa225cbcSrjs 647fa225cbcSrjs if (srfno == I915_XVMC_MAX_SURFACES || 648fa225cbcSrjs pXvMC->nsurfaces >= I915_XVMC_MAX_SURFACES) { 649fa225cbcSrjs xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 650fa225cbcSrjs "[XvMC] i915: Too many surfaces !\n"); 651fa225cbcSrjs return BadAlloc; 652fa225cbcSrjs } 653fa225cbcSrjs 654fa225cbcSrjs *priv = xcalloc(1, sizeof(I915XvMCCreateSurfaceRec)); 655fa225cbcSrjs surfaceRec = (I915XvMCCreateSurfaceRec *)*priv; 656fa225cbcSrjs 657fa225cbcSrjs if (!*priv) { 658fa225cbcSrjs xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 659fa225cbcSrjs "[XvMC] i915: Unable to allocate memory!\n"); 660fa225cbcSrjs return BadAlloc; 661fa225cbcSrjs } 662fa225cbcSrjs 663fa225cbcSrjs *num_priv = sizeof(I915XvMCCreateSurfaceRec) >> 2; 664fa225cbcSrjs sfpriv = (I915XvMCSurfacePriv *)xcalloc(1, sizeof(I915XvMCSurfacePriv)); 665fa225cbcSrjs 666fa225cbcSrjs if (!sfpriv) { 667fa225cbcSrjs xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 668fa225cbcSrjs "[XvMC] i915: Unable to allocate memory!\n"); 669fa225cbcSrjs xfree(*priv); 670fa225cbcSrjs *priv = NULL; 671fa225cbcSrjs *num_priv = 0; 672fa225cbcSrjs return BadAlloc; 673fa225cbcSrjs } 674fa225cbcSrjs 675fa225cbcSrjs ctx = pSubp->context; 676fa225cbcSrjs bufsize = SIZE_XX44(ctx->width, ctx->height); 677fa225cbcSrjs 678fa225cbcSrjs if (!i830_allocate_xvmc_buffer(pScrn, "XvMC surface", 679fa225cbcSrjs &(sfpriv->surface), bufsize, 680fa225cbcSrjs ALIGN_BOTH_ENDS)) { 681fa225cbcSrjs xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 682fa225cbcSrjs "[XvMC] I915XvMCCreateSurface: Failed to allocate XvMC surface space!\n"); 683fa225cbcSrjs xfree(sfpriv); 684fa225cbcSrjs xfree(*priv); 685fa225cbcSrjs *priv = NULL; 686fa225cbcSrjs *num_priv = 0; 687fa225cbcSrjs return BadAlloc; 688fa225cbcSrjs } 689fa225cbcSrjs 690fa225cbcSrjs if (drmAddMap(pI830->drmSubFD, 691fa225cbcSrjs (drm_handle_t)(sfpriv->surface->offset + pI830->LinearAddr), 692fa225cbcSrjs sfpriv->surface->size, DRM_AGP, 0, 693fa225cbcSrjs (drmAddress)&sfpriv->surface_handle) < 0) { 694fa225cbcSrjs xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 695fa225cbcSrjs "[drm] drmAddMap(surface_handle) failed!\n"); 696fa225cbcSrjs i830_free_xvmc_buffer(pScrn, sfpriv->surface); 697fa225cbcSrjs xfree(sfpriv); 698fa225cbcSrjs xfree(*priv); 699fa225cbcSrjs *priv = NULL; 700fa225cbcSrjs *num_priv = 0; 701fa225cbcSrjs return BadAlloc; 702fa225cbcSrjs } 703fa225cbcSrjs 704fa225cbcSrjs surfaceRec->srfno = srfno; 705fa225cbcSrjs surfaceRec->srf.handle = sfpriv->surface_handle; 706fa225cbcSrjs surfaceRec->srf.offset = sfpriv->surface->offset; 707fa225cbcSrjs surfaceRec->srf.size = sfpriv->surface->size; 708fa225cbcSrjs 709fa225cbcSrjs pXvMC->sfprivs[srfno] = sfpriv; 710fa225cbcSrjs pXvMC->surfaces[srfno] = pSubp->subpicture_id; 711fa225cbcSrjs pXvMC->nsurfaces++; 712fa225cbcSrjs 713fa225cbcSrjs return Success; 714fa225cbcSrjs} 715fa225cbcSrjs 716fa225cbcSrjsstatic void i915_xvmc_destroy_context (ScrnInfoPtr pScrn, 717fa225cbcSrjs XvMCContextPtr pContext) 718fa225cbcSrjs{ 719fa225cbcSrjs I915XvMCPtr pXvMC = (I915XvMCPtr)xvmc_driver->devPrivate; 720fa225cbcSrjs int i; 721fa225cbcSrjs 722fa225cbcSrjs for (i = 0; i < I915_XVMC_MAX_CONTEXTS; i++) { 723fa225cbcSrjs if (pXvMC->contexts[i] == pContext->context_id) { 724fa225cbcSrjs i915_unmap_xvmc_buffers(pScrn, pXvMC->ctxprivs[i]); 725fa225cbcSrjs i915_free_xvmc_buffers(pScrn, pXvMC->ctxprivs[i]); 726fa225cbcSrjs xfree(pXvMC->ctxprivs[i]); 727fa225cbcSrjs pXvMC->ctxprivs[i] = 0; 728fa225cbcSrjs pXvMC->ncontexts--; 729fa225cbcSrjs pXvMC->contexts[i] = 0; 730fa225cbcSrjs return; 731fa225cbcSrjs } 732fa225cbcSrjs } 733fa225cbcSrjs 734fa225cbcSrjs return; 735fa225cbcSrjs} 736fa225cbcSrjs 737fa225cbcSrjsstatic void i915_xvmc_destroy_surface (ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf) 738fa225cbcSrjs{ 739fa225cbcSrjs I830Ptr pI830 = I830PTR(pScrn); 740fa225cbcSrjs I915XvMCPtr pXvMC = (I915XvMCPtr)xvmc_driver->devPrivate; 741fa225cbcSrjs int i; 742fa225cbcSrjs 743fa225cbcSrjs for (i = 0; i < I915_XVMC_MAX_SURFACES; i++) { 744fa225cbcSrjs if (pXvMC->surfaces[i] == pSurf->surface_id) { 745fa225cbcSrjs drmRmMap(pI830->drmSubFD, pXvMC->sfprivs[i]->surface_handle); 746fa225cbcSrjs i830_free_xvmc_buffer(pScrn, pXvMC->sfprivs[i]->surface); 747fa225cbcSrjs xfree(pXvMC->sfprivs[i]); 748fa225cbcSrjs pXvMC->nsurfaces--; 749fa225cbcSrjs pXvMC->sfprivs[i] = 0; 750fa225cbcSrjs pXvMC->surfaces[i] = 0; 751fa225cbcSrjs return; 752fa225cbcSrjs } 753fa225cbcSrjs } 754fa225cbcSrjs 755fa225cbcSrjs return; 756fa225cbcSrjs} 757fa225cbcSrjs 758fa225cbcSrjsstatic void i915_xvmc_destroy_subpict (ScrnInfoPtr pScrn, 759fa225cbcSrjs XvMCSubpicturePtr pSubp) 760fa225cbcSrjs{ 761fa225cbcSrjs I830Ptr pI830 = I830PTR(pScrn); 762fa225cbcSrjs I915XvMCPtr pXvMC = (I915XvMCPtr)xvmc_driver->devPrivate; 763fa225cbcSrjs int i; 764fa225cbcSrjs 765fa225cbcSrjs for (i = 0; i < I915_XVMC_MAX_SURFACES; i++) { 766fa225cbcSrjs if (pXvMC->surfaces[i] == pSubp->subpicture_id) { 767fa225cbcSrjs drmRmMap(pI830->drmSubFD, pXvMC->sfprivs[i]->surface_handle); 768fa225cbcSrjs i830_free_xvmc_buffer(pScrn, pXvMC->sfprivs[i]->surface); 769fa225cbcSrjs xfree(pXvMC->sfprivs[i]); 770fa225cbcSrjs pXvMC->nsurfaces--; 771fa225cbcSrjs pXvMC->sfprivs[i] = 0; 772fa225cbcSrjs pXvMC->surfaces[i] = 0; 773fa225cbcSrjs return; 774fa225cbcSrjs } 775fa225cbcSrjs } 776fa225cbcSrjs 777fa225cbcSrjs return; 778fa225cbcSrjs} 779fa225cbcSrjs 780fa225cbcSrjsstatic int i915_xvmc_put_image(ScrnInfoPtr pScrn, 781fa225cbcSrjs short src_x, short src_y, 782fa225cbcSrjs short drw_x, short drw_y, short src_w, 783fa225cbcSrjs short src_h, short drw_w, short drw_h, 784fa225cbcSrjs int id, unsigned char *buf, short width, 785fa225cbcSrjs short height, Bool sync, RegionPtr clipBoxes, pointer data, 786fa225cbcSrjs DrawablePtr pDraw) 787fa225cbcSrjs{ 788fa225cbcSrjs I915XvMCPtr pXvMC = (I915XvMCPtr)xvmc_driver->devPrivate; 789fa225cbcSrjs struct intel_xvmc_command *xvmc_cmd = (struct intel_xvmc_command *)buf; 790fa225cbcSrjs int ret; 791fa225cbcSrjs 792fa225cbcSrjs if (FOURCC_XVMC == id) { 793fa225cbcSrjs switch (xvmc_cmd->command) { 794fa225cbcSrjs case INTEL_XVMC_COMMAND_DISPLAY: 795fa225cbcSrjs if ((xvmc_cmd->srfNo >= I915_XVMC_MAX_SURFACES) || 796fa225cbcSrjs !pXvMC->surfaces[xvmc_cmd->srfNo] || 797fa225cbcSrjs !pXvMC->sfprivs[xvmc_cmd->srfNo]) { 798fa225cbcSrjs xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 799fa225cbcSrjs "[XvMC] i915 put image: Invalid parameters!\n"); 800fa225cbcSrjs return 1; 801fa225cbcSrjs } 802fa225cbcSrjs 803fa225cbcSrjs /* use char *buf to hold our surface offset...hacky! */ 804fa225cbcSrjs buf = (unsigned char *)pXvMC->sfprivs[xvmc_cmd->srfNo]->surface->offset; 805fa225cbcSrjs break; 806fa225cbcSrjs default: 807fa225cbcSrjs return 0; 808fa225cbcSrjs } 809fa225cbcSrjs } 810fa225cbcSrjs 811fa225cbcSrjs ret = pXvMC->savePutImage(pScrn, src_x, src_y, drw_x, drw_y, src_w, src_h, 812fa225cbcSrjs drw_w, drw_h, id, buf, width, height, sync, clipBoxes, 813fa225cbcSrjs data, pDraw); 814fa225cbcSrjs return ret; 815fa225cbcSrjs} 816fa225cbcSrjs 817fa225cbcSrjsstatic Bool i915_xvmc_init(ScrnInfoPtr pScrn, XF86VideoAdaptorPtr XvAdapt) 818fa225cbcSrjs{ 819fa225cbcSrjs I915XvMCPtr pXvMC; 820fa225cbcSrjs 821fa225cbcSrjs pXvMC = (I915XvMCPtr)xcalloc(1, sizeof(I915XvMC)); 822fa225cbcSrjs if (!pXvMC) { 823fa225cbcSrjs xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 824fa225cbcSrjs "[XvMC] alloc driver private failed!\n"); 825fa225cbcSrjs return FALSE; 826fa225cbcSrjs } 827fa225cbcSrjs xvmc_driver->devPrivate = (void*)pXvMC; 828fa225cbcSrjs if (!intel_xvmc_init_batch(pScrn)) { 829fa225cbcSrjs xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 830fa225cbcSrjs "[XvMC] fail to init batch buffer\n"); 831fa225cbcSrjs xfree(pXvMC); 832fa225cbcSrjs return FALSE; 833fa225cbcSrjs } 834fa225cbcSrjs initI915XvMC(pXvMC); 835fa225cbcSrjs 836fa225cbcSrjs /* set up wrappers */ 837fa225cbcSrjs pXvMC->savePutImage = XvAdapt->PutImage; 838fa225cbcSrjs XvAdapt->PutImage = i915_xvmc_put_image; 839fa225cbcSrjs return TRUE; 840fa225cbcSrjs} 841fa225cbcSrjs 842fa225cbcSrjsstatic void i915_xvmc_fini(ScrnInfoPtr pScrn) 843fa225cbcSrjs{ 844fa225cbcSrjs I915XvMCPtr pXvMC = (I915XvMCPtr)xvmc_driver->devPrivate; 845fa225cbcSrjs 846fa225cbcSrjs cleanupI915XvMC(pXvMC); 847fa225cbcSrjs intel_xvmc_fini_batch(pScrn); 848fa225cbcSrjs xfree(xvmc_driver->devPrivate); 849fa225cbcSrjs} 850fa225cbcSrjs 851fa225cbcSrjs/* Fill in the device dependent adaptor record. 852fa225cbcSrjs * This is named "Intel(R) Textured Video" because this code falls under the 853fa225cbcSrjs * XV extenstion, the name must match or it won't be used. 854fa225cbcSrjs * 855fa225cbcSrjs * Surface and Subpicture - see above 856fa225cbcSrjs * Function pointers to functions below 857fa225cbcSrjs */ 858fa225cbcSrjsstatic XF86MCAdaptorRec pAdapt = 859fa225cbcSrjs{ 860fa225cbcSrjs .name = "Intel(R) Textured Video", 861fa225cbcSrjs .num_surfaces = ARRAY_SIZE(ppSI), 862fa225cbcSrjs .surfaces = ppSI, 863fa225cbcSrjs#if 0 864fa225cbcSrjs .num_subpictures = ARRARY_SIZE(i915_subpicture_list), 865fa225cbcSrjs .subpictures = i915_subpicture_list, 866fa225cbcSrjs#endif 867fa225cbcSrjs .num_subpictures = 0, 868fa225cbcSrjs .subpictures = NULL, 869fa225cbcSrjs .CreateContext = (xf86XvMCCreateContextProcPtr) i915_xvmc_create_context, 870fa225cbcSrjs .DestroyContext = (xf86XvMCDestroyContextProcPtr) i915_xvmc_destroy_context, 871fa225cbcSrjs .CreateSurface = (xf86XvMCCreateSurfaceProcPtr) i915_xvmc_create_surface, 872fa225cbcSrjs .DestroySurface = (xf86XvMCDestroySurfaceProcPtr) i915_xvmc_destroy_surface, 873fa225cbcSrjs .CreateSubpicture = (xf86XvMCCreateSubpictureProcPtr) i915_xvmc_create_subpict, 874fa225cbcSrjs .DestroySubpicture = (xf86XvMCDestroySubpictureProcPtr) i915_xvmc_destroy_subpict, 875fa225cbcSrjs}; 876fa225cbcSrjs 877fa225cbcSrjs/* new xvmc driver interface */ 878fa225cbcSrjsstruct intel_xvmc_driver i915_xvmc_driver = { 879fa225cbcSrjs .name = "i915_xvmc", 880fa225cbcSrjs .adaptor = &pAdapt, 881fa225cbcSrjs .flag = XVMC_I915_MPEG2_MC, 882fa225cbcSrjs .init = i915_xvmc_init, 883fa225cbcSrjs .fini = i915_xvmc_fini, 884fa225cbcSrjs}; 885