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