• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <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 */
94 static 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)
113 static 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 
134 static char *
radeon_driconf_get_xml(const char * driver_name)135 radeon_driconf_get_xml(const char *driver_name)
136 {
137    return driGetOptionsXml(radeon_driconf, ARRAY_SIZE(radeon_driconf));
138 }
139 
140 static const __DRIconfigOptionsExtension radeon_config_options = {
141    .base = { __DRI_CONFIG_OPTIONS, 2 },
142    .xml = NULL,
143    .getXml = radeon_driconf_get_xml,
144 };
145 
146 static int
radeonGetParam(__DRIscreen * sPriv,int param,void * value)147 radeonGetParam(__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)
172 static 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)
180 static const __DRItexBufferExtension r200TexBufferExtension = {
181    .base = { __DRI_TEX_BUFFER, 3 },
182 
183    .setTexBuffer        = r200SetTexBuffer,
184    .setTexBuffer2       = r200SetTexBuffer2,
185    .releaseTexBuffer    = NULL,
186 };
187 #endif
188 
189 static void
radeonDRI2Flush(__DRIdrawable * drawable)190 radeonDRI2Flush(__DRIdrawable *drawable)
191 {
192     radeonContextPtr rmesa;
193 
194     rmesa = (radeonContextPtr) drawable->driContextPriv->driverPrivate;
195     radeonFlush(&rmesa->glCtx, 0);
196 }
197 
198 static const struct __DRI2flushExtensionRec radeonFlushExtension = {
199    .base = { __DRI2_FLUSH, 3 },
200 
201    .flush               = radeonDRI2Flush,
202    .invalidate          = dri2InvalidateDrawable,
203 };
204 
205 static __DRIimage *
radeon_create_image_from_name(__DRIscreen * screen,int width,int height,int format,int name,int pitch,void * loaderPrivate)206 radeon_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 
262 static __DRIimage *
radeon_create_image_from_renderbuffer(__DRIcontext * context,int renderbuffer,void * loaderPrivate)263 radeon_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 
298 static void
radeon_destroy_image(__DRIimage * image)299 radeon_destroy_image(__DRIimage *image)
300 {
301    radeon_bo_unref(image->bo);
302    free(image);
303 }
304 
305 static __DRIimage *
radeon_create_image(__DRIscreen * screen,int width,int height,int format,unsigned int use,void * loaderPrivate)306 radeon_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 
362 static GLboolean
radeon_query_image(__DRIimage * image,int attrib,int * value)363 radeon_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 
380 static 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 
radeon_set_screen_flags(radeonScreenPtr screen,int device_id)390 static 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 
484 static int
radeonQueryRendererInteger(__DRIscreen * psp,int param,unsigned int * value)485 radeonQueryRendererInteger(__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 
527 static int
radeonQueryRendererString(__DRIscreen * psp,int param,const char ** value)528 radeonQueryRendererString(__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 
544 static const __DRI2rendererQueryExtension radeonRendererQueryExtension = {
545    .base = { __DRI2_RENDERER_QUERY, 1 },
546 
547    .queryInteger        = radeonQueryRendererInteger,
548    .queryString         = radeonQueryRendererString
549 };
550 
551 
552 static 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 
566 static radeonScreenPtr
radeonCreateScreen2(__DRIscreen * sPriv)567 radeonCreateScreen2(__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  */
620 static void
radeonDestroyScreen(__DRIscreen * sPriv)621 radeonDestroyScreen( __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  */
643 static GLboolean
radeonInitDriver(__DRIscreen * sPriv)644 radeonInitDriver( __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  */
663 static GLboolean
radeonCreateBuffer(__DRIscreen * driScrnPriv,__DRIdrawable * driDrawPriv,const struct gl_config * mesaVis,GLboolean isPixmap)664 radeonCreateBuffer( __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 
radeon_cleanup_renderbuffers(struct radeon_framebuffer * rfb)756 static 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 
777 void
radeonDestroyBuffer(__DRIdrawable * driDrawPriv)778 radeonDestroyBuffer(__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  */
797 static const
radeonInitScreen2(__DRIscreen * psp)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 
854 static 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 
870 static 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. */
876 static 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
__driDriverGetExtensions_r200(void)885 PUBLIC const __DRIextension **__driDriverGetExtensions_r200(void)
886 {
887    globalDriverAPI = &radeon_driver_api;
888 
889    return radeon_driver_extensions;
890 }
891 #else
__driDriverGetExtensions_radeon(void)892 PUBLIC const __DRIextension **__driDriverGetExtensions_radeon(void)
893 {
894    globalDriverAPI = &radeon_driver_api;
895 
896    return radeon_driver_extensions;
897 }
898 #endif
899