summaryrefslogtreecommitdiff
path: root/src/mesa/swrast
diff options
context:
space:
mode:
authorBrian Paul <brian.paul@tungstengraphics.com>2004-06-02 00:16:42 +0000
committerBrian Paul <brian.paul@tungstengraphics.com>2004-06-02 00:16:42 +0000
commitd203091d204ea2e543cd41ea85d0fc57aa794a4b (patch)
treea2d64d26d4faed3f4f92d772098260be22f7923b /src/mesa/swrast
parenta4436a8f4476344f1ec81cacf35f5693d58dcc06 (diff)
Check for NULL texture object when choosing texture sampler. Fixes segfault when fragment program references an incomplete texture
Diffstat (limited to 'src/mesa/swrast')
-rw-r--r--src/mesa/swrast/s_context.c10
-rw-r--r--src/mesa/swrast/s_texture.c190
2 files changed, 107 insertions, 93 deletions
diff --git a/src/mesa/swrast/s_context.c b/src/mesa/swrast/s_context.c
index 972de03b14..06f0d88abd 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 b2ccb81e85..708da94389 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;
}
}