e747fc6991b5e0e92bdce8082d961cd6d64cf604
[mesa.git] / src / mesa / drivers / dri / i915 / 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 "glheader.h"
30 #include "context.h"
31 #include "matrix.h"
32 #include "simple_list.h"
33 #include "extensions.h"
34 #include "framebuffer.h"
35 #include "imports.h"
36 #include "points.h"
37
38 #include "swrast/swrast.h"
39 #include "swrast_setup/swrast_setup.h"
40 #include "tnl/tnl.h"
41 #include "vbo/vbo.h"
42
43 #include "tnl/t_pipeline.h"
44 #include "tnl/t_vertex.h"
45
46 #include "drivers/common/driverfuncs.h"
47
48 #include "intel_screen.h"
49
50 #include "i830_dri.h"
51 #include "i830_common.h"
52
53 #include "intel_tex.h"
54 #include "intel_span.h"
55 #include "intel_tris.h"
56 #include "intel_ioctl.h"
57 #include "intel_batchbuffer.h"
58
59 #include "vblank.h"
60 #include "utils.h"
61 #include "xmlpool.h" /* for symbolic values of enum-type options */
62 #ifndef INTEL_DEBUG
63 int INTEL_DEBUG = (0);
64 #endif
65
66 #define need_GL_ARB_multisample
67 #define need_GL_ARB_point_parameters
68 #define need_GL_ARB_texture_compression
69 #define need_GL_ARB_vertex_buffer_object
70 #define need_GL_ARB_vertex_program
71 #define need_GL_ARB_window_pos
72 #define need_GL_EXT_blend_color
73 #define need_GL_EXT_blend_equation_separate
74 #define need_GL_EXT_blend_func_separate
75 #define need_GL_EXT_blend_minmax
76 #define need_GL_EXT_cull_vertex
77 #define need_GL_EXT_fog_coord
78 #define need_GL_EXT_multi_draw_arrays
79 #define need_GL_EXT_secondary_color
80 #define need_GL_NV_vertex_program
81 #include "extension_helper.h"
82
83 #ifndef VERBOSE
84 int VERBOSE = 0;
85 #endif
86
87 #if DEBUG_LOCKING
88 char *prevLockFile;
89 int prevLockLine;
90 #endif
91
92 /***************************************
93 * Mesa's Driver Functions
94 ***************************************/
95
96 #define DRIVER_DATE "20061017"
97
98 const GLubyte *intelGetString( GLcontext *ctx, GLenum name )
99 {
100 const char * chipset;
101 static char buffer[128];
102
103 switch (name) {
104 case GL_VENDOR:
105 return (GLubyte *)"Tungsten Graphics, Inc";
106 break;
107
108 case GL_RENDERER:
109 switch (INTEL_CONTEXT(ctx)->intelScreen->deviceID) {
110 case PCI_CHIP_845_G:
111 chipset = "Intel(R) 845G"; break;
112 case PCI_CHIP_I830_M:
113 chipset = "Intel(R) 830M"; break;
114 case PCI_CHIP_I855_GM:
115 chipset = "Intel(R) 852GM/855GM"; break;
116 case PCI_CHIP_I865_G:
117 chipset = "Intel(R) 865G"; break;
118 case PCI_CHIP_I915_G:
119 chipset = "Intel(R) 915G"; break;
120 case PCI_CHIP_I915_GM:
121 chipset = "Intel(R) 915GM"; break;
122 case PCI_CHIP_I945_G:
123 chipset = "Intel(R) 945G"; break;
124 case PCI_CHIP_I945_GM:
125 chipset = "Intel(R) 945GM"; break;
126 default:
127 chipset = "Unknown Intel Chipset"; break;
128 }
129
130 (void) driGetRendererString( buffer, chipset, DRIVER_DATE, 0 );
131 return (GLubyte *) buffer;
132
133 default:
134 return NULL;
135 }
136 }
137
138
139 /**
140 * Extension strings exported by the intel driver.
141 *
142 * \note
143 * It appears that ARB_texture_env_crossbar has "disappeared" compared to the
144 * old i830-specific driver.
145 */
146 const struct dri_extension card_extensions[] =
147 {
148 { "GL_ARB_multisample", GL_ARB_multisample_functions },
149 { "GL_ARB_multitexture", NULL },
150 { "GL_ARB_point_parameters", GL_ARB_point_parameters_functions },
151 { "GL_ARB_texture_border_clamp", NULL },
152 { "GL_ARB_texture_compression", GL_ARB_texture_compression_functions },
153 { "GL_ARB_texture_cube_map", NULL },
154 { "GL_ARB_texture_env_add", NULL },
155 { "GL_ARB_texture_env_combine", NULL },
156 { "GL_ARB_texture_env_dot3", NULL },
157 { "GL_ARB_texture_mirrored_repeat", NULL },
158 { "GL_ARB_texture_rectangle", NULL },
159 { "GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions },
160 { "GL_ARB_vertex_program", GL_ARB_vertex_program_functions },
161 { "GL_ARB_window_pos", GL_ARB_window_pos_functions },
162 { "GL_EXT_blend_color", GL_EXT_blend_color_functions },
163 { "GL_EXT_blend_equation_separate", GL_EXT_blend_equation_separate_functions },
164 { "GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions },
165 { "GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions },
166 { "GL_EXT_blend_subtract", NULL },
167 { "GL_EXT_cull_vertex", GL_EXT_cull_vertex_functions },
168 { "GL_EXT_fog_coord", GL_EXT_fog_coord_functions },
169 { "GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions },
170 { "GL_EXT_secondary_color", GL_EXT_secondary_color_functions },
171 { "GL_EXT_stencil_wrap", NULL },
172 { "GL_EXT_texture_edge_clamp", NULL },
173 { "GL_EXT_texture_env_combine", NULL },
174 { "GL_EXT_texture_env_dot3", NULL },
175 { "GL_EXT_texture_filter_anisotropic", NULL },
176 { "GL_EXT_texture_lod_bias", NULL },
177 { "GL_3DFX_texture_compression_FXT1", NULL },
178 { "GL_APPLE_client_storage", NULL },
179 { "GL_MESA_pack_invert", NULL },
180 { "GL_MESA_ycbcr_texture", NULL },
181 { "GL_NV_blend_square", NULL },
182 { "GL_NV_vertex_program", GL_NV_vertex_program_functions },
183 { "GL_NV_vertex_program1_1", NULL },
184 { "GL_SGIS_generate_mipmap", NULL },
185 { NULL, NULL }
186 };
187
188 extern const struct tnl_pipeline_stage _intel_render_stage;
189
190 static const struct tnl_pipeline_stage *intel_pipeline[] = {
191 &_tnl_vertex_transform_stage,
192 &_tnl_vertex_cull_stage,
193 &_tnl_normal_transform_stage,
194 &_tnl_lighting_stage,
195 &_tnl_fog_coordinate_stage,
196 &_tnl_texgen_stage,
197 &_tnl_texture_transform_stage,
198 &_tnl_point_attenuation_stage,
199 &_tnl_vertex_program_stage,
200 #if 1
201 &_intel_render_stage, /* ADD: unclipped rastersetup-to-dma */
202 #endif
203 &_tnl_render_stage,
204 0,
205 };
206
207
208 static const struct dri_debug_control debug_control[] =
209 {
210 { "fall", DEBUG_FALLBACKS },
211 { "tex", DEBUG_TEXTURE },
212 { "ioctl", DEBUG_IOCTL },
213 { "prim", DEBUG_PRIMS },
214 { "vert", DEBUG_VERTS },
215 { "state", DEBUG_STATE },
216 { "verb", DEBUG_VERBOSE },
217 { "dri", DEBUG_DRI },
218 { "dma", DEBUG_DMA },
219 { "san", DEBUG_SANITY },
220 { "sync", DEBUG_SYNC },
221 { "sleep", DEBUG_SLEEP },
222 { "pix", DEBUG_PIXEL },
223 { NULL, 0 }
224 };
225
226
227 static void intelInvalidateState( GLcontext *ctx, GLuint new_state )
228 {
229 _swrast_InvalidateState( ctx, new_state );
230 _swsetup_InvalidateState( ctx, new_state );
231 _vbo_InvalidateState( ctx, new_state );
232 _tnl_InvalidateState( ctx, new_state );
233 _tnl_invalidate_vertex_state( ctx, new_state );
234 INTEL_CONTEXT(ctx)->NewGLState |= new_state;
235 }
236
237
238 void intelInitDriverFunctions( struct dd_function_table *functions )
239 {
240 _mesa_init_driver_functions( functions );
241
242 functions->Clear = intelClear;
243 functions->Flush = intelglFlush;
244 functions->Finish = intelFinish;
245 functions->GetString = intelGetString;
246 functions->UpdateState = intelInvalidateState;
247
248 intelInitTextureFuncs( functions );
249 intelInitPixelFuncs( functions );
250 intelInitStateFuncs( functions );
251 }
252
253 static void intel_emit_invarient_state( GLcontext *ctx )
254 {
255 }
256
257
258
259 GLboolean intelInitContext( intelContextPtr intel,
260 const __GLcontextModes *mesaVis,
261 __DRIcontextPrivate *driContextPriv,
262 void *sharedContextPrivate,
263 struct dd_function_table *functions )
264 {
265 GLcontext *ctx = &intel->ctx;
266 GLcontext *shareCtx = (GLcontext *) sharedContextPrivate;
267 __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
268 intelScreenPrivate *intelScreen = (intelScreenPrivate *)sPriv->private;
269 drmI830Sarea *saPriv = (drmI830Sarea *)
270 (((GLubyte *)sPriv->pSAREA)+intelScreen->sarea_priv_offset);
271 int fthrottle_mode;
272
273 if (!_mesa_initialize_context(&intel->ctx,
274 mesaVis, shareCtx,
275 functions,
276 (void*) intel))
277 return GL_FALSE;
278
279 driContextPriv->driverPrivate = intel;
280 intel->intelScreen = intelScreen;
281 intel->driScreen = sPriv;
282 intel->sarea = saPriv;
283
284
285 (void) memset( intel->texture_heaps, 0, sizeof( intel->texture_heaps ) );
286 make_empty_list( & intel->swapped );
287
288 driParseConfigFiles (&intel->optionCache, &intelScreen->optionCache,
289 intel->driScreen->myNum, "i915");
290
291 ctx->Const.MaxTextureMaxAnisotropy = 2.0;
292
293 ctx->Const.MinLineWidth = 1.0;
294 ctx->Const.MinLineWidthAA = 1.0;
295 ctx->Const.MaxLineWidth = 3.0;
296 ctx->Const.MaxLineWidthAA = 3.0;
297 ctx->Const.LineWidthGranularity = 1.0;
298
299 ctx->Const.MinPointSize = 1.0;
300 ctx->Const.MinPointSizeAA = 1.0;
301 ctx->Const.MaxPointSize = 255.0;
302 ctx->Const.MaxPointSizeAA = 3.0;
303 ctx->Const.PointSizeGranularity = 1.0;
304
305 /* reinitialize the context point state.
306 * It depend on constants in __GLcontextRec::Const
307 */
308 _mesa_init_point(ctx);
309
310 /* Initialize the software rasterizer and helper modules. */
311 _swrast_CreateContext( ctx );
312 _vbo_CreateContext( ctx );
313 _tnl_CreateContext( ctx );
314 _swsetup_CreateContext( ctx );
315
316 /* Install the customized pipeline: */
317 _tnl_destroy_pipeline( ctx );
318 _tnl_install_pipeline( ctx, intel_pipeline );
319
320 /* Configure swrast to match hardware characteristics: */
321 _swrast_allow_pixel_fog( ctx, GL_FALSE );
322 _swrast_allow_vertex_fog( ctx, GL_TRUE );
323
324 /* Dri stuff */
325 intel->hHWContext = driContextPriv->hHWContext;
326 intel->driFd = sPriv->fd;
327 intel->driHwLock = (drmLock *) &sPriv->pSAREA->lock;
328
329 intel->hw_stencil = mesaVis->stencilBits && mesaVis->depthBits == 24;
330 intel->hw_stipple = 1;
331
332 switch(mesaVis->depthBits) {
333 case 0: /* what to do in this case? */
334 case 16:
335 intel->depth_scale = 1.0/0xffff;
336 intel->polygon_offset_scale = 1.0/0xffff;
337 intel->depth_clear_mask = ~0;
338 intel->ClearDepth = 0xffff;
339 break;
340 case 24:
341 intel->depth_scale = 1.0/0xffffff;
342 intel->polygon_offset_scale = 2.0/0xffffff; /* req'd to pass glean */
343 intel->depth_clear_mask = 0x00ffffff;
344 intel->stencil_clear_mask = 0xff000000;
345 intel->ClearDepth = 0x00ffffff;
346 break;
347 default:
348 assert(0);
349 break;
350 }
351
352 /* Initialize swrast, tnl driver tables: */
353 intelInitSpanFuncs( ctx );
354 intelInitTriFuncs( ctx );
355
356
357 intel->RenderIndex = ~0;
358
359 fthrottle_mode = driQueryOptioni(&intel->optionCache, "fthrottle_mode");
360 intel->iw.irq_seq = -1;
361 intel->irqsEmitted = 0;
362
363 intel->do_irqs = (intel->intelScreen->irq_active &&
364 fthrottle_mode == DRI_CONF_FTHROTTLE_IRQS);
365
366 intel->do_usleeps = (fthrottle_mode == DRI_CONF_FTHROTTLE_USLEEPS);
367
368 intel->vblank_flags = (intel->intelScreen->irq_active != 0)
369 ? driGetDefaultVBlankFlags(&intel->optionCache) : VBLANK_FLAG_NO_IRQ;
370
371 (*dri_interface->getUST)(&intel->swap_ust);
372 _math_matrix_ctr (&intel->ViewportMatrix);
373
374 driInitExtensions( ctx, card_extensions, GL_TRUE );
375
376 if (intel->ctx.Mesa_DXTn) {
377 _mesa_enable_extension( ctx, "GL_EXT_texture_compression_s3tc" );
378 _mesa_enable_extension( ctx, "GL_S3_s3tc" );
379 }
380 else if (driQueryOptionb (&intel->optionCache, "force_s3tc_enable")) {
381 _mesa_enable_extension( ctx, "GL_EXT_texture_compression_s3tc" );
382 }
383
384 /* driInitTextureObjects( ctx, & intel->swapped, */
385 /* DRI_TEXMGR_DO_TEXTURE_1D | */
386 /* DRI_TEXMGR_DO_TEXTURE_2D | */
387 /* DRI_TEXMGR_DO_TEXTURE_RECT ); */
388
389
390 intelInitBatchBuffer(&intel->ctx);
391 intel->prim.flush = intel_emit_invarient_state;
392 intel->prim.primitive = ~0;
393
394
395 #if DO_DEBUG
396 INTEL_DEBUG = driParseDebugString( getenv( "INTEL_DEBUG" ),
397 debug_control );
398 INTEL_DEBUG |= driParseDebugString( getenv( "INTEL_DEBUG" ),
399 debug_control );
400 #endif
401
402 #ifndef VERBOSE
403 if (getenv("INTEL_VERBOSE"))
404 VERBOSE=1;
405 #endif
406
407 if (getenv("INTEL_NO_RAST") ||
408 getenv("INTEL_NO_RAST")) {
409 fprintf(stderr, "disabling 3D rasterization\n");
410 FALLBACK(intel, INTEL_FALLBACK_USER, 1);
411 }
412
413 return GL_TRUE;
414 }
415
416 void intelDestroyContext(__DRIcontextPrivate *driContextPriv)
417 {
418 intelContextPtr intel = (intelContextPtr) driContextPriv->driverPrivate;
419
420 assert(intel); /* should never be null */
421 if (intel) {
422 GLboolean release_texture_heaps;
423
424 INTEL_FIREVERTICES( intel );
425
426 intel->vtbl.destroy( intel );
427
428 release_texture_heaps = (intel->ctx.Shared->RefCount == 1);
429 _swsetup_DestroyContext (&intel->ctx);
430 _tnl_DestroyContext (&intel->ctx);
431 _vbo_DestroyContext (&intel->ctx);
432
433 _swrast_DestroyContext (&intel->ctx);
434 intel->Fallback = 0; /* don't call _swrast_Flush later */
435
436 intelDestroyBatchBuffer(&intel->ctx);
437
438
439 if ( release_texture_heaps ) {
440 /* This share group is about to go away, free our private
441 * texture object data.
442 */
443 int i;
444
445 for ( i = 0 ; i < intel->nr_heaps ; i++ ) {
446 driDestroyTextureHeap( intel->texture_heaps[ i ] );
447 intel->texture_heaps[ i ] = NULL;
448 }
449
450 assert( is_empty_list( & intel->swapped ) );
451 }
452
453 /* free the Mesa context */
454 _mesa_destroy_context(&intel->ctx);
455 }
456 }
457
458 void intelSetFrontClipRects( intelContextPtr intel )
459 {
460 __DRIdrawablePrivate *dPriv = intel->driDrawable;
461
462 if (!dPriv) return;
463
464 intel->numClipRects = dPriv->numClipRects;
465 intel->pClipRects = dPriv->pClipRects;
466 intel->drawX = dPriv->x;
467 intel->drawY = dPriv->y;
468 }
469
470
471 void intelSetBackClipRects( intelContextPtr intel )
472 {
473 __DRIdrawablePrivate *dPriv = intel->driDrawable;
474
475 if (!dPriv) return;
476
477 if (intel->sarea->pf_enabled == 0 && dPriv->numBackClipRects == 0) {
478 intel->numClipRects = dPriv->numClipRects;
479 intel->pClipRects = dPriv->pClipRects;
480 intel->drawX = dPriv->x;
481 intel->drawY = dPriv->y;
482 } else {
483 intel->numClipRects = dPriv->numBackClipRects;
484 intel->pClipRects = dPriv->pBackClipRects;
485 intel->drawX = dPriv->backX;
486 intel->drawY = dPriv->backY;
487
488 if (dPriv->numBackClipRects == 1 &&
489 dPriv->x == dPriv->backX &&
490 dPriv->y == dPriv->backY) {
491
492 /* Repeat the calculation of the back cliprect dimensions here
493 * as early versions of dri.a in the Xserver are incorrect. Try
494 * very hard not to restrict future versions of dri.a which
495 * might eg. allocate truly private back buffers.
496 */
497 int x1, y1;
498 int x2, y2;
499
500 x1 = dPriv->x;
501 y1 = dPriv->y;
502 x2 = dPriv->x + dPriv->w;
503 y2 = dPriv->y + dPriv->h;
504
505 if (x1 < 0) x1 = 0;
506 if (y1 < 0) y1 = 0;
507 if (x2 > intel->intelScreen->width) x2 = intel->intelScreen->width;
508 if (y2 > intel->intelScreen->height) y2 = intel->intelScreen->height;
509
510 if (x1 == dPriv->pBackClipRects[0].x1 &&
511 y1 == dPriv->pBackClipRects[0].y1) {
512
513 dPriv->pBackClipRects[0].x2 = x2;
514 dPriv->pBackClipRects[0].y2 = y2;
515 }
516 }
517 }
518 }
519
520
521 void intelWindowMoved( intelContextPtr intel )
522 {
523 __DRIdrawablePrivate *dPriv = intel->driDrawable;
524 GLframebuffer *drawFb = (GLframebuffer *) dPriv->driverPrivate;
525
526 if (!intel->ctx.DrawBuffer) {
527 intelSetFrontClipRects( intel );
528 }
529 else {
530 driUpdateFramebufferSize(&intel->ctx, dPriv);
531 switch (drawFb->_ColorDrawBufferMask[0]) {
532 case BUFFER_BIT_FRONT_LEFT:
533 intelSetFrontClipRects( intel );
534 break;
535 case BUFFER_BIT_BACK_LEFT:
536 intelSetBackClipRects( intel );
537 break;
538 default:
539 /* glDrawBuffer(GL_NONE or GL_FRONT_AND_BACK): software fallback */
540 intelSetFrontClipRects( intel );
541 }
542 }
543
544 if (drawFb->Width != dPriv->w || drawFb->Height != dPriv->h) {
545 /* update Mesa's notion of framebuffer/window size */
546 _mesa_resize_framebuffer(&intel->ctx, drawFb, dPriv->w, dPriv->h);
547 drawFb->Initialized = GL_TRUE; /* XXX remove someday */
548 }
549
550 /* Set state we know depends on drawable parameters:
551 */
552 {
553 GLcontext *ctx = &intel->ctx;
554
555 if (intel->intelScreen->driScrnPriv->ddxMinor >= 7) {
556 drmI830Sarea *sarea = intel->sarea;
557 drm_clip_rect_t drw_rect = { .x1 = dPriv->x, .x2 = dPriv->x + dPriv->w,
558 .y1 = dPriv->y, .y2 = dPriv->y + dPriv->h };
559 drm_clip_rect_t pipeA_rect = { .x1 = sarea->pipeA_x,
560 .x2 = sarea->pipeA_x + sarea->pipeA_w,
561 .y1 = sarea->pipeA_y,
562 .y2 = sarea->pipeA_y + sarea->pipeA_h };
563 drm_clip_rect_t pipeB_rect = { .x1 = sarea->pipeB_x,
564 .x2 = sarea->pipeB_x + sarea->pipeB_w,
565 .y1 = sarea->pipeB_y,
566 .y2 = sarea->pipeB_y + sarea->pipeB_h };
567 GLint areaA = driIntersectArea( drw_rect, pipeA_rect );
568 GLint areaB = driIntersectArea( drw_rect, pipeB_rect );
569 GLuint flags = intel->vblank_flags;
570
571 if (areaB > areaA || (areaA == areaB && areaB > 0)) {
572 flags = intel->vblank_flags | VBLANK_FLAG_SECONDARY;
573 } else {
574 flags = intel->vblank_flags & ~VBLANK_FLAG_SECONDARY;
575 }
576
577 if (flags != intel->vblank_flags) {
578 intel->vblank_flags = flags;
579 driGetCurrentVBlank(dPriv, intel->vblank_flags, &intel->vbl_seq);
580 }
581 } else {
582 intel->vblank_flags &= ~VBLANK_FLAG_SECONDARY;
583 }
584
585 ctx->Driver.Scissor( ctx, ctx->Scissor.X, ctx->Scissor.Y,
586 ctx->Scissor.Width, ctx->Scissor.Height );
587
588 ctx->Driver.DepthRange( ctx,
589 ctx->Viewport.Near,
590 ctx->Viewport.Far );
591 }
592 }
593
594 GLboolean intelUnbindContext(__DRIcontextPrivate *driContextPriv)
595 {
596 return GL_TRUE;
597 }
598
599 GLboolean intelMakeCurrent(__DRIcontextPrivate *driContextPriv,
600 __DRIdrawablePrivate *driDrawPriv,
601 __DRIdrawablePrivate *driReadPriv)
602 {
603
604 if (driContextPriv) {
605 intelContextPtr intel = (intelContextPtr) driContextPriv->driverPrivate;
606
607 if ( intel->driDrawable != driDrawPriv ) {
608 /* Shouldn't the readbuffer be stored also? */
609 driDrawableInitVBlank( driDrawPriv, intel->vblank_flags,
610 &intel->vbl_seq );
611
612 intel->driDrawable = driDrawPriv;
613 intelWindowMoved( intel );
614 }
615
616 _mesa_make_current(&intel->ctx,
617 (GLframebuffer *) driDrawPriv->driverPrivate,
618 (GLframebuffer *) driReadPriv->driverPrivate);
619
620 intel->ctx.Driver.DrawBuffer( &intel->ctx, intel->ctx.Color.DrawBuffer[0] );
621 } else {
622 _mesa_make_current(NULL, NULL, NULL);
623 }
624
625 return GL_TRUE;
626 }
627
628 /**
629 * Use the information in the sarea to update the screen parameters
630 * related to screen rotation.
631 */
632 static void
633 intelUpdateScreenRotation(intelContextPtr intel,
634 __DRIscreenPrivate *sPriv,
635 drmI830Sarea *sarea)
636 {
637 intelScreenPrivate *intelScreen = (intelScreenPrivate *)sPriv->private;
638 intelRegion *colorBuf;
639
640 intelUnmapScreenRegions(intelScreen);
641
642 intelUpdateScreenFromSAREA(intelScreen, sarea);
643
644 /* update the current hw offsets for the color and depth buffers */
645 if (intel->ctx.DrawBuffer->_ColorDrawBufferMask[0] == BUFFER_BIT_BACK_LEFT)
646 colorBuf = &intelScreen->back;
647 else
648 colorBuf = &intelScreen->front;
649 intel->vtbl.update_color_z_regions(intel, colorBuf, &intelScreen->depth);
650
651 if (!intelMapScreenRegions(sPriv)) {
652 fprintf(stderr, "ERROR Remapping screen regions!!!\n");
653 }
654 }
655
656 void intelGetLock( intelContextPtr intel, GLuint flags )
657 {
658 __DRIdrawablePrivate *dPriv = intel->driDrawable;
659 __DRIscreenPrivate *sPriv = intel->driScreen;
660 intelScreenPrivate *intelScreen = (intelScreenPrivate *)sPriv->private;
661 drmI830Sarea * sarea = intel->sarea;
662 unsigned i;
663
664 drmGetLock(intel->driFd, intel->hHWContext, flags);
665
666 /* If the window moved, may need to set a new cliprect now.
667 *
668 * NOTE: This releases and regains the hw lock, so all state
669 * checking must be done *after* this call:
670 */
671 if (dPriv)
672 DRI_VALIDATE_DRAWABLE_INFO(sPriv, dPriv);
673
674 if (dPriv && intel->lastStamp != dPriv->lastStamp) {
675 intelWindowMoved( intel );
676 intel->lastStamp = dPriv->lastStamp;
677 }
678
679 /* If we lost context, need to dump all registers to hardware.
680 * Note that we don't care about 2d contexts, even if they perform
681 * accelerated commands, so the DRI locking in the X server is even
682 * more broken than usual.
683 */
684
685 if (sarea->width != intelScreen->width ||
686 sarea->height != intelScreen->height ||
687 sarea->rotation != intelScreen->current_rotation) {
688 intelUpdateScreenRotation(intel, sPriv, sarea);
689
690 /* This will drop the outstanding batchbuffer on the floor */
691 intel->batch.ptr -= (intel->batch.size - intel->batch.space);
692 intel->batch.space = intel->batch.size;
693 /* lose all primitives */
694 intel->prim.primitive = ~0;
695 intel->prim.start_ptr = 0;
696 intel->prim.flush = 0;
697 intel->vtbl.lost_hardware( intel );
698
699 intel->lastStamp = 0; /* force window update */
700
701 /* Release batch buffer
702 */
703 intelDestroyBatchBuffer(&intel->ctx);
704 intelInitBatchBuffer(&intel->ctx);
705 intel->prim.flush = intel_emit_invarient_state;
706
707 /* Still need to reset the global LRU?
708 */
709 intel_driReinitTextureHeap( intel->texture_heaps[0], intel->intelScreen->tex.size );
710 }
711
712 /* Shared texture managment - if another client has played with
713 * texture space, figure out which if any of our textures have been
714 * ejected, and update our global LRU.
715 */
716 for ( i = 0 ; i < intel->nr_heaps ; i++ ) {
717 DRI_AGE_TEXTURES( intel->texture_heaps[ i ] );
718 }
719 }
720
721
722 void intelSwapBuffers( __DRIdrawablePrivate *dPriv )
723 {
724 if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
725 intelContextPtr intel;
726 GLcontext *ctx;
727 intel = (intelContextPtr) dPriv->driContextPriv->driverPrivate;
728 ctx = &intel->ctx;
729 if (ctx->Visual.doubleBufferMode) {
730 intelScreenPrivate *screen = intel->intelScreen;
731 _mesa_notifySwapBuffers( ctx ); /* flush pending rendering comands */
732 if ( 0 /*intel->doPageFlip*/ ) { /* doPageFlip is never set !!! */
733 intelPageFlip( dPriv );
734 } else {
735 intelCopyBuffer( dPriv, NULL );
736 }
737 if (screen->current_rotation != 0) {
738 intelRotateWindow(intel, dPriv, BUFFER_BIT_FRONT_LEFT);
739 }
740 }
741 } else {
742 /* XXX this shouldn't be an error but we can't handle it for now */
743 fprintf(stderr, "%s: drawable has no context!\n", __FUNCTION__);
744 }
745 }
746
747 void intelCopySubBuffer( __DRIdrawablePrivate *dPriv,
748 int x, int y, int w, int h )
749 {
750 if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
751 intelContextPtr intel;
752 GLcontext *ctx;
753 intel = (intelContextPtr) dPriv->driContextPriv->driverPrivate;
754 ctx = &intel->ctx;
755 if (ctx->Visual.doubleBufferMode) {
756 drm_clip_rect_t rect;
757 rect.x1 = x + dPriv->x;
758 rect.y1 = (dPriv->h - y - h) + dPriv->y;
759 rect.x2 = rect.x1 + w;
760 rect.y2 = rect.y1 + h;
761 _mesa_notifySwapBuffers( ctx ); /* flush pending rendering comands */
762 intelCopyBuffer( dPriv, &rect );
763 }
764 } else {
765 /* XXX this shouldn't be an error but we can't handle it for now */
766 fprintf(stderr, "%s: drawable has no context!\n", __FUNCTION__);
767 }
768 }