s_context.c revision 848b8605
1/*
2 * Mesa 3-D graphics library
3 *
4 * Copyright (C) 1999-2008  Brian Paul   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 "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
23 *
24 * Authors:
25 *    Keith Whitwell <keithw@vmware.com> Brian Paul
26 */
27
28#include "main/imports.h"
29#include "main/bufferobj.h"
30#include "main/colormac.h"
31#include "main/mtypes.h"
32#include "main/samplerobj.h"
33#include "main/teximage.h"
34#include "program/prog_parameter.h"
35#include "program/prog_statevars.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_texfetch.h"
43#include "s_triangle.h"
44#include "s_texfilter.h"
45
46
47/**
48 * Recompute the value of swrast->_RasterMask, etc. according to
49 * the current context.  The _RasterMask field can be easily tested by
50 * drivers to determine certain basic GL state (does the primitive need
51 * stenciling, logic-op, fog, etc?).
52 */
53static void
54_swrast_update_rasterflags( struct gl_context *ctx )
55{
56   SWcontext *swrast = SWRAST_CONTEXT(ctx);
57   GLbitfield rasterMask = 0;
58   GLuint i;
59
60   if (ctx->Color.AlphaEnabled)           rasterMask |= ALPHATEST_BIT;
61   if (ctx->Color.BlendEnabled)           rasterMask |= BLEND_BIT;
62   if (ctx->Depth.Test)                   rasterMask |= DEPTH_BIT;
63   if (swrast->_FogEnabled)               rasterMask |= FOG_BIT;
64   if (ctx->Scissor.EnableFlags)          rasterMask |= CLIP_BIT;
65   if (ctx->Stencil._Enabled)             rasterMask |= STENCIL_BIT;
66   for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) {
67      if (!ctx->Color.ColorMask[i][0] ||
68          !ctx->Color.ColorMask[i][1] ||
69          !ctx->Color.ColorMask[i][2] ||
70          !ctx->Color.ColorMask[i][3]) {
71         rasterMask |= MASKING_BIT;
72         break;
73      }
74   }
75   if (ctx->Color.ColorLogicOpEnabled) rasterMask |= LOGIC_OP_BIT;
76   if (ctx->Texture._MaxEnabledTexImageUnit >= 0) rasterMask |= TEXTURE_BIT;
77   if (   ctx->ViewportArray[0].X < 0
78       || ctx->ViewportArray[0].X + ctx->ViewportArray[0].Width > (GLfloat) ctx->DrawBuffer->Width
79       || ctx->ViewportArray[0].Y < 0
80       || ctx->ViewportArray[0].Y + ctx->ViewportArray[0].Height > (GLfloat) ctx->DrawBuffer->Height) {
81      rasterMask |= CLIP_BIT;
82   }
83
84   if (ctx->Query.CurrentOcclusionObject)
85      rasterMask |= OCCLUSION_BIT;
86
87
88   /* If we're not drawing to exactly one color buffer set the
89    * MULTI_DRAW_BIT flag.  Also set it if we're drawing to no
90    * buffers or the RGBA or CI mask disables all writes.
91    */
92   if (ctx->DrawBuffer->_NumColorDrawBuffers != 1) {
93      /* more than one color buffer designated for writing (or zero buffers) */
94      rasterMask |= MULTI_DRAW_BIT;
95   }
96
97   for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) {
98      if (ctx->Color.ColorMask[i][0] +
99          ctx->Color.ColorMask[i][1] +
100          ctx->Color.ColorMask[i][2] +
101          ctx->Color.ColorMask[i][3] == 0) {
102         rasterMask |= MULTI_DRAW_BIT; /* all RGBA channels disabled */
103         break;
104      }
105   }
106
107
108   if (_swrast_use_fragment_program(ctx)) {
109      rasterMask |= FRAGPROG_BIT;
110   }
111
112   if (ctx->ATIFragmentShader._Enabled) {
113      rasterMask |= ATIFRAGSHADER_BIT;
114   }
115
116#if CHAN_TYPE == GL_FLOAT
117   if (ctx->Color.ClampFragmentColor == GL_TRUE) {
118      rasterMask |= CLAMPING_BIT;
119   }
120#endif
121
122   SWRAST_CONTEXT(ctx)->_RasterMask = rasterMask;
123}
124
125
126/**
127 * Examine polygon cull state to compute the _BackfaceCullSign field.
128 * _BackfaceCullSign will be 0 if no culling, -1 if culling back-faces,
129 * and 1 if culling front-faces.  The Polygon FrontFace state also
130 * factors in.
131 */
132static void
133_swrast_update_polygon( struct gl_context *ctx )
134{
135   GLfloat backface_sign;
136
137   if (ctx->Polygon.CullFlag) {
138      switch (ctx->Polygon.CullFaceMode) {
139      case GL_BACK:
140         backface_sign = -1.0F;
141	 break;
142      case GL_FRONT:
143         backface_sign = 1.0F;
144	 break;
145      case GL_FRONT_AND_BACK:
146         /* fallthrough */
147      default:
148	 backface_sign = 0.0F;
149      }
150   }
151   else {
152      backface_sign = 0.0F;
153   }
154
155   SWRAST_CONTEXT(ctx)->_BackfaceCullSign = backface_sign;
156
157   /* This is for front/back-face determination, but not for culling */
158   SWRAST_CONTEXT(ctx)->_BackfaceSign
159      = (ctx->Polygon.FrontFace == GL_CW) ? -1.0F : 1.0F;
160}
161
162
163
164/**
165 * Update the _PreferPixelFog field to indicate if we need to compute
166 * fog blend factors (from the fog coords) per-fragment.
167 */
168static void
169_swrast_update_fog_hint( struct gl_context *ctx )
170{
171   SWcontext *swrast = SWRAST_CONTEXT(ctx);
172   swrast->_PreferPixelFog = (!swrast->AllowVertexFog ||
173			      _swrast_use_fragment_program(ctx) ||
174			      (ctx->Hint.Fog == GL_NICEST &&
175			       swrast->AllowPixelFog));
176}
177
178
179
180/**
181 * Update the swrast->_TextureCombinePrimary flag.
182 */
183static void
184_swrast_update_texture_env( struct gl_context *ctx )
185{
186   SWcontext *swrast = SWRAST_CONTEXT(ctx);
187   GLuint i;
188
189   swrast->_TextureCombinePrimary = GL_FALSE;
190
191   for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
192      const struct gl_tex_env_combine_state *combine =
193         ctx->Texture.Unit[i]._CurrentCombine;
194      GLuint term;
195      for (term = 0; term < combine->_NumArgsRGB; term++) {
196         if (combine->SourceRGB[term] == GL_PRIMARY_COLOR) {
197            swrast->_TextureCombinePrimary = GL_TRUE;
198            return;
199         }
200         if (combine->SourceA[term] == GL_PRIMARY_COLOR) {
201            swrast->_TextureCombinePrimary = GL_TRUE;
202            return;
203         }
204      }
205   }
206}
207
208
209/**
210 * Determine if we can defer texturing/shading until after Z/stencil
211 * testing.  This potentially allows us to skip texturing/shading for
212 * lots of fragments.
213 */
214static void
215_swrast_update_deferred_texture(struct gl_context *ctx)
216{
217   SWcontext *swrast = SWRAST_CONTEXT(ctx);
218   if (ctx->Color.AlphaEnabled) {
219      /* alpha test depends on post-texture/shader colors */
220      swrast->_DeferredTexture = GL_FALSE;
221   }
222   else {
223      GLboolean use_fprog = _swrast_use_fragment_program(ctx);
224      const struct gl_fragment_program *fprog
225         = ctx->FragmentProgram._Current;
226      if (use_fprog && (fprog->Base.OutputsWritten & (1 << FRAG_RESULT_DEPTH))) {
227         /* Z comes from fragment program/shader */
228         swrast->_DeferredTexture = GL_FALSE;
229      }
230      else if (use_fprog && fprog->UsesKill) {
231         swrast->_DeferredTexture = GL_FALSE;
232      }
233      else if (ctx->Query.CurrentOcclusionObject) {
234         /* occlusion query depends on shader discard/kill results */
235         swrast->_DeferredTexture = GL_FALSE;
236      }
237      else {
238         swrast->_DeferredTexture = GL_TRUE;
239      }
240   }
241}
242
243
244/**
245 * Update swrast->_FogColor and swrast->_FogEnable values.
246 */
247static void
248_swrast_update_fog_state( struct gl_context *ctx )
249{
250   SWcontext *swrast = SWRAST_CONTEXT(ctx);
251   const struct gl_fragment_program *fp = ctx->FragmentProgram._Current;
252
253   assert(fp == NULL || fp->Base.Target == GL_FRAGMENT_PROGRAM_ARB);
254
255   /* determine if fog is needed, and if so, which fog mode */
256   swrast->_FogEnabled = (!_swrast_use_fragment_program(ctx) &&
257			  ctx->Fog.Enabled);
258}
259
260
261/**
262 * Update state for running fragment programs.  Basically, load the
263 * program parameters with current state values.
264 */
265static void
266_swrast_update_fragment_program(struct gl_context *ctx, GLbitfield newState)
267{
268   if (!_swrast_use_fragment_program(ctx))
269      return;
270
271   _mesa_load_state_parameters(ctx,
272                               ctx->FragmentProgram._Current->Base.Parameters);
273}
274
275
276/**
277 * See if we can do early diffuse+specular (primary+secondary) color
278 * add per vertex instead of per-fragment.
279 */
280static void
281_swrast_update_specular_vertex_add(struct gl_context *ctx)
282{
283   SWcontext *swrast = SWRAST_CONTEXT(ctx);
284   GLboolean separateSpecular = ctx->Fog.ColorSumEnabled ||
285      (ctx->Light.Enabled &&
286       ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR);
287
288   swrast->SpecularVertexAdd = (separateSpecular
289                                && ctx->Texture._MaxEnabledTexImageUnit == -1
290                                && !_swrast_use_fragment_program(ctx)
291                                && !ctx->ATIFragmentShader._Enabled);
292}
293
294
295#define _SWRAST_NEW_DERIVED (_SWRAST_NEW_RASTERMASK |	\
296                             _NEW_PROGRAM_CONSTANTS |   \
297			     _NEW_TEXTURE |		\
298			     _NEW_HINT |		\
299			     _NEW_POLYGON )
300
301/* State referenced by _swrast_choose_triangle, _swrast_choose_line.
302 */
303#define _SWRAST_NEW_TRIANGLE (_SWRAST_NEW_DERIVED |		\
304			      _NEW_RENDERMODE|			\
305                              _NEW_POLYGON|			\
306                              _NEW_DEPTH|			\
307                              _NEW_STENCIL|			\
308                              _NEW_COLOR|			\
309                              _NEW_TEXTURE|			\
310                              _SWRAST_NEW_RASTERMASK|		\
311                              _NEW_LIGHT|			\
312                              _NEW_FOG |			\
313			      _MESA_NEW_SEPARATE_SPECULAR)
314
315#define _SWRAST_NEW_LINE (_SWRAST_NEW_DERIVED |		\
316			  _NEW_RENDERMODE|		\
317                          _NEW_LINE|			\
318                          _NEW_TEXTURE|			\
319                          _NEW_LIGHT|			\
320                          _NEW_FOG|			\
321                          _NEW_DEPTH |			\
322                          _MESA_NEW_SEPARATE_SPECULAR)
323
324#define _SWRAST_NEW_POINT (_SWRAST_NEW_DERIVED |	\
325			   _NEW_RENDERMODE |		\
326			   _NEW_POINT |			\
327			   _NEW_TEXTURE |		\
328			   _NEW_LIGHT |			\
329			   _NEW_FOG |			\
330                           _MESA_NEW_SEPARATE_SPECULAR)
331
332#define _SWRAST_NEW_TEXTURE_SAMPLE_FUNC _NEW_TEXTURE
333
334#define _SWRAST_NEW_TEXTURE_ENV_MODE _NEW_TEXTURE
335
336#define _SWRAST_NEW_BLEND_FUNC _NEW_COLOR
337
338
339
340/**
341 * Stub for swrast->Triangle to select a true triangle function
342 * after a state change.
343 */
344static void
345_swrast_validate_triangle( struct gl_context *ctx,
346			   const SWvertex *v0,
347                           const SWvertex *v1,
348                           const SWvertex *v2 )
349{
350   SWcontext *swrast = SWRAST_CONTEXT(ctx);
351
352   _swrast_validate_derived( ctx );
353   swrast->choose_triangle( ctx );
354   ASSERT(swrast->Triangle);
355
356   if (swrast->SpecularVertexAdd) {
357      /* separate specular color, but no texture */
358      swrast->SpecTriangle = swrast->Triangle;
359      swrast->Triangle = _swrast_add_spec_terms_triangle;
360   }
361
362   swrast->Triangle( ctx, v0, v1, v2 );
363}
364
365/**
366 * Called via swrast->Line.  Examine current GL state and choose a software
367 * line routine.  Then call it.
368 */
369static void
370_swrast_validate_line( struct gl_context *ctx, const SWvertex *v0, const SWvertex *v1 )
371{
372   SWcontext *swrast = SWRAST_CONTEXT(ctx);
373
374   _swrast_validate_derived( ctx );
375   swrast->choose_line( ctx );
376   ASSERT(swrast->Line);
377
378   if (swrast->SpecularVertexAdd) {
379      swrast->SpecLine = swrast->Line;
380      swrast->Line = _swrast_add_spec_terms_line;
381   }
382
383   swrast->Line( ctx, v0, v1 );
384}
385
386/**
387 * Called via swrast->Point.  Examine current GL state and choose a software
388 * point routine.  Then call it.
389 */
390static void
391_swrast_validate_point( struct gl_context *ctx, const SWvertex *v0 )
392{
393   SWcontext *swrast = SWRAST_CONTEXT(ctx);
394
395   _swrast_validate_derived( ctx );
396   swrast->choose_point( ctx );
397
398   if (swrast->SpecularVertexAdd) {
399      swrast->SpecPoint = swrast->Point;
400      swrast->Point = _swrast_add_spec_terms_point;
401   }
402
403   swrast->Point( ctx, v0 );
404}
405
406
407/**
408 * Called via swrast->BlendFunc.  Examine GL state to choose a blending
409 * function, then call it.
410 */
411static void _ASMAPI
412_swrast_validate_blend_func(struct gl_context *ctx, GLuint n, const GLubyte mask[],
413                            GLvoid *src, const GLvoid *dst,
414                            GLenum chanType )
415{
416   SWcontext *swrast = SWRAST_CONTEXT(ctx);
417
418   _swrast_validate_derived( ctx ); /* why is this needed? */
419   _swrast_choose_blend_func( ctx, chanType );
420
421   swrast->BlendFunc( ctx, n, mask, src, dst, chanType );
422}
423
424static void
425_swrast_sleep( struct gl_context *ctx, GLbitfield new_state )
426{
427   (void) ctx; (void) new_state;
428}
429
430
431static void
432_swrast_invalidate_state( struct gl_context *ctx, GLbitfield new_state )
433{
434   SWcontext *swrast = SWRAST_CONTEXT(ctx);
435   GLuint i;
436
437   swrast->NewState |= new_state;
438
439   /* After 10 statechanges without any swrast functions being called,
440    * put the module to sleep.
441    */
442   if (++swrast->StateChanges > 10) {
443      swrast->InvalidateState = _swrast_sleep;
444      swrast->NewState = ~0;
445      new_state = ~0;
446   }
447
448   if (new_state & swrast->InvalidateTriangleMask)
449      swrast->Triangle = _swrast_validate_triangle;
450
451   if (new_state & swrast->InvalidateLineMask)
452      swrast->Line = _swrast_validate_line;
453
454   if (new_state & swrast->InvalidatePointMask)
455      swrast->Point = _swrast_validate_point;
456
457   if (new_state & _SWRAST_NEW_BLEND_FUNC)
458      swrast->BlendFunc = _swrast_validate_blend_func;
459
460   if (new_state & _SWRAST_NEW_TEXTURE_SAMPLE_FUNC)
461      for (i = 0 ; i < ARRAY_SIZE(swrast->TextureSample); i++)
462	 swrast->TextureSample[i] = NULL;
463}
464
465
466void
467_swrast_update_texture_samplers(struct gl_context *ctx)
468{
469   SWcontext *swrast = SWRAST_CONTEXT(ctx);
470   GLuint u;
471
472   if (!swrast)
473      return; /* pipe hack */
474
475   for (u = 0; u < ARRAY_SIZE(swrast->TextureSample); u++) {
476      struct gl_texture_object *tObj = ctx->Texture.Unit[u]._Current;
477      /* Note: If tObj is NULL, the sample function will be a simple
478       * function that just returns opaque black (0,0,0,1).
479       */
480      _mesa_update_fetch_functions(ctx, u);
481      swrast->TextureSample[u] =
482         _swrast_choose_texture_sample_func(ctx, tObj,
483                                            _mesa_get_samplerobj(ctx, u));
484   }
485}
486
487
488/**
489 * Update swrast->_ActiveAttribs, swrast->_NumActiveAttribs,
490 * swrast->_ActiveAtttribMask.
491 */
492static void
493_swrast_update_active_attribs(struct gl_context *ctx)
494{
495   SWcontext *swrast = SWRAST_CONTEXT(ctx);
496   GLbitfield64 attribsMask;
497
498   /*
499    * Compute _ActiveAttribsMask = which fragment attributes are needed.
500    */
501   if (_swrast_use_fragment_program(ctx)) {
502      /* fragment program/shader */
503      attribsMask = ctx->FragmentProgram._Current->Base.InputsRead;
504      attribsMask &= ~VARYING_BIT_POS; /* WPOS is always handled specially */
505   }
506   else if (ctx->ATIFragmentShader._Enabled) {
507      attribsMask = ~0;  /* XXX fix me */
508   }
509   else {
510      /* fixed function */
511      attribsMask = 0x0;
512
513#if CHAN_TYPE == GL_FLOAT
514      attribsMask |= VARYING_BIT_COL0;
515#endif
516
517      if (ctx->Fog.ColorSumEnabled ||
518          (ctx->Light.Enabled &&
519           ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)) {
520         attribsMask |= VARYING_BIT_COL1;
521      }
522
523      if (swrast->_FogEnabled)
524         attribsMask |= VARYING_BIT_FOGC;
525
526      attribsMask |= (ctx->Texture._EnabledCoordUnits << VARYING_SLOT_TEX0);
527   }
528
529   swrast->_ActiveAttribMask = attribsMask;
530
531   /* Update _ActiveAttribs[] list */
532   {
533      GLuint i, num = 0;
534      for (i = 0; i < VARYING_SLOT_MAX; i++) {
535         if (attribsMask & BITFIELD64_BIT(i)) {
536            swrast->_ActiveAttribs[num++] = i;
537            /* how should this attribute be interpolated? */
538            if (i == VARYING_SLOT_COL0 || i == VARYING_SLOT_COL1)
539               swrast->_InterpMode[i] = ctx->Light.ShadeModel;
540            else
541               swrast->_InterpMode[i] = GL_SMOOTH;
542         }
543      }
544      swrast->_NumActiveAttribs = num;
545   }
546}
547
548
549void
550_swrast_validate_derived( struct gl_context *ctx )
551{
552   SWcontext *swrast = SWRAST_CONTEXT(ctx);
553
554   if (swrast->NewState) {
555      if (swrast->NewState & _NEW_POLYGON)
556	 _swrast_update_polygon( ctx );
557
558      if (swrast->NewState & (_NEW_HINT | _NEW_PROGRAM))
559	 _swrast_update_fog_hint( ctx );
560
561      if (swrast->NewState & _SWRAST_NEW_TEXTURE_ENV_MODE)
562	 _swrast_update_texture_env( ctx );
563
564      if (swrast->NewState & (_NEW_FOG | _NEW_PROGRAM))
565         _swrast_update_fog_state( ctx );
566
567      if (swrast->NewState & (_NEW_PROGRAM_CONSTANTS | _NEW_PROGRAM))
568	 _swrast_update_fragment_program( ctx, swrast->NewState );
569
570      if (swrast->NewState & (_NEW_TEXTURE | _NEW_PROGRAM)) {
571         _swrast_update_texture_samplers( ctx );
572      }
573
574      if (swrast->NewState & (_NEW_COLOR | _NEW_PROGRAM))
575         _swrast_update_deferred_texture(ctx);
576
577      if (swrast->NewState & _SWRAST_NEW_RASTERMASK)
578 	 _swrast_update_rasterflags( ctx );
579
580      if (swrast->NewState & (_NEW_DEPTH |
581                              _NEW_FOG |
582                              _NEW_LIGHT |
583                              _NEW_PROGRAM |
584                              _NEW_TEXTURE))
585         _swrast_update_active_attribs(ctx);
586
587      if (swrast->NewState & (_NEW_FOG |
588                              _NEW_PROGRAM |
589                              _NEW_LIGHT |
590                              _NEW_TEXTURE))
591         _swrast_update_specular_vertex_add(ctx);
592
593      swrast->NewState = 0;
594      swrast->StateChanges = 0;
595      swrast->InvalidateState = _swrast_invalidate_state;
596   }
597}
598
599#define SWRAST_DEBUG 0
600
601/* Public entrypoints:  See also s_bitmap.c, etc.
602 */
603void
604_swrast_Quad( struct gl_context *ctx,
605	      const SWvertex *v0, const SWvertex *v1,
606              const SWvertex *v2, const SWvertex *v3 )
607{
608   if (SWRAST_DEBUG) {
609      _mesa_debug(ctx, "_swrast_Quad\n");
610      _swrast_print_vertex( ctx, v0 );
611      _swrast_print_vertex( ctx, v1 );
612      _swrast_print_vertex( ctx, v2 );
613      _swrast_print_vertex( ctx, v3 );
614   }
615   SWRAST_CONTEXT(ctx)->Triangle( ctx, v0, v1, v3 );
616   SWRAST_CONTEXT(ctx)->Triangle( ctx, v1, v2, v3 );
617}
618
619void
620_swrast_Triangle( struct gl_context *ctx, const SWvertex *v0,
621                  const SWvertex *v1, const SWvertex *v2 )
622{
623   if (SWRAST_DEBUG) {
624      _mesa_debug(ctx, "_swrast_Triangle\n");
625      _swrast_print_vertex( ctx, v0 );
626      _swrast_print_vertex( ctx, v1 );
627      _swrast_print_vertex( ctx, v2 );
628   }
629   SWRAST_CONTEXT(ctx)->Triangle( ctx, v0, v1, v2 );
630}
631
632void
633_swrast_Line( struct gl_context *ctx, const SWvertex *v0, const SWvertex *v1 )
634{
635   if (SWRAST_DEBUG) {
636      _mesa_debug(ctx, "_swrast_Line\n");
637      _swrast_print_vertex( ctx, v0 );
638      _swrast_print_vertex( ctx, v1 );
639   }
640   SWRAST_CONTEXT(ctx)->Line( ctx, v0, v1 );
641}
642
643void
644_swrast_Point( struct gl_context *ctx, const SWvertex *v0 )
645{
646   if (SWRAST_DEBUG) {
647      _mesa_debug(ctx, "_swrast_Point\n");
648      _swrast_print_vertex( ctx, v0 );
649   }
650   SWRAST_CONTEXT(ctx)->Point( ctx, v0 );
651}
652
653void
654_swrast_InvalidateState( struct gl_context *ctx, GLbitfield new_state )
655{
656   if (SWRAST_DEBUG) {
657      _mesa_debug(ctx, "_swrast_InvalidateState\n");
658   }
659   SWRAST_CONTEXT(ctx)->InvalidateState( ctx, new_state );
660}
661
662void
663_swrast_ResetLineStipple( struct gl_context *ctx )
664{
665   if (SWRAST_DEBUG) {
666      _mesa_debug(ctx, "_swrast_ResetLineStipple\n");
667   }
668   SWRAST_CONTEXT(ctx)->StippleCounter = 0;
669}
670
671void
672_swrast_SetFacing(struct gl_context *ctx, GLuint facing)
673{
674   SWRAST_CONTEXT(ctx)->PointLineFacing = facing;
675}
676
677void
678_swrast_allow_vertex_fog( struct gl_context *ctx, GLboolean value )
679{
680   if (SWRAST_DEBUG) {
681      _mesa_debug(ctx, "_swrast_allow_vertex_fog %d\n", value);
682   }
683   SWRAST_CONTEXT(ctx)->InvalidateState( ctx, _NEW_HINT );
684   SWRAST_CONTEXT(ctx)->AllowVertexFog = value;
685}
686
687void
688_swrast_allow_pixel_fog( struct gl_context *ctx, GLboolean value )
689{
690   if (SWRAST_DEBUG) {
691      _mesa_debug(ctx, "_swrast_allow_pixel_fog %d\n", value);
692   }
693   SWRAST_CONTEXT(ctx)->InvalidateState( ctx, _NEW_HINT );
694   SWRAST_CONTEXT(ctx)->AllowPixelFog = value;
695}
696
697
698/**
699 * Initialize native program limits by copying the logical limits.
700 * See comments in init_program_limits() in context.c
701 */
702static void
703init_program_native_limits(struct gl_program_constants *prog)
704{
705   prog->MaxNativeInstructions = prog->MaxInstructions;
706   prog->MaxNativeAluInstructions = prog->MaxAluInstructions;
707   prog->MaxNativeTexInstructions = prog->MaxTexInstructions;
708   prog->MaxNativeTexIndirections = prog->MaxTexIndirections;
709   prog->MaxNativeAttribs = prog->MaxAttribs;
710   prog->MaxNativeTemps = prog->MaxTemps;
711   prog->MaxNativeAddressRegs = prog->MaxAddressRegs;
712   prog->MaxNativeParameters = prog->MaxParameters;
713}
714
715
716GLboolean
717_swrast_CreateContext( struct gl_context *ctx )
718{
719   GLuint i;
720   SWcontext *swrast = calloc(1, sizeof(SWcontext));
721#ifdef _OPENMP
722   const GLuint maxThreads = omp_get_max_threads();
723#else
724   const GLuint maxThreads = 1;
725#endif
726
727   assert(ctx->Const.MaxViewportWidth <= SWRAST_MAX_WIDTH);
728   assert(ctx->Const.MaxViewportHeight <= SWRAST_MAX_WIDTH);
729
730   assert(ctx->Const.MaxRenderbufferSize <= SWRAST_MAX_WIDTH);
731
732   /* make sure largest texture image is <= SWRAST_MAX_WIDTH in size */
733   assert((1 << (ctx->Const.MaxTextureLevels - 1)) <= SWRAST_MAX_WIDTH);
734   assert((1 << (ctx->Const.MaxCubeTextureLevels - 1)) <= SWRAST_MAX_WIDTH);
735   assert((1 << (ctx->Const.Max3DTextureLevels - 1)) <= SWRAST_MAX_WIDTH);
736
737   assert(PROG_MAX_WIDTH == SWRAST_MAX_WIDTH);
738
739   if (SWRAST_DEBUG) {
740      _mesa_debug(ctx, "_swrast_CreateContext\n");
741   }
742
743   if (!swrast)
744      return GL_FALSE;
745
746   swrast->NewState = ~0;
747
748   swrast->choose_point = _swrast_choose_point;
749   swrast->choose_line = _swrast_choose_line;
750   swrast->choose_triangle = _swrast_choose_triangle;
751
752   swrast->InvalidatePointMask = _SWRAST_NEW_POINT;
753   swrast->InvalidateLineMask = _SWRAST_NEW_LINE;
754   swrast->InvalidateTriangleMask = _SWRAST_NEW_TRIANGLE;
755
756   swrast->Point = _swrast_validate_point;
757   swrast->Line = _swrast_validate_line;
758   swrast->Triangle = _swrast_validate_triangle;
759   swrast->InvalidateState = _swrast_sleep;
760   swrast->BlendFunc = _swrast_validate_blend_func;
761
762   swrast->AllowVertexFog = GL_TRUE;
763   swrast->AllowPixelFog = GL_TRUE;
764
765   swrast->Driver.SpanRenderStart = _swrast_span_render_start;
766   swrast->Driver.SpanRenderFinish = _swrast_span_render_finish;
767
768   for (i = 0; i < ARRAY_SIZE(swrast->TextureSample); i++)
769      swrast->TextureSample[i] = NULL;
770
771   /* SpanArrays is global and shared by all SWspan instances. However, when
772    * using multiple threads, it is necessary to have one SpanArrays instance
773    * per thread.
774    */
775   swrast->SpanArrays = malloc(maxThreads * sizeof(SWspanarrays));
776   if (!swrast->SpanArrays) {
777      free(swrast);
778      return GL_FALSE;
779   }
780   for(i = 0; i < maxThreads; i++) {
781      swrast->SpanArrays[i].ChanType = CHAN_TYPE;
782#if CHAN_TYPE == GL_UNSIGNED_BYTE
783      swrast->SpanArrays[i].rgba = swrast->SpanArrays[i].rgba8;
784#elif CHAN_TYPE == GL_UNSIGNED_SHORT
785      swrast->SpanArrays[i].rgba = swrast->SpanArrays[i].rgba16;
786#else
787      swrast->SpanArrays[i].rgba = swrast->SpanArrays[i].attribs[VARYING_SLOT_COL0];
788#endif
789   }
790
791   /* init point span buffer */
792   swrast->PointSpan.primitive = GL_POINT;
793   swrast->PointSpan.end = 0;
794   swrast->PointSpan.facing = 0;
795   swrast->PointSpan.array = swrast->SpanArrays;
796
797   init_program_native_limits(&ctx->Const.Program[MESA_SHADER_VERTEX]);
798   init_program_native_limits(&ctx->Const.Program[MESA_SHADER_GEOMETRY]);
799   init_program_native_limits(&ctx->Const.Program[MESA_SHADER_FRAGMENT]);
800
801   ctx->swrast_context = swrast;
802
803   swrast->stencil_temp.buf1 = malloc(SWRAST_MAX_WIDTH * sizeof(GLubyte));
804   swrast->stencil_temp.buf2 = malloc(SWRAST_MAX_WIDTH * sizeof(GLubyte));
805   swrast->stencil_temp.buf3 = malloc(SWRAST_MAX_WIDTH * sizeof(GLubyte));
806   swrast->stencil_temp.buf4 = malloc(SWRAST_MAX_WIDTH * sizeof(GLubyte));
807
808   if (!swrast->stencil_temp.buf1 ||
809       !swrast->stencil_temp.buf2 ||
810       !swrast->stencil_temp.buf3 ||
811       !swrast->stencil_temp.buf4) {
812      _swrast_DestroyContext(ctx);
813      return GL_FALSE;
814   }
815
816   return GL_TRUE;
817}
818
819void
820_swrast_DestroyContext( struct gl_context *ctx )
821{
822   SWcontext *swrast = SWRAST_CONTEXT(ctx);
823
824   if (SWRAST_DEBUG) {
825      _mesa_debug(ctx, "_swrast_DestroyContext\n");
826   }
827
828   free( swrast->SpanArrays );
829   free( swrast->ZoomedArrays );
830   free( swrast->TexelBuffer );
831
832   free(swrast->stencil_temp.buf1);
833   free(swrast->stencil_temp.buf2);
834   free(swrast->stencil_temp.buf3);
835   free(swrast->stencil_temp.buf4);
836
837   free( swrast );
838
839   ctx->swrast_context = 0;
840}
841
842
843struct swrast_device_driver *
844_swrast_GetDeviceDriverReference( struct gl_context *ctx )
845{
846   SWcontext *swrast = SWRAST_CONTEXT(ctx);
847   return &swrast->Driver;
848}
849
850void
851_swrast_flush( struct gl_context *ctx )
852{
853   SWcontext *swrast = SWRAST_CONTEXT(ctx);
854   /* flush any pending fragments from rendering points */
855   if (swrast->PointSpan.end > 0) {
856      _swrast_write_rgba_span(ctx, &(swrast->PointSpan));
857      swrast->PointSpan.end = 0;
858   }
859}
860
861void
862_swrast_render_primitive( struct gl_context *ctx, GLenum prim )
863{
864   SWcontext *swrast = SWRAST_CONTEXT(ctx);
865   if (swrast->Primitive == GL_POINTS && prim != GL_POINTS) {
866      _swrast_flush(ctx);
867   }
868   swrast->Primitive = prim;
869}
870
871
872/** called via swrast->Driver.SpanRenderStart() */
873void
874_swrast_span_render_start(struct gl_context *ctx)
875{
876   _swrast_map_textures(ctx);
877   _swrast_map_renderbuffers(ctx);
878}
879
880
881/** called via swrast->Driver.SpanRenderFinish() */
882void
883_swrast_span_render_finish(struct gl_context *ctx)
884{
885   _swrast_unmap_textures(ctx);
886   _swrast_unmap_renderbuffers(ctx);
887}
888
889
890void
891_swrast_render_start( struct gl_context *ctx )
892{
893   SWcontext *swrast = SWRAST_CONTEXT(ctx);
894   if (swrast->Driver.SpanRenderStart)
895      swrast->Driver.SpanRenderStart( ctx );
896   swrast->PointSpan.end = 0;
897}
898
899void
900_swrast_render_finish( struct gl_context *ctx )
901{
902   SWcontext *swrast = SWRAST_CONTEXT(ctx);
903
904   _swrast_flush(ctx);
905
906   if (swrast->Driver.SpanRenderFinish)
907      swrast->Driver.SpanRenderFinish( ctx );
908}
909
910
911#define SWRAST_DEBUG_VERTICES 0
912
913void
914_swrast_print_vertex( struct gl_context *ctx, const SWvertex *v )
915{
916   GLuint i;
917
918   if (SWRAST_DEBUG_VERTICES) {
919      _mesa_debug(ctx, "win %f %f %f %f\n",
920                  v->attrib[VARYING_SLOT_POS][0],
921                  v->attrib[VARYING_SLOT_POS][1],
922                  v->attrib[VARYING_SLOT_POS][2],
923                  v->attrib[VARYING_SLOT_POS][3]);
924
925      for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++)
926	 if (ctx->Texture.Unit[i]._Current)
927	    _mesa_debug(ctx, "texcoord[%d] %f %f %f %f\n", i,
928                        v->attrib[VARYING_SLOT_TEX0 + i][0],
929                        v->attrib[VARYING_SLOT_TEX0 + i][1],
930                        v->attrib[VARYING_SLOT_TEX0 + i][2],
931                        v->attrib[VARYING_SLOT_TEX0 + i][3]);
932
933#if CHAN_TYPE == GL_FLOAT
934      _mesa_debug(ctx, "color %f %f %f %f\n",
935                  v->color[0], v->color[1], v->color[2], v->color[3]);
936#else
937      _mesa_debug(ctx, "color %d %d %d %d\n",
938                  v->color[0], v->color[1], v->color[2], v->color[3]);
939#endif
940      _mesa_debug(ctx, "spec %g %g %g %g\n",
941                  v->attrib[VARYING_SLOT_COL1][0],
942                  v->attrib[VARYING_SLOT_COL1][1],
943                  v->attrib[VARYING_SLOT_COL1][2],
944                  v->attrib[VARYING_SLOT_COL1][3]);
945      _mesa_debug(ctx, "fog %f\n", v->attrib[VARYING_SLOT_FOGC][0]);
946      _mesa_debug(ctx, "index %f\n", v->attrib[VARYING_SLOT_CI][0]);
947      _mesa_debug(ctx, "pointsize %f\n", v->pointSize);
948      _mesa_debug(ctx, "\n");
949   }
950}
951