texstate.c 36.5 KB
Newer Older
jtg's avatar
jtg committed
1
2
/*
 * Mesa 3-D graphics library
Jouk Jansen's avatar
   
Jouk Jansen committed
3
 *
4
 * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
Jouk Jansen's avatar
   
Jouk Jansen committed
5
 *
jtg's avatar
jtg committed
6
7
8
9
10
11
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
Jouk Jansen's avatar
   
Jouk Jansen committed
12
 *
jtg's avatar
jtg committed
13
14
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
Jouk Jansen's avatar
   
Jouk Jansen committed
15
 *
jtg's avatar
jtg committed
16
17
18
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19
20
21
22
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
jtg's avatar
jtg committed
23
24
 */

25
/**
26
27
28
29
 * \file texstate.c
 *
 * Texture state handling.
 */
jtg's avatar
jtg committed
30

31
#include <stdio.h>
32
#include "glheader.h"
33
#include "bufferobj.h"
jtg's avatar
jtg committed
34
35
36
37
#include "context.h"
#include "enums.h"
#include "macros.h"
#include "texobj.h"
38
#include "teximage.h"
jtg's avatar
jtg committed
39
#include "texstate.h"
Jouk Jansen's avatar
   
Jouk Jansen committed
40
#include "mtypes.h"
41
#include "state.h"
42
#include "util/bitscan.h"
43
#include "util/bitset.h"
jtg's avatar
jtg committed
44
45


46
47
48
49
50
51
52
/**
 * Default texture combine environment state.  This is used to initialize
 * a context's texture units and as the basis for converting "classic"
 * texture environmnets to ARB_texture_env_combine style values.
 */
static const struct gl_tex_env_combine_state default_combine_state = {
   GL_MODULATE, GL_MODULATE,
53
54
55
56
   { GL_TEXTURE, GL_PREVIOUS, GL_CONSTANT, GL_CONSTANT },
   { GL_TEXTURE, GL_PREVIOUS, GL_CONSTANT, GL_CONSTANT },
   { GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_ALPHA, GL_SRC_ALPHA },
   { GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA },
57
58
59
   0, 0,
   2, 2
};
jtg's avatar
jtg committed
60
61


62
63
64
65

/**
 * Used by glXCopyContext to copy texture state from one context to another.
 */
66
void
67
_mesa_copy_texture_state( const struct gl_context *src, struct gl_context *dst )
68
{
69
   GLuint u, tex;
70

71
72
   assert(src);
   assert(dst);
73
74
75
76
77
78
79

   dst->Texture.CurrentUnit = src->Texture.CurrentUnit;
   dst->Texture._GenFlags = src->Texture._GenFlags;
   dst->Texture._TexGenEnabled = src->Texture._TexGenEnabled;
   dst->Texture._TexMatEnabled = src->Texture._TexMatEnabled;

   /* per-unit state */
80
   for (u = 0; u < src->Const.MaxCombinedTextureImageUnits; u++) {
81
      dst->Texture.Unit[u].LodBias = src->Texture.Unit[u].LodBias;
82

83
84
85
86
87
88
89
90
91
92
93
94
95
      /*
       * XXX strictly speaking, we should compare texture names/ids and
       * bind textures in the dest context according to id.  For now, only
       * copy bindings if the contexts share the same pool of textures to
       * avoid refcounting bugs.
       */
      if (dst->Shared == src->Shared) {
         /* copy texture object bindings, not contents of texture objects */
         _mesa_lock_context_textures(dst);

         for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) {
            _mesa_reference_texobj(&dst->Texture.Unit[u].CurrentTex[tex],
                                   src->Texture.Unit[u].CurrentTex[tex]);
96
97
98
99
            if (src->Texture.Unit[u].CurrentTex[tex]) {
               dst->Texture.NumCurrentTexUsed =
                  MAX2(dst->Texture.NumCurrentTexUsed, u + 1);
            }
100
         }
101
         dst->Texture.Unit[u]._BoundTextures = src->Texture.Unit[u]._BoundTextures;
102
         _mesa_unlock_context_textures(dst);
103
      }
104
   }
105

106
   for (u = 0; u < src->Const.MaxTextureCoordUnits; u++) {
107
108
109
110
111
112
113
114
115
116
117
118
      dst->Texture.FixedFuncUnit[u].Enabled = src->Texture.FixedFuncUnit[u].Enabled;
      dst->Texture.FixedFuncUnit[u].EnvMode = src->Texture.FixedFuncUnit[u].EnvMode;
      COPY_4V(dst->Texture.FixedFuncUnit[u].EnvColor, src->Texture.FixedFuncUnit[u].EnvColor);
      dst->Texture.FixedFuncUnit[u].TexGenEnabled = src->Texture.FixedFuncUnit[u].TexGenEnabled;
      dst->Texture.FixedFuncUnit[u].GenS = src->Texture.FixedFuncUnit[u].GenS;
      dst->Texture.FixedFuncUnit[u].GenT = src->Texture.FixedFuncUnit[u].GenT;
      dst->Texture.FixedFuncUnit[u].GenR = src->Texture.FixedFuncUnit[u].GenR;
      dst->Texture.FixedFuncUnit[u].GenQ = src->Texture.FixedFuncUnit[u].GenQ;

      /* GL_EXT_texture_env_combine */
      dst->Texture.FixedFuncUnit[u].Combine = src->Texture.FixedFuncUnit[u].Combine;
   }
119
120
121
}


122
123
124
125
/*
 * For debugging
 */
void
126
_mesa_print_texunit_state( struct gl_context *ctx, GLuint unit )
127
{
128
   const struct gl_fixedfunc_texture_unit *texUnit = ctx->Texture.FixedFuncUnit + unit;
129
   printf("Texture Unit %d\n", unit);
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
   printf("  GL_TEXTURE_ENV_MODE = %s\n", _mesa_enum_to_string(texUnit->EnvMode));
   printf("  GL_COMBINE_RGB = %s\n", _mesa_enum_to_string(texUnit->Combine.ModeRGB));
   printf("  GL_COMBINE_ALPHA = %s\n", _mesa_enum_to_string(texUnit->Combine.ModeA));
   printf("  GL_SOURCE0_RGB = %s\n", _mesa_enum_to_string(texUnit->Combine.SourceRGB[0]));
   printf("  GL_SOURCE1_RGB = %s\n", _mesa_enum_to_string(texUnit->Combine.SourceRGB[1]));
   printf("  GL_SOURCE2_RGB = %s\n", _mesa_enum_to_string(texUnit->Combine.SourceRGB[2]));
   printf("  GL_SOURCE0_ALPHA = %s\n", _mesa_enum_to_string(texUnit->Combine.SourceA[0]));
   printf("  GL_SOURCE1_ALPHA = %s\n", _mesa_enum_to_string(texUnit->Combine.SourceA[1]));
   printf("  GL_SOURCE2_ALPHA = %s\n", _mesa_enum_to_string(texUnit->Combine.SourceA[2]));
   printf("  GL_OPERAND0_RGB = %s\n", _mesa_enum_to_string(texUnit->Combine.OperandRGB[0]));
   printf("  GL_OPERAND1_RGB = %s\n", _mesa_enum_to_string(texUnit->Combine.OperandRGB[1]));
   printf("  GL_OPERAND2_RGB = %s\n", _mesa_enum_to_string(texUnit->Combine.OperandRGB[2]));
   printf("  GL_OPERAND0_ALPHA = %s\n", _mesa_enum_to_string(texUnit->Combine.OperandA[0]));
   printf("  GL_OPERAND1_ALPHA = %s\n", _mesa_enum_to_string(texUnit->Combine.OperandA[1]));
   printf("  GL_OPERAND2_ALPHA = %s\n", _mesa_enum_to_string(texUnit->Combine.OperandA[2]));
145
146
147
   printf("  GL_RGB_SCALE = %d\n", 1 << texUnit->Combine.ScaleShiftRGB);
   printf("  GL_ALPHA_SCALE = %d\n", 1 << texUnit->Combine.ScaleShiftA);
   printf("  GL_TEXTURE_ENV_COLOR = (%f, %f, %f, %f)\n", texUnit->EnvColor[0], texUnit->EnvColor[1], texUnit->EnvColor[2], texUnit->EnvColor[3]);
148
149
150
151
}



jtg's avatar
jtg committed
152
153
154
155
/**********************************************************************/
/*                       Texture Environment                          */
/**********************************************************************/

156
157
158
/**
 * Convert "classic" texture environment to ARB_texture_env_combine style
 * environments.
159
 *
160
161
162
 * \param state  texture_env_combine state vector to be filled-in.
 * \param mode   Classic texture environment mode (i.e., \c GL_REPLACE,
 *               \c GL_BLEND, \c GL_DECAL, etc.).
163
 * \param texBaseFormat  Base format of the texture associated with the
164
165
166
 *               texture unit.
 */
static void
167
168
calculate_derived_texenv( struct gl_tex_env_combine_state *state,
			  GLenum mode, GLenum texBaseFormat )
169
170
171
172
173
174
{
   GLenum mode_rgb;
   GLenum mode_a;

   *state = default_combine_state;

175
   switch (texBaseFormat) {
176
177
178
179
180
181
182
183
184
185
   case GL_ALPHA:
      state->SourceRGB[0] = GL_PREVIOUS;
      break;

   case GL_LUMINANCE_ALPHA:
   case GL_INTENSITY:
   case GL_RGBA:
      break;

   case GL_LUMINANCE:
186
187
   case GL_RED:
   case GL_RG:
188
189
190
191
   case GL_RGB:
   case GL_YCBCR_MESA:
      state->SourceA[0] = GL_PREVIOUS;
      break;
192

193
   default:
194
195
196
      _mesa_problem(NULL,
                    "Invalid texBaseFormat 0x%x in calculate_derived_texenv",
                    texBaseFormat);
197
198
199
      return;
   }

200
201
202
   if (mode == GL_REPLACE_EXT)
      mode = GL_REPLACE;

203
   switch (mode) {
204
205
   case GL_REPLACE:
   case GL_MODULATE:
206
      mode_rgb = (texBaseFormat == GL_ALPHA) ? GL_REPLACE : mode;
207
208
      mode_a   = mode;
      break;
209

210
211
212
213
214
215
216
217
218
219
   case GL_DECAL:
      mode_rgb = GL_INTERPOLATE;
      mode_a   = GL_REPLACE;

      state->SourceA[0] = GL_PREVIOUS;

      /* Having alpha / luminance / intensity textures replace using the
       * incoming fragment color matches the definition in NV_texture_shader.
       * The 1.5 spec simply marks these as "undefined".
       */
220
      switch (texBaseFormat) {
221
222
223
224
225
226
      case GL_ALPHA:
      case GL_LUMINANCE:
      case GL_LUMINANCE_ALPHA:
      case GL_INTENSITY:
	 state->SourceRGB[0] = GL_PREVIOUS;
	 break;
227
228
      case GL_RED:
      case GL_RG:
229
230
231
232
233
234
235
236
237
238
239
240
241
242
      case GL_RGB:
      case GL_YCBCR_MESA:
	 mode_rgb = GL_REPLACE;
	 break;
      case GL_RGBA:
	 state->SourceRGB[2] = GL_TEXTURE;
	 break;
      }
      break;

   case GL_BLEND:
      mode_rgb = GL_INTERPOLATE;
      mode_a   = GL_MODULATE;

243
      switch (texBaseFormat) {
244
245
246
247
248
      case GL_ALPHA:
	 mode_rgb = GL_REPLACE;
	 break;
      case GL_INTENSITY:
	 mode_a = GL_INTERPOLATE;
249
250
	 state->SourceA[0] = GL_CONSTANT;
	 state->OperandA[2] = GL_SRC_ALPHA;
251
252
	 /* FALLTHROUGH */
      case GL_LUMINANCE:
253
254
      case GL_RED:
      case GL_RG:
255
256
257
258
259
260
261
262
263
264
265
266
267
      case GL_RGB:
      case GL_LUMINANCE_ALPHA:
      case GL_RGBA:
      case GL_YCBCR_MESA:
	 state->SourceRGB[2] = GL_TEXTURE;
	 state->SourceA[2]   = GL_TEXTURE;
	 state->SourceRGB[0] = GL_CONSTANT;
	 state->OperandRGB[2] = GL_SRC_COLOR;
	 break;
      }
      break;

   case GL_ADD:
268
269
      mode_rgb = (texBaseFormat == GL_ALPHA) ? GL_REPLACE : GL_ADD;
      mode_a   = (texBaseFormat == GL_INTENSITY) ? GL_ADD : GL_MODULATE;
270
271
272
      break;

   default:
273
      _mesa_problem(NULL,
274
275
                    "Invalid texture env mode 0x%x in calculate_derived_texenv",
                    mode);
276
      return;
277
   }
278

279
280
281
282
283
   state->ModeRGB = (state->SourceRGB[0] != GL_PREVIOUS)
       ? mode_rgb : GL_REPLACE;
   state->ModeA   = (state->SourceA[0]   != GL_PREVIOUS)
       ? mode_a   : GL_REPLACE;
}
jtg's avatar
jtg committed
284

285

jtg's avatar
jtg committed
286
/* GL_ARB_multitexture */
287
288
static ALWAYS_INLINE void
active_texture(GLenum texture, bool no_error)
jtg's avatar
jtg committed
289
{
290
   const GLuint texUnit = texture - GL_TEXTURE0;
291

292
293
   GET_CURRENT_CONTEXT(ctx);

jtg's avatar
jtg committed
294
   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
295
      _mesa_debug(ctx, "glActiveTexture %s\n",
296
                  _mesa_enum_to_string(texture));
jtg's avatar
jtg committed
297

298
299
300
   if (ctx->Texture.CurrentUnit == texUnit)
      return;

301
302
   if (!no_error) {
      GLuint k = _mesa_max_tex_unit(ctx);
303

304
      assert(k <= ARRAY_SIZE(ctx->Texture.Unit));
305

306
307
308
309
310
      if (texUnit >= k) {
         _mesa_error(ctx, GL_INVALID_ENUM, "glActiveTexture(texture=%s)",
                     _mesa_enum_to_string(texture));
         return;
      }
Keith Whitwell's avatar
Keith Whitwell committed
311
312
   }

313
314
315
316
317
318
319
320
321
322
323
324
325

   /* The below flush call seems useless because
    * gl_context::Texture::CurrentUnit is not used by
    * _mesa_update_texture_state() and friends.
    *
    * However removing the flush
    * introduced some blinking textures in UT2004. More investigation is
    * needed to find the root cause.
    *
    * https://bugs.freedesktop.org/show_bug.cgi?id=105436
    */
   FLUSH_VERTICES(ctx, _NEW_TEXTURE_STATE);

Keith Whitwell's avatar
Keith Whitwell committed
326
   ctx->Texture.CurrentUnit = texUnit;
327
328
329
330
   if (ctx->Transform.MatrixMode == GL_TEXTURE) {
      /* update current stack pointer */
      ctx->CurrentStack = &ctx->TextureMatrixStack[texUnit];
   }
jtg's avatar
jtg committed
331
332
333
}


334
335
336
337
338
339
340
341
342
343
344
345
346
347
void GLAPIENTRY
_mesa_ActiveTexture_no_error(GLenum texture)
{
   active_texture(texture, true);
}


void GLAPIENTRY
_mesa_ActiveTexture(GLenum texture)
{
   active_texture(texture, false);
}


jtg's avatar
jtg committed
348
/* GL_ARB_multitexture */
349
void GLAPIENTRY
350
_mesa_ClientActiveTexture(GLenum texture)
jtg's avatar
jtg committed
351
{
352
   GET_CURRENT_CONTEXT(ctx);
353
   GLuint texUnit = texture - GL_TEXTURE0;
jtg's avatar
jtg committed
354

355
356
   if (MESA_VERBOSE & (VERBOSE_API | VERBOSE_TEXTURE))
      _mesa_debug(ctx, "glClientActiveTexture %s\n",
357
                  _mesa_enum_to_string(texture));
358

359
360
361
   if (ctx->Array.ActiveTexture == texUnit)
      return;

362
   if (texUnit >= ctx->Const.MaxTextureCoordUnits) {
363
364
      _mesa_error(ctx, GL_INVALID_ENUM, "glClientActiveTexture(texture=%s)",
                  _mesa_enum_to_string(texture));
Keith Whitwell's avatar
Keith Whitwell committed
365
      return;
jtg's avatar
jtg committed
366
   }
Keith Whitwell's avatar
Keith Whitwell committed
367

368
   /* Don't flush vertices. This is a "latched" state. */
Keith Whitwell's avatar
Keith Whitwell committed
369
   ctx->Array.ActiveTexture = texUnit;
jtg's avatar
jtg committed
370
}
371
372
373



374
375
376
377
378
379
380
381
/**********************************************************************/
/*****                    State management                        *****/
/**********************************************************************/


/**
 * \note This routine refers to derived texture attribute values to
 * compute the ENABLE_TEXMAT flags, but is only called on
382
383
 * _NEW_TEXTURE_MATRIX.  On changes to _NEW_TEXTURE_OBJECT/STATE,
 * the ENABLE_TEXMAT flags are updated by _mesa_update_textures(), below.
384
385
386
 *
 * \param ctx GL context.
 */
387
388
void
_mesa_update_texture_matrices(struct gl_context *ctx)
389
{
390
   GLuint u;
391

392
   ctx->Texture._TexMatEnabled = 0x0;
393

394
   for (u = 0; u < ctx->Const.MaxTextureCoordUnits; u++) {
395
      assert(u < ARRAY_SIZE(ctx->TextureMatrixStack));
396
397
      if (_math_matrix_is_dirty(ctx->TextureMatrixStack[u].Top)) {
	 _math_matrix_analyse( ctx->TextureMatrixStack[u].Top );
398

399
	 if (ctx->Texture.Unit[u]._Current &&
400
401
	     ctx->TextureMatrixStack[u].Top->type != MATRIX_IDENTITY)
	    ctx->Texture._TexMatEnabled |= ENABLE_TEXMAT(u);
402
403
404
      }
   }
}
405
406


407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
/**
 * Translate GL combiner state into a MODE_x value
 */
static uint32_t
tex_combine_translate_mode(GLenum envMode, GLenum mode)
{
   switch (mode) {
   case GL_REPLACE: return TEXENV_MODE_REPLACE;
   case GL_MODULATE: return TEXENV_MODE_MODULATE;
   case GL_ADD:
      if (envMode == GL_COMBINE4_NV)
	 return TEXENV_MODE_ADD_PRODUCTS_NV;
      else
	 return TEXENV_MODE_ADD;
   case GL_ADD_SIGNED:
      if (envMode == GL_COMBINE4_NV)
	 return TEXENV_MODE_ADD_PRODUCTS_SIGNED_NV;
      else
	 return TEXENV_MODE_ADD_SIGNED;
   case GL_INTERPOLATE: return TEXENV_MODE_INTERPOLATE;
   case GL_SUBTRACT: return TEXENV_MODE_SUBTRACT;
   case GL_DOT3_RGB: return TEXENV_MODE_DOT3_RGB;
   case GL_DOT3_RGB_EXT: return TEXENV_MODE_DOT3_RGB_EXT;
   case GL_DOT3_RGBA: return TEXENV_MODE_DOT3_RGBA;
   case GL_DOT3_RGBA_EXT: return TEXENV_MODE_DOT3_RGBA_EXT;
   case GL_MODULATE_ADD_ATI: return TEXENV_MODE_MODULATE_ADD_ATI;
   case GL_MODULATE_SIGNED_ADD_ATI: return TEXENV_MODE_MODULATE_SIGNED_ADD_ATI;
   case GL_MODULATE_SUBTRACT_ATI: return TEXENV_MODE_MODULATE_SUBTRACT_ATI;
   default:
      unreachable("Invalid TexEnv Combine mode");
   }
}


static uint8_t
tex_combine_translate_source(GLenum src)
{
   switch (src) {
   case GL_TEXTURE0:
   case GL_TEXTURE1:
   case GL_TEXTURE2:
   case GL_TEXTURE3:
   case GL_TEXTURE4:
   case GL_TEXTURE5:
   case GL_TEXTURE6:
   case GL_TEXTURE7: return TEXENV_SRC_TEXTURE0 + (src - GL_TEXTURE0);
   case GL_TEXTURE: return TEXENV_SRC_TEXTURE;
   case GL_PREVIOUS: return TEXENV_SRC_PREVIOUS;
   case GL_PRIMARY_COLOR: return TEXENV_SRC_PRIMARY_COLOR;
   case GL_CONSTANT: return TEXENV_SRC_CONSTANT;
   case GL_ZERO: return TEXENV_SRC_ZERO;
   case GL_ONE: return TEXENV_SRC_ONE;
   default:
      unreachable("Invalid TexEnv Combine argument source");
   }
}


static uint8_t
tex_combine_translate_operand(GLenum operand)
{
   switch (operand) {
   case GL_SRC_COLOR: return TEXENV_OPR_COLOR;
   case GL_ONE_MINUS_SRC_COLOR: return TEXENV_OPR_ONE_MINUS_COLOR;
   case GL_SRC_ALPHA: return TEXENV_OPR_ALPHA;
   case GL_ONE_MINUS_SRC_ALPHA: return TEXENV_OPR_ONE_MINUS_ALPHA;
   default:
      unreachable("Invalid TexEnv Combine argument source");
   }
}


static void
480
pack_tex_combine(struct gl_fixedfunc_texture_unit *texUnit)
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
{
   struct gl_tex_env_combine_state *state = texUnit->_CurrentCombine;
   struct gl_tex_env_combine_packed *packed = &texUnit->_CurrentCombinePacked;

   memset(packed, 0, sizeof *packed);

   packed->ModeRGB = tex_combine_translate_mode(texUnit->EnvMode, state->ModeRGB);
   packed->ModeA = tex_combine_translate_mode(texUnit->EnvMode, state->ModeA);
   packed->ScaleShiftRGB = state->ScaleShiftRGB;
   packed->ScaleShiftA = state->ScaleShiftA;
   packed->NumArgsRGB = state->_NumArgsRGB;
   packed->NumArgsA = state->_NumArgsA;

   for (int i = 0; i < state->_NumArgsRGB; ++i)
   {
      packed->ArgsRGB[i].Source = tex_combine_translate_source(state->SourceRGB[i]);
      packed->ArgsRGB[i].Operand = tex_combine_translate_operand(state->OperandRGB[i]);
   }

   for (int i = 0; i < state->_NumArgsA; ++i)
   {
      packed->ArgsA[i].Source = tex_combine_translate_source(state->SourceA[i]);
      packed->ArgsA[i].Operand = tex_combine_translate_operand(state->OperandA[i]);
   }
}


508
509
510
511
/**
 * Examine texture unit's combine/env state to update derived state.
 */
static void
512
513
514
update_tex_combine(struct gl_context *ctx,
                   struct gl_texture_unit *texUnit,
                   struct gl_fixedfunc_texture_unit *fftexUnit)
515
{
516
517
   struct gl_tex_env_combine_state *combine;

518
519
520
521
   /* No combiners will apply to this. */
   if (texUnit->_Current->Target == GL_TEXTURE_BUFFER)
      return;

522
523
524
525
   /* Set the texUnit->_CurrentCombine field to point to the user's combiner
    * state, or the combiner state which is derived from traditional texenv
    * mode.
    */
526
527
528
   if (fftexUnit->EnvMode == GL_COMBINE ||
       fftexUnit->EnvMode == GL_COMBINE4_NV) {
      fftexUnit->_CurrentCombine = & fftexUnit->Combine;
529
530
531
532
   }
   else {
      const struct gl_texture_object *texObj = texUnit->_Current;
      GLenum format = texObj->Image[0][texObj->BaseLevel]->_BaseFormat;
533
534

      if (format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL_EXT) {
535
         format = texObj->DepthMode;
536
      }
537
538
      calculate_derived_texenv(&fftexUnit->_EnvMode, fftexUnit->EnvMode, format);
      fftexUnit->_CurrentCombine = & fftexUnit->_EnvMode;
539
540
   }

541
   combine = fftexUnit->_CurrentCombine;
542

543
   /* Determine number of source RGB terms in the combiner function */
544
   switch (combine->ModeRGB) {
545
   case GL_REPLACE:
546
      combine->_NumArgsRGB = 1;
547
548
549
      break;
   case GL_ADD:
   case GL_ADD_SIGNED:
550
      if (fftexUnit->EnvMode == GL_COMBINE4_NV)
551
         combine->_NumArgsRGB = 4;
552
      else
553
         combine->_NumArgsRGB = 2;
554
555
556
557
558
559
560
      break;
   case GL_MODULATE:
   case GL_SUBTRACT:
   case GL_DOT3_RGB:
   case GL_DOT3_RGBA:
   case GL_DOT3_RGB_EXT:
   case GL_DOT3_RGBA_EXT:
561
      combine->_NumArgsRGB = 2;
562
563
564
565
566
      break;
   case GL_INTERPOLATE:
   case GL_MODULATE_ADD_ATI:
   case GL_MODULATE_SIGNED_ADD_ATI:
   case GL_MODULATE_SUBTRACT_ATI:
567
      combine->_NumArgsRGB = 3;
568
569
      break;
   default:
570
      combine->_NumArgsRGB = 0;
571
572
573
574
575
      _mesa_problem(ctx, "invalid RGB combine mode in update_texture_state");
      return;
   }

   /* Determine number of source Alpha terms in the combiner function */
576
   switch (combine->ModeA) {
577
   case GL_REPLACE:
578
      combine->_NumArgsA = 1;
579
580
581
      break;
   case GL_ADD:
   case GL_ADD_SIGNED:
582
      if (fftexUnit->EnvMode == GL_COMBINE4_NV)
583
         combine->_NumArgsA = 4;
584
      else
585
         combine->_NumArgsA = 2;
586
587
588
      break;
   case GL_MODULATE:
   case GL_SUBTRACT:
589
      combine->_NumArgsA = 2;
590
591
592
593
594
      break;
   case GL_INTERPOLATE:
   case GL_MODULATE_ADD_ATI:
   case GL_MODULATE_SIGNED_ADD_ATI:
   case GL_MODULATE_SUBTRACT_ATI:
595
      combine->_NumArgsA = 3;
596
597
      break;
   default:
598
      combine->_NumArgsA = 0;
599
600
601
      _mesa_problem(ctx, "invalid Alpha combine mode in update_texture_state");
      break;
   }
602

603
   pack_tex_combine(fftexUnit);
604
605
}

606
607
608
609
610
611
612
static void
update_texgen(struct gl_context *ctx)
{
   GLuint unit;

   /* Setup texgen for those texture coordinate sets that are in use */
   for (unit = 0; unit < ctx->Const.MaxTextureCoordUnits; unit++) {
613
614
      struct gl_fixedfunc_texture_unit *texUnit =
         &ctx->Texture.FixedFuncUnit[unit];
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638

      texUnit->_GenFlags = 0x0;

      if (!(ctx->Texture._EnabledCoordUnits & (1 << unit)))
	 continue;

      if (texUnit->TexGenEnabled) {
	 if (texUnit->TexGenEnabled & S_BIT) {
	    texUnit->_GenFlags |= texUnit->GenS._ModeBit;
	 }
	 if (texUnit->TexGenEnabled & T_BIT) {
	    texUnit->_GenFlags |= texUnit->GenT._ModeBit;
	 }
	 if (texUnit->TexGenEnabled & R_BIT) {
	    texUnit->_GenFlags |= texUnit->GenR._ModeBit;
	 }
	 if (texUnit->TexGenEnabled & Q_BIT) {
	    texUnit->_GenFlags |= texUnit->GenQ._ModeBit;
	 }

	 ctx->Texture._TexGenEnabled |= ENABLE_TEXGEN(unit);
	 ctx->Texture._GenFlags |= texUnit->_GenFlags;
      }

639
      assert(unit < ARRAY_SIZE(ctx->TextureMatrixStack));
640
641
642
643
      if (ctx->TextureMatrixStack[unit].Top->type != MATRIX_IDENTITY)
	 ctx->Texture._TexMatEnabled |= ENABLE_TEXMAT(unit);
   }
}
644

645
646
static struct gl_texture_object *
update_single_program_texture(struct gl_context *ctx, struct gl_program *prog,
647
                              int unit)
648
649
650
651
{
   gl_texture_index target_index;
   struct gl_texture_unit *texUnit;
   struct gl_texture_object *texObj;
652
   struct gl_sampler_object *sampler;
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668

   texUnit = &ctx->Texture.Unit[unit];

   /* Note: If more than one bit was set in TexturesUsed[unit], then we should
    * have had the draw call rejected already.  From the GL 4.4 specification,
    * section 7.10 ("Samplers"):
    *
    *     "It is not allowed to have variables of different sampler types
    *      pointing to the same texture image unit within a program
    *      object. This situation can only be detected at the next rendering
    *      command issued which triggers shader invocations, and an
    *      INVALID_OPERATION error will then be generated."
    */
   target_index = ffs(prog->TexturesUsed[unit]) - 1;
   texObj = texUnit->CurrentTex[target_index];

669
   sampler = texUnit->Sampler ?
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
      texUnit->Sampler : &texObj->Sampler;

   if (likely(texObj)) {
      if (_mesa_is_texture_complete(texObj, sampler))
         return texObj;

      _mesa_test_texobj_completeness(ctx, texObj);
      if (_mesa_is_texture_complete(texObj, sampler))
         return texObj;
   }

   /* If we've reached this point, we didn't find a complete texture of the
    * shader's target.  From the GL 4.4 core specification, section 11.1.3.5
    * ("Texture Access"):
    *
    *     "If a sampler is used in a shader and the sampler’s associated
    *      texture is not complete, as defined in section 8.17, (0, 0, 0, 1)
    *      will be returned for a non-shadow sampler and 0 for a shadow
    *      sampler."
    *
    * Mesa implements this by creating a hidden texture object with a pixel of
    * that value.
    */
   texObj = _mesa_get_fallback_texture(ctx, target_index);
   assert(texObj);

   return texObj;
}

699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
static inline void
update_single_program_texture_state(struct gl_context *ctx,
                                    struct gl_program *prog,
                                    int unit,
                                    BITSET_WORD *enabled_texture_units)
{
   struct gl_texture_object *texObj;

   texObj = update_single_program_texture(ctx, prog, unit);

   _mesa_reference_texobj(&ctx->Texture.Unit[unit]._Current, texObj);
   BITSET_SET(enabled_texture_units, unit);
   ctx->Texture._MaxEnabledTexImageUnit =
      MAX2(ctx->Texture._MaxEnabledTexImageUnit, (int)unit);
}

715
static void
716
717
update_program_texture_state(struct gl_context *ctx, struct gl_program **prog,
                             BITSET_WORD *enabled_texture_units)
718
{
719
720
   int i;

721
   for (i = 0; i < MESA_SHADER_STAGES; i++) {
722
      GLbitfield mask;
723
      GLuint s;
724

725
      if (!prog[i])
726
727
         continue;

728
729
730
      mask = prog[i]->SamplersUsed;

      while (mask) {
731
         s = u_bit_scan(&mask);
732
733
734
735

         update_single_program_texture_state(ctx, prog[i],
                                             prog[i]->SamplerUnits[s],
                                             enabled_texture_units);
736
      }
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751

      if (unlikely(prog[i]->sh.HasBoundBindlessSampler)) {
         /* Loop over bindless samplers bound to texture units.
          */
         for (s = 0; s < prog[i]->sh.NumBindlessSamplers; s++) {
            struct gl_bindless_sampler *sampler =
               &prog[i]->sh.BindlessSamplers[s];

            if (!sampler->bound)
               continue;

            update_single_program_texture_state(ctx, prog[i], sampler->unit,
                                                enabled_texture_units);
         }
      }
752
753
   }

754
   if (prog[MESA_SHADER_FRAGMENT]) {
755
      const GLuint coordMask = (1 << MAX_TEXTURE_COORD_UNITS) - 1;
756
      ctx->Texture._EnabledCoordUnits |=
757
         (prog[MESA_SHADER_FRAGMENT]->info.inputs_read >> VARYING_SLOT_TEX0) &
758
         coordMask;
759
   }
760
761
762
763
764
765
766
767
768
769
}

static void
update_ff_texture_state(struct gl_context *ctx,
                        BITSET_WORD *enabled_texture_units)
{
   int unit;

   for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
      struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
770
771
      struct gl_fixedfunc_texture_unit *fftexUnit =
         &ctx->Texture.FixedFuncUnit[unit];
772
      GLbitfield mask;
773
      bool complete;
774

775
      if (fftexUnit->Enabled == 0x0)
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
         continue;

      /* If a shader already dictated what texture target was used for this
       * unit, just go along with it.
       */
      if (BITSET_TEST(enabled_texture_units, unit))
         continue;

      /* From the GL 4.4 compat specification, section 16.2 ("Texture Application"):
       *
       *     "Texturing is enabled or disabled using the generic Enable and
       *      Disable commands, respectively, with the symbolic constants
       *      TEXTURE_1D, TEXTURE_2D, TEXTURE_RECTANGLE, TEXTURE_3D, or
       *      TEXTURE_CUBE_MAP to enable the one-, two-, rectangular,
       *      three-dimensional, or cube map texture, respectively. If more
       *      than one of these textures is enabled, the first one enabled
       *      from the following list is used:
       *
       *      • cube map texture
       *      • three-dimensional texture
       *      • rectangular texture
       *      • two-dimensional texture
       *      • one-dimensional texture"
       *
       * Note that the TEXTURE_x_INDEX values are in high to low priority.
       * Also:
       *
       *     "If a texture unit is disabled or has an invalid or incomplete
       *      texture (as defined in section 8.17) bound to it, then blending
       *      is disabled for that texture unit. If the texture environment
       *      for a given enabled texture unit references a disabled texture
       *      unit, or an invalid or incomplete texture that is bound to
       *      another unit, then the results of texture blending are
       *      undefined."
       */
811
      complete = false;
812
      mask = fftexUnit->Enabled;
813
814
815
816
817
818
819
820
821
822
823
824
825
      while (mask) {
         const int texIndex = u_bit_scan(&mask);
         struct gl_texture_object *texObj = texUnit->CurrentTex[texIndex];
         struct gl_sampler_object *sampler = texUnit->Sampler ?
            texUnit->Sampler : &texObj->Sampler;

         if (!_mesa_is_texture_complete(texObj, sampler)) {
            _mesa_test_texobj_completeness(ctx, texObj);
         }
         if (_mesa_is_texture_complete(texObj, sampler)) {
            _mesa_reference_texobj(&texUnit->_Current, texObj);
            complete = true;
            break;
826
827
828
         }
      }

829
      if (!complete)
830
831
832
833
834
835
836
837
838
         continue;

      /* if we get here, we know this texture unit is enabled */
      BITSET_SET(enabled_texture_units, unit);
      ctx->Texture._MaxEnabledTexImageUnit =
         MAX2(ctx->Texture._MaxEnabledTexImageUnit, (int)unit);

      ctx->Texture._EnabledCoordUnits |= 1 << unit;

839
      update_tex_combine(ctx, texUnit, fftexUnit);
840
841
842
   }
}

843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
static void
fix_missing_textures_for_atifs(struct gl_context *ctx,
                               struct gl_program *prog,
                               BITSET_WORD *enabled_texture_units)
{
   GLbitfield mask = prog->SamplersUsed;

   while (mask) {
      const int s = u_bit_scan(&mask);
      const int unit = prog->SamplerUnits[s];
      const gl_texture_index target_index = ffs(prog->TexturesUsed[unit]) - 1;

      if (!ctx->Texture.Unit[unit]._Current) {
         struct gl_texture_object *texObj =
            _mesa_get_fallback_texture(ctx, target_index);
         _mesa_reference_texobj(&ctx->Texture.Unit[unit]._Current, texObj);
         BITSET_SET(enabled_texture_units, unit);
         ctx->Texture._MaxEnabledTexImageUnit =
            MAX2(ctx->Texture._MaxEnabledTexImageUnit, (int)unit);
      }
   }
}

866
867
868
/**
 * \note This routine refers to derived texture matrix values to
 * compute the ENABLE_TEXMAT flags, but is only called on
869
870
871
 * _NEW_TEXTURE_OBJECT/STATE.  On changes to _NEW_TEXTURE_MATRIX,
 * the ENABLE_TEXMAT flags are updated by _mesa_update_texture_matrices,
 * above.
872
873
874
 *
 * \param ctx GL context.
 */
875
876
void
_mesa_update_texture_state(struct gl_context *ctx)
877
878
879
880
881
882
{
   struct gl_program *prog[MESA_SHADER_STAGES];
   int i;
   int old_max_unit = ctx->Texture._MaxEnabledTexImageUnit;
   BITSET_DECLARE(enabled_texture_units, MAX_COMBINED_TEXTURE_IMAGE_UNITS);

883
   memcpy(prog, ctx->_Shader->CurrentProgram, sizeof(prog));
884

885
886
887
   if (prog[MESA_SHADER_FRAGMENT] == NULL &&
       _mesa_arb_fragment_program_enabled(ctx)) {
      prog[MESA_SHADER_FRAGMENT] = ctx->FragmentProgram.Current;
Timothy Arceri's avatar
Timothy Arceri committed
888
889
   }

890
   /* TODO: only set this if there are actual changes */
891
   ctx->NewState |= _NEW_TEXTURE_OBJECT | _NEW_TEXTURE_STATE;
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919

   ctx->Texture._GenFlags = 0x0;
   ctx->Texture._TexMatEnabled = 0x0;
   ctx->Texture._TexGenEnabled = 0x0;
   ctx->Texture._MaxEnabledTexImageUnit = -1;
   ctx->Texture._EnabledCoordUnits = 0x0;

   memset(&enabled_texture_units, 0, sizeof(enabled_texture_units));

   /* First, walk over our programs pulling in all the textures for them.
    * Programs dictate specific texture targets to be enabled, and for a draw
    * call to be valid they can't conflict about which texture targets are
    * used.
    */
   update_program_texture_state(ctx, prog, enabled_texture_units);

   /* Also pull in any textures necessary for fixed function fragment shading.
    */
   if (!prog[MESA_SHADER_FRAGMENT])
      update_ff_texture_state(ctx, enabled_texture_units);

   /* Now, clear out the _Current of any disabled texture units. */
   for (i = 0; i <= ctx->Texture._MaxEnabledTexImageUnit; i++) {
      if (!BITSET_TEST(enabled_texture_units, i))
         _mesa_reference_texobj(&ctx->Texture.Unit[i]._Current, NULL);
   }
   for (i = ctx->Texture._MaxEnabledTexImageUnit + 1; i <= old_max_unit; i++) {
      _mesa_reference_texobj(&ctx->Texture.Unit[i]._Current, NULL);
920
921
   }

922
923
924
925
926
927
928
   /* add fallback texture for SampleMapATI if there is nothing */
   if (_mesa_ati_fragment_shader_enabled(ctx) &&
       ctx->ATIFragmentShader.Current->Program)
      fix_missing_textures_for_atifs(ctx,
                                     ctx->ATIFragmentShader.Current->Program,
                                     enabled_texture_units);

929
   if (!prog[MESA_SHADER_FRAGMENT] || !prog[MESA_SHADER_VERTEX])
930
      update_texgen(ctx);
931
932
933
934
935
936
937
938
939
}


/**********************************************************************/
/*****                      Initialization                        *****/
/**********************************************************************/

/**
 * Allocate the proxy textures for the given context.
940
 *
941
 * \param ctx the context to allocate proxies for.
942
 *
943
 * \return GL_TRUE on success, or GL_FALSE on failure
944
 *
945
946
947
948
 * If run out of memory part way through the allocations, clean up and return
 * GL_FALSE.
 */
static GLboolean
949
alloc_proxy_textures( struct gl_context *ctx )
950
{
951
952
953
   /* NOTE: these values must be in the same order as the TEXTURE_x_INDEX
    * values!
    */
954
   static const GLenum targets[] = {
955
956
      GL_TEXTURE_2D_MULTISAMPLE,
      GL_TEXTURE_2D_MULTISAMPLE_ARRAY,
957
      GL_TEXTURE_CUBE_MAP_ARRAY,
958
959
960
961
      GL_TEXTURE_BUFFER,
      GL_TEXTURE_2D_ARRAY_EXT,
      GL_TEXTURE_1D_ARRAY_EXT,
      GL_TEXTURE_EXTERNAL_OES,
962
      GL_TEXTURE_CUBE_MAP,
963
      GL_TEXTURE_3D,
964
      GL_TEXTURE_RECTANGLE_NV,
965
966
      GL_TEXTURE_2D,
      GL_TEXTURE_1D,
967
968
969
   };
   GLint tgt;

970
   STATIC_ASSERT(ARRAY_SIZE(targets) == NUM_TEXTURE_TARGETS);
971
972
   assert(targets[TEXTURE_2D_INDEX] == GL_TEXTURE_2D);
   assert(targets[TEXTURE_CUBE_INDEX] == GL_TEXTURE_CUBE_MAP);
973
974
975
976
977
978
979
980
981
982
983

   for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) {
      if (!(ctx->Texture.ProxyTex[tgt]
            = ctx->Driver.NewTextureObject(ctx, 0, targets[tgt]))) {
         /* out of memory, free what we did allocate */
         while (--tgt >= 0) {
            ctx->Driver.DeleteTexture(ctx, ctx->Texture.ProxyTex[tgt]);
         }
         return GL_FALSE;
      }
   }
984

985
   assert(ctx->Texture.ProxyTex[0]->RefCount == 1); /* sanity check */
986
987
988
989
   return GL_TRUE;
}


990
991
992
993
/**
 * Initialize texture state for the given context.
 */
GLboolean
994
_mesa_init_texture(struct gl_context *ctx)
995
{
996
   GLuint u;
997
998
999
1000

   /* Texture group */
   ctx->Texture.CurrentUnit = 0;      /* multitexture */

1001
1002
1003
1004
1005
   /* Appendix F.2 of the OpenGL ES 3.0 spec says:
    *
    *     "OpenGL ES 3.0 requires that all cube map filtering be
    *     seamless. OpenGL ES 2.0 specified that a single cube map face be
    *     selected and used for filtering."
1006
1007
1008
1009
1010
1011
1012
1013
1014
    *
    * Unfortunatley, a call to _mesa_is_gles3 below will only work if
    * the driver has already computed and set ctx->Version, however drivers
    * seem to call _mesa_initialize_context (which calls this) early
    * in the CreateContext hook and _mesa_compute_version much later (since
    * it needs information about available extensions). So, we will
    * enable seamless cubemaps by default since GLES2. This should work
    * for most implementations and drivers that don't support seamless
    * cubemaps for GLES2 can still disable it.
1015
    */
1016
   ctx->Texture.CubeMapSeamless = ctx->API == API_OPENGLES2;
1017

Marek Olšák's avatar
Marek Olšák committed
1018
1019
1020
1021
   for (u = 0; u < ARRAY_SIZE(ctx->Texture.Unit); u++) {
      struct gl_texture_unit *texUnit = &ctx->Texture.Unit[u];
      GLuint tex;

1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
      /* initialize current texture object ptrs to the shared default objects */
      for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) {
         _mesa_reference_texobj(&texUnit->CurrentTex[tex],
                                ctx->Shared->DefaultTex[tex]);
      }

      texUnit->_BoundTextures = 0;
   }

   for (u = 0; u < ARRAY_SIZE(ctx->Texture.FixedFuncUnit); u++) {
      struct gl_fixedfunc_texture_unit *texUnit =
         &ctx->Texture.FixedFuncUnit[u];

Marek Olšák's avatar
Marek Olšák committed
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
      texUnit->EnvMode = GL_MODULATE;
      ASSIGN_4V( texUnit->EnvColor, 0.0, 0.0, 0.0, 0.0 );

      texUnit->Combine = default_combine_state;
      texUnit->_EnvMode = default_combine_state;
      texUnit->_CurrentCombine = & texUnit->_EnvMode;

      texUnit->TexGenEnabled = 0x0;
      texUnit->GenS.Mode = GL_EYE_LINEAR;
      texUnit->GenT.Mode = GL_EYE_LINEAR;
      texUnit->GenR.Mode = GL_EYE_LINEAR;
      texUnit->GenQ.Mode = GL_EYE_LINEAR;
      texUnit->GenS._ModeBit = TEXGEN_EYE_LINEAR;
      texUnit->GenT._ModeBit = TEXGEN_EYE_LINEAR;
      texUnit->GenR._ModeBit = TEXGEN_EYE_LINEAR;
      texUnit->GenQ._ModeBit = TEXGEN_EYE_LINEAR;

      /* Yes, these plane coefficients are correct! */
      ASSIGN_4V( texUnit->GenS.ObjectPlane, 1.0, 0.0, 0.0, 0.0 );
      ASSIGN_4V( texUnit->GenT.ObjectPlane, 0.0, 1.0, 0.0, 0.0 );
      ASSIGN_4V( texUnit->GenR.ObjectPlane, 0.0, 0.0, 0.0, 0.0 );
      ASSIGN_4V( texUnit->GenQ.ObjectPlane, 0.0, 0.0, 0.0, 0.0 );
      ASSIGN_4V( texUnit->GenS.EyePlane, 1.0, 0.0, 0.0, 0.0 );
      ASSIGN_4V( texUnit->GenT.EyePlane, 0.0, 1.0, 0.0, 0.0 );
      ASSIGN_4V( texUnit->GenR.EyePlane, 0.0, 0.0, 0.0, 0.0 );
      ASSIGN_4V( texUnit->GenQ.EyePlane, 0.0, 0.0, 0.0, 0.0 );
   }
1062
1063

   /* After we're done initializing the context's texture state the default
1064
1065
    * texture objects' refcounts should be at least
    * MAX_COMBINED_TEXTURE_IMAGE_UNITS + 1.
1066
    */
1067
   assert(ctx->Shared->DefaultTex[TEXTURE_1D_INDEX]->RefCount
1068
          >= MAX_COMBINED_TEXTURE_IMAGE_UNITS + 1);
1069

1070
1071
1072
1073
   /* Allocate proxy textures */
   if (!alloc_proxy_textures( ctx ))
      return GL_FALSE;

1074
1075
1076
1077
   /* GL_ARB_texture_buffer_object */
   _mesa_reference_buffer_object(ctx, &ctx->Texture.BufferObject,
                                 ctx->Shared->NullBufferObj);

1078
1079
   ctx->Texture.NumCurrentTexUsed = 0;

1080
1081
1082
   return GL_TRUE;
}

1083
1084
1085
1086
1087

/**
 * Free dynamically-allocted texture data attached to the given context.
 */
void
1088
_mesa_free_texture_data(struct gl_context *ctx)
1089
{
1090
   GLuint u, tgt;
1091
1092

   /* unreference current textures */
1093
   for (u = 0; u < ARRAY_SIZE(ctx->Texture.Unit); u++) {
1094
1095
1096
      /* The _Current texture could account for another reference */
      _mesa_reference_texobj(&ctx->Texture.Unit[u]._Current, NULL);

1097
      for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) {
1098
         _mesa_reference_texobj(&ctx->Texture.Unit[u].CurrentTex[tgt], NULL);
1099
      }
1100
   }
1101
1102

   /* Free proxy texture objects */
1103
1104
   for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++)
      ctx->Driver.DeleteTexture(ctx, ctx->Texture.ProxyTex[tgt]);
1105
1106
1107

   /* GL_ARB_texture_buffer_object */
   _mesa_reference_buffer_object(ctx, &ctx->Texture.BufferObject, NULL);
1108

1109
   for (u = 0; u < ARRAY_SIZE(ctx->Texture.Unit); u++) {
1110
1111
      _mesa_reference_sampler_object(ctx, &ctx->Texture.Unit[u].Sampler, NULL);
   }
1112
}
1113
1114
1115
1116


/**
 * Update the default texture objects in the given context to reference those
1117
 * specified in the shared state and release those referencing the old
1118
1119
1120
 * shared state.
 */
void
1121
_mesa_update_default_objects_texture(struct gl_context *ctx)
1122
{
1123
   GLuint u, tex;
1124

1125
   for (u = 0; u < ARRAY_SIZE(ctx->Texture.Unit); u++) {
1126
      struct gl_texture_unit *texUnit = &ctx->Texture.Unit[u];
1127
1128
1129
1130
      for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) {
         _mesa_reference_texobj(&texUnit->CurrentTex[tex],
                                ctx->Shared->DefaultTex[tex]);
      }
1131
1132
   }
}