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