Merge commit 'origin/gallium-0.1' into gallium-0.2
[mesa.git] / src / gallium / winsys / drm / intel / dri / intel_context.c
1 /**************************************************************************
2 *
3 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28
29 #include "i830_dri.h"
30
31 #include "intel_screen.h"
32 #include "intel_context.h"
33 #include "intel_swapbuffers.h"
34 #include "intel_batchbuffer.h"
35 #include "intel_winsys_softpipe.h"
36
37 #include "i915simple/i915_screen.h"
38
39 #include "state_tracker/st_public.h"
40 #include "state_tracker/st_context.h"
41 #include "pipe/p_defines.h"
42 #include "pipe/p_context.h"
43
44 #include "utils.h"
45
46
47 #ifdef DEBUG
48 int __intel_debug = 0;
49 #endif
50
51
52 #define need_GL_ARB_multisample
53 #define need_GL_ARB_point_parameters
54 #define need_GL_ARB_texture_compression
55 #define need_GL_ARB_vertex_buffer_object
56 #define need_GL_ARB_vertex_program
57 #define need_GL_ARB_window_pos
58 #define need_GL_EXT_blend_color
59 #define need_GL_EXT_blend_equation_separate
60 #define need_GL_EXT_blend_func_separate
61 #define need_GL_EXT_blend_minmax
62 #define need_GL_EXT_cull_vertex
63 #define need_GL_EXT_fog_coord
64 #define need_GL_EXT_framebuffer_object
65 #define need_GL_EXT_multi_draw_arrays
66 #define need_GL_EXT_secondary_color
67 #define need_GL_NV_vertex_program
68 #include "extension_helper.h"
69
70
71 /**
72 * Extension strings exported by the intel driver.
73 *
74 * \note
75 * It appears that ARB_texture_env_crossbar has "disappeared" compared to the
76 * old i830-specific driver.
77 */
78 const struct dri_extension card_extensions[] = {
79 {"GL_ARB_multisample", GL_ARB_multisample_functions},
80 {"GL_ARB_multitexture", NULL},
81 {"GL_ARB_point_parameters", GL_ARB_point_parameters_functions},
82 {"GL_ARB_texture_border_clamp", NULL},
83 {"GL_ARB_texture_compression", GL_ARB_texture_compression_functions},
84 {"GL_ARB_texture_cube_map", NULL},
85 {"GL_ARB_texture_env_add", NULL},
86 {"GL_ARB_texture_env_combine", NULL},
87 {"GL_ARB_texture_env_dot3", NULL},
88 {"GL_ARB_texture_mirrored_repeat", NULL},
89 {"GL_ARB_texture_rectangle", NULL},
90 {"GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions},
91 {"GL_ARB_pixel_buffer_object", NULL},
92 {"GL_ARB_vertex_program", GL_ARB_vertex_program_functions},
93 {"GL_ARB_window_pos", GL_ARB_window_pos_functions},
94 {"GL_EXT_blend_color", GL_EXT_blend_color_functions},
95 {"GL_EXT_blend_equation_separate", GL_EXT_blend_equation_separate_functions},
96 {"GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions},
97 {"GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions},
98 {"GL_EXT_blend_subtract", NULL},
99 {"GL_EXT_cull_vertex", GL_EXT_cull_vertex_functions},
100 {"GL_EXT_fog_coord", GL_EXT_fog_coord_functions},
101 {"GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions},
102 {"GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions},
103 {"GL_EXT_packed_depth_stencil", NULL},
104 {"GL_EXT_pixel_buffer_object", NULL},
105 {"GL_EXT_secondary_color", GL_EXT_secondary_color_functions},
106 {"GL_EXT_stencil_wrap", NULL},
107 {"GL_EXT_texture_edge_clamp", NULL},
108 {"GL_EXT_texture_env_combine", NULL},
109 {"GL_EXT_texture_env_dot3", NULL},
110 {"GL_EXT_texture_filter_anisotropic", NULL},
111 {"GL_EXT_texture_lod_bias", NULL},
112 {"GL_3DFX_texture_compression_FXT1", NULL},
113 {"GL_APPLE_client_storage", NULL},
114 {"GL_MESA_pack_invert", NULL},
115 {"GL_MESA_ycbcr_texture", NULL},
116 {"GL_NV_blend_square", NULL},
117 {"GL_NV_vertex_program", GL_NV_vertex_program_functions},
118 {"GL_NV_vertex_program1_1", NULL},
119 {"GL_SGIS_generate_mipmap", NULL },
120 {NULL, NULL}
121 };
122
123
124
125 #ifdef DEBUG
126 static const struct dri_debug_control debug_control[] = {
127 {"ioctl", DEBUG_IOCTL},
128 {"bat", DEBUG_BATCH},
129 {"lock", DEBUG_LOCK},
130 {"swap", DEBUG_SWAP},
131 {NULL, 0}
132 };
133 #endif
134
135
136
137 static void
138 intel_lock_hardware(struct intel_be_context *context)
139 {
140 struct intel_context *intel = (struct intel_context *)context;
141 LOCK_HARDWARE(intel);
142 }
143
144 static void
145 intel_unlock_hardware(struct intel_be_context *context)
146 {
147 struct intel_context *intel = (struct intel_context *)context;
148 UNLOCK_HARDWARE(intel);
149 }
150
151 static boolean
152 intel_locked_hardware(struct intel_be_context *context)
153 {
154 struct intel_context *intel = (struct intel_context *)context;
155 return intel->locked ? TRUE : FALSE;
156 }
157
158 GLboolean
159 intelCreateContext(const __GLcontextModes * visual,
160 __DRIcontextPrivate * driContextPriv,
161 void *sharedContextPrivate)
162 {
163 struct intel_context *intel = CALLOC_STRUCT(intel_context);
164 __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
165 struct intel_screen *intelScreen = intel_screen(sPriv);
166 drmI830Sarea *saPriv = intelScreen->sarea;
167 int fthrottle_mode;
168 GLboolean havePools;
169 struct pipe_context *pipe;
170 struct st_context *st_share = NULL;
171
172 if (sharedContextPrivate) {
173 st_share = ((struct intel_context *) sharedContextPrivate)->st;
174 }
175
176 driContextPriv->driverPrivate = intel;
177 intel->intelScreen = intelScreen;
178 intel->driScreen = sPriv;
179 intel->sarea = saPriv;
180
181 driParseConfigFiles(&intel->optionCache, &intelScreen->optionCache,
182 intel->driScreen->myNum, "i915");
183
184
185 /*
186 * memory pools
187 */
188 DRM_LIGHT_LOCK(sPriv->fd, &sPriv->pSAREA->lock, driContextPriv->hHWContext);
189 // ZZZ JB should be per screen and not be done per context
190 havePools = intelCreatePools(sPriv);
191 DRM_UNLOCK(sPriv->fd, &sPriv->pSAREA->lock, driContextPriv->hHWContext);
192 if (!havePools)
193 return GL_FALSE;
194
195
196 /* Dri stuff */
197 intel->hHWContext = driContextPriv->hHWContext;
198 intel->driFd = sPriv->fd;
199 intel->driHwLock = (drmLock *) & sPriv->pSAREA->lock;
200
201 fthrottle_mode = driQueryOptioni(&intel->optionCache, "fthrottle_mode");
202 intel->iw.irq_seq = -1;
203 intel->irqsEmitted = 0;
204
205 intel->last_swap_fence = NULL;
206 intel->first_swap_fence = NULL;
207
208 #ifdef DEBUG
209 __intel_debug = driParseDebugString(getenv("INTEL_DEBUG"), debug_control);
210 #endif
211 intel->base.hardware_lock = intel_lock_hardware;
212 intel->base.hardware_unlock = intel_unlock_hardware;
213 intel->base.hardware_locked = intel_locked_hardware;
214
215 intel_be_init_context(&intel->base, &intelScreen->base);
216
217 /*
218 * Pipe-related setup
219 */
220 if (getenv("INTEL_SP")) {
221 /* use softpipe driver instead of hw */
222 pipe = intel_create_softpipe( intel, &intelScreen->base.base );
223 }
224 else {
225 switch (intel->intelScreen->deviceID) {
226 case PCI_CHIP_I945_G:
227 case PCI_CHIP_I945_GM:
228 case PCI_CHIP_I945_GME:
229 case PCI_CHIP_G33_G:
230 case PCI_CHIP_Q33_G:
231 case PCI_CHIP_Q35_G:
232 case PCI_CHIP_I915_G:
233 case PCI_CHIP_I915_GM:
234 pipe = i915_create_context(intelScreen->base.screen,
235 &intelScreen->base.base,
236 &intel->base.base);
237 break;
238 default:
239 fprintf(stderr, "Unknown PCIID %x in %s, using software driver\n",
240 intel->intelScreen->deviceID, __FUNCTION__);
241
242 pipe = intel_create_softpipe( intel, &intelScreen->base.base );
243 break;
244 }
245 }
246
247 pipe->priv = intel;
248
249 intel->st = st_create_context(pipe, visual, st_share);
250
251 driInitExtensions( intel->st->ctx, card_extensions, GL_TRUE );
252
253 return GL_TRUE;
254 }
255
256
257 void
258 intelDestroyContext(__DRIcontextPrivate * driContextPriv)
259 {
260 struct intel_context *intel = intel_context(driContextPriv);
261
262 assert(intel); /* should never be null */
263 if (intel) {
264 st_finish(intel->st);
265
266 if (intel->last_swap_fence) {
267 driFenceFinish(intel->last_swap_fence, DRM_FENCE_TYPE_EXE, GL_TRUE);
268 driFenceUnReference(&intel->last_swap_fence);
269 intel->last_swap_fence = NULL;
270 }
271 if (intel->first_swap_fence) {
272 driFenceFinish(intel->first_swap_fence, DRM_FENCE_TYPE_EXE, GL_TRUE);
273 driFenceUnReference(&intel->first_swap_fence);
274 intel->first_swap_fence = NULL;
275 }
276
277 if (intel->intelScreen->dummyContext == intel)
278 intel->intelScreen->dummyContext = NULL;
279
280 st_destroy_context(intel->st);
281 intel_be_destroy_context(&intel->base);
282 free(intel);
283 }
284 }
285
286
287 GLboolean
288 intelUnbindContext(__DRIcontextPrivate * driContextPriv)
289 {
290 struct intel_context *intel = intel_context(driContextPriv);
291 st_flush(intel->st, PIPE_FLUSH_RENDER_CACHE, NULL);
292 /* XXX make_current(NULL)? */
293 return GL_TRUE;
294 }
295
296
297 GLboolean
298 intelMakeCurrent(__DRIcontextPrivate * driContextPriv,
299 __DRIdrawablePrivate * driDrawPriv,
300 __DRIdrawablePrivate * driReadPriv)
301 {
302 if (driContextPriv) {
303 struct intel_context *intel = intel_context(driContextPriv);
304 struct intel_framebuffer *draw_fb = intel_framebuffer(driDrawPriv);
305 struct intel_framebuffer *read_fb = intel_framebuffer(driReadPriv);
306
307 assert(draw_fb->stfb);
308 assert(read_fb->stfb);
309
310 /* This is for situations in which we need a rendering context but
311 * there may not be any currently bound.
312 */
313 intel->intelScreen->dummyContext = intel;
314
315 st_make_current(intel->st, draw_fb->stfb, read_fb->stfb);
316
317 if ((intel->driDrawable != driDrawPriv) ||
318 (intel->lastStamp != driDrawPriv->lastStamp)) {
319 intel->driDrawable = driDrawPriv;
320 intelUpdateWindowSize(driDrawPriv);
321 intel->lastStamp = driDrawPriv->lastStamp;
322 }
323
324 /* The size of the draw buffer will have been updated above.
325 * If the readbuffer is a different window, check/update its size now.
326 */
327 if (driReadPriv != driDrawPriv) {
328 intelUpdateWindowSize(driReadPriv);
329 }
330
331 }
332 else {
333 st_make_current(NULL, NULL, NULL);
334 }
335
336 return GL_TRUE;
337 }