s_context.c revision 1c09bcfdda4083636a3ac27d804a34ef87875ce7
1/*
2 * Mesa 3-D graphics library
3 * Version:  6.5.3
4 *
5 * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 *
24 * Authors:
25 *    Keith Whitwell <keith@tungstengraphics.com>
26 *    Brian Paul
27 */
28
29#include "imports.h"
30#include "bufferobj.h"
31#include "context.h"
32#include "colormac.h"
33#include "mtypes.h"
34#include "prog_statevars.h"
35#include "teximage.h"
36#include "swrast.h"
37#include "s_blend.h"
38#include "s_context.h"
39#include "s_lines.h"
40#include "s_points.h"
41#include "s_span.h"
42#include "s_triangle.h"
43#include "s_texfilter.h"
44
45
46/**
47 * Recompute the value of swrast->_RasterMask, etc. according to
48 * the current context.  The _RasterMask field can be easily tested by
49 * drivers to determine certain basic GL state (does the primitive need
50 * stenciling, logic-op, fog, etc?).
51 */
52static void
53_swrast_update_rasterflags( GLcontext *ctx )
54{
55   SWcontext *swrast = SWRAST_CONTEXT(ctx);
56   GLbitfield rasterMask = 0;
57
58   if (ctx->Color.AlphaEnabled)           rasterMask |= ALPHATEST_BIT;
59   if (ctx->Color.BlendEnabled)           rasterMask |= BLEND_BIT;
60   if (ctx->Depth.Test)                   rasterMask |= DEPTH_BIT;
61   if (swrast->_FogEnabled)               rasterMask |= FOG_BIT;
62   if (ctx->Scissor.Enabled)              rasterMask |= CLIP_BIT;
63   if (ctx->Stencil.Enabled)              rasterMask |= STENCIL_BIT;
64   if (ctx->Visual.rgbMode) {
65      const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask);
66      if (colorMask != 0xffffffff)        rasterMask |= MASKING_BIT;
67      if (ctx->Color._LogicOpEnabled)     rasterMask |= LOGIC_OP_BIT;
68      if (ctx->Texture._EnabledUnits)     rasterMask |= TEXTURE_BIT;
69   }
70   else {
71      if (ctx->Color.IndexMask != 0xffffffff) rasterMask |= MASKING_BIT;
72      if (ctx->Color.IndexLogicOpEnabled)     rasterMask |= LOGIC_OP_BIT;
73   }
74
75   if (   ctx->Viewport.X < 0
76       || ctx->Viewport.X + ctx->Viewport.Width > (GLint) ctx->DrawBuffer->Width
77       || ctx->Viewport.Y < 0
78       || ctx->Viewport.Y + ctx->Viewport.Height > (GLint) ctx->DrawBuffer->Height) {
79      rasterMask |= CLIP_BIT;
80   }
81
82   if (ctx->Query.CurrentOcclusionObject)
83      rasterMask |= OCCLUSION_BIT;
84
85
86   /* If we're not drawing to exactly one color buffer set the
87    * MULTI_DRAW_BIT flag.  Also set it if we're drawing to no
88    * buffers or the RGBA or CI mask disables all writes.
89    */
90   if (ctx->DrawBuffer->_NumColorDrawBuffers[0] != 1) {
91      /* more than one color buffer designated for writing (or zero buffers) */
92      rasterMask |= MULTI_DRAW_BIT;
93   }
94   else if (ctx->Visual.rgbMode && *((GLuint *) ctx->Color.ColorMask) == 0) {
95      rasterMask |= MULTI_DRAW_BIT; /* all RGBA channels disabled */
96   }
97   else if (!ctx->Visual.rgbMode && ctx->Color.IndexMask==0) {
98      rasterMask |= MULTI_DRAW_BIT; /* all color index bits disabled */
99   }
100
101   if (ctx->FragmentProgram._Current) {
102      rasterMask |= FRAGPROG_BIT;
103   }
104
105   if (ctx->ATIFragmentShader._Enabled) {
106      rasterMask |= ATIFRAGSHADER_BIT;
107   }
108
109#if CHAN_TYPE == GL_FLOAT
110   if (ctx->Color.ClampFragmentColor == GL_TRUE) {
111      rasterMask |= CLAMPING_BIT;
112   }
113#endif
114
115   SWRAST_CONTEXT(ctx)->_RasterMask = rasterMask;
116}
117
118
119/**
120 * Examine polycon culls tate to compute the _BackfaceSign field.
121 * _BackfaceSign will be 0 if no culling, -1 if culling back-faces,
122 * and 1 if culling front-faces.  The Polygon FrontFace state also
123 * factors in.
124 */
125static void
126_swrast_update_polygon( GLcontext *ctx )
127{
128   GLfloat backface_sign;
129
130   if (ctx->Polygon.CullFlag) {
131      backface_sign = 1.0;
132      switch (ctx->Polygon.CullFaceMode) {
133      case GL_BACK:
134	 if (ctx->Polygon.FrontFace == GL_CCW)
135	    backface_sign = -1.0;
136	 break;
137      case GL_FRONT:
138	 if (ctx->Polygon.FrontFace != GL_CCW)
139	    backface_sign = -1.0;
140	 break;
141      case GL_FRONT_AND_BACK:
142         /* fallthrough */
143      default:
144	 backface_sign = 0.0;
145	 break;
146      }
147   }
148   else {
149      backface_sign = 0.0;
150   }
151
152   SWRAST_CONTEXT(ctx)->_BackfaceSign = backface_sign;
153}
154
155
156/**
157 * Update the _PreferPixelFog field to indicate if we need to compute
158 * fog factors per-fragment.
159 */
160static void
161_swrast_update_fog_hint( GLcontext *ctx )
162{
163   SWcontext *swrast = SWRAST_CONTEXT(ctx);
164   swrast->_PreferPixelFog = (!swrast->AllowVertexFog ||
165                              ctx->FragmentProgram._Current ||
166			      (ctx->Hint.Fog == GL_NICEST &&
167			       swrast->AllowPixelFog));
168}
169
170
171
172/**
173 * Update the swrast->_AnyTextureCombine flag.
174 */
175static void
176_swrast_update_texture_env( GLcontext *ctx )
177{
178   SWcontext *swrast = SWRAST_CONTEXT(ctx);
179   GLuint i;
180   swrast->_AnyTextureCombine = GL_FALSE;
181   for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
182      if (ctx->Texture.Unit[i].EnvMode == GL_COMBINE_EXT ||
183          ctx->Texture.Unit[i].EnvMode == GL_COMBINE4_NV) {
184         swrast->_AnyTextureCombine = GL_TRUE;
185         return;
186      }
187   }
188}
189
190
191/**
192 * Update swrast->_FogColor and swrast->_FogEnable values.
193 */
194static void
195_swrast_update_fog_state( GLcontext *ctx )
196{
197   SWcontext *swrast = SWRAST_CONTEXT(ctx);
198   const struct gl_fragment_program *fp = ctx->FragmentProgram._Current;
199
200   /* determine if fog is needed, and if so, which fog mode */
201   swrast->_FogEnabled = GL_FALSE;
202   if (fp && fp->Base.Target == GL_FRAGMENT_PROGRAM_ARB) {
203      if (fp->FogOption != GL_NONE) {
204         swrast->_FogEnabled = GL_TRUE;
205         swrast->_FogMode = fp->FogOption;
206      }
207   }
208   else if (ctx->Fog.Enabled) {
209      swrast->_FogEnabled = GL_TRUE;
210      swrast->_FogMode = ctx->Fog.Mode;
211   }
212}
213
214
215/**
216 * Update state for running fragment programs.  Basically, load the
217 * program parameters with current state values.
218 */
219static void
220_swrast_update_fragment_program(GLcontext *ctx, GLbitfield newState)
221{
222   const struct gl_fragment_program *fp = ctx->FragmentProgram._Current;
223   if (fp) {
224#if 0
225      /* XXX Need a way to trigger the initial loading of parameters
226       * even when there's no recent state changes.
227       */
228      if (fp->Base.Parameters->StateFlags & newState)
229#endif
230         _mesa_load_state_parameters(ctx, fp->Base.Parameters);
231   }
232}
233
234
235
236#define _SWRAST_NEW_DERIVED (_SWRAST_NEW_RASTERMASK |	\
237			     _NEW_TEXTURE |		\
238			     _NEW_HINT |		\
239			     _NEW_POLYGON )
240
241/* State referenced by _swrast_choose_triangle, _swrast_choose_line.
242 */
243#define _SWRAST_NEW_TRIANGLE (_SWRAST_NEW_DERIVED |		\
244			      _NEW_RENDERMODE|			\
245                              _NEW_POLYGON|			\
246                              _NEW_DEPTH|			\
247                              _NEW_STENCIL|			\
248                              _NEW_COLOR|			\
249                              _NEW_TEXTURE|			\
250                              _SWRAST_NEW_RASTERMASK|		\
251                              _NEW_LIGHT|			\
252                              _NEW_FOG |			\
253			      _DD_NEW_SEPARATE_SPECULAR)
254
255#define _SWRAST_NEW_LINE (_SWRAST_NEW_DERIVED |		\
256			  _NEW_RENDERMODE|		\
257                          _NEW_LINE|			\
258                          _NEW_TEXTURE|			\
259                          _NEW_LIGHT|			\
260                          _NEW_FOG|			\
261                          _NEW_DEPTH |			\
262                          _DD_NEW_SEPARATE_SPECULAR)
263
264#define _SWRAST_NEW_POINT (_SWRAST_NEW_DERIVED |	\
265			   _NEW_RENDERMODE |		\
266			   _NEW_POINT |			\
267			   _NEW_TEXTURE |		\
268			   _NEW_LIGHT |			\
269			   _NEW_FOG |			\
270                           _DD_NEW_SEPARATE_SPECULAR)
271
272#define _SWRAST_NEW_TEXTURE_SAMPLE_FUNC _NEW_TEXTURE
273
274#define _SWRAST_NEW_TEXTURE_ENV_MODE _NEW_TEXTURE
275
276#define _SWRAST_NEW_BLEND_FUNC _NEW_COLOR
277
278
279
280/**
281 * Stub for swrast->Triangle to select a true triangle function
282 * after a state change.
283 */
284static void
285_swrast_validate_triangle( GLcontext *ctx,
286			   const SWvertex *v0,
287                           const SWvertex *v1,
288                           const SWvertex *v2 )
289{
290   SWcontext *swrast = SWRAST_CONTEXT(ctx);
291
292   _swrast_validate_derived( ctx );
293   swrast->choose_triangle( ctx );
294   ASSERT(swrast->Triangle);
295
296   if (ctx->Texture._EnabledUnits == 0
297       && NEED_SECONDARY_COLOR(ctx)
298       && !ctx->FragmentProgram._Current) {
299      /* separate specular color, but no texture */
300      swrast->SpecTriangle = swrast->Triangle;
301      swrast->Triangle = _swrast_add_spec_terms_triangle;
302   }
303
304   swrast->Triangle( ctx, v0, v1, v2 );
305}
306
307/**
308 * Called via swrast->Line.  Examine current GL state and choose a software
309 * line routine.  Then call it.
310 */
311static void
312_swrast_validate_line( GLcontext *ctx, const SWvertex *v0, const SWvertex *v1 )
313{
314   SWcontext *swrast = SWRAST_CONTEXT(ctx);
315
316   _swrast_validate_derived( ctx );
317   swrast->choose_line( ctx );
318   ASSERT(swrast->Line);
319
320   if (ctx->Texture._EnabledUnits == 0
321       && NEED_SECONDARY_COLOR(ctx)
322       && !ctx->FragmentProgram._Current) {
323      swrast->SpecLine = swrast->Line;
324      swrast->Line = _swrast_add_spec_terms_line;
325   }
326
327
328   swrast->Line( ctx, v0, v1 );
329}
330
331/**
332 * Called via swrast->Point.  Examine current GL state and choose a software
333 * point routine.  Then call it.
334 */
335static void
336_swrast_validate_point( GLcontext *ctx, const SWvertex *v0 )
337{
338   SWcontext *swrast = SWRAST_CONTEXT(ctx);
339
340   _swrast_validate_derived( ctx );
341   swrast->choose_point( ctx );
342
343   if (ctx->Texture._EnabledUnits == 0
344       && NEED_SECONDARY_COLOR(ctx)
345       && !ctx->FragmentProgram._Current) {
346      swrast->SpecPoint = swrast->Point;
347      swrast->Point = _swrast_add_spec_terms_point;
348   }
349
350   swrast->Point( ctx, v0 );
351}
352
353
354/**
355 * Called via swrast->BlendFunc.  Examine GL state to choose a blending
356 * function, then call it.
357 */
358static void _ASMAPI
359_swrast_validate_blend_func(GLcontext *ctx, GLuint n, const GLubyte mask[],
360                            GLvoid *src, const GLvoid *dst,
361                            GLenum chanType )
362{
363   SWcontext *swrast = SWRAST_CONTEXT(ctx);
364
365   _swrast_validate_derived( ctx ); /* why is this needed? */
366   _swrast_choose_blend_func( ctx, chanType );
367
368   swrast->BlendFunc( ctx, n, mask, src, dst, chanType );
369}
370
371
372/**
373 * Make sure we have texture image data for all the textures we may need
374 * for subsequent rendering.
375 */
376static void
377_swrast_validate_texture_images(GLcontext *ctx)
378{
379   SWcontext *swrast = SWRAST_CONTEXT(ctx);
380   GLuint u;
381
382   if (!swrast->ValidateTextureImage || !ctx->Texture._EnabledUnits) {
383      /* no textures enabled, or no way to validate images! */
384      return;
385   }
386
387   for (u = 0; u < ctx->Const.MaxTextureImageUnits; u++) {
388      if (ctx->Texture.Unit[u]._ReallyEnabled) {
389         struct gl_texture_object *texObj = ctx->Texture.Unit[u]._Current;
390         ASSERT(texObj);
391         if (texObj) {
392            GLuint numFaces = (texObj->Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
393            GLuint face;
394            for (face = 0; face < numFaces; face++) {
395               GLint lvl;
396               for (lvl = texObj->BaseLevel; lvl <= texObj->_MaxLevel; lvl++) {
397                  struct gl_texture_image *texImg = texObj->Image[face][lvl];
398                  if (texImg && !texImg->Data) {
399                     swrast->ValidateTextureImage(ctx, texObj, face, lvl);
400                     ASSERT(texObj->Image[face][lvl]->Data);
401                  }
402               }
403            }
404         }
405      }
406   }
407}
408
409
410/**
411 * Free the texture image data attached to all currently enabled
412 * textures.  Meant to be called by device drivers when transitioning
413 * from software to hardware rendering.
414 */
415void
416_swrast_eject_texture_images(GLcontext *ctx)
417{
418   GLuint u;
419
420   if (!ctx->Texture._EnabledUnits) {
421      /* no textures enabled */
422      return;
423   }
424
425   for (u = 0; u < ctx->Const.MaxTextureImageUnits; u++) {
426      if (ctx->Texture.Unit[u]._ReallyEnabled) {
427         struct gl_texture_object *texObj = ctx->Texture.Unit[u]._Current;
428         ASSERT(texObj);
429         if (texObj) {
430            GLuint numFaces = (texObj->Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
431            GLuint face;
432            for (face = 0; face < numFaces; face++) {
433               GLint lvl;
434               for (lvl = texObj->BaseLevel; lvl <= texObj->_MaxLevel; lvl++) {
435                  struct gl_texture_image *texImg = texObj->Image[face][lvl];
436                  if (texImg && texImg->Data) {
437                     _mesa_free_texmemory(texImg->Data);
438                     texImg->Data = NULL;
439                  }
440               }
441            }
442         }
443      }
444   }
445}
446
447
448
449static void
450_swrast_sleep( GLcontext *ctx, GLbitfield new_state )
451{
452   (void) ctx; (void) new_state;
453}
454
455
456static void
457_swrast_invalidate_state( GLcontext *ctx, GLbitfield new_state )
458{
459   SWcontext *swrast = SWRAST_CONTEXT(ctx);
460   GLuint i;
461
462   swrast->NewState |= new_state;
463
464   /* After 10 statechanges without any swrast functions being called,
465    * put the module to sleep.
466    */
467   if (++swrast->StateChanges > 10) {
468      swrast->InvalidateState = _swrast_sleep;
469      swrast->NewState = ~0;
470      new_state = ~0;
471   }
472
473   if (new_state & swrast->InvalidateTriangleMask)
474      swrast->Triangle = _swrast_validate_triangle;
475
476   if (new_state & swrast->InvalidateLineMask)
477      swrast->Line = _swrast_validate_line;
478
479   if (new_state & swrast->InvalidatePointMask)
480      swrast->Point = _swrast_validate_point;
481
482   if (new_state & _SWRAST_NEW_BLEND_FUNC)
483      swrast->BlendFunc = _swrast_validate_blend_func;
484
485   if (new_state & _SWRAST_NEW_TEXTURE_SAMPLE_FUNC)
486      for (i = 0 ; i < ctx->Const.MaxTextureImageUnits ; i++)
487	 swrast->TextureSample[i] = NULL;
488}
489
490
491static void
492_swrast_update_texture_samplers(GLcontext *ctx)
493{
494   SWcontext *swrast = SWRAST_CONTEXT(ctx);
495   GLuint u;
496
497   for (u = 0; u < ctx->Const.MaxTextureImageUnits; u++) {
498      const struct gl_texture_object *tObj = ctx->Texture.Unit[u]._Current;
499      /* Note: If tObj is NULL, the sample function will be a simple
500       * function that just returns opaque black (0,0,0,1).
501       */
502      swrast->TextureSample[u] = _swrast_choose_texture_sample_func(ctx, tObj);
503   }
504}
505
506
507/**
508 * Update the swrast->_FragmentAttribs field.
509 */
510static void
511_swrast_update_fragment_attribs(GLcontext *ctx)
512{
513   SWcontext *swrast = SWRAST_CONTEXT(ctx);
514
515   if (ctx->FragmentProgram._Current) {
516      swrast->_FragmentAttribs
517         = ctx->FragmentProgram._Current->Base.InputsRead;
518   }
519   else {
520      GLuint u;
521      swrast->_FragmentAttribs = 0x0;
522
523      if (ctx->Depth.Test)
524         swrast->_FragmentAttribs |= FRAG_BIT_WPOS;
525      if (NEED_SECONDARY_COLOR(ctx))
526         swrast->_FragmentAttribs |= FRAG_BIT_COL1;
527      if (swrast->_FogEnabled)
528         swrast->_FragmentAttribs |= FRAG_BIT_FOGC;
529
530      for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
531         if (ctx->Texture.Unit[u]._ReallyEnabled) {
532            swrast->_FragmentAttribs |= FRAG_BIT_TEX(u);
533         }
534      }
535   }
536
537   /* Find lowest, highest bit set in _FragmentAttribs */
538   {
539      GLuint bits = swrast->_FragmentAttribs;
540      GLuint i = 0;;
541      while (bits) {
542         i++;
543         bits = bits >> 1;
544      }
545      swrast->_MaxFragmentAttrib = i;
546      swrast->_MinFragmentAttrib = FRAG_ATTRIB_TEX0; /* XXX temporary */
547   }
548}
549
550
551/**
552 * Update the swrast->_ColorOutputsMask which indicates which color
553 * renderbuffers (aka rendertargets) are being written to by the current
554 * fragment program.
555 * We also take glDrawBuffers() into account to skip outputs that are
556 * set to GL_NONE.
557 */
558static void
559_swrast_update_color_outputs(GLcontext *ctx)
560{
561   SWcontext *swrast = SWRAST_CONTEXT(ctx);
562   const struct gl_framebuffer *fb = ctx->DrawBuffer;
563
564   swrast->_ColorOutputsMask = 0;
565   swrast->_NumColorOutputs = 0;
566
567   if (ctx->FragmentProgram._Current) {
568      const GLbitfield outputsWritten
569         = ctx->FragmentProgram._Current->Base.OutputsWritten;
570      GLuint output;
571      for (output = 0; output < ctx->Const.MaxDrawBuffers; output++) {
572         if ((outputsWritten & (1 << (FRAG_RESULT_DATA0 + output)))
573             && (fb->_NumColorDrawBuffers[output] > 0)) {
574            swrast->_ColorOutputsMask |= (1 << output);
575            swrast->_NumColorOutputs = output + 1;
576         }
577      }
578   }
579   if (swrast->_ColorOutputsMask == 0x0) {
580      /* no fragment program, or frag prog didn't write to gl_FragData[] */
581      if (fb->_NumColorDrawBuffers[0] > 0) {
582         swrast->_ColorOutputsMask = 0x1;
583         swrast->_NumColorOutputs = 1;
584      }
585   }
586}
587
588
589void
590_swrast_validate_derived( GLcontext *ctx )
591{
592   SWcontext *swrast = SWRAST_CONTEXT(ctx);
593
594   if (swrast->NewState) {
595      if (swrast->NewState & _NEW_POLYGON)
596	 _swrast_update_polygon( ctx );
597
598      if (swrast->NewState & (_NEW_HINT | _NEW_PROGRAM))
599	 _swrast_update_fog_hint( ctx );
600
601      if (swrast->NewState & _SWRAST_NEW_TEXTURE_ENV_MODE)
602	 _swrast_update_texture_env( ctx );
603
604      if (swrast->NewState & (_NEW_FOG | _NEW_PROGRAM))
605         _swrast_update_fog_state( ctx );
606
607      if (swrast->NewState & (_NEW_MODELVIEW |
608                              _NEW_PROJECTION |
609                              _NEW_TEXTURE_MATRIX |
610                              _NEW_FOG |
611                              _NEW_LIGHT |
612                              _NEW_LINE |
613                              _NEW_TEXTURE |
614                              _NEW_TRANSFORM |
615                              _NEW_POINT |
616                              _NEW_VIEWPORT |
617                              _NEW_PROGRAM))
618	 _swrast_update_fragment_program( ctx, swrast->NewState );
619
620      if (swrast->NewState & _NEW_TEXTURE)
621         _swrast_update_texture_samplers( ctx );
622
623      if (swrast->NewState & (_NEW_TEXTURE | _NEW_PROGRAM))
624         _swrast_validate_texture_images( ctx );
625
626      if (swrast->NewState & _SWRAST_NEW_RASTERMASK)
627 	 _swrast_update_rasterflags( ctx );
628
629      if (swrast->NewState & (_NEW_DEPTH |
630                              _NEW_FOG |
631                              _NEW_PROGRAM |
632                              _NEW_TEXTURE))
633         _swrast_update_fragment_attribs(ctx);
634
635      if (swrast->NewState & (_NEW_PROGRAM | _NEW_BUFFERS))
636         _swrast_update_color_outputs(ctx);
637
638      swrast->NewState = 0;
639      swrast->StateChanges = 0;
640      swrast->InvalidateState = _swrast_invalidate_state;
641   }
642}
643
644#define SWRAST_DEBUG 0
645
646/* Public entrypoints:  See also s_accum.c, s_bitmap.c, etc.
647 */
648void
649_swrast_Quad( GLcontext *ctx,
650	      const SWvertex *v0, const SWvertex *v1,
651              const SWvertex *v2, const SWvertex *v3 )
652{
653   if (SWRAST_DEBUG) {
654      _mesa_debug(ctx, "_swrast_Quad\n");
655      _swrast_print_vertex( ctx, v0 );
656      _swrast_print_vertex( ctx, v1 );
657      _swrast_print_vertex( ctx, v2 );
658      _swrast_print_vertex( ctx, v3 );
659   }
660   SWRAST_CONTEXT(ctx)->Triangle( ctx, v0, v1, v3 );
661   SWRAST_CONTEXT(ctx)->Triangle( ctx, v1, v2, v3 );
662}
663
664void
665_swrast_Triangle( GLcontext *ctx, const SWvertex *v0,
666                  const SWvertex *v1, const SWvertex *v2 )
667{
668   if (SWRAST_DEBUG) {
669      _mesa_debug(ctx, "_swrast_Triangle\n");
670      _swrast_print_vertex( ctx, v0 );
671      _swrast_print_vertex( ctx, v1 );
672      _swrast_print_vertex( ctx, v2 );
673   }
674   SWRAST_CONTEXT(ctx)->Triangle( ctx, v0, v1, v2 );
675}
676
677void
678_swrast_Line( GLcontext *ctx, const SWvertex *v0, const SWvertex *v1 )
679{
680   if (SWRAST_DEBUG) {
681      _mesa_debug(ctx, "_swrast_Line\n");
682      _swrast_print_vertex( ctx, v0 );
683      _swrast_print_vertex( ctx, v1 );
684   }
685   SWRAST_CONTEXT(ctx)->Line( ctx, v0, v1 );
686}
687
688void
689_swrast_Point( GLcontext *ctx, const SWvertex *v0 )
690{
691   if (SWRAST_DEBUG) {
692      _mesa_debug(ctx, "_swrast_Point\n");
693      _swrast_print_vertex( ctx, v0 );
694   }
695   SWRAST_CONTEXT(ctx)->Point( ctx, v0 );
696}
697
698void
699_swrast_InvalidateState( GLcontext *ctx, GLbitfield new_state )
700{
701   if (SWRAST_DEBUG) {
702      _mesa_debug(ctx, "_swrast_InvalidateState\n");
703   }
704   SWRAST_CONTEXT(ctx)->InvalidateState( ctx, new_state );
705}
706
707void
708_swrast_ResetLineStipple( GLcontext *ctx )
709{
710   if (SWRAST_DEBUG) {
711      _mesa_debug(ctx, "_swrast_ResetLineStipple\n");
712   }
713   SWRAST_CONTEXT(ctx)->StippleCounter = 0;
714}
715
716void
717_swrast_allow_vertex_fog( GLcontext *ctx, GLboolean value )
718{
719   if (SWRAST_DEBUG) {
720      _mesa_debug(ctx, "_swrast_allow_vertex_fog %d\n", value);
721   }
722   SWRAST_CONTEXT(ctx)->InvalidateState( ctx, _NEW_HINT );
723   SWRAST_CONTEXT(ctx)->AllowVertexFog = value;
724}
725
726void
727_swrast_allow_pixel_fog( GLcontext *ctx, GLboolean value )
728{
729   if (SWRAST_DEBUG) {
730      _mesa_debug(ctx, "_swrast_allow_pixel_fog %d\n", value);
731   }
732   SWRAST_CONTEXT(ctx)->InvalidateState( ctx, _NEW_HINT );
733   SWRAST_CONTEXT(ctx)->AllowPixelFog = value;
734}
735
736
737GLboolean
738_swrast_CreateContext( GLcontext *ctx )
739{
740   GLuint i;
741   SWcontext *swrast = (SWcontext *)CALLOC(sizeof(SWcontext));
742
743   if (SWRAST_DEBUG) {
744      _mesa_debug(ctx, "_swrast_CreateContext\n");
745   }
746
747   if (!swrast)
748      return GL_FALSE;
749
750   swrast->NewState = ~0;
751
752   swrast->choose_point = _swrast_choose_point;
753   swrast->choose_line = _swrast_choose_line;
754   swrast->choose_triangle = _swrast_choose_triangle;
755
756   swrast->InvalidatePointMask = _SWRAST_NEW_POINT;
757   swrast->InvalidateLineMask = _SWRAST_NEW_LINE;
758   swrast->InvalidateTriangleMask = _SWRAST_NEW_TRIANGLE;
759
760   swrast->Point = _swrast_validate_point;
761   swrast->Line = _swrast_validate_line;
762   swrast->Triangle = _swrast_validate_triangle;
763   swrast->InvalidateState = _swrast_sleep;
764   swrast->BlendFunc = _swrast_validate_blend_func;
765
766   swrast->AllowVertexFog = GL_TRUE;
767   swrast->AllowPixelFog = GL_TRUE;
768
769   /* Optimized Accum buffer */
770   swrast->_IntegerAccumMode = GL_FALSE;
771   swrast->_IntegerAccumScaler = 0.0;
772
773   for (i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++)
774      swrast->TextureSample[i] = NULL;
775
776   swrast->SpanArrays = MALLOC_STRUCT(sw_span_arrays);
777   if (!swrast->SpanArrays) {
778      FREE(swrast);
779      return GL_FALSE;
780   }
781   swrast->SpanArrays->ChanType = CHAN_TYPE;
782#if CHAN_TYPE == GL_UNSIGNED_BYTE
783   swrast->SpanArrays->rgba = swrast->SpanArrays->color.sz1.rgba;
784   swrast->SpanArrays->spec = swrast->SpanArrays->color.sz1.spec;
785#elif CHAN_TYPE == GL_UNSIGNED_SHORT
786   swrast->SpanArrays->rgba = swrast->SpanArrays->color.sz2.rgba;
787   swrast->SpanArrays->spec = swrast->SpanArrays->color.sz2.spec;
788#else
789   swrast->SpanArrays->rgba = swrast->SpanArrays->color.sz4.rgba;
790   swrast->SpanArrays->spec = swrast->SpanArrays->color.sz4.spec;
791#endif
792
793   /* init point span buffer */
794   swrast->PointSpan.primitive = GL_POINT;
795   swrast->PointSpan.end = 0;
796   swrast->PointSpan.facing = 0;
797   swrast->PointSpan.array = swrast->SpanArrays;
798
799   swrast->TexelBuffer = (GLchan *) MALLOC(ctx->Const.MaxTextureImageUnits *
800                                           MAX_WIDTH * 4 * sizeof(GLchan));
801   if (!swrast->TexelBuffer) {
802      FREE(swrast->SpanArrays);
803      FREE(swrast);
804      return GL_FALSE;
805   }
806
807   ctx->swrast_context = swrast;
808
809   return GL_TRUE;
810}
811
812void
813_swrast_DestroyContext( GLcontext *ctx )
814{
815   SWcontext *swrast = SWRAST_CONTEXT(ctx);
816
817   if (SWRAST_DEBUG) {
818      _mesa_debug(ctx, "_swrast_DestroyContext\n");
819   }
820
821   FREE( swrast->SpanArrays );
822   FREE( swrast->TexelBuffer );
823   FREE( swrast );
824
825   ctx->swrast_context = 0;
826}
827
828
829struct swrast_device_driver *
830_swrast_GetDeviceDriverReference( GLcontext *ctx )
831{
832   SWcontext *swrast = SWRAST_CONTEXT(ctx);
833   return &swrast->Driver;
834}
835
836void
837_swrast_flush( GLcontext *ctx )
838{
839   SWcontext *swrast = SWRAST_CONTEXT(ctx);
840   /* flush any pending fragments from rendering points */
841   if (swrast->PointSpan.end > 0) {
842      if (ctx->Visual.rgbMode) {
843         _swrast_write_rgba_span(ctx, &(swrast->PointSpan));
844      }
845      else {
846         _swrast_write_index_span(ctx, &(swrast->PointSpan));
847      }
848      swrast->PointSpan.end = 0;
849   }
850}
851
852void
853_swrast_render_primitive( GLcontext *ctx, GLenum prim )
854{
855   SWcontext *swrast = SWRAST_CONTEXT(ctx);
856   if (swrast->Primitive == GL_POINTS && prim != GL_POINTS) {
857      _swrast_flush(ctx);
858   }
859   swrast->Primitive = prim;
860}
861
862
863void
864_swrast_render_start( GLcontext *ctx )
865{
866   SWcontext *swrast = SWRAST_CONTEXT(ctx);
867   if (swrast->Driver.SpanRenderStart)
868      swrast->Driver.SpanRenderStart( ctx );
869   swrast->PointSpan.end = 0;
870}
871
872void
873_swrast_render_finish( GLcontext *ctx )
874{
875   SWcontext *swrast = SWRAST_CONTEXT(ctx);
876   if (swrast->Driver.SpanRenderFinish)
877      swrast->Driver.SpanRenderFinish( ctx );
878
879   _swrast_flush(ctx);
880}
881
882
883#define SWRAST_DEBUG_VERTICES 0
884
885void
886_swrast_print_vertex( GLcontext *ctx, const SWvertex *v )
887{
888   GLuint i;
889
890   if (SWRAST_DEBUG_VERTICES) {
891      _mesa_debug(ctx, "win %f %f %f %f\n",
892                  v->win[0], v->win[1], v->win[2], v->win[3]);
893
894      for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++)
895	 if (ctx->Texture.Unit[i]._ReallyEnabled)
896	    _mesa_debug(ctx, "texcoord[%d] %f %f %f %f\n", i,
897                        v->attrib[FRAG_ATTRIB_TEX0 + i][0],
898                        v->attrib[FRAG_ATTRIB_TEX0 + i][1],
899                        v->attrib[FRAG_ATTRIB_TEX0 + i][2],
900                        v->attrib[FRAG_ATTRIB_TEX0 + i][3]);
901
902#if CHAN_TYPE == GL_FLOAT
903      _mesa_debug(ctx, "color %f %f %f %f\n",
904                  v->color[0], v->color[1], v->color[2], v->color[3]);
905      _mesa_debug(ctx, "spec %f %f %f %f\n",
906                  v->specular[0], v->specular[1],
907                  v->specular[2], v->specular[3]);
908#else
909      _mesa_debug(ctx, "color %d %d %d %d\n",
910                  v->color[0], v->color[1], v->color[2], v->color[3]);
911      _mesa_debug(ctx, "spec %d %d %d %d\n",
912                  v->specular[0], v->specular[1],
913                  v->specular[2], v->specular[3]);
914#endif
915      _mesa_debug(ctx, "fog %f\n", v->fog);
916      _mesa_debug(ctx, "index %d\n", v->index);
917      _mesa_debug(ctx, "pointsize %f\n", v->pointSize);
918      _mesa_debug(ctx, "\n");
919   }
920}
921