Allow different max texture sizes for 1/2D, 3D and cube maps.
[mesa.git] / src / mesa / main / blend.c
index 91267cda7f057603df9d5ad97873a668f7ee9844..382c27d710b43397d8f40578facb30d2d7c95bf0 100644 (file)
@@ -1,21 +1,21 @@
-/* $Id: blend.c,v 1.24 2000/10/31 18:09:44 keithw Exp $ */
+/* $Id: blend.c,v 1.32 2001/03/29 16:50:31 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
  * Version:  3.5
- * 
- * Copyright (C) 1999-2000  Brian Paul   All Rights Reserved.
- * 
+ *
+ * Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
+ *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
  * to deal in the Software without restriction, including without limitation
  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  * and/or sell copies of the Software, and to permit persons to whom the
  * Software is furnished to do so, subject to the following conditions:
- * 
+ *
  * The above copyright notice and this permission notice shall be included
  * in all copies or substantial portions of the Software.
- * 
+ *
  * 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
@@ -25,7 +25,6 @@
  */
 
 
-
 #ifdef PC_HEADER
 #include "all.h"
 #else
 #include "context.h"
 #include "enums.h"
 #include "macros.h"
-#include "types.h"
+#include "mtypes.h"
 #endif
 
 
 void
 _mesa_BlendFunc( GLenum sfactor, GLenum dfactor )
 {
+
    GET_CURRENT_CONTEXT(ctx);
-   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glBlendFunc");
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
 
    if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
       fprintf(stderr, "glBlendFunc %s %s\n",
-             gl_lookup_enum_by_nr(sfactor),
-             gl_lookup_enum_by_nr(dfactor));
+             _mesa_lookup_enum_by_nr(sfactor),
+             _mesa_lookup_enum_by_nr(dfactor));
 
    switch (sfactor) {
       case GL_SRC_COLOR:
       case GL_ONE_MINUS_SRC_COLOR:
          if (!ctx->Extensions.NV_blend_square) {
-            gl_error( ctx, GL_INVALID_ENUM, "glBlendFunc(sfactor)" );
+            _mesa_error( ctx, GL_INVALID_ENUM, "glBlendFunc(sfactor)" );
             return;
          }
          /* fall-through */
@@ -70,10 +70,9 @@ _mesa_BlendFunc( GLenum sfactor, GLenum dfactor )
       case GL_ONE_MINUS_CONSTANT_COLOR:
       case GL_CONSTANT_ALPHA:
       case GL_ONE_MINUS_CONSTANT_ALPHA:
-         ctx->Color.BlendSrcRGB = ctx->Color.BlendSrcA = sfactor;
          break;
       default:
-         gl_error( ctx, GL_INVALID_ENUM, "glBlendFunc(sfactor)" );
+         _mesa_error( ctx, GL_INVALID_ENUM, "glBlendFunc(sfactor)" );
          return;
    }
 
@@ -81,7 +80,7 @@ _mesa_BlendFunc( GLenum sfactor, GLenum dfactor )
       case GL_DST_COLOR:
       case GL_ONE_MINUS_DST_COLOR:
          if (!ctx->Extensions.NV_blend_square) {
-            gl_error( ctx, GL_INVALID_ENUM, "glBlendFunc(dfactor)" );
+            _mesa_error( ctx, GL_INVALID_ENUM, "glBlendFunc(dfactor)" );
             return;
          }
          /* fall-through */
@@ -97,19 +96,24 @@ _mesa_BlendFunc( GLenum sfactor, GLenum dfactor )
       case GL_ONE_MINUS_CONSTANT_COLOR:
       case GL_CONSTANT_ALPHA:
       case GL_ONE_MINUS_CONSTANT_ALPHA:
-         ctx->Color.BlendDstRGB = ctx->Color.BlendDstA = dfactor;
          break;
       default:
-         gl_error( ctx, GL_INVALID_ENUM, "glBlendFunc(dfactor)" );
+         _mesa_error( ctx, GL_INVALID_ENUM, "glBlendFunc(dfactor)" );
          return;
    }
 
-   if (ctx->Driver.BlendFunc) {
-      (*ctx->Driver.BlendFunc)( ctx, sfactor, dfactor );
-   }
+   if (ctx->Color.BlendDstRGB == dfactor &&
+       ctx->Color.BlendSrcRGB == sfactor &&
+       ctx->Color.BlendDstA == dfactor &&
+       ctx->Color.BlendSrcA == sfactor)
+      return;
 
-   ctx->Color.BlendFunc = NULL;
-   ctx->NewState |= _NEW_COLOR;
+   FLUSH_VERTICES(ctx, _NEW_COLOR);
+   ctx->Color.BlendDstRGB = ctx->Color.BlendDstA = dfactor;
+   ctx->Color.BlendSrcRGB = ctx->Color.BlendSrcA = sfactor;
+
+   if (ctx->Driver.BlendFunc)
+      ctx->Driver.BlendFunc( ctx, sfactor, dfactor );
 }
 
 
@@ -119,20 +123,20 @@ _mesa_BlendFuncSeparateEXT( GLenum sfactorRGB, GLenum dfactorRGB,
                             GLenum sfactorA, GLenum dfactorA )
 {
    GET_CURRENT_CONTEXT(ctx);
-   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glBlendFuncSeparate");
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
 
    if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
-      fprintf(stderr, "glBlendFuncSeperate %s %s %s %s\n",
-             gl_lookup_enum_by_nr(sfactorRGB),
-             gl_lookup_enum_by_nr(dfactorRGB),
-             gl_lookup_enum_by_nr(sfactorA),
-             gl_lookup_enum_by_nr(dfactorA));
+      fprintf(stderr, "glBlendFuncSeparate %s %s %s %s\n",
+             _mesa_lookup_enum_by_nr(sfactorRGB),
+             _mesa_lookup_enum_by_nr(dfactorRGB),
+             _mesa_lookup_enum_by_nr(sfactorA),
+             _mesa_lookup_enum_by_nr(dfactorA));
 
    switch (sfactorRGB) {
       case GL_SRC_COLOR:
       case GL_ONE_MINUS_SRC_COLOR:
          if (!ctx->Extensions.NV_blend_square) {
-            gl_error(ctx, GL_INVALID_ENUM, "glBlendFuncSeparate(sfactorRGB)");
+            _mesa_error(ctx, GL_INVALID_ENUM, "glBlendFuncSeparate(sfactorRGB)");
             return;
          }
          /* fall-through */
@@ -149,10 +153,9 @@ _mesa_BlendFuncSeparateEXT( GLenum sfactorRGB, GLenum dfactorRGB,
       case GL_ONE_MINUS_CONSTANT_COLOR:
       case GL_CONSTANT_ALPHA:
       case GL_ONE_MINUS_CONSTANT_ALPHA:
-         ctx->Color.BlendSrcRGB = sfactorRGB;
          break;
       default:
-         gl_error(ctx, GL_INVALID_ENUM, "glBlendFuncSeparate(sfactorRGB)");
+         _mesa_error(ctx, GL_INVALID_ENUM, "glBlendFuncSeparate(sfactorRGB)");
          return;
    }
 
@@ -160,7 +163,7 @@ _mesa_BlendFuncSeparateEXT( GLenum sfactorRGB, GLenum dfactorRGB,
       case GL_DST_COLOR:
       case GL_ONE_MINUS_DST_COLOR:
          if (!ctx->Extensions.NV_blend_square) {
-            gl_error(ctx, GL_INVALID_ENUM, "glBlendFuncSeparate(dfactorRGB)");
+            _mesa_error(ctx, GL_INVALID_ENUM, "glBlendFuncSeparate(dfactorRGB)");
             return;
          }
          /* fall-through */
@@ -176,10 +179,9 @@ _mesa_BlendFuncSeparateEXT( GLenum sfactorRGB, GLenum dfactorRGB,
       case GL_ONE_MINUS_CONSTANT_COLOR:
       case GL_CONSTANT_ALPHA:
       case GL_ONE_MINUS_CONSTANT_ALPHA:
-         ctx->Color.BlendDstRGB = dfactorRGB;
          break;
       default:
-         gl_error(ctx, GL_INVALID_ENUM, "glBlendFuncSeparate(dfactorRGB)");
+         _mesa_error(ctx, GL_INVALID_ENUM, "glBlendFuncSeparate(dfactorRGB)");
          return;
    }
 
@@ -187,7 +189,7 @@ _mesa_BlendFuncSeparateEXT( GLenum sfactorRGB, GLenum dfactorRGB,
       case GL_SRC_COLOR:
       case GL_ONE_MINUS_SRC_COLOR:
          if (!ctx->Extensions.NV_blend_square) {
-            gl_error(ctx, GL_INVALID_ENUM, "glBlendFuncSeparate(sfactorA)");
+            _mesa_error(ctx, GL_INVALID_ENUM, "glBlendFuncSeparate(sfactorA)");
             return;
          }
          /* fall-through */
@@ -204,10 +206,9 @@ _mesa_BlendFuncSeparateEXT( GLenum sfactorRGB, GLenum dfactorRGB,
       case GL_ONE_MINUS_CONSTANT_COLOR:
       case GL_CONSTANT_ALPHA:
       case GL_ONE_MINUS_CONSTANT_ALPHA:
-         ctx->Color.BlendSrcA = sfactorA;
          break;
       default:
-         gl_error(ctx, GL_INVALID_ENUM, "glBlendFuncSeparate(sfactorA)");
+         _mesa_error(ctx, GL_INVALID_ENUM, "glBlendFuncSeparate(sfactorA)");
          return;
    }
 
@@ -215,7 +216,7 @@ _mesa_BlendFuncSeparateEXT( GLenum sfactorRGB, GLenum dfactorRGB,
       case GL_DST_COLOR:
       case GL_ONE_MINUS_DST_COLOR:
          if (!ctx->Extensions.NV_blend_square) {
-            gl_error(ctx, GL_INVALID_ENUM, "glBlendFuncSeparate(dfactorA)");
+            _mesa_error(ctx, GL_INVALID_ENUM, "glBlendFuncSeparate(dfactorA)");
             return;
          }
          /* fall-through */
@@ -231,15 +232,24 @@ _mesa_BlendFuncSeparateEXT( GLenum sfactorRGB, GLenum dfactorRGB,
       case GL_ONE_MINUS_CONSTANT_COLOR:
       case GL_CONSTANT_ALPHA:
       case GL_ONE_MINUS_CONSTANT_ALPHA:
-         ctx->Color.BlendDstA = dfactorA;
          break;
       default:
-         gl_error( ctx, GL_INVALID_ENUM, "glBlendFuncSeparate(dfactorA)" );
+         _mesa_error( ctx, GL_INVALID_ENUM, "glBlendFuncSeparate(dfactorA)" );
          return;
    }
 
-   ctx->Color.BlendFunc = NULL;
-   ctx->NewState |= _NEW_COLOR;
+   if (ctx->Color.BlendSrcRGB == sfactorRGB &&
+       ctx->Color.BlendDstRGB == dfactorRGB &&
+       ctx->Color.BlendSrcA == sfactorA &&
+       ctx->Color.BlendDstA == dfactorA)
+      return;
+
+   FLUSH_VERTICES(ctx, _NEW_COLOR);
+
+   ctx->Color.BlendSrcRGB = sfactorRGB;
+   ctx->Color.BlendDstRGB = dfactorRGB;
+   ctx->Color.BlendSrcA = sfactorA;
+   ctx->Color.BlendDstA = dfactorA;
 
    if (ctx->Driver.BlendFuncSeparate) {
       (*ctx->Driver.BlendFuncSeparate)( ctx, sfactorRGB, dfactorRGB,
@@ -254,56 +264,56 @@ void
 _mesa_BlendEquation( GLenum mode )
 {
    GET_CURRENT_CONTEXT(ctx);
-   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glBlendEquation");
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
 
    if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
       fprintf(stderr, "glBlendEquation %s\n",
-             gl_lookup_enum_by_nr(mode));
+             _mesa_lookup_enum_by_nr(mode));
 
    switch (mode) {
+      case GL_FUNC_ADD_EXT:
+         break;
       case GL_MIN_EXT:
       case GL_MAX_EXT:
-      case GL_FUNC_ADD_EXT:
-         if (ctx->Extensions.EXT_blend_minmax) {
-            ctx->Color.BlendEquation = mode;
-         }
-         else {
-            gl_error(ctx, GL_INVALID_ENUM, "glBlendEquation");
+         if (!ctx->Extensions.EXT_blend_minmax &&
+             !ctx->Extensions.ARB_imaging) {
+            _mesa_error(ctx, GL_INVALID_ENUM, "glBlendEquation");
             return;
          }
+         break;
       case GL_LOGIC_OP:
-         ctx->Color.BlendEquation = mode;
+         if (!ctx->Extensions.EXT_blend_logic_op) {
+            _mesa_error(ctx, GL_INVALID_ENUM, "glBlendEquation");
+            return;
+         }
          break;
       case GL_FUNC_SUBTRACT_EXT:
       case GL_FUNC_REVERSE_SUBTRACT_EXT:
-         if (ctx->Extensions.EXT_blend_subtract) {
-            ctx->Color.BlendEquation = mode;
-         }
-         else {
-            gl_error(ctx, GL_INVALID_ENUM, "glBlendEquation");
+         if (!ctx->Extensions.EXT_blend_subtract &&
+             !ctx->Extensions.ARB_imaging) {
+            _mesa_error(ctx, GL_INVALID_ENUM, "glBlendEquation");
             return;
          }
          break;
       default:
-         gl_error( ctx, GL_INVALID_ENUM, "glBlendEquation" );
+         _mesa_error( ctx, GL_INVALID_ENUM, "glBlendEquation" );
          return;
    }
 
+   if (ctx->Color.BlendEquation == mode)
+      return;
+
+   FLUSH_VERTICES(ctx, _NEW_COLOR);
+   ctx->Color.BlendEquation = mode;
+
    /* This is needed to support 1.1's RGB logic ops AND
     * 1.0's blending logicops.
     */
-   if (mode==GL_LOGIC_OP && ctx->Color.BlendEnabled) {
-      ctx->Color.ColorLogicOpEnabled = GL_TRUE;
-   }
-   else {
-      ctx->Color.ColorLogicOpEnabled = GL_FALSE;
-   }
+   ctx->Color.ColorLogicOpEnabled = (mode==GL_LOGIC_OP &&
+                                    ctx->Color.BlendEnabled);
 
-   ctx->Color.BlendFunc = NULL;
-   ctx->NewState |= _NEW_COLOR;
-   
    if (ctx->Driver.BlendEquation)
-      ctx->Driver.BlendEquation( ctx, mode );
+      (*ctx->Driver.BlendEquation)( ctx, mode );
 }
 
 
@@ -311,11 +321,21 @@ _mesa_BlendEquation( GLenum mode )
 void
 _mesa_BlendColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha )
 {
+   GLfloat tmp[4];
    GET_CURRENT_CONTEXT(ctx);
-   ctx->Color.BlendColor[0] = CLAMP( red,   0.0F, 1.0F );
-   ctx->Color.BlendColor[1] = CLAMP( green, 0.0F, 1.0F );
-   ctx->Color.BlendColor[2] = CLAMP( blue,  0.0F, 1.0F );
-   ctx->Color.BlendColor[3] = CLAMP( alpha, 0.0F, 1.0F );
-   ctx->NewState |= _NEW_COLOR;
-}
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   tmp[0] = CLAMP( red,   0.0, 1.0 );
+   tmp[1] = CLAMP( green, 0.0, 1.0 );
+   tmp[2] = CLAMP( blue,  0.0, 1.0 );
+   tmp[3] = CLAMP( alpha, 0.0, 1.0 );
+
+   if (TEST_EQ_4V(tmp, ctx->Color.BlendColor))
+      return;
 
+   FLUSH_VERTICES(ctx, _NEW_COLOR);
+   COPY_4FV( ctx->Color.BlendColor, tmp );
+
+   if (ctx->Driver.BlendColor)
+      (*ctx->Driver.BlendColor)(ctx, tmp);
+}