Merge branch 'gallium-vertexelementcso'
[mesa.git] / src / gallium / state_trackers / egl / common / egl_g3d.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 <assert.h>
26 #include <stdio.h>
27 #include <string.h>
28 #include "pipe/p_screen.h"
29 #include "util/u_memory.h"
30 #include "util/u_rect.h"
31 #include "util/u_inlines.h"
32 #include "egldriver.h"
33 #include "eglcurrent.h"
34 #include "eglconfigutil.h"
35 #include "egllog.h"
36
37 #include "native.h"
38 #include "egl_g3d.h"
39 #include "egl_g3d_image.h"
40 #include "egl_st.h"
41
42 /**
43 * Validate the draw/read surfaces of the context.
44 */
45 static void
46 egl_g3d_validate_context(_EGLDisplay *dpy, _EGLContext *ctx)
47 {
48 struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
49 struct pipe_screen *screen = gdpy->native->screen;
50 struct egl_g3d_context *gctx = egl_g3d_context(ctx);
51 const uint st_att_map[NUM_NATIVE_ATTACHMENTS] = {
52 ST_SURFACE_FRONT_LEFT,
53 ST_SURFACE_BACK_LEFT,
54 ST_SURFACE_FRONT_RIGHT,
55 ST_SURFACE_BACK_RIGHT,
56 };
57 EGLint num_surfaces, s;
58
59 /* validate draw and/or read buffers */
60 num_surfaces = (gctx->base.ReadSurface == gctx->base.DrawSurface) ? 1 : 2;
61 for (s = 0; s < num_surfaces; s++) {
62 struct pipe_texture *textures[NUM_NATIVE_ATTACHMENTS];
63 struct egl_g3d_surface *gsurf;
64 struct egl_g3d_buffer *gbuf;
65 EGLint att;
66
67 if (s == 0) {
68 gsurf = egl_g3d_surface(gctx->base.DrawSurface);
69 gbuf = &gctx->draw;
70 }
71 else {
72 gsurf = egl_g3d_surface(gctx->base.ReadSurface);
73 gbuf = &gctx->read;
74 }
75
76 if (!gctx->force_validate) {
77 unsigned int seq_num;
78
79 gsurf->native->validate(gsurf->native, gbuf->attachment_mask,
80 &seq_num, NULL, NULL, NULL);
81 /* skip validation */
82 if (gsurf->sequence_number == seq_num)
83 continue;
84 }
85
86 pipe_surface_reference(&gsurf->render_surface, NULL);
87 memset(textures, 0, sizeof(textures));
88
89 gsurf->native->validate(gsurf->native, gbuf->attachment_mask,
90 &gsurf->sequence_number, textures,
91 &gsurf->base.Width, &gsurf->base.Height);
92 for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) {
93 struct pipe_texture *pt = textures[att];
94 struct pipe_surface *ps;
95
96 if (native_attachment_mask_test(gbuf->attachment_mask, att) && pt) {
97 ps = screen->get_tex_surface(screen, pt, 0, 0, 0,
98 PIPE_BUFFER_USAGE_GPU_READ |
99 PIPE_BUFFER_USAGE_GPU_WRITE);
100 gctx->stapi->st_set_framebuffer_surface(gbuf->st_fb,
101 st_att_map[att], ps);
102
103 if (gsurf->render_att == att)
104 pipe_surface_reference(&gsurf->render_surface, ps);
105
106 pipe_surface_reference(&ps, NULL);
107 pipe_texture_reference(&pt, NULL);
108 }
109 }
110
111 gctx->stapi->st_resize_framebuffer(gbuf->st_fb,
112 gsurf->base.Width, gsurf->base.Height);
113 }
114
115 gctx->force_validate = EGL_FALSE;
116
117 }
118
119 /**
120 * Create a st_framebuffer.
121 */
122 static struct st_framebuffer *
123 create_framebuffer(_EGLContext *ctx, _EGLSurface *surf)
124 {
125 struct egl_g3d_context *gctx = egl_g3d_context(ctx);
126 struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
127 struct egl_g3d_config *gconf = egl_g3d_config(gsurf->base.Config);
128
129 return gctx->stapi->st_create_framebuffer(&gconf->native->mode,
130 gconf->native->color_format, gconf->native->depth_format,
131 gconf->native->stencil_format,
132 gsurf->base.Width, gsurf->base.Height, &gsurf->base);
133 }
134
135 /**
136 * Update the attachments of draw/read surfaces.
137 */
138 static void
139 egl_g3d_route_context(_EGLDisplay *dpy, _EGLContext *ctx)
140 {
141 struct egl_g3d_context *gctx = egl_g3d_context(ctx);
142 EGLint s;
143
144 /* route draw and read buffers' attachments */
145 for (s = 0; s < 2; s++) {
146 struct egl_g3d_surface *gsurf;
147 struct egl_g3d_buffer *gbuf;
148
149 if (s == 0) {
150 gsurf = egl_g3d_surface(gctx->base.DrawSurface);
151 gbuf = &gctx->draw;
152 }
153 else {
154 gsurf = egl_g3d_surface(gctx->base.ReadSurface);
155 gbuf = &gctx->read;
156 }
157
158 gbuf->attachment_mask = (1 << gsurf->render_att);
159
160 /* FIXME OpenGL defaults to draw the front or back buffer when the
161 * context is single-buffered or double-buffered respectively. In EGL,
162 * however, the buffer to be drawn is determined by the surface, instead
163 * of the context. As a result, rendering to a pixmap surface with a
164 * double-buffered context does not work as expected.
165 *
166 * gctx->stapi->st_draw_front_buffer(gctx->st_ctx, natt ==
167 * NATIVE_ATTACHMENT_FRONT_LEFT);
168 */
169
170 /*
171 * FIXME If the back buffer is asked for here, and the front buffer is
172 * later needed by the client API (e.g. glDrawBuffer is called to draw
173 * the front buffer), it will create a new pipe texture and draw there.
174 * One fix is to ask for both buffers here, but it would be a waste if
175 * the front buffer is never used. A better fix is to add a callback to
176 * the pipe screen with context private (just like flush_frontbuffer).
177 */
178 }
179 }
180
181 /**
182 * Reallocate the context's framebuffers after draw/read surfaces change.
183 */
184 static EGLBoolean
185 egl_g3d_realloc_context(_EGLDisplay *dpy, _EGLContext *ctx)
186 {
187 struct egl_g3d_context *gctx = egl_g3d_context(ctx);
188 struct egl_g3d_surface *gdraw = egl_g3d_surface(gctx->base.DrawSurface);
189 struct egl_g3d_surface *gread = egl_g3d_surface(gctx->base.ReadSurface);
190
191 /* unreference the old framebuffers */
192 if (gctx->draw.st_fb) {
193 EGLBoolean is_equal = (gctx->draw.st_fb == gctx->read.st_fb);
194 void *priv;
195
196 priv = gctx->stapi->st_framebuffer_private(gctx->draw.st_fb);
197 if (!gdraw || priv != (void *) &gdraw->base) {
198 gctx->stapi->st_unreference_framebuffer(gctx->draw.st_fb);
199 gctx->draw.st_fb = NULL;
200 gctx->draw.attachment_mask = 0x0;
201 }
202
203 if (is_equal) {
204 gctx->read.st_fb = NULL;
205 gctx->draw.attachment_mask = 0x0;
206 }
207 else {
208 priv = gctx->stapi->st_framebuffer_private(gctx->read.st_fb);
209 if (!gread || priv != (void *) &gread->base) {
210 gctx->stapi->st_unreference_framebuffer(gctx->read.st_fb);
211 gctx->read.st_fb = NULL;
212 gctx->draw.attachment_mask = 0x0;
213 }
214 }
215 }
216
217 if (!gdraw)
218 return EGL_TRUE;
219
220 /* create the draw fb */
221 if (!gctx->draw.st_fb) {
222 gctx->draw.st_fb = create_framebuffer(&gctx->base, &gdraw->base);
223 if (!gctx->draw.st_fb)
224 return EGL_FALSE;
225 }
226
227 /* create the read fb */
228 if (!gctx->read.st_fb) {
229 if (gread != gdraw) {
230 gctx->read.st_fb = create_framebuffer(&gctx->base, &gread->base);
231 if (!gctx->read.st_fb) {
232 gctx->stapi->st_unreference_framebuffer(gctx->draw.st_fb);
233 gctx->draw.st_fb = NULL;
234 return EGL_FALSE;
235 }
236 }
237 else {
238 /* there is no st_reference_framebuffer... */
239 gctx->read.st_fb = gctx->draw.st_fb;
240 }
241 }
242
243 egl_g3d_route_context(dpy, &gctx->base);
244 gctx->force_validate = EGL_TRUE;
245
246 return EGL_TRUE;
247 }
248
249 /**
250 * Return the state tracker for the given context.
251 */
252 static const struct egl_g3d_st *
253 egl_g3d_choose_st(_EGLDriver *drv, _EGLContext *ctx)
254 {
255 struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
256 const struct egl_g3d_st *stapi;
257 EGLint idx = -1;
258
259 switch (ctx->ClientAPI) {
260 case EGL_OPENGL_ES_API:
261 switch (ctx->ClientVersion) {
262 case 1:
263 idx = EGL_G3D_ST_OPENGL_ES;
264 break;
265 case 2:
266 idx = EGL_G3D_ST_OPENGL_ES2;
267 break;
268 default:
269 _eglLog(_EGL_WARNING, "unknown client version %d",
270 ctx->ClientVersion);
271 break;
272 }
273 break;
274 case EGL_OPENVG_API:
275 idx = EGL_G3D_ST_OPENVG;
276 break;
277 case EGL_OPENGL_API:
278 idx = EGL_G3D_ST_OPENGL;
279 break;
280 default:
281 _eglLog(_EGL_WARNING, "unknown client API 0x%04x", ctx->ClientAPI);
282 break;
283 }
284
285 stapi = (idx >= 0) ? gdrv->stapis[idx] : NULL;
286 return stapi;
287 }
288
289 /**
290 * Initialize the state trackers.
291 */
292 static void
293 egl_g3d_init_st(_EGLDriver *drv)
294 {
295 struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
296 EGLint i;
297
298 /* already initialized */
299 if (gdrv->api_mask)
300 return;
301
302 for (i = 0; i < NUM_EGL_G3D_STS; i++) {
303 gdrv->stapis[i] = egl_g3d_get_st(i);
304 if (gdrv->stapis[i])
305 gdrv->api_mask |= gdrv->stapis[i]->api_bit;
306 }
307
308 if (gdrv->api_mask)
309 _eglLog(_EGL_DEBUG, "Driver API mask: 0x%x", gdrv->api_mask);
310 else
311 _eglLog(_EGL_WARNING, "No supported client API");
312 }
313
314 /**
315 * Get the probe object of the display.
316 *
317 * Note that this function may be called before the display is initialized.
318 */
319 static struct native_probe *
320 egl_g3d_get_probe(_EGLDriver *drv, _EGLDisplay *dpy)
321 {
322 struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
323 struct native_probe *nprobe;
324
325 nprobe = (struct native_probe *) _eglGetProbeCache(gdrv->probe_key);
326 if (!nprobe || nprobe->display != dpy->NativeDisplay) {
327 if (nprobe)
328 nprobe->destroy(nprobe);
329 nprobe = native_create_probe(dpy->NativeDisplay);
330 _eglSetProbeCache(gdrv->probe_key, (void *) nprobe);
331 }
332
333 return nprobe;
334 }
335
336 /**
337 * Destroy the probe object of the display. The display may be NULL.
338 *
339 * Note that this function may be called before the display is initialized.
340 */
341 static void
342 egl_g3d_destroy_probe(_EGLDriver *drv, _EGLDisplay *dpy)
343 {
344 struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
345 struct native_probe *nprobe;
346
347 nprobe = (struct native_probe *) _eglGetProbeCache(gdrv->probe_key);
348 if (nprobe && (!dpy || nprobe->display == dpy->NativeDisplay)) {
349 nprobe->destroy(nprobe);
350 _eglSetProbeCache(gdrv->probe_key, NULL);
351 }
352 }
353
354 /**
355 * Return an API mask that consists of the state trackers that supports the
356 * given mode.
357 *
358 * FIXME add st_is_mode_supported()?
359 */
360 static EGLint
361 get_mode_api_mask(const __GLcontextModes *mode, EGLint api_mask)
362 {
363 EGLint check;
364
365 /* OpenGL ES 1.x and 2.x are checked together */
366 check = EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT;
367 if (api_mask & check) {
368 /* this is required by EGL, not by OpenGL ES */
369 if (mode->drawableType & GLX_WINDOW_BIT && !mode->doubleBufferMode)
370 api_mask &= ~check;
371 }
372
373 check = EGL_OPENVG_BIT;
374 if (api_mask & check) {
375 /* vega st needs the depth/stencil rb */
376 if (!mode->depthBits && !mode->stencilBits)
377 api_mask &= ~check;
378 }
379
380 return api_mask;
381 }
382
383 #ifdef EGL_MESA_screen_surface
384
385 static void
386 egl_g3d_add_screens(_EGLDriver *drv, _EGLDisplay *dpy)
387 {
388 struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
389 const struct native_connector **native_connectors;
390 EGLint num_connectors, i;
391
392 native_connectors =
393 gdpy->native->modeset->get_connectors(gdpy->native, &num_connectors, NULL);
394 if (!num_connectors) {
395 if (native_connectors)
396 free(native_connectors);
397 return;
398 }
399
400 for (i = 0; i < num_connectors; i++) {
401 const struct native_connector *nconn = native_connectors[i];
402 struct egl_g3d_screen *gscr;
403 const struct native_mode **native_modes;
404 EGLint num_modes, j;
405
406 /* TODO support for hotplug */
407 native_modes =
408 gdpy->native->modeset->get_modes(gdpy->native, nconn, &num_modes);
409 if (!num_modes) {
410 if (native_modes)
411 free(native_modes);
412 continue;
413 }
414
415 gscr = CALLOC_STRUCT(egl_g3d_screen);
416 if (!gscr) {
417 free(native_modes);
418 continue;
419 }
420
421 _eglInitScreen(&gscr->base);
422
423 for (j = 0; j < num_modes; j++) {
424 const struct native_mode *nmode = native_modes[j];
425 _EGLMode *mode;
426
427 mode = _eglAddNewMode(&gscr->base, nmode->width, nmode->height,
428 nmode->refresh_rate, nmode->desc);
429 if (!mode)
430 break;
431 /* gscr->native_modes and gscr->base.Modes should be consistent */
432 assert(mode == &gscr->base.Modes[j]);
433 }
434
435 gscr->native = nconn;
436 gscr->native_modes = native_modes;
437
438 _eglAddScreen(dpy, &gscr->base);
439 }
440
441 free(native_connectors);
442 }
443
444 #endif /* EGL_MESA_screen_surface */
445
446 /**
447 * Add configs to display and return the next config ID.
448 */
449 static EGLint
450 egl_g3d_add_configs(_EGLDriver *drv, _EGLDisplay *dpy, EGLint id)
451 {
452 struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
453 struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
454 const struct native_config **native_configs;
455 int num_configs, i;
456
457 native_configs = gdpy->native->get_configs(gdpy->native,
458 &num_configs);
459 if (!num_configs) {
460 if (native_configs)
461 free(native_configs);
462 return id;
463 }
464
465 for (i = 0; i < num_configs; i++) {
466 EGLint api_mask;
467 struct egl_g3d_config *gconf;
468 EGLBoolean valid;
469
470 gconf = CALLOC_STRUCT(egl_g3d_config);
471 if (!gconf)
472 continue;
473
474 _eglInitConfig(&gconf->base, dpy, id);
475
476 api_mask = get_mode_api_mask(&native_configs[i]->mode, gdrv->api_mask);
477 if (!api_mask) {
478 _eglLog(_EGL_DEBUG, "no state tracker supports config 0x%x",
479 native_configs[i]->mode.visualID);
480 }
481
482 valid = _eglConfigFromContextModesRec(&gconf->base,
483 &native_configs[i]->mode, api_mask, api_mask);
484 if (valid) {
485 #ifdef EGL_MESA_screen_surface
486 /* check if scanout surface bit is set */
487 if (native_configs[i]->scanout_bit) {
488 EGLint val = GET_CONFIG_ATTRIB(&gconf->base, EGL_SURFACE_TYPE);
489 val |= EGL_SCREEN_BIT_MESA;
490 SET_CONFIG_ATTRIB(&gconf->base, EGL_SURFACE_TYPE, val);
491 }
492 #endif
493 valid = _eglValidateConfig(&gconf->base, EGL_FALSE);
494 }
495 if (!valid) {
496 _eglLog(_EGL_DEBUG, "skip invalid config 0x%x",
497 native_configs[i]->mode.visualID);
498 free(gconf);
499 continue;
500 }
501
502 gconf->native = native_configs[i];
503 _eglAddConfig(dpy, &gconf->base);
504 id++;
505 }
506
507 free(native_configs);
508 return id;
509 }
510
511 /**
512 * Flush the front buffer of the context's draw surface.
513 */
514 static void
515 egl_g3d_flush_frontbuffer(struct pipe_screen *screen,
516 struct pipe_surface *surf, void *context_private)
517 {
518 struct egl_g3d_context *gctx = egl_g3d_context(context_private);
519 struct egl_g3d_surface *gsurf = egl_g3d_surface(gctx->base.DrawSurface);
520
521 if (gsurf)
522 gsurf->native->flush_frontbuffer(gsurf->native);
523 }
524
525 /**
526 * Re-validate the context.
527 */
528 static void
529 egl_g3d_update_buffer(struct pipe_screen *screen, void *context_private)
530 {
531 struct egl_g3d_context *gctx = egl_g3d_context(context_private);
532 egl_g3d_validate_context(gctx->base.Resource.Display, &gctx->base);
533 }
534
535 static void
536 egl_g3d_invalid_surface(struct native_display *ndpy,
537 struct native_surface *nsurf,
538 unsigned int seq_num)
539 {
540 /* XXX not thread safe? */
541 struct egl_g3d_surface *gsurf = egl_g3d_surface(nsurf->user_data);
542 struct egl_g3d_context *gctx = egl_g3d_context(gsurf->base.CurrentContext);
543
544 /* set force_validate to skip an unnecessary check */
545 if (gctx)
546 gctx->force_validate = TRUE;
547 }
548
549 static struct native_event_handler egl_g3d_native_event_handler = {
550 .invalid_surface = egl_g3d_invalid_surface
551 };
552
553 static EGLBoolean
554 egl_g3d_terminate(_EGLDriver *drv, _EGLDisplay *dpy)
555 {
556 struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
557 EGLint i;
558
559 _eglReleaseDisplayResources(drv, dpy);
560 _eglCleanupDisplay(dpy);
561
562 if (dpy->Screens) {
563 for (i = 0; i < dpy->NumScreens; i++) {
564 struct egl_g3d_screen *gscr = egl_g3d_screen(dpy->Screens[i]);
565 free(gscr->native_modes);
566 free(gscr);
567 }
568 free(dpy->Screens);
569 }
570
571 if (gdpy->native)
572 gdpy->native->destroy(gdpy->native);
573
574 free(gdpy);
575 dpy->DriverData = NULL;
576
577 return EGL_TRUE;
578 }
579
580 static EGLBoolean
581 egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy,
582 EGLint *major, EGLint *minor)
583 {
584 struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
585 struct egl_g3d_display *gdpy;
586
587 /* the probe object is unlikely to be needed again */
588 egl_g3d_destroy_probe(drv, dpy);
589
590 gdpy = CALLOC_STRUCT(egl_g3d_display);
591 if (!gdpy) {
592 _eglError(EGL_BAD_ALLOC, "eglInitialize");
593 goto fail;
594 }
595 dpy->DriverData = gdpy;
596
597 gdpy->native = native_create_display(dpy->NativeDisplay,
598 &egl_g3d_native_event_handler);
599 if (!gdpy->native) {
600 _eglError(EGL_NOT_INITIALIZED, "eglInitialize(no usable display)");
601 goto fail;
602 }
603
604 gdpy->native->user_data = (void *) dpy;
605 gdpy->native->screen->flush_frontbuffer = egl_g3d_flush_frontbuffer;
606 gdpy->native->screen->update_buffer = egl_g3d_update_buffer;
607
608 egl_g3d_init_st(&gdrv->base);
609 dpy->ClientAPIsMask = gdrv->api_mask;
610
611 #ifdef EGL_MESA_screen_surface
612 /* enable MESA_screen_surface before adding (and validating) configs */
613 if (gdpy->native->modeset) {
614 dpy->Extensions.MESA_screen_surface = EGL_TRUE;
615 egl_g3d_add_screens(drv, dpy);
616 }
617 #endif
618
619 dpy->Extensions.KHR_image_base = EGL_TRUE;
620 if (gdpy->native->get_param(gdpy->native, NATIVE_PARAM_USE_NATIVE_BUFFER))
621 dpy->Extensions.KHR_image_pixmap = EGL_TRUE;
622
623 if (egl_g3d_add_configs(drv, dpy, 1) == 1) {
624 _eglError(EGL_NOT_INITIALIZED, "eglInitialize(unable to add configs)");
625 goto fail;
626 }
627
628 *major = 1;
629 *minor = 4;
630
631 return EGL_TRUE;
632
633 fail:
634 if (gdpy)
635 egl_g3d_terminate(drv, dpy);
636 return EGL_FALSE;
637 }
638
639 static _EGLContext *
640 egl_g3d_create_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
641 _EGLContext *share, const EGLint *attribs)
642 {
643 struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
644 struct egl_g3d_context *gshare = egl_g3d_context(share);
645 struct egl_g3d_config *gconf = egl_g3d_config(conf);
646 struct egl_g3d_context *gctx;
647 const __GLcontextModes *mode;
648
649 gctx = CALLOC_STRUCT(egl_g3d_context);
650 if (!gctx) {
651 _eglError(EGL_BAD_ALLOC, "eglCreateContext");
652 return NULL;
653 }
654
655 if (!_eglInitContext(&gctx->base, dpy, conf, attribs)) {
656 free(gctx);
657 return NULL;
658 }
659
660 gctx->stapi = egl_g3d_choose_st(drv, &gctx->base);
661 if (!gctx->stapi) {
662 free(gctx);
663 return NULL;
664 }
665
666 mode = &gconf->native->mode;
667
668 gctx->pipe = gdpy->native->screen->context_create(
669 gdpy->native->screen,
670 (void *) &gctx->base);
671
672 if (!gctx->pipe) {
673 free(gctx);
674 return NULL;
675 }
676
677 gctx->st_ctx = gctx->stapi->st_create_context(gctx->pipe, mode,
678 (gshare) ? gshare->st_ctx : NULL);
679 if (!gctx->st_ctx) {
680 gctx->pipe->destroy(gctx->pipe);
681 free(gctx);
682 return NULL;
683 }
684
685 return &gctx->base;
686 }
687
688 /**
689 * Destroy a context.
690 */
691 static void
692 destroy_context(_EGLDisplay *dpy, _EGLContext *ctx)
693 {
694 struct egl_g3d_context *gctx = egl_g3d_context(ctx);
695
696 /* FIXME a context might live longer than its display */
697 if (!dpy->Initialized)
698 _eglLog(_EGL_FATAL, "destroy a context with an unitialized display");
699
700 egl_g3d_realloc_context(dpy, &gctx->base);
701 /* it will destroy the associated pipe context */
702 gctx->stapi->st_destroy_context(gctx->st_ctx);
703
704 free(gctx);
705 }
706
707 static EGLBoolean
708 egl_g3d_destroy_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx)
709 {
710 if (!_eglIsContextBound(ctx))
711 destroy_context(dpy, ctx);
712 return EGL_TRUE;
713 }
714
715 struct egl_g3d_create_surface_arg {
716 EGLint type;
717 union {
718 EGLNativeWindowType win;
719 EGLNativePixmapType pix;
720 } u;
721 };
722
723 static _EGLSurface *
724 egl_g3d_create_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
725 struct egl_g3d_create_surface_arg *arg,
726 const EGLint *attribs)
727 {
728 struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
729 struct egl_g3d_config *gconf = egl_g3d_config(conf);
730 struct egl_g3d_surface *gsurf;
731 struct native_surface *nsurf;
732 const char *err;
733
734 switch (arg->type) {
735 case EGL_WINDOW_BIT:
736 err = "eglCreateWindowSurface";
737 break;
738 case EGL_PIXMAP_BIT:
739 err = "eglCreatePixmapSurface";
740 break;
741 case EGL_PBUFFER_BIT:
742 err = "eglCreatePBufferSurface";
743 break;
744 #ifdef EGL_MESA_screen_surface
745 case EGL_SCREEN_BIT_MESA:
746 err = "eglCreateScreenSurface";
747 break;
748 #endif
749 default:
750 err = "eglCreateUnknownSurface";
751 break;
752 }
753
754 gsurf = CALLOC_STRUCT(egl_g3d_surface);
755 if (!gsurf) {
756 _eglError(EGL_BAD_ALLOC, err);
757 return NULL;
758 }
759
760 if (!_eglInitSurface(&gsurf->base, dpy, arg->type, conf, attribs)) {
761 free(gsurf);
762 return NULL;
763 }
764
765 /* create the native surface */
766 switch (arg->type) {
767 case EGL_WINDOW_BIT:
768 nsurf = gdpy->native->create_window_surface(gdpy->native,
769 arg->u.win, gconf->native);
770 break;
771 case EGL_PIXMAP_BIT:
772 nsurf = gdpy->native->create_pixmap_surface(gdpy->native,
773 arg->u.pix, gconf->native);
774 break;
775 case EGL_PBUFFER_BIT:
776 nsurf = gdpy->native->create_pbuffer_surface(gdpy->native,
777 gconf->native, gsurf->base.Width, gsurf->base.Height);
778 break;
779 #ifdef EGL_MESA_screen_surface
780 case EGL_SCREEN_BIT_MESA:
781 /* prefer back buffer (move to _eglInitSurface?) */
782 gsurf->base.RenderBuffer = EGL_BACK_BUFFER;
783 nsurf = gdpy->native->modeset->create_scanout_surface(gdpy->native,
784 gconf->native, gsurf->base.Width, gsurf->base.Height);
785 break;
786 #endif
787 default:
788 nsurf = NULL;
789 break;
790 }
791
792 if (!nsurf) {
793 free(gsurf);
794 return NULL;
795 }
796 /* initialize the geometry */
797 if (!nsurf->validate(nsurf, 0x0, &gsurf->sequence_number, NULL,
798 &gsurf->base.Width, &gsurf->base.Height)) {
799 nsurf->destroy(nsurf);
800 free(gsurf);
801 return NULL;
802 }
803
804 nsurf->user_data = &gsurf->base;
805 gsurf->native = nsurf;
806
807 gsurf->render_att = (gsurf->base.RenderBuffer == EGL_SINGLE_BUFFER) ?
808 NATIVE_ATTACHMENT_FRONT_LEFT : NATIVE_ATTACHMENT_BACK_LEFT;
809 if (!gconf->native->mode.doubleBufferMode)
810 gsurf->render_att = NATIVE_ATTACHMENT_FRONT_LEFT;
811
812 return &gsurf->base;
813 }
814
815 static _EGLSurface *
816 egl_g3d_create_window_surface(_EGLDriver *drv, _EGLDisplay *dpy,
817 _EGLConfig *conf, EGLNativeWindowType win,
818 const EGLint *attribs)
819 {
820 struct egl_g3d_create_surface_arg arg;
821
822 memset(&arg, 0, sizeof(arg));
823 arg.type = EGL_WINDOW_BIT;
824 arg.u.win = win;
825
826 return egl_g3d_create_surface(drv, dpy, conf, &arg, attribs);
827 }
828
829 static _EGLSurface *
830 egl_g3d_create_pixmap_surface(_EGLDriver *drv, _EGLDisplay *dpy,
831 _EGLConfig *conf, EGLNativePixmapType pix,
832 const EGLint *attribs)
833 {
834 struct egl_g3d_create_surface_arg arg;
835
836 memset(&arg, 0, sizeof(arg));
837 arg.type = EGL_PIXMAP_BIT;
838 arg.u.pix = pix;
839
840 return egl_g3d_create_surface(drv, dpy, conf, &arg, attribs);
841 }
842
843 static _EGLSurface *
844 egl_g3d_create_pbuffer_surface(_EGLDriver *drv, _EGLDisplay *dpy,
845 _EGLConfig *conf, const EGLint *attribs)
846 {
847 struct egl_g3d_create_surface_arg arg;
848
849 memset(&arg, 0, sizeof(arg));
850 arg.type = EGL_PBUFFER_BIT;
851
852 return egl_g3d_create_surface(drv, dpy, conf, &arg, attribs);
853 }
854
855 /**
856 * Destroy a surface.
857 */
858 static void
859 destroy_surface(_EGLDisplay *dpy, _EGLSurface *surf)
860 {
861 struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
862
863 /* FIXME a surface might live longer than its display */
864 if (!dpy->Initialized)
865 _eglLog(_EGL_FATAL, "destroy a surface with an unitialized display");
866
867 pipe_surface_reference(&gsurf->render_surface, NULL);
868 gsurf->native->destroy(gsurf->native);
869 free(gsurf);
870 }
871
872 static EGLBoolean
873 egl_g3d_destroy_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf)
874 {
875 if (!_eglIsSurfaceBound(surf))
876 destroy_surface(dpy, surf);
877 return EGL_TRUE;
878 }
879
880 static EGLBoolean
881 egl_g3d_make_current(_EGLDriver *drv, _EGLDisplay *dpy,
882 _EGLSurface *draw, _EGLSurface *read, _EGLContext *ctx)
883 {
884 struct egl_g3d_context *gctx = egl_g3d_context(ctx);
885 struct egl_g3d_surface *gdraw = egl_g3d_surface(draw);
886 struct egl_g3d_context *old_gctx;
887 EGLBoolean ok = EGL_TRUE;
888
889 /* bind the new context and return the "orphaned" one */
890 if (!_eglBindContext(&ctx, &draw, &read))
891 return EGL_FALSE;
892 old_gctx = egl_g3d_context(ctx);
893
894 if (old_gctx) {
895 /* flush old context */
896 old_gctx->stapi->st_flush(old_gctx->st_ctx,
897 PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL);
898
899 /*
900 * The old context is no longer current, and egl_g3d_realloc_context()
901 * should be called to destroy the framebuffers. However, it is possible
902 * that it will be made current again with the same draw/read surfaces.
903 * It might be better to keep it around.
904 */
905 }
906
907 if (gctx) {
908 ok = egl_g3d_realloc_context(dpy, &gctx->base);
909 if (ok) {
910 ok = gctx->stapi->st_make_current(gctx->st_ctx,
911 gctx->draw.st_fb, gctx->read.st_fb);
912 if (ok) {
913 egl_g3d_validate_context(dpy, &gctx->base);
914 if (gdraw->base.Type == EGL_WINDOW_BIT) {
915 gctx->base.WindowRenderBuffer =
916 (gdraw->render_att == NATIVE_ATTACHMENT_FRONT_LEFT) ?
917 EGL_SINGLE_BUFFER : EGL_BACK_BUFFER;
918 }
919 }
920 }
921 }
922 else if (old_gctx) {
923 ok = old_gctx->stapi->st_make_current(NULL, NULL, NULL);
924 old_gctx->base.WindowRenderBuffer = EGL_NONE;
925 }
926
927 if (ctx && !_eglIsContextLinked(ctx))
928 destroy_context(dpy, ctx);
929 if (draw && !_eglIsSurfaceLinked(draw))
930 destroy_surface(dpy, draw);
931 if (read && read != draw && !_eglIsSurfaceLinked(read))
932 destroy_surface(dpy, read);
933
934 return ok;
935 }
936
937 static EGLBoolean
938 egl_g3d_swap_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf)
939 {
940 struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
941 _EGLContext *ctx = _eglGetCurrentContext();
942 struct egl_g3d_context *gctx = NULL;
943
944 /* no-op for pixmap or pbuffer surface */
945 if (gsurf->base.Type == EGL_PIXMAP_BIT ||
946 gsurf->base.Type == EGL_PBUFFER_BIT)
947 return EGL_TRUE;
948
949 /* or when the surface is single-buffered */
950 if (gsurf->render_att == NATIVE_ATTACHMENT_FRONT_LEFT)
951 return EGL_TRUE;
952
953 if (ctx && ctx->DrawSurface == surf)
954 gctx = egl_g3d_context(ctx);
955
956 /* flush if the surface is current */
957 if (gctx)
958 gctx->stapi->st_notify_swapbuffers(gctx->draw.st_fb);
959
960 return gsurf->native->swap_buffers(gsurf->native);
961 }
962
963 /**
964 * Find a config that supports the pixmap.
965 */
966 _EGLConfig *
967 egl_g3d_find_pixmap_config(_EGLDisplay *dpy, EGLNativePixmapType pix)
968 {
969 struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
970 struct egl_g3d_config *gconf;
971 EGLint i;
972
973 for (i = 0; i < dpy->NumConfigs; i++) {
974 gconf = egl_g3d_config(dpy->Configs[i]);
975 if (gdpy->native->is_pixmap_supported(gdpy->native, pix, gconf->native))
976 break;
977 }
978
979 return (i < dpy->NumConfigs) ? &gconf->base : NULL;
980 }
981
982 /**
983 * Get the pipe surface of the given attachment of the native surface.
984 */
985 static struct pipe_surface *
986 get_pipe_surface(struct native_display *ndpy, struct native_surface *nsurf,
987 enum native_attachment natt)
988 {
989 struct pipe_texture *textures[NUM_NATIVE_ATTACHMENTS];
990 struct pipe_surface *psurf;
991
992 textures[natt] = NULL;
993 nsurf->validate(nsurf, 1 << natt, NULL, textures, NULL, NULL);
994 if (!textures[natt])
995 return NULL;
996
997 psurf = ndpy->screen->get_tex_surface(ndpy->screen, textures[natt],
998 0, 0, 0, PIPE_BUFFER_USAGE_CPU_WRITE);
999 pipe_texture_reference(&textures[natt], NULL);
1000
1001 return psurf;
1002 }
1003
1004 static EGLBoolean
1005 egl_g3d_copy_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
1006 EGLNativePixmapType target)
1007 {
1008 struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
1009 struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
1010 _EGLContext *ctx = _eglGetCurrentContext();
1011 struct egl_g3d_config *gconf;
1012 struct native_surface *nsurf;
1013 struct pipe_screen *screen = gdpy->native->screen;
1014 struct pipe_surface *psurf;
1015
1016 if (!gsurf->render_surface)
1017 return EGL_TRUE;
1018
1019 gconf = egl_g3d_config(egl_g3d_find_pixmap_config(dpy, target));
1020 if (!gconf)
1021 return _eglError(EGL_BAD_NATIVE_PIXMAP, "eglCopyBuffers");
1022
1023 nsurf = gdpy->native->create_pixmap_surface(gdpy->native,
1024 target, gconf->native);
1025 if (!nsurf)
1026 return _eglError(EGL_BAD_NATIVE_PIXMAP, "eglCopyBuffers");
1027
1028 /* flush if the surface is current */
1029 if (ctx && ctx->DrawSurface == &gsurf->base) {
1030 struct egl_g3d_context *gctx = egl_g3d_context(ctx);
1031 gctx->stapi->st_flush(gctx->st_ctx,
1032 PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL);
1033 }
1034
1035 psurf = get_pipe_surface(gdpy->native, nsurf, NATIVE_ATTACHMENT_FRONT_LEFT);
1036 if (psurf) {
1037 struct pipe_context pipe;
1038
1039 /**
1040 * XXX This is hacky. If we might allow the EGLDisplay to create a pipe
1041 * context of its own and use the blitter context for this.
1042 */
1043 memset(&pipe, 0, sizeof(pipe));
1044 pipe.screen = screen;
1045
1046 util_surface_copy(&pipe, FALSE, psurf, 0, 0,
1047 gsurf->render_surface, 0, 0, psurf->width, psurf->height);
1048
1049 pipe_surface_reference(&psurf, NULL);
1050 nsurf->flush_frontbuffer(nsurf);
1051 }
1052
1053 nsurf->destroy(nsurf);
1054
1055 return EGL_TRUE;
1056 }
1057
1058 static EGLBoolean
1059 egl_g3d_wait_client(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx)
1060 {
1061 struct egl_g3d_context *gctx = egl_g3d_context(ctx);
1062 gctx->stapi->st_finish(gctx->st_ctx);
1063 return EGL_TRUE;
1064 }
1065
1066 static EGLBoolean
1067 egl_g3d_wait_native(_EGLDriver *drv, _EGLDisplay *dpy, EGLint engine)
1068 {
1069 _EGLContext *ctx = _eglGetCurrentContext();
1070
1071 if (engine != EGL_CORE_NATIVE_ENGINE)
1072 return _eglError(EGL_BAD_PARAMETER, "eglWaitNative");
1073
1074 if (ctx && ctx->DrawSurface) {
1075 struct egl_g3d_surface *gsurf = egl_g3d_surface(ctx->DrawSurface);
1076 gsurf->native->wait(gsurf->native);
1077 }
1078
1079 return EGL_TRUE;
1080 }
1081
1082 static _EGLProc
1083 egl_g3d_get_proc_address(_EGLDriver *drv, const char *procname)
1084 {
1085 struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
1086 _EGLProc proc;
1087 EGLint i;
1088
1089 /* in case this is called before a display is initialized */
1090 egl_g3d_init_st(&gdrv->base);
1091
1092 for (i = 0; i < NUM_EGL_G3D_STS; i++) {
1093 const struct egl_g3d_st *stapi = gdrv->stapis[i];
1094 if (stapi) {
1095 proc = (_EGLProc) stapi->st_get_proc_address(procname);
1096 if (proc)
1097 return proc;
1098 }
1099 }
1100
1101 return (_EGLProc) NULL;
1102 }
1103
1104 static EGLBoolean
1105 egl_g3d_bind_tex_image(_EGLDriver *drv, _EGLDisplay *dpy,
1106 _EGLSurface *surf, EGLint buffer)
1107 {
1108 struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
1109 _EGLContext *es1 = _eglGetAPIContext(EGL_OPENGL_ES_API);
1110 struct egl_g3d_context *gctx;
1111 enum pipe_format target_format;
1112 int target;
1113
1114 if (!gsurf || gsurf->base.Type != EGL_PBUFFER_BIT)
1115 return _eglError(EGL_BAD_SURFACE, "eglBindTexImage");
1116 if (buffer != EGL_BACK_BUFFER)
1117 return _eglError(EGL_BAD_PARAMETER, "eglBindTexImage");
1118 if (gsurf->base.BoundToTexture)
1119 return _eglError(EGL_BAD_ACCESS, "eglBindTexImage");
1120
1121 switch (gsurf->base.TextureFormat) {
1122 case EGL_TEXTURE_RGB:
1123 target_format = PIPE_FORMAT_R8G8B8_UNORM;
1124 break;
1125 case EGL_TEXTURE_RGBA:
1126 target_format = PIPE_FORMAT_B8G8R8A8_UNORM;
1127 break;
1128 default:
1129 return _eglError(EGL_BAD_MATCH, "eglBindTexImage");
1130 }
1131
1132 switch (gsurf->base.TextureTarget) {
1133 case EGL_TEXTURE_2D:
1134 target = ST_TEXTURE_2D;
1135 break;
1136 default:
1137 return _eglError(EGL_BAD_MATCH, "eglBindTexImage");
1138 }
1139
1140 if (!es1)
1141 return EGL_TRUE;
1142 if (!gsurf->render_surface)
1143 return EGL_FALSE;
1144
1145 /* flush properly if the surface is bound */
1146 if (gsurf->base.CurrentContext) {
1147 gctx = egl_g3d_context(gsurf->base.CurrentContext);
1148 gctx->stapi->st_flush(gctx->st_ctx,
1149 PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL);
1150 }
1151
1152 gctx = egl_g3d_context(es1);
1153 gctx->stapi->st_bind_texture_surface(gsurf->render_surface,
1154 target, gsurf->base.MipmapLevel, target_format);
1155
1156 gsurf->base.BoundToTexture = EGL_TRUE;
1157
1158 return EGL_TRUE;
1159 }
1160
1161 static EGLBoolean
1162 egl_g3d_release_tex_image(_EGLDriver *drv, _EGLDisplay *dpy,
1163 _EGLSurface *surf, EGLint buffer)
1164 {
1165 struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
1166
1167 if (!gsurf || gsurf->base.Type != EGL_PBUFFER_BIT ||
1168 !gsurf->base.BoundToTexture)
1169 return _eglError(EGL_BAD_SURFACE, "eglReleaseTexImage");
1170 if (buffer != EGL_BACK_BUFFER)
1171 return _eglError(EGL_BAD_PARAMETER, "eglReleaseTexImage");
1172
1173 if (gsurf->render_surface) {
1174 _EGLContext *ctx = _eglGetAPIContext(EGL_OPENGL_ES_API);
1175 struct egl_g3d_context *gctx = egl_g3d_context(ctx);
1176
1177 /* what if the context the surface binds to is no longer current? */
1178 if (gctx)
1179 gctx->stapi->st_unbind_texture_surface(gsurf->render_surface,
1180 ST_TEXTURE_2D, gsurf->base.MipmapLevel);
1181 }
1182
1183 gsurf->base.BoundToTexture = EGL_FALSE;
1184
1185 return EGL_TRUE;
1186 }
1187
1188 #ifdef EGL_MESA_screen_surface
1189
1190 static _EGLSurface *
1191 egl_g3d_create_screen_surface(_EGLDriver *drv, _EGLDisplay *dpy,
1192 _EGLConfig *conf, const EGLint *attribs)
1193 {
1194 struct egl_g3d_create_surface_arg arg;
1195
1196 memset(&arg, 0, sizeof(arg));
1197 arg.type = EGL_SCREEN_BIT_MESA;
1198
1199 return egl_g3d_create_surface(drv, dpy, conf, &arg, attribs);
1200 }
1201
1202 static EGLBoolean
1203 egl_g3d_show_screen_surface(_EGLDriver *drv, _EGLDisplay *dpy,
1204 _EGLScreen *scr, _EGLSurface *surf,
1205 _EGLMode *mode)
1206 {
1207 struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
1208 struct egl_g3d_screen *gscr = egl_g3d_screen(scr);
1209 struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
1210 struct native_surface *nsurf;
1211 const struct native_mode *nmode;
1212 EGLBoolean changed;
1213
1214 if (gsurf) {
1215 EGLint idx;
1216
1217 if (!mode)
1218 return _eglError(EGL_BAD_MATCH, "eglShowSurfaceMESA");
1219 if (gsurf->base.Type != EGL_SCREEN_BIT_MESA)
1220 return _eglError(EGL_BAD_SURFACE, "eglShowScreenSurfaceMESA");
1221 if (gsurf->base.Width < mode->Width || gsurf->base.Height < mode->Height)
1222 return _eglError(EGL_BAD_MATCH,
1223 "eglShowSurfaceMESA(surface smaller than mode size)");
1224
1225 /* find the index of the mode */
1226 for (idx = 0; idx < gscr->base.NumModes; idx++)
1227 if (mode == &gscr->base.Modes[idx])
1228 break;
1229 if (idx >= gscr->base.NumModes) {
1230 return _eglError(EGL_BAD_MODE_MESA,
1231 "eglShowSurfaceMESA(unknown mode)");
1232 }
1233
1234 nsurf = gsurf->native;
1235 nmode = gscr->native_modes[idx];
1236 }
1237 else {
1238 if (mode)
1239 return _eglError(EGL_BAD_MATCH, "eglShowSurfaceMESA");
1240
1241 /* disable the screen */
1242 nsurf = NULL;
1243 nmode = NULL;
1244 }
1245
1246 /* TODO surface panning by CRTC choosing */
1247 changed = gdpy->native->modeset->program(gdpy->native, 0, nsurf,
1248 gscr->base.OriginX, gscr->base.OriginY, &gscr->native, 1, nmode);
1249 if (changed) {
1250 gscr->base.CurrentSurface = &gsurf->base;
1251 gscr->base.CurrentMode = mode;
1252 }
1253
1254 return changed;
1255 }
1256
1257 #endif /* EGL_MESA_screen_surface */
1258
1259 static EGLint
1260 egl_g3d_probe(_EGLDriver *drv, _EGLDisplay *dpy)
1261 {
1262 struct native_probe *nprobe;
1263 enum native_probe_result res;
1264 EGLint score;
1265
1266 nprobe = egl_g3d_get_probe(drv, dpy);
1267 res = native_get_probe_result(nprobe);
1268
1269 switch (res) {
1270 case NATIVE_PROBE_UNKNOWN:
1271 default:
1272 score = 0;
1273 break;
1274 case NATIVE_PROBE_FALLBACK:
1275 score = 40;
1276 break;
1277 case NATIVE_PROBE_SUPPORTED:
1278 score = 50;
1279 break;
1280 case NATIVE_PROBE_EXACT:
1281 score = 100;
1282 break;
1283 }
1284
1285 return score;
1286 }
1287
1288 static void
1289 egl_g3d_unload(_EGLDriver *drv)
1290 {
1291 struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
1292
1293 egl_g3d_destroy_probe(drv, NULL);
1294 free(gdrv);
1295 }
1296
1297 _EGLDriver *
1298 _eglMain(const char *args)
1299 {
1300 static char driver_name[64];
1301 struct egl_g3d_driver *gdrv;
1302
1303 snprintf(driver_name, sizeof(driver_name),
1304 "Gallium/%s", native_get_name());
1305
1306 gdrv = CALLOC_STRUCT(egl_g3d_driver);
1307 if (!gdrv)
1308 return NULL;
1309
1310 _eglInitDriverFallbacks(&gdrv->base);
1311
1312 gdrv->base.API.Initialize = egl_g3d_initialize;
1313 gdrv->base.API.Terminate = egl_g3d_terminate;
1314 gdrv->base.API.CreateContext = egl_g3d_create_context;
1315 gdrv->base.API.DestroyContext = egl_g3d_destroy_context;
1316 gdrv->base.API.CreateWindowSurface = egl_g3d_create_window_surface;
1317 gdrv->base.API.CreatePixmapSurface = egl_g3d_create_pixmap_surface;
1318 gdrv->base.API.CreatePbufferSurface = egl_g3d_create_pbuffer_surface;
1319 gdrv->base.API.DestroySurface = egl_g3d_destroy_surface;
1320 gdrv->base.API.MakeCurrent = egl_g3d_make_current;
1321 gdrv->base.API.SwapBuffers = egl_g3d_swap_buffers;
1322 gdrv->base.API.CopyBuffers = egl_g3d_copy_buffers;
1323 gdrv->base.API.WaitClient = egl_g3d_wait_client;
1324 gdrv->base.API.WaitNative = egl_g3d_wait_native;
1325 gdrv->base.API.GetProcAddress = egl_g3d_get_proc_address;
1326
1327 gdrv->base.API.BindTexImage = egl_g3d_bind_tex_image;
1328 gdrv->base.API.ReleaseTexImage = egl_g3d_release_tex_image;
1329
1330 gdrv->base.API.CreateImageKHR = egl_g3d_create_image;
1331 gdrv->base.API.DestroyImageKHR = egl_g3d_destroy_image;
1332
1333 #ifdef EGL_MESA_screen_surface
1334 gdrv->base.API.CreateScreenSurfaceMESA = egl_g3d_create_screen_surface;
1335 gdrv->base.API.ShowScreenSurfaceMESA = egl_g3d_show_screen_surface;
1336 #endif
1337
1338 gdrv->base.Name = driver_name;
1339 gdrv->base.Probe = egl_g3d_probe;
1340 gdrv->base.Unload = egl_g3d_unload;
1341
1342 /* the key is " EGL G3D" */
1343 gdrv->probe_key = 0x0E61063D;
1344
1345 return &gdrv->base;
1346 }