New driver for i915 as well as older i830/i845/i865 chipsets.
[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 **************************************************************************/
7
8
9 #include "glheader.h"
10 #include "context.h"
11 #include "matrix.h"
12 #include "simple_list.h"
13 #include "extensions.h"
14 #include "imports.h"
15
16 #include "swrast/swrast.h"
17 #include "swrast_setup/swrast_setup.h"
18 #include "tnl/tnl.h"
19 #include "array_cache/acache.h"
20
21 #include "tnl/t_pipeline.h"
22 #include "tnl/t_vertex.h"
23
24 #include "drivers/common/driverfuncs.h"
25
26 #include "intel_screen.h"
27
28 #include "i830_dri.h"
29 #include "i830_common.h"
30
31 #include "intel_tex.h"
32 #include "intel_span.h"
33 #include "intel_tris.h"
34 #include "intel_ioctl.h"
35 #include "intel_batchbuffer.h"
36
37 #include "utils.h"
38 #ifndef INTEL_DEBUG
39 int INTEL_DEBUG = (0);
40 #endif
41
42 #ifndef VERBOSE
43 int VERBOSE = 0;
44 #endif
45
46 #if DEBUG_LOCKING
47 char *prevLockFile;
48 int prevLockLine;
49 #endif
50
51 const char __driConfigOptions[] = { 0 };
52 const GLuint __driNConfigOptions = 0;
53
54 /***************************************
55 * Mesa's Driver Functions
56 ***************************************/
57
58 #define DRIVER_DATE "20040528"
59
60 const GLubyte *intelGetString( GLcontext *ctx, GLenum name )
61 {
62 const char * chipset;
63 static char buffer[128];
64
65 switch (name) {
66 case GL_VENDOR:
67 return (GLubyte *)"Tungsten Graphics, Inc";
68 break;
69
70 case GL_RENDERER:
71 switch (INTEL_CONTEXT(ctx)->intelScreen->deviceID) {
72 case PCI_CHIP_845_G:
73 chipset = "Intel(R) 845G"; break;
74 case PCI_CHIP_I830_M:
75 chipset = "Intel(R) 830M"; break;
76 case PCI_CHIP_I855_GM:
77 chipset = "Intel(R) 852GM/855GM"; break;
78 case PCI_CHIP_I865_G:
79 chipset = "Intel(R) 865G"; break;
80 case PCI_CHIP_I915_G:
81 chipset = "Intel(R) 915G"; break;
82 default:
83 chipset = "Unknown Intel Chipset"; break;
84 }
85
86 (void) driGetRendererString( buffer, chipset, DRIVER_DATE, 0 );
87 return (GLubyte *) buffer;
88
89 default:
90 return NULL;
91 }
92 }
93
94 static void intelBufferSize(GLframebuffer *buffer,
95 GLuint *width, GLuint *height)
96 {
97 GET_CURRENT_CONTEXT(ctx);
98 intelContextPtr intel = INTEL_CONTEXT(ctx);
99 /* Need to lock to make sure the driDrawable is uptodate. This
100 * information is used to resize Mesa's software buffers, so it has
101 * to be correct.
102 */
103 LOCK_HARDWARE(intel);
104 *width = intel->driDrawable->w;
105 *height = intel->driDrawable->h;
106 UNLOCK_HARDWARE(intel);
107 }
108
109
110
111 /* Extension strings exported by the intel driver.
112 *
113 * NOTE: See implementation of glGetString in each hw_context.c file:
114 * This set of extensions is overridden and many are not actually
115 * exported to the driver. They are however enabled internally as
116 * Mesa requires this when calculating things like GL version number.
117 */
118 static const char * const card_extensions[] =
119 {
120 "GL_APPLE_client_storage",
121 "GL_ARB_multisample",
122 "GL_ARB_multitexture",
123 "GL_ARB_texture_border_clamp",
124 "GL_ARB_texture_compression",
125 "GL_ARB_texture_env_add",
126 "GL_ARB_texture_env_combine",
127 "GL_ARB_texture_env_dot3",
128 "GL_ARB_texture_mirrored_repeat",
129 "GL_ARB_vertex_program",
130 "GL_EXT_blend_color",
131 "GL_EXT_blend_func_separate",
132 "GL_EXT_blend_minmax",
133 "GL_EXT_blend_subtract",
134 "GL_EXT_fog_coord",
135 "GL_EXT_secondary_color",
136 "GL_EXT_stencil_wrap",
137 "GL_EXT_texture_edge_clamp",
138 "GL_EXT_texture_env_add",
139 "GL_EXT_texture_env_combine",
140 "GL_EXT_texture_env_dot3",
141 "GL_EXT_texture_filter_anisotropic",
142 "GL_EXT_texture_lod_bias",
143 "GL_IBM_texture_mirrored_repeat",
144 "GL_INGR_blend_func_separate",
145 "GL_MESA_pack_invert",
146 "GL_MESA_ycbcr_texture",
147 "GL_NV_texture_rectangle",
148 "GL_NV_vertex_program",
149
150 /* New in final:
151 */
152 "GL_ARB_vertex_buffer_object",
153 "GL_ARB_window_pos",
154 "GL_EXT_multi_draw_arrays",
155 "GL_EXT_abgr",
156 "GL_EXT_bgra",
157
158
159 "GL_SGIS_generate_mipmap",
160 "GL_SGIS_texture_border_clamp",
161 "GL_SGIS_texture_edge_clamp",
162 NULL
163 };
164
165
166 extern const struct tnl_pipeline_stage _intel_render_stage;
167
168 static const struct tnl_pipeline_stage *intel_pipeline[] = {
169 &_tnl_vertex_transform_stage,
170 &_tnl_normal_transform_stage,
171 &_tnl_lighting_stage,
172 &_tnl_fog_coordinate_stage,
173 &_tnl_texgen_stage,
174 &_tnl_texture_transform_stage,
175 &_tnl_point_attenuation_stage,
176 &_tnl_vertex_program_stage,
177 #if 1
178 &_intel_render_stage, /* ADD: unclipped rastersetup-to-dma */
179 #endif
180 &_tnl_render_stage,
181 0,
182 };
183
184
185 static const struct dri_debug_control debug_control[] =
186 {
187 { "fall", DEBUG_FALLBACKS },
188 { "tex", DEBUG_TEXTURE },
189 { "ioctl", DEBUG_IOCTL },
190 { "prim", DEBUG_PRIMS },
191 { "vert", DEBUG_VERTS },
192 { "state", DEBUG_STATE },
193 { "verb", DEBUG_VERBOSE },
194 { "dri", DEBUG_DRI },
195 { "dma", DEBUG_DMA },
196 { "san", DEBUG_SANITY },
197 { "sync", DEBUG_SYNC },
198 { "sleep", DEBUG_SLEEP },
199 { "pix", DEBUG_PIXEL },
200 { NULL, 0 }
201 };
202
203
204 static void intelInvalidateState( GLcontext *ctx, GLuint new_state )
205 {
206 _swrast_InvalidateState( ctx, new_state );
207 _swsetup_InvalidateState( ctx, new_state );
208 _ac_InvalidateState( ctx, new_state );
209 _tnl_InvalidateState( ctx, new_state );
210 _tnl_invalidate_vertex_state( ctx, new_state );
211 INTEL_CONTEXT(ctx)->NewGLState |= new_state;
212 }
213
214
215 void intelInitDriverFunctions( struct dd_function_table *functions )
216 {
217 _mesa_init_driver_functions( functions );
218
219 functions->Flush = intelFlush;
220 functions->Clear = intelClear;
221 functions->Finish = intelFinish;
222 functions->GetBufferSize = intelBufferSize;
223 functions->ResizeBuffers = _swrast_alloc_buffers;
224 functions->GetString = intelGetString;
225 functions->UpdateState = intelInvalidateState;
226 functions->CopyColorTable = _swrast_CopyColorTable;
227 functions->CopyColorSubTable = _swrast_CopyColorSubTable;
228 functions->CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
229 functions->CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
230
231 intelInitTextureFuncs( functions );
232 intelInitPixelFuncs( functions );
233 intelInitStateFuncs( functions );
234 }
235
236
237
238 GLboolean intelInitContext( intelContextPtr intel,
239 const __GLcontextModes *mesaVis,
240 __DRIcontextPrivate *driContextPriv,
241 void *sharedContextPrivate,
242 struct dd_function_table *functions )
243 {
244 GLcontext *ctx = &intel->ctx;
245 GLcontext *shareCtx = (GLcontext *) sharedContextPrivate;
246 __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
247 intelScreenPrivate *intelScreen = (intelScreenPrivate *)sPriv->private;
248 drmI830Sarea *saPriv = (drmI830Sarea *)
249 (((GLubyte *)sPriv->pSAREA)+intelScreen->sarea_priv_offset);
250
251 if (!_mesa_initialize_context(&intel->ctx,
252 mesaVis, shareCtx,
253 functions,
254 (void*) intel))
255 return GL_FALSE;
256
257 driContextPriv->driverPrivate = intel;
258 intel->intelScreen = intelScreen;
259 intel->driScreen = sPriv;
260 intel->sarea = saPriv;
261
262
263 (void) memset( intel->texture_heaps, 0, sizeof( intel->texture_heaps ) );
264 make_empty_list( & intel->swapped );
265
266 ctx->Const.MaxTextureMaxAnisotropy = 2.0;
267
268 ctx->Const.MinLineWidth = 1.0;
269 ctx->Const.MinLineWidthAA = 1.0;
270 ctx->Const.MaxLineWidth = 3.0;
271 ctx->Const.MaxLineWidthAA = 3.0;
272 ctx->Const.LineWidthGranularity = 1.0;
273
274 ctx->Const.MinPointSize = 1.0;
275 ctx->Const.MinPointSizeAA = 1.0;
276 ctx->Const.MaxPointSize = 255.0;
277 ctx->Const.MaxPointSizeAA = 3.0;
278 ctx->Const.PointSizeGranularity = 1.0;
279
280 /* Initialize the software rasterizer and helper modules. */
281 _swrast_CreateContext( ctx );
282 _ac_CreateContext( ctx );
283 _tnl_CreateContext( ctx );
284 _swsetup_CreateContext( ctx );
285
286 /* Install the customized pipeline: */
287 _tnl_destroy_pipeline( ctx );
288 _tnl_install_pipeline( ctx, intel_pipeline );
289
290 /* Configure swrast to match hardware characteristics: */
291 _swrast_allow_pixel_fog( ctx, GL_FALSE );
292 _swrast_allow_vertex_fog( ctx, GL_TRUE );
293
294 /* Dri stuff */
295 intel->hHWContext = driContextPriv->hHWContext;
296 intel->driFd = sPriv->fd;
297 intel->driHwLock = (drmLock *) &sPriv->pSAREA->lock;
298
299 intel->hw_stencil = mesaVis->stencilBits && mesaVis->depthBits == 24;
300 intel->hw_stipple = 1;
301
302 switch(mesaVis->depthBits) {
303 case 0: /* what to do in this case? */
304 case 16:
305 intel->depth_scale = 1.0/0xffff;
306 intel->polygon_offset_scale = 1.0/0xffff;
307 intel->depth_clear_mask = ~0;
308 intel->ClearDepth = 0xffff;
309 break;
310 case 24:
311 intel->depth_scale = 1.0/0xffffff;
312 intel->polygon_offset_scale = 2.0/0xffffff; /* req'd to pass glean */
313 intel->depth_clear_mask = 0x00ffffff;
314 intel->stencil_clear_mask = 0xff000000;
315 intel->ClearDepth = 0x00ffffff;
316 break;
317 default:
318 assert(0);
319 break;
320 }
321
322 /* Initialize swrast, tnl driver tables: */
323 intelInitSpanFuncs( ctx );
324 intelInitTriFuncs( ctx );
325
326
327 intel->RenderIndex = ~0;
328
329 intel->do_irqs = (intel->intelScreen->irq_active &&
330 !getenv("INTEL_NO_IRQS"));
331
332 _math_matrix_ctr (&intel->ViewportMatrix);
333
334 driInitExtensions( ctx, card_extensions, GL_TRUE );
335
336 /* driInitTextureObjects( ctx, & intel->swapped, */
337 /* DRI_TEXMGR_DO_TEXTURE_1D | */
338 /* DRI_TEXMGR_DO_TEXTURE_2D | */
339 /* DRI_TEXMGR_DO_TEXTURE_RECT ); */
340
341
342 intel->prim.flush = intelInitBatchBuffer;
343 intel->prim.primitive = ~0;
344
345
346 #if DO_DEBUG
347 INTEL_DEBUG = driParseDebugString( getenv( "INTEL_DEBUG" ),
348 debug_control );
349 INTEL_DEBUG |= driParseDebugString( getenv( "INTEL_DEBUG" ),
350 debug_control );
351 #endif
352
353 #ifndef VERBOSE
354 if (getenv("INTEL_VERBOSE"))
355 VERBOSE=1;
356 #endif
357
358 if (getenv("INTEL_NO_RAST") ||
359 getenv("INTEL_NO_RAST")) {
360 fprintf(stderr, "disabling 3D rasterization\n");
361 FALLBACK(intel, INTEL_FALLBACK_USER, 1);
362 }
363
364 return GL_TRUE;
365 }
366
367 void intelDestroyContext(__DRIcontextPrivate *driContextPriv)
368 {
369 intelContextPtr intel = (intelContextPtr) driContextPriv->driverPrivate;
370
371 assert(intel); /* should never be null */
372 if (intel) {
373 GLboolean release_texture_heaps;
374
375
376 intel->vtbl.destroy( intel );
377
378 release_texture_heaps = (intel->ctx.Shared->RefCount == 1);
379 _swsetup_DestroyContext (&intel->ctx);
380 _tnl_DestroyContext (&intel->ctx);
381 _ac_DestroyContext (&intel->ctx);
382
383 _swrast_DestroyContext (&intel->ctx);
384 intel->Fallback = 0; /* don't call _swrast_Flush later */
385
386 intelDestroyBatchBuffer(&intel->ctx);
387
388
389 if ( release_texture_heaps ) {
390 /* This share group is about to go away, free our private
391 * texture object data.
392 */
393 int i;
394
395 for ( i = 0 ; i < intel->nr_heaps ; i++ ) {
396 driDestroyTextureHeap( intel->texture_heaps[ i ] );
397 intel->texture_heaps[ i ] = NULL;
398 }
399
400 assert( is_empty_list( & intel->swapped ) );
401 }
402
403 /* free the Mesa context */
404 _mesa_destroy_context(&intel->ctx);
405 }
406 }
407
408 void intelSetFrontClipRects( intelContextPtr intel )
409 {
410 __DRIdrawablePrivate *dPriv = intel->driDrawable;
411
412 if (!dPriv) return;
413
414 intel->numClipRects = dPriv->numClipRects;
415 intel->pClipRects = dPriv->pClipRects;
416 intel->drawX = dPriv->x;
417 intel->drawY = dPriv->y;
418 }
419
420
421 void intelSetBackClipRects( intelContextPtr intel )
422 {
423 __DRIdrawablePrivate *dPriv = intel->driDrawable;
424
425 if (!dPriv) return;
426
427 if (intel->sarea->pf_enabled == 0 && dPriv->numBackClipRects == 0) {
428 intel->numClipRects = dPriv->numClipRects;
429 intel->pClipRects = dPriv->pClipRects;
430 intel->drawX = dPriv->x;
431 intel->drawY = dPriv->y;
432 } else {
433 intel->numClipRects = dPriv->numBackClipRects;
434 intel->pClipRects = dPriv->pBackClipRects;
435 intel->drawX = dPriv->backX;
436 intel->drawY = dPriv->backY;
437
438 if (dPriv->numBackClipRects == 1 &&
439 dPriv->x == dPriv->backX &&
440 dPriv->y == dPriv->backY) {
441
442 /* Repeat the calculation of the back cliprect dimensions here
443 * as early versions of dri.a in the Xserver are incorrect. Try
444 * very hard not to restrict future versions of dri.a which
445 * might eg. allocate truly private back buffers.
446 */
447 int x1, y1;
448 int x2, y2;
449
450 x1 = dPriv->x;
451 y1 = dPriv->y;
452 x2 = dPriv->x + dPriv->w;
453 y2 = dPriv->y + dPriv->h;
454
455 if (x1 < 0) x1 = 0;
456 if (y1 < 0) y1 = 0;
457 if (x2 > intel->intelScreen->width) x2 = intel->intelScreen->width;
458 if (y2 > intel->intelScreen->height) y2 = intel->intelScreen->height;
459
460 if (x1 == dPriv->pBackClipRects[0].x1 &&
461 y1 == dPriv->pBackClipRects[0].y1) {
462
463 dPriv->pBackClipRects[0].x2 = x2;
464 dPriv->pBackClipRects[0].y2 = y2;
465 }
466 }
467 }
468 }
469
470
471 void intelWindowMoved( intelContextPtr intel )
472 {
473 switch (intel->ctx.Color._DrawDestMask) {
474 case DD_FRONT_LEFT_BIT:
475 intelSetFrontClipRects( intel );
476 break;
477 case DD_BACK_LEFT_BIT:
478 intelSetBackClipRects( intel );
479 break;
480 default:
481 /* glDrawBuffer(GL_NONE or GL_FRONT_AND_BACK): software fallback */
482 intelSetFrontClipRects( intel );
483 }
484 }
485
486 GLboolean intelUnbindContext(__DRIcontextPrivate *driContextPriv)
487 {
488 return GL_TRUE;
489 }
490
491 GLboolean intelMakeCurrent(__DRIcontextPrivate *driContextPriv,
492 __DRIdrawablePrivate *driDrawPriv,
493 __DRIdrawablePrivate *driReadPriv)
494 {
495
496 if (driContextPriv) {
497 intelContextPtr intel = (intelContextPtr) driContextPriv->driverPrivate;
498
499 if ( intel->driDrawable != driDrawPriv ) {
500 /* Shouldn't the readbuffer be stored also? */
501 intel->driDrawable = driDrawPriv;
502 intelWindowMoved( intel );
503 }
504
505 _mesa_make_current2(&intel->ctx,
506 (GLframebuffer *) driDrawPriv->driverPrivate,
507 (GLframebuffer *) driReadPriv->driverPrivate);
508
509 if (!intel->ctx.Viewport.Width)
510 _mesa_set_viewport(&intel->ctx, 0, 0, driDrawPriv->w, driDrawPriv->h);
511 } else {
512 _mesa_make_current(0,0);
513 }
514
515 return GL_TRUE;
516 }
517
518 void intelGetLock( intelContextPtr intel, GLuint flags )
519 {
520 __DRIdrawablePrivate *dPriv = intel->driDrawable;
521 __DRIscreenPrivate *sPriv = intel->driScreen;
522 drmI830Sarea * sarea = intel->sarea;
523 int me = intel->hHWContext;
524 unsigned i;
525
526 drmGetLock(intel->driFd, intel->hHWContext, flags);
527
528 /* If the window moved, may need to set a new cliprect now.
529 *
530 * NOTE: This releases and regains the hw lock, so all state
531 * checking must be done *after* this call:
532 */
533 if (dPriv)
534 DRI_VALIDATE_DRAWABLE_INFO(sPriv, dPriv);
535
536 /* If we lost context, need to dump all registers to hardware.
537 * Note that we don't care about 2d contexts, even if they perform
538 * accelerated commands, so the DRI locking in the X server is even
539 * more broken than usual.
540 */
541
542 if (sarea->ctxOwner != me) {
543 intel->perf_boxes |= I830_BOX_LOST_CONTEXT;
544 sarea->ctxOwner = me;
545 }
546
547 /* Shared texture managment - if another client has played with
548 * texture space, figure out which if any of our textures have been
549 * ejected, and update our global LRU.
550 */
551
552 for ( i = 0 ; i < intel->nr_heaps ; i++ ) {
553 DRI_AGE_TEXTURES( intel->texture_heaps[ i ] );
554 }
555
556 if (dPriv && intel->lastStamp != dPriv->lastStamp) {
557 intelWindowMoved( intel );
558 intel->lastStamp = dPriv->lastStamp;
559 }
560 }
561
562 void intelSwapBuffers( __DRIdrawablePrivate *dPriv )
563 {
564 if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
565 intelContextPtr intel;
566 GLcontext *ctx;
567 intel = (intelContextPtr) dPriv->driContextPriv->driverPrivate;
568 ctx = &intel->ctx;
569 if (ctx->Visual.doubleBufferMode) {
570 _mesa_notifySwapBuffers( ctx ); /* flush pending rendering comands */
571 if ( 0 /*intel->doPageFlip*/ ) { /* doPageFlip is never set !!! */
572 intelPageFlip( dPriv );
573 } else {
574 intelCopyBuffer( dPriv );
575 }
576 }
577 } else {
578 /* XXX this shouldn't be an error but we can't handle it for now */
579 fprintf(stderr, "%s: drawable has no context!\n", __FUNCTION__);
580 }
581 }
582
583
584 void intelInitState( GLcontext *ctx )
585 {
586 /* Mesa should do this for us:
587 */
588 ctx->Driver.AlphaFunc( ctx,
589 ctx->Color.AlphaFunc,
590 ctx->Color.AlphaRef);
591
592 ctx->Driver.BlendColor( ctx,
593 ctx->Color.BlendColor );
594
595 ctx->Driver.BlendEquationSeparate( ctx,
596 ctx->Color.BlendEquationRGB,
597 ctx->Color.BlendEquationA);
598
599 ctx->Driver.BlendFuncSeparate( ctx,
600 ctx->Color.BlendSrcRGB,
601 ctx->Color.BlendDstRGB,
602 ctx->Color.BlendSrcA,
603 ctx->Color.BlendDstA);
604
605 ctx->Driver.ColorMask( ctx,
606 ctx->Color.ColorMask[RCOMP],
607 ctx->Color.ColorMask[GCOMP],
608 ctx->Color.ColorMask[BCOMP],
609 ctx->Color.ColorMask[ACOMP]);
610
611 ctx->Driver.CullFace( ctx, ctx->Polygon.CullFaceMode );
612 ctx->Driver.DepthFunc( ctx, ctx->Depth.Func );
613 ctx->Driver.DepthMask( ctx, ctx->Depth.Mask );
614
615 ctx->Driver.Enable( ctx, GL_ALPHA_TEST, ctx->Color.AlphaEnabled );
616 ctx->Driver.Enable( ctx, GL_BLEND, ctx->Color.BlendEnabled );
617 ctx->Driver.Enable( ctx, GL_COLOR_LOGIC_OP, ctx->Color.ColorLogicOpEnabled );
618 ctx->Driver.Enable( ctx, GL_COLOR_SUM, ctx->Fog.ColorSumEnabled );
619 ctx->Driver.Enable( ctx, GL_CULL_FACE, ctx->Polygon.CullFlag );
620 ctx->Driver.Enable( ctx, GL_DEPTH_TEST, ctx->Depth.Test );
621 ctx->Driver.Enable( ctx, GL_DITHER, ctx->Color.DitherFlag );
622 ctx->Driver.Enable( ctx, GL_FOG, ctx->Fog.Enabled );
623 ctx->Driver.Enable( ctx, GL_LIGHTING, ctx->Light.Enabled );
624 ctx->Driver.Enable( ctx, GL_LINE_SMOOTH, ctx->Line.SmoothFlag );
625 ctx->Driver.Enable( ctx, GL_POLYGON_STIPPLE, ctx->Polygon.StippleFlag );
626 ctx->Driver.Enable( ctx, GL_SCISSOR_TEST, ctx->Scissor.Enabled );
627 ctx->Driver.Enable( ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled );
628 ctx->Driver.Enable( ctx, GL_TEXTURE_1D, GL_FALSE );
629 ctx->Driver.Enable( ctx, GL_TEXTURE_2D, GL_FALSE );
630 ctx->Driver.Enable( ctx, GL_TEXTURE_RECTANGLE_NV, GL_FALSE );
631 ctx->Driver.Enable( ctx, GL_TEXTURE_3D, GL_FALSE );
632 ctx->Driver.Enable( ctx, GL_TEXTURE_CUBE_MAP, GL_FALSE );
633
634 ctx->Driver.Fogfv( ctx, GL_FOG_COLOR, ctx->Fog.Color );
635 ctx->Driver.Fogfv( ctx, GL_FOG_MODE, 0 );
636 ctx->Driver.Fogfv( ctx, GL_FOG_DENSITY, &ctx->Fog.Density );
637 ctx->Driver.Fogfv( ctx, GL_FOG_START, &ctx->Fog.Start );
638 ctx->Driver.Fogfv( ctx, GL_FOG_END, &ctx->Fog.End );
639
640 ctx->Driver.FrontFace( ctx, ctx->Polygon.FrontFace );
641
642 {
643 GLfloat f = (GLfloat)ctx->Light.Model.ColorControl;
644 ctx->Driver.LightModelfv( ctx, GL_LIGHT_MODEL_COLOR_CONTROL, &f );
645 }
646
647 ctx->Driver.LineWidth( ctx, ctx->Line.Width );
648 ctx->Driver.LogicOpcode( ctx, ctx->Color.LogicOp );
649 ctx->Driver.PointSize( ctx, ctx->Point.Size );
650 ctx->Driver.PolygonStipple( ctx, (const GLubyte *)ctx->PolygonStipple );
651 ctx->Driver.Scissor( ctx, ctx->Scissor.X, ctx->Scissor.Y,
652 ctx->Scissor.Width, ctx->Scissor.Height );
653 ctx->Driver.ShadeModel( ctx, ctx->Light.ShadeModel );
654 ctx->Driver.StencilFunc( ctx,
655 ctx->Stencil.Function[0],
656 ctx->Stencil.Ref[0],
657 ctx->Stencil.ValueMask[0] );
658 ctx->Driver.StencilMask( ctx, ctx->Stencil.WriteMask[0] );
659 ctx->Driver.StencilOp( ctx,
660 ctx->Stencil.FailFunc[0],
661 ctx->Stencil.ZFailFunc[0],
662 ctx->Stencil.ZPassFunc[0]);
663
664
665 ctx->Driver.DrawBuffer( ctx, ctx->Color.DrawBuffer );
666 }