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