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