diff options
author | Brian Paul <[email protected]> | 2004-06-02 00:16:42 +0000 |
---|---|---|
committer | Brian Paul <[email protected]> | 2004-06-02 00:16:42 +0000 |
commit | d203091d204ea2e543cd41ea85d0fc57aa794a4b (patch) | |
tree | a2d64d26d4faed3f4f92d772098260be22f7923b /src/mesa | |
parent | a4436a8f4476344f1ec81cacf35f5693d58dcc06 (diff) |
Check for NULL texture object when choosing texture sampler. Fixes segfault when fragment program references an incomplete texture
Diffstat (limited to 'src/mesa')
-rw-r--r-- | src/mesa/swrast/s_context.c | 10 | ||||
-rw-r--r-- | src/mesa/swrast/s_texture.c | 190 |
2 files changed, 107 insertions, 93 deletions
diff --git a/src/mesa/swrast/s_context.c b/src/mesa/swrast/s_context.c index 972de03b145..06f0d88abd8 100644 --- a/src/mesa/swrast/s_context.c +++ b/src/mesa/swrast/s_context.c @@ -333,6 +333,14 @@ _swrast_validate_blend_func( GLcontext *ctx, GLuint n, } +/** + * Called via the swrast->TextureSample[i] function pointer. + * Basically, given a texture object, an array of texture coords + * and an array of level-of-detail values, return an array of colors. + * In this case, determine the correct texture sampling routine + * (depending on filter mode, texture dimensions, etc) then call the + * sampler routine. + */ static void _swrast_validate_texture_sample( GLcontext *ctx, GLuint texUnit, const struct gl_texture_object *tObj, @@ -344,7 +352,7 @@ _swrast_validate_texture_sample( GLcontext *ctx, GLuint texUnit, _swrast_validate_derived( ctx ); /* Compute min/mag filter threshold */ - if (tObj->MinFilter != tObj->MagFilter) { + if (tObj && tObj->MinFilter != tObj->MagFilter) { if (tObj->MagFilter == GL_LINEAR && (tObj->MinFilter == GL_NEAREST_MIPMAP_NEAREST || tObj->MinFilter == GL_NEAREST_MIPMAP_LINEAR)) { diff --git a/src/mesa/swrast/s_texture.c b/src/mesa/swrast/s_texture.c index b2ccb81e851..708da943897 100644 --- a/src/mesa/swrast/s_texture.c +++ b/src/mesa/swrast/s_texture.c @@ -2656,8 +2656,8 @@ sample_depth_texture2(const GLcontext *ctx, /** * We use this function when a texture object is in an "incomplete" state. * When a fragment program attempts to sample an incomplete texture we - * return black. - * Note: frag progs don't observe texture enable/disable flags. + * return black (see issue 23 in GL_ARB_fragment_program spec). + * Note: fragment programss don't observe the texture enable/disable flags. */ static void null_sample_func( GLcontext *ctx, GLuint texUnit, @@ -2665,16 +2665,21 @@ null_sample_func( GLcontext *ctx, GLuint texUnit, const GLfloat texcoords[][4], const GLfloat lambda[], GLchan rgba[][4]) { + GLuint i; (void) ctx; (void) texUnit; (void) tObj; (void) texcoords; (void) lambda; - _mesa_bzero(rgba, n * 4 * sizeof(GLchan)); + for (i = 0; i < n; i++) { + rgba[i][RCOMP] = 0; + rgba[i][GCOMP] = 0; + rgba[i][BCOMP] = 0; + rgba[i][ACOMP] = CHAN_MAX; + } } - /** * Setup the texture sampling function for this texture object. */ @@ -2682,101 +2687,102 @@ texture_sample_func _swrast_choose_texture_sample_func( GLcontext *ctx, const struct gl_texture_object *t ) { - const GLboolean needLambda = (GLboolean) (t->MinFilter != t->MagFilter); - const GLenum format = t->Image[0][t->BaseLevel]->Format; - - if (!t->Complete) { + if (!t || !t->Complete) { return &null_sample_func; } + else { + const GLboolean needLambda = (GLboolean) (t->MinFilter != t->MagFilter); + const GLenum format = t->Image[0][t->BaseLevel]->Format; - switch (t->Target) { - case GL_TEXTURE_1D: - if (format == GL_DEPTH_COMPONENT) { - return &sample_depth_texture; - } - else if (needLambda) { - return &sample_lambda_1d; - } - else if (t->MinFilter == GL_LINEAR) { - return &sample_linear_1d; - } - else { - ASSERT(t->MinFilter == GL_NEAREST); - return &sample_nearest_1d; - } - break; - case GL_TEXTURE_2D: - if (format == GL_DEPTH_COMPONENT) { - return &sample_depth_texture; - } - else if (needLambda) { - return &sample_lambda_2d; - } - else if (t->MinFilter == GL_LINEAR) { - return &sample_linear_2d; - } - else { - GLint baseLevel = t->BaseLevel; - ASSERT(t->MinFilter == GL_NEAREST); - if (t->WrapS == GL_REPEAT && - t->WrapT == GL_REPEAT && - t->_IsPowerOfTwo && - t->Image[0][baseLevel]->Border == 0 && - t->Image[0][baseLevel]->TexFormat->MesaFormat == MESA_FORMAT_RGB) { - return &opt_sample_rgb_2d; - } - else if (t->WrapS == GL_REPEAT && - t->WrapT == GL_REPEAT && - t->_IsPowerOfTwo && - t->Image[0][baseLevel]->Border == 0 && - t->Image[0][baseLevel]->TexFormat->MesaFormat == MESA_FORMAT_RGBA) { - return &opt_sample_rgba_2d; + switch (t->Target) { + case GL_TEXTURE_1D: + if (format == GL_DEPTH_COMPONENT) { + return &sample_depth_texture; + } + else if (needLambda) { + return &sample_lambda_1d; + } + else if (t->MinFilter == GL_LINEAR) { + return &sample_linear_1d; } else { - return &sample_nearest_2d; + ASSERT(t->MinFilter == GL_NEAREST); + return &sample_nearest_1d; } + break; + case GL_TEXTURE_2D: + if (format == GL_DEPTH_COMPONENT) { + return &sample_depth_texture; + } + else if (needLambda) { + return &sample_lambda_2d; + } + else if (t->MinFilter == GL_LINEAR) { + return &sample_linear_2d; + } + else { + GLint baseLevel = t->BaseLevel; + ASSERT(t->MinFilter == GL_NEAREST); + if (t->WrapS == GL_REPEAT && + t->WrapT == GL_REPEAT && + t->_IsPowerOfTwo && + t->Image[0][baseLevel]->Border == 0 && + t->Image[0][baseLevel]->TexFormat->MesaFormat == MESA_FORMAT_RGB) { + return &opt_sample_rgb_2d; + } + else if (t->WrapS == GL_REPEAT && + t->WrapT == GL_REPEAT && + t->_IsPowerOfTwo && + t->Image[0][baseLevel]->Border == 0 && + t->Image[0][baseLevel]->TexFormat->MesaFormat == MESA_FORMAT_RGBA) { + return &opt_sample_rgba_2d; + } + else { + return &sample_nearest_2d; + } + } + break; + case GL_TEXTURE_3D: + if (needLambda) { + return &sample_lambda_3d; + } + else if (t->MinFilter == GL_LINEAR) { + return &sample_linear_3d; + } + else { + ASSERT(t->MinFilter == GL_NEAREST); + return &sample_nearest_3d; + } + break; + case GL_TEXTURE_CUBE_MAP: + if (needLambda) { + return &sample_lambda_cube; + } + else if (t->MinFilter == GL_LINEAR) { + return &sample_linear_cube; + } + else { + ASSERT(t->MinFilter == GL_NEAREST); + return &sample_nearest_cube; + } + break; + case GL_TEXTURE_RECTANGLE_NV: + if (needLambda) { + return &sample_lambda_rect; + } + else if (t->MinFilter == GL_LINEAR) { + return &sample_linear_rect; + } + else { + ASSERT(t->MinFilter == GL_NEAREST); + return &sample_nearest_rect; + } + break; + default: + _mesa_problem(ctx, + "invalid target in _swrast_choose_texture_sample_func"); + return &null_sample_func; } - break; - case GL_TEXTURE_3D: - if (needLambda) { - return &sample_lambda_3d; - } - else if (t->MinFilter == GL_LINEAR) { - return &sample_linear_3d; - } - else { - ASSERT(t->MinFilter == GL_NEAREST); - return &sample_nearest_3d; - } - break; - case GL_TEXTURE_CUBE_MAP: - if (needLambda) { - return &sample_lambda_cube; - } - else if (t->MinFilter == GL_LINEAR) { - return &sample_linear_cube; - } - else { - ASSERT(t->MinFilter == GL_NEAREST); - return &sample_nearest_cube; - } - break; - case GL_TEXTURE_RECTANGLE_NV: - if (needLambda) { - return &sample_lambda_rect; - } - else if (t->MinFilter == GL_LINEAR) { - return &sample_linear_rect; - } - else { - ASSERT(t->MinFilter == GL_NEAREST); - return &sample_nearest_rect; - } - break; - default: - _mesa_problem(ctx, - "invalid target in _swrast_choose_texture_sample_func"); - return &null_sample_func; } } |