~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_render.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_render.c,v 1.4 2002/02/22 21:45:03 dawes 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
 *
 
36
 */
 
37
 
 
38
#include "tdfx_context.h"
 
39
#include "tdfx_render.h"
 
40
#include "tdfx_state.h"
 
41
#include "tdfx_texman.h"
 
42
#include "swrast/swrast.h"
 
43
 
 
44
/* Clear the color and/or depth buffers.
 
45
 */
 
46
static void tdfxDDClear( GLcontext *ctx,
 
47
                         GLbitfield mask, GLboolean all,
 
48
                         GLint x, GLint y, GLint width, GLint height )
 
49
{
 
50
   tdfxContextPtr fxMesa = (tdfxContextPtr) ctx->DriverCtx;
 
51
   GLbitfield softwareMask = mask & (DD_ACCUM_BIT);
 
52
   const GLuint stencil_size =
 
53
      fxMesa->haveHwStencil ? fxMesa->glCtx->Visual.stencilBits : 0;
 
54
 
 
55
   if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) {
 
56
      fprintf( stderr, "%s( %d, %d, %d, %d )\n",
 
57
               __FUNCTION__, (int) x, (int) y, (int) width, (int) height );
 
58
   }
 
59
 
 
60
   /* Need this check to respond to glScissor and clipping updates */
 
61
   if ((fxMesa->new_state & (TDFX_NEW_CLIP | TDFX_NEW_DEPTH)) ||
 
62
       (fxMesa->dirty & TDFX_UPLOAD_COLOR_MASK)) {
 
63
      tdfxDDUpdateHwState(ctx);
 
64
   }
 
65
 
 
66
   /* we can't clear accum buffers */
 
67
   mask &= ~(DD_ACCUM_BIT);
 
68
 
 
69
   if (mask & DD_STENCIL_BIT) {
 
70
      if (!fxMesa->haveHwStencil || ctx->Stencil.WriteMask != 0xff) {
 
71
         /* Napalm seems to have trouble with stencil write masks != 0xff */
 
72
         /* do stencil clear in software */
 
73
         mask &= ~(DD_STENCIL_BIT);
 
74
         softwareMask |= DD_STENCIL_BIT;
 
75
      }
 
76
   }
 
77
 
 
78
   if (fxMesa->glCtx->Visual.redBits != 8) {
 
79
      /* can only do color masking if running in 24/32bpp on Napalm */
 
80
      if (ctx->Color.ColorMask[RCOMP] != ctx->Color.ColorMask[GCOMP] ||
 
81
          ctx->Color.ColorMask[GCOMP] != ctx->Color.ColorMask[BCOMP]) {
 
82
         softwareMask |= (mask & (DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT));
 
83
         mask &= ~(DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT);
 
84
      }
 
85
   }
 
86
 
 
87
   if (fxMesa->haveHwStencil) {
 
88
      /*
 
89
       * If we want to clear stencil, it must be enabled
 
90
       * in the HW, even if the stencil test is not enabled
 
91
       * in the OGL state.
 
92
       */
 
93
      LOCK_HARDWARE(fxMesa);
 
94
      if (mask & DD_STENCIL_BIT) {
 
95
         fxMesa->Glide.grStencilMask(/*ctx->Stencil.WriteMask*/ 0xff);
 
96
         /* set stencil ref value = desired clear value */
 
97
         fxMesa->Glide.grStencilFunc(GR_CMP_ALWAYS,
 
98
                                     ctx->Stencil.Clear, 0xff);
 
99
         fxMesa->Glide.grStencilOp(GR_STENCILOP_REPLACE,
 
100
                                   GR_STENCILOP_REPLACE, GR_STENCILOP_REPLACE);
 
101
         fxMesa->Glide.grEnable(GR_STENCIL_MODE_EXT);
 
102
      }
 
103
      else {
 
104
         fxMesa->Glide.grDisable(GR_STENCIL_MODE_EXT);
 
105
      }
 
106
      UNLOCK_HARDWARE(fxMesa);
 
107
   }
 
108
 
 
109
   /*
 
110
    * This may be ugly, but it's needed in order to work around a number
 
111
    * of Glide bugs.
 
112
    */
 
113
   BEGIN_CLIP_LOOP(fxMesa);
 
114
   {
 
115
      /*
 
116
       * This could probably be done fancier but doing each possible case
 
117
       * explicitly is less error prone.
 
118
       */
 
119
      switch (mask & ~DD_STENCIL_BIT) {
 
120
      case DD_BACK_LEFT_BIT | DD_DEPTH_BIT:
 
121
         /* back buffer & depth */
 
122
         FX_grColorMaskv_NoLock(ctx, true4); /* work around Voodoo3 bug */
 
123
         fxMesa->Glide.grDepthMask(FXTRUE);
 
124
         fxMesa->Glide.grRenderBuffer(GR_BUFFER_BACKBUFFER);
 
125
         if (stencil_size > 0) {
 
126
            fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor,
 
127
                                           fxMesa->Color.ClearAlpha,
 
128
                                           fxMesa->Depth.Clear,
 
129
                                           (FxU32) ctx->Stencil.Clear);
 
130
         }
 
131
         else
 
132
            fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor,
 
133
                                        fxMesa->Color.ClearAlpha,
 
134
                                        fxMesa->Depth.Clear);
 
135
         if (!ctx->Depth.Mask || !ctx->Depth.Test) {
 
136
            fxMesa->Glide.grDepthMask(FXFALSE);
 
137
         }
 
138
         break;
 
139
      case DD_FRONT_LEFT_BIT | DD_DEPTH_BIT:
 
140
         /* XXX it appears that the depth buffer isn't cleared when
 
141
          * glRenderBuffer(GR_BUFFER_FRONTBUFFER) is set.
 
142
          * This is a work-around/
 
143
          */
 
144
         /* clear depth */
 
145
         fxMesa->Glide.grDepthMask(FXTRUE);
 
146
         fxMesa->Glide.grRenderBuffer(GR_BUFFER_BACKBUFFER);
 
147
         FX_grColorMaskv_NoLock(ctx, false4);
 
148
         if (stencil_size > 0)
 
149
            fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor,
 
150
                                           fxMesa->Color.ClearAlpha,
 
151
                                           fxMesa->Depth.Clear,
 
152
                                           (FxU32) ctx->Stencil.Clear);
 
153
         else
 
154
            fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor,
 
155
                                        fxMesa->Color.ClearAlpha,
 
156
                                        fxMesa->Depth.Clear);
 
157
         /* clear front */
 
158
         FX_grColorMaskv_NoLock(ctx, true4);
 
159
         fxMesa->Glide.grRenderBuffer(GR_BUFFER_FRONTBUFFER);
 
160
         if (stencil_size > 0)
 
161
            fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor,
 
162
                                           fxMesa->Color.ClearAlpha,
 
163
                                           fxMesa->Depth.Clear,
 
164
                                           (FxU32) ctx->Stencil.Clear);
 
165
         else
 
166
            fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor,
 
167
                                        fxMesa->Color.ClearAlpha,
 
168
                                        fxMesa->Depth.Clear);
 
169
         if (!ctx->Depth.Mask || !ctx->Depth.Test) {
 
170
            fxMesa->Glide.grDepthMask(FXFALSE);
 
171
         }
 
172
         break;
 
173
      case DD_BACK_LEFT_BIT:
 
174
         /* back buffer only */
 
175
         fxMesa->Glide.grDepthMask(FXFALSE);
 
176
         fxMesa->Glide.grRenderBuffer(GR_BUFFER_BACKBUFFER);
 
177
         if (stencil_size > 0)
 
178
            fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor,
 
179
                                           fxMesa->Color.ClearAlpha,
 
180
                                           fxMesa->Depth.Clear,
 
181
                                           (FxU32) ctx->Stencil.Clear);
 
182
         else
 
183
            fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor,
 
184
                                        fxMesa->Color.ClearAlpha,
 
185
                                        fxMesa->Depth.Clear);
 
186
         if (ctx->Depth.Mask && ctx->Depth.Test) {
 
187
            fxMesa->Glide.grDepthMask(FXTRUE);
 
188
         }
 
189
         break;
 
190
      case DD_FRONT_LEFT_BIT:
 
191
         /* front buffer only */
 
192
         fxMesa->Glide.grDepthMask(FXFALSE);
 
193
         fxMesa->Glide.grRenderBuffer(GR_BUFFER_FRONTBUFFER);
 
194
         if (stencil_size > 0)
 
195
            fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor,
 
196
                                           fxMesa->Color.ClearAlpha,
 
197
                                           fxMesa->Depth.Clear,
 
198
                                           (FxU32) ctx->Stencil.Clear);
 
199
         else
 
200
            fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor,
 
201
                                        fxMesa->Color.ClearAlpha,
 
202
                                        fxMesa->Depth.Clear);
 
203
         if (ctx->Depth.Mask && ctx->Depth.Test) {
 
204
            fxMesa->Glide.grDepthMask(FXTRUE);
 
205
         }
 
206
         break;
 
207
      case DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT:
 
208
         /* front and back */
 
209
         fxMesa->Glide.grDepthMask(FXFALSE);
 
210
         fxMesa->Glide.grRenderBuffer(GR_BUFFER_BACKBUFFER);
 
211
         if (stencil_size > 0)
 
212
            fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor,
 
213
                                           fxMesa->Color.ClearAlpha,
 
214
                                           fxMesa->Depth.Clear,
 
215
                                           (FxU32) ctx->Stencil.Clear);
 
216
         else
 
217
            fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor,
 
218
                                        fxMesa->Color.ClearAlpha,
 
219
                                        fxMesa->Depth.Clear);
 
220
         fxMesa->Glide.grRenderBuffer(GR_BUFFER_FRONTBUFFER);
 
221
         if (stencil_size > 0)
 
222
            fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor,
 
223
                                           fxMesa->Color.ClearAlpha,
 
224
                                           fxMesa->Depth.Clear,
 
225
                                           (FxU32) ctx->Stencil.Clear);
 
226
         else
 
227
            fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor,
 
228
                                        fxMesa->Color.ClearAlpha,
 
229
                                        fxMesa->Depth.Clear);
 
230
         if (ctx->Depth.Mask && ctx->Depth.Test) {
 
231
            fxMesa->Glide.grDepthMask(FXTRUE);
 
232
         }
 
233
         break;
 
234
      case DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT | DD_DEPTH_BIT:
 
235
         /* clear front */
 
236
         fxMesa->Glide.grDepthMask(FXFALSE);
 
237
         fxMesa->Glide.grRenderBuffer(GR_BUFFER_FRONTBUFFER);
 
238
         if (stencil_size > 0)
 
239
            fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor,
 
240
                                           fxMesa->Color.ClearAlpha,
 
241
                                           fxMesa->Depth.Clear,
 
242
                                           (FxU32) ctx->Stencil.Clear);
 
243
         else
 
244
            fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor,
 
245
                                        fxMesa->Color.ClearAlpha,
 
246
                                        fxMesa->Depth.Clear);
 
247
         /* clear back and depth */
 
248
         fxMesa->Glide.grDepthMask(FXTRUE);
 
249
         fxMesa->Glide.grRenderBuffer(GR_BUFFER_BACKBUFFER);
 
250
         if (stencil_size > 0)
 
251
            fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor,
 
252
                                           fxMesa->Color.ClearAlpha,
 
253
                                           fxMesa->Depth.Clear,
 
254
                                           (FxU32) ctx->Stencil.Clear);
 
255
         else
 
256
            fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor,
 
257
                                        fxMesa->Color.ClearAlpha,
 
258
                                        fxMesa->Depth.Clear);
 
259
         if (!ctx->Depth.Mask || !ctx->Depth.Mask) {
 
260
            fxMesa->Glide.grDepthMask(FXFALSE);
 
261
         }
 
262
         break;
 
263
      case DD_DEPTH_BIT:
 
264
         /* just the depth buffer */
 
265
         fxMesa->Glide.grRenderBuffer(GR_BUFFER_BACKBUFFER);
 
266
         FX_grColorMaskv_NoLock(ctx, false4);
 
267
         fxMesa->Glide.grDepthMask(FXTRUE);
 
268
         if (stencil_size > 0)
 
269
            fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor,
 
270
                                           fxMesa->Color.ClearAlpha,
 
271
                                           fxMesa->Depth.Clear,
 
272
                                           (FxU32) ctx->Stencil.Clear);
 
273
         else
 
274
            fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor,
 
275
                                        fxMesa->Color.ClearAlpha,
 
276
                                        fxMesa->Depth.Clear);
 
277
         FX_grColorMaskv_NoLock(ctx, true4);
 
278
         if (ctx->Color.DrawDestMask & FRONT_LEFT_BIT)
 
279
            fxMesa->Glide.grRenderBuffer(GR_BUFFER_FRONTBUFFER);
 
280
         if (!ctx->Depth.Test || !ctx->Depth.Mask)
 
281
            fxMesa->Glide.grDepthMask(FXFALSE);
 
282
         break;
 
283
      default:
 
284
         /* clear no color buffers or depth buffer but might clear stencil */
 
285
         if (stencil_size > 0 && (mask & DD_STENCIL_BIT)) {
 
286
            /* XXX need this RenderBuffer call to work around Glide bug */
 
287
            fxMesa->Glide.grRenderBuffer(GR_BUFFER_BACKBUFFER);
 
288
            fxMesa->Glide.grDepthMask(FXFALSE);
 
289
            FX_grColorMaskv_NoLock(ctx, false4);
 
290
            fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor,
 
291
                                           fxMesa->Color.ClearAlpha,
 
292
                                           fxMesa->Depth.Clear,
 
293
                                           (FxU32) ctx->Stencil.Clear);
 
294
            if (ctx->Depth.Mask && ctx->Depth.Test) {
 
295
               fxMesa->Glide.grDepthMask(FXTRUE);
 
296
            }
 
297
            FX_grColorMaskv_NoLock(ctx, true4);
 
298
            if (ctx->Color.DrawDestMask & FRONT_LEFT_BIT)
 
299
               fxMesa->Glide.grRenderBuffer(GR_BUFFER_FRONTBUFFER);
 
300
         }
 
301
      }
 
302
   }
 
303
   END_CLIP_LOOP(fxMesa);
 
304
 
 
305
   if (fxMesa->haveHwStencil && (mask & DD_STENCIL_BIT)) {
 
306
      /* We changed the stencil state above.  Signal that we need to
 
307
       * upload it again.
 
308
       */
 
309
      fxMesa->dirty |= TDFX_UPLOAD_STENCIL;
 
310
   }
 
311
 
 
312
   if (softwareMask)
 
313
      _swrast_Clear( ctx, softwareMask, all, x, y, width, height );
 
314
}
 
315
 
 
316
 
 
317
 
 
318
static void tdfxDDFinish( GLcontext *ctx )
 
319
{
 
320
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
 
321
 
 
322
   FLUSH_BATCH( fxMesa );
 
323
 
 
324
   LOCK_HARDWARE( fxMesa );
 
325
   fxMesa->Glide.grFinish();
 
326
   UNLOCK_HARDWARE( fxMesa );
 
327
}
 
328
 
 
329
static void tdfxDDFlush( GLcontext *ctx )
 
330
{
 
331
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
 
332
 
 
333
   FLUSH_BATCH( fxMesa );
 
334
 
 
335
   LOCK_HARDWARE( fxMesa );
 
336
   fxMesa->Glide.grFlush();
 
337
   UNLOCK_HARDWARE( fxMesa );
 
338
}
 
339
 
 
340
 
 
341
#if 0
 
342
static const char *texSource(int k)
 
343
{
 
344
   switch (k) {
 
345
      case GR_CMBX_ZERO:
 
346
         return "GR_CMBX_ZERO";
 
347
      case GR_CMBX_TEXTURE_ALPHA:
 
348
         return "GR_CMBX_TEXTURE_ALPHA";
 
349
      case GR_CMBX_ALOCAL:
 
350
         return "GR_CMBX_ALOCAL";
 
351
      case GR_CMBX_AOTHER:
 
352
         return "GR_CMBX_AOTHER";
 
353
      case GR_CMBX_B:
 
354
         return "GR_CMBX_B";
 
355
      case GR_CMBX_CONSTANT_ALPHA:
 
356
         return "GR_CMBX_CONSTANT_ALPHA";
 
357
      case GR_CMBX_CONSTANT_COLOR:
 
358
         return "GR_CMBX_CONSTANT_COLOR";
 
359
      case GR_CMBX_DETAIL_FACTOR:
 
360
         return "GR_CMBX_DETAIL_FACTOR";
 
361
      case GR_CMBX_ITALPHA:
 
362
         return "GR_CMBX_ITALPHA";
 
363
      case GR_CMBX_ITRGB:
 
364
         return "GR_CMBX_ITRGB";
 
365
      case GR_CMBX_LOCAL_TEXTURE_ALPHA:
 
366
         return "GR_CMBX_LOCAL_TEXTURE_ALPHA";
 
367
      case GR_CMBX_LOCAL_TEXTURE_RGB:
 
368
         return "GR_CMBX_LOCAL_TEXTURE_RGB";
 
369
      case GR_CMBX_LOD_FRAC:
 
370
         return "GR_CMBX_LOD_FRAC";
 
371
      case GR_CMBX_OTHER_TEXTURE_ALPHA:
 
372
         return "GR_CMBX_OTHER_TEXTURE_ALPHA";
 
373
      case GR_CMBX_OTHER_TEXTURE_RGB:
 
374
         return "GR_CMBX_OTHER_TEXTURE_RGB";
 
375
      case GR_CMBX_TEXTURE_RGB:
 
376
         return "GR_CMBX_TEXTURE_RGB";
 
377
      case GR_CMBX_TMU_CALPHA:
 
378
         return "GR_CMBX_TMU_CALPHA";
 
379
      case GR_CMBX_TMU_CCOLOR:
 
380
         return "GR_CMBX_TMU_CCOLOR";
 
381
      default:
 
382
         return "";
 
383
   }
 
384
}
 
385
#endif
 
386
 
 
387
#if 0
 
388
static const char *texMode(int k)
 
389
{
 
390
   switch (k) {
 
391
      case GR_FUNC_MODE_ZERO:
 
392
         return "GR_FUNC_MODE_ZERO";
 
393
      case GR_FUNC_MODE_X:
 
394
         return "GR_FUNC_MODE_X";
 
395
      case GR_FUNC_MODE_ONE_MINUS_X:
 
396
         return "GR_FUNC_MODE_ONE_MINUS_X";
 
397
      case GR_FUNC_MODE_NEGATIVE_X:
 
398
         return "GR_FUNC_MODE_NEGATIVE_X";
 
399
      case GR_FUNC_MODE_X_MINUS_HALF:
 
400
         return "GR_FUNC_MODE_X_MINUS_HALF";
 
401
      default:
 
402
         return "";
 
403
   }
 
404
}
 
405
#endif
 
406
 
 
407
#if 0
 
408
static const char *texInvert(int k)
 
409
{
 
410
   return k ? "FXTRUE" : "FXFALSE";
 
411
}
 
412
#endif
 
413
 
 
414
static void uploadTextureEnv( tdfxContextPtr fxMesa )
 
415
{
 
416
   if (TDFX_IS_NAPALM(fxMesa)) {
 
417
      int unit;
 
418
      for (unit = 0; unit < TDFX_NUM_TMU; unit++) {
 
419
#if 0
 
420
         printf("upload env %d\n", unit);
 
421
         printf("   cSourceA = %s\t", texSource(fxMesa->TexCombineExt[unit].Color.SourceA));
 
422
         printf("     cModeA = %s\n", texMode(fxMesa->TexCombineExt[unit].Color.ModeA));
 
423
         printf("   cSourceB = %s\t", texSource(fxMesa->TexCombineExt[unit].Color.SourceB));
 
424
         printf("     cModeB = %s\n", texMode(fxMesa->TexCombineExt[unit].Color.ModeB));
 
425
         printf("   cSourceC = %s\t", texSource(fxMesa->TexCombineExt[unit].Color.SourceC));
 
426
         printf("   cInvertC = %s\n", texInvert(fxMesa->TexCombineExt[unit].Color.InvertC));
 
427
         printf("   cSourceD = %s\t", texSource(fxMesa->TexCombineExt[unit].Color.SourceD));
 
428
         printf("   cInvertD = %s\n", texInvert(fxMesa->TexCombineExt[unit].Color.InvertD));
 
429
         printf("     cShift = %d\t", fxMesa->TexCombineExt[unit].Color.Shift);
 
430
         printf("    cInvert = %d\n", fxMesa->TexCombineExt[unit].Color.Invert);
 
431
         printf("   aSourceA = %s\t", texSource(fxMesa->TexCombineExt[unit].Alpha.SourceA));
 
432
         printf("     aModeA = %s\n", texMode(fxMesa->TexCombineExt[unit].Alpha.ModeA));
 
433
         printf("   aSourceB = %s\t", texSource(fxMesa->TexCombineExt[unit].Alpha.SourceB));
 
434
         printf("     aModeB = %s\n", texMode(fxMesa->TexCombineExt[unit].Alpha.ModeB));
 
435
         printf("   aSourceC = %s\t", texSource(fxMesa->TexCombineExt[unit].Alpha.SourceC));
 
436
         printf("   aInvertC = %s\n", texInvert(fxMesa->TexCombineExt[unit].Alpha.InvertC));
 
437
         printf("   aSourceD = %s\t", texSource(fxMesa->TexCombineExt[unit].Alpha.SourceD));
 
438
         printf("   aInvertD = %s\n", texInvert(fxMesa->TexCombineExt[unit].Alpha.InvertD));
 
439
         printf("     aShift = %d\t", fxMesa->TexCombineExt[unit].Alpha.Shift);
 
440
         printf("    aInvert = %d\n", fxMesa->TexCombineExt[unit].Alpha.Invert);
 
441
         printf("      Color = 0x%08x\n", fxMesa->TexCombineExt[unit].EnvColor);
 
442
#endif
 
443
         fxMesa->Glide.grTexColorCombineExt(TDFX_TMU0 + unit,
 
444
                                     fxMesa->TexCombineExt[unit].Color.SourceA,
 
445
                                     fxMesa->TexCombineExt[unit].Color.ModeA,
 
446
                                     fxMesa->TexCombineExt[unit].Color.SourceB,
 
447
                                     fxMesa->TexCombineExt[unit].Color.ModeB,
 
448
                                     fxMesa->TexCombineExt[unit].Color.SourceC,
 
449
                                     fxMesa->TexCombineExt[unit].Color.InvertC,
 
450
                                     fxMesa->TexCombineExt[unit].Color.SourceD,
 
451
                                     fxMesa->TexCombineExt[unit].Color.InvertD,
 
452
                                     fxMesa->TexCombineExt[unit].Color.Shift,
 
453
                                     fxMesa->TexCombineExt[unit].Color.Invert);
 
454
         fxMesa->Glide.grTexAlphaCombineExt(TDFX_TMU0 + unit,
 
455
                                     fxMesa->TexCombineExt[unit].Alpha.SourceA,
 
456
                                     fxMesa->TexCombineExt[unit].Alpha.ModeA,
 
457
                                     fxMesa->TexCombineExt[unit].Alpha.SourceB,
 
458
                                     fxMesa->TexCombineExt[unit].Alpha.ModeB,
 
459
                                     fxMesa->TexCombineExt[unit].Alpha.SourceC,
 
460
                                     fxMesa->TexCombineExt[unit].Alpha.InvertC,
 
461
                                     fxMesa->TexCombineExt[unit].Alpha.SourceD,
 
462
                                     fxMesa->TexCombineExt[unit].Alpha.InvertD,
 
463
                                     fxMesa->TexCombineExt[unit].Alpha.Shift,
 
464
                                     fxMesa->TexCombineExt[unit].Alpha.Invert);
 
465
         fxMesa->Glide.grConstantColorValueExt(TDFX_TMU0 + unit,
 
466
                                        fxMesa->TexCombineExt[unit].EnvColor);
 
467
      }
 
468
   }
 
469
   else {
 
470
      /* Voodoo3 */
 
471
      int unit;
 
472
      for (unit = 0; unit < TDFX_NUM_TMU; unit++) {
 
473
         struct tdfx_texcombine *comb = &fxMesa->TexCombine[unit];
 
474
         fxMesa->Glide.grTexCombine(TDFX_TMU0 + unit,
 
475
                                    comb->FunctionRGB,
 
476
                                    comb->FactorRGB,
 
477
                                    comb->FunctionAlpha,
 
478
                                    comb->FactorAlpha,
 
479
                                    comb->InvertRGB,
 
480
                                    comb->InvertAlpha);
 
481
      }
 
482
   }
 
483
}
 
484
 
 
485
 
 
486
static void uploadTextureParams( tdfxContextPtr fxMesa )
 
487
{
 
488
   int unit;
 
489
   for (unit = 0; unit < TDFX_NUM_TMU; unit++) {
 
490
      const struct tdfx_texparams *p = &fxMesa->TexParams[unit];
 
491
      /*
 
492
      printf("upload params %d\n", unit);
 
493
      printf("   clamp %x %x\n", env->sClamp, env->tClamp);
 
494
      printf("   filter %x %x\n", env->minFilt, env->magFilt);
 
495
      printf("   mipmap %x %x\n", env->mmMode, env->LODblend);
 
496
      printf("   lod bias %f\n", env->LodBias);
 
497
      */
 
498
      fxMesa->Glide.grTexClampMode(GR_TMU0 + unit, p->sClamp, p->tClamp);
 
499
      fxMesa->Glide.grTexFilterMode(GR_TMU0 + unit, p->minFilt, p->magFilt);
 
500
      fxMesa->Glide.grTexMipMapMode(GR_TMU0 + unit, p->mmMode, p->LODblend);
 
501
      fxMesa->Glide.grTexLodBiasValue(GR_TMU0 + unit, p->LodBias);
 
502
   }
 
503
}
 
504
 
 
505
 
 
506
static void uploadTextureSource( tdfxContextPtr fxMesa )
 
507
{
 
508
   int unit;
 
509
   for (unit = 0; unit < TDFX_NUM_TMU; unit++) {
 
510
      const struct tdfx_texsource *src = &fxMesa->TexSource[unit];
 
511
      /*
 
512
      printf("upload source %d @ %d %p\n", unit, src->StartAddress, src->Info);
 
513
      */
 
514
      if (src->Info) {
 
515
         /*
 
516
         printf("  smallLodLog2=%d largeLodLog2=%d ar=%d format=%d data=%p\n",
 
517
                src->Info->smallLodLog2, src->Info->largeLodLog2,
 
518
                src->Info->aspectRatioLog2, src->Info->format,
 
519
                src->Info->data);
 
520
         */
 
521
         fxMesa->Glide.grTexSource(GR_TMU0 + unit,
 
522
                                   src->StartAddress,
 
523
                                   src->EvenOdd,
 
524
                                   src->Info);
 
525
      }
 
526
   }
 
527
}
 
528
 
 
529
 
 
530
static void uploadTextureImages( tdfxContextPtr fxMesa )
 
531
{
 
532
   GLcontext *ctx = fxMesa->glCtx;
 
533
   int unit;
 
534
   for (unit = 0; unit < TDFX_NUM_TMU; unit++) {
 
535
      if (ctx->Texture.Unit[unit]._ReallyEnabled == TEXTURE0_2D) {
 
536
         struct gl_texture_object *tObj = ctx->Texture.Unit[unit].Current2D;
 
537
         tdfxTexInfo *ti = TDFX_TEXTURE_DATA(tObj);
 
538
         if (ti && ti->reloadImages && ti->whichTMU != TDFX_TMU_NONE) {
 
539
            /*
 
540
            printf("download texture image on unit %d\n", unit);
 
541
            */
 
542
            tdfxTMDownloadTexture(fxMesa, tObj);
 
543
            ti->reloadImages = GL_FALSE;
 
544
         }
 
545
      }
 
546
   }
 
547
}
 
548
 
 
549
 
 
550
 
 
551
/*
 
552
 * If scissoring is enabled, compute intersection of scissor region
 
553
 * with all X clip rects, resulting in new cliprect list.
 
554
 * If number of cliprects is zero or one, call grClipWindow to setup
 
555
 * the clip region.  Otherwise we'll call grClipWindow inside the
 
556
 * BEGIN_CLIP_LOOP macro.
 
557
 */
 
558
void tdfxUploadClipping( tdfxContextPtr fxMesa )
 
559
{
 
560
   __DRIdrawablePrivate *dPriv = fxMesa->driDrawable;
 
561
 
 
562
   assert(dPriv);
 
563
 
 
564
   if (fxMesa->numClipRects == 0) {
 
565
      /* all drawing clipped away */
 
566
      fxMesa->Glide.grClipWindow(0, 0, 0, 0);
 
567
   }
 
568
   else if (fxMesa->numClipRects == 1) {
 
569
      fxMesa->Glide.grClipWindow(fxMesa->pClipRects[0].x1,
 
570
                            fxMesa->screen_height - fxMesa->pClipRects[0].y2,
 
571
                            fxMesa->pClipRects[0].x2,
 
572
                            fxMesa->screen_height - fxMesa->pClipRects[0].y1);
 
573
   }
 
574
   /* else, we'll do a cliprect loop around all drawing */
 
575
 
 
576
   fxMesa->Glide.grDRIPosition( dPriv->x, dPriv->y, dPriv->w, dPriv->h,
 
577
                                fxMesa->numClipRects, fxMesa->pClipRects );
 
578
}
 
579
 
 
580
 
 
581
void tdfxEmitHwStateLocked( tdfxContextPtr fxMesa )
 
582
{
 
583
   if ( !fxMesa->dirty )
 
584
      return;
 
585
 
 
586
   if ( fxMesa->dirty & TDFX_UPLOAD_COLOR_COMBINE ) {
 
587
      if (TDFX_IS_NAPALM(fxMesa)) {
 
588
         fxMesa->Glide.grColorCombineExt(fxMesa->ColorCombineExt.SourceA,
 
589
                                         fxMesa->ColorCombineExt.ModeA,
 
590
                                         fxMesa->ColorCombineExt.SourceB,
 
591
                                         fxMesa->ColorCombineExt.ModeB,
 
592
                                         fxMesa->ColorCombineExt.SourceC,
 
593
                                         fxMesa->ColorCombineExt.InvertC,
 
594
                                         fxMesa->ColorCombineExt.SourceD,
 
595
                                         fxMesa->ColorCombineExt.InvertD,
 
596
                                         fxMesa->ColorCombineExt.Shift,
 
597
                                         fxMesa->ColorCombineExt.Invert);
 
598
      }
 
599
      else {
 
600
         /* Voodoo 3 */
 
601
         fxMesa->Glide.grColorCombine( fxMesa->ColorCombine.Function,
 
602
                                       fxMesa->ColorCombine.Factor,
 
603
                                       fxMesa->ColorCombine.Local,
 
604
                                       fxMesa->ColorCombine.Other,
 
605
                                       fxMesa->ColorCombine.Invert );
 
606
      }
 
607
      fxMesa->dirty &= ~TDFX_UPLOAD_COLOR_COMBINE;
 
608
   }
 
609
   if ( fxMesa->dirty & TDFX_UPLOAD_ALPHA_COMBINE ) {
 
610
      if (TDFX_IS_NAPALM(fxMesa)) {
 
611
         fxMesa->Glide.grAlphaCombineExt(fxMesa->AlphaCombineExt.SourceA,
 
612
                                         fxMesa->AlphaCombineExt.ModeA,
 
613
                                         fxMesa->AlphaCombineExt.SourceB,
 
614
                                         fxMesa->AlphaCombineExt.ModeB,
 
615
                                         fxMesa->AlphaCombineExt.SourceC,
 
616
                                         fxMesa->AlphaCombineExt.InvertC,
 
617
                                         fxMesa->AlphaCombineExt.SourceD,
 
618
                                         fxMesa->AlphaCombineExt.InvertD,
 
619
                                         fxMesa->AlphaCombineExt.Shift,
 
620
                                         fxMesa->AlphaCombineExt.Invert);
 
621
      }
 
622
      else {
 
623
         /* Voodoo 3 */
 
624
         fxMesa->Glide.grAlphaCombine( fxMesa->AlphaCombine.Function,
 
625
                                       fxMesa->AlphaCombine.Factor,
 
626
                                       fxMesa->AlphaCombine.Local,
 
627
                                       fxMesa->AlphaCombine.Other,
 
628
                                       fxMesa->AlphaCombine.Invert );
 
629
      }
 
630
      fxMesa->dirty &= ~TDFX_UPLOAD_ALPHA_COMBINE;
 
631
   }
 
632
 
 
633
   if ( fxMesa->dirty & TDFX_UPLOAD_RENDER_BUFFER ) {
 
634
      fxMesa->Glide.grRenderBuffer( fxMesa->DrawBuffer );
 
635
      fxMesa->dirty &= ~TDFX_UPLOAD_RENDER_BUFFER;
 
636
   }
 
637
 
 
638
   if ( fxMesa->dirty & TDFX_UPLOAD_STIPPLE) {
 
639
      fxMesa->Glide.grStipplePattern( fxMesa->Stipple.Pattern );
 
640
      fxMesa->Glide.grStippleMode( fxMesa->Stipple.Mode );
 
641
      fxMesa->dirty &= ~TDFX_UPLOAD_STIPPLE;
 
642
   }
 
643
 
 
644
   if ( fxMesa->dirty & TDFX_UPLOAD_ALPHA_TEST ) {
 
645
      fxMesa->Glide.grAlphaTestFunction( fxMesa->Color.AlphaFunc );
 
646
      fxMesa->dirty &= ~TDFX_UPLOAD_ALPHA_TEST;
 
647
   }
 
648
   if ( fxMesa->dirty & TDFX_UPLOAD_ALPHA_REF ) {
 
649
      fxMesa->Glide.grAlphaTestReferenceValue( fxMesa->Color.AlphaRef );
 
650
      fxMesa->dirty &= ~TDFX_UPLOAD_ALPHA_REF;
 
651
   }
 
652
   if ( fxMesa->dirty & TDFX_UPLOAD_BLEND_FUNC ) {
 
653
      if (fxMesa->Glide.grAlphaBlendFunctionExt) {
 
654
         fxMesa->Glide.grAlphaBlendFunctionExt( fxMesa->Color.BlendSrcRGB,
 
655
                                                fxMesa->Color.BlendDstRGB,
 
656
                                                GR_BLEND_OP_ADD,
 
657
                                                fxMesa->Color.BlendSrcA,
 
658
                                                fxMesa->Color.BlendDstA,
 
659
                                                GR_BLEND_OP_ADD );
 
660
      }
 
661
      else {
 
662
         fxMesa->Glide.grAlphaBlendFunction( fxMesa->Color.BlendSrcRGB,
 
663
                                             fxMesa->Color.BlendDstRGB,
 
664
                                             fxMesa->Color.BlendSrcA,
 
665
                                             fxMesa->Color.BlendDstA );
 
666
      }
 
667
      fxMesa->dirty &= ~TDFX_UPLOAD_BLEND_FUNC;
 
668
   }
 
669
 
 
670
   if ( fxMesa->dirty & TDFX_UPLOAD_DEPTH_MODE ) {
 
671
      fxMesa->Glide.grDepthBufferMode( fxMesa->Depth.Mode );
 
672
      fxMesa->dirty &= ~TDFX_UPLOAD_DEPTH_MODE;
 
673
   }
 
674
   if ( fxMesa->dirty & TDFX_UPLOAD_DEPTH_BIAS ) {
 
675
      fxMesa->Glide.grDepthBiasLevel( fxMesa->Depth.Bias );
 
676
      fxMesa->dirty &= ~TDFX_UPLOAD_DEPTH_BIAS;
 
677
   }
 
678
   if ( fxMesa->dirty & TDFX_UPLOAD_DEPTH_FUNC ) {
 
679
      fxMesa->Glide.grDepthBufferFunction( fxMesa->Depth.Func );
 
680
      fxMesa->dirty &= ~TDFX_UPLOAD_DEPTH_FUNC;
 
681
   }
 
682
   if ( fxMesa->dirty & TDFX_UPLOAD_DEPTH_MASK ) {
 
683
      fxMesa->Glide.grDepthMask( fxMesa->Depth.Mask );
 
684
      fxMesa->dirty &= ~TDFX_UPLOAD_DEPTH_MASK;
 
685
   }
 
686
 
 
687
   if ( fxMesa->dirty & TDFX_UPLOAD_DITHER) {
 
688
      fxMesa->Glide.grDitherMode( fxMesa->Color.Dither );
 
689
   }
 
690
 
 
691
   if ( fxMesa->dirty & TDFX_UPLOAD_FOG_MODE ) {
 
692
      fxMesa->Glide.grFogMode( fxMesa->Fog.Mode );
 
693
      fxMesa->dirty &= ~TDFX_UPLOAD_FOG_MODE;
 
694
   }
 
695
   if ( fxMesa->dirty & TDFX_UPLOAD_FOG_COLOR ) {
 
696
      fxMesa->Glide.grFogColorValue( fxMesa->Fog.Color );
 
697
      fxMesa->dirty &= ~TDFX_UPLOAD_FOG_COLOR;
 
698
   }
 
699
   if ( fxMesa->dirty & TDFX_UPLOAD_FOG_TABLE ) {
 
700
      fxMesa->Glide.grFogTable( fxMesa->Fog.Table );
 
701
      fxMesa->dirty &= ~TDFX_UPLOAD_FOG_TABLE;
 
702
   }
 
703
 
 
704
   if ( fxMesa->dirty & TDFX_UPLOAD_CULL ) {
 
705
      fxMesa->Glide.grCullMode( fxMesa->CullMode );
 
706
      fxMesa->dirty &= ~TDFX_UPLOAD_CULL;
 
707
   }
 
708
 
 
709
   if ( fxMesa->dirty & TDFX_UPLOAD_CLIP ) {
 
710
      tdfxUploadClipping( fxMesa );
 
711
      fxMesa->dirty &= ~TDFX_UPLOAD_CLIP;
 
712
   }
 
713
 
 
714
   if ( fxMesa->dirty & TDFX_UPLOAD_COLOR_MASK ) {
 
715
      if ( fxMesa->Glide.grColorMaskExt
 
716
           && fxMesa->glCtx->Visual.redBits == 8) {
 
717
         fxMesa->Glide.grColorMaskExt( fxMesa->Color.ColorMask[RCOMP],
 
718
                                       fxMesa->Color.ColorMask[GCOMP],
 
719
                                       fxMesa->Color.ColorMask[BCOMP],
 
720
                                       fxMesa->Color.ColorMask[ACOMP] );
 
721
      } else {
 
722
         fxMesa->Glide.grColorMask( fxMesa->Color.ColorMask[RCOMP] ||
 
723
                                    fxMesa->Color.ColorMask[GCOMP] ||
 
724
                                    fxMesa->Color.ColorMask[BCOMP],
 
725
                                    fxMesa->Color.ColorMask[ACOMP] );
 
726
      }
 
727
      fxMesa->dirty &= ~TDFX_UPLOAD_COLOR_MASK;
 
728
   }
 
729
 
 
730
/*     if ( fxMesa->dirty & TDFX_UPLOAD_CONSTANT_COLOR ) { */
 
731
/*        grConstantColorValue( fxMesa->Color.MonoColor ); */
 
732
/*        fxMesa->dirty &= ~TDFX_UPLOAD_CONSTANT_COLOR; */
 
733
/*     } */
 
734
 
 
735
   if ( fxMesa->dirty & TDFX_UPLOAD_LINE ) {
 
736
      if (fxMesa->glCtx->Line.SmoothFlag && fxMesa->glCtx->Line.Width == 1.0)
 
737
         fxMesa->Glide.grEnable(GR_AA_ORDERED);
 
738
      else
 
739
         fxMesa->Glide.grDisable(GR_AA_ORDERED);
 
740
      fxMesa->dirty &= ~TDFX_UPLOAD_LINE;
 
741
   }
 
742
 
 
743
   if ( fxMesa->dirty & TDFX_UPLOAD_STENCIL ) {
 
744
      if (fxMesa->glCtx->Stencil.Enabled) {
 
745
         fxMesa->Glide.grEnable(GR_STENCIL_MODE_EXT);
 
746
         fxMesa->Glide.grStencilOp(fxMesa->Stencil.FailFunc,
 
747
                                   fxMesa->Stencil.ZFailFunc,
 
748
                                   fxMesa->Stencil.ZPassFunc);
 
749
         fxMesa->Glide.grStencilFunc(fxMesa->Stencil.Function,
 
750
                                     fxMesa->Stencil.RefValue,
 
751
                                     fxMesa->Stencil.ValueMask);
 
752
         fxMesa->Glide.grStencilMask(fxMesa->Stencil.WriteMask);
 
753
      }
 
754
      else {
 
755
         fxMesa->Glide.grDisable(GR_STENCIL_MODE_EXT);
 
756
      }
 
757
      fxMesa->dirty &= ~TDFX_UPLOAD_STENCIL;
 
758
   }
 
759
 
 
760
   if ( fxMesa->dirty & TDFX_UPLOAD_VERTEX_LAYOUT ) {
 
761
      fxMesa->Glide.grGlideSetVertexLayout( fxMesa->layout[fxMesa->vertexFormat] );
 
762
      fxMesa->dirty &= ~TDFX_UPLOAD_VERTEX_LAYOUT;
 
763
   }
 
764
 
 
765
   if ( fxMesa->dirty & TDFX_UPLOAD_TEXTURE_ENV ) {
 
766
      uploadTextureEnv(fxMesa);
 
767
      fxMesa->dirty &= ~TDFX_UPLOAD_TEXTURE_ENV;
 
768
   }
 
769
 
 
770
   if ( fxMesa->dirty & TDFX_UPLOAD_TEXTURE_PARAMS ) {
 
771
      uploadTextureParams(fxMesa);
 
772
      fxMesa->dirty &= ~TDFX_UPLOAD_TEXTURE_PARAMS;
 
773
   }
 
774
 
 
775
   if ( fxMesa->dirty & TDFX_UPLOAD_TEXTURE_PALETTE ) {
 
776
      if (fxMesa->TexPalette.Data) {
 
777
         fxMesa->Glide.grTexDownloadTable(fxMesa->TexPalette.Type, fxMesa->TexPalette.Data);
 
778
      }
 
779
      fxMesa->dirty &= ~TDFX_UPLOAD_TEXTURE_PALETTE;
 
780
   }
 
781
 
 
782
   if ( fxMesa->dirty & TDFX_UPLOAD_TEXTURE_SOURCE ) {
 
783
      uploadTextureSource(fxMesa);
 
784
      fxMesa->dirty &= ~TDFX_UPLOAD_TEXTURE_SOURCE;
 
785
   }
 
786
 
 
787
   if ( fxMesa->dirty & TDFX_UPLOAD_TEXTURE_IMAGES ) {
 
788
      uploadTextureImages(fxMesa);
 
789
      fxMesa->dirty &= ~TDFX_UPLOAD_TEXTURE_IMAGES;
 
790
   }
 
791
 
 
792
   fxMesa->dirty = 0;
 
793
}
 
794
 
 
795
 
 
796
 
 
797
void tdfxDDInitRenderFuncs( GLcontext *ctx )
 
798
{
 
799
   ctx->Driver.Clear            = tdfxDDClear;
 
800
   ctx->Driver.Finish           = tdfxDDFinish;
 
801
   ctx->Driver.Flush            = tdfxDDFlush;
 
802
}