/*
* Mesa 3-D graphics library
- * Version: 6.1
+ * Version: 6.3
*
* Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
*
#include "texformat.h"
#include "teximage.h"
#include "texstore.h"
-#include "texutil.h"
+static const GLint ZERO = 4, ONE = 5;
-/*** NEWTEXSTORE ***********************************************************/
+static GLboolean can_swizzle(GLenum logicalBaseFormat)
+{
+ switch (logicalBaseFormat) {
+ case GL_RGBA:
+ case GL_RGB:
+ case GL_LUMINANCE_ALPHA:
+ case GL_INTENSITY:
+ case GL_ALPHA:
+ case GL_LUMINANCE:
+ return GL_TRUE;
+ default:
+ return GL_FALSE;
+ }
+}
-static const GLint ZERO = 1000, ONE = 1001;
/**
* When promoting texture formats (see below) we need to compute the
*/
static void
compute_component_mapping(GLenum logicalBaseFormat, GLenum textureBaseFormat,
- GLint map[4])
+ GLubyte map[6])
{
+ map[ZERO] = ZERO;
+ map[ONE] = ONE;
+
/* compute mapping from dest components back to src components */
- switch (logicalBaseFormat) {
- case GL_LUMINANCE:
- map[0] = map[1] = map[2] = 0;
- if (textureBaseFormat == GL_RGBA)
- map[3] = ONE;
- break;
- case GL_ALPHA:
- ASSERT(textureBaseFormat == GL_RGBA);
- map[0] = map[1] = map[2] = ZERO;
- map[3] = 0;
- break;
- case GL_INTENSITY:
- map[0] = map[1] = map[2] = 0;
- if (textureBaseFormat == GL_RGBA)
+ switch (textureBaseFormat) {
+ case GL_RGB:
+ case GL_RGBA:
+ switch (logicalBaseFormat) {
+ case GL_LUMINANCE:
+ map[0] = map[1] = map[2] = 0;
+ if (textureBaseFormat == GL_RGBA)
+ map[3] = ONE;
+ break;
+ case GL_ALPHA:
+ ASSERT(textureBaseFormat == GL_RGBA);
+ map[0] = map[1] = map[2] = ZERO;
map[3] = 0;
+ break;
+ case GL_INTENSITY:
+ map[0] = map[1] = map[2] = 0;
+ if (textureBaseFormat == GL_RGBA)
+ map[3] = 0;
+ break;
+ case GL_LUMINANCE_ALPHA:
+ ASSERT(textureBaseFormat == GL_RGBA);
+ map[0] = map[1] = map[2] = 0;
+ map[3] = 1;
+ break;
+ case GL_RGB:
+ ASSERT(textureBaseFormat == GL_RGBA);
+ map[0] = 0;
+ map[1] = 1;
+ map[2] = 2;
+ map[3] = ONE;
+ break;
+ case GL_RGBA:
+ ASSERT(textureBaseFormat == GL_RGBA);
+ map[0] = 0;
+ map[1] = 1;
+ map[2] = 2;
+ map[3] = 3;
+ break;
+ default:
+ _mesa_problem(NULL, "Unexpected logicalBaseFormat");
+ map[0] = map[1] = map[2] = map[3] = 0;
+ }
break;
case GL_LUMINANCE_ALPHA:
- ASSERT(textureBaseFormat == GL_RGBA);
- map[0] = map[1] = map[2] = 0;
- map[3] = 1;
- break;
- case GL_RGB:
- ASSERT(textureBaseFormat == GL_RGBA);
- map[0] = 0;
- map[1] = 1;
- map[2] = 2;
- map[3] = ONE;
+ switch (logicalBaseFormat) {
+ case GL_LUMINANCE:
+ map[0] = 0;
+ map[1] = ONE;
+ break;
+ case GL_ALPHA:
+ map[0] = ZERO;
+ map[1] = 0;
+ break;
+ case GL_INTENSITY:
+ map[0] = 0;
+ map[1] = 0;
+ break;
+ default:
+ _mesa_problem(NULL, "Unexpected logicalBaseFormat");
+ map[0] = map[1] = 0;
+ }
break;
default:
_mesa_problem(NULL, "Unexpected logicalBaseFormat");
- map[0] = map[1] = map[2] = map[3] = 0;
- }
+ map[0] = map[1] = 0;
+ break;
+ }
}
/* unpack and do transfer ops up to convolution */
for (row = 0; row < srcHeight; row++) {
- const GLvoid *src = _mesa_image_address(srcPacking,
+ const GLvoid *src = _mesa_image_address(dims, srcPacking,
srcAddr, srcWidth, srcHeight,
srcFormat, srcType, img, row, 0);
_mesa_unpack_color_span_float(ctx, srcWidth, GL_RGBA, dst,
/* do post-convolution transfer and pack into tempImage */
{
+ const GLint logComponents
+ = _mesa_components_in_format(logicalBaseFormat);
const GLfloat *src = convImage;
GLfloat *dst = tempImage + img * (convWidth * convHeight * 4);
for (row = 0; row < convHeight; row++) {
dst, &ctx->DefaultPacking,
postConvTransferOps);
src += convWidth * 4;
- dst += convWidth * 4;
+ dst += convWidth * logComponents;
}
}
} /* loop over 3D image slices */
dst = tempImage;
for (img = 0; img < srcDepth; img++) {
const GLubyte *src
- = (const GLubyte *) _mesa_image_address(srcPacking, srcAddr,
+ = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
srcWidth, srcHeight,
srcFormat, srcType,
img, 0, 0);
GLint logComponents = _mesa_components_in_format(logicalBaseFormat);
GLfloat *newImage;
GLint i, n;
- GLint map[4];
+ GLubyte map[6];
- /* we only promote up to RGB and RGBA formats for now */
- ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA);
+ /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
+ ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA ||
+ textureBaseFormat == GL_LUMINANCE_ALPHA);
/* The actual texture format should have at least as many components
* as the logical texture format.
* \param srcPacking source image pixel packing
* \return resulting image with format = textureBaseFormat and type = GLchan.
*/
-static GLchan *
-make_temp_chan_image(GLcontext *ctx, GLuint dims,
- GLenum logicalBaseFormat,
- GLenum textureBaseFormat,
- GLint srcWidth, GLint srcHeight, GLint srcDepth,
- GLenum srcFormat, GLenum srcType,
- const GLvoid *srcAddr,
- const struct gl_pixelstore_attrib *srcPacking)
+GLchan *
+_mesa_make_temp_chan_image(GLcontext *ctx, GLuint dims,
+ GLenum logicalBaseFormat,
+ GLenum textureBaseFormat,
+ GLint srcWidth, GLint srcHeight, GLint srcDepth,
+ GLenum srcFormat, GLenum srcType,
+ const GLvoid *srcAddr,
+ const struct gl_pixelstore_attrib *srcPacking)
{
GLuint transferOps = ctx->_ImageTransferState;
const GLint components = _mesa_components_in_format(logicalBaseFormat);
srcWidth, srcFormat,
srcType);
const GLubyte *src
- = (const GLubyte *) _mesa_image_address(srcPacking, srcAddr,
+ = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
srcWidth, srcHeight,
srcFormat, srcType,
img, 0, 0);
for (row = 0; row < srcHeight; row++) {
- _mesa_unpack_color_span_chan(ctx, srcWidth, logicalBaseFormat,
- dst, srcFormat, srcType, src,
- srcPacking, transferOps);
+ _mesa_unpack_color_span_chan(ctx, srcWidth, logicalBaseFormat, dst,
+ srcFormat, srcType, src, srcPacking,
+ transferOps);
dst += srcWidth * components;
src += srcStride;
}
GLint logComponents = _mesa_components_in_format(logicalBaseFormat);
GLchan *newImage;
GLint i, n;
- GLint map[4];
+ GLubyte map[6];
- /* we only promote up to RGB and RGBA formats for now */
- ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA);
+ /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
+ ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA ||
+ textureBaseFormat == GL_LUMINANCE_ALPHA);
/* The actual texture format should have at least as many components
* as the logical texture format.
}
+static void swizzle_copy(GLubyte *dst,
+ GLuint dstComponents,
+ const GLubyte *src,
+ GLuint srcComponents,
+ GLubyte *map,
+ GLuint count)
+{
+ GLubyte tmp[8];
+ GLint i;
+
+ tmp[ZERO] = 0x0;
+ tmp[ONE] = 0xff;
+
+ switch (dstComponents) {
+ case 4:
+ for (i = 0; i < count; i++) {
+ COPY_4UBV(tmp, src);
+ src += srcComponents;
+ dst[0] = tmp[map[0]];
+ dst[1] = tmp[map[1]];
+ dst[2] = tmp[map[2]];
+ dst[3] = tmp[map[3]];
+ dst += 4;
+ }
+ break;
+ case 3:
+ for (i = 0; i < count; i++) {
+ COPY_4UBV(tmp, src);
+ src += srcComponents;
+ dst[0] = tmp[map[0]];
+ dst[1] = tmp[map[1]];
+ dst[2] = tmp[map[2]];
+ dst += 3;
+ }
+ break;
+ case 2:
+ for (i = 0; i < count; i++) {
+ COPY_4UBV(tmp, src);
+ src += srcComponents;
+ dst[0] = tmp[map[0]];
+ dst[1] = tmp[map[1]];
+ dst += 2;
+ }
+ break;
+ }
+}
+
+
+static void
+_mesa_swizzle_ubyte_image(GLcontext *ctx,
+ GLuint dimensions,
+ GLenum srcFormat,
+ const GLubyte *dstmap, GLint dstComponents,
+
+ GLvoid *dstAddr,
+ GLint dstXoffset, GLint dstYoffset, GLint dstZoffset,
+ GLint dstRowStride, GLint dstImageStride,
+
+ GLint srcWidth, GLint srcHeight, GLint srcDepth,
+ const GLvoid *srcAddr,
+ const struct gl_pixelstore_attrib *srcPacking )
+{
+ GLint srcComponents = _mesa_components_in_format(srcFormat);
+ GLubyte srcmap[6], map[4];
+ GLint i;
+
+ const GLint srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth,
+ srcFormat, GL_UNSIGNED_BYTE);
+ const GLint srcImageStride = _mesa_image_image_stride(srcPacking,
+ srcWidth, srcHeight, srcFormat, GL_UNSIGNED_BYTE);
+ const GLubyte *srcImage = (const GLubyte *) _mesa_image_address(dimensions,
+ srcPacking, srcAddr, srcWidth, srcHeight, srcFormat, GL_UNSIGNED_BYTE, 0, 0, 0);
+
+ GLubyte *dstImage = (GLubyte *) dstAddr
+ + dstZoffset * dstImageStride
+ + dstYoffset * dstRowStride
+ + dstXoffset * dstComponents;
+
+ compute_component_mapping(srcFormat, GL_RGBA, srcmap);
+
+ for (i = 0; i < 4; i++)
+ map[i] = srcmap[dstmap[i]];
+
+ if (srcRowStride == srcWidth * srcComponents &&
+ (srcImageStride == srcWidth * srcHeight * srcComponents ||
+ srcDepth == 1)) {
+ swizzle_copy(dstImage, dstComponents, srcImage, srcComponents, map,
+ srcWidth * srcHeight * srcDepth);
+ }
+ else {
+ GLint img, row;
+ for (img = 0; img < srcDepth; img++) {
+ const GLubyte *srcRow = srcImage;
+ GLubyte *dstRow = dstImage;
+ for (row = 0; row < srcHeight; row++) {
+ swizzle_copy(dstRow, dstComponents, srcRow, srcComponents, map, srcWidth);
+ dstRow += dstRowStride;
+ srcRow += srcRowStride;
+ }
+ srcImage += srcImageStride;
+ dstImage += dstImageStride;
+ }
+ }
+}
+
+
+
+
/**
* Teximage storage routine for when a simple memcpy will do.
* 1D, 2D and 3D images supported.
*/
static void
-memcpy_texture(const struct gl_texture_format *dstFormat,
+memcpy_texture(GLuint dimensions,
+ const struct gl_texture_format *dstFormat,
GLvoid *dstAddr,
GLint dstXoffset, GLint dstYoffset, GLint dstZoffset,
GLint dstRowStride, GLint dstImageStride,
srcFormat, srcType);
const GLint srcImageStride = _mesa_image_image_stride(srcPacking,
srcWidth, srcHeight, srcFormat, srcType);
- const GLubyte *srcImage = (const GLubyte *) _mesa_image_address(srcPacking,
- srcAddr, srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0);
+ const GLubyte *srcImage = (const GLubyte *) _mesa_image_address(dimensions,
+ srcPacking, srcAddr, srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0);
const GLint bytesPerRow = srcWidth * dstFormat->TexelBytes;
const GLint bytesPerImage = srcHeight * bytesPerRow;
const GLint bytesPerTexture = srcDepth * bytesPerImage;
baseInternalFormat == srcFormat &&
srcType == CHAN_TYPE) {
/* simple memcpy path */
- memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+ memcpy_texture(dims,
+ dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
dstRowStride, dstImageStride,
srcWidth, srcHeight, srcDepth, srcFormat, srcType,
srcAddr, srcPacking);
for (img = 0; img < srcDepth; img++) {
const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
srcWidth, srcFormat, srcType);
- GLchan *srcRow = _mesa_image_address(srcPacking, srcAddr, srcWidth,
- srcHeight, srcFormat, srcType,
- img, 0, 0);
+ GLchan *srcRow = (GLchan *) _mesa_image_address(dims, srcPacking,
+ srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
GLchan *dstRow = dstImage;
for (row = 0; row < srcHeight; row++) {
for (col = 0; col < srcWidth; col++) {
}
else {
/* general path */
- const GLchan *tempImage = make_temp_chan_image(ctx, dims,
+ const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
baseInternalFormat,
dstFormat->BaseFormat,
srcWidth, srcHeight, srcDepth,
srcFormat, srcType, srcAddr,
srcPacking);
const GLchan *src = tempImage;
- const GLint bytesPerRow = srcWidth * components * sizeof(GLchan);
+ GLint bytesPerRow;
GLubyte *dstImage = (GLubyte *) dstAddr
+ dstZoffset * dstImageStride
+ dstYoffset * dstRowStride
if (!tempImage)
return GL_FALSE;
_mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
+ bytesPerRow = srcWidth * components * sizeof(GLchan);
for (img = 0; img < srcDepth; img++) {
GLubyte *dstRow = dstImage;
for (row = 0; row < srcHeight; row++) {
}
-/**
- * Store a color index texture image
- */
-GLboolean
-_mesa_texstore_color_index(STORE_PARAMS)
-{
- ASSERT(dstFormat == &_mesa_texformat_color_index);
- ASSERT(dstFormat->TexelBytes == 1 * sizeof(GLchan));
-
- if (!ctx->_ImageTransferState &&
- !srcPacking->SwapBytes &&
- baseInternalFormat == GL_COLOR_INDEX &&
- srcFormat == GL_COLOR_INDEX &&
- srcType == CHAN_TYPE) {
- /* simple memcpy path */
- memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
- dstRowStride, dstImageStride,
- srcWidth, srcHeight, srcDepth, srcFormat, srcType,
- srcAddr, srcPacking);
- }
- else {
- /* general path */
- GLubyte *dstImage = (GLubyte *) dstAddr
- + dstZoffset * dstImageStride
- + dstYoffset * dstRowStride
- + dstXoffset * dstFormat->TexelBytes;
- GLint img, row;
- for (img = 0; img < srcDepth; img++) {
- GLubyte *dstRow = dstImage;
- for (row = 0; row < srcHeight; row++) {
- const GLvoid *src = _mesa_image_address(srcPacking,
- srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
- _mesa_unpack_index_span(ctx, srcWidth, CHAN_TYPE, dstRow,
- srcType, src, srcPacking,
- ctx->_ImageTransferState);
- dstRow += dstRowStride;
- }
- dstImage += dstImageStride;
- }
- }
- return GL_TRUE;
-}
-
-
/**
* Store a floating point depth component texture image.
*/
GLboolean
_mesa_texstore_depth_component_float32(STORE_PARAMS)
{
+ (void) dims;
ASSERT(dstFormat == &_mesa_texformat_depth_component_float32);
ASSERT(dstFormat->TexelBytes == sizeof(GLfloat));
srcFormat == GL_DEPTH_COMPONENT &&
srcType == GL_FLOAT) {
/* simple memcpy path */
- memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+ memcpy_texture(dims,
+ dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
dstRowStride, dstImageStride,
srcWidth, srcHeight, srcDepth, srcFormat, srcType,
srcAddr, srcPacking);
for (img = 0; img < srcDepth; img++) {
GLubyte *dstRow = dstImage;
for (row = 0; row < srcHeight; row++) {
- const GLvoid *src = _mesa_image_address(srcPacking,
+ const GLvoid *src = _mesa_image_address(dims, srcPacking,
srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
_mesa_unpack_depth_span(ctx, srcWidth, (GLfloat *) dstRow,
srcType, src, srcPacking);
GLboolean
_mesa_texstore_depth_component16(STORE_PARAMS)
{
+ (void) dims;
ASSERT(dstFormat == &_mesa_texformat_depth_component16);
ASSERT(dstFormat->TexelBytes == sizeof(GLushort));
srcFormat == GL_DEPTH_COMPONENT &&
srcType == GL_UNSIGNED_SHORT) {
/* simple memcpy path */
- memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+ memcpy_texture(dims,
+ dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
dstRowStride, dstImageStride,
srcWidth, srcHeight, srcDepth, srcFormat, srcType,
srcAddr, srcPacking);
GLubyte *dstRow = dstImage;
for (row = 0; row < srcHeight; row++) {
GLfloat depthTemp[MAX_WIDTH];
- const GLvoid *src = _mesa_image_address(srcPacking,
+ const GLvoid *src = _mesa_image_address(dims, srcPacking,
srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
GLushort *dst16 = (GLushort *) dstRow;
_mesa_unpack_depth_span(ctx, srcWidth, depthTemp,
}
-
-
/**
- * Store an rgb565 texture image.
+ * Store an rgb565 or rgb565_rev texture image.
*/
GLboolean
_mesa_texstore_rgb565(STORE_PARAMS)
{
- ASSERT(dstFormat == &_mesa_texformat_rgb565);
+ ASSERT(dstFormat == &_mesa_texformat_rgb565 ||
+ dstFormat == &_mesa_texformat_rgb565_rev);
ASSERT(dstFormat->TexelBytes == 2);
if (!ctx->_ImageTransferState &&
!srcPacking->SwapBytes &&
+ dstFormat == &_mesa_texformat_rgb565 &&
baseInternalFormat == GL_RGB &&
srcFormat == GL_RGB &&
srcType == GL_UNSIGNED_SHORT_5_6_5) {
/* simple memcpy path */
- memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+ memcpy_texture(dims,
+ dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
dstRowStride, dstImageStride,
srcWidth, srcHeight, srcDepth, srcFormat, srcType,
srcAddr, srcPacking);
const GLint srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth,
srcFormat, srcType);
const GLubyte *src = (const GLubyte *)
- _mesa_image_address(srcPacking, srcAddr, srcWidth, srcHeight,
+ _mesa_image_address(dims, srcPacking, srcAddr, srcWidth, srcHeight,
srcFormat, srcType, 0, 0, 0);
GLubyte *dst = (GLubyte *) dstAddr
+ dstZoffset * dstImageStride
for (row = 0; row < srcHeight; row++) {
const GLubyte *srcUB = (const GLubyte *) src;
GLushort *dstUS = (GLushort *) dst;
- for (col = 0; col < srcWidth; col++) {
- dstUS[col] = PACK_COLOR_565( srcUB[0], srcUB[1], srcUB[2] );
- srcUB += 3;
+ /* check for byteswapped format */
+ if (dstFormat == &_mesa_texformat_rgb565) {
+ for (col = 0; col < srcWidth; col++) {
+ dstUS[col] = PACK_COLOR_565( srcUB[0], srcUB[1], srcUB[2] );
+ srcUB += 3;
+ }
+ }
+ else {
+ for (col = 0; col < srcWidth; col++) {
+ dstUS[col] = PACK_COLOR_565_REV( srcUB[0], srcUB[1], srcUB[2] );
+ srcUB += 3;
+ }
}
dst += dstRowStride;
src += srcRowStride;
}
else {
/* general path */
- const GLchan *tempImage = make_temp_chan_image(ctx, dims,
+ const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
baseInternalFormat,
dstFormat->BaseFormat,
srcWidth, srcHeight, srcDepth,
GLubyte *dstRow = dstImage;
for (row = 0; row < srcHeight; row++) {
GLushort *dstUS = (GLushort *) dstRow;
- for (col = 0; col < srcWidth; col++) {
- dstUS[col] = PACK_COLOR_565( CHAN_TO_UBYTE(src[RCOMP]),
- CHAN_TO_UBYTE(src[GCOMP]),
- CHAN_TO_UBYTE(src[BCOMP]) );
- src += 3;
+ /* check for byteswapped format */
+ if (dstFormat == &_mesa_texformat_rgb565) {
+ for (col = 0; col < srcWidth; col++) {
+ dstUS[col] = PACK_COLOR_565( CHAN_TO_UBYTE(src[RCOMP]),
+ CHAN_TO_UBYTE(src[GCOMP]),
+ CHAN_TO_UBYTE(src[BCOMP]) );
+ src += 3;
+ }
+ }
+ else {
+ for (col = 0; col < srcWidth; col++) {
+ dstUS[col] = PACK_COLOR_565_REV( CHAN_TO_UBYTE(src[RCOMP]),
+ CHAN_TO_UBYTE(src[GCOMP]),
+ CHAN_TO_UBYTE(src[BCOMP]) );
+ src += 3;
+ }
}
dstRow += dstRowStride;
}
const GLuint ui = 1;
const GLubyte littleEndian = *((const GLubyte *) &ui);
- ASSERT(dstFormat == &_mesa_texformat_rgba8888);
+ (void)littleEndian;
+ ASSERT(dstFormat == &_mesa_texformat_rgba8888 ||
+ dstFormat == &_mesa_texformat_rgba8888_rev);
ASSERT(dstFormat->TexelBytes == 4);
if (!ctx->_ImageTransferState &&
!srcPacking->SwapBytes &&
+ dstFormat == &_mesa_texformat_rgba8888 &&
baseInternalFormat == GL_RGBA &&
- srcFormat == GL_RGBA &&
- ((srcType == GL_UNSIGNED_INT_8_8_8_8_REV && littleEndian) ||
- (srcType == GL_UNSIGNED_INT_8_8_8_8 && !littleEndian))) {
+ ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
+ (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8_REV))) {
/* simple memcpy path */
- memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+ memcpy_texture(dims,
+ dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
dstRowStride, dstImageStride,
srcWidth, srcHeight, srcDepth, srcFormat, srcType,
srcAddr, srcPacking);
}
+#if 0
+ else if (!ctx->_ImageTransferState &&
+ !srcPacking->SwapBytes &&
+ srcType == GL_UNSIGNED_BYTE &&
+ dstFormat == &_mesa_texformat_rgba8888 &&
+ littleEndian &&
+ can_swizzle(srcFormat)) {
+ GLubyte dstmap[4];
+
+ /* dstmap - how to swizzle from GL_RGBA to dst format:
+ *
+ * FIXME - add !litteEndian and _rev varients:
+ */
+ dstmap[3] = 0;
+ dstmap[2] = 1;
+ dstmap[1] = 2;
+ dstmap[0] = 3;
+
+ _mesa_swizzle_ubyte_image(ctx, dims,
+ srcFormat,
+ dstmap, 4,
+ dstAddr, dstXoffset, dstYoffset, dstZoffset,
+ dstRowStride, dstImageStride,
+ srcWidth, srcHeight, srcDepth, srcAddr,
+ srcPacking);
+ }
+#endif
else {
/* general path */
- const GLchan *tempImage = make_temp_chan_image(ctx, dims,
+ const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
baseInternalFormat,
dstFormat->BaseFormat,
srcWidth, srcHeight, srcDepth,
GLubyte *dstRow = dstImage;
for (row = 0; row < srcHeight; row++) {
GLuint *dstUI = (GLuint *) dstRow;
- for (col = 0; col < srcWidth; col++) {
- dstUI[col] = PACK_COLOR_8888( CHAN_TO_UBYTE(src[RCOMP]),
- CHAN_TO_UBYTE(src[GCOMP]),
- CHAN_TO_UBYTE(src[BCOMP]),
- CHAN_TO_UBYTE(src[ACOMP]) );
- src += 4;
+ if (dstFormat == &_mesa_texformat_rgba8888) {
+ for (col = 0; col < srcWidth; col++) {
+ dstUI[col] = PACK_COLOR_8888( CHAN_TO_UBYTE(src[RCOMP]),
+ CHAN_TO_UBYTE(src[GCOMP]),
+ CHAN_TO_UBYTE(src[BCOMP]),
+ CHAN_TO_UBYTE(src[ACOMP]) );
+ src += 4;
+ }
+ }
+ else {
+ for (col = 0; col < srcWidth; col++) {
+ dstUI[col] = PACK_COLOR_8888_REV( CHAN_TO_UBYTE(src[RCOMP]),
+ CHAN_TO_UBYTE(src[GCOMP]),
+ CHAN_TO_UBYTE(src[BCOMP]),
+ CHAN_TO_UBYTE(src[ACOMP]) );
+ src += 4;
+ }
}
dstRow += dstRowStride;
}
const GLuint ui = 1;
const GLubyte littleEndian = *((const GLubyte *) &ui);
- ASSERT(dstFormat == &_mesa_texformat_argb8888);
+ ASSERT(dstFormat == &_mesa_texformat_argb8888 ||
+ dstFormat == &_mesa_texformat_argb8888_rev);
ASSERT(dstFormat->TexelBytes == 4);
if (!ctx->_ImageTransferState &&
!srcPacking->SwapBytes &&
+ dstFormat == &_mesa_texformat_argb8888 &&
baseInternalFormat == GL_RGBA &&
srcFormat == GL_BGRA &&
((srcType == GL_UNSIGNED_BYTE && littleEndian) ||
- (srcType == GL_UNSIGNED_INT_8_8_8_8_REV && littleEndian) ||
- (srcType == GL_UNSIGNED_INT_8_8_8_8 && !littleEndian))) {
- /* simple memcpy path */
- memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+ srcType == GL_UNSIGNED_INT_8_8_8_8_REV)) {
+ /* simple memcpy path (little endian) */
+ memcpy_texture(dims,
+ dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
dstRowStride, dstImageStride,
srcWidth, srcHeight, srcDepth, srcFormat, srcType,
srcAddr, srcPacking);
}
+ else if (!ctx->_ImageTransferState &&
+ !srcPacking->SwapBytes &&
+ dstFormat == &_mesa_texformat_argb8888_rev &&
+ baseInternalFormat == GL_RGBA &&
+ srcFormat == GL_BGRA &&
+ ((srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
+ srcType == GL_UNSIGNED_INT_8_8_8_8)) {
+ /* simple memcpy path (big endian) */
+ memcpy_texture(dims,
+ dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+ dstRowStride, dstImageStride,
+ srcWidth, srcHeight, srcDepth, srcFormat, srcType,
+ srcAddr, srcPacking);
+ }
+ else if (!ctx->_ImageTransferState &&
+ !srcPacking->SwapBytes &&
+ dstFormat == &_mesa_texformat_argb8888 &&
+ srcFormat == GL_RGB &&
+ srcType == GL_UNSIGNED_BYTE) {
+
+ int img, row, col;
+ GLubyte *dstImage = (GLubyte *) dstAddr
+ + dstZoffset * dstImageStride
+ + dstYoffset * dstRowStride
+ + dstXoffset * dstFormat->TexelBytes;
+ for (img = 0; img < srcDepth; img++) {
+ const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
+ srcWidth, srcFormat, srcType);
+ GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
+ srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
+ GLubyte *dstRow = dstImage;
+ for (row = 0; row < srcHeight; row++) {
+ for (col = 0; col < srcWidth; col++) {
+ dstRow[col * 4 + 0] = srcRow[col * 3 + BCOMP];
+ dstRow[col * 4 + 1] = srcRow[col * 3 + GCOMP];
+ dstRow[col * 4 + 2] = srcRow[col * 3 + RCOMP];
+ dstRow[col * 4 + 3] = 0xff;
+ }
+ dstRow += dstRowStride;
+ srcRow += srcRowStride;
+ }
+ dstImage += dstImageStride;
+ }
+ }
+ else if (!ctx->_ImageTransferState &&
+ !srcPacking->SwapBytes &&
+ dstFormat == &_mesa_texformat_argb8888 &&
+ srcFormat == GL_RGBA &&
+ srcType == GL_UNSIGNED_BYTE) {
+
+ int img, row, col;
+ GLubyte *dstImage = (GLubyte *) dstAddr
+ + dstZoffset * dstImageStride
+ + dstYoffset * dstRowStride
+ + dstXoffset * dstFormat->TexelBytes;
+ for (img = 0; img < srcDepth; img++) {
+ const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
+ srcWidth, srcFormat, srcType);
+ GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
+ srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
+ GLubyte *dstRow = dstImage;
+ for (row = 0; row < srcHeight; row++) {
+ for (col = 0; col < srcWidth; col++) {
+ dstRow[col * 4 + 0] = srcRow[col * 4 + BCOMP];
+ dstRow[col * 4 + 1] = srcRow[col * 4 + GCOMP];
+ dstRow[col * 4 + 2] = srcRow[col * 4 + RCOMP];
+ dstRow[col * 4 + 3] = srcRow[col * 4 + ACOMP];
+ }
+ dstRow += dstRowStride;
+ srcRow += srcRowStride;
+ }
+ dstImage += dstImageStride;
+ }
+ }
+ else if (!ctx->_ImageTransferState &&
+ !srcPacking->SwapBytes &&
+ dstFormat == &_mesa_texformat_argb8888 &&
+ srcType == GL_UNSIGNED_BYTE &&
+ littleEndian &&
+ can_swizzle(srcFormat)) {
+
+ GLubyte dstmap[4];
+
+ /* dstmap - how to swizzle from GL_RGBA to dst format:
+ */
+ dstmap[3] = 3; /* alpha */
+ dstmap[2] = 0; /* red */
+ dstmap[1] = 1; /* green */
+ dstmap[0] = 2; /* blue */
+
+ _mesa_swizzle_ubyte_image(ctx, dims,
+ srcFormat,
+ dstmap, 4,
+ dstAddr, dstXoffset, dstYoffset, dstZoffset,
+ dstRowStride, dstImageStride,
+ srcWidth, srcHeight, srcDepth, srcAddr,
+ srcPacking);
+ }
else {
/* general path */
- const GLchan *tempImage = make_temp_chan_image(ctx, dims,
+ const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
baseInternalFormat,
dstFormat->BaseFormat,
srcWidth, srcHeight, srcDepth,
GLubyte *dstRow = dstImage;
for (row = 0; row < srcHeight; row++) {
GLuint *dstUI = (GLuint *) dstRow;
- for (col = 0; col < srcWidth; col++) {
- dstUI[col] = PACK_COLOR_8888( CHAN_TO_UBYTE(src[ACOMP]),
- CHAN_TO_UBYTE(src[RCOMP]),
- CHAN_TO_UBYTE(src[GCOMP]),
- CHAN_TO_UBYTE(src[BCOMP]) );
- src += 4;
+ if (dstFormat == &_mesa_texformat_argb8888) {
+ for (col = 0; col < srcWidth; col++) {
+ dstUI[col] = PACK_COLOR_8888( CHAN_TO_UBYTE(src[ACOMP]),
+ CHAN_TO_UBYTE(src[RCOMP]),
+ CHAN_TO_UBYTE(src[GCOMP]),
+ CHAN_TO_UBYTE(src[BCOMP]) );
+ src += 4;
+ }
+ }
+ else {
+ for (col = 0; col < srcWidth; col++) {
+ dstUI[col] = PACK_COLOR_8888_REV( CHAN_TO_UBYTE(src[ACOMP]),
+ CHAN_TO_UBYTE(src[RCOMP]),
+ CHAN_TO_UBYTE(src[GCOMP]),
+ CHAN_TO_UBYTE(src[BCOMP]) );
+ src += 4;
+ }
}
dstRow += dstRowStride;
}
}
-
GLboolean
_mesa_texstore_rgb888(STORE_PARAMS)
{
srcType == GL_UNSIGNED_BYTE &&
littleEndian) {
/* simple memcpy path */
- memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+ memcpy_texture(dims,
+ dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
dstRowStride, dstImageStride,
srcWidth, srcHeight, srcDepth, srcFormat, srcType,
srcAddr, srcPacking);
!srcPacking->SwapBytes &&
srcFormat == GL_RGBA &&
srcType == GL_UNSIGNED_BYTE) {
- /* extract BGR from RGBA */
+ /* extract RGB from RGBA */
int img, row, col;
GLubyte *dstImage = (GLubyte *) dstAddr
+ dstZoffset * dstImageStride
for (img = 0; img < srcDepth; img++) {
const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
srcWidth, srcFormat, srcType);
- GLubyte *srcRow = _mesa_image_address(srcPacking, srcAddr, srcWidth,
- srcHeight, srcFormat, srcType,
- img, 0, 0);
+ GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
+ srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
GLubyte *dstRow = dstImage;
for (row = 0; row < srcHeight; row++) {
for (col = 0; col < srcWidth; col++) {
}
else {
/* general path */
- const GLchan *tempImage = make_temp_chan_image(ctx, dims,
+ const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
baseInternalFormat,
dstFormat->BaseFormat,
srcWidth, srcHeight, srcDepth,
srcFormat, srcType, srcAddr,
srcPacking);
- const GLchan *src = (const GLubyte *) tempImage;
+ const GLchan *src = (const GLchan *) tempImage;
GLubyte *dstImage = (GLubyte *) dstAddr
+ dstZoffset * dstImageStride
+ dstYoffset * dstRowStride
GLboolean
-_mesa_texstore_argb4444(STORE_PARAMS)
+_mesa_texstore_bgr888(STORE_PARAMS)
{
const GLuint ui = 1;
const GLubyte littleEndian = *((const GLubyte *) &ui);
- ASSERT(dstFormat == &_mesa_texformat_argb4444);
+ ASSERT(dstFormat == &_mesa_texformat_bgr888);
+ ASSERT(dstFormat->TexelBytes == 3);
+
+ if (!ctx->_ImageTransferState &&
+ !srcPacking->SwapBytes &&
+ baseInternalFormat == GL_RGB &&
+ srcFormat == GL_RGB &&
+ srcType == GL_UNSIGNED_BYTE &&
+ littleEndian) {
+ /* simple memcpy path */
+ memcpy_texture(dims,
+ dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+ dstRowStride, dstImageStride,
+ srcWidth, srcHeight, srcDepth, srcFormat, srcType,
+ srcAddr, srcPacking);
+ }
+ else if (!ctx->_ImageTransferState &&
+ !srcPacking->SwapBytes &&
+ srcFormat == GL_RGBA &&
+ srcType == GL_UNSIGNED_BYTE) {
+ /* extract BGR from RGBA */
+ int img, row, col;
+ GLubyte *dstImage = (GLubyte *) dstAddr
+ + dstZoffset * dstImageStride
+ + dstYoffset * dstRowStride
+ + dstXoffset * dstFormat->TexelBytes;
+ for (img = 0; img < srcDepth; img++) {
+ const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
+ srcWidth, srcFormat, srcType);
+ GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
+ srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
+ GLubyte *dstRow = dstImage;
+ for (row = 0; row < srcHeight; row++) {
+ for (col = 0; col < srcWidth; col++) {
+ dstRow[col * 3 + 0] = srcRow[col * 4 + RCOMP];
+ dstRow[col * 3 + 1] = srcRow[col * 4 + GCOMP];
+ dstRow[col * 3 + 2] = srcRow[col * 4 + BCOMP];
+ }
+ dstRow += dstRowStride;
+ srcRow += srcRowStride;
+ }
+ dstImage += dstImageStride;
+ }
+ }
+ else {
+ /* general path */
+ const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
+ baseInternalFormat,
+ dstFormat->BaseFormat,
+ srcWidth, srcHeight, srcDepth,
+ srcFormat, srcType, srcAddr,
+ srcPacking);
+ const GLchan *src = (const GLchan *) tempImage;
+ GLubyte *dstImage = (GLubyte *) dstAddr
+ + dstZoffset * dstImageStride
+ + dstYoffset * dstRowStride
+ + dstXoffset * dstFormat->TexelBytes;
+ GLint img, row, col;
+ if (!tempImage)
+ return GL_FALSE;
+ _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
+ for (img = 0; img < srcDepth; img++) {
+ GLubyte *dstRow = dstImage;
+ for (row = 0; row < srcHeight; row++) {
+ for (col = 0; col < srcWidth; col++) {
+ dstRow[col * 3 + 0] = CHAN_TO_UBYTE(src[RCOMP]);
+ dstRow[col * 3 + 1] = CHAN_TO_UBYTE(src[GCOMP]);
+ dstRow[col * 3 + 2] = CHAN_TO_UBYTE(src[BCOMP]);
+ src += 3;
+ }
+ dstRow += dstRowStride;
+ }
+ dstImage += dstImageStride;
+ }
+ _mesa_free((void *) tempImage);
+ }
+ return GL_TRUE;
+}
+
+
+GLboolean
+_mesa_texstore_argb4444(STORE_PARAMS)
+{
+ ASSERT(dstFormat == &_mesa_texformat_argb4444 ||
+ dstFormat == &_mesa_texformat_argb4444_rev);
ASSERT(dstFormat->TexelBytes == 2);
if (!ctx->_ImageTransferState &&
!srcPacking->SwapBytes &&
+ dstFormat == &_mesa_texformat_argb4444 &&
baseInternalFormat == GL_RGBA &&
srcFormat == GL_BGRA &&
- ((srcType == GL_UNSIGNED_SHORT_4_4_4_4_REV && littleEndian) ||
- (srcType == GL_UNSIGNED_SHORT_4_4_4_4 && !littleEndian))) {
+ srcType == GL_UNSIGNED_SHORT_4_4_4_4_REV) {
/* simple memcpy path */
- memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+ memcpy_texture(dims,
+ dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
dstRowStride, dstImageStride,
srcWidth, srcHeight, srcDepth, srcFormat, srcType,
srcAddr, srcPacking);
}
else {
/* general path */
- const GLchan *tempImage = make_temp_chan_image(ctx, dims,
+ const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
baseInternalFormat,
dstFormat->BaseFormat,
srcWidth, srcHeight, srcDepth,
GLubyte *dstRow = dstImage;
for (row = 0; row < srcHeight; row++) {
GLushort *dstUS = (GLushort *) dstRow;
- for (col = 0; col < srcWidth; col++) {
- dstUS[col] = PACK_COLOR_4444( CHAN_TO_UBYTE(src[ACOMP]),
- CHAN_TO_UBYTE(src[RCOMP]),
- CHAN_TO_UBYTE(src[GCOMP]),
- CHAN_TO_UBYTE(src[BCOMP]) );
- src += 4;
+ if (dstFormat == &_mesa_texformat_argb4444) {
+ for (col = 0; col < srcWidth; col++) {
+ dstUS[col] = PACK_COLOR_4444( CHAN_TO_UBYTE(src[ACOMP]),
+ CHAN_TO_UBYTE(src[RCOMP]),
+ CHAN_TO_UBYTE(src[GCOMP]),
+ CHAN_TO_UBYTE(src[BCOMP]) );
+ src += 4;
+ }
+ }
+ else {
+ for (col = 0; col < srcWidth; col++) {
+ dstUS[col] = PACK_COLOR_4444_REV( CHAN_TO_UBYTE(src[ACOMP]),
+ CHAN_TO_UBYTE(src[RCOMP]),
+ CHAN_TO_UBYTE(src[GCOMP]),
+ CHAN_TO_UBYTE(src[BCOMP]) );
+ src += 4;
+ }
}
dstRow += dstRowStride;
}
}
+
GLboolean
_mesa_texstore_argb1555(STORE_PARAMS)
{
- const GLuint ui = 1;
- const GLubyte littleEndian = *((const GLubyte *) &ui);
-
- ASSERT(dstFormat == &_mesa_texformat_argb1555);
+ ASSERT(dstFormat == &_mesa_texformat_argb1555 ||
+ dstFormat == &_mesa_texformat_argb1555_rev);
ASSERT(dstFormat->TexelBytes == 2);
if (!ctx->_ImageTransferState &&
!srcPacking->SwapBytes &&
+ dstFormat == &_mesa_texformat_argb1555 &&
baseInternalFormat == GL_RGBA &&
srcFormat == GL_BGRA &&
- ((srcType == GL_UNSIGNED_SHORT_1_5_5_5_REV && littleEndian) ||
- (srcType == GL_UNSIGNED_SHORT_5_5_5_1 && !littleEndian))) {
+ srcType == GL_UNSIGNED_SHORT_1_5_5_5_REV) {
/* simple memcpy path */
- memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+ memcpy_texture(dims,
+ dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
dstRowStride, dstImageStride,
srcWidth, srcHeight, srcDepth, srcFormat, srcType,
srcAddr, srcPacking);
}
else {
/* general path */
- const GLchan *tempImage = make_temp_chan_image(ctx, dims,
+ const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
baseInternalFormat,
dstFormat->BaseFormat,
srcWidth, srcHeight, srcDepth,
GLubyte *dstRow = dstImage;
for (row = 0; row < srcHeight; row++) {
GLushort *dstUS = (GLushort *) dstRow;
- for (col = 0; col < srcWidth; col++) {
- dstUS[col] = PACK_COLOR_1555( CHAN_TO_UBYTE(src[ACOMP]),
- CHAN_TO_UBYTE(src[RCOMP]),
- CHAN_TO_UBYTE(src[GCOMP]),
- CHAN_TO_UBYTE(src[BCOMP]) );
- src += 4;
+ if (dstFormat == &_mesa_texformat_argb1555) {
+ for (col = 0; col < srcWidth; col++) {
+ dstUS[col] = PACK_COLOR_1555( CHAN_TO_UBYTE(src[ACOMP]),
+ CHAN_TO_UBYTE(src[RCOMP]),
+ CHAN_TO_UBYTE(src[GCOMP]),
+ CHAN_TO_UBYTE(src[BCOMP]) );
+ src += 4;
+ }
+ }
+ else {
+ for (col = 0; col < srcWidth; col++) {
+ dstUS[col] = PACK_COLOR_1555_REV( CHAN_TO_UBYTE(src[ACOMP]),
+ CHAN_TO_UBYTE(src[RCOMP]),
+ CHAN_TO_UBYTE(src[GCOMP]),
+ CHAN_TO_UBYTE(src[BCOMP]) );
+ src += 4;
+ }
}
dstRow += dstRowStride;
}
const GLuint ui = 1;
const GLubyte littleEndian = *((const GLubyte *) &ui);
- ASSERT(dstFormat == &_mesa_texformat_al88);
+ ASSERT(dstFormat == &_mesa_texformat_al88 ||
+ dstFormat == &_mesa_texformat_al88_rev);
ASSERT(dstFormat->TexelBytes == 2);
if (!ctx->_ImageTransferState &&
!srcPacking->SwapBytes &&
+ dstFormat == &_mesa_texformat_al88 &&
baseInternalFormat == GL_LUMINANCE_ALPHA &&
srcFormat == GL_LUMINANCE_ALPHA &&
srcType == GL_UNSIGNED_BYTE &&
littleEndian) {
/* simple memcpy path */
- memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+ memcpy_texture(dims,
+ dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
dstRowStride, dstImageStride,
srcWidth, srcHeight, srcDepth, srcFormat, srcType,
srcAddr, srcPacking);
}
else {
/* general path */
- const GLchan *tempImage = make_temp_chan_image(ctx, dims,
+ const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
baseInternalFormat,
dstFormat->BaseFormat,
srcWidth, srcHeight, srcDepth,
GLubyte *dstRow = dstImage;
for (row = 0; row < srcHeight; row++) {
GLushort *dstUS = (GLushort *) dstRow;
- for (col = 0; col < srcWidth; col++) {
- dstUS[col] = PACK_COLOR_88( CHAN_TO_UBYTE(src[ACOMP]),
- CHAN_TO_UBYTE(src[RCOMP]) );
- src += 2;
+ if (dstFormat == &_mesa_texformat_al88) {
+ for (col = 0; col < srcWidth; col++) {
+ /* src[0] is luminance, src[1] is alpha */
+ dstUS[col] = PACK_COLOR_88( CHAN_TO_UBYTE(src[1]),
+ CHAN_TO_UBYTE(src[0]) );
+ src += 2;
+ }
+ }
+ else {
+ for (col = 0; col < srcWidth; col++) {
+ /* src[0] is luminance, src[1] is alpha */
+ dstUS[col] = PACK_COLOR_88_REV( CHAN_TO_UBYTE(src[1]),
+ CHAN_TO_UBYTE(src[0]) );
+ src += 2;
+ }
}
dstRow += dstRowStride;
}
baseInternalFormat == GL_RGB &&
srcFormat == GL_RGB && srcType == GL_UNSIGNED_BYTE_3_3_2) {
/* simple memcpy path */
- memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+ memcpy_texture(dims,
+ dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
dstRowStride, dstImageStride,
srcWidth, srcHeight, srcDepth, srcFormat, srcType,
srcAddr, srcPacking);
}
else {
/* general path */
- const GLchan *tempImage = make_temp_chan_image(ctx, dims,
+ const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
baseInternalFormat,
dstFormat->BaseFormat,
srcWidth, srcHeight, srcDepth,
}
-
/**
* Texstore for _mesa_texformat_a8, _mesa_texformat_l8, _mesa_texformat_i8.
*/
baseInternalFormat == srcFormat &&
srcType == GL_UNSIGNED_BYTE) {
/* simple memcpy path */
- memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+ memcpy_texture(dims,
+ dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
dstRowStride, dstImageStride,
srcWidth, srcHeight, srcDepth, srcFormat, srcType,
srcAddr, srcPacking);
}
else {
/* general path */
- const GLchan *tempImage = make_temp_chan_image(ctx, dims,
+ const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
baseInternalFormat,
dstFormat->BaseFormat,
srcWidth, srcHeight, srcDepth,
GLboolean
_mesa_texstore_ci8(STORE_PARAMS)
{
+ (void) dims; (void) baseInternalFormat;
ASSERT(dstFormat == &_mesa_texformat_ci8);
ASSERT(dstFormat->TexelBytes == 1);
ASSERT(baseInternalFormat == GL_COLOR_INDEX);
srcFormat == GL_COLOR_INDEX &&
srcType == GL_UNSIGNED_BYTE) {
/* simple memcpy path */
- memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+ memcpy_texture(dims,
+ dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
dstRowStride, dstImageStride,
srcWidth, srcHeight, srcDepth, srcFormat, srcType,
srcAddr, srcPacking);
for (img = 0; img < srcDepth; img++) {
GLubyte *dstRow = dstImage;
for (row = 0; row < srcHeight; row++) {
- const GLvoid *src = _mesa_image_address(srcPacking,
+ const GLvoid *src = _mesa_image_address(dims, srcPacking,
srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
_mesa_unpack_index_span(ctx, srcWidth, GL_UNSIGNED_BYTE, dstRow,
srcType, src, srcPacking,
{
const GLuint ui = 1;
const GLubyte littleEndian = *((const GLubyte *) &ui);
+ (void) ctx; (void) dims; (void) baseInternalFormat;
ASSERT((dstFormat == &_mesa_texformat_ycbcr) ||
(dstFormat == &_mesa_texformat_ycbcr_rev));
ASSERT(baseInternalFormat == GL_YCBCR_MESA);
/* always just memcpy since no pixel transfer ops apply */
- memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+ memcpy_texture(dims,
+ dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
dstRowStride, dstImageStride,
srcWidth, srcHeight, srcDepth, srcFormat, srcType,
srcAddr, srcPacking);
baseInternalFormat == srcFormat &&
srcType == GL_FLOAT) {
/* simple memcpy path */
- memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+ memcpy_texture(dims,
+ dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
dstRowStride, dstImageStride,
srcWidth, srcHeight, srcDepth, srcFormat, srcType,
srcAddr, srcPacking);
srcFormat, srcType, srcAddr,
srcPacking);
const GLfloat *src = tempImage;
- const GLint bytesPerRow = srcWidth * components * sizeof(GLfloat);
+ GLint bytesPerRow;
GLubyte *dstImage = (GLubyte *) dstAddr
+ dstZoffset * dstImageStride
+ dstYoffset * dstRowStride
if (!tempImage)
return GL_FALSE;
_mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
+ bytesPerRow = srcWidth * components * sizeof(GLfloat);
for (img = 0; img < srcDepth; img++) {
GLubyte *dst = dstImage;
for (row = 0; row < srcHeight; row++) {
baseInternalFormat == GL_LUMINANCE_ALPHA ||
baseInternalFormat == GL_INTENSITY);
ASSERT(dstFormat->TexelBytes == components * sizeof(GLhalfARB));
-
- if (!ctx->_ImageTransferState &&
- !srcPacking->SwapBytes &&
- baseInternalFormat == srcFormat &&
- srcType == GL_HALF_FLOAT_ARB) {
- /* simple memcpy path */
- memcpy_texture(dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
- dstRowStride, dstImageStride,
- srcWidth, srcHeight, srcDepth, srcFormat, srcType,
- srcAddr, srcPacking);
- }
- else {
- /* general path */
- const GLfloat *tempImage = make_temp_float_image(ctx, dims,
- baseInternalFormat,
- dstFormat->BaseFormat,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType, srcAddr,
- srcPacking);
- const GLfloat *src = tempImage;
- GLubyte *dstImage = (GLubyte *) dstAddr
- + dstZoffset * dstImageStride
- + dstYoffset * dstRowStride
- + dstXoffset * dstFormat->TexelBytes;
- GLint img, row;
- if (!tempImage)
- return GL_FALSE;
- _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
- for (img = 0; img < srcDepth; img++) {
- GLubyte *dstRow = dstImage;
- for (row = 0; row < srcHeight; row++) {
- GLhalfARB *dstTexel = (GLhalfARB *) dstRow;
- GLint i;
- for (i = 0; i < srcWidth * components; i++) {
- dstTexel[i] = _mesa_float_to_half(src[i]);
- }
- dstRow += dstRowStride;
- src += srcWidth * components;
- }
- dstImage += dstImageStride;
- }
-
- _mesa_free((void *) tempImage);
- }
- return GL_TRUE;
-}
-
-
-#if !NEWTEXSTORE /*****************************************************/
-
-
-/*
- * Given an internal texture format enum or 1, 2, 3, 4 return the
- * corresponding _base_ internal format: GL_ALPHA, GL_LUMINANCE,
- * 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 )
-{
- switch (format) {
- case GL_ALPHA:
- case GL_ALPHA4:
- case GL_ALPHA8:
- case GL_ALPHA12:
- case GL_ALPHA16:
- return 1;
- case 1:
- case GL_LUMINANCE:
- case GL_LUMINANCE4:
- case GL_LUMINANCE8:
- case GL_LUMINANCE12:
- case GL_LUMINANCE16:
- return 1;
- case 2:
- case GL_LUMINANCE_ALPHA:
- case GL_LUMINANCE4_ALPHA4:
- case GL_LUMINANCE6_ALPHA2:
- case GL_LUMINANCE8_ALPHA8:
- case GL_LUMINANCE12_ALPHA4:
- case GL_LUMINANCE12_ALPHA12:
- case GL_LUMINANCE16_ALPHA16:
- return 2;
- case GL_INTENSITY:
- case GL_INTENSITY4:
- case GL_INTENSITY8:
- case GL_INTENSITY12:
- case GL_INTENSITY16:
- return 1;
- case 3:
- case GL_RGB:
- case GL_R3_G3_B2:
- case GL_RGB4:
- case GL_RGB5:
- case GL_RGB8:
- case GL_RGB10:
- case GL_RGB12:
- case GL_RGB16:
- return 3;
- case 4:
- case GL_RGBA:
- case GL_RGBA2:
- case GL_RGBA4:
- case GL_RGB5_A1:
- case GL_RGBA8:
- case GL_RGB10_A2:
- case GL_RGBA12:
- case GL_RGBA16:
- return 4;
- case GL_COLOR_INDEX:
- case GL_COLOR_INDEX1_EXT:
- case GL_COLOR_INDEX2_EXT:
- case GL_COLOR_INDEX4_EXT:
- case GL_COLOR_INDEX8_EXT:
- case GL_COLOR_INDEX12_EXT:
- case GL_COLOR_INDEX16_EXT:
- return 1;
- case GL_DEPTH_COMPONENT:
- case GL_DEPTH_COMPONENT16_SGIX:
- case GL_DEPTH_COMPONENT24_SGIX:
- case GL_DEPTH_COMPONENT32_SGIX:
- return 1;
- case GL_YCBCR_MESA:
- return 2; /* Y + (Cb or Cr) */
- default:
- return -1; /* error */
- }
-}
-
-
-/*
- * This function is used to transfer the user's image data into a texture
- * image buffer. We handle both full texture images and subtexture images.
- * We also take care of all image transfer operations here, including
- * convolution, scale/bias, colortables, etc.
- *
- * The destination texel type is always GLchan.
- * The destination texel format is one of the 6 basic types.
- *
- * A hardware driver may use this as a helper routine to unpack and
- * apply pixel transfer ops into a temporary image buffer. Then,
- * convert the temporary image into the special hardware format.
- *
- * \param
- * dimensions - 1, 2, or 3
- * texDestFormat - GL_LUMINANCE, GL_INTENSITY, GL_LUMINANCE_ALPHA, GL_ALPHA,
- * GL_RGB or GL_RGBA (the destination format)
- * texDestAddr - destination image address
- * srcWidth, srcHeight, srcDepth - size (in pixels) of src and dest images
- * dstXoffset, dstYoffset, dstZoffset - position to store the image within
- * the destination 3D texture
- * dstRowStride, dstImageStride - dest image strides in bytes
- * srcFormat - source image format (GL_ALPHA, GL_RED, GL_RGB, etc)
- * srcType - GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT_5_6_5, GL_FLOAT, etc
- * srcPacking - describes packing of incoming image.
- * transferOps - mask of pixel transfer operations
- */
-static void
-transfer_teximage(GLcontext *ctx, GLuint dimensions,
- GLenum texDestFormat, GLvoid *texDestAddr,
- GLint srcWidth, GLint srcHeight, GLint srcDepth,
- GLint dstXoffset, GLint dstYoffset, GLint dstZoffset,
- GLint dstRowStride, GLint dstImageStride,
- GLenum srcFormat, GLenum srcType,
- const GLvoid *srcAddr,
- const struct gl_pixelstore_attrib *srcPacking,
- GLuint transferOps)
-{
- GLint texComponents;
-
- ASSERT(ctx);
- ASSERT(dimensions >= 1 && dimensions <= 3);
- ASSERT(texDestFormat == GL_LUMINANCE ||
- texDestFormat == GL_INTENSITY ||
- texDestFormat == GL_LUMINANCE_ALPHA ||
- texDestFormat == GL_ALPHA ||
- texDestFormat == GL_RGB ||
- texDestFormat == GL_RGBA ||
- texDestFormat == GL_COLOR_INDEX ||
- texDestFormat == GL_DEPTH_COMPONENT);
- ASSERT(texDestAddr);
- ASSERT(srcWidth >= 0);
- ASSERT(srcHeight >= 0);
- ASSERT(srcDepth >= 0);
- ASSERT(dstXoffset >= 0);
- ASSERT(dstYoffset >= 0);
- ASSERT(dstZoffset >= 0);
- ASSERT(dstRowStride >= 0);
- ASSERT(dstImageStride >= 0);
- ASSERT(srcAddr);
- ASSERT(srcPacking);
-
- texComponents = components_in_intformat(texDestFormat);
-
- /* try common 2D texture cases first */
- if (!transferOps && dimensions == 2 && srcType == CHAN_TYPE) {
-
- if (srcFormat == texDestFormat) {
- /* This will cover the common GL_RGB, GL_RGBA, GL_ALPHA,
- * GL_LUMINANCE_ALPHA, etc. texture formats. Use memcpy().
- */
- const GLchan *src = (const GLchan *) _mesa_image_address(
- srcPacking, srcAddr, srcWidth, srcHeight,
- srcFormat, srcType, 0, 0, 0);
- const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
- srcWidth, srcFormat, srcType);
- const GLint widthInBytes = srcWidth * texComponents * sizeof(GLchan);
- GLchan *dst = (GLchan *) texDestAddr
- + dstYoffset * (dstRowStride / sizeof(GLchan))
- + dstXoffset * texComponents;
- if (srcRowStride == widthInBytes && dstRowStride == widthInBytes) {
- MEMCPY(dst, src, srcHeight * widthInBytes);
- }
- else {
- GLint i;
- for (i = 0; i < srcHeight; i++) {
- MEMCPY(dst, src, widthInBytes);
- src += (srcRowStride / sizeof(GLchan));
- dst += (dstRowStride / sizeof(GLchan));
- }
- }
- return; /* all done */
- }
- else if (srcFormat == GL_RGBA && texDestFormat == GL_RGB) {
- /* commonly used by Quake */
- const GLchan *src = (const GLchan *) _mesa_image_address(
- srcPacking, srcAddr, srcWidth, srcHeight,
- srcFormat, srcType, 0, 0, 0);
- const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
- srcWidth, srcFormat, srcType);
- GLchan *dst = (GLchan *) texDestAddr
- + dstYoffset * (dstRowStride / sizeof(GLchan))
- + dstXoffset * texComponents;
- GLint i, j;
- for (i = 0; i < srcHeight; i++) {
- const GLchan *s = src;
- GLchan *d = dst;
- for (j = 0; j < srcWidth; j++) {
- *d++ = *s++; /*red*/
- *d++ = *s++; /*green*/
- *d++ = *s++; /*blue*/
- s++; /*alpha*/
- }
- src += (srcRowStride / sizeof(GLchan));
- dst += (dstRowStride / sizeof(GLchan));
- }
- return; /* all done */
- }
- }
-
- /*
- * General case solutions
- */
- if (texDestFormat == GL_COLOR_INDEX) {
- /* color index texture */
- const GLenum texType = CHAN_TYPE;
- GLint img, row;
- GLchan *dest = (GLchan *) texDestAddr
- + dstZoffset * (dstImageStride / sizeof(GLchan))
- + dstYoffset * (dstRowStride / sizeof(GLchan))
- + dstXoffset * texComponents;
- for (img = 0; img < srcDepth; img++) {
- GLchan *destRow = dest;
- for (row = 0; row < srcHeight; row++) {
- const GLvoid *src = _mesa_image_address(srcPacking,
- srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
- _mesa_unpack_index_span(ctx, srcWidth, texType, destRow,
- srcType, src, srcPacking, transferOps);
- destRow += (dstRowStride / sizeof(GLchan));
- }
- dest += dstImageStride;
- }
- }
- else if (texDestFormat == GL_YCBCR_MESA) {
- /* YCbCr texture */
- GLint img, row;
- GLushort *dest = (GLushort *) texDestAddr
- + dstZoffset * (dstImageStride / sizeof(GLushort))
- + dstYoffset * (dstRowStride / sizeof(GLushort))
- + dstXoffset * texComponents;
- ASSERT(ctx->Extensions.MESA_ycbcr_texture);
- for (img = 0; img < srcDepth; img++) {
- GLushort *destRow = dest;
- for (row = 0; row < srcHeight; row++) {
- const GLvoid *srcRow = _mesa_image_address(srcPacking,
- srcAddr, srcWidth, srcHeight,
- srcFormat, srcType, img, row, 0);
- MEMCPY(destRow, srcRow, srcWidth * sizeof(GLushort));
- destRow += (dstRowStride / sizeof(GLushort));
- }
- dest += dstImageStride / sizeof(GLushort);
- }
- }
- else if (texDestFormat == GL_DEPTH_COMPONENT) {
- /* Depth texture (shadow maps) */
- GLint img, row;
- GLubyte *dest = (GLubyte *) texDestAddr
- + dstZoffset * dstImageStride
- + dstYoffset * (dstRowStride / sizeof(GLchan))
- + dstXoffset * texComponents;
- for (img = 0; img < srcDepth; img++) {
- GLubyte *destRow = dest;
- for (row = 0; row < srcHeight; row++) {
- const GLvoid *src = _mesa_image_address(srcPacking,
- srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
- _mesa_unpack_depth_span(ctx, srcWidth, (GLfloat *) destRow,
- srcType, src, srcPacking);
- destRow += (dstRowStride / sizeof(GLchan));
- }
- dest += dstImageStride;
- }
- }
- else {
- /* regular, color texture */
- if ((dimensions == 1 && ctx->Pixel.Convolution1DEnabled) ||
- (dimensions >= 2 && ctx->Pixel.Convolution2DEnabled) ||
- (dimensions >= 2 && ctx->Pixel.Separable2DEnabled)) {
- /*
- * Fill texture image with convolution
- */
- GLint img, row;
- GLint convWidth = srcWidth, convHeight = srcHeight;
- GLfloat *tmpImage, *convImage;
- tmpImage = (GLfloat *) MALLOC(srcWidth * srcHeight * 4 * sizeof(GLfloat));
- if (!tmpImage) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
- return;
- }
- convImage = (GLfloat *) MALLOC(srcWidth * srcHeight * 4 * sizeof(GLfloat));
- if (!convImage) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
- FREE(tmpImage);
- return;
- }
-
- for (img = 0; img < srcDepth; img++) {
- const GLfloat *srcf;
- GLfloat *dstf = tmpImage;
- GLchan *dest;
-
- /* unpack and do transfer ops up to convolution */
- for (row = 0; row < srcHeight; row++) {
- const GLvoid *src = _mesa_image_address(srcPacking,
- srcAddr, srcWidth, srcHeight,
- srcFormat, srcType, img, row, 0);
- _mesa_unpack_color_span_float(ctx, srcWidth, GL_RGBA, dstf,
- srcFormat, srcType, src, srcPacking,
- (transferOps & IMAGE_PRE_CONVOLUTION_BITS) | IMAGE_CLAMP_BIT);
- dstf += srcWidth * 4;
- }
-
- /* convolve */
- if (dimensions == 1) {
- ASSERT(ctx->Pixel.Convolution1DEnabled);
- _mesa_convolve_1d_image(ctx, &convWidth, tmpImage, convImage);
- }
- else {
- if (ctx->Pixel.Convolution2DEnabled) {
- _mesa_convolve_2d_image(ctx, &convWidth, &convHeight,
- tmpImage, convImage);
- }
- else {
- ASSERT(ctx->Pixel.Separable2DEnabled);
- _mesa_convolve_sep_image(ctx, &convWidth, &convHeight,
- tmpImage, convImage);
- }
- }
-
- /* packing and transfer ops after convolution */
- srcf = convImage;
- dest = (GLchan *) texDestAddr
- + (dstZoffset + img) * (dstImageStride / sizeof(GLchan))
- + dstYoffset * (dstRowStride / sizeof(GLchan));
- for (row = 0; row < convHeight; row++) {
- _mesa_pack_rgba_span_float(ctx, convWidth,
- (const GLfloat (*)[4]) srcf,
- texDestFormat, CHAN_TYPE,
- dest, &ctx->DefaultPacking,
- transferOps
- & IMAGE_POST_CONVOLUTION_BITS);
- srcf += convWidth * 4;
- dest += (dstRowStride / sizeof(GLchan));
- }
- }
-
- FREE(convImage);
- FREE(tmpImage);
- }
- else {
- /*
- * no convolution
- */
- GLint img, row;
- GLchan *dest = (GLchan *) texDestAddr
- + dstZoffset * (dstImageStride / sizeof(GLchan))
- + dstYoffset * (dstRowStride / sizeof(GLchan))
- + dstXoffset * texComponents;
- for (img = 0; img < srcDepth; img++) {
- GLchan *destRow = dest;
- for (row = 0; row < srcHeight; row++) {
- const GLvoid *srcRow = _mesa_image_address(srcPacking,
- srcAddr, srcWidth, srcHeight,
- srcFormat, srcType, img, row, 0);
- _mesa_unpack_color_span_chan(ctx, srcWidth, texDestFormat,
- destRow, srcFormat, srcType, srcRow,
- srcPacking, transferOps);
- destRow += (dstRowStride / sizeof(GLchan));
- }
- dest += dstImageStride / sizeof(GLchan);
- }
- }
- }
-}
-
-
-
-/*
- * Transfer a texture image from user space to <destAddr> applying all
- * needed image transfer operations and storing the result in the format
- * specified by <dstFormat>. <dstFormat> may be any format from texformat.h.
- * \param
- * dimensions - 1, 2 or 3
- * baseInternalFormat - base format of the internal texture format
- * specified by the user. This is very important, see below.
- * dstFormat - destination image format
- * dstAddr - destination address
- * srcWidth, srcHeight, srcDepth - size of source iamge
- * dstX/Y/Zoffset - as specified by glTexSubImage
- * dstRowStride - stride between dest rows in bytes
- * dstImageStride - stride between dest images in bytes
- * srcFormat, srcType - incoming image format and data type
- * srcAddr - source image address
- * srcPacking - packing params of source image
- *
- * XXX this function is a bit more complicated than it should be. If
- * _mesa_convert_texsubimage[123]d could handle any dest/source formats
- * or if transfer_teximage() could store in any MESA_FORMAT_* format, we
- * could simplify things here.
- */
-void
-_mesa_transfer_teximage(GLcontext *ctx, GLuint dimensions,
- GLenum baseInternalFormat,
- const struct gl_texture_format *dstFormat,
- GLvoid *dstAddr,
- GLint srcWidth, GLint srcHeight, GLint srcDepth,
- GLint dstXoffset, GLint dstYoffset, GLint dstZoffset,
- GLint dstRowStride, GLint dstImageStride,
- GLenum srcFormat, GLenum srcType,
- const GLvoid *srcAddr,
- const struct gl_pixelstore_attrib *srcPacking)
-{
- const GLint dstRowStridePixels = dstRowStride / dstFormat->TexelBytes;
- const GLint dstImageStridePixels = dstImageStride / dstFormat->TexelBytes;
- GLboolean makeTemp;
- GLuint transferOps = ctx->_ImageTransferState;
- GLboolean freeSourceData = GL_FALSE;
- GLint postConvWidth = srcWidth, postConvHeight = srcHeight;
-
- assert(baseInternalFormat > 0);
- ASSERT(baseInternalFormat == GL_LUMINANCE ||
- baseInternalFormat == GL_INTENSITY ||
- baseInternalFormat == GL_LUMINANCE_ALPHA ||
- baseInternalFormat == GL_ALPHA ||
- baseInternalFormat == GL_RGB ||
- baseInternalFormat == GL_RGBA ||
- baseInternalFormat == GL_YCBCR_MESA ||
- baseInternalFormat == GL_COLOR_INDEX ||
- baseInternalFormat == GL_DEPTH_COMPONENT);
-
- if (transferOps & IMAGE_CONVOLUTION_BIT) {
- _mesa_adjust_image_for_convolution(ctx, dimensions, &postConvWidth,
- &postConvHeight);
- }
-
- /*
- * Consider this scenario: The user's source image is GL_RGB and the
- * requested internal format is GL_LUMINANCE. Now suppose the device
- * driver doesn't support GL_LUMINANCE and instead uses RGB16 as the
- * texture format. In that case we still need to do an intermediate
- * conversion to luminance format so that the incoming red channel gets
- * replicated into the dest red, green and blue channels. The following
- * code takes care of that.
- */
- if (dstFormat->BaseFormat != baseInternalFormat) {
- /* Allocate storage for temporary image in the baseInternalFormat */
- const GLint texelSize = _mesa_components_in_format(baseInternalFormat)
- * sizeof(GLchan);
- const GLint bytes = texelSize * postConvWidth * postConvHeight *srcDepth;
- const GLint tmpRowStride = texelSize * postConvWidth;
- const GLint tmpImgStride = texelSize * postConvWidth * postConvHeight;
- GLvoid *tmpImage = MALLOC(bytes);
- if (!tmpImage)
- return;
- transfer_teximage(ctx, dimensions, baseInternalFormat, tmpImage,
- srcWidth, srcHeight, srcDepth,
- 0, 0, 0, /* x/y/zoffset */
- tmpRowStride, tmpImgStride,
- srcFormat, srcType, srcAddr, srcPacking, transferOps);
-
- /* this is our new source image */
- srcWidth = postConvWidth;
- srcHeight = postConvHeight;
- srcFormat = baseInternalFormat;
- srcType = CHAN_TYPE;
- srcAddr = tmpImage;
- srcPacking = &ctx->DefaultPacking;
- freeSourceData = GL_TRUE;
- transferOps = 0; /* image transfer ops were completed */
- }
-
- /* Let the optimized tex conversion functions take a crack at the
- * image conversion if the dest format is a h/w format.
- */
- if (_mesa_is_hardware_tex_format(dstFormat)) {
- if (transferOps) {
- makeTemp = GL_TRUE;
- }
- else {
- if (dimensions == 1) {
- makeTemp = !_mesa_convert_texsubimage1d(dstFormat->MesaFormat,
- dstXoffset,
- srcWidth,
- srcFormat, srcType,
- srcPacking, srcAddr,
- dstAddr);
- }
- else if (dimensions == 2) {
- makeTemp = !_mesa_convert_texsubimage2d(dstFormat->MesaFormat,
- dstXoffset, dstYoffset,
- srcWidth, srcHeight,
- dstRowStridePixels,
- srcFormat, srcType,
- srcPacking, srcAddr,
- dstAddr);
- }
- else {
- assert(dimensions == 3);
- makeTemp = !_mesa_convert_texsubimage3d(dstFormat->MesaFormat,
- dstXoffset, dstYoffset, dstZoffset,
- srcWidth, srcHeight, srcDepth,
- dstRowStridePixels, dstImageStridePixels,
- srcFormat, srcType,
- srcPacking, srcAddr, dstAddr);
- }
- if (!makeTemp) {
- /* all done! */
- if (freeSourceData)
- FREE((void *) srcAddr);
- return;
- }
- }
+
+ if (!ctx->_ImageTransferState &&
+ !srcPacking->SwapBytes &&
+ baseInternalFormat == srcFormat &&
+ srcType == GL_HALF_FLOAT_ARB) {
+ /* simple memcpy path */
+ memcpy_texture(dims,
+ dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+ dstRowStride, dstImageStride,
+ srcWidth, srcHeight, srcDepth, srcFormat, srcType,
+ srcAddr, srcPacking);
}
else {
- /* software texture format */
- makeTemp = GL_FALSE;
- }
-
- if (makeTemp) {
- GLint postConvWidth = srcWidth, postConvHeight = srcHeight;
- GLenum tmpFormat;
- GLuint tmpComps, tmpTexelSize;
- GLint tmpRowStride, tmpImageStride;
- GLubyte *tmpImage;
-
- if (transferOps & IMAGE_CONVOLUTION_BIT) {
- _mesa_adjust_image_for_convolution(ctx, dimensions, &postConvWidth,
- &postConvHeight);
- }
-
- tmpFormat = dstFormat->BaseFormat;
- tmpComps = _mesa_components_in_format(tmpFormat);
- tmpTexelSize = tmpComps * sizeof(GLchan);
- tmpRowStride = postConvWidth * tmpTexelSize;
- tmpImageStride = postConvWidth * postConvHeight * tmpTexelSize;
- tmpImage = (GLubyte *) MALLOC(postConvWidth * postConvHeight *
- srcDepth * tmpTexelSize);
- if (!tmpImage) {
- if (freeSourceData)
- FREE((void *) srcAddr);
- return;
+ /* general path */
+ const GLfloat *tempImage = make_temp_float_image(ctx, dims,
+ baseInternalFormat,
+ dstFormat->BaseFormat,
+ srcWidth, srcHeight, srcDepth,
+ srcFormat, srcType, srcAddr,
+ srcPacking);
+ const GLfloat *src = tempImage;
+ GLubyte *dstImage = (GLubyte *) dstAddr
+ + dstZoffset * dstImageStride
+ + dstYoffset * dstRowStride
+ + dstXoffset * dstFormat->TexelBytes;
+ GLint img, row;
+ if (!tempImage)
+ return GL_FALSE;
+ _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
+ for (img = 0; img < srcDepth; img++) {
+ GLubyte *dstRow = dstImage;
+ for (row = 0; row < srcHeight; row++) {
+ GLhalfARB *dstTexel = (GLhalfARB *) dstRow;
+ GLint i;
+ for (i = 0; i < srcWidth * components; i++) {
+ dstTexel[i] = _mesa_float_to_half(src[i]);
+ }
+ dstRow += dstRowStride;
+ src += srcWidth * components;
+ }
+ dstImage += dstImageStride;
}
- transfer_teximage(ctx, dimensions, tmpFormat, tmpImage,
- srcWidth, srcHeight, srcDepth,
- 0, 0, 0, /* x/y/zoffset */
- tmpRowStride, tmpImageStride,
- srcFormat, srcType, srcAddr, srcPacking, transferOps);
-
- if (freeSourceData)
- FREE((void *) srcAddr);
-
- /* the temp image is our new source image */
- srcWidth = postConvWidth;
- srcHeight = postConvHeight;
- srcFormat = tmpFormat;
- srcType = CHAN_TYPE;
- srcAddr = tmpImage;
- srcPacking = &ctx->DefaultPacking;
- freeSourceData = GL_TRUE;
- }
-
- if (_mesa_is_hardware_tex_format(dstFormat)) {
- assert(makeTemp);
- if (dimensions == 1) {
- GLboolean b;
- b = _mesa_convert_texsubimage1d(dstFormat->MesaFormat,
- dstXoffset,
- srcWidth,
- srcFormat, srcType,
- srcPacking, srcAddr,
- dstAddr);
- assert(b);
- (void) b;
- }
- else if (dimensions == 2) {
- GLboolean b;
- b = _mesa_convert_texsubimage2d(dstFormat->MesaFormat,
- dstXoffset, dstYoffset,
- srcWidth, srcHeight,
- dstRowStridePixels,
- srcFormat, srcType,
- srcPacking, srcAddr,
- dstAddr);
- assert(b);
- (void) b;
- }
- else {
- GLboolean b;
- b = _mesa_convert_texsubimage3d(dstFormat->MesaFormat,
- dstXoffset, dstYoffset, dstZoffset,
- srcWidth, srcHeight, srcDepth,
- dstRowStridePixels, dstImageStridePixels,
- srcFormat, srcType,
- srcPacking, srcAddr, dstAddr);
- assert(b);
- (void) b;
- }
- }
- else {
- /* software format */
- assert(!makeTemp);
- transfer_teximage(ctx, dimensions, dstFormat->BaseFormat, dstAddr,
- srcWidth, srcHeight, srcDepth,
- dstXoffset, dstYoffset, dstZoffset,
- dstRowStride, dstImageStride,
- srcFormat, srcType, srcAddr, srcPacking, transferOps);
+ _mesa_free((void *) tempImage);
}
-
- if (freeSourceData)
- FREE((void *) srcAddr); /* the temp image */
+ return GL_TRUE;
}
/**
- * Given a user's uncompressed texture image, this function takes care of
- * pixel unpacking, pixel transfer, format conversion and compression.
+ * Check if an unpack PBO is active prior to fetching a texture image.
+ * If so, do bounds checking and map the buffer into main memory.
+ * Any errors detected will be recorded.
+ * The caller _must_ call _mesa_unmap_teximage_pbo() too!
*/
-static void
-transfer_compressed_teximage(GLcontext *ctx, GLuint dimensions,
- GLsizei width, GLsizei height, GLsizei depth,
- GLenum srcFormat, GLenum srcType,
- const struct gl_pixelstore_attrib *unpacking,
- const GLvoid *source,
- const struct gl_texture_format *dstFormat,
- GLubyte *dest,
- GLint dstRowStride)
+const GLvoid *
+_mesa_validate_pbo_teximage(GLcontext *ctx, GLuint dimensions,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLenum format, GLenum type, const GLvoid *pixels,
+ const struct gl_pixelstore_attrib *unpack,
+ const char *funcName)
{
- GLchan *tempImage = NULL;
- GLint srcRowStride;
- GLenum baseFormat;
-
- ASSERT(dimensions == 2);
- /* TexelBytes is zero if and only if it's a compressed format */
- ASSERT(dstFormat->TexelBytes == 0);
-
- baseFormat = dstFormat->BaseFormat;
+ GLubyte *buf;
- if (srcFormat != baseFormat || srcType != CHAN_TYPE ||
- ctx->_ImageTransferState != 0 || unpacking->SwapBytes) {
- /* need to convert user's image to texImage->Format, GLchan */
- GLint comps = components_in_intformat(baseFormat);
- GLint postConvWidth = width, postConvHeight = height;
-
- /* XXX convolution untested */
- if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
- _mesa_adjust_image_for_convolution(ctx, dimensions, &postConvWidth,
- &postConvHeight);
- }
-
- tempImage = (GLchan*) MALLOC(width * height * comps * sizeof(GLchan));
- if (!tempImage) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
- return;
- }
- transfer_teximage(ctx, dimensions,
- baseFormat, /* dest format */
- tempImage, /* dst address */
- width, height, depth, /* src size */
- 0, 0, 0, /* x/y/zoffset */
- comps * width, /* dst row stride */
- comps * width * height, /* dst image stride */
- srcFormat, srcType, /* src format, type */
- source, unpacking, /* src and src packing */
- ctx->_ImageTransferState);
- source = tempImage;
- width = postConvWidth;
- height = postConvHeight;
- srcRowStride = width;
+ if (unpack->BufferObj->Name == 0) {
+ /* no PBO */
+ return pixels;
}
- else {
- if (unpacking->RowLength)
- srcRowStride = unpacking->RowLength;
- else
- srcRowStride = width;
+ if (!_mesa_validate_pbo_access(dimensions, unpack, width, height, depth,
+ format, type, pixels)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(invalid PBO access");
+ return NULL;
}
- _mesa_compress_teximage(ctx, width, height, baseFormat,
- (const GLchan *) source, srcRowStride,
- dstFormat, dest, dstRowStride);
- if (tempImage) {
- FREE(tempImage);
+ buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
+ GL_READ_ONLY_ARB, unpack->BufferObj);
+ if (!buf) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(PBO is mapped");
+ return NULL;
}
-}
-
-
-#endif /************************************************************/
-
+ return ADD_POINTERS(buf, pixels);
+}
/**
- * Validate acces to a PBO for texture data.
- *
- * \todo If the PBO is really resident in VRAM, this won't work; the
- * device driver should check for that and do the right thing.
+ * Check if an unpack PBO is active prior to fetching a compressed texture
+ * image.
+ * If so, do bounds checking and map the buffer into main memory.
+ * Any errors detected will be recorded.
+ * The caller _must_ call _mesa_unmap_teximage_pbo() too!
*/
-static const GLvoid *
-validate_pbo_teximage( GLsizei width, GLsizei height, GLsizei depth,
- GLenum format, GLenum type, const GLvoid *pixels,
- const struct gl_pixelstore_attrib *unpack )
+const GLvoid *
+_mesa_validate_pbo_compressed_teximage(GLcontext *ctx,
+ GLsizei imageSize, const GLvoid *pixels,
+ const struct gl_pixelstore_attrib *packing,
+ const char *funcName)
{
- if (unpack->BufferObj->Name == 0) {
- /* no PBO */
+ GLubyte *buf;
+
+ if (packing->BufferObj->Name == 0) {
+ /* not using a PBO - return pointer unchanged */
return pixels;
}
- else if (_mesa_validate_pbo_access(unpack, width, height, depth, format,
- type, pixels)) {
- return ADD_POINTERS(unpack->BufferObj->Data, pixels);
+ if ((const GLubyte *) pixels + imageSize >
+ (const GLubyte *) packing->BufferObj->Size) {
+ /* out of bounds read! */
+ _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(invalid PBO access");
+ return NULL;
+ }
+
+ buf = (GLubyte*) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
+ GL_READ_ONLY_ARB, packing->BufferObj);
+ if (!buf) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(PBO is mapped");
+ return NULL;
}
- /* bad access! */
- return NULL;
+
+ return ADD_POINTERS(buf, pixels);
}
/**
- * Validate that unpacking compressed texture image data from a PBO
- * won't go out of bounds.
- *
- * \todo If the PBO is really resident in VRAM, this won't work; the
- * device driver should check for that and do the right thing.
+ * This function must be called after either of the validate_pbo_*_teximage()
+ * functions. It unmaps the PBO buffer if it was mapped earlier.
*/
-static const GLvoid *
-validate_pbo_compressed_teximage(GLsizei imageSize, const GLvoid *pixels,
- const struct gl_pixelstore_attrib *packing)
+void
+_mesa_unmap_teximage_pbo(GLcontext *ctx, const struct gl_pixelstore_attrib *unpack)
{
- if (packing->BufferObj->Name == 0) {
- /* not using a PBO - return pointer unchanged */
- return pixels;
- }
- else {
- /* using a PBO */
- if ((const GLubyte *) pixels + imageSize >
- (const GLubyte *) packing->BufferObj->Size) {
- /* out of bounds read! */
- return NULL;
- }
- /* OK! */
- return ADD_POINTERS(packing->BufferObj->Data, pixels);
+ if (unpack->BufferObj->Name) {
+ ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
+ unpack->BufferObj);
}
}
-
/*
* This is the software fallback for Driver.TexImage1D()
* and Driver.CopyTexImage1D().
+ * \sa _mesa_store_teximage2d()
*/
void
_mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level,
{
GLint postConvWidth = width;
GLint sizeInBytes;
+ (void) border;
if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
_mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL);
return;
}
- pixels = validate_pbo_teximage(width, 1, 1, format, type, pixels, packing);
- if (!pixels)
+ pixels = _mesa_validate_pbo_teximage(ctx, 1, width, 1, 1, format, type, pixels,
+ packing, "glTexImage1D");
+ if (!pixels) {
+ /* Note: we check for a NULL image pointer here, _after_ we allocated
+ * memory for the texture. That's what the GL spec calls for.
+ */
return;
-
-#if NEWTEXSTORE
- {
+ }
+ else {
const GLint dstRowStride = 0, dstImageStride = 0;
GLboolean success;
ASSERT(texImage->TexFormat->StoreImage);
format, type, pixels, packing);
if (!success) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
- return;
}
}
-#else
- /* unpack image, apply transfer ops and store in texImage->Data */
- if (texImage->IsCompressed) {
- GLint dstRowStride = _mesa_compressed_row_stride(texImage->IntFormat,
- width);
- transfer_compressed_teximage(ctx, 1, width, 1, 1,
- format, type, packing,
- pixels, texImage->TexFormat,
- (GLubyte *) texImage->Data, dstRowStride);
- }
- else {
- _mesa_transfer_teximage(ctx, 1,
- texImage->Format, /* base format */
- texImage->TexFormat, texImage->Data,
- width, 1, 1, /* src size */
- 0, 0, 0, /* dstX/Y/Zoffset */
- 0, /* dstRowStride */
- 0, /* dstImageStride */
- format, type, pixels, packing);
- }
-#endif
/* GL_SGIS_generate_mipmap */
if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
&ctx->Texture.Unit[ctx->Texture.CurrentUnit],
texObj);
}
+
+ _mesa_unmap_teximage_pbo(ctx, packing);
}
-/*
+/**
* This is the software fallback for Driver.TexImage2D()
* and Driver.CopyTexImage2D().
+ * We store the image in heap memory. We know nothing about on-board
+ * VRAM here. But since most DRI drivers rely on keeping a copy of all
+ * textures in main memory, this routine will typically be used by
+ * hardware drivers too.
+ *
* Reasons why a driver might override this function:
- * - Special memory allocation needs
- * - Unusual row/image strides
+ * - Special memory allocation needs (VRAM, AGP, etc)
+ * - Unusual row/image strides or padding
* - Special housekeeping
+ * - Using VRAM-based Pixel Buffer Objects
*/
void
_mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level,
{
GLint postConvWidth = width, postConvHeight = height;
GLint texelBytes, sizeInBytes;
+ (void) border;
if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
_mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth,
return;
}
- pixels = validate_pbo_teximage(width, height, 1,
- format, type, pixels, packing);
- if (!pixels)
+ pixels = _mesa_validate_pbo_teximage(ctx, 2, width, height, 1, format, type,
+ pixels, packing, "glTexImage2D");
+ if (!pixels) {
+ /* Note: we check for a NULL image pointer here, _after_ we allocated
+ * memory for the texture. That's what the GL spec calls for.
+ */
return;
-
-#if NEWTEXSTORE
- {
+ }
+ else {
GLint dstRowStride, dstImageStride = 0;
GLboolean success;
if (texImage->IsCompressed) {
dstRowStride = _mesa_compressed_row_stride(texImage->IntFormat,width);
}
else {
- dstRowStride = width * texImage->TexFormat->TexelBytes;
+ dstRowStride = postConvWidth * texImage->TexFormat->TexelBytes;
}
ASSERT(texImage->TexFormat->StoreImage);
success = texImage->TexFormat->StoreImage(ctx, 2, texImage->Format,
format, type, pixels, packing);
if (!success) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
- return;
}
}
-#else
- /* unpack image, apply transfer ops and store in texImage->Data */
- if (texImage->IsCompressed) {
- GLint dstRowStride = _mesa_compressed_row_stride(texImage->IntFormat,
- width);
- transfer_compressed_teximage(ctx, 2, width, height, 1,
- format, type, packing,
- pixels, texImage->TexFormat,
- (GLubyte *) texImage->Data, dstRowStride);
- }
- else {
- _mesa_transfer_teximage(ctx, 2,
- texImage->Format,
- texImage->TexFormat, texImage->Data,
- width, height, 1, /* src size */
- 0, 0, 0, /* dstX/Y/Zoffset */
- texImage->Width * texelBytes, /* dstRowStride */
- 0, /* dstImageStride */
- format, type, pixels, packing);
- }
-#endif
/* GL_SGIS_generate_mipmap */
if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
&ctx->Texture.Unit[ctx->Texture.CurrentUnit],
texObj);
}
+
+ _mesa_unmap_teximage_pbo(ctx, packing);
}
-/*
+/**
* This is the software fallback for Driver.TexImage3D()
* and Driver.CopyTexImage3D().
+ * \sa _mesa_store_teximage2d()
*/
void
_mesa_store_teximage3d(GLcontext *ctx, GLenum target, GLint level,
struct gl_texture_image *texImage)
{
GLint texelBytes, sizeInBytes;
+ (void) border;
/* choose the texture format */
assert(ctx->Driver.ChooseTextureFormat);
return;
}
- pixels = validate_pbo_teximage(width, height, depth,
- format, type, pixels, packing);
- if (!pixels)
+ pixels = _mesa_validate_pbo_teximage(ctx, 3, width, height, depth, format, type,
+ pixels, packing, "glTexImage3D");
+ if (!pixels) {
+ /* Note: we check for a NULL image pointer here, _after_ we allocated
+ * memory for the texture. That's what the GL spec calls for.
+ */
return;
-
- /* unpack image, apply transfer ops and store in texImage->Data */
-#if NEWTEXSTORE
- {
+ }
+ else {
GLint dstRowStride, dstImageStride;
GLboolean success;
if (texImage->IsCompressed) {
format, type, pixels, packing);
if (!success) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
- return;
}
}
-#else
- if (texImage->IsCompressed) {
- GLint dstRowStride = _mesa_compressed_row_stride(texImage->IntFormat,
- width);
- transfer_compressed_teximage(ctx, 3, width, height, depth,
- format, type, packing,
- pixels, texImage->TexFormat,
- (GLubyte *) texImage->Data, dstRowStride);
- }
- else {
- _mesa_transfer_teximage(ctx, 3,
- texImage->Format,
- texImage->TexFormat, texImage->Data,
- width, height, depth, /* src size */
- 0, 0, 0, /* dstX/Y/Zoffset */
- texImage->Width * texelBytes, /* dstRowStride */
- texImage->Width * texImage->Height * texelBytes,
- format, type, pixels, packing);
- }
-#endif
/* GL_SGIS_generate_mipmap */
if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
&ctx->Texture.Unit[ctx->Texture.CurrentUnit],
texObj);
}
+
+ _mesa_unmap_teximage_pbo(ctx, packing);
}
struct gl_texture_object *texObj,
struct gl_texture_image *texImage)
{
- pixels = validate_pbo_teximage(width, 1, 1,
- format, type, pixels, packing);
+ pixels = _mesa_validate_pbo_teximage(ctx, 1, width, 1, 1, format, type, pixels,
+ packing, "glTexSubImage1D");
if (!pixels)
return;
-#if NEWTEXSTORE
{
const GLint dstRowStride = 0, dstImageStride = 0;
GLboolean success;
format, type, pixels, packing);
if (!success) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage1D");
- return;
}
}
-#else
- if (texImage->IsCompressed) {
- GLint dstRowStride = _mesa_compressed_row_stride(texImage->IntFormat,
- texImage->Width);
- GLubyte *dest = _mesa_compressed_image_address(xoffset, 0, 0,
- texImage->IntFormat,
- texImage->Width,
- (GLubyte*) texImage->Data);
- transfer_compressed_teximage(ctx, 1, /* dimensions */
- width, 1, 1, /* size to replace */
- format, type, /* source format/type */
- packing, /* source packing */
- pixels, /* source data */
- texImage->TexFormat,/* dest format */
- dest, dstRowStride);
- }
- else {
- _mesa_transfer_teximage(ctx, 1,
- texImage->Format,
- texImage->TexFormat, texImage->Data,
- width, 1, 1, /* src size */
- xoffset, 0, 0, /* dest offsets */
- 0, /* dstRowStride */
- 0, /* dstImageStride */
- format, type, pixels, packing);
- }
-#endif
/* GL_SGIS_generate_mipmap */
if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
&ctx->Texture.Unit[ctx->Texture.CurrentUnit],
texObj);
}
+
+ _mesa_unmap_teximage_pbo(ctx, packing);
}
struct gl_texture_object *texObj,
struct gl_texture_image *texImage)
{
- pixels = validate_pbo_teximage(width, height, 1,
- format, type, pixels, packing);
+ pixels = _mesa_validate_pbo_teximage(ctx, 2, width, height, 1, format, type,
+ pixels, packing, "glTexSubImage2D");
if (!pixels)
return;
-#if NEWTEXSTORE
{
GLint dstRowStride = 0, dstImageStride = 0;
GLboolean success;
format, type, pixels, packing);
if (!success) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D");
- return;
}
}
-#else
-
- if (texImage->IsCompressed) {
- GLint dstRowStride = _mesa_compressed_row_stride(texImage->IntFormat,
- texImage->Width);
- GLubyte *dest = _mesa_compressed_image_address(xoffset, yoffset, 0,
- texImage->IntFormat,
- texImage->Width,
- (GLubyte*) texImage->Data);
- transfer_compressed_teximage(ctx, 2, /* dimensions */
- width, height, 1, /* size to replace */
- format, type, /* source format/type */
- packing, /* source packing */
- pixels, /* source data */
- texImage->TexFormat,/* dest format */
- dest, dstRowStride);
- }
- else {
- /* old path */
- _mesa_transfer_teximage(ctx, 2,
- texImage->Format,
- texImage->TexFormat, texImage->Data,
- width, height, 1, /* src size */
- xoffset, yoffset, 0, /* dest offsets */
- texImage->Width *texImage->TexFormat->TexelBytes,
- 0, /* dstImageStride */
- format, type, pixels, packing);
- }
-#endif
/* GL_SGIS_generate_mipmap */
if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
&ctx->Texture.Unit[ctx->Texture.CurrentUnit],
texObj);
}
+
+ _mesa_unmap_teximage_pbo(ctx, packing);
}
struct gl_texture_object *texObj,
struct gl_texture_image *texImage)
{
- pixels = validate_pbo_teximage(width, height, depth,
- format, type, pixels, packing);
+ pixels = _mesa_validate_pbo_teximage(ctx, 3, width, height, depth, format, type,
+ pixels, packing, "glTexSubImage3D");
if (!pixels)
return;
-#if NEWTEXSTORE
{
GLint dstRowStride, dstImageStride;
GLboolean success;
format, type, pixels, packing);
if (!success) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage3D");
- return;
}
}
-#else
- if (texImage->IsCompressed) {
- GLint dstRowStride = _mesa_compressed_row_stride(texImage->IntFormat,
- texImage->Width);
- GLubyte *dest = _mesa_compressed_image_address(xoffset, yoffset, zoffset,
- texImage->IntFormat,
- texImage->Width,
- (GLubyte*) texImage->Data);
- transfer_compressed_teximage(ctx, 3, /* dimensions */
- width, height, depth,/* size to replace */
- format, type, /* source format/type */
- packing, /* source packing */
- pixels, /* source data */
- texImage->TexFormat,/* dest format */
- dest, dstRowStride);
- }
- else {
- const GLint texelBytes = texImage->TexFormat->TexelBytes;
- _mesa_transfer_teximage(ctx, 3,
- texImage->Format,
- texImage->TexFormat, texImage->Data,
- width, height, depth, /* src size */
- xoffset, yoffset, zoffset, /* dest offsets */
- texImage->Width * texelBytes, /* dst row stride */
- texImage->Width * texImage->Height * texelBytes,
- format, type, pixels, packing);
- }
-#endif
+
/* GL_SGIS_generate_mipmap */
if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
_mesa_generate_mipmap(ctx, target,
&ctx->Texture.Unit[ctx->Texture.CurrentUnit],
texObj);
}
+
+ _mesa_unmap_teximage_pbo(ctx, packing);
}
struct gl_texture_image *texImage)
{
/* this space intentionally left blank */
+ (void) ctx;
+ (void) target; (void) level;
+ (void) internalFormat;
+ (void) width; (void) border;
+ (void) imageSize; (void) data;
+ (void) texObj;
+ (void) texImage;
}
struct gl_texture_object *texObj,
struct gl_texture_image *texImage)
{
+ (void) width; (void) height; (void) border;
+
/* This is pretty simple, basically just do a memcpy without worrying
* about the usual image unpacking or image transfer operations.
*/
return;
}
- data = validate_pbo_compressed_teximage(imageSize, data, &ctx->Unpack);
+ data = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, data, &ctx->Unpack,
+ "glCompressedTexImage2D");
if (!data)
return;
/* copy the data */
ASSERT(texImage->CompressedSize == (GLuint) imageSize);
MEMCPY(texImage->Data, data, imageSize);
+
+ /* GL_SGIS_generate_mipmap */
+ if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
+ _mesa_generate_mipmap(ctx, target,
+ &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
+ texObj);
+ }
+
+ _mesa_unmap_teximage_pbo(ctx, &ctx->Unpack);
}
struct gl_texture_image *texImage)
{
/* this space intentionally left blank */
+ (void) ctx;
+ (void) target; (void) level;
+ (void) internalFormat;
+ (void) width; (void) height; (void) depth;
+ (void) border;
+ (void) imageSize; (void) data;
+ (void) texObj;
+ (void) texImage;
}
struct gl_texture_image *texImage)
{
/* this space intentionally left blank */
+ (void) ctx;
+ (void) target; (void) level;
+ (void) xoffset; (void) width;
+ (void) format;
+ (void) imageSize; (void) data;
+ (void) texObj;
+ (void) texImage;
}
GLint i, rows;
GLubyte *dest;
const GLubyte *src;
+ (void) format;
/* these should have been caught sooner */
ASSERT((width & 3) == 0 || width == 2 || width == 1);
ASSERT((xoffset & 3) == 0);
ASSERT((yoffset & 3) == 0);
- data = validate_pbo_compressed_teximage(imageSize, data, &ctx->Unpack);
+ data = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, data, &ctx->Unpack,
+ "glCompressedTexSubImage2D");
if (!data)
return;
dest += destRowStride;
src += srcRowStride;
}
+
+ /* GL_SGIS_generate_mipmap */
+ if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
+ _mesa_generate_mipmap(ctx, target,
+ &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
+ texObj);
+ }
+
+ _mesa_unmap_teximage_pbo(ctx, &ctx->Unpack);
}
struct gl_texture_image *texImage)
{
/* this space intentionally left blank */
+ (void) ctx;
+ (void) target; (void) level;
+ (void) xoffset; (void) yoffset; (void) zoffset;
+ (void) width; (void) height; (void) depth;
+ (void) format;
+ (void) imageSize; (void) data;
+ (void) texObj;
+ (void) texImage;
}
case MESA_FORMAT_ALPHA:
case MESA_FORMAT_LUMINANCE:
case MESA_FORMAT_INTENSITY:
- case MESA_FORMAT_COLOR_INDEX:
{
GLuint i, j, k;
const GLchan *rowA = (const GLchan *) srcRowA;
return;
/* Begin hardware formats */
case MESA_FORMAT_RGBA8888:
+ case MESA_FORMAT_RGBA8888_REV:
case MESA_FORMAT_ARGB8888:
+ case MESA_FORMAT_ARGB8888_REV:
{
GLuint i, j, k;
const GLubyte (*rowA)[4] = (const GLubyte (*)[4]) srcRowA;
}
return;
case MESA_FORMAT_RGB888:
+ case MESA_FORMAT_BGR888:
{
GLuint i, j, k;
const GLubyte (*rowA)[3] = (const GLubyte (*)[3]) srcRowA;
}
return;
case MESA_FORMAT_RGB565:
+ case MESA_FORMAT_RGB565_REV:
{
GLuint i, j, k;
const GLushort *rowA = (const GLushort *) srcRowA;
}
return;
case MESA_FORMAT_ARGB4444:
+ case MESA_FORMAT_ARGB4444_REV:
{
GLuint i, j, k;
const GLushort *rowA = (const GLushort *) srcRowA;
}
return;
case MESA_FORMAT_ARGB1555:
+ case MESA_FORMAT_ARGB1555_REV: /* XXX broken? */
{
GLuint i, j, k;
const GLushort *rowA = (const GLushort *) srcRowA;
}
return;
case MESA_FORMAT_AL88:
+ case MESA_FORMAT_AL88_REV:
{
GLuint i, j, k;
const GLubyte (*rowA)[2] = (const GLubyte (*)[2]) srcRowA;
GLint dstRowStride = _mesa_compressed_row_stride(srcImage->IntFormat,
dstWidth);
ASSERT(srcFormat == GL_RGB || srcFormat == GL_RGBA);
- _mesa_compress_teximage(ctx,
- dstWidth, dstHeight, /* size */
- srcFormat, /* source format */
- (const GLchan *) dstData, /* source buffer */
- dstWidth, /* source row stride */
- dstImage->TexFormat, /* dest format */
- (GLubyte*) dstImage->Data, /* dest buffer */
- dstRowStride ); /* dest row stride */
-
+ dstImage->TexFormat->StoreImage(ctx, 2, dstImage->Format,
+ dstImage->TexFormat,
+ dstImage->Data,
+ 0, 0, 0, /* dstX/Y/Zoffset */
+ dstRowStride, 0, /* strides */
+ dstWidth, dstHeight, 1, /* size */
+ srcFormat, CHAN_TYPE,
+ dstData, /* src data, actually */
+ &ctx->DefaultPacking);
/* swap src and dest pointers */
temp = (GLubyte *) srcData;
srcData = dstData;
} /* loop over mipmap levels */
}
+
+
+/**
+ * Helper function for drivers which need to rescale texture images to
+ * certain aspect ratios.
+ * Nearest filtering only (for broken hardware that can't support
+ * all aspect ratios). This can be made a lot faster, but I don't
+ * really care enough...
+ */
+void
+_mesa_rescale_teximage2d (GLuint bytesPerPixel,
+ GLuint srcStrideInPixels,
+ GLuint dstRowStride,
+ GLint srcWidth, GLint srcHeight,
+ GLint dstWidth, GLint dstHeight,
+ const GLvoid *srcImage, GLvoid *dstImage)
+{
+ GLint row, col;
+
+#define INNER_LOOP( TYPE, HOP, WOP ) \
+ for ( row = 0 ; row < dstHeight ; row++ ) { \
+ GLint srcRow = row HOP hScale; \
+ for ( col = 0 ; col < dstWidth ; col++ ) { \
+ GLint srcCol = col WOP wScale; \
+ dst[col] = src[srcRow * srcStrideInPixels + srcCol]; \
+ } \
+ dst = (TYPE *) ((GLubyte *) dst + dstRowStride); \
+ } \
+
+#define RESCALE_IMAGE( TYPE ) \
+do { \
+ const TYPE *src = (const TYPE *)srcImage; \
+ TYPE *dst = (TYPE *)dstImage; \
+ \
+ if ( srcHeight < dstHeight ) { \
+ const GLint hScale = dstHeight / srcHeight; \
+ if ( srcWidth < dstWidth ) { \
+ const GLint wScale = dstWidth / srcWidth; \
+ INNER_LOOP( TYPE, /, / ); \
+ } \
+ else { \
+ const GLint wScale = srcWidth / dstWidth; \
+ INNER_LOOP( TYPE, /, * ); \
+ } \
+ } \
+ else { \
+ const GLint hScale = srcHeight / dstHeight; \
+ if ( srcWidth < dstWidth ) { \
+ const GLint wScale = dstWidth / srcWidth; \
+ INNER_LOOP( TYPE, *, / ); \
+ } \
+ else { \
+ const GLint wScale = srcWidth / dstWidth; \
+ INNER_LOOP( TYPE, *, * ); \
+ } \
+ } \
+} while (0)
+
+ switch ( bytesPerPixel ) {
+ case 4:
+ RESCALE_IMAGE( GLuint );
+ break;
+
+ case 2:
+ RESCALE_IMAGE( GLushort );
+ break;
+
+ case 1:
+ RESCALE_IMAGE( GLubyte );
+ break;
+ default:
+ _mesa_problem(NULL,"unexpected bytes/pixel in _mesa_rescale_teximage2d");
+ }
+}
+
+
+/**
+ * Upscale an image by replication, not (typical) stretching.
+ * We use this when the image width or height is less than a
+ * certain size (4, 8) and we need to upscale an image.
+ */
+void
+_mesa_upscale_teximage2d (GLsizei inWidth, GLsizei inHeight,
+ GLsizei outWidth, GLsizei outHeight,
+ GLint comps, const GLchan *src, GLint srcRowStride,
+ GLchan *dest )
+{
+ GLint i, j, k;
+
+ ASSERT(outWidth >= inWidth);
+ ASSERT(outHeight >= inHeight);
+#if 0
+ ASSERT(inWidth == 1 || inWidth == 2 || inHeight == 1 || inHeight == 2);
+ ASSERT((outWidth & 3) == 0);
+ ASSERT((outHeight & 3) == 0);
+#endif
+
+ for (i = 0; i < outHeight; i++) {
+ const GLint ii = i % inHeight;
+ for (j = 0; j < outWidth; j++) {
+ const GLint jj = j % inWidth;
+ for (k = 0; k < comps; k++) {
+ dest[(i * outWidth + j) * comps + k]
+ = src[ii * srcRowStride + jj * comps + k];
+ }
+ }
+ }
+}
+
+
+
+/**
+ * This is the software fallback for Driver.GetTexImage().
+ * All error checking will have been done before this routine is called.
+ */
+void
+_mesa_get_teximage(GLcontext *ctx, GLenum target, GLint level,
+ GLenum format, GLenum type, GLvoid *pixels,
+ const struct gl_texture_object *texObj,
+ const struct gl_texture_image *texImage)
+{
+ GLuint dimensions = (target == GL_TEXTURE_3D) ? 3 : 2;
+
+ if (ctx->Pack.BufferObj->Name) {
+ /* pack texture image into a PBO */
+ GLubyte *buf;
+ if (!_mesa_validate_pbo_access(dimensions, &ctx->Pack, texImage->Width,
+ texImage->Height, texImage->Depth,
+ format, type, pixels)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetTexImage(invalid PBO access)");
+ return;
+ }
+ buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
+ GL_WRITE_ONLY_ARB,
+ ctx->Pack.BufferObj);
+ if (!buf) {
+ /* buffer is already mapped - that's an error */
+ _mesa_error(ctx, GL_INVALID_OPERATION,"glGetTexImage(PBO is mapped)");
+ return;
+ }
+ pixels = ADD_POINTERS(buf, pixels);
+ }
+ else if (!pixels) {
+ /* not an error */
+ return;
+ }
+
+ {
+ const GLint width = texImage->Width;
+ const GLint height = texImage->Height;
+ const GLint depth = texImage->Depth;
+ GLint img, row;
+ for (img = 0; img < depth; img++) {
+ for (row = 0; row < height; row++) {
+ /* compute destination address in client memory */
+ GLvoid *dest = _mesa_image_address( dimensions, &ctx->Pack, pixels,
+ width, height, format, type,
+ img, row, 0);
+ assert(dest);
+
+ if (format == GL_COLOR_INDEX) {
+ GLuint indexRow[MAX_WIDTH];
+ GLint col;
+ /* Can't use FetchTexel here because that returns RGBA */
+ if (texImage->TexFormat->IndexBits == 8) {
+ const GLubyte *src = (const GLubyte *) texImage->Data;
+ for (col = 0; col < width; col++) {
+ indexRow[col] = src[texImage->Width *
+ (img * texImage->Height + row) + col];
+ }
+ }
+ else if (texImage->TexFormat->IndexBits == 16) {
+ const GLushort *src = (const GLushort *) texImage->Data;
+ for (col = 0; col < width; col++) {
+ indexRow[col] = src[texImage->Width *
+ (img * texImage->Height + row) + col];
+ }
+ }
+ else {
+ _mesa_problem(ctx,
+ "Color index problem in _mesa_GetTexImage");
+ }
+ _mesa_pack_index_span(ctx, width, type, dest,
+ indexRow, &ctx->Pack,
+ 0 /* no image transfer */);
+ }
+ else if (format == GL_DEPTH_COMPONENT) {
+ GLfloat depthRow[MAX_WIDTH];
+ GLint col;
+ for (col = 0; col < width; col++) {
+ (*texImage->FetchTexelf)(texImage, col, row, img,
+ depthRow + col);
+ }
+ _mesa_pack_depth_span(ctx, width, dest, type,
+ depthRow, &ctx->Pack);
+ }
+ else if (format == GL_YCBCR_MESA) {
+ /* No pixel transfer */
+ const GLint rowstride = texImage->RowStride;
+ MEMCPY(dest,
+ (const GLushort *) texImage->Data + row * rowstride,
+ width * sizeof(GLushort));
+ /* check for byte swapping */
+ if ((texImage->TexFormat->MesaFormat == MESA_FORMAT_YCBCR
+ && type == GL_UNSIGNED_SHORT_8_8_REV_MESA) ||
+ (texImage->TexFormat->MesaFormat == MESA_FORMAT_YCBCR_REV
+ && type == GL_UNSIGNED_SHORT_8_8_MESA)) {
+ if (!ctx->Pack.SwapBytes)
+ _mesa_swap2((GLushort *) dest, width);
+ }
+ else if (ctx->Pack.SwapBytes) {
+ _mesa_swap2((GLushort *) dest, width);
+ }
+ }
+ else {
+ /* general case: convert row to RGBA format */
+ GLfloat rgba[MAX_WIDTH][4];
+ GLint col;
+ for (col = 0; col < width; col++) {
+ (*texImage->FetchTexelf)(texImage, col, row, img, rgba[col]);
+ }
+ _mesa_pack_rgba_span_float(ctx, width,
+ (const GLfloat (*)[4]) rgba,
+ format, type, dest, &ctx->Pack,
+ 0 /* no image transfer */);
+ } /* format */
+ } /* row */
+ } /* img */
+ }
+
+ if (ctx->Pack.BufferObj->Name) {
+ ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
+ ctx->Pack.BufferObj);
+ }
+}
+
+
+
+/**
+ * This is the software fallback for Driver.GetCompressedTexImage().
+ * All error checking will have been done before this routine is called.
+ */
+void
+_mesa_get_compressed_teximage(GLcontext *ctx, GLenum target, GLint level,
+ GLvoid *img,
+ const struct gl_texture_object *texObj,
+ const struct gl_texture_image *texImage)
+{
+ if (ctx->Pack.BufferObj->Name) {
+ /* pack texture image into a PBO */
+ GLubyte *buf;
+ if ((const GLubyte *) img + texImage->CompressedSize >
+ (const GLubyte *) ctx->Pack.BufferObj->Size) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetCompressedTexImage(invalid PBO access)");
+ return;
+ }
+ buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
+ GL_WRITE_ONLY_ARB,
+ ctx->Pack.BufferObj);
+ if (!buf) {
+ /* buffer is already mapped - that's an error */
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetCompressedTexImage(PBO is mapped)");
+ return;
+ }
+ img = ADD_POINTERS(buf, img);
+ }
+ else if (!img) {
+ /* not an error */
+ return;
+ }
+
+ /* just memcpy, no pixelstore or pixel transfer */
+ MEMCPY(img, texImage->Data, texImage->CompressedSize);
+
+ if (ctx->Pack.BufferObj->Name) {
+ ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
+ ctx->Pack.BufferObj);
+ }
+}