1428d7b3dSmrg/*************************************************************************** 2428d7b3dSmrg 3428d7b3dSmrgCopyright 2001 Intel Corporation. All Rights Reserved. 4428d7b3dSmrg 5428d7b3dSmrgPermission is hereby granted, free of charge, to any person obtaining a 6428d7b3dSmrgcopy of this software and associated documentation files (the 7428d7b3dSmrg"Software"), to deal in the Software without restriction, including 8428d7b3dSmrgwithout limitation the rights to use, copy, modify, merge, publish, 9428d7b3dSmrgdistribute, sub license, and/or sell copies of the Software, and to 10428d7b3dSmrgpermit persons to whom the Software is furnished to do so, subject to 11428d7b3dSmrgthe following conditions: 12428d7b3dSmrg 13428d7b3dSmrgThe above copyright notice and this permission notice (including the 14428d7b3dSmrgnext paragraph) shall be included in all copies or substantial portions 15428d7b3dSmrgof the Software. 16428d7b3dSmrg 17428d7b3dSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18428d7b3dSmrgOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19428d7b3dSmrgMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 20428d7b3dSmrgIN NO EVENT SHALL INTEL, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, 21428d7b3dSmrgDAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 22428d7b3dSmrgOTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR 23428d7b3dSmrgTHE USE OR OTHER DEALINGS IN THE SOFTWARE. 24428d7b3dSmrg 25428d7b3dSmrg**************************************************************************/ 26428d7b3dSmrg 27428d7b3dSmrg/************************************************************************* 28428d7b3dSmrg** File libI810XvMC.c 29428d7b3dSmrg** 30428d7b3dSmrg** Authors: 31428d7b3dSmrg** Matt Sottek <matthew.j.sottek@intel.com> 32428d7b3dSmrg** Bob Paauwe <bob.j.paauwe@intel.com> 33428d7b3dSmrg** 34428d7b3dSmrg** 35428d7b3dSmrg***************************************************************************/ 36428d7b3dSmrg#include <stdio.h> 37428d7b3dSmrg#include <stdlib.h> 38428d7b3dSmrg#include <unistd.h> 39428d7b3dSmrg#include <errno.h> 40428d7b3dSmrg#include <signal.h> 41428d7b3dSmrg#include <fcntl.h> 42428d7b3dSmrg#include <dirent.h> 43428d7b3dSmrg#include <string.h> 44428d7b3dSmrg 45428d7b3dSmrg#include <sys/ioctl.h> 46428d7b3dSmrg#include <X11/Xlibint.h> 47428d7b3dSmrg#include <fourcc.h> 48428d7b3dSmrg#include <X11/extensions/Xv.h> 49428d7b3dSmrg#include <X11/extensions/Xvlib.h> 50428d7b3dSmrg#include <X11/extensions/XvMC.h> 51428d7b3dSmrg#include <X11/extensions/XvMClib.h> 52428d7b3dSmrg#include "I810XvMC.h" 53428d7b3dSmrg 54428d7b3dSmrgstatic int error_base; 55428d7b3dSmrgstatic int event_base; 56428d7b3dSmrg 57428d7b3dSmrg/*************************************************************************** 58428d7b3dSmrg// Function: i810_get_free_buffer 59428d7b3dSmrg// Description: Allocates a free dma page using kernel ioctls, then 60428d7b3dSmrg// programs the data into the already allocated dma buffer list. 61428d7b3dSmrg// Arguments: pI810XvMC private data structure from the current context. 62428d7b3dSmrg// Notes: We faked the drmMapBufs for the i810's security so now we have 63428d7b3dSmrg// to insert an allocated page into the correct spot in the faked 64428d7b3dSmrg// list to keep up appearences. 65428d7b3dSmrg// Concept for this function was taken from Mesa sources. 66428d7b3dSmrg// Returns: drmBufPtr containing the information about the allocated page. 67428d7b3dSmrg***************************************************************************/ 68428d7b3dSmrgdrmBufPtr i810_get_free_buffer(i810XvMCContext *pI810XvMC) { 69428d7b3dSmrg drmI810DMA dma; 70428d7b3dSmrg drmBufPtr buf; 71428d7b3dSmrg 72428d7b3dSmrg dma.granted = 0; 73428d7b3dSmrg dma.request_size = 4096; 74428d7b3dSmrg while(!dma.granted) { 75428d7b3dSmrg if(GET_BUFFER(pI810XvMC, dma) || !dma.granted) 76428d7b3dSmrg FLUSH(pI810XvMC); 77428d7b3dSmrg } /* No DMA granted */ 78428d7b3dSmrg 79428d7b3dSmrg buf = &(pI810XvMC->dmabufs->list[dma.request_idx]); 80428d7b3dSmrg buf->idx = dma.request_idx; 81428d7b3dSmrg buf->used = 0; 82428d7b3dSmrg buf->total = dma.request_size; 83428d7b3dSmrg buf->address = (drmAddress)dma.virtual; 84428d7b3dSmrg return buf; 85428d7b3dSmrg} 86428d7b3dSmrg 87428d7b3dSmrg/*************************************************************************** 88428d7b3dSmrg// Function: free_privContext 89428d7b3dSmrg// Description: Free's the private context structure if the reference 90428d7b3dSmrg// count is 0. 91428d7b3dSmrg***************************************************************************/ 92428d7b3dSmrgvoid i810_free_privContext(i810XvMCContext *pI810XvMC) { 93428d7b3dSmrg 94428d7b3dSmrg I810_LOCK(pI810XvMC,DRM_LOCK_QUIESCENT); 95428d7b3dSmrg 96428d7b3dSmrg 97428d7b3dSmrg pI810XvMC->ref--; 98428d7b3dSmrg if(!pI810XvMC->ref) { 99428d7b3dSmrg drmUnmapBufs(pI810XvMC->dmabufs); 100428d7b3dSmrg drmUnmap(pI810XvMC->overlay.address,pI810XvMC->overlay.size); 101428d7b3dSmrg drmUnmap(pI810XvMC->surfaces.address,pI810XvMC->surfaces.size); 102428d7b3dSmrg drmClose(pI810XvMC->fd); 103428d7b3dSmrg 104428d7b3dSmrg free(pI810XvMC->dmabufs->list); 105428d7b3dSmrg free(pI810XvMC); 106428d7b3dSmrg } 107428d7b3dSmrg 108428d7b3dSmrg I810_UNLOCK(pI810XvMC); 109428d7b3dSmrg} 110428d7b3dSmrg 111428d7b3dSmrg 112428d7b3dSmrg/*************************************************************************** 113428d7b3dSmrg// Function: XvMCCreateContext 114428d7b3dSmrg// Description: Create a XvMC context for the given surface parameters. 115428d7b3dSmrg// Arguments: 116428d7b3dSmrg// display - Connection to the X server. 117428d7b3dSmrg// port - XvPortID to use as avertised by the X connection. 118428d7b3dSmrg// surface_type_id - Unique identifier for the Surface type. 119428d7b3dSmrg// width - Width of the surfaces. 120428d7b3dSmrg// height - Height of the surfaces. 121428d7b3dSmrg// flags - one or more of the following 122428d7b3dSmrg// XVMC_DIRECT - A direct rendered context is requested. 123428d7b3dSmrg// 124428d7b3dSmrg// Notes: surface_type_id and width/height parameters must match those 125428d7b3dSmrg// returned by XvMCListSurfaceTypes. 126428d7b3dSmrg// Returns: Status 127428d7b3dSmrg***************************************************************************/ 128428d7b3dSmrg_X_EXPORT Status XvMCCreateContext(Display *display, XvPortID port, 129428d7b3dSmrg int surface_type_id, int width, int height, int flags, 130428d7b3dSmrg XvMCContext *context) { 131428d7b3dSmrg i810XvMCContext *pI810XvMC; 132428d7b3dSmrg int priv_count; 133428d7b3dSmrg uint *priv_data; 134428d7b3dSmrg uint magic; 135428d7b3dSmrg Status ret; 136428d7b3dSmrg int major, minor; 137428d7b3dSmrg 138428d7b3dSmrg /* Verify Obvious things first */ 139428d7b3dSmrg if(context == NULL) { 140428d7b3dSmrg return XvMCBadContext; 141428d7b3dSmrg } 142428d7b3dSmrg 143428d7b3dSmrg if(!(flags & XVMC_DIRECT)) { 144428d7b3dSmrg /* Indirect */ 145428d7b3dSmrg printf("Indirect Rendering not supported!\nUsing Direct."); 146428d7b3dSmrg } 147428d7b3dSmrg 148428d7b3dSmrg /* Limit use to root for now */ 149428d7b3dSmrg if(geteuid()) { 150428d7b3dSmrg printf("Use of XvMC on i810 is currently limited to root\n"); 151428d7b3dSmrg return BadAccess; 152428d7b3dSmrg } 153428d7b3dSmrg 154428d7b3dSmrg /* FIXME: Check $DISPLAY for legal values here */ 155428d7b3dSmrg 156428d7b3dSmrg context->surface_type_id = surface_type_id; 157428d7b3dSmrg context->width = (unsigned short)width; 158428d7b3dSmrg context->height = (unsigned short)height; 159428d7b3dSmrg context->flags = flags; 160428d7b3dSmrg context->port = port; 161428d7b3dSmrg /* 162428d7b3dSmrg Width, Height, and flags are checked against surface_type_id 163428d7b3dSmrg and port for validity inside the X server, no need to check 164428d7b3dSmrg here. 165428d7b3dSmrg */ 166428d7b3dSmrg 167428d7b3dSmrg /* Allocate private Context data */ 168428d7b3dSmrg context->privData = (void *)malloc(sizeof(i810XvMCContext)); 169428d7b3dSmrg if(!context->privData) { 170428d7b3dSmrg printf("Unable to allocate resources for XvMC context.\n"); 171428d7b3dSmrg return BadAlloc; 172428d7b3dSmrg } 173428d7b3dSmrg pI810XvMC = (i810XvMCContext *)context->privData; 174428d7b3dSmrg 175428d7b3dSmrg 176428d7b3dSmrg /* Verify the XvMC extension exists */ 177428d7b3dSmrg if(! XvMCQueryExtension(display, &event_base, 178428d7b3dSmrg &error_base)) { 179428d7b3dSmrg printf("XvMC Extension is not available!\n"); 180428d7b3dSmrg return BadAlloc; 181428d7b3dSmrg } 182428d7b3dSmrg /* Verify XvMC version */ 183428d7b3dSmrg ret = XvMCQueryVersion(display, &major, &minor); 184428d7b3dSmrg if(ret) { 185428d7b3dSmrg printf("XvMCQuery Version Failed, unable to determine protocol version\n"); 186428d7b3dSmrg } 187428d7b3dSmrg /* FIXME: Check Major and Minor here */ 188428d7b3dSmrg 189428d7b3dSmrg /* Check for drm */ 190428d7b3dSmrg if(! drmAvailable()) { 191428d7b3dSmrg printf("Direct Rendering is not avilable on this system!\n"); 192428d7b3dSmrg return BadAlloc; 193428d7b3dSmrg } 194428d7b3dSmrg 195428d7b3dSmrg /* 196428d7b3dSmrg Build the Attribute Atoms, and Initialize the ones that exist 197428d7b3dSmrg in Xv. 198428d7b3dSmrg */ 199428d7b3dSmrg pI810XvMC->xv_colorkey = XInternAtom(display,"XV_COLORKEY",0); 200428d7b3dSmrg if(!pI810XvMC->xv_colorkey) { 201428d7b3dSmrg return XvBadPort; 202428d7b3dSmrg } 203428d7b3dSmrg ret = XvGetPortAttribute(display,port,pI810XvMC->xv_colorkey, 204428d7b3dSmrg &pI810XvMC->colorkey); 205428d7b3dSmrg if(ret) { 206428d7b3dSmrg return ret; 207428d7b3dSmrg } 208428d7b3dSmrg pI810XvMC->xv_brightness = XInternAtom(display,"XV_BRIGHTNESS",0); 209428d7b3dSmrg pI810XvMC->xv_saturation = XInternAtom(display,"XV_SATURATION",0); 210428d7b3dSmrg pI810XvMC->xv_contrast = XInternAtom(display,"XV_CONTRAST",0); 211428d7b3dSmrg pI810XvMC->brightness = 0; 212428d7b3dSmrg pI810XvMC->saturation = 0x80; /* 1.0 in 3.7 format */ 213428d7b3dSmrg pI810XvMC->contrast = 0x40; /* 1.0 in 3.6 format */ 214428d7b3dSmrg 215428d7b3dSmrg /* Open DRI Device */ 216428d7b3dSmrg if((pI810XvMC->fd = drmOpen("i810",NULL)) < 0) { 217428d7b3dSmrg printf("DRM Device for i810 could not be opened.\n"); 218428d7b3dSmrg free(pI810XvMC); 219428d7b3dSmrg return BadAccess; 220428d7b3dSmrg } /* !pI810XvMC->fd */ 221428d7b3dSmrg 222428d7b3dSmrg /* Get magic number and put it in privData for passing */ 223428d7b3dSmrg drmGetMagic(pI810XvMC->fd,&magic); 224428d7b3dSmrg context->flags = (unsigned long)magic; 225428d7b3dSmrg 226428d7b3dSmrg /* 227428d7b3dSmrg Pass control to the X server to create a drm_context_t for us and 228428d7b3dSmrg validate the with/height and flags. 229428d7b3dSmrg */ 230428d7b3dSmrg if((ret = _xvmc_create_context(display, context, &priv_count, &priv_data))) { 231428d7b3dSmrg printf("Unable to create XvMC Context.\n"); 232428d7b3dSmrg return ret; 233428d7b3dSmrg } 234428d7b3dSmrg 235428d7b3dSmrg /* 236428d7b3dSmrg X server returns a structure like this: 237428d7b3dSmrg drm_context_t 238428d7b3dSmrg fbBase 239428d7b3dSmrg OverlayOffset 240428d7b3dSmrg OverlaySize 241428d7b3dSmrg SurfacesOffset 242428d7b3dSmrg SurfacesSize 243428d7b3dSmrg busIdString = 9 char + 1 244428d7b3dSmrg */ 245428d7b3dSmrg if(priv_count != 9) { 246428d7b3dSmrg printf("_xvmc_create_context() returned incorrect data size!\n"); 247428d7b3dSmrg printf("\tExpected 9, got %d\n",priv_count); 248428d7b3dSmrg _xvmc_destroy_context(display, context); 249428d7b3dSmrg free(pI810XvMC); 250428d7b3dSmrg return BadAlloc; 251428d7b3dSmrg } 252428d7b3dSmrg pI810XvMC->drmcontext = priv_data[0]; 253428d7b3dSmrg pI810XvMC->fb_base = priv_data[1]; 254428d7b3dSmrg pI810XvMC->overlay.offset = priv_data[2] + priv_data[1]; 255428d7b3dSmrg pI810XvMC->overlay.size = priv_data[3]; 256428d7b3dSmrg pI810XvMC->surfaces.offset = priv_data[4] + priv_data[1]; 257428d7b3dSmrg pI810XvMC->surfaces.size = priv_data[5]; 258428d7b3dSmrg strncpy(pI810XvMC->busIdString,(char *)&priv_data[6],9); 259428d7b3dSmrg pI810XvMC->busIdString[9] = '\0'; 260428d7b3dSmrg 261428d7b3dSmrg /* Must free the private data we were passed from X */ 262428d7b3dSmrg free(priv_data); 263428d7b3dSmrg 264428d7b3dSmrg /* Initialize private context values */ 265428d7b3dSmrg pI810XvMC->current = 0; 266428d7b3dSmrg pI810XvMC->lock = 0; 267428d7b3dSmrg pI810XvMC->last_flip = 0; 268428d7b3dSmrg pI810XvMC->dual_prime = 0; 269428d7b3dSmrg 270428d7b3dSmrg /* 271428d7b3dSmrg Map dma Buffers: Not really, this would be a drmMapBufs 272428d7b3dSmrg but due to the i810 security model we have to just create an 273428d7b3dSmrg empty data structure to fake it. 274428d7b3dSmrg */ 275428d7b3dSmrg pI810XvMC->dmabufs = (drmBufMapPtr)malloc(sizeof(drmBufMap)); 276428d7b3dSmrg if(pI810XvMC->dmabufs == NULL) { 277428d7b3dSmrg printf("Dma Bufs could not be mapped.\n"); 278428d7b3dSmrg _xvmc_destroy_context(display, context); 279428d7b3dSmrg free(pI810XvMC); 280428d7b3dSmrg return BadAlloc; 281428d7b3dSmrg } /* pI810XvMC->dmabufs == NULL */ 282428d7b3dSmrg memset(pI810XvMC->dmabufs, 0, sizeof(drmBufMap)); 283428d7b3dSmrg pI810XvMC->dmabufs->list = (drmBufPtr)malloc(sizeof(drmBuf) * 284428d7b3dSmrg I810_DMA_BUF_NR); 285428d7b3dSmrg if(pI810XvMC->dmabufs->list == NULL) { 286428d7b3dSmrg printf("Dma Bufs could not be mapped.\n"); 287428d7b3dSmrg _xvmc_destroy_context(display, context); 288428d7b3dSmrg free(pI810XvMC); 289428d7b3dSmrg return BadAlloc; 290428d7b3dSmrg } /* pI810XvMC->dmabufs->list == NULL */ 291428d7b3dSmrg memset(pI810XvMC->dmabufs->list, 0, sizeof(drmBuf) * I810_DMA_BUF_NR); 292428d7b3dSmrg 293428d7b3dSmrg /* Map the Overlay memory */ 294428d7b3dSmrg if(drmMap(pI810XvMC->fd,pI810XvMC->overlay.offset, 295428d7b3dSmrg pI810XvMC->overlay.size,&(pI810XvMC->overlay.address)) < 0) { 296428d7b3dSmrg printf("Unable to map Overlay at offset 0x%x and size 0x%x\n", 297428d7b3dSmrg (unsigned int)pI810XvMC->overlay.offset,pI810XvMC->overlay.size); 298428d7b3dSmrg _xvmc_destroy_context(display, context); 299428d7b3dSmrg free(pI810XvMC->dmabufs->list); 300428d7b3dSmrg free(pI810XvMC); 301428d7b3dSmrg return BadAlloc; 302428d7b3dSmrg } /* drmMap() < 0 */ 303428d7b3dSmrg 304428d7b3dSmrg /* Overlay Regs are offset 1024 into Overlay Map */ 305428d7b3dSmrg pI810XvMC->oregs = (i810OverlayRec *) 306428d7b3dSmrg ((unsigned char *)pI810XvMC->overlay.address + 1024); 307428d7b3dSmrg 308428d7b3dSmrg /* Map Surfaces */ 309428d7b3dSmrg if(drmMap(pI810XvMC->fd,pI810XvMC->surfaces.offset, 310428d7b3dSmrg pI810XvMC->surfaces.size,&(pI810XvMC->surfaces.address)) < 0) { 311428d7b3dSmrg printf("Unable to map XvMC Surfaces.\n"); 312428d7b3dSmrg _xvmc_destroy_context(display, context); 313428d7b3dSmrg free(pI810XvMC->dmabufs->list); 314428d7b3dSmrg free(pI810XvMC); 315428d7b3dSmrg return BadAlloc; 316428d7b3dSmrg } /* drmMap() < 0 */ 317428d7b3dSmrg 318428d7b3dSmrg /* 319428d7b3dSmrg There is a tiny chance that someone was using the overlay and 320428d7b3dSmrg issued a flip that hasn't finished. To be 100% sure I'll just 321428d7b3dSmrg take the lock and sleep for the worst case time for a flip. 322428d7b3dSmrg */ 323428d7b3dSmrg I810_LOCK(pI810XvMC,DRM_LOCK_QUIESCENT); 324428d7b3dSmrg usleep(20000); /* 1/50th Sec for 50hz refresh */ 325428d7b3dSmrg 326428d7b3dSmrg /* Set up Overlay regs with Initial Values */ 327428d7b3dSmrg pI810XvMC->oregs->YRGB_VPH = 0; 328428d7b3dSmrg pI810XvMC->oregs->UV_VPH = 0; 329428d7b3dSmrg pI810XvMC->oregs->HORZ_PH = 0; 330428d7b3dSmrg pI810XvMC->oregs->INIT_PH = 0; 331428d7b3dSmrg pI810XvMC->oregs->DWINPOS = 0; 332428d7b3dSmrg pI810XvMC->oregs->DWINSZ = (I810_XVMC_MAXHEIGHT << 16) | 333428d7b3dSmrg I810_XVMC_MAXWIDTH; 334428d7b3dSmrg pI810XvMC->oregs->SWID = I810_XVMC_MAXWIDTH | (I810_XVMC_MAXWIDTH << 15); 335428d7b3dSmrg pI810XvMC->oregs->SWIDQW = (I810_XVMC_MAXWIDTH >> 3) | 336428d7b3dSmrg (I810_XVMC_MAXWIDTH << 12); 337428d7b3dSmrg pI810XvMC->oregs->SHEIGHT = I810_XVMC_MAXHEIGHT | 338428d7b3dSmrg (I810_XVMC_MAXHEIGHT << 15); 339428d7b3dSmrg pI810XvMC->oregs->YRGBSCALE = 0x80004000; /* scale factor 1 */ 340428d7b3dSmrg pI810XvMC->oregs->UVSCALE = 0x80004000; /* scale factor 1 */ 341428d7b3dSmrg pI810XvMC->oregs->OV0CLRC0 = 0x4000; /* brightness: 0 contrast: 1.0 */ 342428d7b3dSmrg pI810XvMC->oregs->OV0CLRC1 = 0x80; /* saturation: bypass */ 343428d7b3dSmrg 344428d7b3dSmrg /* Destination Colorkey Setup */ 345428d7b3dSmrg pI810XvMC->oregs->DCLRKV = RGB16ToColorKey(pI810XvMC->colorkey); 346428d7b3dSmrg pI810XvMC->oregs->DCLRKM = 0x80070307; 347428d7b3dSmrg 348428d7b3dSmrg 349428d7b3dSmrg pI810XvMC->oregs->SCLRKVH = 0; 350428d7b3dSmrg pI810XvMC->oregs->SCLRKVL = 0; 351428d7b3dSmrg pI810XvMC->oregs->SCLRKM = 0; /* source color key disable */ 352428d7b3dSmrg pI810XvMC->oregs->OV0CONF = 0; /* two 720 pixel line buffers */ 353428d7b3dSmrg 354428d7b3dSmrg pI810XvMC->oregs->OV0CMD = VC_UP_INTERPOLATION | HC_UP_INTERPOLATION | 355428d7b3dSmrg Y_ADJUST | YUV_420; 356428d7b3dSmrg 357428d7b3dSmrg pI810XvMC->ref = 1; 358428d7b3dSmrg 359428d7b3dSmrg I810_UNLOCK(pI810XvMC); 360428d7b3dSmrg 361428d7b3dSmrg return Success; 362428d7b3dSmrg 363428d7b3dSmrg} 364428d7b3dSmrg 365428d7b3dSmrg/*************************************************************************** 366428d7b3dSmrg// Function: XvMCDestroyContext 367428d7b3dSmrg// Description: Destorys the specified context. 368428d7b3dSmrg// 369428d7b3dSmrg// Arguments: 370428d7b3dSmrg// display - Specifies the connection to the server. 371428d7b3dSmrg// context - The context to be destroyed. 372428d7b3dSmrg// 373428d7b3dSmrg// Returns: Status 374428d7b3dSmrg***************************************************************************/ 375428d7b3dSmrg_X_EXPORT Status XvMCDestroyContext(Display *display, XvMCContext *context) { 376428d7b3dSmrg i810XvMCContext *pI810XvMC; 377428d7b3dSmrg 378428d7b3dSmrg if(context == NULL) { 379428d7b3dSmrg return (error_base + XvMCBadContext); 380428d7b3dSmrg } 381428d7b3dSmrg if(context->privData == NULL) { 382428d7b3dSmrg return (error_base + XvMCBadContext); 383428d7b3dSmrg } 384428d7b3dSmrg pI810XvMC = (i810XvMCContext *)context->privData; 385428d7b3dSmrg 386428d7b3dSmrg /* Turn off the overlay */ 387428d7b3dSmrg if(pI810XvMC->last_flip) { 388428d7b3dSmrg I810_LOCK(pI810XvMC,DRM_LOCK_QUIESCENT); 389428d7b3dSmrg 390428d7b3dSmrg /* Make sure last flip is done */ 391428d7b3dSmrg BLOCK_OVERLAY(pI810XvMC,pI810XvMC->current); 392428d7b3dSmrg 393428d7b3dSmrg pI810XvMC->oregs->OV0CMD = VC_UP_INTERPOLATION | HC_UP_INTERPOLATION | 394428d7b3dSmrg Y_ADJUST; 395428d7b3dSmrg pI810XvMC->current = !pI810XvMC->current; 396428d7b3dSmrg if(pI810XvMC->current == 1) { 397428d7b3dSmrg pI810XvMC->oregs->OV0CMD |= BUFFER1_FIELD0; 398428d7b3dSmrg } 399428d7b3dSmrg else { 400428d7b3dSmrg pI810XvMC->oregs->OV0CMD |= BUFFER0_FIELD0; 401428d7b3dSmrg } 402428d7b3dSmrg OVERLAY_FLIP(pI810XvMC); 403428d7b3dSmrg pI810XvMC->last_flip++; 404428d7b3dSmrg 405428d7b3dSmrg /* Wait for the flip */ 406428d7b3dSmrg BLOCK_OVERLAY(pI810XvMC,pI810XvMC->current); 407428d7b3dSmrg 408428d7b3dSmrg I810_UNLOCK(pI810XvMC); 409428d7b3dSmrg } 410428d7b3dSmrg 411428d7b3dSmrg /* Pass Control to the X server to destroy the drm_context_t */ 412428d7b3dSmrg _xvmc_destroy_context(display, context); 413428d7b3dSmrg 414428d7b3dSmrg i810_free_privContext(pI810XvMC); 415428d7b3dSmrg context->privData = NULL; 416428d7b3dSmrg 417428d7b3dSmrg return Success; 418428d7b3dSmrg} 419428d7b3dSmrg 420428d7b3dSmrg 421428d7b3dSmrg/*************************************************************************** 422428d7b3dSmrg// Function: XvMCCreateSurface 423428d7b3dSmrg***************************************************************************/ 424428d7b3dSmrg_X_EXPORT Status XvMCCreateSurface( Display *display, XvMCContext *context, 425428d7b3dSmrg XvMCSurface *surface) { 426428d7b3dSmrg i810XvMCContext *pI810XvMC; 427428d7b3dSmrg i810XvMCSurface *pI810Surface; 428428d7b3dSmrg int priv_count; 429428d7b3dSmrg uint *priv_data; 430428d7b3dSmrg Status ret; 431428d7b3dSmrg 432428d7b3dSmrg if((surface == NULL) || (context == NULL) || (display == NULL)){ 433428d7b3dSmrg return BadValue; 434428d7b3dSmrg } 435428d7b3dSmrg 436428d7b3dSmrg pI810XvMC = (i810XvMCContext *)context->privData; 437428d7b3dSmrg if(pI810XvMC == NULL) { 438428d7b3dSmrg return (error_base + XvMCBadContext); 439428d7b3dSmrg } 440428d7b3dSmrg 441428d7b3dSmrg 442428d7b3dSmrg surface->privData = (i810XvMCSurface *)malloc(sizeof(i810XvMCSurface)); 443428d7b3dSmrg if(!surface->privData) { 444428d7b3dSmrg return BadAlloc; 445428d7b3dSmrg } 446428d7b3dSmrg pI810Surface = (i810XvMCSurface *)surface->privData; 447428d7b3dSmrg 448428d7b3dSmrg /* Initialize private values */ 449428d7b3dSmrg pI810Surface->privContext = pI810XvMC; 450428d7b3dSmrg pI810Surface->last_render = 0; 451428d7b3dSmrg pI810Surface->last_flip = 0; 452428d7b3dSmrg pI810Surface->second_field = 0; 453428d7b3dSmrg 454428d7b3dSmrg if((ret = _xvmc_create_surface(display, context, surface, 455428d7b3dSmrg &priv_count, &priv_data))) { 456428d7b3dSmrg free(pI810Surface); 457428d7b3dSmrg printf("Unable to create XvMCSurface.\n"); 458428d7b3dSmrg return ret; 459428d7b3dSmrg } 460428d7b3dSmrg 461428d7b3dSmrg /* 462428d7b3dSmrg _xvmc_create_subpicture returns 2 uints with the offset into 463428d7b3dSmrg the DRM map for the Y surface and UV surface. 464428d7b3dSmrg */ 465428d7b3dSmrg if(priv_count != 2) { 466428d7b3dSmrg printf("_xvmc_create_surface() return incorrect data size.\n"); 467428d7b3dSmrg printf("Expected 2 got %d\n",priv_count); 468428d7b3dSmrg free(priv_data); 469428d7b3dSmrg free(pI810Surface); 470428d7b3dSmrg return BadAlloc; 471428d7b3dSmrg } 472428d7b3dSmrg /* Data == Client Address, offset == Physical address offset */ 473428d7b3dSmrg pI810Surface->data = pI810XvMC->surfaces.address; 474428d7b3dSmrg pI810Surface->offset = pI810XvMC->surfaces.offset; 475428d7b3dSmrg 476428d7b3dSmrg 477428d7b3dSmrg /* 478428d7b3dSmrg i810's MC Engine needs surfaces of 2^x (x= 9,10,11,12) pitch 479428d7b3dSmrg and the Tiler need 512k aligned surfaces, basically we are 480428d7b3dSmrg stuck with fixed memory with pitch 1024 for Y data. UV = 512. 481428d7b3dSmrg */ 482428d7b3dSmrg pI810Surface->pitch = 10; 483428d7b3dSmrg if((surface->surface_type_id == FOURCC_UYVY) || 484428d7b3dSmrg (surface->surface_type_id == FOURCC_YUY2)) { 485428d7b3dSmrg /* This is not implemented server side. */ 486428d7b3dSmrg pI810Surface->pitch++; 487428d7b3dSmrg } 488428d7b3dSmrg 489428d7b3dSmrg /* 490428d7b3dSmrg offsets[0,1,2] == Offsets from either data or offset for the Y 491428d7b3dSmrg U and V surfaces. 492428d7b3dSmrg */ 493428d7b3dSmrg pI810Surface->offsets[0] = priv_data[0]; 494428d7b3dSmrg if(((unsigned long)pI810Surface->data + pI810Surface->offsets[0]) & 4095) { 495428d7b3dSmrg printf("XvMCCreateSurface: Surface offset 0 is not 4096 aligned\n"); 496428d7b3dSmrg } 497428d7b3dSmrg 498428d7b3dSmrg if((surface->surface_type_id == FOURCC_UYVY) || 499428d7b3dSmrg (surface->surface_type_id == FOURCC_YUY2)) { 500428d7b3dSmrg /* Packed surface, not fully implemented */ 501428d7b3dSmrg pI810Surface->offsets[1] = 0; 502428d7b3dSmrg pI810Surface->offsets[2] = 0; 503428d7b3dSmrg } 504428d7b3dSmrg else { 505428d7b3dSmrg /* Planar surface */ 506428d7b3dSmrg pI810Surface->offsets[1] = priv_data[1]; 507428d7b3dSmrg if(((unsigned long)pI810Surface->data + pI810Surface->offsets[1]) & 2047) { 508428d7b3dSmrg printf("XvMCCreateSurface: Surface offset 1 is not 2048 aligned\n"); 509428d7b3dSmrg } 510428d7b3dSmrg 511428d7b3dSmrg pI810Surface->offsets[2] = ((unsigned long)pI810Surface->offsets[1] + 512428d7b3dSmrg (1<<(pI810Surface->pitch - 1)) * 288); 513428d7b3dSmrg if(((unsigned long)pI810Surface->data + pI810Surface->offsets[2]) & 2047) { 514428d7b3dSmrg printf("XvMCCreateSurface: Surface offset 2 is not 2048 aligned\n"); 515428d7b3dSmrg } 516428d7b3dSmrg 517428d7b3dSmrg } 518428d7b3dSmrg 519428d7b3dSmrg /* Free data returned from xvmc_create_surface */ 520428d7b3dSmrg free(priv_data); 521428d7b3dSmrg 522428d7b3dSmrg /* Clear the surface to 0 */ 523428d7b3dSmrg memset((void *)((unsigned long)pI810Surface->data + (unsigned long)pI810Surface->offsets[0]), 524428d7b3dSmrg 0, ((1<<pI810Surface->pitch) * surface->height)); 525428d7b3dSmrg 526428d7b3dSmrg switch(surface->surface_type_id) { 527428d7b3dSmrg case FOURCC_YV12: 528428d7b3dSmrg case FOURCC_I420: 529428d7b3dSmrg /* Destination buffer info command */ 530428d7b3dSmrg pI810Surface->dbi1y = ((((unsigned int)pI810Surface->offset + 531428d7b3dSmrg pI810Surface->offsets[0]) & ~0xfc000fff) | 532428d7b3dSmrg (pI810Surface->pitch - 9)); 533428d7b3dSmrg pI810Surface->dbi1u = ((((unsigned int)pI810Surface->offset + 534428d7b3dSmrg pI810Surface->offsets[1]) & ~0xfc000fff) | 535428d7b3dSmrg (pI810Surface->pitch - 10)); 536428d7b3dSmrg pI810Surface->dbi1v = ((((unsigned int)pI810Surface->offset + 537428d7b3dSmrg pI810Surface->offsets[2]) & ~0xfc000fff) | 538428d7b3dSmrg (pI810Surface->pitch - 10)); 539428d7b3dSmrg 540428d7b3dSmrg /* Destination buffer variables command */ 541428d7b3dSmrg pI810Surface->dbv1 = (0x8<<20) | (0x8<<16); 542428d7b3dSmrg /* Map info command */ 543428d7b3dSmrg pI810Surface->mi1y = (0x1<<24) | (1<<9) | (pI810Surface->pitch - 3); 544428d7b3dSmrg pI810Surface->mi1u = (0x1<<24) | (1<<9) | (pI810Surface->pitch - 4); 545428d7b3dSmrg pI810Surface->mi1v = (0x1<<24) | (1<<9) | (pI810Surface->pitch - 4); 546428d7b3dSmrg 547428d7b3dSmrg pI810Surface->mi2y = (((unsigned int)surface->height - 1)<<16) | 548428d7b3dSmrg ((unsigned int)surface->width - 1); 549428d7b3dSmrg pI810Surface->mi2u = (((unsigned int)surface->height - 1)<<15) | 550428d7b3dSmrg (((unsigned int)surface->width - 1)>>1); 551428d7b3dSmrg pI810Surface->mi2v = pI810Surface->mi2u; 552428d7b3dSmrg 553428d7b3dSmrg pI810Surface->mi3y = ((unsigned int)pI810Surface->offset + 554428d7b3dSmrg pI810Surface->offsets[0]) & ~0x0000000f; 555428d7b3dSmrg pI810Surface->mi3u = ((unsigned int)pI810Surface->offset + 556428d7b3dSmrg pI810Surface->offsets[1]) & ~0x0000000f; 557428d7b3dSmrg pI810Surface->mi3v = ((unsigned int)pI810Surface->offset + 558428d7b3dSmrg pI810Surface->offsets[2]) & ~0x0000000f; 559428d7b3dSmrg break; 560428d7b3dSmrg case FOURCC_UYVY: 561428d7b3dSmrg case FOURCC_YUY2: 562428d7b3dSmrg default: 563428d7b3dSmrg /* Destination buffer info command */ 564428d7b3dSmrg pI810Surface->dbi1y = ((((unsigned int)pI810Surface->offset + 565428d7b3dSmrg pI810Surface->offsets[0]) & ~0xfc000fff) | 566428d7b3dSmrg (pI810Surface->pitch - 9)); 567428d7b3dSmrg /* Destination buffer variables command */ 568428d7b3dSmrg if(surface->surface_type_id == FOURCC_YUY2) { 569428d7b3dSmrg pI810Surface->dbv1 = 0x5<<8; 570428d7b3dSmrg pI810Surface->mi1y = 0x5<<24 | pI810Surface->pitch | 0x1<<21; 571428d7b3dSmrg } 572428d7b3dSmrg else { 573428d7b3dSmrg pI810Surface->dbv1 = 0x4<<8; 574428d7b3dSmrg pI810Surface->mi1y = 0x5<<24 | (pI810Surface->pitch - 3); 575428d7b3dSmrg } 576428d7b3dSmrg pI810Surface->mi2y = (((unsigned int)surface->width - 1)<<16) | 577428d7b3dSmrg ((unsigned int)surface->height - 1); 578428d7b3dSmrg pI810Surface->mi3y = ((unsigned int)pI810Surface->offset + 579428d7b3dSmrg pI810Surface->offsets[0]) & ~0xfc000fff; 580428d7b3dSmrg break; 581428d7b3dSmrg } 582428d7b3dSmrg pI810XvMC->ref++; 583428d7b3dSmrg 584428d7b3dSmrg return Success; 585428d7b3dSmrg} 586428d7b3dSmrg 587428d7b3dSmrg 588428d7b3dSmrg/*************************************************************************** 589428d7b3dSmrg// Function: XvMCDestroySurface 590428d7b3dSmrg***************************************************************************/ 591428d7b3dSmrg_X_EXPORT Status XvMCDestroySurface(Display *display, XvMCSurface *surface) { 592428d7b3dSmrg i810XvMCSurface *pI810Surface; 593428d7b3dSmrg i810XvMCContext *pI810XvMC; 594428d7b3dSmrg 595428d7b3dSmrg if((display == NULL) || (surface == NULL)) { 596428d7b3dSmrg return BadValue; 597428d7b3dSmrg } 598428d7b3dSmrg if(surface->privData == NULL) { 599428d7b3dSmrg return (error_base + XvMCBadSurface); 600428d7b3dSmrg } 601428d7b3dSmrg 602428d7b3dSmrg pI810Surface = (i810XvMCSurface *)surface->privData; 603428d7b3dSmrg if(pI810Surface->last_flip) { 604428d7b3dSmrg XvMCSyncSurface(display,surface); 605428d7b3dSmrg } 606428d7b3dSmrg pI810XvMC = (i810XvMCContext *)pI810Surface->privContext; 607428d7b3dSmrg 608428d7b3dSmrg _xvmc_destroy_surface(display,surface); 609428d7b3dSmrg 610428d7b3dSmrg i810_free_privContext(pI810XvMC); 611428d7b3dSmrg 612428d7b3dSmrg free(pI810Surface); 613428d7b3dSmrg surface->privData = NULL; 614428d7b3dSmrg return Success; 615428d7b3dSmrg} 616428d7b3dSmrg 617428d7b3dSmrg/*************************************************************************** 618428d7b3dSmrg// Function: XvMCCreateBlocks 619428d7b3dSmrg***************************************************************************/ 620428d7b3dSmrg_X_EXPORT Status XvMCCreateBlocks(Display *display, XvMCContext *context, 621428d7b3dSmrg unsigned int num_blocks, 622428d7b3dSmrg XvMCBlockArray *block) { 623428d7b3dSmrg 624428d7b3dSmrg if((display == NULL) || (context == NULL) || (num_blocks == 0)) { 625428d7b3dSmrg return BadValue; 626428d7b3dSmrg } 627428d7b3dSmrg 628428d7b3dSmrg block->blocks = (short *)malloc(num_blocks<<6 * sizeof(short)); 629428d7b3dSmrg if(block->blocks == NULL) { 630428d7b3dSmrg return BadAlloc; 631428d7b3dSmrg } 632428d7b3dSmrg 633428d7b3dSmrg block->num_blocks = num_blocks; 634428d7b3dSmrg block->context_id = context->context_id; 635428d7b3dSmrg 636428d7b3dSmrg block->privData = NULL; 637428d7b3dSmrg 638428d7b3dSmrg return Success; 639428d7b3dSmrg} 640428d7b3dSmrg 641428d7b3dSmrg/*************************************************************************** 642428d7b3dSmrg// Function: XvMCDestroyBlocks 643428d7b3dSmrg***************************************************************************/ 644428d7b3dSmrg_X_EXPORT Status XvMCDestroyBlocks(Display *display, XvMCBlockArray *block) { 645428d7b3dSmrg if(display == NULL) { 646428d7b3dSmrg return BadValue; 647428d7b3dSmrg } 648428d7b3dSmrg 649428d7b3dSmrg free(block->blocks); 650428d7b3dSmrg block->num_blocks = 0; 651428d7b3dSmrg block->context_id = 0; 652428d7b3dSmrg block->privData = NULL; 653428d7b3dSmrg return Success; 654428d7b3dSmrg} 655428d7b3dSmrg 656428d7b3dSmrg/*************************************************************************** 657428d7b3dSmrg// Function: XvMCCreateMacroBlocks 658428d7b3dSmrg***************************************************************************/ 659428d7b3dSmrg_X_EXPORT Status XvMCCreateMacroBlocks(Display *display, XvMCContext *context, 660428d7b3dSmrg unsigned int num_blocks, 661428d7b3dSmrg XvMCMacroBlockArray *blocks) { 662428d7b3dSmrg 663428d7b3dSmrg if((display == NULL) || (context == NULL) || (blocks == NULL) || 664428d7b3dSmrg (num_blocks == 0)) { 665428d7b3dSmrg return BadValue; 666428d7b3dSmrg } 667428d7b3dSmrg memset(blocks,0,sizeof(XvMCMacroBlockArray)); 668428d7b3dSmrg blocks->context_id = context->context_id; 669428d7b3dSmrg blocks->privData = NULL; 670428d7b3dSmrg 671428d7b3dSmrg blocks->macro_blocks = (XvMCMacroBlock *) 672428d7b3dSmrg malloc(num_blocks * sizeof(XvMCMacroBlock)); 673428d7b3dSmrg if(blocks->macro_blocks == NULL) { 674428d7b3dSmrg return BadAlloc; 675428d7b3dSmrg } 676428d7b3dSmrg blocks->num_blocks = num_blocks; 677428d7b3dSmrg 678428d7b3dSmrg return Success; 679428d7b3dSmrg} 680428d7b3dSmrg 681428d7b3dSmrg/*************************************************************************** 682428d7b3dSmrg// Function: XvMCDestroyMacroBlocks 683428d7b3dSmrg***************************************************************************/ 684428d7b3dSmrg_X_EXPORT Status XvMCDestroyMacroBlocks(Display *display, XvMCMacroBlockArray *block) { 685428d7b3dSmrg if((display == NULL) || (block == NULL)) { 686428d7b3dSmrg return BadValue; 687428d7b3dSmrg } 688428d7b3dSmrg if(block->macro_blocks) { 689428d7b3dSmrg free(block->macro_blocks); 690428d7b3dSmrg } 691428d7b3dSmrg block->context_id = 0; 692428d7b3dSmrg block->num_blocks = 0; 693428d7b3dSmrg block->privData = NULL; 694428d7b3dSmrg 695428d7b3dSmrg return Success; 696428d7b3dSmrg} 697428d7b3dSmrg 698428d7b3dSmrg 699428d7b3dSmrg/*************************************************************************** 700428d7b3dSmrg// Function: dp (Debug Print) 701428d7b3dSmrg// Description: This function prints out in hex i * uint32_t at the address 702428d7b3dSmrg// supplied. This enables you to print out the dma buffers from 703428d7b3dSmrg// within the debugger even though they are not in your address space. 704428d7b3dSmrg***************************************************************************/ 705428d7b3dSmrgvoid dp(unsigned int *address, unsigned int i) { 706428d7b3dSmrg int j; 707428d7b3dSmrg 708428d7b3dSmrg printf("DebugPrint:\n"); 709428d7b3dSmrg for(j=0; j<i; j++) { 710428d7b3dSmrg printf("0x%8.8x ",address[j]); 711428d7b3dSmrg if(j && !(j & 7)) { printf("\n");} 712428d7b3dSmrg } 713428d7b3dSmrg} 714428d7b3dSmrg 715428d7b3dSmrg/*************************************************************************** 716428d7b3dSmrg// Macro: PACK_* 717428d7b3dSmrg// Description: Packs 16bit signed data from blocks into either 8bit unsigned 718428d7b3dSmrg// intra data or 16bit signed correction data, both packed into 719428d7b3dSmrg// 32 bit integers. 720428d7b3dSmrg***************************************************************************/ 721428d7b3dSmrg#define PACK_INTRA_DATA(d,b,n) \ 722428d7b3dSmrg do { \ 723428d7b3dSmrg char *dp = (char *)d; \ 724428d7b3dSmrg char *bp = (char *)b; \ 725428d7b3dSmrg int counter; \ 726428d7b3dSmrg for(counter = 0; counter < n; counter++) { \ 727428d7b3dSmrg *dp++ = *bp; \ 728428d7b3dSmrg bp += 2; \ 729428d7b3dSmrg } \ 730428d7b3dSmrg }while(0); 731428d7b3dSmrg 732428d7b3dSmrg#define PACK_CORR_DATA(d,b,n) \ 733428d7b3dSmrg memcpy(d,b,n); \ 734428d7b3dSmrg d = (uint *)((unsigned long)d + n); 735428d7b3dSmrg 736428d7b3dSmrg#define MARK_CORR_DATA(d,n) \ 737428d7b3dSmrg do { \ 738428d7b3dSmrg uint* q = (uint*)((unsigned long)d - n); \ 739428d7b3dSmrg while((unsigned long)q < (unsigned long)d) { \ 740428d7b3dSmrg *q++ += 0x00330033; \ 741428d7b3dSmrg } \ 742428d7b3dSmrg }while(0); 743428d7b3dSmrg 744428d7b3dSmrg#define MARK_INTRA_BLOCK(d) \ 745428d7b3dSmrg do { \ 746428d7b3dSmrg int q; \ 747428d7b3dSmrg for(q=0; q<16; q++) { \ 748428d7b3dSmrg d[q] += 0x33333333; \ 749428d7b3dSmrg } \ 750428d7b3dSmrg }while(0); 751428d7b3dSmrg 752428d7b3dSmrg/* 753428d7b3dSmrg Used for DCT 1 when we need DCT 0. Instead 754428d7b3dSmrg of reading from one block we read from two and 755428d7b3dSmrg interlace. 756428d7b3dSmrg*/ 757428d7b3dSmrg#define PACK_CORR_DATA_1to0(d,top,bottom) \ 758428d7b3dSmrg do { \ 759428d7b3dSmrg short *t = top,*b = bottom; \ 760428d7b3dSmrg PACK_CORR_DATA(d,t,16); \ 761428d7b3dSmrg t = (short *)((unsigned long)t + 16); \ 762428d7b3dSmrg PACK_CORR_DATA(d,b,16); \ 763428d7b3dSmrg b = (short *)((unsigned long)b + 16); \ 764428d7b3dSmrg PACK_CORR_DATA(d,t,16); \ 765428d7b3dSmrg t = (short *)((unsigned long)t + 16); \ 766428d7b3dSmrg PACK_CORR_DATA(d,b,16); \ 767428d7b3dSmrg b = (short *)((unsigned long)b + 16); \ 768428d7b3dSmrg PACK_CORR_DATA(d,t,16); \ 769428d7b3dSmrg t = (short *)((unsigned long)t + 16); \ 770428d7b3dSmrg PACK_CORR_DATA(d,b,16); \ 771428d7b3dSmrg b = (short *)((unsigned long)b + 16); \ 772428d7b3dSmrg PACK_CORR_DATA(d,t,16); \ 773428d7b3dSmrg t = (short *)((unsigned long)t + 16); \ 774428d7b3dSmrg PACK_CORR_DATA(d,b,16); \ 775428d7b3dSmrg b = (short *)((unsigned long)b + 16); \ 776428d7b3dSmrg }while(0); 777428d7b3dSmrg 778428d7b3dSmrg/* Used for DCT 0 when we need DCT 1. */ 779428d7b3dSmrg#define PACK_CORR_DATA_0to1(d,top,bottom) \ 780428d7b3dSmrg do{ \ 781428d7b3dSmrg short *t = top,*b = bottom; \ 782428d7b3dSmrg PACK_CORR_DATA(d,t,16); \ 783428d7b3dSmrg t = (short *)((unsigned long)t + 32); \ 784428d7b3dSmrg PACK_CORR_DATA(d,t,16); \ 785428d7b3dSmrg t = (short *)((unsigned long)t + 32); \ 786428d7b3dSmrg PACK_CORR_DATA(d,t,16); \ 787428d7b3dSmrg t = (short *)((unsigned long)t + 32); \ 788428d7b3dSmrg PACK_CORR_DATA(d,t,16); \ 789428d7b3dSmrg t = (short *)((unsigned long)t + 32); \ 790428d7b3dSmrg PACK_CORR_DATA(d,b,16); \ 791428d7b3dSmrg b = (short *)((unsigned long)b + 32); \ 792428d7b3dSmrg PACK_CORR_DATA(d,b,16); \ 793428d7b3dSmrg b = (short *)((unsigned long)b + 32); \ 794428d7b3dSmrg PACK_CORR_DATA(d,b,16); \ 795428d7b3dSmrg b = (short *)((unsigned long)b + 32); \ 796428d7b3dSmrg PACK_CORR_DATA(d,b,16); \ 797428d7b3dSmrg b = (short *)((unsigned long)b + 32); \ 798428d7b3dSmrg }while(0); 799428d7b3dSmrg 800428d7b3dSmrg#define PACK_CORR_DATA_SHORT(d,block) \ 801428d7b3dSmrg do { \ 802428d7b3dSmrg short *b = block; \ 803428d7b3dSmrg PACK_CORR_DATA(d,b,16); \ 804428d7b3dSmrg b = (short *)((unsigned long)b + 32); \ 805428d7b3dSmrg PACK_CORR_DATA(d,b,16); \ 806428d7b3dSmrg b = (short *)((unsigned long)b + 32); \ 807428d7b3dSmrg PACK_CORR_DATA(d,b,16); \ 808428d7b3dSmrg b = (short *)((unsigned long)b + 32); \ 809428d7b3dSmrg PACK_CORR_DATA(d,b,16); \ 810428d7b3dSmrg b = (short *)((unsigned long)b + 32); \ 811428d7b3dSmrg }while(0); 812428d7b3dSmrg 813428d7b3dSmrg/* Lookup tables to speed common calculations */ 814428d7b3dSmrgstatic unsigned int drps_table[] = {2<<6,3<<6}; 815428d7b3dSmrg 816428d7b3dSmrgstatic unsigned int mvfs_table[] = { 817428d7b3dSmrg 0x12, 818428d7b3dSmrg 0x1a, 819428d7b3dSmrg 0x13, 820428d7b3dSmrg 0x1b 821428d7b3dSmrg}; 822428d7b3dSmrg 823428d7b3dSmrgstatic unsigned int type_table[] = { 824428d7b3dSmrg 0x1<<12, /* This is an error so make it Forward motion */ 825428d7b3dSmrg 0x1<<12, 826428d7b3dSmrg 0x1<<12, 827428d7b3dSmrg 0x1<<12, 828428d7b3dSmrg 0x2<<12, 829428d7b3dSmrg 0x2<<12, 830428d7b3dSmrg 0x3<<12, 831428d7b3dSmrg 0x3<<12, 832428d7b3dSmrg 0x1<<12, /* Pattern but no Motion, Make motion Forward */ 833428d7b3dSmrg 0x1<<12, 834428d7b3dSmrg 0x1<<12, 835428d7b3dSmrg 0x1<<12, 836428d7b3dSmrg 0x2<<12, 837428d7b3dSmrg 0x2<<12, 838428d7b3dSmrg 0x3<<12, 839428d7b3dSmrg 0x3<<12 840428d7b3dSmrg}; 841428d7b3dSmrg 842428d7b3dSmrgstatic unsigned int y_frame_bytes[] = { 843428d7b3dSmrg 0,0,0,0,128,128,128,128, 844428d7b3dSmrg 128,128,128,128,256,256,256,256, 845428d7b3dSmrg 128,128,128,128,256,256,256,256, 846428d7b3dSmrg 256,256,256,256,384,384,384,384, 847428d7b3dSmrg 128,128,128,128,256,256,256,256, 848428d7b3dSmrg 256,256,256,256,384,384,384,384, 849428d7b3dSmrg 256,256,256,256,384,384,384,384, 850428d7b3dSmrg 384,384,384,384,512,512,512,512 851428d7b3dSmrg}; 852428d7b3dSmrg 853428d7b3dSmrgstatic unsigned int u_frame_bytes[] = { 854428d7b3dSmrg 0,0,128,128,0,0,128,128, 855428d7b3dSmrg 0,0,128,128,0,0,128,128, 856428d7b3dSmrg 0,0,128,128,0,0,128,128, 857428d7b3dSmrg 0,0,128,128,0,0,128,128, 858428d7b3dSmrg 0,0,128,128,0,0,128,128, 859428d7b3dSmrg 0,0,128,128,0,0,128,128, 860428d7b3dSmrg 0,0,128,128,0,0,128,128, 861428d7b3dSmrg 0,0,128,128,0,0,128,128 862428d7b3dSmrg}; 863428d7b3dSmrg 864428d7b3dSmrgstatic unsigned int v_frame_bytes[] = { 865428d7b3dSmrg 0,128,0,128,0,128,0,128, 866428d7b3dSmrg 0,128,0,128,0,128,0,128, 867428d7b3dSmrg 0,128,0,128,0,128,0,128, 868428d7b3dSmrg 0,128,0,128,0,128,0,128, 869428d7b3dSmrg 0,128,0,128,0,128,0,128, 870428d7b3dSmrg 0,128,0,128,0,128,0,128, 871428d7b3dSmrg 0,128,0,128,0,128,0,128, 872428d7b3dSmrg 0,128,0,128,0,128,0,128 873428d7b3dSmrg}; 874428d7b3dSmrg 875428d7b3dSmrgstatic unsigned int y_first_field_bytes[] = { 876428d7b3dSmrg 0,0,0,0,0,0,0,0, 877428d7b3dSmrg 0,0,0,0,0,0,0,0, 878428d7b3dSmrg 128,128,128,128,128,128,128,128, 879428d7b3dSmrg 128,128,128,128,128,128,128,128, 880428d7b3dSmrg 128,128,128,128,128,128,128,128, 881428d7b3dSmrg 128,128,128,128,128,128,128,128, 882428d7b3dSmrg 256,256,256,256,256,256,256,256, 883428d7b3dSmrg 256,256,256,256,256,256,256,256 884428d7b3dSmrg}; 885428d7b3dSmrg 886428d7b3dSmrgstatic unsigned int y_second_field_bytes[] = { 887428d7b3dSmrg 0,0,0,0,128,128,128,128, 888428d7b3dSmrg 128,128,128,128,256,256,256,256, 889428d7b3dSmrg 0,0,0,0,128,128,128,128, 890428d7b3dSmrg 128,128,128,128,256,256,256,256, 891428d7b3dSmrg 0,0,0,0,128,128,128,128, 892428d7b3dSmrg 128,128,128,128,256,256,256,256, 893428d7b3dSmrg 0,0,0,0,128,128,128,128, 894428d7b3dSmrg 128,128,128,128,256,256,256,256 895428d7b3dSmrg}; 896428d7b3dSmrg 897428d7b3dSmrgstatic unsigned int y_dct0_field_bytes[] = { 898428d7b3dSmrg 0,0,0,0,128,128,128,128, 899428d7b3dSmrg 128,128,128,128,256,256,256,256, 900428d7b3dSmrg 128,128,128,128,128,128,128,128, 901428d7b3dSmrg 256,256,256,256,256,256,256,256, 902428d7b3dSmrg 128,128,128,128,256,256,256,256, 903428d7b3dSmrg 128,128,128,128,256,256,256,256, 904428d7b3dSmrg 256,256,256,256,256,256,256,256, 905428d7b3dSmrg 256,256,256,256,256,256,256,256 906428d7b3dSmrg}; 907428d7b3dSmrg 908428d7b3dSmrgstatic unsigned int y_dct1_frame_bytes[] = { 909428d7b3dSmrg 0,0,0,0,256,256,256,256, 910428d7b3dSmrg 256,256,256,256,512,512,512,512, 911428d7b3dSmrg 256,256,256,256,256,256,256,256, 912428d7b3dSmrg 512,512,512,512,512,512,512,512, 913428d7b3dSmrg 256,256,256,256,512,512,512,512, 914428d7b3dSmrg 256,256,256,256,512,512,512,512, 915428d7b3dSmrg 512,512,512,512,512,512,512,512, 916428d7b3dSmrg 512,512,512,512,512,512,512,512 917428d7b3dSmrg}; 918428d7b3dSmrg 919428d7b3dSmrgstatic unsigned int u_field_bytes[] = { 920428d7b3dSmrg 0,0,64,64,0,0,64,64, 921428d7b3dSmrg 0,0,64,64,0,0,64,64, 922428d7b3dSmrg 0,0,64,64,0,0,64,64, 923428d7b3dSmrg 0,0,64,64,0,0,64,64, 924428d7b3dSmrg 0,0,64,64,0,0,64,64, 925428d7b3dSmrg 0,0,64,64,0,0,64,64, 926428d7b3dSmrg 0,0,64,64,0,0,64,64, 927428d7b3dSmrg 0,0,64,64,0,0,64,64 928428d7b3dSmrg}; 929428d7b3dSmrg 930428d7b3dSmrgstatic unsigned int v_field_bytes[] = { 931428d7b3dSmrg 0,64,0,64,0,64,0,64, 932428d7b3dSmrg 0,64,0,64,0,64,0,64, 933428d7b3dSmrg 0,64,0,64,0,64,0,64, 934428d7b3dSmrg 0,64,0,64,0,64,0,64, 935428d7b3dSmrg 0,64,0,64,0,64,0,64, 936428d7b3dSmrg 0,64,0,64,0,64,0,64, 937428d7b3dSmrg 0,64,0,64,0,64,0,64, 938428d7b3dSmrg 0,64,0,64,0,64,0,64 939428d7b3dSmrg}; 940428d7b3dSmrg 941428d7b3dSmrgstatic short empty_block[] = { 942428d7b3dSmrg 0,0,0,0,0,0,0,0, 943428d7b3dSmrg 0,0,0,0,0,0,0,0, 944428d7b3dSmrg 0,0,0,0,0,0,0,0, 945428d7b3dSmrg 0,0,0,0,0,0,0,0, 946428d7b3dSmrg 0,0,0,0,0,0,0,0, 947428d7b3dSmrg 0,0,0,0,0,0,0,0, 948428d7b3dSmrg 0,0,0,0,0,0,0,0, 949428d7b3dSmrg 0,0,0,0,0,0,0,0 950428d7b3dSmrg}; 951428d7b3dSmrg 952428d7b3dSmrg 953428d7b3dSmrg/*************************************************************************** 954428d7b3dSmrg// Function: dispatchYContext 955428d7b3dSmrg// Description: Allocate a DMA buffer write the Y MC Context info in it, 956428d7b3dSmrg// and dispatch it to hardware. 957428d7b3dSmrg***************************************************************************/ 958428d7b3dSmrg 959428d7b3dSmrgstatic __inline__ void dispatchYContext(i810XvMCSurface *privTarget, 960428d7b3dSmrg i810XvMCSurface *privPast, 961428d7b3dSmrg i810XvMCSurface *privFuture, 962428d7b3dSmrg i810XvMCContext *pI810XvMC) { 963428d7b3dSmrg uint *data; 964428d7b3dSmrg drmBufPtr pDMA; 965428d7b3dSmrg drm_i810_mc_t mc; 966428d7b3dSmrg 967428d7b3dSmrg pDMA = i810_get_free_buffer(pI810XvMC); 968428d7b3dSmrg data = pDMA->address; 969428d7b3dSmrg *data++ = CMD_FLUSH; 970428d7b3dSmrg *data++ = BOOLEAN_ENA_2; 971428d7b3dSmrg *data++ = CMD_FLUSH; 972428d7b3dSmrg *data++ = DEST_BUFFER_INFO; 973428d7b3dSmrg *data++ = privTarget->dbi1y; 974428d7b3dSmrg *data++ = DEST_BUFFER_VAR; 975428d7b3dSmrg *data++ = privTarget->dbv1; 976428d7b3dSmrg /* Past Surface */ 977428d7b3dSmrg *data++ = CMD_MAP_INFO; 978428d7b3dSmrg *data++ = privPast->mi1y; 979428d7b3dSmrg *data++ = privPast->mi2y; 980428d7b3dSmrg *data++ = privPast->mi3y; 981428d7b3dSmrg /* Future Surface */ 982428d7b3dSmrg *data++ = CMD_MAP_INFO; 983428d7b3dSmrg *data++ = privFuture->mi1y | 0x1<<28; 984428d7b3dSmrg *data++ = privFuture->mi2y; 985428d7b3dSmrg *data++ = privFuture->mi3y; 986428d7b3dSmrg 987428d7b3dSmrg mc.idx = pDMA->idx; 988428d7b3dSmrg mc.used = (unsigned long)data - (unsigned long)pDMA->address; 989428d7b3dSmrg mc.last_render = ++pI810XvMC->last_render; 990428d7b3dSmrg privTarget->last_render = pI810XvMC->last_render; 991428d7b3dSmrg I810_MC(pI810XvMC,mc); 992428d7b3dSmrg} 993428d7b3dSmrg 994428d7b3dSmrgstatic __inline__ void renderError(void) { 995428d7b3dSmrg printf("Invalid Macroblock Parameters found.\n"); 996428d7b3dSmrg return; 997428d7b3dSmrg} 998428d7b3dSmrg 999428d7b3dSmrg/*************************************************************************** 1000428d7b3dSmrg// Function: renderIntrainFrame 1001428d7b3dSmrg// Description: inline function that sets hardware parameters for an Intra 1002428d7b3dSmrg// encoded macroblock in a Frame picture. 1003428d7b3dSmrg***************************************************************************/ 1004428d7b3dSmrgstatic __inline__ void renderIntrainFrame(uint **datay,uint **datau, 1005428d7b3dSmrg uint **datav, 1006428d7b3dSmrg XvMCMacroBlock *mb, 1007428d7b3dSmrg short *block_ptr) { 1008428d7b3dSmrg 1009428d7b3dSmrg register uint *dy = *datay; 1010428d7b3dSmrg register uint *du = *datau; 1011428d7b3dSmrg register uint *dv = *datav; 1012428d7b3dSmrg 1013428d7b3dSmrg /* Y Blocks */ 1014428d7b3dSmrg *dy++ = GFXBLOCK + 68; 1015428d7b3dSmrg *dy++ = (1<<30) | (3<<28) | (0xf<<24); 1016428d7b3dSmrg *dy++ = ((uint)mb->x<<20) | ((uint)mb->y<<4); 1017428d7b3dSmrg *dy++ = (16<<16) | 16; 1018428d7b3dSmrg *dy++ = 0; 1019428d7b3dSmrg *dy++ = 0; 1020428d7b3dSmrg PACK_INTRA_DATA(dy,block_ptr,256); 1021428d7b3dSmrg dy += 64; 1022428d7b3dSmrg block_ptr += 256; 1023428d7b3dSmrg /* End Y Blocks */ 1024428d7b3dSmrg 1025428d7b3dSmrg /* U Block */ 1026428d7b3dSmrg *du++ = GFXBLOCK + 20; 1027428d7b3dSmrg *du++ = (2<<30) | (1<<28) | (1<<23); 1028428d7b3dSmrg *du++ = (((uint)mb->x)<<19) | (((uint)mb->y)<<3); 1029428d7b3dSmrg *du++ = (8<<16) | 8; 1030428d7b3dSmrg *du++ = 0; 1031428d7b3dSmrg *du++ = 0; 1032428d7b3dSmrg PACK_INTRA_DATA(du,block_ptr,64); 1033428d7b3dSmrg du += 16; 1034428d7b3dSmrg block_ptr += 64; 1035428d7b3dSmrg 1036428d7b3dSmrg /* V Block */ 1037428d7b3dSmrg *dv++ = GFXBLOCK + 20; 1038428d7b3dSmrg *dv++ = (3<<30) | (1<<28) | (1<<22); 1039428d7b3dSmrg *dv++ = (((uint)mb->x)<<19) | (((uint)mb->y)<<3); 1040428d7b3dSmrg *dv++ = (8<<16) | 8; 1041428d7b3dSmrg *dv++ = 0; 1042428d7b3dSmrg *dv++ = 0; 1043428d7b3dSmrg PACK_INTRA_DATA(dv,block_ptr,64); 1044428d7b3dSmrg dv += 16; 1045428d7b3dSmrg block_ptr += 64; 1046428d7b3dSmrg 1047428d7b3dSmrg *datay = dy; 1048428d7b3dSmrg *datau = du; 1049428d7b3dSmrg *datav = dv; 1050428d7b3dSmrg} 1051428d7b3dSmrg 1052428d7b3dSmrg/*************************************************************************** 1053428d7b3dSmrg// Function: renderIntrainFrameDCT1 1054428d7b3dSmrg// Description: inline function that sets hardware parameters for an Intra 1055428d7b3dSmrg// encoded macroblock in a Frame picture with DCT type 1. 1056428d7b3dSmrg***************************************************************************/ 1057428d7b3dSmrgstatic __inline__ void renderIntrainFrameDCT1(uint **datay,uint **datau, 1058428d7b3dSmrg uint **datav,XvMCMacroBlock *mb, 1059428d7b3dSmrg short *block_ptr,uint flags) { 1060428d7b3dSmrg 1061428d7b3dSmrg register uint *dy = *datay; 1062428d7b3dSmrg register uint *du = *datau; 1063428d7b3dSmrg register uint *dv = *datav; 1064428d7b3dSmrg 1065428d7b3dSmrg 1066428d7b3dSmrg /* Y Blocks */ 1067428d7b3dSmrg *dy++ = GFXBLOCK + 36; 1068428d7b3dSmrg *dy++ = (1<<30) | (2<<28) | (0x3<<26) | (0x2<<6); 1069428d7b3dSmrg *dy++ = ((uint)mb->x<<20) | ((uint)mb->y<<3); 1070428d7b3dSmrg *dy++ = (8<<16) | 16; 1071428d7b3dSmrg *dy++ = 0; 1072428d7b3dSmrg *dy++ = 0; 1073428d7b3dSmrg PACK_INTRA_DATA(dy,block_ptr,128); 1074428d7b3dSmrg dy += 32; 1075428d7b3dSmrg block_ptr += 128; 1076428d7b3dSmrg 1077428d7b3dSmrg /* Second Y block */ 1078428d7b3dSmrg *dy++ = GFXBLOCK + 36; 1079428d7b3dSmrg *dy++ = (1<<30) | (2<<28) | (0x3<<26) | (0x3<<6); 1080428d7b3dSmrg *dy++ = ((uint)mb->x<<20) | ((uint)mb->y<<3); 1081428d7b3dSmrg *dy++ = (8<<16) | 16; 1082428d7b3dSmrg *dy++ = 0; 1083428d7b3dSmrg *dy++ = 0; 1084428d7b3dSmrg PACK_INTRA_DATA(dy,block_ptr,128); 1085428d7b3dSmrg dy += 32; 1086428d7b3dSmrg block_ptr += 128; 1087428d7b3dSmrg /* End Y Blocks */ 1088428d7b3dSmrg 1089428d7b3dSmrg 1090428d7b3dSmrg /* U Block */ 1091428d7b3dSmrg *du++ = GFXBLOCK + 20; 1092428d7b3dSmrg *du++ = (2<<30) | (1<<28) | (1<<23); 1093428d7b3dSmrg *du++ = (((uint)mb->x)<<19) | (((uint)mb->y)<<3); 1094428d7b3dSmrg *du++ = (8<<16) | 8; 1095428d7b3dSmrg *du++ = 0; 1096428d7b3dSmrg *du++ = 0; 1097428d7b3dSmrg PACK_INTRA_DATA(du,block_ptr,64); 1098428d7b3dSmrg du += 16; 1099428d7b3dSmrg block_ptr += 64; 1100428d7b3dSmrg 1101428d7b3dSmrg /* V Block */ 1102428d7b3dSmrg *dv++ = GFXBLOCK + 20; 1103428d7b3dSmrg *dv++ = (3<<30) | (1<<28) | (1<<22); 1104428d7b3dSmrg *dv++ = (((uint)mb->x)<<19) | (((uint)mb->y)<<3); 1105428d7b3dSmrg *dv++ = (8<<16) | 8; 1106428d7b3dSmrg *dv++ = 0; 1107428d7b3dSmrg *dv++ = 0; 1108428d7b3dSmrg PACK_INTRA_DATA(dv,block_ptr,64); 1109428d7b3dSmrg dv += 16; 1110428d7b3dSmrg block_ptr += 64; 1111428d7b3dSmrg 1112428d7b3dSmrg *datay = dy; 1113428d7b3dSmrg *datau = du; 1114428d7b3dSmrg *datav = dv; 1115428d7b3dSmrg} 1116428d7b3dSmrg 1117428d7b3dSmrg 1118428d7b3dSmrg/*************************************************************************** 1119428d7b3dSmrg// Function: renderIntrainField 1120428d7b3dSmrg// Description: inline function that sets hardware parameters for an Intra 1121428d7b3dSmrg// encoded macroblock in Field pictures. 1122428d7b3dSmrg***************************************************************************/ 1123428d7b3dSmrgstatic __inline__ void renderIntrainField(uint **datay,uint **datau, 1124428d7b3dSmrg uint **datav, 1125428d7b3dSmrg XvMCMacroBlock *mb,short *block_ptr, 1126428d7b3dSmrg uint ps) { 1127428d7b3dSmrg 1128428d7b3dSmrg register uint *dy = *datay; 1129428d7b3dSmrg register uint *du = *datau; 1130428d7b3dSmrg register uint *dv = *datav; 1131428d7b3dSmrg 1132428d7b3dSmrg uint xy = ((uint)mb->x<<20) | ((uint)mb->y<<4); 1133428d7b3dSmrg uint dw1 = drps_table[~ps & 0x1]; 1134428d7b3dSmrg 1135428d7b3dSmrg /* Y Blocks */ 1136428d7b3dSmrg *dy++ = GFXBLOCK + 68; 1137428d7b3dSmrg *dy++ = (1<<30) | (3<<28) | (0xf<<24) | dw1; 1138428d7b3dSmrg *dy++ = xy; 1139428d7b3dSmrg *dy++ = (16<<16) | 16; 1140428d7b3dSmrg *dy++ = 0; 1141428d7b3dSmrg *dy++ = 0; 1142428d7b3dSmrg PACK_INTRA_DATA(dy,block_ptr,256); 1143428d7b3dSmrg dy += 64; 1144428d7b3dSmrg block_ptr += 256; 1145428d7b3dSmrg /* End Y Blocks */ 1146428d7b3dSmrg 1147428d7b3dSmrg xy >>= 1; 1148428d7b3dSmrg 1149428d7b3dSmrg /* U Block */ 1150428d7b3dSmrg *du++ = GFXBLOCK + 20; 1151428d7b3dSmrg *du++ = (2<<30) | (1<<28) | (1<<23) | dw1; 1152428d7b3dSmrg *du++ = xy; 1153428d7b3dSmrg *du++ = (8<<16) | 8; 1154428d7b3dSmrg *du++ = 0; 1155428d7b3dSmrg *du++ = 0; 1156428d7b3dSmrg PACK_INTRA_DATA(du,block_ptr,64); 1157428d7b3dSmrg du += 16; 1158428d7b3dSmrg block_ptr += 64; 1159428d7b3dSmrg 1160428d7b3dSmrg /* V Block */ 1161428d7b3dSmrg *dv++ = GFXBLOCK + 20; 1162428d7b3dSmrg *dv++ = (3<<30) | (1<<28) | (1<<22) | dw1; 1163428d7b3dSmrg *dv++ = xy; 1164428d7b3dSmrg *dv++ = (8<<16) | 8; 1165428d7b3dSmrg *dv++ = 0; 1166428d7b3dSmrg *dv++ = 0; 1167428d7b3dSmrg PACK_INTRA_DATA(dv,block_ptr,64); 1168428d7b3dSmrg dv += 16; 1169428d7b3dSmrg block_ptr += 64; 1170428d7b3dSmrg 1171428d7b3dSmrg *datay = dy; 1172428d7b3dSmrg *datau = du; 1173428d7b3dSmrg *datav = dv; 1174428d7b3dSmrg} 1175428d7b3dSmrg 1176428d7b3dSmrg 1177428d7b3dSmrg/*************************************************************************** 1178428d7b3dSmrg// Function: renderFieldinField 1179428d7b3dSmrg// Description: inline function that sets hardware parameters for a Field 1180428d7b3dSmrg// encoded macroblock in a Field Picture. 1181428d7b3dSmrg***************************************************************************/ 1182428d7b3dSmrgstatic __inline__ void renderFieldinField(uint **datay,uint **datau, 1183428d7b3dSmrg uint **datav, 1184428d7b3dSmrg XvMCMacroBlock *mb,short *block_ptr, 1185428d7b3dSmrg uint ps, uint flags) { 1186428d7b3dSmrg 1187428d7b3dSmrg register uint *dy = *datay; 1188428d7b3dSmrg register uint *du = *datau; 1189428d7b3dSmrg register uint *dv = *datav; 1190428d7b3dSmrg 1191428d7b3dSmrg /* Motion Vectors */ 1192428d7b3dSmrg short fmv[2]; 1193428d7b3dSmrg short bmv[2]; 1194428d7b3dSmrg /* gfxblock dword 1 */ 1195428d7b3dSmrg uint dw1; 1196428d7b3dSmrg 1197428d7b3dSmrg uint parity = ~ps & XVMC_TOP_FIELD; 1198428d7b3dSmrg 1199428d7b3dSmrg uint ysize = y_frame_bytes[mb->coded_block_pattern]; 1200428d7b3dSmrg uint usize = u_frame_bytes[mb->coded_block_pattern]; 1201428d7b3dSmrg uint vsize = v_frame_bytes[mb->coded_block_pattern]; 1202428d7b3dSmrg 1203428d7b3dSmrg uint xy = ((uint)mb->x<<20) | ((uint)mb->y<<4); 1204428d7b3dSmrg 1205428d7b3dSmrg /* i810 Specific flag used to identify the second field in a P frame */ 1206428d7b3dSmrg if(flags & 0x80000000) { 1207428d7b3dSmrg /* P Frame */ 1208428d7b3dSmrg if((mb->motion_vertical_field_select & XVMC_SELECT_FIRST_FORWARD) == 1209428d7b3dSmrg parity) { 1210428d7b3dSmrg /* Same parity, use reference field (map0) */ 1211428d7b3dSmrg dw1 = 1<<12 | ((0x2 + parity)<<6) | ((0x2 + parity)<<3) | 1212428d7b3dSmrg (((uint)mb->coded_block_pattern)<<22); 1213428d7b3dSmrg fmv[0] = mb->PMV[0][0][1]; 1214428d7b3dSmrg fmv[1] = mb->PMV[0][0][0]; 1215428d7b3dSmrg bmv[0] = 0; 1216428d7b3dSmrg bmv[1] = 0; 1217428d7b3dSmrg } 1218428d7b3dSmrg else { 1219428d7b3dSmrg /* 1220428d7b3dSmrg Opposite parity, set up as if it were backward 1221428d7b3dSmrg motion and use map1. 1222428d7b3dSmrg */ 1223428d7b3dSmrg dw1 = 2<<12 | ((0x2 + parity)<<6) | (0x3 - parity) | 1224428d7b3dSmrg (((uint)mb->coded_block_pattern)<<22); 1225428d7b3dSmrg bmv[0] = mb->PMV[0][0][1]; 1226428d7b3dSmrg bmv[1] = mb->PMV[0][0][0]; 1227428d7b3dSmrg fmv[0] = 0; 1228428d7b3dSmrg fmv[1] = 0; 1229428d7b3dSmrg } 1230428d7b3dSmrg } 1231428d7b3dSmrg else { 1232428d7b3dSmrg dw1 = type_table[mb->macroblock_type & 0xf] | 1233428d7b3dSmrg drps_table[~ps & 0x1] | 1234428d7b3dSmrg mvfs_table[mb->motion_vertical_field_select & 3] | 1235428d7b3dSmrg (((uint)mb->coded_block_pattern)<<22); 1236428d7b3dSmrg 1237428d7b3dSmrg fmv[0] = mb->PMV[0][0][1]; 1238428d7b3dSmrg fmv[1] = mb->PMV[0][0][0]; 1239428d7b3dSmrg 1240428d7b3dSmrg bmv[0] = mb->PMV[0][1][1]; 1241428d7b3dSmrg bmv[1] = mb->PMV[0][1][0]; 1242428d7b3dSmrg } 1243428d7b3dSmrg 1244428d7b3dSmrg /* Y Block */ 1245428d7b3dSmrg *dy++ = GFXBLOCK + 4 + (ysize>>2); 1246428d7b3dSmrg *dy++ = (1<<30) | (3<<28) | dw1; 1247428d7b3dSmrg *dy++ = xy; 1248428d7b3dSmrg *dy++ = (16<<16) | 16; 1249428d7b3dSmrg *dy++ = *(uint *)fmv; 1250428d7b3dSmrg *dy++ = *(uint *)bmv; 1251428d7b3dSmrg PACK_CORR_DATA(dy,block_ptr,ysize); 1252428d7b3dSmrg block_ptr = (short *)((unsigned long)block_ptr + ysize); 1253428d7b3dSmrg /* End Y Blocks */ 1254428d7b3dSmrg 1255428d7b3dSmrg fmv[0] /= 2; 1256428d7b3dSmrg fmv[1] /= 2; 1257428d7b3dSmrg bmv[0] /= 2; 1258428d7b3dSmrg bmv[1] /= 2; 1259428d7b3dSmrg xy >>= 1; 1260428d7b3dSmrg 1261428d7b3dSmrg /* U Block */ 1262428d7b3dSmrg *du++ = GFXBLOCK + 4 + (usize>>2); 1263428d7b3dSmrg *du++ = (2<<30) | (1<<28) | dw1; 1264428d7b3dSmrg *du++ = xy; 1265428d7b3dSmrg *du++ = (8<<16) | 8; 1266428d7b3dSmrg *du++ = *(uint *)fmv; 1267428d7b3dSmrg *du++ = *(uint *)bmv; 1268428d7b3dSmrg PACK_CORR_DATA(du,block_ptr,usize); 1269428d7b3dSmrg block_ptr = (short *)((unsigned long)block_ptr + usize); 1270428d7b3dSmrg 1271428d7b3dSmrg /* V Block */ 1272428d7b3dSmrg *dv++ = GFXBLOCK + 4 + (vsize>>2); 1273428d7b3dSmrg *dv++ = (3<<30) | (1<<28) | dw1; 1274428d7b3dSmrg *dv++ = xy; 1275428d7b3dSmrg *dv++ = (8<<16) | 8; 1276428d7b3dSmrg *dv++ = *(uint *)fmv; 1277428d7b3dSmrg *dv++ = *(uint *)bmv; 1278428d7b3dSmrg PACK_CORR_DATA(dv,block_ptr,vsize); 1279428d7b3dSmrg block_ptr = (short *)((unsigned long)block_ptr + vsize); 1280428d7b3dSmrg 1281428d7b3dSmrg *datay = dy; 1282428d7b3dSmrg *datau = du; 1283428d7b3dSmrg *datav = dv; 1284428d7b3dSmrg} 1285428d7b3dSmrg 1286428d7b3dSmrg/*************************************************************************** 1287428d7b3dSmrg// Function: render16x8inField 1288428d7b3dSmrg// Description: inline function that sets hardware parameters for a 16x8 1289428d7b3dSmrg// encoded macroblock in a field picture. 1290428d7b3dSmrg***************************************************************************/ 1291428d7b3dSmrgstatic __inline__ void render16x8inField(uint **datay,uint **datau, 1292428d7b3dSmrg uint **datav, 1293428d7b3dSmrg XvMCMacroBlock *mb,short *block_ptr, 1294428d7b3dSmrg uint ps, uint flags) { 1295428d7b3dSmrg 1296428d7b3dSmrg register uint *dy = *datay; 1297428d7b3dSmrg register uint *du = *datau; 1298428d7b3dSmrg register uint *dv = *datav; 1299428d7b3dSmrg 1300428d7b3dSmrg /* Motion Vectors */ 1301428d7b3dSmrg short fmv[4]; 1302428d7b3dSmrg short bmv[4]; 1303428d7b3dSmrg /* gfxblock dword 1 */ 1304428d7b3dSmrg uint dw1[2]; 1305428d7b3dSmrg 1306428d7b3dSmrg uint y1size = y_first_field_bytes[mb->coded_block_pattern]; 1307428d7b3dSmrg uint y2size = y_second_field_bytes[mb->coded_block_pattern]; 1308428d7b3dSmrg uint usize = u_field_bytes[mb->coded_block_pattern]; 1309428d7b3dSmrg uint vsize = v_field_bytes[mb->coded_block_pattern]; 1310428d7b3dSmrg 1311428d7b3dSmrg uint parity = ~ps & XVMC_TOP_FIELD; 1312428d7b3dSmrg 1313428d7b3dSmrg uint xy = ((uint)mb->x<<20) | ((uint)mb->y<<4); 1314428d7b3dSmrg 1315428d7b3dSmrg /* i810 Specific flag used to identify the second field in a P frame */ 1316428d7b3dSmrg if(flags & 0x80000000) { 1317428d7b3dSmrg /* P Frame */ 1318428d7b3dSmrg if((mb->motion_vertical_field_select & XVMC_SELECT_FIRST_FORWARD) == 1319428d7b3dSmrg parity) { 1320428d7b3dSmrg /* Same parity, use reference field (map0) */ 1321428d7b3dSmrg dw1[0] = 1<<12 | ((0x2 + parity)<<6) | ((0x2 + parity)<<3) | 1322428d7b3dSmrg (((uint)mb->coded_block_pattern)<<22); 1323428d7b3dSmrg 1324428d7b3dSmrg fmv[0] = mb->PMV[0][0][1]; 1325428d7b3dSmrg fmv[1] = mb->PMV[0][0][0]; 1326428d7b3dSmrg bmv[0] = 0; 1327428d7b3dSmrg bmv[1] = 0; 1328428d7b3dSmrg } 1329428d7b3dSmrg else { 1330428d7b3dSmrg /* 1331428d7b3dSmrg Opposite parity, set up as if it were backward 1332428d7b3dSmrg motion and use map1. 1333428d7b3dSmrg */ 1334428d7b3dSmrg dw1[0] = 2<<12 | ((0x2 + parity)<<6) | (0x3 - parity) | 1335428d7b3dSmrg (((uint)mb->coded_block_pattern)<<22); 1336428d7b3dSmrg 1337428d7b3dSmrg bmv[0] = mb->PMV[0][0][1]; 1338428d7b3dSmrg bmv[1] = mb->PMV[0][0][0]; 1339428d7b3dSmrg fmv[0] = 0; 1340428d7b3dSmrg fmv[1] = 0; 1341428d7b3dSmrg } 1342428d7b3dSmrg if((mb->motion_vertical_field_select & XVMC_SELECT_SECOND_FORWARD) == 1343428d7b3dSmrg (parity<<2)) { 1344428d7b3dSmrg /* Same parity, use reference field (map0) */ 1345428d7b3dSmrg dw1[1] = 1<<12 | ((0x2 + parity)<<6) | ((0x2 + parity)<<3) | 1346428d7b3dSmrg ((((uint)mb->coded_block_pattern<<22) & (0x3<<22)) | 1347428d7b3dSmrg (((uint)mb->coded_block_pattern<<24) & (0x3<<26))); 1348428d7b3dSmrg 1349428d7b3dSmrg fmv[2] = mb->PMV[1][0][1]; 1350428d7b3dSmrg fmv[3] = mb->PMV[1][0][0]; 1351428d7b3dSmrg bmv[2] = 0; 1352428d7b3dSmrg bmv[3] = 0; 1353428d7b3dSmrg } 1354428d7b3dSmrg else { 1355428d7b3dSmrg /* 1356428d7b3dSmrg Opposite parity, set up as if it were backward 1357428d7b3dSmrg motion and use map1. 1358428d7b3dSmrg */ 1359428d7b3dSmrg dw1[1] = 2<<12 | ((0x2 + parity)<<6) | (0x3 - parity) | 1360428d7b3dSmrg ((((uint)mb->coded_block_pattern<<22) & (0x3<<22)) | 1361428d7b3dSmrg (((uint)mb->coded_block_pattern<<24) & (0x3<<26))); 1362428d7b3dSmrg 1363428d7b3dSmrg bmv[2] = mb->PMV[1][0][1]; 1364428d7b3dSmrg bmv[3] = mb->PMV[1][0][0]; 1365428d7b3dSmrg fmv[2] = 0; 1366428d7b3dSmrg fmv[3] = 0; 1367428d7b3dSmrg } 1368428d7b3dSmrg } 1369428d7b3dSmrg else { 1370428d7b3dSmrg dw1[0] = type_table[mb->macroblock_type & 0xf] | 1371428d7b3dSmrg drps_table[~ps & 0x1] | 1372428d7b3dSmrg mvfs_table[mb->motion_vertical_field_select & 3] | 1373428d7b3dSmrg (((uint)mb->coded_block_pattern)<<22); 1374428d7b3dSmrg 1375428d7b3dSmrg dw1[1] = type_table[mb->macroblock_type & 0xf] | 1376428d7b3dSmrg drps_table[~ps & 0x1] | 1377428d7b3dSmrg mvfs_table[(mb->motion_vertical_field_select>>2) & 0x3] | 1378428d7b3dSmrg ((((uint)mb->coded_block_pattern<<22) & (0x3<<22)) | 1379428d7b3dSmrg (((uint)mb->coded_block_pattern<<24) & (0x3<<26))); 1380428d7b3dSmrg 1381428d7b3dSmrg fmv[0] = mb->PMV[0][0][1]; 1382428d7b3dSmrg fmv[1] = mb->PMV[0][0][0]; 1383428d7b3dSmrg fmv[2] = mb->PMV[1][0][1]; 1384428d7b3dSmrg fmv[3] = mb->PMV[1][0][0]; 1385428d7b3dSmrg 1386428d7b3dSmrg bmv[0] = mb->PMV[0][1][1]; 1387428d7b3dSmrg bmv[1] = mb->PMV[0][1][0]; 1388428d7b3dSmrg bmv[2] = mb->PMV[1][1][1]; 1389428d7b3dSmrg bmv[3] = mb->PMV[1][1][0]; 1390428d7b3dSmrg } 1391428d7b3dSmrg 1392428d7b3dSmrg /* First Y Block */ 1393428d7b3dSmrg *dy++ = GFXBLOCK + 4 + (y1size>>2); 1394428d7b3dSmrg *dy++ = (1<<30) | (2<<28) | dw1[0]; 1395428d7b3dSmrg *dy++ = xy; 1396428d7b3dSmrg *dy++ = (8<<16) | 16; 1397428d7b3dSmrg *dy++ = *(uint *)fmv; 1398428d7b3dSmrg *dy++ = *(uint *)bmv; 1399428d7b3dSmrg PACK_CORR_DATA(dy,block_ptr,y1size); 1400428d7b3dSmrg block_ptr = (short *)((unsigned long)block_ptr + y1size); 1401428d7b3dSmrg 1402428d7b3dSmrg /* Second Y Block */ 1403428d7b3dSmrg *dy++ = GFXBLOCK + 4 + (y2size>>2); 1404428d7b3dSmrg *dy++ = (1<<30) | (2<<28) | dw1[1]; 1405428d7b3dSmrg *dy++ = (xy + 8); 1406428d7b3dSmrg *dy++ = (8<<16) | 16; 1407428d7b3dSmrg *dy++ = *(uint *)&fmv[2]; 1408428d7b3dSmrg *dy++ = *(uint *)&bmv[2]; 1409428d7b3dSmrg PACK_CORR_DATA(dy,block_ptr,y2size); 1410428d7b3dSmrg block_ptr = (short *)((unsigned long)block_ptr + y2size); 1411428d7b3dSmrg /* End Y Blocks */ 1412428d7b3dSmrg 1413428d7b3dSmrg fmv[0] /= 2; 1414428d7b3dSmrg fmv[1] /= 2; 1415428d7b3dSmrg fmv[2] /= 2; 1416428d7b3dSmrg fmv[3] /= 2; 1417428d7b3dSmrg 1418428d7b3dSmrg bmv[0] /= 2; 1419428d7b3dSmrg bmv[1] /= 2; 1420428d7b3dSmrg bmv[2] /= 2; 1421428d7b3dSmrg bmv[3] /= 2; 1422428d7b3dSmrg 1423428d7b3dSmrg xy >>= 1; 1424428d7b3dSmrg 1425428d7b3dSmrg /* U Blocks */ 1426428d7b3dSmrg *du++ = GFXBLOCK + 4 + (usize>>2); 1427428d7b3dSmrg *du++ = (2<<30) | (1<<28) | dw1[0]; 1428428d7b3dSmrg *du++ = xy; 1429428d7b3dSmrg *du++ = (4<<16) | 8; 1430428d7b3dSmrg *du++ = *(uint *)fmv; 1431428d7b3dSmrg *du++ = *(uint *)bmv; 1432428d7b3dSmrg PACK_CORR_DATA(du,block_ptr,usize); 1433428d7b3dSmrg block_ptr = (short *)((unsigned long)block_ptr + usize); 1434428d7b3dSmrg 1435428d7b3dSmrg /* Second U block */ 1436428d7b3dSmrg *du++ = GFXBLOCK + 4 + (usize>>2); 1437428d7b3dSmrg *du++ = (2<<30) | (1<<28) | dw1[1]; 1438428d7b3dSmrg *du++ = (xy + 4); 1439428d7b3dSmrg *du++ = (4<<16) | 8; 1440428d7b3dSmrg *du++ = *(uint *)&fmv[2]; 1441428d7b3dSmrg *du++ = *(uint *)&bmv[2]; 1442428d7b3dSmrg PACK_CORR_DATA(du,block_ptr,usize); 1443428d7b3dSmrg block_ptr = (short *)((unsigned long)block_ptr + usize); 1444428d7b3dSmrg /* End U Blocks */ 1445428d7b3dSmrg 1446428d7b3dSmrg /* V Blocks */ 1447428d7b3dSmrg *dv++ = GFXBLOCK + 4 + (vsize>>2); 1448428d7b3dSmrg *dv++ = (3<<30) | (1<<28) | dw1[0]; 1449428d7b3dSmrg *dv++ = xy; 1450428d7b3dSmrg *dv++ = (4<<16) | 8; 1451428d7b3dSmrg *dv++ = *(uint *)fmv; 1452428d7b3dSmrg *dv++ = *(uint *)bmv; 1453428d7b3dSmrg PACK_CORR_DATA(dv,block_ptr,vsize); 1454428d7b3dSmrg block_ptr = (short *)((unsigned long)block_ptr + vsize); 1455428d7b3dSmrg 1456428d7b3dSmrg /* Second V Block */ 1457428d7b3dSmrg *dv++ = GFXBLOCK + 4 + (vsize>>2); 1458428d7b3dSmrg *dv++ = (3<<30) | (1<<28) | dw1[1]; 1459428d7b3dSmrg *dv++ = (xy + 4); 1460428d7b3dSmrg *dv++ = (4<<16) | 8; 1461428d7b3dSmrg *dv++ = *(uint *)&fmv[2]; 1462428d7b3dSmrg *dv++ = *(uint *)&bmv[2]; 1463428d7b3dSmrg PACK_CORR_DATA(dv,block_ptr,vsize); 1464428d7b3dSmrg block_ptr = (short *)((unsigned long)block_ptr + vsize); 1465428d7b3dSmrg /* End V Blocks */ 1466428d7b3dSmrg 1467428d7b3dSmrg *datay = dy; 1468428d7b3dSmrg *datau = du; 1469428d7b3dSmrg *datav = dv; 1470428d7b3dSmrg} 1471428d7b3dSmrg 1472428d7b3dSmrg/*************************************************************************** 1473428d7b3dSmrg// Function: renderDualPrimeinField 1474428d7b3dSmrg// Description: inline function that sets hardware parameters for a Dual 1475428d7b3dSmrg// prime encoded macroblock in a field picture. 1476428d7b3dSmrg***************************************************************************/ 1477428d7b3dSmrgstatic __inline__ void renderDualPrimeinField(uint **datay,uint **datau, 1478428d7b3dSmrg uint **datav,XvMCMacroBlock *mb, 1479428d7b3dSmrg short *block_ptr,uint ps, 1480428d7b3dSmrg uint flags) { 1481428d7b3dSmrg 1482428d7b3dSmrg register uint *dy = *datay; 1483428d7b3dSmrg register uint *du = *datau; 1484428d7b3dSmrg register uint *dv = *datav; 1485428d7b3dSmrg 1486428d7b3dSmrg /* Motion Vectors */ 1487428d7b3dSmrg short fmv[2]; 1488428d7b3dSmrg short bmv[2]; 1489428d7b3dSmrg /* gfxblock dword 1 */ 1490428d7b3dSmrg uint dw1; 1491428d7b3dSmrg 1492428d7b3dSmrg 1493428d7b3dSmrg uint ysize = y_frame_bytes[mb->coded_block_pattern]; 1494428d7b3dSmrg uint usize = u_frame_bytes[mb->coded_block_pattern]; 1495428d7b3dSmrg uint vsize = v_frame_bytes[mb->coded_block_pattern]; 1496428d7b3dSmrg 1497428d7b3dSmrg uint xy = ((uint)mb->x<<20) | ((uint)mb->y<<4); 1498428d7b3dSmrg 1499428d7b3dSmrg 1500428d7b3dSmrg if(ps & XVMC_TOP_FIELD) { 1501428d7b3dSmrg dw1 = (mb->coded_block_pattern<<22) | 3<<12 | 2<<6 | 2<<3 | 3; 1502428d7b3dSmrg } 1503428d7b3dSmrg else { 1504428d7b3dSmrg dw1 = (mb->coded_block_pattern<<22) | 3<<12 | 3<<6 | 3<<3 | 2; 1505428d7b3dSmrg } 1506428d7b3dSmrg fmv[0] = mb->PMV[0][0][1]; 1507428d7b3dSmrg fmv[1] = mb->PMV[0][0][0]; 1508428d7b3dSmrg bmv[0] = mb->PMV[0][1][1]; 1509428d7b3dSmrg bmv[1] = mb->PMV[0][1][0]; 1510428d7b3dSmrg 1511428d7b3dSmrg /* Y Block */ 1512428d7b3dSmrg *dy++ = GFXBLOCK + 4 + (ysize>>2); 1513428d7b3dSmrg *dy++ = (1<<30) | (3<<28) | dw1; 1514428d7b3dSmrg *dy++ = xy; 1515428d7b3dSmrg *dy++ = (16<<16) | 16; 1516428d7b3dSmrg *dy++ = *(uint *)fmv; 1517428d7b3dSmrg *dy++ = *(uint *)bmv; 1518428d7b3dSmrg PACK_CORR_DATA(dy,block_ptr,ysize); 1519428d7b3dSmrg block_ptr = (short *)((unsigned long)block_ptr + ysize); 1520428d7b3dSmrg /* End Y Blocks */ 1521428d7b3dSmrg 1522428d7b3dSmrg fmv[0] /= 2; 1523428d7b3dSmrg fmv[1] /= 2; 1524428d7b3dSmrg bmv[0] /= 2; 1525428d7b3dSmrg bmv[1] /= 2; 1526428d7b3dSmrg xy >>= 1; 1527428d7b3dSmrg 1528428d7b3dSmrg /* U Block */ 1529428d7b3dSmrg *du++ = GFXBLOCK + 4 + (usize>>2); 1530428d7b3dSmrg *du++ = (2<<30) | (1<<28) | dw1; 1531428d7b3dSmrg *du++ = xy; 1532428d7b3dSmrg *du++ = (8<<16) | 8; 1533428d7b3dSmrg *du++ = *(uint *)fmv; 1534428d7b3dSmrg *du++ = *(uint *)bmv; 1535428d7b3dSmrg PACK_CORR_DATA(du,block_ptr,usize); 1536428d7b3dSmrg block_ptr = (short *)((unsigned long)block_ptr + usize); 1537428d7b3dSmrg 1538428d7b3dSmrg /* V Block */ 1539428d7b3dSmrg *dv++ = GFXBLOCK + 4 + (vsize>>2); 1540428d7b3dSmrg *dv++ = (3<<30) | (1<<28) | dw1; 1541428d7b3dSmrg *dv++ = xy; 1542428d7b3dSmrg *dv++ = (8<<16) | 8; 1543428d7b3dSmrg *dv++ = *(uint *)fmv; 1544428d7b3dSmrg *dv++ = *(uint *)bmv; 1545428d7b3dSmrg PACK_CORR_DATA(dv,block_ptr,vsize); 1546428d7b3dSmrg block_ptr = (short *)((unsigned long)block_ptr + vsize); 1547428d7b3dSmrg 1548428d7b3dSmrg *datay = dy; 1549428d7b3dSmrg *datau = du; 1550428d7b3dSmrg *datav = dv; 1551428d7b3dSmrg} 1552428d7b3dSmrg 1553428d7b3dSmrg/*************************************************************************** 1554428d7b3dSmrg// Function: renderFieldinFrame 1555428d7b3dSmrg// Description: inline function that sets hardware parameters for a Field 1556428d7b3dSmrg// encoded macroblock in a frame picture. 1557428d7b3dSmrg***************************************************************************/ 1558428d7b3dSmrgtypedef union { 1559428d7b3dSmrg short s[4]; 1560428d7b3dSmrg uint u[2]; 1561428d7b3dSmrg} su_t; 1562428d7b3dSmrg 1563428d7b3dSmrgstatic __inline__ void renderFieldinFrame(uint **datay,uint **datau, 1564428d7b3dSmrg uint **datav, 1565428d7b3dSmrg XvMCMacroBlock *mb,short *block_ptr, 1566428d7b3dSmrg uint flags) { 1567428d7b3dSmrg 1568428d7b3dSmrg register uint *dy = *datay; 1569428d7b3dSmrg register uint *du = *datau; 1570428d7b3dSmrg register uint *dv = *datav; 1571428d7b3dSmrg 1572428d7b3dSmrg /* Motion Vectors */ 1573428d7b3dSmrg su_t fmv; 1574428d7b3dSmrg su_t bmv; 1575428d7b3dSmrg /* gfxblock dword 1 */ 1576428d7b3dSmrg uint dw1[2]; 1577428d7b3dSmrg 1578428d7b3dSmrg uint y1size = y_first_field_bytes[mb->coded_block_pattern]; 1579428d7b3dSmrg uint y2size = y_second_field_bytes[mb->coded_block_pattern]; 1580428d7b3dSmrg uint usize = u_field_bytes[mb->coded_block_pattern]; 1581428d7b3dSmrg uint vsize = v_field_bytes[mb->coded_block_pattern]; 1582428d7b3dSmrg 1583428d7b3dSmrg uint xy = ((uint)mb->x<<20) | ((uint)mb->y<<3); 1584428d7b3dSmrg 1585428d7b3dSmrg dw1[0] = type_table[mb->macroblock_type & 0xf] | (0x2<<6) | 1586428d7b3dSmrg mvfs_table[mb->motion_vertical_field_select & 3] | 1587428d7b3dSmrg (((uint)mb->coded_block_pattern)<<22); 1588428d7b3dSmrg 1589428d7b3dSmrg dw1[1] = type_table[mb->macroblock_type & 0xf] | (0x3<<6) | 1590428d7b3dSmrg mvfs_table[mb->motion_vertical_field_select>>2] | 1591428d7b3dSmrg (((mb->coded_block_pattern & 0x3) | 1592428d7b3dSmrg ((mb->coded_block_pattern & 0xc)<<2))<<22); 1593428d7b3dSmrg 1594428d7b3dSmrg fmv.s[0] = mb->PMV[0][0][1]/2; 1595428d7b3dSmrg fmv.s[1] = mb->PMV[0][0][0]; 1596428d7b3dSmrg fmv.s[2] = mb->PMV[1][0][1]/2; 1597428d7b3dSmrg fmv.s[3] = mb->PMV[1][0][0]; 1598428d7b3dSmrg 1599428d7b3dSmrg bmv.s[0] = mb->PMV[0][1][1]/2; 1600428d7b3dSmrg bmv.s[1] = mb->PMV[0][1][0]; 1601428d7b3dSmrg bmv.s[2] = mb->PMV[1][1][1]/2; 1602428d7b3dSmrg bmv.s[3] = mb->PMV[1][1][0]; 1603428d7b3dSmrg 1604428d7b3dSmrg /* First Y Block */ 1605428d7b3dSmrg *dy++ = GFXBLOCK + 4 + (y1size>>2); 1606428d7b3dSmrg *dy++ = (1<<30) | (2<<28) | dw1[0]; 1607428d7b3dSmrg *dy++ = xy; 1608428d7b3dSmrg *dy++ = (8<<16) | 16; 1609428d7b3dSmrg *dy++ = fmv.u[0]; 1610428d7b3dSmrg *dy++ = bmv.u[0]; 1611428d7b3dSmrg PACK_CORR_DATA(dy,block_ptr,y1size); 1612428d7b3dSmrg block_ptr = (short *)((unsigned long)block_ptr + y1size); 1613428d7b3dSmrg 1614428d7b3dSmrg /* Second Y Block */ 1615428d7b3dSmrg *dy++ = GFXBLOCK + 4 + (y2size>>2); 1616428d7b3dSmrg *dy++ = (1<<30) | (2<<28) | dw1[1]; 1617428d7b3dSmrg *dy++ = xy; 1618428d7b3dSmrg *dy++ = (8<<16) | 16; 1619428d7b3dSmrg *dy++ = fmv.u[1]; 1620428d7b3dSmrg *dy++ = bmv.u[1]; 1621428d7b3dSmrg PACK_CORR_DATA(dy,block_ptr,y2size); 1622428d7b3dSmrg block_ptr = (short *)((unsigned long)block_ptr + y2size); 1623428d7b3dSmrg /* End Y Blocks */ 1624428d7b3dSmrg 1625428d7b3dSmrg fmv.s[0] /= 2; 1626428d7b3dSmrg fmv.s[1] /= 2; 1627428d7b3dSmrg fmv.s[2] /= 2; 1628428d7b3dSmrg fmv.s[3] /= 2; 1629428d7b3dSmrg 1630428d7b3dSmrg bmv.s[0] /= 2; 1631428d7b3dSmrg bmv.s[1] /= 2; 1632428d7b3dSmrg bmv.s[2] /= 2; 1633428d7b3dSmrg bmv.s[3] /= 2; 1634428d7b3dSmrg 1635428d7b3dSmrg xy >>= 1; 1636428d7b3dSmrg 1637428d7b3dSmrg /* U Blocks */ 1638428d7b3dSmrg *du++ = GFXBLOCK + 4 + (usize>>2); 1639428d7b3dSmrg *du++ = (2<<30) | (1<<28) | dw1[0]; 1640428d7b3dSmrg *du++ = xy; 1641428d7b3dSmrg *du++ = (4<<16) | 8; 1642428d7b3dSmrg *du++ = fmv.u[0]; 1643428d7b3dSmrg *du++ = bmv.u[0]; 1644428d7b3dSmrg if(usize) { 1645428d7b3dSmrg PACK_CORR_DATA_SHORT(du,block_ptr); 1646428d7b3dSmrg } 1647428d7b3dSmrg 1648428d7b3dSmrg /* Second U Block */ 1649428d7b3dSmrg *du++ = GFXBLOCK + 4 + (usize>>2); 1650428d7b3dSmrg *du++ = (2<<30) | (1<<28) | dw1[1]; 1651428d7b3dSmrg *du++ = xy; 1652428d7b3dSmrg *du++ = (4<<16) | 8; 1653428d7b3dSmrg *du++ = fmv.u[1]; 1654428d7b3dSmrg *du++ = bmv.u[1]; 1655428d7b3dSmrg if(usize) { 1656428d7b3dSmrg block_ptr = (short *)((unsigned long)block_ptr + 16); 1657428d7b3dSmrg PACK_CORR_DATA_SHORT(du,block_ptr); 1658428d7b3dSmrg block_ptr = (short *)((unsigned long)block_ptr + 112); 1659428d7b3dSmrg } 1660428d7b3dSmrg /* End U Blocks */ 1661428d7b3dSmrg 1662428d7b3dSmrg /* V Blocks */ 1663428d7b3dSmrg *dv++ = GFXBLOCK + 4 + (vsize>>2); 1664428d7b3dSmrg *dv++ = (3<<30) | (1<<28) | dw1[0]; 1665428d7b3dSmrg *dv++ = xy; 1666428d7b3dSmrg *dv++ = (4<<16) | 8; 1667428d7b3dSmrg *dv++ = fmv.u[0]; 1668428d7b3dSmrg *dv++ = bmv.u[0]; 1669428d7b3dSmrg if(vsize) { 1670428d7b3dSmrg PACK_CORR_DATA_SHORT(dv,block_ptr); 1671428d7b3dSmrg } 1672428d7b3dSmrg 1673428d7b3dSmrg /* Second V Block */ 1674428d7b3dSmrg *dv++ = GFXBLOCK + 4 + (vsize>>2); 1675428d7b3dSmrg *dv++ = (3<<30) | (1<<28) | dw1[1]; 1676428d7b3dSmrg *dv++ = xy; 1677428d7b3dSmrg *dv++ = (4<<16) | 8; 1678428d7b3dSmrg *dv++ = fmv.u[1]; 1679428d7b3dSmrg *dv++ = bmv.u[1]; 1680428d7b3dSmrg if(vsize) { 1681428d7b3dSmrg block_ptr = (short *)((unsigned long)block_ptr + 16); 1682428d7b3dSmrg PACK_CORR_DATA_SHORT(dv,block_ptr); 1683428d7b3dSmrg block_ptr = (short *)((unsigned long)block_ptr + 112); 1684428d7b3dSmrg } 1685428d7b3dSmrg /* End V Blocks */ 1686428d7b3dSmrg 1687428d7b3dSmrg *datay = dy; 1688428d7b3dSmrg *datau = du; 1689428d7b3dSmrg *datav = dv; 1690428d7b3dSmrg} 1691428d7b3dSmrg 1692428d7b3dSmrg/*************************************************************************** 1693428d7b3dSmrg// Function: renderFieldinFrameDCT0 1694428d7b3dSmrg// Description: inline function that sets hardware parameters for a Field 1695428d7b3dSmrg// encoded macroblock in a frame picture with DCT0. 1696428d7b3dSmrg***************************************************************************/ 1697428d7b3dSmrgstatic __inline__ void renderFieldinFrameDCT0(uint **datay,uint **datau, 1698428d7b3dSmrg uint **datav,XvMCMacroBlock *mb, 1699428d7b3dSmrg short *block_ptr,uint flags) { 1700428d7b3dSmrg 1701428d7b3dSmrg register uint *dy = *datay; 1702428d7b3dSmrg register uint *du = *datau; 1703428d7b3dSmrg register uint *dv = *datav; 1704428d7b3dSmrg 1705428d7b3dSmrg /* Motion Vectors */ 1706428d7b3dSmrg su_t fmv; 1707428d7b3dSmrg su_t bmv; 1708428d7b3dSmrg /* CBP */ 1709428d7b3dSmrg uint cbp = (uint)mb->coded_block_pattern; 1710428d7b3dSmrg /* gfxblock dword 1 */ 1711428d7b3dSmrg uint dw1[2]; 1712428d7b3dSmrg 1713428d7b3dSmrg short * top_left_b = NULL; 1714428d7b3dSmrg short * top_right_b = NULL; 1715428d7b3dSmrg short * bottom_left_b = NULL; 1716428d7b3dSmrg short * bottom_right_b = NULL; 1717428d7b3dSmrg 1718428d7b3dSmrg unsigned int ysize = y_dct0_field_bytes[cbp]; 1719428d7b3dSmrg unsigned int usize = u_field_bytes[cbp]; 1720428d7b3dSmrg unsigned int vsize = v_field_bytes[cbp]; 1721428d7b3dSmrg 1722428d7b3dSmrg uint xy = ((uint)mb->x<<20) | ((uint)mb->y<<3); 1723428d7b3dSmrg 1724428d7b3dSmrg dw1[0] = type_table[mb->macroblock_type & 0xf] | (0x2<<6) | 1725428d7b3dSmrg mvfs_table[mb->motion_vertical_field_select & 3] | 1726428d7b3dSmrg ((cbp | ((cbp<<2) & 0x30))<<22); 1727428d7b3dSmrg 1728428d7b3dSmrg dw1[1] = type_table[mb->macroblock_type & 0xf] | (0x3<<6) | 1729428d7b3dSmrg mvfs_table[mb->motion_vertical_field_select>>2] | 1730428d7b3dSmrg ((cbp | ((cbp<<2) & 0x30))<<22); 1731428d7b3dSmrg 1732428d7b3dSmrg 1733428d7b3dSmrg fmv.s[0] = mb->PMV[0][0][1]/2; 1734428d7b3dSmrg fmv.s[1] = mb->PMV[0][0][0]; 1735428d7b3dSmrg fmv.s[2] = mb->PMV[1][0][1]/2; 1736428d7b3dSmrg fmv.s[3] = mb->PMV[1][0][0]; 1737428d7b3dSmrg 1738428d7b3dSmrg bmv.s[0] = mb->PMV[0][1][1]/2; 1739428d7b3dSmrg bmv.s[1] = mb->PMV[0][1][0]; 1740428d7b3dSmrg bmv.s[2] = mb->PMV[1][1][1]/2; 1741428d7b3dSmrg bmv.s[3] = mb->PMV[1][1][0]; 1742428d7b3dSmrg 1743428d7b3dSmrg /* 1744428d7b3dSmrg The i810 cannot use DCT0 directly with field motion, we have to 1745428d7b3dSmrg interlace the data for it. We use a zero block when the CBP has 1746428d7b3dSmrg one half of the to-be-interlaced data but not the other half. 1747428d7b3dSmrg */ 1748428d7b3dSmrg top_left_b = &empty_block[0]; 1749428d7b3dSmrg if(cbp & 0x20) { 1750428d7b3dSmrg top_left_b = block_ptr; 1751428d7b3dSmrg block_ptr += 64; 1752428d7b3dSmrg } 1753428d7b3dSmrg 1754428d7b3dSmrg top_right_b = &empty_block[0]; 1755428d7b3dSmrg if(cbp & 0x10) { 1756428d7b3dSmrg top_right_b = block_ptr; 1757428d7b3dSmrg block_ptr += 64; 1758428d7b3dSmrg } 1759428d7b3dSmrg 1760428d7b3dSmrg bottom_left_b = &empty_block[0]; 1761428d7b3dSmrg if(cbp & 0x8) { 1762428d7b3dSmrg bottom_left_b = block_ptr; 1763428d7b3dSmrg block_ptr += 64; 1764428d7b3dSmrg } 1765428d7b3dSmrg 1766428d7b3dSmrg bottom_right_b = &empty_block[0]; 1767428d7b3dSmrg if(cbp & 0x4) { 1768428d7b3dSmrg bottom_right_b = block_ptr; 1769428d7b3dSmrg block_ptr += 64; 1770428d7b3dSmrg } 1771428d7b3dSmrg 1772428d7b3dSmrg /* First Y Block */ 1773428d7b3dSmrg *dy++ = GFXBLOCK + 4 + (ysize>>2); 1774428d7b3dSmrg *dy++ = (1<<30) | (2<<28) | dw1[0]; 1775428d7b3dSmrg *dy++ = xy; 1776428d7b3dSmrg *dy++ = (8<<16) | 16; 1777428d7b3dSmrg *dy++ = fmv.u[0]; 1778428d7b3dSmrg *dy++ = bmv.u[0]; 1779428d7b3dSmrg if(dw1[0] & (1<<27)) { 1780428d7b3dSmrg PACK_CORR_DATA_0to1(dy,top_left_b,bottom_left_b); 1781428d7b3dSmrg } 1782428d7b3dSmrg if(dw1[0] & (1<<26)) { 1783428d7b3dSmrg PACK_CORR_DATA_0to1(dy,top_right_b,bottom_right_b); 1784428d7b3dSmrg } 1785428d7b3dSmrg 1786428d7b3dSmrg /* Second Y Block */ 1787428d7b3dSmrg *dy++ = GFXBLOCK + 4 + (ysize>>2); 1788428d7b3dSmrg *dy++ = (1<<30) | (2<<28) | dw1[1]; 1789428d7b3dSmrg *dy++ = xy; 1790428d7b3dSmrg *dy++ = (8<<16) | 16; 1791428d7b3dSmrg *dy++ = fmv.u[1]; 1792428d7b3dSmrg *dy++ = bmv.u[1]; 1793428d7b3dSmrg if(dw1[1] & (1<<27)) { 1794428d7b3dSmrg top_left_b = (short *)((unsigned long)top_left_b + 16); 1795428d7b3dSmrg bottom_left_b = (short *)((unsigned long)bottom_left_b + 16); 1796428d7b3dSmrg PACK_CORR_DATA_0to1(dy,top_left_b,bottom_left_b); 1797428d7b3dSmrg } 1798428d7b3dSmrg if(dw1[1] & (1<<26)) { 1799428d7b3dSmrg top_right_b = (short *)((unsigned long)top_right_b + 16); 1800428d7b3dSmrg bottom_right_b = (short *)((unsigned long)bottom_right_b + 16); 1801428d7b3dSmrg PACK_CORR_DATA_0to1(dy,top_right_b,bottom_right_b); 1802428d7b3dSmrg } 1803428d7b3dSmrg /* End Y Blocks */ 1804428d7b3dSmrg 1805428d7b3dSmrg fmv.s[0] /= 2; 1806428d7b3dSmrg fmv.s[1] /= 2; 1807428d7b3dSmrg fmv.s[2] /= 2; 1808428d7b3dSmrg fmv.s[3] /= 2; 1809428d7b3dSmrg 1810428d7b3dSmrg bmv.s[0] /= 2; 1811428d7b3dSmrg bmv.s[1] /= 2; 1812428d7b3dSmrg bmv.s[2] /= 2; 1813428d7b3dSmrg bmv.s[3] /= 2; 1814428d7b3dSmrg 1815428d7b3dSmrg xy >>= 1; 1816428d7b3dSmrg 1817428d7b3dSmrg /* U Blocks */ 1818428d7b3dSmrg *du++ = GFXBLOCK + 4 + (usize>>2); 1819428d7b3dSmrg *du++ = (2<<30) | (1<<28) | dw1[0]; 1820428d7b3dSmrg *du++ = xy; 1821428d7b3dSmrg *du++ = (4<<16) | 8; 1822428d7b3dSmrg *du++ = fmv.u[0]; 1823428d7b3dSmrg *du++ = bmv.u[0]; 1824428d7b3dSmrg if(usize) { 1825428d7b3dSmrg PACK_CORR_DATA_SHORT(du,block_ptr); 1826428d7b3dSmrg } 1827428d7b3dSmrg 1828428d7b3dSmrg /* Second U Block */ 1829428d7b3dSmrg *du++ = GFXBLOCK + 4 + (usize>>2); 1830428d7b3dSmrg *du++ = (2<<30) | (1<<28) | dw1[1]; 1831428d7b3dSmrg *du++ = xy; 1832428d7b3dSmrg *du++ = (4<<16) | 8; 1833428d7b3dSmrg *du++ = fmv.u[1]; 1834428d7b3dSmrg *du++ = bmv.u[1]; 1835428d7b3dSmrg if(usize) { 1836428d7b3dSmrg block_ptr = (short *)((unsigned long)block_ptr + 16); 1837428d7b3dSmrg PACK_CORR_DATA_SHORT(du,block_ptr); 1838428d7b3dSmrg block_ptr = (short *)((unsigned long)block_ptr + 112); 1839428d7b3dSmrg } 1840428d7b3dSmrg /* End U Blocks */ 1841428d7b3dSmrg 1842428d7b3dSmrg /* V Blocks */ 1843428d7b3dSmrg *dv++ = GFXBLOCK + 4 + (vsize>>2); 1844428d7b3dSmrg *dv++ = (3<<30) | (1<<28) | dw1[0]; 1845428d7b3dSmrg *dv++ = xy; 1846428d7b3dSmrg *dv++ = (4<<16) | 8; 1847428d7b3dSmrg *dv++ = fmv.u[0]; 1848428d7b3dSmrg *dv++ = bmv.u[0]; 1849428d7b3dSmrg if(vsize) { 1850428d7b3dSmrg PACK_CORR_DATA_SHORT(dv,block_ptr); 1851428d7b3dSmrg } 1852428d7b3dSmrg 1853428d7b3dSmrg /* Second V Block */ 1854428d7b3dSmrg *dv++ = GFXBLOCK + 4 + (vsize>>2); 1855428d7b3dSmrg *dv++ = (3<<30) | (1<<28) | dw1[1]; 1856428d7b3dSmrg *dv++ = xy; 1857428d7b3dSmrg *dv++ = (4<<16) | 8; 1858428d7b3dSmrg *dv++ = fmv.u[1]; 1859428d7b3dSmrg *dv++ = bmv.u[1]; 1860428d7b3dSmrg if(vsize) { 1861428d7b3dSmrg block_ptr = (short *)((unsigned long)block_ptr + 16); 1862428d7b3dSmrg PACK_CORR_DATA_SHORT(dv,block_ptr); 1863428d7b3dSmrg block_ptr = (short *)((unsigned long)block_ptr + 112); 1864428d7b3dSmrg } 1865428d7b3dSmrg /* End V Blocks */ 1866428d7b3dSmrg 1867428d7b3dSmrg *datay = dy; 1868428d7b3dSmrg *datau = du; 1869428d7b3dSmrg *datav = dv; 1870428d7b3dSmrg} 1871428d7b3dSmrg 1872428d7b3dSmrg/*************************************************************************** 1873428d7b3dSmrg// Function: renderFrameinFrame 1874428d7b3dSmrg// Description: inline function that sets hardware parameters for a Frame 1875428d7b3dSmrg// encoded macroblock in a frame picture. 1876428d7b3dSmrg***************************************************************************/ 1877428d7b3dSmrgstatic __inline__ void renderFrameinFrame(uint **datay,uint **datau, 1878428d7b3dSmrg uint **datav, 1879428d7b3dSmrg XvMCMacroBlock *mb,short *block_ptr, 1880428d7b3dSmrg uint flags) { 1881428d7b3dSmrg 1882428d7b3dSmrg register uint *dy = *datay; 1883428d7b3dSmrg register uint *du = *datau; 1884428d7b3dSmrg register uint *dv = *datav; 1885428d7b3dSmrg 1886428d7b3dSmrg /* Motion Vectors */ 1887428d7b3dSmrg su_t fmv; 1888428d7b3dSmrg su_t bmv; 1889428d7b3dSmrg /* gfxblock dword 1 */ 1890428d7b3dSmrg uint dw1; 1891428d7b3dSmrg 1892428d7b3dSmrg unsigned int ysize = y_frame_bytes[mb->coded_block_pattern]; 1893428d7b3dSmrg unsigned int usize = u_frame_bytes[mb->coded_block_pattern]; 1894428d7b3dSmrg unsigned int vsize = v_frame_bytes[mb->coded_block_pattern]; 1895428d7b3dSmrg 1896428d7b3dSmrg uint xy = ((uint)mb->x<<20) | ((uint)mb->y<<4); 1897428d7b3dSmrg 1898428d7b3dSmrg dw1 = type_table[mb->macroblock_type & 0xf] | 1899428d7b3dSmrg (((uint)mb->coded_block_pattern)<<22); 1900428d7b3dSmrg 1901428d7b3dSmrg 1902428d7b3dSmrg fmv.s[0] = mb->PMV[0][0][1]; 1903428d7b3dSmrg fmv.s[1] = mb->PMV[0][0][0]; 1904428d7b3dSmrg 1905428d7b3dSmrg bmv.s[0] = mb->PMV[0][1][1]; 1906428d7b3dSmrg bmv.s[1] = mb->PMV[0][1][0]; 1907428d7b3dSmrg 1908428d7b3dSmrg /* Y Block */ 1909428d7b3dSmrg *dy++ = GFXBLOCK + 4 + (ysize>>2); 1910428d7b3dSmrg *dy++ = (1<<30) | (3<<28) | dw1; 1911428d7b3dSmrg *dy++ = xy; 1912428d7b3dSmrg *dy++ = (16<<16) | 16; 1913428d7b3dSmrg *dy++ = fmv.u[0]; 1914428d7b3dSmrg *dy++ = bmv.u[0]; 1915428d7b3dSmrg PACK_CORR_DATA(dy,block_ptr,ysize); 1916428d7b3dSmrg block_ptr = (short *)((unsigned long)block_ptr + ysize); 1917428d7b3dSmrg /* End Y Blocks */ 1918428d7b3dSmrg 1919428d7b3dSmrg fmv.s[0] /= 2; 1920428d7b3dSmrg fmv.s[1] /= 2; 1921428d7b3dSmrg 1922428d7b3dSmrg bmv.s[0] /= 2; 1923428d7b3dSmrg bmv.s[1] /= 2; 1924428d7b3dSmrg 1925428d7b3dSmrg xy >>= 1; 1926428d7b3dSmrg 1927428d7b3dSmrg /* U Block */ 1928428d7b3dSmrg *du++ = GFXBLOCK + 4 + (usize>>2); 1929428d7b3dSmrg *du++ = (2<<30) | (1<<28) | dw1; 1930428d7b3dSmrg *du++ = xy; 1931428d7b3dSmrg *du++ = (8<<16) | 8; 1932428d7b3dSmrg *du++ = fmv.u[0]; 1933428d7b3dSmrg *du++ = bmv.u[0]; 1934428d7b3dSmrg PACK_CORR_DATA(du,block_ptr,usize); 1935428d7b3dSmrg block_ptr = (short *)((unsigned long)block_ptr + usize); 1936428d7b3dSmrg /* End U Block */ 1937428d7b3dSmrg 1938428d7b3dSmrg /* V Block */ 1939428d7b3dSmrg *dv++ = GFXBLOCK + 4 + (vsize>>2); 1940428d7b3dSmrg *dv++ = (3<<30) | (1<<28) | dw1; 1941428d7b3dSmrg *dv++ = xy; 1942428d7b3dSmrg *dv++ = (8<<16) | 8; 1943428d7b3dSmrg *dv++ = fmv.u[0]; 1944428d7b3dSmrg *dv++ = bmv.u[0]; 1945428d7b3dSmrg PACK_CORR_DATA(dv,block_ptr,vsize); 1946428d7b3dSmrg block_ptr = (short *)((unsigned long)block_ptr + vsize); 1947428d7b3dSmrg /* End V Block */ 1948428d7b3dSmrg 1949428d7b3dSmrg *datay = dy; 1950428d7b3dSmrg *datau = du; 1951428d7b3dSmrg *datav = dv; 1952428d7b3dSmrg} 1953428d7b3dSmrg 1954428d7b3dSmrg/*************************************************************************** 1955428d7b3dSmrg// Function: renderFrameinFrameDCT1 1956428d7b3dSmrg// Description: inline function that sets hardware parameters for a Frame 1957428d7b3dSmrg// encoded macroblock in a frame picture with DCT type 1. 1958428d7b3dSmrg***************************************************************************/ 1959428d7b3dSmrgstatic __inline__ void renderFrameinFrameDCT1(uint **datay,uint **datau, 1960428d7b3dSmrg uint **datav,XvMCMacroBlock *mb, 1961428d7b3dSmrg short *block_ptr,uint flags) { 1962428d7b3dSmrg 1963428d7b3dSmrg register uint *dy = *datay; 1964428d7b3dSmrg register uint *du = *datau; 1965428d7b3dSmrg register uint *dv = *datav; 1966428d7b3dSmrg 1967428d7b3dSmrg /* Motion Vectors */ 1968428d7b3dSmrg su_t fmv; 1969428d7b3dSmrg su_t bmv; 1970428d7b3dSmrg 1971428d7b3dSmrg short * top_left_b = NULL; 1972428d7b3dSmrg short * top_right_b = NULL; 1973428d7b3dSmrg short * bottom_left_b = NULL; 1974428d7b3dSmrg short * bottom_right_b = NULL; 1975428d7b3dSmrg 1976428d7b3dSmrg uint temp_bp = 0; 1977428d7b3dSmrg 1978428d7b3dSmrg uint ysize = y_dct1_frame_bytes[mb->coded_block_pattern]; 1979428d7b3dSmrg uint usize = u_frame_bytes[mb->coded_block_pattern]; 1980428d7b3dSmrg uint vsize = v_frame_bytes[mb->coded_block_pattern]; 1981428d7b3dSmrg 1982428d7b3dSmrg uint xy = ((uint)mb->x<<20) | ((uint)mb->y<<4); 1983428d7b3dSmrg 1984428d7b3dSmrg uint dw1 = type_table[mb->macroblock_type & 0xf] | 1985428d7b3dSmrg (((uint)mb->coded_block_pattern)<<22); 1986428d7b3dSmrg 1987428d7b3dSmrg fmv.s[0] = mb->PMV[0][0][1]; 1988428d7b3dSmrg fmv.s[1] = mb->PMV[0][0][0]; 1989428d7b3dSmrg 1990428d7b3dSmrg bmv.s[0] = mb->PMV[0][1][1]; 1991428d7b3dSmrg bmv.s[1] = mb->PMV[0][1][0]; 1992428d7b3dSmrg 1993428d7b3dSmrg /* 1994428d7b3dSmrg It is easiest to find out what blocks are in need of reading first 1995428d7b3dSmrg rather than as we go. 1996428d7b3dSmrg */ 1997428d7b3dSmrg top_left_b = &empty_block[0]; 1998428d7b3dSmrg if(dw1 & (1<<27)) { 1999428d7b3dSmrg temp_bp |= (1<<25); 2000428d7b3dSmrg top_left_b = block_ptr; 2001428d7b3dSmrg block_ptr += 64; 2002428d7b3dSmrg } 2003428d7b3dSmrg 2004428d7b3dSmrg top_right_b = &empty_block[0]; 2005428d7b3dSmrg if(dw1 & (1<<26)) { 2006428d7b3dSmrg temp_bp |= (1<<24); 2007428d7b3dSmrg top_right_b = block_ptr; 2008428d7b3dSmrg block_ptr += 64; 2009428d7b3dSmrg } 2010428d7b3dSmrg 2011428d7b3dSmrg bottom_left_b = &empty_block[0]; 2012428d7b3dSmrg if(dw1 & (1<<25)) { 2013428d7b3dSmrg temp_bp |= (1<<27); 2014428d7b3dSmrg bottom_left_b = block_ptr; 2015428d7b3dSmrg block_ptr += 64; 2016428d7b3dSmrg } 2017428d7b3dSmrg 2018428d7b3dSmrg bottom_right_b = &empty_block[0]; 2019428d7b3dSmrg if(dw1 & (1<<24)) { 2020428d7b3dSmrg temp_bp |= (1<<26); 2021428d7b3dSmrg bottom_right_b = block_ptr; 2022428d7b3dSmrg block_ptr += 64; 2023428d7b3dSmrg } 2024428d7b3dSmrg dw1 |= temp_bp; 2025428d7b3dSmrg 2026428d7b3dSmrg /* Y Block */ 2027428d7b3dSmrg *dy++ = GFXBLOCK + 4 + (ysize>>2); 2028428d7b3dSmrg *dy++ = (1<<30) | (3<<28) | dw1; 2029428d7b3dSmrg *dy++ = xy; 2030428d7b3dSmrg *dy++ = (16<<16) | 16; 2031428d7b3dSmrg *dy++ = fmv.u[0]; 2032428d7b3dSmrg *dy++ = bmv.u[0]; 2033428d7b3dSmrg if(dw1 & (1<<27)) { 2034428d7b3dSmrg PACK_CORR_DATA_1to0(dy,top_left_b,bottom_left_b); 2035428d7b3dSmrg top_left_b = (short *)((unsigned long)top_left_b + 64); 2036428d7b3dSmrg bottom_left_b = (short *)((unsigned long)bottom_left_b + 64); 2037428d7b3dSmrg } 2038428d7b3dSmrg if(dw1 & (1<<26)) { 2039428d7b3dSmrg PACK_CORR_DATA_1to0(dy,top_right_b,bottom_right_b); 2040428d7b3dSmrg top_right_b = (short *)((unsigned long)top_right_b + 64); 2041428d7b3dSmrg bottom_right_b = (short *)((unsigned long)bottom_right_b + 64); 2042428d7b3dSmrg } 2043428d7b3dSmrg if(dw1 & (1<<27)) { 2044428d7b3dSmrg PACK_CORR_DATA_1to0(dy,top_left_b,bottom_left_b); 2045428d7b3dSmrg } 2046428d7b3dSmrg if(dw1 & (1<<26)) { 2047428d7b3dSmrg PACK_CORR_DATA_1to0(dy,top_right_b,bottom_right_b); 2048428d7b3dSmrg } 2049428d7b3dSmrg /* End Y Block */ 2050428d7b3dSmrg 2051428d7b3dSmrg fmv.s[0] /= 2; 2052428d7b3dSmrg fmv.s[1] /= 2; 2053428d7b3dSmrg 2054428d7b3dSmrg bmv.s[0] /= 2; 2055428d7b3dSmrg bmv.s[1] /= 2; 2056428d7b3dSmrg 2057428d7b3dSmrg xy >>= 1; 2058428d7b3dSmrg 2059428d7b3dSmrg /* U Block */ 2060428d7b3dSmrg *du++ = GFXBLOCK + 4 + (usize>>2); 2061428d7b3dSmrg *du++ = (2<<30) | (1<<28) | dw1; 2062428d7b3dSmrg *du++ = xy; 2063428d7b3dSmrg *du++ = (8<<16) | 8; 2064428d7b3dSmrg *du++ = fmv.u[0]; 2065428d7b3dSmrg *du++ = bmv.u[0]; 2066428d7b3dSmrg PACK_CORR_DATA(du,block_ptr,usize); 2067428d7b3dSmrg block_ptr = (short *)((unsigned long)block_ptr + usize); 2068428d7b3dSmrg 2069428d7b3dSmrg /* V Block */ 2070428d7b3dSmrg *dv++ = GFXBLOCK + 4 + (vsize>>2); 2071428d7b3dSmrg *dv++ = (3<<30) | (1<<28) | dw1; 2072428d7b3dSmrg *dv++ = xy; 2073428d7b3dSmrg *dv++ = (8<<16) | 8; 2074428d7b3dSmrg *dv++ = fmv.u[0]; 2075428d7b3dSmrg *dv++ = bmv.u[0]; 2076428d7b3dSmrg PACK_CORR_DATA(dv,block_ptr,vsize); 2077428d7b3dSmrg block_ptr = (short *)((unsigned long)block_ptr + vsize); 2078428d7b3dSmrg 2079428d7b3dSmrg *datay = dy; 2080428d7b3dSmrg *datau = du; 2081428d7b3dSmrg *datav = dv; 2082428d7b3dSmrg} 2083428d7b3dSmrg 2084428d7b3dSmrg/*************************************************************************** 2085428d7b3dSmrg// Function: renderDualPrimeinFrame 2086428d7b3dSmrg// Description: inline function that sets hardware parameters for a Dual 2087428d7b3dSmrg// Prime encoded macroblock in a frame picture with dct 1. 2088428d7b3dSmrg***************************************************************************/ 2089428d7b3dSmrgstatic __inline__ void renderDualPrimeinFrame(uint **datay,uint **datau, 2090428d7b3dSmrg uint **datav,XvMCMacroBlock *mb, 2091428d7b3dSmrg short *block_ptr,uint flags) { 2092428d7b3dSmrg 2093428d7b3dSmrg register uint *dy = *datay; 2094428d7b3dSmrg register uint *du = *datau; 2095428d7b3dSmrg register uint *dv = *datav; 2096428d7b3dSmrg 2097428d7b3dSmrg /* Motion Vectors */ 2098428d7b3dSmrg su_t fmv; 2099428d7b3dSmrg su_t bmv; 2100428d7b3dSmrg /* gfxblock dword 1 */ 2101428d7b3dSmrg uint dw1[2]; 2102428d7b3dSmrg 2103428d7b3dSmrg uint y1size = y_first_field_bytes[mb->coded_block_pattern]; 2104428d7b3dSmrg uint y2size = y_second_field_bytes[mb->coded_block_pattern]; 2105428d7b3dSmrg uint usize = u_field_bytes[mb->coded_block_pattern]; 2106428d7b3dSmrg uint vsize = v_field_bytes[mb->coded_block_pattern]; 2107428d7b3dSmrg 2108428d7b3dSmrg uint xy = ((uint)mb->x<<20) | ((uint)mb->y<<3); 2109428d7b3dSmrg 2110428d7b3dSmrg /* 2111428d7b3dSmrg Past Surface (map 0) is used for same parity prediction, 2112428d7b3dSmrg Future surface (map 1) is used for opposite. 2113428d7b3dSmrg */ 2114428d7b3dSmrg dw1[0] = (((uint)mb->coded_block_pattern)<<22) | 2115428d7b3dSmrg 3<<12 | 2<<6 | 2<<3 | 3; 2116428d7b3dSmrg dw1[1] = (((mb->coded_block_pattern & 0x3) | 2117428d7b3dSmrg ((mb->coded_block_pattern & 0xc)<<2))<<22) | 2118428d7b3dSmrg 3<<12 | 3<<6 | 3<<3 | 2; 2119428d7b3dSmrg 2120428d7b3dSmrg fmv.s[0] = mb->PMV[0][0][1]; 2121428d7b3dSmrg fmv.s[1] = mb->PMV[0][0][0]; 2122428d7b3dSmrg bmv.s[0] = mb->PMV[1][0][1]; 2123428d7b3dSmrg bmv.s[1] = mb->PMV[1][0][0]; 2124428d7b3dSmrg 2125428d7b3dSmrg fmv.s[2] = mb->PMV[0][0][1]; 2126428d7b3dSmrg fmv.s[3] = mb->PMV[0][0][0]; 2127428d7b3dSmrg bmv.s[2] = mb->PMV[1][1][1]; 2128428d7b3dSmrg bmv.s[3] = mb->PMV[1][1][0]; 2129428d7b3dSmrg 2130428d7b3dSmrg /* First Y Block */ 2131428d7b3dSmrg *dy++ = GFXBLOCK + 4 + (y1size>>2); 2132428d7b3dSmrg *dy++ = (1<<30) | (2<<28) | dw1[0]; 2133428d7b3dSmrg *dy++ = xy; 2134428d7b3dSmrg *dy++ = (8<<16) | 16; 2135428d7b3dSmrg *dy++ = fmv.u[0]; 2136428d7b3dSmrg *dy++ = bmv.u[0];; 2137428d7b3dSmrg PACK_CORR_DATA(dy,block_ptr,y1size); 2138428d7b3dSmrg block_ptr = (short *)((unsigned long)block_ptr + y1size); 2139428d7b3dSmrg 2140428d7b3dSmrg /* Second Y Block */ 2141428d7b3dSmrg *dy++ = GFXBLOCK + 4 + (y2size>>2); 2142428d7b3dSmrg *dy++ = (1<<30) | (2<<28) | dw1[1]; 2143428d7b3dSmrg *dy++ = xy; 2144428d7b3dSmrg *dy++ = (8<<16) | 16; 2145428d7b3dSmrg *dy++ = fmv.u[1]; 2146428d7b3dSmrg *dy++ = bmv.u[1]; 2147428d7b3dSmrg PACK_CORR_DATA(dy,block_ptr,y2size); 2148428d7b3dSmrg block_ptr = (short *)((unsigned long)block_ptr + y2size); 2149428d7b3dSmrg 2150428d7b3dSmrg fmv.s[0] /= 2; 2151428d7b3dSmrg fmv.s[1] /= 2; 2152428d7b3dSmrg bmv.s[0] /= 2; 2153428d7b3dSmrg bmv.s[1] /= 2; 2154428d7b3dSmrg 2155428d7b3dSmrg fmv.s[2] /= 2; 2156428d7b3dSmrg fmv.s[3] /= 2; 2157428d7b3dSmrg bmv.s[2] /= 2; 2158428d7b3dSmrg bmv.s[3] /= 2; 2159428d7b3dSmrg 2160428d7b3dSmrg xy >>= 1; 2161428d7b3dSmrg 2162428d7b3dSmrg /* U Blocks */ 2163428d7b3dSmrg *du++ = GFXBLOCK + 4 + (usize>>2); 2164428d7b3dSmrg *du++ = (2<<30) | (1<<28) | dw1[0]; 2165428d7b3dSmrg *du++ = xy; 2166428d7b3dSmrg *du++ = (4<<16) | 8; 2167428d7b3dSmrg *du++ = fmv.u[0]; 2168428d7b3dSmrg *du++ = bmv.u[0]; 2169428d7b3dSmrg if(dw1[0] & (1<<23)) { 2170428d7b3dSmrg PACK_CORR_DATA_SHORT(du,block_ptr); 2171428d7b3dSmrg } 2172428d7b3dSmrg 2173428d7b3dSmrg /* Second U Block */ 2174428d7b3dSmrg *du++ = GFXBLOCK + 4 + (usize>>2); 2175428d7b3dSmrg *du++ = (2<<30) | (1<<28) | dw1[1]; 2176428d7b3dSmrg *du++ = xy; 2177428d7b3dSmrg *du++ = (4<<16) | 8; 2178428d7b3dSmrg *du++ = fmv.u[1]; 2179428d7b3dSmrg *du++ = bmv.u[1]; 2180428d7b3dSmrg if(dw1[1] & (1<<23)) { 2181428d7b3dSmrg block_ptr = (short *)((unsigned long)block_ptr + 16); 2182428d7b3dSmrg PACK_CORR_DATA_SHORT(du,block_ptr); 2183428d7b3dSmrg block_ptr = (short *)((unsigned long)block_ptr + 112); 2184428d7b3dSmrg } 2185428d7b3dSmrg /* End U Blocks */ 2186428d7b3dSmrg 2187428d7b3dSmrg /* V Blocks */ 2188428d7b3dSmrg *dv++ = GFXBLOCK + 4 + (vsize>>2); 2189428d7b3dSmrg *dv++ = (3<<30) | (1<<28) | dw1[0]; 2190428d7b3dSmrg *dv++ = xy; 2191428d7b3dSmrg *dv++ = (4<<16) | 8; 2192428d7b3dSmrg *dv++ = fmv.u[0]; 2193428d7b3dSmrg *dv++ = bmv.u[0]; 2194428d7b3dSmrg if(dw1[0] & (1<<22)) { 2195428d7b3dSmrg PACK_CORR_DATA_SHORT(dv,block_ptr); 2196428d7b3dSmrg } 2197428d7b3dSmrg 2198428d7b3dSmrg /* Second V Block */ 2199428d7b3dSmrg *dv++ = GFXBLOCK + 4 + (vsize>>2); 2200428d7b3dSmrg *dv++ = (3<<30) | (1<<28) | dw1[1]; 2201428d7b3dSmrg *dv++ = xy; 2202428d7b3dSmrg *dv++ = (4<<16) | 8; 2203428d7b3dSmrg *dv++ = fmv.u[1]; 2204428d7b3dSmrg *dv++ = bmv.u[1]; 2205428d7b3dSmrg if(dw1[1] & (1<<22)) { 2206428d7b3dSmrg block_ptr = (short *)((unsigned long)block_ptr + 16); 2207428d7b3dSmrg PACK_CORR_DATA_SHORT(dv,block_ptr); 2208428d7b3dSmrg block_ptr = (short *)((unsigned long)block_ptr + 112); 2209428d7b3dSmrg } 2210428d7b3dSmrg /* End V Blocks */ 2211428d7b3dSmrg 2212428d7b3dSmrg *datay = dy; 2213428d7b3dSmrg *datau = du; 2214428d7b3dSmrg *datav = dv; 2215428d7b3dSmrg} 2216428d7b3dSmrg 2217428d7b3dSmrg/*************************************************************************** 2218428d7b3dSmrg// Function: renderDualPrimeinFrameDCT0 2219428d7b3dSmrg// Description: inline function that sets hardware parameters for a Dual 2220428d7b3dSmrg// Prime encoded macroblock in a frame picture with dct 0. 2221428d7b3dSmrg***************************************************************************/ 2222428d7b3dSmrgstatic __inline__ void renderDualPrimeinFrameDCT0(uint **datay,uint **datau, 2223428d7b3dSmrg uint **datav, 2224428d7b3dSmrg XvMCMacroBlock *mb, 2225428d7b3dSmrg short *block_ptr, 2226428d7b3dSmrg uint flags) { 2227428d7b3dSmrg 2228428d7b3dSmrg register uint *dy = *datay; 2229428d7b3dSmrg register uint *du = *datau; 2230428d7b3dSmrg register uint *dv = *datav; 2231428d7b3dSmrg 2232428d7b3dSmrg /* Motion Vectors */ 2233428d7b3dSmrg su_t fmv; 2234428d7b3dSmrg su_t bmv; 2235428d7b3dSmrg /* gfxblock dword 1 */ 2236428d7b3dSmrg uint dw1[2]; 2237428d7b3dSmrg 2238428d7b3dSmrg short * top_left_b = NULL; 2239428d7b3dSmrg short * top_right_b = NULL; 2240428d7b3dSmrg short * bottom_left_b = NULL; 2241428d7b3dSmrg short * bottom_right_b = NULL; 2242428d7b3dSmrg 2243428d7b3dSmrg uint cbp = (uint)mb->coded_block_pattern; 2244428d7b3dSmrg 2245428d7b3dSmrg uint ysize = y_dct0_field_bytes[cbp]; 2246428d7b3dSmrg uint usize = u_field_bytes[cbp]; 2247428d7b3dSmrg uint vsize = v_field_bytes[cbp]; 2248428d7b3dSmrg 2249428d7b3dSmrg uint xy = ((uint)mb->x<<20) | ((uint)mb->y<<3); 2250428d7b3dSmrg 2251428d7b3dSmrg /* 2252428d7b3dSmrg Past Surface (map 0) is used for same parity prediction, 2253428d7b3dSmrg Future surface (map 1) is used for opposite. 2254428d7b3dSmrg */ 2255428d7b3dSmrg dw1[0] = ((cbp | ((cbp<<2) & 0x30))<<22) | 2256428d7b3dSmrg 3<<12 | 2<<6 | 2<<3 | 3; 2257428d7b3dSmrg dw1[1] = ((cbp | ((cbp<<2) & 0x30))<<22) | 2258428d7b3dSmrg 3<<12 | 3<<6 | 3<<3 | 2; 2259428d7b3dSmrg 2260428d7b3dSmrg fmv.s[0] = mb->PMV[0][0][1]; 2261428d7b3dSmrg fmv.s[1] = mb->PMV[0][0][0]; 2262428d7b3dSmrg bmv.s[0] = mb->PMV[1][0][1]; 2263428d7b3dSmrg bmv.s[1] = mb->PMV[1][0][0]; 2264428d7b3dSmrg 2265428d7b3dSmrg fmv.s[2] = mb->PMV[0][0][1]; 2266428d7b3dSmrg fmv.s[3] = mb->PMV[0][0][0]; 2267428d7b3dSmrg bmv.s[2] = mb->PMV[1][1][1]; 2268428d7b3dSmrg bmv.s[3] = mb->PMV[1][1][0]; 2269428d7b3dSmrg 2270428d7b3dSmrg /* 2271428d7b3dSmrg The i810 cannot use DCT0 directly with field motion, we have to 2272428d7b3dSmrg interlace the data for it. We use a zero block when the CBP has 2273428d7b3dSmrg one half of the to-be-interlaced data but not the other half. 2274428d7b3dSmrg */ 2275428d7b3dSmrg top_left_b = &empty_block[0]; 2276428d7b3dSmrg if(cbp & 0x20) { 2277428d7b3dSmrg top_left_b = block_ptr; 2278428d7b3dSmrg block_ptr += 64; 2279428d7b3dSmrg } 2280428d7b3dSmrg 2281428d7b3dSmrg top_right_b = &empty_block[0]; 2282428d7b3dSmrg if(cbp & 0x10) { 2283428d7b3dSmrg top_right_b = block_ptr; 2284428d7b3dSmrg block_ptr += 64; 2285428d7b3dSmrg } 2286428d7b3dSmrg 2287428d7b3dSmrg bottom_left_b = &empty_block[0]; 2288428d7b3dSmrg if(cbp & 0x8) { 2289428d7b3dSmrg bottom_left_b = block_ptr; 2290428d7b3dSmrg block_ptr += 64; 2291428d7b3dSmrg } 2292428d7b3dSmrg 2293428d7b3dSmrg bottom_right_b = &empty_block[0]; 2294428d7b3dSmrg if(cbp & 0x4) { 2295428d7b3dSmrg bottom_right_b = block_ptr; 2296428d7b3dSmrg block_ptr += 64; 2297428d7b3dSmrg } 2298428d7b3dSmrg 2299428d7b3dSmrg /* First Y Block */ 2300428d7b3dSmrg *dy++ = GFXBLOCK + 4 + (ysize>>2); 2301428d7b3dSmrg *dy++ = (1<<30) | (2<<28) | dw1[0]; 2302428d7b3dSmrg *dy++ = xy; 2303428d7b3dSmrg *dy++ = (8<<16) | 16; 2304428d7b3dSmrg *dy++ = fmv.u[0]; 2305428d7b3dSmrg *dy++ = bmv.u[0]; 2306428d7b3dSmrg if(cbp & 0x20) { 2307428d7b3dSmrg PACK_CORR_DATA_0to1(dy,top_left_b,bottom_left_b); 2308428d7b3dSmrg } 2309428d7b3dSmrg if(cbp & 0x10) { 2310428d7b3dSmrg PACK_CORR_DATA_0to1(dy,top_right_b,bottom_right_b); 2311428d7b3dSmrg } 2312428d7b3dSmrg 2313428d7b3dSmrg /* Second Y Block */ 2314428d7b3dSmrg *dy++ = GFXBLOCK + 4 + (ysize>>2); 2315428d7b3dSmrg *dy++ = (1<<30) | (2<<28) | dw1[1]; 2316428d7b3dSmrg *dy++ = xy; 2317428d7b3dSmrg *dy++ = (8<<16) | 16; 2318428d7b3dSmrg *dy++ = fmv.u[1]; 2319428d7b3dSmrg *dy++ = bmv.u[1]; 2320428d7b3dSmrg if(cbp & 0x20) { 2321428d7b3dSmrg top_left_b = (short *)((unsigned long)top_left_b + 16); 2322428d7b3dSmrg bottom_left_b = (short *)((unsigned long)bottom_left_b + 16); 2323428d7b3dSmrg PACK_CORR_DATA_0to1(dy,top_left_b,bottom_left_b); 2324428d7b3dSmrg } 2325428d7b3dSmrg if(cbp & 0x10) { 2326428d7b3dSmrg top_right_b = (short *)((unsigned long)top_right_b + 16); 2327428d7b3dSmrg bottom_right_b = (short *)((unsigned long)bottom_right_b + 16); 2328428d7b3dSmrg PACK_CORR_DATA_0to1(dy,top_right_b,bottom_right_b); 2329428d7b3dSmrg } 2330428d7b3dSmrg /* End Y Blocks */ 2331428d7b3dSmrg 2332428d7b3dSmrg 2333428d7b3dSmrg fmv.s[0] /= 2; 2334428d7b3dSmrg fmv.s[1] /= 2; 2335428d7b3dSmrg bmv.s[0] /= 2; 2336428d7b3dSmrg bmv.s[1] /= 2; 2337428d7b3dSmrg 2338428d7b3dSmrg fmv.s[2] /= 2; 2339428d7b3dSmrg fmv.s[3] /= 2; 2340428d7b3dSmrg bmv.s[2] /= 2; 2341428d7b3dSmrg bmv.s[3] /= 2; 2342428d7b3dSmrg 2343428d7b3dSmrg xy >>= 1; 2344428d7b3dSmrg 2345428d7b3dSmrg /* U Blocks */ 2346428d7b3dSmrg *du++ = GFXBLOCK + 4 + (usize>>2); 2347428d7b3dSmrg *du++ = (2<<30) | (1<<28) | dw1[0]; 2348428d7b3dSmrg *du++ = xy; 2349428d7b3dSmrg *du++ = (4<<16) | 8; 2350428d7b3dSmrg *du++ = fmv.u[0]; 2351428d7b3dSmrg *du++ = bmv.u[0]; 2352428d7b3dSmrg if(cbp & (1<<23)) { 2353428d7b3dSmrg PACK_CORR_DATA_SHORT(du,block_ptr); 2354428d7b3dSmrg } 2355428d7b3dSmrg 2356428d7b3dSmrg /* Second U Block */ 2357428d7b3dSmrg *du++ = GFXBLOCK + 4 + (usize>>2); 2358428d7b3dSmrg *du++ = (2<<30) | (1<<28) | dw1[1]; 2359428d7b3dSmrg *du++ = xy; 2360428d7b3dSmrg *du++ = (4<<16) | 8; 2361428d7b3dSmrg *du++ = fmv.u[1]; 2362428d7b3dSmrg *du++ = bmv.u[1]; 2363428d7b3dSmrg if(cbp & (1<<23)) { 2364428d7b3dSmrg block_ptr = (short *)((unsigned long)block_ptr + 16); 2365428d7b3dSmrg PACK_CORR_DATA_SHORT(du,block_ptr); 2366428d7b3dSmrg block_ptr = (short *)((unsigned long)block_ptr + 112); 2367428d7b3dSmrg } 2368428d7b3dSmrg /* End U Blocks */ 2369428d7b3dSmrg 2370428d7b3dSmrg /* V Blocks */ 2371428d7b3dSmrg *dv++ = GFXBLOCK + 4 + (vsize>>2); 2372428d7b3dSmrg *dv++ = (3<<30) | (1<<28) | dw1[0]; 2373428d7b3dSmrg *dv++ = xy; 2374428d7b3dSmrg *dv++ = (4<<16) | 8; 2375428d7b3dSmrg *dv++ = fmv.u[0]; 2376428d7b3dSmrg *dv++ = bmv.u[0]; 2377428d7b3dSmrg if(cbp & (1<<22)) { 2378428d7b3dSmrg PACK_CORR_DATA_SHORT(dv,block_ptr); 2379428d7b3dSmrg } 2380428d7b3dSmrg 2381428d7b3dSmrg /* Second V Block */ 2382428d7b3dSmrg *dv++ = GFXBLOCK + 4 + (vsize>>2); 2383428d7b3dSmrg *dv++ = (3<<30) | (1<<28) | dw1[1]; 2384428d7b3dSmrg *dv++ = xy; 2385428d7b3dSmrg *dv++ = (4<<16) | 8; 2386428d7b3dSmrg *dv++ = fmv.u[1]; 2387428d7b3dSmrg *dv++ = bmv.u[1]; 2388428d7b3dSmrg if(cbp & (1<<22)) { 2389428d7b3dSmrg block_ptr = (short *)((unsigned long)block_ptr + 16); 2390428d7b3dSmrg PACK_CORR_DATA_SHORT(dv,block_ptr); 2391428d7b3dSmrg block_ptr = (short *)((unsigned long)block_ptr + 112); 2392428d7b3dSmrg } 2393428d7b3dSmrg /* End V Blocks */ 2394428d7b3dSmrg 2395428d7b3dSmrg *datay = dy; 2396428d7b3dSmrg *datau = du; 2397428d7b3dSmrg *datav = dv; 2398428d7b3dSmrg} 2399428d7b3dSmrg 2400428d7b3dSmrg 2401428d7b3dSmrg/*************************************************************************** 2402428d7b3dSmrg// Function: XvMCRenderSurface 2403428d7b3dSmrg// Description: This function does the actual HWMC. Given a list of 2404428d7b3dSmrg// macroblock structures it dispatched the hardware commands to execute 2405428d7b3dSmrg// them. DMA buffer containing Y data are dispatched as they fill up 2406428d7b3dSmrg// U and V DMA buffers are queued until all Y's are done. This minimizes 2407428d7b3dSmrg// the context flipping and flushing required when switching between Y 2408428d7b3dSmrg// U and V surfaces. 2409428d7b3dSmrg***************************************************************************/ 2410428d7b3dSmrg#define UV_QUEUE 14 2411428d7b3dSmrg_X_EXPORT Status XvMCRenderSurface(Display *display, XvMCContext *context, 2412428d7b3dSmrg unsigned int picture_structure, 2413428d7b3dSmrg XvMCSurface *target_surface, 2414428d7b3dSmrg XvMCSurface *past_surface, 2415428d7b3dSmrg XvMCSurface *future_surface, 2416428d7b3dSmrg unsigned int flags, 2417428d7b3dSmrg unsigned int num_macroblocks, 2418428d7b3dSmrg unsigned int first_macroblock, 2419428d7b3dSmrg XvMCMacroBlockArray *macroblock_array, 2420428d7b3dSmrg XvMCBlockArray *blocks) { 2421428d7b3dSmrg /* Dma Data Structures */ 2422428d7b3dSmrg drmBufPtr pDMAy = NULL,pDMAu[UV_QUEUE],pDMAv[UV_QUEUE]; 2423428d7b3dSmrg int u_index = 0,v_index = 0; 2424428d7b3dSmrg int dirty_context = 1; 2425428d7b3dSmrg 2426428d7b3dSmrg /* Block Pointer */ 2427428d7b3dSmrg short *block_ptr; 2428428d7b3dSmrg /* Current Macroblock Pointer */ 2429428d7b3dSmrg XvMCMacroBlock *mb; 2430428d7b3dSmrg 2431428d7b3dSmrg drm_i810_mc_t mc; 2432428d7b3dSmrg int i,j; 2433428d7b3dSmrg i810XvMCSurface *privTarget; 2434428d7b3dSmrg i810XvMCSurface *privFuture = NULL; 2435428d7b3dSmrg i810XvMCSurface *privPast = NULL; 2436428d7b3dSmrg i810XvMCContext *pI810XvMC; 2437428d7b3dSmrg 2438428d7b3dSmrg /* DMA Pointers set to NULL */ 2439428d7b3dSmrg uint *datay = NULL; 2440428d7b3dSmrg uint *datau = NULL; 2441428d7b3dSmrg uint *datav = NULL; 2442428d7b3dSmrg 2443428d7b3dSmrg 2444428d7b3dSmrg /* Check Parameters for validity */ 2445428d7b3dSmrg if((target_surface == NULL) || (context == NULL) || (display == NULL)) { 2446428d7b3dSmrg printf("Error, Invalid Target,Context, or DIsplay!\n"); 2447428d7b3dSmrg return BadValue; 2448428d7b3dSmrg } 2449428d7b3dSmrg 2450428d7b3dSmrg if(num_macroblocks == 0) {return Success;} 2451428d7b3dSmrg if((macroblock_array == NULL) || (blocks == NULL)) {return BadValue;} 2452428d7b3dSmrg if(context->privData == NULL) {return BadValue;} 2453428d7b3dSmrg pI810XvMC = (i810XvMCContext *)context->privData; 2454428d7b3dSmrg 2455428d7b3dSmrg 2456428d7b3dSmrg if(target_surface->privData == NULL) { 2457428d7b3dSmrg printf("Error, Invalid Target Surface!\n"); 2458428d7b3dSmrg return BadValue; 2459428d7b3dSmrg } 2460428d7b3dSmrg privTarget = (i810XvMCSurface *)target_surface->privData; 2461428d7b3dSmrg 2462428d7b3dSmrg if(macroblock_array->num_blocks < (num_macroblocks + first_macroblock)) { 2463428d7b3dSmrg printf("Error, Too many macroblocks requested for MB array size.\n"); 2464428d7b3dSmrg return BadValue; 2465428d7b3dSmrg } 2466428d7b3dSmrg 2467428d7b3dSmrg /* Test For YV12 Surface */ 2468428d7b3dSmrg if(context->surface_type_id != FOURCC_YV12) { 2469428d7b3dSmrg printf("Error, HWMC only possible on YV12 Surfaces\n"); 2470428d7b3dSmrg return BadValue; 2471428d7b3dSmrg } 2472428d7b3dSmrg 2473428d7b3dSmrg /* P Frame Test */ 2474428d7b3dSmrg if(past_surface == NULL) { 2475428d7b3dSmrg /* Just to avoid some ifs later. */ 2476428d7b3dSmrg privPast = privTarget; 2477428d7b3dSmrg } 2478428d7b3dSmrg else { 2479428d7b3dSmrg if(past_surface->privData == NULL) { 2480428d7b3dSmrg printf("Error, Invalid Past Surface!\n"); 2481428d7b3dSmrg return BadValue; 2482428d7b3dSmrg } 2483428d7b3dSmrg privPast = (i810XvMCSurface *)past_surface->privData; 2484428d7b3dSmrg } 2485428d7b3dSmrg 2486428d7b3dSmrg 2487428d7b3dSmrg /* B Frame Test */ 2488428d7b3dSmrg if(future_surface == NULL) { 2489428d7b3dSmrg privFuture = privTarget; 2490428d7b3dSmrg if(pI810XvMC->dual_prime) { 2491428d7b3dSmrg privFuture = privPast; 2492428d7b3dSmrg /* I810 Specific flag for marking when dual prime is in use. */ 2493428d7b3dSmrg flags |= 0x40000000; 2494428d7b3dSmrg } 2495428d7b3dSmrg 2496428d7b3dSmrg /* 2497428d7b3dSmrg References are different for the Second Field Picture. The 2498428d7b3dSmrg i810 needs to know if it is the second field picture in a 2499428d7b3dSmrg P picture. We use a Private flag to mark this. 2500428d7b3dSmrg */ 2501428d7b3dSmrg if(flags & XVMC_SECOND_FIELD) { 2502428d7b3dSmrg /* I810 Specific flag for marking second fields. */ 2503428d7b3dSmrg flags |= 0x80000000; 2504428d7b3dSmrg } 2505428d7b3dSmrg } 2506428d7b3dSmrg else { 2507428d7b3dSmrg if((future_surface->privData == NULL) || (past_surface == NULL)) { 2508428d7b3dSmrg printf("Error, Invalid Future Surface or No Past Surface!\n"); 2509428d7b3dSmrg return BadValue; 2510428d7b3dSmrg } 2511428d7b3dSmrg privFuture = (i810XvMCSurface *)future_surface->privData; 2512428d7b3dSmrg 2513428d7b3dSmrg /* 2514428d7b3dSmrg Undo Second Field flag since the second field in B frames is just like 2515428d7b3dSmrg the first. 2516428d7b3dSmrg */ 2517428d7b3dSmrg flags &= ~0x80000000; 2518428d7b3dSmrg } 2519428d7b3dSmrg 2520428d7b3dSmrg /* Lock For DMA */ 2521428d7b3dSmrg I810_LOCK(pI810XvMC,0); 2522428d7b3dSmrg 2523428d7b3dSmrg for(i=first_macroblock; i<(num_macroblocks + first_macroblock); i++) { 2524428d7b3dSmrg /* Set up values needed for each macroblock */ 2525428d7b3dSmrg mb = ¯oblock_array->macro_blocks[i]; 2526428d7b3dSmrg block_ptr = &(blocks->blocks[mb->index<<6]); 2527428d7b3dSmrg 2528428d7b3dSmrg /* Lockup can happen if the coordinates are too far out of range */ 2529428d7b3dSmrg if(mb->x > target_surface->width>>4) { 2530428d7b3dSmrg mb->x = 0; 2531428d7b3dSmrg } 2532428d7b3dSmrg if(mb->y > target_surface->height>>4) { 2533428d7b3dSmrg mb->y = 0; 2534428d7b3dSmrg } 2535428d7b3dSmrg 2536428d7b3dSmrg /* If buffers are almost full dispatch them */ 2537428d7b3dSmrg if(datay) { 2538428d7b3dSmrg pDMAy->used = (unsigned long)datay - (unsigned long)pDMAy->address; 2539428d7b3dSmrg if(pDMAy->used > 3520) { 2540428d7b3dSmrg if(dirty_context) { 2541428d7b3dSmrg dispatchYContext(privTarget,privPast,privFuture,pI810XvMC); 2542428d7b3dSmrg } 2543428d7b3dSmrg dirty_context = 0; 2544428d7b3dSmrg mc.idx = pDMAy->idx; 2545428d7b3dSmrg mc.used = pDMAy->used; 2546428d7b3dSmrg datay = NULL; 2547428d7b3dSmrg mc.last_render = ++pI810XvMC->last_render; 2548428d7b3dSmrg privTarget->last_render = pI810XvMC->last_render; 2549428d7b3dSmrg I810_MC(pI810XvMC,mc); 2550428d7b3dSmrg } /* datay near full */ 2551428d7b3dSmrg } /* if(datay) */ 2552428d7b3dSmrg if(datau) { 2553428d7b3dSmrg pDMAu[u_index]->used = (unsigned long)datau - (unsigned long)pDMAu[u_index]->address; 2554428d7b3dSmrg if(pDMAu[u_index]->used > 3904) { 2555428d7b3dSmrg u_index++; 2556428d7b3dSmrg datau = NULL; 2557428d7b3dSmrg if(u_index == UV_QUEUE) { 2558428d7b3dSmrg for(j=0; j<UV_QUEUE; j++) { 2559428d7b3dSmrg mc.idx = pDMAu[j]->idx; 2560428d7b3dSmrg mc.used = pDMAu[j]->used; 2561428d7b3dSmrg mc.last_render = ++pI810XvMC->last_render; 2562428d7b3dSmrg privTarget->last_render = pI810XvMC->last_render; 2563428d7b3dSmrg I810_MC(pI810XvMC,mc); 2564428d7b3dSmrg } 2565428d7b3dSmrg u_index = 0; 2566428d7b3dSmrg dirty_context = 1; 2567428d7b3dSmrg } /* if(u_index == UV_QUEUE) */ 2568428d7b3dSmrg } /* datau near full */ 2569428d7b3dSmrg } /* if(datau) */ 2570428d7b3dSmrg if(datav) { 2571428d7b3dSmrg pDMAv[v_index]->used = (unsigned long)datav - (unsigned long)pDMAv[v_index]->address; 2572428d7b3dSmrg if(pDMAv[v_index]->used > 3904) { 2573428d7b3dSmrg v_index++; 2574428d7b3dSmrg datav = NULL; 2575428d7b3dSmrg if(v_index == UV_QUEUE) { 2576428d7b3dSmrg for(j=0; j<UV_QUEUE; j++) { 2577428d7b3dSmrg mc.idx = pDMAv[j]->idx; 2578428d7b3dSmrg mc.used = pDMAv[j]->used; 2579428d7b3dSmrg mc.last_render = ++pI810XvMC->last_render; 2580428d7b3dSmrg privTarget->last_render = pI810XvMC->last_render; 2581428d7b3dSmrg I810_MC(pI810XvMC,mc); 2582428d7b3dSmrg } 2583428d7b3dSmrg v_index = 0; 2584428d7b3dSmrg dirty_context = 1; 2585428d7b3dSmrg } /* if(v_index == UV_QUEUE) */ 2586428d7b3dSmrg } /* datav near full */ 2587428d7b3dSmrg } /* if(datav) */ 2588428d7b3dSmrg 2589428d7b3dSmrg /* Allocate buffers if this is the first loop,or if we just dispatched */ 2590428d7b3dSmrg if(datay == NULL) { 2591428d7b3dSmrg pDMAy = i810_get_free_buffer(pI810XvMC); 2592428d7b3dSmrg datay = pDMAy->address; 2593428d7b3dSmrg }/* if(datay == NULL) */ 2594428d7b3dSmrg if(datau == NULL) { 2595428d7b3dSmrg pDMAu[u_index] = i810_get_free_buffer(pI810XvMC); 2596428d7b3dSmrg datau = pDMAu[u_index]->address; 2597428d7b3dSmrg if(u_index == 0) { 2598428d7b3dSmrg *datau++ = CMD_FLUSH; 2599428d7b3dSmrg *datau++ = BOOLEAN_ENA_2; 2600428d7b3dSmrg *datau++ = CMD_FLUSH; 2601428d7b3dSmrg *datau++ = DEST_BUFFER_INFO; 2602428d7b3dSmrg *datau++ = privTarget->dbi1u; 2603428d7b3dSmrg *datau++ = DEST_BUFFER_VAR; 2604428d7b3dSmrg *datau++ = privTarget->dbv1; 2605428d7b3dSmrg /* Past Surface */ 2606428d7b3dSmrg *datau++ = CMD_MAP_INFO; 2607428d7b3dSmrg *datau++ = privPast->mi1u; 2608428d7b3dSmrg *datau++ = privPast->mi2u; 2609428d7b3dSmrg *datau++ = privPast->mi3u; 2610428d7b3dSmrg /* Future Surface */ 2611428d7b3dSmrg *datau++ = CMD_MAP_INFO; 2612428d7b3dSmrg *datau++ = privFuture->mi1u | 0x1<<28; 2613428d7b3dSmrg *datau++ = privFuture->mi2u; 2614428d7b3dSmrg *datau++ = privFuture->mi3u; 2615428d7b3dSmrg } 2616428d7b3dSmrg } /* if(datau == NULL) */ 2617428d7b3dSmrg if(datav == NULL) { 2618428d7b3dSmrg pDMAv[v_index] = i810_get_free_buffer(pI810XvMC); 2619428d7b3dSmrg datav = pDMAv[v_index]->address; 2620428d7b3dSmrg if(v_index == 0) { 2621428d7b3dSmrg *datav++ = CMD_FLUSH; 2622428d7b3dSmrg *datav++ = BOOLEAN_ENA_2; 2623428d7b3dSmrg *datav++ = CMD_FLUSH; 2624428d7b3dSmrg *datav++ = DEST_BUFFER_INFO; 2625428d7b3dSmrg *datav++ = privTarget->dbi1v; 2626428d7b3dSmrg *datav++ = DEST_BUFFER_VAR; 2627428d7b3dSmrg *datav++ = privTarget->dbv1; 2628428d7b3dSmrg /* Past Surface */ 2629428d7b3dSmrg *datav++ = CMD_MAP_INFO; 2630428d7b3dSmrg *datav++ = privPast->mi1v; 2631428d7b3dSmrg *datav++ = privPast->mi2v; 2632428d7b3dSmrg *datav++ = privPast->mi3v; 2633428d7b3dSmrg /* Future Surface */ 2634428d7b3dSmrg *datav++ = CMD_MAP_INFO; 2635428d7b3dSmrg *datav++ = privFuture->mi1v | 0x1<<28; 2636428d7b3dSmrg *datav++ = privFuture->mi2v; 2637428d7b3dSmrg *datav++ = privFuture->mi3v; 2638428d7b3dSmrg } 2639428d7b3dSmrg }/* if(datav == NULL) */ 2640428d7b3dSmrg 2641428d7b3dSmrg /* Catch no pattern case */ 2642428d7b3dSmrg if(!(mb->macroblock_type & 0x8)) { 2643428d7b3dSmrg mb->coded_block_pattern = 0; 2644428d7b3dSmrg } 2645428d7b3dSmrg 2646428d7b3dSmrg 2647428d7b3dSmrg if(mb->motion_type == XVMC_PREDICTION_DUAL_PRIME) { 2648428d7b3dSmrg /* 2649428d7b3dSmrg By default the maps will not be set up for dual 2650428d7b3dSmrg prime. We have to change them. 2651428d7b3dSmrg */ 2652428d7b3dSmrg if(!pI810XvMC->dual_prime) { 2653428d7b3dSmrg pI810XvMC->dual_prime = 1; 2654428d7b3dSmrg privFuture = privPast; 2655428d7b3dSmrg /* Y */ 2656428d7b3dSmrg *datay++ = CMD_MAP_INFO; 2657428d7b3dSmrg *datay++ = privFuture->mi1y | 0x1<<28; 2658428d7b3dSmrg *datay++ = privFuture->mi2y; 2659428d7b3dSmrg *datay++ = privFuture->mi3y; 2660428d7b3dSmrg /* U */ 2661428d7b3dSmrg *datau++ = CMD_MAP_INFO; 2662428d7b3dSmrg *datau++ = privFuture->mi1u | 0x1<<28; 2663428d7b3dSmrg *datau++ = privFuture->mi2u; 2664428d7b3dSmrg *datau++ = privFuture->mi3u; 2665428d7b3dSmrg /* V */ 2666428d7b3dSmrg *datav++ = CMD_MAP_INFO; 2667428d7b3dSmrg *datav++ = privFuture->mi1v | 0x1<<28; 2668428d7b3dSmrg *datav++ = privFuture->mi2v; 2669428d7b3dSmrg *datav++ = privFuture->mi3v; 2670428d7b3dSmrg } 2671428d7b3dSmrg } 2672428d7b3dSmrg if((pI810XvMC->dual_prime) && 2673428d7b3dSmrg (mb->motion_type != XVMC_PREDICTION_DUAL_PRIME)) { 2674428d7b3dSmrg pI810XvMC->dual_prime = 0; 2675428d7b3dSmrg privFuture = privTarget; 2676428d7b3dSmrg /* Y */ 2677428d7b3dSmrg *datay++ = CMD_MAP_INFO; 2678428d7b3dSmrg *datay++ = privFuture->mi1y | 0x1<<28; 2679428d7b3dSmrg *datay++ = privFuture->mi2y; 2680428d7b3dSmrg *datay++ = privFuture->mi3y; 2681428d7b3dSmrg /* U */ 2682428d7b3dSmrg *datau++ = CMD_MAP_INFO; 2683428d7b3dSmrg *datau++ = privFuture->mi1u | 0x1<<28; 2684428d7b3dSmrg *datau++ = privFuture->mi2u; 2685428d7b3dSmrg *datau++ = privFuture->mi3u; 2686428d7b3dSmrg /* V */ 2687428d7b3dSmrg *datav++ = CMD_MAP_INFO; 2688428d7b3dSmrg *datav++ = privFuture->mi1v | 0x1<<28; 2689428d7b3dSmrg *datav++ = privFuture->mi2v; 2690428d7b3dSmrg *datav++ = privFuture->mi3v; 2691428d7b3dSmrg } 2692428d7b3dSmrg 2693428d7b3dSmrg 2694428d7b3dSmrg /* Frame Picture */ 2695428d7b3dSmrg if((picture_structure & XVMC_FRAME_PICTURE) == XVMC_FRAME_PICTURE) { 2696428d7b3dSmrg /* Intra Blocks */ 2697428d7b3dSmrg if(mb->macroblock_type & XVMC_MB_TYPE_INTRA) { 2698428d7b3dSmrg if(mb->dct_type) { 2699428d7b3dSmrg renderIntrainFrameDCT1(&datay,&datau,&datav,mb,block_ptr,flags); 2700428d7b3dSmrg continue; 2701428d7b3dSmrg } 2702428d7b3dSmrg renderIntrainFrame(&datay,&datau,&datav,mb,block_ptr); 2703428d7b3dSmrg continue; 2704428d7b3dSmrg } 2705428d7b3dSmrg switch((mb->motion_type & 0x3) | (mb->dct_type<<2)) { 2706428d7b3dSmrg case 0x2: /* Frame DCT0 */ 2707428d7b3dSmrg renderFrameinFrame(&datay,&datau,&datav,mb,block_ptr,flags); 2708428d7b3dSmrg continue; 2709428d7b3dSmrg case 0x5: /* Field DCT1 */ 2710428d7b3dSmrg renderFieldinFrame(&datay,&datau,&datav,mb,block_ptr,flags); 2711428d7b3dSmrg continue; 2712428d7b3dSmrg case 0x6: /* Frame DCT1 */ 2713428d7b3dSmrg renderFrameinFrameDCT1(&datay,&datau,&datav,mb,block_ptr,flags); 2714428d7b3dSmrg continue; 2715428d7b3dSmrg case 0x1: /* Field DCT0 */ 2716428d7b3dSmrg renderFieldinFrameDCT0(&datay,&datau,&datav,mb,block_ptr,flags); 2717428d7b3dSmrg continue; 2718428d7b3dSmrg case 0x3: /* Dual Prime DCT0 */ 2719428d7b3dSmrg renderDualPrimeinFrame(&datay,&datau,&datav,mb,block_ptr,flags); 2720428d7b3dSmrg continue; 2721428d7b3dSmrg case 0x7: /* Dual Prime DCT1 */ 2722428d7b3dSmrg renderDualPrimeinFrameDCT0(&datay,&datau,&datav,mb,block_ptr,flags); 2723428d7b3dSmrg continue; 2724428d7b3dSmrg default: /* No Motion Type */ 2725428d7b3dSmrg renderError(); 2726428d7b3dSmrg continue; 2727428d7b3dSmrg } /* Switch */ 2728428d7b3dSmrg } /* Frame Picture */ 2729428d7b3dSmrg 2730428d7b3dSmrg /* Field Pictures */ 2731428d7b3dSmrg if(mb->macroblock_type & XVMC_MB_TYPE_INTRA) { 2732428d7b3dSmrg renderIntrainField(&datay,&datau,&datav,mb,block_ptr,picture_structure); 2733428d7b3dSmrg continue; 2734428d7b3dSmrg } 2735428d7b3dSmrg switch(mb->motion_type & 0x3) { 2736428d7b3dSmrg case 0x1: /* Field Motion */ 2737428d7b3dSmrg renderFieldinField(&datay,&datau,&datav,mb,block_ptr,picture_structure, 2738428d7b3dSmrg flags); 2739428d7b3dSmrg continue; 2740428d7b3dSmrg case 0x2: /* 16x8 Motion */ 2741428d7b3dSmrg render16x8inField(&datay,&datau,&datav,mb,block_ptr,picture_structure, 2742428d7b3dSmrg flags); 2743428d7b3dSmrg continue; 2744428d7b3dSmrg case 0x3: /* Dual Prime */ 2745428d7b3dSmrg renderDualPrimeinField(&datay,&datau,&datav,mb,block_ptr, 2746428d7b3dSmrg picture_structure,flags); 2747428d7b3dSmrg continue; 2748428d7b3dSmrg default: /* No Motion Type */ 2749428d7b3dSmrg renderError(); 2750428d7b3dSmrg continue; 2751428d7b3dSmrg } 2752428d7b3dSmrg continue; 2753428d7b3dSmrg 2754428d7b3dSmrg } /* for each Macroblock */ 2755428d7b3dSmrg 2756428d7b3dSmrg /* Dispatch remaining DMA buffers */ 2757428d7b3dSmrg if(dirty_context) { 2758428d7b3dSmrg dispatchYContext(privTarget,privPast,privFuture,pI810XvMC); 2759428d7b3dSmrg } 2760428d7b3dSmrg mc.idx = pDMAy->idx; 2761428d7b3dSmrg mc.used = (unsigned long)datay - (unsigned long)pDMAy->address; 2762428d7b3dSmrg mc.last_render = ++pI810XvMC->last_render; 2763428d7b3dSmrg privTarget->last_render = pI810XvMC->last_render; 2764428d7b3dSmrg I810_MC(pI810XvMC,mc); 2765428d7b3dSmrg 2766428d7b3dSmrg pDMAu[u_index]->used = (unsigned long)datau - (unsigned long)pDMAu[u_index]->address; 2767428d7b3dSmrg for(j=0; j<=u_index; j++) { 2768428d7b3dSmrg mc.idx = pDMAu[j]->idx; 2769428d7b3dSmrg mc.used = pDMAu[j]->used; 2770428d7b3dSmrg mc.last_render = ++pI810XvMC->last_render; 2771428d7b3dSmrg privTarget->last_render = pI810XvMC->last_render; 2772428d7b3dSmrg I810_MC(pI810XvMC,mc); 2773428d7b3dSmrg } 2774428d7b3dSmrg pDMAv[v_index]->used = (unsigned long)datav - (unsigned long)pDMAv[v_index]->address; 2775428d7b3dSmrg for(j=0; j<=v_index; j++) { 2776428d7b3dSmrg mc.idx = pDMAv[j]->idx; 2777428d7b3dSmrg mc.used = pDMAv[j]->used; 2778428d7b3dSmrg mc.last_render = ++pI810XvMC->last_render; 2779428d7b3dSmrg privTarget->last_render = pI810XvMC->last_render; 2780428d7b3dSmrg I810_MC(pI810XvMC,mc); 2781428d7b3dSmrg } 2782428d7b3dSmrg 2783428d7b3dSmrg I810_UNLOCK(pI810XvMC); 2784428d7b3dSmrg 2785428d7b3dSmrg return Success; 2786428d7b3dSmrg} 2787428d7b3dSmrg 2788428d7b3dSmrg/*************************************************************************** 2789428d7b3dSmrg// Function: XvMCPutSurface 2790428d7b3dSmrg// Description: 2791428d7b3dSmrg// Arguments: 2792428d7b3dSmrg// display: Connection to X server 2793428d7b3dSmrg// surface: Surface to be displayed 2794428d7b3dSmrg// draw: X Drawable on which to display the surface 2795428d7b3dSmrg// srcx: X coordinate of the top left corner of the region to be 2796428d7b3dSmrg// displayed within the surface. 2797428d7b3dSmrg// srcy: Y coordinate of the top left corner of the region to be 2798428d7b3dSmrg// displayed within the surface. 2799428d7b3dSmrg// srcw: Width of the region to be displayed. 2800428d7b3dSmrg// srch: Height of the region to be displayed. 2801428d7b3dSmrg// destx: X cordinate of the top left corner of the destination region 2802428d7b3dSmrg// in the drawable coordinates. 2803428d7b3dSmrg// desty: Y cordinate of the top left corner of the destination region 2804428d7b3dSmrg// in the drawable coordinates. 2805428d7b3dSmrg// destw: Width of the destination region. 2806428d7b3dSmrg// desth: Height of the destination region. 2807428d7b3dSmrg// flags: One or more of the following. 2808428d7b3dSmrg// XVMC_TOP_FIELD - Display only the Top field of the surface. 2809428d7b3dSmrg// XVMC_BOTTOM_FIELD - Display only the Bottom Field of the surface. 2810428d7b3dSmrg// XVMC_FRAME_PICTURE - Display both fields or frame. 2811428d7b3dSmrg// 2812428d7b3dSmrg// Info: Portions of this function derived from i810_video.c (XFree86) 2813428d7b3dSmrg// 2814428d7b3dSmrg// This function is organized so that we wait as long as possible before 2815428d7b3dSmrg// touching the overlay registers. Since we don't know that the last 2816428d7b3dSmrg// flip has happened yet we want to give the overlay as long as 2817428d7b3dSmrg// possible to catch up before we have to check on its progress. This 2818428d7b3dSmrg// makes it unlikely that we have to wait on the last flip. 2819428d7b3dSmrg***************************************************************************/ 2820428d7b3dSmrg_X_EXPORT Status XvMCPutSurface(Display *display,XvMCSurface *surface, 2821428d7b3dSmrg Drawable draw, short srcx, short srcy, 2822428d7b3dSmrg unsigned short srcw, unsigned short srch, 2823428d7b3dSmrg short destx, short desty, 2824428d7b3dSmrg unsigned short destw, unsigned short desth, 2825428d7b3dSmrg int flags) { 2826428d7b3dSmrg i810XvMCContext *pI810XvMC; 2827428d7b3dSmrg i810XvMCSurface *pI810Surface; 2828428d7b3dSmrg i810OverlayRecPtr pORegs; 2829428d7b3dSmrg unsigned int ysrc_offset,uvsrc_offset; 2830428d7b3dSmrg Box extents; 2831428d7b3dSmrg uint window_width,window_height; 2832428d7b3dSmrg unsigned int xscaleInt = 0,xscaleFract = 0,yscaleInt = 0,yscaleFract = 0; 2833428d7b3dSmrg unsigned int xscaleFractUV = 0,xscaleIntUV = 0,yscaleFractUV = 0; 2834428d7b3dSmrg unsigned int yscaleIntUV = 0,yPitch = 0,uvPitch = 0; 2835428d7b3dSmrg unsigned int ovcmd = 0; 2836428d7b3dSmrg uint d; 2837428d7b3dSmrg double xscale,yscale; 2838428d7b3dSmrg int diff; 2839428d7b3dSmrg int clipped_srcx, clipped_srcy, clipped_destx, clipped_desty; 2840428d7b3dSmrg int clipped_srcw, clipped_srch, clipped_destw, clipped_desth; 2841428d7b3dSmrg uint x1,y1,root_width,root_height; 2842428d7b3dSmrg int x2 = 0, y2 = 0,unused; 2843428d7b3dSmrg uint nChilds; 2844428d7b3dSmrg int stat; 2845428d7b3dSmrg Window win,root,parent,*pChilds; 2846428d7b3dSmrg 2847428d7b3dSmrg 2848428d7b3dSmrg if((display == NULL) || (surface == NULL)) { 2849428d7b3dSmrg return BadValue; 2850428d7b3dSmrg } 2851428d7b3dSmrg 2852428d7b3dSmrg if(surface->privData == NULL) { 2853428d7b3dSmrg return (error_base + XvMCBadSurface); 2854428d7b3dSmrg } 2855428d7b3dSmrg pI810Surface = (i810XvMCSurface *)surface->privData; 2856428d7b3dSmrg pI810XvMC = (i810XvMCContext *)pI810Surface->privContext; 2857428d7b3dSmrg pORegs = (i810OverlayRecPtr)pI810XvMC->oregs; 2858428d7b3dSmrg 2859428d7b3dSmrg 2860428d7b3dSmrg switch(surface->surface_type_id) { 2861428d7b3dSmrg case FOURCC_YV12: 2862428d7b3dSmrg case FOURCC_I420: 2863428d7b3dSmrg yPitch = (srcw + 7) & ~7; 2864428d7b3dSmrg uvPitch = ((srcw>>1) + 7) & ~7; 2865428d7b3dSmrg if((flags & XVMC_FRAME_PICTURE) != XVMC_FRAME_PICTURE) { 2866428d7b3dSmrg srch = srch>>1; 2867428d7b3dSmrg } 2868428d7b3dSmrg break; 2869428d7b3dSmrg case FOURCC_UYVY: 2870428d7b3dSmrg case FOURCC_YUY2: 2871428d7b3dSmrg default: 2872428d7b3dSmrg /* FIXME: Non Planar not fully implemented. */ 2873428d7b3dSmrg return BadValue; 2874428d7b3dSmrg yPitch = ((srcw + 7) & ~7) << 1; 2875428d7b3dSmrg break; 2876428d7b3dSmrg }/* switch(surface->surface_type_id) */ 2877428d7b3dSmrg 2878428d7b3dSmrg /* 2879428d7b3dSmrg FIXME: This should be using the DRI's clip rect but that isn't 2880428d7b3dSmrg all hooked up yet. This has some latency but we get by. 2881428d7b3dSmrg */ 2882428d7b3dSmrg win = draw; 2883428d7b3dSmrg XQueryTree(display,win,&root,&parent,&pChilds,&nChilds); 2884428d7b3dSmrg if(nChilds) XFree(pChilds); 2885428d7b3dSmrg XGetGeometry(display,win, &root, &x2, &y2, &window_width, 2886428d7b3dSmrg &window_height, &d, &d); 2887428d7b3dSmrg x1 = x2; 2888428d7b3dSmrg y1 = y2; 2889428d7b3dSmrg win = parent; 2890428d7b3dSmrg do { 2891428d7b3dSmrg XQueryTree(display,win,&root,&parent,&pChilds,&nChilds); 2892428d7b3dSmrg if(nChilds) XFree(pChilds); 2893428d7b3dSmrg XGetGeometry(display,win, &root, &x2, &y2, &d, &d, &d, &d); 2894428d7b3dSmrg x1 += x2; 2895428d7b3dSmrg y1 += y2; 2896428d7b3dSmrg win = parent; 2897428d7b3dSmrg }while(win != root); 2898428d7b3dSmrg XGetGeometry(display,root, &root, &unused, &unused, 2899428d7b3dSmrg &root_width, &root_height, &d, &d); 2900428d7b3dSmrg 2901428d7b3dSmrg /* Left edge of Video window clipped to screen */ 2902428d7b3dSmrg extents.x1 = 0; 2903428d7b3dSmrg if(x1 > extents.x1) { 2904428d7b3dSmrg extents.x1 = x1; 2905428d7b3dSmrg } 2906428d7b3dSmrg /* Right edge of Video window clipped to screen */ 2907428d7b3dSmrg extents.x2 = root_width; 2908428d7b3dSmrg if(extents.x2 > (x1 + window_width)) { 2909428d7b3dSmrg extents.x2 = x1 + window_width; 2910428d7b3dSmrg } 2911428d7b3dSmrg /* Top edge of Video window clipped to screen */ 2912428d7b3dSmrg extents.y1 = 0; 2913428d7b3dSmrg if(y1 > extents.y1) { 2914428d7b3dSmrg extents.y1 = y1; 2915428d7b3dSmrg } 2916428d7b3dSmrg /* Bottom edge of Video window clipped to screen */ 2917428d7b3dSmrg extents.y2 = root_height; 2918428d7b3dSmrg if(extents.y2 > (y1 + window_height)) { 2919428d7b3dSmrg extents.y2 = y1 + window_height; 2920428d7b3dSmrg } 2921428d7b3dSmrg 2922428d7b3dSmrg /* 2923428d7b3dSmrg Clipping is more difficult than is seems. We need to keep the 2924428d7b3dSmrg scaling factors even if the destination window needs to be clipped. 2925428d7b3dSmrg We clip the destination window first then apply a scaled version 2926428d7b3dSmrg to the source window. 2927428d7b3dSmrg */ 2928428d7b3dSmrg 2929428d7b3dSmrg /* Put destination coords in screen coords */ 2930428d7b3dSmrg destx += x1; 2931428d7b3dSmrg desty += y1; 2932428d7b3dSmrg 2933428d7b3dSmrg /* Scale factors requested */ 2934428d7b3dSmrg xscale = (double)srcw / (double)destw; 2935428d7b3dSmrg yscale = (double)srch / (double)desth; 2936428d7b3dSmrg 2937428d7b3dSmrg /* 2938428d7b3dSmrg If destination window needs to be clipped we actually adjust both 2939428d7b3dSmrg the src and dest window so as to keep the scaling that was requested 2940428d7b3dSmrg */ 2941428d7b3dSmrg clipped_srcx = srcx; 2942428d7b3dSmrg clipped_srcy = srcy; 2943428d7b3dSmrg clipped_destx = destx; 2944428d7b3dSmrg clipped_desty = desty; 2945428d7b3dSmrg clipped_srcw = srcw; 2946428d7b3dSmrg clipped_srch = srch; 2947428d7b3dSmrg clipped_destw = destw; 2948428d7b3dSmrg clipped_desth = desth; 2949428d7b3dSmrg 2950428d7b3dSmrg /* Clip to the source surface boundaries */ 2951428d7b3dSmrg if(clipped_srcx < 0) { 2952428d7b3dSmrg clipped_destx += (0 - clipped_srcx) / xscale; 2953428d7b3dSmrg clipped_srcw -= clipped_srcx; 2954428d7b3dSmrg clipped_destw -= clipped_srcx / xscale; 2955428d7b3dSmrg clipped_srcx = 0; 2956428d7b3dSmrg } 2957428d7b3dSmrg if((clipped_srcw + clipped_srcx) > surface->width) { 2958428d7b3dSmrg clipped_srcw = surface->width - clipped_srcx; 2959428d7b3dSmrg clipped_destw -= (clipped_srcw - srcw) / xscale; 2960428d7b3dSmrg } 2961428d7b3dSmrg if(clipped_srcy < 0) { 2962428d7b3dSmrg clipped_desty += (0 - clipped_srcy) / yscale; 2963428d7b3dSmrg clipped_srch -= clipped_srcy; 2964428d7b3dSmrg clipped_desth -= clipped_srcy / yscale; 2965428d7b3dSmrg clipped_srcy = 0; 2966428d7b3dSmrg } 2967428d7b3dSmrg if((clipped_srch + clipped_srcy) > surface->height) { 2968428d7b3dSmrg clipped_srch = surface->height - clipped_srcy; 2969428d7b3dSmrg clipped_desth -= (clipped_srch - srch) / yscale; 2970428d7b3dSmrg } 2971428d7b3dSmrg 2972428d7b3dSmrg /* Clip to the extents */ 2973428d7b3dSmrg if(clipped_destx < extents.x1) { 2974428d7b3dSmrg diff = extents.x1 - clipped_destx; 2975428d7b3dSmrg clipped_srcx += diff * xscale; 2976428d7b3dSmrg clipped_srcw -= diff * xscale; 2977428d7b3dSmrg clipped_destw -= diff; 2978428d7b3dSmrg clipped_destx = extents.x1; 2979428d7b3dSmrg } 2980428d7b3dSmrg 2981428d7b3dSmrg diff = (clipped_destx + clipped_destw) - extents.x2; 2982428d7b3dSmrg if(diff > 0) { 2983428d7b3dSmrg clipped_destw -= diff; 2984428d7b3dSmrg clipped_srcw -= diff * xscale; 2985428d7b3dSmrg } 2986428d7b3dSmrg 2987428d7b3dSmrg if(clipped_desty < extents.y1) { 2988428d7b3dSmrg diff = extents.y1 - clipped_desty; 2989428d7b3dSmrg clipped_srcy += diff * yscale; 2990428d7b3dSmrg clipped_srch -= diff * yscale; 2991428d7b3dSmrg clipped_desth -= diff; 2992428d7b3dSmrg clipped_desty = 0; 2993428d7b3dSmrg } 2994428d7b3dSmrg 2995428d7b3dSmrg diff = (clipped_desty + clipped_desth) - extents.y2; 2996428d7b3dSmrg if(diff > 0) { 2997428d7b3dSmrg clipped_desth -= diff; 2998428d7b3dSmrg clipped_srch -= diff * yscale; 2999428d7b3dSmrg } 3000428d7b3dSmrg 3001428d7b3dSmrg /* If the whole window is clipped turn off the overlay */ 3002428d7b3dSmrg if((clipped_destx + clipped_destw < extents.x1) || 3003428d7b3dSmrg (clipped_desty + clipped_desth < extents.y1) || 3004428d7b3dSmrg (clipped_destx > extents.x2) || 3005428d7b3dSmrg (clipped_desty > extents.y2)) { 3006428d7b3dSmrg return XvMCHideSurface(display, surface); 3007428d7b3dSmrg } 3008428d7b3dSmrg 3009428d7b3dSmrg /* 3010428d7b3dSmrg Adjust the source offset width and height according to the clipped 3011428d7b3dSmrg destination window. 3012428d7b3dSmrg */ 3013428d7b3dSmrg ysrc_offset = ((clipped_srcx + 1) & ~1) + 3014428d7b3dSmrg ((clipped_srcy + 1) & ~1) * (1<<pI810Surface->pitch); 3015428d7b3dSmrg uvsrc_offset = (clipped_srcx>>1) + 3016428d7b3dSmrg (clipped_srcy>>1) * (1<<(pI810Surface->pitch - 1)); 3017428d7b3dSmrg 3018428d7b3dSmrg /* 3019428d7b3dSmrg Initially, YCbCr and Overlay Enable and 3020428d7b3dSmrg vertical chrominance up interpolation and horozontal chrominance 3021428d7b3dSmrg up interpolation 3022428d7b3dSmrg */ 3023428d7b3dSmrg ovcmd = VC_UP_INTERPOLATION | HC_UP_INTERPOLATION | 3024428d7b3dSmrg Y_ADJUST | OVERLAY_ENABLE; 3025428d7b3dSmrg 3026428d7b3dSmrg if ((clipped_destw != clipped_srcw) || 3027428d7b3dSmrg (clipped_desth != clipped_srch)) { 3028428d7b3dSmrg xscaleInt = (clipped_srcw / clipped_destw) & 0x3; 3029428d7b3dSmrg xscaleFract = (clipped_srcw << 12) / clipped_destw; 3030428d7b3dSmrg yscaleInt = (clipped_srch / clipped_desth) & 0x3; 3031428d7b3dSmrg yscaleFract = (clipped_srch << 12) / clipped_desth; 3032428d7b3dSmrg 3033428d7b3dSmrg if (clipped_destw > clipped_srcw) { 3034428d7b3dSmrg /* horizontal up-scaling */ 3035428d7b3dSmrg ovcmd &= ~HORIZONTAL_CHROMINANCE_FILTER; 3036428d7b3dSmrg ovcmd &= ~HORIZONTAL_LUMINANCE_FILTER; 3037428d7b3dSmrg ovcmd |= (HC_UP_INTERPOLATION | HL_UP_INTERPOLATION); 3038428d7b3dSmrg } 3039428d7b3dSmrg 3040428d7b3dSmrg if (clipped_desth > clipped_srch) { 3041428d7b3dSmrg /* vertical up-scaling */ 3042428d7b3dSmrg ovcmd &= ~VERTICAL_CHROMINANCE_FILTER; 3043428d7b3dSmrg ovcmd &= ~VERTICAL_LUMINANCE_FILTER; 3044428d7b3dSmrg ovcmd |= (VC_UP_INTERPOLATION | VL_UP_INTERPOLATION); 3045428d7b3dSmrg } 3046428d7b3dSmrg 3047428d7b3dSmrg if (clipped_destw < clipped_srcw) { 3048428d7b3dSmrg /* horizontal down-scaling */ 3049428d7b3dSmrg ovcmd &= ~HORIZONTAL_CHROMINANCE_FILTER; 3050428d7b3dSmrg ovcmd &= ~HORIZONTAL_LUMINANCE_FILTER; 3051428d7b3dSmrg ovcmd |= (HC_DOWN_INTERPOLATION | HL_DOWN_INTERPOLATION); 3052428d7b3dSmrg } 3053428d7b3dSmrg 3054428d7b3dSmrg if (clipped_desth < clipped_srch) { 3055428d7b3dSmrg /* vertical down-scaling */ 3056428d7b3dSmrg ovcmd &= ~VERTICAL_CHROMINANCE_FILTER; 3057428d7b3dSmrg ovcmd &= ~VERTICAL_LUMINANCE_FILTER; 3058428d7b3dSmrg ovcmd |= (VC_DOWN_INTERPOLATION | VL_DOWN_INTERPOLATION); 3059428d7b3dSmrg } 3060428d7b3dSmrg 3061428d7b3dSmrg /* now calculate the UV scaling factor */ 3062428d7b3dSmrg if (xscaleFract) { 3063428d7b3dSmrg xscaleFractUV = xscaleFract >> MINUV_SCALE; 3064428d7b3dSmrg ovcmd &= ~HC_DOWN_INTERPOLATION; 3065428d7b3dSmrg ovcmd |= HC_UP_INTERPOLATION; 3066428d7b3dSmrg } 3067428d7b3dSmrg 3068428d7b3dSmrg if (xscaleInt) { 3069428d7b3dSmrg xscaleIntUV = xscaleInt >> MINUV_SCALE; 3070428d7b3dSmrg if (xscaleIntUV) { 3071428d7b3dSmrg ovcmd &= ~HC_UP_INTERPOLATION; 3072428d7b3dSmrg } 3073428d7b3dSmrg } 3074428d7b3dSmrg 3075428d7b3dSmrg if (yscaleFract) { 3076428d7b3dSmrg yscaleFractUV = yscaleFract >> MINUV_SCALE; 3077428d7b3dSmrg ovcmd &= ~VC_DOWN_INTERPOLATION; 3078428d7b3dSmrg ovcmd |= VC_UP_INTERPOLATION; 3079428d7b3dSmrg } 3080428d7b3dSmrg 3081428d7b3dSmrg if (yscaleInt) { 3082428d7b3dSmrg yscaleIntUV = yscaleInt >> MINUV_SCALE; 3083428d7b3dSmrg if (yscaleIntUV) { 3084428d7b3dSmrg ovcmd &= ~VC_UP_INTERPOLATION; 3085428d7b3dSmrg ovcmd |= VC_DOWN_INTERPOLATION; 3086428d7b3dSmrg } 3087428d7b3dSmrg } 3088428d7b3dSmrg 3089428d7b3dSmrg }/* if((destw != srcw) || (desth != srch)) */ 3090428d7b3dSmrg 3091428d7b3dSmrg /* Lock the DRM */ 3092428d7b3dSmrg I810_LOCK(pI810XvMC,0); 3093428d7b3dSmrg 3094428d7b3dSmrg /* Block until rendering on this surface is finished */ 3095428d7b3dSmrg stat = XVMC_RENDERING; 3096428d7b3dSmrg while(stat & XVMC_RENDERING) { 3097428d7b3dSmrg XvMCGetSurfaceStatus(display,surface,&stat); 3098428d7b3dSmrg } 3099428d7b3dSmrg /* Block until the last flip is finished */ 3100428d7b3dSmrg if(pI810XvMC->last_flip) { 3101428d7b3dSmrg BLOCK_OVERLAY(pI810XvMC,pI810XvMC->current); 3102428d7b3dSmrg } 3103428d7b3dSmrg 3104428d7b3dSmrg pI810XvMC->current = !pI810XvMC->current; 3105428d7b3dSmrg pORegs->OV0CMD = ovcmd; 3106428d7b3dSmrg 3107428d7b3dSmrg if ((clipped_destw != clipped_srcw) || 3108428d7b3dSmrg (clipped_desth != clipped_srch)) { 3109428d7b3dSmrg pORegs->YRGBSCALE = (xscaleInt << 15) | 3110428d7b3dSmrg ((xscaleFract & 0xFFF) << 3) | (yscaleInt) | 3111428d7b3dSmrg ((yscaleFract & 0xFFF) << 20); 3112428d7b3dSmrg 3113428d7b3dSmrg pORegs->UVSCALE = yscaleIntUV | ((xscaleFractUV & 0xFFF) << 3) | 3114428d7b3dSmrg ((yscaleFractUV & 0xFFF) << 20); 3115428d7b3dSmrg } 3116428d7b3dSmrg else { 3117428d7b3dSmrg /* Normal 1:1 scaling */ 3118428d7b3dSmrg pORegs->YRGBSCALE = 0x80004000; 3119428d7b3dSmrg pORegs->UVSCALE = 0x80004000; 3120428d7b3dSmrg } 3121428d7b3dSmrg 3122428d7b3dSmrg pORegs->SHEIGHT = clipped_srch | (clipped_srch << 15); 3123428d7b3dSmrg pORegs->DWINPOS = (clipped_desty << 16) | clipped_destx; 3124428d7b3dSmrg pORegs->DWINSZ = ((clipped_desth<< 16) | (clipped_destw)); 3125428d7b3dSmrg 3126428d7b3dSmrg /* Attributes */ 3127428d7b3dSmrg pORegs->OV0CLRC0 = ((pI810XvMC->contrast & 0x1ff)<<8) | 3128428d7b3dSmrg (pI810XvMC->brightness & 0xff); 3129428d7b3dSmrg pORegs->OV0CLRC1 = (pI810XvMC->saturation & 0x3ff); 3130428d7b3dSmrg 3131428d7b3dSmrg /* Destination Colorkey Setup */ 3132428d7b3dSmrg pI810XvMC->oregs->DCLRKV = RGB16ToColorKey(pI810XvMC->colorkey); 3133428d7b3dSmrg 3134428d7b3dSmrg /* buffer locations, add the offset from the clipping */ 3135428d7b3dSmrg if(pI810XvMC->current) { 3136428d7b3dSmrg pORegs->OBUF_1Y = (unsigned long)pI810Surface->offset + 3137428d7b3dSmrg (unsigned long)pI810Surface->offsets[0] + ysrc_offset; 3138428d7b3dSmrg pORegs->OBUF_1V = (unsigned long)pI810Surface->offset + 3139428d7b3dSmrg (unsigned long)pI810Surface->offsets[2] + uvsrc_offset; 3140428d7b3dSmrg pORegs->OBUF_1U = (unsigned long)pI810Surface->offset + 3141428d7b3dSmrg (unsigned long)pI810Surface->offsets[1] + uvsrc_offset; 3142428d7b3dSmrg } 3143428d7b3dSmrg else { 3144428d7b3dSmrg pORegs->OBUF_0Y = (unsigned long)pI810Surface->offset + 3145428d7b3dSmrg (unsigned long)pI810Surface->offsets[0] + ysrc_offset; 3146428d7b3dSmrg pORegs->OBUF_0V = (unsigned long)pI810Surface->offset + 3147428d7b3dSmrg (unsigned long)pI810Surface->offsets[2] + uvsrc_offset; 3148428d7b3dSmrg pORegs->OBUF_0U = (unsigned long)pI810Surface->offset + 3149428d7b3dSmrg (unsigned long)pI810Surface->offsets[1] + uvsrc_offset; 3150428d7b3dSmrg } 3151428d7b3dSmrg 3152428d7b3dSmrg switch(surface->surface_type_id) { 3153428d7b3dSmrg case FOURCC_YV12: 3154428d7b3dSmrg case FOURCC_I420: 3155428d7b3dSmrg pORegs->SWID = (uvPitch << 16) | yPitch; 3156428d7b3dSmrg pORegs->SWIDQW = (uvPitch << 13) | (yPitch >> 3); 3157428d7b3dSmrg pORegs->OV0STRIDE = (1<<pI810Surface->pitch) | 3158428d7b3dSmrg ((1<<pI810Surface->pitch) << 15); 3159428d7b3dSmrg pORegs->OV0CMD &= ~SOURCE_FORMAT; 3160428d7b3dSmrg pORegs->OV0CMD |= YUV_420; 3161428d7b3dSmrg if((flags & XVMC_FRAME_PICTURE) != XVMC_FRAME_PICTURE) { 3162428d7b3dSmrg /* Top Field Only */ 3163428d7b3dSmrg if(flags & XVMC_TOP_FIELD) { 3164428d7b3dSmrg if(pI810XvMC->current == 1) { 3165428d7b3dSmrg pORegs->OV0CMD |= (VERTICAL_PHASE_BOTH | FLIP_TYPE_FIELD | 3166428d7b3dSmrg BUFFER1_FIELD0); 3167428d7b3dSmrg } 3168428d7b3dSmrg else { 3169428d7b3dSmrg pORegs->OV0CMD |= (VERTICAL_PHASE_BOTH | FLIP_TYPE_FIELD | 3170428d7b3dSmrg BUFFER0_FIELD0); 3171428d7b3dSmrg } 3172428d7b3dSmrg pORegs->YRGB_VPH = 1<<15 | 1<<31; 3173428d7b3dSmrg pORegs->UV_VPH = 3<<14 | 3<<30; 3174428d7b3dSmrg pORegs->INIT_PH = 0x06 | 0x18; 3175428d7b3dSmrg } 3176428d7b3dSmrg /* Bottom Field Only */ 3177428d7b3dSmrg else { 3178428d7b3dSmrg if(pI810XvMC->current == 1) { 3179428d7b3dSmrg pORegs->OV0CMD |= (VERTICAL_PHASE_BOTH | FLIP_TYPE_FIELD | 3180428d7b3dSmrg BUFFER1_FIELD1); 3181428d7b3dSmrg } 3182428d7b3dSmrg else { 3183428d7b3dSmrg pORegs->OV0CMD |= (VERTICAL_PHASE_BOTH | FLIP_TYPE_FIELD | 3184428d7b3dSmrg BUFFER0_FIELD1); 3185428d7b3dSmrg } 3186428d7b3dSmrg pORegs->YRGB_VPH = 0; 3187428d7b3dSmrg pORegs->UV_VPH = 7<<29 | 7<<13; 3188428d7b3dSmrg pORegs->INIT_PH = 0x06; 3189428d7b3dSmrg } 3190428d7b3dSmrg } 3191428d7b3dSmrg /* Frame Picture */ 3192428d7b3dSmrg else { 3193428d7b3dSmrg if(pI810XvMC->current == 1) { 3194428d7b3dSmrg pORegs->OV0CMD |= BUFFER1_FIELD0; 3195428d7b3dSmrg } 3196428d7b3dSmrg else { 3197428d7b3dSmrg pORegs->OV0CMD |= BUFFER0_FIELD0; 3198428d7b3dSmrg } 3199428d7b3dSmrg pORegs->YRGB_VPH = 0; 3200428d7b3dSmrg pORegs->UV_VPH = 0; 3201428d7b3dSmrg pORegs->INIT_PH = 0; 3202428d7b3dSmrg } 3203428d7b3dSmrg break; 3204428d7b3dSmrg case FOURCC_UYVY: 3205428d7b3dSmrg case FOURCC_YUY2: 3206428d7b3dSmrg default: 3207428d7b3dSmrg pORegs->SWID = srcw; 3208428d7b3dSmrg pORegs->SWIDQW = srcw >> 3; 3209428d7b3dSmrg pORegs->OV0STRIDE = pI810Surface->pitch; 3210428d7b3dSmrg pORegs->OV0CMD &= ~SOURCE_FORMAT; 3211428d7b3dSmrg pORegs->OV0CMD |= YUV_422; 3212428d7b3dSmrg pORegs->OV0CMD &= ~OV_BYTE_ORDER; 3213428d7b3dSmrg if (surface->surface_type_id == FOURCC_UYVY) { 3214428d7b3dSmrg pORegs->OV0CMD |= Y_SWAP; 3215428d7b3dSmrg } 3216428d7b3dSmrg 3217428d7b3dSmrg pORegs->OV0CMD &= ~BUFFER_AND_FIELD; 3218428d7b3dSmrg if(pI810XvMC->current == 1) { 3219428d7b3dSmrg pORegs->OV0CMD |= BUFFER1_FIELD0; 3220428d7b3dSmrg } 3221428d7b3dSmrg else { 3222428d7b3dSmrg pORegs->OV0CMD |= BUFFER0_FIELD0; 3223428d7b3dSmrg } 3224428d7b3dSmrg 3225428d7b3dSmrg break; 3226428d7b3dSmrg } /* switch(surface->surface_type_id) */ 3227428d7b3dSmrg 3228428d7b3dSmrg 3229428d7b3dSmrg 3230428d7b3dSmrg OVERLAY_FLIP(pI810XvMC); 3231428d7b3dSmrg 3232428d7b3dSmrg /* 3233428d7b3dSmrg The Overlay only flips when it knows you changed 3234428d7b3dSmrg something. So the first time change stuff while it 3235428d7b3dSmrg is watching to be sure. 3236428d7b3dSmrg */ 3237428d7b3dSmrg if(!pI810XvMC->last_flip) { 3238428d7b3dSmrg pORegs->OV0CMD &= ~0x4; 3239428d7b3dSmrg if(pI810XvMC->current == 1) { 3240428d7b3dSmrg pORegs->OV0CMD |= BUFFER1_FIELD0; 3241428d7b3dSmrg } 3242428d7b3dSmrg else { 3243428d7b3dSmrg pORegs->OV0CMD |= BUFFER0_FIELD0; 3244428d7b3dSmrg } 3245428d7b3dSmrg } 3246428d7b3dSmrg pI810Surface->last_flip = ++pI810XvMC->last_flip; 3247428d7b3dSmrg I810_UNLOCK(pI810XvMC); 3248428d7b3dSmrg 3249428d7b3dSmrg return Success; 3250428d7b3dSmrg} 3251428d7b3dSmrg 3252428d7b3dSmrg/*************************************************************************** 3253428d7b3dSmrg// Function: XvMCSyncSurface 3254428d7b3dSmrg// Arguments: 3255428d7b3dSmrg// display - Connection to the X server 3256428d7b3dSmrg// surface - The surface to synchronize 3257428d7b3dSmrg// Info: 3258428d7b3dSmrg// Returns: Status 3259428d7b3dSmrg***************************************************************************/ 3260428d7b3dSmrg_X_EXPORT Status XvMCSyncSurface(Display *display,XvMCSurface *surface) { 3261428d7b3dSmrg Status ret; 3262428d7b3dSmrg int stat=0; 3263428d7b3dSmrg /* 3264428d7b3dSmrg FIXME: Perhaps a timer here to prevent lockup? 3265428d7b3dSmrg FIXME: Perhaps a usleep to not be busy waiting? 3266428d7b3dSmrg */ 3267428d7b3dSmrg do { 3268428d7b3dSmrg ret = XvMCGetSurfaceStatus(display,surface,&stat); 3269428d7b3dSmrg }while(!ret && (stat & XVMC_RENDERING)); 3270428d7b3dSmrg return ret; 3271428d7b3dSmrg} 3272428d7b3dSmrg 3273428d7b3dSmrg/*************************************************************************** 3274428d7b3dSmrg// Function: XvMCFlushSurface 3275428d7b3dSmrg// Description: 3276428d7b3dSmrg// This function commits pending rendering requests to ensure that they 3277428d7b3dSmrg// wll be completed in a finite amount of time. 3278428d7b3dSmrg// Arguments: 3279428d7b3dSmrg// display - Connection to X server 3280428d7b3dSmrg// surface - Surface to flush 3281428d7b3dSmrg// Info: 3282428d7b3dSmrg// This command is a noop for i810 becuase we always dispatch buffers in 3283428d7b3dSmrg// render. There is little gain to be had with 4k buffers. 3284428d7b3dSmrg// Returns: Status 3285428d7b3dSmrg***************************************************************************/ 3286428d7b3dSmrg_X_EXPORT Status XvMCFlushSurface(Display * display, XvMCSurface *surface) { 3287428d7b3dSmrg return Success; 3288428d7b3dSmrg} 3289428d7b3dSmrg 3290428d7b3dSmrg/*************************************************************************** 3291428d7b3dSmrg// Function: XvMCGetSurfaceStatus 3292428d7b3dSmrg// Description: 3293428d7b3dSmrg// Arguments: 3294428d7b3dSmrg// display: connection to X server 3295428d7b3dSmrg// surface: The surface to query 3296428d7b3dSmrg// stat: One of the Following 3297428d7b3dSmrg// XVMC_RENDERING - The last XvMCRenderSurface command has not 3298428d7b3dSmrg// completed. 3299428d7b3dSmrg// XVMC_DISPLAYING - The surface is currently being displayed or a 3300428d7b3dSmrg// display is pending. 3301428d7b3dSmrg***************************************************************************/ 3302428d7b3dSmrg_X_EXPORT Status XvMCGetSurfaceStatus(Display *display, XvMCSurface *surface, 3303428d7b3dSmrg int *stat) { 3304428d7b3dSmrg i810XvMCSurface *privSurface; 3305428d7b3dSmrg i810XvMCContext *pI810XvMC; 3306428d7b3dSmrg int temp; 3307428d7b3dSmrg 3308428d7b3dSmrg if((display == NULL) || (surface == NULL) || (stat == NULL)) { 3309428d7b3dSmrg return BadValue; 3310428d7b3dSmrg } 3311428d7b3dSmrg if(surface->privData == NULL) { 3312428d7b3dSmrg return BadValue; 3313428d7b3dSmrg } 3314428d7b3dSmrg *stat = 0; 3315428d7b3dSmrg privSurface = surface->privData; 3316428d7b3dSmrg 3317428d7b3dSmrg pI810XvMC = privSurface->privContext; 3318428d7b3dSmrg if(pI810XvMC == NULL) { 3319428d7b3dSmrg return (error_base + XvMCBadSurface); 3320428d7b3dSmrg } 3321428d7b3dSmrg 3322428d7b3dSmrg I810_LOCK(pI810XvMC,0); 3323428d7b3dSmrg if(privSurface->last_flip) { 3324428d7b3dSmrg /* This can not happen */ 3325428d7b3dSmrg if(pI810XvMC->last_flip < privSurface->last_flip) { 3326428d7b3dSmrg printf("Error: Context last flip is less than surface last flip.\n"); 3327428d7b3dSmrg return BadValue; 3328428d7b3dSmrg } 3329428d7b3dSmrg /* 3330428d7b3dSmrg If the context has 2 or more flips after this surface it 3331428d7b3dSmrg cannot be displaying. Don't bother to check. 3332428d7b3dSmrg */ 3333428d7b3dSmrg if(!(pI810XvMC->last_flip > (privSurface->last_flip + 1))) { 3334428d7b3dSmrg /* 3335428d7b3dSmrg If this surface was the last flipped it is either displaying 3336428d7b3dSmrg or about to be so don't bother checking. 3337428d7b3dSmrg */ 3338428d7b3dSmrg if(pI810XvMC->last_flip == privSurface->last_flip) { 3339428d7b3dSmrg *stat |= XVMC_DISPLAYING; 3340428d7b3dSmrg } 3341428d7b3dSmrg else { 3342428d7b3dSmrg /* 3343428d7b3dSmrg In this case there has been one more flip since our surface's 3344428d7b3dSmrg but we need to check if it is finished or not. 3345428d7b3dSmrg */ 3346428d7b3dSmrg temp = GET_FSTATUS(pI810XvMC); 3347428d7b3dSmrg if(((temp & (1<<20))>>20) != pI810XvMC->current) { 3348428d7b3dSmrg *stat |= XVMC_DISPLAYING; 3349428d7b3dSmrg } 3350428d7b3dSmrg } 3351428d7b3dSmrg } 3352428d7b3dSmrg } 3353428d7b3dSmrg 3354428d7b3dSmrg if(privSurface->last_render && 3355428d7b3dSmrg (privSurface->last_render > GET_RSTATUS(pI810XvMC))) { 3356428d7b3dSmrg *stat |= XVMC_RENDERING; 3357428d7b3dSmrg } 3358428d7b3dSmrg I810_UNLOCK(pI810XvMC); 3359428d7b3dSmrg 3360428d7b3dSmrg return Success; 3361428d7b3dSmrg} 3362428d7b3dSmrg 3363428d7b3dSmrg/*************************************************************************** 3364428d7b3dSmrg// 3365428d7b3dSmrg// Surface manipulation functions 3366428d7b3dSmrg// 3367428d7b3dSmrg***************************************************************************/ 3368428d7b3dSmrg 3369428d7b3dSmrg/*************************************************************************** 3370428d7b3dSmrg// Function: XvMCHideSurface 3371428d7b3dSmrg// Description: Stops the display of a surface. 3372428d7b3dSmrg// Arguments: 3373428d7b3dSmrg// display - Connection to the X server. 3374428d7b3dSmrg// surface - surface to be hidden. 3375428d7b3dSmrg// 3376428d7b3dSmrg// Returns: Status 3377428d7b3dSmrg***************************************************************************/ 3378428d7b3dSmrg_X_EXPORT Status XvMCHideSurface(Display *display, XvMCSurface *surface) { 3379428d7b3dSmrg i810XvMCSurface *pI810Surface; 3380428d7b3dSmrg i810XvMCContext *pI810XvMC; 3381428d7b3dSmrg int ss, xx; 3382428d7b3dSmrg 3383428d7b3dSmrg /* Did we get a good display and surface passed into us? */ 3384428d7b3dSmrg if(display == NULL) { 3385428d7b3dSmrg return BadValue; 3386428d7b3dSmrg } 3387428d7b3dSmrg 3388428d7b3dSmrg if(surface == NULL) { 3389428d7b3dSmrg return (error_base + XvMCBadSurface); 3390428d7b3dSmrg } 3391428d7b3dSmrg 3392428d7b3dSmrg XvMCSyncSurface(display, surface); 3393428d7b3dSmrg 3394428d7b3dSmrg /* Get surface private data pointer */ 3395428d7b3dSmrg if(surface->privData == NULL) { 3396428d7b3dSmrg return (error_base + XvMCBadSurface); 3397428d7b3dSmrg } 3398428d7b3dSmrg pI810Surface = (i810XvMCSurface *)surface->privData; 3399428d7b3dSmrg 3400428d7b3dSmrg /* 3401428d7b3dSmrg Get the status of the surface, if it is not currently displayed 3402428d7b3dSmrg we don't need to worry about it. 3403428d7b3dSmrg */ 3404428d7b3dSmrg if((xx = XvMCGetSurfaceStatus(display, surface, &ss)) != Success) { 3405428d7b3dSmrg return xx; 3406428d7b3dSmrg } 3407428d7b3dSmrg if(! (ss & XVMC_DISPLAYING)) { 3408428d7b3dSmrg return Success; 3409428d7b3dSmrg } 3410428d7b3dSmrg 3411428d7b3dSmrg /* Get the associated context pointer */ 3412428d7b3dSmrg pI810XvMC = (i810XvMCContext *)pI810Surface->privContext; 3413428d7b3dSmrg if(pI810XvMC == NULL) { 3414428d7b3dSmrg return (error_base + XvMCBadSurface); 3415428d7b3dSmrg } 3416428d7b3dSmrg 3417428d7b3dSmrg if(pI810XvMC->last_flip) { 3418428d7b3dSmrg I810_LOCK(pI810XvMC,DRM_LOCK_QUIESCENT); 3419428d7b3dSmrg 3420428d7b3dSmrg /* Make sure last flip is done */ 3421428d7b3dSmrg BLOCK_OVERLAY(pI810XvMC,pI810XvMC->current); 3422428d7b3dSmrg 3423428d7b3dSmrg /* Set the registers to turn the overlay off */ 3424428d7b3dSmrg pI810XvMC->oregs->OV0CMD = VC_UP_INTERPOLATION | HC_UP_INTERPOLATION | 3425428d7b3dSmrg Y_ADJUST; 3426428d7b3dSmrg pI810XvMC->current = !pI810XvMC->current; 3427428d7b3dSmrg if(pI810XvMC->current == 1) { 3428428d7b3dSmrg pI810XvMC->oregs->OV0CMD |= BUFFER1_FIELD0; 3429428d7b3dSmrg } 3430428d7b3dSmrg else { 3431428d7b3dSmrg pI810XvMC->oregs->OV0CMD |= BUFFER0_FIELD0; 3432428d7b3dSmrg } 3433428d7b3dSmrg OVERLAY_FLIP(pI810XvMC); 3434428d7b3dSmrg /* 3435428d7b3dSmrg Increment the context flip but not the surface. This way no 3436428d7b3dSmrg surface has the last flip #. 3437428d7b3dSmrg */ 3438428d7b3dSmrg pI810XvMC->last_flip++; 3439428d7b3dSmrg 3440428d7b3dSmrg 3441428d7b3dSmrg /* Now wait until the hardware reads the registers and makes the change. */ 3442428d7b3dSmrg BLOCK_OVERLAY(pI810XvMC,pI810XvMC->current) 3443428d7b3dSmrg 3444428d7b3dSmrg I810_UNLOCK(pI810XvMC); 3445428d7b3dSmrg } 3446428d7b3dSmrg 3447428d7b3dSmrg return Success; 3448428d7b3dSmrg} 3449428d7b3dSmrg 3450428d7b3dSmrg 3451428d7b3dSmrg 3452428d7b3dSmrg 3453428d7b3dSmrg/*************************************************************************** 3454428d7b3dSmrg// 3455428d7b3dSmrg// Functions that deal with subpictures 3456428d7b3dSmrg// 3457428d7b3dSmrg***************************************************************************/ 3458428d7b3dSmrg 3459428d7b3dSmrg 3460428d7b3dSmrg 3461428d7b3dSmrg/*************************************************************************** 3462428d7b3dSmrg// Function: XvMCCreateSubpicture 3463428d7b3dSmrg// Description: This creates a subpicture by filling out the XvMCSubpicture 3464428d7b3dSmrg// structure passed to it and returning Success. 3465428d7b3dSmrg// Arguments: 3466428d7b3dSmrg// display - Connection to the X server. 3467428d7b3dSmrg// context - The context to create the subpicture for. 3468428d7b3dSmrg// subpicture - Pre-allocated XvMCSubpicture structure to be filled in. 3469428d7b3dSmrg// width - of subpicture 3470428d7b3dSmrg// height - of subpicture 3471428d7b3dSmrg// xvimage_id - The id describing the XvImage format. 3472428d7b3dSmrg// 3473428d7b3dSmrg// Returns: Status 3474428d7b3dSmrg***************************************************************************/ 3475428d7b3dSmrg_X_EXPORT Status XvMCCreateSubpicture(Display *display, XvMCContext *context, 3476428d7b3dSmrg XvMCSubpicture *subpicture, 3477428d7b3dSmrg unsigned short width, unsigned short height, 3478428d7b3dSmrg int xvimage_id) { 3479428d7b3dSmrg i810XvMCContext *pI810XvMC; 3480428d7b3dSmrg i810XvMCSubpicture *pI810Subpicture; 3481428d7b3dSmrg int priv_count; 3482428d7b3dSmrg uint *priv_data; 3483428d7b3dSmrg Status ret; 3484428d7b3dSmrg 3485428d7b3dSmrg if((subpicture == NULL) || (context == NULL) || (display == NULL)){ 3486428d7b3dSmrg return BadValue; 3487428d7b3dSmrg } 3488428d7b3dSmrg 3489428d7b3dSmrg pI810XvMC = (i810XvMCContext *)context->privData; 3490428d7b3dSmrg if(pI810XvMC == NULL) { 3491428d7b3dSmrg return (error_base + XvMCBadContext); 3492428d7b3dSmrg } 3493428d7b3dSmrg 3494428d7b3dSmrg 3495428d7b3dSmrg subpicture->context_id = context->context_id; 3496428d7b3dSmrg subpicture->xvimage_id = xvimage_id; 3497428d7b3dSmrg 3498428d7b3dSmrg /* These need to be checked to make sure they are not too big! */ 3499428d7b3dSmrg subpicture->width = width; 3500428d7b3dSmrg subpicture->height = height; 3501428d7b3dSmrg 3502428d7b3dSmrg subpicture->privData = 3503428d7b3dSmrg (i810XvMCSubpicture *)malloc(sizeof(i810XvMCSubpicture)); 3504428d7b3dSmrg 3505428d7b3dSmrg if(!subpicture->privData) { 3506428d7b3dSmrg return BadAlloc; 3507428d7b3dSmrg } 3508428d7b3dSmrg pI810Subpicture = (i810XvMCSubpicture *)subpicture->privData; 3509428d7b3dSmrg 3510428d7b3dSmrg 3511428d7b3dSmrg if((ret = _xvmc_create_subpicture(display, context, subpicture, 3512428d7b3dSmrg &priv_count, &priv_data))) { 3513428d7b3dSmrg printf("Unable to create XvMCSubpicture.\n"); 3514428d7b3dSmrg return ret; 3515428d7b3dSmrg } 3516428d7b3dSmrg 3517428d7b3dSmrg if(priv_count != 1) { 3518428d7b3dSmrg printf("_xvmc_create_subpicture() returned incorrect data size.\n"); 3519428d7b3dSmrg printf("Expected 1 got %d\n",priv_count); 3520428d7b3dSmrg free(priv_data); 3521428d7b3dSmrg return BadAlloc; 3522428d7b3dSmrg } 3523428d7b3dSmrg /* Data == Client Address, offset == Physical address offset */ 3524428d7b3dSmrg pI810Subpicture->data = pI810XvMC->surfaces.address; 3525428d7b3dSmrg pI810Subpicture->offset = pI810XvMC->surfaces.offset; 3526428d7b3dSmrg 3527428d7b3dSmrg /* Initialize private values */ 3528428d7b3dSmrg pI810Subpicture->privContext = pI810XvMC; 3529428d7b3dSmrg 3530428d7b3dSmrg pI810Subpicture->last_render = 0; 3531428d7b3dSmrg pI810Subpicture->last_flip = 0; 3532428d7b3dSmrg 3533428d7b3dSmrg /* Based on the xvimage_id we will need to set the other values */ 3534428d7b3dSmrg subpicture->num_palette_entries = 16; 3535428d7b3dSmrg subpicture->entry_bytes = 3; 3536428d7b3dSmrg strcpy(subpicture->component_order,"YUV"); 3537428d7b3dSmrg 3538428d7b3dSmrg /* 3539428d7b3dSmrg i810's MC Engine needs surfaces of 2^x (x= 9,10,11,12) pitch 3540428d7b3dSmrg and the Tiler need 512k aligned surfaces, basically we are 3541428d7b3dSmrg stuck with fixed memory with pitch 1024. 3542428d7b3dSmrg */ 3543428d7b3dSmrg pI810Subpicture->pitch = 10; 3544428d7b3dSmrg 3545428d7b3dSmrg /* 3546428d7b3dSmrg offsets[0] == offset into the map described by either 3547428d7b3dSmrg address (Client memeory address) or offset (physical offset from fb base) 3548428d7b3dSmrg */ 3549428d7b3dSmrg pI810Subpicture->offsets[0] = priv_data[0]; 3550428d7b3dSmrg if(((unsigned long)pI810Subpicture->data + pI810Subpicture->offsets[0]) & 4095) { 3551428d7b3dSmrg printf("XvMCCreateSubpicture: Subpicture offset 0 is not 4096 aligned\n"); 3552428d7b3dSmrg } 3553428d7b3dSmrg 3554428d7b3dSmrg /* Free data returned from xvmc_create_surface */ 3555428d7b3dSmrg free(priv_data); 3556428d7b3dSmrg 3557428d7b3dSmrg /* Clear the surface to 0 */ 3558428d7b3dSmrg memset((void *)((unsigned long)pI810Subpicture->data + (unsigned long)pI810Subpicture->offsets[0]), 3559428d7b3dSmrg 0, ((1<<pI810Subpicture->pitch) * subpicture->height)); 3560428d7b3dSmrg 3561428d7b3dSmrg switch(subpicture->xvimage_id) { 3562428d7b3dSmrg case FOURCC_IA44: 3563428d7b3dSmrg case FOURCC_AI44: 3564428d7b3dSmrg /* Destination buffer info command */ 3565428d7b3dSmrg pI810Subpicture->dbi1 = ((((unsigned int)pI810Subpicture->offset + 3566428d7b3dSmrg pI810Subpicture->offsets[0]) & ~0xfc000fff) | 3567428d7b3dSmrg (pI810Subpicture->pitch - 9)); 3568428d7b3dSmrg 3569428d7b3dSmrg /* Destination buffer variables command */ 3570428d7b3dSmrg pI810Subpicture->dbv1 = (0x8<<20) | (0x8<<16); 3571428d7b3dSmrg 3572428d7b3dSmrg /* Map info command */ 3573428d7b3dSmrg pI810Subpicture->mi1 = (0x0<<24) | (3<<21) | (1<<9) | 3574428d7b3dSmrg (pI810Subpicture->pitch - 3); 3575428d7b3dSmrg 3576428d7b3dSmrg pI810Subpicture->mi2 = (((unsigned int)subpicture->height - 1)<<16) | 3577428d7b3dSmrg ((unsigned int)subpicture->width - 1); 3578428d7b3dSmrg 3579428d7b3dSmrg pI810Subpicture->mi3 = ((unsigned int)pI810Subpicture->offset + 3580428d7b3dSmrg pI810Subpicture->offsets[0]) & ~0xfc00000f; 3581428d7b3dSmrg break; 3582428d7b3dSmrg default: 3583428d7b3dSmrg free(subpicture->privData); 3584428d7b3dSmrg return BadMatch; 3585428d7b3dSmrg } 3586428d7b3dSmrg 3587428d7b3dSmrg pI810XvMC->ref++; 3588428d7b3dSmrg return Success; 3589428d7b3dSmrg} 3590428d7b3dSmrg 3591428d7b3dSmrg 3592428d7b3dSmrg 3593428d7b3dSmrg/*************************************************************************** 3594428d7b3dSmrg// Function: XvMCClearSubpicture 3595428d7b3dSmrg// Description: Clear the area of the given subpicture to "color". 3596428d7b3dSmrg// structure passed to it and returning Success. 3597428d7b3dSmrg// Arguments: 3598428d7b3dSmrg// display - Connection to the X server. 3599428d7b3dSmrg// subpicture - Subpicture to clear. 3600428d7b3dSmrg// x, y, width, height - rectangle in the subpicture to clear. 3601428d7b3dSmrg// color - The data to file the rectangle with. 3602428d7b3dSmrg// 3603428d7b3dSmrg// Returns: Status 3604428d7b3dSmrg***************************************************************************/ 3605428d7b3dSmrg_X_EXPORT Status XvMCClearSubpicture(Display *display, XvMCSubpicture *subpicture, 3606428d7b3dSmrg short x, short y, 3607428d7b3dSmrg unsigned short width, unsigned short height, 3608428d7b3dSmrg unsigned int color) { 3609428d7b3dSmrg 3610428d7b3dSmrg i810XvMCContext *pI810XvMC; 3611428d7b3dSmrg i810XvMCSubpicture *pI810Subpicture; 3612428d7b3dSmrg int i; 3613428d7b3dSmrg 3614428d7b3dSmrg if((subpicture == NULL) || (display == NULL)){ 3615428d7b3dSmrg return BadValue; 3616428d7b3dSmrg } 3617428d7b3dSmrg 3618428d7b3dSmrg if(!subpicture->privData) { 3619428d7b3dSmrg return (error_base + XvMCBadSubpicture); 3620428d7b3dSmrg } 3621428d7b3dSmrg pI810Subpicture = (i810XvMCSubpicture *)subpicture->privData; 3622428d7b3dSmrg 3623428d7b3dSmrg pI810XvMC = (i810XvMCContext *)pI810Subpicture->privContext; 3624428d7b3dSmrg if(pI810XvMC == NULL) { 3625428d7b3dSmrg return (error_base + XvMCBadSubpicture); 3626428d7b3dSmrg } 3627428d7b3dSmrg 3628428d7b3dSmrg if((x < 0) || (x + width > subpicture->width)) { 3629428d7b3dSmrg return BadValue; 3630428d7b3dSmrg } 3631428d7b3dSmrg 3632428d7b3dSmrg if((y < 0) || (y + height > subpicture->height)) { 3633428d7b3dSmrg return BadValue; 3634428d7b3dSmrg } 3635428d7b3dSmrg 3636428d7b3dSmrg for(i=y; i<y + height; i++) { 3637428d7b3dSmrg memset((void *)((unsigned long)pI810Subpicture->data + 3638428d7b3dSmrg (unsigned long)pI810Subpicture->offsets[0] + x + 3639428d7b3dSmrg (1<<pI810Subpicture->pitch) * i),(char)color,width); 3640428d7b3dSmrg } 3641428d7b3dSmrg 3642428d7b3dSmrg return Success; 3643428d7b3dSmrg} 3644428d7b3dSmrg 3645428d7b3dSmrg/*************************************************************************** 3646428d7b3dSmrg// Function: XvMCCompositeSubpicture 3647428d7b3dSmrg// Description: Composite the XvImae on the subpicture. This composit uses 3648428d7b3dSmrg// non-premultiplied alpha. Destination alpha is utilized 3649428d7b3dSmrg// except for with indexed subpictures. Indexed subpictures 3650428d7b3dSmrg// use a simple "replace". 3651428d7b3dSmrg// Arguments: 3652428d7b3dSmrg// display - Connection to the X server. 3653428d7b3dSmrg// subpicture - Subpicture to clear. 3654428d7b3dSmrg// image - the XvImage to be used as the source of the composite. 3655428d7b3dSmrg// srcx, srcy, width, height - The rectangle from the image to be used. 3656428d7b3dSmrg// dstx, dsty - location in the subpicture to composite the source. 3657428d7b3dSmrg// 3658428d7b3dSmrg// Returns: Status 3659428d7b3dSmrg***************************************************************************/ 3660428d7b3dSmrg_X_EXPORT Status XvMCCompositeSubpicture(Display *display, XvMCSubpicture *subpicture, 3661428d7b3dSmrg XvImage *image, 3662428d7b3dSmrg short srcx, short srcy, 3663428d7b3dSmrg unsigned short width, unsigned short height, 3664428d7b3dSmrg short dstx, short dsty) { 3665428d7b3dSmrg 3666428d7b3dSmrg i810XvMCContext *pI810XvMC; 3667428d7b3dSmrg i810XvMCSubpicture *pI810Subpicture; 3668428d7b3dSmrg int i; 3669428d7b3dSmrg 3670428d7b3dSmrg if((subpicture == NULL) || (display == NULL)){ 3671428d7b3dSmrg return BadValue; 3672428d7b3dSmrg } 3673428d7b3dSmrg 3674428d7b3dSmrg if(!subpicture->privData) { 3675428d7b3dSmrg return (error_base + XvMCBadSubpicture); 3676428d7b3dSmrg } 3677428d7b3dSmrg pI810Subpicture = (i810XvMCSubpicture *)subpicture->privData; 3678428d7b3dSmrg 3679428d7b3dSmrg pI810XvMC = (i810XvMCContext *)pI810Subpicture->privContext; 3680428d7b3dSmrg if(pI810XvMC == NULL) { 3681428d7b3dSmrg return (error_base + XvMCBadSubpicture); 3682428d7b3dSmrg } 3683428d7b3dSmrg 3684428d7b3dSmrg if((srcx < 0) || (srcx + width > image->width)) { 3685428d7b3dSmrg return BadValue; 3686428d7b3dSmrg } 3687428d7b3dSmrg 3688428d7b3dSmrg if((dstx < 0) || (dstx + width > subpicture->width)) { 3689428d7b3dSmrg return BadValue; 3690428d7b3dSmrg } 3691428d7b3dSmrg 3692428d7b3dSmrg if((srcy < 0) || (srcy + height > image->height)) { 3693428d7b3dSmrg return BadValue; 3694428d7b3dSmrg } 3695428d7b3dSmrg 3696428d7b3dSmrg if((dsty < 0) || (dsty + height > subpicture->height)) { 3697428d7b3dSmrg return BadValue; 3698428d7b3dSmrg } 3699428d7b3dSmrg 3700428d7b3dSmrg for(i=0; i<height; i++) { 3701428d7b3dSmrg memcpy((void *)((unsigned long)pI810Subpicture->data + 3702428d7b3dSmrg (unsigned long)pI810Subpicture->offsets[0] + dstx + 3703428d7b3dSmrg (1<<pI810Subpicture->pitch) * (i + dsty)), 3704428d7b3dSmrg (void *)((unsigned long)image->data + 3705428d7b3dSmrg (unsigned long)image->offsets[0] + srcx + 3706428d7b3dSmrg image->pitches[0] * (i + srcy)) 3707428d7b3dSmrg ,width); 3708428d7b3dSmrg } 3709428d7b3dSmrg 3710428d7b3dSmrg return Success; 3711428d7b3dSmrg 3712428d7b3dSmrg} 3713428d7b3dSmrg 3714428d7b3dSmrg 3715428d7b3dSmrg/*************************************************************************** 3716428d7b3dSmrg// Function: XvMCDestroySubpicture 3717428d7b3dSmrg// Description: Destroys the specified subpicture. 3718428d7b3dSmrg// Arguments: 3719428d7b3dSmrg// display - Connection to the X server. 3720428d7b3dSmrg// subpicture - Subpicture to be destroyed. 3721428d7b3dSmrg// 3722428d7b3dSmrg// Returns: Status 3723428d7b3dSmrg***************************************************************************/ 3724428d7b3dSmrg_X_EXPORT Status XvMCDestroySubpicture(Display *display, XvMCSubpicture *subpicture) { 3725428d7b3dSmrg 3726428d7b3dSmrg i810XvMCSubpicture *pI810Subpicture; 3727428d7b3dSmrg i810XvMCContext *pI810XvMC; 3728428d7b3dSmrg 3729428d7b3dSmrg if((display == NULL) || (subpicture == NULL)) { 3730428d7b3dSmrg return BadValue; 3731428d7b3dSmrg } 3732428d7b3dSmrg if(!subpicture->privData) { 3733428d7b3dSmrg return (error_base + XvMCBadSubpicture); 3734428d7b3dSmrg } 3735428d7b3dSmrg pI810Subpicture = (i810XvMCSubpicture *)subpicture->privData; 3736428d7b3dSmrg 3737428d7b3dSmrg pI810XvMC = (i810XvMCContext *)pI810Subpicture->privContext; 3738428d7b3dSmrg if(!pI810XvMC) { 3739428d7b3dSmrg return (error_base + XvMCBadSubpicture); 3740428d7b3dSmrg } 3741428d7b3dSmrg 3742428d7b3dSmrg 3743428d7b3dSmrg if(pI810Subpicture->last_render) { 3744428d7b3dSmrg XvMCSyncSubpicture(display,subpicture); 3745428d7b3dSmrg } 3746428d7b3dSmrg 3747428d7b3dSmrg _xvmc_destroy_subpicture(display,subpicture); 3748428d7b3dSmrg 3749428d7b3dSmrg i810_free_privContext(pI810XvMC); 3750428d7b3dSmrg 3751428d7b3dSmrg free(pI810Subpicture); 3752428d7b3dSmrg subpicture->privData = NULL; 3753428d7b3dSmrg return Success; 3754428d7b3dSmrg} 3755428d7b3dSmrg 3756428d7b3dSmrg 3757428d7b3dSmrg/*************************************************************************** 3758428d7b3dSmrg// Function: XvMCSetSubpicturePalette 3759428d7b3dSmrg// Description: Set the subpictures palette 3760428d7b3dSmrg// Arguments: 3761428d7b3dSmrg// display - Connection to the X server. 3762428d7b3dSmrg// subpicture - Subpiture to set palette for. 3763428d7b3dSmrg// palette - A pointer to an array holding the palette data. The array 3764428d7b3dSmrg// is num_palette_entries * entry_bytes in size. 3765428d7b3dSmrg// Returns: Status 3766428d7b3dSmrg***************************************************************************/ 3767428d7b3dSmrg 3768428d7b3dSmrg_X_EXPORT Status XvMCSetSubpicturePalette(Display *display, XvMCSubpicture *subpicture, 3769428d7b3dSmrg unsigned char *palette) { 3770428d7b3dSmrg i810XvMCSubpicture *privSubpicture; 3771428d7b3dSmrg int i,j; 3772428d7b3dSmrg 3773428d7b3dSmrg if((display == NULL) || (subpicture == NULL)) { 3774428d7b3dSmrg return BadValue; 3775428d7b3dSmrg } 3776428d7b3dSmrg if(subpicture->privData == NULL) { 3777428d7b3dSmrg return (error_base + XvMCBadSubpicture); 3778428d7b3dSmrg } 3779428d7b3dSmrg privSubpicture = (i810XvMCSubpicture *)subpicture->privData; 3780428d7b3dSmrg 3781428d7b3dSmrg j=0; 3782428d7b3dSmrg for(i=0; i<16; i++) { 3783428d7b3dSmrg privSubpicture->palette[0][i] = palette[j++]; 3784428d7b3dSmrg privSubpicture->palette[1][i] = palette[j++]; 3785428d7b3dSmrg privSubpicture->palette[2][i] = palette[j++]; 3786428d7b3dSmrg } 3787428d7b3dSmrg return Success; 3788428d7b3dSmrg} 3789428d7b3dSmrg 3790428d7b3dSmrg/*************************************************************************** 3791428d7b3dSmrg// Function: XvMCBlendSubpicture 3792428d7b3dSmrg// Description: 3793428d7b3dSmrg// The behavior of this function is different depending on whether 3794428d7b3dSmrg// or not the XVMC_BACKEND_SUBPICTURE flag is set in the XvMCSurfaceInfo. 3795428d7b3dSmrg// i810 only support frontend behavior. 3796428d7b3dSmrg// 3797428d7b3dSmrg// XVMC_BACKEND_SUBPICTURE not set ("frontend" behavior): 3798428d7b3dSmrg// 3799428d7b3dSmrg// XvMCBlendSubpicture is a no-op in this case. 3800428d7b3dSmrg// 3801428d7b3dSmrg// Arguments: 3802428d7b3dSmrg// display - Connection to the X server. 3803428d7b3dSmrg// subpicture - The subpicture to be blended into the video. 3804428d7b3dSmrg// target_surface - The surface to be displayed with the blended subpic. 3805428d7b3dSmrg// source_surface - Source surface prior to blending. 3806428d7b3dSmrg// subx, suby, subw, subh - The rectangle from the subpicture to use. 3807428d7b3dSmrg// surfx, surfy, surfw, surfh - The rectangle in the surface to blend 3808428d7b3dSmrg// blend the subpicture rectangle into. Scaling can ocure if 3809428d7b3dSmrg// XVMC_SUBPICTURE_INDEPENDENT_SCALING is set. 3810428d7b3dSmrg// 3811428d7b3dSmrg// Returns: Status 3812428d7b3dSmrg***************************************************************************/ 3813428d7b3dSmrg_X_EXPORT Status XvMCBlendSubpicture(Display *display, XvMCSurface *target_surface, 3814428d7b3dSmrg XvMCSubpicture *subpicture, 3815428d7b3dSmrg short subx, short suby, 3816428d7b3dSmrg unsigned short subw, unsigned short subh, 3817428d7b3dSmrg short surfx, short surfy, 3818428d7b3dSmrg unsigned short surfw, unsigned short surfh) { 3819428d7b3dSmrg 3820428d7b3dSmrg return BadMatch; 3821428d7b3dSmrg} 3822428d7b3dSmrg 3823428d7b3dSmrg 3824428d7b3dSmrg 3825428d7b3dSmrg/*************************************************************************** 3826428d7b3dSmrg// Function: XvMCBlendSubpicture2 3827428d7b3dSmrg// Description: 3828428d7b3dSmrg// The behavior of this function is different depending on whether 3829428d7b3dSmrg// or not the XVMC_BACKEND_SUBPICTURE flag is set in the XvMCSurfaceInfo. 3830428d7b3dSmrg// i810 only supports frontend blending. 3831428d7b3dSmrg// 3832428d7b3dSmrg// XVMC_BACKEND_SUBPICTURE not set ("frontend" behavior): 3833428d7b3dSmrg// 3834428d7b3dSmrg// XvMCBlendSubpicture2 blends the source_surface and subpicture and 3835428d7b3dSmrg// puts it in the target_surface. This does not effect the status of 3836428d7b3dSmrg// the source surface but will cause the target_surface to query 3837428d7b3dSmrg// XVMC_RENDERING until the blend is completed. 3838428d7b3dSmrg// 3839428d7b3dSmrg// Arguments: 3840428d7b3dSmrg// display - Connection to the X server. 3841428d7b3dSmrg// subpicture - The subpicture to be blended into the video. 3842428d7b3dSmrg// target_surface - The surface to be displayed with the blended subpic. 3843428d7b3dSmrg// source_surface - Source surface prior to blending. 3844428d7b3dSmrg// subx, suby, subw, subh - The rectangle from the subpicture to use. 3845428d7b3dSmrg// surfx, surfy, surfw, surfh - The rectangle in the surface to blend 3846428d7b3dSmrg// blend the subpicture rectangle into. Scaling can ocure if 3847428d7b3dSmrg// XVMC_SUBPICTURE_INDEPENDENT_SCALING is set. 3848428d7b3dSmrg// 3849428d7b3dSmrg// Returns: Status 3850428d7b3dSmrg***************************************************************************/ 3851428d7b3dSmrg_X_EXPORT Status XvMCBlendSubpicture2(Display *display, 3852428d7b3dSmrg XvMCSurface *source_surface, 3853428d7b3dSmrg XvMCSurface *target_surface, 3854428d7b3dSmrg XvMCSubpicture *subpicture, 3855428d7b3dSmrg short subx, short suby, 3856428d7b3dSmrg unsigned short subw, unsigned short subh, 3857428d7b3dSmrg short surfx, short surfy, 3858428d7b3dSmrg unsigned short surfw, unsigned short surfh) { 3859428d7b3dSmrg drmBufPtr pDMA; 3860428d7b3dSmrg unsigned int *data; 3861428d7b3dSmrg i810XvMCContext *pI810XvMC; 3862428d7b3dSmrg i810XvMCSubpicture *privSubpicture; 3863428d7b3dSmrg i810XvMCSurface *privTarget; 3864428d7b3dSmrg i810XvMCSurface *privSource; 3865428d7b3dSmrg drm_i810_mc_t mc; 3866428d7b3dSmrg int i,j; 3867428d7b3dSmrg 3868428d7b3dSmrg if(display == NULL) { 3869428d7b3dSmrg return BadValue; 3870428d7b3dSmrg } 3871428d7b3dSmrg 3872428d7b3dSmrg if(subpicture == NULL) { 3873428d7b3dSmrg return (error_base + XvMCBadSubpicture); 3874428d7b3dSmrg } 3875428d7b3dSmrg 3876428d7b3dSmrg if((target_surface == NULL) || (source_surface == NULL)) { 3877428d7b3dSmrg return (error_base + XvMCBadSurface); 3878428d7b3dSmrg } 3879428d7b3dSmrg 3880428d7b3dSmrg if((subpicture->xvimage_id != FOURCC_AI44) && 3881428d7b3dSmrg (subpicture->xvimage_id != FOURCC_IA44)) { 3882428d7b3dSmrg return (error_base + XvMCBadSubpicture); 3883428d7b3dSmrg } 3884428d7b3dSmrg 3885428d7b3dSmrg if(!subpicture->privData) { 3886428d7b3dSmrg return (error_base + XvMCBadSubpicture); 3887428d7b3dSmrg } 3888428d7b3dSmrg privSubpicture = (i810XvMCSubpicture *)subpicture->privData; 3889428d7b3dSmrg 3890428d7b3dSmrg pI810XvMC = (i810XvMCContext *)privSubpicture->privContext; 3891428d7b3dSmrg if(pI810XvMC == NULL) { 3892428d7b3dSmrg return (error_base + XvMCBadSubpicture); 3893428d7b3dSmrg } 3894428d7b3dSmrg 3895428d7b3dSmrg if(!target_surface->privData) { 3896428d7b3dSmrg return (error_base + XvMCBadSurface); 3897428d7b3dSmrg } 3898428d7b3dSmrg privTarget = (i810XvMCSurface *)target_surface->privData; 3899428d7b3dSmrg 3900428d7b3dSmrg if(!source_surface->privData) { 3901428d7b3dSmrg return (error_base + XvMCBadSurface); 3902428d7b3dSmrg } 3903428d7b3dSmrg privSource = (i810XvMCSurface *)source_surface->privData; 3904428d7b3dSmrg 3905428d7b3dSmrg 3906428d7b3dSmrg /* Check that size isn't bigger than subpicture */ 3907428d7b3dSmrg if((subx + subw) > subpicture->width) { 3908428d7b3dSmrg return BadValue; 3909428d7b3dSmrg } 3910428d7b3dSmrg if((suby + subh) > subpicture->height) { 3911428d7b3dSmrg return BadValue; 3912428d7b3dSmrg } 3913428d7b3dSmrg /* Check that dest isn't bigger than surface */ 3914428d7b3dSmrg if((surfx + surfw) > target_surface->width) { 3915428d7b3dSmrg return BadValue; 3916428d7b3dSmrg } 3917428d7b3dSmrg if((surfy + surfh) > target_surface->height) { 3918428d7b3dSmrg return BadValue; 3919428d7b3dSmrg } 3920428d7b3dSmrg /* Make sure surfaces match */ 3921428d7b3dSmrg if(target_surface->width != source_surface->width) { 3922428d7b3dSmrg return BadValue; 3923428d7b3dSmrg } 3924428d7b3dSmrg if(target_surface->height != source_surface->height) { 3925428d7b3dSmrg return BadValue; 3926428d7b3dSmrg } 3927428d7b3dSmrg 3928428d7b3dSmrg /* Lock For DMA */ 3929428d7b3dSmrg I810_LOCK(pI810XvMC,0); 3930428d7b3dSmrg 3931428d7b3dSmrg /* Allocate DMA buffer */ 3932428d7b3dSmrg pDMA = i810_get_free_buffer(pI810XvMC); 3933428d7b3dSmrg data = pDMA->address; 3934428d7b3dSmrg 3935428d7b3dSmrg /* Copy Y data first */ 3936428d7b3dSmrg /* SOURCE_COPY_BLT */ 3937428d7b3dSmrg *data++ = (2<<29) | (0x43<<22) | 0x4; 3938428d7b3dSmrg *data++ = (0xcc<<16) | (1<<26) | (1<<privTarget->pitch); 3939428d7b3dSmrg *data++ = (target_surface->height<<16) | target_surface->width; 3940428d7b3dSmrg *data++ = privTarget->offset + privTarget->offsets[0]; 3941428d7b3dSmrg *data++ = (1<<privSource->pitch); 3942428d7b3dSmrg *data++ = privSource->offset + privSource->offsets[0]; 3943428d7b3dSmrg 3944428d7b3dSmrg /* Select Context 1 for loading */ 3945428d7b3dSmrg *data++ = CMD_FLUSH; 3946428d7b3dSmrg *data++ = (5<<23) | (1<<17) | (1<<8); 3947428d7b3dSmrg *data++ = CMD_FLUSH; 3948428d7b3dSmrg 3949428d7b3dSmrg /* Load Palette */ 3950428d7b3dSmrg *data++ = MAP_PALETTE_LOAD; 3951428d7b3dSmrg /* 16 levels of alpha for each Y */ 3952428d7b3dSmrg switch(subpicture->xvimage_id) { 3953428d7b3dSmrg case FOURCC_IA44: 3954428d7b3dSmrg for(i=0; i<16; i++) { 3955428d7b3dSmrg for(j=0; j<16; j++) { 3956428d7b3dSmrg *data++ = (j<<12) | (j<<8) | privSubpicture->palette[0][i]; 3957428d7b3dSmrg } 3958428d7b3dSmrg } 3959428d7b3dSmrg break; 3960428d7b3dSmrg case FOURCC_AI44: 3961428d7b3dSmrg for(i=0; i<16; i++) { 3962428d7b3dSmrg for(j=0; j<16; j++) { 3963428d7b3dSmrg *data++ = (i<<12) | (i<<8) | privSubpicture->palette[0][j]; 3964428d7b3dSmrg } 3965428d7b3dSmrg } 3966428d7b3dSmrg break; 3967428d7b3dSmrg } 3968428d7b3dSmrg /* TARGET */ 3969428d7b3dSmrg /* *data++ = CMD_FLUSH; */ 3970428d7b3dSmrg /* *data++ = BOOLEAN_ENA_2; */ 3971428d7b3dSmrg *data++ = CMD_FLUSH; 3972428d7b3dSmrg *data++ = DEST_BUFFER_INFO; 3973428d7b3dSmrg *data++ = privTarget->dbi1y; 3974428d7b3dSmrg *data++ = DEST_BUFFER_VAR; 3975428d7b3dSmrg *data++ = privTarget->dbv1; 3976428d7b3dSmrg 3977428d7b3dSmrg /* ALPHA */ 3978428d7b3dSmrg *data++ = CMD_MAP_INFO; 3979428d7b3dSmrg *data++ = privSubpicture->mi1; 3980428d7b3dSmrg *data++ = privSubpicture->mi2; 3981428d7b3dSmrg *data++ = privSubpicture->mi3; 3982428d7b3dSmrg 3983428d7b3dSmrg *data++ = VERTEX_FORMAT | (1<<8) | (3<<1); 3984428d7b3dSmrg *data++ = BOOLEAN_ENA_1; 3985428d7b3dSmrg *data++ = SRC_DEST_BLEND_MONO | (0x940); 3986428d7b3dSmrg /* Map Filter */ 3987428d7b3dSmrg *data++ = (3<<29) | (0x1c<<24) | (2<<19) | (0x224); 3988428d7b3dSmrg 3989428d7b3dSmrg /* Use context 1 */ 3990428d7b3dSmrg *data++ = CMD_FLUSH; 3991428d7b3dSmrg *data++ = (5<<23) | (1<<16) | 1; 3992428d7b3dSmrg *data++ = CMD_FLUSH; 3993428d7b3dSmrg 3994428d7b3dSmrg /* Drawing Rect Info */ 3995428d7b3dSmrg *data++ = DRAWING_RECT_INFO; 3996428d7b3dSmrg *data++ = 0x0; 3997428d7b3dSmrg *data++ = 0x0; 3998428d7b3dSmrg *data++ = 0x0; 3999428d7b3dSmrg *data++ = 0x0; 4000428d7b3dSmrg *data++ = 0x0; 4001428d7b3dSmrg 4002428d7b3dSmrg /* GFXPRIMITIVE RECTANGLE */ 4003428d7b3dSmrg *data++ = (3<<29) | (0x1f<<24) | (0x7<<18) | 11; 4004428d7b3dSmrg /* Bottom Right Vertex */ 4005428d7b3dSmrg *(float *)data++ = (float) (surfx + surfw); 4006428d7b3dSmrg *(float *)data++ = (float) (surfy + surfh); 4007428d7b3dSmrg *(float *)data++ = (float) (subx + subw); 4008428d7b3dSmrg *(float *)data++ = (float) (suby + subh); 4009428d7b3dSmrg /* Bottom Left Vertex */ 4010428d7b3dSmrg *(float *)data++ = (float) surfx; 4011428d7b3dSmrg *(float *)data++ = (float) (surfy + surfh); 4012428d7b3dSmrg *(float *)data++ = (float) subx; 4013428d7b3dSmrg *(float *)data++ = (float) (suby + subh); 4014428d7b3dSmrg /* Top Left Vertex */ 4015428d7b3dSmrg *(float *)data++ = (float) surfx; 4016428d7b3dSmrg *(float *)data++ = (float) surfy; 4017428d7b3dSmrg *(float *)data++ = (float) subx; 4018428d7b3dSmrg *(float *)data++ = (float) suby; 4019428d7b3dSmrg 4020428d7b3dSmrg /* Load and Use Context 0 */ 4021428d7b3dSmrg *data++ = CMD_FLUSH; 4022428d7b3dSmrg *data++ = (5<<23) | (1<<17) | (1<<16); 4023428d7b3dSmrg *data++ = CMD_FLUSH; 4024428d7b3dSmrg 4025428d7b3dSmrg /* U data */ 4026428d7b3dSmrg /* SOURCE_COPY_BLT */ 4027428d7b3dSmrg *data++ = (2<<29) | (0x43<<22) | 0x4; 4028428d7b3dSmrg *data++ = (0xcc<<16) | (1<<26) | (1<<(privTarget->pitch - 1)); 4029428d7b3dSmrg *data++ = (target_surface->height<<15) | (target_surface->width>>1); 4030428d7b3dSmrg *data++ = (unsigned long)privTarget->offset + (unsigned long)privTarget->offsets[1]; 4031428d7b3dSmrg *data++ = (1<<(privSource->pitch - 1)); 4032428d7b3dSmrg *data++ = (unsigned long)privSource->offset + (unsigned long)privSource->offsets[1]; 4033428d7b3dSmrg 4034428d7b3dSmrg /* Context 1 select */ 4035428d7b3dSmrg *data++ = CMD_FLUSH; 4036428d7b3dSmrg *data++ = (5<<23) | (1<<17) | (1<<8); 4037428d7b3dSmrg *data++ = CMD_FLUSH; 4038428d7b3dSmrg /* ALPHA PALETTE */ 4039428d7b3dSmrg *data++ = MAP_PALETTE_LOAD; 4040428d7b3dSmrg /* 16 levels of alpha for each Y */ 4041428d7b3dSmrg switch(subpicture->xvimage_id) { 4042428d7b3dSmrg case FOURCC_IA44: 4043428d7b3dSmrg for(i=0; i<16; i++) { 4044428d7b3dSmrg for(j=0; j<16; j++) { 4045428d7b3dSmrg *data++ = (j<<12) | (j<<8) | privSubpicture->palette[2][i]; 4046428d7b3dSmrg } 4047428d7b3dSmrg } 4048428d7b3dSmrg break; 4049428d7b3dSmrg case FOURCC_AI44: 4050428d7b3dSmrg for(i=0; i<16; i++) { 4051428d7b3dSmrg for(j=0; j<16; j++) { 4052428d7b3dSmrg *data++ = (i<<12) | (i<<8) | privSubpicture->palette[2][j]; 4053428d7b3dSmrg } 4054428d7b3dSmrg } 4055428d7b3dSmrg break; 4056428d7b3dSmrg } 4057428d7b3dSmrg /* TARGET */ 4058428d7b3dSmrg *data++ = CMD_FLUSH; 4059428d7b3dSmrg *data++ = BOOLEAN_ENA_2; 4060428d7b3dSmrg *data++ = CMD_FLUSH; 4061428d7b3dSmrg *data++ = DEST_BUFFER_INFO; 4062428d7b3dSmrg *data++ = privTarget->dbi1u; 4063428d7b3dSmrg *data++ = DEST_BUFFER_VAR; 4064428d7b3dSmrg *data++ = privTarget->dbv1; 4065428d7b3dSmrg 4066428d7b3dSmrg /* ALPHA */ 4067428d7b3dSmrg *data++ = CMD_MAP_INFO; 4068428d7b3dSmrg *data++ = privSubpicture->mi1; 4069428d7b3dSmrg *data++ = privSubpicture->mi2; 4070428d7b3dSmrg *data++ = privSubpicture->mi3; 4071428d7b3dSmrg 4072428d7b3dSmrg *data++ = VERTEX_FORMAT | (1<<8) | (3<<1); 4073428d7b3dSmrg *data++ = BOOLEAN_ENA_1; 4074428d7b3dSmrg *data++ = SRC_DEST_BLEND_MONO | (0x940); 4075428d7b3dSmrg /* Map Filter */ 4076428d7b3dSmrg *data++ = (3<<29) | (0x1c<<24) | (2<<19) | (1<<16) | (0x224); 4077428d7b3dSmrg 4078428d7b3dSmrg /* Use context 1 */ 4079428d7b3dSmrg *data++ = CMD_FLUSH; 4080428d7b3dSmrg *data++ = (5<<23) | (1<<16) | 1; 4081428d7b3dSmrg *data++ = CMD_FLUSH; 4082428d7b3dSmrg 4083428d7b3dSmrg /* Drawing Rect Info */ 4084428d7b3dSmrg *data++ = (3<<29) | (0x1d<<24) | (0x80<<16) | 3; 4085428d7b3dSmrg *data++ = 0; 4086428d7b3dSmrg *data++ = 0; 4087428d7b3dSmrg *data++ = 0; 4088428d7b3dSmrg *data++ = 0; 4089428d7b3dSmrg *data++ = 0; 4090428d7b3dSmrg 4091428d7b3dSmrg /* Rectangle */ 4092428d7b3dSmrg *data++ = (3<<29) | (0x1f<<24) | (0x7<<18) | 11; 4093428d7b3dSmrg /* Bottom Right */ 4094428d7b3dSmrg *(float *)data++ = (float) ((surfx + surfw)>>1); 4095428d7b3dSmrg *(float *)data++ = (float) ((surfy + surfh)>>1); 4096428d7b3dSmrg *(float *)data++ = (float) subx + subw; 4097428d7b3dSmrg *(float *)data++ = (float) suby + subh; 4098428d7b3dSmrg /* Bottom Left */ 4099428d7b3dSmrg *(float *)data++ = (float) (surfx>>1); 4100428d7b3dSmrg *(float *)data++ = (float) ((surfy + surfh)>>1); 4101428d7b3dSmrg *(float *)data++ = (float) subx; 4102428d7b3dSmrg *(float *)data++ = (float) suby + subh; 4103428d7b3dSmrg /* Top Left */ 4104428d7b3dSmrg *(float *)data++ = (float) (surfx>>1); 4105428d7b3dSmrg *(float *)data++ = (float) (surfy>>1); 4106428d7b3dSmrg *(float *)data++ = (float) subx; 4107428d7b3dSmrg *(float *)data++ = (float) suby; 4108428d7b3dSmrg 4109428d7b3dSmrg /* Load and Use Context 0 */ 4110428d7b3dSmrg *data++ = CMD_FLUSH; 4111428d7b3dSmrg *data++ = (5<<23) | (1<<17) | (1<<16); 4112428d7b3dSmrg *data++ = CMD_FLUSH; 4113428d7b3dSmrg 4114428d7b3dSmrg /* V data */ 4115428d7b3dSmrg /* SOURCE_COPY_BLT */ 4116428d7b3dSmrg *data++ = (2<<29) | (0x43<<22) | 0x4; 4117428d7b3dSmrg *data++ = (0xcc<<16) | (1<<26) | (1<<(privTarget->pitch - 1)); 4118428d7b3dSmrg *data++ = (target_surface->height<<15) | (target_surface->width>>1); 4119428d7b3dSmrg *data++ = (unsigned long)privTarget->offset + (unsigned long)privTarget->offsets[2]; 4120428d7b3dSmrg *data++ = (1<<(privSource->pitch - 1)); 4121428d7b3dSmrg *data++ = (unsigned long)privSource->offset + (unsigned long)privSource->offsets[2]; 4122428d7b3dSmrg 4123428d7b3dSmrg /* Context 1 select */ 4124428d7b3dSmrg *data++ = CMD_FLUSH; 4125428d7b3dSmrg *data++ = (5<<23) | (1<<17) | (1<<8); 4126428d7b3dSmrg *data++ = CMD_FLUSH; 4127428d7b3dSmrg 4128428d7b3dSmrg /* ALPHA PALETTE */ 4129428d7b3dSmrg *data++ = MAP_PALETTE_LOAD; 4130428d7b3dSmrg /* 16 levels of alpha for each Y */ 4131428d7b3dSmrg switch(subpicture->xvimage_id) { 4132428d7b3dSmrg case FOURCC_IA44: 4133428d7b3dSmrg for(i=0; i<16; i++) { 4134428d7b3dSmrg for(j=0; j<16; j++) { 4135428d7b3dSmrg *data++ = (j<<12) | (j<<8) | privSubpicture->palette[1][i]; 4136428d7b3dSmrg } 4137428d7b3dSmrg } 4138428d7b3dSmrg break; 4139428d7b3dSmrg case FOURCC_AI44: 4140428d7b3dSmrg for(i=0; i<16; i++) { 4141428d7b3dSmrg for(j=0; j<16; j++) { 4142428d7b3dSmrg *data++ = (i<<12) | (i<<8) | privSubpicture->palette[1][j]; 4143428d7b3dSmrg } 4144428d7b3dSmrg } 4145428d7b3dSmrg break; 4146428d7b3dSmrg } 4147428d7b3dSmrg /* TARGET */ 4148428d7b3dSmrg *data++ = CMD_FLUSH; 4149428d7b3dSmrg *data++ = BOOLEAN_ENA_2; 4150428d7b3dSmrg *data++ = CMD_FLUSH; 4151428d7b3dSmrg *data++ = DEST_BUFFER_INFO; 4152428d7b3dSmrg *data++ = privTarget->dbi1v; 4153428d7b3dSmrg *data++ = DEST_BUFFER_VAR; 4154428d7b3dSmrg *data++ = privTarget->dbv1; 4155428d7b3dSmrg 4156428d7b3dSmrg /* ALPHA */ 4157428d7b3dSmrg *data++ = CMD_MAP_INFO; 4158428d7b3dSmrg *data++ = privSubpicture->mi1; 4159428d7b3dSmrg *data++ = privSubpicture->mi2; 4160428d7b3dSmrg *data++ = privSubpicture->mi3; 4161428d7b3dSmrg 4162428d7b3dSmrg *data++ = VERTEX_FORMAT | (1<<8) | (3<<1); 4163428d7b3dSmrg *data++ = BOOLEAN_ENA_1; 4164428d7b3dSmrg *data++ = SRC_DEST_BLEND_MONO | (0x940); 4165428d7b3dSmrg /* Map Filter */ 4166428d7b3dSmrg *data++ = (3<<29) | (0x1c<<24) | (2<<19) | (1<<16) | (0x224); 4167428d7b3dSmrg 4168428d7b3dSmrg /* Use context 1 */ 4169428d7b3dSmrg *data++ = CMD_FLUSH; 4170428d7b3dSmrg *data++ = (5<<23) | (1<<16) | 1; 4171428d7b3dSmrg *data++ = CMD_FLUSH; 4172428d7b3dSmrg 4173428d7b3dSmrg /* Drawing Rect Info */ 4174428d7b3dSmrg *data++ = (3<<29) | (0x1d<<24) | (0x80<<16) | 3; 4175428d7b3dSmrg *data++ = 0; 4176428d7b3dSmrg *data++ = 0; 4177428d7b3dSmrg *data++ = 0; 4178428d7b3dSmrg *data++ = 0; 4179428d7b3dSmrg *data++ = 0; 4180428d7b3dSmrg 4181428d7b3dSmrg /* Rectangle */ 4182428d7b3dSmrg *data++ = (3<<29) | (0x1f<<24) | (0x7<<18) | 11; 4183428d7b3dSmrg /* Bottom Right */ 4184428d7b3dSmrg *(float *)data++ = (float) ((surfx + surfw)>>1); 4185428d7b3dSmrg *(float *)data++ = (float) ((surfy + surfh)>>1); 4186428d7b3dSmrg *(float *)data++ = (float) subx + subw; 4187428d7b3dSmrg *(float *)data++ = (float) suby + subh; 4188428d7b3dSmrg /* Bottom Left */ 4189428d7b3dSmrg *(float *)data++ = (float) (surfx>>1); 4190428d7b3dSmrg *(float *)data++ = (float) ((surfy + surfh)>>1); 4191428d7b3dSmrg *(float *)data++ = (float) subx; 4192428d7b3dSmrg *(float *)data++ = (float) suby + subh; 4193428d7b3dSmrg /* Top Left */ 4194428d7b3dSmrg *(float *)data++ = (float) (surfx>>1); 4195428d7b3dSmrg *(float *)data++ = (float) (surfy>>1); 4196428d7b3dSmrg *(float *)data++ = (float) subx; 4197428d7b3dSmrg *(float *)data++ = (float) suby; 4198428d7b3dSmrg 4199428d7b3dSmrg /* Load and Use Context 0 */ 4200428d7b3dSmrg *data++ = CMD_FLUSH; 4201428d7b3dSmrg *data++ = (5<<23) | (1<<17) | (1<<16); 4202428d7b3dSmrg *data++ = CMD_FLUSH; 4203428d7b3dSmrg 4204428d7b3dSmrg 4205428d7b3dSmrg /* Dispatch */ 4206428d7b3dSmrg pDMA->used = (unsigned long)data - (unsigned long)pDMA->address; 4207428d7b3dSmrg mc.idx = pDMA->idx; 4208428d7b3dSmrg mc.used = pDMA->used; 4209428d7b3dSmrg mc.last_render = ++pI810XvMC->last_render; 4210428d7b3dSmrg privTarget->last_render = pI810XvMC->last_render; 4211428d7b3dSmrg I810_MC(pI810XvMC,mc); 4212428d7b3dSmrg 4213428d7b3dSmrg I810_UNLOCK(pI810XvMC); 4214428d7b3dSmrg return Success; 4215428d7b3dSmrg} 4216428d7b3dSmrg 4217428d7b3dSmrg 4218428d7b3dSmrg 4219428d7b3dSmrg/*************************************************************************** 4220428d7b3dSmrg// Function: XvMCSyncSubpicture 4221428d7b3dSmrg// Description: This function blocks until all composite/clear requests on 4222428d7b3dSmrg// the subpicture have been complete. 4223428d7b3dSmrg// Arguments: 4224428d7b3dSmrg// display - Connection to the X server. 4225428d7b3dSmrg// subpicture - The subpicture to synchronize 4226428d7b3dSmrg// 4227428d7b3dSmrg// Returns: Status 4228428d7b3dSmrg***************************************************************************/ 4229428d7b3dSmrg_X_EXPORT Status XvMCSyncSubpicture(Display *display, XvMCSubpicture *subpicture) { 4230428d7b3dSmrg Status ret; 4231428d7b3dSmrg int stat=0; 4232428d7b3dSmrg do { 4233428d7b3dSmrg ret = XvMCGetSubpictureStatus(display,subpicture,&stat); 4234428d7b3dSmrg }while(!ret && (stat & XVMC_RENDERING)); 4235428d7b3dSmrg return ret; 4236428d7b3dSmrg} 4237428d7b3dSmrg 4238428d7b3dSmrg 4239428d7b3dSmrg 4240428d7b3dSmrg/*************************************************************************** 4241428d7b3dSmrg// Function: XvMCFlushSubpicture 4242428d7b3dSmrg// Description: This function commits pending composite/clear requests to 4243428d7b3dSmrg// ensure that they will be completed in a finite amount of 4244428d7b3dSmrg// time. 4245428d7b3dSmrg// Arguments: 4246428d7b3dSmrg// display - Connection to the X server. 4247428d7b3dSmrg// subpicture - The subpicture whos compsiting should be flushed 4248428d7b3dSmrg// 4249428d7b3dSmrg// Returns: Status 4250428d7b3dSmrg// NOTES: i810 always dispatches commands so flush is a no-op 4251428d7b3dSmrg***************************************************************************/ 4252428d7b3dSmrg_X_EXPORT Status XvMCFlushSubpicture(Display *display, XvMCSubpicture *subpicture) { 4253428d7b3dSmrg if(display == NULL) { 4254428d7b3dSmrg return BadValue; 4255428d7b3dSmrg } 4256428d7b3dSmrg if(subpicture == NULL) { 4257428d7b3dSmrg return (error_base + XvMCBadSubpicture); 4258428d7b3dSmrg } 4259428d7b3dSmrg 4260428d7b3dSmrg return Success; 4261428d7b3dSmrg} 4262428d7b3dSmrg 4263428d7b3dSmrg 4264428d7b3dSmrg 4265428d7b3dSmrg/*************************************************************************** 4266428d7b3dSmrg// Function: XvMCGetSubpictureStatus 4267428d7b3dSmrg// Description: This function gets the current status of a subpicture 4268428d7b3dSmrg// 4269428d7b3dSmrg// Arguments: 4270428d7b3dSmrg// display - Connection to the X server. 4271428d7b3dSmrg// subpicture - The subpicture whos status is being queried 4272428d7b3dSmrg// stat - The status of the subpicture. It can be any of the following 4273428d7b3dSmrg// OR'd together: 4274428d7b3dSmrg// XVMC_RENDERING - Last composite or clear request not completed 4275428d7b3dSmrg// XVMC_DISPLAYING - Suppicture currently being displayed. 4276428d7b3dSmrg// 4277428d7b3dSmrg// Returns: Status 4278428d7b3dSmrg// Notes: i810 always blends into a third surface so the subpicture is 4279428d7b3dSmrg// never actually displaying, only a copy of it is displaying. We only 4280428d7b3dSmrg// have to worry about the rendering case. 4281428d7b3dSmrg***************************************************************************/ 4282428d7b3dSmrg_X_EXPORT Status XvMCGetSubpictureStatus(Display *display, XvMCSubpicture *subpicture, 4283428d7b3dSmrg int *stat) { 4284428d7b3dSmrg 4285428d7b3dSmrg i810XvMCSubpicture *privSubpicture; 4286428d7b3dSmrg i810XvMCContext *pI810XvMC; 4287428d7b3dSmrg 4288428d7b3dSmrg if((display == NULL) || (stat == NULL)) { 4289428d7b3dSmrg return BadValue; 4290428d7b3dSmrg } 4291428d7b3dSmrg if((subpicture == NULL) || (subpicture->privData == NULL)) { 4292428d7b3dSmrg return (error_base + XvMCBadSubpicture); 4293428d7b3dSmrg } 4294428d7b3dSmrg *stat = 0; 4295428d7b3dSmrg privSubpicture = (i810XvMCSubpicture *)subpicture->privData; 4296428d7b3dSmrg 4297428d7b3dSmrg pI810XvMC = (i810XvMCContext *)privSubpicture->privContext; 4298428d7b3dSmrg if(pI810XvMC == NULL) { 4299428d7b3dSmrg return (error_base + XvMCBadSubpicture); 4300428d7b3dSmrg } 4301428d7b3dSmrg 4302428d7b3dSmrg I810_LOCK(pI810XvMC,0); 4303428d7b3dSmrg 4304428d7b3dSmrg if(privSubpicture->last_render && 4305428d7b3dSmrg (privSubpicture->last_render > GET_RSTATUS(pI810XvMC))) { 4306428d7b3dSmrg *stat |= XVMC_RENDERING; 4307428d7b3dSmrg } 4308428d7b3dSmrg I810_UNLOCK(pI810XvMC); 4309428d7b3dSmrg 4310428d7b3dSmrg return Success; 4311428d7b3dSmrg} 4312428d7b3dSmrg 4313428d7b3dSmrg#define NUM_XVMC_ATTRIBUTES 4 4314428d7b3dSmrgstatic XvAttribute I810_XVMC_ATTRIBUTES[] = { 4315428d7b3dSmrg {XvGettable | XvSettable, 0, 0xffffff, "XV_COLORKEY"}, 4316428d7b3dSmrg {XvGettable | XvSettable, -127, +127, "XV_BRIGHTNESS"}, 4317428d7b3dSmrg {XvGettable | XvSettable, 0, 0x1ff, "XV_CONTRAST"}, 4318428d7b3dSmrg {XvGettable | XvSettable, 0, 0x3ff, "XV_SATURATION"} 4319428d7b3dSmrg}; 4320428d7b3dSmrg 4321428d7b3dSmrg 4322428d7b3dSmrg/*************************************************************************** 4323428d7b3dSmrg// Function: XvMCQueryAttributes 4324428d7b3dSmrg// Description: An array of XvAttributes of size "number" is returned by 4325428d7b3dSmrg// this function. If there are no attributes, NULL is returned and number 4326428d7b3dSmrg// is set to 0. The array may be freed with free(). 4327428d7b3dSmrg// 4328428d7b3dSmrg// Arguments: 4329428d7b3dSmrg// display - Connection to the X server. 4330428d7b3dSmrg// context - The context whos attributes we are querying. 4331428d7b3dSmrg// number - The number of returned atoms. 4332428d7b3dSmrg// 4333428d7b3dSmrg// Returns: 4334428d7b3dSmrg// An array of XvAttributes. 4335428d7b3dSmrg// Notes: 4336428d7b3dSmrg// For i810 we support these Attributes: 4337428d7b3dSmrg// XV_COLORKEY: The colorkey value, initialized from the Xv value at 4338428d7b3dSmrg// context creation time. 4339428d7b3dSmrg// XV_BRIGHTNESS 4340428d7b3dSmrg// XV_CONTRAST 4341428d7b3dSmrg// XV_SATURATION 4342428d7b3dSmrg***************************************************************************/ 4343428d7b3dSmrg_X_EXPORT XvAttribute *XvMCQueryAttributes(Display *display, XvMCContext *context, 4344428d7b3dSmrg int *number) { 4345428d7b3dSmrg i810XvMCContext *pI810XvMC; 4346428d7b3dSmrg XvAttribute *attributes; 4347428d7b3dSmrg 4348428d7b3dSmrg if(number == NULL) { 4349428d7b3dSmrg return NULL; 4350428d7b3dSmrg } 4351428d7b3dSmrg if(display == NULL) { 4352428d7b3dSmrg *number = 0; 4353428d7b3dSmrg return NULL; 4354428d7b3dSmrg } 4355428d7b3dSmrg if(context == NULL) { 4356428d7b3dSmrg *number = 0; 4357428d7b3dSmrg return NULL; 4358428d7b3dSmrg } 4359428d7b3dSmrg pI810XvMC = context->privData; 4360428d7b3dSmrg if(pI810XvMC == NULL) { 4361428d7b3dSmrg *number = 0; 4362428d7b3dSmrg return NULL; 4363428d7b3dSmrg } 4364428d7b3dSmrg 4365428d7b3dSmrg attributes = (XvAttribute *)malloc(NUM_XVMC_ATTRIBUTES * 4366428d7b3dSmrg sizeof(XvAttribute)); 4367428d7b3dSmrg if(attributes == NULL) { 4368428d7b3dSmrg *number = 0; 4369428d7b3dSmrg return NULL; 4370428d7b3dSmrg } 4371428d7b3dSmrg 4372428d7b3dSmrg memcpy(attributes,I810_XVMC_ATTRIBUTES,(NUM_XVMC_ATTRIBUTES * 4373428d7b3dSmrg sizeof(XvAttribute))); 4374428d7b3dSmrg 4375428d7b3dSmrg *number = NUM_XVMC_ATTRIBUTES; 4376428d7b3dSmrg return attributes; 4377428d7b3dSmrg} 4378428d7b3dSmrg 4379428d7b3dSmrg/*************************************************************************** 4380428d7b3dSmrg// Function: XvMCSetAttribute 4381428d7b3dSmrg// Description: This function sets a context-specific attribute. 4382428d7b3dSmrg// 4383428d7b3dSmrg// Arguments: 4384428d7b3dSmrg// display - Connection to the X server. 4385428d7b3dSmrg// context - The context whos attributes we are querying. 4386428d7b3dSmrg// attribute - The X atom of the attribute to be changed. 4387428d7b3dSmrg// value - The new value for the attribute. 4388428d7b3dSmrg// 4389428d7b3dSmrg// Returns: 4390428d7b3dSmrg// Status 4391428d7b3dSmrg// Notes: 4392428d7b3dSmrg// For i810 we support these Attributes: 4393428d7b3dSmrg// XV_COLORKEY: The colorkey value, initialized from the Xv value at 4394428d7b3dSmrg// context creation time. 4395428d7b3dSmrg// XV_BRIGHTNESS 4396428d7b3dSmrg// XV_CONTRAST 4397428d7b3dSmrg// XV_SATURATION 4398428d7b3dSmrg***************************************************************************/ 4399428d7b3dSmrg_X_EXPORT Status XvMCSetAttribute(Display *display, XvMCContext *context, 4400428d7b3dSmrg Atom attribute, int value) { 4401428d7b3dSmrg i810XvMCContext *pI810XvMC; 4402428d7b3dSmrg 4403428d7b3dSmrg if(display == NULL) { 4404428d7b3dSmrg return BadValue; 4405428d7b3dSmrg } 4406428d7b3dSmrg if(context == NULL) { 4407428d7b3dSmrg return (error_base + XvMCBadContext); 4408428d7b3dSmrg } 4409428d7b3dSmrg pI810XvMC = context->privData; 4410428d7b3dSmrg if(pI810XvMC == NULL) { 4411428d7b3dSmrg return (error_base + XvMCBadContext); 4412428d7b3dSmrg } 4413428d7b3dSmrg 4414428d7b3dSmrg if(attribute == pI810XvMC->xv_colorkey) { 4415428d7b3dSmrg if((value < I810_XVMC_ATTRIBUTES[0].min_value) || 4416428d7b3dSmrg (value > I810_XVMC_ATTRIBUTES[0].max_value)) { 4417428d7b3dSmrg return BadValue; 4418428d7b3dSmrg } 4419428d7b3dSmrg pI810XvMC->colorkey = value; 4420428d7b3dSmrg return Success; 4421428d7b3dSmrg } 4422428d7b3dSmrg if(attribute == pI810XvMC->xv_brightness) { 4423428d7b3dSmrg if((value < I810_XVMC_ATTRIBUTES[1].min_value) || 4424428d7b3dSmrg (value > I810_XVMC_ATTRIBUTES[1].max_value)) { 4425428d7b3dSmrg return BadValue; 4426428d7b3dSmrg } 4427428d7b3dSmrg pI810XvMC->brightness = value; 4428428d7b3dSmrg return Success; 4429428d7b3dSmrg } 4430428d7b3dSmrg if(attribute == pI810XvMC->xv_saturation) { 4431428d7b3dSmrg if((value < I810_XVMC_ATTRIBUTES[2].min_value) || 4432428d7b3dSmrg (value > I810_XVMC_ATTRIBUTES[2].max_value)) { 4433428d7b3dSmrg return BadValue; 4434428d7b3dSmrg } 4435428d7b3dSmrg pI810XvMC->saturation = value; 4436428d7b3dSmrg return Success; 4437428d7b3dSmrg } 4438428d7b3dSmrg if(attribute == pI810XvMC->xv_contrast) { 4439428d7b3dSmrg if((value < I810_XVMC_ATTRIBUTES[3].min_value) || 4440428d7b3dSmrg (value > I810_XVMC_ATTRIBUTES[3].max_value)) { 4441428d7b3dSmrg return BadValue; 4442428d7b3dSmrg } 4443428d7b3dSmrg pI810XvMC->contrast = value; 4444428d7b3dSmrg return Success; 4445428d7b3dSmrg } 4446428d7b3dSmrg return BadValue; 4447428d7b3dSmrg} 4448428d7b3dSmrg 4449428d7b3dSmrg/*************************************************************************** 4450428d7b3dSmrg// Function: XvMCGetAttribute 4451428d7b3dSmrg// Description: This function queries a context-specific attribute and 4452428d7b3dSmrg// returns the value. 4453428d7b3dSmrg// 4454428d7b3dSmrg// Arguments: 4455428d7b3dSmrg// display - Connection to the X server. 4456428d7b3dSmrg// context - The context whos attributes we are querying. 4457428d7b3dSmrg// attribute - The X atom of the attribute to be queried 4458428d7b3dSmrg// value - The returned attribute value 4459428d7b3dSmrg// 4460428d7b3dSmrg// Returns: 4461428d7b3dSmrg// Status 4462428d7b3dSmrg// Notes: 4463428d7b3dSmrg// For i810 we support these Attributes: 4464428d7b3dSmrg// XV_COLORKEY: The colorkey value, initialized from the Xv value at 4465428d7b3dSmrg// context creation time. 4466428d7b3dSmrg// XV_BRIGHTNESS 4467428d7b3dSmrg// XV_CONTRAST 4468428d7b3dSmrg// XV_SATURATION 4469428d7b3dSmrg***************************************************************************/ 4470428d7b3dSmrg_X_EXPORT Status XvMCGetAttribute(Display *display, XvMCContext *context, 4471428d7b3dSmrg Atom attribute, int *value) { 4472428d7b3dSmrg i810XvMCContext *pI810XvMC; 4473428d7b3dSmrg 4474428d7b3dSmrg if(display == NULL) { 4475428d7b3dSmrg return BadValue; 4476428d7b3dSmrg } 4477428d7b3dSmrg if(context == NULL) { 4478428d7b3dSmrg return (error_base + XvMCBadContext); 4479428d7b3dSmrg } 4480428d7b3dSmrg pI810XvMC = context->privData; 4481428d7b3dSmrg if(pI810XvMC == NULL) { 4482428d7b3dSmrg return (error_base + XvMCBadContext); 4483428d7b3dSmrg } 4484428d7b3dSmrg if(value == NULL) { 4485428d7b3dSmrg return BadValue; 4486428d7b3dSmrg } 4487428d7b3dSmrg 4488428d7b3dSmrg if(attribute == pI810XvMC->xv_colorkey) { 4489428d7b3dSmrg *value = pI810XvMC->colorkey; 4490428d7b3dSmrg return Success; 4491428d7b3dSmrg } 4492428d7b3dSmrg if(attribute == pI810XvMC->xv_brightness) { 4493428d7b3dSmrg *value = pI810XvMC->brightness; 4494428d7b3dSmrg return Success; 4495428d7b3dSmrg } 4496428d7b3dSmrg if(attribute == pI810XvMC->xv_saturation) { 4497428d7b3dSmrg *value = pI810XvMC->saturation; 4498428d7b3dSmrg return Success; 4499428d7b3dSmrg } 4500428d7b3dSmrg if(attribute == pI810XvMC->xv_contrast) { 4501428d7b3dSmrg *value = pI810XvMC->contrast; 4502428d7b3dSmrg return Success; 4503428d7b3dSmrg } 4504428d7b3dSmrg return BadValue; 4505428d7b3dSmrg} 4506428d7b3dSmrg 4507428d7b3dSmrg 4508428d7b3dSmrg 4509428d7b3dSmrg 4510