Merge commit 'origin/master' into gallium-0.2
[mesa.git] / src / gallium / state_trackers / egl / egl_context.c
1
2 #include "utils.h"
3 #include <stdlib.h>
4 #include <stdio.h>
5 #include <string.h>
6 #include "egl_tracker.h"
7
8 #include "egllog.h"
9
10
11 #include "pipe/p_context.h"
12 #include "pipe/p_screen.h"
13 #include "pipe/p_winsys.h"
14
15 #include "state_tracker/st_public.h"
16 #include "state_tracker/drm_api.h"
17
18 #include "GL/internal/glcore.h"
19
20 #define need_GL_ARB_multisample
21 #define need_GL_ARB_point_parameters
22 #define need_GL_ARB_texture_compression
23 #define need_GL_ARB_vertex_buffer_object
24 #define need_GL_ARB_vertex_program
25 #define need_GL_ARB_window_pos
26 #define need_GL_EXT_blend_color
27 #define need_GL_EXT_blend_equation_separate
28 #define need_GL_EXT_blend_func_separate
29 #define need_GL_EXT_blend_minmax
30 #define need_GL_EXT_cull_vertex
31 #define need_GL_EXT_fog_coord
32 #define need_GL_EXT_framebuffer_object
33 #define need_GL_EXT_multi_draw_arrays
34 #define need_GL_EXT_secondary_color
35 #define need_GL_NV_vertex_program
36 #include "extension_helper.h"
37
38 /**
39 * TODO HACK! FUGLY!
40 * Copied for intel extentions.
41 */
42 const struct dri_extension card_extensions[] = {
43 {"GL_ARB_multisample", GL_ARB_multisample_functions},
44 {"GL_ARB_multitexture", NULL},
45 {"GL_ARB_point_parameters", GL_ARB_point_parameters_functions},
46 {"GL_ARB_texture_border_clamp", NULL},
47 {"GL_ARB_texture_compression", GL_ARB_texture_compression_functions},
48 {"GL_ARB_texture_cube_map", NULL},
49 {"GL_ARB_texture_env_add", NULL},
50 {"GL_ARB_texture_env_combine", NULL},
51 {"GL_ARB_texture_env_dot3", NULL},
52 {"GL_ARB_texture_mirrored_repeat", NULL},
53 {"GL_ARB_texture_rectangle", NULL},
54 {"GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions},
55 {"GL_ARB_pixel_buffer_object", NULL},
56 {"GL_ARB_vertex_program", GL_ARB_vertex_program_functions},
57 {"GL_ARB_window_pos", GL_ARB_window_pos_functions},
58 {"GL_EXT_blend_color", GL_EXT_blend_color_functions},
59 {"GL_EXT_blend_equation_separate", GL_EXT_blend_equation_separate_functions},
60 {"GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions},
61 {"GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions},
62 {"GL_EXT_blend_subtract", NULL},
63 {"GL_EXT_cull_vertex", GL_EXT_cull_vertex_functions},
64 {"GL_EXT_fog_coord", GL_EXT_fog_coord_functions},
65 {"GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions},
66 {"GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions},
67 {"GL_EXT_packed_depth_stencil", NULL},
68 {"GL_EXT_pixel_buffer_object", NULL},
69 {"GL_EXT_secondary_color", GL_EXT_secondary_color_functions},
70 {"GL_EXT_stencil_wrap", NULL},
71 {"GL_EXT_texture_edge_clamp", NULL},
72 {"GL_EXT_texture_env_combine", NULL},
73 {"GL_EXT_texture_env_dot3", NULL},
74 {"GL_EXT_texture_filter_anisotropic", NULL},
75 {"GL_EXT_texture_lod_bias", NULL},
76 {"GL_3DFX_texture_compression_FXT1", NULL},
77 {"GL_APPLE_client_storage", NULL},
78 {"GL_MESA_pack_invert", NULL},
79 {"GL_MESA_ycbcr_texture", NULL},
80 {"GL_NV_blend_square", NULL},
81 {"GL_NV_vertex_program", GL_NV_vertex_program_functions},
82 {"GL_NV_vertex_program1_1", NULL},
83 {"GL_SGIS_generate_mipmap", NULL },
84 {NULL, NULL}
85 };
86
87 EGLContext
88 drm_create_context(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list)
89 {
90 struct drm_device *dev = (struct drm_device *)drv;
91 struct drm_context *ctx;
92 struct drm_context *share = NULL;
93 struct st_context *st_share = NULL;
94 _EGLConfig *conf;
95 int i;
96 __GLcontextModes *visual;
97
98 conf = _eglLookupConfig(drv, dpy, config);
99 if (!conf) {
100 _eglError(EGL_BAD_CONFIG, "eglCreateContext");
101 return EGL_NO_CONTEXT;
102 }
103
104 for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
105 switch (attrib_list[i]) {
106 /* no attribs defined for now */
107 default:
108 _eglError(EGL_BAD_ATTRIBUTE, "eglCreateContext");
109 return EGL_NO_CONTEXT;
110 }
111 }
112
113 ctx = (struct drm_context *) calloc(1, sizeof(struct drm_context));
114 if (!ctx)
115 goto err_c;
116
117 _eglInitContext(drv, dpy, &ctx->base, config, attrib_list);
118
119 ctx->pipe = drm_api_hocks.create_context(dev->screen);
120 if (!ctx->pipe)
121 goto err_pipe;
122
123 if (share)
124 st_share = share->st;
125
126 visual = drm_visual_from_config(conf);
127 ctx->st = st_create_context(ctx->pipe, visual, st_share);
128 drm_visual_modes_destroy(visual);
129
130 if (!ctx->st)
131 goto err_gl;
132
133 /* generate handle and insert into hash table */
134 _eglSaveContext(&ctx->base);
135 assert(_eglGetContextHandle(&ctx->base));
136
137 return _eglGetContextHandle(&ctx->base);
138
139 err_gl:
140 ctx->pipe->destroy(ctx->pipe);
141 err_pipe:
142 free(ctx);
143 err_c:
144 return EGL_NO_CONTEXT;
145 }
146
147 EGLBoolean
148 drm_destroy_context(_EGLDriver *drv, EGLDisplay dpy, EGLContext context)
149 {
150 struct drm_context *c = lookup_drm_context(context);
151 _eglRemoveContext(&c->base);
152 if (c->base.IsBound) {
153 c->base.DeletePending = EGL_TRUE;
154 } else {
155 st_destroy_context(c->st);
156 c->pipe->destroy(c->pipe);
157 free(c);
158 }
159 return EGL_TRUE;
160 }
161
162 EGLBoolean
163 drm_make_current(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext context)
164 {
165 struct drm_surface *readSurf = lookup_drm_surface(read);
166 struct drm_surface *drawSurf = lookup_drm_surface(draw);
167 struct drm_context *ctx = lookup_drm_context(context);
168 EGLBoolean b;
169
170 b = _eglMakeCurrent(drv, dpy, draw, read, context);
171 if (!b)
172 return EGL_FALSE;
173
174 if (ctx) {
175 if (!drawSurf || !readSurf)
176 return EGL_FALSE;
177
178 drawSurf->user = ctx;
179 readSurf->user = ctx;
180
181 st_make_current(ctx->st, drawSurf->stfb, readSurf->stfb);
182
183 /* st_resize_framebuffer needs a bound context to work */
184 st_resize_framebuffer(drawSurf->stfb, drawSurf->w, drawSurf->h);
185 st_resize_framebuffer(readSurf->stfb, readSurf->w, readSurf->h);
186 } else {
187 drawSurf->user = NULL;
188 readSurf->user = NULL;
189
190 st_make_current(NULL, NULL, NULL);
191 }
192
193 return EGL_TRUE;
194 }