2 * Mesa 3-D graphics library
5 * Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org>
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:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
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.
25 #include "util/u_memory.h"
26 #include "util/u_math.h"
27 #include "util/u_format.h"
28 #include "util/u_inlines.h"
29 #include "pipe/p_compiler.h"
30 #include "pipe/p_screen.h"
31 #include "pipe/p_context.h"
32 #include "pipe/p_state.h"
33 #include "state_tracker/drm_api.h"
36 #include "native_x11.h"
37 #include "x11_screen.h"
39 enum dri2_surface_type
{
40 DRI2_SURFACE_TYPE_WINDOW
,
41 DRI2_SURFACE_TYPE_PIXMAP
,
42 DRI2_SURFACE_TYPE_PBUFFER
46 struct native_display base
;
51 struct x11_screen
*xscr
;
54 struct dri2_config
*configs
;
59 struct native_surface base
;
61 enum dri2_surface_type type
;
62 enum pipe_format color_format
;
63 struct dri2_display
*dri2dpy
;
65 unsigned int sequence_number
;
67 struct pipe_texture
*textures
[NUM_NATIVE_ATTACHMENTS
];
70 boolean have_back
, have_fake
;
72 struct x11_drawable_buffer
*last_xbufs
;
77 struct native_config base
;
80 static INLINE
struct dri2_display
*
81 dri2_display(const struct native_display
*ndpy
)
83 return (struct dri2_display
*) ndpy
;
86 static INLINE
struct dri2_surface
*
87 dri2_surface(const struct native_surface
*nsurf
)
89 return (struct dri2_surface
*) nsurf
;
92 static INLINE
struct dri2_config
*
93 dri2_config(const struct native_config
*nconf
)
95 return (struct dri2_config
*) nconf
;
99 * Get the buffers from the server.
102 dri2_surface_get_buffers(struct native_surface
*nsurf
, uint buffer_mask
)
104 struct dri2_surface
*dri2surf
= dri2_surface(nsurf
);
105 struct dri2_display
*dri2dpy
= dri2surf
->dri2dpy
;
106 unsigned int dri2atts
[NUM_NATIVE_ATTACHMENTS
];
107 int num_ins
, num_outs
, att
, i
;
108 struct x11_drawable_buffer
*xbufs
;
109 struct pipe_texture templ
;
112 /* prepare the attachments */
114 for (att
= 0; att
< NUM_NATIVE_ATTACHMENTS
; att
++) {
115 if (native_attachment_mask_test(buffer_mask
, att
)) {
116 unsigned int dri2att
;
119 case NATIVE_ATTACHMENT_FRONT_LEFT
:
120 dri2att
= DRI2BufferFrontLeft
;
122 case NATIVE_ATTACHMENT_BACK_LEFT
:
123 dri2att
= DRI2BufferBackLeft
;
125 case NATIVE_ATTACHMENT_FRONT_RIGHT
:
126 dri2att
= DRI2BufferFrontRight
;
128 case NATIVE_ATTACHMENT_BACK_RIGHT
:
129 dri2att
= DRI2BufferBackRight
;
137 dri2atts
[num_ins
] = dri2att
;
142 xbufs
= x11_drawable_get_buffers(dri2dpy
->xscr
, dri2surf
->drawable
,
143 &dri2surf
->width
, &dri2surf
->height
,
144 dri2atts
, FALSE
, num_ins
, &num_outs
);
146 /* we should be able to do better... */
147 if (xbufs
&& dri2surf
->last_num_xbufs
== num_outs
&&
148 memcmp(dri2surf
->last_xbufs
, xbufs
, sizeof(*xbufs
) * num_outs
) == 0) {
153 /* free the old buffers */
154 for (i
= 0; i
< NUM_NATIVE_ATTACHMENTS
; i
++)
155 pipe_texture_reference(&dri2surf
->textures
[i
], NULL
);
156 dri2surf
->valid_mask
= 0x0;
157 dri2surf
->sequence_number
++;
159 dri2surf
->have_back
= FALSE
;
160 dri2surf
->have_fake
= FALSE
;
165 memset(&templ
, 0, sizeof(templ
));
166 templ
.target
= PIPE_TEXTURE_2D
;
167 templ
.last_level
= 0;
168 templ
.width0
= dri2surf
->width
;
169 templ
.height0
= dri2surf
->height
;
171 templ
.format
= dri2surf
->color_format
;
172 templ
.tex_usage
= PIPE_TEXTURE_USAGE_RENDER_TARGET
;
175 for (i
= 0; i
< num_outs
; i
++) {
176 struct x11_drawable_buffer
*xbuf
= &xbufs
[i
];
178 enum native_attachment natt
;
180 switch (xbuf
->attachment
) {
181 case DRI2BufferFrontLeft
:
182 natt
= NATIVE_ATTACHMENT_FRONT_LEFT
;
183 desc
= "DRI2 Front Buffer";
185 case DRI2BufferFakeFrontLeft
:
186 natt
= NATIVE_ATTACHMENT_FRONT_LEFT
;
187 desc
= "DRI2 Fake Front Buffer";
188 dri2surf
->have_fake
= TRUE
;
190 case DRI2BufferBackLeft
:
191 natt
= NATIVE_ATTACHMENT_BACK_LEFT
;
192 desc
= "DRI2 Back Buffer";
193 dri2surf
->have_back
= TRUE
;
200 if (!desc
|| dri2surf
->textures
[natt
]) {
202 _eglLog(_EGL_WARNING
, "unknown buffer %d", xbuf
->attachment
);
204 _eglLog(_EGL_WARNING
, "both real and fake front buffers are listed");
208 dri2surf
->textures
[natt
] =
209 dri2dpy
->api
->texture_from_shared_handle(dri2dpy
->api
,
210 dri2dpy
->base
.screen
, &templ
, desc
, xbuf
->pitch
, xbuf
->name
);
211 if (dri2surf
->textures
[natt
])
212 valid_mask
|= 1 << natt
;
215 if (dri2surf
->last_xbufs
)
216 free(dri2surf
->last_xbufs
);
217 dri2surf
->last_xbufs
= xbufs
;
218 dri2surf
->last_num_xbufs
= num_outs
;
220 dri2surf
->valid_mask
= valid_mask
;
224 * Update the buffers of the surface. This is a slow function due to the
225 * round-trip to the server.
228 dri2_surface_update_buffers(struct native_surface
*nsurf
, uint buffer_mask
)
230 struct dri2_surface
*dri2surf
= dri2_surface(nsurf
);
231 struct dri2_display
*dri2dpy
= dri2surf
->dri2dpy
;
233 /* create textures for pbuffer */
234 if (dri2surf
->type
== DRI2_SURFACE_TYPE_PBUFFER
) {
235 struct pipe_screen
*screen
= dri2dpy
->base
.screen
;
236 struct pipe_texture templ
;
237 uint new_valid
= 0x0;
240 buffer_mask
&= ~dri2surf
->valid_mask
;
244 memset(&templ
, 0, sizeof(templ
));
245 templ
.target
= PIPE_TEXTURE_2D
;
246 templ
.last_level
= 0;
247 templ
.width0
= dri2surf
->width
;
248 templ
.height0
= dri2surf
->height
;
250 templ
.format
= dri2surf
->color_format
;
251 templ
.tex_usage
= PIPE_TEXTURE_USAGE_RENDER_TARGET
;
253 for (att
= 0; att
< NUM_NATIVE_ATTACHMENTS
; att
++) {
254 if (native_attachment_mask_test(buffer_mask
, att
)) {
255 assert(!dri2surf
->textures
[att
]);
257 dri2surf
->textures
[att
] = screen
->texture_create(screen
, &templ
);
258 if (!dri2surf
->textures
[att
])
261 new_valid
|= 1 << att
;
262 if (new_valid
== buffer_mask
)
266 dri2surf
->valid_mask
|= new_valid
;
267 /* no need to update sequence number */
270 dri2_surface_get_buffers(&dri2surf
->base
, buffer_mask
);
273 return ((dri2surf
->valid_mask
& buffer_mask
) == buffer_mask
);
277 dri2_surface_flush_frontbuffer(struct native_surface
*nsurf
)
279 struct dri2_surface
*dri2surf
= dri2_surface(nsurf
);
280 struct dri2_display
*dri2dpy
= dri2surf
->dri2dpy
;
282 /* pbuffer is private */
283 if (dri2surf
->type
== DRI2_SURFACE_TYPE_PBUFFER
)
286 /* copy to real front buffer */
287 if (dri2surf
->have_fake
)
288 x11_drawable_copy_buffers(dri2dpy
->xscr
, dri2surf
->drawable
,
289 0, 0, dri2surf
->width
, dri2surf
->height
,
290 DRI2BufferFakeFrontLeft
, DRI2BufferFrontLeft
);
296 dri2_surface_swap_buffers(struct native_surface
*nsurf
)
298 struct dri2_surface
*dri2surf
= dri2_surface(nsurf
);
299 struct dri2_display
*dri2dpy
= dri2surf
->dri2dpy
;
301 /* pbuffer is private */
302 if (dri2surf
->type
== DRI2_SURFACE_TYPE_PBUFFER
)
305 /* copy to front buffer */
306 if (dri2surf
->have_back
)
307 x11_drawable_copy_buffers(dri2dpy
->xscr
, dri2surf
->drawable
,
308 0, 0, dri2surf
->width
, dri2surf
->height
,
309 DRI2BufferBackLeft
, DRI2BufferFrontLeft
);
311 /* and update fake front buffer */
312 if (dri2surf
->have_fake
)
313 x11_drawable_copy_buffers(dri2dpy
->xscr
, dri2surf
->drawable
,
314 0, 0, dri2surf
->width
, dri2surf
->height
,
315 DRI2BufferFrontLeft
, DRI2BufferFakeFrontLeft
);
321 dri2_surface_validate(struct native_surface
*nsurf
, uint attachment_mask
,
322 unsigned int *seq_num
, struct pipe_texture
**textures
,
323 int *width
, int *height
)
325 struct dri2_surface
*dri2surf
= dri2_surface(nsurf
);
327 if (!dri2_surface_update_buffers(&dri2surf
->base
, attachment_mask
))
331 *seq_num
= dri2surf
->sequence_number
;
335 for (att
= 0; att
< NUM_NATIVE_ATTACHMENTS
; att
++) {
336 if (native_attachment_mask_test(attachment_mask
, att
)) {
337 struct pipe_texture
*ptex
= dri2surf
->textures
[att
];
339 textures
[att
] = NULL
;
340 pipe_texture_reference(&textures
[att
], ptex
);
346 *width
= dri2surf
->width
;
348 *height
= dri2surf
->height
;
354 dri2_surface_wait(struct native_surface
*nsurf
)
356 struct dri2_surface
*dri2surf
= dri2_surface(nsurf
);
357 struct dri2_display
*dri2dpy
= dri2surf
->dri2dpy
;
359 if (dri2surf
->have_fake
) {
360 x11_drawable_copy_buffers(dri2dpy
->xscr
, dri2surf
->drawable
,
361 0, 0, dri2surf
->width
, dri2surf
->height
,
362 DRI2BufferFrontLeft
, DRI2BufferFakeFrontLeft
);
367 dri2_surface_destroy(struct native_surface
*nsurf
)
369 struct dri2_surface
*dri2surf
= dri2_surface(nsurf
);
372 if (dri2surf
->last_xbufs
)
373 free(dri2surf
->last_xbufs
);
375 for (i
= 0; i
< NUM_NATIVE_ATTACHMENTS
; i
++) {
376 struct pipe_texture
*ptex
= dri2surf
->textures
[i
];
377 pipe_texture_reference(&ptex
, NULL
);
380 if (dri2surf
->drawable
)
381 x11_drawable_enable_dri2(dri2surf
->dri2dpy
->xscr
,
382 dri2surf
->drawable
, FALSE
);
386 static struct dri2_surface
*
387 dri2_display_create_surface(struct native_display
*ndpy
,
388 enum dri2_surface_type type
,
390 const struct native_config
*nconf
)
392 struct dri2_display
*dri2dpy
= dri2_display(ndpy
);
393 struct dri2_config
*dri2conf
= dri2_config(nconf
);
394 struct dri2_surface
*dri2surf
;
396 dri2surf
= CALLOC_STRUCT(dri2_surface
);
400 dri2surf
->dri2dpy
= dri2dpy
;
401 dri2surf
->type
= type
;
402 dri2surf
->drawable
= drawable
;
403 dri2surf
->color_format
= dri2conf
->base
.color_format
;
405 dri2surf
->base
.destroy
= dri2_surface_destroy
;
406 dri2surf
->base
.swap_buffers
= dri2_surface_swap_buffers
;
407 dri2surf
->base
.flush_frontbuffer
= dri2_surface_flush_frontbuffer
;
408 dri2surf
->base
.validate
= dri2_surface_validate
;
409 dri2surf
->base
.wait
= dri2_surface_wait
;
412 x11_drawable_enable_dri2(dri2dpy
->xscr
, drawable
, TRUE
);
417 static struct native_surface
*
418 dri2_display_create_window_surface(struct native_display
*ndpy
,
419 EGLNativeWindowType win
,
420 const struct native_config
*nconf
)
422 struct dri2_surface
*dri2surf
;
424 dri2surf
= dri2_display_create_surface(ndpy
, DRI2_SURFACE_TYPE_WINDOW
,
425 (Drawable
) win
, nconf
);
426 return (dri2surf
) ? &dri2surf
->base
: NULL
;
429 static struct native_surface
*
430 dri2_display_create_pixmap_surface(struct native_display
*ndpy
,
431 EGLNativePixmapType pix
,
432 const struct native_config
*nconf
)
434 struct dri2_surface
*dri2surf
;
436 dri2surf
= dri2_display_create_surface(ndpy
, DRI2_SURFACE_TYPE_PIXMAP
,
437 (Drawable
) pix
, nconf
);
438 return (dri2surf
) ? &dri2surf
->base
: NULL
;
441 static struct native_surface
*
442 dri2_display_create_pbuffer_surface(struct native_display
*ndpy
,
443 const struct native_config
*nconf
,
444 uint width
, uint height
)
446 struct dri2_surface
*dri2surf
;
448 dri2surf
= dri2_display_create_surface(ndpy
, DRI2_SURFACE_TYPE_PBUFFER
,
449 (Drawable
) None
, nconf
);
451 dri2surf
->width
= width
;
452 dri2surf
->height
= height
;
454 return (dri2surf
) ? &dri2surf
->base
: NULL
;
458 choose_color_format(const __GLcontextModes
*mode
, enum pipe_format formats
[32])
462 switch (mode
->rgbBits
) {
464 formats
[count
++] = PIPE_FORMAT_A8R8G8B8_UNORM
;
465 formats
[count
++] = PIPE_FORMAT_B8G8R8A8_UNORM
;
468 formats
[count
++] = PIPE_FORMAT_X8R8G8B8_UNORM
;
469 formats
[count
++] = PIPE_FORMAT_B8G8R8X8_UNORM
;
470 formats
[count
++] = PIPE_FORMAT_A8R8G8B8_UNORM
;
471 formats
[count
++] = PIPE_FORMAT_B8G8R8A8_UNORM
;
474 formats
[count
++] = PIPE_FORMAT_R5G6B5_UNORM
;
484 choose_depth_stencil_format(const __GLcontextModes
*mode
,
485 enum pipe_format formats
[32])
489 switch (mode
->depthBits
) {
491 formats
[count
++] = PIPE_FORMAT_Z32_UNORM
;
494 if (mode
->stencilBits
) {
495 formats
[count
++] = PIPE_FORMAT_S8Z24_UNORM
;
496 formats
[count
++] = PIPE_FORMAT_Z24S8_UNORM
;
499 formats
[count
++] = PIPE_FORMAT_X8Z24_UNORM
;
500 formats
[count
++] = PIPE_FORMAT_Z24X8_UNORM
;
504 formats
[count
++] = PIPE_FORMAT_Z16_UNORM
;
514 is_format_supported(struct pipe_screen
*screen
,
515 enum pipe_format fmt
, boolean is_color
)
517 return screen
->is_format_supported(screen
, fmt
, PIPE_TEXTURE_2D
,
518 (is_color
) ? PIPE_TEXTURE_USAGE_RENDER_TARGET
:
519 PIPE_TEXTURE_USAGE_DEPTH_STENCIL
, 0);
523 dri2_display_convert_config(struct native_display
*ndpy
,
524 const __GLcontextModes
*mode
,
525 struct native_config
*nconf
)
527 enum pipe_format formats
[32];
530 if (!(mode
->renderType
& GLX_RGBA_BIT
) || !mode
->rgbMode
)
533 /* skip single-buffered configs */
534 if (!mode
->doubleBufferMode
)
538 nconf
->mode
.renderType
= GLX_RGBA_BIT
;
539 nconf
->mode
.rgbMode
= TRUE
;
540 /* pbuffer is allocated locally and is always supported */
541 nconf
->mode
.drawableType
|= GLX_PBUFFER_BIT
;
542 /* the swap method is always copy */
543 nconf
->mode
.swapMethod
= GLX_SWAP_COPY_OML
;
546 nconf
->mode
.rgbBits
=
547 nconf
->mode
.redBits
+ nconf
->mode
.greenBits
+
548 nconf
->mode
.blueBits
+ nconf
->mode
.alphaBits
;
549 if (!(nconf
->mode
.drawableType
& GLX_WINDOW_BIT
)) {
550 nconf
->mode
.visualID
= 0;
551 nconf
->mode
.visualType
= GLX_NONE
;
553 if (!(nconf
->mode
.drawableType
& GLX_PBUFFER_BIT
)) {
554 nconf
->mode
.bindToTextureRgb
= FALSE
;
555 nconf
->mode
.bindToTextureRgba
= FALSE
;
558 nconf
->color_format
= PIPE_FORMAT_NONE
;
559 nconf
->depth_format
= PIPE_FORMAT_NONE
;
560 nconf
->stencil_format
= PIPE_FORMAT_NONE
;
562 /* choose color format */
563 num_formats
= choose_color_format(mode
, formats
);
564 for (i
= 0; i
< num_formats
; i
++) {
565 if (is_format_supported(ndpy
->screen
, formats
[i
], TRUE
)) {
566 nconf
->color_format
= formats
[i
];
570 if (nconf
->color_format
== PIPE_FORMAT_NONE
)
573 /* choose depth/stencil format */
574 num_formats
= choose_depth_stencil_format(mode
, formats
);
575 for (i
= 0; i
< num_formats
; i
++) {
576 if (is_format_supported(ndpy
->screen
, formats
[i
], FALSE
)) {
577 nconf
->depth_format
= formats
[i
];
578 nconf
->stencil_format
= formats
[i
];
582 if ((nconf
->mode
.depthBits
&& nconf
->depth_format
== PIPE_FORMAT_NONE
) ||
583 (nconf
->mode
.stencilBits
&& nconf
->stencil_format
== PIPE_FORMAT_NONE
))
589 static const struct native_config
**
590 dri2_display_get_configs(struct native_display
*ndpy
, int *num_configs
)
592 struct dri2_display
*dri2dpy
= dri2_display(ndpy
);
593 const struct native_config
**configs
;
597 if (!dri2dpy
->configs
) {
598 const __GLcontextModes
*modes
;
599 int num_modes
, count
;
601 modes
= x11_screen_get_glx_configs(dri2dpy
->xscr
);
604 num_modes
= x11_context_modes_count(modes
);
606 dri2dpy
->configs
= calloc(num_modes
, sizeof(*dri2dpy
->configs
));
607 if (!dri2dpy
->configs
)
611 for (i
= 0; i
< num_modes
; i
++) {
612 struct native_config
*nconf
= &dri2dpy
->configs
[count
].base
;
613 if (dri2_display_convert_config(&dri2dpy
->base
, modes
, nconf
))
618 dri2dpy
->num_configs
= count
;
621 configs
= malloc(dri2dpy
->num_configs
* sizeof(*configs
));
623 for (i
= 0; i
< dri2dpy
->num_configs
; i
++)
624 configs
[i
] = (const struct native_config
*) &dri2dpy
->configs
[i
];
626 *num_configs
= dri2dpy
->num_configs
;
633 dri2_display_is_pixmap_supported(struct native_display
*ndpy
,
634 EGLNativePixmapType pix
,
635 const struct native_config
*nconf
)
637 struct dri2_display
*dri2dpy
= dri2_display(ndpy
);
638 uint depth
, nconf_depth
;
640 depth
= x11_drawable_get_depth(dri2dpy
->xscr
, (Drawable
) pix
);
641 nconf_depth
= util_format_get_blocksizebits(nconf
->color_format
);
643 /* simple depth match for now */
644 return (depth
== nconf_depth
|| (depth
== 24 && depth
+ 8 == nconf_depth
));
648 dri2_display_destroy(struct native_display
*ndpy
)
650 struct dri2_display
*dri2dpy
= dri2_display(ndpy
);
652 if (dri2dpy
->configs
)
653 free(dri2dpy
->configs
);
655 if (dri2dpy
->base
.screen
)
656 dri2dpy
->base
.screen
->destroy(dri2dpy
->base
.screen
);
659 x11_screen_destroy(dri2dpy
->xscr
);
660 if (dri2dpy
->own_dpy
)
661 XCloseDisplay(dri2dpy
->dpy
);
662 if (dri2dpy
->api
&& dri2dpy
->api
->destroy
)
663 dri2dpy
->api
->destroy(dri2dpy
->api
);
668 * Initialize DRI2 and pipe screen.
671 dri2_display_init_screen(struct native_display
*ndpy
)
673 struct dri2_display
*dri2dpy
= dri2_display(ndpy
);
674 const char *driver
= dri2dpy
->api
->name
;
675 struct drm_create_screen_arg arg
;
678 if (!x11_screen_support(dri2dpy
->xscr
, X11_SCREEN_EXTENSION_DRI2
) ||
679 !x11_screen_support(dri2dpy
->xscr
, X11_SCREEN_EXTENSION_GLX
)) {
680 _eglLog(_EGL_WARNING
, "GLX/DRI2 is not supported");
684 fd
= x11_screen_enable_dri2(dri2dpy
->xscr
, driver
);
688 memset(&arg
, 0, sizeof(arg
));
689 arg
.mode
= DRM_CREATE_NORMAL
;
690 dri2dpy
->base
.screen
= dri2dpy
->api
->create_screen(dri2dpy
->api
, fd
, &arg
);
691 if (!dri2dpy
->base
.screen
) {
692 _eglLog(_EGL_WARNING
, "failed to create DRM screen");
699 struct native_display
*
700 x11_create_dri2_display(EGLNativeDisplayType dpy
, struct drm_api
*api
)
702 struct dri2_display
*dri2dpy
;
704 dri2dpy
= CALLOC_STRUCT(dri2_display
);
710 _eglLog(_EGL_WARNING
, "failed to create DRM API");
717 dri2dpy
->dpy
= XOpenDisplay(NULL
);
719 dri2_display_destroy(&dri2dpy
->base
);
722 dri2dpy
->own_dpy
= TRUE
;
725 dri2dpy
->xscr_number
= DefaultScreen(dri2dpy
->dpy
);
726 dri2dpy
->xscr
= x11_screen_create(dri2dpy
->dpy
, dri2dpy
->xscr_number
);
727 if (!dri2dpy
->xscr
) {
728 dri2_display_destroy(&dri2dpy
->base
);
732 if (!dri2_display_init_screen(&dri2dpy
->base
)) {
733 dri2_display_destroy(&dri2dpy
->base
);
737 dri2dpy
->base
.destroy
= dri2_display_destroy
;
738 dri2dpy
->base
.get_configs
= dri2_display_get_configs
;
739 dri2dpy
->base
.is_pixmap_supported
= dri2_display_is_pixmap_supported
;
740 dri2dpy
->base
.create_window_surface
= dri2_display_create_window_surface
;
741 dri2dpy
->base
.create_pixmap_surface
= dri2_display_create_pixmap_surface
;
742 dri2dpy
->base
.create_pbuffer_surface
= dri2_display_create_pbuffer_surface
;
744 return &dri2dpy
->base
;