Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5564 serge 1
/**************************************************************************
2
 
3
Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
4
                     VA Linux Systems Inc., Fremont, California.
5
 
6
All Rights Reserved.
7
 
8
Permission is hereby granted, free of charge, to any person obtaining
9
a copy of this software and associated documentation files (the
10
"Software"), to deal in the Software without restriction, including
11
without limitation the rights to use, copy, modify, merge, publish,
12
distribute, sublicense, and/or sell copies of the Software, and to
13
permit persons to whom the Software is furnished to do so, subject to
14
the following conditions:
15
 
16
The above copyright notice and this permission notice (including the
17
next paragraph) shall be included in all copies or substantial
18
portions of the Software.
19
 
20
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23
IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
24
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27
 
28
**************************************************************************/
29
 
30
/**
31
 * \file radeon_screen.c
32
 * Screen initialization functions for the Radeon driver.
33
 *
34
 * \author Kevin E. Martin 
35
 * \author  Gareth Hughes 
36
 */
37
 
38
#include 
39
#include "main/glheader.h"
40
#include "main/imports.h"
41
#include "main/mtypes.h"
42
#include "main/framebuffer.h"
43
#include "main/renderbuffer.h"
44
#include "main/fbobject.h"
45
#include "swrast/s_renderbuffer.h"
46
 
47
#include "radeon_chipset.h"
48
#include "radeon_screen.h"
49
#include "radeon_common.h"
50
#include "radeon_common_context.h"
51
#if defined(RADEON_R100)
52
#include "radeon_context.h"
53
#include "radeon_tex.h"
54
#elif defined(RADEON_R200)
55
#include "r200_context.h"
56
#include "r200_tex.h"
57
#endif
58
 
59
#include "utils.h"
60
 
61
#include "GL/internal/dri_interface.h"
62
 
63
/* Radeon configuration
64
 */
65
#include "xmlpool.h"
66
 
67
#define DRI_CONF_COMMAND_BUFFER_SIZE(def,min,max) \
68
DRI_CONF_OPT_BEGIN_V(command_buffer_size,int,def, # min ":" # max ) \
69
        DRI_CONF_DESC(en,"Size of command buffer (in KB)") \
70
        DRI_CONF_DESC(de,"Grösse des Befehlspuffers (in KB)") \
71
DRI_CONF_OPT_END
72
 
73
#if defined(RADEON_R100)	/* R100 */
74
static const __DRIconfigOptionsExtension radeon_config_options = {
75
   .base = { __DRI_CONFIG_OPTIONS, 1 },
76
   .xml =
77
DRI_CONF_BEGIN
78
    DRI_CONF_SECTION_PERFORMANCE
79
        DRI_CONF_TCL_MODE(DRI_CONF_TCL_CODEGEN)
80
        DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS)
81
        DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0)
82
        DRI_CONF_MAX_TEXTURE_UNITS(3,2,3)
83
        DRI_CONF_HYPERZ("false")
84
        DRI_CONF_COMMAND_BUFFER_SIZE(8, 8, 32)
85
    DRI_CONF_SECTION_END
86
    DRI_CONF_SECTION_QUALITY
87
        DRI_CONF_TEXTURE_DEPTH(DRI_CONF_TEXTURE_DEPTH_FB)
88
        DRI_CONF_DEF_MAX_ANISOTROPY(1.0,"1.0,2.0,4.0,8.0,16.0")
89
        DRI_CONF_NO_NEG_LOD_BIAS("false")
90
        DRI_CONF_FORCE_S3TC_ENABLE("false")
91
        DRI_CONF_COLOR_REDUCTION(DRI_CONF_COLOR_REDUCTION_DITHER)
92
        DRI_CONF_ROUND_MODE(DRI_CONF_ROUND_TRUNC)
93
        DRI_CONF_DITHER_MODE(DRI_CONF_DITHER_XERRORDIFF)
94
    DRI_CONF_SECTION_END
95
    DRI_CONF_SECTION_DEBUG
96
        DRI_CONF_NO_RAST("false")
97
    DRI_CONF_SECTION_END
98
DRI_CONF_END
99
};
100
 
101
#elif defined(RADEON_R200)
102
static const __DRIconfigOptionsExtension radeon_config_options = {
103
   .base = { __DRI_CONFIG_OPTIONS, 1 },
104
   .xml =
105
DRI_CONF_BEGIN
106
    DRI_CONF_SECTION_PERFORMANCE
107
        DRI_CONF_TCL_MODE(DRI_CONF_TCL_CODEGEN)
108
        DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS)
109
        DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0)
110
        DRI_CONF_MAX_TEXTURE_UNITS(6,2,6)
111
        DRI_CONF_HYPERZ("false")
112
        DRI_CONF_COMMAND_BUFFER_SIZE(8, 8, 32)
113
    DRI_CONF_SECTION_END
114
    DRI_CONF_SECTION_QUALITY
115
        DRI_CONF_TEXTURE_DEPTH(DRI_CONF_TEXTURE_DEPTH_FB)
116
        DRI_CONF_DEF_MAX_ANISOTROPY(1.0,"1.0,2.0,4.0,8.0,16.0")
117
        DRI_CONF_NO_NEG_LOD_BIAS("false")
118
        DRI_CONF_FORCE_S3TC_ENABLE("false")
119
        DRI_CONF_COLOR_REDUCTION(DRI_CONF_COLOR_REDUCTION_DITHER)
120
        DRI_CONF_ROUND_MODE(DRI_CONF_ROUND_TRUNC)
121
        DRI_CONF_DITHER_MODE(DRI_CONF_DITHER_XERRORDIFF)
122
        DRI_CONF_TEXTURE_BLEND_QUALITY(1.0,"0.0:1.0")
123
    DRI_CONF_SECTION_END
124
    DRI_CONF_SECTION_DEBUG
125
        DRI_CONF_NO_RAST("false")
126
    DRI_CONF_SECTION_END
127
DRI_CONF_END
128
};
129
#endif
130
 
131
#ifndef RADEON_INFO_TILE_CONFIG
132
#define RADEON_INFO_TILE_CONFIG 0x6
133
#endif
134
 
135
static int
136
radeonGetParam(__DRIscreen *sPriv, int param, void *value)
137
{
138
  int ret;
139
  drm_radeon_getparam_t gp = { 0 };
140
  struct drm_radeon_info info = { 0 };
141
 
142
  if (sPriv->drm_version.major >= 2) {
143
      info.value = (uint64_t)(uintptr_t)value;
144
      switch (param) {
145
      case RADEON_PARAM_DEVICE_ID:
146
          info.request = RADEON_INFO_DEVICE_ID;
147
          break;
148
      case RADEON_PARAM_NUM_GB_PIPES:
149
          info.request = RADEON_INFO_NUM_GB_PIPES;
150
          break;
151
      case RADEON_PARAM_NUM_Z_PIPES:
152
          info.request = RADEON_INFO_NUM_Z_PIPES;
153
          break;
154
      case RADEON_INFO_TILE_CONFIG:
155
	  info.request = RADEON_INFO_TILE_CONFIG;
156
          break;
157
      default:
158
          return -EINVAL;
159
      }
160
      ret = drmCommandWriteRead(sPriv->fd, DRM_RADEON_INFO, &info, sizeof(info));
161
  } else {
162
      gp.param = param;
163
      gp.value = value;
164
 
165
      ret = drmCommandWriteRead(sPriv->fd, DRM_RADEON_GETPARAM, &gp, sizeof(gp));
166
  }
167
  return ret;
168
}
169
 
170
#if defined(RADEON_R100)
171
static const __DRItexBufferExtension radeonTexBufferExtension = {
172
   .base = { __DRI_TEX_BUFFER, 3 },
173
 
174
   .setTexBuffer        = radeonSetTexBuffer,
175
   .setTexBuffer2       = radeonSetTexBuffer2,
176
   .releaseTexBuffer    = NULL,
177
};
178
#elif defined(RADEON_R200)
179
static const __DRItexBufferExtension r200TexBufferExtension = {
180
   .base = { __DRI_TEX_BUFFER, 3 },
181
 
182
   .setTexBuffer        = r200SetTexBuffer,
183
   .setTexBuffer2       = r200SetTexBuffer2,
184
   .releaseTexBuffer    = NULL,
185
};
186
#endif
187
 
188
static void
189
radeonDRI2Flush(__DRIdrawable *drawable)
190
{
191
    radeonContextPtr rmesa;
192
 
193
    rmesa = (radeonContextPtr) drawable->driContextPriv->driverPrivate;
194
    radeonFlush(&rmesa->glCtx);
195
}
196
 
197
static const struct __DRI2flushExtensionRec radeonFlushExtension = {
198
   .base = { __DRI2_FLUSH, 3 },
199
 
200
   .flush               = radeonDRI2Flush,
201
   .invalidate          = dri2InvalidateDrawable,
202
};
203
 
204
static __DRIimage *
205
radeon_create_image_from_name(__DRIscreen *screen,
206
                              int width, int height, int format,
207
                              int name, int pitch, void *loaderPrivate)
208
{
209
   __DRIimage *image;
210
   radeonScreenPtr radeonScreen = screen->driverPrivate;
211
 
212
   if (name == 0)
213
      return NULL;
214
 
215
   image = calloc(1, sizeof *image);
216
   if (image == NULL)
217
      return NULL;
218
 
219
   switch (format) {
220
   case __DRI_IMAGE_FORMAT_RGB565:
221
      image->format = MESA_FORMAT_B5G6R5_UNORM;
222
      image->internal_format = GL_RGB;
223
      image->data_type = GL_UNSIGNED_BYTE;
224
      break;
225
   case __DRI_IMAGE_FORMAT_XRGB8888:
226
      image->format = MESA_FORMAT_B8G8R8X8_UNORM;
227
      image->internal_format = GL_RGB;
228
      image->data_type = GL_UNSIGNED_BYTE;
229
      break;
230
   case __DRI_IMAGE_FORMAT_ARGB8888:
231
      image->format = MESA_FORMAT_B8G8R8A8_UNORM;
232
      image->internal_format = GL_RGBA;
233
      image->data_type = GL_UNSIGNED_BYTE;
234
      break;
235
   default:
236
      free(image);
237
      return NULL;
238
   }
239
 
240
   image->data = loaderPrivate;
241
   image->cpp = _mesa_get_format_bytes(image->format);
242
   image->width = width;
243
   image->pitch = pitch;
244
   image->height = height;
245
 
246
   image->bo = radeon_bo_open(radeonScreen->bom,
247
                              (uint32_t)name,
248
                              image->pitch * image->height * image->cpp,
249
                              0,
250
                              RADEON_GEM_DOMAIN_VRAM,
251
                              0);
252
 
253
   if (image->bo == NULL) {
254
      free(image);
255
      return NULL;
256
   }
257
 
258
   return image;
259
}
260
 
261
static __DRIimage *
262
radeon_create_image_from_renderbuffer(__DRIcontext *context,
263
                                      int renderbuffer, void *loaderPrivate)
264
{
265
   __DRIimage *image;
266
   radeonContextPtr radeon = context->driverPrivate;
267
   struct gl_renderbuffer *rb;
268
   struct radeon_renderbuffer *rrb;
269
 
270
   rb = _mesa_lookup_renderbuffer(&radeon->glCtx, renderbuffer);
271
   if (!rb) {
272
      _mesa_error(&radeon->glCtx,
273
                  GL_INVALID_OPERATION, "glRenderbufferExternalMESA");
274
      return NULL;
275
   }
276
 
277
   rrb = radeon_renderbuffer(rb);
278
   image = calloc(1, sizeof *image);
279
   if (image == NULL)
280
      return NULL;
281
 
282
   image->internal_format = rb->InternalFormat;
283
   image->format = rb->Format;
284
   image->cpp = rrb->cpp;
285
   image->data_type = GL_UNSIGNED_BYTE;
286
   image->data = loaderPrivate;
287
   radeon_bo_ref(rrb->bo);
288
   image->bo = rrb->bo;
289
 
290
   image->width = rb->Width;
291
   image->height = rb->Height;
292
   image->pitch = rrb->pitch / image->cpp;
293
 
294
   return image;
295
}
296
 
297
static void
298
radeon_destroy_image(__DRIimage *image)
299
{
300
   radeon_bo_unref(image->bo);
301
   free(image);
302
}
303
 
304
static __DRIimage *
305
radeon_create_image(__DRIscreen *screen,
306
                    int width, int height, int format,
307
                    unsigned int use,
308
                    void *loaderPrivate)
309
{
310
   __DRIimage *image;
311
   radeonScreenPtr radeonScreen = screen->driverPrivate;
312
 
313
   image = calloc(1, sizeof *image);
314
   if (image == NULL)
315
      return NULL;
316
 
317
   image->dri_format = format;
318
 
319
   switch (format) {
320
   case __DRI_IMAGE_FORMAT_RGB565:
321
      image->format = MESA_FORMAT_B5G6R5_UNORM;
322
      image->internal_format = GL_RGB;
323
      image->data_type = GL_UNSIGNED_BYTE;
324
      break;
325
   case __DRI_IMAGE_FORMAT_XRGB8888:
326
      image->format = MESA_FORMAT_B8G8R8X8_UNORM;
327
      image->internal_format = GL_RGB;
328
      image->data_type = GL_UNSIGNED_BYTE;
329
      break;
330
   case __DRI_IMAGE_FORMAT_ARGB8888:
331
      image->format = MESA_FORMAT_B8G8R8A8_UNORM;
332
      image->internal_format = GL_RGBA;
333
      image->data_type = GL_UNSIGNED_BYTE;
334
      break;
335
   default:
336
      free(image);
337
      return NULL;
338
   }
339
 
340
   image->data = loaderPrivate;
341
   image->cpp = _mesa_get_format_bytes(image->format);
342
   image->width = width;
343
   image->height = height;
344
   image->pitch = ((image->cpp * image->width + 255) & ~255) / image->cpp;
345
 
346
   image->bo = radeon_bo_open(radeonScreen->bom,
347
                              0,
348
                              image->pitch * image->height * image->cpp,
349
                              0,
350
                              RADEON_GEM_DOMAIN_VRAM,
351
                              0);
352
 
353
   if (image->bo == NULL) {
354
      free(image);
355
      return NULL;
356
   }
357
 
358
   return image;
359
}
360
 
361
static GLboolean
362
radeon_query_image(__DRIimage *image, int attrib, int *value)
363
{
364
   switch (attrib) {
365
   case __DRI_IMAGE_ATTRIB_STRIDE:
366
      *value = image->pitch * image->cpp;
367
      return GL_TRUE;
368
   case __DRI_IMAGE_ATTRIB_HANDLE:
369
      *value = image->bo->handle;
370
      return GL_TRUE;
371
   case __DRI_IMAGE_ATTRIB_NAME:
372
      radeon_gem_get_kernel_name(image->bo, (uint32_t *) value);
373
      return GL_TRUE;
374
   default:
375
      return GL_FALSE;
376
   }
377
}
378
 
379
static const __DRIimageExtension radeonImageExtension = {
380
   .base = { __DRI_IMAGE, 1 },
381
 
382
   .createImageFromName         = radeon_create_image_from_name,
383
   .createImageFromRenderbuffer = radeon_create_image_from_renderbuffer,
384
   .destroyImage                = radeon_destroy_image,
385
   .createImage                 = radeon_create_image,
386
   .queryImage                  = radeon_query_image
387
};
388
 
389
static int radeon_set_screen_flags(radeonScreenPtr screen, int device_id)
390
{
391
   screen->device_id = device_id;
392
   screen->chip_flags = 0;
393
   switch ( device_id ) {
394
#if defined(RADEON_R100)
395
   case PCI_CHIP_RN50_515E:
396
   case PCI_CHIP_RN50_5969:
397
	return -1;
398
 
399
   case PCI_CHIP_RADEON_LY:
400
   case PCI_CHIP_RADEON_LZ:
401
   case PCI_CHIP_RADEON_QY:
402
   case PCI_CHIP_RADEON_QZ:
403
      screen->chip_family = CHIP_FAMILY_RV100;
404
      break;
405
 
406
   case PCI_CHIP_RS100_4136:
407
   case PCI_CHIP_RS100_4336:
408
      screen->chip_family = CHIP_FAMILY_RS100;
409
      break;
410
 
411
   case PCI_CHIP_RS200_4137:
412
   case PCI_CHIP_RS200_4337:
413
   case PCI_CHIP_RS250_4237:
414
   case PCI_CHIP_RS250_4437:
415
      screen->chip_family = CHIP_FAMILY_RS200;
416
      break;
417
 
418
   case PCI_CHIP_RADEON_QD:
419
   case PCI_CHIP_RADEON_QE:
420
   case PCI_CHIP_RADEON_QF:
421
   case PCI_CHIP_RADEON_QG:
422
      /* all original radeons (7200) presumably have a stencil op bug */
423
      screen->chip_family = CHIP_FAMILY_R100;
424
      screen->chip_flags = RADEON_CHIPSET_TCL | RADEON_CHIPSET_BROKEN_STENCIL | RADEON_CHIPSET_DEPTH_ALWAYS_TILED;
425
      break;
426
 
427
   case PCI_CHIP_RV200_QW:
428
   case PCI_CHIP_RV200_QX:
429
   case PCI_CHIP_RADEON_LW:
430
   case PCI_CHIP_RADEON_LX:
431
      screen->chip_family = CHIP_FAMILY_RV200;
432
      screen->chip_flags = RADEON_CHIPSET_TCL | RADEON_CHIPSET_DEPTH_ALWAYS_TILED;
433
      break;
434
 
435
#elif defined(RADEON_R200)
436
   case PCI_CHIP_R200_BB:
437
   case PCI_CHIP_R200_QH:
438
   case PCI_CHIP_R200_QL:
439
   case PCI_CHIP_R200_QM:
440
      screen->chip_family = CHIP_FAMILY_R200;
441
      screen->chip_flags = RADEON_CHIPSET_TCL | RADEON_CHIPSET_DEPTH_ALWAYS_TILED;
442
      break;
443
 
444
   case PCI_CHIP_RV250_If:
445
   case PCI_CHIP_RV250_Ig:
446
   case PCI_CHIP_RV250_Ld:
447
   case PCI_CHIP_RV250_Lf:
448
   case PCI_CHIP_RV250_Lg:
449
      screen->chip_family = CHIP_FAMILY_RV250;
450
      screen->chip_flags = R200_CHIPSET_YCBCR_BROKEN | RADEON_CHIPSET_TCL | RADEON_CHIPSET_DEPTH_ALWAYS_TILED;
451
      break;
452
 
453
   case PCI_CHIP_RV280_4C6E:
454
   case PCI_CHIP_RV280_5960:
455
   case PCI_CHIP_RV280_5961:
456
   case PCI_CHIP_RV280_5962:
457
   case PCI_CHIP_RV280_5964:
458
   case PCI_CHIP_RV280_5965:
459
   case PCI_CHIP_RV280_5C61:
460
   case PCI_CHIP_RV280_5C63:
461
      screen->chip_family = CHIP_FAMILY_RV280;
462
      screen->chip_flags = RADEON_CHIPSET_TCL | RADEON_CHIPSET_DEPTH_ALWAYS_TILED;
463
      break;
464
 
465
   case PCI_CHIP_RS300_5834:
466
   case PCI_CHIP_RS300_5835:
467
   case PCI_CHIP_RS350_7834:
468
   case PCI_CHIP_RS350_7835:
469
      screen->chip_family = CHIP_FAMILY_RS300;
470
      screen->chip_flags = RADEON_CHIPSET_DEPTH_ALWAYS_TILED;
471
      break;
472
#endif
473
 
474
   default:
475
      fprintf(stderr, "unknown chip id 0x%x, can't guess.\n",
476
	      device_id);
477
      return -1;
478
   }
479
 
480
   return 0;
481
}
482
 
483
static int
484
radeonQueryRendererInteger(__DRIscreen *psp, int param,
485
			       unsigned int *value)
486
{
487
   radeonScreenPtr screen = (radeonScreenPtr)psp->driverPrivate;
488
 
489
   switch (param) {
490
   case __DRI2_RENDERER_VENDOR_ID:
491
      value[0] = 0x1002;
492
      return 0;
493
   case __DRI2_RENDERER_DEVICE_ID:
494
      value[0] = screen->device_id;
495
      return 0;
496
   case __DRI2_RENDERER_ACCELERATED:
497
      value[0] = 1;
498
      return 0;
499
   case __DRI2_RENDERER_VIDEO_MEMORY: {
500
      struct drm_radeon_gem_info gem_info;
501
      int retval;
502
      memset(&gem_info, 0, sizeof(gem_info));
503
 
504
      /* Get GEM info. */
505
      retval = drmCommandWriteRead(psp->fd, DRM_RADEON_GEM_INFO, &gem_info,
506
				   sizeof(gem_info));
507
 
508
      if (retval) {
509
         fprintf(stderr, "radeon: Failed to get MM info, error number %d\n",
510
                retval);
511
         return -1;
512
 
513
      }
514
      /* XXX: Do we want to return vram_size or vram_visible ? */
515
      value[0] = gem_info.vram_size >> 20;
516
      return 0;
517
   }
518
   case __DRI2_RENDERER_UNIFIED_MEMORY_ARCHITECTURE:
519
      value[0] = 0;
520
      return 0;
521
   default:
522
      return driQueryRendererIntegerCommon(psp, param, value);
523
   }
524
}
525
 
526
static int
527
radeonQueryRendererString(__DRIscreen *psp, int param, const char **value)
528
{
529
   radeonScreenPtr screen = (radeonScreenPtr)psp->driverPrivate;
530
 
531
   switch (param) {
532
   case __DRI2_RENDERER_VENDOR_ID:
533
      value[0] = radeonVendorString;
534
      return 0;
535
   case __DRI2_RENDERER_DEVICE_ID:
536
      value[0] = radeonGetRendererString(screen);
537
      return 0;
538
   default:
539
      return -1;
540
   }
541
}
542
 
543
static const __DRI2rendererQueryExtension radeonRendererQueryExtension = {
544
   .base = { __DRI2_RENDERER_QUERY, 1 },
545
 
546
   .queryInteger        = radeonQueryRendererInteger,
547
   .queryString         = radeonQueryRendererString
548
};
549
 
550
 
551
static const __DRIextension *radeon_screen_extensions[] = {
552
    &dri2ConfigQueryExtension.base,
553
#if defined(RADEON_R100)
554
    &radeonTexBufferExtension.base,
555
#elif defined(RADEON_R200)
556
    &r200TexBufferExtension.base,
557
#endif
558
    &radeonFlushExtension.base,
559
    &radeonImageExtension.base,
560
    &radeonRendererQueryExtension.base,
561
    NULL
562
};
563
 
564
static radeonScreenPtr
565
radeonCreateScreen2(__DRIscreen *sPriv)
566
{
567
   radeonScreenPtr screen;
568
   int ret;
569
   uint32_t device_id = 0;
570
 
571
   /* Allocate the private area */
572
   screen = calloc(1, sizeof(*screen));
573
   if ( !screen ) {
574
      fprintf(stderr, "%s: Could not allocate memory for screen structure", __func__);
575
      fprintf(stderr, "leaving here\n");
576
      return NULL;
577
   }
578
 
579
   radeon_init_debug();
580
 
581
   /* parse information in __driConfigOptions */
582
   driParseOptionInfo (&screen->optionCache, radeon_config_options.xml);
583
 
584
   screen->chip_flags = 0;
585
 
586
   screen->irq = 1;
587
 
588
   ret = radeonGetParam(sPriv, RADEON_PARAM_DEVICE_ID, &device_id);
589
   if (ret) {
590
     free( screen );
591
     fprintf(stderr, "drm_radeon_getparam_t (RADEON_PARAM_DEVICE_ID): %d\n", ret);
592
     return NULL;
593
   }
594
 
595
   ret = radeon_set_screen_flags(screen, device_id);
596
   if (ret == -1) {
597
     free(screen);
598
     return NULL;
599
   }
600
 
601
   if (getenv("RADEON_NO_TCL"))
602
	   screen->chip_flags &= ~RADEON_CHIPSET_TCL;
603
 
604
   sPriv->extensions = radeon_screen_extensions;
605
 
606
   screen->driScreen = sPriv;
607
   screen->bom = radeon_bo_manager_gem_ctor(sPriv->fd);
608
   if (screen->bom == NULL) {
609
       free(screen);
610
       return NULL;
611
   }
612
   return screen;
613
}
614
 
615
/* Destroy the device specific screen private data struct.
616
 */
617
static void
618
radeonDestroyScreen( __DRIscreen *sPriv )
619
{
620
    radeonScreenPtr screen = (radeonScreenPtr)sPriv->driverPrivate;
621
 
622
    if (!screen)
623
        return;
624
 
625
#ifdef RADEON_BO_TRACK
626
    radeon_tracker_print(&screen->bom->tracker, stderr);
627
#endif
628
    radeon_bo_manager_gem_dtor(screen->bom);
629
 
630
    /* free all option information */
631
    driDestroyOptionInfo (&screen->optionCache);
632
 
633
    free( screen );
634
    sPriv->driverPrivate = NULL;
635
}
636
 
637
 
638
/* Initialize the driver specific screen private data.
639
 */
640
static GLboolean
641
radeonInitDriver( __DRIscreen *sPriv )
642
{
643
    sPriv->driverPrivate = (void *) radeonCreateScreen2( sPriv );
644
    if ( !sPriv->driverPrivate ) {
645
        radeonDestroyScreen( sPriv );
646
        return GL_FALSE;
647
    }
648
 
649
    return GL_TRUE;
650
}
651
 
652
 
653
 
654
/**
655
 * Create the Mesa framebuffer and renderbuffers for a given window/drawable.
656
 *
657
 * \todo This function (and its interface) will need to be updated to support
658
 * pbuffers.
659
 */
660
static GLboolean
661
radeonCreateBuffer( __DRIscreen *driScrnPriv,
662
                    __DRIdrawable *driDrawPriv,
663
                    const struct gl_config *mesaVis,
664
                    GLboolean isPixmap )
665
{
666
    radeonScreenPtr screen = (radeonScreenPtr) driScrnPriv->driverPrivate;
667
 
668
    const GLboolean swDepth = GL_FALSE;
669
    const GLboolean swAlpha = GL_FALSE;
670
    const GLboolean swAccum = mesaVis->accumRedBits > 0;
671
    const GLboolean swStencil = mesaVis->stencilBits > 0 &&
672
	mesaVis->depthBits != 24;
673
    mesa_format rgbFormat;
674
    struct radeon_framebuffer *rfb;
675
 
676
    if (isPixmap)
677
      return GL_FALSE; /* not implemented */
678
 
679
    rfb = CALLOC_STRUCT(radeon_framebuffer);
680
    if (!rfb)
681
      return GL_FALSE;
682
 
683
    _mesa_initialize_window_framebuffer(&rfb->base, mesaVis);
684
 
685
    if (mesaVis->redBits == 5)
686
        rgbFormat = _mesa_little_endian() ? MESA_FORMAT_B5G6R5_UNORM : MESA_FORMAT_R5G6B5_UNORM;
687
    else if (mesaVis->alphaBits == 0)
688
        rgbFormat = _mesa_little_endian() ? MESA_FORMAT_B8G8R8X8_UNORM : MESA_FORMAT_X8R8G8B8_UNORM;
689
    else
690
        rgbFormat = _mesa_little_endian() ? MESA_FORMAT_B8G8R8A8_UNORM : MESA_FORMAT_A8R8G8B8_UNORM;
691
 
692
    /* front color renderbuffer */
693
    rfb->color_rb[0] = radeon_create_renderbuffer(rgbFormat, driDrawPriv);
694
    _mesa_add_renderbuffer(&rfb->base, BUFFER_FRONT_LEFT, &rfb->color_rb[0]->base.Base);
695
    rfb->color_rb[0]->has_surface = 1;
696
 
697
    /* back color renderbuffer */
698
    if (mesaVis->doubleBufferMode) {
699
      rfb->color_rb[1] = radeon_create_renderbuffer(rgbFormat, driDrawPriv);
700
	_mesa_add_renderbuffer(&rfb->base, BUFFER_BACK_LEFT, &rfb->color_rb[1]->base.Base);
701
	rfb->color_rb[1]->has_surface = 1;
702
    }
703
 
704
    if (mesaVis->depthBits == 24) {
705
      if (mesaVis->stencilBits == 8) {
706
	struct radeon_renderbuffer *depthStencilRb =
707
           radeon_create_renderbuffer(MESA_FORMAT_Z24_UNORM_S8_UINT, driDrawPriv);
708
	_mesa_add_renderbuffer(&rfb->base, BUFFER_DEPTH, &depthStencilRb->base.Base);
709
	_mesa_add_renderbuffer(&rfb->base, BUFFER_STENCIL, &depthStencilRb->base.Base);
710
	depthStencilRb->has_surface = screen->depthHasSurface;
711
      } else {
712
	/* depth renderbuffer */
713
	struct radeon_renderbuffer *depth =
714
           radeon_create_renderbuffer(MESA_FORMAT_Z24_UNORM_X8_UINT, driDrawPriv);
715
	_mesa_add_renderbuffer(&rfb->base, BUFFER_DEPTH, &depth->base.Base);
716
	depth->has_surface = screen->depthHasSurface;
717
      }
718
    } else if (mesaVis->depthBits == 16) {
719
        /* just 16-bit depth buffer, no hw stencil */
720
	struct radeon_renderbuffer *depth =
721
           radeon_create_renderbuffer(MESA_FORMAT_Z_UNORM16, driDrawPriv);
722
	_mesa_add_renderbuffer(&rfb->base, BUFFER_DEPTH, &depth->base.Base);
723
	depth->has_surface = screen->depthHasSurface;
724
    }
725
 
726
    _swrast_add_soft_renderbuffers(&rfb->base,
727
	    GL_FALSE, /* color */
728
	    swDepth,
729
	    swStencil,
730
	    swAccum,
731
	    swAlpha,
732
	    GL_FALSE /* aux */);
733
    driDrawPriv->driverPrivate = (void *) rfb;
734
 
735
    return (driDrawPriv->driverPrivate != NULL);
736
}
737
 
738
 
739
static void radeon_cleanup_renderbuffers(struct radeon_framebuffer *rfb)
740
{
741
	struct radeon_renderbuffer *rb;
742
 
743
	rb = rfb->color_rb[0];
744
	if (rb && rb->bo) {
745
		radeon_bo_unref(rb->bo);
746
		rb->bo = NULL;
747
	}
748
	rb = rfb->color_rb[1];
749
	if (rb && rb->bo) {
750
		radeon_bo_unref(rb->bo);
751
		rb->bo = NULL;
752
	}
753
	rb = radeon_get_renderbuffer(&rfb->base, BUFFER_DEPTH);
754
	if (rb && rb->bo) {
755
		radeon_bo_unref(rb->bo);
756
		rb->bo = NULL;
757
	}
758
}
759
 
760
void
761
radeonDestroyBuffer(__DRIdrawable *driDrawPriv)
762
{
763
    struct radeon_framebuffer *rfb;
764
    if (!driDrawPriv)
765
	return;
766
 
767
    rfb = (void*)driDrawPriv->driverPrivate;
768
    if (!rfb)
769
	return;
770
    radeon_cleanup_renderbuffers(rfb);
771
    _mesa_reference_framebuffer((struct gl_framebuffer **)(&(driDrawPriv->driverPrivate)), NULL);
772
}
773
 
774
/**
775
 * This is the driver specific part of the createNewScreen entry point.
776
 * Called when using DRI2.
777
 *
778
 * \return the struct gl_config supported by this driver
779
 */
780
static const
781
__DRIconfig **radeonInitScreen2(__DRIscreen *psp)
782
{
783
   static const mesa_format formats[3] = {
784
      MESA_FORMAT_B5G6R5_UNORM,
785
      MESA_FORMAT_B8G8R8X8_UNORM,
786
      MESA_FORMAT_B8G8R8A8_UNORM
787
   };
788
   /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't
789
    * support pageflipping at all.
790
    */
791
   static const GLenum back_buffer_modes[] = {
792
     GLX_NONE, GLX_SWAP_UNDEFINED_OML, /*, GLX_SWAP_COPY_OML*/
793
   };
794
   uint8_t depth_bits[4], stencil_bits[4], msaa_samples_array[1];
795
   int color;
796
   __DRIconfig **configs = NULL;
797
 
798
   psp->max_gl_compat_version = 13;
799
   psp->max_gl_es1_version = 11;
800
 
801
   if (!radeonInitDriver(psp)) {
802
       return NULL;
803
    }
804
   depth_bits[0] = 0;
805
   stencil_bits[0] = 0;
806
   depth_bits[1] = 16;
807
   stencil_bits[1] = 0;
808
   depth_bits[2] = 24;
809
   stencil_bits[2] = 0;
810
   depth_bits[3] = 24;
811
   stencil_bits[3] = 8;
812
 
813
   msaa_samples_array[0] = 0;
814
 
815
   for (color = 0; color < ARRAY_SIZE(formats); color++) {
816
      __DRIconfig **new_configs;
817
 
818
      new_configs = driCreateConfigs(formats[color],
819
				     depth_bits,
820
				     stencil_bits,
821
				     ARRAY_SIZE(depth_bits),
822
				     back_buffer_modes,
823
				     ARRAY_SIZE(back_buffer_modes),
824
				     msaa_samples_array,
825
				     ARRAY_SIZE(msaa_samples_array),
826
				     GL_TRUE);
827
      configs = driConcatConfigs(configs, new_configs);
828
   }
829
 
830
   if (configs == NULL) {
831
      fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__,
832
              __LINE__);
833
      return NULL;
834
   }
835
 
836
   return (const __DRIconfig **)configs;
837
}
838
 
839
static const struct __DriverAPIRec radeon_driver_api = {
840
   .InitScreen      = radeonInitScreen2,
841
   .DestroyScreen   = radeonDestroyScreen,
842
#if defined(RADEON_R200)
843
   .CreateContext   = r200CreateContext,
844
   .DestroyContext  = r200DestroyContext,
845
#else
846
   .CreateContext   = r100CreateContext,
847
   .DestroyContext  = radeonDestroyContext,
848
#endif
849
   .CreateBuffer    = radeonCreateBuffer,
850
   .DestroyBuffer   = radeonDestroyBuffer,
851
   .MakeCurrent     = radeonMakeCurrent,
852
   .UnbindContext   = radeonUnbindContext,
853
};
854
 
855
static const struct __DRIDriverVtableExtensionRec radeon_vtable = {
856
   .base = { __DRI_DRIVER_VTABLE, 1 },
857
   .vtable = &radeon_driver_api,
858
};
859
 
860
/* This is the table of extensions that the loader will dlsym() for. */
861
static const __DRIextension *radeon_driver_extensions[] = {
862
    &driCoreExtension.base,
863
    &driDRI2Extension.base,
864
    &radeon_config_options.base,
865
    &radeon_vtable.base,
866
    NULL
867
};
868
 
869
#ifdef RADEON_R200
870
PUBLIC const __DRIextension **__driDriverGetExtensions_r200(void)
871
{
872
   globalDriverAPI = &radeon_driver_api;
873
 
874
   return radeon_driver_extensions;
875
}
876
#else
877
PUBLIC const __DRIextension **__driDriverGetExtensions_radeon(void)
878
{
879
   globalDriverAPI = &radeon_driver_api;
880
 
881
   return radeon_driver_extensions;
882
}
883
#endif