svga: add missing fallthrough comments
[mesa.git] / src / mesa / main / texstate.c
index edd22537319b1673ffc824e8a44b244ea0b25c35..f21f83edba5cad6ce3921f6fc9a7a68b4a7dcfcb 100644 (file)
@@ -78,19 +78,8 @@ _mesa_copy_texture_state( const struct gl_context *src, struct gl_context *dst )
 
    /* per-unit state */
    for (u = 0; u < src->Const.MaxCombinedTextureImageUnits; u++) {
-      dst->Texture.Unit[u].Enabled = src->Texture.Unit[u].Enabled;
-      dst->Texture.Unit[u].EnvMode = src->Texture.Unit[u].EnvMode;
-      COPY_4V(dst->Texture.Unit[u].EnvColor, src->Texture.Unit[u].EnvColor);
-      dst->Texture.Unit[u].TexGenEnabled = src->Texture.Unit[u].TexGenEnabled;
-      dst->Texture.Unit[u].GenS = src->Texture.Unit[u].GenS;
-      dst->Texture.Unit[u].GenT = src->Texture.Unit[u].GenT;
-      dst->Texture.Unit[u].GenR = src->Texture.Unit[u].GenR;
-      dst->Texture.Unit[u].GenQ = src->Texture.Unit[u].GenQ;
       dst->Texture.Unit[u].LodBias = src->Texture.Unit[u].LodBias;
 
-      /* GL_EXT_texture_env_combine */
-      dst->Texture.Unit[u].Combine = src->Texture.Unit[u].Combine;
-
       /*
        * XXX strictly speaking, we should compare texture names/ids and
        * bind textures in the dest context according to id.  For now, only
@@ -113,6 +102,20 @@ _mesa_copy_texture_state( const struct gl_context *src, struct gl_context *dst )
          _mesa_unlock_context_textures(dst);
       }
    }
+
+   for (u = 0; u < src->Const.MaxTextureCoordUnits; u++) {
+      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;
+   }
 }
 
 
@@ -122,7 +125,7 @@ _mesa_copy_texture_state( const struct gl_context *src, struct gl_context *dst )
 void
 _mesa_print_texunit_state( struct gl_context *ctx, GLuint unit )
 {
-   const struct gl_texture_unit *texUnit = ctx->Texture.Unit + unit;
+   const struct gl_fixedfunc_texture_unit *texUnit = ctx->Texture.FixedFuncUnit + unit;
    printf("Texture Unit %d\n", unit);
    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));
@@ -307,6 +310,19 @@ active_texture(GLenum texture, bool no_error)
       }
    }
 
+
+   /* 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);
+
    ctx->Texture.CurrentUnit = texUnit;
    if (ctx->Transform.MatrixMode == GL_TEXTURE) {
       /* update current stack pointer */
@@ -461,7 +477,7 @@ tex_combine_translate_operand(GLenum operand)
 
 
 static void
-pack_tex_combine(struct gl_texture_unit *texUnit)
+pack_tex_combine(struct gl_fixedfunc_texture_unit *texUnit)
 {
    struct gl_tex_env_combine_state *state = texUnit->_CurrentCombine;
    struct gl_tex_env_combine_packed *packed = &texUnit->_CurrentCombinePacked;
@@ -493,7 +509,9 @@ pack_tex_combine(struct gl_texture_unit *texUnit)
  * Examine texture unit's combine/env state to update derived state.
  */
 static void
-update_tex_combine(struct gl_context *ctx, struct gl_texture_unit *texUnit)
+update_tex_combine(struct gl_context *ctx,
+                   struct gl_texture_unit *texUnit,
+                   struct gl_fixedfunc_texture_unit *fftexUnit)
 {
    struct gl_tex_env_combine_state *combine;
 
@@ -505,9 +523,9 @@ update_tex_combine(struct gl_context *ctx, struct gl_texture_unit *texUnit)
     * state, or the combiner state which is derived from traditional texenv
     * mode.
     */
-   if (texUnit->EnvMode == GL_COMBINE ||
-       texUnit->EnvMode == GL_COMBINE4_NV) {
-      texUnit->_CurrentCombine = & texUnit->Combine;
+   if (fftexUnit->EnvMode == GL_COMBINE ||
+       fftexUnit->EnvMode == GL_COMBINE4_NV) {
+      fftexUnit->_CurrentCombine = & fftexUnit->Combine;
    }
    else {
       const struct gl_texture_object *texObj = texUnit->_Current;
@@ -516,11 +534,11 @@ update_tex_combine(struct gl_context *ctx, struct gl_texture_unit *texUnit)
       if (format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL_EXT) {
          format = texObj->DepthMode;
       }
-      calculate_derived_texenv(&texUnit->_EnvMode, texUnit->EnvMode, format);
-      texUnit->_CurrentCombine = & texUnit->_EnvMode;
+      calculate_derived_texenv(&fftexUnit->_EnvMode, fftexUnit->EnvMode, format);
+      fftexUnit->_CurrentCombine = & fftexUnit->_EnvMode;
    }
 
-   combine = texUnit->_CurrentCombine;
+   combine = fftexUnit->_CurrentCombine;
 
    /* Determine number of source RGB terms in the combiner function */
    switch (combine->ModeRGB) {
@@ -529,7 +547,7 @@ update_tex_combine(struct gl_context *ctx, struct gl_texture_unit *texUnit)
       break;
    case GL_ADD:
    case GL_ADD_SIGNED:
-      if (texUnit->EnvMode == GL_COMBINE4_NV)
+      if (fftexUnit->EnvMode == GL_COMBINE4_NV)
          combine->_NumArgsRGB = 4;
       else
          combine->_NumArgsRGB = 2;
@@ -561,7 +579,7 @@ update_tex_combine(struct gl_context *ctx, struct gl_texture_unit *texUnit)
       break;
    case GL_ADD:
    case GL_ADD_SIGNED:
-      if (texUnit->EnvMode == GL_COMBINE4_NV)
+      if (fftexUnit->EnvMode == GL_COMBINE4_NV)
          combine->_NumArgsA = 4;
       else
          combine->_NumArgsA = 2;
@@ -582,7 +600,7 @@ update_tex_combine(struct gl_context *ctx, struct gl_texture_unit *texUnit)
       break;
    }
 
-   pack_tex_combine(texUnit);
+   pack_tex_combine(fftexUnit);
 }
 
 static void
@@ -592,7 +610,8 @@ update_texgen(struct gl_context *ctx)
 
    /* Setup texgen for those texture coordinate sets that are in use */
    for (unit = 0; unit < ctx->Const.MaxTextureCoordUnits; unit++) {
-      struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
+      struct gl_fixedfunc_texture_unit *texUnit =
+         &ctx->Texture.FixedFuncUnit[unit];
 
       texUnit->_GenFlags = 0x0;
 
@@ -651,11 +670,13 @@ update_single_program_texture(struct gl_context *ctx, struct gl_program *prog,
       texUnit->Sampler : &texObj->Sampler;
 
    if (likely(texObj)) {
-      if (_mesa_is_texture_complete(texObj, sampler))
+      if (_mesa_is_texture_complete(texObj, sampler,
+                                    ctx->Const.ForceIntegerTexNearest))
          return texObj;
 
       _mesa_test_texobj_completeness(ctx, texObj);
-      if (_mesa_is_texture_complete(texObj, sampler))
+      if (_mesa_is_texture_complete(texObj, sampler,
+                                    ctx->Const.ForceIntegerTexNearest))
          return texObj;
    }
 
@@ -686,8 +707,6 @@ update_single_program_texture_state(struct gl_context *ctx,
    struct gl_texture_object *texObj;
 
    texObj = update_single_program_texture(ctx, prog, unit);
-   if (!texObj)
-      return;
 
    _mesa_reference_texobj(&ctx->Texture.Unit[unit]._Current, texObj);
    BITSET_SET(enabled_texture_units, unit);
@@ -750,10 +769,12 @@ update_ff_texture_state(struct gl_context *ctx,
 
    for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
       struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
+      struct gl_fixedfunc_texture_unit *fftexUnit =
+         &ctx->Texture.FixedFuncUnit[unit];
       GLbitfield mask;
       bool complete;
 
-      if (texUnit->Enabled == 0x0)
+      if (fftexUnit->Enabled == 0x0)
          continue;
 
       /* If a shader already dictated what texture target was used for this
@@ -790,17 +811,19 @@ update_ff_texture_state(struct gl_context *ctx,
        *      undefined."
        */
       complete = false;
-      mask = texUnit->Enabled;
+      mask = fftexUnit->Enabled;
       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)) {
+         if (!_mesa_is_texture_complete(texObj, sampler,
+                                        ctx->Const.ForceIntegerTexNearest)) {
             _mesa_test_texobj_completeness(ctx, texObj);
          }
-         if (_mesa_is_texture_complete(texObj, sampler)) {
+         if (_mesa_is_texture_complete(texObj, sampler,
+                                       ctx->Const.ForceIntegerTexNearest)) {
             _mesa_reference_texobj(&texUnit->_Current, texObj);
             complete = true;
             break;
@@ -817,7 +840,30 @@ update_ff_texture_state(struct gl_context *ctx,
 
       ctx->Texture._EnabledCoordUnits |= 1 << unit;
 
-      update_tex_combine(ctx, texUnit);
+      update_tex_combine(ctx, texUnit, fftexUnit);
+   }
+}
+
+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);
+      }
    }
 }
 
@@ -840,11 +886,9 @@ _mesa_update_texture_state(struct gl_context *ctx)
 
    memcpy(prog, ctx->_Shader->CurrentProgram, sizeof(prog));
 
-   if (prog[MESA_SHADER_FRAGMENT] == NULL) {
-      if (_mesa_arb_fragment_program_enabled(ctx))
-         prog[MESA_SHADER_FRAGMENT] = ctx->FragmentProgram.Current;
-      else if (_mesa_ati_fragment_shader_enabled(ctx))
-         prog[MESA_SHADER_FRAGMENT] = ctx->ATIFragmentShader.Current->Program;
+   if (prog[MESA_SHADER_FRAGMENT] == NULL &&
+       _mesa_arb_fragment_program_enabled(ctx)) {
+      prog[MESA_SHADER_FRAGMENT] = ctx->FragmentProgram.Current;
    }
 
    /* TODO: only set this if there are actual changes */
@@ -879,6 +923,13 @@ _mesa_update_texture_state(struct gl_context *ctx)
       _mesa_reference_texobj(&ctx->Texture.Unit[i]._Current, NULL);
    }
 
+   /* 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);
+
    if (!prog[MESA_SHADER_FRAGMENT] || !prog[MESA_SHADER_VERTEX])
       update_texgen(ctx);
 }
@@ -940,55 +991,6 @@ alloc_proxy_textures( struct gl_context *ctx )
 }
 
 
-/**
- * Initialize a texture unit.
- *
- * \param ctx GL context.
- * \param unit texture unit number to be initialized.
- */
-static void
-init_texture_unit( struct gl_context *ctx, GLuint unit )
-{
-   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
-   GLuint tex;
-
-   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 );
-
-   /* 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;
-}
-
-
 /**
  * Initialize texture state for the given context.
  */
@@ -1017,8 +1019,50 @@ _mesa_init_texture(struct gl_context *ctx)
     */
    ctx->Texture.CubeMapSeamless = ctx->API == API_OPENGLES2;
 
-   for (u = 0; u < ARRAY_SIZE(ctx->Texture.Unit); u++)
-      init_texture_unit(ctx, u);
+   for (u = 0; u < ARRAY_SIZE(ctx->Texture.Unit); u++) {
+      struct gl_texture_unit *texUnit = &ctx->Texture.Unit[u];
+      GLuint tex;
+
+      /* 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];
+
+      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 );
+   }
 
    /* After we're done initializing the context's texture state the default
     * texture objects' refcounts should be at least
@@ -1032,8 +1076,7 @@ _mesa_init_texture(struct gl_context *ctx)
       return GL_FALSE;
 
    /* GL_ARB_texture_buffer_object */
-   _mesa_reference_buffer_object(ctx, &ctx->Texture.BufferObject,
-                                 ctx->Shared->NullBufferObj);
+   _mesa_reference_buffer_object(ctx, &ctx->Texture.BufferObject, NULL);
 
    ctx->Texture.NumCurrentTexUsed = 0;