~ubuntu-branches/ubuntu/precise/mesa/precise-updates

« back to all changes in this revision

Viewing changes to src/mesa/drivers/dri/mach64/mach64_screen.c

  • Committer: Package Import Robot
  • Author(s): Robert Hooker
  • Date: 2012-02-02 12:05:48 UTC
  • mfrom: (1.7.1) (3.3.27 sid)
  • Revision ID: package-import@ubuntu.com-20120202120548-nvkma85jq0h4coix
Tags: 8.0~rc2-0ubuntu4
Drop drisearchdir handling, it is no longer needed with multiarch
and dri-alternates being removed.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* -*- mode: c; c-basic-offset: 3 -*- */
2
 
/*
3
 
 * Copyright 2000 Gareth Hughes
4
 
 * All Rights Reserved.
5
 
 *
6
 
 * Permission is hereby granted, free of charge, to any person obtaining a
7
 
 * copy of this software and associated documentation files (the "Software"),
8
 
 * to deal in the Software without restriction, including without limitation
9
 
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
 
 * and/or sell copies of the Software, and to permit persons to whom the
11
 
 * Software is furnished to do so, subject to the following conditions:
12
 
 *
13
 
 * The above copyright notice and this permission notice (including the next
14
 
 * paragraph) shall be included in all copies or substantial portions of the
15
 
 * Software.
16
 
 *
17
 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
 
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
 
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20
 
 * GARETH HUGHES BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21
 
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22
 
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
 
 */
24
 
 
25
 
/*
26
 
 * Authors:
27
 
 *      Gareth Hughes <gareth@valinux.com>
28
 
 *      Leif Delgass <ldelgass@retinalburn.net>
29
 
 *      Jos�Fonseca <j_r_fonseca@yahoo.co.uk>
30
 
 */
31
 
 
32
 
#include "mach64_context.h"
33
 
#include "mach64_ioctl.h"
34
 
#include "mach64_span.h"
35
 
 
36
 
#include "main/context.h"
37
 
#include "main/imports.h"
38
 
#include "main/framebuffer.h"
39
 
#include "main/renderbuffer.h"
40
 
 
41
 
#include "utils.h"
42
 
#include "vblank.h"
43
 
 
44
 
#include "GL/internal/dri_interface.h"
45
 
 
46
 
/* Mach64 configuration
47
 
 */
48
 
#include "xmlpool.h"
49
 
 
50
 
PUBLIC const char __driConfigOptions[] =
51
 
DRI_CONF_BEGIN
52
 
    DRI_CONF_SECTION_PERFORMANCE
53
 
        DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0)
54
 
    DRI_CONF_SECTION_END
55
 
    DRI_CONF_SECTION_DEBUG
56
 
        DRI_CONF_NO_RAST(false)
57
 
#if ENABLE_PERF_BOXES
58
 
        DRI_CONF_PERFORMANCE_BOXES(false)
59
 
#endif
60
 
    DRI_CONF_SECTION_END
61
 
DRI_CONF_END;
62
 
#if ENABLE_PERF_BOXES
63
 
static const GLuint __driNConfigOptions = 3;
64
 
#else
65
 
static const GLuint __driNConfigOptions = 2;
66
 
#endif
67
 
 
68
 
static const __DRIconfig **
69
 
mach64FillInModes( __DRIscreen *psp,
70
 
                   unsigned pixel_bits, unsigned depth_bits,
71
 
                   unsigned stencil_bits, GLboolean have_back_buffer )
72
 
{
73
 
    __DRIconfig **configs;
74
 
    struct gl_config * m;
75
 
    GLenum fb_format;
76
 
    GLenum fb_type;
77
 
    unsigned depth_buffer_factor;
78
 
    unsigned back_buffer_factor;
79
 
    unsigned i;
80
 
 
81
 
    /* Right now GLX_SWAP_COPY_OML isn't supported, but it would be easy
82
 
     * enough to add support.  Basically, if a context is created with an
83
 
     * fbconfig where the swap method is GLX_SWAP_COPY_OML, pageflipping
84
 
     * will never be used.
85
 
     */
86
 
    static const GLenum back_buffer_modes[] = {
87
 
        GLX_NONE, GLX_SWAP_UNDEFINED_OML /*, GLX_SWAP_COPY_OML */
88
 
    };
89
 
 
90
 
    uint8_t depth_bits_array[2];
91
 
    uint8_t stencil_bits_array[2];
92
 
    uint8_t msaa_samples_array[1];
93
 
 
94
 
    depth_bits_array[0] = depth_bits;
95
 
    depth_bits_array[1] = depth_bits;
96
 
    
97
 
    /* Just like with the accumulation buffer, always provide some modes
98
 
     * with a stencil buffer.  It will be a sw fallback, but some apps won't
99
 
     * care about that.
100
 
     */
101
 
    stencil_bits_array[0] = 0;
102
 
    stencil_bits_array[1] = (stencil_bits == 0) ? 8 : stencil_bits;
103
 
 
104
 
    msaa_samples_array[0] = 0;
105
 
 
106
 
    depth_buffer_factor = ((depth_bits != 0) || (stencil_bits != 0)) ? 2 : 1;
107
 
    back_buffer_factor  = (have_back_buffer) ? 2 : 1;
108
 
 
109
 
    if (pixel_bits == 16) {
110
 
       fb_format = GL_RGB;
111
 
       fb_type = GL_UNSIGNED_SHORT_5_6_5;
112
 
    }
113
 
    else {
114
 
       fb_format = GL_BGRA;
115
 
       fb_type = GL_UNSIGNED_INT_8_8_8_8_REV;
116
 
    }
117
 
 
118
 
    configs = driCreateConfigs(fb_format, fb_type,
119
 
                               depth_bits_array, stencil_bits_array,
120
 
                               depth_buffer_factor, back_buffer_modes,
121
 
                               back_buffer_factor,
122
 
                               msaa_samples_array, 1, GL_TRUE);
123
 
    if (configs == NULL) {
124
 
       fprintf(stderr, "[%s:%u] Error creating FBConfig!\n",
125
 
               __func__, __LINE__);
126
 
       return NULL;
127
 
    }
128
 
 
129
 
    /* Mark the visual as slow if there are "fake" stencil bits.
130
 
     */
131
 
    for (i = 0; configs[i]; i++) {
132
 
       m = &configs[i]->modes;
133
 
       if ((m->stencilBits != 0) && (m->stencilBits != stencil_bits)) {
134
 
          m->visualRating = GLX_SLOW_CONFIG;
135
 
       }
136
 
    }
137
 
 
138
 
    return (const __DRIconfig **) configs;
139
 
}
140
 
 
141
 
 
142
 
/* Create the device specific screen private data struct.
143
 
 */
144
 
static mach64ScreenRec *
145
 
mach64CreateScreen( __DRIscreen *sPriv )
146
 
{
147
 
   mach64ScreenPtr mach64Screen;
148
 
   ATIDRIPtr serverInfo = (ATIDRIPtr)sPriv->pDevPriv;
149
 
   int i;
150
 
 
151
 
   if (sPriv->devPrivSize != sizeof(ATIDRIRec)) {
152
 
      fprintf(stderr,"\nERROR!  sizeof(ATIDRIRec) does not match passed size from device driver\n");
153
 
      return GL_FALSE;
154
 
   }
155
 
 
156
 
   if ( MACH64_DEBUG & DEBUG_VERBOSE_DRI ) 
157
 
      fprintf( stderr, "%s\n", __FUNCTION__ );
158
 
 
159
 
   /* Allocate the private area */
160
 
   mach64Screen = (mach64ScreenPtr) CALLOC( sizeof(*mach64Screen) );
161
 
   if ( !mach64Screen ) return NULL;
162
 
 
163
 
   /* parse information in __driConfigOptions */
164
 
   driParseOptionInfo (&mach64Screen->optionCache,
165
 
                       __driConfigOptions, __driNConfigOptions);
166
 
 
167
 
   mach64Screen->IsPCI = serverInfo->IsPCI;
168
 
 
169
 
   {
170
 
      drm_mach64_getparam_t gp;
171
 
      int ret;
172
 
 
173
 
      gp.param = MACH64_PARAM_IRQ_NR;
174
 
      gp.value = (void *) &mach64Screen->irq;
175
 
 
176
 
      ret = drmCommandWriteRead( sPriv->fd, DRM_MACH64_GETPARAM,
177
 
                                    &gp, sizeof(gp));
178
 
      if (ret) {
179
 
         fprintf(stderr, "DRM_MACH64_GETPARAM (MACH64_PARAM_IRQ_NR): %d\n", ret);
180
 
         FREE( mach64Screen );
181
 
         return NULL;
182
 
      }
183
 
   }
184
 
 
185
 
   mach64Screen->mmio.handle = serverInfo->regs;
186
 
   mach64Screen->mmio.size   = serverInfo->regsSize;
187
 
   if ( drmMap( sPriv->fd,
188
 
                mach64Screen->mmio.handle,
189
 
                mach64Screen->mmio.size,
190
 
                (drmAddressPtr)&mach64Screen->mmio.map ) != 0 ) {
191
 
      FREE( mach64Screen );
192
 
      return NULL;
193
 
   }
194
 
 
195
 
   mach64Screen->buffers = drmMapBufs( sPriv->fd );
196
 
   if ( !mach64Screen->buffers ) {
197
 
      drmUnmap( (drmAddress)mach64Screen->mmio.map,
198
 
                mach64Screen->mmio.size );
199
 
      FREE( mach64Screen );
200
 
      return NULL;
201
 
   }
202
 
 
203
 
   if ( !mach64Screen->IsPCI ) {
204
 
      mach64Screen->agpTextures.handle = serverInfo->agp;
205
 
      mach64Screen->agpTextures.size   = serverInfo->agpSize;
206
 
      if ( drmMap( sPriv->fd,
207
 
                   mach64Screen->agpTextures.handle,
208
 
                   mach64Screen->agpTextures.size,
209
 
                   (drmAddressPtr)&mach64Screen->agpTextures.map ) ) {
210
 
         drmUnmapBufs( mach64Screen->buffers );
211
 
         drmUnmap( (drmAddress)mach64Screen->mmio.map, mach64Screen->mmio.size );
212
 
         FREE( mach64Screen );
213
 
         return NULL;
214
 
      }
215
 
   }
216
 
 
217
 
   mach64Screen->AGPMode        = serverInfo->AGPMode;
218
 
 
219
 
   mach64Screen->chipset        = serverInfo->chipset;
220
 
   mach64Screen->width          = serverInfo->width;
221
 
   mach64Screen->height         = serverInfo->height;
222
 
   mach64Screen->mem            = serverInfo->mem;
223
 
   mach64Screen->cpp            = serverInfo->cpp;
224
 
 
225
 
   mach64Screen->frontOffset    = serverInfo->frontOffset;
226
 
   mach64Screen->frontPitch     = serverInfo->frontPitch;
227
 
   mach64Screen->backOffset     = serverInfo->backOffset;
228
 
   mach64Screen->backPitch      = serverInfo->backPitch;
229
 
   mach64Screen->depthOffset    = serverInfo->depthOffset;
230
 
   mach64Screen->depthPitch     = serverInfo->depthPitch;
231
 
 
232
 
   mach64Screen->texOffset[MACH64_CARD_HEAP] = serverInfo->textureOffset;
233
 
   mach64Screen->texSize[MACH64_CARD_HEAP] = serverInfo->textureSize;
234
 
   mach64Screen->logTexGranularity[MACH64_CARD_HEAP] =
235
 
      serverInfo->logTextureGranularity;
236
 
 
237
 
   if ( mach64Screen->IsPCI ) {
238
 
      mach64Screen->numTexHeaps = MACH64_NR_TEX_HEAPS - 1;
239
 
      mach64Screen->firstTexHeap = MACH64_CARD_HEAP;
240
 
      mach64Screen->texOffset[MACH64_AGP_HEAP] = 0;
241
 
      mach64Screen->texSize[MACH64_AGP_HEAP] = 0;
242
 
      mach64Screen->logTexGranularity[MACH64_AGP_HEAP] = 0;
243
 
   } else {
244
 
      if (serverInfo->textureSize > 0) {
245
 
         mach64Screen->numTexHeaps = MACH64_NR_TEX_HEAPS;
246
 
         mach64Screen->firstTexHeap = MACH64_CARD_HEAP;
247
 
      } else {
248
 
         mach64Screen->numTexHeaps = MACH64_NR_TEX_HEAPS - 1;
249
 
         mach64Screen->firstTexHeap = MACH64_AGP_HEAP;
250
 
      }
251
 
      mach64Screen->texOffset[MACH64_AGP_HEAP] = serverInfo->agpTextureOffset;
252
 
      mach64Screen->texSize[MACH64_AGP_HEAP] = serverInfo->agpSize;
253
 
      mach64Screen->logTexGranularity[MACH64_AGP_HEAP] = serverInfo->logAgpTextureGranularity;
254
 
   }
255
 
 
256
 
   mach64Screen->driScreen = sPriv;
257
 
 
258
 
   i = 0;
259
 
   if ( mach64Screen->irq != 0 ) {
260
 
      mach64Screen->extensions[i++] = &driSwapControlExtension.base;
261
 
      mach64Screen->extensions[i++] = &driMediaStreamCounterExtension.base;
262
 
   }
263
 
   mach64Screen->extensions[i++] = NULL;
264
 
   sPriv->extensions = mach64Screen->extensions;
265
 
 
266
 
   return mach64Screen;
267
 
}
268
 
 
269
 
/* Destroy the device specific screen private data struct.
270
 
 */
271
 
static void
272
 
mach64DestroyScreen( __DRIscreen *driScreen )
273
 
{
274
 
   mach64ScreenRec *mach64Screen = (mach64ScreenRec *) driScreen->private;
275
 
 
276
 
   if ( !mach64Screen )
277
 
      return;
278
 
 
279
 
   if ( MACH64_DEBUG & DEBUG_VERBOSE_DRI ) 
280
 
      fprintf( stderr, "%s\n", __FUNCTION__ );
281
 
 
282
 
   if ( !mach64Screen->IsPCI ) {
283
 
      drmUnmap( (drmAddress)mach64Screen->agpTextures.map,
284
 
                mach64Screen->agpTextures.size );
285
 
   }
286
 
 
287
 
   drmUnmapBufs( mach64Screen->buffers );
288
 
   drmUnmap( (drmAddress)mach64Screen->mmio.map, mach64Screen->mmio.size );
289
 
 
290
 
   FREE( mach64Screen );
291
 
   driScreen->private = NULL;
292
 
}
293
 
 
294
 
 
295
 
/* Create and initialize the Mesa and driver specific pixmap buffer
296
 
 * data.
297
 
 */
298
 
static GLboolean
299
 
mach64CreateBuffer( __DRIscreen *driScrnPriv,
300
 
                    __DRIdrawable *driDrawPriv,
301
 
                    const struct gl_config *mesaVis,
302
 
                    GLboolean isPixmap )
303
 
{
304
 
   mach64ScreenPtr screen = (mach64ScreenPtr) driScrnPriv->private;
305
 
 
306
 
   if (isPixmap) {
307
 
      return GL_FALSE; /* not implemented */
308
 
   }
309
 
   else {
310
 
      struct gl_framebuffer *fb = _mesa_create_framebuffer(mesaVis);
311
 
 
312
 
      {
313
 
         driRenderbuffer *frontRb
314
 
            = driNewRenderbuffer(MESA_FORMAT_ARGB8888,
315
 
                                 NULL,
316
 
                                 screen->cpp,
317
 
                                 screen->frontOffset, screen->frontPitch,
318
 
                                 driDrawPriv);
319
 
         mach64SetSpanFunctions(frontRb, mesaVis);
320
 
         _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &frontRb->Base);
321
 
      }
322
 
 
323
 
      if (mesaVis->doubleBufferMode) {
324
 
         driRenderbuffer *backRb
325
 
            = driNewRenderbuffer(MESA_FORMAT_ARGB8888,
326
 
                                 NULL,
327
 
                                 screen->cpp,
328
 
                                 screen->backOffset, screen->backPitch,
329
 
                                 driDrawPriv);
330
 
         mach64SetSpanFunctions(backRb, mesaVis);
331
 
         _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &backRb->Base);
332
 
      }
333
 
 
334
 
      if (mesaVis->depthBits == 16) {
335
 
         driRenderbuffer *depthRb
336
 
            = driNewRenderbuffer(MESA_FORMAT_Z16,
337
 
                                 NULL, screen->cpp,
338
 
                                 screen->depthOffset, screen->depthPitch,
339
 
                                 driDrawPriv);
340
 
         mach64SetSpanFunctions(depthRb, mesaVis);
341
 
         _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base);
342
 
      }
343
 
      else if (mesaVis->depthBits == 24) {
344
 
         /* XXX I don't think 24-bit Z is supported - so this isn't used */
345
 
         driRenderbuffer *depthRb
346
 
            = driNewRenderbuffer(MESA_FORMAT_Z24_S8,
347
 
                                 NULL,
348
 
                                 screen->cpp,
349
 
                                 screen->depthOffset, screen->depthPitch,
350
 
                                 driDrawPriv);
351
 
         mach64SetSpanFunctions(depthRb, mesaVis);
352
 
         _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base);
353
 
      }
354
 
 
355
 
      _mesa_add_soft_renderbuffers(fb,
356
 
                                   GL_FALSE, /* color */
357
 
                                   GL_FALSE, /* depth */
358
 
                                   mesaVis->stencilBits > 0,
359
 
                                   mesaVis->accumRedBits > 0,
360
 
                                   GL_FALSE, /* alpha */
361
 
                                   GL_FALSE /* aux */);
362
 
      driDrawPriv->driverPrivate = (void *) fb;
363
 
 
364
 
      return (driDrawPriv->driverPrivate != NULL);
365
 
   }
366
 
}
367
 
 
368
 
 
369
 
static void
370
 
mach64DestroyBuffer(__DRIdrawable *driDrawPriv)
371
 
{
372
 
   _mesa_reference_framebuffer((struct gl_framebuffer **)(&(driDrawPriv->driverPrivate)), NULL);
373
 
}
374
 
 
375
 
 
376
 
/* Copy the back color buffer to the front color buffer */
377
 
static void
378
 
mach64SwapBuffers(__DRIdrawable *dPriv)
379
 
{
380
 
   if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
381
 
      mach64ContextPtr mmesa;
382
 
      struct gl_context *ctx;
383
 
      mmesa = (mach64ContextPtr) dPriv->driContextPriv->driverPrivate;
384
 
      ctx = mmesa->glCtx;
385
 
      if (ctx->Visual.doubleBufferMode) {
386
 
         _mesa_notifySwapBuffers( ctx );  /* flush pending rendering comands */
387
 
         mach64CopyBuffer( dPriv );
388
 
      }
389
 
   }
390
 
   else {
391
 
      /* XXX this shouldn't be an error but we can't handle it for now */
392
 
      _mesa_problem(NULL, "%s: drawable has no context!", __FUNCTION__);
393
 
   }
394
 
}
395
 
 
396
 
 
397
 
/* Initialize the driver specific screen private data.
398
 
 */
399
 
static GLboolean
400
 
mach64InitDriver( __DRIscreen *driScreen )
401
 
{
402
 
   driScreen->private = (void *) mach64CreateScreen( driScreen );
403
 
 
404
 
   if ( !driScreen->private ) {
405
 
      mach64DestroyScreen( driScreen );
406
 
      return GL_FALSE;
407
 
   }
408
 
 
409
 
   return GL_TRUE;
410
 
}
411
 
 
412
 
/**
413
 
 * This is the driver specific part of the createNewScreen entry point.
414
 
 * 
415
 
 * \todo maybe fold this into intelInitDriver
416
 
 *
417
 
 * \return the struct gl_config supported by this driver
418
 
 */
419
 
static const __DRIconfig **
420
 
mach64InitScreen(__DRIscreen *psp)
421
 
{
422
 
   static const __DRIversion ddx_expected = { 6, 4, 0 };
423
 
   static const __DRIversion dri_expected = { 4, 0, 0 };
424
 
   static const __DRIversion drm_expected = { 2, 0, 0 };
425
 
   ATIDRIPtr dri_priv = (ATIDRIPtr) psp->pDevPriv;
426
 
 
427
 
   if ( ! driCheckDriDdxDrmVersions2( "Mach64",
428
 
                                      &psp->dri_version, & dri_expected,
429
 
                                      &psp->ddx_version, & ddx_expected,
430
 
                                      &psp->drm_version, & drm_expected ) ) {
431
 
      return NULL;
432
 
   }
433
 
   
434
 
   if (!mach64InitDriver(psp))
435
 
      return NULL;
436
 
 
437
 
   return  mach64FillInModes( psp, dri_priv->cpp * 8, 16, 0, 1);
438
 
}
439
 
 
440
 
const struct __DriverAPIRec driDriverAPI = {
441
 
   .InitScreen      = mach64InitScreen,
442
 
   .DestroyScreen   = mach64DestroyScreen,
443
 
   .CreateContext   = mach64CreateContext,
444
 
   .DestroyContext  = mach64DestroyContext,
445
 
   .CreateBuffer    = mach64CreateBuffer,
446
 
   .DestroyBuffer   = mach64DestroyBuffer,
447
 
   .SwapBuffers     = mach64SwapBuffers,
448
 
   .MakeCurrent     = mach64MakeCurrent,
449
 
   .UnbindContext   = mach64UnbindContext,
450
 
   .GetSwapInfo     = NULL,
451
 
   .GetDrawableMSC  = driDrawableGetMSC32,
452
 
   .WaitForMSC      = driWaitForMSC32,
453
 
   .WaitForSBC      = NULL,
454
 
   .SwapBuffersMSC  = NULL
455
 
};
456
 
 
457
 
/* This is the table of extensions that the loader will dlsym() for. */
458
 
PUBLIC const __DRIextension *__driDriverExtensions[] = {
459
 
    &driCoreExtension.base,
460
 
    &driLegacyExtension.base,
461
 
    NULL
462
 
};