mesa: set/get new state for GL_EXT_texture_swizzle
authorBrian Paul <brianp@vmware.com>
Wed, 28 Jan 2009 17:27:33 +0000 (10:27 -0700)
committerBrian Paul <brianp@vmware.com>
Wed, 28 Jan 2009 17:27:33 +0000 (10:27 -0700)
src/mesa/main/extensions.c
src/mesa/main/mtypes.h
src/mesa/main/texobj.c
src/mesa/main/texparam.c

index 0b4cbec648146e3d4c283b2fd654b6a7757e3efe..053f3697d70e4b8f58d97d24fbfe8a26f4a2adb7 100644 (file)
@@ -127,6 +127,7 @@ static const struct {
    { ON,  "GL_EXT_texture_object",             F(EXT_texture_object) },
    { OFF, "GL_EXT_texture_rectangle",          F(NV_texture_rectangle) },
    { OFF, "GL_EXT_texture_sRGB",               F(EXT_texture_sRGB) },
+   { OFF, "GL_EXT_texture_swizzle",            F(EXT_texture_swizzle) },
    { OFF, "GL_EXT_timer_query",                F(EXT_timer_query) },
    { ON,  "GL_EXT_vertex_array",               F(EXT_vertex_array) },
    { OFF, "GL_EXT_vertex_array_bgra",          F(EXT_vertex_array_bgra) },
index b09c5910f80d8a6eccd5730c49630333f488e2a9..8ab0d26f45df10b228716d53c1442316f2f1e978 100644 (file)
@@ -1446,6 +1446,8 @@ struct gl_texture_object
    GLint _MaxLevel;            /**< actual max mipmap level (q in the spec) */
    GLfloat _MaxLambda;         /**< = _MaxLevel - BaseLevel (q - b in spec) */
    GLint CropRect[4];           /**< GL_OES_draw_texture */
+   GLenum Swizzle[4];           /**< GL_EXT_texture_swizzle */
+   GLuint _Swizzle;             /**< same as Swizzle, but SWIZZLE_* format */
    GLboolean GenerateMipmap;    /**< GL_SGIS_generate_mipmap */
    GLboolean _Complete;                /**< Is texture object complete? */
 
@@ -2621,6 +2623,7 @@ struct gl_extensions
    GLboolean EXT_texture_lod_bias;
    GLboolean EXT_texture_mirror_clamp;
    GLboolean EXT_texture_sRGB;
+   GLboolean EXT_texture_swizzle;
    GLboolean EXT_timer_query;
    GLboolean EXT_vertex_array;
    GLboolean EXT_vertex_array_bgra;
index 7848f0be354c88b9fd907e8ff1e39ebf9a4bfc3a..fad39a063476b7494e377bc8750de8f94c683b90 100644 (file)
@@ -42,6 +42,8 @@
 #include "texstate.h"
 #include "texobj.h"
 #include "mtypes.h"
+#include "shader/prog_instruction.h"
+
 
 
 /**********************************************************************/
@@ -138,6 +140,11 @@ _mesa_initialize_texture_object( struct gl_texture_object *obj,
    obj->CompareFunc = GL_LEQUAL;       /* ARB_shadow */
    obj->DepthMode = GL_LUMINANCE;      /* ARB_depth_texture */
    obj->ShadowAmbient = 0.0F;          /* ARB/SGIX_shadow_ambient */
+   obj->Swizzle[0] = GL_RED;
+   obj->Swizzle[1] = GL_GREEN;
+   obj->Swizzle[2] = GL_BLUE;
+   obj->Swizzle[3] = GL_ALPHA;
+   obj->_Swizzle = SWIZZLE_NOOP;
 }
 
 
@@ -252,6 +259,8 @@ _mesa_copy_texture_object( struct gl_texture_object *dest,
    dest->GenerateMipmap = src->GenerateMipmap;
    dest->Palette = src->Palette;
    dest->_Complete = src->_Complete;
+   COPY_4V(dest->Swizzle, src->Swizzle);
+   dest->_Swizzle = src->_Swizzle;
 }
 
 
index 2322d849757745263c16768eeab1b8b17e552278..695bff00970535a5609d348c8b45516d13235912 100644 (file)
@@ -38,6 +38,7 @@
 #include "main/texcompress.h"
 #include "main/texparam.h"
 #include "main/teximage.h"
+#include "shader/prog_instruction.h"
 
 
 /**
@@ -125,6 +126,45 @@ get_texobj(GLcontext *ctx, GLenum target)
 }
 
 
+/**
+ * Convert GL_RED/GREEN/BLUE/ALPHA/ZERO/ONE to SWIZZLE_X/Y/Z/W/ZERO/ONE.
+ * \return -1 if error.
+ */
+static GLint
+comp_to_swizzle(GLenum comp)
+{
+   switch (comp) {
+   case GL_RED:
+      return SWIZZLE_X;
+   case GL_GREEN:
+      return SWIZZLE_Y;
+   case GL_BLUE:
+      return SWIZZLE_Z;
+   case GL_ALPHA:
+      return SWIZZLE_W;
+   case GL_ZERO:
+      return SWIZZLE_ZERO;
+   case GL_ONE:
+      return SWIZZLE_ONE;
+   default:
+      return -1;
+   }
+}
+
+
+static void
+set_swizzle_component(GLuint *swizzle, GLuint comp, GLuint swz)
+{
+   ASSERT(comp < 4);
+   ASSERT(swz <= SWIZZLE_NIL);
+   {
+      GLuint mask = 0x7 << (3 * comp);
+      GLuint s = (*swizzle & ~mask) | (swz << (3 * comp));
+      *swizzle = s;
+   }
+}
+
+
 /** Set an integer-valued texture parameter */
 static void
 set_tex_parameteri(GLcontext *ctx,
@@ -318,9 +358,48 @@ set_tex_parameteri(GLcontext *ctx,
       texObj->CropRect[1] = params[1];
       texObj->CropRect[2] = params[2];
       texObj->CropRect[3] = params[3];
-      break;
+      return;
 #endif
 
+   case GL_TEXTURE_SWIZZLE_R_EXT:
+   case GL_TEXTURE_SWIZZLE_G_EXT:
+   case GL_TEXTURE_SWIZZLE_B_EXT:
+   case GL_TEXTURE_SWIZZLE_A_EXT:
+      if (ctx->Extensions.EXT_texture_swizzle) {
+         const GLuint comp = pname - GL_TEXTURE_SWIZZLE_R_EXT;
+         const GLint swz = comp_to_swizzle(params[0]);
+         ASSERT(comp < 4);
+         if (swz >= 0) {
+            FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+            texObj->Swizzle[comp] = params[0];
+            set_swizzle_component(&texObj->_Swizzle, comp, swz);
+            return;
+         }
+      }
+      _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=0x%x)", pname);
+      return;
+
+   case GL_TEXTURE_SWIZZLE_RGBA_EXT:
+      if (ctx->Extensions.EXT_texture_swizzle) {
+         GLuint comp;
+         FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+         for (comp = 0; comp < 4; comp++) {
+            const GLint swz = comp_to_swizzle(params[comp]);
+            if (swz >= 0) {
+               texObj->Swizzle[comp] = params[comp];
+               set_swizzle_component(&texObj->_Swizzle, comp, swz);
+            }
+            else {
+               _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(param=0x%x)",
+                           params[comp]);
+               return;
+            }
+         }
+         return;
+      }
+      _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=0x%x)", pname);
+      return;
+
    default:
       _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=0x%x)", pname);
    }
@@ -974,63 +1053,63 @@ _mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params )
             *params = obj->MaxAnisotropy;
          }
         else
-           error = 1;
+           error = GL_TRUE;
          break;
       case GL_TEXTURE_COMPARE_SGIX:
          if (ctx->Extensions.SGIX_shadow) {
             *params = (GLfloat) obj->CompareFlag;
          }
         else 
-           error = 1;
+           error = GL_TRUE;
          break;
       case GL_TEXTURE_COMPARE_OPERATOR_SGIX:
          if (ctx->Extensions.SGIX_shadow) {
             *params = (GLfloat) obj->CompareOperator;
          }
         else 
-           error = 1;
+           error = GL_TRUE;
          break;
       case GL_SHADOW_AMBIENT_SGIX: /* aka GL_TEXTURE_COMPARE_FAIL_VALUE_ARB */
          if (ctx->Extensions.SGIX_shadow_ambient) {
             *params = obj->ShadowAmbient;
          }
         else 
-           error = 1;
+           error = GL_TRUE;
          break;
       case GL_GENERATE_MIPMAP_SGIS:
          if (ctx->Extensions.SGIS_generate_mipmap) {
             *params = (GLfloat) obj->GenerateMipmap;
          }
         else 
-           error = 1;
+           error = GL_TRUE;
          break;
       case GL_TEXTURE_COMPARE_MODE_ARB:
          if (ctx->Extensions.ARB_shadow) {
             *params = (GLfloat) obj->CompareMode;
          }
         else 
-           error = 1;
+           error = GL_TRUE;
          break;
       case GL_TEXTURE_COMPARE_FUNC_ARB:
          if (ctx->Extensions.ARB_shadow) {
             *params = (GLfloat) obj->CompareFunc;
          }
         else 
-           error = 1;
+           error = GL_TRUE;
          break;
       case GL_DEPTH_TEXTURE_MODE_ARB:
          if (ctx->Extensions.ARB_depth_texture) {
             *params = (GLfloat) obj->DepthMode;
          }
         else 
-           error = 1;
+           error = GL_TRUE;
          break;
       case GL_TEXTURE_LOD_BIAS:
          if (ctx->Extensions.EXT_texture_lod_bias) {
             *params = obj->LodBias;
          }
         else 
-           error = 1;
+           error = GL_TRUE;
          break;
 #ifdef FEATURE_OES_draw_texture
       case GL_TEXTURE_CROP_RECT_OES:
@@ -1040,10 +1119,37 @@ _mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params )
          params[3] = obj->CropRect[3];
          break;
 #endif
+
+      case GL_TEXTURE_SWIZZLE_R_EXT:
+      case GL_TEXTURE_SWIZZLE_G_EXT:
+      case GL_TEXTURE_SWIZZLE_B_EXT:
+      case GL_TEXTURE_SWIZZLE_A_EXT:
+         if (ctx->Extensions.EXT_texture_swizzle) {
+            GLuint comp = pname - GL_TEXTURE_SWIZZLE_R_EXT;
+            *params = (GLfloat) obj->Swizzle[comp];
+         }
+         else {
+            error = GL_TRUE;
+         }
+         break;
+
+      case GL_TEXTURE_SWIZZLE_RGBA_EXT:
+         if (ctx->Extensions.EXT_texture_swizzle) {
+            GLuint comp;
+            for (comp = 0; comp < 4; comp++) {
+               params[comp] = (GLfloat) obj->Swizzle[comp];
+            }
+         }
+         else {
+            error = GL_TRUE;
+         }
+         break;
+
       default:
-        error = 1;
+        error = GL_TRUE;
         break;
    }
+
    if (error)
       _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameterfv(pname=0x%x)",
                  pname);
@@ -1057,6 +1163,7 @@ _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params )
 {
    struct gl_texture_unit *texUnit;
    struct gl_texture_object *obj;
+   GLboolean error = GL_FALSE;
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END(ctx);
 
@@ -1077,19 +1184,19 @@ _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params )
    switch (pname) {
       case GL_TEXTURE_MAG_FILTER:
          *params = (GLint) obj->MagFilter;
-         return;
+         break;;
       case GL_TEXTURE_MIN_FILTER:
          *params = (GLint) obj->MinFilter;
-         return;
+         break;;
       case GL_TEXTURE_WRAP_S:
          *params = (GLint) obj->WrapS;
-         return;
+         break;;
       case GL_TEXTURE_WRAP_T:
          *params = (GLint) obj->WrapT;
-         return;
+         break;;
       case GL_TEXTURE_WRAP_R:
          *params = (GLint) obj->WrapR;
-         return;
+         break;;
       case GL_TEXTURE_BORDER_COLOR:
          {
             GLfloat b[4];
@@ -1102,7 +1209,7 @@ _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params )
             params[2] = FLOAT_TO_INT(b[2]);
             params[3] = FLOAT_TO_INT(b[3]);
          }
-         return;
+         break;;
       case GL_TEXTURE_RESIDENT:
          {
             GLboolean resident;
@@ -1112,74 +1219,92 @@ _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params )
                resident = GL_TRUE;
             *params = (GLint) resident;
          }
-         return;
+         break;;
       case GL_TEXTURE_PRIORITY:
          *params = FLOAT_TO_INT(obj->Priority);
-         return;
+         break;;
       case GL_TEXTURE_MIN_LOD:
          *params = (GLint) obj->MinLod;
-         return;
+         break;;
       case GL_TEXTURE_MAX_LOD:
          *params = (GLint) obj->MaxLod;
-         return;
+         break;;
       case GL_TEXTURE_BASE_LEVEL:
          *params = obj->BaseLevel;
-         return;
+         break;;
       case GL_TEXTURE_MAX_LEVEL:
          *params = obj->MaxLevel;
-         return;
+         break;;
       case GL_TEXTURE_MAX_ANISOTROPY_EXT:
          if (ctx->Extensions.EXT_texture_filter_anisotropic) {
             *params = (GLint) obj->MaxAnisotropy;
-            return;
+         }
+         else {
+            error = GL_TRUE;
          }
          break;
       case GL_TEXTURE_COMPARE_SGIX:
          if (ctx->Extensions.SGIX_shadow) {
             *params = (GLint) obj->CompareFlag;
-            return;
+         }
+         else {
+            error = GL_TRUE;
          }
          break;
       case GL_TEXTURE_COMPARE_OPERATOR_SGIX:
          if (ctx->Extensions.SGIX_shadow) {
             *params = (GLint) obj->CompareOperator;
-            return;
+         }
+         else {
+            error = GL_TRUE;
          }
          break;
       case GL_SHADOW_AMBIENT_SGIX: /* aka GL_TEXTURE_COMPARE_FAIL_VALUE_ARB */
          if (ctx->Extensions.SGIX_shadow_ambient) {
             *params = (GLint) FLOAT_TO_INT(obj->ShadowAmbient);
-            return;
+         }
+         else {
+            error = GL_TRUE;
          }
          break;
       case GL_GENERATE_MIPMAP_SGIS:
          if (ctx->Extensions.SGIS_generate_mipmap) {
             *params = (GLint) obj->GenerateMipmap;
-            return;
+         }
+         else {
+            error = GL_TRUE;
          }
          break;
       case GL_TEXTURE_COMPARE_MODE_ARB:
          if (ctx->Extensions.ARB_shadow) {
             *params = (GLint) obj->CompareMode;
-            return;
+         }
+         else {
+            error = GL_TRUE;
          }
          break;
       case GL_TEXTURE_COMPARE_FUNC_ARB:
          if (ctx->Extensions.ARB_shadow) {
             *params = (GLint) obj->CompareFunc;
-            return;
+         }
+         else {
+            error = GL_TRUE;
          }
          break;
       case GL_DEPTH_TEXTURE_MODE_ARB:
          if (ctx->Extensions.ARB_depth_texture) {
             *params = (GLint) obj->DepthMode;
-            return;
+         }
+         else {
+            error = GL_TRUE;
          }
          break;
       case GL_TEXTURE_LOD_BIAS:
          if (ctx->Extensions.EXT_texture_lod_bias) {
             *params = (GLint) obj->LodBias;
-            return;
+         }
+         else {
+            error = GL_TRUE;
          }
          break;
 #ifdef FEATURE_OES_draw_texture
@@ -1190,9 +1315,35 @@ _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params )
          params[3] = obj->CropRect[3];
          break;
 #endif
+      case GL_TEXTURE_SWIZZLE_R_EXT:
+      case GL_TEXTURE_SWIZZLE_G_EXT:
+      case GL_TEXTURE_SWIZZLE_B_EXT:
+      case GL_TEXTURE_SWIZZLE_A_EXT:
+         if (ctx->Extensions.EXT_texture_swizzle) {
+            GLuint comp = pname - GL_TEXTURE_SWIZZLE_R_EXT;
+            *params = obj->Swizzle[comp];
+         }
+         else {
+            error = GL_TRUE;
+         }
+         break;
+
+      case GL_TEXTURE_SWIZZLE_RGBA_EXT:
+         if (ctx->Extensions.EXT_texture_swizzle) {
+            COPY_4V(params, obj->Swizzle);
+         }
+         else {
+            error = GL_TRUE;
+         }
+         break;
+
       default:
          ; /* silence warnings */
    }
-   /* If we get here, pname was an unrecognized enum */
-   _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameteriv(pname=0x%x)", pname);
+
+   if (error)
+      _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameteriv(pname=0x%x)",
+                 pname);
+
+   _mesa_unlock_texture(ctx, obj);
 }