06eadd2262ec162420992d61c60a8e85f1f5bd74
[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(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(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(sizeof *image);
314 if (image == NULL)
315 return NULL;
316
317 switch (format) {
318 case __DRI_IMAGE_FORMAT_RGB565:
319 image->format = MESA_FORMAT_RGB565;
320 image->internal_format = GL_RGB;
321 image->data_type = GL_UNSIGNED_BYTE;
322 break;
323 case __DRI_IMAGE_FORMAT_XRGB8888:
324 image->format = MESA_FORMAT_XRGB8888;
325 image->internal_format = GL_RGB;
326 image->data_type = GL_UNSIGNED_BYTE;
327 break;
328 case __DRI_IMAGE_FORMAT_ARGB8888:
329 image->format = MESA_FORMAT_ARGB8888;
330 image->internal_format = GL_RGBA;
331 image->data_type = GL_UNSIGNED_BYTE;
332 break;
333 default:
334 free(image);
335 return NULL;
336 }
337
338 image->data = loaderPrivate;
339 image->cpp = _mesa_get_format_bytes(image->format);
340 image->width = width;
341 image->height = height;
342 image->pitch = ((image->cpp * image->width + 255) & ~255) / image->cpp;
343
344 image->bo = radeon_bo_open(radeonScreen->bom,
345 0,
346 image->pitch * image->height * image->cpp,
347 0,
348 RADEON_GEM_DOMAIN_VRAM,
349 0);
350
351 if (image->bo == NULL) {
352 FREE(image);
353 return NULL;
354 }
355
356 return image;
357 }
358
359 static GLboolean
360 radeon_query_image(__DRIimage *image, int attrib, int *value)
361 {
362 switch (attrib) {
363 case __DRI_IMAGE_ATTRIB_STRIDE:
364 *value = image->pitch * image->cpp;
365 return GL_TRUE;
366 case __DRI_IMAGE_ATTRIB_HANDLE:
367 *value = image->bo->handle;
368 return GL_TRUE;
369 case __DRI_IMAGE_ATTRIB_NAME:
370 radeon_gem_get_kernel_name(image->bo, (uint32_t *) value);
371 return GL_TRUE;
372 default:
373 return GL_FALSE;
374 }
375 }
376
377 static struct __DRIimageExtensionRec radeonImageExtension = {
378 { __DRI_IMAGE, 1 },
379 radeon_create_image_from_name,
380 radeon_create_image_from_renderbuffer,
381 radeon_destroy_image,
382 radeon_create_image,
383 radeon_query_image
384 };
385
386 static int radeon_set_screen_flags(radeonScreenPtr screen, int device_id)
387 {
388 screen->device_id = device_id;
389 screen->chip_flags = 0;
390 switch ( device_id ) {
391 #if defined(RADEON_R100)
392 case PCI_CHIP_RN50_515E:
393 case PCI_CHIP_RN50_5969:
394 return -1;
395
396 case PCI_CHIP_RADEON_LY:
397 case PCI_CHIP_RADEON_LZ:
398 case PCI_CHIP_RADEON_QY:
399 case PCI_CHIP_RADEON_QZ:
400 screen->chip_family = CHIP_FAMILY_RV100;
401 break;
402
403 case PCI_CHIP_RS100_4136:
404 case PCI_CHIP_RS100_4336:
405 screen->chip_family = CHIP_FAMILY_RS100;
406 break;
407
408 case PCI_CHIP_RS200_4137:
409 case PCI_CHIP_RS200_4337:
410 case PCI_CHIP_RS250_4237:
411 case PCI_CHIP_RS250_4437:
412 screen->chip_family = CHIP_FAMILY_RS200;
413 break;
414
415 case PCI_CHIP_RADEON_QD:
416 case PCI_CHIP_RADEON_QE:
417 case PCI_CHIP_RADEON_QF:
418 case PCI_CHIP_RADEON_QG:
419 /* all original radeons (7200) presumably have a stencil op bug */
420 screen->chip_family = CHIP_FAMILY_R100;
421 screen->chip_flags = RADEON_CHIPSET_TCL | RADEON_CHIPSET_BROKEN_STENCIL | RADEON_CHIPSET_DEPTH_ALWAYS_TILED;
422 break;
423
424 case PCI_CHIP_RV200_QW:
425 case PCI_CHIP_RV200_QX:
426 case PCI_CHIP_RADEON_LW:
427 case PCI_CHIP_RADEON_LX:
428 screen->chip_family = CHIP_FAMILY_RV200;
429 screen->chip_flags = RADEON_CHIPSET_TCL | RADEON_CHIPSET_DEPTH_ALWAYS_TILED;
430 break;
431
432 #elif defined(RADEON_R200)
433 case PCI_CHIP_R200_BB:
434 case PCI_CHIP_R200_QH:
435 case PCI_CHIP_R200_QL:
436 case PCI_CHIP_R200_QM:
437 screen->chip_family = CHIP_FAMILY_R200;
438 screen->chip_flags = RADEON_CHIPSET_TCL | RADEON_CHIPSET_DEPTH_ALWAYS_TILED;
439 break;
440
441 case PCI_CHIP_RV250_If:
442 case PCI_CHIP_RV250_Ig:
443 case PCI_CHIP_RV250_Ld:
444 case PCI_CHIP_RV250_Lf:
445 case PCI_CHIP_RV250_Lg:
446 screen->chip_family = CHIP_FAMILY_RV250;
447 screen->chip_flags = R200_CHIPSET_YCBCR_BROKEN | RADEON_CHIPSET_TCL | RADEON_CHIPSET_DEPTH_ALWAYS_TILED;
448 break;
449
450 case PCI_CHIP_RV280_4C6E:
451 case PCI_CHIP_RV280_5960:
452 case PCI_CHIP_RV280_5961:
453 case PCI_CHIP_RV280_5962:
454 case PCI_CHIP_RV280_5964:
455 case PCI_CHIP_RV280_5965:
456 case PCI_CHIP_RV280_5C61:
457 case PCI_CHIP_RV280_5C63:
458 screen->chip_family = CHIP_FAMILY_RV280;
459 screen->chip_flags = RADEON_CHIPSET_TCL | RADEON_CHIPSET_DEPTH_ALWAYS_TILED;
460 break;
461
462 case PCI_CHIP_RS300_5834:
463 case PCI_CHIP_RS300_5835:
464 case PCI_CHIP_RS350_7834:
465 case PCI_CHIP_RS350_7835:
466 screen->chip_family = CHIP_FAMILY_RS300;
467 screen->chip_flags = RADEON_CHIPSET_DEPTH_ALWAYS_TILED;
468 break;
469 #endif
470
471 default:
472 fprintf(stderr, "unknown chip id 0x%x, can't guess.\n",
473 device_id);
474 return -1;
475 }
476
477 return 0;
478 }
479
480 static radeonScreenPtr
481 radeonCreateScreen2(__DRIscreen *sPriv)
482 {
483 radeonScreenPtr screen;
484 int i;
485 int ret;
486 uint32_t device_id = 0;
487
488 /* Allocate the private area */
489 screen = (radeonScreenPtr) CALLOC( sizeof(*screen) );
490 if ( !screen ) {
491 fprintf(stderr, "%s: Could not allocate memory for screen structure", __FUNCTION__);
492 fprintf(stderr, "leaving here\n");
493 return NULL;
494 }
495
496 radeon_init_debug();
497
498 /* parse information in __driConfigOptions */
499 driParseOptionInfo (&screen->optionCache,
500 __driConfigOptions, __driNConfigOptions);
501
502 screen->chip_flags = 0;
503
504 screen->irq = 1;
505
506 ret = radeonGetParam(sPriv, RADEON_PARAM_DEVICE_ID, &device_id);
507 if (ret) {
508 FREE( screen );
509 fprintf(stderr, "drm_radeon_getparam_t (RADEON_PARAM_DEVICE_ID): %d\n", ret);
510 return NULL;
511 }
512
513 ret = radeon_set_screen_flags(screen, device_id);
514 if (ret == -1)
515 return NULL;
516
517 if (getenv("R300_NO_TCL"))
518 screen->chip_flags &= ~RADEON_CHIPSET_TCL;
519
520 i = 0;
521 screen->extensions[i++] = &dri2ConfigQueryExtension.base;
522
523 #if defined(RADEON_R100)
524 screen->extensions[i++] = &radeonTexBufferExtension.base;
525 #elif defined(RADEON_R200)
526 screen->extensions[i++] = &r200TexBufferExtension.base;
527 #endif
528
529 screen->extensions[i++] = &radeonFlushExtension.base;
530 screen->extensions[i++] = &radeonImageExtension.base;
531
532 screen->extensions[i++] = NULL;
533 sPriv->extensions = screen->extensions;
534
535 screen->driScreen = sPriv;
536 screen->bom = radeon_bo_manager_gem_ctor(sPriv->fd);
537 if (screen->bom == NULL) {
538 free(screen);
539 return NULL;
540 }
541 return screen;
542 }
543
544 /* Destroy the device specific screen private data struct.
545 */
546 static void
547 radeonDestroyScreen( __DRIscreen *sPriv )
548 {
549 radeonScreenPtr screen = (radeonScreenPtr)sPriv->driverPrivate;
550
551 if (!screen)
552 return;
553
554 #ifdef RADEON_BO_TRACK
555 radeon_tracker_print(&screen->bom->tracker, stderr);
556 #endif
557 radeon_bo_manager_gem_dtor(screen->bom);
558
559 /* free all option information */
560 driDestroyOptionInfo (&screen->optionCache);
561
562 FREE( screen );
563 sPriv->driverPrivate = NULL;
564 }
565
566
567 /* Initialize the driver specific screen private data.
568 */
569 static GLboolean
570 radeonInitDriver( __DRIscreen *sPriv )
571 {
572 sPriv->driverPrivate = (void *) radeonCreateScreen2( sPriv );
573 if ( !sPriv->driverPrivate ) {
574 radeonDestroyScreen( sPriv );
575 return GL_FALSE;
576 }
577
578 return GL_TRUE;
579 }
580
581
582
583 /**
584 * Create the Mesa framebuffer and renderbuffers for a given window/drawable.
585 *
586 * \todo This function (and its interface) will need to be updated to support
587 * pbuffers.
588 */
589 static GLboolean
590 radeonCreateBuffer( __DRIscreen *driScrnPriv,
591 __DRIdrawable *driDrawPriv,
592 const struct gl_config *mesaVis,
593 GLboolean isPixmap )
594 {
595 radeonScreenPtr screen = (radeonScreenPtr) driScrnPriv->driverPrivate;
596
597 const GLboolean swDepth = GL_FALSE;
598 const GLboolean swAlpha = GL_FALSE;
599 const GLboolean swAccum = mesaVis->accumRedBits > 0;
600 const GLboolean swStencil = mesaVis->stencilBits > 0 &&
601 mesaVis->depthBits != 24;
602 gl_format rgbFormat;
603 struct radeon_framebuffer *rfb;
604
605 if (isPixmap)
606 return GL_FALSE; /* not implemented */
607
608 rfb = CALLOC_STRUCT(radeon_framebuffer);
609 if (!rfb)
610 return GL_FALSE;
611
612 _mesa_initialize_window_framebuffer(&rfb->base, mesaVis);
613
614 if (mesaVis->redBits == 5)
615 rgbFormat = _mesa_little_endian() ? MESA_FORMAT_RGB565 : MESA_FORMAT_RGB565_REV;
616 else if (mesaVis->alphaBits == 0)
617 rgbFormat = _mesa_little_endian() ? MESA_FORMAT_XRGB8888 : MESA_FORMAT_XRGB8888_REV;
618 else
619 rgbFormat = _mesa_little_endian() ? MESA_FORMAT_ARGB8888 : MESA_FORMAT_ARGB8888_REV;
620
621 /* front color renderbuffer */
622 rfb->color_rb[0] = radeon_create_renderbuffer(rgbFormat, driDrawPriv);
623 _mesa_add_renderbuffer(&rfb->base, BUFFER_FRONT_LEFT, &rfb->color_rb[0]->base);
624 rfb->color_rb[0]->has_surface = 1;
625
626 /* back color renderbuffer */
627 if (mesaVis->doubleBufferMode) {
628 rfb->color_rb[1] = radeon_create_renderbuffer(rgbFormat, driDrawPriv);
629 _mesa_add_renderbuffer(&rfb->base, BUFFER_BACK_LEFT, &rfb->color_rb[1]->base);
630 rfb->color_rb[1]->has_surface = 1;
631 }
632
633 if (mesaVis->depthBits == 24) {
634 if (mesaVis->stencilBits == 8) {
635 struct radeon_renderbuffer *depthStencilRb =
636 radeon_create_renderbuffer(MESA_FORMAT_S8_Z24, driDrawPriv);
637 _mesa_add_renderbuffer(&rfb->base, BUFFER_DEPTH, &depthStencilRb->base);
638 _mesa_add_renderbuffer(&rfb->base, BUFFER_STENCIL, &depthStencilRb->base);
639 depthStencilRb->has_surface = screen->depthHasSurface;
640 } else {
641 /* depth renderbuffer */
642 struct radeon_renderbuffer *depth =
643 radeon_create_renderbuffer(MESA_FORMAT_X8_Z24, driDrawPriv);
644 _mesa_add_renderbuffer(&rfb->base, BUFFER_DEPTH, &depth->base);
645 depth->has_surface = screen->depthHasSurface;
646 }
647 } else if (mesaVis->depthBits == 16) {
648 /* just 16-bit depth buffer, no hw stencil */
649 struct radeon_renderbuffer *depth =
650 radeon_create_renderbuffer(MESA_FORMAT_Z16, driDrawPriv);
651 _mesa_add_renderbuffer(&rfb->base, BUFFER_DEPTH, &depth->base);
652 depth->has_surface = screen->depthHasSurface;
653 }
654
655 _swrast_add_soft_renderbuffers(&rfb->base,
656 GL_FALSE, /* color */
657 swDepth,
658 swStencil,
659 swAccum,
660 swAlpha,
661 GL_FALSE /* aux */);
662 driDrawPriv->driverPrivate = (void *) rfb;
663
664 return (driDrawPriv->driverPrivate != NULL);
665 }
666
667
668 static void radeon_cleanup_renderbuffers(struct radeon_framebuffer *rfb)
669 {
670 struct radeon_renderbuffer *rb;
671
672 rb = rfb->color_rb[0];
673 if (rb && rb->bo) {
674 radeon_bo_unref(rb->bo);
675 rb->bo = NULL;
676 }
677 rb = rfb->color_rb[1];
678 if (rb && rb->bo) {
679 radeon_bo_unref(rb->bo);
680 rb->bo = NULL;
681 }
682 rb = radeon_get_renderbuffer(&rfb->base, BUFFER_DEPTH);
683 if (rb && rb->bo) {
684 radeon_bo_unref(rb->bo);
685 rb->bo = NULL;
686 }
687 }
688
689 void
690 radeonDestroyBuffer(__DRIdrawable *driDrawPriv)
691 {
692 struct radeon_framebuffer *rfb;
693 if (!driDrawPriv)
694 return;
695
696 rfb = (void*)driDrawPriv->driverPrivate;
697 if (!rfb)
698 return;
699 radeon_cleanup_renderbuffers(rfb);
700 _mesa_reference_framebuffer((struct gl_framebuffer **)(&(driDrawPriv->driverPrivate)), NULL);
701 }
702
703 #define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
704
705 /**
706 * This is the driver specific part of the createNewScreen entry point.
707 * Called when using DRI2.
708 *
709 * \return the struct gl_config supported by this driver
710 */
711 static const
712 __DRIconfig **radeonInitScreen2(__DRIscreen *psp)
713 {
714 GLenum fb_format[3];
715 GLenum fb_type[3];
716 /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't
717 * support pageflipping at all.
718 */
719 static const GLenum back_buffer_modes[] = {
720 GLX_NONE, GLX_SWAP_UNDEFINED_OML, /*, GLX_SWAP_COPY_OML*/
721 };
722 uint8_t depth_bits[4], stencil_bits[4], msaa_samples_array[1];
723 int color;
724 __DRIconfig **configs = NULL;
725
726 if (!radeonInitDriver(psp)) {
727 return NULL;
728 }
729 depth_bits[0] = 0;
730 stencil_bits[0] = 0;
731 depth_bits[1] = 16;
732 stencil_bits[1] = 0;
733 depth_bits[2] = 24;
734 stencil_bits[2] = 0;
735 depth_bits[3] = 24;
736 stencil_bits[3] = 8;
737
738 msaa_samples_array[0] = 0;
739
740 fb_format[0] = GL_RGB;
741 fb_type[0] = GL_UNSIGNED_SHORT_5_6_5;
742
743 fb_format[1] = GL_BGR;
744 fb_type[1] = GL_UNSIGNED_INT_8_8_8_8_REV;
745
746 fb_format[2] = GL_BGRA;
747 fb_type[2] = GL_UNSIGNED_INT_8_8_8_8_REV;
748
749 for (color = 0; color < ARRAY_SIZE(fb_format); color++) {
750 __DRIconfig **new_configs;
751
752 new_configs = driCreateConfigs(fb_format[color], fb_type[color],
753 depth_bits,
754 stencil_bits,
755 ARRAY_SIZE(depth_bits),
756 back_buffer_modes,
757 ARRAY_SIZE(back_buffer_modes),
758 msaa_samples_array,
759 ARRAY_SIZE(msaa_samples_array),
760 GL_TRUE);
761 if (configs == NULL)
762 configs = new_configs;
763 else
764 configs = driConcatConfigs(configs, new_configs);
765 }
766
767 if (configs == NULL) {
768 fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__,
769 __LINE__);
770 return NULL;
771 }
772
773 return (const __DRIconfig **)configs;
774 }
775
776 const struct __DriverAPIRec driDriverAPI = {
777 .InitScreen = radeonInitScreen2,
778 .DestroyScreen = radeonDestroyScreen,
779 #if defined(RADEON_R200)
780 .CreateContext = r200CreateContext,
781 .DestroyContext = r200DestroyContext,
782 #else
783 .CreateContext = r100CreateContext,
784 .DestroyContext = radeonDestroyContext,
785 #endif
786 .CreateBuffer = radeonCreateBuffer,
787 .DestroyBuffer = radeonDestroyBuffer,
788 .MakeCurrent = radeonMakeCurrent,
789 .UnbindContext = radeonUnbindContext,
790 };
791
792 /* This is the table of extensions that the loader will dlsym() for. */
793 PUBLIC const __DRIextension *__driDriverExtensions[] = {
794 &driCoreExtension.base,
795 &driDRI2Extension.base,
796 NULL
797 };