X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Fconvolve.c;h=faea445e4c8a7ab8f2abd6129707b63a9f147a16;hb=f431a3fb4dc1bf860203d79e54657e3a62bc50df;hp=5bb4e82a8432674af08bb814da60a36d2816d55b;hpb=cdfba5d37519f7be2e1cf728588b632ea06028cb;p=mesa.git diff --git a/src/mesa/main/convolve.c b/src/mesa/main/convolve.c index 5bb4e82a843..faea445e4c8 100644 --- a/src/mesa/main/convolve.c +++ b/src/mesa/main/convolve.c @@ -1,10 +1,10 @@ -/* $Id: convolve.c,v 1.15 2000/11/23 02:50:56 jtaylor Exp $ */ +/* $Id: convolve.c,v 1.24 2001/05/09 22:24:22 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"), @@ -112,31 +112,35 @@ _mesa_ConvolutionFilter1D(GLenum target, GLenum internalFormat, GLsizei width, G { GLenum baseFormat; GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glConvolutionFilter1D"); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); if (target != GL_CONVOLUTION_1D) { - gl_error(ctx, GL_INVALID_ENUM, "glConvolutionFilter1D(target)"); + _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionFilter1D(target)"); return; } baseFormat = base_filter_format(internalFormat); if (baseFormat < 0 || baseFormat == GL_COLOR_INDEX) { - gl_error(ctx, GL_INVALID_ENUM, "glConvolutionFilter1D(internalFormat)"); + _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionFilter1D(internalFormat)"); return; } if (width < 0 || width > MAX_CONVOLUTION_WIDTH) { - gl_error(ctx, GL_INVALID_VALUE, "glConvolutionFilter1D(width)"); + _mesa_error(ctx, GL_INVALID_VALUE, "glConvolutionFilter1D(width)"); return; } - if (!_mesa_is_legal_format_and_type(format, type) || - format == GL_COLOR_INDEX || + if (!_mesa_is_legal_format_and_type(format, type)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glConvolutionFilter1D(format or type)"); + return; + } + + if (format == GL_COLOR_INDEX || format == GL_STENCIL_INDEX || format == GL_DEPTH_COMPONENT || format == GL_INTENSITY || type == GL_BITMAP) { - gl_error(ctx, GL_INVALID_ENUM, "glConvolutionFilter1D(format or type)"); + _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionFilter1D(format or type)"); return; } @@ -182,35 +186,38 @@ _mesa_ConvolutionFilter2D(GLenum target, GLenum internalFormat, GLsizei width, G GLenum baseFormat; GLint i, components; GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glConvolutionFilter2D"); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); if (target != GL_CONVOLUTION_2D) { - gl_error(ctx, GL_INVALID_ENUM, "glConvolutionFilter2D(target)"); + _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionFilter2D(target)"); return; } baseFormat = base_filter_format(internalFormat); if (baseFormat < 0 || baseFormat == GL_COLOR_INDEX) { - gl_error(ctx, GL_INVALID_ENUM, "glConvolutionFilter2D(internalFormat)"); + _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionFilter2D(internalFormat)"); return; } if (width < 0 || width > MAX_CONVOLUTION_WIDTH) { - gl_error(ctx, GL_INVALID_VALUE, "glConvolutionFilter2D(width)"); + _mesa_error(ctx, GL_INVALID_VALUE, "glConvolutionFilter2D(width)"); return; } if (height < 0 || height > MAX_CONVOLUTION_HEIGHT) { - gl_error(ctx, GL_INVALID_VALUE, "glConvolutionFilter2D(height)"); + _mesa_error(ctx, GL_INVALID_VALUE, "glConvolutionFilter2D(height)"); return; } - if (!_mesa_is_legal_format_and_type(format, type) || - format == GL_COLOR_INDEX || + if (!_mesa_is_legal_format_and_type(format, type)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glConvolutionFilter2D(format or type)"); + return; + } + if (format == GL_COLOR_INDEX || format == GL_STENCIL_INDEX || format == GL_DEPTH_COMPONENT || format == GL_INTENSITY || type == GL_BITMAP) { - gl_error(ctx, GL_INVALID_ENUM, "glConvolutionFilter2D(format or type)"); + _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionFilter2D(format or type)"); return; } @@ -236,7 +243,7 @@ _mesa_ConvolutionFilter2D(GLenum target, GLenum internalFormat, GLsizei width, G { const GLfloat *scale = ctx->Pixel.ConvolutionFilterScale[1]; const GLfloat *bias = ctx->Pixel.ConvolutionFilterBias[1]; - for (i = 0; i < width * height * 4; i++) { + for (i = 0; i < width * height; i++) { GLfloat r = ctx->Convolution2D.Filter[i * 4 + 0]; GLfloat g = ctx->Convolution2D.Filter[i * 4 + 1]; GLfloat b = ctx->Convolution2D.Filter[i * 4 + 2]; @@ -261,8 +268,7 @@ _mesa_ConvolutionParameterf(GLenum target, GLenum pname, GLfloat param) { GET_CURRENT_CONTEXT(ctx); GLuint c; - - ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glConvolutionParameterf"); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); switch (target) { case GL_CONVOLUTION_1D: @@ -275,7 +281,7 @@ _mesa_ConvolutionParameterf(GLenum target, GLenum pname, GLfloat param) c = 2; break; default: - gl_error(ctx, GL_INVALID_ENUM, "glConvolutionParameterf(target)"); + _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionParameterf(target)"); return; } @@ -287,12 +293,12 @@ _mesa_ConvolutionParameterf(GLenum target, GLenum pname, GLfloat param) ctx->Pixel.ConvolutionBorderMode[c] = (GLenum) param; } else { - gl_error(ctx, GL_INVALID_ENUM, "glConvolutionParameterf(params)"); + _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionParameterf(params)"); return; } break; default: - gl_error(ctx, GL_INVALID_ENUM, "glConvolutionParameterf(pname)"); + _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionParameterf(pname)"); return; } @@ -306,8 +312,7 @@ _mesa_ConvolutionParameterfv(GLenum target, GLenum pname, const GLfloat *params) GET_CURRENT_CONTEXT(ctx); struct gl_convolution_attrib *conv; GLuint c; - - ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glConvolutionParameterfv"); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); switch (target) { case GL_CONVOLUTION_1D: @@ -323,7 +328,7 @@ _mesa_ConvolutionParameterfv(GLenum target, GLenum pname, const GLfloat *params) conv = &ctx->Separable2D; break; default: - gl_error(ctx, GL_INVALID_ENUM, "glConvolutionParameterfv(target)"); + _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionParameterfv(target)"); return; } @@ -338,7 +343,7 @@ _mesa_ConvolutionParameterfv(GLenum target, GLenum pname, const GLfloat *params) ctx->Pixel.ConvolutionBorderMode[c] = (GLenum) params[0]; } else { - gl_error(ctx, GL_INVALID_ENUM, "glConvolutionParameterfv(params)"); + _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionParameterfv(params)"); return; } break; @@ -349,7 +354,7 @@ _mesa_ConvolutionParameterfv(GLenum target, GLenum pname, const GLfloat *params) COPY_4V(ctx->Pixel.ConvolutionFilterBias[c], params); break; default: - gl_error(ctx, GL_INVALID_ENUM, "glConvolutionParameterfv(pname)"); + _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionParameterfv(pname)"); return; } @@ -362,8 +367,7 @@ _mesa_ConvolutionParameteri(GLenum target, GLenum pname, GLint param) { GET_CURRENT_CONTEXT(ctx); GLuint c; - - ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glConvolutionParameteri"); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); switch (target) { case GL_CONVOLUTION_1D: @@ -376,7 +380,7 @@ _mesa_ConvolutionParameteri(GLenum target, GLenum pname, GLint param) c = 2; break; default: - gl_error(ctx, GL_INVALID_ENUM, "glConvolutionParameteri(target)"); + _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionParameteri(target)"); return; } @@ -388,12 +392,12 @@ _mesa_ConvolutionParameteri(GLenum target, GLenum pname, GLint param) ctx->Pixel.ConvolutionBorderMode[c] = (GLenum) param; } else { - gl_error(ctx, GL_INVALID_ENUM, "glConvolutionParameteri(params)"); + _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionParameteri(params)"); return; } break; default: - gl_error(ctx, GL_INVALID_ENUM, "glConvolutionParameteri(pname)"); + _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionParameteri(pname)"); return; } @@ -407,8 +411,7 @@ _mesa_ConvolutionParameteriv(GLenum target, GLenum pname, const GLint *params) GET_CURRENT_CONTEXT(ctx); struct gl_convolution_attrib *conv; GLuint c; - - ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glConvolutionParameteriv"); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); switch (target) { case GL_CONVOLUTION_1D: @@ -424,7 +427,7 @@ _mesa_ConvolutionParameteriv(GLenum target, GLenum pname, const GLint *params) conv = &ctx->Separable2D; break; default: - gl_error(ctx, GL_INVALID_ENUM, "glConvolutionParameteriv(target)"); + _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionParameteriv(target)"); return; } @@ -442,7 +445,7 @@ _mesa_ConvolutionParameteriv(GLenum target, GLenum pname, const GLint *params) ctx->Pixel.ConvolutionBorderMode[c] = (GLenum) params[0]; } else { - gl_error(ctx, GL_INVALID_ENUM, "glConvolutionParameteriv(params)"); + _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionParameteriv(params)"); return; } break; @@ -453,7 +456,7 @@ _mesa_ConvolutionParameteriv(GLenum target, GLenum pname, const GLint *params) COPY_4V(ctx->Pixel.ConvolutionFilterBias[c], params); break; default: - gl_error(ctx, GL_INVALID_ENUM, "glConvolutionParameteriv(pname)"); + _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionParameteriv(pname)"); return; } @@ -465,34 +468,27 @@ void _mesa_CopyConvolutionFilter1D(GLenum target, GLenum internalFormat, GLint x, GLint y, GLsizei width) { GLenum baseFormat; - GLchan rgba[MAX_CONVOLUTION_WIDTH][4]; GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glCopyConvolutionFilter1D"); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); if (target != GL_CONVOLUTION_1D) { - gl_error(ctx, GL_INVALID_ENUM, "glCopyConvolutionFilter1D(target)"); + _mesa_error(ctx, GL_INVALID_ENUM, "glCopyConvolutionFilter1D(target)"); return; } baseFormat = base_filter_format(internalFormat); if (baseFormat < 0 || baseFormat == GL_COLOR_INDEX) { - gl_error(ctx, GL_INVALID_ENUM, "glCopyConvolutionFilter1D(internalFormat)"); + _mesa_error(ctx, GL_INVALID_ENUM, "glCopyConvolutionFilter1D(internalFormat)"); return; } if (width < 0 || width > MAX_CONVOLUTION_WIDTH) { - gl_error(ctx, GL_INVALID_VALUE, "glCopyConvolutionFilter1D(width)"); + _mesa_error(ctx, GL_INVALID_VALUE, "glCopyConvolutionFilter1D(width)"); return; } - /* read pixels from framebuffer */ - RENDER_START(ctx); - gl_read_rgba_span(ctx, ctx->ReadBuffer, width, x, y, (GLchan (*)[4]) rgba); - RENDER_FINISH(ctx); - - /* store as convolution filter */ - _mesa_ConvolutionFilter1D(target, internalFormat, width, - GL_RGBA, CHAN_TYPE, rgba); + ctx->Driver.CopyConvolutionFilter1D( ctx, target, + internalFormat, x, y, width); } @@ -500,60 +496,32 @@ void _mesa_CopyConvolutionFilter2D(GLenum target, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height) { GLenum baseFormat; - GLint i; - struct gl_pixelstore_attrib packSave; - GLchan rgba[MAX_CONVOLUTION_HEIGHT][MAX_CONVOLUTION_WIDTH][4]; GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glCopyConvolutionFilter2D"); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); if (target != GL_CONVOLUTION_2D) { - gl_error(ctx, GL_INVALID_ENUM, "glCopyConvolutionFilter2D(target)"); + _mesa_error(ctx, GL_INVALID_ENUM, "glCopyConvolutionFilter2D(target)"); return; } baseFormat = base_filter_format(internalFormat); if (baseFormat < 0 || baseFormat == GL_COLOR_INDEX) { - gl_error(ctx, GL_INVALID_ENUM, "glCopyConvolutionFilter2D(internalFormat)"); + _mesa_error(ctx, GL_INVALID_ENUM, "glCopyConvolutionFilter2D(internalFormat)"); return; } if (width < 0 || width > MAX_CONVOLUTION_WIDTH) { - gl_error(ctx, GL_INVALID_VALUE, "glCopyConvolutionFilter2D(width)"); + _mesa_error(ctx, GL_INVALID_VALUE, "glCopyConvolutionFilter2D(width)"); return; } if (height < 0 || height > MAX_CONVOLUTION_HEIGHT) { - gl_error(ctx, GL_INVALID_VALUE, "glCopyConvolutionFilter2D(height)"); + _mesa_error(ctx, GL_INVALID_VALUE, "glCopyConvolutionFilter2D(height)"); return; } - /* read pixels from framebuffer */ - RENDER_START(ctx); - for (i = 0; i < height; i++) { - gl_read_rgba_span(ctx, ctx->ReadBuffer, width, x, y + i, - (GLchan (*)[4]) rgba[i]); - } - RENDER_FINISH(ctx); - - /* - * store as convolution filter - */ - packSave = ctx->Unpack; /* save pixel packing params */ - - ctx->Unpack.Alignment = 1; - ctx->Unpack.RowLength = MAX_CONVOLUTION_WIDTH; - ctx->Unpack.SkipPixels = 0; - ctx->Unpack.SkipRows = 0; - ctx->Unpack.ImageHeight = 0; - ctx->Unpack.SkipImages = 0; - ctx->Unpack.SwapBytes = GL_FALSE; - ctx->Unpack.LsbFirst = GL_FALSE; - ctx->NewState |= _NEW_PACKUNPACK; - - _mesa_ConvolutionFilter2D(target, internalFormat, width, height, - GL_RGBA, CHAN_TYPE, rgba); - - ctx->Unpack = packSave; /* restore pixel packing params */ - ctx->NewState |= _NEW_PACKUNPACK; + ctx->Driver.CopyConvolutionFilter2D( ctx, target, internalFormat, x, y, + width, height ); + } @@ -561,21 +529,25 @@ void _mesa_GetConvolutionFilter(GLenum target, GLenum format, GLenum type, GLvoid *image) { const struct gl_convolution_attrib *filter; - GLint row; + GLuint row; GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetConvolutionFilter"); + ASSERT_OUTSIDE_BEGIN_END(ctx); if (ctx->NewState) { - gl_update_state(ctx); + _mesa_update_state(ctx); + } + + if (!_mesa_is_legal_format_and_type(format, type)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetConvolutionFilter(format or type)"); + return; } - if (!_mesa_is_legal_format_and_type(format, type) || - format == GL_COLOR_INDEX || + if (format == GL_COLOR_INDEX || format == GL_STENCIL_INDEX || format == GL_DEPTH_COMPONENT || format == GL_INTENSITY || type == GL_BITMAP) { - gl_error(ctx, GL_INVALID_ENUM, "glGetConvolutionFilter(format or type)"); + _mesa_error(ctx, GL_INVALID_ENUM, "glGetConvolutionFilter(format or type)"); return; } @@ -587,7 +559,7 @@ _mesa_GetConvolutionFilter(GLenum target, GLenum format, GLenum type, GLvoid *im filter = &(ctx->Convolution2D); break; default: - gl_error(ctx, GL_INVALID_ENUM, "glGetConvolutionFilter(target)"); + _mesa_error(ctx, GL_INVALID_ENUM, "glGetConvolutionFilter(target)"); return; } @@ -609,8 +581,7 @@ _mesa_GetConvolutionParameterfv(GLenum target, GLenum pname, GLfloat *params) GET_CURRENT_CONTEXT(ctx); const struct gl_convolution_attrib *conv; GLuint c; - - ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetConvolutionParameterfv"); + ASSERT_OUTSIDE_BEGIN_END(ctx); switch (target) { case GL_CONVOLUTION_1D: @@ -626,7 +597,7 @@ _mesa_GetConvolutionParameterfv(GLenum target, GLenum pname, GLfloat *params) conv = &ctx->Separable2D; break; default: - gl_error(ctx, GL_INVALID_ENUM, "glGetConvolutionParameterfv(target)"); + _mesa_error(ctx, GL_INVALID_ENUM, "glGetConvolutionParameterfv(target)"); return; } @@ -659,7 +630,7 @@ _mesa_GetConvolutionParameterfv(GLenum target, GLenum pname, GLfloat *params) *params = (GLfloat) ctx->Const.MaxConvolutionHeight; break; default: - gl_error(ctx, GL_INVALID_ENUM, "glGetConvolutionParameterfv(pname)"); + _mesa_error(ctx, GL_INVALID_ENUM, "glGetConvolutionParameterfv(pname)"); return; } } @@ -671,8 +642,7 @@ _mesa_GetConvolutionParameteriv(GLenum target, GLenum pname, GLint *params) GET_CURRENT_CONTEXT(ctx); const struct gl_convolution_attrib *conv; GLuint c; - - ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetConvolutionParameteriv"); + ASSERT_OUTSIDE_BEGIN_END(ctx); switch (target) { case GL_CONVOLUTION_1D: @@ -688,7 +658,7 @@ _mesa_GetConvolutionParameteriv(GLenum target, GLenum pname, GLint *params) conv = &ctx->Separable2D; break; default: - gl_error(ctx, GL_INVALID_ENUM, "glGetConvolutionParameteriv(target)"); + _mesa_error(ctx, GL_INVALID_ENUM, "glGetConvolutionParameteriv(target)"); return; } @@ -730,7 +700,7 @@ _mesa_GetConvolutionParameteriv(GLenum target, GLenum pname, GLint *params) *params = (GLint) ctx->Const.MaxConvolutionHeight; break; default: - gl_error(ctx, GL_INVALID_ENUM, "glGetConvolutionParameteriv(pname)"); + _mesa_error(ctx, GL_INVALID_ENUM, "glGetConvolutionParameteriv(pname)"); return; } } @@ -742,24 +712,28 @@ _mesa_GetSeparableFilter(GLenum target, GLenum format, GLenum type, GLvoid *row, const GLint colStart = MAX_CONVOLUTION_WIDTH * 4; const struct gl_convolution_attrib *filter; GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetSeparableFilter"); + ASSERT_OUTSIDE_BEGIN_END(ctx); if (ctx->NewState) { - gl_update_state(ctx); + _mesa_update_state(ctx); } if (target != GL_SEPARABLE_2D) { - gl_error(ctx, GL_INVALID_ENUM, "glGetSeparableFilter(target)"); + _mesa_error(ctx, GL_INVALID_ENUM, "glGetSeparableFilter(target)"); return; } - if (!_mesa_is_legal_format_and_type(format, type) || - format == GL_COLOR_INDEX || + if (!_mesa_is_legal_format_and_type(format, type)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetConvolutionFilter(format or type)"); + return; + } + + if (format == GL_COLOR_INDEX || format == GL_STENCIL_INDEX || format == GL_DEPTH_COMPONENT || format == GL_INTENSITY || type == GL_BITMAP) { - gl_error(ctx, GL_INVALID_ENUM, "glGetConvolutionFilter(format or type)"); + _mesa_error(ctx, GL_INVALID_ENUM, "glGetConvolutionFilter(format or type)"); return; } @@ -796,35 +770,39 @@ _mesa_SeparableFilter2D(GLenum target, GLenum internalFormat, GLsizei width, GLs const GLint colStart = MAX_CONVOLUTION_WIDTH * 4; GLenum baseFormat; GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glSeparableFilter2D"); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); if (target != GL_SEPARABLE_2D) { - gl_error(ctx, GL_INVALID_ENUM, "glSeparableFilter2D(target)"); + _mesa_error(ctx, GL_INVALID_ENUM, "glSeparableFilter2D(target)"); return; } baseFormat = base_filter_format(internalFormat); if (baseFormat < 0 || baseFormat == GL_COLOR_INDEX) { - gl_error(ctx, GL_INVALID_ENUM, "glSeparableFilter2D(internalFormat)"); + _mesa_error(ctx, GL_INVALID_ENUM, "glSeparableFilter2D(internalFormat)"); return; } if (width < 0 || width > MAX_CONVOLUTION_WIDTH) { - gl_error(ctx, GL_INVALID_VALUE, "glSeparableFilter2D(width)"); + _mesa_error(ctx, GL_INVALID_VALUE, "glSeparableFilter2D(width)"); return; } if (height < 0 || height > MAX_CONVOLUTION_HEIGHT) { - gl_error(ctx, GL_INVALID_VALUE, "glSeparableFilter2D(height)"); + _mesa_error(ctx, GL_INVALID_VALUE, "glSeparableFilter2D(height)"); return; } - if (!_mesa_is_legal_format_and_type(format, type) || - format == GL_COLOR_INDEX || + if (!_mesa_is_legal_format_and_type(format, type)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glSeparableFilter2D(format or type)"); + return; + } + + if (format == GL_COLOR_INDEX || format == GL_STENCIL_INDEX || format == GL_DEPTH_COMPONENT || format == GL_INTENSITY || type == GL_BITMAP) { - gl_error(ctx, GL_INVALID_ENUM, "glSeparableFilter2D(format or type)"); + _mesa_error(ctx, GL_INVALID_ENUM, "glSeparableFilter2D(format or type)"); return; } @@ -1407,3 +1385,33 @@ _mesa_convolve_sep_image(const GLcontext *ctx, ; } } + + + +/* + * This function computes an image's size after convolution. + * If the convolution border mode is GL_REDUCE, the post-convolution + * image will be smaller than the original. + */ +void +_mesa_adjust_image_for_convolution(const GLcontext *ctx, GLuint dimensions, + GLsizei *width, GLsizei *height) +{ + if (ctx->Pixel.Convolution1DEnabled + && dimensions == 1 + && ctx->Pixel.ConvolutionBorderMode[0] == GL_REDUCE) { + *width = *width - (MAX2(ctx->Convolution1D.Width, 1) - 1); + } + else if (ctx->Pixel.Convolution2DEnabled + && dimensions > 1 + && ctx->Pixel.ConvolutionBorderMode[1] == GL_REDUCE) { + *width = *width - (MAX2(ctx->Convolution2D.Width, 1) - 1); + *height = *height - (MAX2(ctx->Convolution2D.Height, 1) - 1); + } + else if (ctx->Pixel.Separable2DEnabled + && dimensions > 1 + && ctx->Pixel.ConvolutionBorderMode[2] == GL_REDUCE) { + *width = *width - (MAX2(ctx->Separable2D.Width, 1) - 1); + *height = *height - (MAX2(ctx->Separable2D.Height, 1) - 1); + } +}