X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Fblend.c;h=0c28352b236c91bac03a8e58fb6fc0f084121a4b;hb=e34c857639380303a43146a50cdd724774f59a2f;hp=09acdf5c588a7ff3b92e92a9b4f66ff8d25a4e4f;hpb=b0824bd860f6d4b3ad28fc142c2eebd840ed6173;p=mesa.git diff --git a/src/mesa/main/blend.c b/src/mesa/main/blend.c index 09acdf5c588..0c28352b236 100644 --- a/src/mesa/main/blend.c +++ b/src/mesa/main/blend.c @@ -22,9 +22,10 @@ * 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. */ @@ -58,11 +59,18 @@ legal_src_factor(const struct gl_context *ctx, GLenum factor) case GL_DST_ALPHA: case GL_ONE_MINUS_DST_ALPHA: case GL_SRC_ALPHA_SATURATE: + return GL_TRUE; case GL_CONSTANT_COLOR: case GL_ONE_MINUS_CONSTANT_COLOR: case GL_CONSTANT_ALPHA: case GL_ONE_MINUS_CONSTANT_ALPHA: - return GL_TRUE; + return _mesa_is_desktop_gl(ctx) || ctx->API == API_OPENGLES2; + case GL_SRC1_COLOR: + case GL_SRC1_ALPHA: + case GL_ONE_MINUS_SRC1_COLOR: + case GL_ONE_MINUS_SRC1_ALPHA: + return _mesa_is_desktop_gl(ctx) + && ctx->Extensions.ARB_blend_func_extended; default: return GL_FALSE; } @@ -88,11 +96,22 @@ legal_dst_factor(const struct gl_context *ctx, GLenum factor) case GL_ONE_MINUS_SRC_ALPHA: case GL_DST_ALPHA: case GL_ONE_MINUS_DST_ALPHA: + return GL_TRUE; case GL_CONSTANT_COLOR: case GL_ONE_MINUS_CONSTANT_COLOR: case GL_CONSTANT_ALPHA: case GL_ONE_MINUS_CONSTANT_ALPHA: - return GL_TRUE; + return _mesa_is_desktop_gl(ctx) || ctx->API == API_OPENGLES2; + case GL_SRC_ALPHA_SATURATE: + return (_mesa_is_desktop_gl(ctx) + && ctx->Extensions.ARB_blend_func_extended) + || _mesa_is_gles3(ctx); + case GL_SRC1_COLOR: + case GL_SRC1_ALPHA: + case GL_ONE_MINUS_SRC1_COLOR: + case GL_ONE_MINUS_SRC1_ALPHA: + return _mesa_is_desktop_gl(ctx) + && ctx->Extensions.ARB_blend_func_extended; default: return GL_FALSE; } @@ -152,9 +171,27 @@ validate_blend_factors(struct gl_context *ctx, const char *func, void GLAPIENTRY _mesa_BlendFunc( GLenum sfactor, GLenum dfactor ) { - _mesa_BlendFuncSeparateEXT(sfactor, dfactor, sfactor, dfactor); + _mesa_BlendFuncSeparate(sfactor, dfactor, sfactor, dfactor); +} + +static GLboolean +blend_factor_is_dual_src(GLenum factor) +{ + return (factor == GL_SRC1_COLOR || + factor == GL_SRC1_ALPHA || + factor == GL_ONE_MINUS_SRC1_COLOR || + factor == GL_ONE_MINUS_SRC1_ALPHA); } +static void +update_uses_dual_src(struct gl_context *ctx, int buf) +{ + ctx->Color.Blend[buf]._UsesDualSrc = + (blend_factor_is_dual_src(ctx->Color.Blend[buf].SrcRGB) || + blend_factor_is_dual_src(ctx->Color.Blend[buf].DstRGB) || + blend_factor_is_dual_src(ctx->Color.Blend[buf].SrcA) || + blend_factor_is_dual_src(ctx->Color.Blend[buf].DstA)); +} /** * Set the separate blend source/dest factors for all draw buffers. @@ -165,13 +202,12 @@ _mesa_BlendFunc( GLenum sfactor, GLenum dfactor ) * \param dfactorA alpha destination factor operator. */ void GLAPIENTRY -_mesa_BlendFuncSeparateEXT( GLenum sfactorRGB, GLenum dfactorRGB, +_mesa_BlendFuncSeparate( GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorA, GLenum dfactorA ) { GLuint buf, numBuffers; GLboolean changed; GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); if (MESA_VERBOSE & VERBOSE_API) _mesa_debug(ctx, "glBlendFuncSeparate %s %s %s %s\n", @@ -209,6 +245,7 @@ _mesa_BlendFuncSeparateEXT( GLenum sfactorRGB, GLenum dfactorRGB, ctx->Color.Blend[buf].DstRGB = dfactorRGB; ctx->Color.Blend[buf].SrcA = sfactorA; ctx->Color.Blend[buf].DstA = dfactorA; + update_uses_dual_src(ctx, buf); } ctx->Color._BlendFuncPerBuffer = GL_FALSE; @@ -219,16 +256,13 @@ _mesa_BlendFuncSeparateEXT( GLenum sfactorRGB, GLenum dfactorRGB, } -#if _HAVE_FULL_GL - - /** * Set blend source/dest factors for one color buffer/target. */ void GLAPIENTRY -_mesa_BlendFunci(GLuint buf, GLenum sfactor, GLenum dfactor) +_mesa_BlendFunciARB(GLuint buf, GLenum sfactor, GLenum dfactor) { - _mesa_BlendFuncSeparatei(buf, sfactor, dfactor, sfactor, dfactor); + _mesa_BlendFuncSeparateiARB(buf, sfactor, dfactor, sfactor, dfactor); } @@ -236,11 +270,10 @@ _mesa_BlendFunci(GLuint buf, GLenum sfactor, GLenum dfactor) * Set separate blend source/dest factors for one color buffer/target. */ void GLAPIENTRY -_mesa_BlendFuncSeparatei(GLuint buf, GLenum sfactorRGB, GLenum dfactorRGB, +_mesa_BlendFuncSeparateiARB(GLuint buf, GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorA, GLenum dfactorA) { GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); if (!ctx->Extensions.ARB_draw_buffers_blend) { _mesa_error(ctx, GL_INVALID_OPERATION, "glBlendFunc[Separate]i()"); @@ -271,6 +304,7 @@ _mesa_BlendFuncSeparatei(GLuint buf, GLenum sfactorRGB, GLenum dfactorRGB, ctx->Color.Blend[buf].DstRGB = dfactorRGB; ctx->Color.Blend[buf].SrcA = sfactorA; ctx->Color.Blend[buf].DstA = dfactorA; + update_uses_dual_src(ctx, buf); ctx->Color._BlendFuncPerBuffer = GL_TRUE; if (ctx->Driver.BlendFuncSeparatei) { @@ -308,7 +342,6 @@ _mesa_BlendEquation( GLenum mode ) GLuint buf, numBuffers; GLboolean changed; GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); if (MESA_VERBOSE & VERBOSE_API) _mesa_debug(ctx, "glBlendEquation(%s)\n", @@ -349,10 +382,9 @@ _mesa_BlendEquation( GLenum mode ) * Set blend equation for one color buffer/target. */ void GLAPIENTRY -_mesa_BlendEquationi(GLuint buf, GLenum mode) +_mesa_BlendEquationiARB(GLuint buf, GLenum mode) { GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); if (MESA_VERBOSE & VERBOSE_API) _mesa_debug(ctx, "glBlendEquationi(%u, %s)\n", @@ -384,12 +416,11 @@ _mesa_BlendEquationi(GLuint buf, GLenum mode) void GLAPIENTRY -_mesa_BlendEquationSeparateEXT( GLenum modeRGB, GLenum modeA ) +_mesa_BlendEquationSeparate( GLenum modeRGB, GLenum modeA ) { GLuint buf, numBuffers; GLboolean changed; GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); if (MESA_VERBOSE & VERBOSE_API) _mesa_debug(ctx, "glBlendEquationSeparateEXT(%s %s)\n", @@ -442,10 +473,9 @@ _mesa_BlendEquationSeparateEXT( GLenum modeRGB, GLenum modeA ) * Set separate blend equations for one color buffer/target. */ void GLAPIENTRY -_mesa_BlendEquationSeparatei(GLuint buf, GLenum modeRGB, GLenum modeA) +_mesa_BlendEquationSeparateiARB(GLuint buf, GLenum modeRGB, GLenum modeA) { GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); if (MESA_VERBOSE & VERBOSE_API) _mesa_debug(ctx, "glBlendEquationSeparatei(%u, %s %s)\n", buf, @@ -482,10 +512,6 @@ _mesa_BlendEquationSeparatei(GLuint buf, GLenum modeRGB, GLenum modeA) } - -#endif /* _HAVE_FULL_GL */ - - /** * Set the blending color. * @@ -505,7 +531,6 @@ _mesa_BlendColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha ) { GLfloat tmp[4]; GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); tmp[0] = red; tmp[1] = green; @@ -542,7 +567,6 @@ void GLAPIENTRY _mesa_AlphaFunc( GLenum func, GLclampf ref ) { GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); if (MESA_VERBOSE & VERBOSE_API) _mesa_debug(ctx, "glAlphaFunc(%s, %f)\n", @@ -590,7 +614,6 @@ void GLAPIENTRY _mesa_LogicOp( GLenum opcode ) { GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); if (MESA_VERBOSE & VERBOSE_API) _mesa_debug(ctx, "glLogicOp(%s)\n", _mesa_lookup_enum_by_nr(opcode)); @@ -628,12 +651,11 @@ _mesa_LogicOp( GLenum opcode ) ctx->Driver.LogicOpcode( ctx, opcode ); } -#if _HAVE_FULL_GL + void GLAPIENTRY _mesa_IndexMask( GLuint mask ) { GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); if (ctx->Color.IndexMask == mask) return; @@ -641,7 +663,6 @@ _mesa_IndexMask( GLuint mask ) FLUSH_VERTICES(ctx, _NEW_COLOR); ctx->Color.IndexMask = mask; } -#endif /** @@ -666,7 +687,6 @@ _mesa_ColorMask( GLboolean red, GLboolean green, GLubyte tmp[4]; GLuint i; GLboolean flushed; - ASSERT_OUTSIDE_BEGIN_END(ctx); if (MESA_VERBOSE & VERBOSE_API) _mesa_debug(ctx, "glColorMask(%d, %d, %d, %d)\n", @@ -700,12 +720,11 @@ _mesa_ColorMask( GLboolean red, GLboolean green, * For GL_EXT_draw_buffers2 and GL3 */ void GLAPIENTRY -_mesa_ColorMaskIndexed( GLuint buf, GLboolean red, GLboolean green, +_mesa_ColorMaski( GLuint buf, GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha ) { GLubyte tmp[4]; GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); if (MESA_VERBOSE & VERBOSE_API) _mesa_debug(ctx, "glColorMaskIndexed %u %d %d %d %d\n", @@ -736,12 +755,10 @@ _mesa_ColorMaskIndexed( GLuint buf, GLboolean red, GLboolean green, void GLAPIENTRY -_mesa_ClampColorARB(GLenum target, GLenum clamp) +_mesa_ClampColor(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; @@ -749,25 +766,113 @@ _mesa_ClampColorARB(GLenum target, GLenum clamp) switch (target) { case GL_CLAMP_VERTEX_COLOR_ARB: + if (ctx->API == API_OPENGL_CORE && + !ctx->Extensions.ARB_color_buffer_float) { + goto invalid_enum; + } FLUSH_VERTICES(ctx, _NEW_LIGHT); ctx->Light.ClampVertexColor = clamp; + _mesa_update_clamp_vertex_color(ctx); break; case GL_CLAMP_FRAGMENT_COLOR_ARB: + if (ctx->API == API_OPENGL_CORE && + !ctx->Extensions.ARB_color_buffer_float) { + goto invalid_enum; + } FLUSH_VERTICES(ctx, _NEW_FRAG_CLAMP); ctx->Color.ClampFragmentColor = clamp; + _mesa_update_clamp_fragment_color(ctx); break; case GL_CLAMP_READ_COLOR_ARB: - FLUSH_VERTICES(ctx, _NEW_COLOR); ctx->Color.ClampReadColor = clamp; break; default: - _mesa_error(ctx, GL_INVALID_ENUM, "glClampColorARB(target)"); - return; + goto invalid_enum; } + return; + +invalid_enum: + _mesa_error(ctx, GL_INVALID_ENUM, "glClampColor(%s)", + _mesa_lookup_enum_by_nr(target)); +} + +static GLboolean +get_clamp_color(const struct gl_framebuffer *fb, GLenum clamp) +{ + if (clamp == GL_TRUE || clamp == GL_FALSE) + return clamp; + + ASSERT(clamp == GL_FIXED_ONLY); + if (!fb) + return GL_TRUE; + + return fb->_AllColorBuffersFixedPoint; +} + +GLboolean +_mesa_get_clamp_fragment_color(const struct gl_context *ctx) +{ + return get_clamp_color(ctx->DrawBuffer, + ctx->Color.ClampFragmentColor); +} + +GLboolean +_mesa_get_clamp_vertex_color(const struct gl_context *ctx) +{ + return get_clamp_color(ctx->DrawBuffer, ctx->Light.ClampVertexColor); +} + +GLboolean +_mesa_get_clamp_read_color(const struct gl_context *ctx) +{ + return get_clamp_color(ctx->ReadBuffer, ctx->Color.ClampReadColor); } +/** + * Update the ctx->Color._ClampFragmentColor field + */ +void +_mesa_update_clamp_fragment_color(struct gl_context *ctx) +{ + struct gl_framebuffer *fb = ctx->DrawBuffer; + + /* Don't clamp if: + * - there is no colorbuffer + * - all colorbuffers are unsigned normalized, so clamping has no effect + * - there is an integer colorbuffer + */ + if (!fb || !fb->_HasSNormOrFloatColorBuffer || fb->_IntegerColor) + ctx->Color._ClampFragmentColor = GL_FALSE; + else + ctx->Color._ClampFragmentColor = _mesa_get_clamp_fragment_color(ctx); +} +/** + * Update the ctx->Color._ClampVertexColor field + */ +void +_mesa_update_clamp_vertex_color(struct gl_context *ctx) +{ + ctx->Light._ClampVertexColor = _mesa_get_clamp_vertex_color(ctx); +} +/** + * Returns an appropriate gl_format for color rendering based on the + * GL_FRAMEBUFFER_SRGB state. + * + * Some drivers implement GL_FRAMEBUFFER_SRGB using a flag on the blend state + * (which GL_FRAMEBUFFER_SRGB maps to reasonably), but some have to do so by + * overriding the format of the surface. This is a helper for doing the + * surface format override variant. + */ +gl_format +_mesa_get_render_format(const struct gl_context *ctx, gl_format format) +{ + if (ctx->Color.sRGBEnabled) + return format; + else + return _mesa_get_srgb_format_linear(format); +} /**********************************************************************/ /** \name Initialization */ @@ -816,10 +921,17 @@ void _mesa_init_color( struct gl_context * ctx ) ctx->Color.DrawBuffer[0] = GL_FRONT; } - ctx->Color.ClampFragmentColor = GL_FIXED_ONLY_ARB; - ctx->Color._ClampFragmentColor = GL_TRUE; + ctx->Color.ClampFragmentColor = ctx->API == API_OPENGL_COMPAT ? + GL_FIXED_ONLY_ARB : GL_FALSE; + ctx->Color._ClampFragmentColor = GL_FALSE; ctx->Color.ClampReadColor = GL_FIXED_ONLY_ARB; - ctx->Color._ClampReadColor = GL_TRUE; + + if (ctx->API == API_OPENGLES2) { + /* GLES 3 behaves as though GL_FRAMEBUFFER_SRGB is always enabled. */ + ctx->Color.sRGBEnabled = GL_TRUE; + } else { + ctx->Color.sRGBEnabled = GL_FALSE; + } } /*@}*/