X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Fblend.c;h=81bd4c2f32038a0eb0d30bb24618d5aa9c25d8b2;hb=6340d6bf22ad0bfedf8565500336237a8da887f5;hp=dad5184dd9207e1543afd69727b1c700e51def0c;hpb=6dc85575000127630489b407c50a4b3ea87c9acb;p=mesa.git diff --git a/src/mesa/main/blend.c b/src/mesa/main/blend.c index dad5184dd92..81bd4c2f320 100644 --- a/src/mesa/main/blend.c +++ b/src/mesa/main/blend.c @@ -5,9 +5,9 @@ /* * Mesa 3-D graphics library - * Version: 4.1 + * Version: 6.5.1 * - * Copyright (C) 1999-2002 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2006 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"), @@ -44,94 +44,23 @@ * \param sfactor source factor operator. * \param dfactor destination factor operator. * - * \sa glBlendFunc(). - * - * Verifies the parameters and updates gl_colorbuffer_attrib. On a change, - * flushes the vertices and notifies the driver via - * dd_function_table::BlendFunc callback. + * \sa glBlendFunc, glBlendFuncSeparateEXT + * + * Swizzles the inputs and calls \c glBlendFuncSeparateEXT. This is done + * using the \c CurrentDispatch table in the context, so this same function + * can be used while compiling display lists. Therefore, there is no need + * for the display list code to save and restore this function. */ -void +void GLAPIENTRY _mesa_BlendFunc( GLenum sfactor, GLenum dfactor ) { - GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); - - if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) - _mesa_debug(ctx, "glBlendFunc %s %s\n", - _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) { - _mesa_error( ctx, GL_INVALID_ENUM, "glBlendFunc(sfactor)" ); - return; - } - /* fall-through */ - case GL_ZERO: - case GL_ONE: - case GL_DST_COLOR: - case GL_ONE_MINUS_DST_COLOR: - case GL_SRC_ALPHA: - case GL_ONE_MINUS_SRC_ALPHA: - case GL_DST_ALPHA: - case GL_ONE_MINUS_DST_ALPHA: - case GL_SRC_ALPHA_SATURATE: - case GL_CONSTANT_COLOR: - case GL_ONE_MINUS_CONSTANT_COLOR: - case GL_CONSTANT_ALPHA: - case GL_ONE_MINUS_CONSTANT_ALPHA: - break; - default: - _mesa_error( ctx, GL_INVALID_ENUM, "glBlendFunc(sfactor)" ); - return; - } - - switch (dfactor) { - case GL_DST_COLOR: - case GL_ONE_MINUS_DST_COLOR: - if (!ctx->Extensions.NV_blend_square) { - _mesa_error( ctx, GL_INVALID_ENUM, "glBlendFunc(dfactor)" ); - return; - } - /* fall-through */ - case GL_ZERO: - case GL_ONE: - case GL_SRC_COLOR: - case GL_ONE_MINUS_SRC_COLOR: - case GL_SRC_ALPHA: - case GL_ONE_MINUS_SRC_ALPHA: - case GL_DST_ALPHA: - case GL_ONE_MINUS_DST_ALPHA: - case GL_CONSTANT_COLOR: - case GL_ONE_MINUS_CONSTANT_COLOR: - case GL_CONSTANT_ALPHA: - case GL_ONE_MINUS_CONSTANT_ALPHA: - break; - default: - _mesa_error( ctx, GL_INVALID_ENUM, "glBlendFunc(dfactor)" ); - return; - } - - if (ctx->Color.BlendDstRGB == dfactor && - ctx->Color.BlendSrcRGB == sfactor && - ctx->Color.BlendDstA == dfactor && - ctx->Color.BlendSrcA == sfactor) - return; - 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 ); + (*ctx->CurrentDispatch->BlendFuncSeparateEXT)( sfactor, dfactor, + sfactor, dfactor ); } -#if _HAVE_FULL_GL - /** * Process GL_EXT_blend_func_separate(). * @@ -144,7 +73,7 @@ _mesa_BlendFunc( GLenum sfactor, GLenum dfactor ) * On a change, flush the vertices and notify the driver via * dd_function_table::BlendFuncSeparate. */ -void +void GLAPIENTRY _mesa_BlendFuncSeparateEXT( GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorA, GLenum dfactorA ) { @@ -162,7 +91,7 @@ _mesa_BlendFuncSeparateEXT( GLenum sfactorRGB, GLenum dfactorRGB, case GL_SRC_COLOR: case GL_ONE_MINUS_SRC_COLOR: if (!ctx->Extensions.NV_blend_square) { - _mesa_error(ctx, GL_INVALID_ENUM, "glBlendFuncSeparate(sfactorRGB)"); + _mesa_error(ctx, GL_INVALID_ENUM, "glBlendFunc or glBlendFuncSeparate (sfactorRGB)"); return; } /* fall-through */ @@ -181,7 +110,7 @@ _mesa_BlendFuncSeparateEXT( GLenum sfactorRGB, GLenum dfactorRGB, case GL_ONE_MINUS_CONSTANT_ALPHA: break; default: - _mesa_error(ctx, GL_INVALID_ENUM, "glBlendFuncSeparate(sfactorRGB)"); + _mesa_error(ctx, GL_INVALID_ENUM, "glBlendFunc or glBlendFuncSeparate (sfactorRGB)"); return; } @@ -189,7 +118,7 @@ _mesa_BlendFuncSeparateEXT( GLenum sfactorRGB, GLenum dfactorRGB, case GL_DST_COLOR: case GL_ONE_MINUS_DST_COLOR: if (!ctx->Extensions.NV_blend_square) { - _mesa_error(ctx, GL_INVALID_ENUM, "glBlendFuncSeparate(dfactorRGB)"); + _mesa_error(ctx, GL_INVALID_ENUM, "glBlendFunc or glBlendFuncSeparate (dfactorRGB)"); return; } /* fall-through */ @@ -207,7 +136,7 @@ _mesa_BlendFuncSeparateEXT( GLenum sfactorRGB, GLenum dfactorRGB, case GL_ONE_MINUS_CONSTANT_ALPHA: break; default: - _mesa_error(ctx, GL_INVALID_ENUM, "glBlendFuncSeparate(dfactorRGB)"); + _mesa_error(ctx, GL_INVALID_ENUM, "glBlendFunc or glBlendFuncSeparate (dfactorRGB)"); return; } @@ -215,7 +144,7 @@ _mesa_BlendFuncSeparateEXT( GLenum sfactorRGB, GLenum dfactorRGB, case GL_SRC_COLOR: case GL_ONE_MINUS_SRC_COLOR: if (!ctx->Extensions.NV_blend_square) { - _mesa_error(ctx, GL_INVALID_ENUM, "glBlendFuncSeparate(sfactorA)"); + _mesa_error(ctx, GL_INVALID_ENUM, "glBlendFunc or glBlendFuncSeparate (sfactorA)"); return; } /* fall-through */ @@ -234,7 +163,7 @@ _mesa_BlendFuncSeparateEXT( GLenum sfactorRGB, GLenum dfactorRGB, case GL_ONE_MINUS_CONSTANT_ALPHA: break; default: - _mesa_error(ctx, GL_INVALID_ENUM, "glBlendFuncSeparate(sfactorA)"); + _mesa_error(ctx, GL_INVALID_ENUM, "glBlendFunc or glBlendFuncSeparate (sfactorA)"); return; } @@ -242,7 +171,7 @@ _mesa_BlendFuncSeparateEXT( GLenum sfactorRGB, GLenum dfactorRGB, case GL_DST_COLOR: case GL_ONE_MINUS_DST_COLOR: if (!ctx->Extensions.NV_blend_square) { - _mesa_error(ctx, GL_INVALID_ENUM, "glBlendFuncSeparate(dfactorA)"); + _mesa_error(ctx, GL_INVALID_ENUM, "glBlendFunc or glBlendFuncSeparate (dfactorA)"); return; } /* fall-through */ @@ -260,7 +189,7 @@ _mesa_BlendFuncSeparateEXT( GLenum sfactorRGB, GLenum dfactorRGB, case GL_ONE_MINUS_CONSTANT_ALPHA: break; default: - _mesa_error( ctx, GL_INVALID_ENUM, "glBlendFuncSeparate(dfactorA)" ); + _mesa_error( ctx, GL_INVALID_ENUM, "glBlendFunc or glBlendFuncSeparate (dfactorA)" ); return; } @@ -284,63 +213,112 @@ _mesa_BlendFuncSeparateEXT( GLenum sfactorRGB, GLenum dfactorRGB, } -/* This is really an extension function! */ -void -_mesa_BlendEquation( GLenum mode ) -{ - GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); - - if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) - _mesa_debug(ctx, "glBlendEquation %s\n", - _mesa_lookup_enum_by_nr(mode)); +#if _HAVE_FULL_GL +static GLboolean +_mesa_validate_blend_equation( GLcontext *ctx, + GLenum mode, GLboolean is_separate ) +{ switch (mode) { - case GL_FUNC_ADD_EXT: + case GL_FUNC_ADD: break; - case GL_MIN_EXT: - case GL_MAX_EXT: + case GL_MIN: + case GL_MAX: if (!ctx->Extensions.EXT_blend_minmax && !ctx->Extensions.ARB_imaging) { - _mesa_error(ctx, GL_INVALID_ENUM, "glBlendEquation"); - return; + return GL_FALSE; } break; + /* glBlendEquationSeparate cannot take GL_LOGIC_OP as a parameter. + */ case GL_LOGIC_OP: - if (!ctx->Extensions.EXT_blend_logic_op) { - _mesa_error(ctx, GL_INVALID_ENUM, "glBlendEquation"); - return; + if (!ctx->Extensions.EXT_blend_logic_op || is_separate) { + return GL_FALSE; } break; - case GL_FUNC_SUBTRACT_EXT: - case GL_FUNC_REVERSE_SUBTRACT_EXT: + case GL_FUNC_SUBTRACT: + case GL_FUNC_REVERSE_SUBTRACT: if (!ctx->Extensions.EXT_blend_subtract && !ctx->Extensions.ARB_imaging) { - _mesa_error(ctx, GL_INVALID_ENUM, "glBlendEquation"); - return; + return GL_FALSE; } break; default: - _mesa_error( ctx, GL_INVALID_ENUM, "glBlendEquation" ); - return; + return GL_FALSE; } - if (ctx->Color.BlendEquation == mode) + return GL_TRUE; +} + + +/* This is really an extension function! */ +void GLAPIENTRY +_mesa_BlendEquation( GLenum mode ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) + _mesa_debug(ctx, "glBlendEquation %s\n", + _mesa_lookup_enum_by_nr(mode)); + + if ( ! _mesa_validate_blend_equation( ctx, mode, GL_FALSE ) ) { + _mesa_error(ctx, GL_INVALID_ENUM, "glBlendEquation"); + return; + } + + if ( (ctx->Color.BlendEquationRGB == mode) && + (ctx->Color.BlendEquationA == 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. - */ - ctx->Color.ColorLogicOpEnabled = (mode==GL_LOGIC_OP && - ctx->Color.BlendEnabled); + ctx->Color.BlendEquationRGB = mode; + ctx->Color.BlendEquationA = mode; - if (ctx->Driver.BlendEquation) - (*ctx->Driver.BlendEquation)( ctx, mode ); + if (ctx->Driver.BlendEquationSeparate) + (*ctx->Driver.BlendEquationSeparate)( ctx, mode, mode ); } + +void GLAPIENTRY +_mesa_BlendEquationSeparateEXT( GLenum modeRGB, GLenum modeA ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) + _mesa_debug(ctx, "glBlendEquationSeparateEXT %s %s\n", + _mesa_lookup_enum_by_nr(modeRGB), + _mesa_lookup_enum_by_nr(modeA)); + + if ( (modeRGB != modeA) && !ctx->Extensions.EXT_blend_equation_separate ) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glBlendEquationSeparateEXT not supported by driver"); + return; + } + + if ( ! _mesa_validate_blend_equation( ctx, modeRGB, GL_TRUE ) ) { + _mesa_error(ctx, GL_INVALID_ENUM, "glBlendEquationSeparateEXT(modeRGB)"); + return; + } + + if ( ! _mesa_validate_blend_equation( ctx, modeA, GL_TRUE ) ) { + _mesa_error(ctx, GL_INVALID_ENUM, "glBlendEquationSeparateEXT(modeA)"); + return; + } + + + if ( (ctx->Color.BlendEquationRGB == modeRGB) && + (ctx->Color.BlendEquationA == modeA) ) + return; + + FLUSH_VERTICES(ctx, _NEW_COLOR); + ctx->Color.BlendEquationRGB = modeRGB; + ctx->Color.BlendEquationA = modeA; + + if (ctx->Driver.BlendEquationSeparate) + (*ctx->Driver.BlendEquationSeparate)( ctx, modeRGB, modeA ); +} #endif @@ -358,7 +336,7 @@ _mesa_BlendEquation( GLenum mode ) * change, flushes the vertices and notifies the driver via * dd_function_table::BlendColor callback. */ -void +void GLAPIENTRY _mesa_BlendColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha ) { GLfloat tmp[4]; @@ -391,7 +369,7 @@ _mesa_BlendColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha ) * On a change, flushes the vertices and notifies the driver via * dd_function_table::AlphaFunc callback. */ -void +void GLAPIENTRY _mesa_AlphaFunc( GLenum func, GLclampf ref ) { GET_CURRENT_CONTEXT(ctx); @@ -436,7 +414,7 @@ gl_colorbuffer_attrib::LogicOp. * On a change, flushes the vertices and notifies the driver via the * dd_function_table::LogicOpcode callback. */ -void +void GLAPIENTRY _mesa_LogicOp( GLenum opcode ) { GET_CURRENT_CONTEXT(ctx); @@ -476,7 +454,7 @@ _mesa_LogicOp( GLenum opcode ) } #if _HAVE_FULL_GL -void +void GLAPIENTRY _mesa_IndexMask( GLuint mask ) { GET_CURRENT_CONTEXT(ctx); @@ -508,7 +486,7 @@ _mesa_IndexMask( GLuint mask ) * change, flushes the vertices and notifies the driver via the * dd_function_table::ColorMask callback. */ -void +void GLAPIENTRY _mesa_ColorMask( GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha ) { @@ -537,12 +515,44 @@ _mesa_ColorMask( GLboolean red, GLboolean green, ctx->Driver.ColorMask( ctx, red, green, blue, alpha ); } + +extern void GLAPIENTRY +_mesa_ClampColorARB(GLenum target, GLenum clamp) +{ + GET_CURRENT_CONTEXT(ctx); + + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (clamp != GL_TRUE && clamp != GL_FALSE && clamp != GL_FIXED_ONLY_ARB) { + _mesa_error(ctx, GL_INVALID_ENUM, "glClampColorARB(clamp)"); + return; + } + + switch (target) { + case GL_CLAMP_VERTEX_COLOR_ARB: + ctx->Light.ClampVertexColor = clamp; + break; + case GL_CLAMP_FRAGMENT_COLOR_ARB: + ctx->Color.ClampFragmentColor = clamp; + break; + case GL_CLAMP_READ_COLOR_ARB: + ctx->Color.ClampReadColor = clamp; + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glClampColorARB(target)"); + return; + } +} + + + + /**********************************************************************/ /** \name Initialization */ /*@{*/ /** - * Initialization of the context color data. + * Initialization of the context's Color attribute group. * * \param ctx GL context. * @@ -552,14 +562,13 @@ _mesa_ColorMask( GLboolean red, GLboolean green, void _mesa_init_color( GLcontext * ctx ) { /* Color buffer group */ - ctx->Color.IndexMask = 0xffffffff; + ctx->Color.IndexMask = ~0u; ctx->Color.ColorMask[0] = 0xff; ctx->Color.ColorMask[1] = 0xff; ctx->Color.ColorMask[2] = 0xff; ctx->Color.ColorMask[3] = 0xff; ctx->Color.ClearIndex = 0; ASSIGN_4V( ctx->Color.ClearColor, 0, 0, 0, 0 ); - ctx->Color.DrawBuffer = GL_FRONT; ctx->Color.AlphaEnabled = GL_FALSE; ctx->Color.AlphaFunc = GL_ALWAYS; ctx->Color.AlphaRef = 0; @@ -568,21 +577,24 @@ void _mesa_init_color( GLcontext * ctx ) ctx->Color.BlendDstRGB = GL_ZERO; ctx->Color.BlendSrcA = GL_ONE; ctx->Color.BlendDstA = GL_ZERO; - ctx->Color.BlendEquation = GL_FUNC_ADD_EXT; + ctx->Color.BlendEquationRGB = GL_FUNC_ADD; + ctx->Color.BlendEquationA = GL_FUNC_ADD; ASSIGN_4V( ctx->Color.BlendColor, 0.0, 0.0, 0.0, 0.0 ); ctx->Color.IndexLogicOpEnabled = GL_FALSE; ctx->Color.ColorLogicOpEnabled = GL_FALSE; + ctx->Color._LogicOpEnabled = GL_FALSE; ctx->Color.LogicOp = GL_COPY; ctx->Color.DitherFlag = GL_TRUE; if (ctx->Visual.doubleBufferMode) { - ctx->Color.DrawBuffer = GL_BACK; - ctx->Color._DrawDestMask = BACK_LEFT_BIT; + ctx->Color.DrawBuffer[0] = GL_BACK; } else { - ctx->Color.DrawBuffer = GL_FRONT; - ctx->Color._DrawDestMask = FRONT_LEFT_BIT; + ctx->Color.DrawBuffer[0] = GL_FRONT; } + + ctx->Color.ClampFragmentColor = GL_FIXED_ONLY_ARB; + ctx->Color.ClampReadColor = GL_FIXED_ONLY_ARB; } /*@}*/