1fa225cbcSrjs/***************************************************************************
2fa225cbcSrjs
3fa225cbcSrjsCopyright 2000 Intel Corporation.  All Rights Reserved.
4fa225cbcSrjs
5fa225cbcSrjsPermission is hereby granted, free of charge, to any person obtaining a
6fa225cbcSrjscopy of this software and associated documentation files (the
7fa225cbcSrjs"Software"), to deal in the Software without restriction, including
8fa225cbcSrjswithout limitation the rights to use, copy, modify, merge, publish,
9fa225cbcSrjsdistribute, sub license, and/or sell copies of the Software, and to
10fa225cbcSrjspermit persons to whom the Software is furnished to do so, subject to
11fa225cbcSrjsthe following conditions:
12fa225cbcSrjs
13fa225cbcSrjsThe above copyright notice and this permission notice (including the
14fa225cbcSrjsnext paragraph) shall be included in all copies or substantial portions
15fa225cbcSrjsof the Software.
16fa225cbcSrjs
17fa225cbcSrjsTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18fa225cbcSrjsOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19fa225cbcSrjsMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
20fa225cbcSrjsIN NO EVENT SHALL INTEL, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
21fa225cbcSrjsDAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
22fa225cbcSrjsOTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
23fa225cbcSrjsTHE USE OR OTHER DEALINGS IN THE SOFTWARE.
24fa225cbcSrjs
25fa225cbcSrjs**************************************************************************/
26fa225cbcSrjs
27fa225cbcSrjs/*
28fa225cbcSrjs * i810_hwmc.c: i810 HWMC Driver
29fa225cbcSrjs *
30fa225cbcSrjs * Authors:
31fa225cbcSrjs *      Matt Sottek <matthew.j.sottek@intel.com>
32fa225cbcSrjs *
33fa225cbcSrjs *
34fa225cbcSrjs */
35fa225cbcSrjs
36fa225cbcSrjs#ifdef HAVE_CONFIG_H
37fa225cbcSrjs#include "config.h"
38fa225cbcSrjs#endif
39fa225cbcSrjs
40fa225cbcSrjs#include <string.h>
41fa225cbcSrjs
42fa225cbcSrjs#include "xf86.h"
43fa225cbcSrjs#include "xf86_OSproc.h"
44fa225cbcSrjs#include "compiler.h"
45fa225cbcSrjs#include "xf86PciInfo.h"
46fa225cbcSrjs#include "xf86Pci.h"
47fa225cbcSrjs#include "xf86fbman.h"
48fa225cbcSrjs#include "regionstr.h"
49fa225cbcSrjs
50fa225cbcSrjs#include "i810.h"
51fa225cbcSrjs#include "i810_dri.h"
52fa225cbcSrjs
53fa225cbcSrjs#include "xf86xv.h"
54fa225cbcSrjs#include "xf86xvmc.h"
55fa225cbcSrjs#include <X11/extensions/Xv.h>
56fa225cbcSrjs#include <X11/extensions/XvMC.h>
57fa225cbcSrjs#include "xaa.h"
58fa225cbcSrjs#include "xaalocal.h"
59fa225cbcSrjs#include "dixstruct.h"
60fa225cbcSrjs#include "fourcc.h"
61fa225cbcSrjs
62fa225cbcSrjsint I810XvMCCreateContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext,
63fa225cbcSrjs                           int *num_priv, long **priv );
64fa225cbcSrjsvoid I810XvMCDestroyContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext);
65fa225cbcSrjs
66fa225cbcSrjsint I810XvMCCreateSurface (ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf,
67fa225cbcSrjs                           int *num_priv, long **priv );
68fa225cbcSrjsvoid I810XvMCDestroySurface (ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf);
69fa225cbcSrjs
70fa225cbcSrjsint I810XvMCCreateSubpicture (ScrnInfoPtr pScrn, XvMCSubpicturePtr pSurf,
71fa225cbcSrjs                               int *num_priv, long **priv );
72fa225cbcSrjsvoid I810XvMCDestroySubpicture (ScrnInfoPtr pScrn, XvMCSubpicturePtr pSurf);
73fa225cbcSrjs
74fa225cbcSrjs
75fa225cbcSrjstypedef struct {
76fa225cbcSrjs  drm_context_t drmcontext;
77fa225cbcSrjs  unsigned int fbBase;
78fa225cbcSrjs  unsigned int OverlayOffset;
79fa225cbcSrjs  unsigned int OverlaySize;
80fa225cbcSrjs  unsigned int SurfacesOffset;
81fa225cbcSrjs  unsigned int SurfacesSize;
82fa225cbcSrjs  char busIdString[10];
83fa225cbcSrjs  char pad[2];
84fa225cbcSrjs} I810XvMCCreateContextRec;
85fa225cbcSrjs
86fa225cbcSrjs
87fa225cbcSrjsstatic int yv12_subpicture_index_list[2] =
88fa225cbcSrjs{
89fa225cbcSrjs  FOURCC_IA44,
90fa225cbcSrjs  FOURCC_AI44
91fa225cbcSrjs};
92fa225cbcSrjs
93fa225cbcSrjsstatic XF86MCImageIDList yv12_subpicture_list =
94fa225cbcSrjs{
95fa225cbcSrjs  2,
96fa225cbcSrjs  yv12_subpicture_index_list
97fa225cbcSrjs};
98fa225cbcSrjs
99fa225cbcSrjsstatic XF86MCSurfaceInfoRec i810_YV12_mpg2_surface =
100fa225cbcSrjs{
101fa225cbcSrjs    FOURCC_YV12,
102fa225cbcSrjs    XVMC_CHROMA_FORMAT_420,
103fa225cbcSrjs    0,
104fa225cbcSrjs    720,
105fa225cbcSrjs    576,
106fa225cbcSrjs    720,
107fa225cbcSrjs    576,
108fa225cbcSrjs    XVMC_MPEG_2,
109fa225cbcSrjs    XVMC_OVERLAID_SURFACE | XVMC_SUBPICTURE_INDEPENDENT_SCALING |
110fa225cbcSrjs    XVMC_INTRA_UNSIGNED,
111fa225cbcSrjs    &yv12_subpicture_list
112fa225cbcSrjs};
113fa225cbcSrjs
114fa225cbcSrjsstatic XF86MCSurfaceInfoRec i810_YV12_mpg1_surface =
115fa225cbcSrjs{
116fa225cbcSrjs    FOURCC_YV12,
117fa225cbcSrjs    XVMC_CHROMA_FORMAT_420,
118fa225cbcSrjs    0,
119fa225cbcSrjs    720,
120fa225cbcSrjs    576,
121fa225cbcSrjs    720,
122fa225cbcSrjs    576,
123fa225cbcSrjs    XVMC_MPEG_1,
124fa225cbcSrjs    XVMC_OVERLAID_SURFACE | XVMC_SUBPICTURE_INDEPENDENT_SCALING |
125fa225cbcSrjs    XVMC_INTRA_UNSIGNED,
126fa225cbcSrjs    &yv12_subpicture_list
127fa225cbcSrjs};
128fa225cbcSrjs
129fa225cbcSrjsstatic XF86MCSurfaceInfoPtr ppSI[2] =
130fa225cbcSrjs{
131fa225cbcSrjs    (XF86MCSurfaceInfoPtr)&i810_YV12_mpg2_surface,
132fa225cbcSrjs    (XF86MCSurfaceInfoPtr)&i810_YV12_mpg1_surface
133fa225cbcSrjs};
134fa225cbcSrjs
135fa225cbcSrjs/* List of subpicture types that we support */
136fa225cbcSrjsstatic XF86ImageRec ia44_subpicture = XVIMAGE_IA44;
137fa225cbcSrjsstatic XF86ImageRec ai44_subpicture = XVIMAGE_AI44;
138fa225cbcSrjs
139fa225cbcSrjsstatic XF86ImagePtr i810_subpicture_list[2] =
140fa225cbcSrjs{
141fa225cbcSrjs  (XF86ImagePtr)&ia44_subpicture,
142fa225cbcSrjs  (XF86ImagePtr)&ai44_subpicture
143fa225cbcSrjs};
144fa225cbcSrjs
145fa225cbcSrjs/* Fill in the device dependent adaptor record.
146fa225cbcSrjs * This is named "I810 Video Overlay" because this code falls under the
147fa225cbcSrjs * XV extenstion, the name must match or it won't be used.
148fa225cbcSrjs *
149fa225cbcSrjs * Surface and Subpicture - see above
150fa225cbcSrjs * Function pointers to functions below
151fa225cbcSrjs */
152fa225cbcSrjsstatic XF86MCAdaptorRec pAdapt =
153fa225cbcSrjs{
154fa225cbcSrjs  "I810 Video Overlay",		/* name */
155fa225cbcSrjs  2,				/* num_surfaces */
156fa225cbcSrjs  ppSI,				/* surfaces */
157fa225cbcSrjs  2,				/* num_subpictures */
158fa225cbcSrjs  i810_subpicture_list,		/* subpictures */
159fa225cbcSrjs  (xf86XvMCCreateContextProcPtr)I810XvMCCreateContext,
160fa225cbcSrjs  (xf86XvMCDestroyContextProcPtr)I810XvMCDestroyContext,
161fa225cbcSrjs  (xf86XvMCCreateSurfaceProcPtr)I810XvMCCreateSurface,
162fa225cbcSrjs  (xf86XvMCDestroySurfaceProcPtr)I810XvMCDestroySurface,
163fa225cbcSrjs  (xf86XvMCCreateSubpictureProcPtr)I810XvMCCreateSubpicture,
164fa225cbcSrjs  (xf86XvMCDestroySubpictureProcPtr)I810XvMCDestroySubpicture
165fa225cbcSrjs};
166fa225cbcSrjs
167fa225cbcSrjsstatic XF86MCAdaptorPtr ppAdapt[1] =
168fa225cbcSrjs{
169fa225cbcSrjs	(XF86MCAdaptorPtr)&pAdapt
170fa225cbcSrjs};
171fa225cbcSrjs
172fa225cbcSrjs/**************************************************************************
173fa225cbcSrjs *
174fa225cbcSrjs *  I810InitMC
175fa225cbcSrjs *
176fa225cbcSrjs *  Initialize the hardware motion compenstation extention for this
177fa225cbcSrjs *  hardware. The initialization routines want the address of the pointers
178fa225cbcSrjs *  to the structures, not the address of the structures. This means we
179fa225cbcSrjs *  allocate (or create static?) the pointer memory and pass that
180fa225cbcSrjs *  address. This seems a little convoluted.
181fa225cbcSrjs *
182fa225cbcSrjs *  We need to allocate memory for the device depended adaptor record.
183fa225cbcSrjs *  This is what holds the pointers to all our device functions.
184fa225cbcSrjs *
185fa225cbcSrjs *  We need to map the overlay registers into the drm.
186fa225cbcSrjs *
187fa225cbcSrjs *  We need to map the surfaces into the drm.
188fa225cbcSrjs *
189fa225cbcSrjs *  Inputs:
190fa225cbcSrjs *    Screen pointer
191fa225cbcSrjs *
192fa225cbcSrjs *  Outputs:
193fa225cbcSrjs *    None, this calls the device independent screen initialization
194fa225cbcSrjs *    function.
195fa225cbcSrjs *
196fa225cbcSrjs *  Revisions:
197fa225cbcSrjs *
198fa225cbcSrjs **************************************************************************/
199fa225cbcSrjsvoid I810InitMC(ScreenPtr pScreen)
200fa225cbcSrjs{
201fa225cbcSrjs  ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
202fa225cbcSrjs  I810Ptr pI810 = I810PTR(pScrn);
203fa225cbcSrjs  int i;
204fa225cbcSrjs
205fa225cbcSrjs  /* Clear the Surface Allocation */
206fa225cbcSrjs  for(i=0; i<I810_MAX_SURFACES; i++) {
207fa225cbcSrjs	pI810->surfaceAllocation[i] = 0;
208fa225cbcSrjs  }
209fa225cbcSrjs
210fa225cbcSrjs  /* Cursor is at a page boundary, Overlay regs are not, don't forget */
211fa225cbcSrjs  if (drmAddMap(pI810->drmSubFD, (drm_handle_t)pI810->CursorStart,
212fa225cbcSrjs                4096, DRM_AGP, 0, (drmAddress) &pI810->overlay_map) < 0) {
213fa225cbcSrjs    xf86DrvMsg(pScreen->myNum, X_ERROR, "drmAddMap(overlay) failed\n");
214fa225cbcSrjs    return;
215fa225cbcSrjs  }
216fa225cbcSrjs  if (drmAddMap(pI810->drmSubFD, (drm_handle_t)pI810->MC.Start,
217fa225cbcSrjs                pI810->MC.Size, DRM_AGP, 0, (drmAddress) &pI810->mc_map) < 0) {
218fa225cbcSrjs    xf86DrvMsg(pScreen->myNum, X_ERROR, "drmAddMap(MC) failed\n");
219fa225cbcSrjs    return;
220fa225cbcSrjs  }
221fa225cbcSrjs  xf86XvMCScreenInit(pScreen, 1, ppAdapt);
222fa225cbcSrjs}
223fa225cbcSrjs
224fa225cbcSrjs/**************************************************************************
225fa225cbcSrjs *
226fa225cbcSrjs *  I810XvMCCreateContext
227fa225cbcSrjs *
228fa225cbcSrjs *  Some info about the private data:
229fa225cbcSrjs *
230fa225cbcSrjs *  Set *num_priv to the number of 32bit words that make up the size of
231fa225cbcSrjs *  of the data that priv will point to.
232fa225cbcSrjs *
233fa225cbcSrjs *  *priv = (long *) xcalloc (elements, sizeof(element))
234fa225cbcSrjs *  *num_priv = (elements * sizeof(element)) >> 2;
235fa225cbcSrjs *
236fa225cbcSrjs **************************************************************************/
237fa225cbcSrjs
238fa225cbcSrjsint I810XvMCCreateContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext,
239fa225cbcSrjs                            int *num_priv, long **priv )
240fa225cbcSrjs{
241fa225cbcSrjs  I810Ptr pI810 = I810PTR(pScrn);
242fa225cbcSrjs  DRIInfoPtr pDRIInfo = pI810->pDRIInfo;
243fa225cbcSrjs  I810XvMCCreateContextRec *contextRec;
244fa225cbcSrjs
245fa225cbcSrjs
246fa225cbcSrjs  if(!pI810->directRenderingEnabled) {
247fa225cbcSrjs    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
248fa225cbcSrjs        "I810XvMCCreateContext: Cannot use XvMC without DRI!\n");
249fa225cbcSrjs    return BadAlloc;
250fa225cbcSrjs  }
251fa225cbcSrjs
252fa225cbcSrjs  /* Context Already in use! */
253fa225cbcSrjs  if(pI810->xvmcContext) {
254fa225cbcSrjs    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
255fa225cbcSrjs        "I810XvMCCreateContext: 2 XvMC Contexts Attempted, not supported.\n");
256fa225cbcSrjs    return BadAlloc;
257fa225cbcSrjs  }
258fa225cbcSrjs
259fa225cbcSrjs  *priv = xcalloc(1,sizeof(I810XvMCCreateContextRec));
260fa225cbcSrjs  contextRec = (I810XvMCCreateContextRec *)*priv;
261fa225cbcSrjs
262fa225cbcSrjs  if(!*priv) {
263fa225cbcSrjs    *num_priv = 0;
264fa225cbcSrjs    return BadAlloc;
265fa225cbcSrjs  }
266fa225cbcSrjs
267fa225cbcSrjs  *num_priv = sizeof(I810XvMCCreateContextRec) >> 2;
268fa225cbcSrjs  if(drmCreateContext(pI810->drmSubFD, &(contextRec->drmcontext) ) < 0) {
269fa225cbcSrjs    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
270fa225cbcSrjs        "I810XvMCCreateContext: Unable to create DRMContext!\n");
271fa225cbcSrjs    xfree(*priv);
272fa225cbcSrjs    return BadAlloc;
273fa225cbcSrjs  }
274fa225cbcSrjs
275fa225cbcSrjs  drmAuthMagic(pI810->drmSubFD, pContext->flags);
276fa225cbcSrjs
277fa225cbcSrjs  pI810->xvmcContext = contextRec->drmcontext;
278fa225cbcSrjs  contextRec->fbBase = pScrn->memPhysBase;
279fa225cbcSrjs
280fa225cbcSrjs  /* Overlay Regs are at 1024 offset into the Cursor Space */
281fa225cbcSrjs  contextRec->OverlayOffset = pI810->CursorStart;
282fa225cbcSrjs  contextRec->OverlaySize = 4096;
283fa225cbcSrjs
284fa225cbcSrjs  contextRec->SurfacesOffset = pI810->MC.Start;
285fa225cbcSrjs  contextRec->SurfacesSize = pI810->MC.Size;
286fa225cbcSrjs  strncpy (contextRec->busIdString, pDRIInfo->busIdString, 9);
287fa225cbcSrjs
288fa225cbcSrjs  return Success;
289fa225cbcSrjs}
290fa225cbcSrjs
291fa225cbcSrjs
292fa225cbcSrjsint I810XvMCCreateSurface (ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf,
293fa225cbcSrjs                           int *num_priv, long **priv )
294fa225cbcSrjs{
295fa225cbcSrjs  I810Ptr pI810 = I810PTR(pScrn);
296fa225cbcSrjs  int i;
297fa225cbcSrjs
298fa225cbcSrjs  *priv = (long *)xcalloc(2,sizeof(long));
299fa225cbcSrjs
300fa225cbcSrjs  if(!*priv) {
301fa225cbcSrjs    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
302fa225cbcSrjs        "I810XvMCCreateSurface: Unable to allocate memory!\n");
303fa225cbcSrjs    *num_priv = 0;
304fa225cbcSrjs    return BadAlloc;
305fa225cbcSrjs  }
306fa225cbcSrjs  *num_priv = 2;
307fa225cbcSrjs
308fa225cbcSrjs  /* Surface Arrangement is different based on 6 or 7 Surfaces */
309fa225cbcSrjs  if(pI810->numSurfaces == 6) {
310fa225cbcSrjs     for(i=0; i<pI810->numSurfaces; i++) {
311fa225cbcSrjs       if(!pI810->surfaceAllocation[i]) {
312fa225cbcSrjs         pI810->surfaceAllocation[i] = pSurf->surface_id;
313fa225cbcSrjs         /* Y data starts at 2MB offset, each surface is 576k */
314fa225cbcSrjs         (*priv)[0] = (2*1024*1024 + 576*1024 * i);
315fa225cbcSrjs         /* UV data starts at 0 offset, each set is 288k */
316fa225cbcSrjs         (*priv)[1] = (576*512 * i);
317fa225cbcSrjs         return Success;
318fa225cbcSrjs       }
319fa225cbcSrjs     }
320fa225cbcSrjs  }
321fa225cbcSrjs  if(pI810->numSurfaces == 7) {
322fa225cbcSrjs     for(i=0; i<pI810->numSurfaces; i++) {
323fa225cbcSrjs       if(!pI810->surfaceAllocation[i]) {
324fa225cbcSrjs         pI810->surfaceAllocation[i] = pSurf->surface_id;
325fa225cbcSrjs         /* Y data starts at 2.5MB offset, each surface is 576k */
326fa225cbcSrjs         (*priv)[0] = (2*1024*1024 + 512*1024 + 576*1024 * i);
327fa225cbcSrjs         /* UV data starts at 0 offset, each set is 288k */
328fa225cbcSrjs         (*priv)[1] = (576*512 * i);
329fa225cbcSrjs         return Success;
330fa225cbcSrjs       }
331fa225cbcSrjs     }
332fa225cbcSrjs  }
333fa225cbcSrjs  (*priv)[0] = 0;
334fa225cbcSrjs  (*priv)[1] = 0;
335fa225cbcSrjs  return BadAlloc;
336fa225cbcSrjs}
337fa225cbcSrjs
338fa225cbcSrjsint I810XvMCCreateSubpicture (ScrnInfoPtr pScrn, XvMCSubpicturePtr pSubp,
339fa225cbcSrjs                              int *num_priv, long **priv )
340fa225cbcSrjs{
341fa225cbcSrjs  I810Ptr pI810 = I810PTR(pScrn);
342fa225cbcSrjs  int i;
343fa225cbcSrjs
344fa225cbcSrjs  *priv = (long *)xcalloc(1,sizeof(long));
345fa225cbcSrjs
346fa225cbcSrjs  if(!*priv) {
347fa225cbcSrjs    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
348fa225cbcSrjs        "I810XvMCCreateSubpicture: Unable to allocate memory!\n");
349fa225cbcSrjs    *num_priv = 0;
350fa225cbcSrjs    return BadAlloc;
351fa225cbcSrjs  }
352fa225cbcSrjs  *num_priv = 1;
353fa225cbcSrjs
354fa225cbcSrjs  if(pI810->numSurfaces == 6) {
355fa225cbcSrjs     for(i=6; i<8; i++) {
356fa225cbcSrjs       if(!pI810->surfaceAllocation[i]) {
357fa225cbcSrjs         pI810->surfaceAllocation[i] = pSubp->subpicture_id;
358fa225cbcSrjs         /* Subpictures are after the Y surfaces in memory */
359fa225cbcSrjs         (*priv)[0] = (2*1024*1024 + 576*1024 * i);
360fa225cbcSrjs         return Success;
361fa225cbcSrjs       }
362fa225cbcSrjs     }
363fa225cbcSrjs  }
364fa225cbcSrjs  if(pI810->numSurfaces == 7) {
365fa225cbcSrjs     for(i=7; i<9; i++) {
366fa225cbcSrjs         if(!pI810->surfaceAllocation[i]) {
367fa225cbcSrjs         pI810->surfaceAllocation[i] = pSubp->subpicture_id;
368fa225cbcSrjs         /* Subpictures are after the Y surfaces in memory */
369fa225cbcSrjs         (*priv)[0] = (2*1024*1024 + 512*1024 + 576*1024 * i);
370fa225cbcSrjs         return Success;
371fa225cbcSrjs       }
372fa225cbcSrjs     }
373fa225cbcSrjs  }
374fa225cbcSrjs
375fa225cbcSrjs  (*priv)[0] = 0;
376fa225cbcSrjs  return BadAlloc;
377fa225cbcSrjs}
378fa225cbcSrjs
379fa225cbcSrjsvoid I810XvMCDestroyContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext)
380fa225cbcSrjs{
381fa225cbcSrjs  I810Ptr pI810 = I810PTR(pScrn);
382fa225cbcSrjs
383fa225cbcSrjs  drmDestroyContext(pI810->drmSubFD,pI810->xvmcContext);
384fa225cbcSrjs  pI810->xvmcContext = 0;
385fa225cbcSrjs}
386fa225cbcSrjs
387fa225cbcSrjsvoid I810XvMCDestroySurface (ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf)
388fa225cbcSrjs{
389fa225cbcSrjs  I810Ptr pI810 = I810PTR(pScrn);
390fa225cbcSrjs  int i;
391fa225cbcSrjs
392fa225cbcSrjs  for(i=0; i<I810_MAX_SURFACES; i++) {
393fa225cbcSrjs    if(pI810->surfaceAllocation[i] == pSurf->surface_id) {
394fa225cbcSrjs      pI810->surfaceAllocation[i] = 0;
395fa225cbcSrjs      return;
396fa225cbcSrjs    }
397fa225cbcSrjs  }
398fa225cbcSrjs  return;
399fa225cbcSrjs}
400fa225cbcSrjs
401fa225cbcSrjsvoid I810XvMCDestroySubpicture (ScrnInfoPtr pScrn, XvMCSubpicturePtr pSubp)
402fa225cbcSrjs{
403fa225cbcSrjs  I810Ptr pI810 = I810PTR(pScrn);
404fa225cbcSrjs  int i;
405fa225cbcSrjs
406fa225cbcSrjs  for(i=pI810->numSurfaces; i<I810_MAX_SURFACES + I810_MAX_SUBPICTURES; i++) {
407fa225cbcSrjs    if(pI810->surfaceAllocation[i] == pSubp->subpicture_id) {
408fa225cbcSrjs      pI810->surfaceAllocation[i] = 0;
409fa225cbcSrjs      return;
410fa225cbcSrjs    }
411fa225cbcSrjs  }
412fa225cbcSrjs  return;
413fa225cbcSrjs}
414fa225cbcSrjs
415fa225cbcSrjs
416fa225cbcSrjs
417fa225cbcSrjs
418fa225cbcSrjs
419fa225cbcSrjs
420