#define DST_TEXEL_BYTES (4 / DST_TEXELS_PER_DWORD)
#define DST_ROW_BYTES (convert->width * DST_TEXEL_BYTES)
#define DST_ROW_STRIDE (convert->dstImageWidth * DST_TEXEL_BYTES)
#define DST_IMG_STRIDE (convert->dstImageWidth * \
convert->dstImageHeight * DST_TEXEL_BYTES)
static GLboolean
TAG(texsubimage2d)( const struct convert_info *convert )
{
const GLubyte *src = (const GLubyte *)convert->srcImage;
GLuint *dst = (GLuint *)((GLubyte *)convert->dstImage +
(convert->yoffset * convert->dstImageWidth +
convert->xoffset) * DST_TEXEL_BYTES);
#if DEBUG_TEXUTIL
_mesa_debug( NULL, __FUNCTION__ "\n" );
#endif
#ifdef CONVERT_DIRECT
MEMCPY( dst, src, convert->height * DST_ROW_BYTES );
#else
{
const GLint texels = convert->width * convert->height;
const GLint dwords = texels / DST_TEXELS_PER_DWORD;
const GLint leftover = texels - dwords * DST_TEXELS_PER_DWORD;
GLint i;
for ( i = 0 ; i < dwords ; i++ ) {
CONVERT_TEXEL_DWORD( *dst++, src );
src += SRC_TEXEL_BYTES * DST_TEXELS_PER_DWORD;
}
for ( i = 0; i < leftover; i++ ) {
CONVERT_TEXEL( *dst++, src );
src += SRC_TEXEL_BYTES;
}
}
#endif
return GL_TRUE;
}
static GLboolean
TAG(texsubimage3d)( const struct convert_info *convert )
{
const GLubyte *src = (const GLubyte *)convert->srcImage;
GLuint *dst = (GLuint *)((GLubyte *)convert->dstImage +
((convert->zoffset * convert->height +
convert->yoffset) * convert->width +
convert->xoffset) * DST_TEXEL_BYTES);
#if DEBUG_TEXUTIL
_mesa_debug( NULL, __FUNCTION__ "\n" );
#endif
#ifdef CONVERT_DIRECT
MEMCPY( dst, src, convert->depth * convert->height * DST_ROW_BYTES );
#else
{
const GLint texels = convert->width * convert->height * convert->depth;
const GLint dwords = texels / DST_TEXELS_PER_DWORD;
const GLint leftover = texels - dwords * DST_TEXELS_PER_DWORD;
GLint i;
for ( i = 0 ; i < dwords ; i++ ) {
CONVERT_TEXEL_DWORD( *dst++, src );
src += SRC_TEXEL_BYTES * DST_TEXELS_PER_DWORD;
}
for ( i = 0; i < leftover; i++ ) {
CONVERT_TEXEL( *dst++, src );
src += SRC_TEXEL_BYTES;
}
}
#endif
return GL_TRUE;
}
static GLboolean
TAG(texsubimage2d_stride)( const struct convert_info *convert )
{
const GLubyte *src = (const GLubyte *)convert->srcImage;
DST_TYPE *dst = (DST_TYPE *)((GLubyte *)convert->dstImage +
(convert->yoffset * convert->dstImageWidth +
convert->xoffset) * DST_TEXEL_BYTES);
GLint adjust;
GLint row, col;
adjust = convert->dstImageWidth - convert->width;
#if DEBUG_TEXUTIL
_mesa_debug( NULL, __FUNCTION__ ":\n" );
_mesa_debug( NULL, " x=%d y=%d w=%d h=%d s=%d\n",
convert->xoffset, convert->yoffset, convert->width,
convert->height, convert->dstImageWidth );
_mesa_debug( NULL, " adjust=%d\n", adjust );
#endif
for ( row = 0 ; row < convert->height ; row++ ) {
for ( col = 0 ; col < convert->width ; col++ ) {
CONVERT_TEXEL( *dst++, src );
src += SRC_TEXEL_BYTES;
}
dst += adjust;
}
return GL_TRUE;
}
static GLboolean
TAG(texsubimage3d_stride)( const struct convert_info *convert )
{
const GLubyte *src = (const GLubyte *)convert->srcImage;
DST_TYPE *dst = (DST_TYPE *)((GLubyte *)convert->dstImage +
((convert->zoffset * convert->dstImageHeight +
convert->yoffset) * convert->dstImageWidth +
convert->xoffset) * DST_TEXEL_BYTES);
GLint adjust;
GLint row, col, img;
adjust = convert->dstImageWidth - convert->width;
#if DEBUG_TEXUTIL
_mesa_debug( NULL, __FUNCTION__ ":\n" );
_mesa_debug( NULL, " x=%d y=%d w=%d h=%d s=%d\n",
convert->xoffset, convert->yoffset, convert->width,
convert->height, convert->dstImageWidth );
_mesa_debug( NULL, " adjust=%d\n", adjust );
#endif
for ( img = 0 ; img < convert->depth ; img++ ) {
for ( row = 0 ; row < convert->height ; row++ ) {
for ( col = 0 ; col < convert->width ; col++ ) {
CONVERT_TEXEL( *dst++, src );
src += SRC_TEXEL_BYTES;
}
dst += adjust;
}
}
return GL_TRUE;
}
static GLboolean
TAG(texsubimage2d_unpack)( const struct convert_info *convert )
{
const GLubyte *src = (const GLubyte *)
_mesa_image_address( convert->unpacking, convert->srcImage,
convert->width, convert->height,
convert->format, convert->type, 0, 0, 0 );
const GLint srcRowStride =
_mesa_image_row_stride( convert->unpacking, convert->width,
convert->format, convert->type );
GLint row, col;
#if DEBUG_TEXUTIL
_mesa_debug( NULL, __FUNCTION__ "\n" );
#endif
if (convert->width & (DST_TEXELS_PER_DWORD - 1)) {
DST_TYPE *dst = (DST_TYPE *)((GLubyte *)convert->dstImage +
(convert->yoffset * convert->width +
convert->xoffset) * DST_TEXEL_BYTES);
for ( row = 0 ; row < convert->height ; row++ ) {
const GLubyte *srcRow = src;
for ( col = 0; col < convert->width; col++ ) {
CONVERT_TEXEL(*dst, src);
src += SRC_TEXEL_BYTES;
}
src = srcRow + srcRowStride;
}
}
else {
GLuint *dst = (GLuint *)((GLubyte *)convert->dstImage +
(convert->yoffset * convert->width +
convert->xoffset) * DST_TEXEL_BYTES);
for ( row = 0 ; row < convert->height ; row++ ) {
#ifdef CONVERT_DIRECT
MEMCPY( dst, src, DST_ROW_STRIDE );
src += srcRowStride;
dst = (GLuint *)((GLubyte *)dst + DST_ROW_STRIDE);
#else
const GLubyte *srcRow = src;
for ( col = convert->width / DST_TEXELS_PER_DWORD ; col ; col-- ) {
CONVERT_TEXEL_DWORD( *dst++, src );
src += SRC_TEXEL_BYTES * DST_TEXELS_PER_DWORD;
}
src = srcRow + srcRowStride;
#endif
}
}
return GL_TRUE;
}
static GLboolean
TAG(texsubimage3d_unpack)( const struct convert_info *convert )
{
const GLubyte *src = (const GLubyte *)
_mesa_image_address( convert->unpacking, convert->srcImage,
convert->width, convert->height,
convert->format, convert->type, 0, 0, 0 );
const GLint srcImgStride = (const GLubyte *)
_mesa_image_address( convert->unpacking, convert->srcImage,
convert->width, convert->height,
convert->format, convert->type, 1, 0, 0 ) - src;
const GLint srcRowStride =
_mesa_image_row_stride( convert->unpacking, convert->width,
convert->format, convert->type );
GLint row, col, img;
#if DEBUG_TEXUTIL
_mesa_debug( NULL, __FUNCTION__ "\n" );
#endif
if (convert->width & (DST_TEXELS_PER_DWORD - 1)) {
DST_TYPE *dst = (DST_TYPE *)((GLubyte *)convert->dstImage +
((convert->zoffset * convert->height +
convert->yoffset) * convert->width +
convert->xoffset) * DST_TEXEL_BYTES);
for ( img = 0 ; img < convert->depth ; img++ ) {
const GLubyte *srcImage = src;
for ( row = 0 ; row < convert->height ; row++ ) {
const GLubyte *srcRow = src;
for ( col = 0; col < convert->width; col++ ) {
CONVERT_TEXEL(*dst, src);
src += SRC_TEXEL_BYTES;
}
src = srcRow + srcRowStride;
}
src = srcImage + srcImgStride;
}
}
else {
GLuint *dst = (GLuint *)((GLubyte *)convert->dstImage +
((convert->zoffset * convert->height +
convert->yoffset) * convert->width +
convert->xoffset) * DST_TEXEL_BYTES);
for ( img = 0 ; img < convert->depth ; img++ ) {
const GLubyte *srcImage = src;
for ( row = 0 ; row < convert->height ; row++ ) {
#ifdef CONVERT_DIRECT
MEMCPY( dst, src, DST_ROW_STRIDE );
src += srcRowStride;
dst = (GLuint *)((GLubyte *)dst + DST_ROW_STRIDE);
#else
const GLubyte *srcRow = src;
for ( col = convert->width / DST_TEXELS_PER_DWORD ; col ; col-- ) {
CONVERT_TEXEL_DWORD( *dst++, src );
src += SRC_TEXEL_BYTES * DST_TEXELS_PER_DWORD;
}
src = srcRow + srcRowStride;
#endif
}
src = srcImage + srcImgStride;
}
}
return GL_TRUE;
}
static GLboolean
TAG(texsubimage2d_stride_unpack)( const struct convert_info *convert )
{
const GLubyte *src = (const GLubyte *)
_mesa_image_address( convert->unpacking, convert->srcImage,
convert->width, convert->height,
convert->format, convert->type, 0, 0, 0 );
const GLint srcRowStride =
_mesa_image_row_stride( convert->unpacking, convert->width,
convert->format, convert->type );
DST_TYPE *dst = (DST_TYPE *)((GLubyte *)convert->dstImage +
(convert->yoffset * convert->dstImageWidth +
convert->xoffset) * DST_TEXEL_BYTES);
GLint row;
#ifndef CONVERT_DIRECT
GLint adjust = convert->dstImageWidth - convert->width;
#endif
#if DEBUG_TEXUTIL
_mesa_debug( NULL, __FUNCTION__ ":\n" );
_mesa_debug( NULL, " x=%d y=%d w=%d h=%d s=%d\n",
convert->xoffset, convert->yoffset, convert->width,
convert->height, convert->dstImageWidth );
#endif
for ( row = 0 ; row < convert->height ; row++ ) {
#ifdef CONVERT_DIRECT
MEMCPY( dst, src, DST_ROW_BYTES );
src += srcRowStride;
dst += convert->dstImageWidth;
#else
const GLubyte *srcRow = src;
GLint col;
for ( col = 0 ; col < convert->width ; col++ ) {
CONVERT_TEXEL( *dst++, src );
src += SRC_TEXEL_BYTES;
}
src = srcRow + srcRowStride;
dst += adjust;
#endif
}
return GL_TRUE;
}
static GLboolean
TAG(texsubimage3d_stride_unpack)( const struct convert_info *convert )
{
const GLubyte *src = (const GLubyte *)
_mesa_image_address( convert->unpacking, convert->srcImage,
convert->width, convert->height,
convert->format, convert->type, 0, 0, 0 );
const GLint srcImgStride = (const GLubyte *)
_mesa_image_address( convert->unpacking, convert->srcImage,
convert->width, convert->height,
convert->format, convert->type, 1, 0, 0 ) - src;
const GLint srcRowStride =
_mesa_image_row_stride( convert->unpacking, convert->width,
convert->format, convert->type );
DST_TYPE *dst = (DST_TYPE *)((GLubyte *)convert->dstImage +
((convert->zoffset * convert->dstImageHeight +
convert->yoffset) * convert->dstImageWidth +
convert->xoffset) * DST_TEXEL_BYTES);
GLint row, img;
#ifndef CONVERT_DIRECT
GLint adjust = convert->dstImageWidth - convert->width;
#endif
#if DEBUG_TEXUTIL
_mesa_debug( NULL, __FUNCTION__ ":\n" );
_mesa_debug( NULL, " x=%d y=%d w=%d h=%d s=%d\n",
convert->xoffset, convert->yoffset, convert->width,
convert->height, convert->dstImageWidth );
#endif
for ( img = 0 ; img < convert->depth ; img++ ) {
const GLubyte *srcImage = src;
for ( row = 0 ; row < convert->height ; row++ ) {
#ifdef CONVERT_DIRECT
MEMCPY( dst, src, DST_ROW_BYTES );
src += srcRowStride;
dst += convert->dstImageWidth;
#else
const GLubyte *srcRow = src;
GLint col;
for ( col = 0 ; col < convert->width ; col++ ) {
CONVERT_TEXEL( *dst++, src );
src += SRC_TEXEL_BYTES;
}
src = srcRow + srcRowStride;
dst += adjust;
#endif
}
src = srcImage + srcImgStride;
}
return GL_TRUE;
}
static convert_func TAG(texsubimage2d_tab)[] = {
TAG(texsubimage2d),
TAG(texsubimage2d_stride),
TAG(texsubimage2d_unpack),
TAG(texsubimage2d_stride_unpack),
};
static convert_func TAG(texsubimage3d_tab)[] = {
TAG(texsubimage3d),
TAG(texsubimage3d_stride),
TAG(texsubimage3d_unpack),
TAG(texsubimage3d_stride_unpack),
};
#ifndef PRESERVE_DST_TYPE
#undef DST_TYPE
#undef DST_TEXELS_PER_DWORD
#endif
#undef SRC_TEXEL_BYTES
#undef DST_TEXEL_BYTES
#undef DST_ROW_BYTES
#undef DST_ROW_STRIDE
#undef CONVERT_TEXEL
#undef CONVERT_TEXEL_DWORD
#undef CONVERT_DIRECT
#undef TAG
#undef PRESERVE_DST_TYPE