-/* $Id: teximage.c,v 1.22 2000/03/21 00:49:33 brianp Exp $ */
/*
* Mesa 3-D graphics library
*/
-/*
- * Default pixel packing of Mesa's internal texture images:
- */
-static struct gl_pixelstore_attrib DefaultPacking = {
- 1, /* Alignment */
- 0, /* RowLength */
- 0, /* SkipPixels */
- 0, /* SkipRows */
- 0, /* ImageHeight */
- 0, /* SkipImages */
- GL_FALSE, /* SwapBytes */
- GL_FALSE /* LsbFirst */
-};
+#ifdef DEBUG
+static void PrintTexture(const struct gl_texture_image *img)
+{
+ int i, j, c;
+ GLubyte *data = img->Data;
+
+ if (!data) {
+ printf("No texture data\n");
+ return;
+ }
+
+ switch (img->Format) {
+ case GL_ALPHA:
+ case GL_LUMINANCE:
+ case GL_INTENSITY:
+ case GL_COLOR_INDEX:
+ c = 1;
+ break;
+ case GL_LUMINANCE_ALPHA:
+ c = 2;
+ break;
+ case GL_RGB:
+ c = 3;
+ break;
+ case GL_RGBA:
+ c = 4;
+ break;
+ default:
+ gl_problem(NULL, "error in PrintTexture\n");
+ return;
+ }
+
+
+ for (i = 0; i < img->Height; i++) {
+ for (j = 0; j < img->Width; j++) {
+ if (c==1)
+ printf("%02x ", data[0]);
+ else if (c==2)
+ printf("%02x%02x ", data[0], data[1]);
+ else if (c==3)
+ printf("%02x%02x%02x ", data[0], data[1], data[2]);
+ else if (c==4)
+ printf("%02x%02x%02x%02x ", data[0], data[1], data[2], data[3]);
+ data += c;
+ }
+ printf("\n");
+ }
+}
+#endif
* GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, or GL_RGBA.
* Return -1 if invalid enum.
*/
-static GLint
-decode_internal_format( GLint format )
+GLint
+_mesa_base_tex_format( GLint format )
{
switch (format) {
case GL_ALPHA:
* Return new gl_texture_image struct with all fields initialized to zero.
*/
struct gl_texture_image *
-gl_alloc_texture_image( void )
+_mesa_alloc_texture_image( void )
{
return CALLOC_STRUCT(gl_texture_image);
}
/*
- * Return a new gl_texture_image struct with most field initialized.
+ * Initialize most fields of a gl_texture_image struct.
*/
-static struct gl_texture_image *
-new_texture_image( GLsizei width, GLsizei height, GLsizei depth,
- GLint border, GLenum internalFormat )
+static void
+init_texture_image( struct gl_texture_image *img,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLint border, GLenum internalFormat )
{
- struct gl_texture_image *img = CALLOC_STRUCT(gl_texture_image);
- if (!img)
- return NULL;
-
- img->Format = (GLenum) decode_internal_format(internalFormat);
+ ASSERT(img);
+ ASSERT(!img->Data);
+ img->Format = (GLenum) _mesa_base_tex_format(internalFormat);
set_teximage_component_sizes( img );
img->IntFormat = (GLenum) internalFormat;
img->Border = border;
img->Height2 = 1 << img->HeightLog2;
img->Depth2 = 1 << img->DepthLog2;
img->MaxLog2 = MAX2(img->WidthLog2, img->HeightLog2);
-
- return img;
}
void
-gl_free_texture_image( struct gl_texture_image *teximage )
+_mesa_free_texture_image( struct gl_texture_image *teximage )
{
if (teximage->Data) {
FREE( teximage->Data );
/* This will cover the common GL_RGB, GL_RGBA, GL_ALPHA,
* GL_LUMINANCE_ALPHA, etc. texture formats.
*/
- const GLubyte *src = (const GLubyte *) gl_pixel_addr_in_image(
+ const GLubyte *src = (const GLubyte *) _mesa_image_address(
unpacking, pixels, width, height, srcFormat, srcType, 0, 0, 0);
const GLint srcStride = _mesa_image_row_stride(unpacking, width,
srcFormat, srcType);
}
else if (srcFormat == GL_RGBA && internalFormat == GL_RGB) {
/* commonly used by Quake */
- const GLubyte *src = (const GLubyte *) gl_pixel_addr_in_image(
+ const GLubyte *src = (const GLubyte *) _mesa_image_address(
unpacking, pixels, width, height, srcFormat, srcType, 0, 0, 0);
const GLint srcStride = _mesa_image_row_stride(unpacking, width,
srcFormat, srcType);
GLint img, row;
for (img = 0; img < depth; img++) {
for (row = 0; row < height; row++) {
- const GLvoid *source = gl_pixel_addr_in_image(unpacking,
+ const GLvoid *source = _mesa_image_address(unpacking,
pixels, width, height, srcFormat, srcType, img, row, 0);
_mesa_unpack_index_span(ctx, width, dstType, dest,
srcType, source, unpacking, GL_TRUE);
GLint img, row;
for (img = 0; img < depth; img++) {
for (row = 0; row < height; row++) {
- const GLvoid *source = gl_pixel_addr_in_image(unpacking,
+ const GLvoid *source = _mesa_image_address(unpacking,
pixels, width, height, srcFormat, srcType, img, row, 0);
_mesa_unpack_ubyte_color_span(ctx, width, dstFormat, dest,
srcFormat, srcType, source, unpacking, GL_TRUE);
}
/* Border */
- if (border!=0 && border!=1) {
+ if (border != 0 && border != 1) {
if (!isProxy) {
char message[100];
sprintf(message, "glTexImage%dD(border)", dimensions);
}
/* Level */
- if (level<0 || level>=ctx->Const.MaxTextureLevels) {
+ if (level < 0 || level >= ctx->Const.MaxTextureLevels) {
if (!isProxy) {
char message[100];
sprintf(message, "glTexImage%dD(level)", dimensions);
return GL_TRUE;
}
- iformat = decode_internal_format( internalFormat );
+ iformat = _mesa_base_tex_format( internalFormat );
if (iformat < 0) {
if (!isProxy) {
char message[100];
return GL_TRUE;
}
- if (!gl_is_legal_format_and_type( format, type )) {
+ if (!_mesa_is_legal_format_and_type( format, type )) {
/* Yes, generate GL_INVALID_OPERATION, not GL_INVALID_ENUM, if there
* is a type/format mismatch. See 1.2 spec page 94, sec 3.6.4.
*/
}
}
- if (!gl_is_legal_format_and_type(format, type)) {
+ if (!_mesa_is_legal_format_and_type(format, type)) {
char message[100];
sprintf(message, "glTexSubImage%dD(format or type)", dimensions);
gl_error(ctx, GL_INVALID_ENUM, message);
return GL_TRUE;
}
- iformat = decode_internal_format( internalFormat );
+ iformat = _mesa_base_tex_format( internalFormat );
if (iformat < 0) {
char message[100];
sprintf(message, "glCopyTexImage%dD(internalFormat)", dimensions);
if (target==GL_TEXTURE_1D) {
struct gl_texture_unit *texUnit;
- struct gl_texture_image *teximage;
+ struct gl_texture_object *texObj;
+ struct gl_texture_image *texImage;
if (texture_error_check( ctx, target, level, internalFormat,
format, type, 1, width, 1, 1, border )) {
}
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
-
- /* free current texture image, if any */
- if (texUnit->CurrentD[1]->Image[level]) {
- gl_free_texture_image( texUnit->CurrentD[1]->Image[level] );
+ texObj = texUnit->CurrentD[1];
+ texImage = texObj->Image[level];
+
+ if (!texImage) {
+ texImage = _mesa_alloc_texture_image();
+ texObj->Image[level] = texImage;
+ if (!texImage) {
+ gl_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
+ return;
+ }
+ }
+ else if (texImage->Data) {
+ FREE(texImage->Data);
+ texImage->Data = NULL;
}
- teximage = new_texture_image(width, 1, 1, border, internalFormat);
+ /* setup the teximage struct's fields */
+ init_texture_image(texImage, width, 1, 1, border, internalFormat);
- /* make new texture from source image */
+ /* process the texture image */
if (pixels) {
- make_texture_image(ctx, teximage, format, type, pixels, &ctx->Unpack);
+ GLboolean retain = GL_TRUE;
+ GLboolean success = GL_FALSE;
+ if (!ctx->Pixel.MapColorFlag && !ctx->Pixel.ScaleOrBiasRGBA
+ && ctx->Driver.TexImage1D) {
+ /* let device driver try to use raw image */
+ success = (*ctx->Driver.TexImage1D)( ctx, target, level, format,
+ type, pixels, &ctx->Unpack,
+ texObj, texImage, &retain);
+ }
+ if (retain || !success) {
+ /* make internal copy of the texture image */
+ make_texture_image(ctx, texImage, format, type,
+ pixels, &ctx->Unpack);
+ if (!success && ctx->Driver.TexImage1D) {
+ /* let device driver try to use unpacked image */
+ (*ctx->Driver.TexImage1D)( ctx, target, level, texImage->Format,
+ GL_UNSIGNED_BYTE, texImage->Data,
+ &_mesa_native_packing,
+ texObj, texImage, &retain);
+ }
+ }
+ if (!retain && texImage->Data) {
+ FREE(texImage->Data);
+ texImage->Data = NULL;
+ }
}
else {
- make_null_texture(teximage);
+ make_null_texture(texImage);
+ if (ctx->Driver.TexImage1D) {
+ GLboolean retain;
+ (*ctx->Driver.TexImage1D)( ctx, target, level, texImage->Format,
+ GL_UNSIGNED_BYTE, texImage->Data,
+ &_mesa_native_packing,
+ texObj, texImage, &retain);
+ }
}
- /* install new texture image */
- texUnit->CurrentD[1]->Image[level] = teximage;
- gl_put_texobj_on_dirty_list( ctx, texUnit->CurrentD[1] );
+ /* state update */
+ gl_put_texobj_on_dirty_list( ctx, texObj );
ctx->NewState |= NEW_TEXTURING;
-
- /* tell driver about change */
- if (ctx->Driver.TexImage) {
- (*ctx->Driver.TexImage)( ctx, GL_TEXTURE_1D,
- texUnit->CurrentD[1],
- level, internalFormat, teximage );
- }
}
else if (target==GL_PROXY_TEXTURE_1D) {
/* Proxy texture: check for errors and update proxy state */
if (target==GL_TEXTURE_2D) {
struct gl_texture_unit *texUnit;
- struct gl_texture_image *teximage;
+ struct gl_texture_object *texObj;
+ struct gl_texture_image *texImage;
if (texture_error_check( ctx, target, level, internalFormat,
format, type, 2, width, height, 1, border )) {
}
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
-
- /* free current texture image, if any */
- if (texUnit->CurrentD[2]->Image[level]) {
- gl_free_texture_image( texUnit->CurrentD[2]->Image[level] );
+ texObj = texUnit->CurrentD[2];
+ texImage = texObj->Image[level];
+
+ if (!texImage) {
+ texImage = _mesa_alloc_texture_image();
+ texObj->Image[level] = texImage;
+ if (!texImage) {
+ gl_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
+ return;
+ }
+ }
+ else if (texImage->Data) {
+ FREE(texImage->Data);
+ texImage->Data = NULL;
}
- teximage = new_texture_image(width, height, 1, border,internalFormat);
+ /* setup the teximage struct's fields */
+ init_texture_image(texImage, width, height, 1, border, internalFormat);
- /* make new texture from source image */
+ /* process the texture image */
if (pixels) {
- make_texture_image(ctx, teximage, format, type, pixels, &ctx->Unpack);
+ GLboolean retain = GL_TRUE;
+ GLboolean success = GL_FALSE;
+ if (!ctx->Pixel.MapColorFlag && !ctx->Pixel.ScaleOrBiasRGBA
+ && ctx->Driver.TexImage2D) {
+ /* let device driver try to use raw image */
+ success = (*ctx->Driver.TexImage2D)( ctx, target, level, format,
+ type, pixels, &ctx->Unpack,
+ texObj, texImage, &retain);
+ }
+ if (retain || !success) {
+ /* make internal copy of the texture image */
+ make_texture_image(ctx, texImage, format, type,
+ pixels, &ctx->Unpack);
+ if (!success && ctx->Driver.TexImage2D) {
+ /* let device driver try to use unpacked image */
+ (*ctx->Driver.TexImage2D)( ctx, target, level, texImage->Format,
+ GL_UNSIGNED_BYTE, texImage->Data,
+ &_mesa_native_packing,
+ texObj, texImage, &retain);
+ }
+ }
+ if (!retain && texImage->Data) {
+ FREE(texImage->Data);
+ texImage->Data = NULL;
+ }
}
else {
- make_null_texture(teximage);
+ make_null_texture(texImage);
+ if (ctx->Driver.TexImage2D) {
+ GLboolean retain;
+ (*ctx->Driver.TexImage2D)( ctx, target, level, texImage->Format,
+ GL_UNSIGNED_BYTE, texImage->Data,
+ &_mesa_native_packing,
+ texObj, texImage, &retain);
+ }
}
- /* install new texture image */
- texUnit->CurrentD[2]->Image[level] = teximage;
- gl_put_texobj_on_dirty_list( ctx, texUnit->CurrentD[2] );
- ctx->NewState |= NEW_TEXTURING;
-
- /* tell driver about change */
+#define OLD_DD_TEXTURE
+#ifdef OLD_DD_TEXTURE
+ /* XXX this will be removed in the future */
if (ctx->Driver.TexImage) {
- (*ctx->Driver.TexImage)( ctx, GL_TEXTURE_2D,
- texUnit->CurrentD[2],
- level, internalFormat, teximage );
+ (*ctx->Driver.TexImage)( ctx, target, texObj, level, internalFormat,
+ texImage );
}
+#endif
+
+ /* state update */
+ gl_put_texobj_on_dirty_list( ctx, texObj );
+ ctx->NewState |= NEW_TEXTURING;
}
else if (target==GL_PROXY_TEXTURE_2D) {
/* Proxy texture: check for errors and update proxy state */
if (target==GL_TEXTURE_3D_EXT) {
struct gl_texture_unit *texUnit;
- struct gl_texture_image *teximage;
+ struct gl_texture_object *texObj;
+ struct gl_texture_image *texImage;
if (texture_error_check( ctx, target, level, internalFormat,
format, type, 3, width, height, depth,
border )) {
}
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
-
- /* free current texture image, if any */
- if (texUnit->CurrentD[3]->Image[level]) {
- gl_free_texture_image( texUnit->CurrentD[3]->Image[level] );
+ texObj = texUnit->CurrentD[3];
+ texImage = texObj->Image[level];
+
+ if (!texImage) {
+ texImage = _mesa_alloc_texture_image();
+ texObj->Image[level] = texImage;
+ if (!texImage) {
+ gl_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
+ return;
+ }
+ }
+ else if (texImage->Data) {
+ FREE(texImage->Data);
+ texImage->Data = NULL;
}
- teximage = new_texture_image(width, height, depth,
- border, internalFormat);
+ /* setup the teximage struct's fields */
+ init_texture_image(texImage, width, height, depth,
+ border, internalFormat);
- /* make new texture from source image */
+ /* process the texture image */
if (pixels) {
- make_texture_image(ctx, teximage, format, type, pixels, &ctx->Unpack);
+ GLboolean retain = GL_TRUE;
+ GLboolean success = GL_FALSE;
+ if (!ctx->Pixel.MapColorFlag && !ctx->Pixel.ScaleOrBiasRGBA
+ && ctx->Driver.TexImage3D) {
+ /* let device driver try to use raw image */
+ success = (*ctx->Driver.TexImage3D)( ctx, target, level, format,
+ type, pixels, &ctx->Unpack,
+ texObj, texImage, &retain);
+ }
+ if (retain || !success) {
+ /* make internal copy of the texture image */
+ make_texture_image(ctx, texImage, format, type,
+ pixels, &ctx->Unpack);
+ if (!success && ctx->Driver.TexImage3D) {
+ /* let device driver try to use unpacked image */
+ (*ctx->Driver.TexImage3D)( ctx, target, level, texImage->Format,
+ GL_UNSIGNED_BYTE, texImage->Data,
+ &_mesa_native_packing,
+ texObj, texImage, &retain);
+ }
+ }
+ if (!retain && texImage->Data) {
+ FREE(texImage->Data);
+ texImage->Data = NULL;
+ }
}
else {
- make_null_texture(teximage);
+ make_null_texture(texImage);
+ if (ctx->Driver.TexImage3D) {
+ GLboolean retain;
+ (*ctx->Driver.TexImage3D)( ctx, target, level, texImage->Format,
+ GL_UNSIGNED_BYTE, texImage->Data,
+ &_mesa_native_packing,
+ texObj, texImage, &retain);
+ }
}
- /* install new texture image */
- texUnit->CurrentD[3]->Image[level] = teximage;
- gl_put_texobj_on_dirty_list( ctx, texUnit->CurrentD[3] );
+ /* state update */
+ gl_put_texobj_on_dirty_list( ctx, texObj );
ctx->NewState |= NEW_TEXTURING;
-
- /* tell driver about change */
- if (ctx->Driver.TexImage) {
- (*ctx->Driver.TexImage)( ctx, GL_TEXTURE_3D_EXT,
- texUnit->CurrentD[3],
- level, internalFormat, teximage );
- }
}
else if (target==GL_PROXY_TEXTURE_3D_EXT) {
/* Proxy texture: check for errors and update proxy state */
* Fetch a texture image from the device driver.
* Store the results in the given texture object at the given mipmap level.
*/
-static void
-get_teximage_from_driver( GLcontext *ctx, GLenum target, GLint level,
- const struct gl_texture_object *texObj )
+void
+_mesa_get_teximage_from_driver( GLcontext *ctx, GLenum target, GLint level,
+ const struct gl_texture_object *texObj )
{
GLvoid *image;
GLenum imgFormat, imgType;
if (!ctx->Driver.GetTexImage)
return;
- image = (*ctx->Driver.GetTexImage)( ctx, target, level,
+ image = (*ctx->Driver.GetTexImage)( ctx, target, level, texObj,
&imgFormat, &imgType, &freeImage);
if (!image)
return;
assert(destComponents > 0);
numPixels = texImage->Width * texImage->Height * texImage->Depth;
assert(numPixels > 0);
- srcBytesPerTexel = gl_bytes_per_pixel(imgFormat, imgType);
+ srcBytesPerTexel = _mesa_bytes_per_pixel(imgFormat, imgType);
assert(srcBytesPerTexel > 0);
if (!texImage->Data) {
for (img = 0; img < depth; img++) {
for (row = 0; row < height; row++) {
_mesa_unpack_index_span(ctx, width, dstType, destPtr,
- imgType, srcPtr, &DefaultPacking, GL_FALSE);
+ imgType, srcPtr, &_mesa_native_packing, GL_FALSE);
destPtr += destBytesPerRow;
srcPtr += srcBytesPerRow;
}
for (img = 0; img < depth; img++) {
for (row = 0; row < height; row++) {
_mesa_unpack_ubyte_color_span(ctx, width, dstFormat, destPtr,
- imgFormat, imgType, srcPtr, &DefaultPacking, GL_FALSE);
+ imgFormat, imgType, srcPtr, &_mesa_native_packing, GL_FALSE);
destPtr += destBytesPerRow;
srcPtr += srcBytesPerRow;
}
return;
}
- if (gl_sizeof_type(type) <= 0) {
+ if (_mesa_sizeof_type(type) <= 0) {
gl_error( ctx, GL_INVALID_ENUM, "glGetTexImage(type)" );
return;
}
- if (gl_components_in_format(format) <= 0) {
+ if (_mesa_components_in_format(format) <= 0) {
gl_error( ctx, GL_INVALID_ENUM, "glGetTexImage(format)" );
return;
}
if (!texImage->Data) {
/* try to get the texture image from the device driver */
- get_teximage_from_driver(ctx, target, level, texObj);
+ _mesa_get_teximage_from_driver(ctx, target, level, texObj);
discardImage = GL_TRUE;
}
else {
for (row = 0; row < height; row++) {
/* compute destination address in client memory */
- GLvoid *dest = gl_pixel_addr_in_image( &ctx->Unpack, pixels,
+ GLvoid *dest = _mesa_image_address( &ctx->Unpack, pixels,
width, height,
format, type, 0, row, 0);
assert(dest);
if (texImage->Format == GL_RGBA) {
const GLubyte *src = texImage->Data + row * width * 4 * sizeof(GLubyte);
- gl_pack_rgba_span( ctx, width, (CONST GLubyte (*)[4]) src,
- format, type, dest,
- &ctx->Pack, GL_TRUE );
+ _mesa_pack_rgba_span( ctx, width, (CONST GLubyte (*)[4]) src,
+ format, type, dest, &ctx->Pack, GL_TRUE );
}
else {
/* fetch RGBA row from texture image then pack it in client mem */
default:
gl_problem( ctx, "bad format in gl_GetTexImage" );
}
- gl_pack_rgba_span( ctx, width, (const GLubyte (*)[4])rgba,
- format, type, dest, &ctx->Pack, GL_TRUE );
+ _mesa_pack_rgba_span( ctx, width, (const GLubyte (*)[4])rgba,
+ format, type, dest, &ctx->Pack, GL_TRUE );
}
}
const GLvoid *pixels )
{
GET_CURRENT_CONTEXT(ctx);
- struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
- struct gl_texture_image *destTex;
+ struct gl_texture_unit *texUnit;
+ struct gl_texture_object *texObj;
+ struct gl_texture_image *texImage;
+ GLboolean success = GL_FALSE;
if (subtexture_error_check(ctx, 1, target, level, xoffset, 0, 0,
width, 1, 1, format, type)) {
return; /* error was detected */
}
- destTex = texUnit->CurrentD[1]->Image[level];
- assert(destTex);
+ texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texObj = texUnit->CurrentD[1];
+ texImage = texObj->Image[level];
+ assert(texImage);
if (width == 0 || !pixels)
return; /* no-op, not an error */
- /*
- * Replace the texture subimage
- */
- {
- const GLint texComponents = components_in_intformat(destTex->Format);
- const GLenum texFormat = destTex->Format;
- const GLint xoffsetb = xoffset + destTex->Border;
- GLubyte *dst = destTex->Data + xoffsetb * texComponents;
+ if (!ctx->Pixel.MapColorFlag && !ctx->Pixel.ScaleOrBiasRGBA
+ && ctx->Driver.TexSubImage1D) {
+ success = (*ctx->Driver.TexSubImage1D)( ctx, target, level, xoffset,
+ width, format, type, pixels,
+ &ctx->Unpack, texObj, texImage );
+ }
+ if (!success) {
+ /* XXX if Driver.TexSubImage1D, unpack image and try again? */
+
+ const GLint texComponents = components_in_intformat(texImage->Format);
+ const GLenum texFormat = texImage->Format;
+ const GLint xoffsetb = xoffset + texImage->Border;
+ GLboolean retain = GL_TRUE;
+ if (!texImage->Data) {
+ _mesa_get_teximage_from_driver( ctx, target, level, texObj );
+ if (!texImage->Data) {
+ make_null_texture(texImage);
+ }
+ if (!texImage->Data)
+ return; /* we're really out of luck! */
+ }
+
if (texFormat == GL_COLOR_INDEX) {
/* color index texture */
- const GLvoid *src = gl_pixel_addr_in_image(&ctx->Unpack, pixels,
- width, 1, format, type, 0, 0, 0);
+ GLubyte *dst = texImage->Data + xoffsetb * texComponents;
+ const GLvoid *src = _mesa_image_address(&ctx->Unpack, pixels, width,
+ 1, format, type, 0, 0, 0);
_mesa_unpack_index_span(ctx, width, GL_UNSIGNED_BYTE, dst,
- type, src, &ctx->Unpack, GL_TRUE);
+ type, src, &ctx->Unpack, GL_TRUE);
}
else {
/* color texture */
- const GLvoid *src = gl_pixel_addr_in_image(&ctx->Unpack, pixels,
- width, 1, format, type, 0, 0, 0);
- _mesa_unpack_ubyte_color_span(ctx, width, texFormat, dst,
- format, type, src, &ctx->Unpack, GL_TRUE);
+ GLubyte *dst = texImage->Data + xoffsetb * texComponents;
+ const GLvoid *src = _mesa_image_address(&ctx->Unpack, pixels, width,
+ 1, format, type, 0, 0, 0);
+ _mesa_unpack_ubyte_color_span(ctx, width, texFormat, dst, format,
+ type, src, &ctx->Unpack, GL_TRUE);
}
- }
- gl_put_texobj_on_dirty_list( ctx, texUnit->CurrentD[1] );
+ if (ctx->Driver.TexImage1D) {
+ (*ctx->Driver.TexImage1D)( ctx, target, level, texImage->Format,
+ GL_UNSIGNED_BYTE, texImage->Data,
+ &_mesa_native_packing, texObj, texImage,
+ &retain );
+ }
- /*
- * Inform device driver of texture image change.
- */
- if (ctx->Driver.TexSubImage) {
- (*ctx->Driver.TexSubImage)(ctx, GL_TEXTURE_1D, texUnit->CurrentD[1],
- level, xoffset, 0, width, 1,
- texUnit->CurrentD[1]->Image[level]->IntFormat,
- destTex );
- }
- else {
- if (ctx->Driver.TexImage) {
- (*ctx->Driver.TexImage)(ctx, GL_TEXTURE_1D, texUnit->CurrentD[1],
- level,
- texUnit->CurrentD[1]->Image[level]->IntFormat,
- destTex );
+ if (!retain && texImage->Data) {
+ FREE(texImage->Data);
+ texImage->Data = NULL;
}
}
+
+ /*gl_put_texobj_on_dirty_list( ctx, texUnit->CurrentD[1] );*/
}
const GLvoid *pixels )
{
GET_CURRENT_CONTEXT(ctx);
- struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
- struct gl_texture_image *destTex;
+ struct gl_texture_unit *texUnit;
+ struct gl_texture_object *texObj;
+ struct gl_texture_image *texImage;
+ GLboolean success = GL_FALSE;
if (subtexture_error_check(ctx, 2, target, level, xoffset, yoffset, 0,
width, height, 1, format, type)) {
return; /* error was detected */
}
- destTex = texUnit->CurrentD[2]->Image[level];
- assert(destTex);
+ texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texObj = texUnit->CurrentD[2];
+ texImage = texObj->Image[level];
+ assert(texImage);
if (width == 0 || height == 0 || !pixels)
return; /* no-op, not an error */
+ if (!ctx->Pixel.MapColorFlag && !ctx->Pixel.ScaleOrBiasRGBA
+ && ctx->Driver.TexSubImage2D) {
+ success = (*ctx->Driver.TexSubImage2D)( ctx, target, level, xoffset,
+ yoffset, width, height, format, type,
+ pixels, &ctx->Unpack, texObj, texImage );
+ }
+ if (!success) {
+ /* XXX if Driver.TexSubImage2D, unpack image and try again? */
+
+ const GLint texComponents = components_in_intformat(texImage->Format);
+ const GLenum texFormat = texImage->Format;
+ const GLint xoffsetb = xoffset + texImage->Border;
+ const GLint yoffsetb = yoffset + texImage->Border;
+ const GLint srcStride = _mesa_image_row_stride(&ctx->Unpack, width,
+ format, type);
+ const GLint dstStride = texImage->Width * texComponents *sizeof(GLubyte);
+ GLboolean retain = GL_TRUE;
+
+ if (!texImage->Data) {
+ _mesa_get_teximage_from_driver( ctx, target, level, texObj );
+ if (!texImage->Data) {
+ make_null_texture(texImage);
+ }
+ if (!texImage->Data)
+ return; /* we're really out of luck! */
+ }
- /*
- * Replace the texture subimage
- */
- {
- const GLint texComponents = components_in_intformat(destTex->Format);
- const GLenum texFormat = destTex->Format;
- const GLint xoffsetb = xoffset + destTex->Border;
- const GLint yoffsetb = yoffset + destTex->Border;
- GLubyte *dst = destTex->Data
- + (yoffsetb * destTex->Width + xoffsetb) * texComponents;
if (texFormat == GL_COLOR_INDEX) {
/* color index texture */
- const GLint stride = destTex->Width * sizeof(GLubyte);
+ GLubyte *dst = texImage->Data
+ + (yoffsetb * texImage->Width + xoffsetb) * texComponents;
+ const GLubyte *src = _mesa_image_address(&ctx->Unpack, pixels,
+ width, height, format, type, 0, 0, 0);
GLint row;
for (row = 0; row < height; row++) {
- const GLvoid *src = gl_pixel_addr_in_image(&ctx->Unpack, pixels,
- width, height, format, type, 0, row, 0);
- _mesa_unpack_index_span(ctx, width, GL_UNSIGNED_BYTE, dst,
- type, src, &ctx->Unpack, GL_TRUE);
- dst += stride;
+ _mesa_unpack_index_span(ctx, width, GL_UNSIGNED_BYTE, dst, type,
+ (const GLvoid *) src, &ctx->Unpack, GL_TRUE);
+ src += srcStride;
+ dst += dstStride;
}
}
else {
/* color texture */
- const GLint stride = destTex->Width * texComponents * sizeof(GLubyte);
+ GLubyte *dst = texImage->Data
+ + (yoffsetb * texImage->Width + xoffsetb) * texComponents;
+ const GLubyte *src = _mesa_image_address(&ctx->Unpack, pixels,
+ width, height, format, type, 0, 0, 0);
GLint row;
for (row = 0; row < height; row++) {
- const GLvoid *src = gl_pixel_addr_in_image(&ctx->Unpack, pixels,
- width, height, format, type, 0, row, 0);
- _mesa_unpack_ubyte_color_span(ctx, width, texFormat, dst,
- format, type, src, &ctx->Unpack, GL_TRUE);
- dst += stride;
+ _mesa_unpack_ubyte_color_span(ctx, width, texFormat, dst, format,
+ type, (const GLvoid *) src, &ctx->Unpack, GL_TRUE);
+ src += srcStride;
+ dst += dstStride;
}
}
- }
- gl_put_texobj_on_dirty_list( ctx, texUnit->CurrentD[2] );
+ if (ctx->Driver.TexImage2D) {
+ (*ctx->Driver.TexImage2D)(ctx, target, level, texImage->Format,
+ GL_UNSIGNED_BYTE, texImage->Data,
+ &_mesa_native_packing, texObj, texImage,
+ &retain);
+ }
- /*
- * Inform device driver of texture image change.
- */
- if (ctx->Driver.TexSubImage) {
- (*ctx->Driver.TexSubImage)(ctx, GL_TEXTURE_2D, texUnit->CurrentD[2],
- level, xoffset, yoffset, width, height,
- texUnit->CurrentD[2]->Image[level]->IntFormat,
- destTex );
- }
- else {
- if (ctx->Driver.TexImage) {
- (*ctx->Driver.TexImage)(ctx, GL_TEXTURE_2D, texUnit->CurrentD[2],
- level,
- texUnit->CurrentD[2]->Image[level]->IntFormat,
- destTex );
+ if (!retain && texImage->Data) {
+ FREE(texImage->Data);
+ texImage->Data = NULL;
+ }
+
+#ifdef OLD_DD_TEXTURE
+ /* XXX this will be removed in the future */
+ if (ctx->Driver.TexSubImage) {
+ (*ctx->Driver.TexSubImage)(ctx, target, texObj, level,
+ xoffset, yoffset, width, height,
+ texImage->IntFormat, texImage);
}
+ else if (ctx->Driver.TexImage) {
+ (*ctx->Driver.TexImage)(ctx, GL_TEXTURE_2D, texObj,
+ level, texImage->IntFormat, texImage );
+ }
+#endif
}
}
const GLvoid *pixels )
{
GET_CURRENT_CONTEXT(ctx);
- struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
- struct gl_texture_image *destTex;
+ struct gl_texture_unit *texUnit;
+ struct gl_texture_object *texObj;
+ struct gl_texture_image *texImage;
+ GLboolean success = GL_FALSE;
if (subtexture_error_check(ctx, 3, target, level, xoffset, yoffset, zoffset,
width, height, depth, format, type)) {
return; /* error was detected */
}
- destTex = texUnit->CurrentD[3]->Image[level];
- assert(destTex);
+ texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texObj = texUnit->CurrentD[3];
+ texImage = texObj->Image[level];
+ assert(texImage);
if (width == 0 || height == 0 || height == 0 || !pixels)
return; /* no-op, not an error */
- /*
- * Replace the texture subimage
- */
- {
- const GLint texComponents = components_in_intformat(destTex->Format);
- const GLenum texFormat = destTex->Format;
- const GLint xoffsetb = xoffset + destTex->Border;
- const GLint yoffsetb = yoffset + destTex->Border;
- const GLint zoffsetb = zoffset + destTex->Border;
- GLint dstRectArea = destTex->Width * destTex->Height;
- GLubyte *dst = destTex->Data
- + (zoffsetb * dstRectArea + yoffsetb * destTex->Width + xoffsetb)
- * texComponents;
+ if (!ctx->Pixel.MapColorFlag && !ctx->Pixel.ScaleOrBiasRGBA
+ && ctx->Driver.TexSubImage3D) {
+ success = (*ctx->Driver.TexSubImage3D)( ctx, target, level, xoffset,
+ yoffset, zoffset, width, height, depth, format,
+ type, pixels, &ctx->Unpack, texObj, texImage );
+ }
+ if (!success) {
+ /* XXX if Driver.TexSubImage3D, unpack image and try again? */
+
+ const GLint texComponents = components_in_intformat(texImage->Format);
+ const GLenum texFormat = texImage->Format;
+ const GLint xoffsetb = xoffset + texImage->Border;
+ const GLint yoffsetb = yoffset + texImage->Border;
+ const GLint zoffsetb = zoffset + texImage->Border;
+ const GLint texWidth = texImage->Width;
+ const GLint dstRectArea = texWidth * texImage->Height;
+ const GLint srcStride = _mesa_image_row_stride(&ctx->Unpack,
+ width, format, type);
+ const GLint dstStride = texWidth * texComponents * sizeof(GLubyte);
+ GLboolean retain = GL_TRUE;
if (texFormat == GL_COLOR_INDEX) {
/* color index texture */
- const GLint stride = destTex->Width * sizeof(GLubyte);
GLint img, row;
for (img = 0; img < depth; img++) {
+ const GLubyte *src = _mesa_image_address(&ctx->Unpack, pixels,
+ width, height, format, type, img, 0, 0);
+ GLubyte *dst = texImage->Data + ((zoffsetb + img) * dstRectArea
+ + yoffsetb * texWidth + xoffsetb) * texComponents;
for (row = 0; row < height; row++) {
- const GLvoid *src = gl_pixel_addr_in_image(&ctx->Unpack, pixels,
- width, height, format, type, img, row, 0);
_mesa_unpack_index_span(ctx, width, GL_UNSIGNED_BYTE, dst,
- type, src, &ctx->Unpack, GL_TRUE);
- dst += stride;
+ type, (const GLvoid *) src, &ctx->Unpack, GL_TRUE);
+ src += srcStride;
+ dst += dstStride;
}
}
}
else {
/* color texture */
- const GLint stride = destTex->Width * texComponents * sizeof(GLubyte);
GLint img, row;
for (img = 0; img < depth; img++) {
+ const GLubyte *src = _mesa_image_address(&ctx->Unpack, pixels,
+ width, height, format, type, img, 0, 0);
+ GLubyte *dst = texImage->Data + ((zoffsetb + img) * dstRectArea
+ + yoffsetb * texWidth + xoffsetb) * texComponents;
for (row = 0; row < height; row++) {
- const GLvoid *src = gl_pixel_addr_in_image(&ctx->Unpack, pixels,
- width, height, format, type, img, row, 0);
_mesa_unpack_ubyte_color_span(ctx, width, texFormat, dst,
- format, type, src, &ctx->Unpack, GL_TRUE);
- dst += stride;
+ format, type, (const GLvoid *) src, &ctx->Unpack, GL_TRUE);
+ src += srcStride;
+ dst += dstStride;
}
}
}
- }
- gl_put_texobj_on_dirty_list( ctx, texUnit->CurrentD[1] );
+ if (ctx->Driver.TexImage3D) {
+ (*ctx->Driver.TexImage3D)(ctx, target, level, texImage->Format,
+ GL_UNSIGNED_BYTE, texImage->Data,
+ &_mesa_native_packing, texObj, texImage,
+ &retain);
+ }
- /*
- * Inform device driver of texture image change.
- */
- /* XXX todo */
+ if (!retain && texImage->Data) {
+ FREE(texImage->Data);
+ texImage->Data = NULL;
+ }
+ }
}
GLint srcx, GLint srcy,
GLint dstx, GLint dsty, GLint dstz )
{
- static struct gl_pixelstore_attrib packing = {
- 1, /* Alignment */
- 0, /* RowLength */
- 0, /* SkipPixels */
- 0, /* SkipRows */
- 0, /* ImageHeight */
- 0, /* SkipImages */
- GL_FALSE, /* SwapBytes */
- GL_FALSE /* LsbFirst */
- };
-
GLint i;
GLint format, components, rectarea;
GLint texwidth, texheight, zoffset;
dst = dest->Data + ( zoffset + (dsty+i) * texwidth + dstx) * components;
_mesa_unpack_ubyte_color_span(ctx, width, format, dst,
GL_RGBA, GL_UNSIGNED_BYTE, rgba,
- &packing, GL_TRUE);
+ &_mesa_native_packing, GL_TRUE);
}
/* Read from draw buffer (the default) */
if (teximage->Data) {
copy_tex_sub_image(ctx, teximage, width, 1, x, y, xoffset, 0, 0);
/* tell driver about the change */
+ /* XXX this is obsolete */
if (ctx->Driver.TexImage) {
(*ctx->Driver.TexImage)( ctx, GL_TEXTURE_1D,
texUnit->CurrentD[1],
copy_tex_sub_image(ctx, teximage, width, height,
x, y, xoffset, yoffset, 0);
/* tell driver about the change */
+ /* XXX this is obsolete */
if (ctx->Driver.TexImage) {
(*ctx->Driver.TexImage)( ctx, GL_TEXTURE_2D,
texUnit->CurrentD[2],
xoffset, yoffset, zoffset, width, height))
return;
- if (ctx->Pixel.MapColorFlag || ctx->Pixel.ScaleOrBiasRGBA
+ if (ctx->Pixel.MapColorFlag || ctx->Pixel.ScaleOrBiasRGBA
|| !ctx->Driver.CopyTexSubImage3D
|| !(*ctx->Driver.CopyTexSubImage3D)(ctx, target, level,
- xoffset, yoffset, zoffset, x, y, width, height )) {
- struct gl_texture_unit *texUnit;
- struct gl_texture_image *teximage;
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
- teximage = texUnit->CurrentD[3]->Image[level];
- assert(teximage);
- if (teximage->Data) {
- copy_tex_sub_image(ctx, teximage, width, height,
+ xoffset, yoffset, zoffset, x, y, width, height )) {
+ struct gl_texture_unit *texUnit;
+ struct gl_texture_image *teximage;
+ texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ teximage = texUnit->CurrentD[3]->Image[level];
+ assert(teximage);
+ if (teximage->Data) {
+ copy_tex_sub_image(ctx, teximage, width, height,
x, y, xoffset, yoffset, zoffset);
- /* tell driver about the change */
- if (ctx->Driver.TexImage) {
- (*ctx->Driver.TexImage)( ctx, GL_TEXTURE_3D,
- texUnit->CurrentD[3],
- level, teximage->IntFormat, teximage );
+ /* tell driver about the change */
+ /* XXX this is obsolete */
+ if (ctx->Driver.TexImage) {
+ (*ctx->Driver.TexImage)( ctx, GL_TEXTURE_3D,
+ texUnit->CurrentD[3],
+ level, teximage->IntFormat, teximage );
}
}
}