diff options
Diffstat (limited to 'src/mesa')
-rw-r--r-- | src/mesa/drivers/glide/fxddtex.c | 108 |
1 files changed, 100 insertions, 8 deletions
diff --git a/src/mesa/drivers/glide/fxddtex.c b/src/mesa/drivers/glide/fxddtex.c index 5e47644e2e..99af41df5d 100644 --- a/src/mesa/drivers/glide/fxddtex.c +++ b/src/mesa/drivers/glide/fxddtex.c @@ -1025,6 +1025,40 @@ PrintTexture(int w, int h, int c, const GLubyte * data) } +static const struct gl_texture_format * +choose_format(GLenum format, GLenum type) +{ + if (type == CHAN_TYPE) { + switch (format) { + case GL_ALPHA: + return &_mesa_texformat_alpha; + case GL_LUMINANCE: + return &_mesa_texformat_luminance; + case GL_LUMINANCE_ALPHA: + return &_mesa_texformat_luminance_alpha; + case GL_INTENSITY: + return &_mesa_texformat_intensity; + case GL_RGB: + return &_mesa_texformat_rgb; + case GL_RGBA: + return &_mesa_texformat_rgba; + case GL_COLOR_INDEX: + return &_mesa_texformat_color_index; + default: + _mesa_problem(NULL, "Unexpected CHAN format in choose_format\n"); + return NULL; + } + } + else if (format == GL_DEPTH_COMPONENT && type == GL_FLOAT) { + return &_mesa_texformat_depth_component; + } + else { + _mesa_problem(NULL, "Unexpected format/type in choose_format\n"); + return NULL; + } +} + + void fxDDTexImage2D(GLcontext * ctx, GLenum target, GLint level, GLint internalFormat, GLint width, GLint height, GLint border, @@ -1170,9 +1204,11 @@ fxDDTexImage2D(GLcontext * ctx, GLenum target, GLint level, fxTexInvalidate(ctx, texObj); /* store the texture image */ - /* XXX check for image rescale */ - if (ctx->_ImageTransferState) { - success = GL_FALSE; /* Can't do image transfer ops here */ + if (ctx->_ImageTransferState || + mml->width != width || + mml->height != height) { + /* Need to image transfer ops or image rescale */ + success = GL_FALSE; } else { success = _mesa_convert_texsubimage2d(mesaTexFormat->IntFormat, @@ -1207,8 +1243,31 @@ fxDDTexImage2D(GLcontext * ctx, GLenum target, GLint level, 0, /* dstImageStride */ format, type, pixels, packing /* src info */ ); - /* this conversion better work! */ - success = _mesa_convert_texsubimage2d(mesaTexFormat->IntFormat, + if (mml->width != width || mml->height != height) { + /* Upscale image to accomodate Glide's image aspect limitations. */ + const struct gl_texture_format *texFormat + = choose_format(simpleFormat, CHAN_TYPE); + GLvoid *rescaledImage = MALLOC(mml->width * mml->height + * texFormat->TexelBytes); + if (!rescaledImage) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); + return; + } + _mesa_rescale_teximage2d(texFormat, + width, height, mml->width, mml->height, + tempImage, rescaledImage); + success = _mesa_convert_texsubimage2d(mesaTexFormat->IntFormat, + 0, 0, /* xoffset, yoffset */ + mml->width, mml->height, + mml->width, /* destImageWidth */ + simpleFormat, /* source format */ + CHAN_TYPE, /* source type */ + &_mesa_native_packing, + rescaledImage, texImage->Data); + FREE(rescaledImage); + } + else { + success = _mesa_convert_texsubimage2d(mesaTexFormat->IntFormat, 0, 0, /* xoffset, yoffset */ mml->width, mml->height, mml->width, /* destImageWidth */ @@ -1216,6 +1275,8 @@ fxDDTexImage2D(GLcontext * ctx, GLenum target, GLint level, CHAN_TYPE, /* source type */ &_mesa_native_packing, tempImage, texImage->Data); + } + /* the conversion had better of worked! */ assert(success); FREE(tempImage); } @@ -1259,7 +1320,9 @@ fxDDTexSubImage2D(GLcontext * ctx, GLenum target, GLint level, assert(texImage->Format); /* XXX check for image rescale */ - if (ctx->_ImageTransferState) { + if (ctx->_ImageTransferState || + texImage->Width != mml->width || + texImage->Height != mml->height) { success = GL_FALSE; } else { @@ -1296,14 +1359,43 @@ fxDDTexSubImage2D(GLcontext * ctx, GLenum target, GLint level, 0, /* dstImageStride */ format, type, pixels, packing /* src info */ ); - /* this conversion better work! */ - success = _mesa_convert_texsubimage2d(texImage->TexFormat->IntFormat, + if (texImage->Width != mml->width || texImage->Height != mml->height) { + /* Upscale image to accomodate Glide's image aspect limitations. */ + const GLint wScale = mml->width / texImage->Width; + const GLint hScale = mml->height / texImage->Height; + const GLint newWidth = width * wScale; + const GLint newHeight = height *hScale; + GLvoid *rescaledImage = MALLOC(newWidth * newHeight + * texImage->TexFormat->TexelBytes); + assert(mml->width >= texImage->Width); + assert(mml->height >= texImage->Height); + if (!rescaledImage) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D"); + return; + } + _mesa_rescale_teximage2d(texImage->TexFormat, + width, height, newWidth, newHeight, + tempImage, rescaledImage); + success = _mesa_convert_texsubimage2d(texImage->TexFormat->IntFormat, + xoffset * wScale, yoffset * hScale, + newWidth, newHeight, + mml->width, /* destImageWidth */ + simpleFormat, /* source format */ + CHAN_TYPE, /* source type */ + &_mesa_native_packing, + rescaledImage, texImage->Data); + FREE(rescaledImage); + } + else { + success = _mesa_convert_texsubimage2d(texImage->TexFormat->IntFormat, xoffset, yoffset, width, height, mml->width, simpleFormat, CHAN_TYPE, &_mesa_native_packing, tempImage, texImage->Data); + } + /* the conversion had better of worked! */ assert(success); FREE(tempImage); } |