103b705cfSriastradh/***************************************************************************
203b705cfSriastradh
303b705cfSriastradhCopyright 2000 Intel Corporation.  All Rights Reserved.
403b705cfSriastradh
503b705cfSriastradhPermission is hereby granted, free of charge, to any person obtaining a
603b705cfSriastradhcopy of this software and associated documentation files (the
703b705cfSriastradh"Software"), to deal in the Software without restriction, including
803b705cfSriastradhwithout limitation the rights to use, copy, modify, merge, publish,
903b705cfSriastradhdistribute, sub license, and/or sell copies of the Software, and to
1003b705cfSriastradhpermit persons to whom the Software is furnished to do so, subject to
1103b705cfSriastradhthe following conditions:
1203b705cfSriastradh
1303b705cfSriastradhThe above copyright notice and this permission notice (including the
1403b705cfSriastradhnext paragraph) shall be included in all copies or substantial portions
1503b705cfSriastradhof the Software.
1603b705cfSriastradh
1703b705cfSriastradhTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
1803b705cfSriastradhOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1903b705cfSriastradhMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
2003b705cfSriastradhIN NO EVENT SHALL INTEL, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
2103b705cfSriastradhDAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
2203b705cfSriastradhOTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
2303b705cfSriastradhTHE USE OR OTHER DEALINGS IN THE SOFTWARE.
2403b705cfSriastradh
2503b705cfSriastradh**************************************************************************/
2603b705cfSriastradh
2703b705cfSriastradh/*
2803b705cfSriastradh * i810_hwmc.c: i810 HWMC Driver
2903b705cfSriastradh *
3003b705cfSriastradh * Authors:
3103b705cfSriastradh *      Matt Sottek <matthew.j.sottek@intel.com>
3203b705cfSriastradh *
3303b705cfSriastradh *
3403b705cfSriastradh */
3503b705cfSriastradh
3603b705cfSriastradh#ifdef HAVE_CONFIG_H
3703b705cfSriastradh#include "config.h"
3803b705cfSriastradh#endif
3903b705cfSriastradh
4003b705cfSriastradh#include <string.h>
4103b705cfSriastradh
4242542f5fSchristos#include "xorg-server.h"
4303b705cfSriastradh#include "xf86.h"
4403b705cfSriastradh#include "xf86_OSproc.h"
4503b705cfSriastradh#include "compiler.h"
4603b705cfSriastradh#include "xf86Pci.h"
4703b705cfSriastradh#include "xf86fbman.h"
4803b705cfSriastradh#include "regionstr.h"
4903b705cfSriastradh
5003b705cfSriastradh#include "i810.h"
5103b705cfSriastradh#include "i810_dri.h"
5203b705cfSriastradh
5303b705cfSriastradh#include "xf86xv.h"
5403b705cfSriastradh#include "xf86xvmc.h"
5503b705cfSriastradh#include <X11/extensions/Xv.h>
5603b705cfSriastradh#include <X11/extensions/XvMC.h>
5703b705cfSriastradh#include "dixstruct.h"
5803b705cfSriastradh#include "fourcc.h"
5903b705cfSriastradh
6003b705cfSriastradhint I810XvMCCreateContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext,
6103b705cfSriastradh                           int *num_priv, long **priv );
6203b705cfSriastradhvoid I810XvMCDestroyContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext);
6303b705cfSriastradh
6403b705cfSriastradhint I810XvMCCreateSurface (ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf,
6503b705cfSriastradh                           int *num_priv, long **priv );
6603b705cfSriastradhvoid I810XvMCDestroySurface (ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf);
6703b705cfSriastradh
6803b705cfSriastradhint I810XvMCCreateSubpicture (ScrnInfoPtr pScrn, XvMCSubpicturePtr pSurf,
6903b705cfSriastradh                               int *num_priv, long **priv );
7003b705cfSriastradhvoid I810XvMCDestroySubpicture (ScrnInfoPtr pScrn, XvMCSubpicturePtr pSurf);
7103b705cfSriastradh
7203b705cfSriastradh
7303b705cfSriastradhtypedef struct {
7403b705cfSriastradh  drm_context_t drmcontext;
7503b705cfSriastradh  unsigned int fbBase;
7603b705cfSriastradh  unsigned int OverlayOffset;
7703b705cfSriastradh  unsigned int OverlaySize;
7803b705cfSriastradh  unsigned int SurfacesOffset;
7903b705cfSriastradh  unsigned int SurfacesSize;
8003b705cfSriastradh  char busIdString[10];
8103b705cfSriastradh  char pad[2];
8203b705cfSriastradh} I810XvMCCreateContextRec;
8303b705cfSriastradh
8403b705cfSriastradh
8503b705cfSriastradhstatic int yv12_subpicture_index_list[2] =
8603b705cfSriastradh{
8703b705cfSriastradh  FOURCC_IA44,
8803b705cfSriastradh  FOURCC_AI44
8903b705cfSriastradh};
9003b705cfSriastradh
9103b705cfSriastradhstatic XF86MCImageIDList yv12_subpicture_list =
9203b705cfSriastradh{
9303b705cfSriastradh  2,
9403b705cfSriastradh  yv12_subpicture_index_list
9503b705cfSriastradh};
9603b705cfSriastradh
9703b705cfSriastradhstatic XF86MCSurfaceInfoRec i810_YV12_mpg2_surface =
9803b705cfSriastradh{
9903b705cfSriastradh    FOURCC_YV12,
10003b705cfSriastradh    XVMC_CHROMA_FORMAT_420,
10103b705cfSriastradh    0,
10203b705cfSriastradh    720,
10303b705cfSriastradh    576,
10403b705cfSriastradh    720,
10503b705cfSriastradh    576,
10603b705cfSriastradh    XVMC_MPEG_2,
10703b705cfSriastradh    XVMC_OVERLAID_SURFACE | XVMC_SUBPICTURE_INDEPENDENT_SCALING |
10803b705cfSriastradh    XVMC_INTRA_UNSIGNED,
10903b705cfSriastradh    &yv12_subpicture_list
11003b705cfSriastradh};
11103b705cfSriastradh
11203b705cfSriastradhstatic XF86MCSurfaceInfoRec i810_YV12_mpg1_surface =
11303b705cfSriastradh{
11403b705cfSriastradh    FOURCC_YV12,
11503b705cfSriastradh    XVMC_CHROMA_FORMAT_420,
11603b705cfSriastradh    0,
11703b705cfSriastradh    720,
11803b705cfSriastradh    576,
11903b705cfSriastradh    720,
12003b705cfSriastradh    576,
12103b705cfSriastradh    XVMC_MPEG_1,
12203b705cfSriastradh    XVMC_OVERLAID_SURFACE | XVMC_SUBPICTURE_INDEPENDENT_SCALING |
12303b705cfSriastradh    XVMC_INTRA_UNSIGNED,
12403b705cfSriastradh    &yv12_subpicture_list
12503b705cfSriastradh};
12603b705cfSriastradh
12703b705cfSriastradhstatic XF86MCSurfaceInfoPtr ppSI[2] =
12803b705cfSriastradh{
12903b705cfSriastradh    (XF86MCSurfaceInfoPtr)&i810_YV12_mpg2_surface,
13003b705cfSriastradh    (XF86MCSurfaceInfoPtr)&i810_YV12_mpg1_surface
13103b705cfSriastradh};
13203b705cfSriastradh
13303b705cfSriastradh/* List of subpicture types that we support */
13403b705cfSriastradhstatic XF86ImageRec ia44_subpicture = XVIMAGE_IA44;
13503b705cfSriastradhstatic XF86ImageRec ai44_subpicture = XVIMAGE_AI44;
13603b705cfSriastradh
13703b705cfSriastradhstatic XF86ImagePtr i810_subpicture_list[2] =
13803b705cfSriastradh{
13903b705cfSriastradh  (XF86ImagePtr)&ia44_subpicture,
14003b705cfSriastradh  (XF86ImagePtr)&ai44_subpicture
14103b705cfSriastradh};
14203b705cfSriastradh
14303b705cfSriastradh/* Fill in the device dependent adaptor record.
14403b705cfSriastradh * This is named "I810 Video Overlay" because this code falls under the
14503b705cfSriastradh * XV extenstion, the name must match or it won't be used.
14603b705cfSriastradh *
14703b705cfSriastradh * Surface and Subpicture - see above
14803b705cfSriastradh * Function pointers to functions below
14903b705cfSriastradh */
15003b705cfSriastradhstatic XF86MCAdaptorRec pAdapt =
15103b705cfSriastradh{
15203b705cfSriastradh  "I810 Video Overlay",		/* name */
15303b705cfSriastradh  2,				/* num_surfaces */
15403b705cfSriastradh  ppSI,				/* surfaces */
15503b705cfSriastradh  2,				/* num_subpictures */
15603b705cfSriastradh  i810_subpicture_list,		/* subpictures */
15703b705cfSriastradh  (xf86XvMCCreateContextProcPtr)I810XvMCCreateContext,
15803b705cfSriastradh  (xf86XvMCDestroyContextProcPtr)I810XvMCDestroyContext,
15903b705cfSriastradh  (xf86XvMCCreateSurfaceProcPtr)I810XvMCCreateSurface,
16003b705cfSriastradh  (xf86XvMCDestroySurfaceProcPtr)I810XvMCDestroySurface,
16103b705cfSriastradh  (xf86XvMCCreateSubpictureProcPtr)I810XvMCCreateSubpicture,
16203b705cfSriastradh  (xf86XvMCDestroySubpictureProcPtr)I810XvMCDestroySubpicture
16303b705cfSriastradh};
16403b705cfSriastradh
16503b705cfSriastradhstatic XF86MCAdaptorPtr ppAdapt[1] =
16603b705cfSriastradh{
16703b705cfSriastradh	(XF86MCAdaptorPtr)&pAdapt
16803b705cfSriastradh};
16903b705cfSriastradh
17003b705cfSriastradh/**************************************************************************
17103b705cfSriastradh *
17203b705cfSriastradh *  I810InitMC
17303b705cfSriastradh *
174fe8aea9eSmrg *  Initialize the hardware motion compensation extension for this
17503b705cfSriastradh *  hardware. The initialization routines want the address of the pointers
17603b705cfSriastradh *  to the structures, not the address of the structures. This means we
17703b705cfSriastradh *  allocate (or create static?) the pointer memory and pass that
17803b705cfSriastradh *  address. This seems a little convoluted.
17903b705cfSriastradh *
18003b705cfSriastradh *  We need to allocate memory for the device depended adaptor record.
18103b705cfSriastradh *  This is what holds the pointers to all our device functions.
18203b705cfSriastradh *
18303b705cfSriastradh *  We need to map the overlay registers into the drm.
18403b705cfSriastradh *
18503b705cfSriastradh *  We need to map the surfaces into the drm.
18603b705cfSriastradh *
18703b705cfSriastradh *  Inputs:
18803b705cfSriastradh *    Screen pointer
18903b705cfSriastradh *
19003b705cfSriastradh *  Outputs:
19103b705cfSriastradh *    None, this calls the device independent screen initialization
19203b705cfSriastradh *    function.
19303b705cfSriastradh *
19403b705cfSriastradh *  Revisions:
19503b705cfSriastradh *
19603b705cfSriastradh **************************************************************************/
19703b705cfSriastradhvoid I810InitMC(ScreenPtr pScreen)
19803b705cfSriastradh{
19903b705cfSriastradh  ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
20003b705cfSriastradh  I810Ptr pI810 = I810PTR(pScrn);
20103b705cfSriastradh  int i;
20203b705cfSriastradh
20303b705cfSriastradh  /* Clear the Surface Allocation */
20403b705cfSriastradh  for(i=0; i<I810_MAX_SURFACES; i++) {
20503b705cfSriastradh	pI810->surfaceAllocation[i] = 0;
20603b705cfSriastradh  }
20703b705cfSriastradh
20803b705cfSriastradh  /* Cursor is at a page boundary, Overlay regs are not, don't forget */
20903b705cfSriastradh  if (drmAddMap(pI810->drmSubFD, (drm_handle_t)pI810->CursorStart,
21003b705cfSriastradh                4096, DRM_AGP, 0, (drmAddress) &pI810->overlay_map) < 0) {
21103b705cfSriastradh    xf86DrvMsg(pScreen->myNum, X_ERROR, "drmAddMap(overlay) failed\n");
21203b705cfSriastradh    return;
21303b705cfSriastradh  }
21403b705cfSriastradh  if (drmAddMap(pI810->drmSubFD, (drm_handle_t)pI810->MC.Start,
21503b705cfSriastradh                pI810->MC.Size, DRM_AGP, 0, (drmAddress) &pI810->mc_map) < 0) {
21603b705cfSriastradh    xf86DrvMsg(pScreen->myNum, X_ERROR, "drmAddMap(MC) failed\n");
21703b705cfSriastradh    return;
21803b705cfSriastradh  }
21903b705cfSriastradh  xf86XvMCScreenInit(pScreen, 1, ppAdapt);
22003b705cfSriastradh}
22103b705cfSriastradh
22203b705cfSriastradh/**************************************************************************
22303b705cfSriastradh *
22403b705cfSriastradh *  I810XvMCCreateContext
22503b705cfSriastradh *
22603b705cfSriastradh *  Some info about the private data:
22703b705cfSriastradh *
22803b705cfSriastradh *  Set *num_priv to the number of 32bit words that make up the size of
22903b705cfSriastradh *  of the data that priv will point to.
23003b705cfSriastradh *
23103b705cfSriastradh *  *priv = (long *) calloc (elements, sizeof(element))
23203b705cfSriastradh *  *num_priv = (elements * sizeof(element)) >> 2;
23303b705cfSriastradh *
23403b705cfSriastradh **************************************************************************/
23503b705cfSriastradh
23603b705cfSriastradhint I810XvMCCreateContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext,
23703b705cfSriastradh                            int *num_priv, long **priv )
23803b705cfSriastradh{
23903b705cfSriastradh  I810Ptr pI810 = I810PTR(pScrn);
24003b705cfSriastradh  DRIInfoPtr pDRIInfo = pI810->pDRIInfo;
24103b705cfSriastradh  I810XvMCCreateContextRec *contextRec;
24203b705cfSriastradh
24303b705cfSriastradh
24403b705cfSriastradh  if(!pI810->directRenderingEnabled) {
24503b705cfSriastradh    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
24603b705cfSriastradh        "I810XvMCCreateContext: Cannot use XvMC without DRI!\n");
24703b705cfSriastradh    return BadAlloc;
24803b705cfSriastradh  }
24903b705cfSriastradh
25003b705cfSriastradh  /* Context Already in use! */
25103b705cfSriastradh  if(pI810->xvmcContext) {
25203b705cfSriastradh    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
25303b705cfSriastradh        "I810XvMCCreateContext: 2 XvMC Contexts Attempted, not supported.\n");
25403b705cfSriastradh    return BadAlloc;
25503b705cfSriastradh  }
25603b705cfSriastradh
25703b705cfSriastradh  *priv = calloc(1,sizeof(I810XvMCCreateContextRec));
25803b705cfSriastradh  contextRec = (I810XvMCCreateContextRec *)*priv;
25903b705cfSriastradh
26003b705cfSriastradh  if(!*priv) {
26103b705cfSriastradh    *num_priv = 0;
26203b705cfSriastradh    return BadAlloc;
26303b705cfSriastradh  }
26403b705cfSriastradh
26503b705cfSriastradh  *num_priv = sizeof(I810XvMCCreateContextRec) >> 2;
26603b705cfSriastradh  if(drmCreateContext(pI810->drmSubFD, &(contextRec->drmcontext) ) < 0) {
26703b705cfSriastradh    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
26803b705cfSriastradh        "I810XvMCCreateContext: Unable to create DRMContext!\n");
26903b705cfSriastradh    free(*priv);
27003b705cfSriastradh    return BadAlloc;
27103b705cfSriastradh  }
27203b705cfSriastradh
27303b705cfSriastradh  drmAuthMagic(pI810->drmSubFD, pContext->flags);
27403b705cfSriastradh
27503b705cfSriastradh  pI810->xvmcContext = contextRec->drmcontext;
27603b705cfSriastradh  contextRec->fbBase = pScrn->memPhysBase;
27703b705cfSriastradh
27803b705cfSriastradh  /* Overlay Regs are at 1024 offset into the Cursor Space */
27903b705cfSriastradh  contextRec->OverlayOffset = pI810->CursorStart;
28003b705cfSriastradh  contextRec->OverlaySize = 4096;
28103b705cfSriastradh
28203b705cfSriastradh  contextRec->SurfacesOffset = pI810->MC.Start;
28303b705cfSriastradh  contextRec->SurfacesSize = pI810->MC.Size;
28403b705cfSriastradh  strncpy (contextRec->busIdString, pDRIInfo->busIdString, 9);
28503b705cfSriastradh
28603b705cfSriastradh  return Success;
28703b705cfSriastradh}
28803b705cfSriastradh
28903b705cfSriastradh
29003b705cfSriastradhint I810XvMCCreateSurface (ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf,
29103b705cfSriastradh                           int *num_priv, long **priv )
29203b705cfSriastradh{
29303b705cfSriastradh  I810Ptr pI810 = I810PTR(pScrn);
29403b705cfSriastradh  int i;
29503b705cfSriastradh
29603b705cfSriastradh  *priv = (long *)calloc(2,sizeof(long));
29703b705cfSriastradh
29803b705cfSriastradh  if(!*priv) {
29903b705cfSriastradh    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
30003b705cfSriastradh        "I810XvMCCreateSurface: Unable to allocate memory!\n");
30103b705cfSriastradh    *num_priv = 0;
30203b705cfSriastradh    return BadAlloc;
30303b705cfSriastradh  }
30403b705cfSriastradh  *num_priv = 2;
30503b705cfSriastradh
30603b705cfSriastradh  /* Surface Arrangement is different based on 6 or 7 Surfaces */
30703b705cfSriastradh  if(pI810->numSurfaces == 6) {
30803b705cfSriastradh     for(i=0; i<pI810->numSurfaces; i++) {
30903b705cfSriastradh       if(!pI810->surfaceAllocation[i]) {
31003b705cfSriastradh         pI810->surfaceAllocation[i] = pSurf->surface_id;
31103b705cfSriastradh         /* Y data starts at 2MB offset, each surface is 576k */
31203b705cfSriastradh         (*priv)[0] = (2*1024*1024 + 576*1024 * i);
31303b705cfSriastradh         /* UV data starts at 0 offset, each set is 288k */
31403b705cfSriastradh         (*priv)[1] = (576*512 * i);
31503b705cfSriastradh         return Success;
31603b705cfSriastradh       }
31703b705cfSriastradh     }
31803b705cfSriastradh  }
31903b705cfSriastradh  if(pI810->numSurfaces == 7) {
32003b705cfSriastradh     for(i=0; i<pI810->numSurfaces; i++) {
32103b705cfSriastradh       if(!pI810->surfaceAllocation[i]) {
32203b705cfSriastradh         pI810->surfaceAllocation[i] = pSurf->surface_id;
32303b705cfSriastradh         /* Y data starts at 2.5MB offset, each surface is 576k */
32403b705cfSriastradh         (*priv)[0] = (2*1024*1024 + 512*1024 + 576*1024 * i);
32503b705cfSriastradh         /* UV data starts at 0 offset, each set is 288k */
32603b705cfSriastradh         (*priv)[1] = (576*512 * i);
32703b705cfSriastradh         return Success;
32803b705cfSriastradh       }
32903b705cfSriastradh     }
33003b705cfSriastradh  }
33103b705cfSriastradh  (*priv)[0] = 0;
33203b705cfSriastradh  (*priv)[1] = 0;
33303b705cfSriastradh  return BadAlloc;
33403b705cfSriastradh}
33503b705cfSriastradh
33603b705cfSriastradhint I810XvMCCreateSubpicture (ScrnInfoPtr pScrn, XvMCSubpicturePtr pSubp,
33703b705cfSriastradh                              int *num_priv, long **priv )
33803b705cfSriastradh{
33903b705cfSriastradh  I810Ptr pI810 = I810PTR(pScrn);
34003b705cfSriastradh  int i;
34103b705cfSriastradh
34203b705cfSriastradh  *priv = (long *)calloc(1,sizeof(long));
34303b705cfSriastradh
34403b705cfSriastradh  if(!*priv) {
34503b705cfSriastradh    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
34603b705cfSriastradh        "I810XvMCCreateSubpicture: Unable to allocate memory!\n");
34703b705cfSriastradh    *num_priv = 0;
34803b705cfSriastradh    return BadAlloc;
34903b705cfSriastradh  }
35003b705cfSriastradh  *num_priv = 1;
35103b705cfSriastradh
35203b705cfSriastradh  if(pI810->numSurfaces == 6) {
35303b705cfSriastradh     for(i=6; i<8; i++) {
35403b705cfSriastradh       if(!pI810->surfaceAllocation[i]) {
35503b705cfSriastradh         pI810->surfaceAllocation[i] = pSubp->subpicture_id;
35603b705cfSriastradh         /* Subpictures are after the Y surfaces in memory */
35703b705cfSriastradh         (*priv)[0] = (2*1024*1024 + 576*1024 * i);
35803b705cfSriastradh         return Success;
35903b705cfSriastradh       }
36003b705cfSriastradh     }
36103b705cfSriastradh  }
36203b705cfSriastradh  if(pI810->numSurfaces == 7) {
36303b705cfSriastradh     for(i=7; i<9; i++) {
36403b705cfSriastradh         if(!pI810->surfaceAllocation[i]) {
36503b705cfSriastradh         pI810->surfaceAllocation[i] = pSubp->subpicture_id;
36603b705cfSriastradh         /* Subpictures are after the Y surfaces in memory */
36703b705cfSriastradh         (*priv)[0] = (2*1024*1024 + 512*1024 + 576*1024 * i);
36803b705cfSriastradh         return Success;
36903b705cfSriastradh       }
37003b705cfSriastradh     }
37103b705cfSriastradh  }
37203b705cfSriastradh
37303b705cfSriastradh  (*priv)[0] = 0;
37403b705cfSriastradh  return BadAlloc;
37503b705cfSriastradh}
37603b705cfSriastradh
37703b705cfSriastradhvoid I810XvMCDestroyContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext)
37803b705cfSriastradh{
37903b705cfSriastradh  I810Ptr pI810 = I810PTR(pScrn);
38003b705cfSriastradh
38103b705cfSriastradh  drmDestroyContext(pI810->drmSubFD,pI810->xvmcContext);
38203b705cfSriastradh  pI810->xvmcContext = 0;
38303b705cfSriastradh}
38403b705cfSriastradh
38503b705cfSriastradhvoid I810XvMCDestroySurface (ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf)
38603b705cfSriastradh{
38703b705cfSriastradh  I810Ptr pI810 = I810PTR(pScrn);
38803b705cfSriastradh  int i;
38903b705cfSriastradh
39003b705cfSriastradh  for(i=0; i<I810_MAX_SURFACES; i++) {
39103b705cfSriastradh    if(pI810->surfaceAllocation[i] == pSurf->surface_id) {
39203b705cfSriastradh      pI810->surfaceAllocation[i] = 0;
39303b705cfSriastradh      return;
39403b705cfSriastradh    }
39503b705cfSriastradh  }
39603b705cfSriastradh  return;
39703b705cfSriastradh}
39803b705cfSriastradh
39903b705cfSriastradhvoid I810XvMCDestroySubpicture (ScrnInfoPtr pScrn, XvMCSubpicturePtr pSubp)
40003b705cfSriastradh{
40103b705cfSriastradh  I810Ptr pI810 = I810PTR(pScrn);
40203b705cfSriastradh  int i;
40303b705cfSriastradh
40403b705cfSriastradh  for(i=pI810->numSurfaces; i<I810_MAX_SURFACES + I810_MAX_SUBPICTURES; i++) {
40503b705cfSriastradh    if(pI810->surfaceAllocation[i] == pSubp->subpicture_id) {
40603b705cfSriastradh      pI810->surfaceAllocation[i] = 0;
40703b705cfSriastradh      return;
40803b705cfSriastradh    }
40903b705cfSriastradh  }
41003b705cfSriastradh  return;
41103b705cfSriastradh}
41203b705cfSriastradh
41303b705cfSriastradh
41403b705cfSriastradh
41503b705cfSriastradh
41603b705cfSriastradh
41703b705cfSriastradh
418