aboutsummaryrefslogtreecommitdiff
path: root/nx-X11/lib/XvMC/hw/i810/I810XvMC.c
diff options
context:
space:
mode:
Diffstat (limited to 'nx-X11/lib/XvMC/hw/i810/I810XvMC.c')
-rw-r--r--nx-X11/lib/XvMC/hw/i810/I810XvMC.c4507
1 files changed, 0 insertions, 4507 deletions
diff --git a/nx-X11/lib/XvMC/hw/i810/I810XvMC.c b/nx-X11/lib/XvMC/hw/i810/I810XvMC.c
deleted file mode 100644
index 89aa3ea4b..000000000
--- a/nx-X11/lib/XvMC/hw/i810/I810XvMC.c
+++ /dev/null
@@ -1,4507 +0,0 @@
-/***************************************************************************
-
-Copyright 2001 Intel Corporation. All Rights Reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sub license, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice (including the
-next paragraph) shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
-IN NO EVENT SHALL INTEL, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
-DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
-THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-**************************************************************************/
-
-/*************************************************************************
-** File libI810XvMC.c
-**
-** Authors:
-** Matt Sottek <matthew.j.sottek@intel.com>
-** Bob Paauwe <bob.j.paauwe@intel.com>
-**
-**
-***************************************************************************/
-/* $XFree86: xc/lib/XvMC/hw/i810/I810XvMC.c,v 1.10 2002/10/30 12:52:01 alanh Exp $ */
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <errno.h>
-#include <signal.h>
-#include <fcntl.h>
-#include <dirent.h>
-#include <string.h>
-
-#include <sys/ioctl.h>
-#include <X11/Xlibint.h>
-#include <fourcc.h>
-#include <X11/extensions/Xv.h>
-#include <X11/extensions/Xvlib.h>
-#include <X11/extensions/XvMC.h>
-#include <X11/extensions/XvMClib.h>
-#include "I810XvMC.h"
-
-static int error_base;
-static int event_base;
-
-/***************************************************************************
-// Function: i810_get_free_buffer
-// Description: Allocates a free dma page using kernel ioctls, then
-// programs the data into the already allocated dma buffer list.
-// Arguments: pI810XvMC private data structure from the current context.
-// Notes: We faked the drmMapBufs for the i810's security so now we have
-// to insert an allocated page into the correct spot in the faked
-// list to keep up appearences.
-// Concept for this function was taken from Mesa sources.
-// Returns: drmBufPtr containing the information about the allocated page.
-***************************************************************************/
-drmBufPtr i810_get_free_buffer(i810XvMCContext *pI810XvMC) {
- drmI810DMA dma;
- drmBufPtr buf;
-
- dma.granted = 0;
- dma.request_size = 4096;
- while(!dma.granted) {
- if(GET_BUFFER(pI810XvMC, dma) || !dma.granted)
- FLUSH(pI810XvMC);
- } /* No DMA granted */
-
- buf = &(pI810XvMC->dmabufs->list[dma.request_idx]);
- buf->idx = dma.request_idx;
- buf->used = 0;
- buf->total = dma.request_size;
- buf->address = (drmAddress)dma.virtual;
- return buf;
-}
-
-/***************************************************************************
-// Function: free_privContext
-// Description: Free's the private context structure if the reference
-// count is 0.
-***************************************************************************/
-void i810_free_privContext(i810XvMCContext *pI810XvMC) {
-
- I810_LOCK(pI810XvMC,DRM_LOCK_QUIESCENT);
-
-
- pI810XvMC->ref--;
- if(!pI810XvMC->ref) {
- drmUnmapBufs(pI810XvMC->dmabufs);
- drmUnmap(pI810XvMC->overlay.address,pI810XvMC->overlay.size);
- drmUnmap(pI810XvMC->surfaces.address,pI810XvMC->surfaces.size);
- drmClose(pI810XvMC->fd);
-
- free(pI810XvMC->dmabufs->list);
- free(pI810XvMC);
- }
-
- I810_UNLOCK(pI810XvMC);
-}
-
-
-/***************************************************************************
-// Function: XvMCCreateContext
-// Description: Create a XvMC context for the given surface parameters.
-// Arguments:
-// display - Connection to the X server.
-// port - XvPortID to use as avertised by the X connection.
-// surface_type_id - Unique identifier for the Surface type.
-// width - Width of the surfaces.
-// height - Height of the surfaces.
-// flags - one or more of the following
-// XVMC_DIRECT - A direct rendered context is requested.
-//
-// Notes: surface_type_id and width/height parameters must match those
-// returned by XvMCListSurfaceTypes.
-// Returns: Status
-***************************************************************************/
-Status XvMCCreateContext(Display *display, XvPortID port,
- int surface_type_id, int width, int height, int flags,
- XvMCContext *context) {
- i810XvMCContext *pI810XvMC;
- char busIdString[10];
- int priv_count;
- uint *priv_data;
- uint magic;
- Status ret;
- int major, minor;
-
- /* Verify Obvious things first */
- if(context == NULL) {
- return XvMCBadContext;
- }
-
- if(!(flags & XVMC_DIRECT)) {
- /* Indirect */
- printf("Indirect Rendering not supported!\nUsing Direct.");
- }
-
- /* Limit use to root for now */
- if(geteuid()) {
- printf("Use of XvMC on i810 is currently limited to root\n");
- return BadAccess;
- }
-
- /* FIXME: Check $DISPLAY for legal values here */
-
- context->surface_type_id = surface_type_id;
- context->width = (unsigned short)width;
- context->height = (unsigned short)height;
- context->flags = flags;
- context->port = port;
- /*
- Width, Height, and flags are checked against surface_type_id
- and port for validity inside the X server, no need to check
- here.
- */
-
- /* Allocate private Context data */
- context->privData = (void *)malloc(sizeof(i810XvMCContext));
- if(!context->privData) {
- printf("Unable to allocate resources for XvMC context.\n");
- return BadAlloc;
- }
- pI810XvMC = (i810XvMCContext *)context->privData;
-
-
- /* Verify the XvMC extension exists */
- if(! XvMCQueryExtension(display, &event_base,
- &error_base)) {
- printf("XvMC Extension is not available!\n");
- return BadAlloc;
- }
- /* Verify XvMC version */
- ret = XvMCQueryVersion(display, &major, &minor);
- if(ret) {
- printf("XvMCQuery Version Failed, unable to determine protocol version\n");
- }
- /* FIXME: Check Major and Minor here */
-
- /* Check for drm */
- if(! drmAvailable()) {
- printf("Direct Rendering is not avilable on this system!\n");
- return BadAlloc;
- }
-
- /*
- Build the Attribute Atoms, and Initialize the ones that exist
- in Xv.
- */
- pI810XvMC->xv_colorkey = XInternAtom(display,"XV_COLORKEY",0);
- if(!pI810XvMC->xv_colorkey) {
- return XvBadPort;
- }
- ret = XvGetPortAttribute(display,port,pI810XvMC->xv_colorkey,
- &pI810XvMC->colorkey);
- if(ret) {
- return ret;
- }
- pI810XvMC->xv_brightness = XInternAtom(display,"XV_BRIGHTNESS",0);
- pI810XvMC->xv_saturation = XInternAtom(display,"XV_SATURATION",0);
- pI810XvMC->xv_contrast = XInternAtom(display,"XV_CONTRAST",0);
- pI810XvMC->brightness = 0;
- pI810XvMC->saturation = 0x80; /* 1.0 in 3.7 format */
- pI810XvMC->contrast = 0x40; /* 1.0 in 3.6 format */
-
- /* Open DRI Device */
- if((pI810XvMC->fd = drmOpen("i810",NULL)) < 0) {
- printf("DRM Device for i810 could not be opened.\n");
- free(busIdString);
- free(pI810XvMC);
- return BadAccess;
- } /* !pI810XvMC->fd */
-
- /* Get magic number and put it in privData for passing */
- drmGetMagic(pI810XvMC->fd,&magic);
- context->flags = (unsigned long)magic;
-
- /*
- Pass control to the X server to create a drm_context_t for us and
- validate the with/height and flags.
- */
- if((ret = _xvmc_create_context(display, context, &priv_count, &priv_data))) {
- printf("Unable to create XvMC Context.\n");
- return ret;
- }
-
- /*
- X server returns a structure like this:
- drm_context_t
- fbBase
- OverlayOffset
- OverlaySize
- SurfacesOffset
- SurfacesSize
- busIdString = 9 char + 1
- */
- if(priv_count != 9) {
- printf("_xvmc_create_context() returned incorrect data size!\n");
- printf("\tExpected 9, got %d\n",priv_count);
- _xvmc_destroy_context(display, context);
- free(pI810XvMC);
- return BadAlloc;
- }
- pI810XvMC->drmcontext = priv_data[0];
- pI810XvMC->fb_base = priv_data[1];
- pI810XvMC->overlay.offset = priv_data[2] + priv_data[1];
- pI810XvMC->overlay.size = priv_data[3];
- pI810XvMC->surfaces.offset = priv_data[4] + priv_data[1];
- pI810XvMC->surfaces.size = priv_data[5];
- strncpy(pI810XvMC->busIdString,(char *)&priv_data[6],9);
- pI810XvMC->busIdString[9] = '\0';
-
- /* Must free the private data we were passed from X */
- free(priv_data);
-
- /* Initialize private context values */
- pI810XvMC->current = 0;
- pI810XvMC->lock = 0;
- pI810XvMC->last_flip = 0;
- pI810XvMC->dual_prime = 0;
-
- /*
- Map dma Buffers: Not really, this would be a drmMapBufs
- but due to the i810 security model we have to just create an
- empty data structure to fake it.
- */
- pI810XvMC->dmabufs = (drmBufMapPtr)malloc(sizeof(drmBufMap));
- if(pI810XvMC->dmabufs == NULL) {
- printf("Dma Bufs could not be mapped.\n");
- _xvmc_destroy_context(display, context);
- free(pI810XvMC);
- return BadAlloc;
- } /* pI810XvMC->dmabufs == NULL */
- memset(pI810XvMC->dmabufs, 0, sizeof(drmBufMap));
- pI810XvMC->dmabufs->list = (drmBufPtr)malloc(sizeof(drmBuf) *
- I810_DMA_BUF_NR);
- if(pI810XvMC->dmabufs->list == NULL) {
- printf("Dma Bufs could not be mapped.\n");
- _xvmc_destroy_context(display, context);
- free(pI810XvMC);
- return BadAlloc;
- } /* pI810XvMC->dmabufs->list == NULL */
- memset(pI810XvMC->dmabufs->list, 0, sizeof(drmBuf) * I810_DMA_BUF_NR);
-
- /* Map the Overlay memory */
- if(drmMap(pI810XvMC->fd,pI810XvMC->overlay.offset,
- pI810XvMC->overlay.size,&(pI810XvMC->overlay.address)) < 0) {
- printf("Unable to map Overlay at offset 0x%x and size 0x%x\n",
- (unsigned int)pI810XvMC->overlay.offset,pI810XvMC->overlay.size);
- _xvmc_destroy_context(display, context);
- free(pI810XvMC->dmabufs->list);
- free(pI810XvMC);
- return BadAlloc;
- } /* drmMap() < 0 */
-
- /* Overlay Regs are offset 1024 into Overlay Map */
- pI810XvMC->oregs = (i810OverlayRec *)
- ((unsigned char *)pI810XvMC->overlay.address + 1024);
-
- /* Map Surfaces */
- if(drmMap(pI810XvMC->fd,pI810XvMC->surfaces.offset,
- pI810XvMC->surfaces.size,&(pI810XvMC->surfaces.address)) < 0) {
- printf("Unable to map XvMC Surfaces.\n");
- _xvmc_destroy_context(display, context);
- free(pI810XvMC->dmabufs->list);
- free(pI810XvMC);
- return BadAlloc;
- } /* drmMap() < 0 */
-
- /*
- There is a tiny chance that someone was using the overlay and
- issued a flip that hasn't finished. To be 100% sure I'll just
- take the lock and sleep for the worst case time for a flip.
- */
- I810_LOCK(pI810XvMC,DRM_LOCK_QUIESCENT);
- usleep(20000); /* 1/50th Sec for 50hz refresh */
-
- /* Set up Overlay regs with Initial Values */
- pI810XvMC->oregs->YRGB_VPH = 0;
- pI810XvMC->oregs->UV_VPH = 0;
- pI810XvMC->oregs->HORZ_PH = 0;
- pI810XvMC->oregs->INIT_PH = 0;
- pI810XvMC->oregs->DWINPOS = 0;
- pI810XvMC->oregs->DWINSZ = (I810_XVMC_MAXHEIGHT << 16) |
- I810_XVMC_MAXWIDTH;
- pI810XvMC->oregs->SWID = I810_XVMC_MAXWIDTH | (I810_XVMC_MAXWIDTH << 15);
- pI810XvMC->oregs->SWIDQW = (I810_XVMC_MAXWIDTH >> 3) |
- (I810_XVMC_MAXWIDTH << 12);
- pI810XvMC->oregs->SHEIGHT = I810_XVMC_MAXHEIGHT |
- (I810_XVMC_MAXHEIGHT << 15);
- pI810XvMC->oregs->YRGBSCALE = 0x80004000; /* scale factor 1 */
- pI810XvMC->oregs->UVSCALE = 0x80004000; /* scale factor 1 */
- pI810XvMC->oregs->OV0CLRC0 = 0x4000; /* brightness: 0 contrast: 1.0 */
- pI810XvMC->oregs->OV0CLRC1 = 0x80; /* saturation: bypass */
-
- /* Destination Colorkey Setup */
- pI810XvMC->oregs->DCLRKV = RGB16ToColorKey(pI810XvMC->colorkey);
- pI810XvMC->oregs->DCLRKM = 0x80070307;
-
-
- pI810XvMC->oregs->SCLRKVH = 0;
- pI810XvMC->oregs->SCLRKVL = 0;
- pI810XvMC->oregs->SCLRKM = 0; /* source color key disable */
- pI810XvMC->oregs->OV0CONF = 0; /* two 720 pixel line buffers */
-
- pI810XvMC->oregs->OV0CMD = VC_UP_INTERPOLATION | HC_UP_INTERPOLATION |
- Y_ADJUST | YUV_420;
-
- pI810XvMC->ref = 1;
-
- I810_UNLOCK(pI810XvMC);
-
- return Success;
-
-}
-
-/***************************************************************************
-// Function: XvMCDestroyContext
-// Description: Destorys the specified context.
-//
-// Arguments:
-// display - Specifies the connection to the server.
-// context - The context to be destroyed.
-//
-// Returns: Status
-***************************************************************************/
-Status XvMCDestroyContext(Display *display, XvMCContext *context) {
- i810XvMCContext *pI810XvMC;
-
- if(context == NULL) {
- return (error_base + XvMCBadContext);
- }
- if(context->privData == NULL) {
- return (error_base + XvMCBadContext);
- }
- pI810XvMC = (i810XvMCContext *)context->privData;
-
- /* Turn off the overlay */
- if(pI810XvMC->last_flip) {
- I810_LOCK(pI810XvMC,DRM_LOCK_QUIESCENT);
-
- /* Make sure last flip is done */
- BLOCK_OVERLAY(pI810XvMC,pI810XvMC->current);
-
- pI810XvMC->oregs->OV0CMD = VC_UP_INTERPOLATION | HC_UP_INTERPOLATION |
- Y_ADJUST;
- pI810XvMC->current = !pI810XvMC->current;
- if(pI810XvMC->current == 1) {
- pI810XvMC->oregs->OV0CMD |= BUFFER1_FIELD0;
- }
- else {
- pI810XvMC->oregs->OV0CMD |= BUFFER0_FIELD0;
- }
- OVERLAY_FLIP(pI810XvMC);
- pI810XvMC->last_flip++;
-
- /* Wait for the flip */
- BLOCK_OVERLAY(pI810XvMC,pI810XvMC->current);
-
- I810_UNLOCK(pI810XvMC);
- }
-
- /* Pass Control to the X server to destroy the drm_context_t */
- _xvmc_destroy_context(display, context);
-
- i810_free_privContext(pI810XvMC);
- context->privData = NULL;
-
- return Success;
-}
-
-
-/***************************************************************************
-// Function: XvMCCreateSurface
-***************************************************************************/
-Status XvMCCreateSurface( Display *display, XvMCContext *context,
- XvMCSurface *surface) {
- i810XvMCContext *pI810XvMC;
- i810XvMCSurface *pI810Surface;
- int priv_count;
- uint *priv_data;
- Status ret;
-
- if((surface == NULL) || (context == NULL) || (display == NULL)){
- return BadValue;
- }
-
- pI810XvMC = (i810XvMCContext *)context->privData;
- if(pI810XvMC == NULL) {
- return (error_base + XvMCBadContext);
- }
-
-
- surface->privData = (i810XvMCSurface *)malloc(sizeof(i810XvMCSurface));
- if(!surface->privData) {
- return BadAlloc;
- }
- pI810Surface = (i810XvMCSurface *)surface->privData;
-
- /* Initialize private values */
- pI810Surface->privContext = pI810XvMC;
- pI810Surface->last_render = 0;
- pI810Surface->last_flip = 0;
- pI810Surface->second_field = 0;
-
- if((ret = _xvmc_create_surface(display, context, surface,
- &priv_count, &priv_data))) {
- free(pI810Surface);
- printf("Unable to create XvMCSurface.\n");
- return ret;
- }
-
- /*
- _xvmc_create_subpicture returns 2 uints with the offset into
- the DRM map for the Y surface and UV surface.
- */
- if(priv_count != 2) {
- printf("_xvmc_create_surface() return incorrect data size.\n");
- printf("Expected 2 got %d\n",priv_count);
- free(priv_data);
- free(pI810Surface);
- return BadAlloc;
- }
- /* Data == Client Address, offset == Physical address offset */
- pI810Surface->data = pI810XvMC->surfaces.address;
- pI810Surface->offset = pI810XvMC->surfaces.offset;
-
-
- /*
- i810's MC Engine needs surfaces of 2^x (x= 9,10,11,12) pitch
- and the Tiler need 512k aligned surfaces, basically we are
- stuck with fixed memory with pitch 1024 for Y data. UV = 512.
- */
- pI810Surface->pitch = 10;
- if((surface->surface_type_id == FOURCC_UYVY) ||
- (surface->surface_type_id == FOURCC_YUY2)) {
- /* This is not implemented server side. */
- pI810Surface->pitch++;
- }
-
- /*
- offsets[0,1,2] == Offsets from either data or offset for the Y
- U and V surfaces.
- */
- pI810Surface->offsets[0] = priv_data[0];
- if(((unsigned long)pI810Surface->data + pI810Surface->offsets[0]) & 4095) {
- printf("XvMCCreateSurface: Surface offset 0 is not 4096 aligned\n");
- }
-
- if((surface->surface_type_id == FOURCC_UYVY) ||
- (surface->surface_type_id == FOURCC_YUY2)) {
- /* Packed surface, not fully implemented */
- pI810Surface->offsets[1] = 0;
- pI810Surface->offsets[2] = 0;
- }
- else {
- /* Planar surface */
- pI810Surface->offsets[1] = priv_data[1];
- if(((unsigned long)pI810Surface->data + pI810Surface->offsets[1]) & 2047) {
- printf("XvMCCreateSurface: Surface offset 1 is not 2048 aligned\n");
- }
-
- pI810Surface->offsets[2] = ((unsigned long)pI810Surface->offsets[1] +
- (1<<(pI810Surface->pitch - 1)) * 288);
- if(((unsigned long)pI810Surface->data + pI810Surface->offsets[2]) & 2047) {
- printf("XvMCCreateSurface: Surface offset 2 is not 2048 aligned\n");
- }
-
- }
-
- /* Free data returned from xvmc_create_surface */
- free(priv_data);
-
- /* Clear the surface to 0 */
- memset((void *)((unsigned long)pI810Surface->data + (unsigned long)pI810Surface->offsets[0]),
- 0, ((1<<pI810Surface->pitch) * surface->height));
-
- switch(surface->surface_type_id) {
- case FOURCC_YV12:
- case FOURCC_I420:
- /* Destination buffer info command */
- pI810Surface->dbi1y = ((((unsigned int)pI810Surface->offset +
- pI810Surface->offsets[0]) & ~0xfc000fff) |
- (pI810Surface->pitch - 9));
- pI810Surface->dbi1u = ((((unsigned int)pI810Surface->offset +
- pI810Surface->offsets[1]) & ~0xfc000fff) |
- (pI810Surface->pitch - 10));
- pI810Surface->dbi1v = ((((unsigned int)pI810Surface->offset +
- pI810Surface->offsets[2]) & ~0xfc000fff) |
- (pI810Surface->pitch - 10));
-
- /* Destination buffer variables command */
- pI810Surface->dbv1 = (0x8<<20) | (0x8<<16);
- /* Map info command */
- pI810Surface->mi1y = (0x1<<24) | (1<<9) | (pI810Surface->pitch - 3);
- pI810Surface->mi1u = (0x1<<24) | (1<<9) | (pI810Surface->pitch - 4);
- pI810Surface->mi1v = (0x1<<24) | (1<<9) | (pI810Surface->pitch - 4);
-
- pI810Surface->mi2y = (((unsigned int)surface->height - 1)<<16) |
- ((unsigned int)surface->width - 1);
- pI810Surface->mi2u = (((unsigned int)surface->height - 1)<<15) |
- (((unsigned int)surface->width - 1)>>1);
- pI810Surface->mi2v = pI810Surface->mi2u;
-
- pI810Surface->mi3y = ((unsigned int)pI810Surface->offset +
- pI810Surface->offsets[0]) & ~0x0000000f;
- pI810Surface->mi3u = ((unsigned int)pI810Surface->offset +
- pI810Surface->offsets[1]) & ~0x0000000f;
- pI810Surface->mi3v = ((unsigned int)pI810Surface->offset +
- pI810Surface->offsets[2]) & ~0x0000000f;
- break;
- case FOURCC_UYVY:
- case FOURCC_YUY2:
- default:
- /* Destination buffer info command */
- pI810Surface->dbi1y = ((((unsigned int)pI810Surface->offset +
- pI810Surface->offsets[0]) & ~0xfc000fff) |
- (pI810Surface->pitch - 9));
- /* Destination buffer variables command */
- if(surface->surface_type_id == FOURCC_YUY2) {
- pI810Surface->dbv1 = 0x5<<8;
- pI810Surface->mi1y = 0x5<<24 | pI810Surface->pitch | 0x1<<21;
- }
- else {
- pI810Surface->dbv1 = 0x4<<8;
- pI810Surface->mi1y = 0x5<<24 | (pI810Surface->pitch - 3);
- }
- pI810Surface->mi2y = (((unsigned int)surface->width - 1)<<16) |
- ((unsigned int)surface->height - 1);
- pI810Surface->mi3y = ((unsigned int)pI810Surface->offset +
- pI810Surface->offsets[0]) & ~0xfc000fff;
- break;
- }
- pI810XvMC->ref++;
-
- return Success;
-}
-
-
-/***************************************************************************
-// Function: XvMCDestroySurface
-***************************************************************************/
-Status XvMCDestroySurface(Display *display, XvMCSurface *surface) {
- i810XvMCSurface *pI810Surface;
- i810XvMCContext *pI810XvMC;
-
- if((display == NULL) || (surface == NULL)) {
- return BadValue;
- }
- if(surface->privData == NULL) {
- return (error_base + XvMCBadSurface);
- }
-
- pI810Surface = (i810XvMCSurface *)surface->privData;
- if(pI810Surface->last_flip) {
- XvMCSyncSurface(display,surface);
- }
- pI810XvMC = (i810XvMCContext *)pI810Surface->privContext;
-
- _xvmc_destroy_surface(display,surface);
-
- i810_free_privContext(pI810XvMC);
-
- free(pI810Surface);
- surface->privData = NULL;
- return Success;
-}
-
-/***************************************************************************
-// Function: XvMCCreateBlocks
-***************************************************************************/
-Status XvMCCreateBlocks(Display *display, XvMCContext *context,
- unsigned int num_blocks,
- XvMCBlockArray *block) {
-
- if((display == NULL) || (context == NULL) || (num_blocks == 0)) {
- return BadValue;
- }
-
- block->blocks = (short *)malloc(num_blocks<<6 * sizeof(short));
- if(block->blocks == NULL) {
- return BadAlloc;
- }
-
- block->num_blocks = num_blocks;
- block->context_id = context->context_id;
-
- block->privData = NULL;
-
- return Success;
-}
-
-/***************************************************************************
-// Function: XvMCDestroyBlocks
-***************************************************************************/
-Status XvMCDestroyBlocks(Display *display, XvMCBlockArray *block) {
- if(display == NULL) {
- return BadValue;
- }
-
- free(block->blocks);
- block->num_blocks = 0;
- block->context_id = 0;
- block->privData = NULL;
- return Success;
-}
-
-/***************************************************************************
-// Function: XvMCCreateMacroBlocks
-***************************************************************************/
-Status XvMCCreateMacroBlocks(Display *display, XvMCContext *context,
- unsigned int num_blocks,
- XvMCMacroBlockArray *blocks) {
-
- if((display == NULL) || (context == NULL) || (blocks == NULL) ||
- (num_blocks == 0)) {
- return BadValue;
- }
- memset(blocks,0,sizeof(XvMCMacroBlockArray));
- blocks->context_id = context->context_id;
- blocks->privData = NULL;
-
- blocks->macro_blocks = (XvMCMacroBlock *)
- malloc(num_blocks * sizeof(XvMCMacroBlock));
- if(blocks->macro_blocks == NULL) {
- return BadAlloc;
- }
- blocks->num_blocks = num_blocks;
-
- return Success;
-}
-
-/***************************************************************************
-// Function: XvMCDestroyMacroBlocks
-***************************************************************************/
-Status XvMCDestroyMacroBlocks(Display *display, XvMCMacroBlockArray *block) {
- if((display == NULL) || (block == NULL)) {
- return BadValue;
- }
- if(block->macro_blocks) {
- free(block->macro_blocks);
- }
- block->context_id = 0;
- block->num_blocks = 0;
- block->privData = NULL;
-
- return Success;
-}
-
-
-/***************************************************************************
-// Function: dp (Debug Print)
-// Description: This function prints out in hex i * uint32_t at the address
-// supplied. This enables you to print out the dma buffers from
-// within the debugger even though they are not in your address space.
-***************************************************************************/
-void dp(unsigned int *address, unsigned int i) {
- int j;
-
- printf("DebugPrint:\n");
- for(j=0; j<i; j++) {
- printf("0x%8.8x ",address[j]);
- if(j && !(j & 7)) { printf("\n");}
- }
-}
-
-/***************************************************************************
-// Macro: PACK_*
-// Description: Packs 16bit signed data from blocks into either 8bit unsigned
-// intra data or 16bit signed correction data, both packed into
-// 32 bit integers.
-***************************************************************************/
-#define PACK_INTRA_DATA(d,b,n) \
- do { \
- char *dp = (char *)d; \
- char *bp = (char *)b; \
- int counter; \
- for(counter = 0; counter < n; counter++) { \
- *dp++ = *bp; \
- bp += 2; \
- } \
- }while(0);
-
-#define PACK_CORR_DATA(d,b,n) \
- memcpy(d,b,n); \
- d = (uint *)((unsigned long)d + n);
-
-#define MARK_CORR_DATA(d,n) \
- do { \
- uint* q = (uint*)((unsigned long)d - n); \
- while((unsigned long)q < (unsigned long)d) { \
- *q++ += 0x00330033; \
- } \
- }while(0);
-
-#define MARK_INTRA_BLOCK(d) \
- do { \
- int q; \
- for(q=0; q<16; q++) { \
- d[q] += 0x33333333; \
- } \
- }while(0);
-
-/*
- Used for DCT 1 when we need DCT 0. Instead
- of reading from one block we read from two and
- interlace.
-*/
-#define PACK_CORR_DATA_1to0(d,top,bottom) \
- do { \
- short *t = top,*b = bottom; \
- PACK_CORR_DATA(d,t,16); \
- t = (short *)((unsigned long)t + 16); \
- PACK_CORR_DATA(d,b,16); \
- b = (short *)((unsigned long)b + 16); \
- PACK_CORR_DATA(d,t,16); \
- t = (short *)((unsigned long)t + 16); \
- PACK_CORR_DATA(d,b,16); \
- b = (short *)((unsigned long)b + 16); \
- PACK_CORR_DATA(d,t,16); \
- t = (short *)((unsigned long)t + 16); \
- PACK_CORR_DATA(d,b,16); \
- b = (short *)((unsigned long)b + 16); \
- PACK_CORR_DATA(d,t,16); \
- t = (short *)((unsigned long)t + 16); \
- PACK_CORR_DATA(d,b,16); \
- b = (short *)((unsigned long)b + 16); \
- }while(0);
-
-/* Used for DCT 0 when we need DCT 1. */
-#define PACK_CORR_DATA_0to1(d,top,bottom) \
- do{ \
- short *t = top,*b = bottom; \
- PACK_CORR_DATA(d,t,16); \
- t = (short *)((unsigned long)t + 32); \
- PACK_CORR_DATA(d,t,16); \
- t = (short *)((unsigned long)t + 32); \
- PACK_CORR_DATA(d,t,16); \
- t = (short *)((unsigned long)t + 32); \
- PACK_CORR_DATA(d,t,16); \
- t = (short *)((unsigned long)t + 32); \
- PACK_CORR_DATA(d,b,16); \
- b = (short *)((unsigned long)b + 32); \
- PACK_CORR_DATA(d,b,16); \
- b = (short *)((unsigned long)b + 32); \
- PACK_CORR_DATA(d,b,16); \
- b = (short *)((unsigned long)b + 32); \
- PACK_CORR_DATA(d,b,16); \
- b = (short *)((unsigned long)b + 32); \
- }while(0);
-
-#define PACK_CORR_DATA_SHORT(d,block) \
- do { \
- short *b = block; \
- PACK_CORR_DATA(d,b,16); \
- b = (short *)((unsigned long)b + 32); \
- PACK_CORR_DATA(d,b,16); \
- b = (short *)((unsigned long)b + 32); \
- PACK_CORR_DATA(d,b,16); \
- b = (short *)((unsigned long)b + 32); \
- PACK_CORR_DATA(d,b,16); \
- b = (short *)((unsigned long)b + 32); \
- }while(0);
-
-/* Lookup tables to speed common calculations */
-static unsigned int drps_table[] = {2<<6,3<<6};
-
-static unsigned int mvfs_table[] = {
- 0x12,
- 0x1a,
- 0x13,
- 0x1b
-};
-
-static unsigned int type_table[] = {
- 0x1<<12, /* This is an error so make it Forward motion */
- 0x1<<12,
- 0x1<<12,
- 0x1<<12,
- 0x2<<12,
- 0x2<<12,
- 0x3<<12,
- 0x3<<12,
- 0x1<<12, /* Pattern but no Motion, Make motion Forward */
- 0x1<<12,
- 0x1<<12,
- 0x1<<12,
- 0x2<<12,
- 0x2<<12,
- 0x3<<12,
- 0x3<<12
-};
-
-static unsigned int y_frame_bytes[] = {
- 0,0,0,0,128,128,128,128,
- 128,128,128,128,256,256,256,256,
- 128,128,128,128,256,256,256,256,
- 256,256,256,256,384,384,384,384,
- 128,128,128,128,256,256,256,256,
- 256,256,256,256,384,384,384,384,
- 256,256,256,256,384,384,384,384,
- 384,384,384,384,512,512,512,512
-};
-
-static unsigned int u_frame_bytes[] = {
- 0,0,128,128,0,0,128,128,
- 0,0,128,128,0,0,128,128,
- 0,0,128,128,0,0,128,128,
- 0,0,128,128,0,0,128,128,
- 0,0,128,128,0,0,128,128,
- 0,0,128,128,0,0,128,128,
- 0,0,128,128,0,0,128,128,
- 0,0,128,128,0,0,128,128
-};
-
-static unsigned int v_frame_bytes[] = {
- 0,128,0,128,0,128,0,128,
- 0,128,0,128,0,128,0,128,
- 0,128,0,128,0,128,0,128,
- 0,128,0,128,0,128,0,128,
- 0,128,0,128,0,128,0,128,
- 0,128,0,128,0,128,0,128,
- 0,128,0,128,0,128,0,128,
- 0,128,0,128,0,128,0,128
-};
-
-static unsigned int y_first_field_bytes[] = {
- 0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,
- 128,128,128,128,128,128,128,128,
- 128,128,128,128,128,128,128,128,
- 128,128,128,128,128,128,128,128,
- 128,128,128,128,128,128,128,128,
- 256,256,256,256,256,256,256,256,
- 256,256,256,256,256,256,256,256
-};
-
-static unsigned int y_second_field_bytes[] = {
- 0,0,0,0,128,128,128,128,
- 128,128,128,128,256,256,256,256,
- 0,0,0,0,128,128,128,128,
- 128,128,128,128,256,256,256,256,
- 0,0,0,0,128,128,128,128,
- 128,128,128,128,256,256,256,256,
- 0,0,0,0,128,128,128,128,
- 128,128,128,128,256,256,256,256
-};
-
-static unsigned int y_dct0_field_bytes[] = {
- 0,0,0,0,128,128,128,128,
- 128,128,128,128,256,256,256,256,
- 128,128,128,128,128,128,128,128,
- 256,256,256,256,256,256,256,256,
- 128,128,128,128,256,256,256,256,
- 128,128,128,128,256,256,256,256,
- 256,256,256,256,256,256,256,256,
- 256,256,256,256,256,256,256,256
-};
-
-static unsigned int y_dct1_frame_bytes[] = {
- 0,0,0,0,256,256,256,256,
- 256,256,256,256,512,512,512,512,
- 256,256,256,256,256,256,256,256,
- 512,512,512,512,512,512,512,512,
- 256,256,256,256,512,512,512,512,
- 256,256,256,256,512,512,512,512,
- 512,512,512,512,512,512,512,512,
- 512,512,512,512,512,512,512,512
-};
-
-static unsigned int u_field_bytes[] = {
- 0,0,64,64,0,0,64,64,
- 0,0,64,64,0,0,64,64,
- 0,0,64,64,0,0,64,64,
- 0,0,64,64,0,0,64,64,
- 0,0,64,64,0,0,64,64,
- 0,0,64,64,0,0,64,64,
- 0,0,64,64,0,0,64,64,
- 0,0,64,64,0,0,64,64
-};
-
-static unsigned int v_field_bytes[] = {
- 0,64,0,64,0,64,0,64,
- 0,64,0,64,0,64,0,64,
- 0,64,0,64,0,64,0,64,
- 0,64,0,64,0,64,0,64,
- 0,64,0,64,0,64,0,64,
- 0,64,0,64,0,64,0,64,
- 0,64,0,64,0,64,0,64,
- 0,64,0,64,0,64,0,64
-};
-
-static short empty_block[] = {
- 0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0
-};
-
-
-/***************************************************************************
-// Function: dispatchYContext
-// Description: Allocate a DMA buffer write the Y MC Context info in it,
-// and dispatch it to hardware.
-***************************************************************************/
-
-static __inline__ void dispatchYContext(i810XvMCSurface *privTarget,
- i810XvMCSurface *privPast,
- i810XvMCSurface *privFuture,
- i810XvMCContext *pI810XvMC) {
- uint *data;
- drmBufPtr pDMA;
- drm_i810_mc_t mc;
-
- pDMA = i810_get_free_buffer(pI810XvMC);
- data = pDMA->address;
- *data++ = CMD_FLUSH;
- *data++ = BOOLEAN_ENA_2;
- *data++ = CMD_FLUSH;
- *data++ = DEST_BUFFER_INFO;
- *data++ = privTarget->dbi1y;
- *data++ = DEST_BUFFER_VAR;
- *data++ = privTarget->dbv1;
- /* Past Surface */
- *data++ = CMD_MAP_INFO;
- *data++ = privPast->mi1y;
- *data++ = privPast->mi2y;
- *data++ = privPast->mi3y;
- /* Future Surface */
- *data++ = CMD_MAP_INFO;
- *data++ = privFuture->mi1y | 0x1<<28;
- *data++ = privFuture->mi2y;
- *data++ = privFuture->mi3y;
-
- mc.idx = pDMA->idx;
- mc.used = (unsigned long)data - (unsigned long)pDMA->address;
- mc.last_render = ++pI810XvMC->last_render;
- privTarget->last_render = pI810XvMC->last_render;
- I810_MC(pI810XvMC,mc);
-}
-
-static __inline__ void renderError(void) {
- printf("Invalid Macroblock Parameters found.\n");
- return;
-}
-
-/***************************************************************************
-// Function: renderIntrainFrame
-// Description: inline function that sets hardware parameters for an Intra
-// encoded macroblock in a Frame picture.
-***************************************************************************/
-static __inline__ void renderIntrainFrame(uint **datay,uint **datau,
- uint **datav,
- XvMCMacroBlock *mb,
- short *block_ptr) {
-
- register uint *dy = *datay;
- register uint *du = *datau;
- register uint *dv = *datav;
-
- /* Y Blocks */
- *dy++ = GFXBLOCK + 68;
- *dy++ = (1<<30) | (3<<28) | (0xf<<24);
- *dy++ = ((uint)mb->x<<20) | ((uint)mb->y<<4);
- *dy++ = (16<<16) | 16;
- *dy++ = 0;
- *dy++ = 0;
- PACK_INTRA_DATA(dy,block_ptr,256);
- dy += 64;
- block_ptr += 256;
- /* End Y Blocks */
-
- /* U Block */
- *du++ = GFXBLOCK + 20;
- *du++ = (2<<30) | (1<<28) | (1<<23);
- *du++ = (((uint)mb->x)<<19) | (((uint)mb->y)<<3);
- *du++ = (8<<16) | 8;
- *du++ = 0;
- *du++ = 0;
- PACK_INTRA_DATA(du,block_ptr,64);
- du += 16;
- block_ptr += 64;
-
- /* V Block */
- *dv++ = GFXBLOCK + 20;
- *dv++ = (3<<30) | (1<<28) | (1<<22);
- *dv++ = (((uint)mb->x)<<19) | (((uint)mb->y)<<3);
- *dv++ = (8<<16) | 8;
- *dv++ = 0;
- *dv++ = 0;
- PACK_INTRA_DATA(dv,block_ptr,64);
- dv += 16;
- block_ptr += 64;
-
- *datay = dy;
- *datau = du;
- *datav = dv;
-}
-
-/***************************************************************************
-// Function: renderIntrainFrameDCT1
-// Description: inline function that sets hardware parameters for an Intra
-// encoded macroblock in a Frame picture with DCT type 1.
-***************************************************************************/
-static __inline__ void renderIntrainFrameDCT1(uint **datay,uint **datau,
- uint **datav,XvMCMacroBlock *mb,
- short *block_ptr,uint flags) {
-
- register uint *dy = *datay;
- register uint *du = *datau;
- register uint *dv = *datav;
-
-
- /* Y Blocks */
- *dy++ = GFXBLOCK + 36;
- *dy++ = (1<<30) | (2<<28) | (0x3<<26) | (0x2<<6);
- *dy++ = ((uint)mb->x<<20) | ((uint)mb->y<<3);
- *dy++ = (8<<16) | 16;
- *dy++ = 0;
- *dy++ = 0;
- PACK_INTRA_DATA(dy,block_ptr,128);
- dy += 32;
- block_ptr += 128;
-
- /* Second Y block */
- *dy++ = GFXBLOCK + 36;
- *dy++ = (1<<30) | (2<<28) | (0x3<<26) | (0x3<<6);
- *dy++ = ((uint)mb->x<<20) | ((uint)mb->y<<3);
- *dy++ = (8<<16) | 16;
- *dy++ = 0;
- *dy++ = 0;
- PACK_INTRA_DATA(dy,block_ptr,128);
- dy += 32;
- block_ptr += 128;
- /* End Y Blocks */
-
-
- /* U Block */
- *du++ = GFXBLOCK + 20;
- *du++ = (2<<30) | (1<<28) | (1<<23);
- *du++ = (((uint)mb->x)<<19) | (((uint)mb->y)<<3);
- *du++ = (8<<16) | 8;
- *du++ = 0;
- *du++ = 0;
- PACK_INTRA_DATA(du,block_ptr,64);
- du += 16;
- block_ptr += 64;
-
- /* V Block */
- *dv++ = GFXBLOCK + 20;
- *dv++ = (3<<30) | (1<<28) | (1<<22);
- *dv++ = (((uint)mb->x)<<19) | (((uint)mb->y)<<3);
- *dv++ = (8<<16) | 8;
- *dv++ = 0;
- *dv++ = 0;
- PACK_INTRA_DATA(dv,block_ptr,64);
- dv += 16;
- block_ptr += 64;
-
- *datay = dy;
- *datau = du;
- *datav = dv;
-}
-
-
-/***************************************************************************
-// Function: renderIntrainField
-// Description: inline function that sets hardware parameters for an Intra
-// encoded macroblock in Field pictures.
-***************************************************************************/
-static __inline__ void renderIntrainField(uint **datay,uint **datau,
- uint **datav,
- XvMCMacroBlock *mb,short *block_ptr,
- uint ps) {
-
- register uint *dy = *datay;
- register uint *du = *datau;
- register uint *dv = *datav;
-
- uint xy = ((uint)mb->x<<20) | ((uint)mb->y<<4);
- uint dw1 = drps_table[~ps & 0x1];
-
- /* Y Blocks */
- *dy++ = GFXBLOCK + 68;
- *dy++ = (1<<30) | (3<<28) | (0xf<<24) | dw1;
- *dy++ = xy;
- *dy++ = (16<<16) | 16;
- *dy++ = 0;
- *dy++ = 0;
- PACK_INTRA_DATA(dy,block_ptr,256);
- dy += 64;
- block_ptr += 256;
- /* End Y Blocks */
-
- xy >>= 1;
-
- /* U Block */
- *du++ = GFXBLOCK + 20;
- *du++ = (2<<30) | (1<<28) | (1<<23) | dw1;
- *du++ = xy;
- *du++ = (8<<16) | 8;
- *du++ = 0;
- *du++ = 0;
- PACK_INTRA_DATA(du,block_ptr,64);
- du += 16;
- block_ptr += 64;
-
- /* V Block */
- *dv++ = GFXBLOCK + 20;
- *dv++ = (3<<30) | (1<<28) | (1<<22) | dw1;
- *dv++ = xy;
- *dv++ = (8<<16) | 8;
- *dv++ = 0;
- *dv++ = 0;
- PACK_INTRA_DATA(dv,block_ptr,64);
- dv += 16;
- block_ptr += 64;
-
- *datay = dy;
- *datau = du;
- *datav = dv;
-}
-
-
-/***************************************************************************
-// Function: renderFieldinField
-// Description: inline function that sets hardware parameters for a Field
-// encoded macroblock in a Field Picture.
-***************************************************************************/
-static __inline__ void renderFieldinField(uint **datay,uint **datau,
- uint **datav,
- XvMCMacroBlock *mb,short *block_ptr,
- uint ps, uint flags) {
-
- register uint *dy = *datay;
- register uint *du = *datau;
- register uint *dv = *datav;
-
- /* Motion Vectors */
- short fmv[2];
- short bmv[2];
- /* gfxblock dword 1 */
- uint dw1;
-
- uint parity = ~ps & XVMC_TOP_FIELD;
-
- uint ysize = y_frame_bytes[mb->coded_block_pattern];
- uint usize = u_frame_bytes[mb->coded_block_pattern];
- uint vsize = v_frame_bytes[mb->coded_block_pattern];
-
- uint xy = ((uint)mb->x<<20) | ((uint)mb->y<<4);
-
- /* i810 Specific flag used to identify the second field in a P frame */
- if(flags & 0x80000000) {
- /* P Frame */
- if((mb->motion_vertical_field_select & XVMC_SELECT_FIRST_FORWARD) ==
- parity) {
- /* Same parity, use reference field (map0) */
- dw1 = 1<<12 | ((0x2 + parity)<<6) | ((0x2 + parity)<<3) |
- (((uint)mb->coded_block_pattern)<<22);
- fmv[0] = mb->PMV[0][0][1];
- fmv[1] = mb->PMV[0][0][0];
- bmv[0] = 0;
- bmv[1] = 0;
- }
- else {
- /*
- Opposite parity, set up as if it were backward
- motion and use map1.
- */
- dw1 = 2<<12 | ((0x2 + parity)<<6) | (0x3 - parity) |
- (((uint)mb->coded_block_pattern)<<22);
- bmv[0] = mb->PMV[0][0][1];
- bmv[1] = mb->PMV[0][0][0];
- fmv[0] = 0;
- fmv[1] = 0;
- }
- }
- else {
- dw1 = type_table[mb->macroblock_type & 0xf] |
- drps_table[~ps & 0x1] |
- mvfs_table[mb->motion_vertical_field_select & 3] |
- (((uint)mb->coded_block_pattern)<<22);
-
- fmv[0] = mb->PMV[0][0][1];
- fmv[1] = mb->PMV[0][0][0];
-
- bmv[0] = mb->PMV[0][1][1];
- bmv[1] = mb->PMV[0][1][0];
- }
-
- /* Y Block */
- *dy++ = GFXBLOCK + 4 + (ysize>>2);
- *dy++ = (1<<30) | (3<<28) | dw1;
- *dy++ = xy;
- *dy++ = (16<<16) | 16;
- *dy++ = *(uint *)fmv;
- *dy++ = *(uint *)bmv;
- PACK_CORR_DATA(dy,block_ptr,ysize);
- block_ptr = (short *)((unsigned long)block_ptr + ysize);
- /* End Y Blocks */
-
- fmv[0] /= 2;
- fmv[1] /= 2;
- bmv[0] /= 2;
- bmv[1] /= 2;
- xy >>= 1;
-
- /* U Block */
- *du++ = GFXBLOCK + 4 + (usize>>2);
- *du++ = (2<<30) | (1<<28) | dw1;
- *du++ = xy;
- *du++ = (8<<16) | 8;
- *du++ = *(uint *)fmv;
- *du++ = *(uint *)bmv;
- PACK_CORR_DATA(du,block_ptr,usize);
- block_ptr = (short *)((unsigned long)block_ptr + usize);
-
- /* V Block */
- *dv++ = GFXBLOCK + 4 + (vsize>>2);
- *dv++ = (3<<30) | (1<<28) | dw1;
- *dv++ = xy;
- *dv++ = (8<<16) | 8;
- *dv++ = *(uint *)fmv;
- *dv++ = *(uint *)bmv;
- PACK_CORR_DATA(dv,block_ptr,vsize);
- block_ptr = (short *)((unsigned long)block_ptr + vsize);
-
- *datay = dy;
- *datau = du;
- *datav = dv;
-}
-
-/***************************************************************************
-// Function: render16x8inField
-// Description: inline function that sets hardware parameters for a 16x8
-// encoded macroblock in a field picture.
-***************************************************************************/
-static __inline__ void render16x8inField(uint **datay,uint **datau,
- uint **datav,
- XvMCMacroBlock *mb,short *block_ptr,
- uint ps, uint flags) {
-
- register uint *dy = *datay;
- register uint *du = *datau;
- register uint *dv = *datav;
-
- /* Motion Vectors */
- short fmv[4];
- short bmv[4];
- /* gfxblock dword 1 */
- uint dw1[2];
-
- uint y1size = y_first_field_bytes[mb->coded_block_pattern];
- uint y2size = y_second_field_bytes[mb->coded_block_pattern];
- uint usize = u_field_bytes[mb->coded_block_pattern];
- uint vsize = v_field_bytes[mb->coded_block_pattern];
-
- uint parity = ~ps & XVMC_TOP_FIELD;
-
- uint xy = ((uint)mb->x<<20) | ((uint)mb->y<<4);
-
- /* i810 Specific flag used to identify the second field in a P frame */
- if(flags & 0x80000000) {
- /* P Frame */
- if((mb->motion_vertical_field_select & XVMC_SELECT_FIRST_FORWARD) ==
- parity) {
- /* Same parity, use reference field (map0) */
- dw1[0] = 1<<12 | ((0x2 + parity)<<6) | ((0x2 + parity)<<3) |
- (((uint)mb->coded_block_pattern)<<22);
-
- fmv[0] = mb->PMV[0][0][1];
- fmv[1] = mb->PMV[0][0][0];
- bmv[0] = 0;
- bmv[1] = 0;
- }
- else {
- /*
- Opposite parity, set up as if it were backward
- motion and use map1.
- */
- dw1[0] = 2<<12 | ((0x2 + parity)<<6) | (0x3 - parity) |
- (((uint)mb->coded_block_pattern)<<22);
-
- bmv[0] = mb->PMV[0][0][1];
- bmv[1] = mb->PMV[0][0][0];
- fmv[0] = 0;
- fmv[1] = 0;
- }
- if((mb->motion_vertical_field_select & XVMC_SELECT_SECOND_FORWARD) ==
- (parity<<2)) {
- /* Same parity, use reference field (map0) */
- dw1[1] = 1<<12 | ((0x2 + parity)<<6) | ((0x2 + parity)<<3) |
- ((((uint)mb->coded_block_pattern<<22) & (0x3<<22)) |
- (((uint)mb->coded_block_pattern<<24) & (0x3<<26)));
-
- fmv[2] = mb->PMV[1][0][1];
- fmv[3] = mb->PMV[1][0][0];
- bmv[2] = 0;
- bmv[3] = 0;
- }
- else {
- /*
- Opposite parity, set up as if it were backward
- motion and use map1.
- */
- dw1[1] = 2<<12 | ((0x2 + parity)<<6) | (0x3 - parity) |
- ((((uint)mb->coded_block_pattern<<22) & (0x3<<22)) |
- (((uint)mb->coded_block_pattern<<24) & (0x3<<26)));
-
- bmv[2] = mb->PMV[1][0][1];
- bmv[3] = mb->PMV[1][0][0];
- fmv[2] = 0;
- fmv[3] = 0;
- }
- }
- else {
- dw1[0] = type_table[mb->macroblock_type & 0xf] |
- drps_table[~ps & 0x1] |
- mvfs_table[mb->motion_vertical_field_select & 3] |
- (((uint)mb->coded_block_pattern)<<22);
-
- dw1[1] = type_table[mb->macroblock_type & 0xf] |
- drps_table[~ps & 0x1] |
- mvfs_table[(mb->motion_vertical_field_select>>2) & 0x3] |
- ((((uint)mb->coded_block_pattern<<22) & (0x3<<22)) |
- (((uint)mb->coded_block_pattern<<24) & (0x3<<26)));
-
- fmv[0] = mb->PMV[0][0][1];
- fmv[1] = mb->PMV[0][0][0];
- fmv[2] = mb->PMV[1][0][1];
- fmv[3] = mb->PMV[1][0][0];
-
- bmv[0] = mb->PMV[0][1][1];
- bmv[1] = mb->PMV[0][1][0];
- bmv[2] = mb->PMV[1][1][1];
- bmv[3] = mb->PMV[1][1][0];
- }
-
- /* First Y Block */
- *dy++ = GFXBLOCK + 4 + (y1size>>2);
- *dy++ = (1<<30) | (2<<28) | dw1[0];
- *dy++ = xy;
- *dy++ = (8<<16) | 16;
- *dy++ = *(uint *)fmv;
- *dy++ = *(uint *)bmv;
- PACK_CORR_DATA(dy,block_ptr,y1size);
- block_ptr = (short *)((unsigned long)block_ptr + y1size);
-
- /* Second Y Block */
- *dy++ = GFXBLOCK + 4 + (y2size>>2);
- *dy++ = (1<<30) | (2<<28) | dw1[1];
- *dy++ = (xy + 8);
- *dy++ = (8<<16) | 16;
- *dy++ = *(uint *)&fmv[2];
- *dy++ = *(uint *)&bmv[2];
- PACK_CORR_DATA(dy,block_ptr,y2size);
- block_ptr = (short *)((unsigned long)block_ptr + y2size);
- /* End Y Blocks */
-
- fmv[0] /= 2;
- fmv[1] /= 2;
- fmv[2] /= 2;
- fmv[3] /= 2;
-
- bmv[0] /= 2;
- bmv[1] /= 2;
- bmv[2] /= 2;
- bmv[3] /= 2;
-
- xy >>= 1;
-
- /* U Blocks */
- *du++ = GFXBLOCK + 4 + (usize>>2);
- *du++ = (2<<30) | (1<<28) | dw1[0];
- *du++ = xy;
- *du++ = (4<<16) | 8;
- *du++ = *(uint *)fmv;
- *du++ = *(uint *)bmv;
- PACK_CORR_DATA(du,block_ptr,usize);
- block_ptr = (short *)((unsigned long)block_ptr + usize);
-
- /* Second U block */
- *du++ = GFXBLOCK + 4 + (usize>>2);
- *du++ = (2<<30) | (1<<28) | dw1[1];
- *du++ = (xy + 4);
- *du++ = (4<<16) | 8;
- *du++ = *(uint *)&fmv[2];
- *du++ = *(uint *)&bmv[2];
- PACK_CORR_DATA(du,block_ptr,usize);
- block_ptr = (short *)((unsigned long)block_ptr + usize);
- /* End U Blocks */
-
- /* V Blocks */
- *dv++ = GFXBLOCK + 4 + (vsize>>2);
- *dv++ = (3<<30) | (1<<28) | dw1[0];
- *dv++ = xy;
- *dv++ = (4<<16) | 8;
- *dv++ = *(uint *)fmv;
- *dv++ = *(uint *)bmv;
- PACK_CORR_DATA(dv,block_ptr,vsize);
- block_ptr = (short *)((unsigned long)block_ptr + vsize);
-
- /* Second V Block */
- *dv++ = GFXBLOCK + 4 + (vsize>>2);
- *dv++ = (3<<30) | (1<<28) | dw1[1];
- *dv++ = (xy + 4);
- *dv++ = (4<<16) | 8;
- *dv++ = *(uint *)&fmv[2];
- *dv++ = *(uint *)&bmv[2];
- PACK_CORR_DATA(dv,block_ptr,vsize);
- block_ptr = (short *)((unsigned long)block_ptr + vsize);
- /* End V Blocks */
-
- *datay = dy;
- *datau = du;
- *datav = dv;
-}
-
-/***************************************************************************
-// Function: renderDualPrimeinField
-// Description: inline function that sets hardware parameters for a Dual
-// prime encoded macroblock in a field picture.
-***************************************************************************/
-static __inline__ void renderDualPrimeinField(uint **datay,uint **datau,
- uint **datav,XvMCMacroBlock *mb,
- short *block_ptr,uint ps,
- uint flags) {
-
- register uint *dy = *datay;
- register uint *du = *datau;
- register uint *dv = *datav;
-
- /* Motion Vectors */
- short fmv[2];
- short bmv[2];
- /* gfxblock dword 1 */
- uint dw1;
-
-
- uint ysize = y_frame_bytes[mb->coded_block_pattern];
- uint usize = u_frame_bytes[mb->coded_block_pattern];
- uint vsize = v_frame_bytes[mb->coded_block_pattern];
-
- uint xy = ((uint)mb->x<<20) | ((uint)mb->y<<4);
-
-
- if(ps & XVMC_TOP_FIELD) {
- dw1 = (mb->coded_block_pattern<<22) | 3<<12 | 2<<6 | 2<<3 | 3;
- }
- else {
- dw1 = (mb->coded_block_pattern<<22) | 3<<12 | 3<<6 | 3<<3 | 2;
- }
- fmv[0] = mb->PMV[0][0][1];
- fmv[1] = mb->PMV[0][0][0];
- bmv[0] = mb->PMV[0][1][1];
- bmv[1] = mb->PMV[0][1][0];
-
- /* Y Block */
- *dy++ = GFXBLOCK + 4 + (ysize>>2);
- *dy++ = (1<<30) | (3<<28) | dw1;
- *dy++ = xy;
- *dy++ = (16<<16) | 16;
- *dy++ = *(uint *)fmv;
- *dy++ = *(uint *)bmv;
- PACK_CORR_DATA(dy,block_ptr,ysize);
- block_ptr = (short *)((unsigned long)block_ptr + ysize);
- /* End Y Blocks */
-
- fmv[0] /= 2;
- fmv[1] /= 2;
- bmv[0] /= 2;
- bmv[1] /= 2;
- xy >>= 1;
-
- /* U Block */
- *du++ = GFXBLOCK + 4 + (usize>>2);
- *du++ = (2<<30) | (1<<28) | dw1;
- *du++ = xy;
- *du++ = (8<<16) | 8;
- *du++ = *(uint *)fmv;
- *du++ = *(uint *)bmv;
- PACK_CORR_DATA(du,block_ptr,usize);
- block_ptr = (short *)((unsigned long)block_ptr + usize);
-
- /* V Block */
- *dv++ = GFXBLOCK + 4 + (vsize>>2);
- *dv++ = (3<<30) | (1<<28) | dw1;
- *dv++ = xy;
- *dv++ = (8<<16) | 8;
- *dv++ = *(uint *)fmv;
- *dv++ = *(uint *)bmv;
- PACK_CORR_DATA(dv,block_ptr,vsize);
- block_ptr = (short *)((unsigned long)block_ptr + vsize);
-
- *datay = dy;
- *datau = du;
- *datav = dv;
-}
-
-/***************************************************************************
-// Function: renderFieldinFrame
-// Description: inline function that sets hardware parameters for a Field
-// encoded macroblock in a frame picture.
-***************************************************************************/
-static __inline__ void renderFieldinFrame(uint **datay,uint **datau,
- uint **datav,
- XvMCMacroBlock *mb,short *block_ptr,
- uint flags) {
-
- register uint *dy = *datay;
- register uint *du = *datau;
- register uint *dv = *datav;
-
- /* Motion Vectors */
- short fmv[4];
- short bmv[4];
- /* gfxblock dword 1 */
- uint dw1[2];
-
- uint y1size = y_first_field_bytes[mb->coded_block_pattern];
- uint y2size = y_second_field_bytes[mb->coded_block_pattern];
- uint usize = u_field_bytes[mb->coded_block_pattern];
- uint vsize = v_field_bytes[mb->coded_block_pattern];
-
- uint xy = ((uint)mb->x<<20) | ((uint)mb->y<<3);
-
- dw1[0] = type_table[mb->macroblock_type & 0xf] | (0x2<<6) |
- mvfs_table[mb->motion_vertical_field_select & 3] |
- (((uint)mb->coded_block_pattern)<<22);
-
- dw1[1] = type_table[mb->macroblock_type & 0xf] | (0x3<<6) |
- mvfs_table[mb->motion_vertical_field_select>>2] |
- (((mb->coded_block_pattern & 0x3) |
- ((mb->coded_block_pattern & 0xc)<<2))<<22);
-
- fmv[0] = mb->PMV[0][0][1]/2;
- fmv[1] = mb->PMV[0][0][0];
- fmv[2] = mb->PMV[1][0][1]/2;
- fmv[3] = mb->PMV[1][0][0];
-
- bmv[0] = mb->PMV[0][1][1]/2;
- bmv[1] = mb->PMV[0][1][0];
- bmv[2] = mb->PMV[1][1][1]/2;
- bmv[3] = mb->PMV[1][1][0];
-
- /* First Y Block */
- *dy++ = GFXBLOCK + 4 + (y1size>>2);
- *dy++ = (1<<30) | (2<<28) | dw1[0];
- *dy++ = xy;
- *dy++ = (8<<16) | 16;
- *dy++ = *(uint *)&fmv[0];
- *dy++ = *(uint *)&bmv[0];
- PACK_CORR_DATA(dy,block_ptr,y1size);
- block_ptr = (short *)((unsigned long)block_ptr + y1size);
-
- /* Second Y Block */
- *dy++ = GFXBLOCK + 4 + (y2size>>2);
- *dy++ = (1<<30) | (2<<28) | dw1[1];
- *dy++ = xy;
- *dy++ = (8<<16) | 16;
- *dy++ = *(uint *)&fmv[2];
- *dy++ = *(uint *)&bmv[2];
- PACK_CORR_DATA(dy,block_ptr,y2size);
- block_ptr = (short *)((unsigned long)block_ptr + y2size);
- /* End Y Blocks */
-
- fmv[0] /= 2;
- fmv[1] /= 2;
- fmv[2] /= 2;
- fmv[3] /= 2;
-
- bmv[0] /= 2;
- bmv[1] /= 2;
- bmv[2] /= 2;
- bmv[3] /= 2;
-
- xy >>= 1;
-
- /* U Blocks */
- *du++ = GFXBLOCK + 4 + (usize>>2);
- *du++ = (2<<30) | (1<<28) | dw1[0];
- *du++ = xy;
- *du++ = (4<<16) | 8;
- *du++ = *(uint *)&fmv[0];
- *du++ = *(uint *)&bmv[0];
- if(usize) {
- PACK_CORR_DATA_SHORT(du,block_ptr);
- }
-
- /* Second U Block */
- *du++ = GFXBLOCK + 4 + (usize>>2);
- *du++ = (2<<30) | (1<<28) | dw1[1];
- *du++ = xy;
- *du++ = (4<<16) | 8;
- *du++ = *(uint *)&fmv[2];
- *du++ = *(uint *)&bmv[2];
- if(usize) {
- block_ptr = (short *)((unsigned long)block_ptr + 16);
- PACK_CORR_DATA_SHORT(du,block_ptr);
- block_ptr = (short *)((unsigned long)block_ptr + 112);
- }
- /* End U Blocks */
-
- /* V Blocks */
- *dv++ = GFXBLOCK + 4 + (vsize>>2);
- *dv++ = (3<<30) | (1<<28) | dw1[0];
- *dv++ = xy;
- *dv++ = (4<<16) | 8;
- *dv++ = *(uint *)&fmv[0];
- *dv++ = *(uint *)&bmv[0];
- if(vsize) {
- PACK_CORR_DATA_SHORT(dv,block_ptr);
- }
-
- /* Second V Block */
- *dv++ = GFXBLOCK + 4 + (vsize>>2);
- *dv++ = (3<<30) | (1<<28) | dw1[1];
- *dv++ = xy;
- *dv++ = (4<<16) | 8;
- *dv++ = *(uint *)&fmv[2];
- *dv++ = *(uint *)&bmv[2];
- if(vsize) {
- block_ptr = (short *)((unsigned long)block_ptr + 16);
- PACK_CORR_DATA_SHORT(dv,block_ptr);
- block_ptr = (short *)((unsigned long)block_ptr + 112);
- }
- /* End V Blocks */
-
- *datay = dy;
- *datau = du;
- *datav = dv;
-}
-
-/***************************************************************************
-// Function: renderFieldinFrameDCT0
-// Description: inline function that sets hardware parameters for a Field
-// encoded macroblock in a frame picture with DCT0.
-***************************************************************************/
-static __inline__ void renderFieldinFrameDCT0(uint **datay,uint **datau,
- uint **datav,XvMCMacroBlock *mb,
- short *block_ptr,uint flags) {
-
- register uint *dy = *datay;
- register uint *du = *datau;
- register uint *dv = *datav;
-
- /* Motion Vectors */
- short fmv[4];
- short bmv[4];
- /* CBP */
- uint cbp = (uint)mb->coded_block_pattern;
- /* gfxblock dword 1 */
- uint dw1[2];
-
- short * top_left_b = NULL;
- short * top_right_b = NULL;
- short * bottom_left_b = NULL;
- short * bottom_right_b = NULL;
-
- unsigned int ysize = y_dct0_field_bytes[cbp];
- unsigned int usize = u_field_bytes[cbp];
- unsigned int vsize = v_field_bytes[cbp];
-
- uint xy = ((uint)mb->x<<20) | ((uint)mb->y<<3);
-
- dw1[0] = type_table[mb->macroblock_type & 0xf] | (0x2<<6) |
- mvfs_table[mb->motion_vertical_field_select & 3] |
- ((cbp | ((cbp<<2) & 0x30))<<22);
-
- dw1[1] = type_table[mb->macroblock_type & 0xf] | (0x3<<6) |
- mvfs_table[mb->motion_vertical_field_select>>2] |
- ((cbp | ((cbp<<2) & 0x30))<<22);
-
-
- fmv[0] = mb->PMV[0][0][1]/2;
- fmv[1] = mb->PMV[0][0][0];
- fmv[2] = mb->PMV[1][0][1]/2;
- fmv[3] = mb->PMV[1][0][0];
-
- bmv[0] = mb->PMV[0][1][1]/2;
- bmv[1] = mb->PMV[0][1][0];
- bmv[2] = mb->PMV[1][1][1]/2;
- bmv[3] = mb->PMV[1][1][0];
-
- /*
- The i810 cannot use DCT0 directly with field motion, we have to
- interlace the data for it. We use a zero block when the CBP has
- one half of the to-be-interlaced data but not the other half.
- */
- top_left_b = &empty_block[0];
- if(cbp & 0x20) {
- top_left_b = block_ptr;
- block_ptr += 64;
- }
-
- top_right_b = &empty_block[0];
- if(cbp & 0x10) {
- top_right_b = block_ptr;
- block_ptr += 64;
- }
-
- bottom_left_b = &empty_block[0];
- if(cbp & 0x8) {
- bottom_left_b = block_ptr;
- block_ptr += 64;
- }
-
- bottom_right_b = &empty_block[0];
- if(cbp & 0x4) {
- bottom_right_b = block_ptr;
- block_ptr += 64;
- }
-
- /* First Y Block */
- *dy++ = GFXBLOCK + 4 + (ysize>>2);
- *dy++ = (1<<30) | (2<<28) | dw1[0];
- *dy++ = xy;
- *dy++ = (8<<16) | 16;
- *dy++ = *(uint *)&fmv[0];
- *dy++ = *(uint *)&bmv[0];
- if(dw1[0] & (1<<27)) {
- PACK_CORR_DATA_0to1(dy,top_left_b,bottom_left_b);
- }
- if(dw1[0] & (1<<26)) {
- PACK_CORR_DATA_0to1(dy,top_right_b,bottom_right_b);
- }
-
- /* Second Y Block */
- *dy++ = GFXBLOCK + 4 + (ysize>>2);
- *dy++ = (1<<30) | (2<<28) | dw1[1];
- *dy++ = xy;
- *dy++ = (8<<16) | 16;
- *dy++ = *(uint *)&fmv[2];
- *dy++ = *(uint *)&bmv[2];
- if(dw1[1] & (1<<27)) {
- top_left_b = (short *)((unsigned long)top_left_b + 16);
- bottom_left_b = (short *)((unsigned long)bottom_left_b + 16);
- PACK_CORR_DATA_0to1(dy,top_left_b,bottom_left_b);
- }
- if(dw1[1] & (1<<26)) {
- top_right_b = (short *)((unsigned long)top_right_b + 16);
- bottom_right_b = (short *)((unsigned long)bottom_right_b + 16);
- PACK_CORR_DATA_0to1(dy,top_right_b,bottom_right_b);
- }
- /* End Y Blocks */
-
- fmv[0] /= 2;
- fmv[1] /= 2;
- fmv[2] /= 2;
- fmv[3] /= 2;
-
- bmv[0] /= 2;
- bmv[1] /= 2;
- bmv[2] /= 2;
- bmv[3] /= 2;
-
- xy >>= 1;
-
- /* U Blocks */
- *du++ = GFXBLOCK + 4 + (usize>>2);
- *du++ = (2<<30) | (1<<28) | dw1[0];
- *du++ = xy;
- *du++ = (4<<16) | 8;
- *du++ = *(uint *)&fmv[0];
- *du++ = *(uint *)&bmv[0];
- if(usize) {
- PACK_CORR_DATA_SHORT(du,block_ptr);
- }
-
- /* Second U Block */
- *du++ = GFXBLOCK + 4 + (usize>>2);
- *du++ = (2<<30) | (1<<28) | dw1[1];
- *du++ = xy;
- *du++ = (4<<16) | 8;
- *du++ = *(uint *)&fmv[2];
- *du++ = *(uint *)&bmv[2];
- if(usize) {
- block_ptr = (short *)((unsigned long)block_ptr + 16);
- PACK_CORR_DATA_SHORT(du,block_ptr);
- block_ptr = (short *)((unsigned long)block_ptr + 112);
- }
- /* End U Blocks */
-
- /* V Blocks */
- *dv++ = GFXBLOCK + 4 + (vsize>>2);
- *dv++ = (3<<30) | (1<<28) | dw1[0];
- *dv++ = xy;
- *dv++ = (4<<16) | 8;
- *dv++ = *(uint *)&fmv[0];
- *dv++ = *(uint *)&bmv[0];
- if(vsize) {
- PACK_CORR_DATA_SHORT(dv,block_ptr);
- }
-
- /* Second V Block */
- *dv++ = GFXBLOCK + 4 + (vsize>>2);
- *dv++ = (3<<30) | (1<<28) | dw1[1];
- *dv++ = xy;
- *dv++ = (4<<16) | 8;
- *dv++ = *(uint *)&fmv[2];
- *dv++ = *(uint *)&bmv[2];
- if(vsize) {
- block_ptr = (short *)((unsigned long)block_ptr + 16);
- PACK_CORR_DATA_SHORT(dv,block_ptr);
- block_ptr = (short *)((unsigned long)block_ptr + 112);
- }
- /* End V Blocks */
-
- *datay = dy;
- *datau = du;
- *datav = dv;
-}
-
-/***************************************************************************
-// Function: renderFrameinFrame
-// Description: inline function that sets hardware parameters for a Frame
-// encoded macroblock in a frame picture.
-***************************************************************************/
-static __inline__ void renderFrameinFrame(uint **datay,uint **datau,
- uint **datav,
- XvMCMacroBlock *mb,short *block_ptr,
- uint flags) {
-
- register uint *dy = *datay;
- register uint *du = *datau;
- register uint *dv = *datav;
-
- /* Motion Vectors */
- short fmv[2];
- short bmv[2];
- /* gfxblock dword 1 */
- uint dw1;
-
- unsigned int ysize = y_frame_bytes[mb->coded_block_pattern];
- unsigned int usize = u_frame_bytes[mb->coded_block_pattern];
- unsigned int vsize = v_frame_bytes[mb->coded_block_pattern];
-
- uint xy = ((uint)mb->x<<20) | ((uint)mb->y<<4);
-
- dw1 = type_table[mb->macroblock_type & 0xf] |
- (((uint)mb->coded_block_pattern)<<22);
-
-
- fmv[0] = mb->PMV[0][0][1];
- fmv[1] = mb->PMV[0][0][0];
-
- bmv[0] = mb->PMV[0][1][1];
- bmv[1] = mb->PMV[0][1][0];
-
- /* Y Block */
- *dy++ = GFXBLOCK + 4 + (ysize>>2);
- *dy++ = (1<<30) | (3<<28) | dw1;
- *dy++ = xy;
- *dy++ = (16<<16) | 16;
- *dy++ = *(uint *)fmv;
- *dy++ = *(uint *)bmv;
- PACK_CORR_DATA(dy,block_ptr,ysize);
- block_ptr = (short *)((unsigned long)block_ptr + ysize);
- /* End Y Blocks */
-
- fmv[0] /= 2;
- fmv[1] /= 2;
-
- bmv[0] /= 2;
- bmv[1] /= 2;
-
- xy >>= 1;
-
- /* U Block */
- *du++ = GFXBLOCK + 4 + (usize>>2);
- *du++ = (2<<30) | (1<<28) | dw1;
- *du++ = xy;
- *du++ = (8<<16) | 8;
- *du++ = *(uint *)fmv;
- *du++ = *(uint *)bmv;
- PACK_CORR_DATA(du,block_ptr,usize);
- block_ptr = (short *)((unsigned long)block_ptr + usize);
- /* End U Block */
-
- /* V Block */
- *dv++ = GFXBLOCK + 4 + (vsize>>2);
- *dv++ = (3<<30) | (1<<28) | dw1;
- *dv++ = xy;
- *dv++ = (8<<16) | 8;
- *dv++ = *(uint *)fmv;
- *dv++ = *(uint *)bmv;
- PACK_CORR_DATA(dv,block_ptr,vsize);
- block_ptr = (short *)((unsigned long)block_ptr + vsize);
- /* End V Block */
-
- *datay = dy;
- *datau = du;
- *datav = dv;
-}
-
-/***************************************************************************
-// Function: renderFrameinFrameDCT1
-// Description: inline function that sets hardware parameters for a Frame
-// encoded macroblock in a frame picture with DCT type 1.
-***************************************************************************/
-static __inline__ void renderFrameinFrameDCT1(uint **datay,uint **datau,
- uint **datav,XvMCMacroBlock *mb,
- short *block_ptr,uint flags) {
-
- register uint *dy = *datay;
- register uint *du = *datau;
- register uint *dv = *datav;
-
- /* Motion Vectors */
- short fmv[4];
- short bmv[4];
-
- short * top_left_b = NULL;
- short * top_right_b = NULL;
- short * bottom_left_b = NULL;
- short * bottom_right_b = NULL;
-
- uint temp_bp = 0;
-
- uint ysize = y_dct1_frame_bytes[mb->coded_block_pattern];
- uint usize = u_frame_bytes[mb->coded_block_pattern];
- uint vsize = v_frame_bytes[mb->coded_block_pattern];
-
- uint xy = ((uint)mb->x<<20) | ((uint)mb->y<<4);
-
- uint dw1 = type_table[mb->macroblock_type & 0xf] |
- (((uint)mb->coded_block_pattern)<<22);
-
- fmv[0] = mb->PMV[0][0][1];
- fmv[1] = mb->PMV[0][0][0];
-
- bmv[0] = mb->PMV[0][1][1];
- bmv[1] = mb->PMV[0][1][0];
-
- /*
- It is easiest to find out what blocks are in need of reading first
- rather than as we go.
- */
- top_left_b = &empty_block[0];
- if(dw1 & (1<<27)) {
- temp_bp |= (1<<25);
- top_left_b = block_ptr;
- block_ptr += 64;
- }
-
- top_right_b = &empty_block[0];
- if(dw1 & (1<<26)) {
- temp_bp |= (1<<24);
- top_right_b = block_ptr;
- block_ptr += 64;
- }
-
- bottom_left_b = &empty_block[0];
- if(dw1 & (1<<25)) {
- temp_bp |= (1<<27);
- bottom_left_b = block_ptr;
- block_ptr += 64;
- }
-
- bottom_right_b = &empty_block[0];
- if(dw1 & (1<<24)) {
- temp_bp |= (1<<26);
- bottom_right_b = block_ptr;
- block_ptr += 64;
- }
- dw1 |= temp_bp;
-
- /* Y Block */
- *dy++ = GFXBLOCK + 4 + (ysize>>2);
- *dy++ = (1<<30) | (3<<28) | dw1;
- *dy++ = xy;
- *dy++ = (16<<16) | 16;
- *dy++ = *(uint *)fmv;
- *dy++ = *(uint *)bmv;
- if(dw1 & (1<<27)) {
- PACK_CORR_DATA_1to0(dy,top_left_b,bottom_left_b);
- top_left_b = (short *)((unsigned long)top_left_b + 64);
- bottom_left_b = (short *)((unsigned long)bottom_left_b + 64);
- }
- if(dw1 & (1<<26)) {
- PACK_CORR_DATA_1to0(dy,top_right_b,bottom_right_b);
- top_right_b = (short *)((unsigned long)top_right_b + 64);
- bottom_right_b = (short *)((unsigned long)bottom_right_b + 64);
- }
- if(dw1 & (1<<27)) {
- PACK_CORR_DATA_1to0(dy,top_left_b,bottom_left_b);
- }
- if(dw1 & (1<<26)) {
- PACK_CORR_DATA_1to0(dy,top_right_b,bottom_right_b);
- }
- /* End Y Block */
-
- fmv[0] /= 2;
- fmv[1] /= 2;
-
- bmv[0] /= 2;
- bmv[1] /= 2;
-
- xy >>= 1;
-
- /* U Block */
- *du++ = GFXBLOCK + 4 + (usize>>2);
- *du++ = (2<<30) | (1<<28) | dw1;
- *du++ = xy;
- *du++ = (8<<16) | 8;
- *du++ = *(uint *)fmv;
- *du++ = *(uint *)bmv;
- PACK_CORR_DATA(du,block_ptr,usize);
- block_ptr = (short *)((unsigned long)block_ptr + usize);
-
- /* V Block */
- *dv++ = GFXBLOCK + 4 + (vsize>>2);
- *dv++ = (3<<30) | (1<<28) | dw1;
- *dv++ = xy;
- *dv++ = (8<<16) | 8;
- *dv++ = *(uint *)fmv;
- *dv++ = *(uint *)bmv;
- PACK_CORR_DATA(dv,block_ptr,vsize);
- block_ptr = (short *)((unsigned long)block_ptr + vsize);
-
- *datay = dy;
- *datau = du;
- *datav = dv;
-}
-
-/***************************************************************************
-// Function: renderDualPrimeinFrame
-// Description: inline function that sets hardware parameters for a Dual
-// Prime encoded macroblock in a frame picture with dct 1.
-***************************************************************************/
-static __inline__ void renderDualPrimeinFrame(uint **datay,uint **datau,
- uint **datav,XvMCMacroBlock *mb,
- short *block_ptr,uint flags) {
-
- register uint *dy = *datay;
- register uint *du = *datau;
- register uint *dv = *datav;
-
- /* Motion Vectors */
- short fmv[4];
- short bmv[4];
- /* gfxblock dword 1 */
- uint dw1[2];
-
- uint y1size = y_first_field_bytes[mb->coded_block_pattern];
- uint y2size = y_second_field_bytes[mb->coded_block_pattern];
- uint usize = u_field_bytes[mb->coded_block_pattern];
- uint vsize = v_field_bytes[mb->coded_block_pattern];
-
- uint xy = ((uint)mb->x<<20) | ((uint)mb->y<<3);
-
- /*
- Past Surface (map 0) is used for same parity prediction,
- Future surface (map 1) is used for opposite.
- */
- dw1[0] = (((uint)mb->coded_block_pattern)<<22) |
- 3<<12 | 2<<6 | 2<<3 | 3;
- dw1[1] = (((mb->coded_block_pattern & 0x3) |
- ((mb->coded_block_pattern & 0xc)<<2))<<22) |
- 3<<12 | 3<<6 | 3<<3 | 2;
-
- fmv[0] = mb->PMV[0][0][1];
- fmv[1] = mb->PMV[0][0][0];
- bmv[0] = mb->PMV[1][0][1];
- bmv[1] = mb->PMV[1][0][0];
-
- fmv[2] = mb->PMV[0][0][1];
- fmv[3] = mb->PMV[0][0][0];
- bmv[2] = mb->PMV[1][1][1];
- bmv[3] = mb->PMV[1][1][0];
-
- /* First Y Block */
- *dy++ = GFXBLOCK + 4 + (y1size>>2);
- *dy++ = (1<<30) | (2<<28) | dw1[0];
- *dy++ = xy;
- *dy++ = (8<<16) | 16;
- *dy++ = *(uint *)fmv;
- *dy++ = *(uint *)bmv;;
- PACK_CORR_DATA(dy,block_ptr,y1size);
- block_ptr = (short *)((unsigned long)block_ptr + y1size);
-
- /* Second Y Block */
- *dy++ = GFXBLOCK + 4 + (y2size>>2);
- *dy++ = (1<<30) | (2<<28) | dw1[1];
- *dy++ = xy;
- *dy++ = (8<<16) | 16;
- *dy++ = *(uint *)&fmv[2];
- *dy++ = *(uint *)&bmv[2];
- PACK_CORR_DATA(dy,block_ptr,y2size);
- block_ptr = (short *)((unsigned long)block_ptr + y2size);
-
- fmv[0] /= 2;
- fmv[1] /= 2;
- bmv[0] /= 2;
- bmv[1] /= 2;
-
- fmv[2] /= 2;
- fmv[3] /= 2;
- bmv[2] /= 2;
- bmv[3] /= 2;
-
- xy >>= 1;
-
- /* U Blocks */
- *du++ = GFXBLOCK + 4 + (usize>>2);
- *du++ = (2<<30) | (1<<28) | dw1[0];
- *du++ = xy;
- *du++ = (4<<16) | 8;
- *du++ = *(uint *)fmv;
- *du++ = *(uint *)bmv;
- if(dw1[0] & (1<<23)) {
- PACK_CORR_DATA_SHORT(du,block_ptr);
- }
-
- /* Second U Block */
- *du++ = GFXBLOCK + 4 + (usize>>2);
- *du++ = (2<<30) | (1<<28) | dw1[1];
- *du++ = xy;
- *du++ = (4<<16) | 8;
- *du++ = *(uint *)&fmv[2];
- *du++ = *(uint *)&bmv[2];
- if(dw1[1] & (1<<23)) {
- block_ptr = (short *)((unsigned long)block_ptr + 16);
- PACK_CORR_DATA_SHORT(du,block_ptr);
- block_ptr = (short *)((unsigned long)block_ptr + 112);
- }
- /* End U Blocks */
-
- /* V Blocks */
- *dv++ = GFXBLOCK + 4 + (vsize>>2);
- *dv++ = (3<<30) | (1<<28) | dw1[0];
- *dv++ = xy;
- *dv++ = (4<<16) | 8;
- *dv++ = *(uint *)fmv;
- *dv++ = *(uint *)bmv;
- if(dw1[0] & (1<<22)) {
- PACK_CORR_DATA_SHORT(dv,block_ptr);
- }
-
- /* Second V Block */
- *dv++ = GFXBLOCK + 4 + (vsize>>2);
- *dv++ = (3<<30) | (1<<28) | dw1[1];
- *dv++ = xy;
- *dv++ = (4<<16) | 8;
- *dv++ = *(uint *)&fmv[2];
- *dv++ = *(uint *)&bmv[2];
- if(dw1[1] & (1<<22)) {
- block_ptr = (short *)((unsigned long)block_ptr + 16);
- PACK_CORR_DATA_SHORT(dv,block_ptr);
- block_ptr = (short *)((unsigned long)block_ptr + 112);
- }
- /* End V Blocks */
-
- *datay = dy;
- *datau = du;
- *datav = dv;
-}
-
-/***************************************************************************
-// Function: renderDualPrimeinFrameDCT0
-// Description: inline function that sets hardware parameters for a Dual
-// Prime encoded macroblock in a frame picture with dct 0.
-***************************************************************************/
-static __inline__ void renderDualPrimeinFrameDCT0(uint **datay,uint **datau,
- uint **datav,
- XvMCMacroBlock *mb,
- short *block_ptr,
- uint flags) {
-
- register uint *dy = *datay;
- register uint *du = *datau;
- register uint *dv = *datav;
-
- /* Motion Vectors */
- short fmv[4];
- short bmv[4];
- /* gfxblock dword 1 */
- uint dw1[2];
-
- short * top_left_b = NULL;
- short * top_right_b = NULL;
- short * bottom_left_b = NULL;
- short * bottom_right_b = NULL;
-
- uint cbp = (uint)mb->coded_block_pattern;
-
- uint ysize = y_dct0_field_bytes[cbp];
- uint usize = u_field_bytes[cbp];
- uint vsize = v_field_bytes[cbp];
-
- uint xy = ((uint)mb->x<<20) | ((uint)mb->y<<3);
-
- /*
- Past Surface (map 0) is used for same parity prediction,
- Future surface (map 1) is used for opposite.
- */
- dw1[0] = ((cbp | ((cbp<<2) & 0x30))<<22) |
- 3<<12 | 2<<6 | 2<<3 | 3;
- dw1[1] = ((cbp | ((cbp<<2) & 0x30))<<22) |
- 3<<12 | 3<<6 | 3<<3 | 2;
-
- fmv[0] = mb->PMV[0][0][1];
- fmv[1] = mb->PMV[0][0][0];
- bmv[0] = mb->PMV[1][0][1];
- bmv[1] = mb->PMV[1][0][0];
-
- fmv[2] = mb->PMV[0][0][1];
- fmv[3] = mb->PMV[0][0][0];
- bmv[2] = mb->PMV[1][1][1];
- bmv[3] = mb->PMV[1][1][0];
-
- /*
- The i810 cannot use DCT0 directly with field motion, we have to
- interlace the data for it. We use a zero block when the CBP has
- one half of the to-be-interlaced data but not the other half.
- */
- top_left_b = &empty_block[0];
- if(cbp & 0x20) {
- top_left_b = block_ptr;
- block_ptr += 64;
- }
-
- top_right_b = &empty_block[0];
- if(cbp & 0x10) {
- top_right_b = block_ptr;
- block_ptr += 64;
- }
-
- bottom_left_b = &empty_block[0];
- if(cbp & 0x8) {
- bottom_left_b = block_ptr;
- block_ptr += 64;
- }
-
- bottom_right_b = &empty_block[0];
- if(cbp & 0x4) {
- bottom_right_b = block_ptr;
- block_ptr += 64;
- }
-
- /* First Y Block */
- *dy++ = GFXBLOCK + 4 + (ysize>>2);
- *dy++ = (1<<30) | (2<<28) | dw1[0];
- *dy++ = xy;
- *dy++ = (8<<16) | 16;
- *dy++ = *(uint *)fmv;
- *dy++ = *(uint *)bmv;
- if(cbp & 0x20) {
- PACK_CORR_DATA_0to1(dy,top_left_b,bottom_left_b);
- }
- if(cbp & 0x10) {
- PACK_CORR_DATA_0to1(dy,top_right_b,bottom_right_b);
- }
-
- /* Second Y Block */
- *dy++ = GFXBLOCK + 4 + (ysize>>2);
- *dy++ = (1<<30) | (2<<28) | dw1[1];
- *dy++ = xy;
- *dy++ = (8<<16) | 16;
- *dy++ = *(uint *)&fmv[2];
- *dy++ = *(uint *)&bmv[2];
- if(cbp & 0x20) {
- top_left_b = (short *)((unsigned long)top_left_b + 16);
- bottom_left_b = (short *)((unsigned long)bottom_left_b + 16);
- PACK_CORR_DATA_0to1(dy,top_left_b,bottom_left_b);
- }
- if(cbp & 0x10) {
- top_right_b = (short *)((unsigned long)top_right_b + 16);
- bottom_right_b = (short *)((unsigned long)bottom_right_b + 16);
- PACK_CORR_DATA_0to1(dy,top_right_b,bottom_right_b);
- }
- /* End Y Blocks */
-
-
- fmv[0] /= 2;
- fmv[1] /= 2;
- bmv[0] /= 2;
- bmv[1] /= 2;
-
- fmv[2] /= 2;
- fmv[3] /= 2;
- bmv[2] /= 2;
- bmv[3] /= 2;
-
- xy >>= 1;
-
- /* U Blocks */
- *du++ = GFXBLOCK + 4 + (usize>>2);
- *du++ = (2<<30) | (1<<28) | dw1[0];
- *du++ = xy;
- *du++ = (4<<16) | 8;
- *du++ = *(uint *)fmv;
- *du++ = *(uint *)bmv;
- if(cbp & (1<<23)) {
- PACK_CORR_DATA_SHORT(du,block_ptr);
- }
-
- /* Second U Block */
- *du++ = GFXBLOCK + 4 + (usize>>2);
- *du++ = (2<<30) | (1<<28) | dw1[1];
- *du++ = xy;
- *du++ = (4<<16) | 8;
- *du++ = *(uint *)&fmv[2];
- *du++ = *(uint *)&bmv[2];
- if(cbp & (1<<23)) {
- block_ptr = (short *)((unsigned long)block_ptr + 16);
- PACK_CORR_DATA_SHORT(du,block_ptr);
- block_ptr = (short *)((unsigned long)block_ptr + 112);
- }
- /* End U Blocks */
-
- /* V Blocks */
- *dv++ = GFXBLOCK + 4 + (vsize>>2);
- *dv++ = (3<<30) | (1<<28) | dw1[0];
- *dv++ = xy;
- *dv++ = (4<<16) | 8;
- *dv++ = *(uint *)fmv;
- *dv++ = *(uint *)bmv;
- if(cbp & (1<<22)) {
- PACK_CORR_DATA_SHORT(dv,block_ptr);
- }
-
- /* Second V Block */
- *dv++ = GFXBLOCK + 4 + (vsize>>2);
- *dv++ = (3<<30) | (1<<28) | dw1[1];
- *dv++ = xy;
- *dv++ = (4<<16) | 8;
- *dv++ = *(uint *)&fmv[2];
- *dv++ = *(uint *)&bmv[2];
- if(cbp & (1<<22)) {
- block_ptr = (short *)((unsigned long)block_ptr + 16);
- PACK_CORR_DATA_SHORT(dv,block_ptr);
- block_ptr = (short *)((unsigned long)block_ptr + 112);
- }
- /* End V Blocks */
-
- *datay = dy;
- *datau = du;
- *datav = dv;
-}
-
-
-/***************************************************************************
-// Function: XvMCRenderSurface
-// Description: This function does the actual HWMC. Given a list of
-// macroblock structures it dispatched the hardware commands to execute
-// them. DMA buffer containing Y data are dispatched as they fill up
-// U and V DMA buffers are queued until all Y's are done. This minimizes
-// the context flipping and flushing required when switching between Y
-// U and V surfaces.
-***************************************************************************/
-#define UV_QUEUE 14
-Status XvMCRenderSurface(Display *display, XvMCContext *context,
- unsigned int picture_structure,
- XvMCSurface *target_surface,
- XvMCSurface *past_surface,
- XvMCSurface *future_surface,
- unsigned int flags,
- unsigned int num_macroblocks,
- unsigned int first_macroblock,
- XvMCMacroBlockArray *macroblock_array,
- XvMCBlockArray *blocks) {
- /* Dma Data Structures */
- drmBufPtr pDMAy = NULL,pDMAu[UV_QUEUE],pDMAv[UV_QUEUE];
- int u_index = 0,v_index = 0;
- int dirty_context = 1;
-
- /* Block Pointer */
- short *block_ptr;
- /* Current Macroblock Pointer */
- XvMCMacroBlock *mb;
-
- drm_i810_mc_t mc;
- int i,j;
- i810XvMCSurface *privTarget;
- i810XvMCSurface *privFuture = NULL;
- i810XvMCSurface *privPast = NULL;
- i810XvMCContext *pI810XvMC;
-
- /* DMA Pointers set to NULL */
- uint *datay = NULL;
- uint *datau = NULL;
- uint *datav = NULL;
-
-
- /* Check Parameters for validity */
- if((target_surface == NULL) || (context == NULL) || (display == NULL)) {
- printf("Error, Invalid Target,Context, or DIsplay!\n");
- return BadValue;
- }
-
- if(num_macroblocks == 0) {return Success;}
- if((macroblock_array == NULL) || (blocks == NULL)) {return BadValue;}
- if(context->privData == NULL) {return BadValue;}
- pI810XvMC = (i810XvMCContext *)context->privData;
-
-
- if(target_surface->privData == NULL) {
- printf("Error, Invalid Target Surface!\n");
- return BadValue;
- }
- privTarget = (i810XvMCSurface *)target_surface->privData;
-
- if(macroblock_array->num_blocks < (num_macroblocks + first_macroblock)) {
- printf("Error, Too many macroblocks requested for MB array size.\n");
- return BadValue;
- }
-
- /* Test For YV12 Surface */
- if(context->surface_type_id != FOURCC_YV12) {
- printf("Error, HWMC only possible on YV12 Surfaces\n");
- return BadValue;
- }
-
- /* P Frame Test */
- if(past_surface == NULL) {
- /* Just to avoid some ifs later. */
- privPast = privTarget;
- }
- else {
- if(past_surface->privData == NULL) {
- printf("Error, Invalid Past Surface!\n");
- return BadValue;
- }
- privPast = (i810XvMCSurface *)past_surface->privData;
- }
-
-
- /* B Frame Test */
- if(future_surface == NULL) {
- privFuture = privTarget;
- if(pI810XvMC->dual_prime) {
- privFuture = privPast;
- /* I810 Specific flag for marking when dual prime is in use. */
- flags |= 0x40000000;
- }
-
- /*
- References are different for the Second Field Picture. The
- i810 needs to know if it is the second field picture in a
- P picture. We use a Private flag to mark this.
- */
- if(flags & XVMC_SECOND_FIELD) {
- /* I810 Specific flag for marking second fields. */
- flags |= 0x80000000;
- }
- }
- else {
- if((future_surface->privData == NULL) || (past_surface == NULL)) {
- printf("Error, Invalid Future Surface or No Past Surface!\n");
- return BadValue;
- }
- privFuture = (i810XvMCSurface *)future_surface->privData;
-
- /*
- Undo Second Field flag since the second field in B frames is just like
- the first.
- */
- flags &= ~0x80000000;
- }
-
- /* Lock For DMA */
- I810_LOCK(pI810XvMC,0);
-
- for(i=first_macroblock; i<(num_macroblocks + first_macroblock); i++) {
- /* Set up values needed for each macroblock */
- mb = &macroblock_array->macro_blocks[i];
- block_ptr = &(blocks->blocks[mb->index<<6]);
-
- /* Lockup can happen if the coordinates are too far out of range */
- if(mb->x > target_surface->width>>4) {
- mb->x = 0;
- }
- if(mb->y > target_surface->height>>4) {
- mb->y = 0;
- }
-
- /* If buffers are almost full dispatch them */
- if(datay) {
- pDMAy->used = (unsigned long)datay - (unsigned long)pDMAy->address;
- if(pDMAy->used > 3520) {
- if(dirty_context) {
- dispatchYContext(privTarget,privPast,privFuture,pI810XvMC);
- }
- dirty_context = 0;
- mc.idx = pDMAy->idx;
- mc.used = pDMAy->used;
- datay = NULL;
- mc.last_render = ++pI810XvMC->last_render;
- privTarget->last_render = pI810XvMC->last_render;
- I810_MC(pI810XvMC,mc);
- } /* datay near full */
- } /* if(datay) */
- if(datau) {
- pDMAu[u_index]->used = (unsigned long)datau - (unsigned long)pDMAu[u_index]->address;
- if(pDMAu[u_index]->used > 3904) {
- u_index++;
- datau = NULL;
- if(u_index == UV_QUEUE) {
- for(j=0; j<UV_QUEUE; j++) {
- mc.idx = pDMAu[j]->idx;
- mc.used = pDMAu[j]->used;
- mc.last_render = ++pI810XvMC->last_render;
- privTarget->last_render = pI810XvMC->last_render;
- I810_MC(pI810XvMC,mc);
- }
- u_index = 0;
- dirty_context = 1;
- } /* if(u_index == UV_QUEUE) */
- } /* datau near full */
- } /* if(datau) */
- if(datav) {
- pDMAv[v_index]->used = (unsigned long)datav - (unsigned long)pDMAv[v_index]->address;
- if(pDMAv[v_index]->used > 3904) {
- v_index++;
- datav = NULL;
- if(v_index == UV_QUEUE) {
- for(j=0; j<UV_QUEUE; j++) {
- mc.idx = pDMAv[j]->idx;
- mc.used = pDMAv[j]->used;
- mc.last_render = ++pI810XvMC->last_render;
- privTarget->last_render = pI810XvMC->last_render;
- I810_MC(pI810XvMC,mc);
- }
- v_index = 0;
- dirty_context = 1;
- } /* if(v_index == UV_QUEUE) */
- } /* datav near full */
- } /* if(datav) */
-
- /* Allocate buffers if this is the first loop,or if we just dispatched */
- if(datay == NULL) {
- pDMAy = i810_get_free_buffer(pI810XvMC);
- datay = pDMAy->address;
- }/* if(datay == NULL) */
- if(datau == NULL) {
- pDMAu[u_index] = i810_get_free_buffer(pI810XvMC);
- datau = pDMAu[u_index]->address;
- if(u_index == 0) {
- *datau++ = CMD_FLUSH;
- *datau++ = BOOLEAN_ENA_2;
- *datau++ = CMD_FLUSH;
- *datau++ = DEST_BUFFER_INFO;
- *datau++ = privTarget->dbi1u;
- *datau++ = DEST_BUFFER_VAR;
- *datau++ = privTarget->dbv1;
- /* Past Surface */
- *datau++ = CMD_MAP_INFO;
- *datau++ = privPast->mi1u;
- *datau++ = privPast->mi2u;
- *datau++ = privPast->mi3u;
- /* Future Surface */
- *datau++ = CMD_MAP_INFO;
- *datau++ = privFuture->mi1u | 0x1<<28;
- *datau++ = privFuture->mi2u;
- *datau++ = privFuture->mi3u;
- }
- } /* if(datau == NULL) */
- if(datav == NULL) {
- pDMAv[v_index] = i810_get_free_buffer(pI810XvMC);
- datav = pDMAv[v_index]->address;
- if(v_index == 0) {
- *datav++ = CMD_FLUSH;
- *datav++ = BOOLEAN_ENA_2;
- *datav++ = CMD_FLUSH;
- *datav++ = DEST_BUFFER_INFO;
- *datav++ = privTarget->dbi1v;
- *datav++ = DEST_BUFFER_VAR;
- *datav++ = privTarget->dbv1;
- /* Past Surface */
- *datav++ = CMD_MAP_INFO;
- *datav++ = privPast->mi1v;
- *datav++ = privPast->mi2v;
- *datav++ = privPast->mi3v;
- /* Future Surface */
- *datav++ = CMD_MAP_INFO;
- *datav++ = privFuture->mi1v | 0x1<<28;
- *datav++ = privFuture->mi2v;
- *datav++ = privFuture->mi3v;
- }
- }/* if(datav == NULL) */
-
- /* Catch no pattern case */
- if(!(mb->macroblock_type & 0x8)) {
- mb->coded_block_pattern = 0;
- }
-
-
- if(mb->motion_type == XVMC_PREDICTION_DUAL_PRIME) {
- /*
- By default the maps will not be set up for dual
- prime. We have to change them.
- */
- if(!pI810XvMC->dual_prime) {
- pI810XvMC->dual_prime = 1;
- privFuture = privPast;
- /* Y */
- *datay++ = CMD_MAP_INFO;
- *datay++ = privFuture->mi1y | 0x1<<28;
- *datay++ = privFuture->mi2y;
- *datay++ = privFuture->mi3y;
- /* U */
- *datau++ = CMD_MAP_INFO;
- *datau++ = privFuture->mi1u | 0x1<<28;
- *datau++ = privFuture->mi2u;
- *datau++ = privFuture->mi3u;
- /* V */
- *datav++ = CMD_MAP_INFO;
- *datav++ = privFuture->mi1v | 0x1<<28;
- *datav++ = privFuture->mi2v;
- *datav++ = privFuture->mi3v;
- }
- }
- if((pI810XvMC->dual_prime) &&
- (mb->motion_type != XVMC_PREDICTION_DUAL_PRIME)) {
- pI810XvMC->dual_prime = 0;
- privFuture = privTarget;
- /* Y */
- *datay++ = CMD_MAP_INFO;
- *datay++ = privFuture->mi1y | 0x1<<28;
- *datay++ = privFuture->mi2y;
- *datay++ = privFuture->mi3y;
- /* U */
- *datau++ = CMD_MAP_INFO;
- *datau++ = privFuture->mi1u | 0x1<<28;
- *datau++ = privFuture->mi2u;
- *datau++ = privFuture->mi3u;
- /* V */
- *datav++ = CMD_MAP_INFO;
- *datav++ = privFuture->mi1v | 0x1<<28;
- *datav++ = privFuture->mi2v;
- *datav++ = privFuture->mi3v;
- }
-
-
- /* Frame Picture */
- if((picture_structure & XVMC_FRAME_PICTURE) == XVMC_FRAME_PICTURE) {
- /* Intra Blocks */
- if(mb->macroblock_type & XVMC_MB_TYPE_INTRA) {
- if(mb->dct_type) {
- renderIntrainFrameDCT1(&datay,&datau,&datav,mb,block_ptr,flags);
- continue;
- }
- renderIntrainFrame(&datay,&datau,&datav,mb,block_ptr);
- continue;
- }
- switch((mb->motion_type & 0x3) | (mb->dct_type<<2)) {
- case 0x2: /* Frame DCT0 */
- renderFrameinFrame(&datay,&datau,&datav,mb,block_ptr,flags);
- continue;
- case 0x5: /* Field DCT1 */
- renderFieldinFrame(&datay,&datau,&datav,mb,block_ptr,flags);
- continue;
- case 0x6: /* Frame DCT1 */
- renderFrameinFrameDCT1(&datay,&datau,&datav,mb,block_ptr,flags);
- continue;
- case 0x1: /* Field DCT0 */
- renderFieldinFrameDCT0(&datay,&datau,&datav,mb,block_ptr,flags);
- continue;
- case 0x3: /* Dual Prime DCT0 */
- renderDualPrimeinFrame(&datay,&datau,&datav,mb,block_ptr,flags);
- continue;
- case 0x7: /* Dual Prime DCT1 */
- renderDualPrimeinFrameDCT0(&datay,&datau,&datav,mb,block_ptr,flags);
- continue;
- default: /* No Motion Type */
- renderError();
- continue;
- } /* Switch */
- } /* Frame Picture */
-
- /* Field Pictures */
- if(mb->macroblock_type & XVMC_MB_TYPE_INTRA) {
- renderIntrainField(&datay,&datau,&datav,mb,block_ptr,picture_structure);
- continue;
- }
- switch(mb->motion_type & 0x3) {
- case 0x1: /* Field Motion */
- renderFieldinField(&datay,&datau,&datav,mb,block_ptr,picture_structure,
- flags);
- continue;
- case 0x2: /* 16x8 Motion */
- render16x8inField(&datay,&datau,&datav,mb,block_ptr,picture_structure,
- flags);
- continue;
- case 0x3: /* Dual Prime */
- renderDualPrimeinField(&datay,&datau,&datav,mb,block_ptr,
- picture_structure,flags);
- continue;
- default: /* No Motion Type */
- renderError();
- continue;
- }
- continue;
-
- } /* for each Macroblock */
-
- /* Dispatch remaining DMA buffers */
- if(dirty_context) {
- dispatchYContext(privTarget,privPast,privFuture,pI810XvMC);
- }
- mc.idx = pDMAy->idx;
- mc.used = (unsigned long)datay - (unsigned long)pDMAy->address;
- mc.last_render = ++pI810XvMC->last_render;
- privTarget->last_render = pI810XvMC->last_render;
- I810_MC(pI810XvMC,mc);
-
- pDMAu[u_index]->used = (unsigned long)datau - (unsigned long)pDMAu[u_index]->address;
- for(j=0; j<=u_index; j++) {
- mc.idx = pDMAu[j]->idx;
- mc.used = pDMAu[j]->used;
- mc.last_render = ++pI810XvMC->last_render;
- privTarget->last_render = pI810XvMC->last_render;
- I810_MC(pI810XvMC,mc);
- }
- pDMAv[v_index]->used = (unsigned long)datav - (unsigned long)pDMAv[v_index]->address;
- for(j=0; j<=v_index; j++) {
- mc.idx = pDMAv[j]->idx;
- mc.used = pDMAv[j]->used;
- mc.last_render = ++pI810XvMC->last_render;
- privTarget->last_render = pI810XvMC->last_render;
- I810_MC(pI810XvMC,mc);
- }
-
- I810_UNLOCK(pI810XvMC);
-
- return Success;
-}
-
-/***************************************************************************
-// Function: XvMCPutSurface
-// Description:
-// Arguments:
-// display: Connection to X server
-// surface: Surface to be displayed
-// draw: X Drawable on which to display the surface
-// srcx: X coordinate of the top left corner of the region to be
-// displayed within the surface.
-// srcy: Y coordinate of the top left corner of the region to be
-// displayed within the surface.
-// srcw: Width of the region to be displayed.
-// srch: Height of the region to be displayed.
-// destx: X cordinate of the top left corner of the destination region
-// in the drawable coordinates.
-// desty: Y cordinate of the top left corner of the destination region
-// in the drawable coordinates.
-// destw: Width of the destination region.
-// desth: Height of the destination region.
-// flags: One or more of the following.
-// XVMC_TOP_FIELD - Display only the Top field of the surface.
-// XVMC_BOTTOM_FIELD - Display only the Bottom Field of the surface.
-// XVMC_FRAME_PICTURE - Display both fields or frame.
-//
-// Info: Portions of this function derived from i810_video.c (XFree86)
-//
-// This function is organized so that we wait as long as possible before
-// touching the overlay registers. Since we don't know that the last
-// flip has happened yet we want to give the overlay as long as
-// possible to catch up before we have to check on its progress. This
-// makes it unlikely that we have to wait on the last flip.
-***************************************************************************/
-Status XvMCPutSurface(Display *display,XvMCSurface *surface,
- Drawable draw, short srcx, short srcy,
- unsigned short srcw, unsigned short srch,
- short destx, short desty,
- unsigned short destw, unsigned short desth,
- int flags) {
- i810XvMCContext *pI810XvMC;
- i810XvMCSurface *pI810Surface;
- i810OverlayRecPtr pORegs;
- unsigned int ysrc_offset,uvsrc_offset;
- Box extents;
- uint window_width,window_height;
- unsigned int xscaleInt = 0,xscaleFract = 0,yscaleInt = 0,yscaleFract = 0;
- unsigned int xscaleFractUV = 0,xscaleIntUV = 0,yscaleFractUV = 0;
- unsigned int yscaleIntUV = 0,yPitch = 0,uvPitch = 0;
- unsigned int ovcmd = 0;
- uint d;
- double xscale,yscale;
- int diff;
- int clipped_srcx, clipped_srcy, clipped_destx, clipped_desty;
- int clipped_srcw, clipped_srch, clipped_destw, clipped_desth;
- uint x1,y1,root_width,root_height;
- int x2 = 0, y2 = 0,unused;
- uint nChilds;
- int stat;
- Window win,root,parent,*pChilds;
-
-
- if((display == NULL) || (surface == NULL)) {
- return BadValue;
- }
-
- if(surface->privData == NULL) {
- return (error_base + XvMCBadSurface);
- }
- pI810Surface = (i810XvMCSurface *)surface->privData;
- pI810XvMC = (i810XvMCContext *)pI810Surface->privContext;
- pORegs = (i810OverlayRecPtr)pI810XvMC->oregs;
-
-
- switch(surface->surface_type_id) {
- case FOURCC_YV12:
- case FOURCC_I420:
- yPitch = (srcw + 7) & ~7;
- uvPitch = ((srcw>>1) + 7) & ~7;
- if((flags & XVMC_FRAME_PICTURE) != XVMC_FRAME_PICTURE) {
- srch = srch>>1;
- }
- break;
- case FOURCC_UYVY:
- case FOURCC_YUY2:
- default:
- /* FIXME: Non Planar not fully implemented. */
- return BadValue;
- yPitch = ((srcw + 7) & ~7) << 1;
- break;
- }/* switch(surface->surface_type_id) */
-
- /*
- FIXME: This should be using the DRI's clip rect but that isn't
- all hooked up yet. This has some latency but we get by.
- */
- win = draw;
- XQueryTree(display,win,&root,&parent,&pChilds,&nChilds);
- if(nChilds) XFree(pChilds);
- XGetGeometry(display,win, &root, &x2, &y2, &window_width,
- &window_height, &d, &d);
- x1 = x2;
- y1 = y2;
- win = parent;
- do {
- XQueryTree(display,win,&root,&parent,&pChilds,&nChilds);
- if(nChilds) XFree(pChilds);
- XGetGeometry(display,win, &root, &x2, &y2, &d, &d, &d, &d);
- x1 += x2;
- y1 += y2;
- win = parent;
- }while(win != root);
- XGetGeometry(display,root, &root, &unused, &unused,
- &root_width, &root_height, &d, &d);
-
- /* Left edge of Video window clipped to screen */
- extents.x1 = 0;
- if(x1 > extents.x1) {
- extents.x1 = x1;
- }
- /* Right edge of Video window clipped to screen */
- extents.x2 = root_width;
- if(extents.x2 > (x1 + window_width)) {
- extents.x2 = x1 + window_width;
- }
- /* Top edge of Video window clipped to screen */
- extents.y1 = 0;
- if(y1 > extents.y1) {
- extents.y1 = y1;
- }
- /* Bottom edge of Video window clipped to screen */
- extents.y2 = root_height;
- if(extents.y2 > (y1 + window_height)) {
- extents.y2 = y1 + window_height;
- }
-
- /*
- Clipping is more difficult than is seems. We need to keep the
- scaling factors even if the destination window needs to be clipped.
- We clip the destination window first then apply a scaled version
- to the source window.
- */
-
- /* Put destination coords in screen coords */
- destx += x1;
- desty += y1;
-
- /* Scale factors requested */
- xscale = (double)srcw / (double)destw;
- yscale = (double)srch / (double)desth;
-
- /*
- If destination window needs to be clipped we actually adjust both
- the src and dest window so as to keep the scaling that was requested
- */
- clipped_srcx = srcx;
- clipped_srcy = srcy;
- clipped_destx = destx;
- clipped_desty = desty;
- clipped_srcw = srcw;
- clipped_srch = srch;
- clipped_destw = destw;
- clipped_desth = desth;
-
- /* Clip to the source surface boundaries */
- if(clipped_srcx < 0) {
- clipped_destx += (0 - clipped_srcx) / xscale;
- clipped_srcw -= clipped_srcx;
- clipped_destw -= clipped_srcx / xscale;
- clipped_srcx = 0;
- }
- if((clipped_srcw + clipped_srcx) > surface->width) {
- clipped_srcw = surface->width - clipped_srcx;
- clipped_destw -= (clipped_srcw - srcw) / xscale;
- }
- if(clipped_srcy < 0) {
- clipped_desty += (0 - clipped_srcy) / yscale;
- clipped_srch -= clipped_srcy;
- clipped_desth -= clipped_srcy / yscale;
- clipped_srcy = 0;
- }
- if((clipped_srch + clipped_srcy) > surface->height) {
- clipped_srch = surface->height - clipped_srcy;
- clipped_desth -= (clipped_srch - srch) / yscale;
- }
-
- /* Clip to the extents */
- if(clipped_destx < extents.x1) {
- diff = extents.x1 - clipped_destx;
- clipped_srcx += diff * xscale;
- clipped_srcw -= diff * xscale;
- clipped_destw -= diff;
- clipped_destx = extents.x1;
- }
-
- diff = (clipped_destx + clipped_destw) - extents.x2;
- if(diff > 0) {
- clipped_destw -= diff;
- clipped_srcw -= diff * xscale;
- }
-
- if(clipped_desty < extents.y1) {
- diff = extents.y1 - clipped_desty;
- clipped_srcy += diff * yscale;
- clipped_srch -= diff * yscale;
- clipped_desth -= diff;
- clipped_desty = 0;
- }
-
- diff = (clipped_desty + clipped_desth) - extents.y2;
- if(diff > 0) {
- clipped_desth -= diff;
- clipped_srch -= diff * yscale;
- }
-
- /* If the whole window is clipped turn off the overlay */
- if((clipped_destx + clipped_destw < extents.x1) ||
- (clipped_desty + clipped_desth < extents.y1) ||
- (clipped_destx > extents.x2) ||
- (clipped_desty > extents.y2)) {
- return XvMCHideSurface(display, surface);
- }
-
- /*
- Adjust the source offset width and height according to the clipped
- destination window.
- */
- ysrc_offset = ((clipped_srcx + 1) & ~1) +
- ((clipped_srcy + 1) & ~1) * (1<<pI810Surface->pitch);
- uvsrc_offset = (clipped_srcx>>1) +
- (clipped_srcy>>1) * (1<<(pI810Surface->pitch - 1));
-
- /*
- Initially, YCbCr and Overlay Enable and
- vertical chrominance up interpolation and horozontal chrominance
- up interpolation
- */
- ovcmd = VC_UP_INTERPOLATION | HC_UP_INTERPOLATION |
- Y_ADJUST | OVERLAY_ENABLE;
-
- if ((clipped_destw != clipped_srcw) ||
- (clipped_desth != clipped_srch)) {
- xscaleInt = (clipped_srcw / clipped_destw) & 0x3;
- xscaleFract = (clipped_srcw << 12) / clipped_destw;
- yscaleInt = (clipped_srch / clipped_desth) & 0x3;
- yscaleFract = (clipped_srch << 12) / clipped_desth;
-
- if (clipped_destw > clipped_srcw) {
- /* horizontal up-scaling */
- ovcmd &= ~HORIZONTAL_CHROMINANCE_FILTER;
- ovcmd &= ~HORIZONTAL_LUMINANCE_FILTER;
- ovcmd |= (HC_UP_INTERPOLATION | HL_UP_INTERPOLATION);
- }
-
- if (clipped_desth > clipped_srch) {
- /* vertical up-scaling */
- ovcmd &= ~VERTICAL_CHROMINANCE_FILTER;
- ovcmd &= ~VERTICAL_LUMINANCE_FILTER;
- ovcmd |= (VC_UP_INTERPOLATION | VL_UP_INTERPOLATION);
- }
-
- if (clipped_destw < clipped_srcw) {
- /* horizontal down-scaling */
- ovcmd &= ~HORIZONTAL_CHROMINANCE_FILTER;
- ovcmd &= ~HORIZONTAL_LUMINANCE_FILTER;
- ovcmd |= (HC_DOWN_INTERPOLATION | HL_DOWN_INTERPOLATION);
- }
-
- if (clipped_desth < clipped_srch) {
- /* vertical down-scaling */
- ovcmd &= ~VERTICAL_CHROMINANCE_FILTER;
- ovcmd &= ~VERTICAL_LUMINANCE_FILTER;
- ovcmd |= (VC_DOWN_INTERPOLATION | VL_DOWN_INTERPOLATION);
- }
-
- /* now calculate the UV scaling factor */
- if (xscaleFract) {
- xscaleFractUV = xscaleFract >> MINUV_SCALE;
- ovcmd &= ~HC_DOWN_INTERPOLATION;
- ovcmd |= HC_UP_INTERPOLATION;
- }
-
- if (xscaleInt) {
- xscaleIntUV = xscaleInt >> MINUV_SCALE;
- if (xscaleIntUV) {
- ovcmd &= ~HC_UP_INTERPOLATION;
- }
- }
-
- if (yscaleFract) {
- yscaleFractUV = yscaleFract >> MINUV_SCALE;
- ovcmd &= ~VC_DOWN_INTERPOLATION;
- ovcmd |= VC_UP_INTERPOLATION;
- }
-
- if (yscaleInt) {
- yscaleIntUV = yscaleInt >> MINUV_SCALE;
- if (yscaleIntUV) {
- ovcmd &= ~VC_UP_INTERPOLATION;
- ovcmd |= VC_DOWN_INTERPOLATION;
- }
- }
-
- }/* if((destw != srcw) || (desth != srch)) */
-
- /* Lock the DRM */
- I810_LOCK(pI810XvMC,0);
-
- /* Block until rendering on this surface is finished */
- stat = XVMC_RENDERING;
- while(stat & XVMC_RENDERING) {
- XvMCGetSurfaceStatus(display,surface,&stat);
- }
- /* Block until the last flip is finished */
- if(pI810XvMC->last_flip) {
- BLOCK_OVERLAY(pI810XvMC,pI810XvMC->current);
- }
-
- pI810XvMC->current = !pI810XvMC->current;
- pORegs->OV0CMD = ovcmd;
-
- if ((clipped_destw != clipped_srcw) ||
- (clipped_desth != clipped_srch)) {
- pORegs->YRGBSCALE = (xscaleInt << 15) |
- ((xscaleFract & 0xFFF) << 3) | (yscaleInt) |
- ((yscaleFract & 0xFFF) << 20);
-
- pORegs->UVSCALE = yscaleIntUV | ((xscaleFractUV & 0xFFF) << 3) |
- ((yscaleFractUV & 0xFFF) << 20);
- }
- else {
- /* Normal 1:1 scaling */
- pORegs->YRGBSCALE = 0x80004000;
- pORegs->UVSCALE = 0x80004000;
- }
-
- pORegs->SHEIGHT = clipped_srch | (clipped_srch << 15);
- pORegs->DWINPOS = (clipped_desty << 16) | clipped_destx;
- pORegs->DWINSZ = ((clipped_desth<< 16) | (clipped_destw));
-
- /* Attributes */
- pORegs->OV0CLRC0 = ((pI810XvMC->contrast & 0x1ff)<<8) |
- (pI810XvMC->brightness & 0xff);
- pORegs->OV0CLRC1 = (pI810XvMC->saturation & 0x3ff);
-
- /* Destination Colorkey Setup */
- pI810XvMC->oregs->DCLRKV = RGB16ToColorKey(pI810XvMC->colorkey);
-
- /* buffer locations, add the offset from the clipping */
- if(pI810XvMC->current) {
- pORegs->OBUF_1Y = (unsigned long)pI810Surface->offset +
- (unsigned long)pI810Surface->offsets[0] + ysrc_offset;
- pORegs->OBUF_1V = (unsigned long)pI810Surface->offset +
- (unsigned long)pI810Surface->offsets[2] + uvsrc_offset;
- pORegs->OBUF_1U = (unsigned long)pI810Surface->offset +
- (unsigned long)pI810Surface->offsets[1] + uvsrc_offset;
- }
- else {
- pORegs->OBUF_0Y = (unsigned long)pI810Surface->offset +
- (unsigned long)pI810Surface->offsets[0] + ysrc_offset;
- pORegs->OBUF_0V = (unsigned long)pI810Surface->offset +
- (unsigned long)pI810Surface->offsets[2] + uvsrc_offset;
- pORegs->OBUF_0U = (unsigned long)pI810Surface->offset +
- (unsigned long)pI810Surface->offsets[1] + uvsrc_offset;
- }
-
- switch(surface->surface_type_id) {
- case FOURCC_YV12:
- case FOURCC_I420:
- pORegs->SWID = (uvPitch << 16) | yPitch;
- pORegs->SWIDQW = (uvPitch << 13) | (yPitch >> 3);
- pORegs->OV0STRIDE = (1<<pI810Surface->pitch) |
- ((1<<pI810Surface->pitch) << 15);
- pORegs->OV0CMD &= ~SOURCE_FORMAT;
- pORegs->OV0CMD |= YUV_420;
- if((flags & XVMC_FRAME_PICTURE) != XVMC_FRAME_PICTURE) {
- /* Top Field Only */
- if(flags & XVMC_TOP_FIELD) {
- if(pI810XvMC->current == 1) {
- pORegs->OV0CMD |= (VERTICAL_PHASE_BOTH | FLIP_TYPE_FIELD |
- BUFFER1_FIELD0);
- }
- else {
- pORegs->OV0CMD |= (VERTICAL_PHASE_BOTH | FLIP_TYPE_FIELD |
- BUFFER0_FIELD0);
- }
- pORegs->YRGB_VPH = 1<<15 | 1<<31;
- pORegs->UV_VPH = 3<<14 | 3<<30;
- pORegs->INIT_PH = 0x06 | 0x18;
- }
- /* Bottom Field Only */
- else {
- if(pI810XvMC->current == 1) {
- pORegs->OV0CMD |= (VERTICAL_PHASE_BOTH | FLIP_TYPE_FIELD |
- BUFFER1_FIELD1);
- }
- else {
- pORegs->OV0CMD |= (VERTICAL_PHASE_BOTH | FLIP_TYPE_FIELD |
- BUFFER0_FIELD1);
- }
- pORegs->YRGB_VPH = 0;
- pORegs->UV_VPH = 7<<29 | 7<<13;
- pORegs->INIT_PH = 0x06;
- }
- }
- /* Frame Picture */
- else {
- if(pI810XvMC->current == 1) {
- pORegs->OV0CMD |= BUFFER1_FIELD0;
- }
- else {
- pORegs->OV0CMD |= BUFFER0_FIELD0;
- }
- pORegs->YRGB_VPH = 0;
- pORegs->UV_VPH = 0;
- pORegs->INIT_PH = 0;
- }
- break;
- case FOURCC_UYVY:
- case FOURCC_YUY2:
- default:
- pORegs->SWID = srcw;
- pORegs->SWIDQW = srcw >> 3;
- pORegs->OV0STRIDE = pI810Surface->pitch;
- pORegs->OV0CMD &= ~SOURCE_FORMAT;
- pORegs->OV0CMD |= YUV_422;
- pORegs->OV0CMD &= ~OV_BYTE_ORDER;
- if (surface->surface_type_id == FOURCC_UYVY) {
- pORegs->OV0CMD |= Y_SWAP;
- }
-
- pORegs->OV0CMD &= ~BUFFER_AND_FIELD;
- if(pI810XvMC->current == 1) {
- pORegs->OV0CMD |= BUFFER1_FIELD0;
- }
- else {
- pORegs->OV0CMD |= BUFFER0_FIELD0;
- }
-
- break;
- } /* switch(surface->surface_type_id) */
-
-
-
- OVERLAY_FLIP(pI810XvMC);
-
- /*
- The Overlay only flips when it knows you changed
- something. So the first time change stuff while it
- is watching to be sure.
- */
- if(!pI810XvMC->last_flip) {
- pORegs->OV0CMD &= ~0x4;
- if(pI810XvMC->current == 1) {
- pORegs->OV0CMD |= BUFFER1_FIELD0;
- }
- else {
- pORegs->OV0CMD |= BUFFER0_FIELD0;
- }
- }
- pI810Surface->last_flip = ++pI810XvMC->last_flip;
- I810_UNLOCK(pI810XvMC);
-
- return Success;
-}
-
-/***************************************************************************
-// Function: XvMCSyncSurface
-// Arguments:
-// display - Connection to the X server
-// surface - The surface to synchronize
-// Info:
-// Returns: Status
-***************************************************************************/
-Status XvMCSyncSurface(Display *display,XvMCSurface *surface) {
- Status ret;
- int stat=0;
- /*
- FIXME: Perhaps a timer here to prevent lockup?
- FIXME: Perhaps a usleep to not be busy waiting?
- */
- do {
- ret = XvMCGetSurfaceStatus(display,surface,&stat);
- }while(!ret && (stat & XVMC_RENDERING));
- return ret;
-}
-
-/***************************************************************************
-// Function: XvMCFlushSurface
-// Description:
-// This function commits pending rendering requests to ensure that they
-// wll be completed in a finite amount of time.
-// Arguments:
-// display - Connection to X server
-// surface - Surface to flush
-// Info:
-// This command is a noop for i810 becuase we always dispatch buffers in
-// render. There is little gain to be had with 4k buffers.
-// Returns: Status
-***************************************************************************/
-Status XvMCFlushSurface(Display * display, XvMCSurface *surface) {
- return Success;
-}
-
-/***************************************************************************
-// Function: XvMCGetSurfaceStatus
-// Description:
-// Arguments:
-// display: connection to X server
-// surface: The surface to query
-// stat: One of the Following
-// XVMC_RENDERING - The last XvMCRenderSurface command has not
-// completed.
-// XVMC_DISPLAYING - The surface is currently being displayed or a
-// display is pending.
-***************************************************************************/
-Status XvMCGetSurfaceStatus(Display *display, XvMCSurface *surface,
- int *stat) {
- i810XvMCSurface *privSurface;
- i810XvMCContext *pI810XvMC;
- int temp;
-
- if((display == NULL) || (surface == NULL) || (stat == NULL)) {
- return BadValue;
- }
- if(surface->privData == NULL) {
- return BadValue;
- }
- *stat = 0;
- privSurface = surface->privData;
-
- pI810XvMC = privSurface->privContext;
- if(pI810XvMC == NULL) {
- return (error_base + XvMCBadSurface);
- }
-
- I810_LOCK(pI810XvMC,0);
- if(privSurface->last_flip) {
- /* This can not happen */
- if(pI810XvMC->last_flip < privSurface->last_flip) {
- printf("Error: Context last flip is less than surface last flip.\n");
- return BadValue;
- }
- /*
- If the context has 2 or more flips after this surface it
- cannot be displaying. Don't bother to check.
- */
- if(!(pI810XvMC->last_flip > (privSurface->last_flip + 1))) {
- /*
- If this surface was the last flipped it is either displaying
- or about to be so don't bother checking.
- */
- if(pI810XvMC->last_flip == privSurface->last_flip) {
- *stat |= XVMC_DISPLAYING;
- }
- else {
- /*
- In this case there has been one more flip since our surface's
- but we need to check if it is finished or not.
- */
- temp = GET_FSTATUS(pI810XvMC);
- if(((temp & (1<<20))>>20) != pI810XvMC->current) {
- *stat |= XVMC_DISPLAYING;
- }
- }
- }
- }
-
- if(privSurface->last_render &&
- (privSurface->last_render > GET_RSTATUS(pI810XvMC))) {
- *stat |= XVMC_RENDERING;
- }
- I810_UNLOCK(pI810XvMC);
-
- return Success;
-}
-
-/***************************************************************************
-//
-// Surface manipulation functions
-//
-***************************************************************************/
-
-/***************************************************************************
-// Function: XvMCHideSurface
-// Description: Stops the display of a surface.
-// Arguments:
-// display - Connection to the X server.
-// surface - surface to be hidden.
-//
-// Returns: Status
-***************************************************************************/
-Status XvMCHideSurface(Display *display, XvMCSurface *surface) {
- i810XvMCSurface *pI810Surface;
- i810XvMCContext *pI810XvMC;
- int ss, xx;
-
- /* Did we get a good display and surface passed into us? */
- if(display == NULL) {
- return BadValue;
- }
-
- if(surface == NULL) {
- return (error_base + XvMCBadSurface);
- }
-
- XvMCSyncSurface(display, surface);
-
- /* Get surface private data pointer */
- if(surface->privData == NULL) {
- return (error_base + XvMCBadSurface);
- }
- pI810Surface = (i810XvMCSurface *)surface->privData;
-
- /*
- Get the status of the surface, if it is not currently displayed
- we don't need to worry about it.
- */
- if((xx = XvMCGetSurfaceStatus(display, surface, &ss)) != Success) {
- return xx;
- }
- if(! (ss & XVMC_DISPLAYING)) {
- return Success;
- }
-
- /* Get the associated context pointer */
- pI810XvMC = (i810XvMCContext *)pI810Surface->privContext;
- if(pI810XvMC == NULL) {
- return (error_base + XvMCBadSurface);
- }
-
- if(pI810XvMC->last_flip) {
- I810_LOCK(pI810XvMC,DRM_LOCK_QUIESCENT);
-
- /* Make sure last flip is done */
- BLOCK_OVERLAY(pI810XvMC,pI810XvMC->current);
-
- /* Set the registers to turn the overlay off */
- pI810XvMC->oregs->OV0CMD = VC_UP_INTERPOLATION | HC_UP_INTERPOLATION |
- Y_ADJUST;
- pI810XvMC->current = !pI810XvMC->current;
- if(pI810XvMC->current == 1) {
- pI810XvMC->oregs->OV0CMD |= BUFFER1_FIELD0;
- }
- else {
- pI810XvMC->oregs->OV0CMD |= BUFFER0_FIELD0;
- }
- OVERLAY_FLIP(pI810XvMC);
- /*
- Increment the context flip but not the surface. This way no
- surface has the last flip #.
- */
- pI810XvMC->last_flip++;
-
-
- /* Now wait until the hardware reads the registers and makes the change. */
- BLOCK_OVERLAY(pI810XvMC,pI810XvMC->current)
-
- I810_UNLOCK(pI810XvMC);
- }
-
- return Success;
-}
-
-
-
-
-/***************************************************************************
-//
-// Functions that deal with subpictures
-//
-***************************************************************************/
-
-
-
-/***************************************************************************
-// Function: XvMCCreateSubpicture
-// Description: This creates a subpicture by filling out the XvMCSubpicture
-// structure passed to it and returning Success.
-// Arguments:
-// display - Connection to the X server.
-// context - The context to create the subpicture for.
-// subpicture - Pre-allocated XvMCSubpicture structure to be filled in.
-// width - of subpicture
-// height - of subpicture
-// xvimage_id - The id describing the XvImage format.
-//
-// Returns: Status
-***************************************************************************/
-Status XvMCCreateSubpicture(Display *display, XvMCContext *context,
- XvMCSubpicture *subpicture,
- unsigned short width, unsigned short height,
- int xvimage_id) {
- i810XvMCContext *pI810XvMC;
- i810XvMCSubpicture *pI810Subpicture;
- int priv_count;
- uint *priv_data;
- Status ret;
-
- if((subpicture == NULL) || (context == NULL) || (display == NULL)){
- return BadValue;
- }
-
- pI810XvMC = (i810XvMCContext *)context->privData;
- if(pI810XvMC == NULL) {
- return (error_base + XvMCBadContext);
- }
-
-
- subpicture->context_id = context->context_id;
- subpicture->xvimage_id = xvimage_id;
-
- /* These need to be checked to make sure they are not too big! */
- subpicture->width = width;
- subpicture->height = height;
-
- subpicture->privData =
- (i810XvMCSubpicture *)malloc(sizeof(i810XvMCSubpicture));
-
- if(!subpicture->privData) {
- return BadAlloc;
- }
- pI810Subpicture = (i810XvMCSubpicture *)subpicture->privData;
-
-
- if((ret = _xvmc_create_subpicture(display, context, subpicture,
- &priv_count, &priv_data))) {
- printf("Unable to create XvMCSubpicture.\n");
- return ret;
- }
-
- if(priv_count != 1) {
- printf("_xvmc_create_subpicture() returned incorrect data size.\n");
- printf("Expected 1 got %d\n",priv_count);
- free(priv_data);
- return BadAlloc;
- }
- /* Data == Client Address, offset == Physical address offset */
- pI810Subpicture->data = pI810XvMC->surfaces.address;
- pI810Subpicture->offset = pI810XvMC->surfaces.offset;
-
- /* Initialize private values */
- pI810Subpicture->privContext = pI810XvMC;
-
- pI810Subpicture->last_render = 0;
- pI810Subpicture->last_flip = 0;
-
- /* Based on the xvimage_id we will need to set the other values */
- subpicture->num_palette_entries = 16;
- subpicture->entry_bytes = 3;
- strcpy(subpicture->component_order,"YUV");
-
- /*
- i810's MC Engine needs surfaces of 2^x (x= 9,10,11,12) pitch
- and the Tiler need 512k aligned surfaces, basically we are
- stuck with fixed memory with pitch 1024.
- */
- pI810Subpicture->pitch = 10;
-
- /*
- offsets[0] == offset into the map described by either
- address (Client memeory address) or offset (physical offset from fb base)
- */
- pI810Subpicture->offsets[0] = priv_data[0];
- if(((unsigned long)pI810Subpicture->data + pI810Subpicture->offsets[0]) & 4095) {
- printf("XvMCCreateSubpicture: Subpicture offset 0 is not 4096 aligned\n");
- }
-
- /* Free data returned from xvmc_create_surface */
- free(priv_data);
-
- /* Clear the surface to 0 */
- memset((void *)((unsigned long)pI810Subpicture->data + (unsigned long)pI810Subpicture->offsets[0]),
- 0, ((1<<pI810Subpicture->pitch) * subpicture->height));
-
- switch(subpicture->xvimage_id) {
- case FOURCC_IA44:
- case FOURCC_AI44:
- /* Destination buffer info command */
- pI810Subpicture->dbi1 = ((((unsigned int)pI810Subpicture->offset +
- pI810Subpicture->offsets[0]) & ~0xfc000fff) |
- (pI810Subpicture->pitch - 9));
-
- /* Destination buffer variables command */
- pI810Subpicture->dbv1 = (0x8<<20) | (0x8<<16);
-
- /* Map info command */
- pI810Subpicture->mi1 = (0x0<<24) | (3<<21) | (1<<9) |
- (pI810Subpicture->pitch - 3);
-
- pI810Subpicture->mi2 = (((unsigned int)subpicture->height - 1)<<16) |
- ((unsigned int)subpicture->width - 1);
-
- pI810Subpicture->mi3 = ((unsigned int)pI810Subpicture->offset +
- pI810Subpicture->offsets[0]) & ~0xfc00000f;
- break;
- default:
- free(subpicture->privData);
- return BadMatch;
- }
-
- pI810XvMC->ref++;
- return Success;
-}
-
-
-
-/***************************************************************************
-// Function: XvMCClearSubpicture
-// Description: Clear the area of the given subpicture to "color".
-// structure passed to it and returning Success.
-// Arguments:
-// display - Connection to the X server.
-// subpicture - Subpicture to clear.
-// x, y, width, height - rectangle in the subpicture to clear.
-// color - The data to file the rectangle with.
-//
-// Returns: Status
-***************************************************************************/
-Status XvMCClearSubpicture(Display *display, XvMCSubpicture *subpicture,
- short x, short y,
- unsigned short width, unsigned short height,
- unsigned int color) {
-
- i810XvMCContext *pI810XvMC;
- i810XvMCSubpicture *pI810Subpicture;
- int i;
-
- if((subpicture == NULL) || (display == NULL)){
- return BadValue;
- }
-
- if(!subpicture->privData) {
- return (error_base + XvMCBadSubpicture);
- }
- pI810Subpicture = (i810XvMCSubpicture *)subpicture->privData;
-
- pI810XvMC = (i810XvMCContext *)pI810Subpicture->privContext;
- if(pI810XvMC == NULL) {
- return (error_base + XvMCBadSubpicture);
- }
-
- if((x < 0) || (x + width > subpicture->width)) {
- return BadValue;
- }
-
- if((y < 0) || (y + height > subpicture->height)) {
- return BadValue;
- }
-
- for(i=y; i<y + height; i++) {
- memset((void *)((unsigned long)pI810Subpicture->data +
- (unsigned long)pI810Subpicture->offsets[0] + x +
- (1<<pI810Subpicture->pitch) * i),(char)color,width);
- }
-
- return Success;
-}
-
-/***************************************************************************
-// Function: XvMCCompositeSubpicture
-// Description: Composite the XvImae on the subpicture. This composit uses
-// non-premultiplied alpha. Destination alpha is utilized
-// except for with indexed subpictures. Indexed subpictures
-// use a simple "replace".
-// Arguments:
-// display - Connection to the X server.
-// subpicture - Subpicture to clear.
-// image - the XvImage to be used as the source of the composite.
-// srcx, srcy, width, height - The rectangle from the image to be used.
-// dstx, dsty - location in the subpicture to composite the source.
-//
-// Returns: Status
-***************************************************************************/
-Status XvMCCompositeSubpicture(Display *display, XvMCSubpicture *subpicture,
- XvImage *image,
- short srcx, short srcy,
- unsigned short width, unsigned short height,
- short dstx, short dsty) {
-
- i810XvMCContext *pI810XvMC;
- i810XvMCSubpicture *pI810Subpicture;
- int i;
-
- if((subpicture == NULL) || (display == NULL)){
- return BadValue;
- }
-
- if(!subpicture->privData) {
- return (error_base + XvMCBadSubpicture);
- }
- pI810Subpicture = (i810XvMCSubpicture *)subpicture->privData;
-
- pI810XvMC = (i810XvMCContext *)pI810Subpicture->privContext;
- if(pI810XvMC == NULL) {
- return (error_base + XvMCBadSubpicture);
- }
-
- if((srcx < 0) || (srcx + width > image->width)) {
- return BadValue;
- }
-
- if((dstx < 0) || (dstx + width > subpicture->width)) {
- return BadValue;
- }
-
- if((srcy < 0) || (srcy + height > image->height)) {
- return BadValue;
- }
-
- if((dsty < 0) || (dsty + height > subpicture->height)) {
- return BadValue;
- }
-
- for(i=0; i<height; i++) {
- memcpy((void *)((unsigned long)pI810Subpicture->data +
- (unsigned long)pI810Subpicture->offsets[0] + dstx +
- (1<<pI810Subpicture->pitch) * (i + dsty)),
- (void *)((unsigned long)image->data +
- (unsigned long)image->offsets[0] + srcx +
- image->pitches[0] * (i + srcy))
- ,width);
- }
-
- return Success;
-
-}
-
-
-/***************************************************************************
-// Function: XvMCDestroySubpicture
-// Description: Destroys the specified subpicture.
-// Arguments:
-// display - Connection to the X server.
-// subpicture - Subpicture to be destroyed.
-//
-// Returns: Status
-***************************************************************************/
-Status XvMCDestroySubpicture(Display *display, XvMCSubpicture *subpicture) {
-
- i810XvMCSubpicture *pI810Subpicture;
- i810XvMCContext *pI810XvMC;
-
- if((display == NULL) || (subpicture == NULL)) {
- return BadValue;
- }
- if(!subpicture->privData) {
- return (error_base + XvMCBadSubpicture);
- }
- pI810Subpicture = (i810XvMCSubpicture *)subpicture->privData;
-
- pI810XvMC = (i810XvMCContext *)pI810Subpicture->privContext;
- if(!pI810XvMC) {
- return (error_base + XvMCBadSubpicture);
- }
-
-
- if(pI810Subpicture->last_render) {
- XvMCSyncSubpicture(display,subpicture);
- }
-
- _xvmc_destroy_subpicture(display,subpicture);
-
- i810_free_privContext(pI810XvMC);
-
- free(pI810Subpicture);
- subpicture->privData = NULL;
- return Success;
-}
-
-
-/***************************************************************************
-// Function: XvMCSetSubpicturePalette
-// Description: Set the subpictures palette
-// Arguments:
-// display - Connection to the X server.
-// subpicture - Subpiture to set palette for.
-// palette - A pointer to an array holding the palette data. The array
-// is num_palette_entries * entry_bytes in size.
-// Returns: Status
-***************************************************************************/
-
-Status XvMCSetSubpicturePalette(Display *display, XvMCSubpicture *subpicture,
- unsigned char *palette) {
- i810XvMCSubpicture *privSubpicture;
- int i,j;
-
- if((display == NULL) || (subpicture == NULL)) {
- return BadValue;
- }
- if(subpicture->privData == NULL) {
- return (error_base + XvMCBadSubpicture);
- }
- privSubpicture = (i810XvMCSubpicture *)subpicture->privData;
-
- j=0;
- for(i=0; i<16; i++) {
- privSubpicture->palette[0][i] = palette[j++];
- privSubpicture->palette[1][i] = palette[j++];
- privSubpicture->palette[2][i] = palette[j++];
- }
- return Success;
-}
-
-/***************************************************************************
-// Function: XvMCBlendSubpicture
-// Description:
-// The behavior of this function is different depending on whether
-// or not the XVMC_BACKEND_SUBPICTURE flag is set in the XvMCSurfaceInfo.
-// i810 only support frontend behavior.
-//
-// XVMC_BACKEND_SUBPICTURE not set ("frontend" behavior):
-//
-// XvMCBlendSubpicture is a no-op in this case.
-//
-// Arguments:
-// display - Connection to the X server.
-// subpicture - The subpicture to be blended into the video.
-// target_surface - The surface to be displayed with the blended subpic.
-// source_surface - Source surface prior to blending.
-// subx, suby, subw, subh - The rectangle from the subpicture to use.
-// surfx, surfy, surfw, surfh - The rectangle in the surface to blend
-// blend the subpicture rectangle into. Scaling can ocure if
-// XVMC_SUBPICTURE_INDEPENDENT_SCALING is set.
-//
-// Returns: Status
-***************************************************************************/
-Status XvMCBlendSubpicture(Display *display, XvMCSurface *target_surface,
- XvMCSubpicture *subpicture,
- short subx, short suby,
- unsigned short subw, unsigned short subh,
- short surfx, short surfy,
- unsigned short surfw, unsigned short surfh) {
-
- return BadMatch;
-}
-
-
-
-/***************************************************************************
-// Function: XvMCBlendSubpicture2
-// Description:
-// The behavior of this function is different depending on whether
-// or not the XVMC_BACKEND_SUBPICTURE flag is set in the XvMCSurfaceInfo.
-// i810 only supports frontend blending.
-//
-// XVMC_BACKEND_SUBPICTURE not set ("frontend" behavior):
-//
-// XvMCBlendSubpicture2 blends the source_surface and subpicture and
-// puts it in the target_surface. This does not effect the status of
-// the source surface but will cause the target_surface to query
-// XVMC_RENDERING until the blend is completed.
-//
-// Arguments:
-// display - Connection to the X server.
-// subpicture - The subpicture to be blended into the video.
-// target_surface - The surface to be displayed with the blended subpic.
-// source_surface - Source surface prior to blending.
-// subx, suby, subw, subh - The rectangle from the subpicture to use.
-// surfx, surfy, surfw, surfh - The rectangle in the surface to blend
-// blend the subpicture rectangle into. Scaling can ocure if
-// XVMC_SUBPICTURE_INDEPENDENT_SCALING is set.
-//
-// Returns: Status
-***************************************************************************/
-Status XvMCBlendSubpicture2(Display *display,
- XvMCSurface *source_surface,
- XvMCSurface *target_surface,
- XvMCSubpicture *subpicture,
- short subx, short suby,
- unsigned short subw, unsigned short subh,
- short surfx, short surfy,
- unsigned short surfw, unsigned short surfh) {
- drmBufPtr pDMA;
- unsigned int *data;
- i810XvMCContext *pI810XvMC;
- i810XvMCSubpicture *privSubpicture;
- i810XvMCSurface *privTarget;
- i810XvMCSurface *privSource;
- drm_i810_mc_t mc;
- int i,j;
-
- if(display == NULL) {
- return BadValue;
- }
-
- if(subpicture == NULL) {
- return (error_base + XvMCBadSubpicture);
- }
-
- if((target_surface == NULL) || (source_surface == NULL)) {
- return (error_base + XvMCBadSurface);
- }
-
- if((subpicture->xvimage_id != FOURCC_AI44) &&
- (subpicture->xvimage_id != FOURCC_IA44)) {
- return (error_base + XvMCBadSubpicture);
- }
-
- if(!subpicture->privData) {
- return (error_base + XvMCBadSubpicture);
- }
- privSubpicture = (i810XvMCSubpicture *)subpicture->privData;
-
- pI810XvMC = (i810XvMCContext *)privSubpicture->privContext;
- if(pI810XvMC == NULL) {
- return (error_base + XvMCBadSubpicture);
- }
-
- if(!target_surface->privData) {
- return (error_base + XvMCBadSurface);
- }
- privTarget = (i810XvMCSurface *)target_surface->privData;
-
- if(!source_surface->privData) {
- return (error_base + XvMCBadSurface);
- }
- privSource = (i810XvMCSurface *)source_surface->privData;
-
-
- /* Check that size isn't bigger than subpicture */
- if((subx + subw) > subpicture->width) {
- return BadValue;
- }
- if((suby + subh) > subpicture->height) {
- return BadValue;
- }
- /* Check that dest isn't bigger than surface */
- if((surfx + surfw) > target_surface->width) {
- return BadValue;
- }
- if((surfy + surfh) > target_surface->height) {
- return BadValue;
- }
- /* Make sure surfaces match */
- if(target_surface->width != source_surface->width) {
- return BadValue;
- }
- if(target_surface->height != source_surface->height) {
- return BadValue;
- }
-
- /* Lock For DMA */
- I810_LOCK(pI810XvMC,0);
-
- /* Allocate DMA buffer */
- pDMA = i810_get_free_buffer(pI810XvMC);
- data = pDMA->address;
-
- /* Copy Y data first */
- /* SOURCE_COPY_BLT */
- *data++ = (2<<29) | (0x43<<22) | 0x4;
- *data++ = (0xcc<<16) | (1<<26) | (1<<privTarget->pitch);
- *data++ = (target_surface->height<<16) | target_surface->width;
- *data++ = privTarget->offset + privTarget->offsets[0];
- *data++ = (1<<privSource->pitch);
- *data++ = privSource->offset + privSource->offsets[0];
-
- /* Select Context 1 for loading */
- *data++ = CMD_FLUSH;
- *data++ = (5<<23) | (1<<17) | (1<<8);
- *data++ = CMD_FLUSH;
-
- /* Load Palette */
- *data++ = MAP_PALETTE_LOAD;
- /* 16 levels of alpha for each Y */
- switch(subpicture->xvimage_id) {
- case FOURCC_IA44:
- for(i=0; i<16; i++) {
- for(j=0; j<16; j++) {
- *data++ = (j<<12) | (j<<8) | privSubpicture->palette[0][i];
- }
- }
- break;
- case FOURCC_AI44:
- for(i=0; i<16; i++) {
- for(j=0; j<16; j++) {
- *data++ = (i<<12) | (i<<8) | privSubpicture->palette[0][j];
- }
- }
- break;
- }
- /* TARGET */
- /* *data++ = CMD_FLUSH; */
- /* *data++ = BOOLEAN_ENA_2; */
- *data++ = CMD_FLUSH;
- *data++ = DEST_BUFFER_INFO;
- *data++ = privTarget->dbi1y;
- *data++ = DEST_BUFFER_VAR;
- *data++ = privTarget->dbv1;
-
- /* ALPHA */
- *data++ = CMD_MAP_INFO;
- *data++ = privSubpicture->mi1;
- *data++ = privSubpicture->mi2;
- *data++ = privSubpicture->mi3;
-
- *data++ = VERTEX_FORMAT | (1<<8) | (3<<1);
- *data++ = BOOLEAN_ENA_1;
- *data++ = SRC_DEST_BLEND_MONO | (0x940);
- /* Map Filter */
- *data++ = (3<<29) | (0x1c<<24) | (2<<19) | (0x224);
-
- /* Use context 1 */
- *data++ = CMD_FLUSH;
- *data++ = (5<<23) | (1<<16) | 1;
- *data++ = CMD_FLUSH;
-
- /* Drawing Rect Info */
- *data++ = DRAWING_RECT_INFO;
- *data++ = 0x0;
- *data++ = 0x0;
- *data++ = 0x0;
- *data++ = 0x0;
- *data++ = 0x0;
-
- /* GFXPRIMITIVE RECTANGLE */
- *data++ = (3<<29) | (0x1f<<24) | (0x7<<18) | 11;
- /* Bottom Right Vertex */
- *(float *)data++ = (float) (surfx + surfw);
- *(float *)data++ = (float) (surfy + surfh);
- *(float *)data++ = (float) (subx + subw);
- *(float *)data++ = (float) (suby + subh);
- /* Bottom Left Vertex */
- *(float *)data++ = (float) surfx;
- *(float *)data++ = (float) (surfy + surfh);
- *(float *)data++ = (float) subx;
- *(float *)data++ = (float) (suby + subh);
- /* Top Left Vertex */
- *(float *)data++ = (float) surfx;
- *(float *)data++ = (float) surfy;
- *(float *)data++ = (float) subx;
- *(float *)data++ = (float) suby;
-
- /* Load and Use Context 0 */
- *data++ = CMD_FLUSH;
- *data++ = (5<<23) | (1<<17) | (1<<16);
- *data++ = CMD_FLUSH;
-
- /* U data */
- /* SOURCE_COPY_BLT */
- *data++ = (2<<29) | (0x43<<22) | 0x4;
- *data++ = (0xcc<<16) | (1<<26) | (1<<(privTarget->pitch - 1));
- *data++ = (target_surface->height<<15) | (target_surface->width>>1);
- *data++ = (unsigned long)privTarget->offset + (unsigned long)privTarget->offsets[1];
- *data++ = (1<<(privSource->pitch - 1));
- *data++ = (unsigned long)privSource->offset + (unsigned long)privSource->offsets[1];
-
- /* Context 1 select */
- *data++ = CMD_FLUSH;
- *data++ = (5<<23) | (1<<17) | (1<<8);
- *data++ = CMD_FLUSH;
- /* ALPHA PALETTE */
- *data++ = MAP_PALETTE_LOAD;
- /* 16 levels of alpha for each Y */
- switch(subpicture->xvimage_id) {
- case FOURCC_IA44:
- for(i=0; i<16; i++) {
- for(j=0; j<16; j++) {
- *data++ = (j<<12) | (j<<8) | privSubpicture->palette[2][i];
- }
- }
- break;
- case FOURCC_AI44:
- for(i=0; i<16; i++) {
- for(j=0; j<16; j++) {
- *data++ = (i<<12) | (i<<8) | privSubpicture->palette[2][j];
- }
- }
- break;
- }
- /* TARGET */
- *data++ = CMD_FLUSH;
- *data++ = BOOLEAN_ENA_2;
- *data++ = CMD_FLUSH;
- *data++ = DEST_BUFFER_INFO;
- *data++ = privTarget->dbi1u;
- *data++ = DEST_BUFFER_VAR;
- *data++ = privTarget->dbv1;
-
- /* ALPHA */
- *data++ = CMD_MAP_INFO;
- *data++ = privSubpicture->mi1;
- *data++ = privSubpicture->mi2;
- *data++ = privSubpicture->mi3;
-
- *data++ = VERTEX_FORMAT | (1<<8) | (3<<1);
- *data++ = BOOLEAN_ENA_1;
- *data++ = SRC_DEST_BLEND_MONO | (0x940);
- /* Map Filter */
- *data++ = (3<<29) | (0x1c<<24) | (2<<19) | (1<<16) | (0x224);
-
- /* Use context 1 */
- *data++ = CMD_FLUSH;
- *data++ = (5<<23) | (1<<16) | 1;
- *data++ = CMD_FLUSH;
-
- /* Drawing Rect Info */
- *data++ = (3<<29) | (0x1d<<24) | (0x80<<16) | 3;
- *data++ = 0;
- *data++ = 0;
- *data++ = 0;
- *data++ = 0;
- *data++ = 0;
-
- /* Rectangle */
- *data++ = (3<<29) | (0x1f<<24) | (0x7<<18) | 11;
- /* Bottom Right */
- *(float *)data++ = (float) ((surfx + surfw)>>1);
- *(float *)data++ = (float) ((surfy + surfh)>>1);
- *(float *)data++ = (float) subx + subw;
- *(float *)data++ = (float) suby + subh;
- /* Bottom Left */
- *(float *)data++ = (float) (surfx>>1);
- *(float *)data++ = (float) ((surfy + surfh)>>1);
- *(float *)data++ = (float) subx;
- *(float *)data++ = (float) suby + subh;
- /* Top Left */
- *(float *)data++ = (float) (surfx>>1);
- *(float *)data++ = (float) (surfy>>1);
- *(float *)data++ = (float) subx;
- *(float *)data++ = (float) suby;
-
- /* Load and Use Context 0 */
- *data++ = CMD_FLUSH;
- *data++ = (5<<23) | (1<<17) | (1<<16);
- *data++ = CMD_FLUSH;
-
- /* V data */
- /* SOURCE_COPY_BLT */
- *data++ = (2<<29) | (0x43<<22) | 0x4;
- *data++ = (0xcc<<16) | (1<<26) | (1<<(privTarget->pitch - 1));
- *data++ = (target_surface->height<<15) | (target_surface->width>>1);
- *data++ = (unsigned long)privTarget->offset + (unsigned long)privTarget->offsets[2];
- *data++ = (1<<(privSource->pitch - 1));
- *data++ = (unsigned long)privSource->offset + (unsigned long)privSource->offsets[2];
-
- /* Context 1 select */
- *data++ = CMD_FLUSH;
- *data++ = (5<<23) | (1<<17) | (1<<8);
- *data++ = CMD_FLUSH;
-
- /* ALPHA PALETTE */
- *data++ = MAP_PALETTE_LOAD;
- /* 16 levels of alpha for each Y */
- switch(subpicture->xvimage_id) {
- case FOURCC_IA44:
- for(i=0; i<16; i++) {
- for(j=0; j<16; j++) {
- *data++ = (j<<12) | (j<<8) | privSubpicture->palette[1][i];
- }
- }
- break;
- case FOURCC_AI44:
- for(i=0; i<16; i++) {
- for(j=0; j<16; j++) {
- *data++ = (i<<12) | (i<<8) | privSubpicture->palette[1][j];
- }
- }
- break;
- }
- /* TARGET */
- *data++ = CMD_FLUSH;
- *data++ = BOOLEAN_ENA_2;
- *data++ = CMD_FLUSH;
- *data++ = DEST_BUFFER_INFO;
- *data++ = privTarget->dbi1v;
- *data++ = DEST_BUFFER_VAR;
- *data++ = privTarget->dbv1;
-
- /* ALPHA */
- *data++ = CMD_MAP_INFO;
- *data++ = privSubpicture->mi1;
- *data++ = privSubpicture->mi2;
- *data++ = privSubpicture->mi3;
-
- *data++ = VERTEX_FORMAT | (1<<8) | (3<<1);
- *data++ = BOOLEAN_ENA_1;
- *data++ = SRC_DEST_BLEND_MONO | (0x940);
- /* Map Filter */
- *data++ = (3<<29) | (0x1c<<24) | (2<<19) | (1<<16) | (0x224);
-
- /* Use context 1 */
- *data++ = CMD_FLUSH;
- *data++ = (5<<23) | (1<<16) | 1;
- *data++ = CMD_FLUSH;
-
- /* Drawing Rect Info */
- *data++ = (3<<29) | (0x1d<<24) | (0x80<<16) | 3;
- *data++ = 0;
- *data++ = 0;
- *data++ = 0;
- *data++ = 0;
- *data++ = 0;
-
- /* Rectangle */
- *data++ = (3<<29) | (0x1f<<24) | (0x7<<18) | 11;
- /* Bottom Right */
- *(float *)data++ = (float) ((surfx + surfw)>>1);
- *(float *)data++ = (float) ((surfy + surfh)>>1);
- *(float *)data++ = (float) subx + subw;
- *(float *)data++ = (float) suby + subh;
- /* Bottom Left */
- *(float *)data++ = (float) (surfx>>1);
- *(float *)data++ = (float) ((surfy + surfh)>>1);
- *(float *)data++ = (float) subx;
- *(float *)data++ = (float) suby + subh;
- /* Top Left */
- *(float *)data++ = (float) (surfx>>1);
- *(float *)data++ = (float) (surfy>>1);
- *(float *)data++ = (float) subx;
- *(float *)data++ = (float) suby;
-
- /* Load and Use Context 0 */
- *data++ = CMD_FLUSH;
- *data++ = (5<<23) | (1<<17) | (1<<16);
- *data++ = CMD_FLUSH;
-
-
- /* Dispatch */
- pDMA->used = (unsigned long)data - (unsigned long)pDMA->address;
- mc.idx = pDMA->idx;
- mc.used = pDMA->used;
- mc.last_render = ++pI810XvMC->last_render;
- privTarget->last_render = pI810XvMC->last_render;
- I810_MC(pI810XvMC,mc);
-
- I810_UNLOCK(pI810XvMC);
- return Success;
-}
-
-
-
-/***************************************************************************
-// Function: XvMCSyncSubpicture
-// Description: This function blocks until all composite/clear requests on
-// the subpicture have been complete.
-// Arguments:
-// display - Connection to the X server.
-// subpicture - The subpicture to synchronize
-//
-// Returns: Status
-***************************************************************************/
-Status XvMCSyncSubpicture(Display *display, XvMCSubpicture *subpicture) {
- Status ret;
- int stat=0;
- do {
- ret = XvMCGetSubpictureStatus(display,subpicture,&stat);
- }while(!ret && (stat & XVMC_RENDERING));
- return ret;
-}
-
-
-
-/***************************************************************************
-// Function: XvMCFlushSubpicture
-// Description: This function commits pending composite/clear requests to
-// ensure that they will be completed in a finite amount of
-// time.
-// Arguments:
-// display - Connection to the X server.
-// subpicture - The subpicture whos compsiting should be flushed
-//
-// Returns: Status
-// NOTES: i810 always dispatches commands so flush is a no-op
-***************************************************************************/
-Status XvMCFlushSubpicture(Display *display, XvMCSubpicture *subpicture) {
- if(display == NULL) {
- return BadValue;
- }
- if(subpicture == NULL) {
- return (error_base + XvMCBadSubpicture);
- }
-
- return Success;
-}
-
-
-
-/***************************************************************************
-// Function: XvMCGetSubpictureStatus
-// Description: This function gets the current status of a subpicture
-//
-// Arguments:
-// display - Connection to the X server.
-// subpicture - The subpicture whos status is being queried
-// stat - The status of the subpicture. It can be any of the following
-// OR'd together:
-// XVMC_RENDERING - Last composite or clear request not completed
-// XVMC_DISPLAYING - Suppicture currently being displayed.
-//
-// Returns: Status
-// Notes: i810 always blends into a third surface so the subpicture is
-// never actually displaying, only a copy of it is displaying. We only
-// have to worry about the rendering case.
-***************************************************************************/
-Status XvMCGetSubpictureStatus(Display *display, XvMCSubpicture *subpicture,
- int *stat) {
-
- i810XvMCSubpicture *privSubpicture;
- i810XvMCContext *pI810XvMC;
-
- if((display == NULL) || (stat == NULL)) {
- return BadValue;
- }
- if((subpicture == NULL) || (subpicture->privData == NULL)) {
- return (error_base + XvMCBadSubpicture);
- }
- *stat = 0;
- privSubpicture = (i810XvMCSubpicture *)subpicture->privData;
-
- pI810XvMC = (i810XvMCContext *)privSubpicture->privContext;
- if(pI810XvMC == NULL) {
- return (error_base + XvMCBadSubpicture);
- }
-
- I810_LOCK(pI810XvMC,0);
-
- if(privSubpicture->last_render &&
- (privSubpicture->last_render > GET_RSTATUS(pI810XvMC))) {
- *stat |= XVMC_RENDERING;
- }
- I810_UNLOCK(pI810XvMC);
-
- return Success;
-}
-
-#define NUM_XVMC_ATTRIBUTES 4
-static XvAttribute I810_XVMC_ATTRIBUTES[] = {
- {XvGettable | XvSettable, 0, 0xffffff, "XV_COLORKEY"},
- {XvGettable | XvSettable, -127, +127, "XV_BRIGHTNESS"},
- {XvGettable | XvSettable, 0, 0x1ff, "XV_CONTRAST"},
- {XvGettable | XvSettable, 0, 0x3ff, "XV_SATURATION"}
-};
-
-
-/***************************************************************************
-// Function: XvMCQueryAttributes
-// Description: An array of XvAttributes of size "number" is returned by
-// this function. If there are no attributes, NULL is returned and number
-// is set to 0. The array may be freed with xfree().
-//
-// Arguments:
-// display - Connection to the X server.
-// context - The context whos attributes we are querying.
-// number - The number of returned atoms.
-//
-// Returns:
-// An array of XvAttributes.
-// Notes:
-// For i810 we support these Attributes:
-// XV_COLORKEY: The colorkey value, initialized from the Xv value at
-// context creation time.
-// XV_BRIGHTNESS
-// XV_CONTRAST
-// XV_SATURATION
-***************************************************************************/
-XvAttribute *XvMCQueryAttributes(Display *display, XvMCContext *context,
- int *number) {
- i810XvMCContext *pI810XvMC;
- XvAttribute *attributes;
-
- if(number == NULL) {
- return NULL;
- }
- if(display == NULL) {
- *number = 0;
- return NULL;
- }
- if(context == NULL) {
- *number = 0;
- return NULL;
- }
- pI810XvMC = context->privData;
- if(pI810XvMC == NULL) {
- *number = 0;
- return NULL;
- }
-
- attributes = (XvAttribute *)malloc(NUM_XVMC_ATTRIBUTES *
- sizeof(XvAttribute));
- if(attributes == NULL) {
- *number = 0;
- return NULL;
- }
-
- memcpy(attributes,I810_XVMC_ATTRIBUTES,(NUM_XVMC_ATTRIBUTES *
- sizeof(XvAttribute)));
-
- *number = NUM_XVMC_ATTRIBUTES;
- return attributes;
-}
-
-/***************************************************************************
-// Function: XvMCSetAttribute
-// Description: This function sets a context-specific attribute.
-//
-// Arguments:
-// display - Connection to the X server.
-// context - The context whos attributes we are querying.
-// attribute - The X atom of the attribute to be changed.
-// value - The new value for the attribute.
-//
-// Returns:
-// Status
-// Notes:
-// For i810 we support these Attributes:
-// XV_COLORKEY: The colorkey value, initialized from the Xv value at
-// context creation time.
-// XV_BRIGHTNESS
-// XV_CONTRAST
-// XV_SATURATION
-***************************************************************************/
-Status XvMCSetAttribute(Display *display, XvMCContext *context,
- Atom attribute, int value) {
- i810XvMCContext *pI810XvMC;
-
- if(display == NULL) {
- return BadValue;
- }
- if(context == NULL) {
- return (error_base + XvMCBadContext);
- }
- pI810XvMC = context->privData;
- if(pI810XvMC == NULL) {
- return (error_base + XvMCBadContext);
- }
-
- if(attribute == pI810XvMC->xv_colorkey) {
- if((value < I810_XVMC_ATTRIBUTES[0].min_value) ||
- (value > I810_XVMC_ATTRIBUTES[0].max_value)) {
- return BadValue;
- }
- pI810XvMC->colorkey = value;
- return Success;
- }
- if(attribute == pI810XvMC->xv_brightness) {
- if((value < I810_XVMC_ATTRIBUTES[1].min_value) ||
- (value > I810_XVMC_ATTRIBUTES[1].max_value)) {
- return BadValue;
- }
- pI810XvMC->brightness = value;
- return Success;
- }
- if(attribute == pI810XvMC->xv_saturation) {
- if((value < I810_XVMC_ATTRIBUTES[2].min_value) ||
- (value > I810_XVMC_ATTRIBUTES[2].max_value)) {
- return BadValue;
- }
- pI810XvMC->saturation = value;
- return Success;
- }
- if(attribute == pI810XvMC->xv_contrast) {
- if((value < I810_XVMC_ATTRIBUTES[3].min_value) ||
- (value > I810_XVMC_ATTRIBUTES[3].max_value)) {
- return BadValue;
- }
- pI810XvMC->contrast = value;
- return Success;
- }
- return BadValue;
-}
-
-/***************************************************************************
-// Function: XvMCGetAttribute
-// Description: This function queries a context-specific attribute and
-// returns the value.
-//
-// Arguments:
-// display - Connection to the X server.
-// context - The context whos attributes we are querying.
-// attribute - The X atom of the attribute to be queried
-// value - The returned attribute value
-//
-// Returns:
-// Status
-// Notes:
-// For i810 we support these Attributes:
-// XV_COLORKEY: The colorkey value, initialized from the Xv value at
-// context creation time.
-// XV_BRIGHTNESS
-// XV_CONTRAST
-// XV_SATURATION
-***************************************************************************/
-Status XvMCGetAttribute(Display *display, XvMCContext *context,
- Atom attribute, int *value) {
- i810XvMCContext *pI810XvMC;
-
- if(display == NULL) {
- return BadValue;
- }
- if(context == NULL) {
- return (error_base + XvMCBadContext);
- }
- pI810XvMC = context->privData;
- if(pI810XvMC == NULL) {
- return (error_base + XvMCBadContext);
- }
- if(value == NULL) {
- return BadValue;
- }
-
- if(attribute == pI810XvMC->xv_colorkey) {
- *value = pI810XvMC->colorkey;
- return Success;
- }
- if(attribute == pI810XvMC->xv_brightness) {
- *value = pI810XvMC->brightness;
- return Success;
- }
- if(attribute == pI810XvMC->xv_saturation) {
- *value = pI810XvMC->saturation;
- return Success;
- }
- if(attribute == pI810XvMC->xv_contrast) {
- *value = pI810XvMC->contrast;
- return Success;
- }
- return BadValue;
-}
-
-
-
-