-/* $Id: teximage.c,v 1.10 1999/11/05 06:43:11 brianp Exp $ */
+/* $Id: teximage.c,v 1.21 2000/03/20 23:40:12 brianp Exp $ */
/*
* Mesa 3-D graphics library
- * Version: 3.1
+ * 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"),
#ifdef PC_HEADER
#include "all.h"
#else
-#ifndef XFree86Server
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#else
-#include "GL/xf86glx.h"
-#endif
+#include "glheader.h"
#include "context.h"
#include "image.h"
-#include "macros.h"
+#include "mem.h"
#include "mmath.h"
#include "span.h"
#include "teximage.h"
#include "texstate.h"
#include "types.h"
-#ifdef XFree86Server
-#include "GL/xf86glx.h"
-#endif
#endif
*/
-
-static struct gl_pixelstore_attrib defaultPacking = {
- 1, /* Alignment */
- 0, /* RowLength */
- 0, /* SkipPixels */
- 0, /* SkipRows */
- 0, /* ImageHeight */
- 0, /* SkipImages */
- GL_FALSE, /* SwapBytes */
- GL_FALSE /* LsbFirst */
+/*
+ * 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 */
};
* If n isn't an exact power of two return -1.
* If n<0 return -1.
*/
-static int logbase2( int n )
+static int
+logbase2( int n )
{
GLint i = 1;
GLint log2 = 0;
* GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, or GL_RGBA.
* Return -1 if invalid enum.
*/
-static GLint decode_internal_format( GLint format )
+static GLint
+decode_internal_format( GLint format )
{
switch (format) {
case GL_ALPHA:
* GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, or GL_RGBA. Return the
* number of components for the format. Return -1 if invalid enum.
*/
-static GLint components_in_intformat( GLint format )
+static GLint
+components_in_intformat( GLint format )
{
switch (format) {
case GL_ALPHA:
-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.
* These fields are set only here by core Mesa but device drivers may
* overwritting these fields to indicate true texel resolution.
*/
-static void set_teximage_component_sizes( struct gl_texture_image *texImage )
+static void
+set_teximage_component_sizes( struct gl_texture_image *texImage )
{
switch (texImage->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 )
+{
+ 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 = an error was detected, GL_FALSE = no errors
*/
static GLboolean
-subtexture_error_check( GLcontext *ctx, GLint dimensions,
+subtexture_error_check( GLcontext *ctx, GLuint dimensions,
GLenum target, GLint level,
GLint xoffset, GLint yoffset, GLint zoffset,
GLint width, GLint height, GLint depth,
* Return: GL_TRUE = an error was detected, GL_FALSE = no errors
*/
static GLboolean
-copytexture_error_check( GLcontext *ctx, GLint dimensions,
+copytexture_error_check( GLcontext *ctx, GLuint dimensions,
GLenum target, GLint level, GLint internalFormat,
GLint width, GLint height, GLint border )
{
static GLboolean
-copytexsubimage_error_check( GLcontext *ctx, GLint dimensions,
+copytexsubimage_error_check( GLcontext *ctx, GLuint dimensions,
GLenum target, GLint level,
GLint xoffset, GLint yoffset, GLint zoffset,
GLsizei width, GLsizei height )
/*
* Called from the API. Note that width includes the border.
*/
-void gl_TexImage1D( GLcontext *ctx, GLenum target, GLint level,
- GLint internalformat,
- GLsizei width, GLint border, GLenum format,
- GLenum type, const GLvoid *pixels )
+void
+_mesa_TexImage1D( GLenum target, GLint level, GLint internalformat,
+ GLsizei width, GLint border, GLenum format,
+ GLenum type, const GLvoid *pixels )
{
- struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ GET_CURRENT_CONTEXT(ctx);
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] );
}
-void gl_TexImage2D( GLcontext *ctx, GLenum target, GLint level,
- GLint internalformat,
- GLsizei width, GLsizei height, GLint border,
- GLenum format, GLenum type,
- const GLvoid *pixels )
+void
+_mesa_TexImage2D( GLenum target, GLint level, GLint internalformat,
+ GLsizei width, GLsizei height, GLint border,
+ GLenum format, GLenum type,
+ const GLvoid *pixels )
{
- struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ GET_CURRENT_CONTEXT(ctx);
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] );
* Called by the API or display list executor.
* Note that width and height include the border.
*/
-void gl_TexImage3D( GLcontext *ctx, GLenum target, GLint level,
- GLint internalformat,
- GLsizei width, GLsizei height, GLsizei depth,
- GLint border, GLenum format, GLenum type,
- const GLvoid *pixels )
+void
+_mesa_TexImage3D( GLenum target, GLint level, GLint internalformat,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLint border, GLenum format, GLenum type,
+ const GLvoid *pixels )
{
- struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glTexImage3D");
- if (target==GL_TEXTURE_3D) {
+ 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);
+}
+
-void gl_GetTexImage( GLcontext *ctx, GLenum target, GLint level, GLenum format,
- GLenum type, GLvoid *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,
+ GLenum type, GLvoid *pixels )
+{
+ 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;
+ }
}
}
-void gl_TexSubImage1D( GLcontext *ctx, GLenum target, GLint level,
- GLint xoffset, GLsizei width,
- GLenum format, GLenum type,
- const GLvoid *pixels )
+void
+_mesa_TexSubImage1D( GLenum target, GLint level,
+ GLint xoffset, GLsizei width,
+ GLenum format, GLenum type,
+ const GLvoid *pixels )
{
+ GET_CURRENT_CONTEXT(ctx);
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
struct gl_texture_image *destTex;
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];
}
-void gl_TexSubImage2D( GLcontext *ctx, GLenum target, GLint level,
- GLint xoffset, GLint yoffset,
- GLsizei width, GLsizei height,
- GLenum format, GLenum type,
- const GLvoid *pixels )
+void
+_mesa_TexSubImage2D( GLenum target, GLint level,
+ GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height,
+ GLenum format, GLenum type,
+ const GLvoid *pixels )
{
+ GET_CURRENT_CONTEXT(ctx);
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
struct gl_texture_image *destTex;
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];
-void gl_TexSubImage3D( GLcontext *ctx, GLenum target, GLint level,
- GLint xoffset, GLint yoffset, GLint zoffset,
- GLsizei width, GLsizei height, GLsizei depth,
- GLenum format, GLenum type,
- const GLvoid *pixels )
+void
+_mesa_TexSubImage3D( GLenum target, GLint level,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLenum format, GLenum type,
+ const GLvoid *pixels )
{
+ GET_CURRENT_CONTEXT(ctx);
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
struct gl_texture_image *destTex;
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);
for (i = 0; i < height; i++) {
- gl_read_rgba_span( ctx, width, x, y + i, (GLubyte (*)[4]) dst );
+ gl_read_rgba_span( ctx, ctx->ReadBuffer, width, x, y + i,
+ (GLubyte (*)[4]) dst );
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;
}
-void gl_CopyTexImage1D( GLcontext *ctx, GLenum target, GLint level,
- GLenum internalFormat,
- GLint x, GLint y,
- GLsizei width, GLint border )
+void
+_mesa_CopyTexImage1D( GLenum target, GLint level,
+ GLenum internalFormat,
+ GLint x, GLint y,
+ GLsizei width, GLint border )
{
+ 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)( ctx, 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);
}
}
-void gl_CopyTexImage2D( GLcontext *ctx, GLenum target, GLint level,
- GLenum internalFormat,
- GLint x, GLint y, GLsizei width, GLsizei height,
- GLint border )
+void
+_mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat,
+ GLint x, GLint y, GLsizei width, GLsizei height,
+ GLint border )
{
+ 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;
}
- {
- struct gl_pixelstore_attrib save = ctx->Unpack;
- ctx->Unpack = defaultPacking;
- (ctx->Exec.TexImage2D)( ctx, target, level, internalFormat, width,
- height, border, GL_RGBA, GL_UNSIGNED_BYTE, image );
- ctx->Unpack = save; /* restore */
- }
+ (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];
GLubyte *dst;
- gl_read_rgba_span( ctx, width, srcx, srcy + i, rgba );
+ gl_read_rgba_span( ctx, ctx->ReadBuffer, width, srcx, srcy + i, rgba );
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);
}
- /* 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 );
}
-void gl_CopyTexSubImage1D( GLcontext *ctx, GLenum target, GLint level,
- GLint xoffset, GLint x, GLint y, GLsizei width )
+void
+_mesa_CopyTexSubImage1D( GLenum target, GLint level,
+ GLint xoffset, GLint x, GLint y, GLsizei width )
{
+ 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 );
+ }
}
}
}
-void gl_CopyTexSubImage2D( GLcontext *ctx, GLenum target, GLint level,
- GLint xoffset, GLint yoffset,
- GLint x, GLint y, GLsizei width, GLsizei height )
+void
+_mesa_CopyTexSubImage2D( GLenum target, GLint level,
+ GLint xoffset, GLint yoffset,
+ GLint x, GLint y, GLsizei width, GLsizei height )
{
+ 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 );
}
}
}
-void gl_CopyTexSubImage3D( GLcontext *ctx, GLenum target, GLint level,
- GLint xoffset, GLint yoffset, GLint zoffset,
- GLint x, GLint y, GLsizei width, GLsizei height )
+void
+_mesa_CopyTexSubImage3D( GLenum target, GLint level,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLint x, GLint y, GLsizei width, GLsizei height )
{
+ 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 );
+ }
}
}
}
-