Merge branch 'mesa_7_7_branch'
[mesa.git] / src / gallium / state_trackers / egl / x11 / native_dri2.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 7.8
4 *
5 * Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org>
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25 #include "util/u_memory.h"
26 #include "util/u_math.h"
27 #include "util/u_format.h"
28 #include "pipe/p_compiler.h"
29 #include "pipe/p_screen.h"
30 #include "pipe/p_context.h"
31 #include "pipe/p_state.h"
32 #include "state_tracker/drm_api.h"
33 #include "egllog.h"
34
35 #include "native_x11.h"
36 #include "x11_screen.h"
37
38 enum dri2_surface_type {
39 DRI2_SURFACE_TYPE_WINDOW,
40 DRI2_SURFACE_TYPE_PIXMAP,
41 DRI2_SURFACE_TYPE_PBUFFER
42 };
43
44 struct dri2_display {
45 struct native_display base;
46 Display *dpy;
47 boolean own_dpy;
48
49 struct drm_api *api;
50 struct x11_screen *xscr;
51 int xscr_number;
52
53 struct dri2_config *configs;
54 int num_configs;
55 };
56
57 struct dri2_surface {
58 struct native_surface base;
59 Drawable drawable;
60 enum dri2_surface_type type;
61 enum pipe_format color_format;
62 struct dri2_display *dri2dpy;
63
64 struct pipe_texture *pbuffer_textures[NUM_NATIVE_ATTACHMENTS];
65 boolean have_back, have_fake;
66 int width, height;
67 unsigned int sequence_number;
68 };
69
70 struct dri2_config {
71 struct native_config base;
72 };
73
74 static INLINE struct dri2_display *
75 dri2_display(const struct native_display *ndpy)
76 {
77 return (struct dri2_display *) ndpy;
78 }
79
80 static INLINE struct dri2_surface *
81 dri2_surface(const struct native_surface *nsurf)
82 {
83 return (struct dri2_surface *) nsurf;
84 }
85
86 static INLINE struct dri2_config *
87 dri2_config(const struct native_config *nconf)
88 {
89 return (struct dri2_config *) nconf;
90 }
91
92 static boolean
93 dri2_surface_flush_frontbuffer(struct native_surface *nsurf)
94 {
95 struct dri2_surface *dri2surf = dri2_surface(nsurf);
96 struct dri2_display *dri2dpy = dri2surf->dri2dpy;
97
98 /* pbuffer is private */
99 if (dri2surf->type == DRI2_SURFACE_TYPE_PBUFFER)
100 return TRUE;
101
102 /* copy to real front buffer */
103 if (dri2surf->have_fake)
104 x11_drawable_copy_buffers(dri2dpy->xscr, dri2surf->drawable,
105 0, 0, dri2surf->width, dri2surf->height,
106 DRI2BufferFakeFrontLeft, DRI2BufferFrontLeft);
107
108 return TRUE;
109 }
110
111 static boolean
112 dri2_surface_swap_buffers(struct native_surface *nsurf)
113 {
114 struct dri2_surface *dri2surf = dri2_surface(nsurf);
115 struct dri2_display *dri2dpy = dri2surf->dri2dpy;
116
117 /* pbuffer is private */
118 if (dri2surf->type == DRI2_SURFACE_TYPE_PBUFFER)
119 return TRUE;
120
121 /* copy to front buffer */
122 if (dri2surf->have_back)
123 x11_drawable_copy_buffers(dri2dpy->xscr, dri2surf->drawable,
124 0, 0, dri2surf->width, dri2surf->height,
125 DRI2BufferBackLeft, DRI2BufferFrontLeft);
126
127 /* and update fake front buffer */
128 if (dri2surf->have_fake)
129 x11_drawable_copy_buffers(dri2dpy->xscr, dri2surf->drawable,
130 0, 0, dri2surf->width, dri2surf->height,
131 DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft);
132
133 return TRUE;
134 }
135
136 static boolean
137 dri2_surface_validate(struct native_surface *nsurf, uint attachment_mask,
138 unsigned int *seq_num, struct pipe_texture **textures,
139 int *width, int *height)
140 {
141 struct dri2_surface *dri2surf = dri2_surface(nsurf);
142 struct dri2_display *dri2dpy = dri2surf->dri2dpy;
143 unsigned int dri2atts[NUM_NATIVE_ATTACHMENTS];
144 struct pipe_texture templ;
145 struct x11_drawable_buffer *xbufs;
146 int num_ins, num_outs, att, i;
147
148 if (attachment_mask) {
149 memset(&templ, 0, sizeof(templ));
150 templ.target = PIPE_TEXTURE_2D;
151 templ.last_level = 0;
152 templ.width0 = dri2surf->width;
153 templ.height0 = dri2surf->height;
154 templ.depth0 = 1;
155 templ.format = dri2surf->color_format;
156 templ.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET;
157
158 if (textures)
159 memset(textures, 0, sizeof(*textures) * NUM_NATIVE_ATTACHMENTS);
160 }
161
162 /* create textures for pbuffer */
163 if (dri2surf->type == DRI2_SURFACE_TYPE_PBUFFER) {
164 struct pipe_screen *screen = dri2dpy->base.screen;
165
166 for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) {
167 struct pipe_texture *ptex = dri2surf->pbuffer_textures[att];
168
169 /* delay the allocation */
170 if (!native_attachment_mask_test(attachment_mask, att))
171 continue;
172
173 if (!ptex) {
174 ptex = screen->texture_create(screen, &templ);
175 dri2surf->pbuffer_textures[att] = ptex;
176 }
177
178 if (textures)
179 pipe_texture_reference(&textures[att], ptex);
180 }
181
182 if (seq_num)
183 *seq_num = dri2surf->sequence_number;
184 if (width)
185 *width = dri2surf->width;
186 if (height)
187 *height = dri2surf->height;
188
189 return TRUE;
190 }
191
192 /* prepare the attachments */
193 num_ins = 0;
194 for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) {
195 if (native_attachment_mask_test(attachment_mask, att)) {
196 unsigned int dri2att;
197
198 switch (att) {
199 case NATIVE_ATTACHMENT_FRONT_LEFT:
200 dri2att = DRI2BufferFrontLeft;
201 break;
202 case NATIVE_ATTACHMENT_BACK_LEFT:
203 dri2att = DRI2BufferBackLeft;
204 break;
205 case NATIVE_ATTACHMENT_FRONT_RIGHT:
206 dri2att = DRI2BufferFrontRight;
207 break;
208 case NATIVE_ATTACHMENT_BACK_RIGHT:
209 dri2att = DRI2BufferBackRight;
210 break;
211 default:
212 assert(0);
213 dri2att = 0;
214 break;
215 }
216
217 dri2atts[num_ins] = dri2att;
218 num_ins++;
219 }
220 }
221
222 dri2surf->have_back = FALSE;
223 dri2surf->have_fake = FALSE;
224
225 /* remember old geometry */
226 templ.width0 = dri2surf->width;
227 templ.height0 = dri2surf->height;
228
229 xbufs = x11_drawable_get_buffers(dri2dpy->xscr, dri2surf->drawable,
230 &dri2surf->width, &dri2surf->height,
231 dri2atts, FALSE, num_ins, &num_outs);
232 if (!xbufs)
233 return FALSE;
234
235 if (templ.width0 != dri2surf->width || templ.height0 != dri2surf->height) {
236 /* are there cases where the buffers change and the geometry doesn't? */
237 dri2surf->sequence_number++;
238
239 templ.width0 = dri2surf->width;
240 templ.height0 = dri2surf->height;
241 }
242
243 for (i = 0; i < num_outs; i++) {
244 struct x11_drawable_buffer *xbuf = &xbufs[i];
245 const char *desc;
246 enum native_attachment natt;
247
248 switch (xbuf->attachment) {
249 case DRI2BufferFrontLeft:
250 natt = NATIVE_ATTACHMENT_FRONT_LEFT;
251 desc = "DRI2 Front Buffer";
252 break;
253 case DRI2BufferFakeFrontLeft:
254 natt = NATIVE_ATTACHMENT_FRONT_LEFT;
255 desc = "DRI2 Fake Front Buffer";
256 dri2surf->have_fake = TRUE;
257 break;
258 case DRI2BufferBackLeft:
259 natt = NATIVE_ATTACHMENT_BACK_LEFT;
260 desc = "DRI2 Back Buffer";
261 dri2surf->have_back = TRUE;
262 break;
263 default:
264 desc = NULL;
265 break;
266 }
267
268 if (!desc || !native_attachment_mask_test(attachment_mask, natt) ||
269 (textures && textures[natt])) {
270 if (!desc)
271 _eglLog(_EGL_WARNING, "unknown buffer %d", xbuf->attachment);
272 else if (!native_attachment_mask_test(attachment_mask, natt))
273 _eglLog(_EGL_WARNING, "unexpected buffer %d", xbuf->attachment);
274 else
275 _eglLog(_EGL_WARNING, "both real and fake front buffers are listed");
276 continue;
277 }
278
279 if (textures) {
280 struct pipe_texture *ptex =
281 dri2dpy->api->texture_from_shared_handle(dri2dpy->api,
282 dri2dpy->base.screen, &templ,
283 desc, xbuf->pitch, xbuf->name);
284 if (ptex) {
285 /* the caller owns the textures */
286 textures[natt] = ptex;
287 }
288 }
289 }
290
291 free(xbufs);
292
293 if (seq_num)
294 *seq_num = dri2surf->sequence_number;
295 if (width)
296 *width = dri2surf->width;
297 if (height)
298 *height = dri2surf->height;
299
300 return TRUE;
301 }
302
303 static void
304 dri2_surface_wait(struct native_surface *nsurf)
305 {
306 struct dri2_surface *dri2surf = dri2_surface(nsurf);
307 struct dri2_display *dri2dpy = dri2surf->dri2dpy;
308
309 if (dri2surf->have_fake) {
310 x11_drawable_copy_buffers(dri2dpy->xscr, dri2surf->drawable,
311 0, 0, dri2surf->width, dri2surf->height,
312 DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft);
313 }
314 }
315
316 static void
317 dri2_surface_destroy(struct native_surface *nsurf)
318 {
319 struct dri2_surface *dri2surf = dri2_surface(nsurf);
320 int i;
321
322 for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++) {
323 struct pipe_texture *ptex = dri2surf->pbuffer_textures[i];
324 pipe_texture_reference(&ptex, NULL);
325 }
326
327 if (dri2surf->drawable)
328 x11_drawable_enable_dri2(dri2surf->dri2dpy->xscr,
329 dri2surf->drawable, FALSE);
330 free(dri2surf);
331 }
332
333 static struct dri2_surface *
334 dri2_display_create_surface(struct native_display *ndpy,
335 enum dri2_surface_type type,
336 Drawable drawable,
337 const struct native_config *nconf)
338 {
339 struct dri2_display *dri2dpy = dri2_display(ndpy);
340 struct dri2_config *dri2conf = dri2_config(nconf);
341 struct dri2_surface *dri2surf;
342
343 dri2surf = CALLOC_STRUCT(dri2_surface);
344 if (!dri2surf)
345 return NULL;
346
347 if (drawable)
348 x11_drawable_enable_dri2(dri2dpy->xscr, drawable, TRUE);
349
350 dri2surf->dri2dpy = dri2dpy;
351 dri2surf->type = type;
352 dri2surf->drawable = drawable;
353 dri2surf->color_format = dri2conf->base.color_format;
354
355 dri2surf->base.destroy = dri2_surface_destroy;
356 dri2surf->base.swap_buffers = dri2_surface_swap_buffers;
357 dri2surf->base.flush_frontbuffer = dri2_surface_flush_frontbuffer;
358 dri2surf->base.validate = dri2_surface_validate;
359 dri2surf->base.wait = dri2_surface_wait;
360
361 return dri2surf;
362 }
363
364 static struct native_surface *
365 dri2_display_create_window_surface(struct native_display *ndpy,
366 EGLNativeWindowType win,
367 const struct native_config *nconf)
368 {
369 struct dri2_surface *dri2surf;
370
371 dri2surf = dri2_display_create_surface(ndpy, DRI2_SURFACE_TYPE_WINDOW,
372 (Drawable) win, nconf);
373 return (dri2surf) ? &dri2surf->base : NULL;
374 }
375
376 static struct native_surface *
377 dri2_display_create_pixmap_surface(struct native_display *ndpy,
378 EGLNativePixmapType pix,
379 const struct native_config *nconf)
380 {
381 struct dri2_surface *dri2surf;
382
383 dri2surf = dri2_display_create_surface(ndpy, DRI2_SURFACE_TYPE_PIXMAP,
384 (Drawable) pix, nconf);
385 return (dri2surf) ? &dri2surf->base : NULL;
386 }
387
388 static struct native_surface *
389 dri2_display_create_pbuffer_surface(struct native_display *ndpy,
390 const struct native_config *nconf,
391 uint width, uint height)
392 {
393 struct dri2_surface *dri2surf;
394
395 dri2surf = dri2_display_create_surface(ndpy, DRI2_SURFACE_TYPE_PBUFFER,
396 (Drawable) None, nconf);
397 if (dri2surf) {
398 dri2surf->width = width;
399 dri2surf->height = height;
400 }
401 return (dri2surf) ? &dri2surf->base : NULL;
402 }
403
404 static struct pipe_context *
405 dri2_display_create_context(struct native_display *ndpy, void *context_private)
406 {
407 struct dri2_display *dri2dpy = dri2_display(ndpy);
408 struct pipe_context *pctx;
409
410 pctx = dri2dpy->api->create_context(dri2dpy->api, dri2dpy->base.screen);
411 if (pctx)
412 pctx->priv = context_private;
413 return pctx;
414 }
415
416 static int
417 choose_color_format(const __GLcontextModes *mode, enum pipe_format formats[32])
418 {
419 int count = 0;
420
421 switch (mode->rgbBits) {
422 case 32:
423 formats[count++] = PIPE_FORMAT_A8R8G8B8_UNORM;
424 formats[count++] = PIPE_FORMAT_B8G8R8A8_UNORM;
425 break;
426 case 24:
427 formats[count++] = PIPE_FORMAT_X8R8G8B8_UNORM;
428 formats[count++] = PIPE_FORMAT_B8G8R8X8_UNORM;
429 formats[count++] = PIPE_FORMAT_A8R8G8B8_UNORM;
430 formats[count++] = PIPE_FORMAT_B8G8R8A8_UNORM;
431 break;
432 case 16:
433 formats[count++] = PIPE_FORMAT_R5G6B5_UNORM;
434 break;
435 default:
436 break;
437 }
438
439 return count;
440 }
441
442 static int
443 choose_depth_stencil_format(const __GLcontextModes *mode,
444 enum pipe_format formats[32])
445 {
446 int count = 0;
447
448 switch (mode->depthBits) {
449 case 32:
450 formats[count++] = PIPE_FORMAT_Z32_UNORM;
451 break;
452 case 24:
453 if (mode->stencilBits) {
454 formats[count++] = PIPE_FORMAT_S8Z24_UNORM;
455 formats[count++] = PIPE_FORMAT_Z24S8_UNORM;
456 }
457 else {
458 formats[count++] = PIPE_FORMAT_X8Z24_UNORM;
459 formats[count++] = PIPE_FORMAT_Z24X8_UNORM;
460 }
461 break;
462 case 16:
463 formats[count++] = PIPE_FORMAT_Z16_UNORM;
464 break;
465 default:
466 break;
467 }
468
469 return count;
470 }
471
472 static boolean
473 is_format_supported(struct pipe_screen *screen,
474 enum pipe_format fmt, boolean is_color)
475 {
476 return screen->is_format_supported(screen, fmt, PIPE_TEXTURE_2D,
477 (is_color) ? PIPE_TEXTURE_USAGE_RENDER_TARGET :
478 PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0);
479 }
480
481 static boolean
482 dri2_display_convert_config(struct native_display *ndpy,
483 const __GLcontextModes *mode,
484 struct native_config *nconf)
485 {
486 enum pipe_format formats[32];
487 int num_formats, i;
488
489 if (!(mode->renderType & GLX_RGBA_BIT) || !mode->rgbMode)
490 return FALSE;
491
492 /* skip single-buffered configs */
493 if (!mode->doubleBufferMode)
494 return FALSE;
495
496 nconf->mode = *mode;
497 nconf->mode.renderType = GLX_RGBA_BIT;
498 nconf->mode.rgbMode = TRUE;
499 /* pbuffer is allocated locally and is always supported */
500 nconf->mode.drawableType |= GLX_PBUFFER_BIT;
501 /* the swap method is always copy */
502 nconf->mode.swapMethod = GLX_SWAP_COPY_OML;
503
504 /* fix up */
505 nconf->mode.rgbBits =
506 nconf->mode.redBits + nconf->mode.greenBits +
507 nconf->mode.blueBits + nconf->mode.alphaBits;
508 if (!(nconf->mode.drawableType & GLX_WINDOW_BIT)) {
509 nconf->mode.visualID = 0;
510 nconf->mode.visualType = GLX_NONE;
511 }
512 if (!(nconf->mode.drawableType & GLX_PBUFFER_BIT)) {
513 nconf->mode.bindToTextureRgb = FALSE;
514 nconf->mode.bindToTextureRgba = FALSE;
515 }
516
517 nconf->color_format = PIPE_FORMAT_NONE;
518 nconf->depth_format = PIPE_FORMAT_NONE;
519 nconf->stencil_format = PIPE_FORMAT_NONE;
520
521 /* choose color format */
522 num_formats = choose_color_format(mode, formats);
523 for (i = 0; i < num_formats; i++) {
524 if (is_format_supported(ndpy->screen, formats[i], TRUE)) {
525 nconf->color_format = formats[i];
526 break;
527 }
528 }
529 if (nconf->color_format == PIPE_FORMAT_NONE)
530 return FALSE;
531
532 /* choose depth/stencil format */
533 num_formats = choose_depth_stencil_format(mode, formats);
534 for (i = 0; i < num_formats; i++) {
535 if (is_format_supported(ndpy->screen, formats[i], FALSE)) {
536 nconf->depth_format = formats[i];
537 nconf->stencil_format = formats[i];
538 break;
539 }
540 }
541 if ((nconf->mode.depthBits && nconf->depth_format == PIPE_FORMAT_NONE) ||
542 (nconf->mode.stencilBits && nconf->stencil_format == PIPE_FORMAT_NONE))
543 return FALSE;
544
545 return TRUE;
546 }
547
548 static const struct native_config **
549 dri2_display_get_configs(struct native_display *ndpy, int *num_configs)
550 {
551 struct dri2_display *dri2dpy = dri2_display(ndpy);
552 const struct native_config **configs;
553 int i;
554
555 /* first time */
556 if (!dri2dpy->configs) {
557 const __GLcontextModes *modes;
558 int num_modes, count;
559
560 modes = x11_screen_get_glx_configs(dri2dpy->xscr);
561 if (!modes)
562 return NULL;
563 num_modes = x11_context_modes_count(modes);
564
565 dri2dpy->configs = calloc(num_modes, sizeof(*dri2dpy->configs));
566 if (!dri2dpy->configs)
567 return NULL;
568
569 count = 0;
570 for (i = 0; i < num_modes; i++) {
571 struct native_config *nconf = &dri2dpy->configs[count].base;
572 if (dri2_display_convert_config(&dri2dpy->base, modes, nconf))
573 count++;
574 modes = modes->next;
575 }
576
577 dri2dpy->num_configs = count;
578 }
579
580 configs = malloc(dri2dpy->num_configs * sizeof(*configs));
581 if (configs) {
582 for (i = 0; i < dri2dpy->num_configs; i++)
583 configs[i] = (const struct native_config *) &dri2dpy->configs[i];
584 if (num_configs)
585 *num_configs = dri2dpy->num_configs;
586 }
587
588 return configs;
589 }
590
591 static boolean
592 dri2_display_is_pixmap_supported(struct native_display *ndpy,
593 EGLNativePixmapType pix,
594 const struct native_config *nconf)
595 {
596 struct dri2_display *dri2dpy = dri2_display(ndpy);
597 uint depth, nconf_depth;
598
599 depth = x11_drawable_get_depth(dri2dpy->xscr, (Drawable) pix);
600 nconf_depth = util_format_get_blocksizebits(nconf->color_format);
601
602 /* simple depth match for now */
603 return (depth == nconf_depth || (depth == 24 && depth + 8 == nconf_depth));
604 }
605
606 static void
607 dri2_display_destroy(struct native_display *ndpy)
608 {
609 struct dri2_display *dri2dpy = dri2_display(ndpy);
610
611 if (dri2dpy->configs)
612 free(dri2dpy->configs);
613
614 if (dri2dpy->base.screen)
615 dri2dpy->base.screen->destroy(dri2dpy->base.screen);
616
617 if (dri2dpy->xscr)
618 x11_screen_destroy(dri2dpy->xscr);
619 if (dri2dpy->own_dpy)
620 XCloseDisplay(dri2dpy->dpy);
621 if (dri2dpy->api && dri2dpy->api->destroy)
622 dri2dpy->api->destroy(dri2dpy->api);
623 free(dri2dpy);
624 }
625
626 /**
627 * Initialize DRI2 and pipe screen.
628 */
629 static boolean
630 dri2_display_init_screen(struct native_display *ndpy)
631 {
632 struct dri2_display *dri2dpy = dri2_display(ndpy);
633 const char *driver = dri2dpy->api->name;
634 struct drm_create_screen_arg arg;
635 int fd;
636
637 if (!x11_screen_support(dri2dpy->xscr, X11_SCREEN_EXTENSION_DRI2) ||
638 !x11_screen_support(dri2dpy->xscr, X11_SCREEN_EXTENSION_GLX)) {
639 _eglLog(_EGL_WARNING, "GLX/DRI2 is not supported");
640 return FALSE;
641 }
642
643 fd = x11_screen_enable_dri2(dri2dpy->xscr, driver);
644 if (fd < 0)
645 return FALSE;
646
647 memset(&arg, 0, sizeof(arg));
648 arg.mode = DRM_CREATE_NORMAL;
649 dri2dpy->base.screen = dri2dpy->api->create_screen(dri2dpy->api, fd, &arg);
650 if (!dri2dpy->base.screen) {
651 _eglLog(_EGL_WARNING, "failed to create DRM screen");
652 return FALSE;
653 }
654
655 return TRUE;
656 }
657
658 struct native_display *
659 x11_create_dri2_display(EGLNativeDisplayType dpy, struct drm_api *api)
660 {
661 struct dri2_display *dri2dpy;
662
663 dri2dpy = CALLOC_STRUCT(dri2_display);
664 if (!dri2dpy)
665 return NULL;
666
667 dri2dpy->api = api;
668 if (!dri2dpy->api) {
669 _eglLog(_EGL_WARNING, "failed to create DRM API");
670 free(dri2dpy);
671 return NULL;
672 }
673
674 dri2dpy->dpy = dpy;
675 if (!dri2dpy->dpy) {
676 dri2dpy->dpy = XOpenDisplay(NULL);
677 if (!dri2dpy->dpy) {
678 dri2_display_destroy(&dri2dpy->base);
679 return NULL;
680 }
681 dri2dpy->own_dpy = TRUE;
682 }
683
684 dri2dpy->xscr_number = DefaultScreen(dri2dpy->dpy);
685 dri2dpy->xscr = x11_screen_create(dri2dpy->dpy, dri2dpy->xscr_number);
686 if (!dri2dpy->xscr) {
687 dri2_display_destroy(&dri2dpy->base);
688 return NULL;
689 }
690
691 if (!dri2_display_init_screen(&dri2dpy->base)) {
692 dri2_display_destroy(&dri2dpy->base);
693 return NULL;
694 }
695
696 dri2dpy->base.destroy = dri2_display_destroy;
697 dri2dpy->base.get_configs = dri2_display_get_configs;
698 dri2dpy->base.is_pixmap_supported = dri2_display_is_pixmap_supported;
699 dri2dpy->base.create_context = dri2_display_create_context;
700 dri2dpy->base.create_window_surface = dri2_display_create_window_surface;
701 dri2dpy->base.create_pixmap_surface = dri2_display_create_pixmap_surface;
702 dri2dpy->base.create_pbuffer_surface = dri2_display_create_pbuffer_surface;
703
704 return &dri2dpy->base;
705 }