mesa: Validate the layer selection of an array texture too
[mesa.git] / src / mesa / main / texstate.c
index 1fd09e98538c3cdc8ccf727f7e03324c88d9ec4c..dad69a8f62775d053c1208447cc8d7e895380813 100644 (file)
@@ -1,6 +1,5 @@
 /*
  * Mesa 3-D graphics library
- * Version:  7.5
  *
  * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
  *
  * 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
- * BRIAN PAUL 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.
+ * 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.
  */
 
 /** 
@@ -29,7 +29,6 @@
  */
 
 #include "glheader.h"
-#include "mfeatures.h"
 #include "bufferobj.h"
 #include "colormac.h"
 #include "colortab.h"
@@ -286,7 +285,7 @@ calculate_derived_texenv( struct gl_tex_env_combine_state *state,
 
 /* GL_ARB_multitexture */
 void GLAPIENTRY
-_mesa_ActiveTextureARB(GLenum texture)
+_mesa_ActiveTexture(GLenum texture)
 {
    const GLuint texUnit = texture - GL_TEXTURE0;
    GLuint k;
@@ -297,8 +296,6 @@ _mesa_ActiveTextureARB(GLenum texture)
             ctx->Const.MaxTextureCoordUnits);
 
    ASSERT(k <= Elements(ctx->Texture.Unit));
-   
-   ASSERT_OUTSIDE_BEGIN_END(ctx);
 
    if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
       _mesa_debug(ctx, "glActiveTexture %s\n",
@@ -325,11 +322,10 @@ _mesa_ActiveTextureARB(GLenum texture)
 
 /* GL_ARB_multitexture */
 void GLAPIENTRY
-_mesa_ClientActiveTextureARB(GLenum texture)
+_mesa_ClientActiveTexture(GLenum texture)
 {
    GET_CURRENT_CONTEXT(ctx);
    GLuint texUnit = texture - GL_TEXTURE0;
-   ASSERT_OUTSIDE_BEGIN_END(ctx);
 
    if (MESA_VERBOSE & (VERBOSE_API | VERBOSE_TEXTURE))
       _mesa_debug(ctx, "glClientActiveTexture %s\n",
@@ -480,6 +476,43 @@ update_tex_combine(struct gl_context *ctx, struct gl_texture_unit *texUnit)
    }
 }
 
+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++) {
+      struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
+
+      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;
+      }
+
+      ASSERT(unit < Elements(ctx->TextureMatrixStack));
+      if (ctx->TextureMatrixStack[unit].Top->type != MATRIX_IDENTITY)
+        ctx->Texture._TexMatEnabled |= ENABLE_TEXMAT(unit);
+   }
+}
 
 /**
  * \note This routine refers to derived texture matrix values to
@@ -495,16 +528,17 @@ update_texture_state( struct gl_context *ctx )
    GLuint unit;
    struct gl_program *fprog = NULL;
    struct gl_program *vprog = NULL;
+   struct gl_program *gprog = NULL;
    GLbitfield enabledFragUnits = 0x0;
 
    if (ctx->Shader.CurrentVertexProgram &&
        ctx->Shader.CurrentVertexProgram->LinkStatus) {
       vprog = ctx->Shader.CurrentVertexProgram->_LinkedShaders[MESA_SHADER_VERTEX]->Program;
-   } else if (ctx->VertexProgram._Enabled) {
-      /* XXX enable this if/when non-shader vertex programs get
-       * texture fetches:
-       vprog = &ctx->VertexProgram.Current->Base;
-       */
+   }
+
+   if (ctx->Shader.CurrentGeometryProgram &&
+       ctx->Shader.CurrentGeometryProgram->LinkStatus) {
+      gprog = ctx->Shader.CurrentGeometryProgram->_LinkedShaders[MESA_SHADER_GEOMETRY]->Program;
    }
 
    if (ctx->Shader.CurrentFragmentProgram &&
@@ -515,10 +549,6 @@ update_texture_state( struct gl_context *ctx )
       fprog = &ctx->FragmentProgram.Current->Base;
    }
 
-   /* FINISHME: Geometry shader texture accesses should also be considered
-    * FINISHME: here.
-    */
-
    /* TODO: only set this if there are actual changes */
    ctx->NewState |= _NEW_TEXTURE;
 
@@ -534,6 +564,7 @@ update_texture_state( struct gl_context *ctx )
       struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
       GLbitfield enabledVertTargets = 0x0;
       GLbitfield enabledFragTargets = 0x0;
+      GLbitfield enabledGeomTargets = 0x0;
       GLbitfield enabledTargets = 0x0;
       GLuint texIndex;
 
@@ -547,6 +578,10 @@ update_texture_state( struct gl_context *ctx )
          enabledVertTargets |= vprog->TexturesUsed[unit];
       }
 
+      if (gprog) {
+         enabledGeomTargets |= gprog->TexturesUsed[unit];
+      }
+
       if (fprog) {
          enabledFragTargets |= fprog->TexturesUsed[unit];
       }
@@ -555,7 +590,8 @@ update_texture_state( struct gl_context *ctx )
          enabledFragTargets |= texUnit->Enabled;
       }
 
-      enabledTargets = enabledVertTargets | enabledFragTargets;
+      enabledTargets = enabledVertTargets | enabledFragTargets |
+                       enabledGeomTargets;
 
       texUnit->_ReallyEnabled = 0x0;
 
@@ -566,8 +602,8 @@ update_texture_state( struct gl_context *ctx )
 
       /* Look for the highest priority texture target that's enabled (or used
        * by the vert/frag shaders) and "complete".  That's the one we'll use
-       * for texturing.  If we're using vert/frag program we're guaranteed
-       * that bitcount(enabledBits) <= 1.
+       * for texturing.
+       *
        * Note that the TEXTURE_x_INDEX values are in high to low priority.
        */
       for (texIndex = 0; texIndex < NUM_TEXTURE_TARGETS; texIndex++) {
@@ -596,10 +632,15 @@ update_texture_state( struct gl_context *ctx )
             struct gl_texture_object *texObj;
             gl_texture_index texTarget;
 
-            assert(_mesa_bitcount(enabledTargets) == 1);
-
             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;
+            }
+
             _mesa_reference_texobj(&texUnit->_Current, texObj);
             texUnit->_ReallyEnabled = 1 << texTarget;
          }
@@ -616,7 +657,8 @@ update_texture_state( struct gl_context *ctx )
       if (enabledFragTargets)
          enabledFragUnits |= (1 << unit);
 
-      update_tex_combine(ctx, texUnit);
+      if (!fprog)
+         update_tex_combine(ctx, texUnit);
    }
 
 
@@ -624,43 +666,14 @@ update_texture_state( struct gl_context *ctx )
    if (fprog) {
       const GLuint coordMask = (1 << MAX_TEXTURE_COORD_UNITS) - 1;
       ctx->Texture._EnabledCoordUnits
-         = (fprog->InputsRead >> FRAG_ATTRIB_TEX0) & coordMask;
+         = (fprog->InputsRead >> VARYING_SLOT_TEX0) & coordMask;
    }
    else {
       ctx->Texture._EnabledCoordUnits = enabledFragUnits;
    }
 
-   /* 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];
-
-      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;
-      }
-
-      ASSERT(unit < Elements(ctx->TextureMatrixStack));
-      if (ctx->TextureMatrixStack[unit].Top->type != MATRIX_IDENTITY)
-        ctx->Texture._TexMatEnabled |= ENABLE_TEXMAT(unit);
-   }
+   if (!fprog || !vprog)
+      update_texgen(ctx);
 }
 
 
@@ -699,6 +712,9 @@ alloc_proxy_textures( struct gl_context *ctx )
     * values!
     */
    static const GLenum targets[] = {
+      GL_TEXTURE_2D_MULTISAMPLE,
+      GL_TEXTURE_2D_MULTISAMPLE_ARRAY,
+      GL_TEXTURE_CUBE_MAP_ARRAY,
       GL_TEXTURE_BUFFER,
       GL_TEXTURE_2D_ARRAY_EXT,
       GL_TEXTURE_1D_ARRAY_EXT,