1428d7b3dSmrg/***************************************************************************
2428d7b3dSmrg
3428d7b3dSmrgCopyright 2000 Intel Corporation.  All Rights Reserved.
4428d7b3dSmrg
5428d7b3dSmrgPermission is hereby granted, free of charge, to any person obtaining a
6428d7b3dSmrgcopy of this software and associated documentation files (the
7428d7b3dSmrg"Software"), to deal in the Software without restriction, including
8428d7b3dSmrgwithout limitation the rights to use, copy, modify, merge, publish,
9428d7b3dSmrgdistribute, sub license, and/or sell copies of the Software, and to
10428d7b3dSmrgpermit persons to whom the Software is furnished to do so, subject to
11428d7b3dSmrgthe following conditions:
12428d7b3dSmrg
13428d7b3dSmrgThe above copyright notice and this permission notice (including the
14428d7b3dSmrgnext paragraph) shall be included in all copies or substantial portions
15428d7b3dSmrgof the Software.
16428d7b3dSmrg
17428d7b3dSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18428d7b3dSmrgOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19428d7b3dSmrgMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
20428d7b3dSmrgIN NO EVENT SHALL INTEL, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
21428d7b3dSmrgDAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
22428d7b3dSmrgOTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
23428d7b3dSmrgTHE USE OR OTHER DEALINGS IN THE SOFTWARE.
24428d7b3dSmrg
25428d7b3dSmrg**************************************************************************/
26428d7b3dSmrg
27428d7b3dSmrg/*
28428d7b3dSmrg * i810_hwmc.c: i810 HWMC Driver
29428d7b3dSmrg *
30428d7b3dSmrg * Authors:
31428d7b3dSmrg *      Matt Sottek <matthew.j.sottek@intel.com>
32428d7b3dSmrg *
33428d7b3dSmrg *
34428d7b3dSmrg */
35428d7b3dSmrg
36428d7b3dSmrg#ifdef HAVE_CONFIG_H
37428d7b3dSmrg#include "config.h"
38428d7b3dSmrg#endif
39428d7b3dSmrg
40428d7b3dSmrg#include <string.h>
41428d7b3dSmrg
42428d7b3dSmrg#include "xorg-server.h"
43428d7b3dSmrg#include "xf86.h"
44428d7b3dSmrg#include "xf86_OSproc.h"
45428d7b3dSmrg#include "compiler.h"
46428d7b3dSmrg#include "xf86Pci.h"
47428d7b3dSmrg#include "xf86fbman.h"
48428d7b3dSmrg#include "regionstr.h"
49428d7b3dSmrg
50428d7b3dSmrg#include "i810.h"
51428d7b3dSmrg#include "i810_dri.h"
52428d7b3dSmrg
53428d7b3dSmrg#include "xf86xv.h"
54428d7b3dSmrg#include "xf86xvmc.h"
55428d7b3dSmrg#include <X11/extensions/Xv.h>
56428d7b3dSmrg#include <X11/extensions/XvMC.h>
57428d7b3dSmrg#include "dixstruct.h"
58428d7b3dSmrg#include "fourcc.h"
59428d7b3dSmrg
60428d7b3dSmrgint I810XvMCCreateContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext,
61428d7b3dSmrg                           int *num_priv, long **priv );
62428d7b3dSmrgvoid I810XvMCDestroyContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext);
63428d7b3dSmrg
64428d7b3dSmrgint I810XvMCCreateSurface (ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf,
65428d7b3dSmrg                           int *num_priv, long **priv );
66428d7b3dSmrgvoid I810XvMCDestroySurface (ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf);
67428d7b3dSmrg
68428d7b3dSmrgint I810XvMCCreateSubpicture (ScrnInfoPtr pScrn, XvMCSubpicturePtr pSurf,
69428d7b3dSmrg                               int *num_priv, long **priv );
70428d7b3dSmrgvoid I810XvMCDestroySubpicture (ScrnInfoPtr pScrn, XvMCSubpicturePtr pSurf);
71428d7b3dSmrg
72428d7b3dSmrg
73428d7b3dSmrgtypedef struct {
74428d7b3dSmrg  drm_context_t drmcontext;
75428d7b3dSmrg  unsigned int fbBase;
76428d7b3dSmrg  unsigned int OverlayOffset;
77428d7b3dSmrg  unsigned int OverlaySize;
78428d7b3dSmrg  unsigned int SurfacesOffset;
79428d7b3dSmrg  unsigned int SurfacesSize;
80428d7b3dSmrg  char busIdString[10];
81428d7b3dSmrg  char pad[2];
82428d7b3dSmrg} I810XvMCCreateContextRec;
83428d7b3dSmrg
84428d7b3dSmrg
85428d7b3dSmrgstatic int yv12_subpicture_index_list[2] =
86428d7b3dSmrg{
87428d7b3dSmrg  FOURCC_IA44,
88428d7b3dSmrg  FOURCC_AI44
89428d7b3dSmrg};
90428d7b3dSmrg
91428d7b3dSmrgstatic XF86MCImageIDList yv12_subpicture_list =
92428d7b3dSmrg{
93428d7b3dSmrg  2,
94428d7b3dSmrg  yv12_subpicture_index_list
95428d7b3dSmrg};
96428d7b3dSmrg
97428d7b3dSmrgstatic XF86MCSurfaceInfoRec i810_YV12_mpg2_surface =
98428d7b3dSmrg{
99428d7b3dSmrg    FOURCC_YV12,
100428d7b3dSmrg    XVMC_CHROMA_FORMAT_420,
101428d7b3dSmrg    0,
102428d7b3dSmrg    720,
103428d7b3dSmrg    576,
104428d7b3dSmrg    720,
105428d7b3dSmrg    576,
106428d7b3dSmrg    XVMC_MPEG_2,
107428d7b3dSmrg    XVMC_OVERLAID_SURFACE | XVMC_SUBPICTURE_INDEPENDENT_SCALING |
108428d7b3dSmrg    XVMC_INTRA_UNSIGNED,
109428d7b3dSmrg    &yv12_subpicture_list
110428d7b3dSmrg};
111428d7b3dSmrg
112428d7b3dSmrgstatic XF86MCSurfaceInfoRec i810_YV12_mpg1_surface =
113428d7b3dSmrg{
114428d7b3dSmrg    FOURCC_YV12,
115428d7b3dSmrg    XVMC_CHROMA_FORMAT_420,
116428d7b3dSmrg    0,
117428d7b3dSmrg    720,
118428d7b3dSmrg    576,
119428d7b3dSmrg    720,
120428d7b3dSmrg    576,
121428d7b3dSmrg    XVMC_MPEG_1,
122428d7b3dSmrg    XVMC_OVERLAID_SURFACE | XVMC_SUBPICTURE_INDEPENDENT_SCALING |
123428d7b3dSmrg    XVMC_INTRA_UNSIGNED,
124428d7b3dSmrg    &yv12_subpicture_list
125428d7b3dSmrg};
126428d7b3dSmrg
127428d7b3dSmrgstatic XF86MCSurfaceInfoPtr ppSI[2] =
128428d7b3dSmrg{
129428d7b3dSmrg    (XF86MCSurfaceInfoPtr)&i810_YV12_mpg2_surface,
130428d7b3dSmrg    (XF86MCSurfaceInfoPtr)&i810_YV12_mpg1_surface
131428d7b3dSmrg};
132428d7b3dSmrg
133428d7b3dSmrg/* List of subpicture types that we support */
134428d7b3dSmrgstatic XF86ImageRec ia44_subpicture = XVIMAGE_IA44;
135428d7b3dSmrgstatic XF86ImageRec ai44_subpicture = XVIMAGE_AI44;
136428d7b3dSmrg
137428d7b3dSmrgstatic XF86ImagePtr i810_subpicture_list[2] =
138428d7b3dSmrg{
139428d7b3dSmrg  (XF86ImagePtr)&ia44_subpicture,
140428d7b3dSmrg  (XF86ImagePtr)&ai44_subpicture
141428d7b3dSmrg};
142428d7b3dSmrg
143428d7b3dSmrg/* Fill in the device dependent adaptor record.
144428d7b3dSmrg * This is named "I810 Video Overlay" because this code falls under the
145428d7b3dSmrg * XV extenstion, the name must match or it won't be used.
146428d7b3dSmrg *
147428d7b3dSmrg * Surface and Subpicture - see above
148428d7b3dSmrg * Function pointers to functions below
149428d7b3dSmrg */
150428d7b3dSmrgstatic XF86MCAdaptorRec pAdapt =
151428d7b3dSmrg{
152428d7b3dSmrg  "I810 Video Overlay",		/* name */
153428d7b3dSmrg  2,				/* num_surfaces */
154428d7b3dSmrg  ppSI,				/* surfaces */
155428d7b3dSmrg  2,				/* num_subpictures */
156428d7b3dSmrg  i810_subpicture_list,		/* subpictures */
157428d7b3dSmrg  (xf86XvMCCreateContextProcPtr)I810XvMCCreateContext,
158428d7b3dSmrg  (xf86XvMCDestroyContextProcPtr)I810XvMCDestroyContext,
159428d7b3dSmrg  (xf86XvMCCreateSurfaceProcPtr)I810XvMCCreateSurface,
160428d7b3dSmrg  (xf86XvMCDestroySurfaceProcPtr)I810XvMCDestroySurface,
161428d7b3dSmrg  (xf86XvMCCreateSubpictureProcPtr)I810XvMCCreateSubpicture,
162428d7b3dSmrg  (xf86XvMCDestroySubpictureProcPtr)I810XvMCDestroySubpicture
163428d7b3dSmrg};
164428d7b3dSmrg
165428d7b3dSmrgstatic XF86MCAdaptorPtr ppAdapt[1] =
166428d7b3dSmrg{
167428d7b3dSmrg	(XF86MCAdaptorPtr)&pAdapt
168428d7b3dSmrg};
169428d7b3dSmrg
170428d7b3dSmrg/**************************************************************************
171428d7b3dSmrg *
172428d7b3dSmrg *  I810InitMC
173428d7b3dSmrg *
174428d7b3dSmrg *  Initialize the hardware motion compenstation extention for this
175428d7b3dSmrg *  hardware. The initialization routines want the address of the pointers
176428d7b3dSmrg *  to the structures, not the address of the structures. This means we
177428d7b3dSmrg *  allocate (or create static?) the pointer memory and pass that
178428d7b3dSmrg *  address. This seems a little convoluted.
179428d7b3dSmrg *
180428d7b3dSmrg *  We need to allocate memory for the device depended adaptor record.
181428d7b3dSmrg *  This is what holds the pointers to all our device functions.
182428d7b3dSmrg *
183428d7b3dSmrg *  We need to map the overlay registers into the drm.
184428d7b3dSmrg *
185428d7b3dSmrg *  We need to map the surfaces into the drm.
186428d7b3dSmrg *
187428d7b3dSmrg *  Inputs:
188428d7b3dSmrg *    Screen pointer
189428d7b3dSmrg *
190428d7b3dSmrg *  Outputs:
191428d7b3dSmrg *    None, this calls the device independent screen initialization
192428d7b3dSmrg *    function.
193428d7b3dSmrg *
194428d7b3dSmrg *  Revisions:
195428d7b3dSmrg *
196428d7b3dSmrg **************************************************************************/
197428d7b3dSmrgvoid I810InitMC(ScreenPtr pScreen)
198428d7b3dSmrg{
199428d7b3dSmrg  ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
200428d7b3dSmrg  I810Ptr pI810 = I810PTR(pScrn);
201428d7b3dSmrg  int i;
202428d7b3dSmrg
203428d7b3dSmrg  /* Clear the Surface Allocation */
204428d7b3dSmrg  for(i=0; i<I810_MAX_SURFACES; i++) {
205428d7b3dSmrg	pI810->surfaceAllocation[i] = 0;
206428d7b3dSmrg  }
207428d7b3dSmrg
208428d7b3dSmrg  /* Cursor is at a page boundary, Overlay regs are not, don't forget */
209428d7b3dSmrg  if (drmAddMap(pI810->drmSubFD, (drm_handle_t)pI810->CursorStart,
210428d7b3dSmrg                4096, DRM_AGP, 0, (drmAddress) &pI810->overlay_map) < 0) {
211428d7b3dSmrg    xf86DrvMsg(pScreen->myNum, X_ERROR, "drmAddMap(overlay) failed\n");
212428d7b3dSmrg    return;
213428d7b3dSmrg  }
214428d7b3dSmrg  if (drmAddMap(pI810->drmSubFD, (drm_handle_t)pI810->MC.Start,
215428d7b3dSmrg                pI810->MC.Size, DRM_AGP, 0, (drmAddress) &pI810->mc_map) < 0) {
216428d7b3dSmrg    xf86DrvMsg(pScreen->myNum, X_ERROR, "drmAddMap(MC) failed\n");
217428d7b3dSmrg    return;
218428d7b3dSmrg  }
219428d7b3dSmrg  xf86XvMCScreenInit(pScreen, 1, ppAdapt);
220428d7b3dSmrg}
221428d7b3dSmrg
222428d7b3dSmrg/**************************************************************************
223428d7b3dSmrg *
224428d7b3dSmrg *  I810XvMCCreateContext
225428d7b3dSmrg *
226428d7b3dSmrg *  Some info about the private data:
227428d7b3dSmrg *
228428d7b3dSmrg *  Set *num_priv to the number of 32bit words that make up the size of
229428d7b3dSmrg *  of the data that priv will point to.
230428d7b3dSmrg *
231428d7b3dSmrg *  *priv = (long *) calloc (elements, sizeof(element))
232428d7b3dSmrg *  *num_priv = (elements * sizeof(element)) >> 2;
233428d7b3dSmrg *
234428d7b3dSmrg **************************************************************************/
235428d7b3dSmrg
236428d7b3dSmrgint I810XvMCCreateContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext,
237428d7b3dSmrg                            int *num_priv, long **priv )
238428d7b3dSmrg{
239428d7b3dSmrg  I810Ptr pI810 = I810PTR(pScrn);
240428d7b3dSmrg  DRIInfoPtr pDRIInfo = pI810->pDRIInfo;
241428d7b3dSmrg  I810XvMCCreateContextRec *contextRec;
242428d7b3dSmrg
243428d7b3dSmrg
244428d7b3dSmrg  if(!pI810->directRenderingEnabled) {
245428d7b3dSmrg    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
246428d7b3dSmrg        "I810XvMCCreateContext: Cannot use XvMC without DRI!\n");
247428d7b3dSmrg    return BadAlloc;
248428d7b3dSmrg  }
249428d7b3dSmrg
250428d7b3dSmrg  /* Context Already in use! */
251428d7b3dSmrg  if(pI810->xvmcContext) {
252428d7b3dSmrg    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
253428d7b3dSmrg        "I810XvMCCreateContext: 2 XvMC Contexts Attempted, not supported.\n");
254428d7b3dSmrg    return BadAlloc;
255428d7b3dSmrg  }
256428d7b3dSmrg
257428d7b3dSmrg  *priv = calloc(1,sizeof(I810XvMCCreateContextRec));
258428d7b3dSmrg  contextRec = (I810XvMCCreateContextRec *)*priv;
259428d7b3dSmrg
260428d7b3dSmrg  if(!*priv) {
261428d7b3dSmrg    *num_priv = 0;
262428d7b3dSmrg    return BadAlloc;
263428d7b3dSmrg  }
264428d7b3dSmrg
265428d7b3dSmrg  *num_priv = sizeof(I810XvMCCreateContextRec) >> 2;
266428d7b3dSmrg  if(drmCreateContext(pI810->drmSubFD, &(contextRec->drmcontext) ) < 0) {
267428d7b3dSmrg    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
268428d7b3dSmrg        "I810XvMCCreateContext: Unable to create DRMContext!\n");
269428d7b3dSmrg    free(*priv);
270428d7b3dSmrg    return BadAlloc;
271428d7b3dSmrg  }
272428d7b3dSmrg
273428d7b3dSmrg  drmAuthMagic(pI810->drmSubFD, pContext->flags);
274428d7b3dSmrg
275428d7b3dSmrg  pI810->xvmcContext = contextRec->drmcontext;
276428d7b3dSmrg  contextRec->fbBase = pScrn->memPhysBase;
277428d7b3dSmrg
278428d7b3dSmrg  /* Overlay Regs are at 1024 offset into the Cursor Space */
279428d7b3dSmrg  contextRec->OverlayOffset = pI810->CursorStart;
280428d7b3dSmrg  contextRec->OverlaySize = 4096;
281428d7b3dSmrg
282428d7b3dSmrg  contextRec->SurfacesOffset = pI810->MC.Start;
283428d7b3dSmrg  contextRec->SurfacesSize = pI810->MC.Size;
284428d7b3dSmrg  strncpy (contextRec->busIdString, pDRIInfo->busIdString, 9);
285428d7b3dSmrg
286428d7b3dSmrg  return Success;
287428d7b3dSmrg}
288428d7b3dSmrg
289428d7b3dSmrg
290428d7b3dSmrgint I810XvMCCreateSurface (ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf,
291428d7b3dSmrg                           int *num_priv, long **priv )
292428d7b3dSmrg{
293428d7b3dSmrg  I810Ptr pI810 = I810PTR(pScrn);
294428d7b3dSmrg  int i;
295428d7b3dSmrg
296428d7b3dSmrg  *priv = (long *)calloc(2,sizeof(long));
297428d7b3dSmrg
298428d7b3dSmrg  if(!*priv) {
299428d7b3dSmrg    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
300428d7b3dSmrg        "I810XvMCCreateSurface: Unable to allocate memory!\n");
301428d7b3dSmrg    *num_priv = 0;
302428d7b3dSmrg    return BadAlloc;
303428d7b3dSmrg  }
304428d7b3dSmrg  *num_priv = 2;
305428d7b3dSmrg
306428d7b3dSmrg  /* Surface Arrangement is different based on 6 or 7 Surfaces */
307428d7b3dSmrg  if(pI810->numSurfaces == 6) {
308428d7b3dSmrg     for(i=0; i<pI810->numSurfaces; i++) {
309428d7b3dSmrg       if(!pI810->surfaceAllocation[i]) {
310428d7b3dSmrg         pI810->surfaceAllocation[i] = pSurf->surface_id;
311428d7b3dSmrg         /* Y data starts at 2MB offset, each surface is 576k */
312428d7b3dSmrg         (*priv)[0] = (2*1024*1024 + 576*1024 * i);
313428d7b3dSmrg         /* UV data starts at 0 offset, each set is 288k */
314428d7b3dSmrg         (*priv)[1] = (576*512 * i);
315428d7b3dSmrg         return Success;
316428d7b3dSmrg       }
317428d7b3dSmrg     }
318428d7b3dSmrg  }
319428d7b3dSmrg  if(pI810->numSurfaces == 7) {
320428d7b3dSmrg     for(i=0; i<pI810->numSurfaces; i++) {
321428d7b3dSmrg       if(!pI810->surfaceAllocation[i]) {
322428d7b3dSmrg         pI810->surfaceAllocation[i] = pSurf->surface_id;
323428d7b3dSmrg         /* Y data starts at 2.5MB offset, each surface is 576k */
324428d7b3dSmrg         (*priv)[0] = (2*1024*1024 + 512*1024 + 576*1024 * i);
325428d7b3dSmrg         /* UV data starts at 0 offset, each set is 288k */
326428d7b3dSmrg         (*priv)[1] = (576*512 * i);
327428d7b3dSmrg         return Success;
328428d7b3dSmrg       }
329428d7b3dSmrg     }
330428d7b3dSmrg  }
331428d7b3dSmrg  (*priv)[0] = 0;
332428d7b3dSmrg  (*priv)[1] = 0;
333428d7b3dSmrg  return BadAlloc;
334428d7b3dSmrg}
335428d7b3dSmrg
336428d7b3dSmrgint I810XvMCCreateSubpicture (ScrnInfoPtr pScrn, XvMCSubpicturePtr pSubp,
337428d7b3dSmrg                              int *num_priv, long **priv )
338428d7b3dSmrg{
339428d7b3dSmrg  I810Ptr pI810 = I810PTR(pScrn);
340428d7b3dSmrg  int i;
341428d7b3dSmrg
342428d7b3dSmrg  *priv = (long *)calloc(1,sizeof(long));
343428d7b3dSmrg
344428d7b3dSmrg  if(!*priv) {
345428d7b3dSmrg    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
346428d7b3dSmrg        "I810XvMCCreateSubpicture: Unable to allocate memory!\n");
347428d7b3dSmrg    *num_priv = 0;
348428d7b3dSmrg    return BadAlloc;
349428d7b3dSmrg  }
350428d7b3dSmrg  *num_priv = 1;
351428d7b3dSmrg
352428d7b3dSmrg  if(pI810->numSurfaces == 6) {
353428d7b3dSmrg     for(i=6; i<8; i++) {
354428d7b3dSmrg       if(!pI810->surfaceAllocation[i]) {
355428d7b3dSmrg         pI810->surfaceAllocation[i] = pSubp->subpicture_id;
356428d7b3dSmrg         /* Subpictures are after the Y surfaces in memory */
357428d7b3dSmrg         (*priv)[0] = (2*1024*1024 + 576*1024 * i);
358428d7b3dSmrg         return Success;
359428d7b3dSmrg       }
360428d7b3dSmrg     }
361428d7b3dSmrg  }
362428d7b3dSmrg  if(pI810->numSurfaces == 7) {
363428d7b3dSmrg     for(i=7; i<9; i++) {
364428d7b3dSmrg         if(!pI810->surfaceAllocation[i]) {
365428d7b3dSmrg         pI810->surfaceAllocation[i] = pSubp->subpicture_id;
366428d7b3dSmrg         /* Subpictures are after the Y surfaces in memory */
367428d7b3dSmrg         (*priv)[0] = (2*1024*1024 + 512*1024 + 576*1024 * i);
368428d7b3dSmrg         return Success;
369428d7b3dSmrg       }
370428d7b3dSmrg     }
371428d7b3dSmrg  }
372428d7b3dSmrg
373428d7b3dSmrg  (*priv)[0] = 0;
374428d7b3dSmrg  return BadAlloc;
375428d7b3dSmrg}
376428d7b3dSmrg
377428d7b3dSmrgvoid I810XvMCDestroyContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext)
378428d7b3dSmrg{
379428d7b3dSmrg  I810Ptr pI810 = I810PTR(pScrn);
380428d7b3dSmrg
381428d7b3dSmrg  drmDestroyContext(pI810->drmSubFD,pI810->xvmcContext);
382428d7b3dSmrg  pI810->xvmcContext = 0;
383428d7b3dSmrg}
384428d7b3dSmrg
385428d7b3dSmrgvoid I810XvMCDestroySurface (ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf)
386428d7b3dSmrg{
387428d7b3dSmrg  I810Ptr pI810 = I810PTR(pScrn);
388428d7b3dSmrg  int i;
389428d7b3dSmrg
390428d7b3dSmrg  for(i=0; i<I810_MAX_SURFACES; i++) {
391428d7b3dSmrg    if(pI810->surfaceAllocation[i] == pSurf->surface_id) {
392428d7b3dSmrg      pI810->surfaceAllocation[i] = 0;
393428d7b3dSmrg      return;
394428d7b3dSmrg    }
395428d7b3dSmrg  }
396428d7b3dSmrg  return;
397428d7b3dSmrg}
398428d7b3dSmrg
399428d7b3dSmrgvoid I810XvMCDestroySubpicture (ScrnInfoPtr pScrn, XvMCSubpicturePtr pSubp)
400428d7b3dSmrg{
401428d7b3dSmrg  I810Ptr pI810 = I810PTR(pScrn);
402428d7b3dSmrg  int i;
403428d7b3dSmrg
404428d7b3dSmrg  for(i=pI810->numSurfaces; i<I810_MAX_SURFACES + I810_MAX_SUBPICTURES; i++) {
405428d7b3dSmrg    if(pI810->surfaceAllocation[i] == pSubp->subpicture_id) {
406428d7b3dSmrg      pI810->surfaceAllocation[i] = 0;
407428d7b3dSmrg      return;
408428d7b3dSmrg    }
409428d7b3dSmrg  }
410428d7b3dSmrg  return;
411428d7b3dSmrg}
412428d7b3dSmrg
413428d7b3dSmrg
414428d7b3dSmrg
415428d7b3dSmrg
416428d7b3dSmrg
417428d7b3dSmrg
418