1 /**************************************************************************
3 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
6 **************************************************************************/
12 #include "simple_list.h"
13 #include "extensions.h"
16 #include "swrast/swrast.h"
17 #include "swrast_setup/swrast_setup.h"
19 #include "array_cache/acache.h"
21 #include "tnl/t_pipeline.h"
22 #include "tnl/t_vertex.h"
24 #include "drivers/common/driverfuncs.h"
26 #include "intel_screen.h"
29 #include "i830_common.h"
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"
39 int INTEL_DEBUG
= (0);
51 const char __driConfigOptions
[] = { 0 };
52 const GLuint __driNConfigOptions
= 0;
54 /***************************************
55 * Mesa's Driver Functions
56 ***************************************/
58 #define DRIVER_DATE "20040528"
60 const GLubyte
*intelGetString( GLcontext
*ctx
, GLenum name
)
63 static char buffer
[128];
67 return (GLubyte
*)"Tungsten Graphics, Inc";
71 switch (INTEL_CONTEXT(ctx
)->intelScreen
->deviceID
) {
73 chipset
= "Intel(R) 845G"; break;
75 chipset
= "Intel(R) 830M"; break;
76 case PCI_CHIP_I855_GM
:
77 chipset
= "Intel(R) 852GM/855GM"; break;
79 chipset
= "Intel(R) 865G"; break;
81 chipset
= "Intel(R) 915G"; break;
83 chipset
= "Unknown Intel Chipset"; break;
86 (void) driGetRendererString( buffer
, chipset
, DRIVER_DATE
, 0 );
87 return (GLubyte
*) buffer
;
94 static void intelBufferSize(GLframebuffer
*buffer
,
95 GLuint
*width
, GLuint
*height
)
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
103 LOCK_HARDWARE(intel
);
104 *width
= intel
->driDrawable
->w
;
105 *height
= intel
->driDrawable
->h
;
106 UNLOCK_HARDWARE(intel
);
111 /* Extension strings exported by the intel driver.
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.
118 static const char * const card_extensions
[] =
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",
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",
152 "GL_ARB_vertex_buffer_object",
154 "GL_EXT_multi_draw_arrays",
159 "GL_SGIS_generate_mipmap",
160 "GL_SGIS_texture_border_clamp",
161 "GL_SGIS_texture_edge_clamp",
166 extern const struct tnl_pipeline_stage _intel_render_stage
;
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
,
174 &_tnl_texture_transform_stage
,
175 &_tnl_point_attenuation_stage
,
176 &_tnl_vertex_program_stage
,
178 &_intel_render_stage
, /* ADD: unclipped rastersetup-to-dma */
185 static const struct dri_debug_control debug_control
[] =
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
},
204 static void intelInvalidateState( GLcontext
*ctx
, GLuint new_state
)
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
;
215 void intelInitDriverFunctions( struct dd_function_table
*functions
)
217 _mesa_init_driver_functions( functions
);
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
;
231 intelInitTextureFuncs( functions
);
232 intelInitPixelFuncs( functions
);
233 intelInitStateFuncs( functions
);
238 GLboolean
intelInitContext( intelContextPtr intel
,
239 const __GLcontextModes
*mesaVis
,
240 __DRIcontextPrivate
*driContextPriv
,
241 void *sharedContextPrivate
,
242 struct dd_function_table
*functions
)
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
);
251 if (!_mesa_initialize_context(&intel
->ctx
,
257 driContextPriv
->driverPrivate
= intel
;
258 intel
->intelScreen
= intelScreen
;
259 intel
->driScreen
= sPriv
;
260 intel
->sarea
= saPriv
;
263 (void) memset( intel
->texture_heaps
, 0, sizeof( intel
->texture_heaps
) );
264 make_empty_list( & intel
->swapped
);
266 ctx
->Const
.MaxTextureMaxAnisotropy
= 2.0;
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;
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;
280 /* Initialize the software rasterizer and helper modules. */
281 _swrast_CreateContext( ctx
);
282 _ac_CreateContext( ctx
);
283 _tnl_CreateContext( ctx
);
284 _swsetup_CreateContext( ctx
);
286 /* Install the customized pipeline: */
287 _tnl_destroy_pipeline( ctx
);
288 _tnl_install_pipeline( ctx
, intel_pipeline
);
290 /* Configure swrast to match hardware characteristics: */
291 _swrast_allow_pixel_fog( ctx
, GL_FALSE
);
292 _swrast_allow_vertex_fog( ctx
, GL_TRUE
);
295 intel
->hHWContext
= driContextPriv
->hHWContext
;
296 intel
->driFd
= sPriv
->fd
;
297 intel
->driHwLock
= (drmLock
*) &sPriv
->pSAREA
->lock
;
299 intel
->hw_stencil
= mesaVis
->stencilBits
&& mesaVis
->depthBits
== 24;
300 intel
->hw_stipple
= 1;
302 switch(mesaVis
->depthBits
) {
303 case 0: /* what to do in this case? */
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;
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;
322 /* Initialize swrast, tnl driver tables: */
323 intelInitSpanFuncs( ctx
);
324 intelInitTriFuncs( ctx
);
327 intel
->RenderIndex
= ~0;
329 intel
->do_irqs
= (intel
->intelScreen
->irq_active
&&
330 !getenv("INTEL_NO_IRQS"));
332 _math_matrix_ctr (&intel
->ViewportMatrix
);
334 driInitExtensions( ctx
, card_extensions
, GL_TRUE
);
336 /* driInitTextureObjects( ctx, & intel->swapped, */
337 /* DRI_TEXMGR_DO_TEXTURE_1D | */
338 /* DRI_TEXMGR_DO_TEXTURE_2D | */
339 /* DRI_TEXMGR_DO_TEXTURE_RECT ); */
342 intel
->prim
.flush
= intelInitBatchBuffer
;
343 intel
->prim
.primitive
= ~0;
347 INTEL_DEBUG
= driParseDebugString( getenv( "INTEL_DEBUG" ),
349 INTEL_DEBUG
|= driParseDebugString( getenv( "INTEL_DEBUG" ),
354 if (getenv("INTEL_VERBOSE"))
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);
367 void intelDestroyContext(__DRIcontextPrivate
*driContextPriv
)
369 intelContextPtr intel
= (intelContextPtr
) driContextPriv
->driverPrivate
;
371 assert(intel
); /* should never be null */
373 GLboolean release_texture_heaps
;
376 intel
->vtbl
.destroy( intel
);
378 release_texture_heaps
= (intel
->ctx
.Shared
->RefCount
== 1);
379 _swsetup_DestroyContext (&intel
->ctx
);
380 _tnl_DestroyContext (&intel
->ctx
);
381 _ac_DestroyContext (&intel
->ctx
);
383 _swrast_DestroyContext (&intel
->ctx
);
384 intel
->Fallback
= 0; /* don't call _swrast_Flush later */
386 intelDestroyBatchBuffer(&intel
->ctx
);
389 if ( release_texture_heaps
) {
390 /* This share group is about to go away, free our private
391 * texture object data.
395 for ( i
= 0 ; i
< intel
->nr_heaps
; i
++ ) {
396 driDestroyTextureHeap( intel
->texture_heaps
[ i
] );
397 intel
->texture_heaps
[ i
] = NULL
;
400 assert( is_empty_list( & intel
->swapped
) );
403 /* free the Mesa context */
404 _mesa_destroy_context(&intel
->ctx
);
408 void intelSetFrontClipRects( intelContextPtr intel
)
410 __DRIdrawablePrivate
*dPriv
= intel
->driDrawable
;
414 intel
->numClipRects
= dPriv
->numClipRects
;
415 intel
->pClipRects
= dPriv
->pClipRects
;
416 intel
->drawX
= dPriv
->x
;
417 intel
->drawY
= dPriv
->y
;
421 void intelSetBackClipRects( intelContextPtr intel
)
423 __DRIdrawablePrivate
*dPriv
= intel
->driDrawable
;
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
;
433 intel
->numClipRects
= dPriv
->numBackClipRects
;
434 intel
->pClipRects
= dPriv
->pBackClipRects
;
435 intel
->drawX
= dPriv
->backX
;
436 intel
->drawY
= dPriv
->backY
;
438 if (dPriv
->numBackClipRects
== 1 &&
439 dPriv
->x
== dPriv
->backX
&&
440 dPriv
->y
== dPriv
->backY
) {
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.
452 x2
= dPriv
->x
+ dPriv
->w
;
453 y2
= dPriv
->y
+ dPriv
->h
;
457 if (x2
> intel
->intelScreen
->width
) x2
= intel
->intelScreen
->width
;
458 if (y2
> intel
->intelScreen
->height
) y2
= intel
->intelScreen
->height
;
460 if (x1
== dPriv
->pBackClipRects
[0].x1
&&
461 y1
== dPriv
->pBackClipRects
[0].y1
) {
463 dPriv
->pBackClipRects
[0].x2
= x2
;
464 dPriv
->pBackClipRects
[0].y2
= y2
;
471 void intelWindowMoved( intelContextPtr intel
)
473 switch (intel
->ctx
.Color
._DrawDestMask
) {
474 case DD_FRONT_LEFT_BIT
:
475 intelSetFrontClipRects( intel
);
477 case DD_BACK_LEFT_BIT
:
478 intelSetBackClipRects( intel
);
481 /* glDrawBuffer(GL_NONE or GL_FRONT_AND_BACK): software fallback */
482 intelSetFrontClipRects( intel
);
486 GLboolean
intelUnbindContext(__DRIcontextPrivate
*driContextPriv
)
491 GLboolean
intelMakeCurrent(__DRIcontextPrivate
*driContextPriv
,
492 __DRIdrawablePrivate
*driDrawPriv
,
493 __DRIdrawablePrivate
*driReadPriv
)
496 if (driContextPriv
) {
497 intelContextPtr intel
= (intelContextPtr
) driContextPriv
->driverPrivate
;
499 if ( intel
->driDrawable
!= driDrawPriv
) {
500 /* Shouldn't the readbuffer be stored also? */
501 intel
->driDrawable
= driDrawPriv
;
502 intelWindowMoved( intel
);
505 _mesa_make_current2(&intel
->ctx
,
506 (GLframebuffer
*) driDrawPriv
->driverPrivate
,
507 (GLframebuffer
*) driReadPriv
->driverPrivate
);
509 if (!intel
->ctx
.Viewport
.Width
)
510 _mesa_set_viewport(&intel
->ctx
, 0, 0, driDrawPriv
->w
, driDrawPriv
->h
);
512 _mesa_make_current(0,0);
518 void intelGetLock( intelContextPtr intel
, GLuint flags
)
520 __DRIdrawablePrivate
*dPriv
= intel
->driDrawable
;
521 __DRIscreenPrivate
*sPriv
= intel
->driScreen
;
522 drmI830Sarea
* sarea
= intel
->sarea
;
523 int me
= intel
->hHWContext
;
526 drmGetLock(intel
->driFd
, intel
->hHWContext
, flags
);
528 /* If the window moved, may need to set a new cliprect now.
530 * NOTE: This releases and regains the hw lock, so all state
531 * checking must be done *after* this call:
534 DRI_VALIDATE_DRAWABLE_INFO(sPriv
, dPriv
);
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.
542 if (sarea
->ctxOwner
!= me
) {
543 intel
->perf_boxes
|= I830_BOX_LOST_CONTEXT
;
544 sarea
->ctxOwner
= me
;
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.
552 for ( i
= 0 ; i
< intel
->nr_heaps
; i
++ ) {
553 DRI_AGE_TEXTURES( intel
->texture_heaps
[ i
] );
556 if (dPriv
&& intel
->lastStamp
!= dPriv
->lastStamp
) {
557 intelWindowMoved( intel
);
558 intel
->lastStamp
= dPriv
->lastStamp
;
562 void intelSwapBuffers( __DRIdrawablePrivate
*dPriv
)
564 if (dPriv
->driContextPriv
&& dPriv
->driContextPriv
->driverPrivate
) {
565 intelContextPtr intel
;
567 intel
= (intelContextPtr
) dPriv
->driContextPriv
->driverPrivate
;
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
);
574 intelCopyBuffer( dPriv
);
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__
);
584 void intelInitState( GLcontext
*ctx
)
586 /* Mesa should do this for us:
588 ctx
->Driver
.AlphaFunc( ctx
,
589 ctx
->Color
.AlphaFunc
,
590 ctx
->Color
.AlphaRef
);
592 ctx
->Driver
.BlendColor( ctx
,
593 ctx
->Color
.BlendColor
);
595 ctx
->Driver
.BlendEquationSeparate( ctx
,
596 ctx
->Color
.BlendEquationRGB
,
597 ctx
->Color
.BlendEquationA
);
599 ctx
->Driver
.BlendFuncSeparate( ctx
,
600 ctx
->Color
.BlendSrcRGB
,
601 ctx
->Color
.BlendDstRGB
,
602 ctx
->Color
.BlendSrcA
,
603 ctx
->Color
.BlendDstA
);
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
]);
611 ctx
->Driver
.CullFace( ctx
, ctx
->Polygon
.CullFaceMode
);
612 ctx
->Driver
.DepthFunc( ctx
, ctx
->Depth
.Func
);
613 ctx
->Driver
.DepthMask( ctx
, ctx
->Depth
.Mask
);
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
);
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
);
640 ctx
->Driver
.FrontFace( ctx
, ctx
->Polygon
.FrontFace
);
643 GLfloat f
= (GLfloat
)ctx
->Light
.Model
.ColorControl
;
644 ctx
->Driver
.LightModelfv( ctx
, GL_LIGHT_MODEL_COLOR_CONTROL
, &f
);
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],
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]);
665 ctx
->Driver
.DrawBuffer( ctx
, ctx
->Color
.DrawBuffer
);