• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Mesa 3-D graphics library
3  *
4  * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included
14  * in all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22  * OTHER DEALINGS IN THE SOFTWARE.
23  */
24 
25 /**
26  * \file texstate.c
27  *
28  * Texture state handling.
29  */
30 
31 #include <stdio.h>
32 #include "glheader.h"
33 #include "bufferobj.h"
34 #include "context.h"
35 #include "enums.h"
36 #include "macros.h"
37 #include "texobj.h"
38 #include "teximage.h"
39 #include "texstate.h"
40 #include "mtypes.h"
41 #include "util/bitscan.h"
42 #include "util/bitset.h"
43 
44 
45 /**
46  * Default texture combine environment state.  This is used to initialize
47  * a context's texture units and as the basis for converting "classic"
48  * texture environmnets to ARB_texture_env_combine style values.
49  */
50 static const struct gl_tex_env_combine_state default_combine_state = {
51    GL_MODULATE, GL_MODULATE,
52    { GL_TEXTURE, GL_PREVIOUS, GL_CONSTANT, GL_CONSTANT },
53    { GL_TEXTURE, GL_PREVIOUS, GL_CONSTANT, GL_CONSTANT },
54    { GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_ALPHA, GL_SRC_ALPHA },
55    { GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA },
56    0, 0,
57    2, 2
58 };
59 
60 
61 
62 /**
63  * Used by glXCopyContext to copy texture state from one context to another.
64  */
65 void
_mesa_copy_texture_state(const struct gl_context * src,struct gl_context * dst)66 _mesa_copy_texture_state( const struct gl_context *src, struct gl_context *dst )
67 {
68    GLuint u, tex;
69 
70    assert(src);
71    assert(dst);
72 
73    dst->Texture.CurrentUnit = src->Texture.CurrentUnit;
74    dst->Texture._GenFlags = src->Texture._GenFlags;
75    dst->Texture._TexGenEnabled = src->Texture._TexGenEnabled;
76    dst->Texture._TexMatEnabled = src->Texture._TexMatEnabled;
77 
78    /* per-unit state */
79    for (u = 0; u < src->Const.MaxCombinedTextureImageUnits; u++) {
80       dst->Texture.Unit[u].Enabled = src->Texture.Unit[u].Enabled;
81       dst->Texture.Unit[u].EnvMode = src->Texture.Unit[u].EnvMode;
82       COPY_4V(dst->Texture.Unit[u].EnvColor, src->Texture.Unit[u].EnvColor);
83       dst->Texture.Unit[u].TexGenEnabled = src->Texture.Unit[u].TexGenEnabled;
84       dst->Texture.Unit[u].GenS = src->Texture.Unit[u].GenS;
85       dst->Texture.Unit[u].GenT = src->Texture.Unit[u].GenT;
86       dst->Texture.Unit[u].GenR = src->Texture.Unit[u].GenR;
87       dst->Texture.Unit[u].GenQ = src->Texture.Unit[u].GenQ;
88       dst->Texture.Unit[u].LodBias = src->Texture.Unit[u].LodBias;
89 
90       /* GL_EXT_texture_env_combine */
91       dst->Texture.Unit[u].Combine = src->Texture.Unit[u].Combine;
92 
93       /*
94        * XXX strictly speaking, we should compare texture names/ids and
95        * bind textures in the dest context according to id.  For now, only
96        * copy bindings if the contexts share the same pool of textures to
97        * avoid refcounting bugs.
98        */
99       if (dst->Shared == src->Shared) {
100          /* copy texture object bindings, not contents of texture objects */
101          _mesa_lock_context_textures(dst);
102 
103          for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) {
104             _mesa_reference_texobj(&dst->Texture.Unit[u].CurrentTex[tex],
105                                    src->Texture.Unit[u].CurrentTex[tex]);
106             if (src->Texture.Unit[u].CurrentTex[tex]) {
107                dst->Texture.NumCurrentTexUsed =
108                   MAX2(dst->Texture.NumCurrentTexUsed, u + 1);
109             }
110          }
111          dst->Texture.Unit[u]._BoundTextures = src->Texture.Unit[u]._BoundTextures;
112          _mesa_unlock_context_textures(dst);
113       }
114    }
115 }
116 
117 
118 /*
119  * For debugging
120  */
121 void
_mesa_print_texunit_state(struct gl_context * ctx,GLuint unit)122 _mesa_print_texunit_state( struct gl_context *ctx, GLuint unit )
123 {
124    const struct gl_texture_unit *texUnit = ctx->Texture.Unit + unit;
125    printf("Texture Unit %d\n", unit);
126    printf("  GL_TEXTURE_ENV_MODE = %s\n", _mesa_enum_to_string(texUnit->EnvMode));
127    printf("  GL_COMBINE_RGB = %s\n", _mesa_enum_to_string(texUnit->Combine.ModeRGB));
128    printf("  GL_COMBINE_ALPHA = %s\n", _mesa_enum_to_string(texUnit->Combine.ModeA));
129    printf("  GL_SOURCE0_RGB = %s\n", _mesa_enum_to_string(texUnit->Combine.SourceRGB[0]));
130    printf("  GL_SOURCE1_RGB = %s\n", _mesa_enum_to_string(texUnit->Combine.SourceRGB[1]));
131    printf("  GL_SOURCE2_RGB = %s\n", _mesa_enum_to_string(texUnit->Combine.SourceRGB[2]));
132    printf("  GL_SOURCE0_ALPHA = %s\n", _mesa_enum_to_string(texUnit->Combine.SourceA[0]));
133    printf("  GL_SOURCE1_ALPHA = %s\n", _mesa_enum_to_string(texUnit->Combine.SourceA[1]));
134    printf("  GL_SOURCE2_ALPHA = %s\n", _mesa_enum_to_string(texUnit->Combine.SourceA[2]));
135    printf("  GL_OPERAND0_RGB = %s\n", _mesa_enum_to_string(texUnit->Combine.OperandRGB[0]));
136    printf("  GL_OPERAND1_RGB = %s\n", _mesa_enum_to_string(texUnit->Combine.OperandRGB[1]));
137    printf("  GL_OPERAND2_RGB = %s\n", _mesa_enum_to_string(texUnit->Combine.OperandRGB[2]));
138    printf("  GL_OPERAND0_ALPHA = %s\n", _mesa_enum_to_string(texUnit->Combine.OperandA[0]));
139    printf("  GL_OPERAND1_ALPHA = %s\n", _mesa_enum_to_string(texUnit->Combine.OperandA[1]));
140    printf("  GL_OPERAND2_ALPHA = %s\n", _mesa_enum_to_string(texUnit->Combine.OperandA[2]));
141    printf("  GL_RGB_SCALE = %d\n", 1 << texUnit->Combine.ScaleShiftRGB);
142    printf("  GL_ALPHA_SCALE = %d\n", 1 << texUnit->Combine.ScaleShiftA);
143    printf("  GL_TEXTURE_ENV_COLOR = (%f, %f, %f, %f)\n", texUnit->EnvColor[0], texUnit->EnvColor[1], texUnit->EnvColor[2], texUnit->EnvColor[3]);
144 }
145 
146 
147 
148 /**********************************************************************/
149 /*                       Texture Environment                          */
150 /**********************************************************************/
151 
152 /**
153  * Convert "classic" texture environment to ARB_texture_env_combine style
154  * environments.
155  *
156  * \param state  texture_env_combine state vector to be filled-in.
157  * \param mode   Classic texture environment mode (i.e., \c GL_REPLACE,
158  *               \c GL_BLEND, \c GL_DECAL, etc.).
159  * \param texBaseFormat  Base format of the texture associated with the
160  *               texture unit.
161  */
162 static void
calculate_derived_texenv(struct gl_tex_env_combine_state * state,GLenum mode,GLenum texBaseFormat)163 calculate_derived_texenv( struct gl_tex_env_combine_state *state,
164 			  GLenum mode, GLenum texBaseFormat )
165 {
166    GLenum mode_rgb;
167    GLenum mode_a;
168 
169    *state = default_combine_state;
170 
171    switch (texBaseFormat) {
172    case GL_ALPHA:
173       state->SourceRGB[0] = GL_PREVIOUS;
174       break;
175 
176    case GL_LUMINANCE_ALPHA:
177    case GL_INTENSITY:
178    case GL_RGBA:
179       break;
180 
181    case GL_LUMINANCE:
182    case GL_RED:
183    case GL_RG:
184    case GL_RGB:
185    case GL_YCBCR_MESA:
186       state->SourceA[0] = GL_PREVIOUS;
187       break;
188 
189    default:
190       _mesa_problem(NULL,
191                     "Invalid texBaseFormat 0x%x in calculate_derived_texenv",
192                     texBaseFormat);
193       return;
194    }
195 
196    if (mode == GL_REPLACE_EXT)
197       mode = GL_REPLACE;
198 
199    switch (mode) {
200    case GL_REPLACE:
201    case GL_MODULATE:
202       mode_rgb = (texBaseFormat == GL_ALPHA) ? GL_REPLACE : mode;
203       mode_a   = mode;
204       break;
205 
206    case GL_DECAL:
207       mode_rgb = GL_INTERPOLATE;
208       mode_a   = GL_REPLACE;
209 
210       state->SourceA[0] = GL_PREVIOUS;
211 
212       /* Having alpha / luminance / intensity textures replace using the
213        * incoming fragment color matches the definition in NV_texture_shader.
214        * The 1.5 spec simply marks these as "undefined".
215        */
216       switch (texBaseFormat) {
217       case GL_ALPHA:
218       case GL_LUMINANCE:
219       case GL_LUMINANCE_ALPHA:
220       case GL_INTENSITY:
221 	 state->SourceRGB[0] = GL_PREVIOUS;
222 	 break;
223       case GL_RED:
224       case GL_RG:
225       case GL_RGB:
226       case GL_YCBCR_MESA:
227 	 mode_rgb = GL_REPLACE;
228 	 break;
229       case GL_RGBA:
230 	 state->SourceRGB[2] = GL_TEXTURE;
231 	 break;
232       }
233       break;
234 
235    case GL_BLEND:
236       mode_rgb = GL_INTERPOLATE;
237       mode_a   = GL_MODULATE;
238 
239       switch (texBaseFormat) {
240       case GL_ALPHA:
241 	 mode_rgb = GL_REPLACE;
242 	 break;
243       case GL_INTENSITY:
244 	 mode_a = GL_INTERPOLATE;
245 	 state->SourceA[0] = GL_CONSTANT;
246 	 state->OperandA[2] = GL_SRC_ALPHA;
247 	 /* FALLTHROUGH */
248       case GL_LUMINANCE:
249       case GL_RED:
250       case GL_RG:
251       case GL_RGB:
252       case GL_LUMINANCE_ALPHA:
253       case GL_RGBA:
254       case GL_YCBCR_MESA:
255 	 state->SourceRGB[2] = GL_TEXTURE;
256 	 state->SourceA[2]   = GL_TEXTURE;
257 	 state->SourceRGB[0] = GL_CONSTANT;
258 	 state->OperandRGB[2] = GL_SRC_COLOR;
259 	 break;
260       }
261       break;
262 
263    case GL_ADD:
264       mode_rgb = (texBaseFormat == GL_ALPHA) ? GL_REPLACE : GL_ADD;
265       mode_a   = (texBaseFormat == GL_INTENSITY) ? GL_ADD : GL_MODULATE;
266       break;
267 
268    default:
269       _mesa_problem(NULL,
270                     "Invalid texture env mode 0x%x in calculate_derived_texenv",
271                     mode);
272       return;
273    }
274 
275    state->ModeRGB = (state->SourceRGB[0] != GL_PREVIOUS)
276        ? mode_rgb : GL_REPLACE;
277    state->ModeA   = (state->SourceA[0]   != GL_PREVIOUS)
278        ? mode_a   : GL_REPLACE;
279 }
280 
281 
282 
283 
284 /* GL_ARB_multitexture */
285 void GLAPIENTRY
_mesa_ActiveTexture(GLenum texture)286 _mesa_ActiveTexture(GLenum texture)
287 {
288    const GLuint texUnit = texture - GL_TEXTURE0;
289    GLuint k;
290    GET_CURRENT_CONTEXT(ctx);
291 
292    if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
293       _mesa_debug(ctx, "glActiveTexture %s\n",
294                   _mesa_enum_to_string(texture));
295 
296    if (ctx->Texture.CurrentUnit == texUnit)
297       return;
298 
299    k = _mesa_max_tex_unit(ctx);
300 
301    assert(k <= ARRAY_SIZE(ctx->Texture.Unit));
302 
303    if (texUnit >= k) {
304       _mesa_error(ctx, GL_INVALID_ENUM, "glActiveTexture(texture=%s)",
305                   _mesa_enum_to_string(texture));
306       return;
307    }
308 
309    FLUSH_VERTICES(ctx, _NEW_TEXTURE);
310 
311    ctx->Texture.CurrentUnit = texUnit;
312    if (ctx->Transform.MatrixMode == GL_TEXTURE) {
313       /* update current stack pointer */
314       ctx->CurrentStack = &ctx->TextureMatrixStack[texUnit];
315    }
316 }
317 
318 
319 /* GL_ARB_multitexture */
320 void GLAPIENTRY
_mesa_ClientActiveTexture(GLenum texture)321 _mesa_ClientActiveTexture(GLenum texture)
322 {
323    GET_CURRENT_CONTEXT(ctx);
324    GLuint texUnit = texture - GL_TEXTURE0;
325 
326    if (MESA_VERBOSE & (VERBOSE_API | VERBOSE_TEXTURE))
327       _mesa_debug(ctx, "glClientActiveTexture %s\n",
328                   _mesa_enum_to_string(texture));
329 
330    if (ctx->Array.ActiveTexture == texUnit)
331       return;
332 
333    if (texUnit >= ctx->Const.MaxTextureCoordUnits) {
334       _mesa_error(ctx, GL_INVALID_ENUM, "glClientActiveTexture(texture=%s)",
335                   _mesa_enum_to_string(texture));
336       return;
337    }
338 
339    FLUSH_VERTICES(ctx, _NEW_ARRAY);
340    ctx->Array.ActiveTexture = texUnit;
341 }
342 
343 
344 
345 /**********************************************************************/
346 /*****                    State management                        *****/
347 /**********************************************************************/
348 
349 
350 /**
351  * \note This routine refers to derived texture attribute values to
352  * compute the ENABLE_TEXMAT flags, but is only called on
353  * _NEW_TEXTURE_MATRIX.  On changes to _NEW_TEXTURE, the ENABLE_TEXMAT
354  * flags are updated by _mesa_update_textures(), below.
355  *
356  * \param ctx GL context.
357  */
358 static void
update_texture_matrices(struct gl_context * ctx)359 update_texture_matrices( struct gl_context *ctx )
360 {
361    GLuint u;
362 
363    ctx->Texture._TexMatEnabled = 0x0;
364 
365    for (u = 0; u < ctx->Const.MaxTextureCoordUnits; u++) {
366       assert(u < ARRAY_SIZE(ctx->TextureMatrixStack));
367       if (_math_matrix_is_dirty(ctx->TextureMatrixStack[u].Top)) {
368 	 _math_matrix_analyse( ctx->TextureMatrixStack[u].Top );
369 
370 	 if (ctx->Texture.Unit[u]._Current &&
371 	     ctx->TextureMatrixStack[u].Top->type != MATRIX_IDENTITY)
372 	    ctx->Texture._TexMatEnabled |= ENABLE_TEXMAT(u);
373       }
374    }
375 }
376 
377 
378 /**
379  * Examine texture unit's combine/env state to update derived state.
380  */
381 static void
update_tex_combine(struct gl_context * ctx,struct gl_texture_unit * texUnit)382 update_tex_combine(struct gl_context *ctx, struct gl_texture_unit *texUnit)
383 {
384    struct gl_tex_env_combine_state *combine;
385 
386    /* No combiners will apply to this. */
387    if (texUnit->_Current->Target == GL_TEXTURE_BUFFER)
388       return;
389 
390    /* Set the texUnit->_CurrentCombine field to point to the user's combiner
391     * state, or the combiner state which is derived from traditional texenv
392     * mode.
393     */
394    if (texUnit->EnvMode == GL_COMBINE ||
395        texUnit->EnvMode == GL_COMBINE4_NV) {
396       texUnit->_CurrentCombine = & texUnit->Combine;
397    }
398    else {
399       const struct gl_texture_object *texObj = texUnit->_Current;
400       GLenum format = texObj->Image[0][texObj->BaseLevel]->_BaseFormat;
401 
402       if (format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL_EXT) {
403          format = texObj->DepthMode;
404       }
405       calculate_derived_texenv(&texUnit->_EnvMode, texUnit->EnvMode, format);
406       texUnit->_CurrentCombine = & texUnit->_EnvMode;
407    }
408 
409    combine = texUnit->_CurrentCombine;
410 
411    /* Determine number of source RGB terms in the combiner function */
412    switch (combine->ModeRGB) {
413    case GL_REPLACE:
414       combine->_NumArgsRGB = 1;
415       break;
416    case GL_ADD:
417    case GL_ADD_SIGNED:
418       if (texUnit->EnvMode == GL_COMBINE4_NV)
419          combine->_NumArgsRGB = 4;
420       else
421          combine->_NumArgsRGB = 2;
422       break;
423    case GL_MODULATE:
424    case GL_SUBTRACT:
425    case GL_DOT3_RGB:
426    case GL_DOT3_RGBA:
427    case GL_DOT3_RGB_EXT:
428    case GL_DOT3_RGBA_EXT:
429       combine->_NumArgsRGB = 2;
430       break;
431    case GL_INTERPOLATE:
432    case GL_MODULATE_ADD_ATI:
433    case GL_MODULATE_SIGNED_ADD_ATI:
434    case GL_MODULATE_SUBTRACT_ATI:
435       combine->_NumArgsRGB = 3;
436       break;
437    default:
438       combine->_NumArgsRGB = 0;
439       _mesa_problem(ctx, "invalid RGB combine mode in update_texture_state");
440       return;
441    }
442 
443    /* Determine number of source Alpha terms in the combiner function */
444    switch (combine->ModeA) {
445    case GL_REPLACE:
446       combine->_NumArgsA = 1;
447       break;
448    case GL_ADD:
449    case GL_ADD_SIGNED:
450       if (texUnit->EnvMode == GL_COMBINE4_NV)
451          combine->_NumArgsA = 4;
452       else
453          combine->_NumArgsA = 2;
454       break;
455    case GL_MODULATE:
456    case GL_SUBTRACT:
457       combine->_NumArgsA = 2;
458       break;
459    case GL_INTERPOLATE:
460    case GL_MODULATE_ADD_ATI:
461    case GL_MODULATE_SIGNED_ADD_ATI:
462    case GL_MODULATE_SUBTRACT_ATI:
463       combine->_NumArgsA = 3;
464       break;
465    default:
466       combine->_NumArgsA = 0;
467       _mesa_problem(ctx, "invalid Alpha combine mode in update_texture_state");
468       break;
469    }
470 }
471 
472 static void
update_texgen(struct gl_context * ctx)473 update_texgen(struct gl_context *ctx)
474 {
475    GLuint unit;
476 
477    /* Setup texgen for those texture coordinate sets that are in use */
478    for (unit = 0; unit < ctx->Const.MaxTextureCoordUnits; unit++) {
479       struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
480 
481       texUnit->_GenFlags = 0x0;
482 
483       if (!(ctx->Texture._EnabledCoordUnits & (1 << unit)))
484 	 continue;
485 
486       if (texUnit->TexGenEnabled) {
487 	 if (texUnit->TexGenEnabled & S_BIT) {
488 	    texUnit->_GenFlags |= texUnit->GenS._ModeBit;
489 	 }
490 	 if (texUnit->TexGenEnabled & T_BIT) {
491 	    texUnit->_GenFlags |= texUnit->GenT._ModeBit;
492 	 }
493 	 if (texUnit->TexGenEnabled & R_BIT) {
494 	    texUnit->_GenFlags |= texUnit->GenR._ModeBit;
495 	 }
496 	 if (texUnit->TexGenEnabled & Q_BIT) {
497 	    texUnit->_GenFlags |= texUnit->GenQ._ModeBit;
498 	 }
499 
500 	 ctx->Texture._TexGenEnabled |= ENABLE_TEXGEN(unit);
501 	 ctx->Texture._GenFlags |= texUnit->_GenFlags;
502       }
503 
504       assert(unit < ARRAY_SIZE(ctx->TextureMatrixStack));
505       if (ctx->TextureMatrixStack[unit].Top->type != MATRIX_IDENTITY)
506 	 ctx->Texture._TexMatEnabled |= ENABLE_TEXMAT(unit);
507    }
508 }
509 
510 static struct gl_texture_object *
update_single_program_texture(struct gl_context * ctx,struct gl_program * prog,int s)511 update_single_program_texture(struct gl_context *ctx, struct gl_program *prog,
512                               int s)
513 {
514    gl_texture_index target_index;
515    struct gl_texture_unit *texUnit;
516    struct gl_texture_object *texObj;
517    struct gl_sampler_object *sampler;
518    int unit;
519 
520    if (!(prog->SamplersUsed & (1 << s)))
521       return NULL;
522 
523    unit = prog->SamplerUnits[s];
524    texUnit = &ctx->Texture.Unit[unit];
525 
526    /* Note: If more than one bit was set in TexturesUsed[unit], then we should
527     * have had the draw call rejected already.  From the GL 4.4 specification,
528     * section 7.10 ("Samplers"):
529     *
530     *     "It is not allowed to have variables of different sampler types
531     *      pointing to the same texture image unit within a program
532     *      object. This situation can only be detected at the next rendering
533     *      command issued which triggers shader invocations, and an
534     *      INVALID_OPERATION error will then be generated."
535     */
536    target_index = ffs(prog->TexturesUsed[unit]) - 1;
537    texObj = texUnit->CurrentTex[target_index];
538 
539    sampler = texUnit->Sampler ?
540       texUnit->Sampler : &texObj->Sampler;
541 
542    if (likely(texObj)) {
543       if (_mesa_is_texture_complete(texObj, sampler))
544          return texObj;
545 
546       _mesa_test_texobj_completeness(ctx, texObj);
547       if (_mesa_is_texture_complete(texObj, sampler))
548          return texObj;
549    }
550 
551    /* If we've reached this point, we didn't find a complete texture of the
552     * shader's target.  From the GL 4.4 core specification, section 11.1.3.5
553     * ("Texture Access"):
554     *
555     *     "If a sampler is used in a shader and the sampler’s associated
556     *      texture is not complete, as defined in section 8.17, (0, 0, 0, 1)
557     *      will be returned for a non-shadow sampler and 0 for a shadow
558     *      sampler."
559     *
560     * Mesa implements this by creating a hidden texture object with a pixel of
561     * that value.
562     */
563    texObj = _mesa_get_fallback_texture(ctx, target_index);
564    assert(texObj);
565 
566    return texObj;
567 }
568 
569 static void
update_program_texture_state(struct gl_context * ctx,struct gl_program ** prog,BITSET_WORD * enabled_texture_units)570 update_program_texture_state(struct gl_context *ctx, struct gl_program **prog,
571                              BITSET_WORD *enabled_texture_units)
572 {
573    int i;
574 
575    for (i = 0; i < MESA_SHADER_STAGES; i++) {
576       int s;
577 
578       if (!prog[i])
579          continue;
580 
581       /* We can't only do the shifting trick as the loop condition because if
582        * sampler 31 is active, the next iteration tries to shift by 32, which is
583        * undefined.
584        */
585       for (s = 0; s < MAX_SAMPLERS && (1 << s) <= prog[i]->SamplersUsed; s++) {
586          struct gl_texture_object *texObj;
587 
588          texObj = update_single_program_texture(ctx, prog[i], s);
589          if (texObj) {
590             int unit = prog[i]->SamplerUnits[s];
591             _mesa_reference_texobj(&ctx->Texture.Unit[unit]._Current, texObj);
592             BITSET_SET(enabled_texture_units, unit);
593             ctx->Texture._MaxEnabledTexImageUnit =
594                MAX2(ctx->Texture._MaxEnabledTexImageUnit, (int)unit);
595          }
596       }
597    }
598 
599    if (prog[MESA_SHADER_FRAGMENT]) {
600       const GLuint coordMask = (1 << MAX_TEXTURE_COORD_UNITS) - 1;
601       ctx->Texture._EnabledCoordUnits |=
602          (prog[MESA_SHADER_FRAGMENT]->info.inputs_read >> VARYING_SLOT_TEX0) &
603          coordMask;
604    }
605 }
606 
607 static void
update_ff_texture_state(struct gl_context * ctx,BITSET_WORD * enabled_texture_units)608 update_ff_texture_state(struct gl_context *ctx,
609                         BITSET_WORD *enabled_texture_units)
610 {
611    int unit;
612 
613    for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
614       struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
615       GLbitfield mask;
616       bool complete;
617 
618       if (texUnit->Enabled == 0x0)
619          continue;
620 
621       /* If a shader already dictated what texture target was used for this
622        * unit, just go along with it.
623        */
624       if (BITSET_TEST(enabled_texture_units, unit))
625          continue;
626 
627       /* From the GL 4.4 compat specification, section 16.2 ("Texture Application"):
628        *
629        *     "Texturing is enabled or disabled using the generic Enable and
630        *      Disable commands, respectively, with the symbolic constants
631        *      TEXTURE_1D, TEXTURE_2D, TEXTURE_RECTANGLE, TEXTURE_3D, or
632        *      TEXTURE_CUBE_MAP to enable the one-, two-, rectangular,
633        *      three-dimensional, or cube map texture, respectively. If more
634        *      than one of these textures is enabled, the first one enabled
635        *      from the following list is used:
636        *
637        *      • cube map texture
638        *      • three-dimensional texture
639        *      • rectangular texture
640        *      • two-dimensional texture
641        *      • one-dimensional texture"
642        *
643        * Note that the TEXTURE_x_INDEX values are in high to low priority.
644        * Also:
645        *
646        *     "If a texture unit is disabled or has an invalid or incomplete
647        *      texture (as defined in section 8.17) bound to it, then blending
648        *      is disabled for that texture unit. If the texture environment
649        *      for a given enabled texture unit references a disabled texture
650        *      unit, or an invalid or incomplete texture that is bound to
651        *      another unit, then the results of texture blending are
652        *      undefined."
653        */
654       complete = false;
655       mask = texUnit->Enabled;
656       while (mask) {
657          const int texIndex = u_bit_scan(&mask);
658          struct gl_texture_object *texObj = texUnit->CurrentTex[texIndex];
659          struct gl_sampler_object *sampler = texUnit->Sampler ?
660             texUnit->Sampler : &texObj->Sampler;
661 
662          if (!_mesa_is_texture_complete(texObj, sampler)) {
663             _mesa_test_texobj_completeness(ctx, texObj);
664          }
665          if (_mesa_is_texture_complete(texObj, sampler)) {
666             _mesa_reference_texobj(&texUnit->_Current, texObj);
667             complete = true;
668             break;
669          }
670       }
671 
672       if (!complete)
673          continue;
674 
675       /* if we get here, we know this texture unit is enabled */
676       BITSET_SET(enabled_texture_units, unit);
677       ctx->Texture._MaxEnabledTexImageUnit =
678          MAX2(ctx->Texture._MaxEnabledTexImageUnit, (int)unit);
679 
680       ctx->Texture._EnabledCoordUnits |= 1 << unit;
681 
682       update_tex_combine(ctx, texUnit);
683    }
684 }
685 
686 /**
687  * \note This routine refers to derived texture matrix values to
688  * compute the ENABLE_TEXMAT flags, but is only called on
689  * _NEW_TEXTURE.  On changes to _NEW_TEXTURE_MATRIX, the ENABLE_TEXMAT
690  * flags are updated by _mesa_update_texture_matrices, above.
691  *
692  * \param ctx GL context.
693  */
694 static void
update_texture_state(struct gl_context * ctx)695 update_texture_state( struct gl_context *ctx )
696 {
697    struct gl_program *prog[MESA_SHADER_STAGES];
698    int i;
699    int old_max_unit = ctx->Texture._MaxEnabledTexImageUnit;
700    BITSET_DECLARE(enabled_texture_units, MAX_COMBINED_TEXTURE_IMAGE_UNITS);
701 
702    for (i = 0; i < MESA_SHADER_STAGES; i++) {
703       if (ctx->_Shader->CurrentProgram[i] &&
704           ctx->_Shader->CurrentProgram[i]->data->LinkStatus) {
705          prog[i] = ctx->_Shader->CurrentProgram[i]->_LinkedShaders[i]->Program;
706       } else {
707          if (i == MESA_SHADER_FRAGMENT && ctx->FragmentProgram._Enabled)
708             prog[i] = ctx->FragmentProgram.Current;
709          else
710             prog[i] = NULL;
711       }
712    }
713 
714    /* TODO: only set this if there are actual changes */
715    ctx->NewState |= _NEW_TEXTURE;
716 
717    ctx->Texture._GenFlags = 0x0;
718    ctx->Texture._TexMatEnabled = 0x0;
719    ctx->Texture._TexGenEnabled = 0x0;
720    ctx->Texture._MaxEnabledTexImageUnit = -1;
721    ctx->Texture._EnabledCoordUnits = 0x0;
722 
723    memset(&enabled_texture_units, 0, sizeof(enabled_texture_units));
724 
725    /* First, walk over our programs pulling in all the textures for them.
726     * Programs dictate specific texture targets to be enabled, and for a draw
727     * call to be valid they can't conflict about which texture targets are
728     * used.
729     */
730    update_program_texture_state(ctx, prog, enabled_texture_units);
731 
732    /* Also pull in any textures necessary for fixed function fragment shading.
733     */
734    if (!prog[MESA_SHADER_FRAGMENT])
735       update_ff_texture_state(ctx, enabled_texture_units);
736 
737    /* Now, clear out the _Current of any disabled texture units. */
738    for (i = 0; i <= ctx->Texture._MaxEnabledTexImageUnit; i++) {
739       if (!BITSET_TEST(enabled_texture_units, i))
740          _mesa_reference_texobj(&ctx->Texture.Unit[i]._Current, NULL);
741    }
742    for (i = ctx->Texture._MaxEnabledTexImageUnit + 1; i <= old_max_unit; i++) {
743       _mesa_reference_texobj(&ctx->Texture.Unit[i]._Current, NULL);
744    }
745 
746    if (!prog[MESA_SHADER_FRAGMENT] || !prog[MESA_SHADER_VERTEX])
747       update_texgen(ctx);
748 }
749 
750 
751 /**
752  * Update texture-related derived state.
753  */
754 void
_mesa_update_texture(struct gl_context * ctx,GLuint new_state)755 _mesa_update_texture( struct gl_context *ctx, GLuint new_state )
756 {
757    if (new_state & _NEW_TEXTURE_MATRIX)
758       update_texture_matrices( ctx );
759 
760    if (new_state & (_NEW_TEXTURE | _NEW_PROGRAM))
761       update_texture_state( ctx );
762 }
763 
764 
765 /**********************************************************************/
766 /*****                      Initialization                        *****/
767 /**********************************************************************/
768 
769 /**
770  * Allocate the proxy textures for the given context.
771  *
772  * \param ctx the context to allocate proxies for.
773  *
774  * \return GL_TRUE on success, or GL_FALSE on failure
775  *
776  * If run out of memory part way through the allocations, clean up and return
777  * GL_FALSE.
778  */
779 static GLboolean
alloc_proxy_textures(struct gl_context * ctx)780 alloc_proxy_textures( struct gl_context *ctx )
781 {
782    /* NOTE: these values must be in the same order as the TEXTURE_x_INDEX
783     * values!
784     */
785    static const GLenum targets[] = {
786       GL_TEXTURE_2D_MULTISAMPLE,
787       GL_TEXTURE_2D_MULTISAMPLE_ARRAY,
788       GL_TEXTURE_CUBE_MAP_ARRAY,
789       GL_TEXTURE_BUFFER,
790       GL_TEXTURE_2D_ARRAY_EXT,
791       GL_TEXTURE_1D_ARRAY_EXT,
792       GL_TEXTURE_EXTERNAL_OES,
793       GL_TEXTURE_CUBE_MAP,
794       GL_TEXTURE_3D,
795       GL_TEXTURE_RECTANGLE_NV,
796       GL_TEXTURE_2D,
797       GL_TEXTURE_1D,
798    };
799    GLint tgt;
800 
801    STATIC_ASSERT(ARRAY_SIZE(targets) == NUM_TEXTURE_TARGETS);
802    assert(targets[TEXTURE_2D_INDEX] == GL_TEXTURE_2D);
803    assert(targets[TEXTURE_CUBE_INDEX] == GL_TEXTURE_CUBE_MAP);
804 
805    for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) {
806       if (!(ctx->Texture.ProxyTex[tgt]
807             = ctx->Driver.NewTextureObject(ctx, 0, targets[tgt]))) {
808          /* out of memory, free what we did allocate */
809          while (--tgt >= 0) {
810             ctx->Driver.DeleteTexture(ctx, ctx->Texture.ProxyTex[tgt]);
811          }
812          return GL_FALSE;
813       }
814    }
815 
816    assert(ctx->Texture.ProxyTex[0]->RefCount == 1); /* sanity check */
817    return GL_TRUE;
818 }
819 
820 
821 /**
822  * Initialize a texture unit.
823  *
824  * \param ctx GL context.
825  * \param unit texture unit number to be initialized.
826  */
827 static void
init_texture_unit(struct gl_context * ctx,GLuint unit)828 init_texture_unit( struct gl_context *ctx, GLuint unit )
829 {
830    struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
831    GLuint tex;
832 
833    texUnit->EnvMode = GL_MODULATE;
834    ASSIGN_4V( texUnit->EnvColor, 0.0, 0.0, 0.0, 0.0 );
835 
836    texUnit->Combine = default_combine_state;
837    texUnit->_EnvMode = default_combine_state;
838    texUnit->_CurrentCombine = & texUnit->_EnvMode;
839 
840    texUnit->TexGenEnabled = 0x0;
841    texUnit->GenS.Mode = GL_EYE_LINEAR;
842    texUnit->GenT.Mode = GL_EYE_LINEAR;
843    texUnit->GenR.Mode = GL_EYE_LINEAR;
844    texUnit->GenQ.Mode = GL_EYE_LINEAR;
845    texUnit->GenS._ModeBit = TEXGEN_EYE_LINEAR;
846    texUnit->GenT._ModeBit = TEXGEN_EYE_LINEAR;
847    texUnit->GenR._ModeBit = TEXGEN_EYE_LINEAR;
848    texUnit->GenQ._ModeBit = TEXGEN_EYE_LINEAR;
849 
850    /* Yes, these plane coefficients are correct! */
851    ASSIGN_4V( texUnit->GenS.ObjectPlane, 1.0, 0.0, 0.0, 0.0 );
852    ASSIGN_4V( texUnit->GenT.ObjectPlane, 0.0, 1.0, 0.0, 0.0 );
853    ASSIGN_4V( texUnit->GenR.ObjectPlane, 0.0, 0.0, 0.0, 0.0 );
854    ASSIGN_4V( texUnit->GenQ.ObjectPlane, 0.0, 0.0, 0.0, 0.0 );
855    ASSIGN_4V( texUnit->GenS.EyePlane, 1.0, 0.0, 0.0, 0.0 );
856    ASSIGN_4V( texUnit->GenT.EyePlane, 0.0, 1.0, 0.0, 0.0 );
857    ASSIGN_4V( texUnit->GenR.EyePlane, 0.0, 0.0, 0.0, 0.0 );
858    ASSIGN_4V( texUnit->GenQ.EyePlane, 0.0, 0.0, 0.0, 0.0 );
859 
860    /* initialize current texture object ptrs to the shared default objects */
861    for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) {
862       _mesa_reference_texobj(&texUnit->CurrentTex[tex],
863                              ctx->Shared->DefaultTex[tex]);
864    }
865 
866    texUnit->_BoundTextures = 0;
867 }
868 
869 
870 /**
871  * Initialize texture state for the given context.
872  */
873 GLboolean
_mesa_init_texture(struct gl_context * ctx)874 _mesa_init_texture(struct gl_context *ctx)
875 {
876    GLuint u;
877 
878    /* Texture group */
879    ctx->Texture.CurrentUnit = 0;      /* multitexture */
880 
881    /* Appendix F.2 of the OpenGL ES 3.0 spec says:
882     *
883     *     "OpenGL ES 3.0 requires that all cube map filtering be
884     *     seamless. OpenGL ES 2.0 specified that a single cube map face be
885     *     selected and used for filtering."
886     *
887     * Unfortunatley, a call to _mesa_is_gles3 below will only work if
888     * the driver has already computed and set ctx->Version, however drivers
889     * seem to call _mesa_initialize_context (which calls this) early
890     * in the CreateContext hook and _mesa_compute_version much later (since
891     * it needs information about available extensions). So, we will
892     * enable seamless cubemaps by default since GLES2. This should work
893     * for most implementations and drivers that don't support seamless
894     * cubemaps for GLES2 can still disable it.
895     */
896    ctx->Texture.CubeMapSeamless = ctx->API == API_OPENGLES2;
897 
898    for (u = 0; u < ARRAY_SIZE(ctx->Texture.Unit); u++)
899       init_texture_unit(ctx, u);
900 
901    /* After we're done initializing the context's texture state the default
902     * texture objects' refcounts should be at least
903     * MAX_COMBINED_TEXTURE_IMAGE_UNITS + 1.
904     */
905    assert(ctx->Shared->DefaultTex[TEXTURE_1D_INDEX]->RefCount
906           >= MAX_COMBINED_TEXTURE_IMAGE_UNITS + 1);
907 
908    /* Allocate proxy textures */
909    if (!alloc_proxy_textures( ctx ))
910       return GL_FALSE;
911 
912    /* GL_ARB_texture_buffer_object */
913    _mesa_reference_buffer_object(ctx, &ctx->Texture.BufferObject,
914                                  ctx->Shared->NullBufferObj);
915 
916    ctx->Texture.NumCurrentTexUsed = 0;
917 
918    return GL_TRUE;
919 }
920 
921 
922 /**
923  * Free dynamically-allocted texture data attached to the given context.
924  */
925 void
_mesa_free_texture_data(struct gl_context * ctx)926 _mesa_free_texture_data(struct gl_context *ctx)
927 {
928    GLuint u, tgt;
929 
930    /* unreference current textures */
931    for (u = 0; u < ARRAY_SIZE(ctx->Texture.Unit); u++) {
932       /* The _Current texture could account for another reference */
933       _mesa_reference_texobj(&ctx->Texture.Unit[u]._Current, NULL);
934 
935       for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) {
936          _mesa_reference_texobj(&ctx->Texture.Unit[u].CurrentTex[tgt], NULL);
937       }
938    }
939 
940    /* Free proxy texture objects */
941    for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++)
942       ctx->Driver.DeleteTexture(ctx, ctx->Texture.ProxyTex[tgt]);
943 
944    /* GL_ARB_texture_buffer_object */
945    _mesa_reference_buffer_object(ctx, &ctx->Texture.BufferObject, NULL);
946 
947    for (u = 0; u < ARRAY_SIZE(ctx->Texture.Unit); u++) {
948       _mesa_reference_sampler_object(ctx, &ctx->Texture.Unit[u].Sampler, NULL);
949    }
950 }
951 
952 
953 /**
954  * Update the default texture objects in the given context to reference those
955  * specified in the shared state and release those referencing the old
956  * shared state.
957  */
958 void
_mesa_update_default_objects_texture(struct gl_context * ctx)959 _mesa_update_default_objects_texture(struct gl_context *ctx)
960 {
961    GLuint u, tex;
962 
963    for (u = 0; u < ARRAY_SIZE(ctx->Texture.Unit); u++) {
964       struct gl_texture_unit *texUnit = &ctx->Texture.Unit[u];
965       for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) {
966          _mesa_reference_texobj(&texUnit->CurrentTex[tex],
967                                 ctx->Shared->DefaultTex[tex]);
968       }
969    }
970 }
971