diff options
Diffstat (limited to 'src/savage_hwmc.c')
-rw-r--r-- | src/savage_hwmc.c | 403 |
1 files changed, 403 insertions, 0 deletions
diff --git a/src/savage_hwmc.c b/src/savage_hwmc.c new file mode 100644 index 0000000..37d314d --- /dev/null +++ b/src/savage_hwmc.c @@ -0,0 +1,403 @@ +/* + * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2003 S3 Graphics, Inc. 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 + * VIA, S3 GRAPHICS, 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. + */ + +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86Resources.h" +#include "xf86_ansic.h" +#include "compiler.h" +#include "xf86PciInfo.h" +#include "xf86Pci.h" +#include "xf86fbman.h" +#include "regionstr.h" + +#include "savage_driver.h" +#include "savage_dri.h" + +#include "xf86xv.h" +#include "xf86xvmc.h" +#include "Xv.h" +#include "XvMC.h" +#include "xaa.h" +#include "xaalocal.h" +#include "dixstruct.h" +#include "fourcc.h" + +#define SAVAGE_MAX_SURFACES 5 +#define SAVAGE_MAX_SUBPICTURES 1 + +#define XVMC_IDCT_8BIT 0x80000000 + + +int SAVAGEXvMCCreateContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext, + int *num_priv, long **priv ); +void SAVAGEXvMCDestroyContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext); + +int SAVAGEXvMCCreateSurface (ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf, + int *num_priv, long **priv ); +void SAVAGEXvMCDestroySurface (ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf); + +int SAVAGEXvMCCreateSubpicture (ScrnInfoPtr pScrn, XvMCSubpicturePtr pSurf, + int *num_priv, long **priv ); +void SAVAGEXvMCDestroySubpicture (ScrnInfoPtr pScrn, XvMCSubpicturePtr pSurf); + + +typedef struct { + drm_context_t drmcontext; + unsigned int fbBase; + unsigned int MMIOHandle; + unsigned int MMIOSize; + unsigned int SurfaceHandle; + unsigned int SurfaceOffset; + unsigned int SurfaceSize; + unsigned int DCTBlockHandle; + unsigned int DCTBlockOffset; + unsigned int DCTBlockSize; + unsigned int ApertureHandle; + unsigned int ApertureSize; + unsigned int bitsPerPixel; + unsigned int frameX0; + unsigned int frameY0; + unsigned int IOBase; + unsigned int displayWidth; + char busIdString[10]; + char pad[2]; +} SAVAGEXvMCCreateContextRec; + + +static int yv12_subpicture_index_list[1] = +{ + FOURCC_IA44 +}; + +static XF86MCImageIDList yv12_subpicture_list = +{ + 1, + yv12_subpicture_index_list +}; + +static XF86MCSurfaceInfoRec savage_YV12_mpg2_surface = +{ + FOURCC_YV12, + XVMC_CHROMA_FORMAT_420, + 0, + 720, + 576, + 720, + 576, + XVMC_MPEG_2, + XVMC_OVERLAID_SURFACE | XVMC_INTRA_UNSIGNED | XVMC_BACKEND_SUBPICTURE | XVMC_IDCT_8BIT, + &yv12_subpicture_list +}; + +static XF86MCSurfaceInfoPtr ppSI[1] = +{ + (XF86MCSurfaceInfoPtr)&savage_YV12_mpg2_surface, +}; + +/* List of subpicture types that we support */ +static XF86ImageRec ia44_subpicture = XVIMAGE_IA44; + +static XF86ImagePtr savage_subpicture_list[1] = +{ + (XF86ImagePtr)&ia44_subpicture, +}; + +/* Fill in the device dependent adaptor record. + * This is named "SAVAGE Video Overlay" because this code falls under the + * XV extenstion, the name must match or it won't be used. + * + * Surface and Subpicture - see above + * Function pointers to functions below + */ +static XF86MCAdaptorRec pAdapt = +{ + "Savage Streams Engine", /* name */ + 1, /* num_surfaces */ + ppSI, /* surfaces */ + 1, /* num_subpictures */ + savage_subpicture_list, /* subpictures */ + (xf86XvMCCreateContextProcPtr)SAVAGEXvMCCreateContext, + (xf86XvMCDestroyContextProcPtr)SAVAGEXvMCDestroyContext, + (xf86XvMCCreateSurfaceProcPtr)SAVAGEXvMCCreateSurface, + (xf86XvMCDestroySurfaceProcPtr)SAVAGEXvMCDestroySurface, + (xf86XvMCCreateSubpictureProcPtr)SAVAGEXvMCCreateSubpicture, + (xf86XvMCDestroySubpictureProcPtr)SAVAGEXvMCDestroySubpicture +}; + +static XF86MCAdaptorPtr ppAdapt[1] = +{ + (XF86MCAdaptorPtr)&pAdapt +}; + +/************************************************************************** + * + * SAVAGEInitMC + * + * Initialize the hardware motion compenstation extention for this + * hardware. The initialization routines want the address of the pointers + * to the structures, not the address of the structures. This means we + * allocate (or create static?) the pointer memory and pass that + * address. This seems a little convoluted. + * + * We need to allocate memory for the device depended adaptor record. + * This is what holds the pointers to all our device functions. + * + * We need to map the overlay registers into the drm. + * + * We need to map the surfaces into the drm. + * + * Inputs: + * Screen pointer + * + * Outputs: + * None, this calls the device independent screen initialization + * function. + * + * Revisions: + * + **************************************************************************/ +Bool SAVAGEInitMC(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + SavagePtr pSAVAGE = SAVPTR(pScrn); + DRIInfoPtr pDRIInfo = pSAVAGE->pDRIInfo; + SAVAGEDRIPtr pSAVAGEDriPriv = (SAVAGEDRIPtr)pDRIInfo->devPrivate; + int i; + unsigned int offset; + + /* Clear the Surface Allocation */ + for(i=0; i<SAVAGE_MAX_SURFACES; i++) { + pSAVAGE->surfaceAllocation[i] = 0; + } + + if(pSAVAGE->hwmcSize == 0) + { + xf86DrvMsg(X_ERROR, pScrn->scrnIndex, + "SAVAGEInitMC: There is not enough memory!\n"); + return FALSE; + } + + offset = pSAVAGE->hwmcOffset + pSAVAGE->FrameBufferBase; + + if(drmAddMap(pSAVAGE->drmFD, offset, pSAVAGE->hwmcSize, + DRM_FRAME_BUFFER, 0, &pSAVAGEDriPriv->xvmcSurfHandle) < 0) + { + + xf86DrvMsg(X_ERROR, pScrn->scrnIndex, + "SAVAGEInitMC: Cannot add map to drm!\n"); + return FALSE; + } + + return xf86XvMCScreenInit(pScreen, 1, ppAdapt); +} + +/************************************************************************** + * + * SAVAGEXvMCCreateContext + * + * Some info about the private data: + * + * Set *num_priv to the number of 32bit words that make up the size of + * of the data that priv will point to. + * + * *priv = (long *) xcalloc (elements, sizeof(element)) + * *num_priv = (elements * sizeof(element)) >> 2; + * + **************************************************************************/ + +int SAVAGEXvMCCreateContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext, + int *num_priv, long **priv ) +{ + SavagePtr pSAVAGE = SAVPTR(pScrn); + DRIInfoPtr pDRIInfo = pSAVAGE->pDRIInfo; + SAVAGEDRIPtr pSAVAGEDriPriv = (SAVAGEDRIPtr)pDRIInfo->devPrivate; + SAVAGEXvMCCreateContextRec *contextRec; + vgaHWPtr hwp = VGAHWPTR(pScrn); + + + if(!pSAVAGE->directRenderingEnabled) { + xf86DrvMsg(X_ERROR, pScrn->scrnIndex, + "SAVAGEXvMCCreateContext: Cannot use XvMC without DRI!\n"); + return BadAlloc; + } + + /* Context Already in use! */ + if(pSAVAGE->xvmcContext) { + xf86DrvMsg(X_WARNING, pScrn->scrnIndex, + "SAVAGEXvMCCreateContext: 2 XvMC Contexts Attempted, not supported.\n"); + return BadAlloc; + } + + *priv = xcalloc(1,sizeof(SAVAGEXvMCCreateContextRec)); + contextRec = (SAVAGEXvMCCreateContextRec *)*priv; + + if(!*priv) { + *num_priv = 0; + return(BadAlloc); + } + + *num_priv = sizeof(SAVAGEXvMCCreateContextRec) >> 2; + + if(drmCreateContext(pSAVAGE->drmFD, &(contextRec->drmcontext) ) < 0) { + xf86DrvMsg(X_ERROR, pScrn->scrnIndex, + "SAVAGEXvMCCreateContext: Unable to create DRMContext!\n"); + xfree(*priv); + return(BadAlloc); + } + + drmAuthMagic(pSAVAGE->drmFD, pContext->flags); + + pSAVAGE->xvmcContext = contextRec->drmcontext; + contextRec->fbBase = pScrn->memPhysBase; + + contextRec->MMIOHandle = pSAVAGEDriPriv->registers.handle; + contextRec->MMIOSize = pSAVAGEDriPriv->registers.size; + + contextRec->DCTBlockHandle = pSAVAGEDriPriv->agpTextures.handle; + contextRec->DCTBlockOffset = pSAVAGEDriPriv->agpTextures.offset; + contextRec->DCTBlockSize = pSAVAGEDriPriv->agpTextures.size; + + contextRec->SurfaceHandle = pSAVAGEDriPriv->xvmcSurfHandle; + contextRec->SurfaceOffset = pSAVAGE->hwmcOffset; + contextRec->SurfaceSize = pSAVAGE->hwmcSize; + + contextRec->ApertureHandle = pSAVAGEDriPriv->aperture.handle; + contextRec->ApertureSize = pSAVAGEDriPriv->aperture.size; + + contextRec->bitsPerPixel = pScrn->bitsPerPixel; + contextRec->frameX0 = pScrn->frameX0; + contextRec->frameY0 = pScrn->frameY0; + contextRec->IOBase = hwp->IOBase; + contextRec->displayWidth = pScrn->displayWidth; + + + strncpy (contextRec->busIdString, pDRIInfo->busIdString, 9); + + return Success; +} + + +int SAVAGEXvMCCreateSurface (ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf, + int *num_priv, long **priv ) +{ + SavagePtr pSAVAGE = SAVPTR(pScrn); + int i; + /* This size is used for flip, mixer, subpicture and palette buffers*/ + unsigned int offset = ((786*576*2 + 2048)*5 + 2048) & 0xfffff800; + + *priv = (long *)xcalloc(2,sizeof(long)); + + if(!*priv) { + xf86DrvMsg(X_ERROR, pScrn->scrnIndex, + "SAVAGEXvMCCreateSurface: Unable to allocate memory!\n"); + *num_priv = 0; + return (BadAlloc); + } + *num_priv = 1; + + /* Surface Arrangement is different based on 6 or 7 Surfaces */ + for(i = 0; i < SAVAGE_MAX_SURFACES; i++) { + if(!pSAVAGE->surfaceAllocation[i]) { + pSAVAGE->surfaceAllocation[i] = pSurf->surface_id; + (*priv)[0] = offset + (576 * 786 * 2 + 2048) * i; + /* UV data starts at 0 offset, each set is 288k * */ + return Success; + } + } + + (*priv)[0] = 0; + return BadAlloc; +} + +int SAVAGEXvMCCreateSubpicture (ScrnInfoPtr pScrn, XvMCSubpicturePtr pSubp, + int *num_priv, long **priv ) +{ + SavagePtr pSAVAGE = SAVPTR(pScrn); + int i; + + *priv = (long *)xcalloc(1,sizeof(long)); + + if(!*priv) { + xf86DrvMsg(X_ERROR, pScrn->scrnIndex, + "SAVAGEXvMCCreateSubpicture: Unable to allocate memory!\n"); + *num_priv = 0; + return (BadAlloc); + } + + *num_priv = 1; + + for(i = SAVAGE_MAX_SURFACES; i < SAVAGE_MAX_SURFACES + SAVAGE_MAX_SUBPICTURES; i++) { + if(!pSAVAGE->surfaceAllocation[i]) { + pSAVAGE->surfaceAllocation[i] = pSubp->subpicture_id; + (*priv)[0] = ( 576*1024 * i); + return Success; + } + } + + (*priv)[0] = 0; + return BadAlloc; +} + +void SAVAGEXvMCDestroyContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext) +{ + SavagePtr pSAVAGE = SAVPTR(pScrn); + + drmDestroyContext(pSAVAGE->drmFD,pSAVAGE->xvmcContext); + pSAVAGE->xvmcContext = 0; +} + +void SAVAGEXvMCDestroySurface (ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf) +{ + SavagePtr pSAVAGE = SAVPTR(pScrn); + int i; + + for(i=0; i<SAVAGE_MAX_SURFACES; i++) { + if(pSAVAGE->surfaceAllocation[i] == pSurf->surface_id) { + pSAVAGE->surfaceAllocation[i] = 0; + return; + } + } + return; +} + +void SAVAGEXvMCDestroySubpicture (ScrnInfoPtr pScrn, XvMCSubpicturePtr pSubp) +{ + SavagePtr pSAVAGE = SAVPTR(pScrn); + int i; + + for(i = SAVAGE_MAX_SURFACES; i < SAVAGE_MAX_SURFACES + SAVAGE_MAX_SUBPICTURES; i++) { + if(pSAVAGE->surfaceAllocation[i] == pSubp->subpicture_id) { + pSAVAGE->surfaceAllocation[i] = 0; + return; + } + } + return; +} + + + + + + |