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