Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

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