~ubuntu-branches/ubuntu/quantal/mesa-glw/quantal

« back to all changes in this revision

Viewing changes to src/mesa/main/texstate.c

  • Committer: Bazaar Package Importer
  • Author(s): Morten Kjeldgaard
  • Date: 2008-05-06 16:19:15 UTC
  • Revision ID: james.westby@ubuntu.com-20080506161915-uynz7nftmfixu6bq
Tags: upstream-7.0.3
ImportĀ upstreamĀ versionĀ 7.0.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Mesa 3-D graphics library
 
3
 * Version:  6.5.3
 
4
 *
 
5
 * Copyright (C) 1999-2007  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
 
 
25
/** 
 
26
 * \file texstate.c
 
27
 *
 
28
 * Texture state handling.
 
29
 */
 
30
 
 
31
#include "glheader.h"
 
32
#include "colormac.h"
 
33
#include "colortab.h"
 
34
#include "context.h"
 
35
#include "enums.h"
 
36
#include "macros.h"
 
37
#include "texcompress.h"
 
38
#include "texobj.h"
 
39
#include "teximage.h"
 
40
#include "texstate.h"
 
41
#include "texenvprogram.h"
 
42
#include "mtypes.h"
 
43
#include "math/m_xform.h"
 
44
 
 
45
 
 
46
#define ENUM_TO_FLOAT(X) ((GLfloat)(GLint)(X))
 
47
#define ENUM_TO_DOUBLE(X) ((GLdouble)(GLint)(X))
 
48
 
 
49
 
 
50
/**
 
51
 * Default texture combine environment state.  This is used to initialize
 
52
 * a context's texture units and as the basis for converting "classic"
 
53
 * texture environmnets to ARB_texture_env_combine style values.
 
54
 */
 
55
static const struct gl_tex_env_combine_state default_combine_state = {
 
56
   GL_MODULATE, GL_MODULATE,
 
57
   { GL_TEXTURE, GL_PREVIOUS, GL_CONSTANT },
 
58
   { GL_TEXTURE, GL_PREVIOUS, GL_CONSTANT },
 
59
   { GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_ALPHA },
 
60
   { GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA },
 
61
   0, 0,
 
62
   2, 2
 
63
};
 
64
 
 
65
 
 
66
 
 
67
/**
 
68
 * Used by glXCopyContext to copy texture state from one context to another.
 
69
 */
 
70
void
 
71
_mesa_copy_texture_state( const GLcontext *src, GLcontext *dst )
 
72
{
 
73
   GLuint i;
 
74
 
 
75
   ASSERT(src);
 
76
   ASSERT(dst);
 
77
 
 
78
   dst->Texture.CurrentUnit = src->Texture.CurrentUnit;
 
79
   dst->Texture._GenFlags = src->Texture._GenFlags;
 
80
   dst->Texture._TexGenEnabled = src->Texture._TexGenEnabled;
 
81
   dst->Texture._TexMatEnabled = src->Texture._TexMatEnabled;
 
82
   dst->Texture.SharedPalette = src->Texture.SharedPalette;
 
83
 
 
84
   /* per-unit state */
 
85
   for (i = 0; i < src->Const.MaxTextureUnits; i++) {
 
86
      dst->Texture.Unit[i].Enabled = src->Texture.Unit[i].Enabled;
 
87
      dst->Texture.Unit[i].EnvMode = src->Texture.Unit[i].EnvMode;
 
88
      COPY_4V(dst->Texture.Unit[i].EnvColor, src->Texture.Unit[i].EnvColor);
 
89
      dst->Texture.Unit[i].TexGenEnabled = src->Texture.Unit[i].TexGenEnabled;
 
90
      dst->Texture.Unit[i].GenModeS = src->Texture.Unit[i].GenModeS;
 
91
      dst->Texture.Unit[i].GenModeT = src->Texture.Unit[i].GenModeT;
 
92
      dst->Texture.Unit[i].GenModeR = src->Texture.Unit[i].GenModeR;
 
93
      dst->Texture.Unit[i].GenModeQ = src->Texture.Unit[i].GenModeQ;
 
94
      dst->Texture.Unit[i]._GenBitS = src->Texture.Unit[i]._GenBitS;
 
95
      dst->Texture.Unit[i]._GenBitT = src->Texture.Unit[i]._GenBitT;
 
96
      dst->Texture.Unit[i]._GenBitR = src->Texture.Unit[i]._GenBitR;
 
97
      dst->Texture.Unit[i]._GenBitQ = src->Texture.Unit[i]._GenBitQ;
 
98
      dst->Texture.Unit[i]._GenFlags = src->Texture.Unit[i]._GenFlags;
 
99
      COPY_4V(dst->Texture.Unit[i].ObjectPlaneS, src->Texture.Unit[i].ObjectPlaneS);
 
100
      COPY_4V(dst->Texture.Unit[i].ObjectPlaneT, src->Texture.Unit[i].ObjectPlaneT);
 
101
      COPY_4V(dst->Texture.Unit[i].ObjectPlaneR, src->Texture.Unit[i].ObjectPlaneR);
 
102
      COPY_4V(dst->Texture.Unit[i].ObjectPlaneQ, src->Texture.Unit[i].ObjectPlaneQ);
 
103
      COPY_4V(dst->Texture.Unit[i].EyePlaneS, src->Texture.Unit[i].EyePlaneS);
 
104
      COPY_4V(dst->Texture.Unit[i].EyePlaneT, src->Texture.Unit[i].EyePlaneT);
 
105
      COPY_4V(dst->Texture.Unit[i].EyePlaneR, src->Texture.Unit[i].EyePlaneR);
 
106
      COPY_4V(dst->Texture.Unit[i].EyePlaneQ, src->Texture.Unit[i].EyePlaneQ);
 
107
      dst->Texture.Unit[i].LodBias = src->Texture.Unit[i].LodBias;
 
108
 
 
109
      /* GL_EXT_texture_env_combine */
 
110
      dst->Texture.Unit[i].Combine.ModeRGB = src->Texture.Unit[i].Combine.ModeRGB;
 
111
      dst->Texture.Unit[i].Combine.ModeA = src->Texture.Unit[i].Combine.ModeA;
 
112
      COPY_3V(dst->Texture.Unit[i].Combine.SourceRGB, src->Texture.Unit[i].Combine.SourceRGB);
 
113
      COPY_3V(dst->Texture.Unit[i].Combine.SourceA, src->Texture.Unit[i].Combine.SourceA);
 
114
      COPY_3V(dst->Texture.Unit[i].Combine.OperandRGB, src->Texture.Unit[i].Combine.OperandRGB);
 
115
      COPY_3V(dst->Texture.Unit[i].Combine.OperandA, src->Texture.Unit[i].Combine.OperandA);
 
116
      dst->Texture.Unit[i].Combine.ScaleShiftRGB = src->Texture.Unit[i].Combine.ScaleShiftRGB;
 
117
      dst->Texture.Unit[i].Combine.ScaleShiftA = src->Texture.Unit[i].Combine.ScaleShiftA;
 
118
 
 
119
      /* copy texture object bindings, not contents of texture objects */
 
120
      _mesa_lock_context_textures(dst);
 
121
 
 
122
      _mesa_reference_texobj(&dst->Texture.Unit[i].Current1D,
 
123
                             src->Texture.Unit[i].Current1D);
 
124
      _mesa_reference_texobj(&dst->Texture.Unit[i].Current2D,
 
125
                             src->Texture.Unit[i].Current2D);
 
126
      _mesa_reference_texobj(&dst->Texture.Unit[i].Current3D,
 
127
                             src->Texture.Unit[i].Current3D);
 
128
      _mesa_reference_texobj(&dst->Texture.Unit[i].CurrentCubeMap,
 
129
                             src->Texture.Unit[i].CurrentCubeMap);
 
130
      _mesa_reference_texobj(&dst->Texture.Unit[i].CurrentRect,
 
131
                             src->Texture.Unit[i].CurrentRect);
 
132
 
 
133
      _mesa_unlock_context_textures(dst);
 
134
   }
 
135
}
 
136
 
 
137
 
 
138
/*
 
139
 * For debugging
 
140
 */
 
141
void
 
142
_mesa_print_texunit_state( GLcontext *ctx, GLuint unit )
 
143
{
 
144
   const struct gl_texture_unit *texUnit = ctx->Texture.Unit + unit;
 
145
   _mesa_printf("Texture Unit %d\n", unit);
 
146
   _mesa_printf("  GL_TEXTURE_ENV_MODE = %s\n", _mesa_lookup_enum_by_nr(texUnit->EnvMode));
 
147
   _mesa_printf("  GL_COMBINE_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.ModeRGB));
 
148
   _mesa_printf("  GL_COMBINE_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.ModeA));
 
149
   _mesa_printf("  GL_SOURCE0_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceRGB[0]));
 
150
   _mesa_printf("  GL_SOURCE1_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceRGB[1]));
 
151
   _mesa_printf("  GL_SOURCE2_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceRGB[2]));
 
152
   _mesa_printf("  GL_SOURCE0_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceA[0]));
 
153
   _mesa_printf("  GL_SOURCE1_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceA[1]));
 
154
   _mesa_printf("  GL_SOURCE2_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceA[2]));
 
155
   _mesa_printf("  GL_OPERAND0_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandRGB[0]));
 
156
   _mesa_printf("  GL_OPERAND1_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandRGB[1]));
 
157
   _mesa_printf("  GL_OPERAND2_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandRGB[2]));
 
158
   _mesa_printf("  GL_OPERAND0_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandA[0]));
 
159
   _mesa_printf("  GL_OPERAND1_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandA[1]));
 
160
   _mesa_printf("  GL_OPERAND2_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandA[2]));
 
161
   _mesa_printf("  GL_RGB_SCALE = %d\n", 1 << texUnit->Combine.ScaleShiftRGB);
 
162
   _mesa_printf("  GL_ALPHA_SCALE = %d\n", 1 << texUnit->Combine.ScaleShiftA);
 
163
   _mesa_printf("  GL_TEXTURE_ENV_COLOR = (%f, %f, %f, %f)\n", texUnit->EnvColor[0], texUnit->EnvColor[1], texUnit->EnvColor[2], texUnit->EnvColor[3]);
 
164
}
 
165
 
 
166
 
 
167
 
 
168
/**********************************************************************/
 
169
/*                       Texture Environment                          */
 
170
/**********************************************************************/
 
171
 
 
172
/**
 
173
 * Convert "classic" texture environment to ARB_texture_env_combine style
 
174
 * environments.
 
175
 * 
 
176
 * \param state  texture_env_combine state vector to be filled-in.
 
177
 * \param mode   Classic texture environment mode (i.e., \c GL_REPLACE,
 
178
 *               \c GL_BLEND, \c GL_DECAL, etc.).
 
179
 * \param texBaseFormat  Base format of the texture associated with the
 
180
 *               texture unit.
 
181
 */
 
182
static void
 
183
calculate_derived_texenv( struct gl_tex_env_combine_state *state,
 
184
                          GLenum mode, GLenum texBaseFormat )
 
185
{
 
186
   GLenum mode_rgb;
 
187
   GLenum mode_a;
 
188
 
 
189
   *state = default_combine_state;
 
190
 
 
191
   switch (texBaseFormat) {
 
192
   case GL_ALPHA:
 
193
      state->SourceRGB[0] = GL_PREVIOUS;
 
194
      break;
 
195
 
 
196
   case GL_LUMINANCE_ALPHA:
 
197
   case GL_INTENSITY:
 
198
   case GL_RGBA:
 
199
      break;
 
200
 
 
201
   case GL_LUMINANCE:
 
202
   case GL_RGB:
 
203
   case GL_YCBCR_MESA:
 
204
      state->SourceA[0] = GL_PREVIOUS;
 
205
      break;
 
206
      
 
207
   default:
 
208
      _mesa_problem(NULL, "Invalid texBaseFormat in calculate_derived_texenv");
 
209
      return;
 
210
   }
 
211
 
 
212
   switch (mode) {
 
213
   case GL_REPLACE:
 
214
   case GL_MODULATE:
 
215
      mode_rgb = (texBaseFormat == GL_ALPHA) ? GL_REPLACE : mode;
 
216
      mode_a   = mode;
 
217
      break;
 
218
   
 
219
   case GL_DECAL:
 
220
      mode_rgb = GL_INTERPOLATE;
 
221
      mode_a   = GL_REPLACE;
 
222
 
 
223
      state->SourceA[0] = GL_PREVIOUS;
 
224
 
 
225
      /* Having alpha / luminance / intensity textures replace using the
 
226
       * incoming fragment color matches the definition in NV_texture_shader.
 
227
       * The 1.5 spec simply marks these as "undefined".
 
228
       */
 
229
      switch (texBaseFormat) {
 
230
      case GL_ALPHA:
 
231
      case GL_LUMINANCE:
 
232
      case GL_LUMINANCE_ALPHA:
 
233
      case GL_INTENSITY:
 
234
         state->SourceRGB[0] = GL_PREVIOUS;
 
235
         break;
 
236
      case GL_RGB:
 
237
      case GL_YCBCR_MESA:
 
238
         mode_rgb = GL_REPLACE;
 
239
         break;
 
240
      case GL_RGBA:
 
241
         state->SourceRGB[2] = GL_TEXTURE;
 
242
         break;
 
243
      }
 
244
      break;
 
245
 
 
246
   case GL_BLEND:
 
247
      mode_rgb = GL_INTERPOLATE;
 
248
      mode_a   = GL_MODULATE;
 
249
 
 
250
      switch (texBaseFormat) {
 
251
      case GL_ALPHA:
 
252
         mode_rgb = GL_REPLACE;
 
253
         break;
 
254
      case GL_INTENSITY:
 
255
         mode_a = GL_INTERPOLATE;
 
256
         state->SourceA[0] = GL_CONSTANT;
 
257
         state->OperandA[2] = GL_SRC_ALPHA;
 
258
         /* FALLTHROUGH */
 
259
      case GL_LUMINANCE:
 
260
      case GL_RGB:
 
261
      case GL_LUMINANCE_ALPHA:
 
262
      case GL_RGBA:
 
263
      case GL_YCBCR_MESA:
 
264
         state->SourceRGB[2] = GL_TEXTURE;
 
265
         state->SourceA[2]   = GL_TEXTURE;
 
266
         state->SourceRGB[0] = GL_CONSTANT;
 
267
         state->OperandRGB[2] = GL_SRC_COLOR;
 
268
         break;
 
269
      }
 
270
      break;
 
271
 
 
272
   case GL_ADD:
 
273
      mode_rgb = (texBaseFormat == GL_ALPHA) ? GL_REPLACE : GL_ADD;
 
274
      mode_a   = (texBaseFormat == GL_INTENSITY) ? GL_ADD : GL_MODULATE;
 
275
      break;
 
276
 
 
277
   default:
 
278
      _mesa_problem(NULL,
 
279
                    "Invalid texture env mode in calculate_derived_texenv");
 
280
      return;
 
281
   }
 
282
   
 
283
   state->ModeRGB = (state->SourceRGB[0] != GL_PREVIOUS)
 
284
       ? mode_rgb : GL_REPLACE;
 
285
   state->ModeA   = (state->SourceA[0]   != GL_PREVIOUS)
 
286
       ? mode_a   : GL_REPLACE;
 
287
}
 
288
 
 
289
 
 
290
void GLAPIENTRY
 
291
_mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param )
 
292
{
 
293
   GLuint maxUnit;
 
294
   GET_CURRENT_CONTEXT(ctx);
 
295
   struct gl_texture_unit *texUnit;
 
296
   ASSERT_OUTSIDE_BEGIN_END(ctx);
 
297
 
 
298
   maxUnit = (target == GL_POINT_SPRITE_NV && pname == GL_COORD_REPLACE_NV)
 
299
      ? ctx->Const.MaxTextureCoordUnits : ctx->Const.MaxTextureImageUnits;
 
300
   if (ctx->Texture.CurrentUnit >= maxUnit) {
 
301
      _mesa_error(ctx, GL_INVALID_OPERATION, "glTexEnvfv(current unit)");
 
302
      return;
 
303
   }
 
304
 
 
305
   texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
 
306
 
 
307
#define TE_ERROR(errCode, msg, value)                           \
 
308
   _mesa_error(ctx, errCode, msg, _mesa_lookup_enum_by_nr(value));
 
309
 
 
310
   if (target == GL_TEXTURE_ENV) {
 
311
      switch (pname) {
 
312
      case GL_TEXTURE_ENV_MODE:
 
313
         {
 
314
            const GLenum mode = (GLenum) (GLint) *param;
 
315
            if (texUnit->EnvMode == mode)
 
316
               return;
 
317
            if (mode == GL_MODULATE ||
 
318
                mode == GL_BLEND ||
 
319
                mode == GL_DECAL ||
 
320
                mode == GL_REPLACE ||
 
321
                (mode == GL_ADD && ctx->Extensions.EXT_texture_env_add) ||
 
322
                (mode == GL_COMBINE &&
 
323
                 (ctx->Extensions.EXT_texture_env_combine ||
 
324
                  ctx->Extensions.ARB_texture_env_combine))) {
 
325
               /* legal */
 
326
               FLUSH_VERTICES(ctx, _NEW_TEXTURE);
 
327
               texUnit->EnvMode = mode;
 
328
            }
 
329
            else {
 
330
               TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
 
331
               return;
 
332
            }
 
333
         }
 
334
         break;
 
335
      case GL_TEXTURE_ENV_COLOR:
 
336
         {
 
337
            GLfloat tmp[4];
 
338
            tmp[0] = CLAMP( param[0], 0.0F, 1.0F );
 
339
            tmp[1] = CLAMP( param[1], 0.0F, 1.0F );
 
340
            tmp[2] = CLAMP( param[2], 0.0F, 1.0F );
 
341
            tmp[3] = CLAMP( param[3], 0.0F, 1.0F );
 
342
            if (TEST_EQ_4V(tmp, texUnit->EnvColor))
 
343
               return;
 
344
            FLUSH_VERTICES(ctx, _NEW_TEXTURE);
 
345
            COPY_4FV(texUnit->EnvColor, tmp);
 
346
         }
 
347
         break;
 
348
      case GL_COMBINE_RGB:
 
349
         if (ctx->Extensions.EXT_texture_env_combine ||
 
350
             ctx->Extensions.ARB_texture_env_combine) {
 
351
            const GLenum mode = (GLenum) (GLint) *param;
 
352
            if (texUnit->Combine.ModeRGB == mode)
 
353
               return;
 
354
            switch (mode) {
 
355
            case GL_REPLACE:
 
356
            case GL_MODULATE:
 
357
            case GL_ADD:
 
358
            case GL_ADD_SIGNED:
 
359
            case GL_INTERPOLATE:
 
360
               /* OK */
 
361
               break;
 
362
            case GL_SUBTRACT:
 
363
               if (!ctx->Extensions.ARB_texture_env_combine) {
 
364
                  TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
 
365
                  return;
 
366
               }
 
367
               break;
 
368
            case GL_DOT3_RGB_EXT:
 
369
            case GL_DOT3_RGBA_EXT:
 
370
               if (!ctx->Extensions.EXT_texture_env_dot3) {
 
371
                  TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
 
372
                  return;
 
373
               }
 
374
               break;
 
375
            case GL_DOT3_RGB:
 
376
            case GL_DOT3_RGBA:
 
377
               if (!ctx->Extensions.ARB_texture_env_dot3) {
 
378
                  TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
 
379
                  return;
 
380
               }
 
381
               break;
 
382
            case GL_MODULATE_ADD_ATI:
 
383
            case GL_MODULATE_SIGNED_ADD_ATI:
 
384
            case GL_MODULATE_SUBTRACT_ATI:
 
385
               if (!ctx->Extensions.ATI_texture_env_combine3) {
 
386
                  TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
 
387
                  return;
 
388
               }
 
389
               break;
 
390
            default:
 
391
               TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
 
392
               return;
 
393
            }
 
394
            FLUSH_VERTICES(ctx, _NEW_TEXTURE);
 
395
            texUnit->Combine.ModeRGB = mode;
 
396
         }
 
397
         else {
 
398
            TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
 
399
            return;
 
400
         }
 
401
         break;
 
402
      case GL_COMBINE_ALPHA:
 
403
         if (ctx->Extensions.EXT_texture_env_combine ||
 
404
             ctx->Extensions.ARB_texture_env_combine) {
 
405
            const GLenum mode = (GLenum) (GLint) *param;
 
406
            if (texUnit->Combine.ModeA == mode)
 
407
               return;
 
408
            switch (mode) {
 
409
            case GL_REPLACE:
 
410
            case GL_MODULATE:
 
411
            case GL_ADD:
 
412
            case GL_ADD_SIGNED:
 
413
            case GL_INTERPOLATE:
 
414
               /* OK */
 
415
               break;
 
416
            case GL_SUBTRACT:
 
417
               if (!ctx->Extensions.ARB_texture_env_combine) {
 
418
                  TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
 
419
                  return;
 
420
               }
 
421
               break;
 
422
            case GL_MODULATE_ADD_ATI:
 
423
            case GL_MODULATE_SIGNED_ADD_ATI:
 
424
            case GL_MODULATE_SUBTRACT_ATI:
 
425
               if (!ctx->Extensions.ATI_texture_env_combine3) {
 
426
                  TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
 
427
                  return;
 
428
               }
 
429
               break;
 
430
            default:
 
431
               TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
 
432
               return;
 
433
            }
 
434
            FLUSH_VERTICES(ctx, _NEW_TEXTURE);
 
435
            texUnit->Combine.ModeA = mode;
 
436
         }
 
437
         else {
 
438
            TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
 
439
            return;
 
440
         }
 
441
         break;
 
442
      case GL_SOURCE0_RGB:
 
443
      case GL_SOURCE1_RGB:
 
444
      case GL_SOURCE2_RGB:
 
445
         if (ctx->Extensions.EXT_texture_env_combine ||
 
446
             ctx->Extensions.ARB_texture_env_combine) {
 
447
            const GLenum source = (GLenum) (GLint) *param;
 
448
            const GLuint s = pname - GL_SOURCE0_RGB;
 
449
            if (texUnit->Combine.SourceRGB[s] == source)
 
450
               return;
 
451
            if (source == GL_TEXTURE ||
 
452
                source == GL_CONSTANT ||
 
453
                source == GL_PRIMARY_COLOR ||
 
454
                source == GL_PREVIOUS ||
 
455
                (ctx->Extensions.ARB_texture_env_crossbar &&
 
456
                 source >= GL_TEXTURE0 &&
 
457
                 source < GL_TEXTURE0 + ctx->Const.MaxTextureUnits) ||
 
458
                (ctx->Extensions.ATI_texture_env_combine3 &&
 
459
                 (source == GL_ZERO || source == GL_ONE))) {
 
460
               /* legal */
 
461
               FLUSH_VERTICES(ctx, _NEW_TEXTURE);
 
462
               texUnit->Combine.SourceRGB[s] = source;
 
463
            }
 
464
            else {
 
465
               TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", source);
 
466
               return;
 
467
            }
 
468
         }
 
469
         else {
 
470
            TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
 
471
            return;
 
472
         }
 
473
         break;
 
474
      case GL_SOURCE0_ALPHA:
 
475
      case GL_SOURCE1_ALPHA:
 
476
      case GL_SOURCE2_ALPHA:
 
477
         if (ctx->Extensions.EXT_texture_env_combine ||
 
478
             ctx->Extensions.ARB_texture_env_combine) {
 
479
            const GLenum source = (GLenum) (GLint) *param;
 
480
            const GLuint s = pname - GL_SOURCE0_ALPHA;
 
481
            if (texUnit->Combine.SourceA[s] == source)
 
482
               return;
 
483
            if (source == GL_TEXTURE ||
 
484
                source == GL_CONSTANT ||
 
485
                source == GL_PRIMARY_COLOR ||
 
486
                source == GL_PREVIOUS ||
 
487
                (ctx->Extensions.ARB_texture_env_crossbar &&
 
488
                 source >= GL_TEXTURE0 &&
 
489
                 source < GL_TEXTURE0 + ctx->Const.MaxTextureUnits) ||
 
490
                (ctx->Extensions.ATI_texture_env_combine3 &&
 
491
                 (source == GL_ZERO || source == GL_ONE))) {
 
492
               /* legal */
 
493
               FLUSH_VERTICES(ctx, _NEW_TEXTURE);
 
494
               texUnit->Combine.SourceA[s] = source;
 
495
            }
 
496
            else {
 
497
               TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", source);
 
498
               return;
 
499
            }
 
500
         }
 
501
         else {
 
502
            TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
 
503
            return;
 
504
         }
 
505
         break;
 
506
      case GL_OPERAND0_RGB:
 
507
      case GL_OPERAND1_RGB:
 
508
         if (ctx->Extensions.EXT_texture_env_combine ||
 
509
             ctx->Extensions.ARB_texture_env_combine) {
 
510
            const GLenum operand = (GLenum) (GLint) *param;
 
511
            const GLuint s = pname - GL_OPERAND0_RGB;
 
512
            if (texUnit->Combine.OperandRGB[s] == operand)
 
513
               return;
 
514
            switch (operand) {
 
515
            case GL_SRC_COLOR:
 
516
            case GL_ONE_MINUS_SRC_COLOR:
 
517
            case GL_SRC_ALPHA:
 
518
            case GL_ONE_MINUS_SRC_ALPHA:
 
519
               FLUSH_VERTICES(ctx, _NEW_TEXTURE);
 
520
               texUnit->Combine.OperandRGB[s] = operand;
 
521
               break;
 
522
            default:
 
523
               TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand);
 
524
               return;
 
525
            }
 
526
         }
 
527
         else {
 
528
            TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
 
529
            return;
 
530
         }
 
531
         break;
 
532
      case GL_OPERAND0_ALPHA:
 
533
      case GL_OPERAND1_ALPHA:
 
534
         if (ctx->Extensions.EXT_texture_env_combine ||
 
535
             ctx->Extensions.ARB_texture_env_combine) {
 
536
            const GLenum operand = (GLenum) (GLint) *param;
 
537
            if (texUnit->Combine.OperandA[pname-GL_OPERAND0_ALPHA] == operand)
 
538
               return;
 
539
            switch (operand) {
 
540
            case GL_SRC_ALPHA:
 
541
            case GL_ONE_MINUS_SRC_ALPHA:
 
542
               FLUSH_VERTICES(ctx, _NEW_TEXTURE);
 
543
               texUnit->Combine.OperandA[pname-GL_OPERAND0_ALPHA] = operand;
 
544
               break;
 
545
            default:
 
546
               TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand);
 
547
               return;
 
548
            }
 
549
         }
 
550
         else {
 
551
            TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
 
552
            return;
 
553
         }
 
554
         break;
 
555
      case GL_OPERAND2_RGB:
 
556
         if (ctx->Extensions.ARB_texture_env_combine) {
 
557
            const GLenum operand = (GLenum) (GLint) *param;
 
558
            if (texUnit->Combine.OperandRGB[2] == operand)
 
559
               return;
 
560
            switch (operand) {
 
561
            case GL_SRC_COLOR:           /* ARB combine only */
 
562
            case GL_ONE_MINUS_SRC_COLOR: /* ARB combine only */
 
563
            case GL_SRC_ALPHA:
 
564
            case GL_ONE_MINUS_SRC_ALPHA: /* ARB combine only */
 
565
               FLUSH_VERTICES(ctx, _NEW_TEXTURE);
 
566
               texUnit->Combine.OperandRGB[2] = operand;
 
567
               break;
 
568
            default:
 
569
               TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand);
 
570
               return;
 
571
            }
 
572
         }
 
573
         else if (ctx->Extensions.EXT_texture_env_combine) {
 
574
            const GLenum operand = (GLenum) (GLint) *param;
 
575
            if (texUnit->Combine.OperandRGB[2] == operand)
 
576
               return;
 
577
            /* operand must be GL_SRC_ALPHA which is the initial value - thus
 
578
               don't need to actually compare the operand to the possible value */
 
579
            else {
 
580
               TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand);
 
581
               return;
 
582
            }
 
583
         }
 
584
         else {
 
585
            TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
 
586
            return;
 
587
         }
 
588
         break;
 
589
      case GL_OPERAND2_ALPHA:
 
590
         if (ctx->Extensions.ARB_texture_env_combine) {
 
591
            const GLenum operand = (GLenum) (GLint) *param;
 
592
            if (texUnit->Combine.OperandA[2] == operand)
 
593
               return;
 
594
            switch (operand) {
 
595
            case GL_SRC_ALPHA:
 
596
            case GL_ONE_MINUS_SRC_ALPHA: /* ARB combine only */
 
597
               FLUSH_VERTICES(ctx, _NEW_TEXTURE);
 
598
               texUnit->Combine.OperandA[2] = operand;
 
599
               break;
 
600
            default:
 
601
               TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand);
 
602
               return;
 
603
            }
 
604
         }
 
605
         else if (ctx->Extensions.EXT_texture_env_combine) {
 
606
            const GLenum operand = (GLenum) (GLint) *param;
 
607
            if (texUnit->Combine.OperandA[2] == operand)
 
608
               return;
 
609
            /* operand must be GL_SRC_ALPHA which is the initial value - thus
 
610
               don't need to actually compare the operand to the possible value */
 
611
            else {
 
612
               TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand);
 
613
               return;
 
614
            }
 
615
         }
 
616
         else {
 
617
            TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
 
618
            return;
 
619
         }
 
620
         break;
 
621
      case GL_RGB_SCALE:
 
622
         if (ctx->Extensions.EXT_texture_env_combine ||
 
623
             ctx->Extensions.ARB_texture_env_combine) {
 
624
            GLuint newshift;
 
625
            if (*param == 1.0) {
 
626
               newshift = 0;
 
627
            }
 
628
            else if (*param == 2.0) {
 
629
               newshift = 1;
 
630
            }
 
631
            else if (*param == 4.0) {
 
632
               newshift = 2;
 
633
            }
 
634
            else {
 
635
               _mesa_error( ctx, GL_INVALID_VALUE,
 
636
                            "glTexEnv(GL_RGB_SCALE not 1, 2 or 4)" );
 
637
               return;
 
638
            }
 
639
            if (texUnit->Combine.ScaleShiftRGB == newshift)
 
640
               return;
 
641
            FLUSH_VERTICES(ctx, _NEW_TEXTURE);
 
642
            texUnit->Combine.ScaleShiftRGB = newshift;
 
643
         }
 
644
         else {
 
645
            TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
 
646
            return;
 
647
         }
 
648
         break;
 
649
      case GL_ALPHA_SCALE:
 
650
         if (ctx->Extensions.EXT_texture_env_combine ||
 
651
             ctx->Extensions.ARB_texture_env_combine) {
 
652
            GLuint newshift;
 
653
            if (*param == 1.0) {
 
654
               newshift = 0;
 
655
            }
 
656
            else if (*param == 2.0) {
 
657
               newshift = 1;
 
658
            }
 
659
            else if (*param == 4.0) {
 
660
               newshift = 2;
 
661
            }
 
662
            else {
 
663
               _mesa_error( ctx, GL_INVALID_VALUE,
 
664
                            "glTexEnv(GL_ALPHA_SCALE not 1, 2 or 4)" );
 
665
               return;
 
666
            }
 
667
            if (texUnit->Combine.ScaleShiftA == newshift)
 
668
               return;
 
669
            FLUSH_VERTICES(ctx, _NEW_TEXTURE);
 
670
            texUnit->Combine.ScaleShiftA = newshift;
 
671
         }
 
672
         else {
 
673
            TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
 
674
            return;
 
675
         }
 
676
         break;
 
677
      default:
 
678
         _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(pname)" );
 
679
         return;
 
680
      }
 
681
   }
 
682
   else if (target == GL_TEXTURE_FILTER_CONTROL_EXT) {
 
683
      /* GL_EXT_texture_lod_bias */
 
684
      if (!ctx->Extensions.EXT_texture_lod_bias) {
 
685
         _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(target=0x%x)", target );
 
686
         return;
 
687
      }
 
688
      if (pname == GL_TEXTURE_LOD_BIAS_EXT) {
 
689
         if (texUnit->LodBias == param[0])
 
690
            return;
 
691
         FLUSH_VERTICES(ctx, _NEW_TEXTURE);
 
692
         texUnit->LodBias = param[0];
 
693
      }
 
694
      else {
 
695
         TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
 
696
         return;
 
697
      }
 
698
   }
 
699
   else if (target == GL_POINT_SPRITE_NV) {
 
700
      /* GL_ARB_point_sprite / GL_NV_point_sprite */
 
701
      if (!ctx->Extensions.NV_point_sprite
 
702
          && !ctx->Extensions.ARB_point_sprite) {
 
703
         _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(target=0x%x)", target );
 
704
         return;
 
705
      }
 
706
      if (pname == GL_COORD_REPLACE_NV) {
 
707
         const GLenum value = (GLenum) param[0];
 
708
         if (value == GL_TRUE || value == GL_FALSE) {
 
709
            /* It's kind of weird to set point state via glTexEnv,
 
710
             * but that's what the spec calls for.
 
711
             */
 
712
            const GLboolean state = (GLboolean) value;
 
713
            if (ctx->Point.CoordReplace[ctx->Texture.CurrentUnit] == state)
 
714
               return;
 
715
            FLUSH_VERTICES(ctx, _NEW_POINT);
 
716
            ctx->Point.CoordReplace[ctx->Texture.CurrentUnit] = state;
 
717
         }
 
718
         else {
 
719
            _mesa_error( ctx, GL_INVALID_VALUE, "glTexEnv(param=0x%x)", value);
 
720
            return;
 
721
         }
 
722
      }
 
723
      else {
 
724
         _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(pname=0x%x)", pname );
 
725
         return;
 
726
      }
 
727
   }
 
728
   else {
 
729
      _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(target=0x%x)",target );
 
730
      return;
 
731
   }
 
732
 
 
733
   if (MESA_VERBOSE&(VERBOSE_API|VERBOSE_TEXTURE))
 
734
      _mesa_debug(ctx, "glTexEnv %s %s %.1f(%s) ...\n",
 
735
                  _mesa_lookup_enum_by_nr(target),
 
736
                  _mesa_lookup_enum_by_nr(pname),
 
737
                  *param,
 
738
                  _mesa_lookup_enum_by_nr((GLenum) (GLint) *param));
 
739
 
 
740
   /* Tell device driver about the new texture environment */
 
741
   if (ctx->Driver.TexEnv) {
 
742
      (*ctx->Driver.TexEnv)( ctx, target, pname, param );
 
743
   }
 
744
}
 
745
 
 
746
 
 
747
void GLAPIENTRY
 
748
_mesa_TexEnvf( GLenum target, GLenum pname, GLfloat param )
 
749
{
 
750
   _mesa_TexEnvfv( target, pname, &param );
 
751
}
 
752
 
 
753
 
 
754
 
 
755
void GLAPIENTRY
 
756
_mesa_TexEnvi( GLenum target, GLenum pname, GLint param )
 
757
{
 
758
   GLfloat p[4];
 
759
   p[0] = (GLfloat) param;
 
760
   p[1] = p[2] = p[3] = 0.0;
 
761
   _mesa_TexEnvfv( target, pname, p );
 
762
}
 
763
 
 
764
 
 
765
void GLAPIENTRY
 
766
_mesa_TexEnviv( GLenum target, GLenum pname, const GLint *param )
 
767
{
 
768
   GLfloat p[4];
 
769
   if (pname == GL_TEXTURE_ENV_COLOR) {
 
770
      p[0] = INT_TO_FLOAT( param[0] );
 
771
      p[1] = INT_TO_FLOAT( param[1] );
 
772
      p[2] = INT_TO_FLOAT( param[2] );
 
773
      p[3] = INT_TO_FLOAT( param[3] );
 
774
   }
 
775
   else {
 
776
      p[0] = (GLfloat) param[0];
 
777
      p[1] = p[2] = p[3] = 0;  /* init to zero, just to be safe */
 
778
   }
 
779
   _mesa_TexEnvfv( target, pname, p );
 
780
}
 
781
 
 
782
 
 
783
void GLAPIENTRY
 
784
_mesa_GetTexEnvfv( GLenum target, GLenum pname, GLfloat *params )
 
785
{
 
786
   GLuint maxUnit;
 
787
   const struct gl_texture_unit *texUnit;
 
788
   GET_CURRENT_CONTEXT(ctx);
 
789
   ASSERT_OUTSIDE_BEGIN_END(ctx);
 
790
 
 
791
   maxUnit = (target == GL_POINT_SPRITE_NV && pname == GL_COORD_REPLACE_NV)
 
792
      ? ctx->Const.MaxTextureCoordUnits : ctx->Const.MaxTextureImageUnits;
 
793
   if (ctx->Texture.CurrentUnit >= maxUnit) {
 
794
      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexEnvfv(current unit)");
 
795
      return;
 
796
   }
 
797
 
 
798
   texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
 
799
 
 
800
   if (target == GL_TEXTURE_ENV) {
 
801
      switch (pname) {
 
802
         case GL_TEXTURE_ENV_MODE:
 
803
            *params = ENUM_TO_FLOAT(texUnit->EnvMode);
 
804
            break;
 
805
         case GL_TEXTURE_ENV_COLOR:
 
806
            COPY_4FV( params, texUnit->EnvColor );
 
807
            break;
 
808
         case GL_COMBINE_RGB:
 
809
            if (ctx->Extensions.EXT_texture_env_combine ||
 
810
                ctx->Extensions.ARB_texture_env_combine) {
 
811
               *params = (GLfloat) texUnit->Combine.ModeRGB;
 
812
            }
 
813
            else {
 
814
               _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
 
815
            }
 
816
            break;
 
817
         case GL_COMBINE_ALPHA:
 
818
            if (ctx->Extensions.EXT_texture_env_combine ||
 
819
                ctx->Extensions.ARB_texture_env_combine) {
 
820
               *params = (GLfloat) texUnit->Combine.ModeA;
 
821
            }
 
822
            else {
 
823
               _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
 
824
            }
 
825
            break;
 
826
         case GL_SOURCE0_RGB:
 
827
         case GL_SOURCE1_RGB:
 
828
         case GL_SOURCE2_RGB:
 
829
            if (ctx->Extensions.EXT_texture_env_combine ||
 
830
                ctx->Extensions.ARB_texture_env_combine) {
 
831
               const unsigned rgb_idx = pname - GL_SOURCE0_RGB;
 
832
               *params = (GLfloat) texUnit->Combine.SourceRGB[rgb_idx];
 
833
            }
 
834
            else {
 
835
               _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
 
836
            }
 
837
            break;
 
838
         case GL_SOURCE0_ALPHA:
 
839
         case GL_SOURCE1_ALPHA:
 
840
         case GL_SOURCE2_ALPHA:
 
841
            if (ctx->Extensions.EXT_texture_env_combine ||
 
842
                ctx->Extensions.ARB_texture_env_combine) {
 
843
               const unsigned alpha_idx = pname - GL_SOURCE0_ALPHA;
 
844
               *params = (GLfloat) texUnit->Combine.SourceA[alpha_idx];
 
845
            }
 
846
            else {
 
847
               _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
 
848
            }
 
849
            break;
 
850
         case GL_OPERAND0_RGB:
 
851
         case GL_OPERAND1_RGB:
 
852
         case GL_OPERAND2_RGB:
 
853
            if (ctx->Extensions.EXT_texture_env_combine ||
 
854
                ctx->Extensions.ARB_texture_env_combine) {
 
855
               const unsigned op_rgb = pname - GL_OPERAND0_RGB;
 
856
               *params = (GLfloat) texUnit->Combine.OperandRGB[op_rgb];
 
857
            }
 
858
            else {
 
859
               _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
 
860
            }
 
861
            break;
 
862
         case GL_OPERAND0_ALPHA:
 
863
         case GL_OPERAND1_ALPHA:
 
864
         case GL_OPERAND2_ALPHA:
 
865
            if (ctx->Extensions.EXT_texture_env_combine ||
 
866
                ctx->Extensions.ARB_texture_env_combine) {
 
867
               const unsigned op_alpha = pname - GL_OPERAND0_ALPHA;
 
868
               *params = (GLfloat) texUnit->Combine.OperandA[op_alpha];
 
869
            }
 
870
            else {
 
871
               _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
 
872
            }
 
873
            break;
 
874
         case GL_RGB_SCALE:
 
875
            if (ctx->Extensions.EXT_texture_env_combine ||
 
876
                ctx->Extensions.ARB_texture_env_combine) {
 
877
               if (texUnit->Combine.ScaleShiftRGB == 0)
 
878
                  *params = 1.0;
 
879
               else if (texUnit->Combine.ScaleShiftRGB == 1)
 
880
                  *params = 2.0;
 
881
               else
 
882
                  *params = 4.0;
 
883
            }
 
884
            else {
 
885
               _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
 
886
               return;
 
887
            }
 
888
            break;
 
889
         case GL_ALPHA_SCALE:
 
890
            if (ctx->Extensions.EXT_texture_env_combine ||
 
891
                ctx->Extensions.ARB_texture_env_combine) {
 
892
               if (texUnit->Combine.ScaleShiftA == 0)
 
893
                  *params = 1.0;
 
894
               else if (texUnit->Combine.ScaleShiftA == 1)
 
895
                  *params = 2.0;
 
896
               else
 
897
                  *params = 4.0;
 
898
            }
 
899
            else {
 
900
               _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
 
901
               return;
 
902
            }
 
903
            break;
 
904
         default:
 
905
            _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname=0x%x)", pname);
 
906
      }
 
907
   }
 
908
   else if (target == GL_TEXTURE_FILTER_CONTROL_EXT) {
 
909
      /* GL_EXT_texture_lod_bias */
 
910
      if (!ctx->Extensions.EXT_texture_lod_bias) {
 
911
         _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(target)" );
 
912
         return;
 
913
      }
 
914
      if (pname == GL_TEXTURE_LOD_BIAS_EXT) {
 
915
         *params = texUnit->LodBias;
 
916
      }
 
917
      else {
 
918
         _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)" );
 
919
         return;
 
920
      }
 
921
   }
 
922
   else if (target == GL_POINT_SPRITE_NV) {
 
923
      /* GL_ARB_point_sprite / GL_NV_point_sprite */
 
924
      if (!ctx->Extensions.NV_point_sprite
 
925
          && !ctx->Extensions.ARB_point_sprite) {
 
926
         _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(target)" );
 
927
         return;
 
928
      }
 
929
      if (pname == GL_COORD_REPLACE_NV) {
 
930
         *params = (GLfloat) ctx->Point.CoordReplace[ctx->Texture.CurrentUnit];
 
931
      }
 
932
      else {
 
933
         _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)" );
 
934
         return;
 
935
      }
 
936
   }
 
937
   else {
 
938
      _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(target)" );
 
939
      return;
 
940
   }
 
941
}
 
942
 
 
943
 
 
944
void GLAPIENTRY
 
945
_mesa_GetTexEnviv( GLenum target, GLenum pname, GLint *params )
 
946
{
 
947
   GLuint maxUnit;
 
948
   const struct gl_texture_unit *texUnit;
 
949
   GET_CURRENT_CONTEXT(ctx);
 
950
   ASSERT_OUTSIDE_BEGIN_END(ctx);
 
951
 
 
952
   maxUnit = (target == GL_POINT_SPRITE_NV && pname == GL_COORD_REPLACE_NV)
 
953
      ? ctx->Const.MaxTextureCoordUnits : ctx->Const.MaxTextureImageUnits;
 
954
   if (ctx->Texture.CurrentUnit >= maxUnit) {
 
955
      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexEnviv(current unit)");
 
956
      return;
 
957
   }
 
958
 
 
959
   texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
 
960
 
 
961
   if (target == GL_TEXTURE_ENV) {
 
962
      switch (pname) {
 
963
         case GL_TEXTURE_ENV_MODE:
 
964
            *params = (GLint) texUnit->EnvMode;
 
965
            break;
 
966
         case GL_TEXTURE_ENV_COLOR:
 
967
            params[0] = FLOAT_TO_INT( texUnit->EnvColor[0] );
 
968
            params[1] = FLOAT_TO_INT( texUnit->EnvColor[1] );
 
969
            params[2] = FLOAT_TO_INT( texUnit->EnvColor[2] );
 
970
            params[3] = FLOAT_TO_INT( texUnit->EnvColor[3] );
 
971
            break;
 
972
         case GL_COMBINE_RGB:
 
973
            if (ctx->Extensions.EXT_texture_env_combine ||
 
974
                ctx->Extensions.ARB_texture_env_combine) {
 
975
               *params = (GLint) texUnit->Combine.ModeRGB;
 
976
            }
 
977
            else {
 
978
               _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
 
979
            }
 
980
            break;
 
981
         case GL_COMBINE_ALPHA:
 
982
            if (ctx->Extensions.EXT_texture_env_combine ||
 
983
                ctx->Extensions.ARB_texture_env_combine) {
 
984
               *params = (GLint) texUnit->Combine.ModeA;
 
985
            }
 
986
            else {
 
987
               _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
 
988
            }
 
989
            break;
 
990
         case GL_SOURCE0_RGB:
 
991
         case GL_SOURCE1_RGB:
 
992
         case GL_SOURCE2_RGB:
 
993
            if (ctx->Extensions.EXT_texture_env_combine ||
 
994
                ctx->Extensions.ARB_texture_env_combine) {
 
995
               const unsigned rgb_idx = pname - GL_SOURCE0_RGB;
 
996
               *params = (GLint) texUnit->Combine.SourceRGB[rgb_idx];
 
997
            }
 
998
            else {
 
999
               _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
 
1000
            }
 
1001
            break;
 
1002
         case GL_SOURCE0_ALPHA:
 
1003
         case GL_SOURCE1_ALPHA:
 
1004
         case GL_SOURCE2_ALPHA:
 
1005
            if (ctx->Extensions.EXT_texture_env_combine ||
 
1006
                ctx->Extensions.ARB_texture_env_combine) {
 
1007
               const unsigned alpha_idx = pname - GL_SOURCE0_ALPHA;
 
1008
               *params = (GLint) texUnit->Combine.SourceA[alpha_idx];
 
1009
            }
 
1010
            else {
 
1011
               _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
 
1012
            }
 
1013
            break;
 
1014
         case GL_OPERAND0_RGB:
 
1015
         case GL_OPERAND1_RGB:
 
1016
         case GL_OPERAND2_RGB:
 
1017
            if (ctx->Extensions.EXT_texture_env_combine ||
 
1018
                ctx->Extensions.ARB_texture_env_combine) {
 
1019
               const unsigned op_rgb = pname - GL_OPERAND0_RGB;
 
1020
               *params = (GLint) texUnit->Combine.OperandRGB[op_rgb];
 
1021
            }
 
1022
            else {
 
1023
               _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
 
1024
            }
 
1025
            break;
 
1026
         case GL_OPERAND0_ALPHA:
 
1027
         case GL_OPERAND1_ALPHA:
 
1028
         case GL_OPERAND2_ALPHA:
 
1029
            if (ctx->Extensions.EXT_texture_env_combine ||
 
1030
                ctx->Extensions.ARB_texture_env_combine) {
 
1031
               const unsigned op_alpha = pname - GL_OPERAND0_ALPHA;
 
1032
               *params = (GLint) texUnit->Combine.OperandA[op_alpha];
 
1033
            }
 
1034
            else {
 
1035
               _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
 
1036
            }
 
1037
            break;
 
1038
         case GL_RGB_SCALE:
 
1039
            if (ctx->Extensions.EXT_texture_env_combine ||
 
1040
                ctx->Extensions.ARB_texture_env_combine) {
 
1041
               if (texUnit->Combine.ScaleShiftRGB == 0)
 
1042
                  *params = 1;
 
1043
               else if (texUnit->Combine.ScaleShiftRGB == 1)
 
1044
                  *params = 2;
 
1045
               else
 
1046
                  *params = 4;
 
1047
            }
 
1048
            else {
 
1049
               _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
 
1050
               return;
 
1051
            }
 
1052
            break;
 
1053
         case GL_ALPHA_SCALE:
 
1054
            if (ctx->Extensions.EXT_texture_env_combine ||
 
1055
                ctx->Extensions.ARB_texture_env_combine) {
 
1056
               if (texUnit->Combine.ScaleShiftA == 0)
 
1057
                  *params = 1;
 
1058
               else if (texUnit->Combine.ScaleShiftA == 1)
 
1059
                  *params = 2;
 
1060
               else
 
1061
                  *params = 4;
 
1062
            }
 
1063
            else {
 
1064
               _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
 
1065
               return;
 
1066
            }
 
1067
            break;
 
1068
         default:
 
1069
            _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname=0x%x)",
 
1070
                        pname);
 
1071
      }
 
1072
   }
 
1073
   else if (target == GL_TEXTURE_FILTER_CONTROL_EXT) {
 
1074
      /* GL_EXT_texture_lod_bias */
 
1075
      if (!ctx->Extensions.EXT_texture_lod_bias) {
 
1076
         _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(target)" );
 
1077
         return;
 
1078
      }
 
1079
      if (pname == GL_TEXTURE_LOD_BIAS_EXT) {
 
1080
         *params = (GLint) texUnit->LodBias;
 
1081
      }
 
1082
      else {
 
1083
         _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)" );
 
1084
         return;
 
1085
      }
 
1086
   }
 
1087
   else if (target == GL_POINT_SPRITE_NV) {
 
1088
      /* GL_ARB_point_sprite / GL_NV_point_sprite */
 
1089
      if (!ctx->Extensions.NV_point_sprite
 
1090
          && !ctx->Extensions.ARB_point_sprite) {
 
1091
         _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(target)" );
 
1092
         return;
 
1093
      }
 
1094
      if (pname == GL_COORD_REPLACE_NV) {
 
1095
         *params = (GLint) ctx->Point.CoordReplace[ctx->Texture.CurrentUnit];
 
1096
      }
 
1097
      else {
 
1098
         _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)" );
 
1099
         return;
 
1100
      }
 
1101
   }
 
1102
   else {
 
1103
      _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(target)" );
 
1104
      return;
 
1105
   }
 
1106
}
 
1107
 
 
1108
 
 
1109
 
 
1110
 
 
1111
/**********************************************************************/
 
1112
/*                       Texture Parameters                           */
 
1113
/**********************************************************************/
 
1114
 
 
1115
static GLboolean 
 
1116
_mesa_validate_texture_wrap_mode(GLcontext * ctx,
 
1117
                                 GLenum target, GLenum eparam)
 
1118
{
 
1119
   const struct gl_extensions * const e = & ctx->Extensions;
 
1120
 
 
1121
   if (eparam == GL_CLAMP || eparam == GL_CLAMP_TO_EDGE ||
 
1122
       (eparam == GL_CLAMP_TO_BORDER && e->ARB_texture_border_clamp)) {
 
1123
      /* any texture target */
 
1124
      return GL_TRUE;
 
1125
   }
 
1126
   else if (target != GL_TEXTURE_RECTANGLE_NV &&
 
1127
            (eparam == GL_REPEAT ||
 
1128
             (eparam == GL_MIRRORED_REPEAT &&
 
1129
              e->ARB_texture_mirrored_repeat) ||
 
1130
             (eparam == GL_MIRROR_CLAMP_EXT &&
 
1131
              (e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp)) ||
 
1132
             (eparam == GL_MIRROR_CLAMP_TO_EDGE_EXT &&
 
1133
              (e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp)) ||
 
1134
             (eparam == GL_MIRROR_CLAMP_TO_BORDER_EXT &&
 
1135
              (e->EXT_texture_mirror_clamp)))) {
 
1136
      /* non-rectangle texture */
 
1137
      return GL_TRUE;
 
1138
   }
 
1139
 
 
1140
   _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
 
1141
   return GL_FALSE;
 
1142
}
 
1143
 
 
1144
 
 
1145
void GLAPIENTRY
 
1146
_mesa_TexParameterf( GLenum target, GLenum pname, GLfloat param )
 
1147
{
 
1148
   _mesa_TexParameterfv(target, pname, &param);
 
1149
}
 
1150
 
 
1151
 
 
1152
void GLAPIENTRY
 
1153
_mesa_TexParameterfv( GLenum target, GLenum pname, const GLfloat *params )
 
1154
{
 
1155
   const GLenum eparam = (GLenum) (GLint) params[0];
 
1156
   struct gl_texture_unit *texUnit;
 
1157
   struct gl_texture_object *texObj;
 
1158
   GET_CURRENT_CONTEXT(ctx);
 
1159
   ASSERT_OUTSIDE_BEGIN_END(ctx);
 
1160
 
 
1161
   if (MESA_VERBOSE&(VERBOSE_API|VERBOSE_TEXTURE))
 
1162
      _mesa_debug(ctx, "glTexParameter %s %s %.1f(%s)...\n",
 
1163
                  _mesa_lookup_enum_by_nr(target),
 
1164
                  _mesa_lookup_enum_by_nr(pname),
 
1165
                  *params,
 
1166
                  _mesa_lookup_enum_by_nr(eparam));
 
1167
 
 
1168
   if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureImageUnits) {
 
1169
      _mesa_error(ctx, GL_INVALID_OPERATION, "glTexParameterfv(current unit)");
 
1170
      return;
 
1171
   }
 
1172
 
 
1173
   texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
 
1174
 
 
1175
   switch (target) {
 
1176
      case GL_TEXTURE_1D:
 
1177
         texObj = texUnit->Current1D;
 
1178
         break;
 
1179
      case GL_TEXTURE_2D:
 
1180
         texObj = texUnit->Current2D;
 
1181
         break;
 
1182
      case GL_TEXTURE_3D:
 
1183
         texObj = texUnit->Current3D;
 
1184
         break;
 
1185
      case GL_TEXTURE_CUBE_MAP:
 
1186
         if (!ctx->Extensions.ARB_texture_cube_map) {
 
1187
            _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(target)" );
 
1188
            return;
 
1189
         }
 
1190
         texObj = texUnit->CurrentCubeMap;
 
1191
         break;
 
1192
      case GL_TEXTURE_RECTANGLE_NV:
 
1193
         if (!ctx->Extensions.NV_texture_rectangle) {
 
1194
            _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(target)" );
 
1195
            return;
 
1196
         }
 
1197
         texObj = texUnit->CurrentRect;
 
1198
         break;
 
1199
      default:
 
1200
         _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(target)" );
 
1201
         return;
 
1202
   }
 
1203
 
 
1204
   switch (pname) {
 
1205
      case GL_TEXTURE_MIN_FILTER:
 
1206
         /* A small optimization */
 
1207
         if (texObj->MinFilter == eparam)
 
1208
            return;
 
1209
         if (eparam==GL_NEAREST || eparam==GL_LINEAR) {
 
1210
            FLUSH_VERTICES(ctx, _NEW_TEXTURE);
 
1211
            texObj->MinFilter = eparam;
 
1212
         }
 
1213
         else if ((eparam==GL_NEAREST_MIPMAP_NEAREST ||
 
1214
                   eparam==GL_LINEAR_MIPMAP_NEAREST ||
 
1215
                   eparam==GL_NEAREST_MIPMAP_LINEAR ||
 
1216
                   eparam==GL_LINEAR_MIPMAP_LINEAR) &&
 
1217
                  texObj->Target != GL_TEXTURE_RECTANGLE_NV) {
 
1218
            FLUSH_VERTICES(ctx, _NEW_TEXTURE);
 
1219
            texObj->MinFilter = eparam;
 
1220
         }
 
1221
         else {
 
1222
            _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
 
1223
            return;
 
1224
         }
 
1225
         break;
 
1226
      case GL_TEXTURE_MAG_FILTER:
 
1227
         /* A small optimization */
 
1228
         if (texObj->MagFilter == eparam)
 
1229
            return;
 
1230
 
 
1231
         if (eparam==GL_NEAREST || eparam==GL_LINEAR) {
 
1232
            FLUSH_VERTICES(ctx, _NEW_TEXTURE);
 
1233
            texObj->MagFilter = eparam;
 
1234
         }
 
1235
         else {
 
1236
            _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
 
1237
            return;
 
1238
         }
 
1239
         break;
 
1240
      case GL_TEXTURE_WRAP_S:
 
1241
         if (texObj->WrapS == eparam)
 
1242
            return;
 
1243
         if (_mesa_validate_texture_wrap_mode(ctx, texObj->Target, eparam)) {
 
1244
            FLUSH_VERTICES(ctx, _NEW_TEXTURE);
 
1245
            texObj->WrapS = eparam;
 
1246
         }
 
1247
         else {
 
1248
            return;
 
1249
         }
 
1250
         break;
 
1251
      case GL_TEXTURE_WRAP_T:
 
1252
         if (texObj->WrapT == eparam)
 
1253
            return;
 
1254
         if (_mesa_validate_texture_wrap_mode(ctx, texObj->Target, eparam)) {
 
1255
            FLUSH_VERTICES(ctx, _NEW_TEXTURE);
 
1256
            texObj->WrapT = eparam;
 
1257
         }
 
1258
         else {
 
1259
            return;
 
1260
         }
 
1261
         break;
 
1262
      case GL_TEXTURE_WRAP_R:
 
1263
         if (texObj->WrapR == eparam)
 
1264
            return;
 
1265
         if (_mesa_validate_texture_wrap_mode(ctx, texObj->Target, eparam)) {
 
1266
            FLUSH_VERTICES(ctx, _NEW_TEXTURE);
 
1267
            texObj->WrapR = eparam;
 
1268
         }
 
1269
         else {
 
1270
            return;
 
1271
         }
 
1272
         break;
 
1273
      case GL_TEXTURE_BORDER_COLOR:
 
1274
         FLUSH_VERTICES(ctx, _NEW_TEXTURE);
 
1275
         texObj->BorderColor[RCOMP] = params[0];
 
1276
         texObj->BorderColor[GCOMP] = params[1];
 
1277
         texObj->BorderColor[BCOMP] = params[2];
 
1278
         texObj->BorderColor[ACOMP] = params[3];
 
1279
         UNCLAMPED_FLOAT_TO_CHAN(texObj->_BorderChan[RCOMP], params[0]);
 
1280
         UNCLAMPED_FLOAT_TO_CHAN(texObj->_BorderChan[GCOMP], params[1]);
 
1281
         UNCLAMPED_FLOAT_TO_CHAN(texObj->_BorderChan[BCOMP], params[2]);
 
1282
         UNCLAMPED_FLOAT_TO_CHAN(texObj->_BorderChan[ACOMP], params[3]);
 
1283
         break;
 
1284
      case GL_TEXTURE_MIN_LOD:
 
1285
         if (texObj->MinLod == params[0])
 
1286
            return;
 
1287
         FLUSH_VERTICES(ctx, _NEW_TEXTURE);
 
1288
         texObj->MinLod = params[0];
 
1289
         break;
 
1290
      case GL_TEXTURE_MAX_LOD:
 
1291
         if (texObj->MaxLod == params[0])
 
1292
            return;
 
1293
         FLUSH_VERTICES(ctx, _NEW_TEXTURE);
 
1294
         texObj->MaxLod = params[0];
 
1295
         break;
 
1296
      case GL_TEXTURE_BASE_LEVEL:
 
1297
         if (params[0] < 0.0) {
 
1298
            _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)");
 
1299
            return;
 
1300
         }
 
1301
         if (target == GL_TEXTURE_RECTANGLE_ARB && params[0] != 0.0) {
 
1302
            _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)");
 
1303
            return;
 
1304
         }
 
1305
         FLUSH_VERTICES(ctx, _NEW_TEXTURE);
 
1306
         texObj->BaseLevel = (GLint) params[0];
 
1307
         break;
 
1308
      case GL_TEXTURE_MAX_LEVEL:
 
1309
         if (params[0] < 0.0) {
 
1310
            _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)");
 
1311
            return;
 
1312
         }
 
1313
         if (target == GL_TEXTURE_RECTANGLE_ARB) {
 
1314
            _mesa_error(ctx, GL_INVALID_OPERATION, "glTexParameter(param)");
 
1315
            return;
 
1316
         }
 
1317
         FLUSH_VERTICES(ctx, _NEW_TEXTURE);
 
1318
         texObj->MaxLevel = (GLint) params[0];
 
1319
         break;
 
1320
      case GL_TEXTURE_PRIORITY:
 
1321
         FLUSH_VERTICES(ctx, _NEW_TEXTURE);
 
1322
         texObj->Priority = CLAMP( params[0], 0.0F, 1.0F );
 
1323
         break;
 
1324
      case GL_TEXTURE_MAX_ANISOTROPY_EXT:
 
1325
         if (ctx->Extensions.EXT_texture_filter_anisotropic) {
 
1326
            if (params[0] < 1.0) {
 
1327
               _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
 
1328
               return;
 
1329
            }
 
1330
            FLUSH_VERTICES(ctx, _NEW_TEXTURE);
 
1331
            /* clamp to max, that's what NVIDIA does */
 
1332
            texObj->MaxAnisotropy = MIN2(params[0],
 
1333
                                         ctx->Const.MaxTextureMaxAnisotropy);
 
1334
         }
 
1335
         else {
 
1336
            _mesa_error(ctx, GL_INVALID_ENUM,
 
1337
                        "glTexParameter(pname=GL_TEXTURE_MAX_ANISOTROPY_EXT)");
 
1338
            return;
 
1339
         }
 
1340
         break;
 
1341
      case GL_TEXTURE_COMPARE_SGIX:
 
1342
         if (ctx->Extensions.SGIX_shadow) {
 
1343
            FLUSH_VERTICES(ctx, _NEW_TEXTURE);
 
1344
            texObj->CompareFlag = params[0] ? GL_TRUE : GL_FALSE;
 
1345
         }
 
1346
         else {
 
1347
            _mesa_error(ctx, GL_INVALID_ENUM,
 
1348
                        "glTexParameter(pname=GL_TEXTURE_COMPARE_SGIX)");
 
1349
            return;
 
1350
         }
 
1351
         break;
 
1352
      case GL_TEXTURE_COMPARE_OPERATOR_SGIX:
 
1353
         if (ctx->Extensions.SGIX_shadow) {
 
1354
            GLenum op = (GLenum) params[0];
 
1355
            if (op == GL_TEXTURE_LEQUAL_R_SGIX ||
 
1356
                op == GL_TEXTURE_GEQUAL_R_SGIX) {
 
1357
               FLUSH_VERTICES(ctx, _NEW_TEXTURE);
 
1358
               texObj->CompareOperator = op;
 
1359
            }
 
1360
            else {
 
1361
               _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(param)");
 
1362
            }
 
1363
         }
 
1364
         else {
 
1365
            _mesa_error(ctx, GL_INVALID_ENUM,
 
1366
                    "glTexParameter(pname=GL_TEXTURE_COMPARE_OPERATOR_SGIX)");
 
1367
            return;
 
1368
         }
 
1369
         break;
 
1370
      case GL_SHADOW_AMBIENT_SGIX: /* aka GL_TEXTURE_COMPARE_FAIL_VALUE_ARB */
 
1371
         if (ctx->Extensions.SGIX_shadow_ambient) {
 
1372
            FLUSH_VERTICES(ctx, _NEW_TEXTURE);
 
1373
            texObj->ShadowAmbient = CLAMP(params[0], 0.0F, 1.0F);
 
1374
         }
 
1375
         else {
 
1376
            _mesa_error(ctx, GL_INVALID_ENUM,
 
1377
                        "glTexParameter(pname=GL_SHADOW_AMBIENT_SGIX)");
 
1378
            return;
 
1379
         }
 
1380
         break;
 
1381
      case GL_GENERATE_MIPMAP_SGIS:
 
1382
         if (ctx->Extensions.SGIS_generate_mipmap) {
 
1383
            texObj->GenerateMipmap = params[0] ? GL_TRUE : GL_FALSE;
 
1384
         }
 
1385
         else {
 
1386
            _mesa_error(ctx, GL_INVALID_ENUM,
 
1387
                        "glTexParameter(pname=GL_GENERATE_MIPMAP_SGIS)");
 
1388
            return;
 
1389
         }
 
1390
         break;
 
1391
      case GL_TEXTURE_COMPARE_MODE_ARB:
 
1392
         if (ctx->Extensions.ARB_shadow) {
 
1393
            const GLenum mode = (GLenum) params[0];
 
1394
            if (mode == GL_NONE || mode == GL_COMPARE_R_TO_TEXTURE_ARB) {
 
1395
               FLUSH_VERTICES(ctx, _NEW_TEXTURE);
 
1396
               texObj->CompareMode = mode;
 
1397
            }
 
1398
            else {
 
1399
               _mesa_error(ctx, GL_INVALID_ENUM,
 
1400
                           "glTexParameter(bad GL_TEXTURE_COMPARE_MODE_ARB: 0x%x)", mode);
 
1401
               return;
 
1402
            }
 
1403
         }
 
1404
         else {
 
1405
            _mesa_error(ctx, GL_INVALID_ENUM,
 
1406
                        "glTexParameter(pname=GL_TEXTURE_COMPARE_MODE_ARB)");
 
1407
            return;
 
1408
         }
 
1409
         break;
 
1410
      case GL_TEXTURE_COMPARE_FUNC_ARB:
 
1411
         if (ctx->Extensions.ARB_shadow) {
 
1412
            const GLenum func = (GLenum) params[0];
 
1413
            if (func == GL_LEQUAL || func == GL_GEQUAL) {
 
1414
               FLUSH_VERTICES(ctx, _NEW_TEXTURE);
 
1415
               texObj->CompareFunc = func;
 
1416
            }
 
1417
            else if (ctx->Extensions.EXT_shadow_funcs &&
 
1418
                     (func == GL_EQUAL ||
 
1419
                      func == GL_NOTEQUAL ||
 
1420
                      func == GL_LESS ||
 
1421
                      func == GL_GREATER ||
 
1422
                      func == GL_ALWAYS ||
 
1423
                      func == GL_NEVER)) {
 
1424
               FLUSH_VERTICES(ctx, _NEW_TEXTURE);
 
1425
               texObj->CompareFunc = func;
 
1426
            }
 
1427
            else {
 
1428
               _mesa_error(ctx, GL_INVALID_ENUM,
 
1429
                           "glTexParameter(bad GL_TEXTURE_COMPARE_FUNC_ARB)");
 
1430
               return;
 
1431
            }
 
1432
         }
 
1433
         else {
 
1434
            _mesa_error(ctx, GL_INVALID_ENUM,
 
1435
                        "glTexParameter(pname=GL_TEXTURE_COMPARE_FUNC_ARB)");
 
1436
            return;
 
1437
         }
 
1438
         break;
 
1439
      case GL_DEPTH_TEXTURE_MODE_ARB:
 
1440
         if (ctx->Extensions.ARB_depth_texture) {
 
1441
            const GLenum result = (GLenum) params[0];
 
1442
            if (result == GL_LUMINANCE || result == GL_INTENSITY
 
1443
                || result == GL_ALPHA) {
 
1444
               FLUSH_VERTICES(ctx, _NEW_TEXTURE);
 
1445
               texObj->DepthMode = result;
 
1446
            }
 
1447
            else {
 
1448
               _mesa_error(ctx, GL_INVALID_ENUM,
 
1449
                          "glTexParameter(bad GL_DEPTH_TEXTURE_MODE_ARB)");
 
1450
               return;
 
1451
            }
 
1452
         }
 
1453
         else {
 
1454
            _mesa_error(ctx, GL_INVALID_ENUM,
 
1455
                        "glTexParameter(pname=GL_DEPTH_TEXTURE_MODE_ARB)");
 
1456
            return;
 
1457
         }
 
1458
         break;
 
1459
      case GL_TEXTURE_LOD_BIAS:
 
1460
         /* NOTE: this is really part of OpenGL 1.4, not EXT_texture_lod_bias*/
 
1461
         if (ctx->Extensions.EXT_texture_lod_bias) {
 
1462
            if (texObj->LodBias != params[0]) {
 
1463
               FLUSH_VERTICES(ctx, _NEW_TEXTURE);
 
1464
               texObj->LodBias = params[0];
 
1465
            }
 
1466
         }
 
1467
         break;
 
1468
 
 
1469
      default:
 
1470
         _mesa_error(ctx, GL_INVALID_ENUM,
 
1471
                     "glTexParameter(pname=0x%x)", pname);
 
1472
         return;
 
1473
   }
 
1474
 
 
1475
   texObj->Complete = GL_FALSE;
 
1476
 
 
1477
   if (ctx->Driver.TexParameter) {
 
1478
      (*ctx->Driver.TexParameter)( ctx, target, texObj, pname, params );
 
1479
   }
 
1480
}
 
1481
 
 
1482
 
 
1483
void GLAPIENTRY
 
1484
_mesa_TexParameteri( GLenum target, GLenum pname, GLint param )
 
1485
{
 
1486
   GLfloat fparam[4];
 
1487
   if (pname == GL_TEXTURE_PRIORITY)
 
1488
      fparam[0] = INT_TO_FLOAT(param);
 
1489
   else
 
1490
      fparam[0] = (GLfloat) param;
 
1491
   fparam[1] = fparam[2] = fparam[3] = 0.0;
 
1492
   _mesa_TexParameterfv(target, pname, fparam);
 
1493
}
 
1494
 
 
1495
 
 
1496
void GLAPIENTRY
 
1497
_mesa_TexParameteriv( GLenum target, GLenum pname, const GLint *params )
 
1498
{
 
1499
   GLfloat fparam[4];
 
1500
   if (pname == GL_TEXTURE_BORDER_COLOR) {
 
1501
      fparam[0] = INT_TO_FLOAT(params[0]);
 
1502
      fparam[1] = INT_TO_FLOAT(params[1]);
 
1503
      fparam[2] = INT_TO_FLOAT(params[2]);
 
1504
      fparam[3] = INT_TO_FLOAT(params[3]);
 
1505
   }
 
1506
   else {
 
1507
      if (pname == GL_TEXTURE_PRIORITY)
 
1508
         fparam[0] = INT_TO_FLOAT(params[0]);
 
1509
      else
 
1510
         fparam[0] = (GLfloat) params[0];
 
1511
      fparam[1] = fparam[2] = fparam[3] = 0.0F;
 
1512
   }
 
1513
   _mesa_TexParameterfv(target, pname, fparam);
 
1514
}
 
1515
 
 
1516
 
 
1517
void GLAPIENTRY
 
1518
_mesa_GetTexLevelParameterfv( GLenum target, GLint level,
 
1519
                              GLenum pname, GLfloat *params )
 
1520
{
 
1521
   GLint iparam;
 
1522
   _mesa_GetTexLevelParameteriv( target, level, pname, &iparam );
 
1523
   *params = (GLfloat) iparam;
 
1524
}
 
1525
 
 
1526
 
 
1527
static GLuint
 
1528
tex_image_dimensions(GLcontext *ctx, GLenum target)
 
1529
{
 
1530
   switch (target) {
 
1531
      case GL_TEXTURE_1D:
 
1532
      case GL_PROXY_TEXTURE_1D:
 
1533
         return 1;
 
1534
      case GL_TEXTURE_2D:
 
1535
      case GL_PROXY_TEXTURE_2D:
 
1536
         return 2;
 
1537
      case GL_TEXTURE_3D:
 
1538
      case GL_PROXY_TEXTURE_3D:
 
1539
         return 3;
 
1540
      case GL_TEXTURE_CUBE_MAP:
 
1541
      case GL_PROXY_TEXTURE_CUBE_MAP:
 
1542
      case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
 
1543
      case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
 
1544
      case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
 
1545
      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
 
1546
      case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
 
1547
      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
 
1548
         return ctx->Extensions.ARB_texture_cube_map ? 2 : 0;
 
1549
      case GL_TEXTURE_RECTANGLE_NV:
 
1550
      case GL_PROXY_TEXTURE_RECTANGLE_NV:
 
1551
         return ctx->Extensions.NV_texture_rectangle ? 2 : 0;
 
1552
      default:
 
1553
         _mesa_problem(ctx, "bad target in _mesa_tex_target_dimensions()");
 
1554
         return 0;
 
1555
   }
 
1556
}
 
1557
 
 
1558
 
 
1559
void GLAPIENTRY
 
1560
_mesa_GetTexLevelParameteriv( GLenum target, GLint level,
 
1561
                              GLenum pname, GLint *params )
 
1562
{
 
1563
   const struct gl_texture_unit *texUnit;
 
1564
   struct gl_texture_object *texObj;
 
1565
   const struct gl_texture_image *img = NULL;
 
1566
   GLuint dimensions;
 
1567
   GLboolean isProxy;
 
1568
   GLint maxLevels;
 
1569
   GET_CURRENT_CONTEXT(ctx);
 
1570
   ASSERT_OUTSIDE_BEGIN_END(ctx);
 
1571
 
 
1572
   if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureImageUnits) {
 
1573
      _mesa_error(ctx, GL_INVALID_OPERATION,
 
1574
                  "glGetTexLevelParameteriv(current unit)");
 
1575
      return;
 
1576
   }
 
1577
 
 
1578
   texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
 
1579
 
 
1580
   /* this will catch bad target values */
 
1581
   dimensions = tex_image_dimensions(ctx, target);  /* 1, 2 or 3 */
 
1582
   if (dimensions == 0) {
 
1583
      _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(target)");
 
1584
      return;
 
1585
   }
 
1586
 
 
1587
   maxLevels = _mesa_max_texture_levels(ctx, target);
 
1588
   if (maxLevels == 0) {
 
1589
      /* should not happen since <target> was just checked above */
 
1590
      _mesa_problem(ctx, "maxLevels=0 in _mesa_GetTexLevelParameter");
 
1591
      return;
 
1592
   }
 
1593
 
 
1594
   if (level < 0 || level >= maxLevels) {
 
1595
      _mesa_error( ctx, GL_INVALID_VALUE, "glGetTexLevelParameter[if]v" );
 
1596
      return;
 
1597
   }
 
1598
 
 
1599
   texObj = _mesa_select_tex_object(ctx, texUnit, target);
 
1600
   _mesa_lock_texture(ctx, texObj);
 
1601
 
 
1602
   img = _mesa_select_tex_image(ctx, texObj, target, level);
 
1603
   if (!img || !img->TexFormat) {
 
1604
      /* undefined texture image */
 
1605
      if (pname == GL_TEXTURE_COMPONENTS)
 
1606
         *params = 1;
 
1607
      else
 
1608
         *params = 0;
 
1609
      goto out;
 
1610
   }
 
1611
 
 
1612
   isProxy = _mesa_is_proxy_texture(target);
 
1613
 
 
1614
   switch (pname) {
 
1615
      case GL_TEXTURE_WIDTH:
 
1616
         *params = img->Width;
 
1617
         break;
 
1618
      case GL_TEXTURE_HEIGHT:
 
1619
         *params = img->Height;
 
1620
         break;
 
1621
      case GL_TEXTURE_DEPTH:
 
1622
         *params = img->Depth;
 
1623
         break;
 
1624
      case GL_TEXTURE_INTERNAL_FORMAT:
 
1625
         *params = img->InternalFormat;
 
1626
         break;
 
1627
      case GL_TEXTURE_BORDER:
 
1628
         *params = img->Border;
 
1629
         break;
 
1630
      case GL_TEXTURE_RED_SIZE:
 
1631
         if (img->_BaseFormat == GL_RGB || img->_BaseFormat == GL_RGBA)
 
1632
            *params = img->TexFormat->RedBits;
 
1633
         else
 
1634
            *params = 0;
 
1635
         break;
 
1636
      case GL_TEXTURE_GREEN_SIZE:
 
1637
         if (img->_BaseFormat == GL_RGB || img->_BaseFormat == GL_RGBA)
 
1638
            *params = img->TexFormat->GreenBits;
 
1639
         else
 
1640
            *params = 0;
 
1641
         break;
 
1642
      case GL_TEXTURE_BLUE_SIZE:
 
1643
         if (img->_BaseFormat == GL_RGB || img->_BaseFormat == GL_RGBA)
 
1644
            *params = img->TexFormat->BlueBits;
 
1645
         else
 
1646
            *params = 0;
 
1647
         break;
 
1648
      case GL_TEXTURE_ALPHA_SIZE:
 
1649
         if (img->_BaseFormat == GL_ALPHA ||
 
1650
             img->_BaseFormat == GL_LUMINANCE_ALPHA ||
 
1651
             img->_BaseFormat == GL_RGBA)
 
1652
            *params = img->TexFormat->AlphaBits;
 
1653
         else
 
1654
            *params = 0;
 
1655
         break;
 
1656
      case GL_TEXTURE_INTENSITY_SIZE:
 
1657
         if (img->_BaseFormat != GL_INTENSITY)
 
1658
            *params = 0;
 
1659
         else if (img->TexFormat->IntensityBits > 0)
 
1660
            *params = img->TexFormat->IntensityBits;
 
1661
         else /* intensity probably stored as rgb texture */
 
1662
            *params = MIN2(img->TexFormat->RedBits, img->TexFormat->GreenBits);
 
1663
         break;
 
1664
      case GL_TEXTURE_LUMINANCE_SIZE:
 
1665
         if (img->_BaseFormat != GL_LUMINANCE &&
 
1666
             img->_BaseFormat != GL_LUMINANCE_ALPHA)
 
1667
            *params = 0;
 
1668
         else if (img->TexFormat->LuminanceBits > 0)
 
1669
            *params = img->TexFormat->LuminanceBits;
 
1670
         else /* luminance probably stored as rgb texture */
 
1671
            *params = MIN2(img->TexFormat->RedBits, img->TexFormat->GreenBits);
 
1672
         break;
 
1673
      case GL_TEXTURE_INDEX_SIZE_EXT:
 
1674
         if (img->_BaseFormat == GL_COLOR_INDEX)
 
1675
            *params = img->TexFormat->IndexBits;
 
1676
         else
 
1677
            *params = 0;
 
1678
         break;
 
1679
      case GL_TEXTURE_DEPTH_SIZE_ARB:
 
1680
         if (ctx->Extensions.SGIX_depth_texture ||
 
1681
             ctx->Extensions.ARB_depth_texture)
 
1682
            *params = img->TexFormat->DepthBits;
 
1683
         else
 
1684
            _mesa_error(ctx, GL_INVALID_ENUM,
 
1685
                        "glGetTexLevelParameter[if]v(pname)");
 
1686
         break;
 
1687
      case GL_TEXTURE_STENCIL_SIZE_EXT:
 
1688
         if (ctx->Extensions.EXT_packed_depth_stencil) {
 
1689
            *params = img->TexFormat->StencilBits;
 
1690
         }
 
1691
         else {
 
1692
            _mesa_error(ctx, GL_INVALID_ENUM,
 
1693
                        "glGetTexLevelParameter[if]v(pname)");
 
1694
         }
 
1695
         break;
 
1696
 
 
1697
      /* GL_ARB_texture_compression */
 
1698
      case GL_TEXTURE_COMPRESSED_IMAGE_SIZE:
 
1699
         if (ctx->Extensions.ARB_texture_compression) {
 
1700
            if (img->IsCompressed && !isProxy) {
 
1701
               /* Don't use ctx->Driver.CompressedTextureSize() since that
 
1702
                * may returned a padded hardware size.
 
1703
                */
 
1704
               *params = _mesa_compressed_texture_size(ctx, img->Width,
 
1705
                                                   img->Height, img->Depth,
 
1706
                                                   img->TexFormat->MesaFormat);
 
1707
            }
 
1708
            else {
 
1709
               _mesa_error(ctx, GL_INVALID_OPERATION,
 
1710
                           "glGetTexLevelParameter[if]v(pname)");
 
1711
            }
 
1712
         }
 
1713
         else {
 
1714
            _mesa_error(ctx, GL_INVALID_ENUM,
 
1715
                        "glGetTexLevelParameter[if]v(pname)");
 
1716
         }
 
1717
         break;
 
1718
      case GL_TEXTURE_COMPRESSED:
 
1719
         if (ctx->Extensions.ARB_texture_compression) {
 
1720
            *params = (GLint) img->IsCompressed;
 
1721
         }
 
1722
         else {
 
1723
            _mesa_error(ctx, GL_INVALID_ENUM,
 
1724
                        "glGetTexLevelParameter[if]v(pname)");
 
1725
         }
 
1726
         break;
 
1727
 
 
1728
      /* GL_ARB_texture_float */
 
1729
      case GL_TEXTURE_RED_TYPE_ARB:
 
1730
         if (ctx->Extensions.ARB_texture_float) {
 
1731
            *params = img->TexFormat->RedBits ? img->TexFormat->DataType : GL_NONE;
 
1732
         }
 
1733
         else {
 
1734
            _mesa_error(ctx, GL_INVALID_ENUM,
 
1735
                        "glGetTexLevelParameter[if]v(pname)");
 
1736
         }
 
1737
         break;
 
1738
      case GL_TEXTURE_GREEN_TYPE_ARB:
 
1739
         if (ctx->Extensions.ARB_texture_float) {
 
1740
            *params = img->TexFormat->GreenBits ? img->TexFormat->DataType : GL_NONE;
 
1741
         }
 
1742
         else {
 
1743
            _mesa_error(ctx, GL_INVALID_ENUM,
 
1744
                        "glGetTexLevelParameter[if]v(pname)");
 
1745
         }
 
1746
         break;
 
1747
      case GL_TEXTURE_BLUE_TYPE_ARB:
 
1748
         if (ctx->Extensions.ARB_texture_float) {
 
1749
            *params = img->TexFormat->BlueBits ? img->TexFormat->DataType : GL_NONE;
 
1750
         }
 
1751
         else {
 
1752
            _mesa_error(ctx, GL_INVALID_ENUM,
 
1753
                        "glGetTexLevelParameter[if]v(pname)");
 
1754
         }
 
1755
         break;
 
1756
      case GL_TEXTURE_ALPHA_TYPE_ARB:
 
1757
         if (ctx->Extensions.ARB_texture_float) {
 
1758
            *params = img->TexFormat->AlphaBits ? img->TexFormat->DataType : GL_NONE;
 
1759
         }
 
1760
         else {
 
1761
            _mesa_error(ctx, GL_INVALID_ENUM,
 
1762
                        "glGetTexLevelParameter[if]v(pname)");
 
1763
         }
 
1764
         break;
 
1765
      case GL_TEXTURE_LUMINANCE_TYPE_ARB:
 
1766
         if (ctx->Extensions.ARB_texture_float) {
 
1767
            *params = img->TexFormat->LuminanceBits ? img->TexFormat->DataType : GL_NONE;
 
1768
         }
 
1769
         else {
 
1770
            _mesa_error(ctx, GL_INVALID_ENUM,
 
1771
                        "glGetTexLevelParameter[if]v(pname)");
 
1772
         }
 
1773
         break;
 
1774
      case GL_TEXTURE_INTENSITY_TYPE_ARB:
 
1775
         if (ctx->Extensions.ARB_texture_float) {
 
1776
            *params = img->TexFormat->IntensityBits ? img->TexFormat->DataType : GL_NONE;
 
1777
         }
 
1778
         else {
 
1779
            _mesa_error(ctx, GL_INVALID_ENUM,
 
1780
                        "glGetTexLevelParameter[if]v(pname)");
 
1781
         }
 
1782
         break;
 
1783
      case GL_TEXTURE_DEPTH_TYPE_ARB:
 
1784
         if (ctx->Extensions.ARB_texture_float) {
 
1785
            *params = img->TexFormat->DepthBits ? img->TexFormat->DataType : GL_NONE;
 
1786
         }
 
1787
         else {
 
1788
            _mesa_error(ctx, GL_INVALID_ENUM,
 
1789
                        "glGetTexLevelParameter[if]v(pname)");
 
1790
         }
 
1791
         break;
 
1792
 
 
1793
      default:
 
1794
         _mesa_error(ctx, GL_INVALID_ENUM,
 
1795
                     "glGetTexLevelParameter[if]v(pname)");
 
1796
   }
 
1797
 
 
1798
 out:
 
1799
   _mesa_unlock_texture(ctx, texObj);
 
1800
}
 
1801
 
 
1802
 
 
1803
 
 
1804
void GLAPIENTRY
 
1805
_mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params )
 
1806
{
 
1807
   struct gl_texture_unit *texUnit;
 
1808
   struct gl_texture_object *obj;
 
1809
   GLboolean error = GL_FALSE;
 
1810
   GET_CURRENT_CONTEXT(ctx);
 
1811
   ASSERT_OUTSIDE_BEGIN_END(ctx);
 
1812
 
 
1813
   if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureImageUnits) {
 
1814
      _mesa_error(ctx, GL_INVALID_OPERATION,
 
1815
                  "glGetTexParameterfv(current unit)");
 
1816
      return;
 
1817
   }
 
1818
 
 
1819
   texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
 
1820
 
 
1821
   obj = _mesa_select_tex_object(ctx, texUnit, target);
 
1822
   if (!obj) {
 
1823
      _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameterfv(target)");
 
1824
      return;
 
1825
   }
 
1826
 
 
1827
   _mesa_lock_texture(ctx, obj);
 
1828
   switch (pname) {
 
1829
      case GL_TEXTURE_MAG_FILTER:
 
1830
         *params = ENUM_TO_FLOAT(obj->MagFilter);
 
1831
         break;
 
1832
      case GL_TEXTURE_MIN_FILTER:
 
1833
         *params = ENUM_TO_FLOAT(obj->MinFilter);
 
1834
         break;
 
1835
      case GL_TEXTURE_WRAP_S:
 
1836
         *params = ENUM_TO_FLOAT(obj->WrapS);
 
1837
         break;
 
1838
      case GL_TEXTURE_WRAP_T:
 
1839
         *params = ENUM_TO_FLOAT(obj->WrapT);
 
1840
         break;
 
1841
      case GL_TEXTURE_WRAP_R:
 
1842
         *params = ENUM_TO_FLOAT(obj->WrapR);
 
1843
         break;
 
1844
      case GL_TEXTURE_BORDER_COLOR:
 
1845
         params[0] = CLAMP(obj->BorderColor[0], 0.0F, 1.0F);
 
1846
         params[1] = CLAMP(obj->BorderColor[1], 0.0F, 1.0F);
 
1847
         params[2] = CLAMP(obj->BorderColor[2], 0.0F, 1.0F);
 
1848
         params[3] = CLAMP(obj->BorderColor[3], 0.0F, 1.0F);
 
1849
         break;
 
1850
      case GL_TEXTURE_RESIDENT:
 
1851
         {
 
1852
            GLboolean resident;
 
1853
            if (ctx->Driver.IsTextureResident)
 
1854
               resident = ctx->Driver.IsTextureResident(ctx, obj);
 
1855
            else
 
1856
               resident = GL_TRUE;
 
1857
            *params = ENUM_TO_FLOAT(resident);
 
1858
         }
 
1859
         break;
 
1860
      case GL_TEXTURE_PRIORITY:
 
1861
         *params = obj->Priority;
 
1862
         break;
 
1863
      case GL_TEXTURE_MIN_LOD:
 
1864
         *params = obj->MinLod;
 
1865
         break;
 
1866
      case GL_TEXTURE_MAX_LOD:
 
1867
         *params = obj->MaxLod;
 
1868
         break;
 
1869
      case GL_TEXTURE_BASE_LEVEL:
 
1870
         *params = (GLfloat) obj->BaseLevel;
 
1871
         break;
 
1872
      case GL_TEXTURE_MAX_LEVEL:
 
1873
         *params = (GLfloat) obj->MaxLevel;
 
1874
         break;
 
1875
      case GL_TEXTURE_MAX_ANISOTROPY_EXT:
 
1876
         if (ctx->Extensions.EXT_texture_filter_anisotropic) {
 
1877
            *params = obj->MaxAnisotropy;
 
1878
         }
 
1879
         else
 
1880
            error = 1;
 
1881
         break;
 
1882
      case GL_TEXTURE_COMPARE_SGIX:
 
1883
         if (ctx->Extensions.SGIX_shadow) {
 
1884
            *params = (GLfloat) obj->CompareFlag;
 
1885
         }
 
1886
         else 
 
1887
            error = 1;
 
1888
         break;
 
1889
      case GL_TEXTURE_COMPARE_OPERATOR_SGIX:
 
1890
         if (ctx->Extensions.SGIX_shadow) {
 
1891
            *params = (GLfloat) obj->CompareOperator;
 
1892
         }
 
1893
         else 
 
1894
            error = 1;
 
1895
         break;
 
1896
      case GL_SHADOW_AMBIENT_SGIX: /* aka GL_TEXTURE_COMPARE_FAIL_VALUE_ARB */
 
1897
         if (ctx->Extensions.SGIX_shadow_ambient) {
 
1898
            *params = obj->ShadowAmbient;
 
1899
         }
 
1900
         else 
 
1901
            error = 1;
 
1902
         break;
 
1903
      case GL_GENERATE_MIPMAP_SGIS:
 
1904
         if (ctx->Extensions.SGIS_generate_mipmap) {
 
1905
            *params = (GLfloat) obj->GenerateMipmap;
 
1906
         }
 
1907
         else 
 
1908
            error = 1;
 
1909
         break;
 
1910
      case GL_TEXTURE_COMPARE_MODE_ARB:
 
1911
         if (ctx->Extensions.ARB_shadow) {
 
1912
            *params = (GLfloat) obj->CompareMode;
 
1913
         }
 
1914
         else 
 
1915
            error = 1;
 
1916
         break;
 
1917
      case GL_TEXTURE_COMPARE_FUNC_ARB:
 
1918
         if (ctx->Extensions.ARB_shadow) {
 
1919
            *params = (GLfloat) obj->CompareFunc;
 
1920
         }
 
1921
         else 
 
1922
            error = 1;
 
1923
         break;
 
1924
      case GL_DEPTH_TEXTURE_MODE_ARB:
 
1925
         if (ctx->Extensions.ARB_depth_texture) {
 
1926
            *params = (GLfloat) obj->DepthMode;
 
1927
         }
 
1928
         else 
 
1929
            error = 1;
 
1930
         break;
 
1931
      case GL_TEXTURE_LOD_BIAS:
 
1932
         if (ctx->Extensions.EXT_texture_lod_bias) {
 
1933
            *params = obj->LodBias;
 
1934
         }
 
1935
         else 
 
1936
            error = 1;
 
1937
         break;
 
1938
      default:
 
1939
         error = 1;
 
1940
         break;
 
1941
   }
 
1942
   if (error)
 
1943
      _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameterfv(pname=0x%x)",
 
1944
                  pname);
 
1945
 
 
1946
   _mesa_unlock_texture(ctx, obj);
 
1947
}
 
1948
 
 
1949
 
 
1950
void GLAPIENTRY
 
1951
_mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params )
 
1952
{
 
1953
   struct gl_texture_unit *texUnit;
 
1954
   struct gl_texture_object *obj;
 
1955
   GET_CURRENT_CONTEXT(ctx);
 
1956
   ASSERT_OUTSIDE_BEGIN_END(ctx);
 
1957
 
 
1958
   if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureImageUnits) {
 
1959
      _mesa_error(ctx, GL_INVALID_OPERATION,
 
1960
                  "glGetTexParameteriv(current unit)");
 
1961
      return;
 
1962
   }
 
1963
 
 
1964
   texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
 
1965
 
 
1966
   obj = _mesa_select_tex_object(ctx, texUnit, target);
 
1967
   if (!obj) {
 
1968
      _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameteriv(target)");
 
1969
      return;
 
1970
   }
 
1971
 
 
1972
   switch (pname) {
 
1973
      case GL_TEXTURE_MAG_FILTER:
 
1974
         *params = (GLint) obj->MagFilter;
 
1975
         return;
 
1976
      case GL_TEXTURE_MIN_FILTER:
 
1977
         *params = (GLint) obj->MinFilter;
 
1978
         return;
 
1979
      case GL_TEXTURE_WRAP_S:
 
1980
         *params = (GLint) obj->WrapS;
 
1981
         return;
 
1982
      case GL_TEXTURE_WRAP_T:
 
1983
         *params = (GLint) obj->WrapT;
 
1984
         return;
 
1985
      case GL_TEXTURE_WRAP_R:
 
1986
         *params = (GLint) obj->WrapR;
 
1987
         return;
 
1988
      case GL_TEXTURE_BORDER_COLOR:
 
1989
         {
 
1990
            GLfloat b[4];
 
1991
            b[0] = CLAMP(obj->BorderColor[0], 0.0F, 1.0F);
 
1992
            b[1] = CLAMP(obj->BorderColor[1], 0.0F, 1.0F);
 
1993
            b[2] = CLAMP(obj->BorderColor[2], 0.0F, 1.0F);
 
1994
            b[3] = CLAMP(obj->BorderColor[3], 0.0F, 1.0F);
 
1995
            params[0] = FLOAT_TO_INT(b[0]);
 
1996
            params[1] = FLOAT_TO_INT(b[1]);
 
1997
            params[2] = FLOAT_TO_INT(b[2]);
 
1998
            params[3] = FLOAT_TO_INT(b[3]);
 
1999
         }
 
2000
         return;
 
2001
      case GL_TEXTURE_RESIDENT:
 
2002
         {
 
2003
            GLboolean resident;
 
2004
            if (ctx->Driver.IsTextureResident)
 
2005
               resident = ctx->Driver.IsTextureResident(ctx, obj);
 
2006
            else
 
2007
               resident = GL_TRUE;
 
2008
            *params = (GLint) resident;
 
2009
         }
 
2010
         return;
 
2011
      case GL_TEXTURE_PRIORITY:
 
2012
         *params = FLOAT_TO_INT(obj->Priority);
 
2013
         return;
 
2014
      case GL_TEXTURE_MIN_LOD:
 
2015
         *params = (GLint) obj->MinLod;
 
2016
         return;
 
2017
      case GL_TEXTURE_MAX_LOD:
 
2018
         *params = (GLint) obj->MaxLod;
 
2019
         return;
 
2020
      case GL_TEXTURE_BASE_LEVEL:
 
2021
         *params = obj->BaseLevel;
 
2022
         return;
 
2023
      case GL_TEXTURE_MAX_LEVEL:
 
2024
         *params = obj->MaxLevel;
 
2025
         return;
 
2026
      case GL_TEXTURE_MAX_ANISOTROPY_EXT:
 
2027
         if (ctx->Extensions.EXT_texture_filter_anisotropic) {
 
2028
            *params = (GLint) obj->MaxAnisotropy;
 
2029
            return;
 
2030
         }
 
2031
         break;
 
2032
      case GL_TEXTURE_COMPARE_SGIX:
 
2033
         if (ctx->Extensions.SGIX_shadow) {
 
2034
            *params = (GLint) obj->CompareFlag;
 
2035
            return;
 
2036
         }
 
2037
         break;
 
2038
      case GL_TEXTURE_COMPARE_OPERATOR_SGIX:
 
2039
         if (ctx->Extensions.SGIX_shadow) {
 
2040
            *params = (GLint) obj->CompareOperator;
 
2041
            return;
 
2042
         }
 
2043
         break;
 
2044
      case GL_SHADOW_AMBIENT_SGIX: /* aka GL_TEXTURE_COMPARE_FAIL_VALUE_ARB */
 
2045
         if (ctx->Extensions.SGIX_shadow_ambient) {
 
2046
            *params = (GLint) FLOAT_TO_INT(obj->ShadowAmbient);
 
2047
            return;
 
2048
         }
 
2049
         break;
 
2050
      case GL_GENERATE_MIPMAP_SGIS:
 
2051
         if (ctx->Extensions.SGIS_generate_mipmap) {
 
2052
            *params = (GLint) obj->GenerateMipmap;
 
2053
            return;
 
2054
         }
 
2055
         break;
 
2056
      case GL_TEXTURE_COMPARE_MODE_ARB:
 
2057
         if (ctx->Extensions.ARB_shadow) {
 
2058
            *params = (GLint) obj->CompareMode;
 
2059
            return;
 
2060
         }
 
2061
         break;
 
2062
      case GL_TEXTURE_COMPARE_FUNC_ARB:
 
2063
         if (ctx->Extensions.ARB_shadow) {
 
2064
            *params = (GLint) obj->CompareFunc;
 
2065
            return;
 
2066
         }
 
2067
         break;
 
2068
      case GL_DEPTH_TEXTURE_MODE_ARB:
 
2069
         if (ctx->Extensions.ARB_depth_texture) {
 
2070
            *params = (GLint) obj->DepthMode;
 
2071
            return;
 
2072
         }
 
2073
         break;
 
2074
      case GL_TEXTURE_LOD_BIAS:
 
2075
         if (ctx->Extensions.EXT_texture_lod_bias) {
 
2076
            *params = (GLint) obj->LodBias;
 
2077
            return;
 
2078
         }
 
2079
         break;
 
2080
      default:
 
2081
         ; /* silence warnings */
 
2082
   }
 
2083
   /* If we get here, pname was an unrecognized enum */
 
2084
   _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameteriv(pname=0x%x)", pname);
 
2085
}
 
2086
 
 
2087
 
 
2088
 
 
2089
 
 
2090
/**********************************************************************/
 
2091
/*                    Texture Coord Generation                        */
 
2092
/**********************************************************************/
 
2093
 
 
2094
#if FEATURE_texgen
 
2095
void GLAPIENTRY
 
2096
_mesa_TexGenfv( GLenum coord, GLenum pname, const GLfloat *params )
 
2097
{
 
2098
   GET_CURRENT_CONTEXT(ctx);
 
2099
   struct gl_texture_unit *texUnit;
 
2100
   ASSERT_OUTSIDE_BEGIN_END(ctx);
 
2101
 
 
2102
   if (MESA_VERBOSE&(VERBOSE_API|VERBOSE_TEXTURE))
 
2103
      _mesa_debug(ctx, "glTexGen %s %s %.1f(%s)...\n",
 
2104
                  _mesa_lookup_enum_by_nr(coord),
 
2105
                  _mesa_lookup_enum_by_nr(pname),
 
2106
                  *params,
 
2107
                  _mesa_lookup_enum_by_nr((GLenum) (GLint) *params));
 
2108
 
 
2109
   if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureCoordUnits) {
 
2110
      _mesa_error(ctx, GL_INVALID_OPERATION, "glTexGen(current unit)");
 
2111
      return;
 
2112
   }
 
2113
 
 
2114
   texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
 
2115
 
 
2116
   switch (coord) {
 
2117
      case GL_S:
 
2118
         if (pname==GL_TEXTURE_GEN_MODE) {
 
2119
            GLenum mode = (GLenum) (GLint) *params;
 
2120
            GLbitfield bits;
 
2121
            switch (mode) {
 
2122
            case GL_OBJECT_LINEAR:
 
2123
               bits = TEXGEN_OBJ_LINEAR;
 
2124
               break;
 
2125
            case GL_EYE_LINEAR:
 
2126
               bits = TEXGEN_EYE_LINEAR;
 
2127
               break;
 
2128
            case GL_REFLECTION_MAP_NV:
 
2129
               bits = TEXGEN_REFLECTION_MAP_NV;
 
2130
               break;
 
2131
            case GL_NORMAL_MAP_NV:
 
2132
               bits = TEXGEN_NORMAL_MAP_NV;
 
2133
               break;
 
2134
            case GL_SPHERE_MAP:
 
2135
               bits = TEXGEN_SPHERE_MAP;
 
2136
               break;
 
2137
            default:
 
2138
               _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" );
 
2139
               return;
 
2140
            }
 
2141
            if (texUnit->GenModeS == mode)
 
2142
               return;
 
2143
            FLUSH_VERTICES(ctx, _NEW_TEXTURE);
 
2144
            texUnit->GenModeS = mode;
 
2145
            texUnit->_GenBitS = bits;
 
2146
         }
 
2147
         else if (pname==GL_OBJECT_PLANE) {
 
2148
            if (TEST_EQ_4V(texUnit->ObjectPlaneS, params))
 
2149
                return;
 
2150
            FLUSH_VERTICES(ctx, _NEW_TEXTURE);
 
2151
            COPY_4FV(texUnit->ObjectPlaneS, params);
 
2152
         }
 
2153
         else if (pname==GL_EYE_PLANE) {
 
2154
            GLfloat tmp[4];
 
2155
            /* Transform plane equation by the inverse modelview matrix */
 
2156
            if (_math_matrix_is_dirty(ctx->ModelviewMatrixStack.Top)) {
 
2157
               _math_matrix_analyse( ctx->ModelviewMatrixStack.Top );
 
2158
            }
 
2159
            _mesa_transform_vector( tmp, params, ctx->ModelviewMatrixStack.Top->inv );
 
2160
            if (TEST_EQ_4V(texUnit->EyePlaneS, tmp))
 
2161
               return;
 
2162
            FLUSH_VERTICES(ctx, _NEW_TEXTURE);
 
2163
            COPY_4FV(texUnit->EyePlaneS, tmp);
 
2164
         }
 
2165
         else {
 
2166
            _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(pname)" );
 
2167
            return;
 
2168
         }
 
2169
         break;
 
2170
      case GL_T:
 
2171
         if (pname==GL_TEXTURE_GEN_MODE) {
 
2172
            GLenum mode = (GLenum) (GLint) *params;
 
2173
            GLbitfield bitt;
 
2174
            switch (mode) {
 
2175
               case GL_OBJECT_LINEAR:
 
2176
                  bitt = TEXGEN_OBJ_LINEAR;
 
2177
                  break;
 
2178
               case GL_EYE_LINEAR:
 
2179
                  bitt = TEXGEN_EYE_LINEAR;
 
2180
                  break;
 
2181
               case GL_REFLECTION_MAP_NV:
 
2182
                  bitt = TEXGEN_REFLECTION_MAP_NV;
 
2183
                  break;
 
2184
               case GL_NORMAL_MAP_NV:
 
2185
                  bitt = TEXGEN_NORMAL_MAP_NV;
 
2186
                  break;
 
2187
               case GL_SPHERE_MAP:
 
2188
                  bitt = TEXGEN_SPHERE_MAP;
 
2189
                  break;
 
2190
               default:
 
2191
                  _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" );
 
2192
                  return;
 
2193
            }
 
2194
            if (texUnit->GenModeT == mode)
 
2195
               return;
 
2196
            FLUSH_VERTICES(ctx, _NEW_TEXTURE);
 
2197
            texUnit->GenModeT = mode;
 
2198
            texUnit->_GenBitT = bitt;
 
2199
         }
 
2200
         else if (pname==GL_OBJECT_PLANE) {
 
2201
            if (TEST_EQ_4V(texUnit->ObjectPlaneT, params))
 
2202
                return;
 
2203
            FLUSH_VERTICES(ctx, _NEW_TEXTURE);
 
2204
            COPY_4FV(texUnit->ObjectPlaneT, params);
 
2205
         }
 
2206
         else if (pname==GL_EYE_PLANE) {
 
2207
            GLfloat tmp[4];
 
2208
            /* Transform plane equation by the inverse modelview matrix */
 
2209
            if (_math_matrix_is_dirty(ctx->ModelviewMatrixStack.Top)) {
 
2210
               _math_matrix_analyse( ctx->ModelviewMatrixStack.Top );
 
2211
            }
 
2212
            _mesa_transform_vector( tmp, params, ctx->ModelviewMatrixStack.Top->inv );
 
2213
            if (TEST_EQ_4V(texUnit->EyePlaneT, tmp))
 
2214
                return;
 
2215
            FLUSH_VERTICES(ctx, _NEW_TEXTURE);
 
2216
            COPY_4FV(texUnit->EyePlaneT, tmp);
 
2217
         }
 
2218
         else {
 
2219
            _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(pname)" );
 
2220
            return;
 
2221
         }
 
2222
         break;
 
2223
      case GL_R:
 
2224
         if (pname==GL_TEXTURE_GEN_MODE) {
 
2225
            GLenum mode = (GLenum) (GLint) *params;
 
2226
            GLbitfield bitr;
 
2227
            switch (mode) {
 
2228
            case GL_OBJECT_LINEAR:
 
2229
               bitr = TEXGEN_OBJ_LINEAR;
 
2230
               break;
 
2231
            case GL_REFLECTION_MAP_NV:
 
2232
               bitr = TEXGEN_REFLECTION_MAP_NV;
 
2233
               break;
 
2234
            case GL_NORMAL_MAP_NV:
 
2235
               bitr = TEXGEN_NORMAL_MAP_NV;
 
2236
               break;
 
2237
            case GL_EYE_LINEAR:
 
2238
               bitr = TEXGEN_EYE_LINEAR;
 
2239
               break;
 
2240
            default:
 
2241
               _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" );
 
2242
               return;
 
2243
            }
 
2244
            if (texUnit->GenModeR == mode)
 
2245
               return;
 
2246
            FLUSH_VERTICES(ctx, _NEW_TEXTURE);
 
2247
            texUnit->GenModeR = mode;
 
2248
            texUnit->_GenBitR = bitr;
 
2249
         }
 
2250
         else if (pname==GL_OBJECT_PLANE) {
 
2251
            if (TEST_EQ_4V(texUnit->ObjectPlaneR, params))
 
2252
                return;
 
2253
            FLUSH_VERTICES(ctx, _NEW_TEXTURE);
 
2254
            COPY_4FV(texUnit->ObjectPlaneR, params);
 
2255
         }
 
2256
         else if (pname==GL_EYE_PLANE) {
 
2257
            GLfloat tmp[4];
 
2258
            /* Transform plane equation by the inverse modelview matrix */
 
2259
            if (_math_matrix_is_dirty(ctx->ModelviewMatrixStack.Top)) {
 
2260
               _math_matrix_analyse( ctx->ModelviewMatrixStack.Top );
 
2261
            }
 
2262
            _mesa_transform_vector( tmp, params, ctx->ModelviewMatrixStack.Top->inv );
 
2263
            if (TEST_EQ_4V(texUnit->EyePlaneR, tmp))
 
2264
               return;
 
2265
            FLUSH_VERTICES(ctx, _NEW_TEXTURE);
 
2266
            COPY_4FV(texUnit->EyePlaneR, tmp);
 
2267
         }
 
2268
         else {
 
2269
            _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(pname)" );
 
2270
            return;
 
2271
         }
 
2272
         break;
 
2273
      case GL_Q:
 
2274
         if (pname==GL_TEXTURE_GEN_MODE) {
 
2275
            GLenum mode = (GLenum) (GLint) *params;
 
2276
            GLbitfield bitq;
 
2277
            switch (mode) {
 
2278
            case GL_OBJECT_LINEAR:
 
2279
               bitq = TEXGEN_OBJ_LINEAR;
 
2280
               break;
 
2281
            case GL_EYE_LINEAR:
 
2282
               bitq = TEXGEN_EYE_LINEAR;
 
2283
               break;
 
2284
            default:
 
2285
               _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" );
 
2286
               return;
 
2287
            }
 
2288
            if (texUnit->GenModeQ == mode)
 
2289
               return;
 
2290
            FLUSH_VERTICES(ctx, _NEW_TEXTURE);
 
2291
            texUnit->GenModeQ = mode;
 
2292
            texUnit->_GenBitQ = bitq;
 
2293
         }
 
2294
         else if (pname==GL_OBJECT_PLANE) {
 
2295
            if (TEST_EQ_4V(texUnit->ObjectPlaneQ, params))
 
2296
                return;
 
2297
            FLUSH_VERTICES(ctx, _NEW_TEXTURE);
 
2298
            COPY_4FV(texUnit->ObjectPlaneQ, params);
 
2299
         }
 
2300
         else if (pname==GL_EYE_PLANE) {
 
2301
            GLfloat tmp[4];
 
2302
            /* Transform plane equation by the inverse modelview matrix */
 
2303
            if (_math_matrix_is_dirty(ctx->ModelviewMatrixStack.Top)) {
 
2304
               _math_matrix_analyse( ctx->ModelviewMatrixStack.Top );
 
2305
            }
 
2306
            _mesa_transform_vector( tmp, params, ctx->ModelviewMatrixStack.Top->inv );
 
2307
            if (TEST_EQ_4V(texUnit->EyePlaneQ, tmp))
 
2308
               return;
 
2309
            FLUSH_VERTICES(ctx, _NEW_TEXTURE);
 
2310
            COPY_4FV(texUnit->EyePlaneQ, tmp);
 
2311
         }
 
2312
         else {
 
2313
            _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(pname)" );
 
2314
            return;
 
2315
         }
 
2316
         break;
 
2317
      default:
 
2318
         _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(coord)" );
 
2319
         return;
 
2320
   }
 
2321
 
 
2322
   if (ctx->Driver.TexGen)
 
2323
      ctx->Driver.TexGen( ctx, coord, pname, params );
 
2324
}
 
2325
 
 
2326
 
 
2327
void GLAPIENTRY
 
2328
_mesa_TexGeniv(GLenum coord, GLenum pname, const GLint *params )
 
2329
{
 
2330
   GLfloat p[4];
 
2331
   p[0] = (GLfloat) params[0];
 
2332
   if (pname == GL_TEXTURE_GEN_MODE) {
 
2333
      p[1] = p[2] = p[3] = 0.0F;
 
2334
   }
 
2335
   else {
 
2336
      p[1] = (GLfloat) params[1];
 
2337
      p[2] = (GLfloat) params[2];
 
2338
      p[3] = (GLfloat) params[3];
 
2339
   }
 
2340
   _mesa_TexGenfv(coord, pname, p);
 
2341
}
 
2342
 
 
2343
 
 
2344
void GLAPIENTRY
 
2345
_mesa_TexGend(GLenum coord, GLenum pname, GLdouble param )
 
2346
{
 
2347
   GLfloat p = (GLfloat) param;
 
2348
   _mesa_TexGenfv( coord, pname, &p );
 
2349
}
 
2350
 
 
2351
 
 
2352
void GLAPIENTRY
 
2353
_mesa_TexGendv(GLenum coord, GLenum pname, const GLdouble *params )
 
2354
{
 
2355
   GLfloat p[4];
 
2356
   p[0] = (GLfloat) params[0];
 
2357
   if (pname == GL_TEXTURE_GEN_MODE) {
 
2358
      p[1] = p[2] = p[3] = 0.0F;
 
2359
   }
 
2360
   else {
 
2361
      p[1] = (GLfloat) params[1];
 
2362
      p[2] = (GLfloat) params[2];
 
2363
      p[3] = (GLfloat) params[3];
 
2364
   }
 
2365
   _mesa_TexGenfv( coord, pname, p );
 
2366
}
 
2367
 
 
2368
 
 
2369
void GLAPIENTRY
 
2370
_mesa_TexGenf( GLenum coord, GLenum pname, GLfloat param )
 
2371
{
 
2372
   _mesa_TexGenfv(coord, pname, &param);
 
2373
}
 
2374
 
 
2375
 
 
2376
void GLAPIENTRY
 
2377
_mesa_TexGeni( GLenum coord, GLenum pname, GLint param )
 
2378
{
 
2379
   _mesa_TexGeniv( coord, pname, &param );
 
2380
}
 
2381
 
 
2382
 
 
2383
 
 
2384
void GLAPIENTRY
 
2385
_mesa_GetTexGendv( GLenum coord, GLenum pname, GLdouble *params )
 
2386
{
 
2387
   const struct gl_texture_unit *texUnit;
 
2388
   GET_CURRENT_CONTEXT(ctx);
 
2389
   ASSERT_OUTSIDE_BEGIN_END(ctx);
 
2390
 
 
2391
   if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureCoordUnits) {
 
2392
      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexGendv(current unit)");
 
2393
      return;
 
2394
   }
 
2395
 
 
2396
   texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
 
2397
 
 
2398
   switch (coord) {
 
2399
      case GL_S:
 
2400
         if (pname==GL_TEXTURE_GEN_MODE) {
 
2401
            params[0] = ENUM_TO_DOUBLE(texUnit->GenModeS);
 
2402
         }
 
2403
         else if (pname==GL_OBJECT_PLANE) {
 
2404
            COPY_4V( params, texUnit->ObjectPlaneS );
 
2405
         }
 
2406
         else if (pname==GL_EYE_PLANE) {
 
2407
            COPY_4V( params, texUnit->EyePlaneS );
 
2408
         }
 
2409
         else {
 
2410
            _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(pname)" );
 
2411
            return;
 
2412
         }
 
2413
         break;
 
2414
      case GL_T:
 
2415
         if (pname==GL_TEXTURE_GEN_MODE) {
 
2416
            params[0] = ENUM_TO_DOUBLE(texUnit->GenModeT);
 
2417
         }
 
2418
         else if (pname==GL_OBJECT_PLANE) {
 
2419
            COPY_4V( params, texUnit->ObjectPlaneT );
 
2420
         }
 
2421
         else if (pname==GL_EYE_PLANE) {
 
2422
            COPY_4V( params, texUnit->EyePlaneT );
 
2423
         }
 
2424
         else {
 
2425
            _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(pname)" );
 
2426
            return;
 
2427
         }
 
2428
         break;
 
2429
      case GL_R:
 
2430
         if (pname==GL_TEXTURE_GEN_MODE) {
 
2431
            params[0] = ENUM_TO_DOUBLE(texUnit->GenModeR);
 
2432
         }
 
2433
         else if (pname==GL_OBJECT_PLANE) {
 
2434
            COPY_4V( params, texUnit->ObjectPlaneR );
 
2435
         }
 
2436
         else if (pname==GL_EYE_PLANE) {
 
2437
            COPY_4V( params, texUnit->EyePlaneR );
 
2438
         }
 
2439
         else {
 
2440
            _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(pname)" );
 
2441
            return;
 
2442
         }
 
2443
         break;
 
2444
      case GL_Q:
 
2445
         if (pname==GL_TEXTURE_GEN_MODE) {
 
2446
            params[0] = ENUM_TO_DOUBLE(texUnit->GenModeQ);
 
2447
         }
 
2448
         else if (pname==GL_OBJECT_PLANE) {
 
2449
            COPY_4V( params, texUnit->ObjectPlaneQ );
 
2450
         }
 
2451
         else if (pname==GL_EYE_PLANE) {
 
2452
            COPY_4V( params, texUnit->EyePlaneQ );
 
2453
         }
 
2454
         else {
 
2455
            _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(pname)" );
 
2456
            return;
 
2457
         }
 
2458
         break;
 
2459
      default:
 
2460
         _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(coord)" );
 
2461
         return;
 
2462
   }
 
2463
}
 
2464
 
 
2465
 
 
2466
 
 
2467
void GLAPIENTRY
 
2468
_mesa_GetTexGenfv( GLenum coord, GLenum pname, GLfloat *params )
 
2469
{
 
2470
   const struct gl_texture_unit *texUnit;
 
2471
   GET_CURRENT_CONTEXT(ctx);
 
2472
   ASSERT_OUTSIDE_BEGIN_END(ctx);
 
2473
 
 
2474
   if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureCoordUnits) {
 
2475
      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexGenfv(current unit)");
 
2476
      return;
 
2477
   }
 
2478
 
 
2479
   texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
 
2480
 
 
2481
   switch (coord) {
 
2482
      case GL_S:
 
2483
         if (pname==GL_TEXTURE_GEN_MODE) {
 
2484
            params[0] = ENUM_TO_FLOAT(texUnit->GenModeS);
 
2485
         }
 
2486
         else if (pname==GL_OBJECT_PLANE) {
 
2487
            COPY_4V( params, texUnit->ObjectPlaneS );
 
2488
         }
 
2489
         else if (pname==GL_EYE_PLANE) {
 
2490
            COPY_4V( params, texUnit->EyePlaneS );
 
2491
         }
 
2492
         else {
 
2493
            _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(pname)" );
 
2494
            return;
 
2495
         }
 
2496
         break;
 
2497
      case GL_T:
 
2498
         if (pname==GL_TEXTURE_GEN_MODE) {
 
2499
            params[0] = ENUM_TO_FLOAT(texUnit->GenModeT);
 
2500
         }
 
2501
         else if (pname==GL_OBJECT_PLANE) {
 
2502
            COPY_4V( params, texUnit->ObjectPlaneT );
 
2503
         }
 
2504
         else if (pname==GL_EYE_PLANE) {
 
2505
            COPY_4V( params, texUnit->EyePlaneT );
 
2506
         }
 
2507
         else {
 
2508
            _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(pname)" );
 
2509
            return;
 
2510
         }
 
2511
         break;
 
2512
      case GL_R:
 
2513
         if (pname==GL_TEXTURE_GEN_MODE) {
 
2514
            params[0] = ENUM_TO_FLOAT(texUnit->GenModeR);
 
2515
         }
 
2516
         else if (pname==GL_OBJECT_PLANE) {
 
2517
            COPY_4V( params, texUnit->ObjectPlaneR );
 
2518
         }
 
2519
         else if (pname==GL_EYE_PLANE) {
 
2520
            COPY_4V( params, texUnit->EyePlaneR );
 
2521
         }
 
2522
         else {
 
2523
            _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(pname)" );
 
2524
            return;
 
2525
         }
 
2526
         break;
 
2527
      case GL_Q:
 
2528
         if (pname==GL_TEXTURE_GEN_MODE) {
 
2529
            params[0] = ENUM_TO_FLOAT(texUnit->GenModeQ);
 
2530
         }
 
2531
         else if (pname==GL_OBJECT_PLANE) {
 
2532
            COPY_4V( params, texUnit->ObjectPlaneQ );
 
2533
         }
 
2534
         else if (pname==GL_EYE_PLANE) {
 
2535
            COPY_4V( params, texUnit->EyePlaneQ );
 
2536
         }
 
2537
         else {
 
2538
            _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(pname)" );
 
2539
            return;
 
2540
         }
 
2541
         break;
 
2542
      default:
 
2543
         _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(coord)" );
 
2544
         return;
 
2545
   }
 
2546
}
 
2547
 
 
2548
 
 
2549
 
 
2550
void GLAPIENTRY
 
2551
_mesa_GetTexGeniv( GLenum coord, GLenum pname, GLint *params )
 
2552
{
 
2553
   const struct gl_texture_unit *texUnit;
 
2554
   GET_CURRENT_CONTEXT(ctx);
 
2555
   ASSERT_OUTSIDE_BEGIN_END(ctx);
 
2556
 
 
2557
   if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureCoordUnits) {
 
2558
      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexGeniv(current unit)");
 
2559
      return;
 
2560
   }
 
2561
 
 
2562
   texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
 
2563
 
 
2564
   switch (coord) {
 
2565
      case GL_S:
 
2566
         if (pname==GL_TEXTURE_GEN_MODE) {
 
2567
            params[0] = texUnit->GenModeS;
 
2568
         }
 
2569
         else if (pname==GL_OBJECT_PLANE) {
 
2570
            params[0] = (GLint) texUnit->ObjectPlaneS[0];
 
2571
            params[1] = (GLint) texUnit->ObjectPlaneS[1];
 
2572
            params[2] = (GLint) texUnit->ObjectPlaneS[2];
 
2573
            params[3] = (GLint) texUnit->ObjectPlaneS[3];
 
2574
         }
 
2575
         else if (pname==GL_EYE_PLANE) {
 
2576
            params[0] = (GLint) texUnit->EyePlaneS[0];
 
2577
            params[1] = (GLint) texUnit->EyePlaneS[1];
 
2578
            params[2] = (GLint) texUnit->EyePlaneS[2];
 
2579
            params[3] = (GLint) texUnit->EyePlaneS[3];
 
2580
         }
 
2581
         else {
 
2582
            _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(pname)" );
 
2583
            return;
 
2584
         }
 
2585
         break;
 
2586
      case GL_T:
 
2587
         if (pname==GL_TEXTURE_GEN_MODE) {
 
2588
            params[0] = texUnit->GenModeT;
 
2589
         }
 
2590
         else if (pname==GL_OBJECT_PLANE) {
 
2591
            params[0] = (GLint) texUnit->ObjectPlaneT[0];
 
2592
            params[1] = (GLint) texUnit->ObjectPlaneT[1];
 
2593
            params[2] = (GLint) texUnit->ObjectPlaneT[2];
 
2594
            params[3] = (GLint) texUnit->ObjectPlaneT[3];
 
2595
         }
 
2596
         else if (pname==GL_EYE_PLANE) {
 
2597
            params[0] = (GLint) texUnit->EyePlaneT[0];
 
2598
            params[1] = (GLint) texUnit->EyePlaneT[1];
 
2599
            params[2] = (GLint) texUnit->EyePlaneT[2];
 
2600
            params[3] = (GLint) texUnit->EyePlaneT[3];
 
2601
         }
 
2602
         else {
 
2603
            _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(pname)" );
 
2604
            return;
 
2605
         }
 
2606
         break;
 
2607
      case GL_R:
 
2608
         if (pname==GL_TEXTURE_GEN_MODE) {
 
2609
            params[0] = texUnit->GenModeR;
 
2610
         }
 
2611
         else if (pname==GL_OBJECT_PLANE) {
 
2612
            params[0] = (GLint) texUnit->ObjectPlaneR[0];
 
2613
            params[1] = (GLint) texUnit->ObjectPlaneR[1];
 
2614
            params[2] = (GLint) texUnit->ObjectPlaneR[2];
 
2615
            params[3] = (GLint) texUnit->ObjectPlaneR[3];
 
2616
         }
 
2617
         else if (pname==GL_EYE_PLANE) {
 
2618
            params[0] = (GLint) texUnit->EyePlaneR[0];
 
2619
            params[1] = (GLint) texUnit->EyePlaneR[1];
 
2620
            params[2] = (GLint) texUnit->EyePlaneR[2];
 
2621
            params[3] = (GLint) texUnit->EyePlaneR[3];
 
2622
         }
 
2623
         else {
 
2624
            _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(pname)" );
 
2625
            return;
 
2626
         }
 
2627
         break;
 
2628
      case GL_Q:
 
2629
         if (pname==GL_TEXTURE_GEN_MODE) {
 
2630
            params[0] = texUnit->GenModeQ;
 
2631
         }
 
2632
         else if (pname==GL_OBJECT_PLANE) {
 
2633
            params[0] = (GLint) texUnit->ObjectPlaneQ[0];
 
2634
            params[1] = (GLint) texUnit->ObjectPlaneQ[1];
 
2635
            params[2] = (GLint) texUnit->ObjectPlaneQ[2];
 
2636
            params[3] = (GLint) texUnit->ObjectPlaneQ[3];
 
2637
         }
 
2638
         else if (pname==GL_EYE_PLANE) {
 
2639
            params[0] = (GLint) texUnit->EyePlaneQ[0];
 
2640
            params[1] = (GLint) texUnit->EyePlaneQ[1];
 
2641
            params[2] = (GLint) texUnit->EyePlaneQ[2];
 
2642
            params[3] = (GLint) texUnit->EyePlaneQ[3];
 
2643
         }
 
2644
         else {
 
2645
            _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(pname)" );
 
2646
            return;
 
2647
         }
 
2648
         break;
 
2649
      default:
 
2650
         _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(coord)" );
 
2651
         return;
 
2652
   }
 
2653
}
 
2654
#endif
 
2655
 
 
2656
 
 
2657
/* GL_ARB_multitexture */
 
2658
void GLAPIENTRY
 
2659
_mesa_ActiveTextureARB(GLenum texture)
 
2660
{
 
2661
   GET_CURRENT_CONTEXT(ctx);
 
2662
   const GLuint texUnit = texture - GL_TEXTURE0;
 
2663
   ASSERT_OUTSIDE_BEGIN_END(ctx);
 
2664
 
 
2665
   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
 
2666
      _mesa_debug(ctx, "glActiveTexture %s\n",
 
2667
                  _mesa_lookup_enum_by_nr(texture));
 
2668
 
 
2669
   /* XXX error-check against max(coordunits, imageunits) */
 
2670
   if (texUnit >= ctx->Const.MaxTextureUnits) {
 
2671
      _mesa_error(ctx, GL_INVALID_ENUM, "glActiveTexture(texture)");
 
2672
      return;
 
2673
   }
 
2674
 
 
2675
   if (ctx->Texture.CurrentUnit == texUnit)
 
2676
      return;
 
2677
 
 
2678
   FLUSH_VERTICES(ctx, _NEW_TEXTURE);
 
2679
 
 
2680
   ctx->Texture.CurrentUnit = texUnit;
 
2681
   if (ctx->Transform.MatrixMode == GL_TEXTURE) {
 
2682
      /* update current stack pointer */
 
2683
      ctx->CurrentStack = &ctx->TextureMatrixStack[texUnit];
 
2684
   }
 
2685
 
 
2686
   if (ctx->Driver.ActiveTexture) {
 
2687
      (*ctx->Driver.ActiveTexture)( ctx, (GLuint) texUnit );
 
2688
   }
 
2689
}
 
2690
 
 
2691
 
 
2692
/* GL_ARB_multitexture */
 
2693
void GLAPIENTRY
 
2694
_mesa_ClientActiveTextureARB(GLenum texture)
 
2695
{
 
2696
   GET_CURRENT_CONTEXT(ctx);
 
2697
   GLuint texUnit = texture - GL_TEXTURE0;
 
2698
   ASSERT_OUTSIDE_BEGIN_END(ctx);
 
2699
 
 
2700
   if (texUnit >= ctx->Const.MaxTextureCoordUnits) {
 
2701
      _mesa_error(ctx, GL_INVALID_ENUM, "glClientActiveTexture(texture)");
 
2702
      return;
 
2703
   }
 
2704
 
 
2705
   FLUSH_VERTICES(ctx, _NEW_ARRAY);
 
2706
   ctx->Array.ActiveTexture = texUnit;
 
2707
}
 
2708
 
 
2709
 
 
2710
 
 
2711
/**********************************************************************/
 
2712
/*****                    State management                        *****/
 
2713
/**********************************************************************/
 
2714
 
 
2715
 
 
2716
/**
 
2717
 * \note This routine refers to derived texture attribute values to
 
2718
 * compute the ENABLE_TEXMAT flags, but is only called on
 
2719
 * _NEW_TEXTURE_MATRIX.  On changes to _NEW_TEXTURE, the ENABLE_TEXMAT
 
2720
 * flags are updated by _mesa_update_textures(), below.
 
2721
 *
 
2722
 * \param ctx GL context.
 
2723
 */
 
2724
static void
 
2725
update_texture_matrices( GLcontext *ctx )
 
2726
{
 
2727
   GLuint i;
 
2728
 
 
2729
   ctx->Texture._TexMatEnabled = 0;
 
2730
 
 
2731
   for (i=0; i < ctx->Const.MaxTextureUnits; i++) {
 
2732
      if (_math_matrix_is_dirty(ctx->TextureMatrixStack[i].Top)) {
 
2733
         _math_matrix_analyse( ctx->TextureMatrixStack[i].Top );
 
2734
 
 
2735
         if (ctx->Texture.Unit[i]._ReallyEnabled &&
 
2736
             ctx->TextureMatrixStack[i].Top->type != MATRIX_IDENTITY)
 
2737
            ctx->Texture._TexMatEnabled |= ENABLE_TEXMAT(i);
 
2738
 
 
2739
         if (ctx->Driver.TextureMatrix)
 
2740
            ctx->Driver.TextureMatrix( ctx, i, ctx->TextureMatrixStack[i].Top);
 
2741
      }
 
2742
   }
 
2743
}
 
2744
 
 
2745
 
 
2746
/**
 
2747
 * Helper function for determining which texture object (1D, 2D, cube, etc)
 
2748
 * should actually be used.
 
2749
 */
 
2750
static void
 
2751
texture_override(GLcontext *ctx,
 
2752
                 struct gl_texture_unit *texUnit, GLbitfield enableBits,
 
2753
                 struct gl_texture_object *texObj, GLuint textureBit)
 
2754
{
 
2755
   if (!texUnit->_ReallyEnabled && (enableBits & textureBit)) {
 
2756
      if (!texObj->Complete) {
 
2757
         _mesa_test_texobj_completeness(ctx, texObj);
 
2758
      }
 
2759
      if (texObj->Complete) {
 
2760
         texUnit->_ReallyEnabled = textureBit;
 
2761
         texUnit->_Current = texObj;
 
2762
      }
 
2763
   }
 
2764
}
 
2765
 
 
2766
 
 
2767
/**
 
2768
 * \note This routine refers to derived texture matrix values to
 
2769
 * compute the ENABLE_TEXMAT flags, but is only called on
 
2770
 * _NEW_TEXTURE.  On changes to _NEW_TEXTURE_MATRIX, the ENABLE_TEXMAT
 
2771
 * flags are updated by _mesa_update_texture_matrices, above.
 
2772
 *
 
2773
 * \param ctx GL context.
 
2774
 */
 
2775
static void
 
2776
update_texture_state( GLcontext *ctx )
 
2777
{
 
2778
   GLuint unit;
 
2779
   struct gl_fragment_program *fprog = NULL;
 
2780
   struct gl_vertex_program *vprog = NULL;
 
2781
 
 
2782
   if (ctx->Shader.CurrentProgram &&
 
2783
       ctx->Shader.CurrentProgram->LinkStatus) {
 
2784
      fprog = ctx->Shader.CurrentProgram->FragmentProgram;
 
2785
      vprog = ctx->Shader.CurrentProgram->VertexProgram;
 
2786
   }
 
2787
   else {
 
2788
      if (ctx->FragmentProgram._Enabled) {
 
2789
         fprog = ctx->FragmentProgram.Current;
 
2790
      }
 
2791
      if (ctx->VertexProgram._Enabled) {
 
2792
         /* XXX enable this if/when non-shader vertex programs get
 
2793
          * texture fetches:
 
2794
         vprog = ctx->VertexProgram.Current;
 
2795
         */
 
2796
      }
 
2797
   }
 
2798
 
 
2799
   ctx->NewState |= _NEW_TEXTURE; /* TODO: only set this if there are 
 
2800
                                   * actual changes. 
 
2801
                                   */
 
2802
 
 
2803
   ctx->Texture._EnabledUnits = 0;
 
2804
   ctx->Texture._GenFlags = 0;
 
2805
   ctx->Texture._TexMatEnabled = 0;
 
2806
   ctx->Texture._TexGenEnabled = 0;
 
2807
 
 
2808
   /*
 
2809
    * Update texture unit state.
 
2810
    */
 
2811
   for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
 
2812
      struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
 
2813
      GLbitfield enableBits;
 
2814
 
 
2815
      texUnit->_Current = NULL;
 
2816
      texUnit->_ReallyEnabled = 0;
 
2817
      texUnit->_GenFlags = 0;
 
2818
 
 
2819
      /* Get the bitmask of texture enables.
 
2820
       * enableBits will be a mask of the TEXTURE_*_BIT flags indicating
 
2821
       * which texture targets are enabled (fixed function) or referenced
 
2822
       * by a fragment shader/program.  When multiple flags are set, we'll
 
2823
       * settle on the one with highest priority (see texture_override below).
 
2824
       */
 
2825
      if (fprog || vprog) {
 
2826
         enableBits = 0x0;
 
2827
         if (fprog)
 
2828
            enableBits |= fprog->Base.TexturesUsed[unit];
 
2829
         if (vprog)
 
2830
            enableBits |= vprog->Base.TexturesUsed[unit];
 
2831
      }
 
2832
      else {
 
2833
         if (!texUnit->Enabled)
 
2834
            continue;
 
2835
         enableBits = texUnit->Enabled;
 
2836
      }
 
2837
 
 
2838
      /* Look for the highest-priority texture target that's enabled and
 
2839
       * complete.  That's the one we'll use for texturing.  If we're using
 
2840
       * a fragment program we're guaranteed that bitcount(enabledBits) <= 1.
 
2841
       */
 
2842
      texture_override(ctx, texUnit, enableBits,
 
2843
                       texUnit->CurrentCubeMap, TEXTURE_CUBE_BIT);
 
2844
      texture_override(ctx, texUnit, enableBits,
 
2845
                       texUnit->Current3D, TEXTURE_3D_BIT);
 
2846
      texture_override(ctx, texUnit, enableBits,
 
2847
                       texUnit->CurrentRect, TEXTURE_RECT_BIT);
 
2848
      texture_override(ctx, texUnit, enableBits,
 
2849
                       texUnit->Current2D, TEXTURE_2D_BIT);
 
2850
      texture_override(ctx, texUnit, enableBits,
 
2851
                       texUnit->Current1D, TEXTURE_1D_BIT);
 
2852
 
 
2853
      if (!texUnit->_ReallyEnabled) {
 
2854
         continue;
 
2855
      }
 
2856
 
 
2857
      if (texUnit->_ReallyEnabled)
 
2858
         ctx->Texture._EnabledUnits |= (1 << unit);
 
2859
 
 
2860
      if (texUnit->EnvMode == GL_COMBINE) {
 
2861
         texUnit->_CurrentCombine = & texUnit->Combine;
 
2862
      }
 
2863
      else {
 
2864
         const struct gl_texture_object *texObj = texUnit->_Current;
 
2865
         GLenum format = texObj->Image[0][texObj->BaseLevel]->_BaseFormat;
 
2866
         if (format == GL_COLOR_INDEX) {
 
2867
            format = GL_RGBA;  /* a bit of a hack */
 
2868
         }
 
2869
         else if (format == GL_DEPTH_COMPONENT
 
2870
                  || format == GL_DEPTH_STENCIL_EXT) {
 
2871
            format = texObj->DepthMode;
 
2872
         }
 
2873
         calculate_derived_texenv(&texUnit->_EnvMode, texUnit->EnvMode, format);
 
2874
         texUnit->_CurrentCombine = & texUnit->_EnvMode;
 
2875
      }
 
2876
 
 
2877
      switch (texUnit->_CurrentCombine->ModeRGB) {
 
2878
      case GL_REPLACE:
 
2879
         texUnit->_CurrentCombine->_NumArgsRGB = 1;
 
2880
         break;
 
2881
      case GL_MODULATE:
 
2882
      case GL_ADD:
 
2883
      case GL_ADD_SIGNED:
 
2884
      case GL_SUBTRACT:
 
2885
      case GL_DOT3_RGB:
 
2886
      case GL_DOT3_RGBA:
 
2887
      case GL_DOT3_RGB_EXT:
 
2888
      case GL_DOT3_RGBA_EXT:
 
2889
         texUnit->_CurrentCombine->_NumArgsRGB = 2;
 
2890
         break;
 
2891
      case GL_INTERPOLATE:
 
2892
      case GL_MODULATE_ADD_ATI:
 
2893
      case GL_MODULATE_SIGNED_ADD_ATI:
 
2894
      case GL_MODULATE_SUBTRACT_ATI:
 
2895
         texUnit->_CurrentCombine->_NumArgsRGB = 3;
 
2896
         break;
 
2897
      default:
 
2898
         texUnit->_CurrentCombine->_NumArgsRGB = 0;
 
2899
         _mesa_problem(ctx, "invalid RGB combine mode in update_texture_state");
 
2900
         return;
 
2901
      }
 
2902
 
 
2903
      switch (texUnit->_CurrentCombine->ModeA) {
 
2904
      case GL_REPLACE:
 
2905
         texUnit->_CurrentCombine->_NumArgsA = 1;
 
2906
         break;
 
2907
      case GL_MODULATE:
 
2908
      case GL_ADD:
 
2909
      case GL_ADD_SIGNED:
 
2910
      case GL_SUBTRACT:
 
2911
         texUnit->_CurrentCombine->_NumArgsA = 2;
 
2912
         break;
 
2913
      case GL_INTERPOLATE:
 
2914
      case GL_MODULATE_ADD_ATI:
 
2915
      case GL_MODULATE_SIGNED_ADD_ATI:
 
2916
      case GL_MODULATE_SUBTRACT_ATI:
 
2917
         texUnit->_CurrentCombine->_NumArgsA = 3;
 
2918
         break;
 
2919
      default:
 
2920
         texUnit->_CurrentCombine->_NumArgsA = 0;
 
2921
         _mesa_problem(ctx, "invalid Alpha combine mode in update_texture_state");
 
2922
         break;
 
2923
      }
 
2924
 
 
2925
      if (texUnit->TexGenEnabled) {
 
2926
         if (texUnit->TexGenEnabled & S_BIT) {
 
2927
            texUnit->_GenFlags |= texUnit->_GenBitS;
 
2928
         }
 
2929
         if (texUnit->TexGenEnabled & T_BIT) {
 
2930
            texUnit->_GenFlags |= texUnit->_GenBitT;
 
2931
         }
 
2932
         if (texUnit->TexGenEnabled & Q_BIT) {
 
2933
            texUnit->_GenFlags |= texUnit->_GenBitQ;
 
2934
         }
 
2935
         if (texUnit->TexGenEnabled & R_BIT) {
 
2936
            texUnit->_GenFlags |= texUnit->_GenBitR;
 
2937
         }
 
2938
 
 
2939
         ctx->Texture._TexGenEnabled |= ENABLE_TEXGEN(unit);
 
2940
         ctx->Texture._GenFlags |= texUnit->_GenFlags;
 
2941
      }
 
2942
 
 
2943
      if (ctx->TextureMatrixStack[unit].Top->type != MATRIX_IDENTITY)
 
2944
         ctx->Texture._TexMatEnabled |= ENABLE_TEXMAT(unit);
 
2945
   }
 
2946
 
 
2947
   /* Determine which texture coordinate sets are actually needed */
 
2948
   if (fprog) {
 
2949
      const GLuint coordMask = (1 << MAX_TEXTURE_COORD_UNITS) - 1;
 
2950
      ctx->Texture._EnabledCoordUnits
 
2951
         = (fprog->Base.InputsRead >> FRAG_ATTRIB_TEX0) & coordMask;
 
2952
   }
 
2953
   else {
 
2954
      ctx->Texture._EnabledCoordUnits = ctx->Texture._EnabledUnits;
 
2955
   }
 
2956
}
 
2957
 
 
2958
 
 
2959
/**
 
2960
 * Update texture-related derived state.
 
2961
 */
 
2962
void
 
2963
_mesa_update_texture( GLcontext *ctx, GLuint new_state )
 
2964
{
 
2965
   if (new_state & _NEW_TEXTURE_MATRIX)
 
2966
      update_texture_matrices( ctx );
 
2967
 
 
2968
   if (new_state & (_NEW_TEXTURE | _NEW_PROGRAM))
 
2969
      update_texture_state( ctx );
 
2970
}
 
2971
 
 
2972
 
 
2973
/**********************************************************************/
 
2974
/*****                      Initialization                        *****/
 
2975
/**********************************************************************/
 
2976
 
 
2977
/**
 
2978
 * Allocate the proxy textures for the given context.
 
2979
 * 
 
2980
 * \param ctx the context to allocate proxies for.
 
2981
 * 
 
2982
 * \return GL_TRUE on success, or GL_FALSE on failure
 
2983
 * 
 
2984
 * If run out of memory part way through the allocations, clean up and return
 
2985
 * GL_FALSE.
 
2986
 */
 
2987
static GLboolean
 
2988
alloc_proxy_textures( GLcontext *ctx )
 
2989
{
 
2990
   ctx->Texture.Proxy1D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_1D);
 
2991
   if (!ctx->Texture.Proxy1D)
 
2992
      goto cleanup;
 
2993
 
 
2994
   ctx->Texture.Proxy2D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_2D);
 
2995
   if (!ctx->Texture.Proxy2D)
 
2996
      goto cleanup;
 
2997
 
 
2998
   ctx->Texture.Proxy3D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_3D);
 
2999
   if (!ctx->Texture.Proxy3D)
 
3000
      goto cleanup;
 
3001
 
 
3002
   ctx->Texture.ProxyCubeMap = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_CUBE_MAP_ARB);
 
3003
   if (!ctx->Texture.ProxyCubeMap)
 
3004
      goto cleanup;
 
3005
 
 
3006
   ctx->Texture.ProxyRect = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_RECTANGLE_NV);
 
3007
   if (!ctx->Texture.ProxyRect)
 
3008
      goto cleanup;
 
3009
 
 
3010
   assert(ctx->Texture.Proxy1D->RefCount == 1);
 
3011
 
 
3012
   return GL_TRUE;
 
3013
 
 
3014
 cleanup:
 
3015
   if (ctx->Texture.Proxy1D)
 
3016
      (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy1D);
 
3017
   if (ctx->Texture.Proxy2D)
 
3018
      (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy2D);
 
3019
   if (ctx->Texture.Proxy3D)
 
3020
      (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy3D);
 
3021
   if (ctx->Texture.ProxyCubeMap)
 
3022
      (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.ProxyCubeMap);
 
3023
   if (ctx->Texture.ProxyRect)
 
3024
      (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.ProxyRect);
 
3025
   return GL_FALSE;
 
3026
}
 
3027
 
 
3028
 
 
3029
/**
 
3030
 * Initialize a texture unit.
 
3031
 *
 
3032
 * \param ctx GL context.
 
3033
 * \param unit texture unit number to be initialized.
 
3034
 */
 
3035
static void
 
3036
init_texture_unit( GLcontext *ctx, GLuint unit )
 
3037
{
 
3038
   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
 
3039
 
 
3040
   texUnit->EnvMode = GL_MODULATE;
 
3041
   ASSIGN_4V( texUnit->EnvColor, 0.0, 0.0, 0.0, 0.0 );
 
3042
 
 
3043
   texUnit->Combine = default_combine_state;
 
3044
   texUnit->_EnvMode = default_combine_state;
 
3045
   texUnit->_CurrentCombine = & texUnit->_EnvMode;
 
3046
 
 
3047
   texUnit->TexGenEnabled = 0;
 
3048
   texUnit->GenModeS = GL_EYE_LINEAR;
 
3049
   texUnit->GenModeT = GL_EYE_LINEAR;
 
3050
   texUnit->GenModeR = GL_EYE_LINEAR;
 
3051
   texUnit->GenModeQ = GL_EYE_LINEAR;
 
3052
   texUnit->_GenBitS = TEXGEN_EYE_LINEAR;
 
3053
   texUnit->_GenBitT = TEXGEN_EYE_LINEAR;
 
3054
   texUnit->_GenBitR = TEXGEN_EYE_LINEAR;
 
3055
   texUnit->_GenBitQ = TEXGEN_EYE_LINEAR;
 
3056
 
 
3057
   /* Yes, these plane coefficients are correct! */
 
3058
   ASSIGN_4V( texUnit->ObjectPlaneS, 1.0, 0.0, 0.0, 0.0 );
 
3059
   ASSIGN_4V( texUnit->ObjectPlaneT, 0.0, 1.0, 0.0, 0.0 );
 
3060
   ASSIGN_4V( texUnit->ObjectPlaneR, 0.0, 0.0, 0.0, 0.0 );
 
3061
   ASSIGN_4V( texUnit->ObjectPlaneQ, 0.0, 0.0, 0.0, 0.0 );
 
3062
   ASSIGN_4V( texUnit->EyePlaneS, 1.0, 0.0, 0.0, 0.0 );
 
3063
   ASSIGN_4V( texUnit->EyePlaneT, 0.0, 1.0, 0.0, 0.0 );
 
3064
   ASSIGN_4V( texUnit->EyePlaneR, 0.0, 0.0, 0.0, 0.0 );
 
3065
   ASSIGN_4V( texUnit->EyePlaneQ, 0.0, 0.0, 0.0, 0.0 );
 
3066
 
 
3067
   /* initialize current texture object ptrs to the shared default objects */
 
3068
   _mesa_reference_texobj(&texUnit->Current1D, ctx->Shared->Default1D);
 
3069
   _mesa_reference_texobj(&texUnit->Current2D, ctx->Shared->Default2D);
 
3070
   _mesa_reference_texobj(&texUnit->Current3D, ctx->Shared->Default3D);
 
3071
   _mesa_reference_texobj(&texUnit->CurrentCubeMap, ctx->Shared->DefaultCubeMap);
 
3072
   _mesa_reference_texobj(&texUnit->CurrentRect, ctx->Shared->DefaultRect);
 
3073
}
 
3074
 
 
3075
 
 
3076
/**
 
3077
 * Initialize texture state for the given context.
 
3078
 */
 
3079
GLboolean
 
3080
_mesa_init_texture(GLcontext *ctx)
 
3081
{
 
3082
   GLuint i;
 
3083
 
 
3084
   assert(MAX_TEXTURE_LEVELS >= MAX_3D_TEXTURE_LEVELS);
 
3085
   assert(MAX_TEXTURE_LEVELS >= MAX_CUBE_TEXTURE_LEVELS);
 
3086
 
 
3087
   /* Texture group */
 
3088
   ctx->Texture.CurrentUnit = 0;      /* multitexture */
 
3089
   ctx->Texture._EnabledUnits = 0;
 
3090
   ctx->Texture.SharedPalette = GL_FALSE;
 
3091
   _mesa_init_colortable(&ctx->Texture.Palette);
 
3092
 
 
3093
   for (i = 0; i < MAX_TEXTURE_UNITS; i++)
 
3094
      init_texture_unit( ctx, i );
 
3095
 
 
3096
   /* After we're done initializing the context's texture state the default
 
3097
    * texture objects' refcounts should be at least MAX_TEXTURE_UNITS + 1.
 
3098
    */
 
3099
   assert(ctx->Shared->Default1D->RefCount >= MAX_TEXTURE_UNITS + 1);
 
3100
 
 
3101
   _mesa_TexEnvProgramCacheInit( ctx );
 
3102
 
 
3103
   /* Allocate proxy textures */
 
3104
   if (!alloc_proxy_textures( ctx ))
 
3105
      return GL_FALSE;
 
3106
 
 
3107
   return GL_TRUE;
 
3108
}
 
3109
 
 
3110
 
 
3111
/**
 
3112
 * Free dynamically-allocated texture data attached to the given context.
 
3113
 */
 
3114
void
 
3115
_mesa_free_texture_data(GLcontext *ctx)
 
3116
{
 
3117
   GLuint u;
 
3118
 
 
3119
   /* unreference current textures */
 
3120
   for (u = 0; u < MAX_TEXTURE_IMAGE_UNITS; u++) {
 
3121
      struct gl_texture_unit *unit = ctx->Texture.Unit + u;
 
3122
      _mesa_reference_texobj(&unit->Current1D, NULL);
 
3123
      _mesa_reference_texobj(&unit->Current2D, NULL);
 
3124
      _mesa_reference_texobj(&unit->Current3D, NULL);
 
3125
      _mesa_reference_texobj(&unit->CurrentCubeMap, NULL);
 
3126
      _mesa_reference_texobj(&unit->CurrentRect, NULL);
 
3127
   }
 
3128
 
 
3129
   /* Free proxy texture objects */
 
3130
   (ctx->Driver.DeleteTexture)(ctx,  ctx->Texture.Proxy1D );
 
3131
   (ctx->Driver.DeleteTexture)(ctx,  ctx->Texture.Proxy2D );
 
3132
   (ctx->Driver.DeleteTexture)(ctx,  ctx->Texture.Proxy3D );
 
3133
   (ctx->Driver.DeleteTexture)(ctx,  ctx->Texture.ProxyCubeMap );
 
3134
   (ctx->Driver.DeleteTexture)(ctx,  ctx->Texture.ProxyRect );
 
3135
 
 
3136
   for (u = 0; u < MAX_TEXTURE_IMAGE_UNITS; u++)
 
3137
      _mesa_free_colortable_data( &ctx->Texture.Unit[u].ColorTable );
 
3138
 
 
3139
   _mesa_TexEnvProgramCacheDestroy( ctx );
 
3140
}