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