main: remove extern C around #includes in ff_fragment_shader.cpp
[mesa.git] / src / mesa / main / texstate.c
index 0082caf2b1ebc9b4d8a7127017708cc6e46fc757..e0f085218320d543f89204410ed1546c2dc62a0b 100644 (file)
@@ -91,10 +91,6 @@ _mesa_copy_texture_state( const struct gl_context *src, struct gl_context *dst )
       /* GL_EXT_texture_env_combine */
       dst->Texture.Unit[u].Combine = src->Texture.Unit[u].Combine;
 
-      /* GL_ATI_envmap_bumpmap - need this? */
-      dst->Texture.Unit[u].BumpTarget = src->Texture.Unit[u].BumpTarget;
-      COPY_4V(dst->Texture.Unit[u].RotMatrix, src->Texture.Unit[u].RotMatrix);
-
       /*
        * XXX strictly speaking, we should compare texture names/ids and
        * bind textures in the dest context according to id.  For now, only
@@ -108,7 +104,12 @@ _mesa_copy_texture_state( const struct gl_context *src, struct gl_context *dst )
          for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) {
             _mesa_reference_texobj(&dst->Texture.Unit[u].CurrentTex[tex],
                                    src->Texture.Unit[u].CurrentTex[tex]);
+            if (src->Texture.Unit[u].CurrentTex[tex]) {
+               dst->Texture.NumCurrentTexUsed =
+                  MAX2(dst->Texture.NumCurrentTexUsed, u + 1);
+            }
          }
+         dst->Texture.Unit[u]._BoundTextures = src->Texture.Unit[u]._BoundTextures;
          _mesa_unlock_context_textures(dst);
       }
    }
@@ -183,7 +184,6 @@ calculate_derived_texenv( struct gl_tex_env_combine_state *state,
    case GL_RG:
    case GL_RGB:
    case GL_YCBCR_MESA:
-   case GL_DUDV_ATI:
       state->SourceA[0] = GL_PREVIOUS;
       break;
       
@@ -225,7 +225,6 @@ calculate_derived_texenv( struct gl_tex_env_combine_state *state,
       case GL_RG:
       case GL_RGB:
       case GL_YCBCR_MESA:
-      case GL_DUDV_ATI:
         mode_rgb = GL_REPLACE;
         break;
       case GL_RGBA:
@@ -254,7 +253,6 @@ calculate_derived_texenv( struct gl_tex_env_combine_state *state,
       case GL_LUMINANCE_ALPHA:
       case GL_RGBA:
       case GL_YCBCR_MESA:
-      case GL_DUDV_ATI:
         state->SourceRGB[2] = GL_TEXTURE;
         state->SourceA[2]   = GL_TEXTURE;
         state->SourceRGB[0] = GL_CONSTANT;
@@ -438,10 +436,6 @@ update_tex_combine(struct gl_context *ctx, struct gl_texture_unit *texUnit)
    case GL_MODULATE_SUBTRACT_ATI:
       combine->_NumArgsRGB = 3;
       break;
-   case GL_BUMP_ENVMAP_ATI:
-      /* no real arguments for this case */
-      combine->_NumArgsRGB = 0;
-      break;
    default:
       combine->_NumArgsRGB = 0;
       _mesa_problem(ctx, "invalid RGB combine mode in update_texture_state");
@@ -515,68 +509,93 @@ update_texgen(struct gl_context *ctx)
    }
 }
 
+static struct gl_texture_object *
+update_single_program_texture(struct gl_context *ctx, struct gl_program *prog,
+                              int s)
+{
+   gl_texture_index target_index;
+   struct gl_texture_unit *texUnit;
+   struct gl_texture_object *texObj;
+   struct gl_sampler_object *sampler;
+   int unit;
+
+   if (!(prog->SamplersUsed & (1 << s)))
+      return NULL;
+
+   unit = prog->SamplerUnits[s];
+   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];
+
+   sampler = texUnit->Sampler ?
+      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;
+}
+
 static void
 update_program_texture_state(struct gl_context *ctx, struct gl_program **prog,
                              BITSET_WORD *enabled_texture_units)
 {
-   GLuint unit;
    int i;
 
-   for (unit = 0; unit < ctx->Const.MaxCombinedTextureImageUnits; unit++) {
-      struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
-      GLbitfield enabledTargets = 0x0;
-      GLuint texIndex;
-
-      for (i = 0; i < MESA_SHADER_STAGES; i++) {
-         if (prog[i])
-            enabledTargets |= prog[i]->TexturesUsed[unit];
-      }
+   for (i = 0; i < MESA_SHADER_STAGES; i++) {
+      int s;
 
-      if (enabledTargets == 0x0) {
-         /* neither vertex nor fragment processing uses this unit */
+      if (!prog[i])
          continue;
-      }
 
-      for (texIndex = 0; texIndex < NUM_TEXTURE_TARGETS; texIndex++) {
-         if (enabledTargets & (1 << texIndex)) {
-            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);
-               break;
-            }
-         }
-      }
-
-      if (texIndex == NUM_TEXTURE_TARGETS) {
-         /* If we get here it means the shader is expecting a texture
-          * object, but there isn't one (or it's incomplete).  Use the
-          * fallback texture.
-          */
+      /* We can't only do the shifting trick as the loop condition because if
+       * sampler 31 is active, the next iteration tries to shift by 32, which is
+       * undefined.
+       */
+      for (s = 0; s < MAX_SAMPLERS && (1 << s) <= prog[i]->SamplersUsed; s++) {
          struct gl_texture_object *texObj;
-         gl_texture_index texTarget;
-
-         texTarget = (gl_texture_index) (ffs(enabledTargets) - 1);
-         texObj = _mesa_get_fallback_texture(ctx, texTarget);
 
-         assert(texObj);
-         if (!texObj) {
-            /* invalid fallback texture: don't enable the texture unit */
-            continue;
+         texObj = update_single_program_texture(ctx, prog[i], s);
+         if (texObj) {
+            int unit = prog[i]->SamplerUnits[s];
+            _mesa_reference_texobj(&ctx->Texture.Unit[unit]._Current, texObj);
+            BITSET_SET(enabled_texture_units, unit);
+            ctx->Texture._MaxEnabledTexImageUnit =
+               MAX2(ctx->Texture._MaxEnabledTexImageUnit, (int)unit);
          }
-
-         _mesa_reference_texobj(&texUnit->_Current, texObj);
       }
-
-      /* 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);
    }
 
    if (prog[MESA_SHADER_FRAGMENT]) {
@@ -818,7 +837,6 @@ init_texture_unit( struct gl_context *ctx, GLuint unit )
    texUnit->Combine = default_combine_state;
    texUnit->_EnvMode = default_combine_state;
    texUnit->_CurrentCombine = & texUnit->_EnvMode;
-   texUnit->BumpTarget = GL_TEXTURE0;
 
    texUnit->TexGenEnabled = 0x0;
    texUnit->GenS.Mode = GL_EYE_LINEAR;
@@ -840,14 +858,13 @@ init_texture_unit( struct gl_context *ctx, GLuint unit )
    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 );
 
-   /* no mention of this in spec, but maybe id matrix expected? */
-   ASSIGN_4V( texUnit->RotMatrix, 1.0, 0.0, 0.0, 1.0 );
-
    /* 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;
 }
 
 
@@ -888,6 +905,8 @@ _mesa_init_texture(struct gl_context *ctx)
    _mesa_reference_buffer_object(ctx, &ctx->Texture.BufferObject,
                                  ctx->Shared->NullBufferObj);
 
+   ctx->Texture.NumCurrentTexUsed = 0;
+
    return GL_TRUE;
 }