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