savage_hwmc.c revision aa9e3350
1/* 2 * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. 3 * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * the rights to use, copy, modify, merge, publish, distribute, sub license, 9 * and/or sell copies of the Software, and to permit persons to whom the 10 * Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice (including the 13 * next paragraph) shall be included in all copies or substantial portions 14 * of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 19 * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 * DEALINGS IN THE SOFTWARE. 23 */ 24 25#ifdef HAVE_CONFIG_H 26#include "config.h" 27#endif 28 29#include "xf86.h" 30#include "xf86_OSproc.h" 31#include "compiler.h" 32#include "xf86Pci.h" 33#include "xf86fbman.h" 34#include "regionstr.h" 35 36#include "savage_driver.h" 37#include "savage_dri.h" 38 39#include "xf86xv.h" 40#include "xf86xvmc.h" 41#include <X11/extensions/Xv.h> 42#include <X11/extensions/XvMC.h> 43#ifdef HAVE_XAA_H 44#include "xaalocal.h" 45#endif 46#include "dixstruct.h" 47#include "fourcc.h" 48 49#define SAVAGE_MAX_SURFACES 5 50#define SAVAGE_MAX_SUBPICTURES 1 51 52#define XVMC_IDCT_8BIT 0x80000000 53 54 55int SAVAGEXvMCCreateContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext, 56 int *num_priv, long **priv ); 57void SAVAGEXvMCDestroyContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext); 58 59int SAVAGEXvMCCreateSurface (ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf, 60 int *num_priv, long **priv ); 61void SAVAGEXvMCDestroySurface (ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf); 62 63int SAVAGEXvMCCreateSubpicture (ScrnInfoPtr pScrn, XvMCSubpicturePtr pSurf, 64 int *num_priv, long **priv ); 65void SAVAGEXvMCDestroySubpicture (ScrnInfoPtr pScrn, XvMCSubpicturePtr pSurf); 66 67 68typedef struct { 69 drm_context_t drmcontext; 70 unsigned int fbBase; 71 unsigned int MMIOHandle; 72 unsigned int MMIOSize; 73 unsigned int SurfaceHandle; 74 unsigned int SurfaceOffset; 75 unsigned int SurfaceSize; 76 unsigned int DCTBlockHandle; 77 unsigned int DCTBlockOffset; 78 unsigned int DCTBlockSize; 79 unsigned int ApertureHandle; 80 unsigned int ApertureSize; 81 unsigned int bitsPerPixel; 82 unsigned int frameX0; 83 unsigned int frameY0; 84 unsigned int IOBase; 85 unsigned int displayWidth; 86 char busIdString[10]; 87 char pad[2]; 88} SAVAGEXvMCCreateContextRec; 89 90 91static int yv12_subpicture_index_list[1] = 92{ 93 FOURCC_IA44 94}; 95 96static XF86MCImageIDList yv12_subpicture_list = 97{ 98 1, 99 yv12_subpicture_index_list 100}; 101 102static XF86MCSurfaceInfoRec savage_YV12_mpg2_surface = 103{ 104 FOURCC_YV12, 105 XVMC_CHROMA_FORMAT_420, 106 0, 107 720, 108 576, 109 720, 110 576, 111 XVMC_MPEG_2, 112 XVMC_OVERLAID_SURFACE | XVMC_INTRA_UNSIGNED | XVMC_BACKEND_SUBPICTURE | XVMC_IDCT_8BIT, 113 &yv12_subpicture_list 114}; 115 116static XF86MCSurfaceInfoPtr ppSI[1] = 117{ 118 (XF86MCSurfaceInfoPtr)&savage_YV12_mpg2_surface, 119}; 120 121/* List of subpicture types that we support */ 122static XF86ImageRec ia44_subpicture = XVIMAGE_IA44; 123 124static XF86ImagePtr savage_subpicture_list[1] = 125{ 126 (XF86ImagePtr)&ia44_subpicture, 127}; 128 129/* Fill in the device dependent adaptor record. 130 * This is named "SAVAGE Video Overlay" because this code falls under the 131 * XV extenstion, the name must match or it won't be used. 132 * 133 * Surface and Subpicture - see above 134 * Function pointers to functions below 135 */ 136static XF86MCAdaptorRec pAdapt = 137{ 138 "Savage Streams Engine", /* name */ 139 1, /* num_surfaces */ 140 ppSI, /* surfaces */ 141 1, /* num_subpictures */ 142 savage_subpicture_list, /* subpictures */ 143 (xf86XvMCCreateContextProcPtr)SAVAGEXvMCCreateContext, 144 (xf86XvMCDestroyContextProcPtr)SAVAGEXvMCDestroyContext, 145 (xf86XvMCCreateSurfaceProcPtr)SAVAGEXvMCCreateSurface, 146 (xf86XvMCDestroySurfaceProcPtr)SAVAGEXvMCDestroySurface, 147 (xf86XvMCCreateSubpictureProcPtr)SAVAGEXvMCCreateSubpicture, 148 (xf86XvMCDestroySubpictureProcPtr)SAVAGEXvMCDestroySubpicture 149}; 150 151static XF86MCAdaptorPtr ppAdapt[1] = 152{ 153 (XF86MCAdaptorPtr)&pAdapt 154}; 155 156/************************************************************************** 157 * 158 * SAVAGEInitMC 159 * 160 * Initialize the hardware motion compenstation extention for this 161 * hardware. The initialization routines want the address of the pointers 162 * to the structures, not the address of the structures. This means we 163 * allocate (or create static?) the pointer memory and pass that 164 * address. This seems a little convoluted. 165 * 166 * We need to allocate memory for the device depended adaptor record. 167 * This is what holds the pointers to all our device functions. 168 * 169 * We need to map the overlay registers into the drm. 170 * 171 * We need to map the surfaces into the drm. 172 * 173 * Inputs: 174 * Screen pointer 175 * 176 * Outputs: 177 * None, this calls the device independent screen initialization 178 * function. 179 * 180 * Revisions: 181 * 182 **************************************************************************/ 183Bool SAVAGEInitMC(ScreenPtr pScreen) 184{ 185 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 186 SavagePtr pSAVAGE = SAVPTR(pScrn); 187 DRIInfoPtr pDRIInfo = pSAVAGE->pDRIInfo; 188 SAVAGEDRIPtr pSAVAGEDriPriv = (SAVAGEDRIPtr)pDRIInfo->devPrivate; 189 int i; 190 unsigned int offset; 191 192 /* Clear the Surface Allocation */ 193 for(i=0; i<SAVAGE_MAX_SURFACES; i++) { 194 pSAVAGE->surfaceAllocation[i] = 0; 195 } 196 197 if(pSAVAGE->hwmcSize == 0) 198 { 199 xf86DrvMsg(X_ERROR, pScrn->scrnIndex, 200 "SAVAGEInitMC: There is not enough memory!\n"); 201 return FALSE; 202 } 203 204 offset = pSAVAGE->hwmcOffset + pSAVAGE->FbRegion.base; 205 206 if(drmAddMap(pSAVAGE->drmFD, offset, pSAVAGE->hwmcSize, 207 DRM_FRAME_BUFFER, 0, &pSAVAGEDriPriv->xvmcSurfHandle) < 0) 208 { 209 210 xf86DrvMsg(X_ERROR, pScrn->scrnIndex, 211 "SAVAGEInitMC: Cannot add map to drm!\n"); 212 return FALSE; 213 } 214 215 return xf86XvMCScreenInit(pScreen, 1, ppAdapt); 216} 217 218/************************************************************************** 219 * 220 * SAVAGEXvMCCreateContext 221 * 222 * Some info about the private data: 223 * 224 * Set *num_priv to the number of 32bit words that make up the size of 225 * of the data that priv will point to. 226 * 227 * *priv = (long *) calloc (elements, sizeof(element)) 228 * *num_priv = (elements * sizeof(element)) >> 2; 229 * 230 **************************************************************************/ 231 232int SAVAGEXvMCCreateContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext, 233 int *num_priv, long **priv ) 234{ 235 SavagePtr pSAVAGE = SAVPTR(pScrn); 236 DRIInfoPtr pDRIInfo = pSAVAGE->pDRIInfo; 237 SAVAGEDRIPtr pSAVAGEDriPriv = (SAVAGEDRIPtr)pDRIInfo->devPrivate; 238 SAVAGEDRIServerPrivatePtr pSAVAGEDRIServer = pSAVAGE->DRIServerInfo; 239 SAVAGEXvMCCreateContextRec *contextRec; 240 vgaHWPtr hwp = VGAHWPTR(pScrn); 241 242 243 if(!pSAVAGE->directRenderingEnabled) { 244 xf86DrvMsg(X_ERROR, pScrn->scrnIndex, 245 "SAVAGEXvMCCreateContext: Cannot use XvMC without DRI!\n"); 246 return BadAlloc; 247 } 248 249 /* Context Already in use! */ 250 if(pSAVAGE->xvmcContext) { 251 xf86DrvMsg(X_WARNING, pScrn->scrnIndex, 252 "SAVAGEXvMCCreateContext: 2 XvMC Contexts Attempted, not supported.\n"); 253 return BadAlloc; 254 } 255 256 *priv = calloc(1,sizeof(SAVAGEXvMCCreateContextRec)); 257 contextRec = (SAVAGEXvMCCreateContextRec *)*priv; 258 259 if(!*priv) { 260 *num_priv = 0; 261 return(BadAlloc); 262 } 263 264 *num_priv = sizeof(SAVAGEXvMCCreateContextRec) >> 2; 265 266 if(drmCreateContext(pSAVAGE->drmFD, &(contextRec->drmcontext) ) < 0) { 267 xf86DrvMsg(X_ERROR, pScrn->scrnIndex, 268 "SAVAGEXvMCCreateContext: Unable to create DRMContext!\n"); 269 free(*priv); 270 return(BadAlloc); 271 } 272 273 drmAuthMagic(pSAVAGE->drmFD, pContext->flags); 274 275 pSAVAGE->xvmcContext = contextRec->drmcontext; 276 contextRec->fbBase = pScrn->memPhysBase; 277 278 contextRec->MMIOHandle = pSAVAGEDRIServer->registers.handle; 279 contextRec->MMIOSize = pSAVAGEDRIServer->registers.size; 280 281 contextRec->DCTBlockHandle = pSAVAGEDRIServer->agpTextures.handle; 282 contextRec->DCTBlockOffset = pSAVAGEDRIServer->agpTextures.offset; 283 contextRec->DCTBlockSize = pSAVAGEDRIServer->agpTextures.size; 284 285 contextRec->SurfaceHandle = pSAVAGEDriPriv->xvmcSurfHandle; 286 contextRec->SurfaceOffset = pSAVAGE->hwmcOffset; 287 contextRec->SurfaceSize = pSAVAGE->hwmcSize; 288 289 contextRec->ApertureHandle = pSAVAGEDriPriv->apertureHandle; 290 contextRec->ApertureSize = pSAVAGEDriPriv->apertureSize; 291 292 contextRec->bitsPerPixel = pScrn->bitsPerPixel; 293 contextRec->frameX0 = pScrn->frameX0; 294 contextRec->frameY0 = pScrn->frameY0; 295 contextRec->IOBase = hwp->IOBase; 296 contextRec->displayWidth = pScrn->displayWidth; 297 298 299 strncpy (contextRec->busIdString, pDRIInfo->busIdString, 9); 300 301 return Success; 302} 303 304 305int SAVAGEXvMCCreateSurface (ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf, 306 int *num_priv, long **priv ) 307{ 308 SavagePtr pSAVAGE = SAVPTR(pScrn); 309 int i; 310 /* This size is used for flip, mixer, subpicture and palette buffers*/ 311 unsigned int offset = ((786*576*2 + 2048)*5 + 2048) & 0xfffff800; 312 313 *priv = (long *)calloc(2,sizeof(long)); 314 315 if(!*priv) { 316 xf86DrvMsg(X_ERROR, pScrn->scrnIndex, 317 "SAVAGEXvMCCreateSurface: Unable to allocate memory!\n"); 318 *num_priv = 0; 319 return (BadAlloc); 320 } 321 *num_priv = 1; 322 323 /* Surface Arrangement is different based on 6 or 7 Surfaces */ 324 for(i = 0; i < SAVAGE_MAX_SURFACES; i++) { 325 if(!pSAVAGE->surfaceAllocation[i]) { 326 pSAVAGE->surfaceAllocation[i] = pSurf->surface_id; 327 (*priv)[0] = offset + (576 * 786 * 2 + 2048) * i; 328 /* UV data starts at 0 offset, each set is 288k * */ 329 return Success; 330 } 331 } 332 333 (*priv)[0] = 0; 334 return BadAlloc; 335} 336 337int SAVAGEXvMCCreateSubpicture (ScrnInfoPtr pScrn, XvMCSubpicturePtr pSubp, 338 int *num_priv, long **priv ) 339{ 340 SavagePtr pSAVAGE = SAVPTR(pScrn); 341 int i; 342 343 *priv = (long *)calloc(1,sizeof(long)); 344 345 if(!*priv) { 346 xf86DrvMsg(X_ERROR, pScrn->scrnIndex, 347 "SAVAGEXvMCCreateSubpicture: Unable to allocate memory!\n"); 348 *num_priv = 0; 349 return (BadAlloc); 350 } 351 352 *num_priv = 1; 353 354 for(i = SAVAGE_MAX_SURFACES; i < SAVAGE_MAX_SURFACES + SAVAGE_MAX_SUBPICTURES; i++) { 355 if(!pSAVAGE->surfaceAllocation[i]) { 356 pSAVAGE->surfaceAllocation[i] = pSubp->subpicture_id; 357 (*priv)[0] = ( 576*1024 * i); 358 return Success; 359 } 360 } 361 362 (*priv)[0] = 0; 363 return BadAlloc; 364} 365 366void SAVAGEXvMCDestroyContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext) 367{ 368 SavagePtr pSAVAGE = SAVPTR(pScrn); 369 370 drmDestroyContext(pSAVAGE->drmFD,pSAVAGE->xvmcContext); 371 pSAVAGE->xvmcContext = 0; 372} 373 374void SAVAGEXvMCDestroySurface (ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf) 375{ 376 SavagePtr pSAVAGE = SAVPTR(pScrn); 377 int i; 378 379 for(i=0; i<SAVAGE_MAX_SURFACES; i++) { 380 if(pSAVAGE->surfaceAllocation[i] == pSurf->surface_id) { 381 pSAVAGE->surfaceAllocation[i] = 0; 382 return; 383 } 384 } 385 return; 386} 387 388void SAVAGEXvMCDestroySubpicture (ScrnInfoPtr pScrn, XvMCSubpicturePtr pSubp) 389{ 390 SavagePtr pSAVAGE = SAVPTR(pScrn); 391 int i; 392 393 for(i = SAVAGE_MAX_SURFACES; i < SAVAGE_MAX_SURFACES + SAVAGE_MAX_SUBPICTURES; i++) { 394 if(pSAVAGE->surfaceAllocation[i] == pSubp->subpicture_id) { 395 pSAVAGE->surfaceAllocation[i] = 0; 396 return; 397 } 398 } 399 return; 400} 401 402 403 404 405 406 407