acd4cc1e2c5ffb45364f8a88a58e4bb8ad1adea4
[mesa.git] / src / mesa / drivers / dri / radeon / radeon_screen.c
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/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 #define STANDALONE_MMIO
48 #include "radeon_chipset.h"
49 #include "radeon_macros.h"
50 #include "radeon_screen.h"
51 #include "radeon_common.h"
52 #include "radeon_common_context.h"
53 #if defined(RADEON_R100)
54 #include "radeon_context.h"
55 #include "radeon_tex.h"
56 #elif defined(RADEON_R200)
57 #include "r200_context.h"
58 #include "r200_tex.h"
59 #endif
60
61 #include "utils.h"
62
63 #include "GL/internal/dri_interface.h"
64
65 /* Radeon configuration
66 */
67 #include "xmlpool.h"
68
69 #define DRI_CONF_COMMAND_BUFFER_SIZE(def,min,max) \
70 DRI_CONF_OPT_BEGIN_V(command_buffer_size,int,def, # min ":" # max ) \
71 DRI_CONF_DESC(en,"Size of command buffer (in KB)") \
72 DRI_CONF_DESC(de,"Grösse des Befehlspuffers (in KB)") \
73 DRI_CONF_OPT_END
74
75 #if defined(RADEON_R100) /* R100 */
76 PUBLIC const char __driConfigOptions[] =
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_ALLOW_LARGE_TEXTURES(2)
95 DRI_CONF_SECTION_END
96 DRI_CONF_SECTION_DEBUG
97 DRI_CONF_NO_RAST(false)
98 DRI_CONF_SECTION_END
99 DRI_CONF_END;
100 static const GLuint __driNConfigOptions = 15;
101
102 #elif defined(RADEON_R200)
103
104 PUBLIC const char __driConfigOptions[] =
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_ALLOW_LARGE_TEXTURES(2)
123 DRI_CONF_TEXTURE_BLEND_QUALITY(1.0,"0.0:1.0")
124 DRI_CONF_SECTION_END
125 DRI_CONF_SECTION_DEBUG
126 DRI_CONF_NO_RAST(false)
127 DRI_CONF_SECTION_END
128 DRI_CONF_SECTION_SOFTWARE
129 DRI_CONF_NV_VERTEX_PROGRAM(false)
130 DRI_CONF_SECTION_END
131 DRI_CONF_END;
132 static const GLuint __driNConfigOptions = 17;
133
134 #endif
135
136 #ifndef RADEON_INFO_TILE_CONFIG
137 #define RADEON_INFO_TILE_CONFIG 0x6
138 #endif
139
140 static int
141 radeonGetParam(__DRIscreen *sPriv, int param, void *value)
142 {
143 int ret;
144 drm_radeon_getparam_t gp = { 0 };
145 struct drm_radeon_info info = { 0 };
146
147 if (sPriv->drm_version.major >= 2) {
148 info.value = (uint64_t)(uintptr_t)value;
149 switch (param) {
150 case RADEON_PARAM_DEVICE_ID:
151 info.request = RADEON_INFO_DEVICE_ID;
152 break;
153 case RADEON_PARAM_NUM_GB_PIPES:
154 info.request = RADEON_INFO_NUM_GB_PIPES;
155 break;
156 case RADEON_PARAM_NUM_Z_PIPES:
157 info.request = RADEON_INFO_NUM_Z_PIPES;
158 break;
159 case RADEON_INFO_TILE_CONFIG:
160 info.request = RADEON_INFO_TILE_CONFIG;
161 break;
162 default:
163 return -EINVAL;
164 }
165 ret = drmCommandWriteRead(sPriv->fd, DRM_RADEON_INFO, &info, sizeof(info));
166 } else {
167 gp.param = param;
168 gp.value = value;
169
170 ret = drmCommandWriteRead(sPriv->fd, DRM_RADEON_GETPARAM, &gp, sizeof(gp));
171 }
172 return ret;
173 }
174
175 #if defined(RADEON_R100)
176 static const __DRItexBufferExtension radeonTexBufferExtension = {
177 { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION },
178 radeonSetTexBuffer,
179 radeonSetTexBuffer2,
180 };
181 #elif defined(RADEON_R200)
182 static const __DRItexBufferExtension r200TexBufferExtension = {
183 { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION },
184 r200SetTexBuffer,
185 r200SetTexBuffer2,
186 };
187 #endif
188
189 static void
190 radeonDRI2Flush(__DRIdrawable *drawable)
191 {
192 radeonContextPtr rmesa;
193
194 rmesa = (radeonContextPtr) drawable->driContextPriv->driverPrivate;
195 radeonFlush(rmesa->glCtx);
196 }
197
198 static const struct __DRI2flushExtensionRec radeonFlushExtension = {
199 { __DRI2_FLUSH, __DRI2_FLUSH_VERSION },
200 radeonDRI2Flush,
201 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_RGB565;
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_XRGB8888;
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_ARGB8888;
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_RGB565;
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_XRGB8888;
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_ARGB8888;
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 struct __DRIimageExtensionRec radeonImageExtension = {
380 { __DRI_IMAGE, 1 },
381 radeon_create_image_from_name,
382 radeon_create_image_from_renderbuffer,
383 radeon_destroy_image,
384 radeon_create_image,
385 radeon_query_image
386 };
387
388 static int radeon_set_screen_flags(radeonScreenPtr screen, int device_id)
389 {
390 screen->device_id = device_id;
391 screen->chip_flags = 0;
392 switch ( device_id ) {
393 #if defined(RADEON_R100)
394 case PCI_CHIP_RN50_515E:
395 case PCI_CHIP_RN50_5969:
396 return -1;
397
398 case PCI_CHIP_RADEON_LY:
399 case PCI_CHIP_RADEON_LZ:
400 case PCI_CHIP_RADEON_QY:
401 case PCI_CHIP_RADEON_QZ:
402 screen->chip_family = CHIP_FAMILY_RV100;
403 break;
404
405 case PCI_CHIP_RS100_4136:
406 case PCI_CHIP_RS100_4336:
407 screen->chip_family = CHIP_FAMILY_RS100;
408 break;
409
410 case PCI_CHIP_RS200_4137:
411 case PCI_CHIP_RS200_4337:
412 case PCI_CHIP_RS250_4237:
413 case PCI_CHIP_RS250_4437:
414 screen->chip_family = CHIP_FAMILY_RS200;
415 break;
416
417 case PCI_CHIP_RADEON_QD:
418 case PCI_CHIP_RADEON_QE:
419 case PCI_CHIP_RADEON_QF:
420 case PCI_CHIP_RADEON_QG:
421 /* all original radeons (7200) presumably have a stencil op bug */
422 screen->chip_family = CHIP_FAMILY_R100;
423 screen->chip_flags = RADEON_CHIPSET_TCL | RADEON_CHIPSET_BROKEN_STENCIL | RADEON_CHIPSET_DEPTH_ALWAYS_TILED;
424 break;
425
426 case PCI_CHIP_RV200_QW:
427 case PCI_CHIP_RV200_QX:
428 case PCI_CHIP_RADEON_LW:
429 case PCI_CHIP_RADEON_LX:
430 screen->chip_family = CHIP_FAMILY_RV200;
431 screen->chip_flags = RADEON_CHIPSET_TCL | RADEON_CHIPSET_DEPTH_ALWAYS_TILED;
432 break;
433
434 #elif defined(RADEON_R200)
435 case PCI_CHIP_R200_BB:
436 case PCI_CHIP_R200_QH:
437 case PCI_CHIP_R200_QL:
438 case PCI_CHIP_R200_QM:
439 screen->chip_family = CHIP_FAMILY_R200;
440 screen->chip_flags = RADEON_CHIPSET_TCL | RADEON_CHIPSET_DEPTH_ALWAYS_TILED;
441 break;
442
443 case PCI_CHIP_RV250_If:
444 case PCI_CHIP_RV250_Ig:
445 case PCI_CHIP_RV250_Ld:
446 case PCI_CHIP_RV250_Lf:
447 case PCI_CHIP_RV250_Lg:
448 screen->chip_family = CHIP_FAMILY_RV250;
449 screen->chip_flags = R200_CHIPSET_YCBCR_BROKEN | RADEON_CHIPSET_TCL | RADEON_CHIPSET_DEPTH_ALWAYS_TILED;
450 break;
451
452 case PCI_CHIP_RV280_4C6E:
453 case PCI_CHIP_RV280_5960:
454 case PCI_CHIP_RV280_5961:
455 case PCI_CHIP_RV280_5962:
456 case PCI_CHIP_RV280_5964:
457 case PCI_CHIP_RV280_5965:
458 case PCI_CHIP_RV280_5C61:
459 case PCI_CHIP_RV280_5C63:
460 screen->chip_family = CHIP_FAMILY_RV280;
461 screen->chip_flags = RADEON_CHIPSET_TCL | RADEON_CHIPSET_DEPTH_ALWAYS_TILED;
462 break;
463
464 case PCI_CHIP_RS300_5834:
465 case PCI_CHIP_RS300_5835:
466 case PCI_CHIP_RS350_7834:
467 case PCI_CHIP_RS350_7835:
468 screen->chip_family = CHIP_FAMILY_RS300;
469 screen->chip_flags = RADEON_CHIPSET_DEPTH_ALWAYS_TILED;
470 break;
471 #endif
472
473 default:
474 fprintf(stderr, "unknown chip id 0x%x, can't guess.\n",
475 device_id);
476 return -1;
477 }
478
479 return 0;
480 }
481
482 static radeonScreenPtr
483 radeonCreateScreen2(__DRIscreen *sPriv)
484 {
485 radeonScreenPtr screen;
486 int i;
487 int ret;
488 uint32_t device_id = 0;
489
490 /* Allocate the private area */
491 screen = (radeonScreenPtr) calloc(1, sizeof(*screen));
492 if ( !screen ) {
493 fprintf(stderr, "%s: Could not allocate memory for screen structure", __FUNCTION__);
494 fprintf(stderr, "leaving here\n");
495 return NULL;
496 }
497
498 radeon_init_debug();
499
500 /* parse information in __driConfigOptions */
501 driParseOptionInfo (&screen->optionCache,
502 __driConfigOptions, __driNConfigOptions);
503
504 screen->chip_flags = 0;
505
506 screen->irq = 1;
507
508 ret = radeonGetParam(sPriv, RADEON_PARAM_DEVICE_ID, &device_id);
509 if (ret) {
510 free( screen );
511 fprintf(stderr, "drm_radeon_getparam_t (RADEON_PARAM_DEVICE_ID): %d\n", ret);
512 return NULL;
513 }
514
515 ret = radeon_set_screen_flags(screen, device_id);
516 if (ret == -1)
517 return NULL;
518
519 if (getenv("RADEON_NO_TCL"))
520 screen->chip_flags &= ~RADEON_CHIPSET_TCL;
521
522 i = 0;
523 screen->extensions[i++] = &dri2ConfigQueryExtension.base;
524
525 #if defined(RADEON_R100)
526 screen->extensions[i++] = &radeonTexBufferExtension.base;
527 #elif defined(RADEON_R200)
528 screen->extensions[i++] = &r200TexBufferExtension.base;
529 #endif
530
531 screen->extensions[i++] = &radeonFlushExtension.base;
532 screen->extensions[i++] = &radeonImageExtension.base;
533
534 screen->extensions[i++] = NULL;
535 sPriv->extensions = screen->extensions;
536
537 screen->driScreen = sPriv;
538 screen->bom = radeon_bo_manager_gem_ctor(sPriv->fd);
539 if (screen->bom == NULL) {
540 free(screen);
541 return NULL;
542 }
543 return screen;
544 }
545
546 /* Destroy the device specific screen private data struct.
547 */
548 static void
549 radeonDestroyScreen( __DRIscreen *sPriv )
550 {
551 radeonScreenPtr screen = (radeonScreenPtr)sPriv->driverPrivate;
552
553 if (!screen)
554 return;
555
556 #ifdef RADEON_BO_TRACK
557 radeon_tracker_print(&screen->bom->tracker, stderr);
558 #endif
559 radeon_bo_manager_gem_dtor(screen->bom);
560
561 /* free all option information */
562 driDestroyOptionInfo (&screen->optionCache);
563
564 free( screen );
565 sPriv->driverPrivate = NULL;
566 }
567
568
569 /* Initialize the driver specific screen private data.
570 */
571 static GLboolean
572 radeonInitDriver( __DRIscreen *sPriv )
573 {
574 sPriv->driverPrivate = (void *) radeonCreateScreen2( sPriv );
575 if ( !sPriv->driverPrivate ) {
576 radeonDestroyScreen( sPriv );
577 return GL_FALSE;
578 }
579
580 return GL_TRUE;
581 }
582
583
584
585 /**
586 * Create the Mesa framebuffer and renderbuffers for a given window/drawable.
587 *
588 * \todo This function (and its interface) will need to be updated to support
589 * pbuffers.
590 */
591 static GLboolean
592 radeonCreateBuffer( __DRIscreen *driScrnPriv,
593 __DRIdrawable *driDrawPriv,
594 const struct gl_config *mesaVis,
595 GLboolean isPixmap )
596 {
597 radeonScreenPtr screen = (radeonScreenPtr) driScrnPriv->driverPrivate;
598
599 const GLboolean swDepth = GL_FALSE;
600 const GLboolean swAlpha = GL_FALSE;
601 const GLboolean swAccum = mesaVis->accumRedBits > 0;
602 const GLboolean swStencil = mesaVis->stencilBits > 0 &&
603 mesaVis->depthBits != 24;
604 gl_format rgbFormat;
605 struct radeon_framebuffer *rfb;
606
607 if (isPixmap)
608 return GL_FALSE; /* not implemented */
609
610 rfb = CALLOC_STRUCT(radeon_framebuffer);
611 if (!rfb)
612 return GL_FALSE;
613
614 _mesa_initialize_window_framebuffer(&rfb->base, mesaVis);
615
616 if (mesaVis->redBits == 5)
617 rgbFormat = _mesa_little_endian() ? MESA_FORMAT_RGB565 : MESA_FORMAT_RGB565_REV;
618 else if (mesaVis->alphaBits == 0)
619 rgbFormat = _mesa_little_endian() ? MESA_FORMAT_XRGB8888 : MESA_FORMAT_XRGB8888_REV;
620 else
621 rgbFormat = _mesa_little_endian() ? MESA_FORMAT_ARGB8888 : MESA_FORMAT_ARGB8888_REV;
622
623 /* front color renderbuffer */
624 rfb->color_rb[0] = radeon_create_renderbuffer(rgbFormat, driDrawPriv);
625 _mesa_add_renderbuffer(&rfb->base, BUFFER_FRONT_LEFT, &rfb->color_rb[0]->base.Base);
626 rfb->color_rb[0]->has_surface = 1;
627
628 /* back color renderbuffer */
629 if (mesaVis->doubleBufferMode) {
630 rfb->color_rb[1] = radeon_create_renderbuffer(rgbFormat, driDrawPriv);
631 _mesa_add_renderbuffer(&rfb->base, BUFFER_BACK_LEFT, &rfb->color_rb[1]->base.Base);
632 rfb->color_rb[1]->has_surface = 1;
633 }
634
635 if (mesaVis->depthBits == 24) {
636 if (mesaVis->stencilBits == 8) {
637 struct radeon_renderbuffer *depthStencilRb =
638 radeon_create_renderbuffer(MESA_FORMAT_S8_Z24, driDrawPriv);
639 _mesa_add_renderbuffer(&rfb->base, BUFFER_DEPTH, &depthStencilRb->base.Base);
640 _mesa_add_renderbuffer(&rfb->base, BUFFER_STENCIL, &depthStencilRb->base.Base);
641 depthStencilRb->has_surface = screen->depthHasSurface;
642 } else {
643 /* depth renderbuffer */
644 struct radeon_renderbuffer *depth =
645 radeon_create_renderbuffer(MESA_FORMAT_X8_Z24, driDrawPriv);
646 _mesa_add_renderbuffer(&rfb->base, BUFFER_DEPTH, &depth->base.Base);
647 depth->has_surface = screen->depthHasSurface;
648 }
649 } else if (mesaVis->depthBits == 16) {
650 /* just 16-bit depth buffer, no hw stencil */
651 struct radeon_renderbuffer *depth =
652 radeon_create_renderbuffer(MESA_FORMAT_Z16, driDrawPriv);
653 _mesa_add_renderbuffer(&rfb->base, BUFFER_DEPTH, &depth->base.Base);
654 depth->has_surface = screen->depthHasSurface;
655 }
656
657 _swrast_add_soft_renderbuffers(&rfb->base,
658 GL_FALSE, /* color */
659 swDepth,
660 swStencil,
661 swAccum,
662 swAlpha,
663 GL_FALSE /* aux */);
664 driDrawPriv->driverPrivate = (void *) rfb;
665
666 return (driDrawPriv->driverPrivate != NULL);
667 }
668
669
670 static void radeon_cleanup_renderbuffers(struct radeon_framebuffer *rfb)
671 {
672 struct radeon_renderbuffer *rb;
673
674 rb = rfb->color_rb[0];
675 if (rb && rb->bo) {
676 radeon_bo_unref(rb->bo);
677 rb->bo = NULL;
678 }
679 rb = rfb->color_rb[1];
680 if (rb && rb->bo) {
681 radeon_bo_unref(rb->bo);
682 rb->bo = NULL;
683 }
684 rb = radeon_get_renderbuffer(&rfb->base, BUFFER_DEPTH);
685 if (rb && rb->bo) {
686 radeon_bo_unref(rb->bo);
687 rb->bo = NULL;
688 }
689 }
690
691 void
692 radeonDestroyBuffer(__DRIdrawable *driDrawPriv)
693 {
694 struct radeon_framebuffer *rfb;
695 if (!driDrawPriv)
696 return;
697
698 rfb = (void*)driDrawPriv->driverPrivate;
699 if (!rfb)
700 return;
701 radeon_cleanup_renderbuffers(rfb);
702 _mesa_reference_framebuffer((struct gl_framebuffer **)(&(driDrawPriv->driverPrivate)), NULL);
703 }
704
705 #define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
706
707 /**
708 * This is the driver specific part of the createNewScreen entry point.
709 * Called when using DRI2.
710 *
711 * \return the struct gl_config supported by this driver
712 */
713 static const
714 __DRIconfig **radeonInitScreen2(__DRIscreen *psp)
715 {
716 GLenum fb_format[3];
717 GLenum fb_type[3];
718 /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't
719 * support pageflipping at all.
720 */
721 static const GLenum back_buffer_modes[] = {
722 GLX_NONE, GLX_SWAP_UNDEFINED_OML, /*, GLX_SWAP_COPY_OML*/
723 };
724 uint8_t depth_bits[4], stencil_bits[4], msaa_samples_array[1];
725 int color;
726 __DRIconfig **configs = NULL;
727
728 if (!radeonInitDriver(psp)) {
729 return NULL;
730 }
731 depth_bits[0] = 0;
732 stencil_bits[0] = 0;
733 depth_bits[1] = 16;
734 stencil_bits[1] = 0;
735 depth_bits[2] = 24;
736 stencil_bits[2] = 0;
737 depth_bits[3] = 24;
738 stencil_bits[3] = 8;
739
740 msaa_samples_array[0] = 0;
741
742 fb_format[0] = GL_RGB;
743 fb_type[0] = GL_UNSIGNED_SHORT_5_6_5;
744
745 fb_format[1] = GL_BGR;
746 fb_type[1] = GL_UNSIGNED_INT_8_8_8_8_REV;
747
748 fb_format[2] = GL_BGRA;
749 fb_type[2] = GL_UNSIGNED_INT_8_8_8_8_REV;
750
751 for (color = 0; color < ARRAY_SIZE(fb_format); color++) {
752 __DRIconfig **new_configs;
753
754 new_configs = driCreateConfigs(fb_format[color], fb_type[color],
755 depth_bits,
756 stencil_bits,
757 ARRAY_SIZE(depth_bits),
758 back_buffer_modes,
759 ARRAY_SIZE(back_buffer_modes),
760 msaa_samples_array,
761 ARRAY_SIZE(msaa_samples_array),
762 GL_TRUE);
763 configs = driConcatConfigs(configs, new_configs);
764 }
765
766 if (configs == NULL) {
767 fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__,
768 __LINE__);
769 return NULL;
770 }
771
772 return (const __DRIconfig **)configs;
773 }
774
775 const struct __DriverAPIRec driDriverAPI = {
776 .InitScreen = radeonInitScreen2,
777 .DestroyScreen = radeonDestroyScreen,
778 #if defined(RADEON_R200)
779 .CreateContext = r200CreateContext,
780 .DestroyContext = r200DestroyContext,
781 #else
782 .CreateContext = r100CreateContext,
783 .DestroyContext = radeonDestroyContext,
784 #endif
785 .CreateBuffer = radeonCreateBuffer,
786 .DestroyBuffer = radeonDestroyBuffer,
787 .MakeCurrent = radeonMakeCurrent,
788 .UnbindContext = radeonUnbindContext,
789 };
790
791 /* This is the table of extensions that the loader will dlsym() for. */
792 PUBLIC const __DRIextension *__driDriverExtensions[] = {
793 &driCoreExtension.base,
794 &driDRI2Extension.base,
795 NULL
796 };