diff options
Diffstat (limited to 'mesalib/src/mesa')
25 files changed, 364 insertions, 330 deletions
diff --git a/mesalib/src/mesa/drivers/dri/common/dri_util.c b/mesalib/src/mesa/drivers/dri/common/dri_util.c index db7322ec4..53707a80d 100644 --- a/mesalib/src/mesa/drivers/dri/common/dri_util.c +++ b/mesalib/src/mesa/drivers/dri/common/dri_util.c @@ -1,3 +1,27 @@ +/* + * (C) Copyright IBM Corporation 2002, 2004 + * 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 + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, 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 (including the next + * paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS AND/OR THEIR SUPPLIERS 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. + */ + /** * \file dri_util.c * DRI utility functions. diff --git a/mesalib/src/mesa/drivers/dri/common/drirc b/mesalib/src/mesa/drivers/dri/common/drirc index 755174afd..2d9287852 100644 --- a/mesalib/src/mesa/drivers/dri/common/drirc +++ b/mesalib/src/mesa/drivers/dri/common/drirc @@ -1,15 +1,15 @@ <driconf> <device screen="0" driver="i965"> - <application executable="Sanctuary"> + <application name="Unigine Sanctuary" executable="Sanctuary"> <option name="force_glsl_extensions_warn" value="true" /> </application> - <application executable="Tropics"> + <application name="Unigine Tropics" executable="Tropics"> <option name="force_glsl_extensions_warn" value="true" /> </application> - <application executable="heaven_x86"> + <application name="Unigine Heaven (32-bit)" executable="heaven_x86"> <option name="force_glsl_extensions_warn" value="true" /> </application> - <application executable="heaven_x64"> + <application name="Unigine Heaven (64-bit)" executable="heaven_x64"> <option name="force_glsl_extensions_warn" value="true" /> </application> </device> diff --git a/mesalib/src/mesa/main/api_validate.c b/mesalib/src/mesa/main/api_validate.c index 4e94f47e3..02495a15a 100644 --- a/mesalib/src/mesa/main/api_validate.c +++ b/mesalib/src/mesa/main/api_validate.c @@ -29,6 +29,7 @@ #include "imports.h" #include "mfeatures.h" #include "mtypes.h" +#include "enums.h" #include "vbo/vbo.h" @@ -204,18 +205,60 @@ check_index_bounds(struct gl_context *ctx, GLsizei count, GLenum type, * are supported. */ GLboolean -_mesa_valid_prim_mode(const struct gl_context *ctx, GLenum mode) +_mesa_valid_prim_mode(struct gl_context *ctx, GLenum mode, const char *name) { if (ctx->Extensions.ARB_geometry_shader4 && mode > GL_TRIANGLE_STRIP_ADJACENCY_ARB) { + _mesa_error(ctx, GL_INVALID_ENUM, "%s(mode=%x)", name, mode); return GL_FALSE; } else if (mode > GL_POLYGON) { - return GL_FALSE; - } - else { - return GL_TRUE; + _mesa_error(ctx, GL_INVALID_ENUM, "%s(mode=%x)", name, mode); + return GL_FALSE; + } + + /* From the GL_EXT_transform_feedback spec: + * + * "The error INVALID_OPERATION is generated if Begin, or any command + * that performs an explicit Begin, is called when: + * + * * a geometry shader is not active and <mode> does not match the + * allowed begin modes for the current transform feedback state as + * given by table X.1. + * + * * a geometry shader is active and the output primitive type of the + * geometry shader does not match the allowed begin modes for the + * current transform feedback state as given by table X.1. + * + */ + if (ctx->TransformFeedback.CurrentObject->Active && + !ctx->TransformFeedback.CurrentObject->Paused) { + GLboolean pass = GL_TRUE; + + switch (mode) { + case GL_POINTS: + pass = ctx->TransformFeedback.Mode == GL_POINTS; + break; + case GL_LINES: + case GL_LINE_STRIP: + case GL_LINE_LOOP: + pass = ctx->TransformFeedback.Mode == GL_LINES; + break; + default: + pass = ctx->TransformFeedback.Mode == GL_TRIANGLES; + break; + } + if (!pass) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "%s(mode=%s vs transform feedback %s)", + name, + _mesa_lookup_prim_by_nr(mode), + _mesa_lookup_prim_by_nr(ctx->TransformFeedback.Mode)); + return GL_FALSE; + } } + + return GL_TRUE; } @@ -237,8 +280,7 @@ _mesa_validate_DrawElements(struct gl_context *ctx, return GL_FALSE; } - if (!_mesa_valid_prim_mode(ctx, mode)) { - _mesa_error(ctx, GL_INVALID_ENUM, "glDrawElements(mode)" ); + if (!_mesa_valid_prim_mode(ctx, mode, "glDrawElements")) { return GL_FALSE; } @@ -294,8 +336,7 @@ _mesa_validate_DrawRangeElements(struct gl_context *ctx, GLenum mode, return GL_FALSE; } - if (!_mesa_valid_prim_mode(ctx, mode)) { - _mesa_error(ctx, GL_INVALID_ENUM, "glDrawRangeElements(mode)" ); + if (!_mesa_valid_prim_mode(ctx, mode, "glDrawRangeElements")) { return GL_FALSE; } @@ -353,8 +394,7 @@ _mesa_validate_DrawArrays(struct gl_context *ctx, return GL_FALSE; } - if (!_mesa_valid_prim_mode(ctx, mode)) { - _mesa_error(ctx, GL_INVALID_ENUM, "glDrawArrays(mode)" ); + if (!_mesa_valid_prim_mode(ctx, mode, "glDrawArrays")) { return GL_FALSE; } @@ -389,9 +429,7 @@ _mesa_validate_DrawArraysInstanced(struct gl_context *ctx, GLenum mode, GLint fi return GL_FALSE; } - if (!_mesa_valid_prim_mode(ctx, mode)) { - _mesa_error(ctx, GL_INVALID_ENUM, - "glDrawArraysInstanced(mode=0x%x)", mode); + if (!_mesa_valid_prim_mode(ctx, mode, "glDrawArraysInstanced")) { return GL_FALSE; } @@ -429,9 +467,7 @@ _mesa_validate_DrawElementsInstanced(struct gl_context *ctx, return GL_FALSE; } - if (!_mesa_valid_prim_mode(ctx, mode)) { - _mesa_error(ctx, GL_INVALID_ENUM, - "glDrawElementsInstanced(mode = 0x%x)", mode); + if (!_mesa_valid_prim_mode(ctx, mode, "glDrawElementsInstanced")) { return GL_FALSE; } @@ -485,8 +521,7 @@ _mesa_validate_DrawTransformFeedback(struct gl_context *ctx, { ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); - if (!_mesa_valid_prim_mode(ctx, mode)) { - _mesa_error(ctx, GL_INVALID_ENUM, "glDrawTransformFeedback(mode)"); + if (!_mesa_valid_prim_mode(ctx, mode, "glDrawTransformFeedback")) { return GL_FALSE; } diff --git a/mesalib/src/mesa/main/api_validate.h b/mesalib/src/mesa/main/api_validate.h index f4948424c..d92fd433f 100644 --- a/mesalib/src/mesa/main/api_validate.h +++ b/mesalib/src/mesa/main/api_validate.h @@ -43,7 +43,7 @@ _mesa_max_buffer_index(struct gl_context *ctx, GLuint count, GLenum type, extern GLboolean -_mesa_valid_prim_mode(const struct gl_context *ctx, GLenum mode); +_mesa_valid_prim_mode(struct gl_context *ctx, GLenum mode, const char *name); extern GLboolean diff --git a/mesalib/src/mesa/main/dlist.c b/mesalib/src/mesa/main/dlist.c index 420ddcc0c..f113573d8 100644 --- a/mesalib/src/mesa/main/dlist.c +++ b/mesalib/src/mesa/main/dlist.c @@ -5767,10 +5767,16 @@ save_Begin(GLenum mode) Node *n; GLboolean error = GL_FALSE; - if (!_mesa_valid_prim_mode(ctx, mode)) { - _mesa_compile_error(ctx, GL_INVALID_ENUM, "glBegin(mode)"); + if (mode > GL_POLYGON) { + _mesa_error(ctx, GL_INVALID_ENUM, "glBegin(mode=%x)", mode); error = GL_TRUE; } + if (ctx->ExecuteFlag) { + if (!_mesa_valid_prim_mode(ctx, mode, "glBegin")) { + error = GL_TRUE; + } + } + else if (ctx->Driver.CurrentSavePrimitive == PRIM_UNKNOWN) { /* Typically the first begin. This may raise an error on * playback, depending on whether CallList is issued from inside diff --git a/mesalib/src/mesa/main/getstring.c b/mesalib/src/mesa/main/getstring.c index 90e028055..2f445aaf9 100644 --- a/mesalib/src/mesa/main/getstring.c +++ b/mesalib/src/mesa/main/getstring.c @@ -53,6 +53,8 @@ shading_language_version(struct gl_context *ctx) return (const GLubyte *) "1.20"; case 130: return (const GLubyte *) "1.30"; + case 140: + return (const GLubyte *) "1.40"; default: _mesa_problem(ctx, "Invalid GLSL version in shading_language_version()"); diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h index f76096a49..a3827d48d 100644 --- a/mesalib/src/mesa/main/mtypes.h +++ b/mesalib/src/mesa/main/mtypes.h @@ -1316,7 +1316,9 @@ struct gl_texture_object 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? */ + GLboolean _BaseComplete; /**< Is the base texture level valid? */ + GLboolean _MipmapComplete; /**< Is the whole mipmap valid? */ + GLboolean _IsIntegerFormat; /**< Does the texture store integer values? */ GLboolean _RenderToTexture; /**< Any rendering to this texture? */ GLboolean Purgeable; /**< Is the buffer purgeable under memory pressure? */ GLboolean Immutable; /**< GL_ARB_texture_storage */ diff --git a/mesalib/src/mesa/main/samplerobj.c b/mesalib/src/mesa/main/samplerobj.c index 7cf0654ad..5d1b2adbb 100644 --- a/mesalib/src/mesa/main/samplerobj.c +++ b/mesalib/src/mesa/main/samplerobj.c @@ -55,12 +55,11 @@ _mesa_lookup_samplerobj(struct gl_context *ctx, GLuint name) * Handle reference counting. */ void -_mesa_reference_sampler_object(struct gl_context *ctx, - struct gl_sampler_object **ptr, - struct gl_sampler_object *samp) +_mesa_reference_sampler_object_(struct gl_context *ctx, + struct gl_sampler_object **ptr, + struct gl_sampler_object *samp) { - if (*ptr == samp) - return; + assert(*ptr != samp); /* The inline wrapper should prevent no-op calls */ if (*ptr) { /* Unreference the old sampler */ diff --git a/mesalib/src/mesa/main/samplerobj.h b/mesalib/src/mesa/main/samplerobj.h index fe7d5a7d3..0bfda4351 100644 --- a/mesalib/src/mesa/main/samplerobj.h +++ b/mesalib/src/mesa/main/samplerobj.h @@ -37,10 +37,29 @@ _mesa_get_samplerobj(struct gl_context *ctx, GLuint unit) return &ctx->Texture.Unit[unit]._Current->Sampler; } + +/** Does the given filter state do mipmap filtering? */ +static inline GLboolean +_mesa_is_mipmap_filter(const struct gl_sampler_object *samp) +{ + return samp->MinFilter != GL_NEAREST && samp->MinFilter != GL_LINEAR; +} + + extern void +_mesa_reference_sampler_object_(struct gl_context *ctx, + struct gl_sampler_object **ptr, + struct gl_sampler_object *samp); + +static inline void _mesa_reference_sampler_object(struct gl_context *ctx, struct gl_sampler_object **ptr, - struct gl_sampler_object *samp); + struct gl_sampler_object *samp) +{ + if (*ptr != samp) + _mesa_reference_sampler_object_(ctx, ptr, samp); +} + extern void _mesa_init_sampler_object(struct gl_sampler_object *sampObj, GLuint name); diff --git a/mesalib/src/mesa/main/teximage.c b/mesalib/src/mesa/main/teximage.c index cf0a0cb2a..c54118212 100644 --- a/mesalib/src/mesa/main/teximage.c +++ b/mesalib/src/mesa/main/teximage.c @@ -43,6 +43,7 @@ #include "state.h" #include "texcompress.h" #include "teximage.h" +#include "texobj.h" #include "texstate.h" #include "texpal.h" #include "mtypes.h" @@ -2602,9 +2603,7 @@ teximage(struct gl_context *ctx, GLuint dims, _mesa_update_fbo_texture(ctx, texObj, face, level); - /* state update */ - texObj->_Complete = GL_FALSE; - ctx->NewState |= _NEW_TEXTURE; + _mesa_dirty_texobj(ctx, texObj, GL_TRUE); } else { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage%uD", dims); @@ -2702,9 +2701,7 @@ _mesa_EGLImageTargetTexture2DOES (GLenum target, GLeglImageOES image) ctx->Driver.EGLImageTargetTexture2D(ctx, target, texObj, texImage, image); - /* state update */ - texObj->_Complete = GL_FALSE; - ctx->NewState |= _NEW_TEXTURE; + _mesa_dirty_texobj(ctx, texObj, GL_TRUE); } _mesa_unlock_texture(ctx, texObj); @@ -2965,9 +2962,7 @@ copyteximage(struct gl_context *ctx, GLuint dims, _mesa_update_fbo_texture(ctx, texObj, face, level); - /* state update */ - texObj->_Complete = GL_FALSE; - ctx->NewState |= _NEW_TEXTURE; + _mesa_dirty_texobj(ctx, texObj, GL_TRUE); } else { /* probably too large of image */ @@ -3598,9 +3593,7 @@ compressedteximage(struct gl_context *ctx, GLuint dims, check_gen_mipmap(ctx, target, texObj, level); - /* state update */ - texObj->_Complete = GL_FALSE; - ctx->NewState |= _NEW_TEXTURE; + _mesa_dirty_texobj(ctx, texObj, GL_TRUE); } else { _mesa_error(ctx, GL_OUT_OF_MEMORY, diff --git a/mesalib/src/mesa/main/texobj.c b/mesalib/src/mesa/main/texobj.c index 590594826..cfaac64bf 100644 --- a/mesalib/src/mesa/main/texobj.c +++ b/mesalib/src/mesa/main/texobj.c @@ -262,7 +262,8 @@ _mesa_copy_texture_object( struct gl_texture_object *dest, dest->_MaxLevel = src->_MaxLevel; dest->_MaxLambda = src->_MaxLambda; dest->GenerateMipmap = src->GenerateMipmap; - dest->_Complete = src->_Complete; + dest->_BaseComplete = src->_BaseComplete; + dest->_MipmapComplete = src->_MipmapComplete; COPY_4V(dest->Swizzle, src->Swizzle); dest->_Swizzle = src->_Swizzle; @@ -386,14 +387,26 @@ _mesa_reference_texobj_(struct gl_texture_object **ptr, } +enum base_mipmap { BASE, MIPMAP }; + /** - * Mark a texture object as incomplete. + * Mark a texture object as incomplete. There are actually three kinds of + * (in)completeness: + * 1. "base incomplete": the base level of the texture is invalid so no + * texturing is possible. + * 2. "mipmap incomplete": a non-base level of the texture is invalid so + * mipmap filtering isn't possible, but non-mipmap filtering is. + * 3. "texture incompleteness": some combination of texture state and + * sampler state renders the texture incomplete. + * * \param t texture object + * \param bm either BASE or MIPMAP to indicate what's incomplete * \param fmt... string describing why it's incomplete (for debugging). */ static void -incomplete(struct gl_texture_object *t, const char *fmt, ...) +incomplete(struct gl_texture_object *t, enum base_mipmap bm, + const char *fmt, ...) { #if 0 va_list args; @@ -405,7 +418,9 @@ incomplete(struct gl_texture_object *t, const char *fmt, ...) printf("Texture Obj %d incomplete because: %s\n", t->Name, s); #endif - t->_Complete = GL_FALSE; + if (bm == BASE) + t->_BaseComplete = GL_FALSE; + t->_MipmapComplete = GL_FALSE; } @@ -426,79 +441,94 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx, struct gl_texture_object *t ) { const GLint baseLevel = t->BaseLevel; + const struct gl_texture_image *baseImage; GLint maxLog2 = 0, maxLevels = 0; - t->_Complete = GL_TRUE; /* be optimistic */ + /* We'll set these to FALSE if tests fail below */ + t->_BaseComplete = GL_TRUE; + t->_MipmapComplete = GL_TRUE; /* Detect cases where the application set the base level to an invalid * value. */ if ((baseLevel < 0) || (baseLevel >= MAX_TEXTURE_LEVELS)) { - incomplete(t, "base level = %d is invalid", baseLevel); + incomplete(t, BASE, "base level = %d is invalid", baseLevel); + return; + } + + if (t->MaxLevel < baseLevel) { + incomplete(t, BASE, "MAX_LEVEL (%d) < BASE_LEVEL (%d)", + t->MaxLevel, baseLevel); return; } + baseImage = t->Image[0][baseLevel]; + /* Always need the base level image */ - if (!t->Image[0][baseLevel]) { - incomplete(t, "Image[baseLevel=%d] == NULL", baseLevel); + if (!baseImage) { + incomplete(t, BASE, "Image[baseLevel=%d] == NULL", baseLevel); return; } /* Check width/height/depth for zero */ - if (t->Image[0][baseLevel]->Width == 0 || - t->Image[0][baseLevel]->Height == 0 || - t->Image[0][baseLevel]->Depth == 0) { - incomplete(t, "texture width = 0"); + if (baseImage->Width == 0 || + baseImage->Height == 0 || + baseImage->Depth == 0) { + incomplete(t, BASE, "texture width or height or depth = 0"); return; } - /* Compute _MaxLevel */ - if ((t->Target == GL_TEXTURE_1D) || - (t->Target == GL_TEXTURE_1D_ARRAY_EXT)) { - maxLog2 = t->Image[0][baseLevel]->WidthLog2; - maxLevels = ctx->Const.MaxTextureLevels; + /* Check if the texture values are integer */ + { + GLenum datatype = _mesa_get_format_datatype(baseImage->TexFormat); + t->_IsIntegerFormat = datatype == GL_INT || datatype == GL_UNSIGNED_INT; } - else if ((t->Target == GL_TEXTURE_2D) || - (t->Target == GL_TEXTURE_2D_ARRAY_EXT)) { - maxLog2 = MAX2(t->Image[0][baseLevel]->WidthLog2, - t->Image[0][baseLevel]->HeightLog2); + + /* Compute _MaxLevel (the maximum mipmap level we'll sample from given the + * mipmap image sizes and GL_TEXTURE_MAX_LEVEL state). + */ + switch (t->Target) { + case GL_TEXTURE_1D: + case GL_TEXTURE_1D_ARRAY_EXT: + maxLog2 = baseImage->WidthLog2; maxLevels = ctx->Const.MaxTextureLevels; - } - else if (t->Target == GL_TEXTURE_3D) { - GLint max = MAX2(t->Image[0][baseLevel]->WidthLog2, - t->Image[0][baseLevel]->HeightLog2); - maxLog2 = MAX2(max, (GLint)(t->Image[0][baseLevel]->DepthLog2)); + break; + case GL_TEXTURE_2D: + case GL_TEXTURE_2D_ARRAY_EXT: + maxLog2 = MAX2(baseImage->WidthLog2, + baseImage->HeightLog2); + maxLevels = ctx->Const.MaxTextureLevels; + break; + case GL_TEXTURE_3D: + maxLog2 = MAX3(baseImage->WidthLog2, + baseImage->HeightLog2, + baseImage->DepthLog2); maxLevels = ctx->Const.Max3DTextureLevels; - } - else if (t->Target == GL_TEXTURE_CUBE_MAP_ARB) { - maxLog2 = MAX2(t->Image[0][baseLevel]->WidthLog2, - t->Image[0][baseLevel]->HeightLog2); + break; + case GL_TEXTURE_CUBE_MAP_ARB: + maxLog2 = MAX2(baseImage->WidthLog2, + baseImage->HeightLog2); maxLevels = ctx->Const.MaxCubeTextureLevels; - } - else if (t->Target == GL_TEXTURE_RECTANGLE_NV || - t->Target == GL_TEXTURE_EXTERNAL_OES) { + break; + case GL_TEXTURE_RECTANGLE_NV: + case GL_TEXTURE_BUFFER: + case GL_TEXTURE_EXTERNAL_OES: maxLog2 = 0; /* not applicable */ maxLevels = 1; /* no mipmapping */ - } - else { + break; + default: _mesa_problem(ctx, "Bad t->Target in _mesa_test_texobj_completeness"); return; } ASSERT(maxLevels > 0); - if (t->MaxLevel < t->BaseLevel) { - incomplete(t, "MAX_LEVEL (%d) < BASE_LEVEL (%d)", - t->MaxLevel, t->BaseLevel); - return; - } - - t->_MaxLevel = baseLevel + maxLog2; + t->_MaxLevel = baseLevel + maxLog2; /* 'p' in the GL spec */ t->_MaxLevel = MIN2(t->_MaxLevel, t->MaxLevel); - t->_MaxLevel = MIN2(t->_MaxLevel, maxLevels - 1); + t->_MaxLevel = MIN2(t->_MaxLevel, maxLevels - 1); /* 'q' in the GL spec */ /* Compute _MaxLambda = q - b (see the 1.2 spec) used during mipmapping */ - t->_MaxLambda = (GLfloat) (t->_MaxLevel - t->BaseLevel); + t->_MaxLambda = (GLfloat) (t->_MaxLevel - baseLevel); if (t->Immutable) { /* This texture object was created with glTexStorage1/2/3D() so we @@ -510,193 +540,103 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx, } if (t->Target == GL_TEXTURE_CUBE_MAP_ARB) { - /* make sure that all six cube map level 0 images are the same size */ - const GLuint w = t->Image[0][baseLevel]->Width2; - const GLuint h = t->Image[0][baseLevel]->Height2; + /* Make sure that all six cube map level 0 images are the same size. + * Note: we know that the image's width==height (we enforce that + * at glTexImage time) so we only need to test the width here. + */ GLuint face; + assert(baseImage->Width2 == baseImage->Height); for (face = 1; face < 6; face++) { + assert(t->Image[face][baseLevel]->Width2 == + t->Image[face][baseLevel]->Height2); if (t->Image[face][baseLevel] == NULL || - t->Image[face][baseLevel]->Width2 != w || - t->Image[face][baseLevel]->Height2 != h) { - incomplete(t, "Cube face missing or mismatched size"); + t->Image[face][baseLevel]->Width2 != baseImage->Width2) { + incomplete(t, BASE, "Cube face missing or mismatched size"); return; } } } - /* extra checking for mipmaps */ - if (t->Sampler.MinFilter != GL_NEAREST && t->Sampler.MinFilter != GL_LINEAR) { - /* - * Mipmapping: determine if we have a complete set of mipmaps - */ + /* + * Do mipmap consistency checking. + * Note: we don't care about the current texture sampler state here. + * To determine texture completeness we'll either look at _BaseComplete + * or _MipmapComplete depending on the current minification filter mode. + */ + { GLint i; - GLint minLevel = baseLevel; - GLint maxLevel = t->_MaxLevel; + const GLint minLevel = baseLevel; + const GLint maxLevel = t->_MaxLevel; + GLuint width, height, depth, face, numFaces = 1; if (minLevel > maxLevel) { - incomplete(t, "minLevel > maxLevel"); + incomplete(t, BASE, "minLevel > maxLevel"); return; } - /* Test dimension-independent attributes */ - for (i = minLevel; i <= maxLevel; i++) { - if (t->Image[0][i]) { - if (t->Image[0][i]->TexFormat != t->Image[0][baseLevel]->TexFormat) { - incomplete(t, "Format[i] != Format[baseLevel]"); - return; - } - if (t->Image[0][i]->Border != t->Image[0][baseLevel]->Border) { - incomplete(t, "Border[i] != Border[baseLevel]"); - return; - } - } - } + /* Get the base image's dimensions */ + width = baseImage->Width2; + height = baseImage->Height2; + depth = baseImage->Depth2; - /* Test things which depend on number of texture image dimensions */ - if ((t->Target == GL_TEXTURE_1D) || - (t->Target == GL_TEXTURE_1D_ARRAY_EXT)) { - /* Test 1-D mipmaps */ - GLuint width = t->Image[0][baseLevel]->Width2; - for (i = baseLevel + 1; i < maxLevels; i++) { - if (width > 1) { - width /= 2; - } - if (i >= minLevel && i <= maxLevel) { - const struct gl_texture_image *img = t->Image[0][i]; - if (!img) { - incomplete(t, "1D Image[%d] is missing", i); - return; - } - if (img->Width2 != width ) { - incomplete(t, "1D Image[%d] bad width %u", i, img->Width2); - return; - } - } - if (width == 1) { - return; /* found smallest needed mipmap, all done! */ - } + /* Note: this loop will be a no-op for RECT, BUFFER, EXTERNAL textures */ + for (i = baseLevel + 1; i < maxLevels; i++) { + /* Compute the expected size of image at level[i] */ + if (width > 1) { + width /= 2; } - } - else if ((t->Target == GL_TEXTURE_2D) || - (t->Target == GL_TEXTURE_2D_ARRAY_EXT)) { - /* Test 2-D mipmaps */ - GLuint width = t->Image[0][baseLevel]->Width2; - GLuint height = t->Image[0][baseLevel]->Height2; - for (i = baseLevel + 1; i < maxLevels; i++) { - if (width > 1) { - width /= 2; - } - if (height > 1) { - height /= 2; - } + if (height > 1 && t->Target != GL_TEXTURE_1D_ARRAY) { + height /= 2; + } + if (depth > 1 && t->Target != GL_TEXTURE_2D_ARRAY) { + depth /= 2; + } + + /* loop over cube faces (or single face otherwise) */ + for (face = 0; face < numFaces; face++) { if (i >= minLevel && i <= maxLevel) { - const struct gl_texture_image *img = t->Image[0][i]; + const struct gl_texture_image *img = t->Image[face][i]; + if (!img) { - incomplete(t, "2D Image[%d of %d] is missing", i, maxLevel); + incomplete(t, MIPMAP, "TexImage[%d] is missing", i); return; } - if (img->Width2 != width) { - incomplete(t, "2D Image[%d] bad width %u", i, img->Width2); - return; - } - if (img->Height2 != height) { - incomplete(t, "2D Image[i] bad height %u", i, img->Height2); - return; - } - if (width==1 && height==1) { - return; /* found smallest needed mipmap, all done! */ - } - } - } - } - else if (t->Target == GL_TEXTURE_3D) { - /* Test 3-D mipmaps */ - GLuint width = t->Image[0][baseLevel]->Width2; - GLuint height = t->Image[0][baseLevel]->Height2; - GLuint depth = t->Image[0][baseLevel]->Depth2; - for (i = baseLevel + 1; i < maxLevels; i++) { - if (width > 1) { - width /= 2; - } - if (height > 1) { - height /= 2; - } - if (depth > 1) { - depth /= 2; - } - if (i >= minLevel && i <= maxLevel) { - const struct gl_texture_image *img = t->Image[0][i]; - if (!img) { - incomplete(t, "3D Image[%d] is missing", i); + if (img->TexFormat != baseImage->TexFormat) { + incomplete(t, MIPMAP, "Format[i] != Format[baseLevel]"); return; } - if (img->_BaseFormat == GL_DEPTH_COMPONENT) { - incomplete(t, "GL_DEPTH_COMPONENT only works with 1/2D tex"); + if (img->Border != baseImage->Border) { + incomplete(t, MIPMAP, "Border[i] != Border[baseLevel]"); return; } if (img->Width2 != width) { - incomplete(t, "3D Image[%d] bad width %u", i, img->Width2); + incomplete(t, MIPMAP, "TexImage[%d] bad width %u", i, img->Width2); return; } if (img->Height2 != height) { - incomplete(t, "3D Image[%d] bad height %u", i, img->Height2); + incomplete(t, MIPMAP, "TexImage[%d] bad height %u", i, img->Height2); return; } if (img->Depth2 != depth) { - incomplete(t, "3D Image[%d] bad depth %u", i, img->Depth2); + incomplete(t, MIPMAP, "TexImage[%d] bad depth %u", i, img->Depth2); return; } - } - if (width == 1 && height == 1 && depth == 1) { - return; /* found smallest needed mipmap, all done! */ - } - } - } - else if (t->Target == GL_TEXTURE_CUBE_MAP_ARB) { - /* make sure 6 cube faces are consistant */ - GLuint width = t->Image[0][baseLevel]->Width2; - GLuint height = t->Image[0][baseLevel]->Height2; - for (i = baseLevel + 1; i < maxLevels; i++) { - if (width > 1) { - width /= 2; - } - if (height > 1) { - height /= 2; - } - if (i >= minLevel && i <= maxLevel) { - GLuint face; - for (face = 0; face < 6; face++) { - /* check that we have images defined */ - if (!t->Image[face][i]) { - incomplete(t, "CubeMap Image[n][i] == NULL"); - return; - } - /* Don't support GL_DEPTH_COMPONENT for cube maps */ - if (ctx->VersionMajor < 3 && !ctx->Extensions.EXT_gpu_shader4) { - if (t->Image[face][i]->_BaseFormat == GL_DEPTH_COMPONENT) { - incomplete(t, "GL_DEPTH_COMPONENT only works with 1/2D tex"); - return; - } - } - /* check that all six images have same size */ - if (t->Image[face][i]->Width2 != width || - t->Image[face][i]->Height2 != height) { - incomplete(t, "CubeMap Image[n][i] bad size"); + + /* Extra checks for cube textures */ + if (face > 0) { + /* check that cube faces are the same size */ + if (img->Width2 != t->Image[0][i]->Width2 || + img->Height2 != t->Image[0][i]->Height2) { + incomplete(t, MIPMAP, "CubeMap Image[n][i] bad size"); return; } - } - } - if (width == 1 && height == 1) { - return; /* found smallest needed mipmap, all done! */ + } } } - } - else if (t->Target == GL_TEXTURE_RECTANGLE_NV) { - /* XXX special checking? */ - } - else { - /* Target = ??? */ - _mesa_problem(ctx, "Bug in gl_test_texture_object_completeness\n"); + + if (width == 1 && height == 1 && depth == 1) { + return; /* found smallest needed mipmap, all done! */ + } } } } @@ -752,7 +692,8 @@ void _mesa_dirty_texobj(struct gl_context *ctx, struct gl_texture_object *texObj, GLboolean invalidate_state) { - texObj->_Complete = GL_FALSE; + texObj->_BaseComplete = GL_FALSE; + texObj->_MipmapComplete = GL_FALSE; if (invalidate_state) ctx->NewState |= _NEW_TEXTURE; } @@ -875,7 +816,8 @@ _mesa_get_fallback_texture(struct gl_context *ctx, gl_texture_index tex) } _mesa_test_texobj_completeness(ctx, texObj); - assert(texObj->_Complete); + assert(texObj->_BaseComplete); + assert(texObj->_MipmapComplete); ctx->Shared->FallbackTex[tex] = texObj; } diff --git a/mesalib/src/mesa/main/texobj.h b/mesalib/src/mesa/main/texobj.h index 03dfbe304..c020b9013 100644 --- a/mesalib/src/mesa/main/texobj.h +++ b/mesalib/src/mesa/main/texobj.h @@ -35,6 +35,7 @@ #include "compiler.h" #include "glheader.h" #include "mtypes.h" +#include "samplerobj.h" /** @@ -77,6 +78,26 @@ _mesa_reference_texobj(struct gl_texture_object **ptr, } +/** Is the texture "complete" with respect to the given sampler state? */ +static inline GLboolean +_mesa_is_texture_complete(const struct gl_texture_object *texObj, + const struct gl_sampler_object *sampler) +{ + if (texObj->_IsIntegerFormat && + (sampler->MagFilter != GL_NEAREST || + (sampler->MinFilter != GL_NEAREST && + sampler->MinFilter != GL_NEAREST_MIPMAP_NEAREST))) { + /* If the format is integer, only nearest filtering is allowed */ + return GL_FALSE; + } + + if (_mesa_is_mipmap_filter(sampler)) + return texObj->_MipmapComplete; + else + return texObj->_BaseComplete; +} + + extern void _mesa_test_texobj_completeness( const struct gl_context *ctx, struct gl_texture_object *obj ); diff --git a/mesalib/src/mesa/main/texparam.c b/mesalib/src/mesa/main/texparam.c index 9a2ec518f..9abc503e3 100644 --- a/mesalib/src/mesa/main/texparam.c +++ b/mesalib/src/mesa/main/texparam.c @@ -41,6 +41,7 @@ #include "main/mtypes.h" #include "main/state.h" #include "main/texcompress.h" +#include "main/texobj.h" #include "main/texparam.h" #include "main/teximage.h" #include "main/texstate.h" @@ -211,8 +212,7 @@ flush(struct gl_context *ctx) /** * This is called just prior to changing any texture object state which - * can effect texture completeness (texture base level, max level, - * minification filter). + * can effect texture completeness (texture base level, max level). * Any pending rendering will be flushed out, we'll set the _NEW_TEXTURE * state flag and then mark the texture object as 'incomplete' so that any * per-texture derived state gets recomputed. @@ -221,7 +221,7 @@ static inline void incomplete(struct gl_context *ctx, struct gl_texture_object *texObj) { FLUSH_VERTICES(ctx, _NEW_TEXTURE); - texObj->_Complete = GL_FALSE; + _mesa_dirty_texobj(ctx, texObj, GL_TRUE); } @@ -241,7 +241,7 @@ set_tex_parameteri(struct gl_context *ctx, switch (params[0]) { case GL_NEAREST: case GL_LINEAR: - incomplete(ctx, texObj); + flush(ctx); texObj->Sampler.MinFilter = params[0]; return GL_TRUE; case GL_NEAREST_MIPMAP_NEAREST: @@ -250,7 +250,7 @@ set_tex_parameteri(struct gl_context *ctx, case GL_LINEAR_MIPMAP_LINEAR: if (texObj->Target != GL_TEXTURE_RECTANGLE_NV && texObj->Target != GL_TEXTURE_EXTERNAL_OES) { - incomplete(ctx, texObj); + flush(ctx); texObj->Sampler.MinFilter = params[0]; return GL_TRUE; } diff --git a/mesalib/src/mesa/main/texstate.c b/mesalib/src/mesa/main/texstate.c index 187ec9c36..ee778ffd0 100644 --- a/mesalib/src/mesa/main/texstate.c +++ b/mesalib/src/mesa/main/texstate.c @@ -569,10 +569,13 @@ update_texture_state( struct gl_context *ctx ) for (texIndex = 0; texIndex < NUM_TEXTURE_TARGETS; texIndex++) { if (enabledTargets & (1 << texIndex)) { struct gl_texture_object *texObj = texUnit->CurrentTex[texIndex]; - if (!texObj->_Complete) { + struct gl_sampler_object *sampler = texUnit->Sampler ? + texUnit->Sampler : &texObj->Sampler; + + if (!_mesa_is_texture_complete(texObj, sampler)) { _mesa_test_texobj_completeness(ctx, texObj); } - if (texObj->_Complete) { + if (_mesa_is_texture_complete(texObj, sampler)) { texUnit->_ReallyEnabled = 1 << texIndex; _mesa_reference_texobj(&texUnit->_Current, texObj); break; diff --git a/mesalib/src/mesa/main/transformfeedback.c b/mesalib/src/mesa/main/transformfeedback.c index c2114c227..f2c1435d9 100644 --- a/mesalib/src/mesa/main/transformfeedback.c +++ b/mesalib/src/mesa/main/transformfeedback.c @@ -89,33 +89,6 @@ reference_transform_feedback_object(struct gl_transform_feedback_object **ptr, /** - * Check if the given primitive mode (as in glBegin(mode)) is compatible - * with the current transform feedback mode (if it's enabled). - * This is to be called from glBegin(), glDrawArrays(), glDrawElements(), etc. - * - * \return GL_TRUE if the mode is OK, GL_FALSE otherwise. - */ -GLboolean -_mesa_validate_primitive_mode(struct gl_context *ctx, GLenum mode) -{ - if (ctx->TransformFeedback.CurrentObject->Active && - !ctx->TransformFeedback.CurrentObject->Paused) { - switch (mode) { - case GL_POINTS: - return ctx->TransformFeedback.Mode == GL_POINTS; - case GL_LINES: - case GL_LINE_STRIP: - case GL_LINE_LOOP: - return ctx->TransformFeedback.Mode == GL_LINES; - default: - return ctx->TransformFeedback.Mode == GL_TRIANGLES; - } - } - return GL_TRUE; -} - - -/** * Check that all the buffer objects currently bound for transform * feedback actually exist. Raise a GL_INVALID_OPERATION error if * any buffers are missing. diff --git a/mesalib/src/mesa/main/transformfeedback.h b/mesalib/src/mesa/main/transformfeedback.h index 8a6672d58..7d63de017 100644 --- a/mesalib/src/mesa/main/transformfeedback.h +++ b/mesalib/src/mesa/main/transformfeedback.h @@ -42,9 +42,6 @@ _mesa_free_transform_feedback(struct gl_context *ctx); #if FEATURE_EXT_transform_feedback extern GLboolean -_mesa_validate_primitive_mode(struct gl_context *ctx, GLenum mode); - -extern GLboolean _mesa_validate_transform_feedback_buffers(struct gl_context *ctx); diff --git a/mesalib/src/mesa/main/uniform_query.cpp b/mesalib/src/mesa/main/uniform_query.cpp index 869f7d373..991df7896 100644 --- a/mesalib/src/mesa/main/uniform_query.cpp +++ b/mesalib/src/mesa/main/uniform_query.cpp @@ -203,10 +203,18 @@ _mesa_get_uniform(struct gl_context *ctx, GLuint program, GLint location, const union gl_constant_value *const src = &uni->storage[offset * elements]; - unsigned bytes = sizeof(uni->storage[0]) * elements; - if (bytes > (unsigned) bufSize) { - elements = bufSize / sizeof(uni->storage[0]); - bytes = bufSize; + assert(returnType == GLSL_TYPE_FLOAT || returnType == GLSL_TYPE_INT || + returnType == GLSL_TYPE_UINT); + /* The three (currently) supported types all have the same size, + * which is of course the same as their union. That'll change + * with glGetUniformdv()... + */ + unsigned bytes = sizeof(src[0]) * elements; + if (bufSize < 0 || bytes > (unsigned) bufSize) { + _mesa_error( ctx, GL_INVALID_OPERATION, + "glGetnUniform*vARB(out of bounds: bufSize is %d," + " but %u bytes are required)", bufSize, bytes ); + return; } /* If the return type and the uniform's native type are "compatible," diff --git a/mesalib/src/mesa/main/uniforms.c b/mesalib/src/mesa/main/uniforms.c index e0214a88a..be1e1728d 100644 --- a/mesalib/src/mesa/main/uniforms.c +++ b/mesalib/src/mesa/main/uniforms.c @@ -479,7 +479,7 @@ _mesa_GetnUniformdvARB(GLhandleARB program, GLint location, (void) params; /* - _mesa_get_uniform(ctx, program, location, bufSize, GL_DOUBLE, params); + _mesa_get_uniform(ctx, program, location, bufSize, GLSL_TYPE_DOUBLE, params); */ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformdvARB" "(GL_ARB_gpu_shader_fp64 not implemented)"); diff --git a/mesalib/src/mesa/state_tracker/st_cb_texture.c b/mesalib/src/mesa/state_tracker/st_cb_texture.c index ea59ccf25..f9c190a68 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_texture.c +++ b/mesalib/src/mesa/state_tracker/st_cb_texture.c @@ -1243,7 +1243,7 @@ st_finalize_texture(struct gl_context *ctx, enum pipe_format firstImageFormat; GLuint ptWidth, ptHeight, ptDepth, ptLayers; - if (stObj->base._Complete) { + if (_mesa_is_texture_complete(tObj, &tObj->Sampler)) { /* The texture is complete and we know exactly how many mipmap levels * are present/needed. This is conditional because we may be called * from the st_generate_mipmap() function when the texture object is diff --git a/mesalib/src/mesa/state_tracker/st_extensions.c b/mesalib/src/mesa/state_tracker/st_extensions.c index 33bc6ed72..afea0ea4f 100644 --- a/mesalib/src/mesa/state_tracker/st_extensions.c +++ b/mesalib/src/mesa/state_tracker/st_extensions.c @@ -216,6 +216,8 @@ void st_init_limits(struct st_context *st) if (options->EmitNoLoops) options->MaxUnrollIterations = MIN2(screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_INSTRUCTIONS), 65536); + else + options->MaxUnrollIterations = 255; /* SM3 limit */ } /* PIPE_SHADER_CAP_MAX_INPUTS for the FS specifies the maximum number diff --git a/mesalib/src/mesa/state_tracker/st_texture.c b/mesalib/src/mesa/state_tracker/st_texture.c index 132d7a81c..9627a6117 100644 --- a/mesalib/src/mesa/state_tracker/st_texture.c +++ b/mesalib/src/mesa/state_tracker/st_texture.c @@ -222,6 +222,9 @@ st_texture_image_map(struct st_context *st, struct st_texture_image *stImage, DBG("%s \n", __FUNCTION__); + if (!stImage->pt) + return NULL; + if (stObj->pt != stImage->pt) level = 0; else diff --git a/mesalib/src/mesa/swrast/s_context.c b/mesalib/src/mesa/swrast/s_context.c index beb915879..432db71c8 100644 --- a/mesalib/src/mesa/swrast/s_context.c +++ b/mesalib/src/mesa/swrast/s_context.c @@ -30,6 +30,7 @@ #include "main/bufferobj.h" #include "main/colormac.h" #include "main/mtypes.h" +#include "main/samplerobj.h" #include "main/teximage.h" #include "program/prog_parameter.h" #include "program/prog_statevars.h" @@ -482,7 +483,9 @@ _swrast_update_texture_samplers(struct gl_context *ctx) if (tObj) { _mesa_update_fetch_functions(tObj); } - swrast->TextureSample[u] = _swrast_choose_texture_sample_func(ctx, tObj); + swrast->TextureSample[u] = + _swrast_choose_texture_sample_func(ctx, tObj, + _mesa_get_samplerobj(ctx, u)); } } diff --git a/mesalib/src/mesa/swrast/s_texfilter.c b/mesalib/src/mesa/swrast/s_texfilter.c index d142d3d07..412316f36 100644 --- a/mesalib/src/mesa/swrast/s_texfilter.c +++ b/mesalib/src/mesa/swrast/s_texfilter.c @@ -27,6 +27,7 @@ #include "main/context.h" #include "main/colormac.h" #include "main/imports.h" +#include "main/texobj.h" #include "s_context.h" #include "s_texfilter.h" @@ -3612,9 +3613,10 @@ null_sample_func( struct gl_context *ctx, */ texture_sample_func _swrast_choose_texture_sample_func( struct gl_context *ctx, - const struct gl_texture_object *t ) + const struct gl_texture_object *t, + const struct gl_sampler_object *sampler) { - if (!t || !t->_Complete) { + if (!t || !_mesa_is_texture_complete(t, sampler)) { return &null_sample_func; } else { diff --git a/mesalib/src/mesa/swrast/s_texfilter.h b/mesalib/src/mesa/swrast/s_texfilter.h index fd7e5776f..58b57365c 100644 --- a/mesalib/src/mesa/swrast/s_texfilter.h +++ b/mesalib/src/mesa/swrast/s_texfilter.h @@ -1,41 +1,42 @@ -/*
- * Mesa 3-D graphics library
- * Version: 6.5
- *
- * Copyright (C) 1999-2005 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
- * 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.
- */
-
-
-#ifndef S_TEXFILTER_H
-#define S_TEXFILTER_H
-
-
-#include "s_context.h"
-
-struct gl_context;
-struct gl_texture_object;
-
-
-extern texture_sample_func
-_swrast_choose_texture_sample_func( struct gl_context *ctx,
- const struct gl_texture_object *tObj );
-
-
-#endif
+/* + * Mesa 3-D graphics library + * Version: 6.5 + * + * Copyright (C) 1999-2005 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 + * 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. + */ + + +#ifndef S_TEXFILTER_H +#define S_TEXFILTER_H + + +#include "s_context.h" + +struct gl_context; +struct gl_texture_object; + + +extern texture_sample_func +_swrast_choose_texture_sample_func( struct gl_context *ctx, + const struct gl_texture_object *tObj, + const struct gl_sampler_object *sampler); + + +#endif diff --git a/mesalib/src/mesa/vbo/vbo_exec_api.c b/mesalib/src/mesa/vbo/vbo_exec_api.c index cb5f9ae52..306199067 100644 --- a/mesalib/src/mesa/vbo/vbo_exec_api.c +++ b/mesalib/src/mesa/vbo/vbo_exec_api.c @@ -696,8 +696,7 @@ static void GLAPIENTRY vbo_exec_Begin( GLenum mode ) struct vbo_exec_context *exec = &vbo_context(ctx)->exec; int i; - if (!_mesa_valid_prim_mode(ctx, mode)) { - _mesa_error(ctx, GL_INVALID_ENUM, "glBegin"); + if (!_mesa_valid_prim_mode(ctx, mode, "glBegin")) { return; } |