- * No pixel transfer operations or special texel encodings allowed.
- * 1D, 2D and 3D images supported.
- */
-static void
-memcpy_texture(struct gl_context *ctx,
- GLuint dimensions,
- gl_format dstFormat,
- GLint dstRowStride,
- GLubyte **dstSlices,
- GLint srcWidth, GLint srcHeight, GLint srcDepth,
- GLenum srcFormat, GLenum srcType,
- const GLvoid *srcAddr,
- const struct gl_pixelstore_attrib *srcPacking)
-{
- const GLint srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth,
- srcFormat, srcType);
- const GLint srcImageStride = _mesa_image_image_stride(srcPacking,
- srcWidth, srcHeight, srcFormat, srcType);
- const GLubyte *srcImage = (const GLubyte *) _mesa_image_address(dimensions,
- srcPacking, srcAddr, srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0);
- const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
- const GLint bytesPerRow = srcWidth * texelBytes;
-
- if (dstRowStride == srcRowStride &&
- dstRowStride == bytesPerRow) {
- /* memcpy image by image */
- GLint img;
- for (img = 0; img < srcDepth; img++) {
- GLubyte *dstImage = dstSlices[img];
- memcpy(dstImage, srcImage, bytesPerRow * srcHeight);
- srcImage += srcImageStride;
- }
- }
- else {
- /* memcpy row by row */
- GLint img, row;
- for (img = 0; img < srcDepth; img++) {
- const GLubyte *srcRow = srcImage;
- GLubyte *dstRow = dstSlices[img];
- for (row = 0; row < srcHeight; row++) {
- memcpy(dstRow, srcRow, bytesPerRow);
- dstRow += dstRowStride;
- srcRow += srcRowStride;
- }
- srcImage += srcImageStride;
- }
- }
-}
-
-
-/**
- * General-case function for storing a color texture images with
- * components that can be represented with ubytes. Example destination
- * texture formats are MESA_FORMAT_ARGB888, ARGB4444, RGB565.
- */
-static GLboolean
-store_ubyte_texture(TEXSTORE_PARAMS)
-{
- const GLint srcRowStride = srcWidth * 4 * sizeof(GLubyte);
- GLubyte *tempImage, *src;
- GLint img;
-
- tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
- baseInternalFormat,
- GL_RGBA,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType, srcAddr,
- srcPacking);
- if (!tempImage)
- return GL_FALSE;
-
- src = tempImage;
- for (img = 0; img < srcDepth; img++) {
- _mesa_pack_ubyte_rgba_rect(dstFormat, srcWidth, srcHeight,
- src, srcRowStride,
- dstSlices[img], dstRowStride);
- src += srcHeight * srcRowStride;
- }
- free(tempImage);
-
- return GL_TRUE;
-}
-
-
-
-
-/**
- * Store a 32-bit integer or float depth component texture image.
- */
-static GLboolean
-_mesa_texstore_z32(TEXSTORE_PARAMS)
-{
- const GLuint depthScale = 0xffffffff;
- GLenum dstType;
- (void) dims;
- ASSERT(dstFormat == MESA_FORMAT_Z32 ||
- dstFormat == MESA_FORMAT_Z32_FLOAT);
- ASSERT(_mesa_get_format_bytes(dstFormat) == sizeof(GLuint));
-
- if (dstFormat == MESA_FORMAT_Z32)
- dstType = GL_UNSIGNED_INT;
- else
- dstType = GL_FLOAT;
-
- if (ctx->Pixel.DepthScale == 1.0f &&
- ctx->Pixel.DepthBias == 0.0f &&
- !srcPacking->SwapBytes &&
- baseInternalFormat == GL_DEPTH_COMPONENT &&
- srcFormat == GL_DEPTH_COMPONENT &&
- srcType == dstType) {
- /* simple memcpy path */
- memcpy_texture(ctx, dims,
- dstFormat,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth, srcFormat, srcType,
- srcAddr, srcPacking);
- }
- else {
- /* general path */
- GLint img, row;
- for (img = 0; img < srcDepth; img++) {
- GLubyte *dstRow = dstSlices[img];
- for (row = 0; row < srcHeight; row++) {
- const GLvoid *src = _mesa_image_address(dims, srcPacking,
- srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
- _mesa_unpack_depth_span(ctx, srcWidth,
- dstType, dstRow,
- depthScale, srcType, src, srcPacking);
- dstRow += dstRowStride;
- }
- }
- }
- return GL_TRUE;
-}
-
-
-/**
- * Store a 24-bit integer depth component texture image.
- */
-static GLboolean
-_mesa_texstore_x8_z24(TEXSTORE_PARAMS)
-{
- const GLuint depthScale = 0xffffff;
-
- (void) dims;
- ASSERT(dstFormat == MESA_FORMAT_X8_Z24);
-
- {
- /* general path */
- GLint img, row;
- for (img = 0; img < srcDepth; img++) {
- GLubyte *dstRow = dstSlices[img];
- for (row = 0; row < srcHeight; row++) {
- const GLvoid *src = _mesa_image_address(dims, srcPacking,
- srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
- _mesa_unpack_depth_span(ctx, srcWidth,
- GL_UNSIGNED_INT, (GLuint *) dstRow,
- depthScale, srcType, src, srcPacking);
- dstRow += dstRowStride;
- }
- }
- }
- return GL_TRUE;
-}
-
-
-/**
- * Store a 24-bit integer depth component texture image.
- */
-static GLboolean
-_mesa_texstore_z24_x8(TEXSTORE_PARAMS)
-{
- const GLuint depthScale = 0xffffff;
-
- (void) dims;
- ASSERT(dstFormat == MESA_FORMAT_Z24_X8);
-
- {
- /* general path */
- GLint img, row;
- for (img = 0; img < srcDepth; img++) {
- GLubyte *dstRow = dstSlices[img];
- for (row = 0; row < srcHeight; row++) {
- const GLvoid *src = _mesa_image_address(dims, srcPacking,
- srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
- GLuint *dst = (GLuint *) dstRow;
- GLint i;
- _mesa_unpack_depth_span(ctx, srcWidth,
- GL_UNSIGNED_INT, dst,
- depthScale, srcType, src, srcPacking);
- for (i = 0; i < srcWidth; i++)
- dst[i] <<= 8;
- dstRow += dstRowStride;
- }
- }
- }
- return GL_TRUE;
-}
-
-
-/**
- * Store a 16-bit integer depth component texture image.
- */
-static GLboolean
-_mesa_texstore_z16(TEXSTORE_PARAMS)
-{
- const GLuint depthScale = 0xffff;
- (void) dims;
- ASSERT(dstFormat == MESA_FORMAT_Z16);
- ASSERT(_mesa_get_format_bytes(dstFormat) == sizeof(GLushort));
-
- if (ctx->Pixel.DepthScale == 1.0f &&
- ctx->Pixel.DepthBias == 0.0f &&
- !srcPacking->SwapBytes &&
- baseInternalFormat == GL_DEPTH_COMPONENT &&
- srcFormat == GL_DEPTH_COMPONENT &&
- srcType == GL_UNSIGNED_SHORT) {
- /* simple memcpy path */
- memcpy_texture(ctx, dims,
- dstFormat,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth, srcFormat, srcType,
- srcAddr, srcPacking);
- }
- else {
- /* general path */
- GLint img, row;
- for (img = 0; img < srcDepth; img++) {
- GLubyte *dstRow = dstSlices[img];
- for (row = 0; row < srcHeight; row++) {
- 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,
- GL_UNSIGNED_SHORT, dst16, depthScale,
- srcType, src, srcPacking);
- dstRow += dstRowStride;
- }
- }
- }
- return GL_TRUE;
-}
-
-
-/**
- * Store an rgb565 or rgb565_rev texture image.
- */
-static GLboolean
-_mesa_texstore_rgb565(TEXSTORE_PARAMS)
-{
- ASSERT(dstFormat == MESA_FORMAT_RGB565 ||
- dstFormat == MESA_FORMAT_RGB565_REV);
- ASSERT(_mesa_get_format_bytes(dstFormat) == 2);
-
- if (!ctx->_ImageTransferState &&
- baseInternalFormat == GL_RGB &&
- _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
- srcPacking->SwapBytes)) {
- /* simple memcpy path */
- memcpy_texture(ctx, dims,
- dstFormat,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth, srcFormat, srcType,
- srcAddr, srcPacking);
- }
- else if (!ctx->_ImageTransferState &&
- !srcPacking->SwapBytes &&
- baseInternalFormat == GL_RGB &&
- srcFormat == GL_RGB &&
- srcType == GL_UNSIGNED_BYTE &&
- dims == 2) {
- /* do optimized tex store */
- const GLint srcRowStride =
- _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(dims, srcPacking, srcAddr, srcWidth, srcHeight,
- srcFormat, srcType, 0, 0, 0);
- GLubyte *dst = dstSlices[0];
- GLint row, col;
- for (row = 0; row < srcHeight; row++) {
- const GLubyte *srcUB = (const GLubyte *) src;
- GLushort *dstUS = (GLushort *) dst;
- /* check for byteswapped format */
- if (dstFormat == MESA_FORMAT_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 {
- return store_ubyte_texture(ctx, dims, baseInternalFormat,
- dstFormat, dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType, srcAddr, srcPacking);
- }
- return GL_TRUE;
-}
-
-
-/**
- * Store a texture in MESA_FORMAT_RGBA8888 or MESA_FORMAT_RGBA8888_REV.
- */
-static GLboolean
-_mesa_texstore_rgba8888(TEXSTORE_PARAMS)
-{
- const GLboolean littleEndian = _mesa_little_endian();
-
- ASSERT(dstFormat == MESA_FORMAT_RGBA8888 ||
- dstFormat == MESA_FORMAT_RGBA8888_REV ||
- dstFormat == MESA_FORMAT_RGBX8888 ||
- dstFormat == MESA_FORMAT_RGBX8888_REV);
- ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
-
- if (!ctx->_ImageTransferState &&
- baseInternalFormat == GL_RGBA &&
- _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
- srcPacking->SwapBytes)) {
- /* simple memcpy path */
- memcpy_texture(ctx, dims,
- dstFormat,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth, srcFormat, srcType,
- srcAddr, srcPacking);
- }
- else if (!ctx->_ImageTransferState &&
- (srcType == GL_UNSIGNED_BYTE ||
- srcType == GL_UNSIGNED_INT_8_8_8_8 ||
- srcType == GL_UNSIGNED_INT_8_8_8_8_REV) &&
- can_swizzle(baseInternalFormat) &&
- can_swizzle(srcFormat)) {
-
- GLubyte dstmap[4];
-
- /* dstmap - how to swizzle from RGBA to dst format:
- */
- if ((littleEndian && (dstFormat == MESA_FORMAT_RGBA8888 ||
- dstFormat == MESA_FORMAT_RGBX8888)) ||
- (!littleEndian && (dstFormat == MESA_FORMAT_RGBA8888_REV ||
- dstFormat == MESA_FORMAT_RGBX8888_REV))) {
- dstmap[3] = 0;
- dstmap[2] = 1;
- dstmap[1] = 2;
- dstmap[0] = 3;
- }
- else {
- dstmap[3] = 3;
- dstmap[2] = 2;
- dstmap[1] = 1;
- dstmap[0] = 0;
- }
-
- _mesa_swizzle_ubyte_image(ctx, dims,
- srcFormat,
- srcType,
- baseInternalFormat,
- dstmap, 4,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth, srcAddr,
- srcPacking);
- }
- else {
- return store_ubyte_texture(ctx, dims, baseInternalFormat,
- dstFormat, dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType, srcAddr, srcPacking);
- }
- return GL_TRUE;
-}
-
-
-static GLboolean
-_mesa_texstore_argb8888(TEXSTORE_PARAMS)
-{
- const GLboolean littleEndian = _mesa_little_endian();
-
- ASSERT(dstFormat == MESA_FORMAT_ARGB8888 ||
- dstFormat == MESA_FORMAT_ARGB8888_REV ||
- dstFormat == MESA_FORMAT_XRGB8888 ||
- dstFormat == MESA_FORMAT_XRGB8888_REV );
- ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
-
- if (!ctx->_ImageTransferState &&
- baseInternalFormat == GL_RGBA &&
- _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
- srcPacking->SwapBytes)) {
- /* simple memcpy path (big endian) */
- memcpy_texture(ctx, dims,
- dstFormat,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth, srcFormat, srcType,
- srcAddr, srcPacking);
- }
- else if (!ctx->_ImageTransferState &&
- !srcPacking->SwapBytes &&
- (dstFormat == MESA_FORMAT_ARGB8888 ||
- dstFormat == MESA_FORMAT_XRGB8888) &&
- srcFormat == GL_RGB &&
- (baseInternalFormat == GL_RGBA ||
- baseInternalFormat == GL_RGB) &&
- srcType == GL_UNSIGNED_BYTE) {
- int img, row, col;
- 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 = dstSlices[img];
- for (row = 0; row < srcHeight; row++) {
- GLuint *d4 = (GLuint *) dstRow;
- for (col = 0; col < srcWidth; col++) {
- d4[col] = PACK_COLOR_8888(0xff,
- srcRow[col * 3 + RCOMP],
- srcRow[col * 3 + GCOMP],
- srcRow[col * 3 + BCOMP]);
- }
- dstRow += dstRowStride;
- srcRow += srcRowStride;
- }
- }
- }
- else if (!ctx->_ImageTransferState &&
- !srcPacking->SwapBytes &&
- dstFormat == MESA_FORMAT_ARGB8888 &&
- srcFormat == GL_LUMINANCE_ALPHA &&
- baseInternalFormat == GL_RGBA &&
- srcType == GL_UNSIGNED_BYTE) {
- /* special case of storing LA -> ARGB8888 */
- int img, row, col;
- const GLint srcRowStride =
- _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
- for (img = 0; img < srcDepth; img++) {
- const GLubyte *srcRow = (const GLubyte *)
- _mesa_image_address(dims, srcPacking, srcAddr, srcWidth,
- srcHeight, srcFormat, srcType, img, 0, 0);
- GLubyte *dstRow = dstSlices[img];
- for (row = 0; row < srcHeight; row++) {
- GLuint *d4 = (GLuint *) dstRow;
- for (col = 0; col < srcWidth; col++) {
- GLubyte l = srcRow[col * 2 + 0], a = srcRow[col * 2 + 1];
- d4[col] = PACK_COLOR_8888(a, l, l, l);
- }
- dstRow += dstRowStride;
- srcRow += srcRowStride;
- }
- }
- }
- else if (!ctx->_ImageTransferState &&
- !srcPacking->SwapBytes &&
- dstFormat == MESA_FORMAT_ARGB8888 &&
- srcFormat == GL_RGBA &&
- baseInternalFormat == GL_RGBA &&
- srcType == GL_UNSIGNED_BYTE) {
- /* same as above case, but src data has alpha too */
- GLint img, row, col;
- /* For some reason, streaming copies to write-combined regions
- * are extremely sensitive to the characteristics of how the
- * source data is retrieved. By reordering the source reads to
- * be in-order, the speed of this operation increases by half.
- * Strangely the same isn't required for the RGB path, above.
- */
- 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 = dstSlices[img];
- for (row = 0; row < srcHeight; row++) {
- GLuint *d4 = (GLuint *) dstRow;
- for (col = 0; col < srcWidth; col++) {
- d4[col] = PACK_COLOR_8888(srcRow[col * 4 + ACOMP],
- srcRow[col * 4 + RCOMP],
- srcRow[col * 4 + GCOMP],
- srcRow[col * 4 + BCOMP]);
- }
- dstRow += dstRowStride;
- srcRow += srcRowStride;
- }
- }
- }
- else if (!ctx->_ImageTransferState &&
- (srcType == GL_UNSIGNED_BYTE ||
- srcType == GL_UNSIGNED_INT_8_8_8_8 ||
- srcType == GL_UNSIGNED_INT_8_8_8_8_REV) &&
- can_swizzle(baseInternalFormat) &&
- can_swizzle(srcFormat)) {
-
- GLubyte dstmap[4];
-
- /* dstmap - how to swizzle from RGBA to dst format:
- */
- if ((littleEndian && dstFormat == MESA_FORMAT_ARGB8888) ||
- (littleEndian && dstFormat == MESA_FORMAT_XRGB8888) ||
- (!littleEndian && dstFormat == MESA_FORMAT_ARGB8888_REV) ||
- (!littleEndian && dstFormat == MESA_FORMAT_XRGB8888_REV)) {
- dstmap[3] = 3; /* alpha */
- dstmap[2] = 0; /* red */
- dstmap[1] = 1; /* green */
- dstmap[0] = 2; /* blue */
- }
- else {
- assert((littleEndian && dstFormat == MESA_FORMAT_ARGB8888_REV) ||
- (!littleEndian && dstFormat == MESA_FORMAT_ARGB8888) ||
- (littleEndian && dstFormat == MESA_FORMAT_XRGB8888_REV) ||
- (!littleEndian && dstFormat == MESA_FORMAT_XRGB8888));
- dstmap[3] = 2;
- dstmap[2] = 1;
- dstmap[1] = 0;
- dstmap[0] = 3;
- }
-
- _mesa_swizzle_ubyte_image(ctx, dims,
- srcFormat,
- srcType,
- baseInternalFormat,
- dstmap, 4,
- dstRowStride,
- dstSlices,
- srcWidth, srcHeight, srcDepth, srcAddr,
- srcPacking);
- }
- else {
- return store_ubyte_texture(ctx, dims, baseInternalFormat,
- dstFormat, dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType, srcAddr, srcPacking);
- }
- return GL_TRUE;
-}
-
-
-static GLboolean
-_mesa_texstore_rgb888(TEXSTORE_PARAMS)
-{
- ASSERT(dstFormat == MESA_FORMAT_RGB888);
- ASSERT(_mesa_get_format_bytes(dstFormat) == 3);
-
- if (!ctx->_ImageTransferState &&
- baseInternalFormat == GL_RGB &&
- _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
- srcPacking->SwapBytes)) {
- /* simple memcpy path */
- memcpy_texture(ctx, dims,
- dstFormat,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth, srcFormat, srcType,
- srcAddr, srcPacking);
- }
- else if (!ctx->_ImageTransferState &&
- !srcPacking->SwapBytes &&
- srcFormat == GL_RGBA &&
- srcType == GL_UNSIGNED_BYTE) {
- /* extract RGB from RGBA */
- GLint img, row, col;
- 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 = dstSlices[img];
- for (row = 0; row < srcHeight; row++) {
- for (col = 0; col < srcWidth; col++) {
- dstRow[col * 3 + 0] = srcRow[col * 4 + BCOMP];
- dstRow[col * 3 + 1] = srcRow[col * 4 + GCOMP];
- dstRow[col * 3 + 2] = srcRow[col * 4 + RCOMP];
- }
- dstRow += dstRowStride;
- srcRow += srcRowStride;
- }
- }
- }
- else if (!ctx->_ImageTransferState &&
- srcType == GL_UNSIGNED_BYTE &&
- can_swizzle(baseInternalFormat) &&
- can_swizzle(srcFormat)) {
-
- GLubyte dstmap[4];
-
- /* dstmap - how to swizzle from RGBA to dst format:
- */
- dstmap[0] = 2;
- dstmap[1] = 1;
- dstmap[2] = 0;
- dstmap[3] = ONE; /* ? */
-
- _mesa_swizzle_ubyte_image(ctx, dims,
- srcFormat,
- srcType,
- baseInternalFormat,
- dstmap, 3,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth, srcAddr,
- srcPacking);
- }
- else {
- return store_ubyte_texture(ctx, dims, baseInternalFormat,
- dstFormat, dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType, srcAddr, srcPacking);
- }
- return GL_TRUE;
-}
-
-
-static GLboolean
-_mesa_texstore_bgr888(TEXSTORE_PARAMS)
-{
- ASSERT(dstFormat == MESA_FORMAT_BGR888);
- ASSERT(_mesa_get_format_bytes(dstFormat) == 3);
-
- if (!ctx->_ImageTransferState &&
- baseInternalFormat == GL_RGB &&
- _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
- srcPacking->SwapBytes)) {
- /* simple memcpy path */
- memcpy_texture(ctx, dims,
- dstFormat,
- dstRowStride, dstSlices,
- 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;
- 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 = dstSlices[img];
- 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;
- }
- }
- }
- else if (!ctx->_ImageTransferState &&
- srcType == GL_UNSIGNED_BYTE &&
- can_swizzle(baseInternalFormat) &&
- can_swizzle(srcFormat)) {
-
- GLubyte dstmap[4];
-
- /* dstmap - how to swizzle from RGBA to dst format:
- */
- dstmap[0] = 0;
- dstmap[1] = 1;
- dstmap[2] = 2;
- dstmap[3] = ONE; /* ? */
-
- _mesa_swizzle_ubyte_image(ctx, dims,
- srcFormat,
- srcType,
- baseInternalFormat,
- dstmap, 3,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth, srcAddr,
- srcPacking);
- }
- else {
- return store_ubyte_texture(ctx, dims, baseInternalFormat,
- dstFormat, dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType, srcAddr, srcPacking);
- }
- return GL_TRUE;
-}
-
-
-static GLboolean
-_mesa_texstore_argb4444(TEXSTORE_PARAMS)
-{
- ASSERT(dstFormat == MESA_FORMAT_ARGB4444 ||
- dstFormat == MESA_FORMAT_ARGB4444_REV);
- ASSERT(_mesa_get_format_bytes(dstFormat) == 2);
-
- if (!ctx->_ImageTransferState &&
- baseInternalFormat == GL_RGBA &&
- _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
- srcPacking->SwapBytes)) {
- /* simple memcpy path */
- memcpy_texture(ctx, dims,
- dstFormat,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth, srcFormat, srcType,
- srcAddr, srcPacking);
- }
- else {
- return store_ubyte_texture(ctx, dims, baseInternalFormat,
- dstFormat, dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType, srcAddr, srcPacking);
- }
- return GL_TRUE;
-}
-
-static GLboolean
-_mesa_texstore_rgba5551(TEXSTORE_PARAMS)
-{
- ASSERT(dstFormat == MESA_FORMAT_RGBA5551);
- ASSERT(_mesa_get_format_bytes(dstFormat) == 2);
-
- if (!ctx->_ImageTransferState &&
- baseInternalFormat == GL_RGBA &&
- _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
- srcPacking->SwapBytes)) {
- /* simple memcpy path */
- memcpy_texture(ctx, dims,
- dstFormat,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth, srcFormat, srcType,
- srcAddr, srcPacking);
- }
- else {
- return store_ubyte_texture(ctx, dims, baseInternalFormat,
- dstFormat, dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType, srcAddr, srcPacking);
- }
- return GL_TRUE;
-}
-
-static GLboolean
-_mesa_texstore_argb1555(TEXSTORE_PARAMS)
-{
- ASSERT(dstFormat == MESA_FORMAT_ARGB1555 ||
- dstFormat == MESA_FORMAT_ARGB1555_REV);
- ASSERT(_mesa_get_format_bytes(dstFormat) == 2);
-
- if (!ctx->_ImageTransferState &&
- baseInternalFormat == GL_RGBA &&
- _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
- srcPacking->SwapBytes)) {
- /* simple memcpy path */
- memcpy_texture(ctx, dims,
- dstFormat,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth, srcFormat, srcType,
- srcAddr, srcPacking);
- }
- else {
- return store_ubyte_texture(ctx, dims, baseInternalFormat,
- dstFormat, dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType, srcAddr, srcPacking);
- }
- return GL_TRUE;
-}
-
-
-static GLboolean
-_mesa_texstore_argb2101010(TEXSTORE_PARAMS)
-{
- const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
-
- ASSERT(dstFormat == MESA_FORMAT_ARGB2101010);
- ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
-
- if (!ctx->_ImageTransferState &&
- baseInternalFormat == GL_RGBA &&
- _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
- srcPacking->SwapBytes)) {
- /* simple memcpy path */
- memcpy_texture(ctx, dims,
- dstFormat,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth, srcFormat, srcType,
- srcAddr, srcPacking);
- }
- else {
- /* general path */
- const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
- baseInternalFormat,
- baseFormat,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType, srcAddr,
- srcPacking,
- ctx->_ImageTransferState);
- const GLfloat *src = tempImage;
- GLint img, row, col;
- if (!tempImage)
- return GL_FALSE;
- for (img = 0; img < srcDepth; img++) {
- GLubyte *dstRow = dstSlices[img];
- if (baseInternalFormat == GL_RGBA) {
- for (row = 0; row < srcHeight; row++) {
- GLuint *dstUI = (GLuint *) dstRow;
- for (col = 0; col < srcWidth; col++) {
- GLushort a,r,g,b;
-
- UNCLAMPED_FLOAT_TO_USHORT(a, src[ACOMP]);
- UNCLAMPED_FLOAT_TO_USHORT(r, src[RCOMP]);
- UNCLAMPED_FLOAT_TO_USHORT(g, src[GCOMP]);
- UNCLAMPED_FLOAT_TO_USHORT(b, src[BCOMP]);
- dstUI[col] = PACK_COLOR_2101010_US(a, r, g, b);
- src += 4;
- }
- dstRow += dstRowStride;
- }
- } else if (baseInternalFormat == GL_RGB) {
- for (row = 0; row < srcHeight; row++) {
- GLuint *dstUI = (GLuint *) dstRow;
- for (col = 0; col < srcWidth; col++) {
- GLushort r,g,b;
-
- UNCLAMPED_FLOAT_TO_USHORT(r, src[RCOMP]);
- UNCLAMPED_FLOAT_TO_USHORT(g, src[GCOMP]);
- UNCLAMPED_FLOAT_TO_USHORT(b, src[BCOMP]);
- dstUI[col] = PACK_COLOR_2101010_US(0xffff, r, g, b);
- src += 4;
- }
- dstRow += dstRowStride;
- }
- } else {
- ASSERT(0);
- }
- }
- free((void *) tempImage);
- }
- return GL_TRUE;
-}
-
-
-/**
- * Do texstore for 2-channel, 4-bit/channel, unsigned normalized formats.
- */
-static GLboolean
-_mesa_texstore_unorm44(TEXSTORE_PARAMS)
-{
- const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
-
- ASSERT(dstFormat == MESA_FORMAT_AL44);
- ASSERT(_mesa_get_format_bytes(dstFormat) == 1);
-
- {
- /* general path */
- const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
- baseInternalFormat,
- baseFormat,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType, srcAddr,
- srcPacking);
- const GLubyte *src = tempImage;
- GLint img, row, col;
- if (!tempImage)
- return GL_FALSE;
- for (img = 0; img < srcDepth; img++) {
- GLubyte *dstRow = dstSlices[img];
- for (row = 0; row < srcHeight; row++) {
- GLubyte *dstUS = (GLubyte *) dstRow;
- for (col = 0; col < srcWidth; col++) {
- /* src[0] is luminance, src[1] is alpha */
- dstUS[col] = PACK_COLOR_44( src[1],
- src[0] );
- src += 2;
- }
- dstRow += dstRowStride;
- }
- }
- free((void *) tempImage);
- }
- return GL_TRUE;
-}
-
-
-/**
- * Do texstore for 2-channel, 8-bit/channel, unsigned normalized formats.
- */
-static GLboolean
-_mesa_texstore_unorm88(TEXSTORE_PARAMS)
-{
- const GLboolean littleEndian = _mesa_little_endian();
- const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
-
- ASSERT(dstFormat == MESA_FORMAT_AL88 ||
- dstFormat == MESA_FORMAT_AL88_REV ||
- dstFormat == MESA_FORMAT_GR88 ||
- dstFormat == MESA_FORMAT_RG88);
- ASSERT(_mesa_get_format_bytes(dstFormat) == 2);
-
- if (!ctx->_ImageTransferState &&
- !srcPacking->SwapBytes &&
- ((dstFormat == MESA_FORMAT_AL88 &&
- baseInternalFormat == GL_LUMINANCE_ALPHA &&
- srcFormat == GL_LUMINANCE_ALPHA) ||
- (dstFormat == MESA_FORMAT_GR88 &&
- baseInternalFormat == srcFormat)) &&
- srcType == GL_UNSIGNED_BYTE &&
- littleEndian) {
- /* simple memcpy path */
- memcpy_texture(ctx, dims,
- dstFormat,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth, srcFormat, srcType,
- srcAddr, srcPacking);
- }
- else if (!ctx->_ImageTransferState &&
- littleEndian &&
- srcType == GL_UNSIGNED_BYTE &&
- can_swizzle(baseInternalFormat) &&
- can_swizzle(srcFormat)) {
- GLubyte dstmap[4];
-
- /* dstmap - how to swizzle from RGBA to dst format:
- */
- if (dstFormat == MESA_FORMAT_AL88 || dstFormat == MESA_FORMAT_AL88_REV) {
- if ((littleEndian && dstFormat == MESA_FORMAT_AL88) ||
- (!littleEndian && dstFormat == MESA_FORMAT_AL88_REV)) {
- dstmap[0] = 0;
- dstmap[1] = 3;
- }
- else {
- dstmap[0] = 3;
- dstmap[1] = 0;
- }
- }
- else {
- if ((littleEndian && dstFormat == MESA_FORMAT_GR88) ||
- (!littleEndian && dstFormat == MESA_FORMAT_RG88)) {
- dstmap[0] = 0;
- dstmap[1] = 1;
- }
- else {
- dstmap[0] = 1;
- dstmap[1] = 0;
- }
- }
- dstmap[2] = ZERO; /* ? */
- dstmap[3] = ONE; /* ? */
-
- _mesa_swizzle_ubyte_image(ctx, dims,
- srcFormat,
- srcType,
- baseInternalFormat,
- dstmap, 2,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth, srcAddr,
- srcPacking);
- }
- else {
- /* general path */
- const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
- baseInternalFormat,
- baseFormat,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType, srcAddr,
- srcPacking);
- const GLubyte *src = tempImage;
- GLint img, row, col;
- if (!tempImage)
- return GL_FALSE;
- for (img = 0; img < srcDepth; img++) {
- GLubyte *dstRow = dstSlices[img];
- for (row = 0; row < srcHeight; row++) {
- GLushort *dstUS = (GLushort *) dstRow;
- if (dstFormat == MESA_FORMAT_AL88 ||
- dstFormat == MESA_FORMAT_GR88) {
- for (col = 0; col < srcWidth; col++) {
- /* src[0] is luminance (or R), src[1] is alpha (or G) */
- dstUS[col] = PACK_COLOR_88( src[1],
- src[0] );
- src += 2;
- }
- }
- else {
- for (col = 0; col < srcWidth; col++) {
- /* src[0] is luminance (or R), src[1] is alpha (or G) */
- dstUS[col] = PACK_COLOR_88_REV( src[1],
- src[0] );
- src += 2;
- }
- }
- dstRow += dstRowStride;
- }
- }
- free((void *) tempImage);
- }
- return GL_TRUE;
-}
-
-
-/**
- * Do texstore for 2-channel, 16-bit/channel, unsigned normalized formats.
- */
-static GLboolean
-_mesa_texstore_unorm1616(TEXSTORE_PARAMS)
-{
- const GLboolean littleEndian = _mesa_little_endian();
- const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
-
- ASSERT(dstFormat == MESA_FORMAT_AL1616 ||
- dstFormat == MESA_FORMAT_AL1616_REV ||
- dstFormat == MESA_FORMAT_RG1616 ||
- dstFormat == MESA_FORMAT_RG1616_REV);
- ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
-
- if (!ctx->_ImageTransferState &&
- !srcPacking->SwapBytes &&
- ((dstFormat == MESA_FORMAT_AL1616 &&
- baseInternalFormat == GL_LUMINANCE_ALPHA &&
- srcFormat == GL_LUMINANCE_ALPHA) ||
- (dstFormat == MESA_FORMAT_RG1616 &&
- baseInternalFormat == srcFormat)) &&
- srcType == GL_UNSIGNED_SHORT &&
- littleEndian) {
- /* simple memcpy path */
- memcpy_texture(ctx, dims,
- dstFormat,
- dstRowStride, dstSlices,
- srcWidth, srcHeight, srcDepth, srcFormat, srcType,
- srcAddr, srcPacking);
- }
- else {
- /* general path */
- const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
- baseInternalFormat,
- baseFormat,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType, srcAddr,
- srcPacking,
- ctx->_ImageTransferState);
- const GLfloat *src = tempImage;
- GLint img, row, col;
- if (!tempImage)
- return GL_FALSE;
- for (img = 0; img < srcDepth; img++) {
- GLubyte *dstRow = dstSlices[img];
- for (row = 0; row < srcHeight; row++) {
- GLuint *dstUI = (GLuint *) dstRow;
- if (dstFormat == MESA_FORMAT_AL1616 ||
- dstFormat == MESA_FORMAT_RG1616) {
- for (col = 0; col < srcWidth; col++) {
- GLushort l, a;
-
- UNCLAMPED_FLOAT_TO_USHORT(l, src[0]);
- UNCLAMPED_FLOAT_TO_USHORT(a, src[1]);
- dstUI[col] = PACK_COLOR_1616(a, l);
- src += 2;
- }
- }
- else {
- for (col = 0; col < srcWidth; col++) {
- GLushort l, a;
-
- UNCLAMPED_FLOAT_TO_USHORT(l, src[0]);
- UNCLAMPED_FLOAT_TO_USHORT(a, src[1]);
- dstUI[col] = PACK_COLOR_1616_REV(a, l);
- src += 2;
- }
- }
- dstRow += dstRowStride;
- }
- }
- free((void *) tempImage);
- }
- return GL_TRUE;
-}
-
-
-/* Texstore for R16, A16, L16, I16. */
-static GLboolean
-_mesa_texstore_unorm16(TEXSTORE_PARAMS)