/* Copyright (c) 2001, Stanford University
All rights reserved.
See the file LICENSE.txt for information on redistributing this software. */
#include "cr_packfunctions.h"
#include "cr_glstate.h"
#include "cr_pixeldata.h"
#include "cr_version.h"
#include "packspu.h"
#include "packspu_proto.h"
static GLboolean packspu_CheckTexImageFormat(GLenum format)
{
if (format!=GL_COLOR_INDEX
&& format!=GL_RED
&& format!=GL_GREEN
&& format!=GL_BLUE
&& format!=GL_ALPHA
&& format!=GL_RGB
&& format!=GL_BGR
&& format!=GL_RGBA
&& format!=GL_BGRA
&& format!=GL_LUMINANCE
&& format!=GL_LUMINANCE_ALPHA
&& format!=GL_DEPTH_COMPONENT
&& format!=GL_DEPTH_STENCIL)
{
/*crWarning("crPackCheckTexImageFormat FAILED format 0x%x isn't valid", format);*/
return GL_FALSE;
}
return GL_TRUE;
}
static GLboolean packspu_CheckTexImageType(GLenum type)
{
if (type!=GL_UNSIGNED_BYTE
&& type!=GL_BYTE
&& type!=GL_BITMAP
&& type!=GL_UNSIGNED_SHORT
&& type!=GL_SHORT
&& type!=GL_UNSIGNED_INT
&& type!=GL_INT
&& type!=GL_FLOAT
&& type!=GL_UNSIGNED_BYTE_3_3_2
&& type!=GL_UNSIGNED_BYTE_2_3_3_REV
&& type!=GL_UNSIGNED_SHORT_5_6_5
&& type!=GL_UNSIGNED_SHORT_5_6_5_REV
&& type!=GL_UNSIGNED_SHORT_4_4_4_4
&& type!=GL_UNSIGNED_SHORT_4_4_4_4_REV
&& type!=GL_UNSIGNED_SHORT_5_5_5_1
&& type!=GL_UNSIGNED_SHORT_1_5_5_5_REV
&& type!=GL_UNSIGNED_INT_8_8_8_8
&& type!=GL_UNSIGNED_INT_8_8_8_8_REV
&& type!=GL_UNSIGNED_INT_10_10_10_2
&& type!=GL_UNSIGNED_INT_2_10_10_10_REV
&& type!=GL_UNSIGNED_INT_24_8)
{
/*crWarning("crPackCheckTexImageType FAILED type 0x%x isn't valid", type);*/
return GL_FALSE;
}
return GL_TRUE;
}
static GLboolean packspu_CheckTexImageInternalFormat(GLint internalformat)
{
if (internalformat!=1
&& internalformat!=2
&& internalformat!=3
&& internalformat!=4
&& internalformat!=GL_ALPHA
&& internalformat!=GL_ALPHA4
&& internalformat!=GL_ALPHA8
&& internalformat!=GL_ALPHA12
&& internalformat!=GL_ALPHA16
&& internalformat!=GL_COMPRESSED_ALPHA
&& internalformat!=GL_COMPRESSED_LUMINANCE
&& internalformat!=GL_COMPRESSED_LUMINANCE_ALPHA
&& internalformat!=GL_COMPRESSED_INTENSITY
&& internalformat!=GL_COMPRESSED_RGB
&& internalformat!=GL_COMPRESSED_RGBA
&& internalformat!=GL_DEPTH_COMPONENT
&& internalformat!=GL_DEPTH_COMPONENT16
&& internalformat!=GL_DEPTH_COMPONENT24
&& internalformat!=GL_DEPTH_COMPONENT32
&& internalformat!=GL_DEPTH24_STENCIL8
&& internalformat!=GL_LUMINANCE
&& internalformat!=GL_LUMINANCE4
&& internalformat!=GL_LUMINANCE8
&& internalformat!=GL_LUMINANCE12
&& internalformat!=GL_LUMINANCE16
&& internalformat!=GL_LUMINANCE_ALPHA
&& internalformat!=GL_LUMINANCE4_ALPHA4
&& internalformat!=GL_LUMINANCE6_ALPHA2
&& internalformat!=GL_LUMINANCE8_ALPHA8
&& internalformat!=GL_LUMINANCE12_ALPHA4
&& internalformat!=GL_LUMINANCE12_ALPHA12
&& internalformat!=GL_LUMINANCE16_ALPHA16
&& internalformat!=GL_INTENSITY
&& internalformat!=GL_INTENSITY4
&& internalformat!=GL_INTENSITY8
&& internalformat!=GL_INTENSITY12
&& internalformat!=GL_INTENSITY16
&& internalformat!=GL_R3_G3_B2
&& internalformat!=GL_RGB
&& internalformat!=GL_RGB4
&& internalformat!=GL_RGB5
&& internalformat!=GL_RGB8
&& internalformat!=GL_RGB10
&& internalformat!=GL_RGB12
&& internalformat!=GL_RGB16
&& internalformat!=GL_RGBA
&& internalformat!=GL_RGBA2
&& internalformat!=GL_RGBA4
&& internalformat!=GL_RGB5_A1
&& internalformat!=GL_RGBA8
&& internalformat!=GL_RGB10_A2
&& internalformat!=GL_RGBA12
&& internalformat!=GL_RGBA16
&& internalformat!=GL_SLUMINANCE
&& internalformat!=GL_SLUMINANCE8
&& internalformat!=GL_SLUMINANCE_ALPHA
&& internalformat!=GL_SLUMINANCE8_ALPHA8
&& internalformat!=GL_SRGB
&& internalformat!=GL_SRGB8
&& internalformat!=GL_SRGB_ALPHA
&& internalformat!=GL_SRGB8_ALPHA8
#ifdef CR_EXT_texture_compression_s3tc
&& internalformat!=GL_COMPRESSED_RGB_S3TC_DXT1_EXT
&& internalformat!=GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
&& internalformat!=GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
&& internalformat!=GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
# ifdef CR_EXT_texture_sRGB
&& internalformat!=GL_COMPRESSED_SRGB_S3TC_DXT1_EXT
&& internalformat!=GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT
&& internalformat!=GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT
&& internalformat!=GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT
# endif
#endif
/*@todo ARB_texture_float*/
&& internalformat!=GL_RGBA32F_ARB
&& internalformat!=GL_RGB32F_ARB
&& internalformat!=GL_ALPHA32F_ARB
&& internalformat!=GL_INTENSITY32F_ARB
&& internalformat!=GL_LUMINANCE32F_ARB
&& internalformat!=GL_LUMINANCE_ALPHA32F_ARB
&& internalformat!=GL_RGBA16F_ARB
&& internalformat!=GL_RGB16F_ARB
&& internalformat!=GL_ALPHA16F_ARB
&& internalformat!=GL_INTENSITY16F_ARB
&& internalformat!=GL_LUMINANCE16F_ARB
&& internalformat!=GL_LUMINANCE_ALPHA16F_ARB
)
{
/*crWarning("crPackCheckTexImageInternalFormat FAILED internalformat 0x%x isn't valid", internalformat);*/
return GL_FALSE;
}
return GL_TRUE;
}
static GLboolean packspu_CheckTexImageParams(GLint internalformat, GLenum format, GLenum type)
{
return packspu_CheckTexImageFormat(format)
&& packspu_CheckTexImageType(type)
&& packspu_CheckTexImageInternalFormat(internalformat);
}
static GLboolean packspu_CheckTexImageFormatType(GLenum format, GLenum type)
{
return packspu_CheckTexImageFormat(format)
&& packspu_CheckTexImageType(type);
}
static const CRPixelPackState _defaultPacking = {
0, /* rowLength */
0, /* skipRows */
0, /* skipPixels */
1, /* alignment */
0, /* imageHeight */
0, /* skipImages */
GL_FALSE, /* swapBytes */
GL_FALSE, /* psLSBFirst */
};
#define APPLY_IF_NEQ(state, field, enum) \
if (state.field != _defaultPacking.field) \
{ \
crPackPixelStorei(enum, state.field); \
}
#define RESTORE_IF_NEQ(state, field, enum) \
if (state.field != _defaultPacking.field) \
{ \
crPackPixelStorei(enum, _defaultPacking.field); \
}
static void packspu_ApplyUnpackState()
{
GET_THREAD(thread);
ContextInfo *ctx = thread->currentContext;
CRClientState *clientState = &(ctx->clientState->client);
APPLY_IF_NEQ(clientState->unpack, rowLength, GL_UNPACK_ROW_LENGTH);
APPLY_IF_NEQ(clientState->unpack, skipRows, GL_UNPACK_SKIP_ROWS);
APPLY_IF_NEQ(clientState->unpack, skipPixels, GL_UNPACK_SKIP_PIXELS);
APPLY_IF_NEQ(clientState->unpack, alignment, GL_UNPACK_ALIGNMENT);
APPLY_IF_NEQ(clientState->unpack, imageHeight, GL_UNPACK_IMAGE_HEIGHT);
APPLY_IF_NEQ(clientState->unpack, skipImages, GL_UNPACK_SKIP_IMAGES);
APPLY_IF_NEQ(clientState->unpack, swapBytes, GL_UNPACK_SWAP_BYTES);
APPLY_IF_NEQ(clientState->unpack, psLSBFirst, GL_UNPACK_LSB_FIRST);
}
static void packspu_RestoreUnpackState()
{
GET_THREAD(thread);
ContextInfo *ctx = thread->currentContext;
CRClientState *clientState = &(ctx->clientState->client);
RESTORE_IF_NEQ(clientState->unpack, rowLength, GL_UNPACK_ROW_LENGTH);
RESTORE_IF_NEQ(clientState->unpack, skipRows, GL_UNPACK_SKIP_ROWS);
RESTORE_IF_NEQ(clientState->unpack, skipPixels, GL_UNPACK_SKIP_PIXELS);
RESTORE_IF_NEQ(clientState->unpack, alignment, GL_UNPACK_ALIGNMENT);
RESTORE_IF_NEQ(clientState->unpack, imageHeight, GL_UNPACK_IMAGE_HEIGHT);
RESTORE_IF_NEQ(clientState->unpack, skipImages, GL_UNPACK_SKIP_IMAGES);
RESTORE_IF_NEQ(clientState->unpack, swapBytes, GL_UNPACK_SWAP_BYTES);
RESTORE_IF_NEQ(clientState->unpack, psLSBFirst, GL_UNPACK_LSB_FIRST);
}
static void packspu_ApplyPackState()
{
GET_THREAD(thread);
ContextInfo *ctx = thread->currentContext;
CRClientState *clientState = &(ctx->clientState->client);
APPLY_IF_NEQ(clientState->pack, rowLength, GL_PACK_ROW_LENGTH);
APPLY_IF_NEQ(clientState->pack, skipRows, GL_PACK_SKIP_ROWS);
APPLY_IF_NEQ(clientState->pack, skipPixels, GL_PACK_SKIP_PIXELS);
APPLY_IF_NEQ(clientState->pack, alignment, GL_PACK_ALIGNMENT);
APPLY_IF_NEQ(clientState->pack, imageHeight, GL_PACK_IMAGE_HEIGHT);
APPLY_IF_NEQ(clientState->pack, skipImages, GL_PACK_SKIP_IMAGES);
APPLY_IF_NEQ(clientState->pack, swapBytes, GL_PACK_SWAP_BYTES);
APPLY_IF_NEQ(clientState->pack, psLSBFirst, GL_PACK_LSB_FIRST);
}
static void packspu_RestorePackState()
{
GET_THREAD(thread);
ContextInfo *ctx = thread->currentContext;
CRClientState *clientState = &(ctx->clientState->client);
RESTORE_IF_NEQ(clientState->pack, rowLength, GL_PACK_ROW_LENGTH);
RESTORE_IF_NEQ(clientState->pack, skipRows, GL_PACK_SKIP_ROWS);
RESTORE_IF_NEQ(clientState->pack, skipPixels, GL_PACK_SKIP_PIXELS);
RESTORE_IF_NEQ(clientState->pack, alignment, GL_PACK_ALIGNMENT);
RESTORE_IF_NEQ(clientState->pack, imageHeight, GL_PACK_IMAGE_HEIGHT);
RESTORE_IF_NEQ(clientState->pack, skipImages, GL_PACK_SKIP_IMAGES);
RESTORE_IF_NEQ(clientState->pack, swapBytes, GL_PACK_SWAP_BYTES);
RESTORE_IF_NEQ(clientState->pack, psLSBFirst, GL_PACK_LSB_FIRST);
}
void PACKSPU_APIENTRY packspu_PixelStoref( GLenum pname, GLfloat param )
{
/* NOTE: we do not send pixel store parameters to the server!
* When we pack a glDrawPixels or glTexImage2D image we interpret
* the user's pixel store parameters at that time and pack the
* image in a canonical layout (see util/pixel.c).
*/
crStatePixelStoref( pname, param );
}
void PACKSPU_APIENTRY packspu_PixelStorei( GLenum pname, GLint param )
{
crStatePixelStorei( pname, param );
}
void PACKSPU_APIENTRY packspu_DrawPixels( GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels )
{
GET_THREAD(thread);
ContextInfo *ctx = thread->currentContext;
CRClientState *clientState = &(ctx->clientState->client);
if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
{
packspu_ApplyUnpackState();
}
crPackDrawPixels( width, height, format, type, pixels, &(clientState->unpack) );
if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
{
packspu_RestoreUnpackState();
}
}
void PACKSPU_APIENTRY packspu_ReadPixels( GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels )
{
GET_THREAD(thread);
ContextInfo *ctx = thread->currentContext;
CRClientState *clientState = &(ctx->clientState->client);
int writeback;
if (crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
{
packspu_ApplyPackState();
}
crPackReadPixels(x, y, width, height, format, type, pixels, &(clientState->pack), &writeback);
if (crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
{
packspu_RestorePackState();
}
#ifdef CR_ARB_pixel_buffer_object
if (!crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
#endif
{
pack_spu.ReadPixels++;
packspuFlush((void *) thread);
CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
}
}
/*@todo check with pbo's*/
void PACKSPU_APIENTRY packspu_CopyPixels( GLint x, GLint y, GLsizei width, GLsizei height, GLenum type )
{
GET_THREAD(thread);
if (pack_spu.swap)
crPackCopyPixelsSWAP( x, y, width, height, type );
else
crPackCopyPixels( x, y, width, height, type );
/* XXX why flush here? */
packspuFlush( (void *) thread );
}
void PACKSPU_APIENTRY packspu_Bitmap( GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap )
{
GET_CONTEXT(ctx);
CRClientState *clientState = &(ctx->clientState->client);
if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
{
packspu_ApplyUnpackState();
}
crPackBitmap(width, height, xorig, yorig, xmove, ymove, bitmap, &(clientState->unpack));
if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
{
packspu_RestoreUnpackState();
}
}
void PACKSPU_APIENTRY packspu_TexImage1D( GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels )
{
GET_CONTEXT(ctx);
CRClientState *clientState = &(ctx->clientState->client);
if (!packspu_CheckTexImageParams(internalformat, format, type))
{
if (pixels || crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
{
crWarning("packspu_TexImage1D invalid internalFormat(%x)/format(%x)/type(%x)", internalformat, format, type);
return;
}
internalformat = packspu_CheckTexImageInternalFormat(internalformat) ? internalformat:GL_RGBA;
format = packspu_CheckTexImageFormat(format) ? format:GL_RGBA;
type = packspu_CheckTexImageType(type) ? type:GL_UNSIGNED_BYTE;
}
if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
{
packspu_ApplyUnpackState();
}
if (pack_spu.swap)
crPackTexImage1DSWAP( target, level, internalformat, width, border, format, type, pixels, &(clientState->unpack) );
else
crPackTexImage1D( target, level, internalformat, width, border, format, type, pixels, &(clientState->unpack) );
if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
{
packspu_RestoreUnpackState();
}
}
void PACKSPU_APIENTRY packspu_TexImage2D( GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels )
{
GET_CONTEXT(ctx);
CRClientState *clientState = &(ctx->clientState->client);
if (!packspu_CheckTexImageParams(internalformat, format, type))
{
if (pixels || crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
{
crWarning("packspu_TexImage2D invalid internalFormat(%x)/format(%x)/type(%x)", internalformat, format, type);
return;
}
internalformat = packspu_CheckTexImageInternalFormat(internalformat) ? internalformat:GL_RGBA;
format = packspu_CheckTexImageFormat(format) ? format:GL_RGBA;
type = packspu_CheckTexImageType(type) ? type:GL_UNSIGNED_BYTE;
}
if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
{
packspu_ApplyUnpackState();
}
if (pack_spu.swap)
crPackTexImage2DSWAP( target, level, internalformat, width, height, border, format, type, pixels, &(clientState->unpack) );
else
crPackTexImage2D( target, level, internalformat, width, height, border, format, type, pixels, &(clientState->unpack) );
if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
{
packspu_RestoreUnpackState();
}
}
#ifdef GL_EXT_texture3D
void PACKSPU_APIENTRY packspu_TexImage3DEXT( GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels )
{
GET_CONTEXT(ctx);
CRClientState *clientState = &(ctx->clientState->client);
if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
{
packspu_ApplyUnpackState();
}
if (pack_spu.swap)
crPackTexImage3DEXTSWAP( target, level, internalformat, width, height, depth, border, format, type, pixels, &(clientState->unpack) );
else
crPackTexImage3DEXT( target, level, internalformat, width, height, depth, border, format, type, pixels, &(clientState->unpack) );
if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
{
packspu_RestoreUnpackState();
}
}
#endif
#ifdef CR_OPENGL_VERSION_1_2
void PACKSPU_APIENTRY packspu_TexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels )
{
GET_CONTEXT(ctx);
CRClientState *clientState = &(ctx->clientState->client);
if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
{
packspu_ApplyUnpackState();
}
if (pack_spu.swap)
crPackTexImage3DSWAP( target, level, internalformat, width, height, depth, border, format, type, pixels, &(clientState->unpack) );
else
crPackTexImage3D( target, level, internalformat, width, height, depth, border, format, type, pixels, &(clientState->unpack) );
if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
{
packspu_RestoreUnpackState();
}
}
#endif /* CR_OPENGL_VERSION_1_2 */
void PACKSPU_APIENTRY packspu_TexSubImage1D( GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels )
{
GET_CONTEXT(ctx);
CRClientState *clientState = &(ctx->clientState->client);
if (!packspu_CheckTexImageFormatType(format, type))
{
crWarning("packspu_TexSubImage1D invalid format(%x)/type(%x)", format, type);
return;
}
if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
{
packspu_ApplyUnpackState();
}
if (pack_spu.swap)
crPackTexSubImage1DSWAP( target, level, xoffset, width, format, type, pixels, &(clientState->unpack) );
else
crPackTexSubImage1D( target, level, xoffset, width, format, type, pixels, &(clientState->unpack) );
if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
{
packspu_RestoreUnpackState();
}
}
void PACKSPU_APIENTRY packspu_TexSubImage2D( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels )
{
GET_CONTEXT(ctx);
CRClientState *clientState = &(ctx->clientState->client);
if (!packspu_CheckTexImageFormatType(format, type))
{
crWarning("packspu_TexSubImage2D invalid format(%x)/type(%x)", format, type);
return;
}
if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
{
packspu_ApplyUnpackState();
}
if (pack_spu.swap)
crPackTexSubImage2DSWAP( target, level, xoffset, yoffset, width, height, format, type, pixels, &(clientState->unpack) );
else
crPackTexSubImage2D( target, level, xoffset, yoffset, width, height, format, type, pixels, &(clientState->unpack) );
if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
{
packspu_RestoreUnpackState();
}
}
#ifdef CR_OPENGL_VERSION_1_2
void PACKSPU_APIENTRY packspu_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_CONTEXT(ctx);
CRClientState *clientState = &(ctx->clientState->client);
if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
{
packspu_ApplyUnpackState();
}
if (pack_spu.swap)
crPackTexSubImage3DSWAP( target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels, &(clientState->unpack) );
else
crPackTexSubImage3D( target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels, &(clientState->unpack) );
if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
{
packspu_RestoreUnpackState();
}
}
#endif /* CR_OPENGL_VERSION_1_2 */
void PACKSPU_APIENTRY packspu_ZPixCR( GLsizei width, GLsizei height, GLenum format, GLenum type, GLenum ztype, GLint zparm, GLint length, const GLvoid *pixels )
{
GET_CONTEXT(ctx);
CRClientState *clientState = &(ctx->clientState->client);
if (pack_spu.swap)
crPackZPixCRSWAP( width, height, format, type, ztype, zparm, length, pixels, &(clientState->unpack) );
else
crPackZPixCR( width, height, format, type, ztype, zparm, length, pixels, &(clientState->unpack) );
}
void PACKSPU_APIENTRY packspu_GetTexImage (GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels)
{
GET_THREAD(thread);
ContextInfo *ctx = thread->currentContext;
CRClientState *clientState = &(ctx->clientState->client);
int writeback = 1;
/* XXX note: we're not observing the pixel pack parameters here unless PACK PBO is bound
* To do so, we'd have to allocate a temporary image buffer (how large???)
* and copy the image to the user's buffer using the pixel pack params.
*/
if (crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
{
packspu_ApplyPackState();
}
if (pack_spu.swap)
crPackGetTexImageSWAP( target, level, format, type, pixels, &(clientState->pack), &writeback );
else
crPackGetTexImage( target, level, format, type, pixels, &(clientState->pack), &writeback );
if (crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
{
packspu_RestorePackState();
}
#ifdef CR_ARB_pixel_buffer_object
if (!crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
#endif
{
packspuFlush( (void *) thread );
CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
}
}
void PACKSPU_APIENTRY packspu_GetCompressedTexImageARB( GLenum target, GLint level, GLvoid * img )
{
GET_THREAD(thread);
int writeback = 1;
if (crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
{
packspu_ApplyPackState();
}
if (pack_spu.swap)
{
crPackGetCompressedTexImageARBSWAP( target, level, img, &writeback );
}
else
{
crPackGetCompressedTexImageARB( target, level, img, &writeback );
}
if (crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
{
packspu_RestorePackState();
}
#ifdef CR_ARB_pixel_buffer_object
if (!crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
#endif
{
packspuFlush( (void *) thread );
CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
}
}
void PACKSPU_APIENTRY
packspu_CompressedTexImage1DARB(GLenum target, GLint level, GLenum internalformat, GLsizei width,
GLint border, GLsizei imagesize, const GLvoid *data)
{
if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
{
packspu_ApplyUnpackState();
}
crPackCompressedTexImage1DARB(target, level, internalformat, width, border, imagesize, data);
if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
{
packspu_RestoreUnpackState();
}
}
void PACKSPU_APIENTRY
packspu_CompressedTexImage2DARB(GLenum target, GLint level, GLenum internalformat, GLsizei width,
GLsizei height, GLint border, GLsizei imagesize, const GLvoid *data)
{
if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
{
packspu_ApplyUnpackState();
}
crPackCompressedTexImage2DARB(target, level, internalformat, width, height, border, imagesize, data);
if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
{
packspu_RestoreUnpackState();
}
}
void PACKSPU_APIENTRY
packspu_CompressedTexImage3DARB(GLenum target, GLint level, GLenum internalformat, GLsizei width,
GLsizei height, GLsizei depth, GLint border, GLsizei imagesize, const GLvoid *data)
{
if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
{
packspu_ApplyUnpackState();
}
crPackCompressedTexImage3DARB(target, level, internalformat, width, height, depth, border, imagesize, data);
if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
{
packspu_RestoreUnpackState();
}
}
void PACKSPU_APIENTRY
packspu_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset, GLsizei width,
GLenum format, GLsizei imagesize, const GLvoid *data)
{
if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
{
packspu_ApplyUnpackState();
}
crPackCompressedTexSubImage1DARB(target, level, xoffset, width, format, imagesize, data);
if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
{
packspu_RestoreUnpackState();
}
}
void PACKSPU_APIENTRY
packspu_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset, GLint yoffset,
GLsizei width, GLsizei height, GLenum format, GLsizei imagesize, const GLvoid *data)
{
if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
{
packspu_ApplyUnpackState();
}
crPackCompressedTexSubImage2DARB(target, level, xoffset, yoffset, width, height, format, imagesize, data);
if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
{
packspu_RestoreUnpackState();
}
}
void PACKSPU_APIENTRY
packspu_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset, GLint yoffset,
GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format,
GLsizei imagesize, const GLvoid *data)
{
if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
{
packspu_ApplyUnpackState();
}
crPackCompressedTexSubImage3DARB(target, level, xoffset, yoffset, zoffset, width, height, depth, format, imagesize, data);
if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
{
packspu_RestoreUnpackState();
}
}