mesa: rename _mesa_add_renderbuffer* functions
[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 NULL
548 };
549
550 static radeonScreenPtr
551 radeonCreateScreen2(__DRIscreen *sPriv)
552 {
553 radeonScreenPtr screen;
554 int ret;
555 uint32_t device_id = 0;
556
557 /* Allocate the private area */
558 screen = calloc(1, sizeof(*screen));
559 if ( !screen ) {
560 fprintf(stderr, "%s: Could not allocate memory for screen structure", __func__);
561 fprintf(stderr, "leaving here\n");
562 return NULL;
563 }
564
565 radeon_init_debug();
566
567 /* parse information in __driConfigOptions */
568 driParseOptionInfo (&screen->optionCache, radeon_config_options.xml);
569
570 screen->chip_flags = 0;
571
572 screen->irq = 1;
573
574 ret = radeonGetParam(sPriv, RADEON_PARAM_DEVICE_ID, &device_id);
575 if (ret) {
576 free( screen );
577 fprintf(stderr, "drm_radeon_getparam_t (RADEON_PARAM_DEVICE_ID): %d\n", ret);
578 return NULL;
579 }
580
581 ret = radeon_set_screen_flags(screen, device_id);
582 if (ret == -1) {
583 free(screen);
584 return NULL;
585 }
586
587 if (getenv("RADEON_NO_TCL"))
588 screen->chip_flags &= ~RADEON_CHIPSET_TCL;
589
590 sPriv->extensions = radeon_screen_extensions;
591
592 screen->driScreen = sPriv;
593 screen->bom = radeon_bo_manager_gem_ctor(sPriv->fd);
594 if (screen->bom == NULL) {
595 free(screen);
596 return NULL;
597 }
598 return screen;
599 }
600
601 /* Destroy the device specific screen private data struct.
602 */
603 static void
604 radeonDestroyScreen( __DRIscreen *sPriv )
605 {
606 radeonScreenPtr screen = (radeonScreenPtr)sPriv->driverPrivate;
607
608 if (!screen)
609 return;
610
611 #ifdef RADEON_BO_TRACK
612 radeon_tracker_print(&screen->bom->tracker, stderr);
613 #endif
614 radeon_bo_manager_gem_dtor(screen->bom);
615
616 /* free all option information */
617 driDestroyOptionInfo (&screen->optionCache);
618
619 free( screen );
620 sPriv->driverPrivate = NULL;
621 }
622
623
624 /* Initialize the driver specific screen private data.
625 */
626 static GLboolean
627 radeonInitDriver( __DRIscreen *sPriv )
628 {
629 sPriv->driverPrivate = (void *) radeonCreateScreen2( sPriv );
630 if ( !sPriv->driverPrivate ) {
631 radeonDestroyScreen( sPriv );
632 return GL_FALSE;
633 }
634
635 return GL_TRUE;
636 }
637
638
639
640 /**
641 * Create the Mesa framebuffer and renderbuffers for a given window/drawable.
642 *
643 * \todo This function (and its interface) will need to be updated to support
644 * pbuffers.
645 */
646 static GLboolean
647 radeonCreateBuffer( __DRIscreen *driScrnPriv,
648 __DRIdrawable *driDrawPriv,
649 const struct gl_config *mesaVis,
650 GLboolean isPixmap )
651 {
652 radeonScreenPtr screen = (radeonScreenPtr) driScrnPriv->driverPrivate;
653
654 const GLboolean swDepth = GL_FALSE;
655 const GLboolean swAlpha = GL_FALSE;
656 const GLboolean swAccum = mesaVis->accumRedBits > 0;
657 const GLboolean swStencil = mesaVis->stencilBits > 0 &&
658 mesaVis->depthBits != 24;
659 mesa_format rgbFormat;
660 struct radeon_framebuffer *rfb;
661
662 if (isPixmap)
663 return GL_FALSE; /* not implemented */
664
665 rfb = CALLOC_STRUCT(radeon_framebuffer);
666 if (!rfb)
667 return GL_FALSE;
668
669 _mesa_initialize_window_framebuffer(&rfb->base, mesaVis);
670
671 if (mesaVis->redBits == 5)
672 rgbFormat = _mesa_little_endian() ? MESA_FORMAT_B5G6R5_UNORM : MESA_FORMAT_R5G6B5_UNORM;
673 else if (mesaVis->alphaBits == 0)
674 rgbFormat = _mesa_little_endian() ? MESA_FORMAT_B8G8R8X8_UNORM : MESA_FORMAT_X8R8G8B8_UNORM;
675 else
676 rgbFormat = _mesa_little_endian() ? MESA_FORMAT_B8G8R8A8_UNORM : MESA_FORMAT_A8R8G8B8_UNORM;
677
678 /* front color renderbuffer */
679 rfb->color_rb[0] = radeon_create_renderbuffer(rgbFormat, driDrawPriv);
680 _mesa_attach_and_own_rb(&rfb->base, BUFFER_FRONT_LEFT, &rfb->color_rb[0]->base.Base);
681 rfb->color_rb[0]->has_surface = 1;
682
683 /* back color renderbuffer */
684 if (mesaVis->doubleBufferMode) {
685 rfb->color_rb[1] = radeon_create_renderbuffer(rgbFormat, driDrawPriv);
686 _mesa_attach_and_own_rb(&rfb->base, BUFFER_BACK_LEFT, &rfb->color_rb[1]->base.Base);
687 rfb->color_rb[1]->has_surface = 1;
688 }
689
690 if (mesaVis->depthBits == 24) {
691 if (mesaVis->stencilBits == 8) {
692 struct radeon_renderbuffer *depthStencilRb =
693 radeon_create_renderbuffer(MESA_FORMAT_Z24_UNORM_S8_UINT, driDrawPriv);
694 _mesa_attach_and_own_rb(&rfb->base, BUFFER_DEPTH, &depthStencilRb->base.Base);
695 _mesa_attach_and_reference_rb(&rfb->base, BUFFER_STENCIL, &depthStencilRb->base.Base);
696 depthStencilRb->has_surface = screen->depthHasSurface;
697 } else {
698 /* depth renderbuffer */
699 struct radeon_renderbuffer *depth =
700 radeon_create_renderbuffer(MESA_FORMAT_Z24_UNORM_X8_UINT, driDrawPriv);
701 _mesa_attach_and_own_rb(&rfb->base, BUFFER_DEPTH, &depth->base.Base);
702 depth->has_surface = screen->depthHasSurface;
703 }
704 } else if (mesaVis->depthBits == 16) {
705 /* just 16-bit depth buffer, no hw stencil */
706 struct radeon_renderbuffer *depth =
707 radeon_create_renderbuffer(MESA_FORMAT_Z_UNORM16, driDrawPriv);
708 _mesa_attach_and_own_rb(&rfb->base, BUFFER_DEPTH, &depth->base.Base);
709 depth->has_surface = screen->depthHasSurface;
710 }
711
712 _swrast_add_soft_renderbuffers(&rfb->base,
713 GL_FALSE, /* color */
714 swDepth,
715 swStencil,
716 swAccum,
717 swAlpha,
718 GL_FALSE /* aux */);
719 driDrawPriv->driverPrivate = (void *) rfb;
720
721 return (driDrawPriv->driverPrivate != NULL);
722 }
723
724
725 static void radeon_cleanup_renderbuffers(struct radeon_framebuffer *rfb)
726 {
727 struct radeon_renderbuffer *rb;
728
729 rb = rfb->color_rb[0];
730 if (rb && rb->bo) {
731 radeon_bo_unref(rb->bo);
732 rb->bo = NULL;
733 }
734 rb = rfb->color_rb[1];
735 if (rb && rb->bo) {
736 radeon_bo_unref(rb->bo);
737 rb->bo = NULL;
738 }
739 rb = radeon_get_renderbuffer(&rfb->base, BUFFER_DEPTH);
740 if (rb && rb->bo) {
741 radeon_bo_unref(rb->bo);
742 rb->bo = NULL;
743 }
744 }
745
746 void
747 radeonDestroyBuffer(__DRIdrawable *driDrawPriv)
748 {
749 struct radeon_framebuffer *rfb;
750 if (!driDrawPriv)
751 return;
752
753 rfb = (void*)driDrawPriv->driverPrivate;
754 if (!rfb)
755 return;
756 radeon_cleanup_renderbuffers(rfb);
757 _mesa_reference_framebuffer((struct gl_framebuffer **)(&(driDrawPriv->driverPrivate)), NULL);
758 }
759
760 /**
761 * This is the driver specific part of the createNewScreen entry point.
762 * Called when using DRI2.
763 *
764 * \return the struct gl_config supported by this driver
765 */
766 static const
767 __DRIconfig **radeonInitScreen2(__DRIscreen *psp)
768 {
769 static const mesa_format formats[3] = {
770 MESA_FORMAT_B5G6R5_UNORM,
771 MESA_FORMAT_B8G8R8X8_UNORM,
772 MESA_FORMAT_B8G8R8A8_UNORM
773 };
774 /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't
775 * support pageflipping at all.
776 */
777 static const GLenum back_buffer_modes[] = {
778 GLX_NONE, GLX_SWAP_UNDEFINED_OML, /*, GLX_SWAP_COPY_OML*/
779 };
780 uint8_t depth_bits[4], stencil_bits[4], msaa_samples_array[1];
781 int color;
782 __DRIconfig **configs = NULL;
783
784 psp->max_gl_compat_version = 13;
785 psp->max_gl_es1_version = 11;
786
787 if (!radeonInitDriver(psp)) {
788 return NULL;
789 }
790 depth_bits[0] = 0;
791 stencil_bits[0] = 0;
792 depth_bits[1] = 16;
793 stencil_bits[1] = 0;
794 depth_bits[2] = 24;
795 stencil_bits[2] = 0;
796 depth_bits[3] = 24;
797 stencil_bits[3] = 8;
798
799 msaa_samples_array[0] = 0;
800
801 for (color = 0; color < ARRAY_SIZE(formats); color++) {
802 __DRIconfig **new_configs;
803
804 new_configs = driCreateConfigs(formats[color],
805 depth_bits,
806 stencil_bits,
807 ARRAY_SIZE(depth_bits),
808 back_buffer_modes,
809 ARRAY_SIZE(back_buffer_modes),
810 msaa_samples_array,
811 ARRAY_SIZE(msaa_samples_array),
812 GL_TRUE, GL_FALSE);
813 configs = driConcatConfigs(configs, new_configs);
814 }
815
816 if (configs == NULL) {
817 fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__,
818 __LINE__);
819 return NULL;
820 }
821
822 return (const __DRIconfig **)configs;
823 }
824
825 static const struct __DriverAPIRec radeon_driver_api = {
826 .InitScreen = radeonInitScreen2,
827 .DestroyScreen = radeonDestroyScreen,
828 #if defined(RADEON_R200)
829 .CreateContext = r200CreateContext,
830 .DestroyContext = r200DestroyContext,
831 #else
832 .CreateContext = r100CreateContext,
833 .DestroyContext = radeonDestroyContext,
834 #endif
835 .CreateBuffer = radeonCreateBuffer,
836 .DestroyBuffer = radeonDestroyBuffer,
837 .MakeCurrent = radeonMakeCurrent,
838 .UnbindContext = radeonUnbindContext,
839 };
840
841 static const struct __DRIDriverVtableExtensionRec radeon_vtable = {
842 .base = { __DRI_DRIVER_VTABLE, 1 },
843 .vtable = &radeon_driver_api,
844 };
845
846 /* This is the table of extensions that the loader will dlsym() for. */
847 static const __DRIextension *radeon_driver_extensions[] = {
848 &driCoreExtension.base,
849 &driDRI2Extension.base,
850 &radeon_config_options.base,
851 &radeon_vtable.base,
852 NULL
853 };
854
855 #ifdef RADEON_R200
856 PUBLIC const __DRIextension **__driDriverGetExtensions_r200(void)
857 {
858 globalDriverAPI = &radeon_driver_api;
859
860 return radeon_driver_extensions;
861 }
862 #else
863 PUBLIC const __DRIextension **__driDriverGetExtensions_radeon(void)
864 {
865 globalDriverAPI = &radeon_driver_api;
866
867 return radeon_driver_extensions;
868 }
869 #endif