~ubuntu-branches/ubuntu/gutsy/vnc4/gutsy

« back to all changes in this revision

Viewing changes to unix/xc/lib/GL/mesa/src/drv/tdfx/tdfx_state.c

  • Committer: Bazaar Package Importer
  • Author(s): Ola Lundqvist
  • Date: 2006-05-15 20:35:17 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20060515203517-l4lre1ku942mn26k
Tags: 4.1.1+X4.3.0-10
* Correction of critical security issue. Thanks to Martin Kogler
  <e9925248@student.tuwien.ac.at> that informed me about the issue,
  and provided the patch.
  This flaw was originally found by Steve Wiseman of intelliadmin.com.
* Applied patch from Javier Kohen <jkohen@users.sourceforge.net> that
  inform the user that only 8 first characters of the password will
  actually be used when typing more than 8 characters, closes:
  #355619.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- mode: c; c-basic-offset: 3 -*-
 
2
 *
 
3
 * Copyright 2000 VA Linux Systems Inc., Fremont, California.
 
4
 *
 
5
 * 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 (including the next
 
15
 * paragraph) shall be included in all copies or substantial portions of the
 
16
 * Software.
 
17
 *
 
18
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
19
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
20
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 
21
 * VA LINUX SYSTEMS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 
22
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
 
23
 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 
24
 * SOFTWARE.
 
25
 */
 
26
/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_state.c,v 1.7 2002/10/30 12:52:00 alanh Exp $ */
 
27
 
 
28
/*
 
29
 * Original rewrite:
 
30
 *      Gareth Hughes <gareth@valinux.com>, 29 Sep - 1 Oct 2000
 
31
 *
 
32
 * Authors:
 
33
 *      Gareth Hughes <gareth@valinux.com>
 
34
 *      Brian Paul <brianp@valinux.com>
 
35
 *      Keith Whitwell <keith@tungstengraphics.com> (port to 3.5)
 
36
 *
 
37
 */
 
38
 
 
39
#include "mtypes.h"
 
40
#include "texformat.h"
 
41
#include "texstore.h"
 
42
 
 
43
#include "swrast/swrast.h"
 
44
#include "array_cache/acache.h"
 
45
#include "tnl/tnl.h"
 
46
#include "tnl/t_pipeline.h"
 
47
#include "swrast_setup/swrast_setup.h"
 
48
 
 
49
#include "tdfx_context.h"
 
50
#include "tdfx_state.h"
 
51
#include "tdfx_vb.h"
 
52
#include "tdfx_tex.h"
 
53
#include "tdfx_texman.h"
 
54
#include "tdfx_texstate.h"
 
55
#include "tdfx_tris.h"
 
56
#include "tdfx_render.h"
 
57
 
 
58
 
 
59
 
 
60
/* =============================================================
 
61
 * Alpha blending
 
62
 */
 
63
 
 
64
static void tdfxUpdateAlphaMode( GLcontext *ctx )
 
65
{
 
66
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
 
67
   GrCmpFnc_t func;
 
68
   GrAlphaBlendFnc_t srcRGB, dstRGB, srcA, dstA;
 
69
   GrAlpha_t ref = ctx->Color.AlphaRef;
 
70
 
 
71
   if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) {
 
72
      fprintf( stderr, "%s()\n", __FUNCTION__ );
 
73
   }
 
74
 
 
75
   if ( ctx->Color.AlphaEnabled ) {
 
76
      switch ( ctx->Color.AlphaFunc ) {
 
77
      case GL_NEVER:
 
78
         func = GR_CMP_NEVER;
 
79
         break;
 
80
      case GL_LESS:
 
81
         func = GR_CMP_LESS;
 
82
         break;
 
83
      case GL_LEQUAL:
 
84
         func = GR_CMP_LEQUAL;
 
85
         break;
 
86
      case GL_EQUAL:
 
87
         func = GR_CMP_EQUAL;
 
88
         break;
 
89
      case GL_GEQUAL:
 
90
         func = GR_CMP_GEQUAL;
 
91
         break;
 
92
      case GL_GREATER:
 
93
         func = GR_CMP_GREATER;
 
94
         break;
 
95
      case GL_NOTEQUAL:
 
96
         func = GR_CMP_NOTEQUAL;
 
97
         break;
 
98
      case GL_ALWAYS:
 
99
      default:
 
100
         func = GR_CMP_ALWAYS;
 
101
         break;
 
102
      }
 
103
   } else {
 
104
      func = GR_CMP_ALWAYS;
 
105
   }
 
106
 
 
107
   if ( ctx->Color.BlendEnabled
 
108
        && (fxMesa->Fallback & TDFX_FALLBACK_BLEND) == 0 ) {
 
109
      switch ( ctx->Color.BlendSrcRGB ) {
 
110
      case GL_ZERO:
 
111
         srcRGB = GR_BLEND_ZERO;
 
112
         break;
 
113
      case GL_ONE:
 
114
         srcRGB = GR_BLEND_ONE;
 
115
         break;
 
116
      case GL_DST_COLOR:
 
117
         srcRGB = GR_BLEND_DST_COLOR;
 
118
         break;
 
119
      case GL_ONE_MINUS_DST_COLOR:
 
120
         srcRGB = GR_BLEND_ONE_MINUS_DST_COLOR;
 
121
         break;
 
122
      case GL_SRC_ALPHA:
 
123
         srcRGB = GR_BLEND_SRC_ALPHA;
 
124
         break;
 
125
      case GL_ONE_MINUS_SRC_ALPHA:
 
126
         srcRGB = GR_BLEND_ONE_MINUS_SRC_ALPHA;
 
127
         break;
 
128
      case GL_DST_ALPHA:
 
129
         srcRGB = GR_BLEND_DST_ALPHA;
 
130
         break;
 
131
      case GL_ONE_MINUS_DST_ALPHA:
 
132
         srcRGB = GR_BLEND_ONE_MINUS_DST_ALPHA;
 
133
         break;
 
134
      case GL_SRC_ALPHA_SATURATE:
 
135
         srcRGB = GR_BLEND_ALPHA_SATURATE;
 
136
         break;
 
137
      default:
 
138
         srcRGB = GR_BLEND_ONE;
 
139
      }
 
140
 
 
141
      switch ( ctx->Color.BlendSrcA ) {
 
142
      case GL_ZERO:
 
143
         srcA = GR_BLEND_ZERO;
 
144
         break;
 
145
      case GL_ONE:
 
146
         srcA = GR_BLEND_ONE;
 
147
         break;
 
148
      case GL_DST_COLOR:
 
149
         srcA = GR_BLEND_DST_ALPHA;  /* Napalm only */
 
150
         break;
 
151
      case GL_ONE_MINUS_DST_COLOR:
 
152
         srcA = GR_BLEND_ONE_MINUS_DST_ALPHA;  /* Napalm only */
 
153
         break;
 
154
      case GL_SRC_ALPHA:
 
155
         srcA = GR_BLEND_SRC_ALPHA;  /* Napalm only */
 
156
         break;
 
157
      case GL_ONE_MINUS_SRC_ALPHA:
 
158
         srcA = GR_BLEND_ONE_MINUS_SRC_ALPHA;  /* Napalm only */
 
159
         break;
 
160
      case GL_DST_ALPHA:
 
161
         srcA = GR_BLEND_DST_ALPHA;  /* Napalm only */
 
162
         break;
 
163
      case GL_ONE_MINUS_DST_ALPHA:
 
164
         srcA = GR_BLEND_ONE_MINUS_DST_ALPHA;  /* Napalm only */
 
165
         break;
 
166
      case GL_SRC_ALPHA_SATURATE:
 
167
         srcA = GR_BLEND_ONE;
 
168
         break;
 
169
      default:
 
170
         srcA = GR_BLEND_ONE;
 
171
      }
 
172
 
 
173
      switch ( ctx->Color.BlendDstRGB ) {
 
174
      case GL_ZERO:
 
175
         dstRGB = GR_BLEND_ZERO;
 
176
         break;
 
177
      case GL_ONE:
 
178
         dstRGB = GR_BLEND_ONE;
 
179
         break;
 
180
      case GL_SRC_COLOR:
 
181
         dstRGB = GR_BLEND_SRC_COLOR;
 
182
         break;
 
183
      case GL_ONE_MINUS_SRC_COLOR:
 
184
         dstRGB = GR_BLEND_ONE_MINUS_SRC_COLOR;
 
185
         break;
 
186
      case GL_SRC_ALPHA:
 
187
         dstRGB = GR_BLEND_SRC_ALPHA;
 
188
         break;
 
189
      case GL_ONE_MINUS_SRC_ALPHA:
 
190
         dstRGB = GR_BLEND_ONE_MINUS_SRC_ALPHA;
 
191
         break;
 
192
      case GL_DST_ALPHA:
 
193
         dstRGB = GR_BLEND_DST_ALPHA;
 
194
         break;
 
195
      case GL_ONE_MINUS_DST_ALPHA:
 
196
         dstRGB = GR_BLEND_ONE_MINUS_DST_ALPHA;
 
197
         break;
 
198
      default:
 
199
         dstRGB = GR_BLEND_ZERO;
 
200
      }
 
201
 
 
202
      switch ( ctx->Color.BlendDstA ) {
 
203
      case GL_ZERO:
 
204
         dstA = GR_BLEND_ZERO;
 
205
         break;
 
206
      case GL_ONE:
 
207
         dstA = GR_BLEND_ONE;
 
208
         break;
 
209
      case GL_SRC_COLOR:
 
210
         dstA = GR_BLEND_SRC_ALPHA;  /* Napalm only */
 
211
         break;
 
212
      case GL_ONE_MINUS_SRC_COLOR:
 
213
         dstA = GR_BLEND_ONE_MINUS_SRC_ALPHA;  /* Napalm only */
 
214
         break;
 
215
      case GL_SRC_ALPHA:
 
216
         dstA = GR_BLEND_SRC_ALPHA;  /* Napalm only */
 
217
         break;
 
218
      case GL_ONE_MINUS_SRC_ALPHA:
 
219
         dstA = GR_BLEND_ONE_MINUS_SRC_ALPHA;  /* Napalm only */
 
220
         break;
 
221
      case GL_DST_ALPHA:
 
222
         dstA = GR_BLEND_DST_ALPHA;  /* Napalm only */
 
223
         break;
 
224
      case GL_ONE_MINUS_DST_ALPHA:
 
225
         dstA = GR_BLEND_ONE_MINUS_DST_ALPHA;  /* Napalm only */
 
226
         break;
 
227
      default:
 
228
         dstA = GR_BLEND_ZERO;
 
229
      }
 
230
   } else {
 
231
      /* blend disabled */
 
232
      srcRGB = GR_BLEND_ONE;
 
233
      dstRGB = GR_BLEND_ZERO;
 
234
      srcA = GR_BLEND_ONE;
 
235
      dstA = GR_BLEND_ZERO;
 
236
   }
 
237
 
 
238
   if ( fxMesa->Color.AlphaFunc != func ) {
 
239
      fxMesa->Color.AlphaFunc = func;
 
240
      fxMesa->dirty |= TDFX_UPLOAD_ALPHA_TEST;
 
241
   }
 
242
   if ( fxMesa->Color.AlphaRef != ref ) {
 
243
      fxMesa->Color.AlphaRef = ref;
 
244
      fxMesa->dirty |= TDFX_UPLOAD_ALPHA_REF;
 
245
   }
 
246
 
 
247
   if ( fxMesa->Color.BlendSrcRGB != srcRGB ||
 
248
        fxMesa->Color.BlendDstRGB != dstRGB ||
 
249
        fxMesa->Color.BlendSrcA != srcA ||
 
250
        fxMesa->Color.BlendDstA != dstA )
 
251
   {
 
252
      fxMesa->Color.BlendSrcRGB = srcRGB;
 
253
      fxMesa->Color.BlendDstRGB = dstRGB;
 
254
      fxMesa->Color.BlendSrcA = srcA;
 
255
      fxMesa->Color.BlendDstA = dstA;
 
256
      fxMesa->dirty |= TDFX_UPLOAD_BLEND_FUNC;
 
257
   }
 
258
}
 
259
 
 
260
static void tdfxDDAlphaFunc( GLcontext *ctx, GLenum func, GLchan ref )
 
261
{
 
262
   tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx );
 
263
 
 
264
   FLUSH_BATCH( fxMesa );
 
265
   fxMesa->new_state |= TDFX_NEW_ALPHA;
 
266
}
 
267
 
 
268
static void tdfxDDBlendEquation( GLcontext *ctx, GLenum mode )
 
269
{
 
270
   tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx );
 
271
 
 
272
   FLUSH_BATCH( fxMesa );
 
273
   fxMesa->new_state |= TDFX_NEW_ALPHA;
 
274
}
 
275
 
 
276
static void tdfxDDBlendFunc( GLcontext *ctx, GLenum sfactor, GLenum dfactor )
 
277
{
 
278
   tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx );
 
279
 
 
280
   FLUSH_BATCH( fxMesa );
 
281
   fxMesa->new_state |= TDFX_NEW_ALPHA;
 
282
 
 
283
   /*
 
284
    * XXX - Voodoo5 seems to suffer from precision problems in some
 
285
    * blend modes.  To pass all the conformance tests we'd have to
 
286
    * fall back to software for many modes.  Revisit someday.
 
287
    */
 
288
}
 
289
 
 
290
static void tdfxDDBlendFuncSeparate( GLcontext *ctx,
 
291
                                     GLenum sfactorRGB, GLenum dfactorRGB,
 
292
                                     GLenum sfactorA, GLenum dfactorA )
 
293
{
 
294
   tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx );
 
295
 
 
296
   FLUSH_BATCH( fxMesa );
 
297
   fxMesa->new_state |= TDFX_NEW_ALPHA;
 
298
}
 
299
 
 
300
/* =============================================================
 
301
 * Stipple
 
302
 */
 
303
 
 
304
void tdfxUpdateStipple( GLcontext *ctx )
 
305
{
 
306
   tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx );
 
307
   GrStippleMode_t mode = GR_STIPPLE_DISABLE;
 
308
 
 
309
   if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) {
 
310
      fprintf( stderr, "%s()\n", __FUNCTION__ );
 
311
   }
 
312
 
 
313
   FLUSH_BATCH( fxMesa );
 
314
 
 
315
   if (ctx->Polygon.StippleFlag) {
 
316
      mode = GR_STIPPLE_PATTERN;
 
317
   }
 
318
 
 
319
   if ( fxMesa->Stipple.Mode != mode ) {
 
320
      fxMesa->Stipple.Mode = mode;
 
321
      fxMesa->dirty |= TDFX_UPLOAD_STIPPLE;
 
322
   }
 
323
}
 
324
 
 
325
 
 
326
/* =============================================================
 
327
 * Depth testing
 
328
 */
 
329
 
 
330
static void tdfxUpdateZMode( GLcontext *ctx )
 
331
{
 
332
   tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx );
 
333
   GrCmpFnc_t func;
 
334
   FxI32 bias;
 
335
   FxBool mask;
 
336
 
 
337
   if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) 
 
338
      fprintf( stderr, "%s()\n", __FUNCTION__ );
 
339
 
 
340
 
 
341
   bias = (FxI32) (ctx->Polygon.OffsetUnits * TDFX_DEPTH_BIAS_SCALE);
 
342
 
 
343
   if ( ctx->Depth.Test ) {
 
344
      switch ( ctx->Depth.Func ) {
 
345
      case GL_NEVER:
 
346
         func = GR_CMP_NEVER;
 
347
         break;
 
348
      case GL_LESS:
 
349
         func = GR_CMP_LESS;
 
350
         break;
 
351
      case GL_LEQUAL:
 
352
         func = GR_CMP_LEQUAL;
 
353
         break;
 
354
      case GL_EQUAL:
 
355
         func = GR_CMP_EQUAL;
 
356
         break;
 
357
      case GL_GEQUAL:
 
358
         func = GR_CMP_GEQUAL;
 
359
         break;
 
360
      case GL_GREATER:
 
361
         func = GR_CMP_GREATER;
 
362
         break;
 
363
      case GL_NOTEQUAL:
 
364
         func = GR_CMP_NOTEQUAL;
 
365
         break;
 
366
      case GL_ALWAYS:
 
367
      default:
 
368
         func = GR_CMP_ALWAYS;
 
369
         break;
 
370
      }
 
371
 
 
372
      if ( ctx->Depth.Mask ) {
 
373
         mask = FXTRUE;
 
374
      }
 
375
      else {
 
376
         mask = FXFALSE;
 
377
      }
 
378
   }
 
379
   else {
 
380
      /* depth testing disabled */
 
381
      func = GR_CMP_ALWAYS;  /* fragments always pass */
 
382
      mask = FXFALSE;        /* zbuffer is not touched */
 
383
   }
 
384
 
 
385
   fxMesa->Depth.Clear = (FxU32) (((1 << fxMesa->glCtx->Visual.depthBits) - 1)
 
386
                                  * ctx->Depth.Clear);
 
387
 
 
388
   if ( fxMesa->Depth.Bias != bias ) {
 
389
      fxMesa->Depth.Bias = bias;
 
390
      fxMesa->dirty |= TDFX_UPLOAD_DEPTH_BIAS;
 
391
   }
 
392
   if ( fxMesa->Depth.Func != func ) {
 
393
      fxMesa->Depth.Func = func;
 
394
      fxMesa->dirty |= TDFX_UPLOAD_DEPTH_FUNC | TDFX_UPLOAD_DEPTH_MASK;
 
395
   }
 
396
   if ( fxMesa->Depth.Mask != mask ) {
 
397
      fxMesa->Depth.Mask = mask;
 
398
      fxMesa->dirty |= TDFX_UPLOAD_DEPTH_MASK;
 
399
   }
 
400
}
 
401
 
 
402
static void tdfxDDDepthFunc( GLcontext *ctx, GLenum func )
 
403
{
 
404
   tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx );
 
405
 
 
406
   FLUSH_BATCH( fxMesa );
 
407
   fxMesa->new_state |= TDFX_NEW_DEPTH;
 
408
}
 
409
 
 
410
static void tdfxDDDepthMask( GLcontext *ctx, GLboolean flag )
 
411
{
 
412
   tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx );
 
413
 
 
414
   FLUSH_BATCH( fxMesa );
 
415
   fxMesa->new_state |= TDFX_NEW_DEPTH;
 
416
}
 
417
 
 
418
static void tdfxDDClearDepth( GLcontext *ctx, GLclampd d )
 
419
{
 
420
   tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx );
 
421
 
 
422
   FLUSH_BATCH( fxMesa );
 
423
   fxMesa->new_state |= TDFX_NEW_DEPTH;
 
424
}
 
425
 
 
426
 
 
427
 
 
428
/* =============================================================
 
429
 * Stencil
 
430
 */
 
431
 
 
432
 
 
433
/* Evaluate all stencil state and make the Glide calls.
 
434
 */
 
435
static GrStencil_t convertGLStencilOp( GLenum op )
 
436
{
 
437
   switch ( op ) {
 
438
   case GL_KEEP:
 
439
      return GR_STENCILOP_KEEP;
 
440
   case GL_ZERO:
 
441
      return GR_STENCILOP_ZERO;
 
442
   case GL_REPLACE:
 
443
      return GR_STENCILOP_REPLACE;
 
444
   case GL_INCR:
 
445
      return GR_STENCILOP_INCR_CLAMP;
 
446
   case GL_DECR:
 
447
      return GR_STENCILOP_DECR_CLAMP;
 
448
   case GL_INVERT:
 
449
      return GR_STENCILOP_INVERT;
 
450
   case GL_INCR_WRAP_EXT:
 
451
      return GR_STENCILOP_INCR_WRAP;
 
452
   case GL_DECR_WRAP_EXT:
 
453
      return GR_STENCILOP_DECR_WRAP;
 
454
   default:
 
455
      _mesa_problem( NULL, "bad stencil op in convertGLStencilOp" );
 
456
   }
 
457
   return GR_STENCILOP_KEEP;   /* never get, silence compiler warning */
 
458
}
 
459
 
 
460
 
 
461
static void tdfxUpdateStencil( GLcontext *ctx )
 
462
{
 
463
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
 
464
 
 
465
   if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) {
 
466
      fprintf( stderr, "%s()\n", __FUNCTION__ );
 
467
   }
 
468
 
 
469
   if (fxMesa->haveHwStencil) {
 
470
      if (ctx->Stencil.Enabled) {
 
471
         fxMesa->Stencil.Function = ctx->Stencil.Function - GL_NEVER;
 
472
         fxMesa->Stencil.RefValue = ctx->Stencil.Ref;
 
473
         fxMesa->Stencil.ValueMask = ctx->Stencil.ValueMask;
 
474
         fxMesa->Stencil.WriteMask = ctx->Stencil.WriteMask;
 
475
         fxMesa->Stencil.FailFunc = convertGLStencilOp(ctx->Stencil.FailFunc);
 
476
         fxMesa->Stencil.ZFailFunc =convertGLStencilOp(ctx->Stencil.ZFailFunc);
 
477
         fxMesa->Stencil.ZPassFunc =convertGLStencilOp(ctx->Stencil.ZPassFunc);
 
478
         fxMesa->Stencil.Clear = ctx->Stencil.Clear & 0xff;
 
479
      }
 
480
      fxMesa->dirty |= TDFX_UPLOAD_STENCIL;
 
481
   }
 
482
}
 
483
 
 
484
 
 
485
static void tdfxDDStencilFunc( GLcontext *ctx, GLenum func,
 
486
                               GLint ref, GLuint mask )
 
487
{
 
488
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
 
489
 
 
490
   FLUSH_BATCH( fxMesa );
 
491
   fxMesa->new_state |= TDFX_NEW_STENCIL;
 
492
}
 
493
 
 
494
static void tdfxDDStencilMask( GLcontext *ctx, GLuint mask )
 
495
{
 
496
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
 
497
 
 
498
   FLUSH_BATCH( fxMesa );
 
499
   fxMesa->new_state |= TDFX_NEW_STENCIL;
 
500
}
 
501
 
 
502
static void tdfxDDStencilOp( GLcontext *ctx, GLenum sfail,
 
503
                             GLenum zfail, GLenum zpass )
 
504
{
 
505
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
 
506
 
 
507
   FLUSH_BATCH( fxMesa );
 
508
   fxMesa->new_state |= TDFX_NEW_STENCIL;
 
509
}
 
510
 
 
511
 
 
512
/* =============================================================
 
513
 * Fog - orthographic fog still not working
 
514
 */
 
515
 
 
516
static void tdfxUpdateFogAttrib( GLcontext *ctx )
 
517
{
 
518
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
 
519
   GrFogMode_t mode;
 
520
   GrColor_t color;
 
521
 
 
522
   if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) {
 
523
      fprintf( stderr, "%s()\n", __FUNCTION__ );
 
524
   }
 
525
 
 
526
   if ( ctx->Fog.Enabled ) {
 
527
      mode = GR_FOG_WITH_TABLE_ON_Q;
 
528
   } else {
 
529
      mode = GR_FOG_DISABLE;
 
530
   }
 
531
 
 
532
   color = TDFXPACKCOLOR888((GLubyte)(ctx->Fog.Color[0]*255.0F),
 
533
                            (GLubyte)(ctx->Fog.Color[1]*255.0F),
 
534
                            (GLubyte)(ctx->Fog.Color[2]*255.0F));
 
535
 
 
536
   if ( fxMesa->Fog.Mode != mode ) {
 
537
      fxMesa->Fog.Mode = mode;
 
538
      fxMesa->dirty |= TDFX_UPLOAD_FOG_MODE;
 
539
   }
 
540
   if ( fxMesa->Fog.Color != color ) {
 
541
      fxMesa->Fog.Color = color;
 
542
      fxMesa->dirty |= TDFX_UPLOAD_FOG_COLOR;
 
543
   }
 
544
   if ( fxMesa->Fog.TableMode != ctx->Fog.Mode ||
 
545
        fxMesa->Fog.Density != ctx->Fog.Density ||
 
546
        fxMesa->Fog.Near != ctx->Fog.Start ||
 
547
        fxMesa->Fog.Far != ctx->Fog.End )
 
548
   {
 
549
      switch( ctx->Fog.Mode ) {
 
550
      case GL_EXP:
 
551
         fxMesa->Glide.guFogGenerateExp( fxMesa->Fog.Table, ctx->Fog.Density );
 
552
         break;
 
553
      case GL_EXP2:
 
554
         fxMesa->Glide.guFogGenerateExp2( fxMesa->Fog.Table, ctx->Fog.Density);
 
555
         break;
 
556
      case GL_LINEAR:
 
557
         fxMesa->Glide.guFogGenerateLinear( fxMesa->Fog.Table,
 
558
                                            ctx->Fog.Start, ctx->Fog.End );
 
559
         break;
 
560
      }
 
561
 
 
562
      fxMesa->Fog.TableMode = ctx->Fog.Mode;
 
563
      fxMesa->Fog.Density = ctx->Fog.Density;
 
564
      fxMesa->Fog.Near = ctx->Fog.Start;
 
565
      fxMesa->Fog.Far = ctx->Fog.End;
 
566
      fxMesa->dirty |= TDFX_UPLOAD_FOG_TABLE;
 
567
   }
 
568
}
 
569
 
 
570
static void tdfxDDFogfv( GLcontext *ctx, GLenum pname, const GLfloat *param )
 
571
{
 
572
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
 
573
 
 
574
   FLUSH_BATCH( fxMesa );
 
575
   fxMesa->new_state |= TDFX_NEW_FOG;
 
576
}
 
577
 
 
578
 
 
579
/* =============================================================
 
580
 * Clipping
 
581
 */
 
582
 
 
583
static int intersect_rect( XF86DRIClipRectPtr out,
 
584
                           const XF86DRIClipRectPtr a,
 
585
                           const XF86DRIClipRectPtr b)
 
586
{
 
587
   *out = *a;
 
588
   if (b->x1 > out->x1) out->x1 = b->x1;
 
589
   if (b->y1 > out->y1) out->y1 = b->y1;
 
590
   if (b->x2 < out->x2) out->x2 = b->x2;
 
591
   if (b->y2 < out->y2) out->y2 = b->y2;
 
592
   if (out->x1 >= out->x2) return 0;
 
593
   if (out->y1 >= out->y2) return 0;
 
594
   return 1;
 
595
}
 
596
 
 
597
 
 
598
/*
 
599
 * Examine XF86 cliprect list and scissor state to recompute our
 
600
 * cliprect list.
 
601
 */
 
602
void tdfxUpdateClipping( GLcontext *ctx )
 
603
{
 
604
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
 
605
   __DRIdrawablePrivate *dPriv = fxMesa->driDrawable;
 
606
 
 
607
   if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) {
 
608
      fprintf( stderr, "%s()\n", __FUNCTION__ );
 
609
   }
 
610
 
 
611
   assert(ctx);
 
612
   assert(fxMesa);
 
613
   assert(dPriv);
 
614
 
 
615
   if ( dPriv->x != fxMesa->x_offset || dPriv->y != fxMesa->y_offset ||
 
616
        dPriv->w != fxMesa->width || dPriv->h != fxMesa->height ) {
 
617
      fxMesa->x_offset = dPriv->x;
 
618
      fxMesa->y_offset = dPriv->y;
 
619
      fxMesa->width = dPriv->w;
 
620
      fxMesa->height = dPriv->h;
 
621
      fxMesa->y_delta =
 
622
         fxMesa->screen_height - fxMesa->y_offset - fxMesa->height;
 
623
      tdfxUpdateViewport( ctx );
 
624
   }
 
625
 
 
626
   if (fxMesa->scissoredClipRects && fxMesa->pClipRects) {
 
627
      free(fxMesa->pClipRects);
 
628
   }
 
629
 
 
630
   if (ctx->Scissor.Enabled) {
 
631
      /* intersect OpenGL scissor box with all cliprects to make a new
 
632
       * list of cliprects.
 
633
       */
 
634
      XF86DRIClipRectRec scissor;
 
635
      int x1 = ctx->Scissor.X + fxMesa->x_offset;
 
636
      int y1 = fxMesa->screen_height - fxMesa->y_delta
 
637
             - ctx->Scissor.Y - ctx->Scissor.Height;
 
638
      int x2 = x1 + ctx->Scissor.Width;
 
639
      int y2 = y1 + ctx->Scissor.Height;
 
640
      scissor.x1 = MAX2(x1, 0);
 
641
      scissor.y1 = MAX2(y1, 0);
 
642
      scissor.x2 = MAX2(x2, 0);
 
643
      scissor.y2 = MAX2(y2, 0);
 
644
 
 
645
      assert(scissor.x2 >= scissor.x1);
 
646
      assert(scissor.y2 >= scissor.y1);
 
647
 
 
648
      fxMesa->pClipRects = malloc(dPriv->numClipRects
 
649
                                  * sizeof(XF86DRIClipRectRec));
 
650
      if (fxMesa->pClipRects) {
 
651
         int i;
 
652
         fxMesa->numClipRects = 0;
 
653
         for (i = 0; i < dPriv->numClipRects; i++) {
 
654
            if (intersect_rect(&fxMesa->pClipRects[fxMesa->numClipRects],
 
655
                               &scissor, &dPriv->pClipRects[i])) {
 
656
               fxMesa->numClipRects++;
 
657
            }
 
658
         }
 
659
         fxMesa->scissoredClipRects = GL_TRUE;
 
660
      }
 
661
      else {
 
662
         /* out of memory, forgo scissor */
 
663
         fxMesa->numClipRects = dPriv->numClipRects;
 
664
         fxMesa->pClipRects = dPriv->pClipRects;
 
665
         fxMesa->scissoredClipRects = GL_FALSE;
 
666
      }
 
667
   }
 
668
   else {
 
669
      fxMesa->numClipRects = dPriv->numClipRects;
 
670
      fxMesa->pClipRects = dPriv->pClipRects;
 
671
      fxMesa->scissoredClipRects = GL_FALSE;
 
672
   }
 
673
 
 
674
   fxMesa->dirty |= TDFX_UPLOAD_CLIP;
 
675
}
 
676
 
 
677
 
 
678
 
 
679
/* =============================================================
 
680
 * Culling
 
681
 */
 
682
 
 
683
void tdfxUpdateCull( GLcontext *ctx )
 
684
{
 
685
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
 
686
   GrCullMode_t mode = GR_CULL_DISABLE;
 
687
 
 
688
   /* KW: don't need to check raster_primitive here as we don't
 
689
    * attempt to draw lines or points with triangles.
 
690
    */
 
691
   if ( ctx->Polygon.CullFlag ) {
 
692
      switch ( ctx->Polygon.CullFaceMode ) {
 
693
      case GL_FRONT:
 
694
         if ( ctx->Polygon.FrontFace == GL_CCW ) {
 
695
            mode = GR_CULL_POSITIVE;
 
696
         } else {
 
697
            mode = GR_CULL_NEGATIVE;
 
698
         }
 
699
         break;
 
700
 
 
701
      case GL_BACK:
 
702
         if ( ctx->Polygon.FrontFace == GL_CCW ) {
 
703
            mode = GR_CULL_NEGATIVE;
 
704
         } else {
 
705
            mode = GR_CULL_POSITIVE;
 
706
         }
 
707
         break;
 
708
 
 
709
      case GL_FRONT_AND_BACK:
 
710
         /* Handled as a fallback on triangles in tdfx_tris.c */
 
711
         return;
 
712
 
 
713
      default:
 
714
         ASSERT(0);
 
715
         break;
 
716
      }
 
717
   }
 
718
 
 
719
   if ( fxMesa->CullMode != mode ) {
 
720
      fxMesa->CullMode = mode;
 
721
      fxMesa->dirty |= TDFX_UPLOAD_CULL;
 
722
   }
 
723
}
 
724
 
 
725
static void tdfxDDCullFace( GLcontext *ctx, GLenum mode )
 
726
{
 
727
   tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx );
 
728
 
 
729
   FLUSH_BATCH( fxMesa );
 
730
   fxMesa->new_state |= TDFX_NEW_CULL;
 
731
}
 
732
 
 
733
static void tdfxDDFrontFace( GLcontext *ctx, GLenum mode )
 
734
{
 
735
   tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx );
 
736
 
 
737
   FLUSH_BATCH( fxMesa );
 
738
   fxMesa->new_state |= TDFX_NEW_CULL;
 
739
}
 
740
 
 
741
 
 
742
/* =============================================================
 
743
 * Line drawing.
 
744
 */
 
745
 
 
746
static void tdfxUpdateLine( GLcontext *ctx )
 
747
{
 
748
   tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx );
 
749
 
 
750
   if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) {
 
751
      fprintf( stderr, "%s()\n", __FUNCTION__ );
 
752
   }
 
753
 
 
754
   FLUSH_BATCH( fxMesa );
 
755
   fxMesa->dirty |= TDFX_UPLOAD_LINE;
 
756
}
 
757
 
 
758
 
 
759
static void tdfxDDLineWidth( GLcontext *ctx, GLfloat width )
 
760
{
 
761
   tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx );
 
762
   FLUSH_BATCH( fxMesa );
 
763
   fxMesa->new_state |= TDFX_NEW_LINE;
 
764
}
 
765
 
 
766
 
 
767
/* =============================================================
 
768
 * Color Attributes
 
769
 */
 
770
 
 
771
static void tdfxDDColorMask( GLcontext *ctx,
 
772
                             GLboolean r, GLboolean g,
 
773
                             GLboolean b, GLboolean a )
 
774
{
 
775
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
 
776
 
 
777
   FLUSH_BATCH( fxMesa );
 
778
 
 
779
   if ( fxMesa->Color.ColorMask[RCOMP] != r ||
 
780
        fxMesa->Color.ColorMask[GCOMP] != g ||
 
781
        fxMesa->Color.ColorMask[BCOMP] != b ||
 
782
        fxMesa->Color.ColorMask[ACOMP] != a ) {
 
783
      fxMesa->Color.ColorMask[RCOMP] = r;
 
784
      fxMesa->Color.ColorMask[GCOMP] = g;
 
785
      fxMesa->Color.ColorMask[BCOMP] = b;
 
786
      fxMesa->Color.ColorMask[ACOMP] = a;
 
787
      fxMesa->dirty |= TDFX_UPLOAD_COLOR_MASK;
 
788
 
 
789
      if (ctx->Visual.redBits < 8) {
 
790
         /* Can't do RGB colormasking in 16bpp mode. */
 
791
         /* We can completely ignore the alpha mask. */
 
792
         FALLBACK( fxMesa, TDFX_FALLBACK_COLORMASK, (r != g || g != b) );
 
793
      }
 
794
   }
 
795
}
 
796
 
 
797
 
 
798
static void tdfxDDClearColor( GLcontext *ctx,
 
799
                              const GLchan color[4] )
 
800
{
 
801
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
 
802
   FLUSH_BATCH( fxMesa );
 
803
   fxMesa->Color.ClearColor = TDFXPACKCOLOR888( color[0], color[1], color[2] );
 
804
   fxMesa->Color.ClearAlpha = color[3];
 
805
}
 
806
 
 
807
 
 
808
/* =============================================================
 
809
 * Light Model
 
810
 */
 
811
 
 
812
static void tdfxDDLightModelfv( GLcontext *ctx, GLenum pname,
 
813
                                const GLfloat *param )
 
814
{
 
815
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
 
816
 
 
817
   if ( pname == GL_LIGHT_MODEL_COLOR_CONTROL ) {
 
818
      FALLBACK( fxMesa, TDFX_FALLBACK_SPECULAR,
 
819
                (ctx->Light.Enabled &&
 
820
                 ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR ));
 
821
   }
 
822
}
 
823
 
 
824
static void tdfxDDShadeModel( GLcontext *ctx, GLenum mode )
 
825
{
 
826
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
 
827
 
 
828
   /* FIXME: Can we implement native flat shading? */
 
829
   FLUSH_BATCH( fxMesa );
 
830
   fxMesa->new_state |= TDFX_NEW_TEXTURE;
 
831
}
 
832
 
 
833
 
 
834
/* =============================================================
 
835
 * Scissor
 
836
 */
 
837
 
 
838
static void
 
839
tdfxDDScissor(GLcontext * ctx, GLint x, GLint y, GLsizei w, GLsizei h)
 
840
{
 
841
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
 
842
   FLUSH_BATCH( fxMesa );
 
843
   fxMesa->new_state |= TDFX_NEW_CLIP;
 
844
}
 
845
 
 
846
/* =============================================================
 
847
 * Render
 
848
 */
 
849
 
 
850
static void tdfxUpdateRenderAttrib( GLcontext *ctx )
 
851
{
 
852
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
 
853
   FLUSH_BATCH( fxMesa );
 
854
   fxMesa->dirty |= TDFX_UPLOAD_RENDER_BUFFER;
 
855
}
 
856
 
 
857
/* =============================================================
 
858
 * Viewport
 
859
 */
 
860
 
 
861
void tdfxUpdateViewport( GLcontext *ctx )
 
862
{
 
863
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
 
864
   const GLfloat *v = ctx->Viewport._WindowMap.m;
 
865
   GLfloat *m = fxMesa->hw_viewport;
 
866
 
 
867
   m[MAT_SX] = v[MAT_SX];
 
868
   m[MAT_TX] = v[MAT_TX] + fxMesa->x_offset + TRI_X_OFFSET;
 
869
   m[MAT_SY] = v[MAT_SY];
 
870
   m[MAT_TY] = v[MAT_TY] + fxMesa->y_delta + TRI_Y_OFFSET;
 
871
   m[MAT_SZ] = v[MAT_SZ];
 
872
   m[MAT_TZ] = v[MAT_TZ];
 
873
 
 
874
   fxMesa->SetupNewInputs |= VERT_CLIP;
 
875
}
 
876
 
 
877
 
 
878
static void tdfxDDViewport( GLcontext *ctx, GLint x, GLint y,
 
879
                            GLsizei w, GLsizei h )
 
880
{
 
881
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
 
882
   FLUSH_BATCH( fxMesa );
 
883
   fxMesa->new_state |= TDFX_NEW_VIEWPORT;
 
884
}
 
885
 
 
886
 
 
887
static void tdfxDDDepthRange( GLcontext *ctx, GLclampd nearVal, GLclampd farVal )
 
888
{
 
889
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
 
890
   FLUSH_BATCH( fxMesa );
 
891
   fxMesa->new_state |= TDFX_NEW_VIEWPORT;
 
892
}
 
893
 
 
894
 
 
895
/* =============================================================
 
896
 * State enable/disable
 
897
 */
 
898
 
 
899
static void tdfxDDEnable( GLcontext *ctx, GLenum cap, GLboolean state )
 
900
{
 
901
   tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx );
 
902
 
 
903
   switch ( cap ) {
 
904
   case GL_ALPHA_TEST:
 
905
      FLUSH_BATCH( fxMesa );
 
906
      fxMesa->new_state |= TDFX_NEW_ALPHA;
 
907
      break;
 
908
 
 
909
   case GL_BLEND:
 
910
      FLUSH_BATCH( fxMesa );
 
911
      fxMesa->new_state |= TDFX_NEW_ALPHA;
 
912
      FALLBACK( fxMesa, TDFX_FALLBACK_LOGICOP,
 
913
                (ctx->Color.ColorLogicOpEnabled &&
 
914
                 ctx->Color.LogicOp != GL_COPY));
 
915
      break;
 
916
 
 
917
   case GL_CULL_FACE:
 
918
      FLUSH_BATCH( fxMesa );
 
919
      fxMesa->new_state |= TDFX_NEW_CULL;
 
920
      break;
 
921
 
 
922
   case GL_DEPTH_TEST:
 
923
      FLUSH_BATCH( fxMesa );
 
924
      fxMesa->new_state |= TDFX_NEW_DEPTH;
 
925
      break;
 
926
 
 
927
   case GL_DITHER:
 
928
      FLUSH_BATCH( fxMesa );
 
929
      if ( state ) {
 
930
         fxMesa->Color.Dither = GR_DITHER_2x2;
 
931
      } else {
 
932
         fxMesa->Color.Dither = GR_DITHER_DISABLE;
 
933
      }
 
934
      fxMesa->dirty |= TDFX_UPLOAD_DITHER;
 
935
      break;
 
936
 
 
937
   case GL_FOG:
 
938
      FLUSH_BATCH( fxMesa );
 
939
      fxMesa->new_state |= TDFX_NEW_FOG;
 
940
      break;
 
941
 
 
942
   case GL_COLOR_LOGIC_OP:
 
943
      FALLBACK( fxMesa, TDFX_FALLBACK_LOGICOP,
 
944
                (ctx->Color.ColorLogicOpEnabled &&
 
945
                 ctx->Color.LogicOp != GL_COPY));
 
946
      break;
 
947
 
 
948
   case GL_LIGHTING:
 
949
      FALLBACK( fxMesa, TDFX_FALLBACK_SPECULAR,
 
950
                (ctx->Light.Enabled &&
 
951
                 ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR ));
 
952
      break;
 
953
 
 
954
   case GL_LINE_SMOOTH:
 
955
      FLUSH_BATCH( fxMesa );
 
956
      fxMesa->new_state |= TDFX_NEW_LINE;
 
957
      break;
 
958
 
 
959
   case GL_LINE_STIPPLE:
 
960
      FALLBACK(fxMesa, TDFX_FALLBACK_LINE_STIPPLE, state);
 
961
      break;
 
962
 
 
963
   case GL_POLYGON_STIPPLE:
 
964
      FLUSH_BATCH(fxMesa);
 
965
      fxMesa->new_state |= TDFX_NEW_STIPPLE;
 
966
      break;
 
967
 
 
968
   case GL_SCISSOR_TEST:
 
969
      FLUSH_BATCH( fxMesa );
 
970
      fxMesa->new_state |= TDFX_NEW_CLIP;
 
971
      break;
 
972
 
 
973
   case GL_STENCIL_TEST:
 
974
      FLUSH_BATCH( fxMesa );
 
975
      FALLBACK( fxMesa, TDFX_FALLBACK_STENCIL, state && !fxMesa->haveHwStencil);
 
976
      break;
 
977
 
 
978
   case GL_TEXTURE_1D:
 
979
   case GL_TEXTURE_3D:
 
980
      FLUSH_BATCH( fxMesa );
 
981
      FALLBACK( fxMesa, TDFX_FALLBACK_TEXTURE_1D_3D, state); /* wrong */
 
982
      fxMesa->new_state |= TDFX_NEW_TEXTURE;
 
983
      break;
 
984
 
 
985
   case GL_TEXTURE_2D:
 
986
      FLUSH_BATCH( fxMesa );
 
987
      fxMesa->new_state |= TDFX_NEW_TEXTURE;
 
988
      break;
 
989
 
 
990
   default:
 
991
      return;
 
992
   }
 
993
}
 
994
 
 
995
 
 
996
 
 
997
/* Set the buffer used for drawing */
 
998
/* XXX support for separate read/draw buffers hasn't been tested */
 
999
static void tdfxDDSetDrawBuffer( GLcontext *ctx, GLenum mode )
 
1000
{
 
1001
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
 
1002
 
 
1003
   if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) {
 
1004
      fprintf( stderr, "%s()\n", __FUNCTION__ );
 
1005
   }
 
1006
 
 
1007
   FLUSH_BATCH( fxMesa );
 
1008
 
 
1009
   switch( mode) {
 
1010
   case GL_FRONT_LEFT:
 
1011
      fxMesa->DrawBuffer = fxMesa->ReadBuffer = GR_BUFFER_FRONTBUFFER;
 
1012
      fxMesa->new_state |= TDFX_NEW_RENDER;
 
1013
      FALLBACK( fxMesa, TDFX_FALLBACK_DRAW_BUFFER, GL_FALSE );
 
1014
      break;
 
1015
 
 
1016
   case GL_BACK_LEFT:
 
1017
      fxMesa->DrawBuffer = fxMesa->ReadBuffer = GR_BUFFER_BACKBUFFER;
 
1018
      fxMesa->new_state |= TDFX_NEW_RENDER;
 
1019
      FALLBACK( fxMesa, TDFX_FALLBACK_DRAW_BUFFER, GL_FALSE );
 
1020
      break;
 
1021
 
 
1022
   case GL_NONE:
 
1023
      FX_grColorMaskv( ctx, false4 );
 
1024
      FALLBACK( fxMesa, TDFX_FALLBACK_DRAW_BUFFER, GL_FALSE );
 
1025
      break;
 
1026
 
 
1027
   default:
 
1028
      FALLBACK( fxMesa, TDFX_FALLBACK_DRAW_BUFFER, GL_TRUE );
 
1029
      break;
 
1030
   }
 
1031
}
 
1032
 
 
1033
 
 
1034
 
 
1035
/* =============================================================
 
1036
 * Polygon stipple
 
1037
 */
 
1038
 
 
1039
static void tdfxDDPolygonStipple( GLcontext *ctx, const GLubyte *mask )
 
1040
{
 
1041
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
 
1042
   const GLubyte *m = mask;
 
1043
   GLubyte q[4];
 
1044
   int i,j,k;
 
1045
   GLboolean allBitsSet;
 
1046
 
 
1047
/*     int active = (ctx->Polygon.StippleFlag &&  */
 
1048
/*               fxMesa->reduced_prim == GL_TRIANGLES); */
 
1049
 
 
1050
   FLUSH_BATCH(fxMesa);
 
1051
   fxMesa->Stipple.Pattern = 0xffffffff;
 
1052
   fxMesa->dirty |= TDFX_UPLOAD_STIPPLE;
 
1053
   fxMesa->new_state |= TDFX_NEW_STIPPLE;
 
1054
 
 
1055
   /* Check if the stipple pattern is fully opaque.  If so, use software
 
1056
    * rendering.  This basically a trick to make sure the OpenGL conformance
 
1057
    * test passes.
 
1058
    */
 
1059
   allBitsSet = GL_TRUE;
 
1060
   for (i = 0; i < 32; i++) {
 
1061
      if (((GLuint *) mask)[i] != 0xffffffff) {
 
1062
         allBitsSet = GL_FALSE;
 
1063
         break;
 
1064
      }
 
1065
   }
 
1066
   if (allBitsSet) {
 
1067
      fxMesa->haveHwStipple = GL_FALSE;
 
1068
      return;
 
1069
   }
 
1070
 
 
1071
   q[0] = mask[0];
 
1072
   q[1] = mask[4];
 
1073
   q[2] = mask[8];
 
1074
   q[3] = mask[12];
 
1075
 
 
1076
   for (k = 0 ; k < 8 ; k++)
 
1077
      for (j = 0 ; j < 4; j++)
 
1078
         for (i = 0 ; i < 4 ; i++,m++) {
 
1079
            if (*m != q[j]) {
 
1080
               fxMesa->haveHwStipple = GL_FALSE;
 
1081
               return;
 
1082
            }
 
1083
         }
 
1084
 
 
1085
   fxMesa->haveHwStipple = GL_TRUE;
 
1086
   fxMesa->Stipple.Pattern = ( (q[0] << 0) |
 
1087
                               (q[1] << 8) |
 
1088
                               (q[2] << 16) |
 
1089
                               (q[3] << 24) );
 
1090
}
 
1091
 
 
1092
 
 
1093
 
 
1094
static void tdfxDDRenderMode( GLcontext *ctx, GLenum mode )
 
1095
{
 
1096
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
 
1097
   FALLBACK( fxMesa, TDFX_FALLBACK_RENDER_MODE, (mode != GL_RENDER) );
 
1098
}
 
1099
 
 
1100
 
 
1101
 
 
1102
static void tdfxDDPrintState( const char *msg, GLuint flags )
 
1103
{
 
1104
   fprintf( stderr,
 
1105
            "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s%s%s\n",
 
1106
            msg,
 
1107
            flags,
 
1108
            (flags & TDFX_NEW_COLOR) ? "color, " : "",
 
1109
            (flags & TDFX_NEW_ALPHA) ? "alpha, " : "",
 
1110
            (flags & TDFX_NEW_DEPTH) ? "depth, " : "",
 
1111
            (flags & TDFX_NEW_RENDER) ? "render, " : "",
 
1112
            (flags & TDFX_NEW_FOG) ? "fog, " : "",
 
1113
            (flags & TDFX_NEW_STENCIL) ? "stencil, " : "",
 
1114
            (flags & TDFX_NEW_STIPPLE) ? "stipple, " : "",
 
1115
            (flags & TDFX_NEW_CLIP) ? "clip, " : "",
 
1116
            (flags & TDFX_NEW_VIEWPORT) ? "viewport, " : "",
 
1117
            (flags & TDFX_NEW_CULL) ? "cull, " : "",
 
1118
            (flags & TDFX_NEW_GLIDE) ? "glide, " : "",
 
1119
            (flags & TDFX_NEW_TEXTURE) ? "texture, " : "",
 
1120
            (flags & TDFX_NEW_CONTEXT) ? "context, " : "");
 
1121
}
 
1122
 
 
1123
 
 
1124
 
 
1125
void tdfxDDUpdateHwState( GLcontext *ctx )
 
1126
{
 
1127
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
 
1128
   int new_state = fxMesa->new_state;
 
1129
 
 
1130
   if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) {
 
1131
      fprintf( stderr, "%s()\n", __FUNCTION__ );
 
1132
   }
 
1133
 
 
1134
   if ( new_state )
 
1135
   {
 
1136
      FLUSH_BATCH( fxMesa );
 
1137
 
 
1138
      fxMesa->new_state = 0;
 
1139
 
 
1140
      if ( 0 )
 
1141
         tdfxDDPrintState( "tdfxUpdateHwState", new_state );
 
1142
 
 
1143
      /* Update the various parts of the context's state.
 
1144
       */
 
1145
      if ( new_state & TDFX_NEW_ALPHA ) {
 
1146
         tdfxUpdateAlphaMode( ctx );
 
1147
      }
 
1148
 
 
1149
      if ( new_state & TDFX_NEW_DEPTH )
 
1150
         tdfxUpdateZMode( ctx );
 
1151
 
 
1152
      if ( new_state & TDFX_NEW_FOG )
 
1153
         tdfxUpdateFogAttrib( ctx );
 
1154
 
 
1155
      if ( new_state & TDFX_NEW_CLIP )
 
1156
         tdfxUpdateClipping( ctx );
 
1157
 
 
1158
      if ( new_state & TDFX_NEW_STIPPLE )
 
1159
         tdfxUpdateStipple( ctx );
 
1160
 
 
1161
      if ( new_state & TDFX_NEW_CULL )
 
1162
         tdfxUpdateCull( ctx );
 
1163
 
 
1164
      if ( new_state & TDFX_NEW_LINE )
 
1165
         tdfxUpdateLine( ctx );
 
1166
 
 
1167
      if ( new_state & TDFX_NEW_VIEWPORT )
 
1168
         tdfxUpdateViewport( ctx );
 
1169
 
 
1170
      if ( new_state & TDFX_NEW_RENDER )
 
1171
         tdfxUpdateRenderAttrib( ctx );
 
1172
 
 
1173
      if ( new_state & TDFX_NEW_STENCIL )
 
1174
         tdfxUpdateStencil( ctx );
 
1175
 
 
1176
      if ( new_state & TDFX_NEW_TEXTURE ) {
 
1177
         tdfxUpdateTextureState( ctx );
 
1178
      }
 
1179
      else if ( new_state & TDFX_NEW_TEXTURE_BIND ) {
 
1180
         tdfxUpdateTextureBinding( ctx );
 
1181
      }
 
1182
   }
 
1183
 
 
1184
   if ( 0 ) {
 
1185
      FxI32 bias = (FxI32) (ctx->Polygon.OffsetUnits * TDFX_DEPTH_BIAS_SCALE);
 
1186
 
 
1187
      if ( fxMesa->Depth.Bias != bias ) {
 
1188
         fxMesa->Depth.Bias = bias;
 
1189
         fxMesa->dirty |= TDFX_UPLOAD_DEPTH_BIAS;
 
1190
      }
 
1191
   }
 
1192
 
 
1193
   if ( fxMesa->dirty ) {
 
1194
      LOCK_HARDWARE( fxMesa );
 
1195
      tdfxEmitHwStateLocked( fxMesa );
 
1196
      UNLOCK_HARDWARE( fxMesa );
 
1197
   }
 
1198
}
 
1199
 
 
1200
 
 
1201
static void tdfxDDInvalidateState( GLcontext *ctx, GLuint new_state )
 
1202
{
 
1203
   _swrast_InvalidateState( ctx, new_state );
 
1204
   _swsetup_InvalidateState( ctx, new_state );
 
1205
   _ac_InvalidateState( ctx, new_state );
 
1206
   _tnl_InvalidateState( ctx, new_state );
 
1207
   TDFX_CONTEXT(ctx)->new_gl_state |= new_state;
 
1208
}
 
1209
 
 
1210
 
 
1211
 
 
1212
/* Initialize the context's Glide state mirror.  These values will be
 
1213
 * used as Glide function call parameters when the time comes.
 
1214
 */
 
1215
void tdfxInitState( tdfxContextPtr fxMesa )
 
1216
{
 
1217
   GLcontext *ctx = fxMesa->glCtx;
 
1218
   GLint i;
 
1219
 
 
1220
   fxMesa->ColorCombine.Function        = GR_COMBINE_FUNCTION_LOCAL;
 
1221
   fxMesa->ColorCombine.Factor          = GR_COMBINE_FACTOR_NONE;
 
1222
   fxMesa->ColorCombine.Local           = GR_COMBINE_LOCAL_ITERATED;
 
1223
   fxMesa->ColorCombine.Other           = GR_COMBINE_OTHER_NONE;
 
1224
   fxMesa->ColorCombine.Invert          = FXFALSE;
 
1225
   fxMesa->AlphaCombine.Function        = GR_COMBINE_FUNCTION_LOCAL;
 
1226
   fxMesa->AlphaCombine.Factor          = GR_COMBINE_FACTOR_NONE;
 
1227
   fxMesa->AlphaCombine.Local           = GR_COMBINE_LOCAL_ITERATED;
 
1228
   fxMesa->AlphaCombine.Other           = GR_COMBINE_OTHER_NONE;
 
1229
   fxMesa->AlphaCombine.Invert          = FXFALSE;
 
1230
 
 
1231
   fxMesa->ColorCombineExt.SourceA      = GR_CMBX_ITRGB;
 
1232
   fxMesa->ColorCombineExt.ModeA        = GR_FUNC_MODE_X;
 
1233
   fxMesa->ColorCombineExt.SourceB      = GR_CMBX_ZERO;
 
1234
   fxMesa->ColorCombineExt.ModeB        = GR_FUNC_MODE_ZERO;
 
1235
   fxMesa->ColorCombineExt.SourceC      = GR_CMBX_ZERO;
 
1236
   fxMesa->ColorCombineExt.InvertC      = FXTRUE;
 
1237
   fxMesa->ColorCombineExt.SourceD      = GR_CMBX_ZERO;
 
1238
   fxMesa->ColorCombineExt.InvertD      = FXFALSE;
 
1239
   fxMesa->ColorCombineExt.Shift        = 0;
 
1240
   fxMesa->ColorCombineExt.Invert       = FXFALSE;
 
1241
   fxMesa->AlphaCombineExt.SourceA      = GR_CMBX_ITALPHA;
 
1242
   fxMesa->AlphaCombineExt.ModeA        = GR_FUNC_MODE_X;
 
1243
   fxMesa->AlphaCombineExt.SourceB      = GR_CMBX_ZERO;
 
1244
   fxMesa->AlphaCombineExt.ModeB        = GR_FUNC_MODE_ZERO;
 
1245
   fxMesa->AlphaCombineExt.SourceC      = GR_CMBX_ZERO;
 
1246
   fxMesa->AlphaCombineExt.InvertC      = FXTRUE;
 
1247
   fxMesa->AlphaCombineExt.SourceD      = GR_CMBX_ZERO;
 
1248
   fxMesa->AlphaCombineExt.InvertD      = FXFALSE;
 
1249
   fxMesa->AlphaCombineExt.Shift        = 0;
 
1250
   fxMesa->AlphaCombineExt.Invert       = FXFALSE;
 
1251
 
 
1252
   fxMesa->sScale0 = fxMesa->tScale0 = 1.0;
 
1253
   fxMesa->sScale1 = fxMesa->tScale1 = 1.0;
 
1254
 
 
1255
   fxMesa->TexPalette.Type = 0;
 
1256
   fxMesa->TexPalette.Data = NULL;
 
1257
 
 
1258
   for ( i = 0 ; i < TDFX_NUM_TMU ; i++ ) {
 
1259
      fxMesa->TexSource[i].StartAddress = 0;
 
1260
      fxMesa->TexSource[i].EvenOdd      = GR_MIPMAPLEVELMASK_EVEN;
 
1261
      fxMesa->TexSource[i].Info         = NULL;
 
1262
 
 
1263
      fxMesa->TexCombine[i].FunctionRGB         = 0;
 
1264
      fxMesa->TexCombine[i].FactorRGB           = 0;
 
1265
      fxMesa->TexCombine[i].FunctionAlpha       = 0;
 
1266
      fxMesa->TexCombine[i].FactorAlpha         = 0;
 
1267
      fxMesa->TexCombine[i].InvertRGB           = FXFALSE;
 
1268
      fxMesa->TexCombine[i].InvertAlpha         = FXFALSE;
 
1269
 
 
1270
      fxMesa->TexCombineExt[i].Alpha.SourceA    = 0;
 
1271
      /* XXX more state to init here */
 
1272
      fxMesa->TexCombineExt[i].Color.SourceA    = 0;
 
1273
      fxMesa->TexCombineExt[i].EnvColor        = 0x0;
 
1274
 
 
1275
      fxMesa->TexParams[i].sClamp       = GR_TEXTURECLAMP_WRAP;
 
1276
      fxMesa->TexParams[i].tClamp       = GR_TEXTURECLAMP_WRAP;
 
1277
      fxMesa->TexParams[i].minFilt      = GR_TEXTUREFILTER_POINT_SAMPLED;
 
1278
      fxMesa->TexParams[i].magFilt      = GR_TEXTUREFILTER_BILINEAR;
 
1279
      fxMesa->TexParams[i].mmMode       = GR_MIPMAP_DISABLE;
 
1280
      fxMesa->TexParams[i].LODblend     = FXFALSE;
 
1281
      fxMesa->TexParams[i].LodBias      = 0.0;
 
1282
 
 
1283
      fxMesa->TexState.EnvMode[i]       = ~0;
 
1284
      fxMesa->TexState.TexFormat[i]     = ~0;
 
1285
      fxMesa->TexState.Enabled          = 0;
 
1286
   }
 
1287
 
 
1288
   if ( ctx->Visual.doubleBufferMode) {
 
1289
      fxMesa->DrawBuffer                = GR_BUFFER_BACKBUFFER;
 
1290
      fxMesa->ReadBuffer                = GR_BUFFER_BACKBUFFER;
 
1291
   } else {
 
1292
      fxMesa->DrawBuffer                = GR_BUFFER_FRONTBUFFER;
 
1293
      fxMesa->ReadBuffer                = GR_BUFFER_FRONTBUFFER;
 
1294
   }
 
1295
 
 
1296
   fxMesa->Color.ClearColor             = 0x00000000;
 
1297
   fxMesa->Color.ClearAlpha             = 0x00;
 
1298
   fxMesa->Color.ColorMask[RCOMP]       = FXTRUE;
 
1299
   fxMesa->Color.ColorMask[BCOMP]       = FXTRUE;
 
1300
   fxMesa->Color.ColorMask[GCOMP]       = FXTRUE;
 
1301
   fxMesa->Color.ColorMask[ACOMP]       = FXTRUE;
 
1302
   fxMesa->Color.MonoColor              = 0xffffffff;
 
1303
 
 
1304
   fxMesa->Color.AlphaFunc              = GR_CMP_ALWAYS;
 
1305
   fxMesa->Color.AlphaRef               = 0x00;
 
1306
   fxMesa->Color.BlendSrcRGB            = GR_BLEND_ONE;
 
1307
   fxMesa->Color.BlendDstRGB            = GR_BLEND_ZERO;
 
1308
   fxMesa->Color.BlendSrcA              = GR_BLEND_ONE;
 
1309
   fxMesa->Color.BlendSrcA              = GR_BLEND_ZERO;
 
1310
 
 
1311
   fxMesa->Color.Dither                 = GR_DITHER_2x2;
 
1312
 
 
1313
   if ( fxMesa->glCtx->Visual.depthBits > 0 ) {
 
1314
      fxMesa->Depth.Mode                = GR_DEPTHBUFFER_ZBUFFER;
 
1315
   } else {
 
1316
      fxMesa->Depth.Mode                = GR_DEPTHBUFFER_DISABLE;
 
1317
   }
 
1318
   fxMesa->Depth.Bias                   = 0;
 
1319
   fxMesa->Depth.Func                   = GR_CMP_LESS;
 
1320
   fxMesa->Depth.Clear                  = 0; /* computed later */
 
1321
   fxMesa->Depth.Mask                   = FXTRUE;
 
1322
 
 
1323
 
 
1324
   fxMesa->Fog.Mode                     = GR_FOG_DISABLE;
 
1325
   fxMesa->Fog.Color                    = 0x00000000;
 
1326
   fxMesa->Fog.Table                    = NULL;
 
1327
   fxMesa->Fog.Density                  = 1.0;
 
1328
   fxMesa->Fog.Near                     = 1.0;
 
1329
   fxMesa->Fog.Far                      = 1.0;
 
1330
 
 
1331
   fxMesa->Stencil.Function             = GR_CMP_ALWAYS;
 
1332
   fxMesa->Stencil.RefValue             = 0;
 
1333
   fxMesa->Stencil.ValueMask            = 0xff;
 
1334
   fxMesa->Stencil.WriteMask            = 0xff;
 
1335
   fxMesa->Stencil.FailFunc             = 0;
 
1336
   fxMesa->Stencil.ZFailFunc            = 0;
 
1337
   fxMesa->Stencil.ZPassFunc            = 0;
 
1338
   fxMesa->Stencil.Clear                = 0;
 
1339
 
 
1340
   fxMesa->Stipple.Mode                 = GR_STIPPLE_DISABLE;
 
1341
   fxMesa->Stipple.Pattern              = 0xffffffff;
 
1342
 
 
1343
   fxMesa->Scissor.minX                 = 0;
 
1344
   fxMesa->Scissor.minY                 = 0;
 
1345
   fxMesa->Scissor.maxX                 = 0;
 
1346
   fxMesa->Scissor.maxY                 = 0;
 
1347
 
 
1348
   fxMesa->Viewport.Mode                = GR_WINDOW_COORDS;
 
1349
   fxMesa->Viewport.X                   = 0;
 
1350
   fxMesa->Viewport.Y                   = 0;
 
1351
   fxMesa->Viewport.Width               = 0;
 
1352
   fxMesa->Viewport.Height              = 0;
 
1353
   fxMesa->Viewport.Near                = 0.0;
 
1354
   fxMesa->Viewport.Far                 = 0.0;
 
1355
 
 
1356
   fxMesa->CullMode                     = GR_CULL_DISABLE;
 
1357
 
 
1358
   fxMesa->Glide.ColorFormat            = GR_COLORFORMAT_ABGR;
 
1359
   fxMesa->Glide.Origin                 = GR_ORIGIN_LOWER_LEFT;
 
1360
   fxMesa->Glide.Initialized            = FXFALSE;
 
1361
}
 
1362
 
 
1363
 
 
1364
 
 
1365
void tdfxDDInitStateFuncs( GLcontext *ctx )
 
1366
{
 
1367
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
 
1368
 
 
1369
   ctx->Driver.UpdateState              = tdfxDDInvalidateState;
 
1370
 
 
1371
 
 
1372
   /* State notification callbacks:
 
1373
    */
 
1374
   ctx->Driver.ClearIndex               = NULL;
 
1375
   ctx->Driver.ClearColor               = tdfxDDClearColor;
 
1376
   ctx->Driver.SetDrawBuffer            = tdfxDDSetDrawBuffer;
 
1377
 
 
1378
   ctx->Driver.IndexMask                = NULL;
 
1379
   ctx->Driver.ColorMask                = tdfxDDColorMask;
 
1380
 
 
1381
   ctx->Driver.AlphaFunc                = tdfxDDAlphaFunc;
 
1382
   ctx->Driver.BlendEquation            = tdfxDDBlendEquation;
 
1383
   ctx->Driver.BlendFunc                = tdfxDDBlendFunc;
 
1384
   ctx->Driver.BlendFuncSeparate        = tdfxDDBlendFuncSeparate;
 
1385
   ctx->Driver.ClearDepth               = tdfxDDClearDepth;
 
1386
   ctx->Driver.ClearStencil             = NULL;
 
1387
   ctx->Driver.CullFace                 = tdfxDDCullFace;
 
1388
   ctx->Driver.FrontFace                = tdfxDDFrontFace;
 
1389
   ctx->Driver.DepthFunc                = tdfxDDDepthFunc;
 
1390
   ctx->Driver.DepthMask                = tdfxDDDepthMask;
 
1391
   ctx->Driver.DepthRange               = tdfxDDDepthRange;
 
1392
   ctx->Driver.Enable                   = tdfxDDEnable;
 
1393
   ctx->Driver.Fogfv                    = tdfxDDFogfv;
 
1394
   ctx->Driver.Hint                     = NULL;
 
1395
   ctx->Driver.Lightfv                  = NULL;
 
1396
   ctx->Driver.LightModelfv             = tdfxDDLightModelfv;
 
1397
   ctx->Driver.LineStipple              = NULL;
 
1398
   ctx->Driver.LineWidth                = tdfxDDLineWidth;
 
1399
   ctx->Driver.PolygonStipple           = tdfxDDPolygonStipple;
 
1400
   ctx->Driver.RenderMode               = tdfxDDRenderMode;
 
1401
   ctx->Driver.Scissor                  = tdfxDDScissor;
 
1402
   ctx->Driver.ShadeModel               = tdfxDDShadeModel;
 
1403
 
 
1404
   ctx->Driver.BindTexture              = tdfxDDBindTexture;
 
1405
   ctx->Driver.DeleteTexture            = tdfxDDDeleteTexture;
 
1406
   ctx->Driver.TexEnv                   = tdfxDDTexEnv;
 
1407
   ctx->Driver.TexParameter             = tdfxDDTexParameter;
 
1408
   ctx->Driver.ChooseTextureFormat      = tdfxDDChooseTextureFormat;
 
1409
   ctx->Driver.TexImage2D               = tdfxDDTexImage2D;
 
1410
   ctx->Driver.TexSubImage2D            = tdfxDDTexSubImage2D;
 
1411
   /*
 
1412
   ctx->Driver.TexImage2D               = _mesa_store_teximage2d;
 
1413
   ctx->Driver.TexSubImage2D            = _mesa_store_texsubimage2d;
 
1414
   */
 
1415
 
 
1416
   ctx->Driver.TexImage1D               = _mesa_store_teximage1d;
 
1417
   ctx->Driver.TexImage3D               = _mesa_store_teximage3d;
 
1418
   ctx->Driver.TexSubImage1D            = _mesa_store_texsubimage1d;
 
1419
   ctx->Driver.TexSubImage3D            = _mesa_store_texsubimage3d;
 
1420
   ctx->Driver.CopyTexImage1D           = _swrast_copy_teximage1d;
 
1421
   ctx->Driver.CopyTexImage2D           = _swrast_copy_teximage2d;
 
1422
   ctx->Driver.CopyTexSubImage1D        = _swrast_copy_texsubimage1d;
 
1423
   ctx->Driver.CopyTexSubImage2D        = _swrast_copy_texsubimage2d;
 
1424
   ctx->Driver.CopyTexSubImage3D        = _swrast_copy_texsubimage3d;
 
1425
   ctx->Driver.TestProxyTexImage        = _mesa_test_proxy_teximage;
 
1426
 
 
1427
/*     ctx->Driver.GetTexImage          = tdfxDDGetTexImage; */
 
1428
   ctx->Driver.UpdateTexturePalette     = tdfxDDTexturePalette;
 
1429
 
 
1430
   if ( fxMesa->haveHwStencil ) {
 
1431
      ctx->Driver.StencilFunc           = tdfxDDStencilFunc;
 
1432
      ctx->Driver.StencilMask           = tdfxDDStencilMask;
 
1433
      ctx->Driver.StencilOp             = tdfxDDStencilOp;
 
1434
   } else {
 
1435
      ctx->Driver.StencilFunc           = NULL;
 
1436
      ctx->Driver.StencilMask           = NULL;
 
1437
      ctx->Driver.StencilOp             = NULL;
 
1438
   }
 
1439
 
 
1440
   ctx->Driver.Viewport                 = tdfxDDViewport;
 
1441
 
 
1442
 
 
1443
   /* Swrast hooks for imaging extensions:
 
1444
    */
 
1445
   ctx->Driver.CopyColorTable = _swrast_CopyColorTable;
 
1446
   ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable;
 
1447
   ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
 
1448
   ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
 
1449
}