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