1fa225cbcSrjs/***************************************************************************
2fa225cbcSrjs
3fa225cbcSrjsCopyright 2001 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** File libI810XvMC.c
29fa225cbcSrjs**
30fa225cbcSrjs** Authors:
31fa225cbcSrjs**      Matt Sottek <matthew.j.sottek@intel.com>
32fa225cbcSrjs**      Bob Paauwe  <bob.j.paauwe@intel.com>
33fa225cbcSrjs**
34fa225cbcSrjs**
35fa225cbcSrjs***************************************************************************/
36fa225cbcSrjs#include <stdio.h>
37fa225cbcSrjs#include <stdlib.h>
38fa225cbcSrjs#include <unistd.h>
39fa225cbcSrjs#include <errno.h>
40fa225cbcSrjs#include <signal.h>
41fa225cbcSrjs#include <fcntl.h>
42fa225cbcSrjs#include <dirent.h>
43fa225cbcSrjs#include <string.h>
44fa225cbcSrjs
45fa225cbcSrjs#include <sys/ioctl.h>
46fa225cbcSrjs#include <X11/Xlibint.h>
47fa225cbcSrjs#include <fourcc.h>
48fa225cbcSrjs#include <X11/extensions/Xv.h>
49fa225cbcSrjs#include <X11/extensions/Xvlib.h>
50fa225cbcSrjs#include <X11/extensions/XvMC.h>
51fa225cbcSrjs#include <X11/extensions/XvMClib.h>
52fa225cbcSrjs#include "I810XvMC.h"
53fa225cbcSrjs
54fa225cbcSrjsstatic int error_base;
55fa225cbcSrjsstatic int event_base;
56fa225cbcSrjs
57fa225cbcSrjs/***************************************************************************
58fa225cbcSrjs// Function: i810_get_free_buffer
59fa225cbcSrjs// Description: Allocates a free dma page using kernel ioctls, then
60fa225cbcSrjs//   programs the data into the already allocated dma buffer list.
61fa225cbcSrjs// Arguments: pI810XvMC private data structure from the current context.
62fa225cbcSrjs// Notes: We faked the drmMapBufs for the i810's security so now we have
63fa225cbcSrjs//   to insert an allocated page into the correct spot in the faked
64fa225cbcSrjs//   list to keep up appearences.
65fa225cbcSrjs//   Concept for this function was taken from Mesa sources.
66fa225cbcSrjs// Returns: drmBufPtr containing the information about the allocated page.
67fa225cbcSrjs***************************************************************************/
68fa225cbcSrjsdrmBufPtr i810_get_free_buffer(i810XvMCContext *pI810XvMC) {
69fa225cbcSrjs   drmI810DMA dma;
70fa225cbcSrjs   drmBufPtr buf;
71fa225cbcSrjs
72fa225cbcSrjs   dma.granted = 0;
73fa225cbcSrjs   dma.request_size = 4096;
74fa225cbcSrjs   while(!dma.granted) {
75fa225cbcSrjs     if(GET_BUFFER(pI810XvMC, dma) || !dma.granted)
76fa225cbcSrjs       FLUSH(pI810XvMC);
77fa225cbcSrjs   } /* No DMA granted */
78fa225cbcSrjs
79fa225cbcSrjs   buf = &(pI810XvMC->dmabufs->list[dma.request_idx]);
80fa225cbcSrjs   buf->idx = dma.request_idx;
81fa225cbcSrjs   buf->used = 0;
82fa225cbcSrjs   buf->total = dma.request_size;
83fa225cbcSrjs   buf->address = (drmAddress)dma.virtual;
84fa225cbcSrjs   return buf;
85fa225cbcSrjs}
86fa225cbcSrjs
87fa225cbcSrjs/***************************************************************************
88fa225cbcSrjs// Function: free_privContext
89fa225cbcSrjs// Description: Free's the private context structure if the reference
90fa225cbcSrjs//  count is 0.
91fa225cbcSrjs***************************************************************************/
92fa225cbcSrjsvoid i810_free_privContext(i810XvMCContext *pI810XvMC) {
93fa225cbcSrjs
94fa225cbcSrjs  I810_LOCK(pI810XvMC,DRM_LOCK_QUIESCENT);
95fa225cbcSrjs
96fa225cbcSrjs
97fa225cbcSrjs  pI810XvMC->ref--;
98fa225cbcSrjs  if(!pI810XvMC->ref) {
99fa225cbcSrjs    drmUnmapBufs(pI810XvMC->dmabufs);
100fa225cbcSrjs    drmUnmap(pI810XvMC->overlay.address,pI810XvMC->overlay.size);
101fa225cbcSrjs    drmUnmap(pI810XvMC->surfaces.address,pI810XvMC->surfaces.size);
102fa225cbcSrjs    drmClose(pI810XvMC->fd);
103fa225cbcSrjs
104fa225cbcSrjs    free(pI810XvMC->dmabufs->list);
105fa225cbcSrjs    free(pI810XvMC);
106fa225cbcSrjs  }
107fa225cbcSrjs
108fa225cbcSrjs  I810_UNLOCK(pI810XvMC);
109fa225cbcSrjs}
110fa225cbcSrjs
111fa225cbcSrjs
112fa225cbcSrjs/***************************************************************************
113fa225cbcSrjs// Function: XvMCCreateContext
114fa225cbcSrjs// Description: Create a XvMC context for the given surface parameters.
115fa225cbcSrjs// Arguments:
116fa225cbcSrjs//   display - Connection to the X server.
117fa225cbcSrjs//   port - XvPortID to use as avertised by the X connection.
118fa225cbcSrjs//   surface_type_id - Unique identifier for the Surface type.
119fa225cbcSrjs//   width - Width of the surfaces.
120fa225cbcSrjs//   height - Height of the surfaces.
121fa225cbcSrjs//   flags - one or more of the following
122fa225cbcSrjs//      XVMC_DIRECT - A direct rendered context is requested.
123fa225cbcSrjs//
124fa225cbcSrjs// Notes: surface_type_id and width/height parameters must match those
125fa225cbcSrjs//        returned by XvMCListSurfaceTypes.
126fa225cbcSrjs// Returns: Status
127fa225cbcSrjs***************************************************************************/
128fa225cbcSrjs_X_EXPORT Status XvMCCreateContext(Display *display, XvPortID port,
129fa225cbcSrjs			 int surface_type_id, int width, int height, int flags,
130fa225cbcSrjs			 XvMCContext *context) {
131fa225cbcSrjs  i810XvMCContext *pI810XvMC;
132fa225cbcSrjs  int priv_count;
133fa225cbcSrjs  uint *priv_data;
134fa225cbcSrjs  uint magic;
135fa225cbcSrjs  Status ret;
136fa225cbcSrjs  int major, minor;
137fa225cbcSrjs
138fa225cbcSrjs  /* Verify Obvious things first */
139fa225cbcSrjs  if(context == NULL) {
140fa225cbcSrjs    return XvMCBadContext;
141fa225cbcSrjs  }
142fa225cbcSrjs
143fa225cbcSrjs  if(!(flags & XVMC_DIRECT)) {
144fa225cbcSrjs    /* Indirect */
145fa225cbcSrjs    printf("Indirect Rendering not supported!\nUsing Direct.");
146fa225cbcSrjs  }
147fa225cbcSrjs
148fa225cbcSrjs  /* Limit use to root for now */
149fa225cbcSrjs  if(geteuid()) {
150fa225cbcSrjs    printf("Use of XvMC on i810 is currently limited to root\n");
151fa225cbcSrjs    return BadAccess;
152fa225cbcSrjs  }
153fa225cbcSrjs
154fa225cbcSrjs  /* FIXME: Check $DISPLAY for legal values here */
155fa225cbcSrjs
156fa225cbcSrjs  context->surface_type_id = surface_type_id;
157fa225cbcSrjs  context->width = (unsigned short)width;
158fa225cbcSrjs  context->height = (unsigned short)height;
159fa225cbcSrjs  context->flags = flags;
160fa225cbcSrjs  context->port = port;
161fa225cbcSrjs  /*
162fa225cbcSrjs     Width, Height, and flags are checked against surface_type_id
163fa225cbcSrjs     and port for validity inside the X server, no need to check
164fa225cbcSrjs     here.
165fa225cbcSrjs  */
166fa225cbcSrjs
167fa225cbcSrjs  /* Allocate private Context data */
168fa225cbcSrjs  context->privData = (void *)malloc(sizeof(i810XvMCContext));
169fa225cbcSrjs  if(!context->privData) {
170fa225cbcSrjs    printf("Unable to allocate resources for XvMC context.\n");
171fa225cbcSrjs    return BadAlloc;
172fa225cbcSrjs  }
173fa225cbcSrjs  pI810XvMC = (i810XvMCContext *)context->privData;
174fa225cbcSrjs
175fa225cbcSrjs
176fa225cbcSrjs  /* Verify the XvMC extension exists */
177fa225cbcSrjs  if(! XvMCQueryExtension(display, &event_base,
178fa225cbcSrjs			  &error_base)) {
179fa225cbcSrjs    printf("XvMC Extension is not available!\n");
180fa225cbcSrjs    return BadAlloc;
181fa225cbcSrjs  }
182fa225cbcSrjs  /* Verify XvMC version */
183fa225cbcSrjs  ret = XvMCQueryVersion(display, &major, &minor);
184fa225cbcSrjs  if(ret) {
185fa225cbcSrjs    printf("XvMCQuery Version Failed, unable to determine protocol version\n");
186fa225cbcSrjs  }
187fa225cbcSrjs  /* FIXME: Check Major and Minor here */
188fa225cbcSrjs
189fa225cbcSrjs  /* Check for drm */
190fa225cbcSrjs  if(! drmAvailable()) {
191fa225cbcSrjs    printf("Direct Rendering is not avilable on this system!\n");
192fa225cbcSrjs    return BadAlloc;
193fa225cbcSrjs  }
194fa225cbcSrjs
195fa225cbcSrjs  /*
196fa225cbcSrjs     Build the Attribute Atoms, and Initialize the ones that exist
197fa225cbcSrjs     in Xv.
198fa225cbcSrjs  */
199fa225cbcSrjs  pI810XvMC->xv_colorkey = XInternAtom(display,"XV_COLORKEY",0);
200fa225cbcSrjs  if(!pI810XvMC->xv_colorkey) {
201fa225cbcSrjs    return XvBadPort;
202fa225cbcSrjs  }
203fa225cbcSrjs  ret = XvGetPortAttribute(display,port,pI810XvMC->xv_colorkey,
204fa225cbcSrjs			   &pI810XvMC->colorkey);
205fa225cbcSrjs  if(ret) {
206fa225cbcSrjs    return ret;
207fa225cbcSrjs  }
208fa225cbcSrjs  pI810XvMC->xv_brightness = XInternAtom(display,"XV_BRIGHTNESS",0);
209fa225cbcSrjs  pI810XvMC->xv_saturation = XInternAtom(display,"XV_SATURATION",0);
210fa225cbcSrjs  pI810XvMC->xv_contrast = XInternAtom(display,"XV_CONTRAST",0);
211fa225cbcSrjs  pI810XvMC->brightness = 0;
212fa225cbcSrjs  pI810XvMC->saturation = 0x80;  /* 1.0 in 3.7 format */
213fa225cbcSrjs  pI810XvMC->contrast = 0x40; /* 1.0 in 3.6 format */
214fa225cbcSrjs
215fa225cbcSrjs  /* Open DRI Device */
216fa225cbcSrjs  if((pI810XvMC->fd = drmOpen("i810",NULL)) < 0) {
217fa225cbcSrjs    printf("DRM Device for i810 could not be opened.\n");
218fa225cbcSrjs    free(pI810XvMC);
219fa225cbcSrjs    return BadAccess;
220fa225cbcSrjs  } /* !pI810XvMC->fd */
221fa225cbcSrjs
222fa225cbcSrjs  /* Get magic number and put it in privData for passing */
223fa225cbcSrjs  drmGetMagic(pI810XvMC->fd,&magic);
224fa225cbcSrjs  context->flags = (unsigned long)magic;
225fa225cbcSrjs
226fa225cbcSrjs  /*
227fa225cbcSrjs    Pass control to the X server to create a drm_context_t for us and
228fa225cbcSrjs    validate the with/height and flags.
229fa225cbcSrjs  */
230fa225cbcSrjs  if((ret = _xvmc_create_context(display, context, &priv_count, &priv_data))) {
231fa225cbcSrjs    printf("Unable to create XvMC Context.\n");
232fa225cbcSrjs    return ret;
233fa225cbcSrjs  }
234fa225cbcSrjs
235fa225cbcSrjs  /*
236fa225cbcSrjs     X server returns a structure like this:
237fa225cbcSrjs     drm_context_t
238fa225cbcSrjs     fbBase
239fa225cbcSrjs     OverlayOffset
240fa225cbcSrjs     OverlaySize
241fa225cbcSrjs     SurfacesOffset
242fa225cbcSrjs     SurfacesSize
243fa225cbcSrjs     busIdString = 9 char + 1
244fa225cbcSrjs  */
245fa225cbcSrjs  if(priv_count != 9) {
246fa225cbcSrjs    printf("_xvmc_create_context() returned incorrect data size!\n");
247fa225cbcSrjs    printf("\tExpected 9, got %d\n",priv_count);
248fa225cbcSrjs    _xvmc_destroy_context(display, context);
249fa225cbcSrjs    free(pI810XvMC);
250fa225cbcSrjs    return BadAlloc;
251fa225cbcSrjs  }
252fa225cbcSrjs  pI810XvMC->drmcontext = priv_data[0];
253fa225cbcSrjs  pI810XvMC->fb_base = priv_data[1];
254fa225cbcSrjs  pI810XvMC->overlay.offset = priv_data[2] + priv_data[1];
255fa225cbcSrjs  pI810XvMC->overlay.size = priv_data[3];
256fa225cbcSrjs  pI810XvMC->surfaces.offset = priv_data[4] + priv_data[1];
257fa225cbcSrjs  pI810XvMC->surfaces.size = priv_data[5];
258fa225cbcSrjs  strncpy(pI810XvMC->busIdString,(char *)&priv_data[6],9);
259fa225cbcSrjs  pI810XvMC->busIdString[9] = '\0';
260fa225cbcSrjs
261fa225cbcSrjs  /* Must free the private data we were passed from X */
262fa225cbcSrjs  free(priv_data);
263fa225cbcSrjs
264fa225cbcSrjs  /* Initialize private context values */
265fa225cbcSrjs  pI810XvMC->current = 0;
266fa225cbcSrjs  pI810XvMC->lock = 0;
267fa225cbcSrjs  pI810XvMC->last_flip = 0;
268fa225cbcSrjs  pI810XvMC->dual_prime = 0;
269fa225cbcSrjs
270fa225cbcSrjs  /*
271fa225cbcSrjs     Map dma Buffers: Not really, this would be a drmMapBufs
272fa225cbcSrjs     but due to the i810 security model we have to just create an
273fa225cbcSrjs     empty data structure to fake it.
274fa225cbcSrjs  */
275fa225cbcSrjs  pI810XvMC->dmabufs = (drmBufMapPtr)malloc(sizeof(drmBufMap));
276fa225cbcSrjs  if(pI810XvMC->dmabufs == NULL) {
277fa225cbcSrjs    printf("Dma Bufs could not be mapped.\n");
278fa225cbcSrjs    _xvmc_destroy_context(display, context);
279fa225cbcSrjs    free(pI810XvMC);
280fa225cbcSrjs    return BadAlloc;
281fa225cbcSrjs  } /* pI810XvMC->dmabufs == NULL */
282fa225cbcSrjs  memset(pI810XvMC->dmabufs, 0, sizeof(drmBufMap));
283fa225cbcSrjs  pI810XvMC->dmabufs->list = (drmBufPtr)malloc(sizeof(drmBuf) *
284fa225cbcSrjs					       I810_DMA_BUF_NR);
285fa225cbcSrjs  if(pI810XvMC->dmabufs->list == NULL) {
286fa225cbcSrjs    printf("Dma Bufs could not be mapped.\n");
287fa225cbcSrjs    _xvmc_destroy_context(display, context);
288fa225cbcSrjs    free(pI810XvMC);
289fa225cbcSrjs    return BadAlloc;
290fa225cbcSrjs  } /* pI810XvMC->dmabufs->list == NULL */
291fa225cbcSrjs  memset(pI810XvMC->dmabufs->list, 0, sizeof(drmBuf) * I810_DMA_BUF_NR);
292fa225cbcSrjs
293fa225cbcSrjs  /* Map the Overlay memory */
294fa225cbcSrjs  if(drmMap(pI810XvMC->fd,pI810XvMC->overlay.offset,
295fa225cbcSrjs	    pI810XvMC->overlay.size,&(pI810XvMC->overlay.address)) < 0) {
296fa225cbcSrjs    printf("Unable to map Overlay at offset 0x%x and size 0x%x\n",
297fa225cbcSrjs	   (unsigned int)pI810XvMC->overlay.offset,pI810XvMC->overlay.size);
298fa225cbcSrjs    _xvmc_destroy_context(display, context);
299fa225cbcSrjs    free(pI810XvMC->dmabufs->list);
300fa225cbcSrjs    free(pI810XvMC);
301fa225cbcSrjs    return BadAlloc;
302fa225cbcSrjs  } /* drmMap() < 0 */
303fa225cbcSrjs
304fa225cbcSrjs  /* Overlay Regs are offset 1024 into Overlay Map */
305fa225cbcSrjs  pI810XvMC->oregs = (i810OverlayRec *)
306fa225cbcSrjs    ((unsigned char *)pI810XvMC->overlay.address + 1024);
307fa225cbcSrjs
308fa225cbcSrjs  /* Map Surfaces */
309fa225cbcSrjs  if(drmMap(pI810XvMC->fd,pI810XvMC->surfaces.offset,
310fa225cbcSrjs	    pI810XvMC->surfaces.size,&(pI810XvMC->surfaces.address)) < 0) {
311fa225cbcSrjs    printf("Unable to map XvMC Surfaces.\n");
312fa225cbcSrjs    _xvmc_destroy_context(display, context);
313fa225cbcSrjs    free(pI810XvMC->dmabufs->list);
314fa225cbcSrjs    free(pI810XvMC);
315fa225cbcSrjs    return BadAlloc;
316fa225cbcSrjs  } /* drmMap() < 0 */
317fa225cbcSrjs
318fa225cbcSrjs  /*
319fa225cbcSrjs    There is a tiny chance that someone was using the overlay and
320fa225cbcSrjs    issued a flip that hasn't finished. To be 100% sure I'll just
321fa225cbcSrjs    take the lock and sleep for the worst case time for a flip.
322fa225cbcSrjs  */
323fa225cbcSrjs  I810_LOCK(pI810XvMC,DRM_LOCK_QUIESCENT);
324fa225cbcSrjs  usleep(20000);  /* 1/50th Sec for 50hz refresh */
325fa225cbcSrjs
326fa225cbcSrjs  /* Set up Overlay regs with Initial Values */
327fa225cbcSrjs  pI810XvMC->oregs->YRGB_VPH = 0;
328fa225cbcSrjs  pI810XvMC->oregs->UV_VPH = 0;
329fa225cbcSrjs  pI810XvMC->oregs->HORZ_PH = 0;
330fa225cbcSrjs  pI810XvMC->oregs->INIT_PH = 0;
331fa225cbcSrjs  pI810XvMC->oregs->DWINPOS = 0;
332fa225cbcSrjs  pI810XvMC->oregs->DWINSZ = (I810_XVMC_MAXHEIGHT << 16) |
333fa225cbcSrjs    I810_XVMC_MAXWIDTH;
334fa225cbcSrjs  pI810XvMC->oregs->SWID =  I810_XVMC_MAXWIDTH | (I810_XVMC_MAXWIDTH << 15);
335fa225cbcSrjs  pI810XvMC->oregs->SWIDQW = (I810_XVMC_MAXWIDTH >> 3) |
336fa225cbcSrjs    (I810_XVMC_MAXWIDTH << 12);
337fa225cbcSrjs  pI810XvMC->oregs->SHEIGHT = I810_XVMC_MAXHEIGHT |
338fa225cbcSrjs    (I810_XVMC_MAXHEIGHT << 15);
339fa225cbcSrjs  pI810XvMC->oregs->YRGBSCALE = 0x80004000; /* scale factor 1 */
340fa225cbcSrjs  pI810XvMC->oregs->UVSCALE = 0x80004000;   /* scale factor 1 */
341fa225cbcSrjs  pI810XvMC->oregs->OV0CLRC0 = 0x4000;      /* brightness: 0 contrast: 1.0 */
342fa225cbcSrjs  pI810XvMC->oregs->OV0CLRC1 = 0x80;        /* saturation: bypass */
343fa225cbcSrjs
344fa225cbcSrjs  /* Destination Colorkey Setup */
345fa225cbcSrjs  pI810XvMC->oregs->DCLRKV = RGB16ToColorKey(pI810XvMC->colorkey);
346fa225cbcSrjs  pI810XvMC->oregs->DCLRKM = 0x80070307;
347fa225cbcSrjs
348fa225cbcSrjs
349fa225cbcSrjs  pI810XvMC->oregs->SCLRKVH = 0;
350fa225cbcSrjs  pI810XvMC->oregs->SCLRKVL = 0;
351fa225cbcSrjs  pI810XvMC->oregs->SCLRKM = 0; /* source color key disable */
352fa225cbcSrjs  pI810XvMC->oregs->OV0CONF = 0; /* two 720 pixel line buffers */
353fa225cbcSrjs
354fa225cbcSrjs  pI810XvMC->oregs->OV0CMD = VC_UP_INTERPOLATION | HC_UP_INTERPOLATION |
355fa225cbcSrjs    Y_ADJUST | YUV_420;
356fa225cbcSrjs
357fa225cbcSrjs  pI810XvMC->ref = 1;
358fa225cbcSrjs
359fa225cbcSrjs  I810_UNLOCK(pI810XvMC);
360fa225cbcSrjs
361fa225cbcSrjs  return Success;
362fa225cbcSrjs
363fa225cbcSrjs}
364fa225cbcSrjs
365fa225cbcSrjs/***************************************************************************
366fa225cbcSrjs// Function: XvMCDestroyContext
367fa225cbcSrjs// Description: Destorys the specified context.
368fa225cbcSrjs//
369fa225cbcSrjs// Arguments:
370fa225cbcSrjs//   display - Specifies the connection to the server.
371fa225cbcSrjs//   context - The context to be destroyed.
372fa225cbcSrjs//
373fa225cbcSrjs// Returns: Status
374fa225cbcSrjs***************************************************************************/
375fa225cbcSrjs_X_EXPORT Status XvMCDestroyContext(Display *display, XvMCContext *context) {
376fa225cbcSrjs  i810XvMCContext *pI810XvMC;
377fa225cbcSrjs
378fa225cbcSrjs  if(context == NULL) {
379fa225cbcSrjs    return (error_base + XvMCBadContext);
380fa225cbcSrjs  }
381fa225cbcSrjs  if(context->privData == NULL) {
382fa225cbcSrjs    return (error_base + XvMCBadContext);
383fa225cbcSrjs  }
384fa225cbcSrjs  pI810XvMC = (i810XvMCContext *)context->privData;
385fa225cbcSrjs
386fa225cbcSrjs  /* Turn off the overlay */
387fa225cbcSrjs  if(pI810XvMC->last_flip) {
388fa225cbcSrjs    I810_LOCK(pI810XvMC,DRM_LOCK_QUIESCENT);
389fa225cbcSrjs
390fa225cbcSrjs    /* Make sure last flip is done */
391fa225cbcSrjs    BLOCK_OVERLAY(pI810XvMC,pI810XvMC->current);
392fa225cbcSrjs
393fa225cbcSrjs    pI810XvMC->oregs->OV0CMD = VC_UP_INTERPOLATION | HC_UP_INTERPOLATION |
394fa225cbcSrjs      Y_ADJUST;
395fa225cbcSrjs    pI810XvMC->current = !pI810XvMC->current;
396fa225cbcSrjs    if(pI810XvMC->current == 1) {
397fa225cbcSrjs      pI810XvMC->oregs->OV0CMD |= BUFFER1_FIELD0;
398fa225cbcSrjs    }
399fa225cbcSrjs    else {
400fa225cbcSrjs      pI810XvMC->oregs->OV0CMD |= BUFFER0_FIELD0;
401fa225cbcSrjs    }
402fa225cbcSrjs    OVERLAY_FLIP(pI810XvMC);
403fa225cbcSrjs    pI810XvMC->last_flip++;
404fa225cbcSrjs
405fa225cbcSrjs    /* Wait for the flip */
406fa225cbcSrjs    BLOCK_OVERLAY(pI810XvMC,pI810XvMC->current);
407fa225cbcSrjs
408fa225cbcSrjs    I810_UNLOCK(pI810XvMC);
409fa225cbcSrjs  }
410fa225cbcSrjs
411fa225cbcSrjs  /* Pass Control to the X server to destroy the drm_context_t */
412fa225cbcSrjs  _xvmc_destroy_context(display, context);
413fa225cbcSrjs
414fa225cbcSrjs  i810_free_privContext(pI810XvMC);
415fa225cbcSrjs  context->privData = NULL;
416fa225cbcSrjs
417fa225cbcSrjs  return Success;
418fa225cbcSrjs}
419fa225cbcSrjs
420fa225cbcSrjs
421fa225cbcSrjs/***************************************************************************
422fa225cbcSrjs// Function: XvMCCreateSurface
423fa225cbcSrjs***************************************************************************/
424fa225cbcSrjs_X_EXPORT Status XvMCCreateSurface( Display *display, XvMCContext *context,
425fa225cbcSrjs			  XvMCSurface *surface) {
426fa225cbcSrjs  i810XvMCContext *pI810XvMC;
427fa225cbcSrjs  i810XvMCSurface *pI810Surface;
428fa225cbcSrjs  int priv_count;
429fa225cbcSrjs  uint *priv_data;
430fa225cbcSrjs  Status ret;
431fa225cbcSrjs
432fa225cbcSrjs  if((surface == NULL) || (context == NULL) || (display == NULL)){
433fa225cbcSrjs    return BadValue;
434fa225cbcSrjs  }
435fa225cbcSrjs
436fa225cbcSrjs  pI810XvMC = (i810XvMCContext *)context->privData;
437fa225cbcSrjs  if(pI810XvMC == NULL) {
438fa225cbcSrjs    return (error_base + XvMCBadContext);
439fa225cbcSrjs  }
440fa225cbcSrjs
441fa225cbcSrjs
442fa225cbcSrjs  surface->privData = (i810XvMCSurface *)malloc(sizeof(i810XvMCSurface));
443fa225cbcSrjs  if(!surface->privData) {
444fa225cbcSrjs    return BadAlloc;
445fa225cbcSrjs  }
446fa225cbcSrjs  pI810Surface = (i810XvMCSurface *)surface->privData;
447fa225cbcSrjs
448fa225cbcSrjs  /* Initialize private values */
449fa225cbcSrjs  pI810Surface->privContext = pI810XvMC;
450fa225cbcSrjs  pI810Surface->last_render = 0;
451fa225cbcSrjs  pI810Surface->last_flip = 0;
452fa225cbcSrjs  pI810Surface->second_field = 0;
453fa225cbcSrjs
454fa225cbcSrjs  if((ret = _xvmc_create_surface(display, context, surface,
455fa225cbcSrjs				&priv_count, &priv_data))) {
456fa225cbcSrjs    free(pI810Surface);
457fa225cbcSrjs    printf("Unable to create XvMCSurface.\n");
458fa225cbcSrjs    return ret;
459fa225cbcSrjs  }
460fa225cbcSrjs
461fa225cbcSrjs  /*
462fa225cbcSrjs    _xvmc_create_subpicture returns 2 uints with the offset into
463fa225cbcSrjs    the DRM map for the Y surface and UV surface.
464fa225cbcSrjs  */
465fa225cbcSrjs  if(priv_count != 2) {
466fa225cbcSrjs    printf("_xvmc_create_surface() return incorrect data size.\n");
467fa225cbcSrjs    printf("Expected 2 got %d\n",priv_count);
468fa225cbcSrjs    free(priv_data);
469fa225cbcSrjs    free(pI810Surface);
470fa225cbcSrjs    return BadAlloc;
471fa225cbcSrjs  }
472fa225cbcSrjs  /* Data == Client Address, offset == Physical address offset */
473fa225cbcSrjs  pI810Surface->data = pI810XvMC->surfaces.address;
474fa225cbcSrjs  pI810Surface->offset = pI810XvMC->surfaces.offset;
475fa225cbcSrjs
476fa225cbcSrjs
477fa225cbcSrjs  /*
478fa225cbcSrjs     i810's MC Engine needs surfaces of 2^x (x= 9,10,11,12) pitch
479fa225cbcSrjs     and the Tiler need 512k aligned surfaces, basically we are
480fa225cbcSrjs     stuck with fixed memory with pitch 1024 for Y data. UV = 512.
481fa225cbcSrjs  */
482fa225cbcSrjs  pI810Surface->pitch = 10;
483fa225cbcSrjs  if((surface->surface_type_id == FOURCC_UYVY) ||
484fa225cbcSrjs     (surface->surface_type_id == FOURCC_YUY2)) {
485fa225cbcSrjs    /* This is not implemented server side. */
486fa225cbcSrjs    pI810Surface->pitch++;
487fa225cbcSrjs  }
488fa225cbcSrjs
489fa225cbcSrjs  /*
490fa225cbcSrjs    offsets[0,1,2] == Offsets from either data or offset for the Y
491fa225cbcSrjs    U and V surfaces.
492fa225cbcSrjs  */
493fa225cbcSrjs  pI810Surface->offsets[0] = priv_data[0];
494fa225cbcSrjs  if(((unsigned long)pI810Surface->data + pI810Surface->offsets[0]) & 4095) {
495fa225cbcSrjs    printf("XvMCCreateSurface: Surface offset 0 is not 4096 aligned\n");
496fa225cbcSrjs  }
497fa225cbcSrjs
498fa225cbcSrjs  if((surface->surface_type_id == FOURCC_UYVY) ||
499fa225cbcSrjs     (surface->surface_type_id == FOURCC_YUY2)) {
500fa225cbcSrjs    /* Packed surface, not fully implemented */
501fa225cbcSrjs    pI810Surface->offsets[1] = 0;
502fa225cbcSrjs    pI810Surface->offsets[2] = 0;
503fa225cbcSrjs  }
504fa225cbcSrjs  else {
505fa225cbcSrjs    /* Planar surface */
506fa225cbcSrjs    pI810Surface->offsets[1] = priv_data[1];
507fa225cbcSrjs    if(((unsigned long)pI810Surface->data + pI810Surface->offsets[1]) & 2047) {
508fa225cbcSrjs      printf("XvMCCreateSurface: Surface offset 1 is not 2048 aligned\n");
509fa225cbcSrjs    }
510fa225cbcSrjs
511fa225cbcSrjs    pI810Surface->offsets[2] = ((unsigned long)pI810Surface->offsets[1] +
512fa225cbcSrjs				(1<<(pI810Surface->pitch - 1)) * 288);
513fa225cbcSrjs    if(((unsigned long)pI810Surface->data + pI810Surface->offsets[2]) & 2047) {
514fa225cbcSrjs      printf("XvMCCreateSurface: Surface offset 2 is not 2048 aligned\n");
515fa225cbcSrjs    }
516fa225cbcSrjs
517fa225cbcSrjs  }
518fa225cbcSrjs
519fa225cbcSrjs  /* Free data returned from xvmc_create_surface */
520fa225cbcSrjs  free(priv_data);
521fa225cbcSrjs
522fa225cbcSrjs  /* Clear the surface to 0 */
523fa225cbcSrjs  memset((void *)((unsigned long)pI810Surface->data + (unsigned long)pI810Surface->offsets[0]),
524fa225cbcSrjs	 0, ((1<<pI810Surface->pitch) * surface->height));
525fa225cbcSrjs
526fa225cbcSrjs  switch(surface->surface_type_id) {
527fa225cbcSrjs  case FOURCC_YV12:
528fa225cbcSrjs  case FOURCC_I420:
529fa225cbcSrjs    /* Destination buffer info command */
530fa225cbcSrjs    pI810Surface->dbi1y = ((((unsigned int)pI810Surface->offset +
531fa225cbcSrjs			     pI810Surface->offsets[0]) & ~0xfc000fff) |
532fa225cbcSrjs			   (pI810Surface->pitch - 9));
533fa225cbcSrjs    pI810Surface->dbi1u = ((((unsigned int)pI810Surface->offset +
534fa225cbcSrjs			     pI810Surface->offsets[1]) & ~0xfc000fff) |
535fa225cbcSrjs			   (pI810Surface->pitch - 10));
536fa225cbcSrjs    pI810Surface->dbi1v = ((((unsigned int)pI810Surface->offset +
537fa225cbcSrjs			     pI810Surface->offsets[2]) & ~0xfc000fff) |
538fa225cbcSrjs			   (pI810Surface->pitch - 10));
539fa225cbcSrjs
540fa225cbcSrjs    /* Destination buffer variables command */
541fa225cbcSrjs    pI810Surface->dbv1 = (0x8<<20) | (0x8<<16);
542fa225cbcSrjs    /* Map info command */
543fa225cbcSrjs    pI810Surface->mi1y = (0x1<<24) | (1<<9) | (pI810Surface->pitch - 3);
544fa225cbcSrjs    pI810Surface->mi1u = (0x1<<24) | (1<<9) | (pI810Surface->pitch - 4);
545fa225cbcSrjs    pI810Surface->mi1v = (0x1<<24) | (1<<9) | (pI810Surface->pitch - 4);
546fa225cbcSrjs
547fa225cbcSrjs    pI810Surface->mi2y = (((unsigned int)surface->height - 1)<<16) |
548fa225cbcSrjs      ((unsigned int)surface->width - 1);
549fa225cbcSrjs    pI810Surface->mi2u = (((unsigned int)surface->height - 1)<<15) |
550fa225cbcSrjs      (((unsigned int)surface->width - 1)>>1);
551fa225cbcSrjs    pI810Surface->mi2v = pI810Surface->mi2u;
552fa225cbcSrjs
553fa225cbcSrjs    pI810Surface->mi3y = ((unsigned int)pI810Surface->offset +
554fa225cbcSrjs			  pI810Surface->offsets[0]) & ~0x0000000f;
555fa225cbcSrjs    pI810Surface->mi3u = ((unsigned int)pI810Surface->offset +
556fa225cbcSrjs			  pI810Surface->offsets[1]) & ~0x0000000f;
557fa225cbcSrjs    pI810Surface->mi3v = ((unsigned int)pI810Surface->offset +
558fa225cbcSrjs			  pI810Surface->offsets[2]) & ~0x0000000f;
559fa225cbcSrjs    break;
560fa225cbcSrjs  case FOURCC_UYVY:
561fa225cbcSrjs  case FOURCC_YUY2:
562fa225cbcSrjs  default:
563fa225cbcSrjs    /* Destination buffer info command */
564fa225cbcSrjs    pI810Surface->dbi1y = ((((unsigned int)pI810Surface->offset +
565fa225cbcSrjs			     pI810Surface->offsets[0]) & ~0xfc000fff) |
566fa225cbcSrjs			   (pI810Surface->pitch - 9));
567fa225cbcSrjs    /* Destination buffer variables command */
568fa225cbcSrjs    if(surface->surface_type_id == FOURCC_YUY2) {
569fa225cbcSrjs      pI810Surface->dbv1 = 0x5<<8;
570fa225cbcSrjs      pI810Surface->mi1y = 0x5<<24 | pI810Surface->pitch | 0x1<<21;
571fa225cbcSrjs    }
572fa225cbcSrjs    else {
573fa225cbcSrjs      pI810Surface->dbv1 = 0x4<<8;
574fa225cbcSrjs      pI810Surface->mi1y = 0x5<<24 | (pI810Surface->pitch - 3);
575fa225cbcSrjs    }
576fa225cbcSrjs    pI810Surface->mi2y = (((unsigned int)surface->width - 1)<<16) |
577fa225cbcSrjs      ((unsigned int)surface->height - 1);
578fa225cbcSrjs    pI810Surface->mi3y = ((unsigned int)pI810Surface->offset +
579fa225cbcSrjs			  pI810Surface->offsets[0]) & ~0xfc000fff;
580fa225cbcSrjs    break;
581fa225cbcSrjs  }
582fa225cbcSrjs  pI810XvMC->ref++;
583fa225cbcSrjs
584fa225cbcSrjs  return Success;
585fa225cbcSrjs}
586fa225cbcSrjs
587fa225cbcSrjs
588fa225cbcSrjs/***************************************************************************
589fa225cbcSrjs// Function: XvMCDestroySurface
590fa225cbcSrjs***************************************************************************/
591fa225cbcSrjs_X_EXPORT Status XvMCDestroySurface(Display *display, XvMCSurface *surface) {
592fa225cbcSrjs  i810XvMCSurface *pI810Surface;
593fa225cbcSrjs  i810XvMCContext *pI810XvMC;
594fa225cbcSrjs
595fa225cbcSrjs  if((display == NULL) || (surface == NULL)) {
596fa225cbcSrjs    return BadValue;
597fa225cbcSrjs  }
598fa225cbcSrjs  if(surface->privData == NULL) {
599fa225cbcSrjs    return (error_base + XvMCBadSurface);
600fa225cbcSrjs  }
601fa225cbcSrjs
602fa225cbcSrjs  pI810Surface = (i810XvMCSurface *)surface->privData;
603fa225cbcSrjs  if(pI810Surface->last_flip) {
604fa225cbcSrjs    XvMCSyncSurface(display,surface);
605fa225cbcSrjs  }
606fa225cbcSrjs  pI810XvMC = (i810XvMCContext *)pI810Surface->privContext;
607fa225cbcSrjs
608fa225cbcSrjs  _xvmc_destroy_surface(display,surface);
609fa225cbcSrjs
610fa225cbcSrjs  i810_free_privContext(pI810XvMC);
611fa225cbcSrjs
612fa225cbcSrjs  free(pI810Surface);
613fa225cbcSrjs  surface->privData = NULL;
614fa225cbcSrjs  return Success;
615fa225cbcSrjs}
616fa225cbcSrjs
617fa225cbcSrjs/***************************************************************************
618fa225cbcSrjs// Function: XvMCCreateBlocks
619fa225cbcSrjs***************************************************************************/
620fa225cbcSrjs_X_EXPORT Status XvMCCreateBlocks(Display *display, XvMCContext *context,
621fa225cbcSrjs			unsigned int num_blocks,
622fa225cbcSrjs			XvMCBlockArray *block) {
623fa225cbcSrjs
624fa225cbcSrjs  if((display == NULL) || (context == NULL) || (num_blocks == 0)) {
625fa225cbcSrjs    return BadValue;
626fa225cbcSrjs  }
627fa225cbcSrjs
628fa225cbcSrjs  block->blocks = (short *)malloc(num_blocks<<6 * sizeof(short));
629fa225cbcSrjs  if(block->blocks == NULL) {
630fa225cbcSrjs    return BadAlloc;
631fa225cbcSrjs  }
632fa225cbcSrjs
633fa225cbcSrjs  block->num_blocks = num_blocks;
634fa225cbcSrjs  block->context_id = context->context_id;
635fa225cbcSrjs
636fa225cbcSrjs  block->privData = NULL;
637fa225cbcSrjs
638fa225cbcSrjs  return Success;
639fa225cbcSrjs}
640fa225cbcSrjs
641fa225cbcSrjs/***************************************************************************
642fa225cbcSrjs// Function: XvMCDestroyBlocks
643fa225cbcSrjs***************************************************************************/
644fa225cbcSrjs_X_EXPORT Status XvMCDestroyBlocks(Display *display, XvMCBlockArray *block) {
645fa225cbcSrjs  if(display == NULL) {
646fa225cbcSrjs    return BadValue;
647fa225cbcSrjs  }
648fa225cbcSrjs
649fa225cbcSrjs  free(block->blocks);
650fa225cbcSrjs  block->num_blocks = 0;
651fa225cbcSrjs  block->context_id = 0;
652fa225cbcSrjs  block->privData = NULL;
653fa225cbcSrjs  return Success;
654fa225cbcSrjs}
655fa225cbcSrjs
656fa225cbcSrjs/***************************************************************************
657fa225cbcSrjs// Function: XvMCCreateMacroBlocks
658fa225cbcSrjs***************************************************************************/
659fa225cbcSrjs_X_EXPORT Status XvMCCreateMacroBlocks(Display *display, XvMCContext *context,
660fa225cbcSrjs			     unsigned int num_blocks,
661fa225cbcSrjs			     XvMCMacroBlockArray *blocks) {
662fa225cbcSrjs
663fa225cbcSrjs  if((display == NULL) || (context == NULL) || (blocks == NULL) ||
664fa225cbcSrjs      (num_blocks == 0)) {
665fa225cbcSrjs    return BadValue;
666fa225cbcSrjs  }
667fa225cbcSrjs  memset(blocks,0,sizeof(XvMCMacroBlockArray));
668fa225cbcSrjs  blocks->context_id = context->context_id;
669fa225cbcSrjs  blocks->privData = NULL;
670fa225cbcSrjs
671fa225cbcSrjs  blocks->macro_blocks = (XvMCMacroBlock *)
672fa225cbcSrjs    malloc(num_blocks * sizeof(XvMCMacroBlock));
673fa225cbcSrjs  if(blocks->macro_blocks == NULL) {
674fa225cbcSrjs    return BadAlloc;
675fa225cbcSrjs  }
676fa225cbcSrjs  blocks->num_blocks = num_blocks;
677fa225cbcSrjs
678fa225cbcSrjs  return Success;
679fa225cbcSrjs}
680fa225cbcSrjs
681fa225cbcSrjs/***************************************************************************
682fa225cbcSrjs// Function: XvMCDestroyMacroBlocks
683fa225cbcSrjs***************************************************************************/
684fa225cbcSrjs_X_EXPORT Status XvMCDestroyMacroBlocks(Display *display, XvMCMacroBlockArray *block) {
685fa225cbcSrjs  if((display == NULL) || (block == NULL)) {
686fa225cbcSrjs    return BadValue;
687fa225cbcSrjs  }
688fa225cbcSrjs  if(block->macro_blocks) {
689fa225cbcSrjs    free(block->macro_blocks);
690fa225cbcSrjs  }
691fa225cbcSrjs  block->context_id = 0;
692fa225cbcSrjs  block->num_blocks = 0;
693fa225cbcSrjs  block->privData = NULL;
694fa225cbcSrjs
695fa225cbcSrjs  return Success;
696fa225cbcSrjs}
697fa225cbcSrjs
698fa225cbcSrjs
699fa225cbcSrjs/***************************************************************************
700fa225cbcSrjs// Function: dp (Debug Print)
701fa225cbcSrjs// Description: This function prints out in hex i * uint32_t at the address
702fa225cbcSrjs//  supplied. This enables you to print out the dma buffers from
703fa225cbcSrjs//  within the debugger even though they are not in your address space.
704fa225cbcSrjs***************************************************************************/
705fa225cbcSrjsvoid dp(unsigned int *address, unsigned int i) {
706fa225cbcSrjs  int j;
707fa225cbcSrjs
708fa225cbcSrjs  printf("DebugPrint:\n");
709fa225cbcSrjs  for(j=0; j<i; j++) {
710fa225cbcSrjs    printf("0x%8.8x ",address[j]);
711fa225cbcSrjs    if(j && !(j & 7)) { printf("\n");}
712fa225cbcSrjs  }
713fa225cbcSrjs}
714fa225cbcSrjs
715fa225cbcSrjs/***************************************************************************
716fa225cbcSrjs// Macro: PACK_*
717fa225cbcSrjs// Description: Packs 16bit signed data from blocks into either 8bit unsigned
718fa225cbcSrjs//  intra data or 16bit signed correction data, both packed into
719fa225cbcSrjs//  32 bit integers.
720fa225cbcSrjs***************************************************************************/
721fa225cbcSrjs#define PACK_INTRA_DATA(d,b,n)                  \
722fa225cbcSrjs  do {                                          \
723fa225cbcSrjs   char *dp = (char *)d;                        \
724fa225cbcSrjs   char *bp = (char *)b;                        \
725fa225cbcSrjs   int counter;                                 \
726fa225cbcSrjs   for(counter = 0; counter < n; counter++) {   \
727fa225cbcSrjs     *dp++ = *bp;                               \
728fa225cbcSrjs     bp += 2;                                   \
729fa225cbcSrjs   }                                            \
730fa225cbcSrjs  }while(0);
731fa225cbcSrjs
732fa225cbcSrjs#define PACK_CORR_DATA(d,b,n)          \
733fa225cbcSrjs            memcpy(d,b,n);             \
734fa225cbcSrjs            d = (uint *)((unsigned long)d + n);
735fa225cbcSrjs
736fa225cbcSrjs#define MARK_CORR_DATA(d,n)                          \
737fa225cbcSrjs            do {                                     \
738fa225cbcSrjs              uint* q = (uint*)((unsigned long)d - n);        \
739fa225cbcSrjs              while((unsigned long)q < (unsigned long)d) {             \
740fa225cbcSrjs               *q++ += 0x00330033;                   \
741fa225cbcSrjs              }                                      \
742fa225cbcSrjs	    }while(0);
743fa225cbcSrjs
744fa225cbcSrjs#define MARK_INTRA_BLOCK(d)         \
745fa225cbcSrjs           do {                     \
746fa225cbcSrjs             int q;                 \
747fa225cbcSrjs             for(q=0; q<16; q++) {  \
748fa225cbcSrjs               d[q] += 0x33333333;  \
749fa225cbcSrjs             }                      \
750fa225cbcSrjs	    }while(0);
751fa225cbcSrjs
752fa225cbcSrjs/*
753fa225cbcSrjs  Used for DCT 1 when we need DCT 0. Instead
754fa225cbcSrjs  of reading from one block we read from two and
755fa225cbcSrjs  interlace.
756fa225cbcSrjs*/
757fa225cbcSrjs#define PACK_CORR_DATA_1to0(d,top,bottom)            \
758fa225cbcSrjs            do {                                     \
759fa225cbcSrjs              short *t = top,*b = bottom;            \
760fa225cbcSrjs              PACK_CORR_DATA(d,t,16);                \
761fa225cbcSrjs              t = (short *)((unsigned long)t + 16);           \
762fa225cbcSrjs              PACK_CORR_DATA(d,b,16);                \
763fa225cbcSrjs              b = (short *)((unsigned long)b + 16);           \
764fa225cbcSrjs              PACK_CORR_DATA(d,t,16);                \
765fa225cbcSrjs              t = (short *)((unsigned long)t + 16);           \
766fa225cbcSrjs              PACK_CORR_DATA(d,b,16);                \
767fa225cbcSrjs              b = (short *)((unsigned long)b + 16);           \
768fa225cbcSrjs              PACK_CORR_DATA(d,t,16);                \
769fa225cbcSrjs              t = (short *)((unsigned long)t + 16);           \
770fa225cbcSrjs              PACK_CORR_DATA(d,b,16);                \
771fa225cbcSrjs              b = (short *)((unsigned long)b + 16);           \
772fa225cbcSrjs              PACK_CORR_DATA(d,t,16);                \
773fa225cbcSrjs              t = (short *)((unsigned long)t + 16);           \
774fa225cbcSrjs              PACK_CORR_DATA(d,b,16);                \
775fa225cbcSrjs              b = (short *)((unsigned long)b + 16);           \
776fa225cbcSrjs            }while(0);
777fa225cbcSrjs
778fa225cbcSrjs/* Used for DCT 0 when we need DCT 1. */
779fa225cbcSrjs#define PACK_CORR_DATA_0to1(d,top,bottom)            \
780fa225cbcSrjs            do{                                      \
781fa225cbcSrjs              short *t = top,*b = bottom;            \
782fa225cbcSrjs              PACK_CORR_DATA(d,t,16);                \
783fa225cbcSrjs              t = (short *)((unsigned long)t + 32);           \
784fa225cbcSrjs              PACK_CORR_DATA(d,t,16);                \
785fa225cbcSrjs              t = (short *)((unsigned long)t + 32);           \
786fa225cbcSrjs              PACK_CORR_DATA(d,t,16);                \
787fa225cbcSrjs              t = (short *)((unsigned long)t + 32);           \
788fa225cbcSrjs              PACK_CORR_DATA(d,t,16);                \
789fa225cbcSrjs              t = (short *)((unsigned long)t + 32);           \
790fa225cbcSrjs              PACK_CORR_DATA(d,b,16);                \
791fa225cbcSrjs              b = (short *)((unsigned long)b + 32);           \
792fa225cbcSrjs              PACK_CORR_DATA(d,b,16);                \
793fa225cbcSrjs              b = (short *)((unsigned long)b + 32);           \
794fa225cbcSrjs              PACK_CORR_DATA(d,b,16);                \
795fa225cbcSrjs              b = (short *)((unsigned long)b + 32);           \
796fa225cbcSrjs              PACK_CORR_DATA(d,b,16);                \
797fa225cbcSrjs              b = (short *)((unsigned long)b + 32);           \
798fa225cbcSrjs            }while(0);
799fa225cbcSrjs
800fa225cbcSrjs#define PACK_CORR_DATA_SHORT(d,block)                \
801fa225cbcSrjs            do {                                     \
802fa225cbcSrjs              short *b = block;                      \
803fa225cbcSrjs              PACK_CORR_DATA(d,b,16);                \
804fa225cbcSrjs              b = (short *)((unsigned long)b + 32);           \
805fa225cbcSrjs              PACK_CORR_DATA(d,b,16);                \
806fa225cbcSrjs              b = (short *)((unsigned long)b + 32);           \
807fa225cbcSrjs              PACK_CORR_DATA(d,b,16);                \
808fa225cbcSrjs              b = (short *)((unsigned long)b + 32);           \
809fa225cbcSrjs              PACK_CORR_DATA(d,b,16);                \
810fa225cbcSrjs              b = (short *)((unsigned long)b + 32);           \
811fa225cbcSrjs            }while(0);
812fa225cbcSrjs
813fa225cbcSrjs/* Lookup tables to speed common calculations */
814fa225cbcSrjsstatic unsigned int drps_table[] = {2<<6,3<<6};
815fa225cbcSrjs
816fa225cbcSrjsstatic unsigned int mvfs_table[] = {
817fa225cbcSrjs  0x12,
818fa225cbcSrjs  0x1a,
819fa225cbcSrjs  0x13,
820fa225cbcSrjs  0x1b
821fa225cbcSrjs};
822fa225cbcSrjs
823fa225cbcSrjsstatic unsigned int type_table[] = {
824fa225cbcSrjs  0x1<<12,   /* This is an error so make it Forward motion */
825fa225cbcSrjs  0x1<<12,
826fa225cbcSrjs  0x1<<12,
827fa225cbcSrjs  0x1<<12,
828fa225cbcSrjs  0x2<<12,
829fa225cbcSrjs  0x2<<12,
830fa225cbcSrjs  0x3<<12,
831fa225cbcSrjs  0x3<<12,
832fa225cbcSrjs  0x1<<12,  /* Pattern but no Motion, Make motion Forward */
833fa225cbcSrjs  0x1<<12,
834fa225cbcSrjs  0x1<<12,
835fa225cbcSrjs  0x1<<12,
836fa225cbcSrjs  0x2<<12,
837fa225cbcSrjs  0x2<<12,
838fa225cbcSrjs  0x3<<12,
839fa225cbcSrjs  0x3<<12
840fa225cbcSrjs};
841fa225cbcSrjs
842fa225cbcSrjsstatic unsigned int y_frame_bytes[] = {
843fa225cbcSrjs  0,0,0,0,128,128,128,128,
844fa225cbcSrjs  128,128,128,128,256,256,256,256,
845fa225cbcSrjs  128,128,128,128,256,256,256,256,
846fa225cbcSrjs  256,256,256,256,384,384,384,384,
847fa225cbcSrjs  128,128,128,128,256,256,256,256,
848fa225cbcSrjs  256,256,256,256,384,384,384,384,
849fa225cbcSrjs  256,256,256,256,384,384,384,384,
850fa225cbcSrjs  384,384,384,384,512,512,512,512
851fa225cbcSrjs};
852fa225cbcSrjs
853fa225cbcSrjsstatic unsigned int u_frame_bytes[] = {
854fa225cbcSrjs  0,0,128,128,0,0,128,128,
855fa225cbcSrjs  0,0,128,128,0,0,128,128,
856fa225cbcSrjs  0,0,128,128,0,0,128,128,
857fa225cbcSrjs  0,0,128,128,0,0,128,128,
858fa225cbcSrjs  0,0,128,128,0,0,128,128,
859fa225cbcSrjs  0,0,128,128,0,0,128,128,
860fa225cbcSrjs  0,0,128,128,0,0,128,128,
861fa225cbcSrjs  0,0,128,128,0,0,128,128
862fa225cbcSrjs};
863fa225cbcSrjs
864fa225cbcSrjsstatic unsigned int v_frame_bytes[] = {
865fa225cbcSrjs  0,128,0,128,0,128,0,128,
866fa225cbcSrjs  0,128,0,128,0,128,0,128,
867fa225cbcSrjs  0,128,0,128,0,128,0,128,
868fa225cbcSrjs  0,128,0,128,0,128,0,128,
869fa225cbcSrjs  0,128,0,128,0,128,0,128,
870fa225cbcSrjs  0,128,0,128,0,128,0,128,
871fa225cbcSrjs  0,128,0,128,0,128,0,128,
872fa225cbcSrjs  0,128,0,128,0,128,0,128
873fa225cbcSrjs};
874fa225cbcSrjs
875fa225cbcSrjsstatic unsigned int y_first_field_bytes[] = {
876fa225cbcSrjs  0,0,0,0,0,0,0,0,
877fa225cbcSrjs  0,0,0,0,0,0,0,0,
878fa225cbcSrjs  128,128,128,128,128,128,128,128,
879fa225cbcSrjs  128,128,128,128,128,128,128,128,
880fa225cbcSrjs  128,128,128,128,128,128,128,128,
881fa225cbcSrjs  128,128,128,128,128,128,128,128,
882fa225cbcSrjs  256,256,256,256,256,256,256,256,
883fa225cbcSrjs  256,256,256,256,256,256,256,256
884fa225cbcSrjs};
885fa225cbcSrjs
886fa225cbcSrjsstatic unsigned int y_second_field_bytes[] = {
887fa225cbcSrjs  0,0,0,0,128,128,128,128,
888fa225cbcSrjs  128,128,128,128,256,256,256,256,
889fa225cbcSrjs  0,0,0,0,128,128,128,128,
890fa225cbcSrjs  128,128,128,128,256,256,256,256,
891fa225cbcSrjs  0,0,0,0,128,128,128,128,
892fa225cbcSrjs  128,128,128,128,256,256,256,256,
893fa225cbcSrjs  0,0,0,0,128,128,128,128,
894fa225cbcSrjs  128,128,128,128,256,256,256,256
895fa225cbcSrjs};
896fa225cbcSrjs
897fa225cbcSrjsstatic unsigned int y_dct0_field_bytes[] = {
898fa225cbcSrjs  0,0,0,0,128,128,128,128,
899fa225cbcSrjs  128,128,128,128,256,256,256,256,
900fa225cbcSrjs  128,128,128,128,128,128,128,128,
901fa225cbcSrjs  256,256,256,256,256,256,256,256,
902fa225cbcSrjs  128,128,128,128,256,256,256,256,
903fa225cbcSrjs  128,128,128,128,256,256,256,256,
904fa225cbcSrjs  256,256,256,256,256,256,256,256,
905fa225cbcSrjs  256,256,256,256,256,256,256,256
906fa225cbcSrjs};
907fa225cbcSrjs
908fa225cbcSrjsstatic unsigned int y_dct1_frame_bytes[] = {
909fa225cbcSrjs  0,0,0,0,256,256,256,256,
910fa225cbcSrjs  256,256,256,256,512,512,512,512,
911fa225cbcSrjs  256,256,256,256,256,256,256,256,
912fa225cbcSrjs  512,512,512,512,512,512,512,512,
913fa225cbcSrjs  256,256,256,256,512,512,512,512,
914fa225cbcSrjs  256,256,256,256,512,512,512,512,
915fa225cbcSrjs  512,512,512,512,512,512,512,512,
916fa225cbcSrjs  512,512,512,512,512,512,512,512
917fa225cbcSrjs};
918fa225cbcSrjs
919fa225cbcSrjsstatic unsigned int u_field_bytes[] = {
920fa225cbcSrjs  0,0,64,64,0,0,64,64,
921fa225cbcSrjs  0,0,64,64,0,0,64,64,
922fa225cbcSrjs  0,0,64,64,0,0,64,64,
923fa225cbcSrjs  0,0,64,64,0,0,64,64,
924fa225cbcSrjs  0,0,64,64,0,0,64,64,
925fa225cbcSrjs  0,0,64,64,0,0,64,64,
926fa225cbcSrjs  0,0,64,64,0,0,64,64,
927fa225cbcSrjs  0,0,64,64,0,0,64,64
928fa225cbcSrjs};
929fa225cbcSrjs
930fa225cbcSrjsstatic unsigned int v_field_bytes[] = {
931fa225cbcSrjs  0,64,0,64,0,64,0,64,
932fa225cbcSrjs  0,64,0,64,0,64,0,64,
933fa225cbcSrjs  0,64,0,64,0,64,0,64,
934fa225cbcSrjs  0,64,0,64,0,64,0,64,
935fa225cbcSrjs  0,64,0,64,0,64,0,64,
936fa225cbcSrjs  0,64,0,64,0,64,0,64,
937fa225cbcSrjs  0,64,0,64,0,64,0,64,
938fa225cbcSrjs  0,64,0,64,0,64,0,64
939fa225cbcSrjs};
940fa225cbcSrjs
941fa225cbcSrjsstatic short empty_block[] = {
942fa225cbcSrjs  0,0,0,0,0,0,0,0,
943fa225cbcSrjs  0,0,0,0,0,0,0,0,
944fa225cbcSrjs  0,0,0,0,0,0,0,0,
945fa225cbcSrjs  0,0,0,0,0,0,0,0,
946fa225cbcSrjs  0,0,0,0,0,0,0,0,
947fa225cbcSrjs  0,0,0,0,0,0,0,0,
948fa225cbcSrjs  0,0,0,0,0,0,0,0,
949fa225cbcSrjs  0,0,0,0,0,0,0,0
950fa225cbcSrjs};
951fa225cbcSrjs
952fa225cbcSrjs
953fa225cbcSrjs/***************************************************************************
954fa225cbcSrjs// Function: dispatchYContext
955fa225cbcSrjs// Description: Allocate a DMA buffer write the Y MC Context info in it,
956fa225cbcSrjs//  and dispatch it to hardware.
957fa225cbcSrjs***************************************************************************/
958fa225cbcSrjs
959fa225cbcSrjsstatic __inline__ void dispatchYContext(i810XvMCSurface *privTarget,
960fa225cbcSrjs					i810XvMCSurface *privPast,
961fa225cbcSrjs					i810XvMCSurface *privFuture,
962fa225cbcSrjs					i810XvMCContext *pI810XvMC) {
963fa225cbcSrjs  uint *data;
964fa225cbcSrjs  drmBufPtr pDMA;
965fa225cbcSrjs  drm_i810_mc_t mc;
966fa225cbcSrjs
967fa225cbcSrjs  pDMA = i810_get_free_buffer(pI810XvMC);
968fa225cbcSrjs  data = pDMA->address;
969fa225cbcSrjs  *data++ = CMD_FLUSH;
970fa225cbcSrjs  *data++ = BOOLEAN_ENA_2;
971fa225cbcSrjs  *data++ = CMD_FLUSH;
972fa225cbcSrjs  *data++ = DEST_BUFFER_INFO;
973fa225cbcSrjs  *data++ = privTarget->dbi1y;
974fa225cbcSrjs  *data++ = DEST_BUFFER_VAR;
975fa225cbcSrjs  *data++ = privTarget->dbv1;
976fa225cbcSrjs  /* Past Surface */
977fa225cbcSrjs  *data++ = CMD_MAP_INFO;
978fa225cbcSrjs  *data++ = privPast->mi1y;
979fa225cbcSrjs  *data++ = privPast->mi2y;
980fa225cbcSrjs  *data++ = privPast->mi3y;
981fa225cbcSrjs  /* Future Surface */
982fa225cbcSrjs  *data++ = CMD_MAP_INFO;
983fa225cbcSrjs  *data++ = privFuture->mi1y | 0x1<<28;
984fa225cbcSrjs  *data++ = privFuture->mi2y;
985fa225cbcSrjs  *data++ = privFuture->mi3y;
986fa225cbcSrjs
987fa225cbcSrjs  mc.idx = pDMA->idx;
988fa225cbcSrjs  mc.used = (unsigned long)data - (unsigned long)pDMA->address;
989fa225cbcSrjs  mc.last_render = ++pI810XvMC->last_render;
990fa225cbcSrjs  privTarget->last_render = pI810XvMC->last_render;
991fa225cbcSrjs  I810_MC(pI810XvMC,mc);
992fa225cbcSrjs}
993fa225cbcSrjs
994fa225cbcSrjsstatic __inline__ void renderError(void) {
995fa225cbcSrjs  printf("Invalid Macroblock Parameters found.\n");
996fa225cbcSrjs  return;
997fa225cbcSrjs}
998fa225cbcSrjs
999fa225cbcSrjs/***************************************************************************
1000fa225cbcSrjs// Function: renderIntrainFrame
1001fa225cbcSrjs// Description: inline function that sets hardware parameters for an Intra
1002fa225cbcSrjs//  encoded macroblock in a Frame picture.
1003fa225cbcSrjs***************************************************************************/
1004fa225cbcSrjsstatic __inline__ void renderIntrainFrame(uint **datay,uint **datau,
1005fa225cbcSrjs					  uint **datav,
1006fa225cbcSrjs					  XvMCMacroBlock *mb,
1007fa225cbcSrjs					  short *block_ptr) {
1008fa225cbcSrjs
1009fa225cbcSrjs  register uint *dy = *datay;
1010fa225cbcSrjs  register uint *du = *datau;
1011fa225cbcSrjs  register uint *dv = *datav;
1012fa225cbcSrjs
1013fa225cbcSrjs  /* Y Blocks */
1014fa225cbcSrjs  *dy++ = GFXBLOCK + 68;
1015fa225cbcSrjs  *dy++ = (1<<30) | (3<<28) | (0xf<<24);
1016fa225cbcSrjs  *dy++ = ((uint)mb->x<<20) | ((uint)mb->y<<4);
1017fa225cbcSrjs  *dy++ = (16<<16) | 16;
1018fa225cbcSrjs  *dy++ = 0;
1019fa225cbcSrjs  *dy++ = 0;
1020fa225cbcSrjs  PACK_INTRA_DATA(dy,block_ptr,256);
1021fa225cbcSrjs  dy += 64;
1022fa225cbcSrjs  block_ptr += 256;
1023fa225cbcSrjs  /* End Y Blocks */
1024fa225cbcSrjs
1025fa225cbcSrjs  /* U Block */
1026fa225cbcSrjs  *du++ = GFXBLOCK + 20;
1027fa225cbcSrjs  *du++ = (2<<30) | (1<<28) | (1<<23);
1028fa225cbcSrjs  *du++ = (((uint)mb->x)<<19) | (((uint)mb->y)<<3);
1029fa225cbcSrjs  *du++ = (8<<16) | 8;
1030fa225cbcSrjs  *du++ = 0;
1031fa225cbcSrjs  *du++ = 0;
1032fa225cbcSrjs  PACK_INTRA_DATA(du,block_ptr,64);
1033fa225cbcSrjs  du += 16;
1034fa225cbcSrjs  block_ptr += 64;
1035fa225cbcSrjs
1036fa225cbcSrjs  /* V Block */
1037fa225cbcSrjs  *dv++ = GFXBLOCK + 20;
1038fa225cbcSrjs  *dv++ = (3<<30) | (1<<28) | (1<<22);
1039fa225cbcSrjs  *dv++ = (((uint)mb->x)<<19) | (((uint)mb->y)<<3);
1040fa225cbcSrjs  *dv++ = (8<<16) | 8;
1041fa225cbcSrjs  *dv++ = 0;
1042fa225cbcSrjs  *dv++ = 0;
1043fa225cbcSrjs  PACK_INTRA_DATA(dv,block_ptr,64);
1044fa225cbcSrjs  dv += 16;
1045fa225cbcSrjs  block_ptr += 64;
1046fa225cbcSrjs
1047fa225cbcSrjs  *datay = dy;
1048fa225cbcSrjs  *datau = du;
1049fa225cbcSrjs  *datav = dv;
1050fa225cbcSrjs}
1051fa225cbcSrjs
1052fa225cbcSrjs/***************************************************************************
1053fa225cbcSrjs// Function: renderIntrainFrameDCT1
1054fa225cbcSrjs// Description: inline function that sets hardware parameters for an Intra
1055fa225cbcSrjs//  encoded macroblock in a Frame picture with DCT type 1.
1056fa225cbcSrjs***************************************************************************/
1057fa225cbcSrjsstatic __inline__ void renderIntrainFrameDCT1(uint **datay,uint **datau,
1058fa225cbcSrjs					      uint **datav,XvMCMacroBlock *mb,
1059fa225cbcSrjs					      short *block_ptr,uint flags) {
1060fa225cbcSrjs
1061fa225cbcSrjs  register uint *dy = *datay;
1062fa225cbcSrjs  register uint *du = *datau;
1063fa225cbcSrjs  register uint *dv = *datav;
1064fa225cbcSrjs
1065fa225cbcSrjs
1066fa225cbcSrjs  /* Y Blocks */
1067fa225cbcSrjs  *dy++ = GFXBLOCK + 36;
1068fa225cbcSrjs  *dy++ = (1<<30) | (2<<28) | (0x3<<26) | (0x2<<6);
1069fa225cbcSrjs  *dy++ = ((uint)mb->x<<20) | ((uint)mb->y<<3);
1070fa225cbcSrjs  *dy++ = (8<<16) | 16;
1071fa225cbcSrjs  *dy++ = 0;
1072fa225cbcSrjs  *dy++ = 0;
1073fa225cbcSrjs  PACK_INTRA_DATA(dy,block_ptr,128);
1074fa225cbcSrjs  dy += 32;
1075fa225cbcSrjs  block_ptr += 128;
1076fa225cbcSrjs
1077fa225cbcSrjs  /* Second Y block */
1078fa225cbcSrjs  *dy++ = GFXBLOCK + 36;
1079fa225cbcSrjs  *dy++ = (1<<30) | (2<<28) | (0x3<<26) | (0x3<<6);
1080fa225cbcSrjs  *dy++ = ((uint)mb->x<<20) | ((uint)mb->y<<3);
1081fa225cbcSrjs  *dy++ = (8<<16) | 16;
1082fa225cbcSrjs  *dy++ = 0;
1083fa225cbcSrjs  *dy++ = 0;
1084fa225cbcSrjs  PACK_INTRA_DATA(dy,block_ptr,128);
1085fa225cbcSrjs  dy += 32;
1086fa225cbcSrjs  block_ptr += 128;
1087fa225cbcSrjs  /* End Y Blocks */
1088fa225cbcSrjs
1089fa225cbcSrjs
1090fa225cbcSrjs  /* U Block */
1091fa225cbcSrjs  *du++ = GFXBLOCK + 20;
1092fa225cbcSrjs  *du++ = (2<<30) | (1<<28) | (1<<23);
1093fa225cbcSrjs  *du++ = (((uint)mb->x)<<19) | (((uint)mb->y)<<3);
1094fa225cbcSrjs  *du++ = (8<<16) | 8;
1095fa225cbcSrjs  *du++ = 0;
1096fa225cbcSrjs  *du++ = 0;
1097fa225cbcSrjs  PACK_INTRA_DATA(du,block_ptr,64);
1098fa225cbcSrjs  du += 16;
1099fa225cbcSrjs  block_ptr += 64;
1100fa225cbcSrjs
1101fa225cbcSrjs  /* V Block */
1102fa225cbcSrjs  *dv++ = GFXBLOCK + 20;
1103fa225cbcSrjs  *dv++ = (3<<30) | (1<<28) | (1<<22);
1104fa225cbcSrjs  *dv++ = (((uint)mb->x)<<19) | (((uint)mb->y)<<3);
1105fa225cbcSrjs  *dv++ = (8<<16) | 8;
1106fa225cbcSrjs  *dv++ = 0;
1107fa225cbcSrjs  *dv++ = 0;
1108fa225cbcSrjs  PACK_INTRA_DATA(dv,block_ptr,64);
1109fa225cbcSrjs  dv += 16;
1110fa225cbcSrjs  block_ptr += 64;
1111fa225cbcSrjs
1112fa225cbcSrjs  *datay = dy;
1113fa225cbcSrjs  *datau = du;
1114fa225cbcSrjs  *datav = dv;
1115fa225cbcSrjs}
1116fa225cbcSrjs
1117fa225cbcSrjs
1118fa225cbcSrjs/***************************************************************************
1119fa225cbcSrjs// Function: renderIntrainField
1120fa225cbcSrjs// Description: inline function that sets hardware parameters for an Intra
1121fa225cbcSrjs//  encoded macroblock in Field pictures.
1122fa225cbcSrjs***************************************************************************/
1123fa225cbcSrjsstatic __inline__ void renderIntrainField(uint **datay,uint **datau,
1124fa225cbcSrjs					  uint **datav,
1125fa225cbcSrjs					  XvMCMacroBlock *mb,short *block_ptr,
1126fa225cbcSrjs					  uint ps) {
1127fa225cbcSrjs
1128fa225cbcSrjs  register uint *dy = *datay;
1129fa225cbcSrjs  register uint *du = *datau;
1130fa225cbcSrjs  register uint *dv = *datav;
1131fa225cbcSrjs
1132fa225cbcSrjs  uint xy = ((uint)mb->x<<20) | ((uint)mb->y<<4);
1133fa225cbcSrjs  uint dw1 = drps_table[~ps & 0x1];
1134fa225cbcSrjs
1135fa225cbcSrjs  /* Y Blocks */
1136fa225cbcSrjs  *dy++ = GFXBLOCK + 68;
1137fa225cbcSrjs  *dy++ = (1<<30) | (3<<28) | (0xf<<24) | dw1;
1138fa225cbcSrjs  *dy++ = xy;
1139fa225cbcSrjs  *dy++ = (16<<16) | 16;
1140fa225cbcSrjs  *dy++ = 0;
1141fa225cbcSrjs  *dy++ = 0;
1142fa225cbcSrjs  PACK_INTRA_DATA(dy,block_ptr,256);
1143fa225cbcSrjs  dy += 64;
1144fa225cbcSrjs  block_ptr += 256;
1145fa225cbcSrjs  /* End Y Blocks */
1146fa225cbcSrjs
1147fa225cbcSrjs  xy >>= 1;
1148fa225cbcSrjs
1149fa225cbcSrjs  /* U Block */
1150fa225cbcSrjs  *du++ = GFXBLOCK + 20;
1151fa225cbcSrjs  *du++ = (2<<30) | (1<<28) | (1<<23) | dw1;
1152fa225cbcSrjs  *du++ = xy;
1153fa225cbcSrjs  *du++ = (8<<16) | 8;
1154fa225cbcSrjs  *du++ = 0;
1155fa225cbcSrjs  *du++ = 0;
1156fa225cbcSrjs  PACK_INTRA_DATA(du,block_ptr,64);
1157fa225cbcSrjs  du += 16;
1158fa225cbcSrjs  block_ptr += 64;
1159fa225cbcSrjs
1160fa225cbcSrjs  /* V Block */
1161fa225cbcSrjs  *dv++ = GFXBLOCK + 20;
1162fa225cbcSrjs  *dv++ = (3<<30) | (1<<28) | (1<<22) | dw1;
1163fa225cbcSrjs  *dv++ = xy;
1164fa225cbcSrjs  *dv++ = (8<<16) | 8;
1165fa225cbcSrjs  *dv++ = 0;
1166fa225cbcSrjs  *dv++ = 0;
1167fa225cbcSrjs  PACK_INTRA_DATA(dv,block_ptr,64);
1168fa225cbcSrjs  dv += 16;
1169fa225cbcSrjs  block_ptr += 64;
1170fa225cbcSrjs
1171fa225cbcSrjs  *datay = dy;
1172fa225cbcSrjs  *datau = du;
1173fa225cbcSrjs  *datav = dv;
1174fa225cbcSrjs}
1175fa225cbcSrjs
1176fa225cbcSrjs
1177fa225cbcSrjs/***************************************************************************
1178fa225cbcSrjs// Function: renderFieldinField
1179fa225cbcSrjs// Description: inline function that sets hardware parameters for a Field
1180fa225cbcSrjs//  encoded macroblock in a Field Picture.
1181fa225cbcSrjs***************************************************************************/
1182fa225cbcSrjsstatic __inline__ void renderFieldinField(uint **datay,uint **datau,
1183fa225cbcSrjs					  uint **datav,
1184fa225cbcSrjs					  XvMCMacroBlock *mb,short *block_ptr,
1185fa225cbcSrjs					  uint ps, uint flags) {
1186fa225cbcSrjs
1187fa225cbcSrjs  register uint *dy = *datay;
1188fa225cbcSrjs  register uint *du = *datau;
1189fa225cbcSrjs  register uint *dv = *datav;
1190fa225cbcSrjs
1191fa225cbcSrjs  /* Motion Vectors */
1192fa225cbcSrjs  short fmv[2];
1193fa225cbcSrjs  short bmv[2];
1194fa225cbcSrjs  /* gfxblock dword 1 */
1195fa225cbcSrjs  uint dw1;
1196fa225cbcSrjs
1197fa225cbcSrjs  uint parity = ~ps & XVMC_TOP_FIELD;
1198fa225cbcSrjs
1199fa225cbcSrjs  uint ysize = y_frame_bytes[mb->coded_block_pattern];
1200fa225cbcSrjs  uint usize = u_frame_bytes[mb->coded_block_pattern];
1201fa225cbcSrjs  uint vsize = v_frame_bytes[mb->coded_block_pattern];
1202fa225cbcSrjs
1203fa225cbcSrjs  uint xy = ((uint)mb->x<<20) | ((uint)mb->y<<4);
1204fa225cbcSrjs
1205fa225cbcSrjs  /* i810 Specific flag used to identify the second field in a P frame */
1206fa225cbcSrjs  if(flags & 0x80000000) {
1207fa225cbcSrjs    /* P Frame */
1208fa225cbcSrjs    if((mb->motion_vertical_field_select & XVMC_SELECT_FIRST_FORWARD) ==
1209fa225cbcSrjs      parity) {
1210fa225cbcSrjs      /* Same parity, use reference field (map0) */
1211fa225cbcSrjs      dw1 = 1<<12 | ((0x2 + parity)<<6) | ((0x2 + parity)<<3) |
1212fa225cbcSrjs	(((uint)mb->coded_block_pattern)<<22);
1213fa225cbcSrjs      fmv[0] = mb->PMV[0][0][1];
1214fa225cbcSrjs      fmv[1] = mb->PMV[0][0][0];
1215fa225cbcSrjs      bmv[0] = 0;
1216fa225cbcSrjs      bmv[1] = 0;
1217fa225cbcSrjs    }
1218fa225cbcSrjs    else {
1219fa225cbcSrjs      /*
1220fa225cbcSrjs	Opposite parity, set up as if it were backward
1221fa225cbcSrjs	motion and use map1.
1222fa225cbcSrjs      */
1223fa225cbcSrjs      dw1 = 2<<12 | ((0x2 + parity)<<6) | (0x3 - parity) |
1224fa225cbcSrjs	(((uint)mb->coded_block_pattern)<<22);
1225fa225cbcSrjs      bmv[0] = mb->PMV[0][0][1];
1226fa225cbcSrjs      bmv[1] = mb->PMV[0][0][0];
1227fa225cbcSrjs      fmv[0] = 0;
1228fa225cbcSrjs      fmv[1] = 0;
1229fa225cbcSrjs    }
1230fa225cbcSrjs  }
1231fa225cbcSrjs  else {
1232fa225cbcSrjs    dw1 = type_table[mb->macroblock_type & 0xf] |
1233fa225cbcSrjs      drps_table[~ps & 0x1] |
1234fa225cbcSrjs      mvfs_table[mb->motion_vertical_field_select & 3] |
1235fa225cbcSrjs      (((uint)mb->coded_block_pattern)<<22);
1236fa225cbcSrjs
1237fa225cbcSrjs    fmv[0] = mb->PMV[0][0][1];
1238fa225cbcSrjs    fmv[1] = mb->PMV[0][0][0];
1239fa225cbcSrjs
1240fa225cbcSrjs    bmv[0] = mb->PMV[0][1][1];
1241fa225cbcSrjs    bmv[1] = mb->PMV[0][1][0];
1242fa225cbcSrjs  }
1243fa225cbcSrjs
1244fa225cbcSrjs  /* Y Block */
1245fa225cbcSrjs  *dy++ = GFXBLOCK + 4 + (ysize>>2);
1246fa225cbcSrjs  *dy++ = (1<<30) | (3<<28) | dw1;
1247fa225cbcSrjs  *dy++ = xy;
1248fa225cbcSrjs  *dy++ = (16<<16) | 16;
1249fa225cbcSrjs  *dy++ = *(uint *)fmv;
1250fa225cbcSrjs  *dy++ = *(uint *)bmv;
1251fa225cbcSrjs  PACK_CORR_DATA(dy,block_ptr,ysize);
1252fa225cbcSrjs  block_ptr = (short *)((unsigned long)block_ptr + ysize);
1253fa225cbcSrjs  /* End Y Blocks */
1254fa225cbcSrjs
1255fa225cbcSrjs  fmv[0] /= 2;
1256fa225cbcSrjs  fmv[1] /= 2;
1257fa225cbcSrjs  bmv[0] /= 2;
1258fa225cbcSrjs  bmv[1] /= 2;
1259fa225cbcSrjs  xy >>= 1;
1260fa225cbcSrjs
1261fa225cbcSrjs  /* U Block */
1262fa225cbcSrjs  *du++ = GFXBLOCK + 4 + (usize>>2);
1263fa225cbcSrjs  *du++ = (2<<30) | (1<<28) | dw1;
1264fa225cbcSrjs  *du++ = xy;
1265fa225cbcSrjs  *du++ = (8<<16) | 8;
1266fa225cbcSrjs  *du++ = *(uint *)fmv;
1267fa225cbcSrjs  *du++ = *(uint *)bmv;
1268fa225cbcSrjs  PACK_CORR_DATA(du,block_ptr,usize);
1269fa225cbcSrjs  block_ptr = (short *)((unsigned long)block_ptr + usize);
1270fa225cbcSrjs
1271fa225cbcSrjs  /* V Block */
1272fa225cbcSrjs  *dv++ = GFXBLOCK + 4 + (vsize>>2);
1273fa225cbcSrjs  *dv++ = (3<<30) | (1<<28) | dw1;
1274fa225cbcSrjs  *dv++ = xy;
1275fa225cbcSrjs  *dv++ = (8<<16) | 8;
1276fa225cbcSrjs  *dv++ = *(uint *)fmv;
1277fa225cbcSrjs  *dv++ = *(uint *)bmv;
1278fa225cbcSrjs  PACK_CORR_DATA(dv,block_ptr,vsize);
1279fa225cbcSrjs  block_ptr = (short *)((unsigned long)block_ptr + vsize);
1280fa225cbcSrjs
1281fa225cbcSrjs  *datay = dy;
1282fa225cbcSrjs  *datau = du;
1283fa225cbcSrjs  *datav = dv;
1284fa225cbcSrjs}
1285fa225cbcSrjs
1286fa225cbcSrjs/***************************************************************************
1287fa225cbcSrjs// Function: render16x8inField
1288fa225cbcSrjs// Description: inline function that sets hardware parameters for a 16x8
1289fa225cbcSrjs//  encoded macroblock in a field picture.
1290fa225cbcSrjs***************************************************************************/
1291fa225cbcSrjsstatic __inline__ void render16x8inField(uint **datay,uint **datau,
1292fa225cbcSrjs					 uint **datav,
1293fa225cbcSrjs					 XvMCMacroBlock *mb,short *block_ptr,
1294fa225cbcSrjs					 uint ps, uint flags) {
1295fa225cbcSrjs
1296fa225cbcSrjs  register uint *dy = *datay;
1297fa225cbcSrjs  register uint *du = *datau;
1298fa225cbcSrjs  register uint *dv = *datav;
1299fa225cbcSrjs
1300fa225cbcSrjs  /* Motion Vectors */
1301fa225cbcSrjs  short fmv[4];
1302fa225cbcSrjs  short bmv[4];
1303fa225cbcSrjs  /* gfxblock dword 1 */
1304fa225cbcSrjs  uint dw1[2];
1305fa225cbcSrjs
1306fa225cbcSrjs  uint y1size = y_first_field_bytes[mb->coded_block_pattern];
1307fa225cbcSrjs  uint y2size = y_second_field_bytes[mb->coded_block_pattern];
1308fa225cbcSrjs  uint usize = u_field_bytes[mb->coded_block_pattern];
1309fa225cbcSrjs  uint vsize = v_field_bytes[mb->coded_block_pattern];
1310fa225cbcSrjs
1311fa225cbcSrjs  uint parity = ~ps & XVMC_TOP_FIELD;
1312fa225cbcSrjs
1313fa225cbcSrjs  uint xy = ((uint)mb->x<<20) | ((uint)mb->y<<4);
1314fa225cbcSrjs
1315fa225cbcSrjs  /* i810 Specific flag used to identify the second field in a P frame */
1316fa225cbcSrjs  if(flags & 0x80000000) {
1317fa225cbcSrjs    /* P Frame */
1318fa225cbcSrjs    if((mb->motion_vertical_field_select & XVMC_SELECT_FIRST_FORWARD) ==
1319fa225cbcSrjs      parity) {
1320fa225cbcSrjs      /* Same parity, use reference field (map0) */
1321fa225cbcSrjs      dw1[0] = 1<<12 | ((0x2 + parity)<<6) | ((0x2 + parity)<<3) |
1322fa225cbcSrjs	(((uint)mb->coded_block_pattern)<<22);
1323fa225cbcSrjs
1324fa225cbcSrjs      fmv[0] = mb->PMV[0][0][1];
1325fa225cbcSrjs      fmv[1] = mb->PMV[0][0][0];
1326fa225cbcSrjs      bmv[0] = 0;
1327fa225cbcSrjs      bmv[1] = 0;
1328fa225cbcSrjs    }
1329fa225cbcSrjs    else {
1330fa225cbcSrjs      /*
1331fa225cbcSrjs	Opposite parity, set up as if it were backward
1332fa225cbcSrjs	motion and use map1.
1333fa225cbcSrjs      */
1334fa225cbcSrjs      dw1[0] = 2<<12 | ((0x2 + parity)<<6) | (0x3 - parity) |
1335fa225cbcSrjs	(((uint)mb->coded_block_pattern)<<22);
1336fa225cbcSrjs
1337fa225cbcSrjs      bmv[0] = mb->PMV[0][0][1];
1338fa225cbcSrjs      bmv[1] = mb->PMV[0][0][0];
1339fa225cbcSrjs      fmv[0] = 0;
1340fa225cbcSrjs      fmv[1] = 0;
1341fa225cbcSrjs    }
1342fa225cbcSrjs    if((mb->motion_vertical_field_select & XVMC_SELECT_SECOND_FORWARD) ==
1343fa225cbcSrjs       (parity<<2)) {
1344fa225cbcSrjs      /* Same parity, use reference field (map0) */
1345fa225cbcSrjs      dw1[1] = 1<<12 | ((0x2 + parity)<<6) | ((0x2 + parity)<<3) |
1346fa225cbcSrjs	((((uint)mb->coded_block_pattern<<22) & (0x3<<22)) |
1347fa225cbcSrjs	 (((uint)mb->coded_block_pattern<<24) & (0x3<<26)));
1348fa225cbcSrjs
1349fa225cbcSrjs      fmv[2] = mb->PMV[1][0][1];
1350fa225cbcSrjs      fmv[3] = mb->PMV[1][0][0];
1351fa225cbcSrjs      bmv[2] = 0;
1352fa225cbcSrjs      bmv[3] = 0;
1353fa225cbcSrjs    }
1354fa225cbcSrjs    else {
1355fa225cbcSrjs      /*
1356fa225cbcSrjs	 Opposite parity, set up as if it were backward
1357fa225cbcSrjs	 motion and use map1.
1358fa225cbcSrjs      */
1359fa225cbcSrjs      dw1[1] = 2<<12 | ((0x2 + parity)<<6) | (0x3 - parity) |
1360fa225cbcSrjs	((((uint)mb->coded_block_pattern<<22) & (0x3<<22)) |
1361fa225cbcSrjs	 (((uint)mb->coded_block_pattern<<24) & (0x3<<26)));
1362fa225cbcSrjs
1363fa225cbcSrjs      bmv[2] = mb->PMV[1][0][1];
1364fa225cbcSrjs      bmv[3] = mb->PMV[1][0][0];
1365fa225cbcSrjs      fmv[2] = 0;
1366fa225cbcSrjs      fmv[3] = 0;
1367fa225cbcSrjs    }
1368fa225cbcSrjs  }
1369fa225cbcSrjs  else {
1370fa225cbcSrjs    dw1[0] = type_table[mb->macroblock_type & 0xf] |
1371fa225cbcSrjs      drps_table[~ps & 0x1] |
1372fa225cbcSrjs      mvfs_table[mb->motion_vertical_field_select & 3] |
1373fa225cbcSrjs      (((uint)mb->coded_block_pattern)<<22);
1374fa225cbcSrjs
1375fa225cbcSrjs    dw1[1] = type_table[mb->macroblock_type & 0xf] |
1376fa225cbcSrjs      drps_table[~ps & 0x1] |
1377fa225cbcSrjs      mvfs_table[(mb->motion_vertical_field_select>>2) & 0x3] |
1378fa225cbcSrjs      ((((uint)mb->coded_block_pattern<<22) & (0x3<<22)) |
1379fa225cbcSrjs       (((uint)mb->coded_block_pattern<<24) & (0x3<<26)));
1380fa225cbcSrjs
1381fa225cbcSrjs    fmv[0] = mb->PMV[0][0][1];
1382fa225cbcSrjs    fmv[1] = mb->PMV[0][0][0];
1383fa225cbcSrjs    fmv[2] = mb->PMV[1][0][1];
1384fa225cbcSrjs    fmv[3] = mb->PMV[1][0][0];
1385fa225cbcSrjs
1386fa225cbcSrjs    bmv[0] = mb->PMV[0][1][1];
1387fa225cbcSrjs    bmv[1] = mb->PMV[0][1][0];
1388fa225cbcSrjs    bmv[2] = mb->PMV[1][1][1];
1389fa225cbcSrjs    bmv[3] = mb->PMV[1][1][0];
1390fa225cbcSrjs  }
1391fa225cbcSrjs
1392fa225cbcSrjs  /* First Y Block */
1393fa225cbcSrjs  *dy++ = GFXBLOCK + 4 + (y1size>>2);
1394fa225cbcSrjs  *dy++ = (1<<30) | (2<<28) | dw1[0];
1395fa225cbcSrjs  *dy++ = xy;
1396fa225cbcSrjs  *dy++ = (8<<16) | 16;
1397fa225cbcSrjs  *dy++ = *(uint *)fmv;
1398fa225cbcSrjs  *dy++ = *(uint *)bmv;
1399fa225cbcSrjs  PACK_CORR_DATA(dy,block_ptr,y1size);
1400fa225cbcSrjs  block_ptr = (short *)((unsigned long)block_ptr + y1size);
1401fa225cbcSrjs
1402fa225cbcSrjs  /* Second Y Block */
1403fa225cbcSrjs  *dy++ = GFXBLOCK + 4 + (y2size>>2);
1404fa225cbcSrjs  *dy++ = (1<<30) | (2<<28) | dw1[1];
1405fa225cbcSrjs  *dy++ = (xy + 8);
1406fa225cbcSrjs  *dy++ = (8<<16) | 16;
1407fa225cbcSrjs  *dy++ = *(uint *)&fmv[2];
1408fa225cbcSrjs  *dy++ = *(uint *)&bmv[2];
1409fa225cbcSrjs  PACK_CORR_DATA(dy,block_ptr,y2size);
1410fa225cbcSrjs  block_ptr = (short *)((unsigned long)block_ptr + y2size);
1411fa225cbcSrjs  /* End Y Blocks */
1412fa225cbcSrjs
1413fa225cbcSrjs  fmv[0] /= 2;
1414fa225cbcSrjs  fmv[1] /= 2;
1415fa225cbcSrjs  fmv[2] /= 2;
1416fa225cbcSrjs  fmv[3] /= 2;
1417fa225cbcSrjs
1418fa225cbcSrjs  bmv[0] /= 2;
1419fa225cbcSrjs  bmv[1] /= 2;
1420fa225cbcSrjs  bmv[2] /= 2;
1421fa225cbcSrjs  bmv[3] /= 2;
1422fa225cbcSrjs
1423fa225cbcSrjs  xy >>= 1;
1424fa225cbcSrjs
1425fa225cbcSrjs  /* U Blocks */
1426fa225cbcSrjs  *du++ = GFXBLOCK + 4 + (usize>>2);
1427fa225cbcSrjs  *du++ = (2<<30) | (1<<28) | dw1[0];
1428fa225cbcSrjs  *du++ = xy;
1429fa225cbcSrjs  *du++ = (4<<16) | 8;
1430fa225cbcSrjs  *du++ = *(uint *)fmv;
1431fa225cbcSrjs  *du++ = *(uint *)bmv;
1432fa225cbcSrjs  PACK_CORR_DATA(du,block_ptr,usize);
1433fa225cbcSrjs  block_ptr = (short *)((unsigned long)block_ptr + usize);
1434fa225cbcSrjs
1435fa225cbcSrjs  /* Second U block */
1436fa225cbcSrjs  *du++ = GFXBLOCK + 4 + (usize>>2);
1437fa225cbcSrjs  *du++ = (2<<30) | (1<<28) | dw1[1];
1438fa225cbcSrjs  *du++ = (xy + 4);
1439fa225cbcSrjs  *du++ = (4<<16) | 8;
1440fa225cbcSrjs  *du++ = *(uint *)&fmv[2];
1441fa225cbcSrjs  *du++ = *(uint *)&bmv[2];
1442fa225cbcSrjs  PACK_CORR_DATA(du,block_ptr,usize);
1443fa225cbcSrjs  block_ptr = (short *)((unsigned long)block_ptr + usize);
1444fa225cbcSrjs  /* End U Blocks */
1445fa225cbcSrjs
1446fa225cbcSrjs  /* V Blocks */
1447fa225cbcSrjs  *dv++ = GFXBLOCK + 4 + (vsize>>2);
1448fa225cbcSrjs  *dv++ = (3<<30) | (1<<28) | dw1[0];
1449fa225cbcSrjs  *dv++ = xy;
1450fa225cbcSrjs  *dv++ = (4<<16) | 8;
1451fa225cbcSrjs  *dv++ = *(uint *)fmv;
1452fa225cbcSrjs  *dv++ = *(uint *)bmv;
1453fa225cbcSrjs  PACK_CORR_DATA(dv,block_ptr,vsize);
1454fa225cbcSrjs  block_ptr = (short *)((unsigned long)block_ptr + vsize);
1455fa225cbcSrjs
1456fa225cbcSrjs  /* Second V Block */
1457fa225cbcSrjs  *dv++ = GFXBLOCK + 4 + (vsize>>2);
1458fa225cbcSrjs  *dv++ = (3<<30) | (1<<28) | dw1[1];
1459fa225cbcSrjs  *dv++ = (xy + 4);
1460fa225cbcSrjs  *dv++ = (4<<16) | 8;
1461fa225cbcSrjs  *dv++ = *(uint *)&fmv[2];
1462fa225cbcSrjs  *dv++ = *(uint *)&bmv[2];
1463fa225cbcSrjs  PACK_CORR_DATA(dv,block_ptr,vsize);
1464fa225cbcSrjs  block_ptr = (short *)((unsigned long)block_ptr + vsize);
1465fa225cbcSrjs  /* End V Blocks */
1466fa225cbcSrjs
1467fa225cbcSrjs  *datay = dy;
1468fa225cbcSrjs  *datau = du;
1469fa225cbcSrjs  *datav = dv;
1470fa225cbcSrjs}
1471fa225cbcSrjs
1472fa225cbcSrjs/***************************************************************************
1473fa225cbcSrjs// Function: renderDualPrimeinField
1474fa225cbcSrjs// Description: inline function that sets hardware parameters for a Dual
1475fa225cbcSrjs//  prime encoded macroblock in a field picture.
1476fa225cbcSrjs***************************************************************************/
1477fa225cbcSrjsstatic __inline__ void renderDualPrimeinField(uint **datay,uint **datau,
1478fa225cbcSrjs					      uint **datav,XvMCMacroBlock *mb,
1479fa225cbcSrjs					      short *block_ptr,uint ps,
1480fa225cbcSrjs					      uint flags) {
1481fa225cbcSrjs
1482fa225cbcSrjs  register uint *dy = *datay;
1483fa225cbcSrjs  register uint *du = *datau;
1484fa225cbcSrjs  register uint *dv = *datav;
1485fa225cbcSrjs
1486fa225cbcSrjs  /* Motion Vectors */
1487fa225cbcSrjs  short fmv[2];
1488fa225cbcSrjs  short bmv[2];
1489fa225cbcSrjs  /* gfxblock dword 1 */
1490fa225cbcSrjs  uint dw1;
1491fa225cbcSrjs
1492fa225cbcSrjs
1493fa225cbcSrjs  uint ysize = y_frame_bytes[mb->coded_block_pattern];
1494fa225cbcSrjs  uint usize = u_frame_bytes[mb->coded_block_pattern];
1495fa225cbcSrjs  uint vsize = v_frame_bytes[mb->coded_block_pattern];
1496fa225cbcSrjs
1497fa225cbcSrjs  uint xy = ((uint)mb->x<<20) | ((uint)mb->y<<4);
1498fa225cbcSrjs
1499fa225cbcSrjs
1500fa225cbcSrjs  if(ps & XVMC_TOP_FIELD) {
1501fa225cbcSrjs    dw1 = (mb->coded_block_pattern<<22) | 3<<12 | 2<<6 | 2<<3 | 3;
1502fa225cbcSrjs  }
1503fa225cbcSrjs  else {
1504fa225cbcSrjs    dw1 = (mb->coded_block_pattern<<22) | 3<<12 | 3<<6 | 3<<3 | 2;
1505fa225cbcSrjs  }
1506fa225cbcSrjs  fmv[0] = mb->PMV[0][0][1];
1507fa225cbcSrjs  fmv[1] = mb->PMV[0][0][0];
1508fa225cbcSrjs  bmv[0] = mb->PMV[0][1][1];
1509fa225cbcSrjs  bmv[1] = mb->PMV[0][1][0];
1510fa225cbcSrjs
1511fa225cbcSrjs  /* Y Block */
1512fa225cbcSrjs  *dy++ = GFXBLOCK + 4 + (ysize>>2);
1513fa225cbcSrjs  *dy++ = (1<<30) | (3<<28) | dw1;
1514fa225cbcSrjs  *dy++ = xy;
1515fa225cbcSrjs  *dy++ = (16<<16) | 16;
1516fa225cbcSrjs  *dy++ = *(uint *)fmv;
1517fa225cbcSrjs  *dy++ = *(uint *)bmv;
1518fa225cbcSrjs  PACK_CORR_DATA(dy,block_ptr,ysize);
1519fa225cbcSrjs  block_ptr = (short *)((unsigned long)block_ptr + ysize);
1520fa225cbcSrjs  /* End Y Blocks */
1521fa225cbcSrjs
1522fa225cbcSrjs  fmv[0] /= 2;
1523fa225cbcSrjs  fmv[1] /= 2;
1524fa225cbcSrjs  bmv[0] /= 2;
1525fa225cbcSrjs  bmv[1] /= 2;
1526fa225cbcSrjs  xy >>= 1;
1527fa225cbcSrjs
1528fa225cbcSrjs  /* U Block */
1529fa225cbcSrjs  *du++ = GFXBLOCK + 4 + (usize>>2);
1530fa225cbcSrjs  *du++ = (2<<30) | (1<<28) | dw1;
1531fa225cbcSrjs  *du++ = xy;
1532fa225cbcSrjs  *du++ = (8<<16) | 8;
1533fa225cbcSrjs  *du++ = *(uint *)fmv;
1534fa225cbcSrjs  *du++ = *(uint *)bmv;
1535fa225cbcSrjs  PACK_CORR_DATA(du,block_ptr,usize);
1536fa225cbcSrjs  block_ptr = (short *)((unsigned long)block_ptr + usize);
1537fa225cbcSrjs
1538fa225cbcSrjs  /* V Block */
1539fa225cbcSrjs  *dv++ = GFXBLOCK + 4 + (vsize>>2);
1540fa225cbcSrjs  *dv++ = (3<<30) | (1<<28) | dw1;
1541fa225cbcSrjs  *dv++ = xy;
1542fa225cbcSrjs  *dv++ = (8<<16) | 8;
1543fa225cbcSrjs  *dv++ = *(uint *)fmv;
1544fa225cbcSrjs  *dv++ = *(uint *)bmv;
1545fa225cbcSrjs  PACK_CORR_DATA(dv,block_ptr,vsize);
1546fa225cbcSrjs  block_ptr = (short *)((unsigned long)block_ptr + vsize);
1547fa225cbcSrjs
1548fa225cbcSrjs  *datay = dy;
1549fa225cbcSrjs  *datau = du;
1550fa225cbcSrjs  *datav = dv;
1551fa225cbcSrjs}
1552fa225cbcSrjs
1553fa225cbcSrjs/***************************************************************************
1554fa225cbcSrjs// Function: renderFieldinFrame
1555fa225cbcSrjs// Description: inline function that sets hardware parameters for a Field
1556fa225cbcSrjs//  encoded macroblock in a frame picture.
1557fa225cbcSrjs***************************************************************************/
1558fa225cbcSrjstypedef union {
1559fa225cbcSrjs  short	s[4];
1560fa225cbcSrjs  uint  u[2];
1561fa225cbcSrjs} su_t;
1562fa225cbcSrjs
1563fa225cbcSrjsstatic __inline__ void renderFieldinFrame(uint **datay,uint **datau,
1564fa225cbcSrjs					  uint **datav,
1565fa225cbcSrjs					  XvMCMacroBlock *mb,short *block_ptr,
1566fa225cbcSrjs					  uint flags) {
1567fa225cbcSrjs
1568fa225cbcSrjs  register uint *dy = *datay;
1569fa225cbcSrjs  register uint *du = *datau;
1570fa225cbcSrjs  register uint *dv = *datav;
1571fa225cbcSrjs
1572fa225cbcSrjs  /* Motion Vectors */
1573fa225cbcSrjs  su_t fmv;
1574fa225cbcSrjs  su_t bmv;
1575fa225cbcSrjs  /* gfxblock dword 1 */
1576fa225cbcSrjs  uint dw1[2];
1577fa225cbcSrjs
1578fa225cbcSrjs  uint y1size = y_first_field_bytes[mb->coded_block_pattern];
1579fa225cbcSrjs  uint y2size = y_second_field_bytes[mb->coded_block_pattern];
1580fa225cbcSrjs  uint usize = u_field_bytes[mb->coded_block_pattern];
1581fa225cbcSrjs  uint vsize = v_field_bytes[mb->coded_block_pattern];
1582fa225cbcSrjs
1583fa225cbcSrjs  uint xy = ((uint)mb->x<<20) | ((uint)mb->y<<3);
1584fa225cbcSrjs
1585fa225cbcSrjs  dw1[0] = type_table[mb->macroblock_type & 0xf] | (0x2<<6) |
1586fa225cbcSrjs    mvfs_table[mb->motion_vertical_field_select & 3] |
1587fa225cbcSrjs    (((uint)mb->coded_block_pattern)<<22);
1588fa225cbcSrjs
1589fa225cbcSrjs  dw1[1] = type_table[mb->macroblock_type & 0xf] | (0x3<<6) |
1590fa225cbcSrjs    mvfs_table[mb->motion_vertical_field_select>>2] |
1591fa225cbcSrjs    (((mb->coded_block_pattern & 0x3) |
1592fa225cbcSrjs      ((mb->coded_block_pattern & 0xc)<<2))<<22);
1593fa225cbcSrjs
1594fa225cbcSrjs  fmv.s[0] = mb->PMV[0][0][1]/2;
1595fa225cbcSrjs  fmv.s[1] = mb->PMV[0][0][0];
1596fa225cbcSrjs  fmv.s[2] = mb->PMV[1][0][1]/2;
1597fa225cbcSrjs  fmv.s[3] = mb->PMV[1][0][0];
1598fa225cbcSrjs
1599fa225cbcSrjs  bmv.s[0] = mb->PMV[0][1][1]/2;
1600fa225cbcSrjs  bmv.s[1] = mb->PMV[0][1][0];
1601fa225cbcSrjs  bmv.s[2] = mb->PMV[1][1][1]/2;
1602fa225cbcSrjs  bmv.s[3] = mb->PMV[1][1][0];
1603fa225cbcSrjs
1604fa225cbcSrjs  /* First Y Block */
1605fa225cbcSrjs  *dy++ = GFXBLOCK + 4 + (y1size>>2);
1606fa225cbcSrjs  *dy++ = (1<<30) | (2<<28) | dw1[0];
1607fa225cbcSrjs  *dy++ = xy;
1608fa225cbcSrjs  *dy++ = (8<<16) | 16;
1609fa225cbcSrjs  *dy++ = fmv.u[0];
1610fa225cbcSrjs  *dy++ = bmv.u[0];
1611fa225cbcSrjs  PACK_CORR_DATA(dy,block_ptr,y1size);
1612fa225cbcSrjs  block_ptr = (short *)((unsigned long)block_ptr + y1size);
1613fa225cbcSrjs
1614fa225cbcSrjs  /* Second Y Block */
1615fa225cbcSrjs  *dy++ = GFXBLOCK + 4 + (y2size>>2);
1616fa225cbcSrjs  *dy++ = (1<<30) | (2<<28) | dw1[1];
1617fa225cbcSrjs  *dy++ = xy;
1618fa225cbcSrjs  *dy++ = (8<<16) | 16;
1619fa225cbcSrjs  *dy++ = fmv.u[1];
1620fa225cbcSrjs  *dy++ = bmv.u[1];
1621fa225cbcSrjs  PACK_CORR_DATA(dy,block_ptr,y2size);
1622fa225cbcSrjs  block_ptr = (short *)((unsigned long)block_ptr + y2size);
1623fa225cbcSrjs  /* End Y Blocks */
1624fa225cbcSrjs
1625fa225cbcSrjs  fmv.s[0] /= 2;
1626fa225cbcSrjs  fmv.s[1] /= 2;
1627fa225cbcSrjs  fmv.s[2] /= 2;
1628fa225cbcSrjs  fmv.s[3] /= 2;
1629fa225cbcSrjs
1630fa225cbcSrjs  bmv.s[0] /= 2;
1631fa225cbcSrjs  bmv.s[1] /= 2;
1632fa225cbcSrjs  bmv.s[2] /= 2;
1633fa225cbcSrjs  bmv.s[3] /= 2;
1634fa225cbcSrjs
1635fa225cbcSrjs  xy >>= 1;
1636fa225cbcSrjs
1637fa225cbcSrjs  /* U Blocks */
1638fa225cbcSrjs  *du++ = GFXBLOCK + 4 + (usize>>2);
1639fa225cbcSrjs  *du++ = (2<<30) | (1<<28) | dw1[0];
1640fa225cbcSrjs  *du++ = xy;
1641fa225cbcSrjs  *du++ = (4<<16) | 8;
1642fa225cbcSrjs  *du++ = fmv.u[0];
1643fa225cbcSrjs  *du++ = bmv.u[0];
1644fa225cbcSrjs  if(usize) {
1645fa225cbcSrjs    PACK_CORR_DATA_SHORT(du,block_ptr);
1646fa225cbcSrjs  }
1647fa225cbcSrjs
1648fa225cbcSrjs  /* Second U Block */
1649fa225cbcSrjs  *du++ = GFXBLOCK + 4 + (usize>>2);
1650fa225cbcSrjs  *du++ = (2<<30) | (1<<28) | dw1[1];
1651fa225cbcSrjs  *du++ = xy;
1652fa225cbcSrjs  *du++ = (4<<16) | 8;
1653fa225cbcSrjs  *du++ = fmv.u[1];
1654fa225cbcSrjs  *du++ = bmv.u[1];
1655fa225cbcSrjs  if(usize) {
1656fa225cbcSrjs    block_ptr = (short *)((unsigned long)block_ptr + 16);
1657fa225cbcSrjs    PACK_CORR_DATA_SHORT(du,block_ptr);
1658fa225cbcSrjs    block_ptr = (short *)((unsigned long)block_ptr + 112);
1659fa225cbcSrjs  }
1660fa225cbcSrjs  /* End U Blocks */
1661fa225cbcSrjs
1662fa225cbcSrjs  /* V Blocks */
1663fa225cbcSrjs  *dv++ = GFXBLOCK + 4 + (vsize>>2);
1664fa225cbcSrjs  *dv++ = (3<<30) | (1<<28) | dw1[0];
1665fa225cbcSrjs  *dv++ = xy;
1666fa225cbcSrjs  *dv++ = (4<<16) | 8;
1667fa225cbcSrjs  *dv++ = fmv.u[0];
1668fa225cbcSrjs  *dv++ = bmv.u[0];
1669fa225cbcSrjs  if(vsize) {
1670fa225cbcSrjs    PACK_CORR_DATA_SHORT(dv,block_ptr);
1671fa225cbcSrjs  }
1672fa225cbcSrjs
1673fa225cbcSrjs  /* Second V Block */
1674fa225cbcSrjs  *dv++ = GFXBLOCK + 4 + (vsize>>2);
1675fa225cbcSrjs  *dv++ = (3<<30) | (1<<28) | dw1[1];
1676fa225cbcSrjs  *dv++ = xy;
1677fa225cbcSrjs  *dv++ = (4<<16) | 8;
1678fa225cbcSrjs  *dv++ = fmv.u[1];
1679fa225cbcSrjs  *dv++ = bmv.u[1];
1680fa225cbcSrjs  if(vsize) {
1681fa225cbcSrjs    block_ptr = (short *)((unsigned long)block_ptr + 16);
1682fa225cbcSrjs    PACK_CORR_DATA_SHORT(dv,block_ptr);
1683fa225cbcSrjs    block_ptr = (short *)((unsigned long)block_ptr + 112);
1684fa225cbcSrjs  }
1685fa225cbcSrjs  /* End V Blocks */
1686fa225cbcSrjs
1687fa225cbcSrjs  *datay = dy;
1688fa225cbcSrjs  *datau = du;
1689fa225cbcSrjs  *datav = dv;
1690fa225cbcSrjs}
1691fa225cbcSrjs
1692fa225cbcSrjs/***************************************************************************
1693fa225cbcSrjs// Function: renderFieldinFrameDCT0
1694fa225cbcSrjs// Description: inline function that sets hardware parameters for a Field
1695fa225cbcSrjs//  encoded macroblock in a frame picture with DCT0.
1696fa225cbcSrjs***************************************************************************/
1697fa225cbcSrjsstatic __inline__ void renderFieldinFrameDCT0(uint **datay,uint **datau,
1698fa225cbcSrjs					      uint **datav,XvMCMacroBlock *mb,
1699fa225cbcSrjs					      short *block_ptr,uint flags) {
1700fa225cbcSrjs
1701fa225cbcSrjs  register uint *dy = *datay;
1702fa225cbcSrjs  register uint *du = *datau;
1703fa225cbcSrjs  register uint *dv = *datav;
1704fa225cbcSrjs
1705fa225cbcSrjs  /* Motion Vectors */
1706fa225cbcSrjs  su_t fmv;
1707fa225cbcSrjs  su_t bmv;
1708fa225cbcSrjs  /* CBP */
1709fa225cbcSrjs  uint cbp = (uint)mb->coded_block_pattern;
1710fa225cbcSrjs  /* gfxblock dword 1 */
1711fa225cbcSrjs  uint dw1[2];
1712fa225cbcSrjs
1713fa225cbcSrjs  short * top_left_b = NULL;
1714fa225cbcSrjs  short * top_right_b = NULL;
1715fa225cbcSrjs  short * bottom_left_b = NULL;
1716fa225cbcSrjs  short * bottom_right_b = NULL;
1717fa225cbcSrjs
1718fa225cbcSrjs  unsigned int ysize = y_dct0_field_bytes[cbp];
1719fa225cbcSrjs  unsigned int usize = u_field_bytes[cbp];
1720fa225cbcSrjs  unsigned int vsize = v_field_bytes[cbp];
1721fa225cbcSrjs
1722fa225cbcSrjs  uint xy = ((uint)mb->x<<20) | ((uint)mb->y<<3);
1723fa225cbcSrjs
1724fa225cbcSrjs  dw1[0] = type_table[mb->macroblock_type & 0xf] | (0x2<<6) |
1725fa225cbcSrjs    mvfs_table[mb->motion_vertical_field_select & 3] |
1726fa225cbcSrjs    ((cbp | ((cbp<<2) & 0x30))<<22);
1727fa225cbcSrjs
1728fa225cbcSrjs  dw1[1] = type_table[mb->macroblock_type & 0xf] | (0x3<<6) |
1729fa225cbcSrjs    mvfs_table[mb->motion_vertical_field_select>>2] |
1730fa225cbcSrjs    ((cbp | ((cbp<<2) & 0x30))<<22);
1731fa225cbcSrjs
1732fa225cbcSrjs
1733fa225cbcSrjs  fmv.s[0] = mb->PMV[0][0][1]/2;
1734fa225cbcSrjs  fmv.s[1] = mb->PMV[0][0][0];
1735fa225cbcSrjs  fmv.s[2] = mb->PMV[1][0][1]/2;
1736fa225cbcSrjs  fmv.s[3] = mb->PMV[1][0][0];
1737fa225cbcSrjs
1738fa225cbcSrjs  bmv.s[0] = mb->PMV[0][1][1]/2;
1739fa225cbcSrjs  bmv.s[1] = mb->PMV[0][1][0];
1740fa225cbcSrjs  bmv.s[2] = mb->PMV[1][1][1]/2;
1741fa225cbcSrjs  bmv.s[3] = mb->PMV[1][1][0];
1742fa225cbcSrjs
1743fa225cbcSrjs  /*
1744fa225cbcSrjs    The i810 cannot use DCT0 directly with field motion, we have to
1745fa225cbcSrjs    interlace the data for it. We use a zero block when the CBP has
1746fa225cbcSrjs    one half of the to-be-interlaced data but not the other half.
1747fa225cbcSrjs  */
1748fa225cbcSrjs  top_left_b = &empty_block[0];
1749fa225cbcSrjs  if(cbp & 0x20) {
1750fa225cbcSrjs    top_left_b = block_ptr;
1751fa225cbcSrjs    block_ptr += 64;
1752fa225cbcSrjs  }
1753fa225cbcSrjs
1754fa225cbcSrjs  top_right_b = &empty_block[0];
1755fa225cbcSrjs  if(cbp & 0x10) {
1756fa225cbcSrjs    top_right_b = block_ptr;
1757fa225cbcSrjs    block_ptr += 64;
1758fa225cbcSrjs  }
1759fa225cbcSrjs
1760fa225cbcSrjs  bottom_left_b = &empty_block[0];
1761fa225cbcSrjs  if(cbp & 0x8) {
1762fa225cbcSrjs    bottom_left_b = block_ptr;
1763fa225cbcSrjs    block_ptr += 64;
1764fa225cbcSrjs  }
1765fa225cbcSrjs
1766fa225cbcSrjs  bottom_right_b = &empty_block[0];
1767fa225cbcSrjs  if(cbp & 0x4) {
1768fa225cbcSrjs    bottom_right_b = block_ptr;
1769fa225cbcSrjs    block_ptr += 64;
1770fa225cbcSrjs  }
1771fa225cbcSrjs
1772fa225cbcSrjs  /* First Y Block */
1773fa225cbcSrjs  *dy++ = GFXBLOCK + 4 + (ysize>>2);
1774fa225cbcSrjs  *dy++ = (1<<30) | (2<<28) | dw1[0];
1775fa225cbcSrjs  *dy++ = xy;
1776fa225cbcSrjs  *dy++ = (8<<16) | 16;
1777fa225cbcSrjs  *dy++ = fmv.u[0];
1778fa225cbcSrjs  *dy++ = bmv.u[0];
1779fa225cbcSrjs  if(dw1[0] & (1<<27)) {
1780fa225cbcSrjs    PACK_CORR_DATA_0to1(dy,top_left_b,bottom_left_b);
1781fa225cbcSrjs  }
1782fa225cbcSrjs  if(dw1[0] & (1<<26)) {
1783fa225cbcSrjs    PACK_CORR_DATA_0to1(dy,top_right_b,bottom_right_b);
1784fa225cbcSrjs  }
1785fa225cbcSrjs
1786fa225cbcSrjs  /* Second Y Block */
1787fa225cbcSrjs  *dy++ = GFXBLOCK + 4 + (ysize>>2);
1788fa225cbcSrjs  *dy++ = (1<<30) | (2<<28) | dw1[1];
1789fa225cbcSrjs  *dy++ = xy;
1790fa225cbcSrjs  *dy++ = (8<<16) | 16;
1791fa225cbcSrjs  *dy++ = fmv.u[1];
1792fa225cbcSrjs  *dy++ = bmv.u[1];
1793fa225cbcSrjs  if(dw1[1] & (1<<27)) {
1794fa225cbcSrjs    top_left_b = (short *)((unsigned long)top_left_b + 16);
1795fa225cbcSrjs    bottom_left_b = (short *)((unsigned long)bottom_left_b + 16);
1796fa225cbcSrjs    PACK_CORR_DATA_0to1(dy,top_left_b,bottom_left_b);
1797fa225cbcSrjs  }
1798fa225cbcSrjs  if(dw1[1] & (1<<26)) {
1799fa225cbcSrjs    top_right_b = (short *)((unsigned long)top_right_b + 16);
1800fa225cbcSrjs    bottom_right_b = (short *)((unsigned long)bottom_right_b + 16);
1801fa225cbcSrjs    PACK_CORR_DATA_0to1(dy,top_right_b,bottom_right_b);
1802fa225cbcSrjs  }
1803fa225cbcSrjs  /* End Y Blocks */
1804fa225cbcSrjs
1805fa225cbcSrjs  fmv.s[0] /= 2;
1806fa225cbcSrjs  fmv.s[1] /= 2;
1807fa225cbcSrjs  fmv.s[2] /= 2;
1808fa225cbcSrjs  fmv.s[3] /= 2;
1809fa225cbcSrjs
1810fa225cbcSrjs  bmv.s[0] /= 2;
1811fa225cbcSrjs  bmv.s[1] /= 2;
1812fa225cbcSrjs  bmv.s[2] /= 2;
1813fa225cbcSrjs  bmv.s[3] /= 2;
1814fa225cbcSrjs
1815fa225cbcSrjs  xy >>= 1;
1816fa225cbcSrjs
1817fa225cbcSrjs  /* U Blocks */
1818fa225cbcSrjs  *du++ = GFXBLOCK + 4 + (usize>>2);
1819fa225cbcSrjs  *du++ = (2<<30) | (1<<28) | dw1[0];
1820fa225cbcSrjs  *du++ = xy;
1821fa225cbcSrjs  *du++ = (4<<16) | 8;
1822fa225cbcSrjs  *du++ = fmv.u[0];
1823fa225cbcSrjs  *du++ = bmv.u[0];
1824fa225cbcSrjs  if(usize) {
1825fa225cbcSrjs    PACK_CORR_DATA_SHORT(du,block_ptr);
1826fa225cbcSrjs  }
1827fa225cbcSrjs
1828fa225cbcSrjs  /* Second U Block */
1829fa225cbcSrjs  *du++ = GFXBLOCK + 4 + (usize>>2);
1830fa225cbcSrjs  *du++ = (2<<30) | (1<<28) | dw1[1];
1831fa225cbcSrjs  *du++ = xy;
1832fa225cbcSrjs  *du++ = (4<<16) | 8;
1833fa225cbcSrjs  *du++ = fmv.u[1];
1834fa225cbcSrjs  *du++ = bmv.u[1];
1835fa225cbcSrjs  if(usize) {
1836fa225cbcSrjs    block_ptr = (short *)((unsigned long)block_ptr + 16);
1837fa225cbcSrjs    PACK_CORR_DATA_SHORT(du,block_ptr);
1838fa225cbcSrjs    block_ptr = (short *)((unsigned long)block_ptr + 112);
1839fa225cbcSrjs  }
1840fa225cbcSrjs  /* End U Blocks */
1841fa225cbcSrjs
1842fa225cbcSrjs  /* V Blocks */
1843fa225cbcSrjs  *dv++ = GFXBLOCK + 4 + (vsize>>2);
1844fa225cbcSrjs  *dv++ = (3<<30) | (1<<28) | dw1[0];
1845fa225cbcSrjs  *dv++ = xy;
1846fa225cbcSrjs  *dv++ = (4<<16) | 8;
1847fa225cbcSrjs  *dv++ = fmv.u[0];
1848fa225cbcSrjs  *dv++ = bmv.u[0];
1849fa225cbcSrjs  if(vsize) {
1850fa225cbcSrjs    PACK_CORR_DATA_SHORT(dv,block_ptr);
1851fa225cbcSrjs  }
1852fa225cbcSrjs
1853fa225cbcSrjs  /* Second V Block */
1854fa225cbcSrjs  *dv++ = GFXBLOCK + 4 + (vsize>>2);
1855fa225cbcSrjs  *dv++ = (3<<30) | (1<<28) | dw1[1];
1856fa225cbcSrjs  *dv++ = xy;
1857fa225cbcSrjs  *dv++ = (4<<16) | 8;
1858fa225cbcSrjs  *dv++ = fmv.u[1];
1859fa225cbcSrjs  *dv++ = bmv.u[1];
1860fa225cbcSrjs  if(vsize) {
1861fa225cbcSrjs    block_ptr = (short *)((unsigned long)block_ptr + 16);
1862fa225cbcSrjs    PACK_CORR_DATA_SHORT(dv,block_ptr);
1863fa225cbcSrjs    block_ptr = (short *)((unsigned long)block_ptr + 112);
1864fa225cbcSrjs  }
1865fa225cbcSrjs  /* End V Blocks */
1866fa225cbcSrjs
1867fa225cbcSrjs  *datay = dy;
1868fa225cbcSrjs  *datau = du;
1869fa225cbcSrjs  *datav = dv;
1870fa225cbcSrjs}
1871fa225cbcSrjs
1872fa225cbcSrjs/***************************************************************************
1873fa225cbcSrjs// Function: renderFrameinFrame
1874fa225cbcSrjs// Description: inline function that sets hardware parameters for a Frame
1875fa225cbcSrjs//  encoded macroblock in a frame picture.
1876fa225cbcSrjs***************************************************************************/
1877fa225cbcSrjsstatic __inline__ void renderFrameinFrame(uint **datay,uint **datau,
1878fa225cbcSrjs					  uint **datav,
1879fa225cbcSrjs					  XvMCMacroBlock *mb,short *block_ptr,
1880fa225cbcSrjs					  uint flags) {
1881fa225cbcSrjs
1882fa225cbcSrjs  register uint *dy = *datay;
1883fa225cbcSrjs  register uint *du = *datau;
1884fa225cbcSrjs  register uint *dv = *datav;
1885fa225cbcSrjs
1886fa225cbcSrjs  /* Motion Vectors */
1887fa225cbcSrjs  su_t fmv;
1888fa225cbcSrjs  su_t bmv;
1889fa225cbcSrjs  /* gfxblock dword 1 */
1890fa225cbcSrjs  uint dw1;
1891fa225cbcSrjs
1892fa225cbcSrjs  unsigned int ysize = y_frame_bytes[mb->coded_block_pattern];
1893fa225cbcSrjs  unsigned int usize = u_frame_bytes[mb->coded_block_pattern];
1894fa225cbcSrjs  unsigned int vsize = v_frame_bytes[mb->coded_block_pattern];
1895fa225cbcSrjs
1896fa225cbcSrjs  uint xy = ((uint)mb->x<<20) | ((uint)mb->y<<4);
1897fa225cbcSrjs
1898fa225cbcSrjs  dw1 = type_table[mb->macroblock_type & 0xf] |
1899fa225cbcSrjs    (((uint)mb->coded_block_pattern)<<22);
1900fa225cbcSrjs
1901fa225cbcSrjs
1902fa225cbcSrjs  fmv.s[0] = mb->PMV[0][0][1];
1903fa225cbcSrjs  fmv.s[1] = mb->PMV[0][0][0];
1904fa225cbcSrjs
1905fa225cbcSrjs  bmv.s[0] = mb->PMV[0][1][1];
1906fa225cbcSrjs  bmv.s[1] = mb->PMV[0][1][0];
1907fa225cbcSrjs
1908fa225cbcSrjs  /* Y Block */
1909fa225cbcSrjs  *dy++ = GFXBLOCK + 4 + (ysize>>2);
1910fa225cbcSrjs  *dy++ = (1<<30) | (3<<28) | dw1;
1911fa225cbcSrjs  *dy++ = xy;
1912fa225cbcSrjs  *dy++ = (16<<16) | 16;
1913fa225cbcSrjs  *dy++ = fmv.u[0];
1914fa225cbcSrjs  *dy++ = bmv.u[0];
1915fa225cbcSrjs  PACK_CORR_DATA(dy,block_ptr,ysize);
1916fa225cbcSrjs  block_ptr = (short *)((unsigned long)block_ptr + ysize);
1917fa225cbcSrjs  /* End Y Blocks */
1918fa225cbcSrjs
1919fa225cbcSrjs  fmv.s[0] /= 2;
1920fa225cbcSrjs  fmv.s[1] /= 2;
1921fa225cbcSrjs
1922fa225cbcSrjs  bmv.s[0] /= 2;
1923fa225cbcSrjs  bmv.s[1] /= 2;
1924fa225cbcSrjs
1925fa225cbcSrjs  xy >>= 1;
1926fa225cbcSrjs
1927fa225cbcSrjs  /* U Block */
1928fa225cbcSrjs  *du++ = GFXBLOCK + 4 + (usize>>2);
1929fa225cbcSrjs  *du++ = (2<<30) | (1<<28) | dw1;
1930fa225cbcSrjs  *du++ = xy;
1931fa225cbcSrjs  *du++ = (8<<16) | 8;
1932fa225cbcSrjs  *du++ = fmv.u[0];
1933fa225cbcSrjs  *du++ = bmv.u[0];
1934fa225cbcSrjs  PACK_CORR_DATA(du,block_ptr,usize);
1935fa225cbcSrjs  block_ptr = (short *)((unsigned long)block_ptr + usize);
1936fa225cbcSrjs  /* End U Block */
1937fa225cbcSrjs
1938fa225cbcSrjs  /* V Block */
1939fa225cbcSrjs  *dv++ = GFXBLOCK + 4 + (vsize>>2);
1940fa225cbcSrjs  *dv++ = (3<<30) | (1<<28) | dw1;
1941fa225cbcSrjs  *dv++ = xy;
1942fa225cbcSrjs  *dv++ = (8<<16) | 8;
1943fa225cbcSrjs  *dv++ = fmv.u[0];
1944fa225cbcSrjs  *dv++ = bmv.u[0];
1945fa225cbcSrjs  PACK_CORR_DATA(dv,block_ptr,vsize);
1946fa225cbcSrjs  block_ptr = (short *)((unsigned long)block_ptr + vsize);
1947fa225cbcSrjs  /* End V Block */
1948fa225cbcSrjs
1949fa225cbcSrjs  *datay = dy;
1950fa225cbcSrjs  *datau = du;
1951fa225cbcSrjs  *datav = dv;
1952fa225cbcSrjs}
1953fa225cbcSrjs
1954fa225cbcSrjs/***************************************************************************
1955fa225cbcSrjs// Function: renderFrameinFrameDCT1
1956fa225cbcSrjs// Description: inline function that sets hardware parameters for a Frame
1957fa225cbcSrjs//  encoded macroblock in a frame picture with DCT type 1.
1958fa225cbcSrjs***************************************************************************/
1959fa225cbcSrjsstatic __inline__ void renderFrameinFrameDCT1(uint **datay,uint **datau,
1960fa225cbcSrjs					      uint **datav,XvMCMacroBlock *mb,
1961fa225cbcSrjs					      short *block_ptr,uint flags) {
1962fa225cbcSrjs
1963fa225cbcSrjs  register uint *dy = *datay;
1964fa225cbcSrjs  register uint *du = *datau;
1965fa225cbcSrjs  register uint *dv = *datav;
1966fa225cbcSrjs
1967fa225cbcSrjs  /* Motion Vectors */
1968fa225cbcSrjs  su_t fmv;
1969fa225cbcSrjs  su_t bmv;
1970fa225cbcSrjs
1971fa225cbcSrjs  short * top_left_b = NULL;
1972fa225cbcSrjs  short * top_right_b = NULL;
1973fa225cbcSrjs  short * bottom_left_b = NULL;
1974fa225cbcSrjs  short * bottom_right_b = NULL;
1975fa225cbcSrjs
1976fa225cbcSrjs  uint temp_bp = 0;
1977fa225cbcSrjs
1978fa225cbcSrjs  uint ysize = y_dct1_frame_bytes[mb->coded_block_pattern];
1979fa225cbcSrjs  uint usize = u_frame_bytes[mb->coded_block_pattern];
1980fa225cbcSrjs  uint vsize = v_frame_bytes[mb->coded_block_pattern];
1981fa225cbcSrjs
1982fa225cbcSrjs  uint xy = ((uint)mb->x<<20) | ((uint)mb->y<<4);
1983fa225cbcSrjs
1984fa225cbcSrjs  uint dw1 = type_table[mb->macroblock_type & 0xf] |
1985fa225cbcSrjs    (((uint)mb->coded_block_pattern)<<22);
1986fa225cbcSrjs
1987fa225cbcSrjs  fmv.s[0] = mb->PMV[0][0][1];
1988fa225cbcSrjs  fmv.s[1] = mb->PMV[0][0][0];
1989fa225cbcSrjs
1990fa225cbcSrjs  bmv.s[0] = mb->PMV[0][1][1];
1991fa225cbcSrjs  bmv.s[1] = mb->PMV[0][1][0];
1992fa225cbcSrjs
1993fa225cbcSrjs  /*
1994fa225cbcSrjs    It is easiest to find out what blocks are in need of reading first
1995fa225cbcSrjs    rather than as we go.
1996fa225cbcSrjs  */
1997fa225cbcSrjs  top_left_b = &empty_block[0];
1998fa225cbcSrjs  if(dw1 & (1<<27)) {
1999fa225cbcSrjs    temp_bp |= (1<<25);
2000fa225cbcSrjs    top_left_b = block_ptr;
2001fa225cbcSrjs    block_ptr += 64;
2002fa225cbcSrjs  }
2003fa225cbcSrjs
2004fa225cbcSrjs  top_right_b = &empty_block[0];
2005fa225cbcSrjs  if(dw1 & (1<<26)) {
2006fa225cbcSrjs    temp_bp |= (1<<24);
2007fa225cbcSrjs    top_right_b = block_ptr;
2008fa225cbcSrjs    block_ptr += 64;
2009fa225cbcSrjs  }
2010fa225cbcSrjs
2011fa225cbcSrjs  bottom_left_b = &empty_block[0];
2012fa225cbcSrjs  if(dw1 & (1<<25)) {
2013fa225cbcSrjs    temp_bp |= (1<<27);
2014fa225cbcSrjs    bottom_left_b = block_ptr;
2015fa225cbcSrjs    block_ptr += 64;
2016fa225cbcSrjs  }
2017fa225cbcSrjs
2018fa225cbcSrjs  bottom_right_b = &empty_block[0];
2019fa225cbcSrjs  if(dw1 & (1<<24)) {
2020fa225cbcSrjs    temp_bp |= (1<<26);
2021fa225cbcSrjs    bottom_right_b = block_ptr;
2022fa225cbcSrjs    block_ptr += 64;
2023fa225cbcSrjs  }
2024fa225cbcSrjs  dw1 |= temp_bp;
2025fa225cbcSrjs
2026fa225cbcSrjs  /* Y Block */
2027fa225cbcSrjs  *dy++ = GFXBLOCK + 4 + (ysize>>2);
2028fa225cbcSrjs  *dy++ = (1<<30) | (3<<28) | dw1;
2029fa225cbcSrjs  *dy++ = xy;
2030fa225cbcSrjs  *dy++ = (16<<16) | 16;
2031fa225cbcSrjs  *dy++ = fmv.u[0];
2032fa225cbcSrjs  *dy++ = bmv.u[0];
2033fa225cbcSrjs  if(dw1 & (1<<27)) {
2034fa225cbcSrjs    PACK_CORR_DATA_1to0(dy,top_left_b,bottom_left_b);
2035fa225cbcSrjs    top_left_b = (short *)((unsigned long)top_left_b + 64);
2036fa225cbcSrjs    bottom_left_b = (short *)((unsigned long)bottom_left_b + 64);
2037fa225cbcSrjs  }
2038fa225cbcSrjs  if(dw1 & (1<<26)) {
2039fa225cbcSrjs    PACK_CORR_DATA_1to0(dy,top_right_b,bottom_right_b);
2040fa225cbcSrjs    top_right_b = (short *)((unsigned long)top_right_b + 64);
2041fa225cbcSrjs    bottom_right_b = (short *)((unsigned long)bottom_right_b + 64);
2042fa225cbcSrjs  }
2043fa225cbcSrjs  if(dw1 & (1<<27)) {
2044fa225cbcSrjs    PACK_CORR_DATA_1to0(dy,top_left_b,bottom_left_b);
2045fa225cbcSrjs  }
2046fa225cbcSrjs  if(dw1 & (1<<26)) {
2047fa225cbcSrjs    PACK_CORR_DATA_1to0(dy,top_right_b,bottom_right_b);
2048fa225cbcSrjs  }
2049fa225cbcSrjs  /* End Y Block */
2050fa225cbcSrjs
2051fa225cbcSrjs  fmv.s[0] /= 2;
2052fa225cbcSrjs  fmv.s[1] /= 2;
2053fa225cbcSrjs
2054fa225cbcSrjs  bmv.s[0] /= 2;
2055fa225cbcSrjs  bmv.s[1] /= 2;
2056fa225cbcSrjs
2057fa225cbcSrjs  xy >>= 1;
2058fa225cbcSrjs
2059fa225cbcSrjs  /* U Block */
2060fa225cbcSrjs  *du++ = GFXBLOCK + 4 + (usize>>2);
2061fa225cbcSrjs  *du++ = (2<<30) | (1<<28) | dw1;
2062fa225cbcSrjs  *du++ = xy;
2063fa225cbcSrjs  *du++ = (8<<16) | 8;
2064fa225cbcSrjs  *du++ = fmv.u[0];
2065fa225cbcSrjs  *du++ = bmv.u[0];
2066fa225cbcSrjs  PACK_CORR_DATA(du,block_ptr,usize);
2067fa225cbcSrjs  block_ptr = (short *)((unsigned long)block_ptr + usize);
2068fa225cbcSrjs
2069fa225cbcSrjs  /* V Block */
2070fa225cbcSrjs  *dv++ = GFXBLOCK + 4 + (vsize>>2);
2071fa225cbcSrjs  *dv++ = (3<<30) | (1<<28) | dw1;
2072fa225cbcSrjs  *dv++ = xy;
2073fa225cbcSrjs  *dv++ = (8<<16) | 8;
2074fa225cbcSrjs  *dv++ = fmv.u[0];
2075fa225cbcSrjs  *dv++ = bmv.u[0];
2076fa225cbcSrjs  PACK_CORR_DATA(dv,block_ptr,vsize);
2077fa225cbcSrjs  block_ptr = (short *)((unsigned long)block_ptr + vsize);
2078fa225cbcSrjs
2079fa225cbcSrjs  *datay = dy;
2080fa225cbcSrjs  *datau = du;
2081fa225cbcSrjs  *datav = dv;
2082fa225cbcSrjs}
2083fa225cbcSrjs
2084fa225cbcSrjs/***************************************************************************
2085fa225cbcSrjs// Function: renderDualPrimeinFrame
2086fa225cbcSrjs// Description: inline function that sets hardware parameters for a Dual
2087fa225cbcSrjs//  Prime encoded macroblock in a frame picture with dct 1.
2088fa225cbcSrjs***************************************************************************/
2089fa225cbcSrjsstatic __inline__ void renderDualPrimeinFrame(uint **datay,uint **datau,
2090fa225cbcSrjs					      uint **datav,XvMCMacroBlock *mb,
2091fa225cbcSrjs					      short *block_ptr,uint flags) {
2092fa225cbcSrjs
2093fa225cbcSrjs  register uint *dy = *datay;
2094fa225cbcSrjs  register uint *du = *datau;
2095fa225cbcSrjs  register uint *dv = *datav;
2096fa225cbcSrjs
2097fa225cbcSrjs  /* Motion Vectors */
2098fa225cbcSrjs  su_t fmv;
2099fa225cbcSrjs  su_t bmv;
2100fa225cbcSrjs  /* gfxblock dword 1 */
2101fa225cbcSrjs  uint dw1[2];
2102fa225cbcSrjs
2103fa225cbcSrjs  uint y1size = y_first_field_bytes[mb->coded_block_pattern];
2104fa225cbcSrjs  uint y2size = y_second_field_bytes[mb->coded_block_pattern];
2105fa225cbcSrjs  uint usize = u_field_bytes[mb->coded_block_pattern];
2106fa225cbcSrjs  uint vsize = v_field_bytes[mb->coded_block_pattern];
2107fa225cbcSrjs
2108fa225cbcSrjs  uint xy = ((uint)mb->x<<20) | ((uint)mb->y<<3);
2109fa225cbcSrjs
2110fa225cbcSrjs  /*
2111fa225cbcSrjs    Past Surface (map 0) is used for same parity prediction,
2112fa225cbcSrjs    Future surface (map 1) is used for opposite.
2113fa225cbcSrjs  */
2114fa225cbcSrjs  dw1[0] = (((uint)mb->coded_block_pattern)<<22) |
2115fa225cbcSrjs    3<<12 | 2<<6 | 2<<3 | 3;
2116fa225cbcSrjs  dw1[1] = (((mb->coded_block_pattern & 0x3) |
2117fa225cbcSrjs	     ((mb->coded_block_pattern & 0xc)<<2))<<22) |
2118fa225cbcSrjs    3<<12 | 3<<6 | 3<<3 | 2;
2119fa225cbcSrjs
2120fa225cbcSrjs  fmv.s[0] = mb->PMV[0][0][1];
2121fa225cbcSrjs  fmv.s[1] = mb->PMV[0][0][0];
2122fa225cbcSrjs  bmv.s[0] = mb->PMV[1][0][1];
2123fa225cbcSrjs  bmv.s[1] = mb->PMV[1][0][0];
2124fa225cbcSrjs
2125fa225cbcSrjs  fmv.s[2] = mb->PMV[0][0][1];
2126fa225cbcSrjs  fmv.s[3] = mb->PMV[0][0][0];
2127fa225cbcSrjs  bmv.s[2] = mb->PMV[1][1][1];
2128fa225cbcSrjs  bmv.s[3] = mb->PMV[1][1][0];
2129fa225cbcSrjs
2130fa225cbcSrjs  /* First Y Block */
2131fa225cbcSrjs  *dy++ = GFXBLOCK + 4 + (y1size>>2);
2132fa225cbcSrjs  *dy++ = (1<<30) | (2<<28) | dw1[0];
2133fa225cbcSrjs  *dy++ = xy;
2134fa225cbcSrjs  *dy++ = (8<<16) | 16;
2135fa225cbcSrjs  *dy++ = fmv.u[0];
2136fa225cbcSrjs  *dy++ = bmv.u[0];;
2137fa225cbcSrjs  PACK_CORR_DATA(dy,block_ptr,y1size);
2138fa225cbcSrjs  block_ptr = (short *)((unsigned long)block_ptr + y1size);
2139fa225cbcSrjs
2140fa225cbcSrjs  /* Second Y Block */
2141fa225cbcSrjs  *dy++ = GFXBLOCK + 4 + (y2size>>2);
2142fa225cbcSrjs  *dy++ = (1<<30) | (2<<28) | dw1[1];
2143fa225cbcSrjs  *dy++ = xy;
2144fa225cbcSrjs  *dy++ = (8<<16) | 16;
2145fa225cbcSrjs  *dy++ = fmv.u[1];
2146fa225cbcSrjs  *dy++ = bmv.u[1];
2147fa225cbcSrjs  PACK_CORR_DATA(dy,block_ptr,y2size);
2148fa225cbcSrjs  block_ptr = (short *)((unsigned long)block_ptr + y2size);
2149fa225cbcSrjs
2150fa225cbcSrjs  fmv.s[0] /= 2;
2151fa225cbcSrjs  fmv.s[1] /= 2;
2152fa225cbcSrjs  bmv.s[0] /= 2;
2153fa225cbcSrjs  bmv.s[1] /= 2;
2154fa225cbcSrjs
2155fa225cbcSrjs  fmv.s[2] /= 2;
2156fa225cbcSrjs  fmv.s[3] /= 2;
2157fa225cbcSrjs  bmv.s[2] /= 2;
2158fa225cbcSrjs  bmv.s[3] /= 2;
2159fa225cbcSrjs
2160fa225cbcSrjs  xy >>= 1;
2161fa225cbcSrjs
2162fa225cbcSrjs  /* U Blocks */
2163fa225cbcSrjs  *du++ = GFXBLOCK + 4 + (usize>>2);
2164fa225cbcSrjs  *du++ = (2<<30) | (1<<28) | dw1[0];
2165fa225cbcSrjs  *du++ = xy;
2166fa225cbcSrjs  *du++ = (4<<16) | 8;
2167fa225cbcSrjs  *du++ = fmv.u[0];
2168fa225cbcSrjs  *du++ = bmv.u[0];
2169fa225cbcSrjs  if(dw1[0] & (1<<23)) {
2170fa225cbcSrjs    PACK_CORR_DATA_SHORT(du,block_ptr);
2171fa225cbcSrjs  }
2172fa225cbcSrjs
2173fa225cbcSrjs  /* Second U Block */
2174fa225cbcSrjs  *du++ = GFXBLOCK + 4 + (usize>>2);
2175fa225cbcSrjs  *du++ = (2<<30) | (1<<28) | dw1[1];
2176fa225cbcSrjs  *du++ = xy;
2177fa225cbcSrjs  *du++ = (4<<16) | 8;
2178fa225cbcSrjs  *du++ = fmv.u[1];
2179fa225cbcSrjs  *du++ = bmv.u[1];
2180fa225cbcSrjs  if(dw1[1] & (1<<23)) {
2181fa225cbcSrjs    block_ptr = (short *)((unsigned long)block_ptr + 16);
2182fa225cbcSrjs    PACK_CORR_DATA_SHORT(du,block_ptr);
2183fa225cbcSrjs    block_ptr = (short *)((unsigned long)block_ptr + 112);
2184fa225cbcSrjs  }
2185fa225cbcSrjs  /* End U Blocks */
2186fa225cbcSrjs
2187fa225cbcSrjs  /* V Blocks */
2188fa225cbcSrjs  *dv++ = GFXBLOCK + 4 + (vsize>>2);
2189fa225cbcSrjs  *dv++ = (3<<30) | (1<<28) | dw1[0];
2190fa225cbcSrjs  *dv++ = xy;
2191fa225cbcSrjs  *dv++ = (4<<16) | 8;
2192fa225cbcSrjs  *dv++ = fmv.u[0];
2193fa225cbcSrjs  *dv++ = bmv.u[0];
2194fa225cbcSrjs  if(dw1[0] & (1<<22)) {
2195fa225cbcSrjs    PACK_CORR_DATA_SHORT(dv,block_ptr);
2196fa225cbcSrjs  }
2197fa225cbcSrjs
2198fa225cbcSrjs  /* Second V Block */
2199fa225cbcSrjs  *dv++ = GFXBLOCK + 4 + (vsize>>2);
2200fa225cbcSrjs  *dv++ = (3<<30) | (1<<28) | dw1[1];
2201fa225cbcSrjs  *dv++ = xy;
2202fa225cbcSrjs  *dv++ = (4<<16) | 8;
2203fa225cbcSrjs  *dv++ = fmv.u[1];
2204fa225cbcSrjs  *dv++ = bmv.u[1];
2205fa225cbcSrjs  if(dw1[1] & (1<<22)) {
2206fa225cbcSrjs    block_ptr = (short *)((unsigned long)block_ptr + 16);
2207fa225cbcSrjs    PACK_CORR_DATA_SHORT(dv,block_ptr);
2208fa225cbcSrjs    block_ptr = (short *)((unsigned long)block_ptr + 112);
2209fa225cbcSrjs  }
2210fa225cbcSrjs  /* End V Blocks */
2211fa225cbcSrjs
2212fa225cbcSrjs  *datay = dy;
2213fa225cbcSrjs  *datau = du;
2214fa225cbcSrjs  *datav = dv;
2215fa225cbcSrjs}
2216fa225cbcSrjs
2217fa225cbcSrjs/***************************************************************************
2218fa225cbcSrjs// Function: renderDualPrimeinFrameDCT0
2219fa225cbcSrjs// Description: inline function that sets hardware parameters for a Dual
2220fa225cbcSrjs//  Prime encoded macroblock in a frame picture with dct 0.
2221fa225cbcSrjs***************************************************************************/
2222fa225cbcSrjsstatic __inline__ void renderDualPrimeinFrameDCT0(uint **datay,uint **datau,
2223fa225cbcSrjs						  uint **datav,
2224fa225cbcSrjs						  XvMCMacroBlock *mb,
2225fa225cbcSrjs						  short *block_ptr,
2226fa225cbcSrjs						  uint flags) {
2227fa225cbcSrjs
2228fa225cbcSrjs  register uint *dy = *datay;
2229fa225cbcSrjs  register uint *du = *datau;
2230fa225cbcSrjs  register uint *dv = *datav;
2231fa225cbcSrjs
2232fa225cbcSrjs  /* Motion Vectors */
2233fa225cbcSrjs  su_t fmv;
2234fa225cbcSrjs  su_t bmv;
2235fa225cbcSrjs  /* gfxblock dword 1 */
2236fa225cbcSrjs  uint dw1[2];
2237fa225cbcSrjs
2238fa225cbcSrjs  short * top_left_b = NULL;
2239fa225cbcSrjs  short * top_right_b = NULL;
2240fa225cbcSrjs  short * bottom_left_b = NULL;
2241fa225cbcSrjs  short * bottom_right_b = NULL;
2242fa225cbcSrjs
2243fa225cbcSrjs  uint cbp = (uint)mb->coded_block_pattern;
2244fa225cbcSrjs
2245fa225cbcSrjs  uint ysize = y_dct0_field_bytes[cbp];
2246fa225cbcSrjs  uint usize = u_field_bytes[cbp];
2247fa225cbcSrjs  uint vsize = v_field_bytes[cbp];
2248fa225cbcSrjs
2249fa225cbcSrjs  uint xy = ((uint)mb->x<<20) | ((uint)mb->y<<3);
2250fa225cbcSrjs
2251fa225cbcSrjs  /*
2252fa225cbcSrjs    Past Surface (map 0) is used for same parity prediction,
2253fa225cbcSrjs    Future surface (map 1) is used for opposite.
2254fa225cbcSrjs  */
2255fa225cbcSrjs  dw1[0] = ((cbp | ((cbp<<2) & 0x30))<<22) |
2256fa225cbcSrjs    3<<12 | 2<<6 | 2<<3 | 3;
2257fa225cbcSrjs  dw1[1] = ((cbp | ((cbp<<2) & 0x30))<<22) |
2258fa225cbcSrjs    3<<12 | 3<<6 | 3<<3 | 2;
2259fa225cbcSrjs
2260fa225cbcSrjs  fmv.s[0] = mb->PMV[0][0][1];
2261fa225cbcSrjs  fmv.s[1] = mb->PMV[0][0][0];
2262fa225cbcSrjs  bmv.s[0] = mb->PMV[1][0][1];
2263fa225cbcSrjs  bmv.s[1] = mb->PMV[1][0][0];
2264fa225cbcSrjs
2265fa225cbcSrjs  fmv.s[2] = mb->PMV[0][0][1];
2266fa225cbcSrjs  fmv.s[3] = mb->PMV[0][0][0];
2267fa225cbcSrjs  bmv.s[2] = mb->PMV[1][1][1];
2268fa225cbcSrjs  bmv.s[3] = mb->PMV[1][1][0];
2269fa225cbcSrjs
2270fa225cbcSrjs  /*
2271fa225cbcSrjs    The i810 cannot use DCT0 directly with field motion, we have to
2272fa225cbcSrjs    interlace the data for it. We use a zero block when the CBP has
2273fa225cbcSrjs    one half of the to-be-interlaced data but not the other half.
2274fa225cbcSrjs  */
2275fa225cbcSrjs  top_left_b = &empty_block[0];
2276fa225cbcSrjs  if(cbp & 0x20) {
2277fa225cbcSrjs    top_left_b = block_ptr;
2278fa225cbcSrjs    block_ptr += 64;
2279fa225cbcSrjs  }
2280fa225cbcSrjs
2281fa225cbcSrjs  top_right_b = &empty_block[0];
2282fa225cbcSrjs  if(cbp & 0x10) {
2283fa225cbcSrjs    top_right_b = block_ptr;
2284fa225cbcSrjs    block_ptr += 64;
2285fa225cbcSrjs  }
2286fa225cbcSrjs
2287fa225cbcSrjs  bottom_left_b = &empty_block[0];
2288fa225cbcSrjs  if(cbp & 0x8) {
2289fa225cbcSrjs    bottom_left_b = block_ptr;
2290fa225cbcSrjs    block_ptr += 64;
2291fa225cbcSrjs  }
2292fa225cbcSrjs
2293fa225cbcSrjs  bottom_right_b = &empty_block[0];
2294fa225cbcSrjs  if(cbp & 0x4) {
2295fa225cbcSrjs    bottom_right_b = block_ptr;
2296fa225cbcSrjs    block_ptr += 64;
2297fa225cbcSrjs  }
2298fa225cbcSrjs
2299fa225cbcSrjs  /* First Y Block */
2300fa225cbcSrjs  *dy++ = GFXBLOCK + 4 + (ysize>>2);
2301fa225cbcSrjs  *dy++ = (1<<30) | (2<<28) | dw1[0];
2302fa225cbcSrjs  *dy++ = xy;
2303fa225cbcSrjs  *dy++ = (8<<16) | 16;
2304fa225cbcSrjs  *dy++ = fmv.u[0];
2305fa225cbcSrjs  *dy++ = bmv.u[0];
2306fa225cbcSrjs  if(cbp & 0x20) {
2307fa225cbcSrjs    PACK_CORR_DATA_0to1(dy,top_left_b,bottom_left_b);
2308fa225cbcSrjs  }
2309fa225cbcSrjs  if(cbp & 0x10) {
2310fa225cbcSrjs    PACK_CORR_DATA_0to1(dy,top_right_b,bottom_right_b);
2311fa225cbcSrjs  }
2312fa225cbcSrjs
2313fa225cbcSrjs  /* Second Y Block */
2314fa225cbcSrjs  *dy++ = GFXBLOCK + 4 + (ysize>>2);
2315fa225cbcSrjs  *dy++ = (1<<30) | (2<<28) | dw1[1];
2316fa225cbcSrjs  *dy++ = xy;
2317fa225cbcSrjs  *dy++ = (8<<16) | 16;
2318fa225cbcSrjs  *dy++ = fmv.u[1];
2319fa225cbcSrjs  *dy++ = bmv.u[1];
2320fa225cbcSrjs  if(cbp & 0x20) {
2321fa225cbcSrjs    top_left_b = (short *)((unsigned long)top_left_b + 16);
2322fa225cbcSrjs    bottom_left_b = (short *)((unsigned long)bottom_left_b + 16);
2323fa225cbcSrjs    PACK_CORR_DATA_0to1(dy,top_left_b,bottom_left_b);
2324fa225cbcSrjs  }
2325fa225cbcSrjs  if(cbp & 0x10) {
2326fa225cbcSrjs    top_right_b = (short *)((unsigned long)top_right_b + 16);
2327fa225cbcSrjs    bottom_right_b = (short *)((unsigned long)bottom_right_b + 16);
2328fa225cbcSrjs    PACK_CORR_DATA_0to1(dy,top_right_b,bottom_right_b);
2329fa225cbcSrjs  }
2330fa225cbcSrjs  /* End Y Blocks */
2331fa225cbcSrjs
2332fa225cbcSrjs
2333fa225cbcSrjs  fmv.s[0] /= 2;
2334fa225cbcSrjs  fmv.s[1] /= 2;
2335fa225cbcSrjs  bmv.s[0] /= 2;
2336fa225cbcSrjs  bmv.s[1] /= 2;
2337fa225cbcSrjs
2338fa225cbcSrjs  fmv.s[2] /= 2;
2339fa225cbcSrjs  fmv.s[3] /= 2;
2340fa225cbcSrjs  bmv.s[2] /= 2;
2341fa225cbcSrjs  bmv.s[3] /= 2;
2342fa225cbcSrjs
2343fa225cbcSrjs  xy >>= 1;
2344fa225cbcSrjs
2345fa225cbcSrjs  /* U Blocks */
2346fa225cbcSrjs  *du++ = GFXBLOCK + 4 + (usize>>2);
2347fa225cbcSrjs  *du++ = (2<<30) | (1<<28) | dw1[0];
2348fa225cbcSrjs  *du++ = xy;
2349fa225cbcSrjs  *du++ = (4<<16) | 8;
2350fa225cbcSrjs  *du++ = fmv.u[0];
2351fa225cbcSrjs  *du++ = bmv.u[0];
2352fa225cbcSrjs  if(cbp & (1<<23)) {
2353fa225cbcSrjs    PACK_CORR_DATA_SHORT(du,block_ptr);
2354fa225cbcSrjs  }
2355fa225cbcSrjs
2356fa225cbcSrjs  /* Second U Block */
2357fa225cbcSrjs  *du++ = GFXBLOCK + 4 + (usize>>2);
2358fa225cbcSrjs  *du++ = (2<<30) | (1<<28) | dw1[1];
2359fa225cbcSrjs  *du++ = xy;
2360fa225cbcSrjs  *du++ = (4<<16) | 8;
2361fa225cbcSrjs  *du++ = fmv.u[1];
2362fa225cbcSrjs  *du++ = bmv.u[1];
2363fa225cbcSrjs  if(cbp & (1<<23)) {
2364fa225cbcSrjs    block_ptr = (short *)((unsigned long)block_ptr + 16);
2365fa225cbcSrjs    PACK_CORR_DATA_SHORT(du,block_ptr);
2366fa225cbcSrjs    block_ptr = (short *)((unsigned long)block_ptr + 112);
2367fa225cbcSrjs  }
2368fa225cbcSrjs  /* End U Blocks */
2369fa225cbcSrjs
2370fa225cbcSrjs  /* V Blocks */
2371fa225cbcSrjs  *dv++ = GFXBLOCK + 4 + (vsize>>2);
2372fa225cbcSrjs  *dv++ = (3<<30) | (1<<28) | dw1[0];
2373fa225cbcSrjs  *dv++ = xy;
2374fa225cbcSrjs  *dv++ = (4<<16) | 8;
2375fa225cbcSrjs  *dv++ = fmv.u[0];
2376fa225cbcSrjs  *dv++ = bmv.u[0];
2377fa225cbcSrjs  if(cbp & (1<<22)) {
2378fa225cbcSrjs    PACK_CORR_DATA_SHORT(dv,block_ptr);
2379fa225cbcSrjs  }
2380fa225cbcSrjs
2381fa225cbcSrjs  /* Second V Block */
2382fa225cbcSrjs  *dv++ = GFXBLOCK + 4 + (vsize>>2);
2383fa225cbcSrjs  *dv++ = (3<<30) | (1<<28) | dw1[1];
2384fa225cbcSrjs  *dv++ = xy;
2385fa225cbcSrjs  *dv++ = (4<<16) | 8;
2386fa225cbcSrjs  *dv++ = fmv.u[1];
2387fa225cbcSrjs  *dv++ = bmv.u[1];
2388fa225cbcSrjs  if(cbp & (1<<22)) {
2389fa225cbcSrjs    block_ptr = (short *)((unsigned long)block_ptr + 16);
2390fa225cbcSrjs    PACK_CORR_DATA_SHORT(dv,block_ptr);
2391fa225cbcSrjs    block_ptr = (short *)((unsigned long)block_ptr + 112);
2392fa225cbcSrjs  }
2393fa225cbcSrjs  /* End V Blocks */
2394fa225cbcSrjs
2395fa225cbcSrjs  *datay = dy;
2396fa225cbcSrjs  *datau = du;
2397fa225cbcSrjs  *datav = dv;
2398fa225cbcSrjs}
2399fa225cbcSrjs
2400fa225cbcSrjs
2401fa225cbcSrjs/***************************************************************************
2402fa225cbcSrjs// Function: XvMCRenderSurface
2403fa225cbcSrjs// Description: This function does the actual HWMC. Given a list of
2404fa225cbcSrjs//  macroblock structures it dispatched the hardware commands to execute
2405fa225cbcSrjs//  them. DMA buffer containing Y data are dispatched as they fill up
2406fa225cbcSrjs//  U and V DMA buffers are queued until all Y's are done. This minimizes
2407fa225cbcSrjs//  the context flipping and flushing required when switching between Y
2408fa225cbcSrjs//  U and V surfaces.
2409fa225cbcSrjs***************************************************************************/
2410fa225cbcSrjs#define UV_QUEUE 14
2411fa225cbcSrjs_X_EXPORT Status XvMCRenderSurface(Display *display, XvMCContext *context,
2412fa225cbcSrjs			 unsigned int picture_structure,
2413fa225cbcSrjs			 XvMCSurface *target_surface,
2414fa225cbcSrjs			 XvMCSurface *past_surface,
2415fa225cbcSrjs			 XvMCSurface *future_surface,
2416fa225cbcSrjs			 unsigned int flags,
2417fa225cbcSrjs			 unsigned int num_macroblocks,
2418fa225cbcSrjs			 unsigned int first_macroblock,
2419fa225cbcSrjs			 XvMCMacroBlockArray *macroblock_array,
2420fa225cbcSrjs			 XvMCBlockArray *blocks) {
2421fa225cbcSrjs  /* Dma Data Structures */
2422fa225cbcSrjs  drmBufPtr pDMAy = NULL,pDMAu[UV_QUEUE],pDMAv[UV_QUEUE];
2423fa225cbcSrjs  int u_index = 0,v_index = 0;
2424fa225cbcSrjs  int dirty_context = 1;
2425fa225cbcSrjs
2426fa225cbcSrjs  /* Block Pointer */
2427fa225cbcSrjs  short *block_ptr;
2428fa225cbcSrjs  /* Current Macroblock Pointer */
2429fa225cbcSrjs  XvMCMacroBlock *mb;
2430fa225cbcSrjs
2431fa225cbcSrjs  drm_i810_mc_t mc;
2432fa225cbcSrjs  int i,j;
2433fa225cbcSrjs  i810XvMCSurface *privTarget;
2434fa225cbcSrjs  i810XvMCSurface *privFuture = NULL;
2435fa225cbcSrjs  i810XvMCSurface *privPast = NULL;
2436fa225cbcSrjs  i810XvMCContext *pI810XvMC;
2437fa225cbcSrjs
2438fa225cbcSrjs  /* DMA Pointers set to NULL */
2439fa225cbcSrjs  uint *datay = NULL;
2440fa225cbcSrjs  uint *datau = NULL;
2441fa225cbcSrjs  uint *datav = NULL;
2442fa225cbcSrjs
2443fa225cbcSrjs
2444fa225cbcSrjs  /* Check Parameters for validity */
2445fa225cbcSrjs  if((target_surface == NULL) || (context == NULL) || (display == NULL)) {
2446fa225cbcSrjs    printf("Error, Invalid Target,Context, or DIsplay!\n");
2447fa225cbcSrjs    return BadValue;
2448fa225cbcSrjs  }
2449fa225cbcSrjs
2450fa225cbcSrjs  if(num_macroblocks == 0) {return Success;}
2451fa225cbcSrjs  if((macroblock_array == NULL) || (blocks == NULL)) {return BadValue;}
2452fa225cbcSrjs  if(context->privData == NULL) {return BadValue;}
2453fa225cbcSrjs  pI810XvMC = (i810XvMCContext *)context->privData;
2454fa225cbcSrjs
2455fa225cbcSrjs
2456fa225cbcSrjs  if(target_surface->privData == NULL) {
2457fa225cbcSrjs    printf("Error, Invalid Target Surface!\n");
2458fa225cbcSrjs    return BadValue;
2459fa225cbcSrjs  }
2460fa225cbcSrjs  privTarget = (i810XvMCSurface *)target_surface->privData;
2461fa225cbcSrjs
2462fa225cbcSrjs  if(macroblock_array->num_blocks < (num_macroblocks + first_macroblock)) {
2463fa225cbcSrjs    printf("Error, Too many macroblocks requested for MB array size.\n");
2464fa225cbcSrjs    return BadValue;
2465fa225cbcSrjs  }
2466fa225cbcSrjs
2467fa225cbcSrjs  /* Test For YV12 Surface */
2468fa225cbcSrjs  if(context->surface_type_id != FOURCC_YV12) {
2469fa225cbcSrjs    printf("Error, HWMC only possible on YV12 Surfaces\n");
2470fa225cbcSrjs    return BadValue;
2471fa225cbcSrjs  }
2472fa225cbcSrjs
2473fa225cbcSrjs  /* P Frame Test */
2474fa225cbcSrjs  if(past_surface == NULL) {
2475fa225cbcSrjs    /* Just to avoid some ifs later. */
2476fa225cbcSrjs    privPast = privTarget;
2477fa225cbcSrjs  }
2478fa225cbcSrjs  else {
2479fa225cbcSrjs    if(past_surface->privData == NULL) {
2480fa225cbcSrjs      printf("Error, Invalid Past Surface!\n");
2481fa225cbcSrjs      return BadValue;
2482fa225cbcSrjs    }
2483fa225cbcSrjs    privPast = (i810XvMCSurface *)past_surface->privData;
2484fa225cbcSrjs  }
2485fa225cbcSrjs
2486fa225cbcSrjs
2487fa225cbcSrjs  /* B Frame Test */
2488fa225cbcSrjs  if(future_surface == NULL) {
2489fa225cbcSrjs    privFuture = privTarget;
2490fa225cbcSrjs    if(pI810XvMC->dual_prime) {
2491fa225cbcSrjs      privFuture = privPast;
2492fa225cbcSrjs      /* I810 Specific flag for marking when dual prime is in use. */
2493fa225cbcSrjs      flags |= 0x40000000;
2494fa225cbcSrjs    }
2495fa225cbcSrjs
2496fa225cbcSrjs    /*
2497fa225cbcSrjs      References are different for the Second Field Picture. The
2498fa225cbcSrjs      i810 needs to know if it is the second field picture in a
2499fa225cbcSrjs      P picture. We use a Private flag to mark this.
2500fa225cbcSrjs    */
2501fa225cbcSrjs    if(flags & XVMC_SECOND_FIELD) {
2502fa225cbcSrjs      /* I810 Specific flag for marking second fields. */
2503fa225cbcSrjs      flags |= 0x80000000;
2504fa225cbcSrjs    }
2505fa225cbcSrjs  }
2506fa225cbcSrjs  else {
2507fa225cbcSrjs    if((future_surface->privData == NULL) || (past_surface == NULL)) {
2508fa225cbcSrjs      printf("Error, Invalid Future Surface or No Past Surface!\n");
2509fa225cbcSrjs      return BadValue;
2510fa225cbcSrjs    }
2511fa225cbcSrjs    privFuture = (i810XvMCSurface *)future_surface->privData;
2512fa225cbcSrjs
2513fa225cbcSrjs    /*
2514fa225cbcSrjs      Undo Second Field flag since the second field in B frames is just like
2515fa225cbcSrjs      the first.
2516fa225cbcSrjs    */
2517fa225cbcSrjs    flags &= ~0x80000000;
2518fa225cbcSrjs  }
2519fa225cbcSrjs
2520fa225cbcSrjs  /* Lock For DMA */
2521fa225cbcSrjs  I810_LOCK(pI810XvMC,0);
2522fa225cbcSrjs
2523fa225cbcSrjs  for(i=first_macroblock; i<(num_macroblocks + first_macroblock); i++) {
2524fa225cbcSrjs    /* Set up values needed for each macroblock */
2525fa225cbcSrjs    mb = &macroblock_array->macro_blocks[i];
2526fa225cbcSrjs    block_ptr = &(blocks->blocks[mb->index<<6]);
2527fa225cbcSrjs
2528fa225cbcSrjs    /* Lockup can happen if the coordinates are too far out of range */
2529fa225cbcSrjs    if(mb->x > target_surface->width>>4) {
2530fa225cbcSrjs      mb->x = 0;
2531fa225cbcSrjs    }
2532fa225cbcSrjs    if(mb->y > target_surface->height>>4) {
2533fa225cbcSrjs      mb->y = 0;
2534fa225cbcSrjs    }
2535fa225cbcSrjs
2536fa225cbcSrjs    /* If buffers are almost full dispatch them */
2537fa225cbcSrjs    if(datay) {
2538fa225cbcSrjs      pDMAy->used = (unsigned long)datay - (unsigned long)pDMAy->address;
2539fa225cbcSrjs      if(pDMAy->used  > 3520) {
2540fa225cbcSrjs	if(dirty_context) {
2541fa225cbcSrjs	  dispatchYContext(privTarget,privPast,privFuture,pI810XvMC);
2542fa225cbcSrjs	}
2543fa225cbcSrjs	dirty_context = 0;
2544fa225cbcSrjs	mc.idx = pDMAy->idx;
2545fa225cbcSrjs	mc.used = pDMAy->used;
2546fa225cbcSrjs	datay = NULL;
2547fa225cbcSrjs	mc.last_render = ++pI810XvMC->last_render;
2548fa225cbcSrjs	privTarget->last_render = pI810XvMC->last_render;
2549fa225cbcSrjs	I810_MC(pI810XvMC,mc);
2550fa225cbcSrjs      } /* datay near full */
2551fa225cbcSrjs    } /* if(datay) */
2552fa225cbcSrjs    if(datau) {
2553fa225cbcSrjs      pDMAu[u_index]->used = (unsigned long)datau - (unsigned long)pDMAu[u_index]->address;
2554fa225cbcSrjs      if(pDMAu[u_index]->used > 3904) {
2555fa225cbcSrjs	u_index++;
2556fa225cbcSrjs	datau = NULL;
2557fa225cbcSrjs	if(u_index == UV_QUEUE) {
2558fa225cbcSrjs	  for(j=0; j<UV_QUEUE; j++) {
2559fa225cbcSrjs	    mc.idx = pDMAu[j]->idx;
2560fa225cbcSrjs	    mc.used = pDMAu[j]->used;
2561fa225cbcSrjs	    mc.last_render = ++pI810XvMC->last_render;
2562fa225cbcSrjs	    privTarget->last_render = pI810XvMC->last_render;
2563fa225cbcSrjs	    I810_MC(pI810XvMC,mc);
2564fa225cbcSrjs	  }
2565fa225cbcSrjs	  u_index = 0;
2566fa225cbcSrjs	  dirty_context = 1;
2567fa225cbcSrjs	} /* if(u_index == UV_QUEUE) */
2568fa225cbcSrjs      } /* datau near full */
2569fa225cbcSrjs    } /* if(datau) */
2570fa225cbcSrjs    if(datav) {
2571fa225cbcSrjs      pDMAv[v_index]->used = (unsigned long)datav - (unsigned long)pDMAv[v_index]->address;
2572fa225cbcSrjs      if(pDMAv[v_index]->used > 3904) {
2573fa225cbcSrjs	v_index++;
2574fa225cbcSrjs	datav = NULL;
2575fa225cbcSrjs	if(v_index == UV_QUEUE) {
2576fa225cbcSrjs	  for(j=0; j<UV_QUEUE; j++) {
2577fa225cbcSrjs	    mc.idx = pDMAv[j]->idx;
2578fa225cbcSrjs	    mc.used = pDMAv[j]->used;
2579fa225cbcSrjs	    mc.last_render = ++pI810XvMC->last_render;
2580fa225cbcSrjs	    privTarget->last_render = pI810XvMC->last_render;
2581fa225cbcSrjs	    I810_MC(pI810XvMC,mc);
2582fa225cbcSrjs	  }
2583fa225cbcSrjs	  v_index = 0;
2584fa225cbcSrjs	  dirty_context = 1;
2585fa225cbcSrjs	} /* if(v_index == UV_QUEUE) */
2586fa225cbcSrjs      } /* datav near full */
2587fa225cbcSrjs    } /* if(datav) */
2588fa225cbcSrjs
2589fa225cbcSrjs    /* Allocate buffers if this is the first loop,or if we just dispatched */
2590fa225cbcSrjs    if(datay == NULL) {
2591fa225cbcSrjs      pDMAy = i810_get_free_buffer(pI810XvMC);
2592fa225cbcSrjs      datay = pDMAy->address;
2593fa225cbcSrjs    }/* if(datay == NULL) */
2594fa225cbcSrjs    if(datau == NULL) {
2595fa225cbcSrjs      pDMAu[u_index] = i810_get_free_buffer(pI810XvMC);
2596fa225cbcSrjs      datau = pDMAu[u_index]->address;
2597fa225cbcSrjs      if(u_index == 0) {
2598fa225cbcSrjs	*datau++ = CMD_FLUSH;
2599fa225cbcSrjs	*datau++ = BOOLEAN_ENA_2;
2600fa225cbcSrjs	*datau++ = CMD_FLUSH;
2601fa225cbcSrjs	*datau++ = DEST_BUFFER_INFO;
2602fa225cbcSrjs	*datau++ = privTarget->dbi1u;
2603fa225cbcSrjs	*datau++ = DEST_BUFFER_VAR;
2604fa225cbcSrjs	*datau++ = privTarget->dbv1;
2605fa225cbcSrjs	/* Past Surface */
2606fa225cbcSrjs	*datau++ = CMD_MAP_INFO;
2607fa225cbcSrjs	*datau++ = privPast->mi1u;
2608fa225cbcSrjs	*datau++ = privPast->mi2u;
2609fa225cbcSrjs	*datau++ = privPast->mi3u;
2610fa225cbcSrjs	/* Future Surface */
2611fa225cbcSrjs	*datau++ = CMD_MAP_INFO;
2612fa225cbcSrjs	*datau++ = privFuture->mi1u | 0x1<<28;
2613fa225cbcSrjs	*datau++ = privFuture->mi2u;
2614fa225cbcSrjs	*datau++ = privFuture->mi3u;
2615fa225cbcSrjs      }
2616fa225cbcSrjs    } /* if(datau == NULL) */
2617fa225cbcSrjs    if(datav == NULL) {
2618fa225cbcSrjs      pDMAv[v_index] = i810_get_free_buffer(pI810XvMC);
2619fa225cbcSrjs      datav = pDMAv[v_index]->address;
2620fa225cbcSrjs      if(v_index == 0) {
2621fa225cbcSrjs	*datav++ = CMD_FLUSH;
2622fa225cbcSrjs	*datav++ = BOOLEAN_ENA_2;
2623fa225cbcSrjs	*datav++ = CMD_FLUSH;
2624fa225cbcSrjs	*datav++ = DEST_BUFFER_INFO;
2625fa225cbcSrjs	*datav++ = privTarget->dbi1v;
2626fa225cbcSrjs	*datav++ = DEST_BUFFER_VAR;
2627fa225cbcSrjs	*datav++ = privTarget->dbv1;
2628fa225cbcSrjs	/* Past Surface */
2629fa225cbcSrjs	*datav++ = CMD_MAP_INFO;
2630fa225cbcSrjs	*datav++ = privPast->mi1v;
2631fa225cbcSrjs	*datav++ = privPast->mi2v;
2632fa225cbcSrjs	*datav++ = privPast->mi3v;
2633fa225cbcSrjs	/* Future Surface */
2634fa225cbcSrjs	*datav++ = CMD_MAP_INFO;
2635fa225cbcSrjs	*datav++ = privFuture->mi1v | 0x1<<28;
2636fa225cbcSrjs	*datav++ = privFuture->mi2v;
2637fa225cbcSrjs	*datav++ = privFuture->mi3v;
2638fa225cbcSrjs      }
2639fa225cbcSrjs    }/* if(datav == NULL) */
2640fa225cbcSrjs
2641fa225cbcSrjs    /* Catch no pattern case */
2642fa225cbcSrjs    if(!(mb->macroblock_type & 0x8)) {
2643fa225cbcSrjs      mb->coded_block_pattern = 0;
2644fa225cbcSrjs    }
2645fa225cbcSrjs
2646fa225cbcSrjs
2647fa225cbcSrjs    if(mb->motion_type == XVMC_PREDICTION_DUAL_PRIME) {
2648fa225cbcSrjs      /*
2649fa225cbcSrjs	By default the maps will not be set up for dual
2650fa225cbcSrjs	prime. We have to change them.
2651fa225cbcSrjs      */
2652fa225cbcSrjs      if(!pI810XvMC->dual_prime) {
2653fa225cbcSrjs	pI810XvMC->dual_prime = 1;
2654fa225cbcSrjs	privFuture = privPast;
2655fa225cbcSrjs	/* Y */
2656fa225cbcSrjs	*datay++ = CMD_MAP_INFO;
2657fa225cbcSrjs	*datay++ = privFuture->mi1y | 0x1<<28;
2658fa225cbcSrjs	*datay++ = privFuture->mi2y;
2659fa225cbcSrjs	*datay++ = privFuture->mi3y;
2660fa225cbcSrjs	/* U */
2661fa225cbcSrjs	*datau++ = CMD_MAP_INFO;
2662fa225cbcSrjs	*datau++ = privFuture->mi1u | 0x1<<28;
2663fa225cbcSrjs	*datau++ = privFuture->mi2u;
2664fa225cbcSrjs	*datau++ = privFuture->mi3u;
2665fa225cbcSrjs	/* V */
2666fa225cbcSrjs	*datav++ = CMD_MAP_INFO;
2667fa225cbcSrjs	*datav++ = privFuture->mi1v | 0x1<<28;
2668fa225cbcSrjs	*datav++ = privFuture->mi2v;
2669fa225cbcSrjs	*datav++ = privFuture->mi3v;
2670fa225cbcSrjs      }
2671fa225cbcSrjs    }
2672fa225cbcSrjs    if((pI810XvMC->dual_prime) &&
2673fa225cbcSrjs       (mb->motion_type != XVMC_PREDICTION_DUAL_PRIME)) {
2674fa225cbcSrjs      	pI810XvMC->dual_prime = 0;
2675fa225cbcSrjs	privFuture = privTarget;
2676fa225cbcSrjs	/* Y */
2677fa225cbcSrjs	*datay++ = CMD_MAP_INFO;
2678fa225cbcSrjs	*datay++ = privFuture->mi1y | 0x1<<28;
2679fa225cbcSrjs	*datay++ = privFuture->mi2y;
2680fa225cbcSrjs	*datay++ = privFuture->mi3y;
2681fa225cbcSrjs	/* U */
2682fa225cbcSrjs	*datau++ = CMD_MAP_INFO;
2683fa225cbcSrjs	*datau++ = privFuture->mi1u | 0x1<<28;
2684fa225cbcSrjs	*datau++ = privFuture->mi2u;
2685fa225cbcSrjs	*datau++ = privFuture->mi3u;
2686fa225cbcSrjs	/* V */
2687fa225cbcSrjs	*datav++ = CMD_MAP_INFO;
2688fa225cbcSrjs	*datav++ = privFuture->mi1v | 0x1<<28;
2689fa225cbcSrjs	*datav++ = privFuture->mi2v;
2690fa225cbcSrjs	*datav++ = privFuture->mi3v;
2691fa225cbcSrjs    }
2692fa225cbcSrjs
2693fa225cbcSrjs
2694fa225cbcSrjs    /* Frame Picture */
2695fa225cbcSrjs    if((picture_structure & XVMC_FRAME_PICTURE) == XVMC_FRAME_PICTURE) {
2696fa225cbcSrjs      /* Intra Blocks */
2697fa225cbcSrjs      if(mb->macroblock_type & XVMC_MB_TYPE_INTRA) {
2698fa225cbcSrjs	if(mb->dct_type) {
2699fa225cbcSrjs	  renderIntrainFrameDCT1(&datay,&datau,&datav,mb,block_ptr,flags);
2700fa225cbcSrjs	  continue;
2701fa225cbcSrjs	}
2702fa225cbcSrjs	renderIntrainFrame(&datay,&datau,&datav,mb,block_ptr);
2703fa225cbcSrjs	continue;
2704fa225cbcSrjs      }
2705fa225cbcSrjs      switch((mb->motion_type & 0x3) | (mb->dct_type<<2)) {
2706fa225cbcSrjs      case 0x2:  /* Frame DCT0 */
2707fa225cbcSrjs	renderFrameinFrame(&datay,&datau,&datav,mb,block_ptr,flags);
2708fa225cbcSrjs	continue;
2709fa225cbcSrjs      case 0x5:  /* Field DCT1 */
2710fa225cbcSrjs	renderFieldinFrame(&datay,&datau,&datav,mb,block_ptr,flags);
2711fa225cbcSrjs	continue;
2712fa225cbcSrjs      case 0x6: /* Frame DCT1 */
2713fa225cbcSrjs	renderFrameinFrameDCT1(&datay,&datau,&datav,mb,block_ptr,flags);
2714fa225cbcSrjs	continue;
2715fa225cbcSrjs      case 0x1: /* Field DCT0 */
2716fa225cbcSrjs	renderFieldinFrameDCT0(&datay,&datau,&datav,mb,block_ptr,flags);
2717fa225cbcSrjs	continue;
2718fa225cbcSrjs      case 0x3:  /* Dual Prime DCT0 */
2719fa225cbcSrjs	renderDualPrimeinFrame(&datay,&datau,&datav,mb,block_ptr,flags);
2720fa225cbcSrjs	continue;
2721fa225cbcSrjs      case 0x7:  /* Dual Prime DCT1 */
2722fa225cbcSrjs	renderDualPrimeinFrameDCT0(&datay,&datau,&datav,mb,block_ptr,flags);
2723fa225cbcSrjs	continue;
2724fa225cbcSrjs      default:  /* No Motion Type */
2725fa225cbcSrjs	renderError();
2726fa225cbcSrjs	continue;
2727fa225cbcSrjs      } /* Switch */
2728fa225cbcSrjs    } /* Frame Picture */
2729fa225cbcSrjs
2730fa225cbcSrjs    /* Field Pictures */
2731fa225cbcSrjs    if(mb->macroblock_type & XVMC_MB_TYPE_INTRA) {
2732fa225cbcSrjs      renderIntrainField(&datay,&datau,&datav,mb,block_ptr,picture_structure);
2733fa225cbcSrjs      continue;
2734fa225cbcSrjs    }
2735fa225cbcSrjs    switch(mb->motion_type & 0x3) {
2736fa225cbcSrjs    case 0x1: /* Field Motion */
2737fa225cbcSrjs      renderFieldinField(&datay,&datau,&datav,mb,block_ptr,picture_structure,
2738fa225cbcSrjs			 flags);
2739fa225cbcSrjs      continue;
2740fa225cbcSrjs    case 0x2: /* 16x8 Motion */
2741fa225cbcSrjs      render16x8inField(&datay,&datau,&datav,mb,block_ptr,picture_structure,
2742fa225cbcSrjs			flags);
2743fa225cbcSrjs      continue;
2744fa225cbcSrjs    case 0x3: /* Dual Prime */
2745fa225cbcSrjs      renderDualPrimeinField(&datay,&datau,&datav,mb,block_ptr,
2746fa225cbcSrjs			     picture_structure,flags);
2747fa225cbcSrjs      continue;
2748fa225cbcSrjs    default:  /* No Motion Type */
2749fa225cbcSrjs      renderError();
2750fa225cbcSrjs      continue;
2751fa225cbcSrjs    }
2752fa225cbcSrjs    continue;
2753fa225cbcSrjs
2754fa225cbcSrjs  } /* for each Macroblock */
2755fa225cbcSrjs
2756fa225cbcSrjs  /* Dispatch remaining DMA buffers */
2757fa225cbcSrjs  if(dirty_context) {
2758fa225cbcSrjs    dispatchYContext(privTarget,privPast,privFuture,pI810XvMC);
2759fa225cbcSrjs  }
2760fa225cbcSrjs  mc.idx = pDMAy->idx;
2761fa225cbcSrjs  mc.used = (unsigned long)datay - (unsigned long)pDMAy->address;
2762fa225cbcSrjs  mc.last_render = ++pI810XvMC->last_render;
2763fa225cbcSrjs  privTarget->last_render = pI810XvMC->last_render;
2764fa225cbcSrjs  I810_MC(pI810XvMC,mc);
2765fa225cbcSrjs
2766fa225cbcSrjs  pDMAu[u_index]->used = (unsigned long)datau - (unsigned long)pDMAu[u_index]->address;
2767fa225cbcSrjs  for(j=0; j<=u_index; j++) {
2768fa225cbcSrjs    mc.idx = pDMAu[j]->idx;
2769fa225cbcSrjs    mc.used = pDMAu[j]->used;
2770fa225cbcSrjs    mc.last_render = ++pI810XvMC->last_render;
2771fa225cbcSrjs    privTarget->last_render = pI810XvMC->last_render;
2772fa225cbcSrjs    I810_MC(pI810XvMC,mc);
2773fa225cbcSrjs  }
2774fa225cbcSrjs  pDMAv[v_index]->used = (unsigned long)datav - (unsigned long)pDMAv[v_index]->address;
2775fa225cbcSrjs  for(j=0; j<=v_index; j++) {
2776fa225cbcSrjs    mc.idx = pDMAv[j]->idx;
2777fa225cbcSrjs    mc.used = pDMAv[j]->used;
2778fa225cbcSrjs    mc.last_render = ++pI810XvMC->last_render;
2779fa225cbcSrjs    privTarget->last_render = pI810XvMC->last_render;
2780fa225cbcSrjs    I810_MC(pI810XvMC,mc);
2781fa225cbcSrjs  }
2782fa225cbcSrjs
2783fa225cbcSrjs  I810_UNLOCK(pI810XvMC);
2784fa225cbcSrjs
2785fa225cbcSrjs  return Success;
2786fa225cbcSrjs}
2787fa225cbcSrjs
2788fa225cbcSrjs/***************************************************************************
2789fa225cbcSrjs// Function: XvMCPutSurface
2790fa225cbcSrjs// Description:
2791fa225cbcSrjs// Arguments:
2792fa225cbcSrjs//  display: Connection to X server
2793fa225cbcSrjs//  surface: Surface to be displayed
2794fa225cbcSrjs//  draw: X Drawable on which to display the surface
2795fa225cbcSrjs//  srcx: X coordinate of the top left corner of the region to be
2796fa225cbcSrjs//          displayed within the surface.
2797fa225cbcSrjs//  srcy: Y coordinate of the top left corner of the region to be
2798fa225cbcSrjs//          displayed within the surface.
2799fa225cbcSrjs//  srcw: Width of the region to be displayed.
2800fa225cbcSrjs//  srch: Height of the region to be displayed.
2801fa225cbcSrjs//  destx: X cordinate of the top left corner of the destination region
2802fa225cbcSrjs//         in the drawable coordinates.
2803fa225cbcSrjs//  desty: Y cordinate of the top left corner of the destination region
2804fa225cbcSrjs//         in the drawable coordinates.
2805fa225cbcSrjs//  destw: Width of the destination region.
2806fa225cbcSrjs//  desth: Height of the destination region.
2807fa225cbcSrjs//  flags: One or more of the following.
2808fa225cbcSrjs//     XVMC_TOP_FIELD - Display only the Top field of the surface.
2809fa225cbcSrjs//     XVMC_BOTTOM_FIELD - Display only the Bottom Field of the surface.
2810fa225cbcSrjs//     XVMC_FRAME_PICTURE - Display both fields or frame.
2811fa225cbcSrjs//
2812fa225cbcSrjs// Info: Portions of this function derived from i810_video.c (XFree86)
2813fa225cbcSrjs//
2814fa225cbcSrjs//   This function is organized so that we wait as long as possible before
2815fa225cbcSrjs//   touching the overlay registers. Since we don't know that the last
2816fa225cbcSrjs//   flip has happened yet we want to give the overlay as long as
2817fa225cbcSrjs//   possible to catch up before we have to check on its progress. This
2818fa225cbcSrjs//   makes it unlikely that we have to wait on the last flip.
2819fa225cbcSrjs***************************************************************************/
2820fa225cbcSrjs_X_EXPORT Status XvMCPutSurface(Display *display,XvMCSurface *surface,
2821fa225cbcSrjs		      Drawable draw, short srcx, short srcy,
2822fa225cbcSrjs		      unsigned short srcw, unsigned short srch,
2823fa225cbcSrjs		      short destx, short desty,
2824fa225cbcSrjs		      unsigned short destw, unsigned short desth,
2825fa225cbcSrjs		      int flags) {
2826fa225cbcSrjs  i810XvMCContext *pI810XvMC;
2827fa225cbcSrjs  i810XvMCSurface *pI810Surface;
2828fa225cbcSrjs  i810OverlayRecPtr pORegs;
2829fa225cbcSrjs  unsigned int ysrc_offset,uvsrc_offset;
2830fa225cbcSrjs  Box extents;
2831fa225cbcSrjs  uint window_width,window_height;
2832fa225cbcSrjs  unsigned int xscaleInt = 0,xscaleFract = 0,yscaleInt = 0,yscaleFract = 0;
2833fa225cbcSrjs  unsigned int xscaleFractUV = 0,xscaleIntUV = 0,yscaleFractUV = 0;
2834fa225cbcSrjs  unsigned int yscaleIntUV = 0,yPitch = 0,uvPitch = 0;
2835fa225cbcSrjs  unsigned int ovcmd = 0;
2836fa225cbcSrjs  uint d;
2837fa225cbcSrjs  double xscale,yscale;
2838fa225cbcSrjs  int diff;
2839fa225cbcSrjs  int clipped_srcx, clipped_srcy, clipped_destx, clipped_desty;
2840fa225cbcSrjs  int clipped_srcw, clipped_srch, clipped_destw, clipped_desth;
2841fa225cbcSrjs  uint x1,y1,root_width,root_height;
2842fa225cbcSrjs  int x2 = 0, y2 = 0,unused;
2843fa225cbcSrjs  uint nChilds;
2844fa225cbcSrjs  int stat;
2845fa225cbcSrjs  Window win,root,parent,*pChilds;
2846fa225cbcSrjs
2847fa225cbcSrjs
2848fa225cbcSrjs  if((display == NULL) || (surface == NULL)) {
2849fa225cbcSrjs    return BadValue;
2850fa225cbcSrjs  }
2851fa225cbcSrjs
2852fa225cbcSrjs  if(surface->privData == NULL) {
2853fa225cbcSrjs    return (error_base + XvMCBadSurface);
2854fa225cbcSrjs  }
2855fa225cbcSrjs  pI810Surface = (i810XvMCSurface *)surface->privData;
2856fa225cbcSrjs  pI810XvMC = (i810XvMCContext *)pI810Surface->privContext;
2857fa225cbcSrjs  pORegs = (i810OverlayRecPtr)pI810XvMC->oregs;
2858fa225cbcSrjs
2859fa225cbcSrjs
2860fa225cbcSrjs  switch(surface->surface_type_id) {
2861fa225cbcSrjs  case FOURCC_YV12:
2862fa225cbcSrjs  case FOURCC_I420:
2863fa225cbcSrjs    yPitch = (srcw + 7) & ~7;
2864fa225cbcSrjs    uvPitch = ((srcw>>1) + 7) & ~7;
2865fa225cbcSrjs    if((flags & XVMC_FRAME_PICTURE) != XVMC_FRAME_PICTURE) {
2866fa225cbcSrjs      srch = srch>>1;
2867fa225cbcSrjs    }
2868fa225cbcSrjs    break;
2869fa225cbcSrjs  case FOURCC_UYVY:
2870fa225cbcSrjs  case FOURCC_YUY2:
2871fa225cbcSrjs  default:
2872fa225cbcSrjs    /* FIXME: Non Planar not fully implemented. */
2873fa225cbcSrjs    return BadValue;
2874fa225cbcSrjs    yPitch = ((srcw + 7) & ~7) << 1;
2875fa225cbcSrjs    break;
2876fa225cbcSrjs  }/* switch(surface->surface_type_id) */
2877fa225cbcSrjs
2878fa225cbcSrjs  /*
2879fa225cbcSrjs    FIXME: This should be using the DRI's clip rect but that isn't
2880fa225cbcSrjs    all hooked up yet. This has some latency but we get by.
2881fa225cbcSrjs  */
2882fa225cbcSrjs  win = draw;
2883fa225cbcSrjs  XQueryTree(display,win,&root,&parent,&pChilds,&nChilds);
2884fa225cbcSrjs  if(nChilds) XFree(pChilds);
2885fa225cbcSrjs  XGetGeometry(display,win, &root, &x2, &y2, &window_width,
2886fa225cbcSrjs	       &window_height, &d, &d);
2887fa225cbcSrjs  x1 = x2;
2888fa225cbcSrjs  y1 = y2;
2889fa225cbcSrjs  win = parent;
2890fa225cbcSrjs  do {
2891fa225cbcSrjs    XQueryTree(display,win,&root,&parent,&pChilds,&nChilds);
2892fa225cbcSrjs    if(nChilds) XFree(pChilds);
2893fa225cbcSrjs    XGetGeometry(display,win, &root, &x2, &y2, &d, &d, &d, &d);
2894fa225cbcSrjs    x1 += x2;
2895fa225cbcSrjs    y1 += y2;
2896fa225cbcSrjs    win = parent;
2897fa225cbcSrjs  }while(win != root);
2898fa225cbcSrjs  XGetGeometry(display,root, &root, &unused, &unused,
2899fa225cbcSrjs               &root_width, &root_height, &d, &d);
2900fa225cbcSrjs
2901fa225cbcSrjs  /* Left edge of Video window clipped to screen */
2902fa225cbcSrjs  extents.x1 = 0;
2903fa225cbcSrjs  if(x1 > extents.x1) {
2904fa225cbcSrjs    extents.x1 = x1;
2905fa225cbcSrjs  }
2906fa225cbcSrjs  /* Right edge of Video window clipped to screen */
2907fa225cbcSrjs  extents.x2 = root_width;
2908fa225cbcSrjs  if(extents.x2 > (x1 + window_width)) {
2909fa225cbcSrjs    extents.x2 = x1 + window_width;
2910fa225cbcSrjs  }
2911fa225cbcSrjs  /* Top edge of Video window clipped to screen */
2912fa225cbcSrjs  extents.y1 = 0;
2913fa225cbcSrjs  if(y1 > extents.y1) {
2914fa225cbcSrjs    extents.y1 = y1;
2915fa225cbcSrjs  }
2916fa225cbcSrjs  /* Bottom edge of Video window clipped to screen */
2917fa225cbcSrjs  extents.y2 = root_height;
2918fa225cbcSrjs  if(extents.y2 > (y1 + window_height)) {
2919fa225cbcSrjs    extents.y2 = y1 + window_height;
2920fa225cbcSrjs  }
2921fa225cbcSrjs
2922fa225cbcSrjs  /*
2923fa225cbcSrjs    Clipping is more difficult than is seems. We need to keep the
2924fa225cbcSrjs    scaling factors even if the destination window needs to be clipped.
2925fa225cbcSrjs    We clip the destination window first then apply a scaled version
2926fa225cbcSrjs    to the source window.
2927fa225cbcSrjs  */
2928fa225cbcSrjs
2929fa225cbcSrjs  /* Put destination coords in screen coords */
2930fa225cbcSrjs  destx += x1;
2931fa225cbcSrjs  desty += y1;
2932fa225cbcSrjs
2933fa225cbcSrjs  /* Scale factors requested */
2934fa225cbcSrjs  xscale = (double)srcw / (double)destw;
2935fa225cbcSrjs  yscale = (double)srch / (double)desth;
2936fa225cbcSrjs
2937fa225cbcSrjs  /*
2938fa225cbcSrjs    If destination window needs to be clipped we actually adjust both
2939fa225cbcSrjs    the src and dest window so as to keep the scaling that was requested
2940fa225cbcSrjs  */
2941fa225cbcSrjs  clipped_srcx = srcx;
2942fa225cbcSrjs  clipped_srcy = srcy;
2943fa225cbcSrjs  clipped_destx = destx;
2944fa225cbcSrjs  clipped_desty = desty;
2945fa225cbcSrjs  clipped_srcw = srcw;
2946fa225cbcSrjs  clipped_srch = srch;
2947fa225cbcSrjs  clipped_destw = destw;
2948fa225cbcSrjs  clipped_desth = desth;
2949fa225cbcSrjs
2950fa225cbcSrjs  /* Clip to the source surface boundaries */
2951fa225cbcSrjs  if(clipped_srcx < 0) {
2952fa225cbcSrjs    clipped_destx += (0 - clipped_srcx) / xscale;
2953fa225cbcSrjs    clipped_srcw -= clipped_srcx;
2954fa225cbcSrjs    clipped_destw -= clipped_srcx / xscale;
2955fa225cbcSrjs    clipped_srcx = 0;
2956fa225cbcSrjs  }
2957fa225cbcSrjs  if((clipped_srcw + clipped_srcx) > surface->width) {
2958fa225cbcSrjs    clipped_srcw = surface->width - clipped_srcx;
2959fa225cbcSrjs    clipped_destw -= (clipped_srcw - srcw) / xscale;
2960fa225cbcSrjs  }
2961fa225cbcSrjs  if(clipped_srcy < 0) {
2962fa225cbcSrjs    clipped_desty += (0 - clipped_srcy) / yscale;
2963fa225cbcSrjs    clipped_srch -= clipped_srcy;
2964fa225cbcSrjs    clipped_desth -= clipped_srcy / yscale;
2965fa225cbcSrjs    clipped_srcy = 0;
2966fa225cbcSrjs  }
2967fa225cbcSrjs  if((clipped_srch + clipped_srcy) > surface->height) {
2968fa225cbcSrjs    clipped_srch = surface->height - clipped_srcy;
2969fa225cbcSrjs    clipped_desth -= (clipped_srch - srch) / yscale;
2970fa225cbcSrjs  }
2971fa225cbcSrjs
2972fa225cbcSrjs  /* Clip to the extents */
2973fa225cbcSrjs  if(clipped_destx < extents.x1) {
2974fa225cbcSrjs    diff = extents.x1 - clipped_destx;
2975fa225cbcSrjs    clipped_srcx += diff * xscale;
2976fa225cbcSrjs    clipped_srcw -= diff * xscale;
2977fa225cbcSrjs    clipped_destw -= diff;
2978fa225cbcSrjs    clipped_destx = extents.x1;
2979fa225cbcSrjs  }
2980fa225cbcSrjs
2981fa225cbcSrjs  diff = (clipped_destx + clipped_destw) - extents.x2;
2982fa225cbcSrjs  if(diff > 0) {
2983fa225cbcSrjs    clipped_destw -= diff;
2984fa225cbcSrjs    clipped_srcw -= diff * xscale;
2985fa225cbcSrjs  }
2986fa225cbcSrjs
2987fa225cbcSrjs  if(clipped_desty < extents.y1) {
2988fa225cbcSrjs    diff = extents.y1 - clipped_desty;
2989fa225cbcSrjs    clipped_srcy += diff * yscale;
2990fa225cbcSrjs    clipped_srch -= diff * yscale;
2991fa225cbcSrjs    clipped_desth -= diff;
2992fa225cbcSrjs    clipped_desty = 0;
2993fa225cbcSrjs  }
2994fa225cbcSrjs
2995fa225cbcSrjs  diff = (clipped_desty + clipped_desth) - extents.y2;
2996fa225cbcSrjs  if(diff > 0) {
2997fa225cbcSrjs    clipped_desth -= diff;
2998fa225cbcSrjs    clipped_srch -= diff * yscale;
2999fa225cbcSrjs  }
3000fa225cbcSrjs
3001fa225cbcSrjs  /* If the whole window is clipped turn off the overlay */
3002fa225cbcSrjs  if((clipped_destx + clipped_destw < extents.x1) ||
3003fa225cbcSrjs     (clipped_desty + clipped_desth < extents.y1) ||
3004fa225cbcSrjs     (clipped_destx > extents.x2) ||
3005fa225cbcSrjs     (clipped_desty > extents.y2)) {
3006fa225cbcSrjs    return XvMCHideSurface(display, surface);
3007fa225cbcSrjs  }
3008fa225cbcSrjs
3009fa225cbcSrjs  /*
3010fa225cbcSrjs    Adjust the source offset width and height according to the clipped
3011fa225cbcSrjs    destination window.
3012fa225cbcSrjs  */
3013fa225cbcSrjs  ysrc_offset = ((clipped_srcx + 1) & ~1) +
3014fa225cbcSrjs    ((clipped_srcy + 1) & ~1) * (1<<pI810Surface->pitch);
3015fa225cbcSrjs  uvsrc_offset = (clipped_srcx>>1) +
3016fa225cbcSrjs    (clipped_srcy>>1) * (1<<(pI810Surface->pitch - 1));
3017fa225cbcSrjs
3018fa225cbcSrjs  /*
3019fa225cbcSrjs    Initially, YCbCr and Overlay Enable and
3020fa225cbcSrjs    vertical chrominance up interpolation and horozontal chrominance
3021fa225cbcSrjs    up interpolation
3022fa225cbcSrjs  */
3023fa225cbcSrjs  ovcmd = VC_UP_INTERPOLATION | HC_UP_INTERPOLATION |
3024fa225cbcSrjs    Y_ADJUST | OVERLAY_ENABLE;
3025fa225cbcSrjs
3026fa225cbcSrjs  if ((clipped_destw != clipped_srcw) ||
3027fa225cbcSrjs      (clipped_desth != clipped_srch)) {
3028fa225cbcSrjs    xscaleInt = (clipped_srcw / clipped_destw) & 0x3;
3029fa225cbcSrjs    xscaleFract = (clipped_srcw << 12) / clipped_destw;
3030fa225cbcSrjs    yscaleInt = (clipped_srch / clipped_desth) & 0x3;
3031fa225cbcSrjs    yscaleFract = (clipped_srch << 12) / clipped_desth;
3032fa225cbcSrjs
3033fa225cbcSrjs    if (clipped_destw > clipped_srcw) {
3034fa225cbcSrjs      /* horizontal up-scaling */
3035fa225cbcSrjs      ovcmd &= ~HORIZONTAL_CHROMINANCE_FILTER;
3036fa225cbcSrjs      ovcmd &= ~HORIZONTAL_LUMINANCE_FILTER;
3037fa225cbcSrjs      ovcmd |= (HC_UP_INTERPOLATION | HL_UP_INTERPOLATION);
3038fa225cbcSrjs    }
3039fa225cbcSrjs
3040fa225cbcSrjs    if (clipped_desth > clipped_srch) {
3041fa225cbcSrjs      /* vertical up-scaling */
3042fa225cbcSrjs      ovcmd &= ~VERTICAL_CHROMINANCE_FILTER;
3043fa225cbcSrjs      ovcmd &= ~VERTICAL_LUMINANCE_FILTER;
3044fa225cbcSrjs      ovcmd |= (VC_UP_INTERPOLATION | VL_UP_INTERPOLATION);
3045fa225cbcSrjs    }
3046fa225cbcSrjs
3047fa225cbcSrjs    if (clipped_destw < clipped_srcw) {
3048fa225cbcSrjs      /* horizontal down-scaling */
3049fa225cbcSrjs      ovcmd &= ~HORIZONTAL_CHROMINANCE_FILTER;
3050fa225cbcSrjs      ovcmd &= ~HORIZONTAL_LUMINANCE_FILTER;
3051fa225cbcSrjs      ovcmd |= (HC_DOWN_INTERPOLATION | HL_DOWN_INTERPOLATION);
3052fa225cbcSrjs    }
3053fa225cbcSrjs
3054fa225cbcSrjs    if (clipped_desth < clipped_srch) {
3055fa225cbcSrjs      /* vertical down-scaling */
3056fa225cbcSrjs      ovcmd &= ~VERTICAL_CHROMINANCE_FILTER;
3057fa225cbcSrjs      ovcmd &= ~VERTICAL_LUMINANCE_FILTER;
3058fa225cbcSrjs      ovcmd |= (VC_DOWN_INTERPOLATION | VL_DOWN_INTERPOLATION);
3059fa225cbcSrjs    }
3060fa225cbcSrjs
3061fa225cbcSrjs    /* now calculate the UV scaling factor */
3062fa225cbcSrjs    if (xscaleFract) {
3063fa225cbcSrjs      xscaleFractUV = xscaleFract >> MINUV_SCALE;
3064fa225cbcSrjs      ovcmd &= ~HC_DOWN_INTERPOLATION;
3065fa225cbcSrjs      ovcmd |= HC_UP_INTERPOLATION;
3066fa225cbcSrjs    }
3067fa225cbcSrjs
3068fa225cbcSrjs    if (xscaleInt) {
3069fa225cbcSrjs      xscaleIntUV = xscaleInt >> MINUV_SCALE;
3070fa225cbcSrjs      if (xscaleIntUV) {
3071fa225cbcSrjs	ovcmd &= ~HC_UP_INTERPOLATION;
3072fa225cbcSrjs      }
3073fa225cbcSrjs    }
3074fa225cbcSrjs
3075fa225cbcSrjs    if (yscaleFract) {
3076fa225cbcSrjs      yscaleFractUV = yscaleFract >> MINUV_SCALE;
3077fa225cbcSrjs      ovcmd &= ~VC_DOWN_INTERPOLATION;
3078fa225cbcSrjs      ovcmd |= VC_UP_INTERPOLATION;
3079fa225cbcSrjs    }
3080fa225cbcSrjs
3081fa225cbcSrjs    if (yscaleInt) {
3082fa225cbcSrjs      yscaleIntUV = yscaleInt >> MINUV_SCALE;
3083fa225cbcSrjs      if (yscaleIntUV) {
3084fa225cbcSrjs	ovcmd &= ~VC_UP_INTERPOLATION;
3085fa225cbcSrjs	ovcmd |= VC_DOWN_INTERPOLATION;
3086fa225cbcSrjs      }
3087fa225cbcSrjs    }
3088fa225cbcSrjs
3089fa225cbcSrjs  }/* if((destw != srcw) || (desth != srch)) */
3090fa225cbcSrjs
3091fa225cbcSrjs  /* Lock the DRM */
3092fa225cbcSrjs  I810_LOCK(pI810XvMC,0);
3093fa225cbcSrjs
3094fa225cbcSrjs  /* Block until rendering on this surface is finished */
3095fa225cbcSrjs  stat = XVMC_RENDERING;
3096fa225cbcSrjs  while(stat & XVMC_RENDERING) {
3097fa225cbcSrjs    XvMCGetSurfaceStatus(display,surface,&stat);
3098fa225cbcSrjs  }
3099fa225cbcSrjs  /* Block until the last flip is finished */
3100fa225cbcSrjs  if(pI810XvMC->last_flip) {
3101fa225cbcSrjs    BLOCK_OVERLAY(pI810XvMC,pI810XvMC->current);
3102fa225cbcSrjs  }
3103fa225cbcSrjs
3104fa225cbcSrjs  pI810XvMC->current = !pI810XvMC->current;
3105fa225cbcSrjs  pORegs->OV0CMD = ovcmd;
3106fa225cbcSrjs
3107fa225cbcSrjs  if ((clipped_destw != clipped_srcw) ||
3108fa225cbcSrjs      (clipped_desth != clipped_srch)) {
3109fa225cbcSrjs    pORegs->YRGBSCALE = (xscaleInt << 15) |
3110fa225cbcSrjs      ((xscaleFract & 0xFFF) << 3) | (yscaleInt) |
3111fa225cbcSrjs      ((yscaleFract & 0xFFF) << 20);
3112fa225cbcSrjs
3113fa225cbcSrjs    pORegs->UVSCALE = yscaleIntUV | ((xscaleFractUV & 0xFFF) << 3) |
3114fa225cbcSrjs      ((yscaleFractUV & 0xFFF) << 20);
3115fa225cbcSrjs  }
3116fa225cbcSrjs  else {
3117fa225cbcSrjs    /* Normal 1:1 scaling */
3118fa225cbcSrjs    pORegs->YRGBSCALE = 0x80004000;
3119fa225cbcSrjs    pORegs->UVSCALE = 0x80004000;
3120fa225cbcSrjs  }
3121fa225cbcSrjs
3122fa225cbcSrjs  pORegs->SHEIGHT = clipped_srch | (clipped_srch << 15);
3123fa225cbcSrjs  pORegs->DWINPOS = (clipped_desty << 16) | clipped_destx;
3124fa225cbcSrjs  pORegs->DWINSZ = ((clipped_desth<< 16) | (clipped_destw));
3125fa225cbcSrjs
3126fa225cbcSrjs  /* Attributes */
3127fa225cbcSrjs  pORegs->OV0CLRC0 = ((pI810XvMC->contrast & 0x1ff)<<8) |
3128fa225cbcSrjs    (pI810XvMC->brightness & 0xff);
3129fa225cbcSrjs  pORegs->OV0CLRC1 = (pI810XvMC->saturation & 0x3ff);
3130fa225cbcSrjs
3131fa225cbcSrjs  /* Destination Colorkey Setup */
3132fa225cbcSrjs  pI810XvMC->oregs->DCLRKV = RGB16ToColorKey(pI810XvMC->colorkey);
3133fa225cbcSrjs
3134fa225cbcSrjs  /* buffer locations, add the offset from the clipping */
3135fa225cbcSrjs  if(pI810XvMC->current) {
3136fa225cbcSrjs    pORegs->OBUF_1Y = (unsigned long)pI810Surface->offset +
3137fa225cbcSrjs      (unsigned long)pI810Surface->offsets[0] + ysrc_offset;
3138fa225cbcSrjs    pORegs->OBUF_1V = (unsigned long)pI810Surface->offset +
3139fa225cbcSrjs      (unsigned long)pI810Surface->offsets[2] + uvsrc_offset;
3140fa225cbcSrjs    pORegs->OBUF_1U = (unsigned long)pI810Surface->offset +
3141fa225cbcSrjs      (unsigned long)pI810Surface->offsets[1] + uvsrc_offset;
3142fa225cbcSrjs  }
3143fa225cbcSrjs  else {
3144fa225cbcSrjs    pORegs->OBUF_0Y = (unsigned long)pI810Surface->offset +
3145fa225cbcSrjs      (unsigned long)pI810Surface->offsets[0] + ysrc_offset;
3146fa225cbcSrjs    pORegs->OBUF_0V = (unsigned long)pI810Surface->offset +
3147fa225cbcSrjs      (unsigned long)pI810Surface->offsets[2] + uvsrc_offset;
3148fa225cbcSrjs    pORegs->OBUF_0U = (unsigned long)pI810Surface->offset +
3149fa225cbcSrjs      (unsigned long)pI810Surface->offsets[1] + uvsrc_offset;
3150fa225cbcSrjs  }
3151fa225cbcSrjs
3152fa225cbcSrjs  switch(surface->surface_type_id) {
3153fa225cbcSrjs  case FOURCC_YV12:
3154fa225cbcSrjs  case FOURCC_I420:
3155fa225cbcSrjs    pORegs->SWID = (uvPitch << 16) | yPitch;
3156fa225cbcSrjs    pORegs->SWIDQW = (uvPitch << 13) | (yPitch >> 3);
3157fa225cbcSrjs    pORegs->OV0STRIDE = (1<<pI810Surface->pitch) |
3158fa225cbcSrjs      ((1<<pI810Surface->pitch) << 15);
3159fa225cbcSrjs    pORegs->OV0CMD &= ~SOURCE_FORMAT;
3160fa225cbcSrjs    pORegs->OV0CMD |= YUV_420;
3161fa225cbcSrjs    if((flags & XVMC_FRAME_PICTURE) != XVMC_FRAME_PICTURE) {
3162fa225cbcSrjs      /* Top Field Only */
3163fa225cbcSrjs      if(flags & XVMC_TOP_FIELD) {
3164fa225cbcSrjs	if(pI810XvMC->current == 1) {
3165fa225cbcSrjs	  pORegs->OV0CMD |= (VERTICAL_PHASE_BOTH | FLIP_TYPE_FIELD |
3166fa225cbcSrjs			     BUFFER1_FIELD0);
3167fa225cbcSrjs	}
3168fa225cbcSrjs	else {
3169fa225cbcSrjs	  pORegs->OV0CMD |= (VERTICAL_PHASE_BOTH | FLIP_TYPE_FIELD |
3170fa225cbcSrjs			     BUFFER0_FIELD0);
3171fa225cbcSrjs	}
3172fa225cbcSrjs	pORegs->YRGB_VPH = 1<<15 | 1<<31;
3173fa225cbcSrjs	pORegs->UV_VPH = 3<<14 | 3<<30;
3174fa225cbcSrjs	pORegs->INIT_PH = 0x06 | 0x18;
3175fa225cbcSrjs      }
3176fa225cbcSrjs      /* Bottom Field Only */
3177fa225cbcSrjs      else {
3178fa225cbcSrjs	if(pI810XvMC->current == 1) {
3179fa225cbcSrjs	  pORegs->OV0CMD |= (VERTICAL_PHASE_BOTH | FLIP_TYPE_FIELD |
3180fa225cbcSrjs			     BUFFER1_FIELD1);
3181fa225cbcSrjs	}
3182fa225cbcSrjs	else {
3183fa225cbcSrjs	  pORegs->OV0CMD |= (VERTICAL_PHASE_BOTH | FLIP_TYPE_FIELD |
3184fa225cbcSrjs			     BUFFER0_FIELD1);
3185fa225cbcSrjs	}
3186fa225cbcSrjs	pORegs->YRGB_VPH = 0;
3187fa225cbcSrjs	pORegs->UV_VPH = 7<<29 | 7<<13;
3188fa225cbcSrjs	pORegs->INIT_PH = 0x06;
3189fa225cbcSrjs      }
3190fa225cbcSrjs    }
3191fa225cbcSrjs    /* Frame Picture */
3192fa225cbcSrjs    else {
3193fa225cbcSrjs      if(pI810XvMC->current == 1) {
3194fa225cbcSrjs	pORegs->OV0CMD |= BUFFER1_FIELD0;
3195fa225cbcSrjs      }
3196fa225cbcSrjs      else {
3197fa225cbcSrjs	pORegs->OV0CMD |= BUFFER0_FIELD0;
3198fa225cbcSrjs      }
3199fa225cbcSrjs      pORegs->YRGB_VPH = 0;
3200fa225cbcSrjs      pORegs->UV_VPH = 0;
3201fa225cbcSrjs      pORegs->INIT_PH = 0;
3202fa225cbcSrjs    }
3203fa225cbcSrjs    break;
3204fa225cbcSrjs  case FOURCC_UYVY:
3205fa225cbcSrjs  case FOURCC_YUY2:
3206fa225cbcSrjs  default:
3207fa225cbcSrjs    pORegs->SWID = srcw;
3208fa225cbcSrjs    pORegs->SWIDQW = srcw >> 3;
3209fa225cbcSrjs    pORegs->OV0STRIDE = pI810Surface->pitch;
3210fa225cbcSrjs    pORegs->OV0CMD &= ~SOURCE_FORMAT;
3211fa225cbcSrjs    pORegs->OV0CMD |= YUV_422;
3212fa225cbcSrjs    pORegs->OV0CMD &= ~OV_BYTE_ORDER;
3213fa225cbcSrjs    if (surface->surface_type_id == FOURCC_UYVY) {
3214fa225cbcSrjs      pORegs->OV0CMD |= Y_SWAP;
3215fa225cbcSrjs    }
3216fa225cbcSrjs
3217fa225cbcSrjs    pORegs->OV0CMD &= ~BUFFER_AND_FIELD;
3218fa225cbcSrjs    if(pI810XvMC->current == 1) {
3219fa225cbcSrjs      pORegs->OV0CMD |= BUFFER1_FIELD0;
3220fa225cbcSrjs    }
3221fa225cbcSrjs    else {
3222fa225cbcSrjs      pORegs->OV0CMD |= BUFFER0_FIELD0;
3223fa225cbcSrjs    }
3224fa225cbcSrjs
3225fa225cbcSrjs    break;
3226fa225cbcSrjs  } /* switch(surface->surface_type_id) */
3227fa225cbcSrjs
3228fa225cbcSrjs
3229fa225cbcSrjs
3230fa225cbcSrjs  OVERLAY_FLIP(pI810XvMC);
3231fa225cbcSrjs
3232fa225cbcSrjs  /*
3233fa225cbcSrjs    The Overlay only flips when it knows you changed
3234fa225cbcSrjs    something. So the first time change stuff while it
3235fa225cbcSrjs    is watching to be sure.
3236fa225cbcSrjs  */
3237fa225cbcSrjs  if(!pI810XvMC->last_flip) {
3238fa225cbcSrjs    pORegs->OV0CMD &= ~0x4;
3239fa225cbcSrjs    if(pI810XvMC->current == 1) {
3240fa225cbcSrjs      pORegs->OV0CMD |= BUFFER1_FIELD0;
3241fa225cbcSrjs    }
3242fa225cbcSrjs    else {
3243fa225cbcSrjs      pORegs->OV0CMD |= BUFFER0_FIELD0;
3244fa225cbcSrjs    }
3245fa225cbcSrjs  }
3246fa225cbcSrjs  pI810Surface->last_flip = ++pI810XvMC->last_flip;
3247fa225cbcSrjs  I810_UNLOCK(pI810XvMC);
3248fa225cbcSrjs
3249fa225cbcSrjs  return Success;
3250fa225cbcSrjs}
3251fa225cbcSrjs
3252fa225cbcSrjs/***************************************************************************
3253fa225cbcSrjs// Function: XvMCSyncSurface
3254fa225cbcSrjs// Arguments:
3255fa225cbcSrjs//   display - Connection to the X server
3256fa225cbcSrjs//   surface - The surface to synchronize
3257fa225cbcSrjs// Info:
3258fa225cbcSrjs// Returns: Status
3259fa225cbcSrjs***************************************************************************/
3260fa225cbcSrjs_X_EXPORT Status XvMCSyncSurface(Display *display,XvMCSurface *surface) {
3261fa225cbcSrjs  Status ret;
3262fa225cbcSrjs  int stat=0;
3263fa225cbcSrjs  /*
3264fa225cbcSrjs    FIXME: Perhaps a timer here to prevent lockup?
3265fa225cbcSrjs    FIXME: Perhaps a usleep to not be busy waiting?
3266fa225cbcSrjs  */
3267fa225cbcSrjs  do {
3268fa225cbcSrjs    ret = XvMCGetSurfaceStatus(display,surface,&stat);
3269fa225cbcSrjs  }while(!ret && (stat & XVMC_RENDERING));
3270fa225cbcSrjs  return ret;
3271fa225cbcSrjs}
3272fa225cbcSrjs
3273fa225cbcSrjs/***************************************************************************
3274fa225cbcSrjs// Function: XvMCFlushSurface
3275fa225cbcSrjs// Description:
3276fa225cbcSrjs//   This function commits pending rendering requests to ensure that they
3277fa225cbcSrjs//   wll be completed in a finite amount of time.
3278fa225cbcSrjs// Arguments:
3279fa225cbcSrjs//   display - Connection to X server
3280fa225cbcSrjs//   surface - Surface to flush
3281fa225cbcSrjs// Info:
3282fa225cbcSrjs//   This command is a noop for i810 becuase we always dispatch buffers in
3283fa225cbcSrjs//   render. There is little gain to be had with 4k buffers.
3284fa225cbcSrjs// Returns: Status
3285fa225cbcSrjs***************************************************************************/
3286fa225cbcSrjs_X_EXPORT Status XvMCFlushSurface(Display * display, XvMCSurface *surface) {
3287fa225cbcSrjs  return Success;
3288fa225cbcSrjs}
3289fa225cbcSrjs
3290fa225cbcSrjs/***************************************************************************
3291fa225cbcSrjs// Function: XvMCGetSurfaceStatus
3292fa225cbcSrjs// Description:
3293fa225cbcSrjs// Arguments:
3294fa225cbcSrjs//  display: connection to X server
3295fa225cbcSrjs//  surface: The surface to query
3296fa225cbcSrjs//  stat: One of the Following
3297fa225cbcSrjs//    XVMC_RENDERING - The last XvMCRenderSurface command has not
3298fa225cbcSrjs//                     completed.
3299fa225cbcSrjs//    XVMC_DISPLAYING - The surface is currently being displayed or a
3300fa225cbcSrjs//                     display is pending.
3301fa225cbcSrjs***************************************************************************/
3302fa225cbcSrjs_X_EXPORT Status XvMCGetSurfaceStatus(Display *display, XvMCSurface *surface,
3303fa225cbcSrjs			    int *stat) {
3304fa225cbcSrjs  i810XvMCSurface *privSurface;
3305fa225cbcSrjs  i810XvMCContext *pI810XvMC;
3306fa225cbcSrjs  int temp;
3307fa225cbcSrjs
3308fa225cbcSrjs  if((display == NULL) || (surface == NULL) || (stat == NULL)) {
3309fa225cbcSrjs    return BadValue;
3310fa225cbcSrjs  }
3311fa225cbcSrjs  if(surface->privData == NULL) {
3312fa225cbcSrjs    return BadValue;
3313fa225cbcSrjs  }
3314fa225cbcSrjs  *stat = 0;
3315fa225cbcSrjs  privSurface = surface->privData;
3316fa225cbcSrjs
3317fa225cbcSrjs  pI810XvMC = privSurface->privContext;
3318fa225cbcSrjs  if(pI810XvMC == NULL) {
3319fa225cbcSrjs    return (error_base + XvMCBadSurface);
3320fa225cbcSrjs  }
3321fa225cbcSrjs
3322fa225cbcSrjs  I810_LOCK(pI810XvMC,0);
3323fa225cbcSrjs  if(privSurface->last_flip) {
3324fa225cbcSrjs    /* This can not happen */
3325fa225cbcSrjs    if(pI810XvMC->last_flip < privSurface->last_flip) {
3326fa225cbcSrjs      printf("Error: Context last flip is less than surface last flip.\n");
3327fa225cbcSrjs      return BadValue;
3328fa225cbcSrjs    }
3329fa225cbcSrjs    /*
3330fa225cbcSrjs      If the context has 2 or more flips after this surface it
3331fa225cbcSrjs      cannot be displaying. Don't bother to check.
3332fa225cbcSrjs    */
3333fa225cbcSrjs    if(!(pI810XvMC->last_flip > (privSurface->last_flip + 1))) {
3334fa225cbcSrjs      /*
3335fa225cbcSrjs	If this surface was the last flipped it is either displaying
3336fa225cbcSrjs	or about to be so don't bother checking.
3337fa225cbcSrjs      */
3338fa225cbcSrjs      if(pI810XvMC->last_flip == privSurface->last_flip) {
3339fa225cbcSrjs	*stat |= XVMC_DISPLAYING;
3340fa225cbcSrjs      }
3341fa225cbcSrjs      else {
3342fa225cbcSrjs	/*
3343fa225cbcSrjs	  In this case there has been one more flip since our surface's
3344fa225cbcSrjs	  but we need to check if it is finished or not.
3345fa225cbcSrjs	*/
3346fa225cbcSrjs	temp = GET_FSTATUS(pI810XvMC);
3347fa225cbcSrjs	if(((temp & (1<<20))>>20) != pI810XvMC->current) {
3348fa225cbcSrjs	  *stat |= XVMC_DISPLAYING;
3349fa225cbcSrjs	}
3350fa225cbcSrjs      }
3351fa225cbcSrjs    }
3352fa225cbcSrjs  }
3353fa225cbcSrjs
3354fa225cbcSrjs  if(privSurface->last_render &&
3355fa225cbcSrjs      (privSurface->last_render > GET_RSTATUS(pI810XvMC))) {
3356fa225cbcSrjs    *stat |= XVMC_RENDERING;
3357fa225cbcSrjs  }
3358fa225cbcSrjs  I810_UNLOCK(pI810XvMC);
3359fa225cbcSrjs
3360fa225cbcSrjs  return Success;
3361fa225cbcSrjs}
3362fa225cbcSrjs
3363fa225cbcSrjs/***************************************************************************
3364fa225cbcSrjs//
3365fa225cbcSrjs//  Surface manipulation functions
3366fa225cbcSrjs//
3367fa225cbcSrjs***************************************************************************/
3368fa225cbcSrjs
3369fa225cbcSrjs/***************************************************************************
3370fa225cbcSrjs// Function: XvMCHideSurface
3371fa225cbcSrjs// Description: Stops the display of a surface.
3372fa225cbcSrjs// Arguments:
3373fa225cbcSrjs//   display - Connection to the X server.
3374fa225cbcSrjs//   surface - surface to be hidden.
3375fa225cbcSrjs//
3376fa225cbcSrjs// Returns: Status
3377fa225cbcSrjs***************************************************************************/
3378fa225cbcSrjs_X_EXPORT Status XvMCHideSurface(Display *display, XvMCSurface *surface) {
3379fa225cbcSrjs  i810XvMCSurface *pI810Surface;
3380fa225cbcSrjs  i810XvMCContext *pI810XvMC;
3381fa225cbcSrjs  int ss, xx;
3382fa225cbcSrjs
3383fa225cbcSrjs  /* Did we get a good display and surface passed into us? */
3384fa225cbcSrjs  if(display == NULL) {
3385fa225cbcSrjs    return BadValue;
3386fa225cbcSrjs  }
3387fa225cbcSrjs
3388fa225cbcSrjs  if(surface == NULL) {
3389fa225cbcSrjs    return (error_base + XvMCBadSurface);
3390fa225cbcSrjs  }
3391fa225cbcSrjs
3392fa225cbcSrjs  XvMCSyncSurface(display, surface);
3393fa225cbcSrjs
3394fa225cbcSrjs  /* Get surface private data pointer */
3395fa225cbcSrjs  if(surface->privData == NULL) {
3396fa225cbcSrjs    return (error_base + XvMCBadSurface);
3397fa225cbcSrjs  }
3398fa225cbcSrjs  pI810Surface = (i810XvMCSurface *)surface->privData;
3399fa225cbcSrjs
3400fa225cbcSrjs  /*
3401fa225cbcSrjs    Get the status of the surface, if it is not currently displayed
3402fa225cbcSrjs    we don't need to worry about it.
3403fa225cbcSrjs  */
3404fa225cbcSrjs  if((xx = XvMCGetSurfaceStatus(display, surface, &ss)) != Success) {
3405fa225cbcSrjs    return xx;
3406fa225cbcSrjs  }
3407fa225cbcSrjs  if(! (ss & XVMC_DISPLAYING)) {
3408fa225cbcSrjs    return Success;
3409fa225cbcSrjs  }
3410fa225cbcSrjs
3411fa225cbcSrjs  /* Get the associated context pointer */
3412fa225cbcSrjs  pI810XvMC = (i810XvMCContext *)pI810Surface->privContext;
3413fa225cbcSrjs  if(pI810XvMC == NULL) {
3414fa225cbcSrjs    return (error_base + XvMCBadSurface);
3415fa225cbcSrjs  }
3416fa225cbcSrjs
3417fa225cbcSrjs  if(pI810XvMC->last_flip) {
3418fa225cbcSrjs    I810_LOCK(pI810XvMC,DRM_LOCK_QUIESCENT);
3419fa225cbcSrjs
3420fa225cbcSrjs    /* Make sure last flip is done */
3421fa225cbcSrjs    BLOCK_OVERLAY(pI810XvMC,pI810XvMC->current);
3422fa225cbcSrjs
3423fa225cbcSrjs    /* Set the registers to turn the overlay off */
3424fa225cbcSrjs    pI810XvMC->oregs->OV0CMD = VC_UP_INTERPOLATION | HC_UP_INTERPOLATION |
3425fa225cbcSrjs      Y_ADJUST;
3426fa225cbcSrjs    pI810XvMC->current = !pI810XvMC->current;
3427fa225cbcSrjs    if(pI810XvMC->current == 1) {
3428fa225cbcSrjs      pI810XvMC->oregs->OV0CMD |= BUFFER1_FIELD0;
3429fa225cbcSrjs    }
3430fa225cbcSrjs    else {
3431fa225cbcSrjs      pI810XvMC->oregs->OV0CMD |= BUFFER0_FIELD0;
3432fa225cbcSrjs    }
3433fa225cbcSrjs    OVERLAY_FLIP(pI810XvMC);
3434fa225cbcSrjs    /*
3435fa225cbcSrjs      Increment the context flip but not the surface. This way no
3436fa225cbcSrjs      surface has the last flip #.
3437fa225cbcSrjs    */
3438fa225cbcSrjs    pI810XvMC->last_flip++;
3439fa225cbcSrjs
3440fa225cbcSrjs
3441fa225cbcSrjs    /* Now wait until the hardware reads the registers and makes the change. */
3442fa225cbcSrjs    BLOCK_OVERLAY(pI810XvMC,pI810XvMC->current)
3443fa225cbcSrjs
3444fa225cbcSrjs      I810_UNLOCK(pI810XvMC);
3445fa225cbcSrjs  }
3446fa225cbcSrjs
3447fa225cbcSrjs  return Success;
3448fa225cbcSrjs}
3449fa225cbcSrjs
3450fa225cbcSrjs
3451fa225cbcSrjs
3452fa225cbcSrjs
3453fa225cbcSrjs/***************************************************************************
3454fa225cbcSrjs//
3455fa225cbcSrjs// Functions that deal with subpictures
3456fa225cbcSrjs//
3457fa225cbcSrjs***************************************************************************/
3458fa225cbcSrjs
3459fa225cbcSrjs
3460fa225cbcSrjs
3461fa225cbcSrjs/***************************************************************************
3462fa225cbcSrjs// Function: XvMCCreateSubpicture
3463fa225cbcSrjs// Description: This creates a subpicture by filling out the XvMCSubpicture
3464fa225cbcSrjs//              structure passed to it and returning Success.
3465fa225cbcSrjs// Arguments:
3466fa225cbcSrjs//   display - Connection to the X server.
3467fa225cbcSrjs//   context - The context to create the subpicture for.
3468fa225cbcSrjs//   subpicture - Pre-allocated XvMCSubpicture structure to be filled in.
3469fa225cbcSrjs//   width - of subpicture
3470fa225cbcSrjs//   height - of subpicture
3471fa225cbcSrjs//   xvimage_id - The id describing the XvImage format.
3472fa225cbcSrjs//
3473fa225cbcSrjs// Returns: Status
3474fa225cbcSrjs***************************************************************************/
3475fa225cbcSrjs_X_EXPORT Status XvMCCreateSubpicture(Display *display, XvMCContext *context,
3476fa225cbcSrjs                          XvMCSubpicture *subpicture,
3477fa225cbcSrjs                          unsigned short width, unsigned short height,
3478fa225cbcSrjs                          int xvimage_id) {
3479fa225cbcSrjs  i810XvMCContext *pI810XvMC;
3480fa225cbcSrjs  i810XvMCSubpicture *pI810Subpicture;
3481fa225cbcSrjs  int priv_count;
3482fa225cbcSrjs  uint *priv_data;
3483fa225cbcSrjs  Status ret;
3484fa225cbcSrjs
3485fa225cbcSrjs  if((subpicture == NULL) || (context == NULL) || (display == NULL)){
3486fa225cbcSrjs    return BadValue;
3487fa225cbcSrjs  }
3488fa225cbcSrjs
3489fa225cbcSrjs  pI810XvMC = (i810XvMCContext *)context->privData;
3490fa225cbcSrjs  if(pI810XvMC == NULL) {
3491fa225cbcSrjs    return (error_base + XvMCBadContext);
3492fa225cbcSrjs  }
3493fa225cbcSrjs
3494fa225cbcSrjs
3495fa225cbcSrjs  subpicture->context_id = context->context_id;
3496fa225cbcSrjs  subpicture->xvimage_id = xvimage_id;
3497fa225cbcSrjs
3498fa225cbcSrjs  /* These need to be checked to make sure they are not too big! */
3499fa225cbcSrjs  subpicture->width = width;
3500fa225cbcSrjs  subpicture->height = height;
3501fa225cbcSrjs
3502fa225cbcSrjs  subpicture->privData =
3503fa225cbcSrjs    (i810XvMCSubpicture *)malloc(sizeof(i810XvMCSubpicture));
3504fa225cbcSrjs
3505fa225cbcSrjs  if(!subpicture->privData) {
3506fa225cbcSrjs    return BadAlloc;
3507fa225cbcSrjs  }
3508fa225cbcSrjs  pI810Subpicture = (i810XvMCSubpicture *)subpicture->privData;
3509fa225cbcSrjs
3510fa225cbcSrjs
3511fa225cbcSrjs  if((ret = _xvmc_create_subpicture(display, context, subpicture,
3512fa225cbcSrjs				    &priv_count, &priv_data))) {
3513fa225cbcSrjs    printf("Unable to create XvMCSubpicture.\n");
3514fa225cbcSrjs    return ret;
3515fa225cbcSrjs  }
3516fa225cbcSrjs
3517fa225cbcSrjs  if(priv_count != 1) {
3518fa225cbcSrjs    printf("_xvmc_create_subpicture() returned incorrect data size.\n");
3519fa225cbcSrjs    printf("Expected 1 got %d\n",priv_count);
3520fa225cbcSrjs    free(priv_data);
3521fa225cbcSrjs    return BadAlloc;
3522fa225cbcSrjs  }
3523fa225cbcSrjs  /* Data == Client Address, offset == Physical address offset */
3524fa225cbcSrjs  pI810Subpicture->data = pI810XvMC->surfaces.address;
3525fa225cbcSrjs  pI810Subpicture->offset = pI810XvMC->surfaces.offset;
3526fa225cbcSrjs
3527fa225cbcSrjs  /* Initialize private values */
3528fa225cbcSrjs  pI810Subpicture->privContext = pI810XvMC;
3529fa225cbcSrjs
3530fa225cbcSrjs  pI810Subpicture->last_render = 0;
3531fa225cbcSrjs  pI810Subpicture->last_flip = 0;
3532fa225cbcSrjs
3533fa225cbcSrjs  /* Based on the xvimage_id we will need to set the other values */
3534fa225cbcSrjs  subpicture->num_palette_entries = 16;
3535fa225cbcSrjs  subpicture->entry_bytes = 3;
3536fa225cbcSrjs  strcpy(subpicture->component_order,"YUV");
3537fa225cbcSrjs
3538fa225cbcSrjs  /*
3539fa225cbcSrjs    i810's MC Engine needs surfaces of 2^x (x= 9,10,11,12) pitch
3540fa225cbcSrjs    and the Tiler need 512k aligned surfaces, basically we are
3541fa225cbcSrjs    stuck with fixed memory with pitch 1024.
3542fa225cbcSrjs  */
3543fa225cbcSrjs  pI810Subpicture->pitch = 10;
3544fa225cbcSrjs
3545fa225cbcSrjs  /*
3546fa225cbcSrjs     offsets[0] == offset into the map described by either
3547fa225cbcSrjs     address (Client memeory address) or offset (physical offset from fb base)
3548fa225cbcSrjs  */
3549fa225cbcSrjs  pI810Subpicture->offsets[0] = priv_data[0];
3550fa225cbcSrjs  if(((unsigned long)pI810Subpicture->data + pI810Subpicture->offsets[0]) & 4095) {
3551fa225cbcSrjs    printf("XvMCCreateSubpicture: Subpicture offset 0 is not 4096 aligned\n");
3552fa225cbcSrjs  }
3553fa225cbcSrjs
3554fa225cbcSrjs  /* Free data returned from xvmc_create_surface */
3555fa225cbcSrjs  free(priv_data);
3556fa225cbcSrjs
3557fa225cbcSrjs  /* Clear the surface to 0 */
3558fa225cbcSrjs  memset((void *)((unsigned long)pI810Subpicture->data + (unsigned long)pI810Subpicture->offsets[0]),
3559fa225cbcSrjs	 0, ((1<<pI810Subpicture->pitch) * subpicture->height));
3560fa225cbcSrjs
3561fa225cbcSrjs  switch(subpicture->xvimage_id) {
3562fa225cbcSrjs  case FOURCC_IA44:
3563fa225cbcSrjs  case FOURCC_AI44:
3564fa225cbcSrjs    /* Destination buffer info command */
3565fa225cbcSrjs    pI810Subpicture->dbi1 = ((((unsigned int)pI810Subpicture->offset +
3566fa225cbcSrjs			       pI810Subpicture->offsets[0]) & ~0xfc000fff) |
3567fa225cbcSrjs			     (pI810Subpicture->pitch - 9));
3568fa225cbcSrjs
3569fa225cbcSrjs    /* Destination buffer variables command */
3570fa225cbcSrjs    pI810Subpicture->dbv1 = (0x8<<20) | (0x8<<16);
3571fa225cbcSrjs
3572fa225cbcSrjs    /* Map info command */
3573fa225cbcSrjs    pI810Subpicture->mi1 = (0x0<<24) | (3<<21) | (1<<9) |
3574fa225cbcSrjs      (pI810Subpicture->pitch - 3);
3575fa225cbcSrjs
3576fa225cbcSrjs    pI810Subpicture->mi2 = (((unsigned int)subpicture->height - 1)<<16) |
3577fa225cbcSrjs      ((unsigned int)subpicture->width - 1);
3578fa225cbcSrjs
3579fa225cbcSrjs    pI810Subpicture->mi3 = ((unsigned int)pI810Subpicture->offset +
3580fa225cbcSrjs			 pI810Subpicture->offsets[0]) & ~0xfc00000f;
3581fa225cbcSrjs    break;
3582fa225cbcSrjs  default:
3583fa225cbcSrjs    free(subpicture->privData);
3584fa225cbcSrjs    return BadMatch;
3585fa225cbcSrjs  }
3586fa225cbcSrjs
3587fa225cbcSrjs  pI810XvMC->ref++;
3588fa225cbcSrjs  return Success;
3589fa225cbcSrjs}
3590fa225cbcSrjs
3591fa225cbcSrjs
3592fa225cbcSrjs
3593fa225cbcSrjs/***************************************************************************
3594fa225cbcSrjs// Function: XvMCClearSubpicture
3595fa225cbcSrjs// Description: Clear the area of the given subpicture to "color".
3596fa225cbcSrjs//              structure passed to it and returning Success.
3597fa225cbcSrjs// Arguments:
3598fa225cbcSrjs//   display - Connection to the X server.
3599fa225cbcSrjs//   subpicture - Subpicture to clear.
3600fa225cbcSrjs//   x, y, width, height - rectangle in the subpicture to clear.
3601fa225cbcSrjs//   color - The data to file the rectangle with.
3602fa225cbcSrjs//
3603fa225cbcSrjs// Returns: Status
3604fa225cbcSrjs***************************************************************************/
3605fa225cbcSrjs_X_EXPORT Status XvMCClearSubpicture(Display *display, XvMCSubpicture *subpicture,
3606fa225cbcSrjs                          short x, short y,
3607fa225cbcSrjs                          unsigned short width, unsigned short height,
3608fa225cbcSrjs                          unsigned int color) {
3609fa225cbcSrjs
3610fa225cbcSrjs  i810XvMCContext *pI810XvMC;
3611fa225cbcSrjs  i810XvMCSubpicture *pI810Subpicture;
3612fa225cbcSrjs  int i;
3613fa225cbcSrjs
3614fa225cbcSrjs  if((subpicture == NULL) || (display == NULL)){
3615fa225cbcSrjs    return BadValue;
3616fa225cbcSrjs  }
3617fa225cbcSrjs
3618fa225cbcSrjs  if(!subpicture->privData) {
3619fa225cbcSrjs    return (error_base + XvMCBadSubpicture);
3620fa225cbcSrjs  }
3621fa225cbcSrjs  pI810Subpicture = (i810XvMCSubpicture *)subpicture->privData;
3622fa225cbcSrjs
3623fa225cbcSrjs  pI810XvMC = (i810XvMCContext *)pI810Subpicture->privContext;
3624fa225cbcSrjs  if(pI810XvMC == NULL) {
3625fa225cbcSrjs    return (error_base + XvMCBadSubpicture);
3626fa225cbcSrjs  }
3627fa225cbcSrjs
3628fa225cbcSrjs  if((x < 0) || (x + width > subpicture->width)) {
3629fa225cbcSrjs    return BadValue;
3630fa225cbcSrjs  }
3631fa225cbcSrjs
3632fa225cbcSrjs  if((y < 0) || (y + height > subpicture->height)) {
3633fa225cbcSrjs    return BadValue;
3634fa225cbcSrjs  }
3635fa225cbcSrjs
3636fa225cbcSrjs  for(i=y; i<y + height; i++) {
3637fa225cbcSrjs    memset((void *)((unsigned long)pI810Subpicture->data +
3638fa225cbcSrjs		    (unsigned long)pI810Subpicture->offsets[0] + x +
3639fa225cbcSrjs		    (1<<pI810Subpicture->pitch) * i),(char)color,width);
3640fa225cbcSrjs  }
3641fa225cbcSrjs
3642fa225cbcSrjs  return Success;
3643fa225cbcSrjs}
3644fa225cbcSrjs
3645fa225cbcSrjs/***************************************************************************
3646fa225cbcSrjs// Function: XvMCCompositeSubpicture
3647fa225cbcSrjs// Description: Composite the XvImae on the subpicture. This composit uses
3648fa225cbcSrjs//              non-premultiplied alpha. Destination alpha is utilized
3649fa225cbcSrjs//              except for with indexed subpictures. Indexed subpictures
3650fa225cbcSrjs//              use a simple "replace".
3651fa225cbcSrjs// Arguments:
3652fa225cbcSrjs//   display - Connection to the X server.
3653fa225cbcSrjs//   subpicture - Subpicture to clear.
3654fa225cbcSrjs//   image - the XvImage to be used as the source of the composite.
3655fa225cbcSrjs//   srcx, srcy, width, height - The rectangle from the image to be used.
3656fa225cbcSrjs//   dstx, dsty - location in the subpicture to composite the source.
3657fa225cbcSrjs//
3658fa225cbcSrjs// Returns: Status
3659fa225cbcSrjs***************************************************************************/
3660fa225cbcSrjs_X_EXPORT Status XvMCCompositeSubpicture(Display *display, XvMCSubpicture *subpicture,
3661fa225cbcSrjs                               XvImage *image,
3662fa225cbcSrjs                               short srcx, short srcy,
3663fa225cbcSrjs                               unsigned short width, unsigned short height,
3664fa225cbcSrjs                               short dstx, short dsty) {
3665fa225cbcSrjs
3666fa225cbcSrjs  i810XvMCContext *pI810XvMC;
3667fa225cbcSrjs  i810XvMCSubpicture *pI810Subpicture;
3668fa225cbcSrjs  int i;
3669fa225cbcSrjs
3670fa225cbcSrjs  if((subpicture == NULL) || (display == NULL)){
3671fa225cbcSrjs    return BadValue;
3672fa225cbcSrjs  }
3673fa225cbcSrjs
3674fa225cbcSrjs  if(!subpicture->privData) {
3675fa225cbcSrjs    return (error_base + XvMCBadSubpicture);
3676fa225cbcSrjs  }
3677fa225cbcSrjs  pI810Subpicture = (i810XvMCSubpicture *)subpicture->privData;
3678fa225cbcSrjs
3679fa225cbcSrjs  pI810XvMC = (i810XvMCContext *)pI810Subpicture->privContext;
3680fa225cbcSrjs  if(pI810XvMC == NULL) {
3681fa225cbcSrjs    return (error_base + XvMCBadSubpicture);
3682fa225cbcSrjs  }
3683fa225cbcSrjs
3684fa225cbcSrjs  if((srcx < 0) || (srcx + width > image->width)) {
3685fa225cbcSrjs    return BadValue;
3686fa225cbcSrjs  }
3687fa225cbcSrjs
3688fa225cbcSrjs  if((dstx < 0) || (dstx + width > subpicture->width)) {
3689fa225cbcSrjs    return BadValue;
3690fa225cbcSrjs  }
3691fa225cbcSrjs
3692fa225cbcSrjs  if((srcy < 0) || (srcy + height > image->height)) {
3693fa225cbcSrjs    return BadValue;
3694fa225cbcSrjs  }
3695fa225cbcSrjs
3696fa225cbcSrjs  if((dsty < 0) || (dsty + height > subpicture->height)) {
3697fa225cbcSrjs    return BadValue;
3698fa225cbcSrjs  }
3699fa225cbcSrjs
3700fa225cbcSrjs  for(i=0; i<height; i++) {
3701fa225cbcSrjs    memcpy((void *)((unsigned long)pI810Subpicture->data +
3702fa225cbcSrjs		    (unsigned long)pI810Subpicture->offsets[0] + dstx +
3703fa225cbcSrjs		    (1<<pI810Subpicture->pitch) * (i + dsty)),
3704fa225cbcSrjs	   (void *)((unsigned long)image->data +
3705fa225cbcSrjs		    (unsigned long)image->offsets[0] + srcx +
3706fa225cbcSrjs		    image->pitches[0] * (i + srcy))
3707fa225cbcSrjs	   ,width);
3708fa225cbcSrjs  }
3709fa225cbcSrjs
3710fa225cbcSrjs  return Success;
3711fa225cbcSrjs
3712fa225cbcSrjs}
3713fa225cbcSrjs
3714fa225cbcSrjs
3715fa225cbcSrjs/***************************************************************************
3716fa225cbcSrjs// Function: XvMCDestroySubpicture
3717fa225cbcSrjs// Description: Destroys the specified subpicture.
3718fa225cbcSrjs// Arguments:
3719fa225cbcSrjs//   display - Connection to the X server.
3720fa225cbcSrjs//   subpicture - Subpicture to be destroyed.
3721fa225cbcSrjs//
3722fa225cbcSrjs// Returns: Status
3723fa225cbcSrjs***************************************************************************/
3724fa225cbcSrjs_X_EXPORT Status XvMCDestroySubpicture(Display *display, XvMCSubpicture *subpicture) {
3725fa225cbcSrjs
3726fa225cbcSrjs  i810XvMCSubpicture *pI810Subpicture;
3727fa225cbcSrjs  i810XvMCContext *pI810XvMC;
3728fa225cbcSrjs
3729fa225cbcSrjs  if((display == NULL) || (subpicture == NULL)) {
3730fa225cbcSrjs    return BadValue;
3731fa225cbcSrjs  }
3732fa225cbcSrjs  if(!subpicture->privData) {
3733fa225cbcSrjs    return (error_base + XvMCBadSubpicture);
3734fa225cbcSrjs  }
3735fa225cbcSrjs  pI810Subpicture = (i810XvMCSubpicture *)subpicture->privData;
3736fa225cbcSrjs
3737fa225cbcSrjs  pI810XvMC = (i810XvMCContext *)pI810Subpicture->privContext;
3738fa225cbcSrjs  if(!pI810XvMC) {
3739fa225cbcSrjs    return (error_base + XvMCBadSubpicture);
3740fa225cbcSrjs  }
3741fa225cbcSrjs
3742fa225cbcSrjs
3743fa225cbcSrjs  if(pI810Subpicture->last_render) {
3744fa225cbcSrjs    XvMCSyncSubpicture(display,subpicture);
3745fa225cbcSrjs  }
3746fa225cbcSrjs
3747fa225cbcSrjs  _xvmc_destroy_subpicture(display,subpicture);
3748fa225cbcSrjs
3749fa225cbcSrjs  i810_free_privContext(pI810XvMC);
3750fa225cbcSrjs
3751fa225cbcSrjs  free(pI810Subpicture);
3752fa225cbcSrjs  subpicture->privData = NULL;
3753fa225cbcSrjs  return Success;
3754fa225cbcSrjs}
3755fa225cbcSrjs
3756fa225cbcSrjs
3757fa225cbcSrjs/***************************************************************************
3758fa225cbcSrjs// Function: XvMCSetSubpicturePalette
3759fa225cbcSrjs// Description: Set the subpictures palette
3760fa225cbcSrjs// Arguments:
3761fa225cbcSrjs//   display - Connection to the X server.
3762fa225cbcSrjs//   subpicture - Subpiture to set palette for.
3763fa225cbcSrjs//   palette - A pointer to an array holding the palette data. The array
3764fa225cbcSrjs//     is num_palette_entries * entry_bytes in size.
3765fa225cbcSrjs// Returns: Status
3766fa225cbcSrjs***************************************************************************/
3767fa225cbcSrjs
3768fa225cbcSrjs_X_EXPORT Status XvMCSetSubpicturePalette(Display *display, XvMCSubpicture *subpicture,
3769fa225cbcSrjs				unsigned char *palette) {
3770fa225cbcSrjs i810XvMCSubpicture *privSubpicture;
3771fa225cbcSrjs int i,j;
3772fa225cbcSrjs
3773fa225cbcSrjs if((display == NULL) || (subpicture == NULL)) {
3774fa225cbcSrjs   return BadValue;
3775fa225cbcSrjs }
3776fa225cbcSrjs if(subpicture->privData == NULL) {
3777fa225cbcSrjs   return (error_base + XvMCBadSubpicture);
3778fa225cbcSrjs }
3779fa225cbcSrjs privSubpicture = (i810XvMCSubpicture *)subpicture->privData;
3780fa225cbcSrjs
3781fa225cbcSrjs j=0;
3782fa225cbcSrjs for(i=0; i<16; i++) {
3783fa225cbcSrjs   privSubpicture->palette[0][i] = palette[j++];
3784fa225cbcSrjs   privSubpicture->palette[1][i] = palette[j++];
3785fa225cbcSrjs   privSubpicture->palette[2][i] = palette[j++];
3786fa225cbcSrjs }
3787fa225cbcSrjs return Success;
3788fa225cbcSrjs}
3789fa225cbcSrjs
3790fa225cbcSrjs/***************************************************************************
3791fa225cbcSrjs// Function: XvMCBlendSubpicture
3792fa225cbcSrjs// Description:
3793fa225cbcSrjs//    The behavior of this function is different depending on whether
3794fa225cbcSrjs//    or not the XVMC_BACKEND_SUBPICTURE flag is set in the XvMCSurfaceInfo.
3795fa225cbcSrjs//    i810 only support frontend behavior.
3796fa225cbcSrjs//
3797fa225cbcSrjs//    XVMC_BACKEND_SUBPICTURE not set ("frontend" behavior):
3798fa225cbcSrjs//
3799fa225cbcSrjs//    XvMCBlendSubpicture is a no-op in this case.
3800fa225cbcSrjs//
3801fa225cbcSrjs// Arguments:
3802fa225cbcSrjs//   display - Connection to the X server.
3803fa225cbcSrjs//   subpicture - The subpicture to be blended into the video.
3804fa225cbcSrjs//   target_surface - The surface to be displayed with the blended subpic.
3805fa225cbcSrjs//   source_surface - Source surface prior to blending.
3806fa225cbcSrjs//   subx, suby, subw, subh - The rectangle from the subpicture to use.
3807fa225cbcSrjs//   surfx, surfy, surfw, surfh - The rectangle in the surface to blend
3808fa225cbcSrjs//      blend the subpicture rectangle into. Scaling can ocure if
3809fa225cbcSrjs//      XVMC_SUBPICTURE_INDEPENDENT_SCALING is set.
3810fa225cbcSrjs//
3811fa225cbcSrjs// Returns: Status
3812fa225cbcSrjs***************************************************************************/
3813fa225cbcSrjs_X_EXPORT Status XvMCBlendSubpicture(Display *display, XvMCSurface *target_surface,
3814fa225cbcSrjs                         XvMCSubpicture *subpicture,
3815fa225cbcSrjs                         short subx, short suby,
3816fa225cbcSrjs                         unsigned short subw, unsigned short subh,
3817fa225cbcSrjs                         short surfx, short surfy,
3818fa225cbcSrjs                         unsigned short surfw, unsigned short surfh) {
3819fa225cbcSrjs
3820fa225cbcSrjs  return BadMatch;
3821fa225cbcSrjs}
3822fa225cbcSrjs
3823fa225cbcSrjs
3824fa225cbcSrjs
3825fa225cbcSrjs/***************************************************************************
3826fa225cbcSrjs// Function: XvMCBlendSubpicture2
3827fa225cbcSrjs// Description:
3828fa225cbcSrjs//    The behavior of this function is different depending on whether
3829fa225cbcSrjs//    or not the XVMC_BACKEND_SUBPICTURE flag is set in the XvMCSurfaceInfo.
3830fa225cbcSrjs//    i810 only supports frontend blending.
3831fa225cbcSrjs//
3832fa225cbcSrjs//    XVMC_BACKEND_SUBPICTURE not set ("frontend" behavior):
3833fa225cbcSrjs//
3834fa225cbcSrjs//    XvMCBlendSubpicture2 blends the source_surface and subpicture and
3835fa225cbcSrjs//    puts it in the target_surface.  This does not effect the status of
3836fa225cbcSrjs//    the source surface but will cause the target_surface to query
3837fa225cbcSrjs//    XVMC_RENDERING until the blend is completed.
3838fa225cbcSrjs//
3839fa225cbcSrjs// Arguments:
3840fa225cbcSrjs//   display - Connection to the X server.
3841fa225cbcSrjs//   subpicture - The subpicture to be blended into the video.
3842fa225cbcSrjs//   target_surface - The surface to be displayed with the blended subpic.
3843fa225cbcSrjs//   source_surface - Source surface prior to blending.
3844fa225cbcSrjs//   subx, suby, subw, subh - The rectangle from the subpicture to use.
3845fa225cbcSrjs//   surfx, surfy, surfw, surfh - The rectangle in the surface to blend
3846fa225cbcSrjs//      blend the subpicture rectangle into. Scaling can ocure if
3847fa225cbcSrjs//      XVMC_SUBPICTURE_INDEPENDENT_SCALING is set.
3848fa225cbcSrjs//
3849fa225cbcSrjs// Returns: Status
3850fa225cbcSrjs***************************************************************************/
3851fa225cbcSrjs_X_EXPORT Status XvMCBlendSubpicture2(Display *display,
3852fa225cbcSrjs                          XvMCSurface *source_surface,
3853fa225cbcSrjs                          XvMCSurface *target_surface,
3854fa225cbcSrjs                          XvMCSubpicture *subpicture,
3855fa225cbcSrjs                          short subx, short suby,
3856fa225cbcSrjs                          unsigned short subw, unsigned short subh,
3857fa225cbcSrjs                          short surfx, short surfy,
3858fa225cbcSrjs                          unsigned short surfw, unsigned short surfh) {
3859fa225cbcSrjs  drmBufPtr pDMA;
3860fa225cbcSrjs  unsigned int *data;
3861fa225cbcSrjs  i810XvMCContext *pI810XvMC;
3862fa225cbcSrjs  i810XvMCSubpicture *privSubpicture;
3863fa225cbcSrjs  i810XvMCSurface *privTarget;
3864fa225cbcSrjs  i810XvMCSurface *privSource;
3865fa225cbcSrjs  drm_i810_mc_t mc;
3866fa225cbcSrjs  int i,j;
3867fa225cbcSrjs
3868fa225cbcSrjs  if(display == NULL) {
3869fa225cbcSrjs    return BadValue;
3870fa225cbcSrjs  }
3871fa225cbcSrjs
3872fa225cbcSrjs  if(subpicture == NULL) {
3873fa225cbcSrjs    return (error_base + XvMCBadSubpicture);
3874fa225cbcSrjs  }
3875fa225cbcSrjs
3876fa225cbcSrjs  if((target_surface == NULL) || (source_surface == NULL)) {
3877fa225cbcSrjs    return (error_base + XvMCBadSurface);
3878fa225cbcSrjs  }
3879fa225cbcSrjs
3880fa225cbcSrjs  if((subpicture->xvimage_id != FOURCC_AI44) &&
3881fa225cbcSrjs     (subpicture->xvimage_id != FOURCC_IA44)) {
3882fa225cbcSrjs      return (error_base + XvMCBadSubpicture);
3883fa225cbcSrjs  }
3884fa225cbcSrjs
3885fa225cbcSrjs  if(!subpicture->privData) {
3886fa225cbcSrjs    return (error_base + XvMCBadSubpicture);
3887fa225cbcSrjs  }
3888fa225cbcSrjs  privSubpicture = (i810XvMCSubpicture *)subpicture->privData;
3889fa225cbcSrjs
3890fa225cbcSrjs  pI810XvMC = (i810XvMCContext *)privSubpicture->privContext;
3891fa225cbcSrjs  if(pI810XvMC == NULL) {
3892fa225cbcSrjs    return (error_base + XvMCBadSubpicture);
3893fa225cbcSrjs  }
3894fa225cbcSrjs
3895fa225cbcSrjs  if(!target_surface->privData) {
3896fa225cbcSrjs    return (error_base + XvMCBadSurface);
3897fa225cbcSrjs  }
3898fa225cbcSrjs  privTarget = (i810XvMCSurface *)target_surface->privData;
3899fa225cbcSrjs
3900fa225cbcSrjs  if(!source_surface->privData) {
3901fa225cbcSrjs    return (error_base + XvMCBadSurface);
3902fa225cbcSrjs  }
3903fa225cbcSrjs  privSource = (i810XvMCSurface *)source_surface->privData;
3904fa225cbcSrjs
3905fa225cbcSrjs
3906fa225cbcSrjs  /* Check that size isn't bigger than subpicture */
3907fa225cbcSrjs  if((subx + subw) > subpicture->width) {
3908fa225cbcSrjs    return BadValue;
3909fa225cbcSrjs  }
3910fa225cbcSrjs  if((suby + subh) > subpicture->height) {
3911fa225cbcSrjs    return BadValue;
3912fa225cbcSrjs  }
3913fa225cbcSrjs  /* Check that dest isn't bigger than surface */
3914fa225cbcSrjs  if((surfx + surfw) > target_surface->width) {
3915fa225cbcSrjs    return BadValue;
3916fa225cbcSrjs  }
3917fa225cbcSrjs  if((surfy + surfh) > target_surface->height) {
3918fa225cbcSrjs    return BadValue;
3919fa225cbcSrjs  }
3920fa225cbcSrjs  /* Make sure surfaces match */
3921fa225cbcSrjs  if(target_surface->width != source_surface->width) {
3922fa225cbcSrjs    return BadValue;
3923fa225cbcSrjs  }
3924fa225cbcSrjs  if(target_surface->height != source_surface->height) {
3925fa225cbcSrjs    return BadValue;
3926fa225cbcSrjs  }
3927fa225cbcSrjs
3928fa225cbcSrjs  /* Lock For DMA */
3929fa225cbcSrjs  I810_LOCK(pI810XvMC,0);
3930fa225cbcSrjs
3931fa225cbcSrjs  /* Allocate DMA buffer */
3932fa225cbcSrjs  pDMA = i810_get_free_buffer(pI810XvMC);
3933fa225cbcSrjs  data = pDMA->address;
3934fa225cbcSrjs
3935fa225cbcSrjs  /* Copy Y data first */
3936fa225cbcSrjs  /* SOURCE_COPY_BLT */
3937fa225cbcSrjs  *data++ = (2<<29) | (0x43<<22) | 0x4;
3938fa225cbcSrjs  *data++ = (0xcc<<16) | (1<<26) | (1<<privTarget->pitch);
3939fa225cbcSrjs  *data++ = (target_surface->height<<16) | target_surface->width;
3940fa225cbcSrjs  *data++ = privTarget->offset + privTarget->offsets[0];
3941fa225cbcSrjs  *data++ = (1<<privSource->pitch);
3942fa225cbcSrjs  *data++ = privSource->offset + privSource->offsets[0];
3943fa225cbcSrjs
3944fa225cbcSrjs  /* Select Context 1 for loading */
3945fa225cbcSrjs  *data++ = CMD_FLUSH;
3946fa225cbcSrjs  *data++ = (5<<23) | (1<<17) | (1<<8);
3947fa225cbcSrjs  *data++ = CMD_FLUSH;
3948fa225cbcSrjs
3949fa225cbcSrjs  /* Load Palette */
3950fa225cbcSrjs  *data++ = MAP_PALETTE_LOAD;
3951fa225cbcSrjs  /* 16 levels of alpha for each Y */
3952fa225cbcSrjs  switch(subpicture->xvimage_id) {
3953fa225cbcSrjs  case FOURCC_IA44:
3954fa225cbcSrjs    for(i=0; i<16; i++) {
3955fa225cbcSrjs      for(j=0; j<16; j++) {
3956fa225cbcSrjs        *data++ = (j<<12) | (j<<8) | privSubpicture->palette[0][i];
3957fa225cbcSrjs      }
3958fa225cbcSrjs    }
3959fa225cbcSrjs    break;
3960fa225cbcSrjs  case FOURCC_AI44:
3961fa225cbcSrjs    for(i=0; i<16; i++) {
3962fa225cbcSrjs      for(j=0; j<16; j++) {
3963fa225cbcSrjs        *data++ = (i<<12) | (i<<8) | privSubpicture->palette[0][j];
3964fa225cbcSrjs      }
3965fa225cbcSrjs    }
3966fa225cbcSrjs    break;
3967fa225cbcSrjs  }
3968fa225cbcSrjs  /* TARGET */
3969fa225cbcSrjs  /* *data++ = CMD_FLUSH; */
3970fa225cbcSrjs  /* *data++ = BOOLEAN_ENA_2; */
3971fa225cbcSrjs  *data++ = CMD_FLUSH;
3972fa225cbcSrjs  *data++ = DEST_BUFFER_INFO;
3973fa225cbcSrjs  *data++ = privTarget->dbi1y;
3974fa225cbcSrjs  *data++ = DEST_BUFFER_VAR;
3975fa225cbcSrjs  *data++ = privTarget->dbv1;
3976fa225cbcSrjs
3977fa225cbcSrjs  /* ALPHA */
3978fa225cbcSrjs  *data++ = CMD_MAP_INFO;
3979fa225cbcSrjs  *data++ = privSubpicture->mi1;
3980fa225cbcSrjs  *data++ = privSubpicture->mi2;
3981fa225cbcSrjs  *data++ = privSubpicture->mi3;
3982fa225cbcSrjs
3983fa225cbcSrjs  *data++ = VERTEX_FORMAT | (1<<8) | (3<<1);
3984fa225cbcSrjs  *data++ = BOOLEAN_ENA_1;
3985fa225cbcSrjs  *data++ = SRC_DEST_BLEND_MONO | (0x940);
3986fa225cbcSrjs  /* Map Filter */
3987fa225cbcSrjs  *data++ = (3<<29) | (0x1c<<24) | (2<<19) | (0x224);
3988fa225cbcSrjs
3989fa225cbcSrjs  /* Use context 1 */
3990fa225cbcSrjs  *data++ = CMD_FLUSH;
3991fa225cbcSrjs  *data++ = (5<<23) | (1<<16) | 1;
3992fa225cbcSrjs  *data++ = CMD_FLUSH;
3993fa225cbcSrjs
3994fa225cbcSrjs  /* Drawing Rect Info */
3995fa225cbcSrjs  *data++ = DRAWING_RECT_INFO;
3996fa225cbcSrjs  *data++ = 0x0;
3997fa225cbcSrjs  *data++ = 0x0;
3998fa225cbcSrjs  *data++ = 0x0;
3999fa225cbcSrjs  *data++ = 0x0;
4000fa225cbcSrjs  *data++ = 0x0;
4001fa225cbcSrjs
4002fa225cbcSrjs  /* GFXPRIMITIVE RECTANGLE */
4003fa225cbcSrjs  *data++ = (3<<29) | (0x1f<<24) | (0x7<<18) | 11;
4004fa225cbcSrjs  /* Bottom Right Vertex */
4005fa225cbcSrjs  *(float *)data++ = (float) (surfx + surfw);
4006fa225cbcSrjs  *(float *)data++ = (float) (surfy + surfh);
4007fa225cbcSrjs  *(float *)data++ = (float) (subx + subw);
4008fa225cbcSrjs  *(float *)data++ = (float) (suby + subh);
4009fa225cbcSrjs  /* Bottom Left Vertex */
4010fa225cbcSrjs  *(float *)data++ = (float) surfx;
4011fa225cbcSrjs  *(float *)data++ = (float) (surfy + surfh);
4012fa225cbcSrjs  *(float *)data++ = (float) subx;
4013fa225cbcSrjs  *(float *)data++ = (float) (suby + subh);
4014fa225cbcSrjs  /* Top Left Vertex */
4015fa225cbcSrjs  *(float *)data++ = (float) surfx;
4016fa225cbcSrjs  *(float *)data++ = (float) surfy;
4017fa225cbcSrjs  *(float *)data++ = (float) subx;
4018fa225cbcSrjs  *(float *)data++ = (float) suby;
4019fa225cbcSrjs
4020fa225cbcSrjs  /* Load and Use Context 0 */
4021fa225cbcSrjs  *data++ = CMD_FLUSH;
4022fa225cbcSrjs  *data++ = (5<<23) | (1<<17) | (1<<16);
4023fa225cbcSrjs  *data++ = CMD_FLUSH;
4024fa225cbcSrjs
4025fa225cbcSrjs  /* U data */
4026fa225cbcSrjs  /* SOURCE_COPY_BLT */
4027fa225cbcSrjs  *data++ = (2<<29) | (0x43<<22) | 0x4;
4028fa225cbcSrjs  *data++ = (0xcc<<16) | (1<<26) | (1<<(privTarget->pitch - 1));
4029fa225cbcSrjs  *data++ = (target_surface->height<<15) | (target_surface->width>>1);
4030fa225cbcSrjs  *data++ = (unsigned long)privTarget->offset + (unsigned long)privTarget->offsets[1];
4031fa225cbcSrjs  *data++ = (1<<(privSource->pitch - 1));
4032fa225cbcSrjs  *data++ = (unsigned long)privSource->offset + (unsigned long)privSource->offsets[1];
4033fa225cbcSrjs
4034fa225cbcSrjs  /* Context 1 select */
4035fa225cbcSrjs  *data++ = CMD_FLUSH;
4036fa225cbcSrjs  *data++ = (5<<23) | (1<<17) | (1<<8);
4037fa225cbcSrjs  *data++ = CMD_FLUSH;
4038fa225cbcSrjs  /* ALPHA PALETTE */
4039fa225cbcSrjs  *data++ = MAP_PALETTE_LOAD;
4040fa225cbcSrjs  /* 16 levels of alpha for each Y */
4041fa225cbcSrjs  switch(subpicture->xvimage_id) {
4042fa225cbcSrjs  case FOURCC_IA44:
4043fa225cbcSrjs    for(i=0; i<16; i++) {
4044fa225cbcSrjs      for(j=0; j<16; j++) {
4045fa225cbcSrjs        *data++ = (j<<12) | (j<<8) | privSubpicture->palette[2][i];
4046fa225cbcSrjs      }
4047fa225cbcSrjs    }
4048fa225cbcSrjs    break;
4049fa225cbcSrjs  case FOURCC_AI44:
4050fa225cbcSrjs    for(i=0; i<16; i++) {
4051fa225cbcSrjs      for(j=0; j<16; j++) {
4052fa225cbcSrjs        *data++ = (i<<12) | (i<<8) | privSubpicture->palette[2][j];
4053fa225cbcSrjs      }
4054fa225cbcSrjs    }
4055fa225cbcSrjs    break;
4056fa225cbcSrjs  }
4057fa225cbcSrjs  /* TARGET */
4058fa225cbcSrjs  *data++ = CMD_FLUSH;
4059fa225cbcSrjs  *data++ = BOOLEAN_ENA_2;
4060fa225cbcSrjs  *data++ = CMD_FLUSH;
4061fa225cbcSrjs  *data++ = DEST_BUFFER_INFO;
4062fa225cbcSrjs  *data++ = privTarget->dbi1u;
4063fa225cbcSrjs  *data++ = DEST_BUFFER_VAR;
4064fa225cbcSrjs  *data++ = privTarget->dbv1;
4065fa225cbcSrjs
4066fa225cbcSrjs  /* ALPHA */
4067fa225cbcSrjs  *data++ = CMD_MAP_INFO;
4068fa225cbcSrjs  *data++ = privSubpicture->mi1;
4069fa225cbcSrjs  *data++ = privSubpicture->mi2;
4070fa225cbcSrjs  *data++ = privSubpicture->mi3;
4071fa225cbcSrjs
4072fa225cbcSrjs  *data++ = VERTEX_FORMAT | (1<<8) | (3<<1);
4073fa225cbcSrjs  *data++ = BOOLEAN_ENA_1;
4074fa225cbcSrjs  *data++ = SRC_DEST_BLEND_MONO | (0x940);
4075fa225cbcSrjs  /* Map Filter */
4076fa225cbcSrjs  *data++ = (3<<29) | (0x1c<<24) | (2<<19) | (1<<16) | (0x224);
4077fa225cbcSrjs
4078fa225cbcSrjs  /* Use context 1 */
4079fa225cbcSrjs  *data++ = CMD_FLUSH;
4080fa225cbcSrjs  *data++ = (5<<23) | (1<<16) | 1;
4081fa225cbcSrjs  *data++ = CMD_FLUSH;
4082fa225cbcSrjs
4083fa225cbcSrjs  /* Drawing Rect Info */
4084fa225cbcSrjs  *data++ = (3<<29) | (0x1d<<24) | (0x80<<16) | 3;
4085fa225cbcSrjs  *data++ = 0;
4086fa225cbcSrjs  *data++ = 0;
4087fa225cbcSrjs  *data++ = 0;
4088fa225cbcSrjs  *data++ = 0;
4089fa225cbcSrjs  *data++ = 0;
4090fa225cbcSrjs
4091fa225cbcSrjs  /* Rectangle */
4092fa225cbcSrjs  *data++ = (3<<29) | (0x1f<<24) | (0x7<<18) | 11;
4093fa225cbcSrjs  /* Bottom Right */
4094fa225cbcSrjs  *(float *)data++ = (float) ((surfx + surfw)>>1);
4095fa225cbcSrjs  *(float *)data++ = (float) ((surfy + surfh)>>1);
4096fa225cbcSrjs  *(float *)data++ = (float) subx + subw;
4097fa225cbcSrjs  *(float *)data++ = (float) suby + subh;
4098fa225cbcSrjs  /* Bottom Left */
4099fa225cbcSrjs  *(float *)data++ = (float) (surfx>>1);
4100fa225cbcSrjs  *(float *)data++ = (float) ((surfy + surfh)>>1);
4101fa225cbcSrjs  *(float *)data++ = (float) subx;
4102fa225cbcSrjs  *(float *)data++ = (float) suby + subh;
4103fa225cbcSrjs  /* Top Left */
4104fa225cbcSrjs  *(float *)data++ = (float) (surfx>>1);
4105fa225cbcSrjs  *(float *)data++ = (float) (surfy>>1);
4106fa225cbcSrjs  *(float *)data++ = (float) subx;
4107fa225cbcSrjs  *(float *)data++ = (float) suby;
4108fa225cbcSrjs
4109fa225cbcSrjs  /* Load and Use Context 0 */
4110fa225cbcSrjs  *data++ = CMD_FLUSH;
4111fa225cbcSrjs  *data++ = (5<<23) | (1<<17) | (1<<16);
4112fa225cbcSrjs  *data++ = CMD_FLUSH;
4113fa225cbcSrjs
4114fa225cbcSrjs  /* V data */
4115fa225cbcSrjs  /* SOURCE_COPY_BLT */
4116fa225cbcSrjs  *data++ = (2<<29) | (0x43<<22) | 0x4;
4117fa225cbcSrjs  *data++ = (0xcc<<16) | (1<<26) | (1<<(privTarget->pitch - 1));
4118fa225cbcSrjs  *data++ = (target_surface->height<<15) | (target_surface->width>>1);
4119fa225cbcSrjs  *data++ = (unsigned long)privTarget->offset + (unsigned long)privTarget->offsets[2];
4120fa225cbcSrjs  *data++ = (1<<(privSource->pitch - 1));
4121fa225cbcSrjs  *data++ = (unsigned long)privSource->offset + (unsigned long)privSource->offsets[2];
4122fa225cbcSrjs
4123fa225cbcSrjs  /* Context 1 select */
4124fa225cbcSrjs  *data++ = CMD_FLUSH;
4125fa225cbcSrjs  *data++ = (5<<23) | (1<<17) | (1<<8);
4126fa225cbcSrjs  *data++ = CMD_FLUSH;
4127fa225cbcSrjs
4128fa225cbcSrjs  /* ALPHA PALETTE */
4129fa225cbcSrjs  *data++ = MAP_PALETTE_LOAD;
4130fa225cbcSrjs  /* 16 levels of alpha for each Y */
4131fa225cbcSrjs  switch(subpicture->xvimage_id) {
4132fa225cbcSrjs  case FOURCC_IA44:
4133fa225cbcSrjs    for(i=0; i<16; i++) {
4134fa225cbcSrjs      for(j=0; j<16; j++) {
4135fa225cbcSrjs        *data++ = (j<<12) | (j<<8) | privSubpicture->palette[1][i];
4136fa225cbcSrjs      }
4137fa225cbcSrjs    }
4138fa225cbcSrjs    break;
4139fa225cbcSrjs  case FOURCC_AI44:
4140fa225cbcSrjs    for(i=0; i<16; i++) {
4141fa225cbcSrjs      for(j=0; j<16; j++) {
4142fa225cbcSrjs        *data++ = (i<<12) | (i<<8) | privSubpicture->palette[1][j];
4143fa225cbcSrjs      }
4144fa225cbcSrjs    }
4145fa225cbcSrjs    break;
4146fa225cbcSrjs  }
4147fa225cbcSrjs  /* TARGET */
4148fa225cbcSrjs  *data++ = CMD_FLUSH;
4149fa225cbcSrjs  *data++ = BOOLEAN_ENA_2;
4150fa225cbcSrjs  *data++ = CMD_FLUSH;
4151fa225cbcSrjs  *data++ = DEST_BUFFER_INFO;
4152fa225cbcSrjs  *data++ = privTarget->dbi1v;
4153fa225cbcSrjs  *data++ = DEST_BUFFER_VAR;
4154fa225cbcSrjs  *data++ = privTarget->dbv1;
4155fa225cbcSrjs
4156fa225cbcSrjs  /* ALPHA */
4157fa225cbcSrjs  *data++ = CMD_MAP_INFO;
4158fa225cbcSrjs  *data++ = privSubpicture->mi1;
4159fa225cbcSrjs  *data++ = privSubpicture->mi2;
4160fa225cbcSrjs  *data++ = privSubpicture->mi3;
4161fa225cbcSrjs
4162fa225cbcSrjs  *data++ = VERTEX_FORMAT | (1<<8) | (3<<1);
4163fa225cbcSrjs  *data++ = BOOLEAN_ENA_1;
4164fa225cbcSrjs  *data++ = SRC_DEST_BLEND_MONO | (0x940);
4165fa225cbcSrjs  /* Map Filter */
4166fa225cbcSrjs  *data++ = (3<<29) | (0x1c<<24) | (2<<19) | (1<<16) | (0x224);
4167fa225cbcSrjs
4168fa225cbcSrjs  /* Use context 1 */
4169fa225cbcSrjs  *data++ = CMD_FLUSH;
4170fa225cbcSrjs  *data++ = (5<<23) | (1<<16) | 1;
4171fa225cbcSrjs  *data++ = CMD_FLUSH;
4172fa225cbcSrjs
4173fa225cbcSrjs  /* Drawing Rect Info */
4174fa225cbcSrjs  *data++ = (3<<29) | (0x1d<<24) | (0x80<<16) | 3;
4175fa225cbcSrjs  *data++ = 0;
4176fa225cbcSrjs  *data++ = 0;
4177fa225cbcSrjs  *data++ = 0;
4178fa225cbcSrjs  *data++ = 0;
4179fa225cbcSrjs  *data++ = 0;
4180fa225cbcSrjs
4181fa225cbcSrjs  /* Rectangle */
4182fa225cbcSrjs  *data++ = (3<<29) | (0x1f<<24) | (0x7<<18) | 11;
4183fa225cbcSrjs  /* Bottom Right */
4184fa225cbcSrjs  *(float *)data++ = (float) ((surfx + surfw)>>1);
4185fa225cbcSrjs  *(float *)data++ = (float) ((surfy + surfh)>>1);
4186fa225cbcSrjs  *(float *)data++ = (float) subx + subw;
4187fa225cbcSrjs  *(float *)data++ = (float) suby + subh;
4188fa225cbcSrjs  /* Bottom Left */
4189fa225cbcSrjs  *(float *)data++ = (float) (surfx>>1);
4190fa225cbcSrjs  *(float *)data++ = (float) ((surfy + surfh)>>1);
4191fa225cbcSrjs  *(float *)data++ = (float) subx;
4192fa225cbcSrjs  *(float *)data++ = (float) suby + subh;
4193fa225cbcSrjs  /* Top Left */
4194fa225cbcSrjs  *(float *)data++ = (float) (surfx>>1);
4195fa225cbcSrjs  *(float *)data++ = (float) (surfy>>1);
4196fa225cbcSrjs  *(float *)data++ = (float) subx;
4197fa225cbcSrjs  *(float *)data++ = (float) suby;
4198fa225cbcSrjs
4199fa225cbcSrjs  /* Load and Use Context 0 */
4200fa225cbcSrjs  *data++ = CMD_FLUSH;
4201fa225cbcSrjs  *data++ = (5<<23) | (1<<17) | (1<<16);
4202fa225cbcSrjs  *data++ = CMD_FLUSH;
4203fa225cbcSrjs
4204fa225cbcSrjs
4205fa225cbcSrjs  /* Dispatch */
4206fa225cbcSrjs  pDMA->used = (unsigned long)data - (unsigned long)pDMA->address;
4207fa225cbcSrjs  mc.idx = pDMA->idx;
4208fa225cbcSrjs  mc.used = pDMA->used;
4209fa225cbcSrjs  mc.last_render = ++pI810XvMC->last_render;
4210fa225cbcSrjs  privTarget->last_render = pI810XvMC->last_render;
4211fa225cbcSrjs  I810_MC(pI810XvMC,mc);
4212fa225cbcSrjs
4213fa225cbcSrjs  I810_UNLOCK(pI810XvMC);
4214fa225cbcSrjs  return Success;
4215fa225cbcSrjs}
4216fa225cbcSrjs
4217fa225cbcSrjs
4218fa225cbcSrjs
4219fa225cbcSrjs/***************************************************************************
4220fa225cbcSrjs// Function: XvMCSyncSubpicture
4221fa225cbcSrjs// Description: This function blocks until all composite/clear requests on
4222fa225cbcSrjs//              the subpicture have been complete.
4223fa225cbcSrjs// Arguments:
4224fa225cbcSrjs//   display - Connection to the X server.
4225fa225cbcSrjs//   subpicture - The subpicture to synchronize
4226fa225cbcSrjs//
4227fa225cbcSrjs// Returns: Status
4228fa225cbcSrjs***************************************************************************/
4229fa225cbcSrjs_X_EXPORT Status XvMCSyncSubpicture(Display *display, XvMCSubpicture *subpicture) {
4230fa225cbcSrjs  Status ret;
4231fa225cbcSrjs  int stat=0;
4232fa225cbcSrjs  do {
4233fa225cbcSrjs    ret = XvMCGetSubpictureStatus(display,subpicture,&stat);
4234fa225cbcSrjs  }while(!ret && (stat & XVMC_RENDERING));
4235fa225cbcSrjs  return ret;
4236fa225cbcSrjs}
4237fa225cbcSrjs
4238fa225cbcSrjs
4239fa225cbcSrjs
4240fa225cbcSrjs/***************************************************************************
4241fa225cbcSrjs// Function: XvMCFlushSubpicture
4242fa225cbcSrjs// Description: This function commits pending composite/clear requests to
4243fa225cbcSrjs//              ensure that they will be completed in a finite amount of
4244fa225cbcSrjs//              time.
4245fa225cbcSrjs// Arguments:
4246fa225cbcSrjs//   display - Connection to the X server.
4247fa225cbcSrjs//   subpicture - The subpicture whos compsiting should be flushed
4248fa225cbcSrjs//
4249fa225cbcSrjs// Returns: Status
4250fa225cbcSrjs// NOTES: i810 always dispatches commands so flush is a no-op
4251fa225cbcSrjs***************************************************************************/
4252fa225cbcSrjs_X_EXPORT Status XvMCFlushSubpicture(Display *display, XvMCSubpicture *subpicture) {
4253fa225cbcSrjs  if(display == NULL) {
4254fa225cbcSrjs    return BadValue;
4255fa225cbcSrjs  }
4256fa225cbcSrjs  if(subpicture == NULL) {
4257fa225cbcSrjs    return (error_base + XvMCBadSubpicture);
4258fa225cbcSrjs  }
4259fa225cbcSrjs
4260fa225cbcSrjs  return Success;
4261fa225cbcSrjs}
4262fa225cbcSrjs
4263fa225cbcSrjs
4264fa225cbcSrjs
4265fa225cbcSrjs/***************************************************************************
4266fa225cbcSrjs// Function: XvMCGetSubpictureStatus
4267fa225cbcSrjs// Description: This function gets the current status of a subpicture
4268fa225cbcSrjs//
4269fa225cbcSrjs// Arguments:
4270fa225cbcSrjs//   display - Connection to the X server.
4271fa225cbcSrjs//   subpicture - The subpicture whos status is being queried
4272fa225cbcSrjs//   stat - The status of the subpicture. It can be any of the following
4273fa225cbcSrjs//          OR'd together:
4274fa225cbcSrjs//          XVMC_RENDERING  - Last composite or clear request not completed
4275fa225cbcSrjs//          XVMC_DISPLAYING - Suppicture currently being displayed.
4276fa225cbcSrjs//
4277fa225cbcSrjs// Returns: Status
4278fa225cbcSrjs// Notes: i810 always blends into a third surface so the subpicture is
4279fa225cbcSrjs//  never actually displaying, only a copy of it is displaying. We only
4280fa225cbcSrjs//  have to worry about the rendering case.
4281fa225cbcSrjs***************************************************************************/
4282fa225cbcSrjs_X_EXPORT Status XvMCGetSubpictureStatus(Display *display, XvMCSubpicture *subpicture,
4283fa225cbcSrjs                             int *stat) {
4284fa225cbcSrjs
4285fa225cbcSrjs  i810XvMCSubpicture *privSubpicture;
4286fa225cbcSrjs  i810XvMCContext *pI810XvMC;
4287fa225cbcSrjs
4288fa225cbcSrjs  if((display == NULL) || (stat == NULL)) {
4289fa225cbcSrjs    return BadValue;
4290fa225cbcSrjs  }
4291fa225cbcSrjs  if((subpicture == NULL) || (subpicture->privData == NULL)) {
4292fa225cbcSrjs    return (error_base + XvMCBadSubpicture);
4293fa225cbcSrjs  }
4294fa225cbcSrjs  *stat = 0;
4295fa225cbcSrjs  privSubpicture = (i810XvMCSubpicture *)subpicture->privData;
4296fa225cbcSrjs
4297fa225cbcSrjs  pI810XvMC = (i810XvMCContext *)privSubpicture->privContext;
4298fa225cbcSrjs  if(pI810XvMC == NULL) {
4299fa225cbcSrjs    return (error_base + XvMCBadSubpicture);
4300fa225cbcSrjs  }
4301fa225cbcSrjs
4302fa225cbcSrjs  I810_LOCK(pI810XvMC,0);
4303fa225cbcSrjs
4304fa225cbcSrjs  if(privSubpicture->last_render &&
4305fa225cbcSrjs      (privSubpicture->last_render > GET_RSTATUS(pI810XvMC))) {
4306fa225cbcSrjs    *stat |= XVMC_RENDERING;
4307fa225cbcSrjs  }
4308fa225cbcSrjs  I810_UNLOCK(pI810XvMC);
4309fa225cbcSrjs
4310fa225cbcSrjs  return Success;
4311fa225cbcSrjs}
4312fa225cbcSrjs
4313fa225cbcSrjs#define NUM_XVMC_ATTRIBUTES 4
4314fa225cbcSrjsstatic XvAttribute I810_XVMC_ATTRIBUTES[] = {
4315fa225cbcSrjs  {XvGettable | XvSettable, 0, 0xffffff, "XV_COLORKEY"},
4316fa225cbcSrjs  {XvGettable | XvSettable, -127, +127, "XV_BRIGHTNESS"},
4317fa225cbcSrjs  {XvGettable | XvSettable, 0, 0x1ff, "XV_CONTRAST"},
4318fa225cbcSrjs  {XvGettable | XvSettable, 0, 0x3ff, "XV_SATURATION"}
4319fa225cbcSrjs};
4320fa225cbcSrjs
4321fa225cbcSrjs
4322fa225cbcSrjs/***************************************************************************
4323fa225cbcSrjs// Function: XvMCQueryAttributes
4324fa225cbcSrjs// Description: An array of XvAttributes of size "number" is returned by
4325fa225cbcSrjs//   this function. If there are no attributes, NULL is returned and number
4326fa225cbcSrjs//   is set to 0. The array may be freed with xfree().
4327fa225cbcSrjs//
4328fa225cbcSrjs// Arguments:
4329fa225cbcSrjs//   display - Connection to the X server.
4330fa225cbcSrjs//   context - The context whos attributes we are querying.
4331fa225cbcSrjs//   number - The number of returned atoms.
4332fa225cbcSrjs//
4333fa225cbcSrjs// Returns:
4334fa225cbcSrjs//  An array of XvAttributes.
4335fa225cbcSrjs// Notes:
4336fa225cbcSrjs//   For i810 we support these Attributes:
4337fa225cbcSrjs//    XV_COLORKEY: The colorkey value, initialized from the Xv value at
4338fa225cbcSrjs//                 context creation time.
4339fa225cbcSrjs//    XV_BRIGHTNESS
4340fa225cbcSrjs//    XV_CONTRAST
4341fa225cbcSrjs//    XV_SATURATION
4342fa225cbcSrjs***************************************************************************/
4343fa225cbcSrjs_X_EXPORT XvAttribute *XvMCQueryAttributes(Display *display, XvMCContext *context,
4344fa225cbcSrjs				 int *number) {
4345fa225cbcSrjs  i810XvMCContext *pI810XvMC;
4346fa225cbcSrjs  XvAttribute *attributes;
4347fa225cbcSrjs
4348fa225cbcSrjs  if(number == NULL) {
4349fa225cbcSrjs    return NULL;
4350fa225cbcSrjs  }
4351fa225cbcSrjs  if(display == NULL) {
4352fa225cbcSrjs    *number = 0;
4353fa225cbcSrjs    return NULL;
4354fa225cbcSrjs  }
4355fa225cbcSrjs  if(context == NULL) {
4356fa225cbcSrjs    *number = 0;
4357fa225cbcSrjs    return NULL;
4358fa225cbcSrjs  }
4359fa225cbcSrjs  pI810XvMC = context->privData;
4360fa225cbcSrjs  if(pI810XvMC == NULL) {
4361fa225cbcSrjs    *number = 0;
4362fa225cbcSrjs    return NULL;
4363fa225cbcSrjs  }
4364fa225cbcSrjs
4365fa225cbcSrjs  attributes = (XvAttribute *)malloc(NUM_XVMC_ATTRIBUTES *
4366fa225cbcSrjs				     sizeof(XvAttribute));
4367fa225cbcSrjs  if(attributes == NULL) {
4368fa225cbcSrjs    *number = 0;
4369fa225cbcSrjs    return NULL;
4370fa225cbcSrjs  }
4371fa225cbcSrjs
4372fa225cbcSrjs  memcpy(attributes,I810_XVMC_ATTRIBUTES,(NUM_XVMC_ATTRIBUTES *
4373fa225cbcSrjs					  sizeof(XvAttribute)));
4374fa225cbcSrjs
4375fa225cbcSrjs  *number = NUM_XVMC_ATTRIBUTES;
4376fa225cbcSrjs  return attributes;
4377fa225cbcSrjs}
4378fa225cbcSrjs
4379fa225cbcSrjs/***************************************************************************
4380fa225cbcSrjs// Function: XvMCSetAttribute
4381fa225cbcSrjs// Description: This function sets a context-specific attribute.
4382fa225cbcSrjs//
4383fa225cbcSrjs// Arguments:
4384fa225cbcSrjs//   display - Connection to the X server.
4385fa225cbcSrjs//   context - The context whos attributes we are querying.
4386fa225cbcSrjs//   attribute - The X atom of the attribute to be changed.
4387fa225cbcSrjs//   value - The new value for the attribute.
4388fa225cbcSrjs//
4389fa225cbcSrjs// Returns:
4390fa225cbcSrjs//  Status
4391fa225cbcSrjs// Notes:
4392fa225cbcSrjs//   For i810 we support these Attributes:
4393fa225cbcSrjs//    XV_COLORKEY: The colorkey value, initialized from the Xv value at
4394fa225cbcSrjs//                 context creation time.
4395fa225cbcSrjs//    XV_BRIGHTNESS
4396fa225cbcSrjs//    XV_CONTRAST
4397fa225cbcSrjs//    XV_SATURATION
4398fa225cbcSrjs***************************************************************************/
4399fa225cbcSrjs_X_EXPORT Status XvMCSetAttribute(Display *display, XvMCContext *context,
4400fa225cbcSrjs			Atom attribute, int value) {
4401fa225cbcSrjs  i810XvMCContext *pI810XvMC;
4402fa225cbcSrjs
4403fa225cbcSrjs  if(display == NULL) {
4404fa225cbcSrjs    return BadValue;
4405fa225cbcSrjs  }
4406fa225cbcSrjs  if(context == NULL) {
4407fa225cbcSrjs    return (error_base + XvMCBadContext);
4408fa225cbcSrjs  }
4409fa225cbcSrjs  pI810XvMC = context->privData;
4410fa225cbcSrjs  if(pI810XvMC == NULL) {
4411fa225cbcSrjs    return (error_base + XvMCBadContext);
4412fa225cbcSrjs  }
4413fa225cbcSrjs
4414fa225cbcSrjs  if(attribute == pI810XvMC->xv_colorkey) {
4415fa225cbcSrjs    if((value < I810_XVMC_ATTRIBUTES[0].min_value) ||
4416fa225cbcSrjs       (value > I810_XVMC_ATTRIBUTES[0].max_value)) {
4417fa225cbcSrjs      return BadValue;
4418fa225cbcSrjs    }
4419fa225cbcSrjs    pI810XvMC->colorkey = value;
4420fa225cbcSrjs    return Success;
4421fa225cbcSrjs  }
4422fa225cbcSrjs  if(attribute == pI810XvMC->xv_brightness) {
4423fa225cbcSrjs    if((value < I810_XVMC_ATTRIBUTES[1].min_value) ||
4424fa225cbcSrjs       (value > I810_XVMC_ATTRIBUTES[1].max_value)) {
4425fa225cbcSrjs      return BadValue;
4426fa225cbcSrjs    }
4427fa225cbcSrjs    pI810XvMC->brightness = value;
4428fa225cbcSrjs    return Success;
4429fa225cbcSrjs  }
4430fa225cbcSrjs  if(attribute == pI810XvMC->xv_saturation) {
4431fa225cbcSrjs    if((value < I810_XVMC_ATTRIBUTES[2].min_value) ||
4432fa225cbcSrjs       (value > I810_XVMC_ATTRIBUTES[2].max_value)) {
4433fa225cbcSrjs      return BadValue;
4434fa225cbcSrjs    }
4435fa225cbcSrjs    pI810XvMC->saturation = value;
4436fa225cbcSrjs    return Success;
4437fa225cbcSrjs  }
4438fa225cbcSrjs  if(attribute == pI810XvMC->xv_contrast) {
4439fa225cbcSrjs    if((value < I810_XVMC_ATTRIBUTES[3].min_value) ||
4440fa225cbcSrjs       (value > I810_XVMC_ATTRIBUTES[3].max_value)) {
4441fa225cbcSrjs      return BadValue;
4442fa225cbcSrjs    }
4443fa225cbcSrjs    pI810XvMC->contrast = value;
4444fa225cbcSrjs    return Success;
4445fa225cbcSrjs  }
4446fa225cbcSrjs  return BadValue;
4447fa225cbcSrjs}
4448fa225cbcSrjs
4449fa225cbcSrjs/***************************************************************************
4450fa225cbcSrjs// Function: XvMCGetAttribute
4451fa225cbcSrjs// Description: This function queries a context-specific attribute and
4452fa225cbcSrjs//   returns the value.
4453fa225cbcSrjs//
4454fa225cbcSrjs// Arguments:
4455fa225cbcSrjs//   display - Connection to the X server.
4456fa225cbcSrjs//   context - The context whos attributes we are querying.
4457fa225cbcSrjs//   attribute - The X atom of the attribute to be queried
4458fa225cbcSrjs//   value - The returned attribute value
4459fa225cbcSrjs//
4460fa225cbcSrjs// Returns:
4461fa225cbcSrjs//  Status
4462fa225cbcSrjs// Notes:
4463fa225cbcSrjs//   For i810 we support these Attributes:
4464fa225cbcSrjs//    XV_COLORKEY: The colorkey value, initialized from the Xv value at
4465fa225cbcSrjs//                 context creation time.
4466fa225cbcSrjs//    XV_BRIGHTNESS
4467fa225cbcSrjs//    XV_CONTRAST
4468fa225cbcSrjs//    XV_SATURATION
4469fa225cbcSrjs***************************************************************************/
4470fa225cbcSrjs_X_EXPORT Status XvMCGetAttribute(Display *display, XvMCContext *context,
4471fa225cbcSrjs			Atom attribute, int *value) {
4472fa225cbcSrjs  i810XvMCContext *pI810XvMC;
4473fa225cbcSrjs
4474fa225cbcSrjs  if(display == NULL) {
4475fa225cbcSrjs    return BadValue;
4476fa225cbcSrjs  }
4477fa225cbcSrjs  if(context == NULL) {
4478fa225cbcSrjs    return (error_base + XvMCBadContext);
4479fa225cbcSrjs  }
4480fa225cbcSrjs  pI810XvMC = context->privData;
4481fa225cbcSrjs  if(pI810XvMC == NULL) {
4482fa225cbcSrjs    return (error_base + XvMCBadContext);
4483fa225cbcSrjs  }
4484fa225cbcSrjs  if(value == NULL) {
4485fa225cbcSrjs    return BadValue;
4486fa225cbcSrjs  }
4487fa225cbcSrjs
4488fa225cbcSrjs  if(attribute == pI810XvMC->xv_colorkey) {
4489fa225cbcSrjs    *value = pI810XvMC->colorkey;
4490fa225cbcSrjs    return Success;
4491fa225cbcSrjs  }
4492fa225cbcSrjs  if(attribute == pI810XvMC->xv_brightness) {
4493fa225cbcSrjs    *value = pI810XvMC->brightness;
4494fa225cbcSrjs    return Success;
4495fa225cbcSrjs  }
4496fa225cbcSrjs  if(attribute == pI810XvMC->xv_saturation) {
4497fa225cbcSrjs    *value = pI810XvMC->saturation;
4498fa225cbcSrjs    return Success;
4499fa225cbcSrjs  }
4500fa225cbcSrjs  if(attribute == pI810XvMC->xv_contrast) {
4501fa225cbcSrjs    *value = pI810XvMC->contrast;
4502fa225cbcSrjs    return Success;
4503fa225cbcSrjs  }
4504fa225cbcSrjs  return BadValue;
4505fa225cbcSrjs}
4506fa225cbcSrjs
4507fa225cbcSrjs
4508fa225cbcSrjs
4509fa225cbcSrjs
4510