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