-/* $Id: teximage.c,v 1.13 1999/11/24 18:48:31 brianp Exp $ */
+/* $Id: teximage.c,v 1.21 2000/03/20 23:40:12 brianp Exp $ */
/*
* Mesa 3-D graphics library
* Version: 3.3
*
- * Copyright (C) 1999 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2000 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"),
*/
+/*
+ * 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 */
+};
+
+
/*
* Compute log base 2 of n.
-struct gl_texture_image *
-gl_alloc_texture_image( void )
-{
- return CALLOC_STRUCT(gl_texture_image);
-}
-
-
-
-void
-gl_free_texture_image( struct gl_texture_image *teximage )
-{
- if (teximage->Data) {
- FREE( teximage->Data );
- teximage->Data = NULL;
- }
- FREE( teximage );
-}
-
-
-
/*
* Examine the texImage->Format field and set the Red, Green, Blue, etc
* texel component sizes to default values.
}
+
+/*
+ * Return new gl_texture_image struct with all fields initialized to zero.
+ */
+struct gl_texture_image *
+gl_alloc_texture_image( void )
+{
+ return CALLOC_STRUCT(gl_texture_image);
+}
+
+
+
+/*
+ * Return a new gl_texture_image struct with most field initialized.
+ */
+static struct gl_texture_image *
+new_texture_image( 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);
+ set_teximage_component_sizes( img );
+ img->IntFormat = (GLenum) internalFormat;
+ img->Border = border;
+ img->Width = width;
+ img->Height = height;
+ img->Depth = depth;
+ img->WidthLog2 = logbase2(width - 2 * border);
+ if (height == 1) /* 1-D texture */
+ img->HeightLog2 = 0;
+ else
+ img->HeightLog2 = logbase2(height - 2 * border);
+ if (depth == 1) /* 2-D texture */
+ img->DepthLog2 = 0;
+ else
+ img->DepthLog2 = logbase2(depth - 2 * border);
+ img->Width2 = 1 << img->WidthLog2;
+ 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 )
+{
+ if (teximage->Data) {
+ FREE( teximage->Data );
+ teximage->Data = NULL;
+ }
+ FREE( teximage );
+}
+
+
+
/* Need this to prevent an out-of-bounds memory access when using
* X86 optimized code.
*/
/*
* Allocate and initialize the texture_image struct
*/
- texImage = gl_alloc_texture_image();
+ texImage = new_texture_image(width, height, depth, border, internalFormat);
if (!texImage)
return NULL;
- texImage->Format = (GLenum) decode_internal_format(internalFormat);
- set_teximage_component_sizes( texImage );
- texImage->IntFormat = (GLenum) internalFormat;
- texImage->Border = border;
- texImage->Width = width;
- texImage->Height = height;
- texImage->Depth = depth;
- texImage->WidthLog2 = logbase2(width - 2 * border);
- if (height == 1) /* 1-D texture */
- texImage->HeightLog2 = 0;
- else
- texImage->HeightLog2 = logbase2(height - 2 * border);
- if (depth == 1) /* 2-D texture */
- texImage->DepthLog2 = 0;
- else
- texImage->DepthLog2 = logbase2(depth - 2 * border);
- texImage->Width2 = 1 << texImage->WidthLog2;
- texImage->Height2 = 1 << texImage->HeightLog2;
- texImage->Depth2 = 1 << texImage->DepthLog2;
- texImage->MaxLog2 = MAX2(texImage->WidthLog2, texImage->HeightLog2);
-
components = components_in_intformat(internalFormat);
numPixels = texImage->Width * texImage->Height * texImage->Depth;
/* This will cover the common GL_RGB, GL_RGBA, GL_ALPHA,
* GL_LUMINANCE_ALPHA, etc. texture formats.
*/
- const GLubyte *src = gl_pixel_addr_in_image(unpacking,
+ const GLubyte *src = (const GLubyte *) gl_pixel_addr_in_image(unpacking,
pixels, width, height, srcFormat, srcType, 0, 0, 0);
- const GLubyte *src1 = gl_pixel_addr_in_image(unpacking,
+ const GLubyte *src1 = (const GLubyte *) gl_pixel_addr_in_image(unpacking,
pixels, width, height, srcFormat, srcType, 0, 1, 0);
const GLint srcStride = src1 - src;
GLubyte *dst = texImage->Data;
}
else if (srcFormat == GL_RGBA && internalFormat == GL_RGB) {
/* commonly used by Quake */
- const GLubyte *src = gl_pixel_addr_in_image(unpacking,
+ const GLubyte *src = (const GLubyte *) gl_pixel_addr_in_image(unpacking,
pixels, width, height, srcFormat, srcType, 0, 0, 0);
- const GLubyte *src1 = gl_pixel_addr_in_image(unpacking,
+ const GLubyte *src1 = (const GLubyte *) gl_pixel_addr_in_image(unpacking,
pixels, width, height, srcFormat, srcType, 0, 1, 0);
const GLint srcStride = src1 - src;
GLubyte *dst = texImage->Data;
components = components_in_intformat(internalFormat);
numPixels = width * height * depth;
- texImage = gl_alloc_texture_image();
- if (!texImage)
- return NULL;
-
- texImage->Format = (GLenum) decode_internal_format(internalFormat);
- set_teximage_component_sizes( texImage );
- texImage->IntFormat = internalFormat;
- texImage->Border = border;
- texImage->Width = width;
- texImage->Height = height;
- texImage->Depth = depth;
- texImage->WidthLog2 = logbase2(width - 2*border);
- if (height==1) /* 1-D texture */
- texImage->HeightLog2 = 0;
- else
- texImage->HeightLog2 = logbase2(height - 2*border);
- if (depth==1) /* 2-D texture */
- texImage->DepthLog2 = 0;
- else
- texImage->DepthLog2 = logbase2(depth - 2*border);
- texImage->Width2 = 1 << texImage->WidthLog2;
- texImage->Height2 = 1 << texImage->HeightLog2;
- texImage->Depth2 = 1 << texImage->DepthLog2;
- texImage->MaxLog2 = MAX2( texImage->WidthLog2, texImage->HeightLog2 );
-
- /* XXX should we really allocate memory for the image or let it be NULL? */
- /*texImage->Data = NULL;*/
+ texImage = new_texture_image(width, height, depth, border, internalFormat);
+ /* It's easier later if we really do have a texture image, rather than
+ * a NULL image pointer.
+ */
texImage->Data = (GLubyte *) MALLOC( numPixels * components + EXTRA_BYTE );
/*
* interesting instead of leaving it indeterminate.
*/
if (texImage->Data) {
- char message[8][32] = {
+ static const char message[8][32] = {
" X X XXXXX XXX X ",
" XX XX X X X X X ",
" X X X X X X X ",
return GL_TRUE;
}
- teximage = texUnit->CurrentD[3]->Image[level];
+ teximage = texUnit->CurrentD[dimensions]->Image[level];
if (!teximage) {
char message[100];
sprintf(message, "glCopyTexSubImage%dD(undefined texture)", dimensions);
GLenum type, const GLvoid *pixels )
{
GET_CURRENT_CONTEXT(ctx);
- struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glTexImage1D");
if (target==GL_TEXTURE_1D) {
+ struct gl_texture_unit *texUnit;
struct gl_texture_image *teximage;
+
if (texture_error_check( ctx, target, level, internalformat,
format, type, 1, width, 1, 1, border )) {
- /* error in texture image was detected */
- return;
+ return; /* error in texture image was detected */
}
+ 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] );
const GLvoid *pixels )
{
GET_CURRENT_CONTEXT(ctx);
- struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glTexImage2D");
if (target==GL_TEXTURE_2D) {
+ struct gl_texture_unit *texUnit;
struct gl_texture_image *teximage;
+
if (texture_error_check( ctx, target, level, internalformat,
format, type, 2, width, height, 1, border )) {
- /* error in texture image was detected */
- return;
+ return; /* error in texture image was detected */
}
+ 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] );
const GLvoid *pixels )
{
GET_CURRENT_CONTEXT(ctx);
- struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
- ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glTexImage3DEXT");
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glTexImage3D");
if (target==GL_TEXTURE_3D_EXT) {
+ struct gl_texture_unit *texUnit;
struct gl_texture_image *teximage;
if (texture_error_check( ctx, target, level, internalformat,
format, type, 3, width, height, depth,
border )) {
- /* error in texture image was detected */
- return;
+ return; /* error in texture image was detected */
}
+ 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] );
}
+void
+_mesa_TexImage3DEXT( GLenum target, GLint level, GLenum internalformat,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLint border, GLenum format, GLenum type,
+ const GLvoid *pixels )
+{
+ _mesa_TexImage3D(target, level, (GLint) internalformat, width, height,
+ depth, border, format, type, pixels);
+}
+
+
+/*
+ * 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 )
+{
+ GLvoid *image;
+ GLenum imgFormat, imgType;
+ GLboolean freeImage;
+ struct gl_texture_image *texImage;
+ GLint destComponents, numPixels, srcBytesPerTexel;
+
+ if (!ctx->Driver.GetTexImage)
+ return;
+
+ image = (*ctx->Driver.GetTexImage)( ctx, target, level,
+ &imgFormat, &imgType, &freeImage);
+ if (!image)
+ return;
+
+ texImage = texObj->Image[level];
+ ASSERT(texImage);
+ if (!texImage)
+ return;
+
+ destComponents = components_in_intformat(texImage->Format);
+ assert(destComponents > 0);
+ numPixels = texImage->Width * texImage->Height * texImage->Depth;
+ assert(numPixels > 0);
+ srcBytesPerTexel = gl_bytes_per_pixel(imgFormat, imgType);
+ assert(srcBytesPerTexel > 0);
+
+ if (!texImage->Data) {
+ /* Allocate memory for the texture image data */
+ texImage->Data = (GLubyte *) MALLOC(numPixels * destComponents + EXTRA_BYTE);
+ }
+
+ if (imgFormat == texImage->Format && imgType == GL_UNSIGNED_BYTE) {
+ /* We got lucky! The driver's format and type match Mesa's format. */
+ if (texImage->Data) {
+ MEMCPY(texImage->Data, image, numPixels * destComponents);
+ }
+ }
+ else {
+ /* Convert the texture image from the driver's format to Mesa's
+ * internal format.
+ */
+ const GLint width = texImage->Width;
+ const GLint height = texImage->Height;
+ const GLint depth = texImage->Depth;
+ const GLint destBytesPerRow = width * destComponents * sizeof(GLchan);
+ const GLint srcBytesPerRow = width * srcBytesPerTexel;
+ const GLenum dstType = GL_UNSIGNED_BYTE;
+ const GLenum dstFormat = texImage->Format;
+ const GLubyte *srcPtr = (const GLubyte *) image;
+ GLubyte *destPtr = texImage->Data;
+
+ if (texImage->Format == GL_COLOR_INDEX) {
+ /* color index texture */
+ GLint img, row;
+ assert(imgFormat == GL_COLOR_INDEX);
+ 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);
+ destPtr += destBytesPerRow;
+ srcPtr += srcBytesPerRow;
+ }
+ }
+ }
+ else {
+ /* color texture */
+ GLint img, row;
+ 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);
+ destPtr += destBytesPerRow;
+ srcPtr += srcBytesPerRow;
+ }
+ }
+ }
+ }
+
+ if (freeImage)
+ FREE(image);
+}
+
void
_mesa_GetTexImage( GLenum target, GLint level, GLenum format,
{
GET_CURRENT_CONTEXT(ctx);
const struct gl_texture_object *texObj;
+ struct gl_texture_image *texImage;
+ GLboolean discardImage;
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetTexImage");
}
if (!pixels)
- return; /* XXX generate an error??? */
+ return;
switch (target) {
case GL_TEXTURE_1D:
return;
}
- if (texObj->Image[level] && texObj->Image[level]->Data) {
- const struct gl_texture_image *texImage = texObj->Image[level];
+ texImage = texObj->Image[level];
+ if (!texImage) {
+ /* invalid mipmap level */
+ return;
+ }
+
+ if (!texImage->Data) {
+ /* try to get the texture image from the device driver */
+ get_teximage_from_driver(ctx, target, level, texObj);
+ discardImage = GL_TRUE;
+ }
+ else {
+ discardImage = GL_FALSE;
+ }
+
+ if (texImage->Data) {
GLint width = texImage->Width;
GLint height = texImage->Height;
GLint row;
assert(dest);
if (texImage->Format == GL_RGBA) {
const GLubyte *src = texImage->Data + row * width * 4 * sizeof(GLubyte);
- gl_pack_rgba_span( ctx, width, (void *) src, format, type, dest,
+ gl_pack_rgba_span( ctx, width, (CONST GLubyte (*)[4]) src,
+ format, type, dest,
&ctx->Pack, GL_TRUE );
}
else {
format, type, dest, &ctx->Pack, GL_TRUE );
}
}
+
+ /* if we got the teximage from the device driver we'll discard it now */
+ if (discardImage) {
+ FREE(texImage->Data);
+ texImage->Data = NULL;
+ }
}
}
if (subtexture_error_check(ctx, 1, target, level, xoffset, 0, 0,
width, 1, 1, format, type)) {
- /* error was detected */
- return;
+ return; /* error was detected */
}
destTex = texUnit->CurrentD[1]->Image[level];
if (subtexture_error_check(ctx, 2, target, level, xoffset, yoffset, 0,
width, height, 1, format, type)) {
- /* error was detected */
- return;
+ return; /* error was detected */
}
destTex = texUnit->CurrentD[2]->Image[level];
if (subtexture_error_check(ctx, 3, target, level, xoffset, yoffset, zoffset,
width, height, depth, format, type)) {
- /* error was detected */
- return;
+ return; /* error was detected */
}
destTex = texUnit->CurrentD[3]->Image[level];
GLint stride, i;
GLubyte *image, *dst;
- image = MALLOC(width * height * 4 * sizeof(GLubyte));
+ image = (GLubyte *) MALLOC(width * height * 4 * sizeof(GLubyte));
if (!image)
return NULL;
/* Select buffer to read from */
- (void) (*ctx->Driver.SetBuffer)( ctx, ctx->Pixel.DriverReadBuffer );
+ (*ctx->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer,
+ ctx->Pixel.DriverReadBuffer );
dst = image;
stride = width * 4 * sizeof(GLubyte);
dst += stride;
}
- /* Restore drawing buffer */
- (void) (*ctx->Driver.SetBuffer)( ctx, ctx->Color.DriverDrawBuffer );
+ /* Read from draw buffer (the default) */
+ (*ctx->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer,
+ ctx->Color.DriverDrawBuffer );
return image;
}
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glCopyTexImage1D");
- if (!copytexture_error_check(ctx, 1, target, level, internalFormat,
- width, 1, border)) {
+ if (copytexture_error_check(ctx, 1, target, level, internalFormat,
+ width, 1, border))
+ return;
+
+ if (ctx->Pixel.MapColorFlag || ctx->Pixel.ScaleOrBiasRGBA
+ || !ctx->Driver.CopyTexImage1D
+ || !(*ctx->Driver.CopyTexImage1D)(ctx, target, level,
+ internalFormat, x, y, width, border))
+ {
GLubyte *image = read_color_image( ctx, x, y, width, 1 );
if (!image) {
gl_error( ctx, GL_OUT_OF_MEMORY, "glCopyTexImage1D" );
return;
}
- (*ctx->Exec.TexImage1D)( target, level, internalFormat, width,
- border, GL_RGBA, GL_UNSIGNED_BYTE, image );
+ (*ctx->Exec->TexImage1D)( target, level, internalFormat, width,
+ border, GL_RGBA, GL_UNSIGNED_BYTE, image );
FREE(image);
}
}
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glCopyTexImage2D");
- if (!copytexture_error_check(ctx, 2, target, level, internalFormat,
- width, height, border)) {
+ if (copytexture_error_check(ctx, 2, target, level, internalFormat,
+ width, height, border))
+ return;
+
+ if (ctx->Pixel.MapColorFlag || ctx->Pixel.ScaleOrBiasRGBA
+ || !ctx->Driver.CopyTexImage2D
+ || !(*ctx->Driver.CopyTexImage2D)(ctx, target, level,
+ internalFormat, x, y, width, height, border))
+ {
GLubyte *image = read_color_image( ctx, x, y, width, height );
if (!image) {
gl_error( ctx, GL_OUT_OF_MEMORY, "glCopyTexImage2D" );
return;
}
- (ctx->Exec.TexImage2D)( target, level, internalFormat, width,
- height, border, GL_RGBA, GL_UNSIGNED_BYTE, image );
+ (ctx->Exec->TexImage2D)( target, level, internalFormat, width,
+ height, border, GL_RGBA, GL_UNSIGNED_BYTE, image );
FREE(image);
}
}
components = components_in_intformat( format );
/* Select buffer to read from */
- (void) (*ctx->Driver.SetBuffer)( ctx, ctx->Pixel.DriverReadBuffer );
+ (*ctx->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer,
+ ctx->Pixel.DriverReadBuffer );
for (i = 0;i < height; i++) {
GLubyte rgba[MAX_WIDTH][4];
&packing, GL_TRUE);
}
- /* Restore drawing buffer */
- (void) (*ctx->Driver.SetBuffer)( ctx, ctx->Color.DriverDrawBuffer );
+ /* Read from draw buffer (the default) */
+ (*ctx->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer,
+ ctx->Color.DriverDrawBuffer );
}
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glCopyTexSubImage1D");
- if (!copytexsubimage_error_check(ctx, 1, target, level,
- xoffset, 0, 0, width, 1)) {
+ if (copytexsubimage_error_check(ctx, 1, target, level,
+ xoffset, 0, 0, width, 1))
+ return;
+
+ if (ctx->Pixel.MapColorFlag || ctx->Pixel.ScaleOrBiasRGBA
+ || !ctx->Driver.CopyTexSubImage1D
+ || !(*ctx->Driver.CopyTexSubImage1D)(ctx, target, level,
+ xoffset, x, y, width)) {
struct gl_texture_unit *texUnit;
struct gl_texture_image *teximage;
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
assert(teximage);
if (teximage->Data) {
copy_tex_sub_image(ctx, teximage, width, 1, x, y, xoffset, 0, 0);
- /* tell driver about the change */
- if (ctx->Driver.TexImage) {
- (*ctx->Driver.TexImage)( ctx, GL_TEXTURE_1D,
- texUnit->CurrentD[1],
- level, teximage->IntFormat, teximage );
- }
+ /* tell driver about the change */
+ if (ctx->Driver.TexImage) {
+ (*ctx->Driver.TexImage)( ctx, GL_TEXTURE_1D,
+ texUnit->CurrentD[1],
+ level, teximage->IntFormat, teximage );
+ }
}
}
}
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glCopyTexSubImage2D");
- if (!copytexsubimage_error_check(ctx, 2, target, level,
- xoffset, yoffset, 0, width, height)) {
+ if (copytexsubimage_error_check(ctx, 2, target, level,
+ xoffset, yoffset, 0, width, height))
+ return;
+
+ if (ctx->Pixel.MapColorFlag || ctx->Pixel.ScaleOrBiasRGBA
+ || !ctx->Driver.CopyTexSubImage2D
+ || !(*ctx->Driver.CopyTexSubImage2D)(ctx, target, level,
+ xoffset, yoffset, x, y, width, height )) {
struct gl_texture_unit *texUnit;
struct gl_texture_image *teximage;
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
if (teximage->Data) {
copy_tex_sub_image(ctx, teximage, width, height,
x, y, xoffset, yoffset, 0);
- /* tell driver about the change */
- if (ctx->Driver.TexImage) {
- (*ctx->Driver.TexImage)( ctx, GL_TEXTURE_2D,
- texUnit->CurrentD[2],
- level, teximage->IntFormat, teximage );
+ /* tell driver about the change */
+ if (ctx->Driver.TexImage) {
+ (*ctx->Driver.TexImage)( ctx, GL_TEXTURE_2D,
+ texUnit->CurrentD[2],
+ level, teximage->IntFormat, teximage );
}
}
}
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glCopyTexSubImage3D");
- if (!copytexsubimage_error_check(ctx, 3, target, level,
- xoffset, yoffset, zoffset, 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,
+ if (copytexsubimage_error_check(ctx, 3, target, level,
+ xoffset, yoffset, zoffset, width, height))
+ return;
+
+ 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,
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 */
+ if (ctx->Driver.TexImage) {
+ (*ctx->Driver.TexImage)( ctx, GL_TEXTURE_3D,
+ texUnit->CurrentD[3],
+ level, teximage->IntFormat, teximage );
+ }
}
}
}
-