-/* $Id: texutil.c,v 1.14 2001/03/12 00:48:39 gareth Exp $ */
+/* $Id: texutil.c,v 1.15 2001/03/18 08:53:50 gareth Exp $ */
/*
* Mesa 3-D graphics library
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Gareth Hughes <gareth@valinux.com>
*/
-
#ifdef PC_HEADER
#include "all.h"
#else
#include "glheader.h"
#include "context.h"
+#include "enums.h"
#include "image.h"
+#include "macros.h"
#include "mem.h"
-#include "texutil.h"
#include "mtypes.h"
+#include "texformat.h"
+#include "texutil.h"
#endif
+#define DBG 0
-/*
- * Texture utilities which may be useful to device drivers.
- * See the texutil.h for the list of supported internal formats.
- * It's expected that new formats will be added for new hardware.
+
+struct gl_texture_convert {
+ GLint xoffset, yoffset, zoffset; /* Subimage offset */
+ GLint width, height, depth; /* Subimage region */
+
+ GLint imageWidth, imageHeight; /* Full image dimensions */
+ GLenum format, type;
+
+ const struct gl_pixelstore_attrib *packing;
+
+ const GLvoid *srcImage;
+ GLvoid *dstImage;
+
+ GLint index;
+};
+
+typedef GLboolean (*convert_func)( struct gl_texture_convert *convert );
+
+#define CONVERT_STRIDE_BIT 0x1
+#define CONVERT_PACKING_BIT 0x2
+
+
+
+/* ================================================================
+ * RGBA8888 textures:
*/
+#define DST_TYPE GLuint
+#define DST_TEXELS_PER_DWORD 1
-/*
- * If the system is little endian and can do 4-byte word stores on
- * non 4-byte-aligned addresses then we can use this optimization.
+#define CONVERT_TEXEL( src ) \
+ PACK_COLOR_8888( src[3], src[2], src[1], src[0] )
+
+#define CONVERT_DIRECT
+
+#define SRC_TEXEL_BYTES 4
+
+#define TAG(x) x##_rgba8888_direct
+#define PRESERVE_DST_TYPE
+#include "texutil_tmp.h"
+
+
+#define CONVERT_TEXEL( src ) \
+ PACK_COLOR_8888( src[0], src[1], src[2], src[3] )
+
+#define CONVERT_TEXEL_DWORD( src ) CONVERT_TEXEL( src )
+
+#define SRC_TEXEL_BYTES 4
+
+#define TAG(x) x##_abgr8888_to_rgba8888
+#define PRESERVE_DST_TYPE
+#include "texutil_tmp.h"
+
+
+#define CONVERT_TEXEL( src ) \
+ PACK_COLOR_8888( src[0], src[1], src[2], 0xff )
+
+#define CONVERT_TEXEL_DWORD( src ) CONVERT_TEXEL( src )
+
+#define SRC_TEXEL_BYTES 3
+
+#define TAG(x) x##_bgr888_to_rgba8888
+#include "texutil_tmp.h"
+
+
+#define CONVERT_RGBA8888( name ) \
+static GLboolean \
+convert_##name##_rgba8888( struct gl_texture_convert *convert ) \
+{ \
+ convert_func *tab; \
+ GLint index = convert->index; \
+ \
+ if ( convert->format == GL_ABGR_EXT && \
+ convert->type == GL_UNSIGNED_INT_8_8_8_8_REV ) \
+ { \
+ tab = name##_tab_rgba8888_direct; \
+ } \
+ else if ( convert->format == GL_RGBA && \
+ ( convert->type == GL_UNSIGNED_BYTE || \
+ convert->type == GL_UNSIGNED_INT_8_8_8_8 ) ) \
+ { \
+ tab = name##_tab_abgr8888_to_rgba8888; \
+ } \
+ else if ( convert->format == GL_RGB && \
+ convert->type == GL_UNSIGNED_BYTE ) \
+ { \
+ tab = name##_tab_bgr888_to_rgba8888; \
+ } \
+ else \
+ { \
+ /* Can't handle this source format/type combination */ \
+ return GL_FALSE; \
+ } \
+ \
+ return tab[index]( convert ); \
+}
+
+CONVERT_RGBA8888( texsubimage2d )
+CONVERT_RGBA8888( texsubimage3d )
+
+
+
+/* ================================================================
+ * ARGB8888 textures:
*/
-#if defined(__i386__)
-#define DO_32BIT_STORES000
-#endif
+#define DST_TYPE GLuint
+#define DST_TEXELS_PER_DWORD 1
+#define CONVERT_TEXEL( src ) \
+ PACK_COLOR_8888( src[3], src[2], src[1], src[0] )
-/*
- * Convert texture image data into one a specific internal format.
- * Input:
- * dstFormat - the destination internal format
- * dstWidth, dstHeight - the destination image size
- * dstImage - pointer to destination image buffer
- * dstRowStride - bytes to jump between image rows
- * srcWidth, srcHeight - size of texture image
- * srcFormat, srcType - format and datatype of source image
- * srcImage - pointer to user's texture image
- * packing - describes how user's texture image is packed.
- * Return: pointer to resulting image data or NULL if error or out of memory
- * or NULL if we can't process the given image format/type/internalFormat
- * combination.
- *
- * Supported type conversions:
- * srcFormat srcType dstFormat
- * GL_INTENSITY GL_UNSIGNED_BYTE MESA_I8
- * GL_LUMINANCE GL_UNSIGNED_BYTE MESA_L8
- * GL_ALPHA GL_UNSIGNED_BYTE MESA_A8
- * GL_COLOR_INDEX GL_UNSIGNED_BYTE MESA_C8
- * GL_LUMINANCE_ALPHA GL_UNSIGNED_BYTE MESA_A8_L8
- * GL_RGB GL_UNSIGNED_BYTE MESA_R5_G6_B5
- * GL_RGB GL_UNSIGNED_SHORT_5_6_5 MESA_R5_G6_B5
- * GL_RGBA GL_UNSIGNED_BYTE MESA_A4_R4_G4_B4
- * GL_BGRA GL_UNSIGNED_SHORT_4_4_4_4_REV MESA_A4_R4_G4_B4
- * GL_BGRA GL_UNSIGHED_SHORT_1_5_5_5_REV MESA_A1_R5_G5_B5
- * GL_RGBA GL_UNSIGNED_BYTE MESA_A1_R5_G5_B5
- * GL_BGRA GL_UNSIGNED_INT_8_8_8_8_REV MESA_A8_R8_G8_B8
- * GL_RGBA GL_UNSIGNED_BYTE MESA_A8_R8_G8_B8
- * GL_RGB GL_UNSIGNED_BYTE MESA_A8_R8_G8_B8
- * more to be added for new drivers...
- *
- * Notes:
- * Some hardware only supports texture images of specific aspect ratios.
- * This code will do power-of-two image up-scaling if that's needed.
- *
- *
+#define CONVERT_DIRECT
+
+#define SRC_TEXEL_BYTES 4
+
+#define TAG(x) x##_argb8888_direct
+#define PRESERVE_DST_TYPE
+#include "texutil_tmp.h"
+
+
+#define CONVERT_TEXEL( src ) \
+ PACK_COLOR_8888( src[3], src[0], src[1], src[2] )
+
+#define CONVERT_TEXEL_DWORD( src ) CONVERT_TEXEL( src )
+
+#define SRC_TEXEL_BYTES 4
+
+#define TAG(x) x##_abgr8888_to_argb8888
+#define PRESERVE_DST_TYPE
+#include "texutil_tmp.h"
+
+
+#define CONVERT_TEXEL( src ) \
+ PACK_COLOR_8888( 0xff, src[0], src[1], src[2] )
+
+#define CONVERT_TEXEL_DWORD( src ) CONVERT_TEXEL( src )
+
+#define SRC_TEXEL_BYTES 3
+
+#define TAG(x) x##_bgr888_to_argb8888
+#include "texutil_tmp.h"
+
+
+#define CONVERT_ARGB8888( name ) \
+static GLboolean \
+convert_##name##_argb8888( struct gl_texture_convert *convert ) \
+{ \
+ convert_func *tab; \
+ GLint index = convert->index; \
+ \
+ if ( convert->format == GL_BGRA && \
+ convert->type == GL_UNSIGNED_INT_8_8_8_8_REV ) \
+ { \
+ tab = name##_tab_argb8888_direct; \
+ } \
+ else if ( convert->format == GL_RGBA && \
+ convert->type == GL_UNSIGNED_BYTE ) \
+ { \
+ tab = name##_tab_abgr8888_to_argb8888; \
+ } \
+ else if ( convert->format == GL_RGB && \
+ convert->type == GL_UNSIGNED_BYTE ) \
+ { \
+ tab = name##_tab_bgr888_to_argb8888; \
+ } \
+ else \
+ { \
+ /* Can't handle this source format/type combination */ \
+ return GL_FALSE; \
+ } \
+ \
+ return tab[index]( convert ); \
+}
+
+CONVERT_ARGB8888( texsubimage2d )
+CONVERT_ARGB8888( texsubimage3d )
+
+
+
+/* ================================================================
+ * RGB888 textures:
*/
-GLboolean
-_mesa_convert_teximage(MesaIntTexFormat dstFormat,
- GLint dstWidth, GLint dstHeight, GLvoid *dstImage,
- GLint dstRowStride,
- GLint srcWidth, GLint srcHeight,
- GLenum srcFormat, GLenum srcType,
- const GLvoid *srcImage,
- const struct gl_pixelstore_attrib *packing)
+
+static GLboolean
+convert_texsubimage2d_rgb888( struct gl_texture_convert *convert )
{
- const GLint wScale = dstWidth / srcWidth; /* must be power of two */
- const GLint hScale = dstHeight / srcHeight; /* must be power of two */
- ASSERT(dstWidth >= srcWidth);
- ASSERT(dstHeight >= srcHeight);
- ASSERT(dstImage);
- ASSERT(srcImage);
- ASSERT(packing);
-
- switch (dstFormat) {
- case MESA_I8:
- case MESA_L8:
- case MESA_A8:
- case MESA_C8:
- if (srcType != GL_UNSIGNED_BYTE ||
- ((srcFormat != GL_INTENSITY) &&
- (srcFormat != GL_LUMINANCE) &&
- (srcFormat != GL_ALPHA) &&
- (srcFormat != GL_COLOR_INDEX))) {
- /* bad internal format / srcFormat combination */
- return GL_FALSE;
- }
- else {
- /* store as 8-bit texels */
- if (wScale == 1 && hScale == 1) {
- /* no scaling needed - fast case */
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
- srcFormat, srcType, 0, 0, 0);
- const GLint srcStride = _mesa_image_row_stride(packing,
- srcWidth, srcFormat, srcType);
- GLubyte *dst = (GLubyte *) dstImage;
- GLint row;
- for (row = 0; row < dstHeight; row++) {
- MEMCPY(dst, src, dstWidth * sizeof(GLubyte));
- dst += dstRowStride;
- src += srcStride;
- }
- }
- else {
- /* must rescale image */
- GLubyte *dst = (GLubyte *) dstImage;
- GLint row;
- for (row = 0; row < dstHeight; row++) {
- GLint srcRow = row / hScale;
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth,
- srcHeight, srcFormat, srcType, 0, srcRow, 0);
- GLint col;
- for (col = 0; col < dstWidth; col++) {
- dst[col] = src[col / wScale];
- }
- dst += dstRowStride;
- }
- }
- }
- break;
-
- case MESA_A8_L8:
- if (srcType != GL_UNSIGNED_BYTE || srcFormat != GL_LUMINANCE_ALPHA) {
- return GL_FALSE;
- }
- else {
- /* store as 16-bit texels */
- if (wScale == 1 && hScale == 1) {
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
- srcFormat, srcType, 0, 0, 0);
- const GLint srcStride = _mesa_image_row_stride(packing,
- srcWidth, srcFormat, srcType);
- GLushort *dst = (GLushort *) dstImage;
- GLint row, col;
- for (row = 0; row < dstHeight; row++) {
- for (col = 0; col < dstWidth; col++) {
- GLubyte luminance = src[col * 2 + 0];
- GLubyte alpha = src[col * 2 + 1];
- dst[col] = ((GLushort) alpha << 8) | luminance;
- }
- dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
- src += srcStride;
- }
- }
- else {
- /* must rescale */
- GLushort *dst = (GLushort *) dstImage;
- GLint row, col;
- for (row = 0; row < dstHeight; row++) {
- GLint srcRow = row / hScale;
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth,
- srcHeight, srcFormat, srcType, 0, srcRow, 0);
- const GLint srcStride = _mesa_image_row_stride(packing,
- srcWidth, srcFormat, srcType);
- for (col = 0; col < dstWidth; col++) {
- GLint srcCol = col / wScale;
- GLubyte luminance = src[srcCol * 2 + 0];
- GLubyte alpha = src[srcCol * 2 + 1];
- dst[col] = ((GLushort) alpha << 8) | luminance;
- }
- dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
- src += srcStride;
- }
- }
- }
- break;
-
- case MESA_R5_G6_B5:
- if (srcFormat == GL_RGB && srcType == GL_UNSIGNED_SHORT_5_6_5) {
- /* special, optimized case */
- if (wScale == 1 && hScale == 1) {
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
- srcFormat, srcType, 0, 0, 0);
- const GLint srcStride = _mesa_image_row_stride(packing,
- srcWidth, srcFormat, srcType);
- GLushort *dst = (GLushort *) dstImage;
- GLint row;
- for (row = 0; row < dstHeight; row++) {
- MEMCPY(dst, src, dstWidth * sizeof(GLushort));
- src += srcStride;
- dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
- }
- }
- else {
- /* must rescale image */
- GLushort *dst = (GLushort *) dstImage;
- GLint row;
- for (row = 0; row < dstHeight; row++) {
- GLint srcRow = row / hScale;
- const GLushort *src = (const GLushort *)
- _mesa_image_address(packing, srcImage, srcWidth,
- srcHeight, srcFormat, srcType, 0, srcRow, 0);
- GLint col;
- for (col = 0; col < dstWidth; col++) {
- dst[col] = src[col / wScale];
- }
- dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
- }
- }
- }
- else if (srcFormat == GL_RGB && srcType == GL_UNSIGNED_BYTE) {
- /* general case */
- if (wScale == 1 && hScale == 1) {
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
- srcFormat, srcType, 0, 0, 0);
- const GLint srcStride = _mesa_image_row_stride(packing,
- srcWidth, srcFormat, srcType);
-#ifdef DO_32BIT_STORES
- GLuint *dst = (GLuint *) dstImage;
- GLint row;
- for (row = 0; row < dstHeight; row++) {
- GLint col, col3;
- GLint halfDstWidth = dstWidth >> 1;
- for (col = col3 = 0; col < halfDstWidth; col++, col3 += 6) {
- GLubyte r0 = src[col3 + 0];
- GLubyte g0 = src[col3 + 1];
- GLubyte b0 = src[col3 + 2];
- GLubyte r1 = src[col3 + 3];
- GLubyte g1 = src[col3 + 4];
- GLubyte b1 = src[col3 + 5];
- GLuint d0 = ((r0 & 0xf8) << 8)
- | ((g0 & 0xfc) << 3)
- | ((b0 & 0xf8) >> 3);
- GLuint d1 = ((r1 & 0xf8) << 8)
- | ((g1 & 0xfc) << 3)
- | ((b1 & 0xf8) >> 3);
- dst[col] = (d1 << 16) | d0;
- }
- src += srcStride;
- dst = (GLuint *) ((GLubyte *) dst + dstRowStride);
- }
-#else /* 16-bit stores */
- GLushort *dst = (GLushort *) dstImage;
- GLint row;
- for (row = 0; row < dstHeight; row++) {
- GLint col, col3;
- for (col = col3 = 0; col < dstWidth; col++, col3 += 3) {
- GLubyte r = src[col3 + 0];
- GLubyte g = src[col3 + 1];
- GLubyte b = src[col3 + 2];
- dst[col] = ((r & 0xf8) << 8)
- | ((g & 0xfc) << 3)
- | ((b & 0xf8) >> 3);
- }
- src += srcStride;
- dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
- }
-#endif
- }
- else {
- /* must rescale image */
- GLushort *dst = (GLushort *) dstImage;
- GLint row;
- for (row = 0; row < dstHeight; row++) {
- GLint srcRow = row / hScale;
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth,
- srcHeight, srcFormat, srcType, 0, srcRow, 0);
- GLint col;
- for (col = 0; col < dstWidth; col++) {
- GLint col3 = (col / wScale) * 3;
- GLubyte r = src[col3 + 0];
- GLubyte g = src[col3 + 1];
- GLubyte b = src[col3 + 2];
- dst[col] = ((r & 0xf8) << 8)
- | ((g & 0xfc) << 3)
- | ((b & 0xf8) >> 3);
- }
- dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
- }
- }
- }
- else if (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE) {
- /* general case (used by Quake3) */
- if (wScale == 1 && hScale == 1) {
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
- srcFormat, srcType, 0, 0, 0);
- const GLint srcStride = _mesa_image_row_stride(packing,
- srcWidth, srcFormat, srcType);
-#ifdef DO_32BIT_STORES
- GLuint *dst = dstImage;
- GLint row;
- for (row = 0; row < dstHeight; row++) {
- GLint col, col4;
- GLint halfDstWidth = dstWidth >> 1;
- for (col = col4 = 0; col < halfDstWidth; col++, col4 += 8) {
- GLubyte r0 = src[col4 + 0];
- GLubyte g0 = src[col4 + 1];
- GLubyte b0 = src[col4 + 2];
- GLubyte r1 = src[col4 + 4];
- GLubyte g1 = src[col4 + 5];
- GLubyte b1 = src[col4 + 6];
- GLuint d0 = ((r0 & 0xf8) << 8)
- | ((g0 & 0xfc) << 3)
- | ((b0 & 0xf8) >> 3);
- GLuint d1 = ((r1 & 0xf8) << 8)
- | ((g1 & 0xfc) << 3)
- | ((b1 & 0xf8) >> 3);
- dst[col] = (d1 << 16) | d0;
- }
- src += srcStride;
- dst = (GLuint *) ((GLubyte *) dst + dstRowStride);
- }
-#else /* 16-bit stores */
- GLushort *dst = (GLushort *) dstImage;
- GLint row;
- for (row = 0; row < dstHeight; row++) {
- GLint col, col4;
- for (col = col4 = 0; col < dstWidth; col++, col4 += 4) {
- GLubyte r = src[col4 + 0];
- GLubyte g = src[col4 + 1];
- GLubyte b = src[col4 + 2];
- dst[col] = ((r & 0xf8) << 8)
- | ((g & 0xfc) << 3)
- | ((b & 0xf8) >> 3);
- }
- src += srcStride;
- dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
- }
-#endif
- }
- else {
- /* must rescale image */
- GLushort *dst = (GLushort *) dstImage;
- GLint row;
- for (row = 0; row < dstHeight; row++) {
- GLint srcRow = row / hScale;
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth,
- srcHeight, srcFormat, srcType, 0, srcRow, 0);
- GLint col;
- for (col = 0; col < dstWidth; col++) {
- GLint col4 = (col / wScale) * 4;
- GLubyte r = src[col4 + 0];
- GLubyte g = src[col4 + 1];
- GLubyte b = src[col4 + 2];
- dst[col] = ((r & 0xf8) << 8)
- | ((g & 0xfc) << 3)
- | ((b & 0xf8) >> 3);
- }
- dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
- }
- }
- }
- else {
- /* can't handle this srcFormat/srcType combination */
- return GL_FALSE;
- }
- break;
-
- case MESA_A4_R4_G4_B4:
- /* store as 16-bit texels (GR_TEXFMT_ARGB_4444) */
- if (srcFormat == GL_BGRA && srcType == GL_UNSIGNED_SHORT_4_4_4_4_REV){
- /* special, optimized case */
- if (wScale == 1 && hScale == 1) {
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
- srcFormat, srcType, 0, 0, 0);
- const GLint srcStride = _mesa_image_row_stride(packing,
- srcWidth, srcFormat, srcType);
- GLushort *dst = (GLushort *) dstImage;
- GLint row;
- for (row = 0; row < dstHeight; row++) {
- MEMCPY(dst, src, dstWidth * sizeof(GLushort));
- src += srcStride;
- dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
- }
- }
- else {
- /* must rescale image */
- GLushort *dst = (GLushort *) dstImage;
- GLint row;
- for (row = 0; row < dstHeight; row++) {
- GLint srcRow = row / hScale;
- const GLushort *src = (const GLushort *)
- _mesa_image_address(packing, srcImage, srcWidth,
- srcHeight, srcFormat, srcType, 0, srcRow, 0);
- GLint col;
- for (col = 0; col < dstWidth; col++) {
- dst[col] = src[col / wScale];
- }
- dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
- }
- }
- }
- else if (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE) {
- /* general case */
- if (wScale == 1 && hScale == 1) {
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
- srcFormat, srcType, 0, 0, 0);
- const GLint srcStride = _mesa_image_row_stride(packing,
- srcWidth, srcFormat, srcType);
-#ifdef DO_32BIT_STORES
- GLuint *dst = dstImage;
- GLint row;
- for (row = 0; row < dstHeight; row++) {
- GLint col, col4;
- GLint halfDstWidth = dstWidth >> 1;
- for (col = col4 = 0; col < halfDstWidth; col++, col4 += 8) {
- GLubyte r0 = src[col4 + 0];
- GLubyte g0 = src[col4 + 1];
- GLubyte b0 = src[col4 + 2];
- GLubyte a0 = src[col4 + 3];
- GLubyte r1 = src[col4 + 4];
- GLubyte g1 = src[col4 + 5];
- GLubyte b1 = src[col4 + 6];
- GLubyte a1 = src[col4 + 7];
- GLuint d0 = ((a0 & 0xf0) << 8)
- | ((r0 & 0xf0) << 4)
- | ((g0 & 0xf0) )
- | ((b0 & 0xf0) >> 4);
- GLuint d1 = ((a1 & 0xf0) << 8)
- | ((r1 & 0xf0) << 4)
- | ((g1 & 0xf0) )
- | ((b1 & 0xf0) >> 4);
- dst[col] = (d1 << 16) | d0;
- }
- src += srcStride;
- dst = (GLuint *) ((GLubyte *) dst + dstRowStride);
- }
-#else /* 16-bit stores */
- GLushort *dst = (GLushort *) dstImage;
- GLint row;
- for (row = 0; row < dstHeight; row++) {
- GLint col, col4;
- for (col = col4 = 0; col < dstWidth; col++, col4 += 4) {
- GLubyte r = src[col4 + 0];
- GLubyte g = src[col4 + 1];
- GLubyte b = src[col4 + 2];
- GLubyte a = src[col4 + 3];
- dst[col] = ((a & 0xf0) << 8)
- | ((r & 0xf0) << 4)
- | ((g & 0xf0) )
- | ((b & 0xf0) >> 4);
- }
- src += srcStride;
- dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
- }
-#endif
- }
- else {
- /* must rescale image */
- GLushort *dst = (GLushort *) dstImage;
- GLint row;
- for (row = 0; row < dstHeight; row++) {
- GLint srcRow = row / hScale;
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth,
- srcHeight, srcFormat, srcType, 0, srcRow, 0);
- GLint col;
- for (col = 0; col < dstWidth; col++) {
- GLint col4 = (col / wScale) * 4;
- GLubyte r = src[col4 + 0];
- GLubyte g = src[col4 + 1];
- GLubyte b = src[col4 + 2];
- GLubyte a = src[col4 + 3];
- dst[col] = ((a & 0xf0) << 8)
- | ((r & 0xf0) << 4)
- | ((g & 0xf0) )
- | ((b & 0xf0) >> 4);
- }
- dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
- }
- }
- }
- else {
- /* can't handle this format/srcType combination */
- return GL_FALSE;
- }
- break;
-
- case MESA_A1_R5_G5_B5:
- /* store as 16-bit texels (GR_TEXFMT_ARGB_1555) */
- if (srcFormat == GL_BGRA && srcType == GL_UNSIGNED_SHORT_1_5_5_5_REV){
- /* special, optimized case */
- if (wScale == 1 && hScale == 1) {
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
- srcFormat, srcType, 0, 0, 0);
- const GLint srcStride = _mesa_image_row_stride(packing,
- srcWidth, srcFormat, srcType);
- GLushort *dst = (GLushort *) dstImage;
- GLint row;
- for (row = 0; row < dstHeight; row++) {
- MEMCPY(dst, src, dstWidth * sizeof(GLushort));
- src += srcStride;
- dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
- }
- }
- else {
- /* must rescale image */
- GLushort *dst = (GLushort *) dstImage;
- GLint row;
- for (row = 0; row < dstHeight; row++) {
- GLint srcRow = row / hScale;
- const GLushort *src = (const GLushort *)
- _mesa_image_address(packing, srcImage, srcWidth,
- srcHeight, srcFormat, srcType, 0, srcRow, 0);
- GLint col;
- for (col = 0; col < dstWidth; col++) {
- dst[col] = src[col / wScale];
- }
- dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
- }
- }
- }
- else if (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE) {
- /* general case */
- if (wScale == 1 && hScale == 1) {
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
- srcFormat, srcType, 0, 0, 0);
- const GLint srcStride = _mesa_image_row_stride(packing,
- srcWidth, srcFormat, srcType);
- GLushort *dst = (GLushort *) dstImage;
- GLint row;
- for (row = 0; row < dstHeight; row++) {
- GLint col, col4;
- for (col = col4 = 0; col < dstWidth; col++, col4 += 4) {
- GLubyte r = src[col4 + 0];
- GLubyte g = src[col4 + 1];
- GLubyte b = src[col4 + 2];
- GLubyte a = src[col4 + 3];
- dst[col] = ((a & 0x80) << 8)
- | ((r & 0xf8) << 7)
- | ((g & 0xf8) << 2)
- | ((b & 0xf8) >> 3);
- }
- src += srcStride;
- dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
- }
- }
- else {
- /* must rescale image */
- GLushort *dst = (GLushort *) dstImage;
- GLint row;
- for (row = 0; row < dstHeight; row++) {
- GLint srcRow = row / hScale;
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth,
- srcHeight, srcFormat, srcType, 0, srcRow, 0);
- GLint col;
- for (col = 0; col < dstWidth; col++) {
- GLint col4 = (col / wScale) * 4;
- GLubyte r = src[col4 + 0];
- GLubyte g = src[col4 + 1];
- GLubyte b = src[col4 + 2];
- GLubyte a = src[col4 + 3];
- dst[col] = ((a & 0x80) << 8)
- | ((r & 0xf8) << 7)
- | ((g & 0xf8) << 2)
- | ((b & 0xf8) >> 3);
- }
- dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
- }
- }
- }
- else {
- /* can't handle this source format/type combination */
- return GL_FALSE;
- }
- break;
-
- case MESA_A8_R8_G8_B8:
- case MESA_FF_R8_G8_B8:
- /* 32-bit texels */
- if (srcFormat == GL_BGRA && srcType == GL_UNSIGNED_INT_8_8_8_8_REV){
- /* special, optimized case */
- if (wScale == 1 && hScale == 1) {
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
- srcFormat, srcType, 0, 0, 0);
- const GLint srcStride = _mesa_image_row_stride(packing,
- srcWidth, srcFormat, srcType);
- GLuint *dst = (GLuint *) dstImage;
- GLint row;
- for (row = 0; row < dstHeight; row++) {
- MEMCPY(dst, src, dstWidth * sizeof(GLuint));
- src += srcStride;
- dst = (GLuint *) ((GLubyte *) dst + dstRowStride);
- }
- }
- else {
- /* must rescale image */
- GLuint *dst = (GLuint *) dstImage;
- GLint row;
- for (row = 0; row < dstHeight; row++) {
- GLint srcRow = row / hScale;
- const GLuint *src = (const GLuint *)
- _mesa_image_address(packing, srcImage, srcWidth,
- srcHeight, srcFormat, srcType, 0, srcRow, 0);
- GLint col;
- for (col = 0; col < dstWidth; col++) {
- dst[col] = src[col / wScale];
- }
- dst = (GLuint *) ((GLubyte *) dst + dstRowStride);
- }
- }
- }
- else if (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE) {
- /* general case */
- if (wScale == 1 && hScale == 1) {
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
- srcFormat, srcType, 0, 0, 0);
- const GLint srcStride = _mesa_image_row_stride(packing,
- srcWidth, srcFormat, srcType);
- GLuint *dst = (GLuint *) dstImage;
- GLint row;
- for (row = 0; row < dstHeight; row++) {
- GLint col, col4;
- for (col = col4 = 0; col < dstWidth; col++, col4 += 4) {
- GLubyte r = src[col4 + 0];
- GLubyte g = src[col4 + 1];
- GLubyte b = src[col4 + 2];
- GLubyte a = src[col4 + 3];
- dst[col] = (a << 24) | (r << 16) | (g << 8) | b;
- }
- src += srcStride;
- dst = (GLuint *) ((GLubyte *) dst + dstRowStride);
- }
- }
- else {
- /* must rescale image */
- GLuint *dst = (GLuint *) dstImage;
- GLint row;
- for (row = 0; row < dstHeight; row++) {
- GLint srcRow = row / hScale;
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth,
- srcHeight, srcFormat, srcType, 0, srcRow, 0);
- GLint col;
- for (col = 0; col < dstWidth; col++) {
- GLint col4 = (col / wScale) * 4;
- GLubyte r = src[col4 + 0];
- GLubyte g = src[col4 + 1];
- GLubyte b = src[col4 + 2];
- GLubyte a = src[col4 + 3];
- dst[col] = (a << 24) | (r << 16) | (g << 8) | b;
- }
- dst = (GLuint *) ((GLubyte *) dst + dstRowStride);
- }
- }
- }
- else if (srcFormat == GL_RGB && srcType == GL_UNSIGNED_BYTE) {
- /* general case */
- if (wScale == 1 && hScale == 1) {
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
- srcFormat, srcType, 0, 0, 0);
- const GLint srcStride = _mesa_image_row_stride(packing,
- srcWidth, srcFormat, srcType);
- GLuint *dst = (GLuint *) dstImage;
- GLint row;
- for (row = 0; row < dstHeight; row++) {
- GLint col, col3;
- for (col = col3 = 0; col < dstWidth; col++, col3 += 3) {
- GLubyte r = src[col3 + 0];
- GLubyte g = src[col3 + 1];
- GLubyte b = src[col3 + 2];
- GLubyte a = 255;
- dst[col] = (a << 24) | (r << 16) | (g << 8) | b;
- }
- src += srcStride;
- dst = (GLuint *) ((GLubyte *) dst + dstRowStride);
- }
- }
- else {
- /* must rescale image */
- GLuint *dst = (GLuint *) dstImage;
- GLint row;
- for (row = 0; row < dstHeight; row++) {
- GLint srcRow = row / hScale;
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth,
- srcHeight, srcFormat, srcType, 0, srcRow, 0);
- GLint col;
- for (col = 0; col < dstWidth; col++) {
- GLint col3 = (col / wScale) * 3;
- GLubyte r = src[col3 + 0];
- GLubyte g = src[col3 + 1];
- GLubyte b = src[col3 + 2];
- GLubyte a = 255;
- dst[col] = (a << 24) | (r << 16) | (g << 8) | b;
- }
- dst = (GLuint *) ((GLubyte *) dst + dstRowStride);
- }
- }
- }
- else {
- /* can't handle this source format/type combination */
- return GL_FALSE;
- }
- if (dstFormat == MESA_FF_R8_G8_B8) {
- /* set alpha bytes to 0xff */
- GLint i;
- GLubyte *dst = (GLubyte *) dstImage;
- for (i = 0; i < dstWidth * dstHeight; i++) {
- dst[i * 4 + 3] = 0xff;
- }
- }
- break;
-
- default:
- /* unexpected internal format! */
- return GL_FALSE;
- }
- return GL_TRUE;
+ /* This is a placeholder for now...
+ */
+ return GL_FALSE;
}
+static GLboolean
+convert_texsubimage3d_rgb888( struct gl_texture_convert *convert )
+{
+ /* This is a placeholder for now...
+ */
+ return GL_FALSE;
+}
-/*
- * Replace a subregion of a texture image with new data.
- * Input:
- * dstFormat - destination image format
- * dstXoffset, dstYoffset - destination for new subregion (in texels)
- * dstWidth, dstHeight - total size of dest image (in texels)
- * dstImage - pointer to dest image
- * dstRowStride - bytes to jump between image rows (in bytes)
- * width, height - size of region to copy/replace (in texels)
- * srcWidth, srcHeight - size of the corresponding gl_texture_image
- * srcFormat, srcType - source image format and datatype
- * srcImage - source image
- * packing - source image packing information.
- * Return: GL_TRUE or GL_FALSE for success, failure
- *
- * Notes:
- * Like _mesa_convert_teximage(), we can do power-of-two image scaling
- * to accomodate hardware with texture image aspect ratio constraints.
- * dstWidth / srcWidth is used to compute the horizontal scaling factor and
- * dstHeight / srcHeight is used to compute the vertical scaling factor.
+
+/* ================================================================
+ * RGB565 textures:
*/
-GLboolean
-_mesa_convert_texsubimage(MesaIntTexFormat dstFormat,
- GLint dstXoffset, GLint dstYoffset,
- GLint dstWidth, GLint dstHeight, GLvoid *dstImage,
- GLint dstRowStride,
- GLint width, GLint height,
- GLint srcWidth, GLint srcHeight,
- GLenum srcFormat, GLenum srcType,
- const GLvoid *srcImage,
- const struct gl_pixelstore_attrib *packing)
-{
- const GLint wScale = dstWidth / srcWidth; /* must be power of two */
- const GLint hScale = dstHeight / srcHeight; /* must be power of two */
- ASSERT(dstWidth >= srcWidth);
- ASSERT(dstHeight >= srcHeight);
- ASSERT(dstImage);
- ASSERT(srcImage);
- ASSERT(packing);
-
- width *= wScale;
- height *= hScale;
- dstXoffset *= wScale;
- dstYoffset *= hScale;
-
- /* XXX hscale != 1 and wscale != 1 not tested!!!! */
-
- switch (dstFormat) {
- case MESA_I8:
- case MESA_L8:
- case MESA_A8:
- case MESA_C8:
- if (srcType != GL_UNSIGNED_BYTE ||
- ((srcFormat != GL_INTENSITY) &&
- (srcFormat != GL_LUMINANCE) &&
- (srcFormat != GL_ALPHA) &&
- (srcFormat != GL_COLOR_INDEX))) {
- /* bad internal format / srcFormat combination */
- return GL_FALSE;
- }
- else {
- /* store as 8-bit texels */
- if (wScale == 1 && hScale == 1) {
- /* no scaling needed - fast case */
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
- srcFormat, srcType, 0, 0, 0);
- const GLint srcStride = _mesa_image_row_stride(packing,
- width, srcFormat, srcType);
- GLubyte *dst = (GLubyte *) dstImage
- + dstYoffset * dstRowStride + dstXoffset;
- GLint row;
- for (row = 0; row < height; row++) {
- MEMCPY(dst, src, width * sizeof(GLubyte));
- dst += dstRowStride;
- src += srcStride;
- }
- }
- else {
- /* must rescale image */
- GLubyte *dst = (GLubyte *) dstImage
- + dstYoffset * dstRowStride + dstXoffset;
- GLint row;
- for (row = 0; row < height; row++) {
- GLint srcRow = row / hScale;
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth,
- srcHeight, srcFormat, srcType, 0, srcRow, 0);
- GLint col;
- for (col = 0; col < width; col++) {
- dst[col] = src[col / wScale];
- }
- dst += dstRowStride;
- }
- }
- }
- break;
-
- case MESA_A8_L8:
- if (srcType != GL_UNSIGNED_BYTE || srcFormat != GL_LUMINANCE_ALPHA) {
- return GL_FALSE;
- }
- else {
- /* store as 16-bit texels */
- if (wScale == 1 && hScale == 1) {
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
- srcFormat, srcType, 0, 0, 0);
- const GLint srcStride = _mesa_image_row_stride(packing,
- width, srcFormat, srcType);
- GLushort *dst = (GLushort *) ((GLubyte *) dstImage
- + dstYoffset * dstRowStride) + dstXoffset;
- GLint row, col;
- for (row = 0; row < height; row++) {
- for (col = 0; col < width; col++) {
- GLubyte luminance = src[col * 2 + 0];
- GLubyte alpha = src[col * 2 + 1];
- dst[col] = ((GLushort) alpha << 8) | luminance;
- }
- dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
- src += srcStride;
- }
- }
- else {
- /* must rescale */
- GLushort *dst = (GLushort *) ((GLubyte *) dstImage
- + dstYoffset * dstRowStride) + dstXoffset;
- GLint row, col;
- for (row = 0; row < height; row++) {
- GLint srcRow = row / hScale;
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth,
- srcHeight, srcFormat, srcType, 0, srcRow, 0);
- const GLint srcStride = _mesa_image_row_stride(packing,
- width, srcFormat, srcType);
- for (col = 0; col < width; col++) {
- GLint srcCol = col / wScale;
- GLubyte luminance = src[srcCol * 2 + 0];
- GLubyte alpha = src[srcCol * 2 + 1];
- dst[col] = ((GLushort) alpha << 8) | luminance;
- }
- dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
- src += srcStride;
- }
- }
- }
- break;
-
- case MESA_R5_G6_B5:
- if (srcFormat == GL_RGB && srcType == GL_UNSIGNED_SHORT_5_6_5) {
- /* special, optimized case */
- if (wScale == 1 && hScale == 1) {
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
- srcFormat, srcType, 0, 0, 0);
- const GLint srcStride = _mesa_image_row_stride(packing,
- width, srcFormat, srcType);
- GLushort *dst = (GLushort *) ((GLubyte *) dstImage
- + dstYoffset * dstRowStride) + dstXoffset;
- GLint row;
- for (row = 0; row < height; row++) {
- MEMCPY(dst, src, width * sizeof(GLushort));
- src += srcStride;
- dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
- }
- }
- else {
- /* must rescale image */
- GLushort *dst = (GLushort *) ((GLubyte *) dstImage
- + dstYoffset * dstRowStride) + dstXoffset;
- GLint row;
- for (row = 0; row < height; row++) {
- GLint srcRow = row / hScale;
- const GLushort *src = (const GLushort *)
- _mesa_image_address(packing, srcImage, srcWidth,
- srcHeight, srcFormat, srcType, 0, srcRow, 0);
- GLint col;
- for (col = 0; col < width; col++) {
- dst[col] = src[col / wScale];
- }
- dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
- }
- }
- }
- else if (srcFormat == GL_RGB && srcType == GL_UNSIGNED_BYTE) {
- /* general case */
- if (wScale == 1 && hScale == 1) {
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
- srcFormat, srcType, 0, 0, 0);
- const GLint srcStride = _mesa_image_row_stride(packing,
- width, srcFormat, srcType);
- GLushort *dst = (GLushort *) ((GLubyte *) dstImage
- + dstYoffset * dstRowStride) + dstXoffset;
- GLint row;
- for (row = 0; row < height; row++) {
- GLint col, col3;
- for (col = col3 = 0; col < width; col++, col3 += 3) {
- GLubyte r = src[col3 + 0];
- GLubyte g = src[col3 + 1];
- GLubyte b = src[col3 + 2];
- dst[col] = ((r & 0xf8) << 8)
- | ((g & 0xfc) << 3)
- | ((b & 0xf8) >> 3);
- }
- src += srcStride;
- dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
- }
- }
- else {
- /* must rescale image */
- GLushort *dst = (GLushort *) ((GLubyte *) dstImage
- + dstYoffset * dstRowStride) + dstXoffset;
- GLint row;
- for (row = 0; row < height; row++) {
- GLint srcRow = row / hScale;
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth,
- srcHeight, srcFormat, srcType, 0, srcRow, 0);
- GLint col;
- for (col = 0; col < width; col++) {
- GLint col3 = (col / wScale) * 3;
- GLubyte r = src[col3 + 0];
- GLubyte g = src[col3 + 1];
- GLubyte b = src[col3 + 2];
- dst[col] = ((r & 0xf8) << 8)
- | ((g & 0xfc) << 3)
- | ((b & 0xf8) >> 3);
- }
- dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
- }
- }
- }
- else if (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE) {
- /* general case (used by Quake3) */
- if (wScale == 1 && hScale == 1) {
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
- srcFormat, srcType, 0, 0, 0);
- const GLint srcStride = _mesa_image_row_stride(packing,
- width, srcFormat, srcType);
- GLushort *dst = (GLushort *) ((GLubyte *) dstImage
- + dstYoffset * dstRowStride) + dstXoffset;
- GLint row;
- for (row = 0; row < height; row++) {
- GLint col, col4;
- for (col = col4 = 0; col < width; col++, col4 += 4) {
- GLubyte r = src[col4 + 0];
- GLubyte g = src[col4 + 1];
- GLubyte b = src[col4 + 2];
- dst[col] = ((r & 0xf8) << 8)
- | ((g & 0xfc) << 3)
- | ((b & 0xf8) >> 3);
- }
- src += srcStride;
- dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
- }
- }
- else {
- /* must rescale image */
- GLushort *dst = (GLushort *) ((GLubyte *) dstImage
- + dstYoffset * dstRowStride) + dstXoffset;
- GLint row;
- for (row = 0; row < height; row++) {
- GLint srcRow = row / hScale;
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth,
- srcHeight, srcFormat, srcType, 0, srcRow, 0);
- GLint col;
- for (col = 0; col < width; col++) {
- GLint col4 = (col / wScale) * 4;
- GLubyte r = src[col4 + 0];
- GLubyte g = src[col4 + 1];
- GLubyte b = src[col4 + 2];
- dst[col] = ((r & 0xf8) << 8)
- | ((g & 0xfc) << 3)
- | ((b & 0xf8) >> 3);
- }
- dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
- }
- }
- }
- else {
- /* can't handle this srcFormat/srcType combination */
- return GL_FALSE;
- }
- break;
-
- case MESA_A4_R4_G4_B4:
- /* store as 16-bit texels (GR_TEXFMT_ARGB_4444) */
- if (srcFormat == GL_BGRA && srcType == GL_UNSIGNED_SHORT_4_4_4_4_REV){
- /* special, optimized case */
- if (wScale == 1 && hScale == 1) {
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
- srcFormat, srcType, 0, 0, 0);
- const GLint srcStride = _mesa_image_row_stride(packing,
- width, srcFormat, srcType);
- GLushort *dst = (GLushort *) ((GLubyte *) dstImage
- + dstYoffset * dstRowStride) + dstXoffset;
- GLint row;
- for (row = 0; row < height; row++) {
- MEMCPY(dst, src, width * sizeof(GLushort));
- src += srcStride;
- dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
- }
- }
- else {
- /* must rescale image */
- GLushort *dst = (GLushort *) ((GLubyte *) dstImage
- + dstYoffset * dstRowStride) + dstXoffset;
- GLint row;
- for (row = 0; row < height; row++) {
- GLint srcRow = row / hScale;
- const GLushort *src = (const GLushort *)
- _mesa_image_address(packing, srcImage, srcWidth,
- srcHeight, srcFormat, srcType, 0, srcRow, 0);
- GLint col;
- for (col = 0; col < width; col++) {
- dst[col] = src[col / wScale];
- }
- dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
- }
- }
- }
- else if (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE) {
- /* general case */
- if (wScale == 1 && hScale == 1) {
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
- srcFormat, srcType, 0, 0, 0);
- const GLint srcStride = _mesa_image_row_stride(packing,
- width, srcFormat, srcType);
- GLushort *dst = (GLushort *) ((GLubyte *) dstImage
- + dstYoffset * dstRowStride) + dstXoffset;
- GLint row;
- for (row = 0; row < height; row++) {
- GLint col, col4;
- for (col = col4 = 0; col < width; col++, col4 += 4) {
- GLubyte r = src[col4 + 0];
- GLubyte g = src[col4 + 1];
- GLubyte b = src[col4 + 2];
- GLubyte a = src[col4 + 3];
- dst[col] = ((a & 0xf0) << 8)
- | ((r & 0xf0) << 4)
- | ((g & 0xf0) )
- | ((b & 0xf0) >> 4);
- }
- src += srcStride;
- dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
- }
- }
- else {
- /* must rescale image */
- GLushort *dst = (GLushort *) ((GLubyte *) dstImage
- + dstYoffset * dstRowStride) + dstXoffset;
- GLint row;
- for (row = 0; row < height; row++) {
- GLint srcRow = row / hScale;
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth,
- srcHeight, srcFormat, srcType, 0, srcRow, 0);
- GLint col;
- for (col = 0; col < width; col++) {
- GLint col4 = (col / wScale) * 4;
- GLubyte r = src[col4 + 0];
- GLubyte g = src[col4 + 1];
- GLubyte b = src[col4 + 2];
- GLubyte a = src[col4 + 3];
- dst[col] = ((a & 0xf0) << 8)
- | ((r & 0xf0) << 4)
- | ((g & 0xf0) )
- | ((b & 0xf0) >> 4);
- }
- dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
- }
- }
- }
- else {
- /* can't handle this format/srcType combination */
- return GL_FALSE;
- }
- break;
-
- case MESA_A1_R5_G5_B5:
- /* store as 16-bit texels (GR_TEXFMT_ARGB_1555) */
- if (srcFormat == GL_BGRA && srcType == GL_UNSIGNED_SHORT_1_5_5_5_REV){
- /* special, optimized case */
- if (wScale == 1 && hScale == 1) {
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
- srcFormat, srcType, 0, 0, 0);
- const GLint srcStride = _mesa_image_row_stride(packing,
- width, srcFormat, srcType);
- GLushort *dst = (GLushort *) ((GLubyte *) dstImage
- + dstYoffset * dstRowStride) + dstXoffset;
- GLint row;
- for (row = 0; row < height; row++) {
- MEMCPY(dst, src, width * sizeof(GLushort));
- src += srcStride;
- dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
- }
- }
- else {
- /* must rescale image */
- GLushort *dst = (GLushort *) ((GLubyte *) dstImage
- + dstYoffset * dstRowStride) + dstXoffset;
- GLint row;
- for (row = 0; row < height; row++) {
- GLint srcRow = row / hScale;
- const GLushort *src = (const GLushort *)
- _mesa_image_address(packing, srcImage, srcWidth,
- srcHeight, srcFormat, srcType, 0, srcRow, 0);
- GLint col;
- for (col = 0; col < width; col++) {
- dst[col] = src[col / wScale];
- }
- dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
- }
- }
- }
- else if (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE) {
- /* general case */
- if (wScale == 1 && hScale == 1) {
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
- srcFormat, srcType, 0, 0, 0);
- const GLint srcStride = _mesa_image_row_stride(packing,
- width, srcFormat, srcType);
- GLushort *dst = (GLushort *) ((GLubyte *) dstImage
- + dstYoffset * dstRowStride) + dstXoffset;
- GLint row;
- for (row = 0; row < height; row++) {
- GLint col, col4;
- for (col = col4 = 0; col < width; col++, col4 += 4) {
- GLubyte r = src[col4 + 0];
- GLubyte g = src[col4 + 1];
- GLubyte b = src[col4 + 2];
- GLubyte a = src[col4 + 3];
- dst[col] = ((a & 0x80) << 8)
- | ((r & 0xf8) << 7)
- | ((g & 0xf8) << 2)
- | ((b & 0xf8) >> 3);
- }
- src += srcStride;
- dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
- }
- }
- else {
- /* must rescale image */
- GLushort *dst = (GLushort *) ((GLubyte *) dstImage
- + dstYoffset * dstRowStride) + dstXoffset;
- GLint row;
- for (row = 0; row < height; row++) {
- GLint srcRow = row / hScale;
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth,
- srcHeight, srcFormat, srcType, 0, srcRow, 0);
- GLint col;
- for (col = 0; col < width; col++) {
- GLint col4 = (col / wScale) * 4;
- GLubyte r = src[col4 + 0];
- GLubyte g = src[col4 + 1];
- GLubyte b = src[col4 + 2];
- GLubyte a = src[col4 + 3];
- dst[col] = ((a & 0x80) << 8)
- | ((r & 0xf8) << 7)
- | ((g & 0xf8) << 2)
- | ((b & 0xf8) >> 3);
- }
- dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
- }
- }
- }
- else {
- /* can't handle this source format/type combination */
- return GL_FALSE;
- }
- break;
-
- case MESA_A8_R8_G8_B8:
- case MESA_FF_R8_G8_B8:
- /* 32-bit texels */
- if (srcFormat == GL_BGRA && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) {
- /* special, optimized case */
- if (wScale == 1 && hScale == 1) {
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
- srcFormat, srcType, 0, 0, 0);
- const GLint srcStride = _mesa_image_row_stride(packing,
- width, srcFormat, srcType);
- GLuint *dst = (GLuint *) ((GLubyte *) dstImage
- + dstYoffset * dstRowStride) + dstXoffset;
- GLint row;
- for (row = 0; row < height; row++) {
- MEMCPY(dst, src, width * sizeof(GLuint));
- src += srcStride;
- dst = (GLuint *) ((GLubyte *) dst + dstRowStride);
- }
- }
- else {
- /* must rescale image */
- GLuint *dst = (GLuint *) ((GLubyte *) dstImage
- + dstYoffset * dstRowStride) + dstXoffset;
- GLint row;
- for (row = 0; row < height; row++) {
- GLint srcRow = row / hScale;
- const GLuint *src = (const GLuint *)
- _mesa_image_address(packing, srcImage, srcWidth,
- srcHeight, srcFormat, srcType, 0, srcRow, 0);
- GLint col;
- for (col = 0; col < width; col++) {
- dst[col] = src[col / wScale];
- }
- dst = (GLuint *) ((GLubyte *) dst + dstRowStride);
- }
- }
- if (dstFormat == MESA_FF_R8_G8_B8) {
- /* set alpha bytes to 0xff */
- GLint row, col;
- GLubyte *dst = (GLubyte *) dstImage
- + dstYoffset * dstRowStride + dstXoffset * 4;
- assert(wScale == 1 && hScale == 1); /* XXX not done */
- for (row = 0; row < height; row++) {
- for (col = 0; col < width; col++) {
- dst[col * 4 + 3] = 0xff;
- }
- dst = dst + dstRowStride;
- }
- }
- }
- else if (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE) {
- /* general case */
- const GLubyte aMask = (dstFormat==MESA_FF_R8_G8_B8) ? 0xff : 0x00;
- if (wScale == 1 && hScale == 1) {
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
- srcFormat, srcType, 0, 0, 0);
- const GLint srcStride = _mesa_image_row_stride(packing,
- width, srcFormat, srcType);
- GLuint *dst = (GLuint *) ((GLubyte *) dstImage
- + dstYoffset * dstRowStride) + dstXoffset;
- GLint row;
- for (row = 0; row < height; row++) {
- GLint col, col4;
- for (col = col4 = 0; col < width; col++, col4 += 4) {
- GLubyte r = src[col4 + 0];
- GLubyte g = src[col4 + 1];
- GLubyte b = src[col4 + 2];
- GLubyte a = src[col4 + 3] | aMask;
- dst[col] = (a << 24) | (r << 16) | (g << 8) | b;
- }
- src += srcStride;
- dst = (GLuint *) ((GLubyte *) dst + dstRowStride);
- }
- }
- else {
- /* must rescale image */
- GLuint *dst = (GLuint *) ((GLubyte *) dstImage
- + dstYoffset * dstRowStride) + dstXoffset;
- GLint row;
- for (row = 0; row < height; row++) {
- GLint srcRow = row / hScale;
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address(packing, srcImage, srcWidth,
- srcHeight, srcFormat, srcType, 0, srcRow, 0);
- GLint col;
- for (col = 0; col < width; col++) {
- GLint col4 = (col / wScale) * 4;
- GLubyte r = src[col4 + 0];
- GLubyte g = src[col4 + 1];
- GLubyte b = src[col4 + 2];
- GLubyte a = src[col4 + 3] | aMask;
- dst[col] = (a << 24) | (r << 16) | (g << 8) | b;
- }
- dst = (GLuint *) ((GLubyte *) dst + dstRowStride);
- }
- }
- }
- else {
- /* can't handle this source format/type combination */
- return GL_FALSE;
- }
- break;
-
-
- default:
- /* unexpected internal format! */
- return GL_FALSE;
- }
- return GL_TRUE;
+
+#define DST_TYPE GLushort
+#define DST_TEXELS_PER_DWORD 2
+
+#define CONVERT_TEXEL( src ) \
+ PACK_COLOR_565( src[0], src[1], src[2] )
+
+#define CONVERT_DIRECT
+
+#define SRC_TEXEL_BYTES 2
+
+#define TAG(x) x##_rgb565_direct
+#define PRESERVE_DST_TYPE
+#include "texutil_tmp.h"
+
+
+#define CONVERT_TEXEL( src ) \
+ PACK_COLOR_565( src[0], src[1], src[2] )
+
+#define CONVERT_TEXEL_DWORD( src ) \
+ ((PACK_COLOR_565( src[0], src[1], src[2] )) | \
+ (PACK_COLOR_565( src[3], src[4], src[5] ) << 16))
+
+#define SRC_TEXEL_BYTES 3
+
+#define TAG(x) x##_bgr888_to_rgb565
+#define PRESERVE_DST_TYPE
+#include "texutil_tmp.h"
+
+
+#define CONVERT_TEXEL( src ) \
+ PACK_COLOR_565( src[0], src[1], src[2] )
+
+#define CONVERT_TEXEL_DWORD( src ) \
+ ((PACK_COLOR_565( src[0], src[1], src[2] )) | \
+ (PACK_COLOR_565( src[4], src[5], src[6] ) << 16))
+
+#define SRC_TEXEL_BYTES 4
+
+#define TAG(x) x##_abgr8888_to_rgb565
+#include "texutil_tmp.h"
+
+
+#define CONVERT_RGB565( name ) \
+static GLboolean \
+convert_##name##_rgb565( struct gl_texture_convert *convert ) \
+{ \
+ convert_func *tab; \
+ GLint index = convert->index; \
+ \
+ if ( convert->format == GL_RGB && \
+ convert->type == GL_UNSIGNED_SHORT_5_6_5 ) \
+ { \
+ tab = name##_tab_rgb565_direct; \
+ } \
+ else if ( convert->format == GL_RGB && \
+ convert->type == GL_UNSIGNED_BYTE ) \
+ { \
+ tab = name##_tab_bgr888_to_rgb565; \
+ } \
+ else if ( convert->format == GL_RGBA && \
+ convert->type == GL_UNSIGNED_BYTE ) \
+ { \
+ tab = name##_tab_abgr8888_to_rgb565; \
+ } \
+ else \
+ { \
+ /* Can't handle this source format/type combination */ \
+ return GL_FALSE; \
+ } \
+ \
+ return tab[index]( convert ); \
}
+CONVERT_RGB565( texsubimage2d )
+CONVERT_RGB565( texsubimage3d )
-/*
- * Used to convert 16-bit texels into GLubyte color components.
+/* ================================================================
+ * ARGB4444 textures:
+ */
+
+#define DST_TYPE GLushort
+#define DST_TEXELS_PER_DWORD 2
+
+#define CONVERT_TEXEL( src ) \
+ PACK_COLOR_4444( src[3], src[0], src[1], src[2] )
+
+#define CONVERT_DIRECT
+
+#define SRC_TEXEL_BYTES 2
+
+#define TAG(x) x##_argb4444_direct
+#define PRESERVE_DST_TYPE
+#include "texutil_tmp.h"
+
+
+#define CONVERT_TEXEL( src ) \
+ PACK_COLOR_4444( src[3], src[0], src[1], src[2] )
+
+#define CONVERT_TEXEL_DWORD( src ) \
+ ((PACK_COLOR_4444( src[3], src[0], src[1], src[2] )) | \
+ (PACK_COLOR_4444( src[7], src[4], src[5], src[6] ) << 16))
+
+#define SRC_TEXEL_BYTES 4
+
+#define TAG(x) x##_rgba8888_to_argb4444
+#include "texutil_tmp.h"
+
+
+#define CONVERT_ARGB4444( name ) \
+static GLboolean \
+convert_##name##_argb4444( struct gl_texture_convert *convert ) \
+{ \
+ convert_func *tab; \
+ GLint index = convert->index; \
+ \
+ if ( convert->format == GL_BGRA && \
+ convert->type == GL_UNSIGNED_SHORT_4_4_4_4_REV ) \
+ { \
+ tab = name##_tab_argb4444_direct; \
+ } \
+ else if ( convert->format == GL_RGBA && \
+ convert->type == GL_UNSIGNED_BYTE ) \
+ { \
+ tab = name##_tab_rgba8888_to_argb4444; \
+ } \
+ else \
+ { \
+ /* Can't handle this source format/type combination */ \
+ return GL_FALSE; \
+ } \
+ \
+ return tab[index]( convert ); \
+}
+
+CONVERT_ARGB4444( texsubimage2d )
+CONVERT_ARGB4444( texsubimage3d )
+
+
+
+/* ================================================================
+ * ARGB1555 textures:
+ */
+
+#define DST_TYPE GLushort
+#define DST_TEXELS_PER_DWORD 2
+
+#define CONVERT_TEXEL( src ) \
+ PACK_COLOR_1555( src[3], src[0], src[1], src[2] )
+
+#define CONVERT_DIRECT
+
+#define SRC_TEXEL_BYTES 2
+
+#define TAG(x) x##_argb1555_direct
+#define PRESERVE_DST_TYPE
+#include "texutil_tmp.h"
+
+
+#define CONVERT_TEXEL( src ) \
+ PACK_COLOR_1555( src[3], src[0], src[1], src[2] )
+
+#define CONVERT_TEXEL_DWORD( src ) \
+ ((PACK_COLOR_1555( src[3], src[0], src[1], src[2] )) | \
+ (PACK_COLOR_1555( src[7], src[4], src[5], src[6] ) << 16))
+
+#define SRC_TEXEL_BYTES 4
+
+#define TAG(x) x##_rgba8888_to_argb1555
+#include "texutil_tmp.h"
+
+
+#define CONVERT_ARGB1555( name ) \
+static GLboolean \
+convert_##name##_argb1555( struct gl_texture_convert *convert ) \
+{ \
+ convert_func *tab; \
+ GLint index = convert->index; \
+ \
+ if ( convert->format == GL_BGRA && \
+ convert->type == GL_UNSIGNED_SHORT_1_5_5_5_REV ) \
+ { \
+ tab = name##_tab_argb1555_direct; \
+ } \
+ else if ( convert->format == GL_RGBA && \
+ convert->type == GL_UNSIGNED_BYTE ) \
+ { \
+ tab = name##_tab_rgba8888_to_argb1555; \
+ } \
+ else \
+ { \
+ /* Can't handle this source format/type combination */ \
+ return GL_FALSE; \
+ } \
+ \
+ return tab[index]( convert ); \
+}
+
+CONVERT_ARGB1555( texsubimage2d )
+CONVERT_ARGB1555( texsubimage3d )
+
+
+
+/* ================================================================
+ * AL88 textures:
+ */
+
+#define DST_TYPE GLushort
+#define DST_TEXELS_PER_DWORD 2
+
+#define CONVERT_TEXEL( src ) \
+ PACK_COLOR_88( src[0], src[1] )
+
+#define CONVERT_DIRECT
+
+#define SRC_TEXEL_BYTES 2
+
+#define TAG(x) x##_al88_direct
+#define PRESERVE_DST_TYPE
+#include "texutil_tmp.h"
+
+
+#define CONVERT_TEXEL( src ) \
+ PACK_COLOR_88( src[0], 0x00 )
+
+#define CONVERT_TEXEL_DWORD( src ) \
+ ((PACK_COLOR_88( src[0], 0x00 )) | \
+ (PACK_COLOR_88( src[1], 0x00 ) << 16))
+
+#define SRC_TEXEL_BYTES 1
+
+#define TAG(x) x##_a8_to_al88
+#define PRESERVE_DST_TYPE
+#include "texutil_tmp.h"
+
+
+#define CONVERT_TEXEL( src ) \
+ PACK_COLOR_88( 0xff, src[0] )
+
+#define CONVERT_TEXEL_DWORD( src ) \
+ ((PACK_COLOR_88( 0xff, src[0] )) | \
+ (PACK_COLOR_88( 0xff, src[1] ) << 16))
+
+#define SRC_TEXEL_BYTES 1
+
+#define TAG(x) x##_l8_to_al88
+#include "texutil_tmp.h"
+
+
+#define CONVERT_AL88( name ) \
+static GLboolean \
+convert_##name##_al88( struct gl_texture_convert *convert ) \
+{ \
+ convert_func *tab; \
+ GLint index = convert->index; \
+ \
+ if ( convert->format == GL_LUMINANCE_ALPHA && \
+ convert->type == GL_UNSIGNED_BYTE ) \
+ { \
+ tab = name##_tab_al88_direct; \
+ } \
+ else if ( convert->format == GL_ALPHA && \
+ convert->type == GL_UNSIGNED_BYTE ) \
+ { \
+ tab = name##_tab_a8_to_al88; \
+ } \
+ else if ( convert->format == GL_LUMINANCE && \
+ convert->type == GL_UNSIGNED_BYTE ) \
+ { \
+ tab = name##_tab_l8_to_al88; \
+ } \
+ else \
+ { \
+ /* Can't handle this source format/type combination */ \
+ return GL_FALSE; \
+ } \
+ \
+ return tab[index]( convert ); \
+}
+
+CONVERT_AL88( texsubimage2d )
+CONVERT_AL88( texsubimage3d )
+
+
+
+/* ================================================================
+ * RGB332 textures:
*/
-static GLubyte R5G6B5toRed[0xffff];
-static GLubyte R5G6B5toGreen[0xffff];
-static GLubyte R5G6B5toBlue[0xffff];
-
-static GLubyte A4R4G4B4toRed[0xffff];
-static GLubyte A4R4G4B4toGreen[0xffff];
-static GLubyte A4R4G4B4toBlue[0xffff];
-static GLubyte A4R4G4B4toAlpha[0xffff];
-
-static GLubyte A1R5G5B5toRed[0xffff];
-static GLubyte A1R5G5B5toGreen[0xffff];
-static GLubyte A1R5G5B5toBlue[0xffff];
-static GLubyte A1R5G5B5toAlpha[0xffff];
-
-static void
-generate_lookup_tables(void)
+
+static GLboolean
+convert_texsubimage2d_rgb332( struct gl_texture_convert *convert )
{
- GLint i;
- for (i = 0; i <= 0xffff; i++) {
- GLint r = (i >> 8) & 0xf8;
- GLint g = (i >> 3) & 0xfc;
- GLint b = (i << 3) & 0xf8;
- r = r * 255 / 0xf8;
- g = g * 255 / 0xfc;
- b = b * 255 / 0xf8;
- R5G6B5toRed[i] = r;
- R5G6B5toGreen[i] = g;
- R5G6B5toBlue[i] = b;
- }
+ /* This is a placeholder for now...
+ */
+ return GL_FALSE;
+}
- for (i = 0; i <= 0xffff; i++) {
- GLint r = (i >> 8) & 0xf;
- GLint g = (i >> 4) & 0xf;
- GLint b = (i ) & 0xf;
- GLint a = (i >> 12) & 0xf;
- r = r * 255 / 0xf;
- g = g * 255 / 0xf;
- b = b * 255 / 0xf;
- a = a * 255 / 0xf;
- A4R4G4B4toRed[i] = r;
- A4R4G4B4toGreen[i] = g;
- A4R4G4B4toBlue[i] = b;
- A4R4G4B4toAlpha[i] = a;
- }
+static GLboolean
+convert_texsubimage3d_rgb332( struct gl_texture_convert *convert )
+{
+ /* This is a placeholder for now...
+ */
+ return GL_FALSE;
+}
- for (i = 0; i <= 0xffff; i++) {
- GLint r = (i >> 10) & 0xf8;
- GLint g = (i >> 5) & 0xf8;
- GLint b = (i ) & 0xf8;
- GLint a = (i >> 15) & 0x1;
- r = r * 255 / 0xf8;
- g = g * 255 / 0xf8;
- b = b * 255 / 0xf8;
- a = a * 255;
- A1R5G5B5toRed[i] = r;
- A1R5G5B5toGreen[i] = g;
- A1R5G5B5toBlue[i] = b;
- A1R5G5B5toAlpha[i] = a;
- }
+
+
+/* ================================================================
+ * CI8 (and all other single-byte texel) textures:
+ */
+
+#define DST_TYPE GLubyte
+#define DST_TEXELS_PER_DWORD 4
+
+#define CONVERT_TEXEL( src ) src[0]
+
+#define CONVERT_DIRECT
+
+#define SRC_TEXEL_BYTES 1
+
+#define TAG(x) x##_ci8_direct
+#include "texutil_tmp.h"
+
+
+#define CONVERT_CI8( name ) \
+static GLboolean \
+convert_##name##_ci8( struct gl_texture_convert *convert ) \
+{ \
+ convert_func *tab; \
+ GLint index = convert->index; \
+ \
+ if ( ( convert->format == GL_ALPHA || \
+ convert->format == GL_LUMINANCE || \
+ convert->format == GL_INTENSITY || \
+ convert->format == GL_COLOR_INDEX ) && \
+ convert->type == GL_UNSIGNED_BYTE ) \
+ { \
+ tab = name##_tab_ci8_direct; \
+ } \
+ else \
+ { \
+ /* Can't handle this source format/type combination */ \
+ return GL_FALSE; \
+ } \
+ \
+ return tab[index]( convert ); \
}
+CONVERT_CI8( texsubimage2d )
+CONVERT_CI8( texsubimage3d )
-/*
- * Convert a texture image from an internal format to one of Mesa's
- * core internal formats. This is likely to be used by glGetTexImage
- * and for fetching texture images when falling back to software rendering.
- *
- * Input:
- * srcFormat - source image format
- * srcWidth, srcHeight - source image size
- * srcImage - source image pointer
- * srcRowStride - bytes to jump between image rows
- * dstWidth, dstHeight - size of dest image
- * dstFormat - format of dest image (must be one of Mesa's IntFormat values)
- * dstImage - pointer to dest image
- * Notes:
- * This function will do power of two image down-scaling to accomodate
- * drivers with limited texture image aspect ratios.
- * The implicit dest data type is GL_UNSIGNED_BYTE.
+
+/* ================================================================
+ * Global entry points
*/
-void
-_mesa_unconvert_teximage(MesaIntTexFormat srcFormat,
- GLint srcWidth, GLint srcHeight,
- const GLvoid *srcImage, GLint srcRowStride,
- GLint dstWidth, GLint dstHeight,
- GLenum dstFormat, GLubyte *dstImage)
+
+static convert_func gl_convert_texsubimage2d_tab[] = {
+ convert_texsubimage2d_rgba8888,
+ convert_texsubimage2d_argb8888,
+ convert_texsubimage2d_rgb888,
+ convert_texsubimage2d_rgb565,
+ convert_texsubimage2d_argb4444,
+ convert_texsubimage2d_argb1555,
+ convert_texsubimage2d_al88,
+ convert_texsubimage2d_rgb332,
+ convert_texsubimage2d_ci8, /* These are all the same... */
+ convert_texsubimage2d_ci8,
+ convert_texsubimage2d_ci8,
+ convert_texsubimage2d_ci8,
+};
+
+static convert_func gl_convert_texsubimage3d_tab[] = {
+ convert_texsubimage3d_rgba8888,
+ convert_texsubimage3d_argb8888,
+ convert_texsubimage3d_rgb888,
+ convert_texsubimage3d_rgb565,
+ convert_texsubimage3d_argb4444,
+ convert_texsubimage3d_argb1555,
+ convert_texsubimage3d_al88,
+ convert_texsubimage3d_rgb332,
+ convert_texsubimage3d_ci8, /* These are all the same... */
+ convert_texsubimage3d_ci8,
+ convert_texsubimage3d_ci8,
+ convert_texsubimage3d_ci8,
+};
+
+
+/* See if we need to care about the pixel store attributes when we're
+ * converting the texture image. This should be stored as
+ * packing->_SomeBoolean and updated when the values change, to avoid
+ * testing every time...
+ */
+static INLINE GLboolean
+convert_needs_packing( const struct gl_pixelstore_attrib *packing,
+ GLenum format, GLenum type )
{
- static GLboolean firstCall = GL_TRUE;
- const GLint wScale = srcWidth / dstWidth; /* must be power of two */
- const GLint hScale = srcHeight / dstHeight; /* must be power of two */
- ASSERT(srcWidth >= dstWidth);
- ASSERT(srcHeight >= dstHeight);
- ASSERT(dstImage);
- ASSERT(srcImage);
-
- if (firstCall) {
- generate_lookup_tables();
- firstCall = GL_FALSE;
+ if ( ( packing->Alignment == 1 ||
+ ( packing->Alignment == 4 && /* Pick up the common Q3A case... */
+ format == GL_RGBA && type == GL_UNSIGNED_BYTE ) ) &&
+ packing->RowLength == 0 &&
+ packing->SkipPixels == 0 &&
+ packing->SkipRows == 0 &&
+ packing->ImageHeight == 0 &&
+ packing->SkipImages == 0 &&
+ packing->SwapBytes == GL_FALSE &&
+ packing->LsbFirst == GL_FALSE ) {
+ return GL_FALSE;
+ } else {
+ return GL_TRUE;
}
+}
- switch (srcFormat) {
- case MESA_I8:
- case MESA_L8:
- case MESA_A8:
- case MESA_C8:
-#ifdef DEBUG
- if (srcFormat == MESA_I8) {
- ASSERT(dstFormat == GL_INTENSITY);
- }
- else if (srcFormat == MESA_L8) {
- ASSERT(dstFormat == GL_LUMINANCE);
- }
- else if (srcFormat == MESA_A8) {
- ASSERT(dstFormat == GL_ALPHA);
- }
- else if (srcFormat == MESA_C8) {
- ASSERT(dstFormat == GL_COLOR_INDEX);
- }
-#endif
- if (wScale == 1 && hScale == 1) {
- /* easy! */
- MEMCPY(dstImage, srcImage, dstWidth * dstHeight * sizeof(GLubyte));
- }
- else {
- /* rescale */
- const GLubyte *src8 = (const GLubyte *) srcImage;
- GLint row, col;
- for (row = 0; row < dstHeight; row++) {
- GLint srcRow = row * hScale;
- for (col = 0; col < dstWidth; col++) {
- GLint srcCol = col * wScale;
- *dstImage++ = src8[srcRow * srcWidth + srcCol];
- }
- }
- }
- break;
- case MESA_A8_L8:
- ASSERT(dstFormat == GL_LUMINANCE_ALPHA);
- if (wScale == 1 && hScale == 1) {
- GLint i, n = dstWidth * dstHeight;
- const GLushort *texel = (const GLushort *) srcImage;
- for (i = 0; i < n; i++) {
- const GLushort tex = *texel++;
- *dstImage++ = (tex & 0xff); /* luminance */
- *dstImage++ = (tex >> 8); /* alpha */
- }
- }
- else {
- /* rescale */
- const GLushort *src16 = (const GLushort *) srcImage;
- GLint row, col;
- for (row = 0; row < dstHeight; row++) {
- GLint srcRow = row * hScale;
- for (col = 0; col < dstWidth; col++) {
- GLint srcCol = col * wScale;
- const GLushort tex = src16[srcRow * srcWidth + srcCol];
- *dstImage++ = (tex & 0xff); /* luminance */
- *dstImage++ = (tex >> 8); /* alpha */
- }
- }
- }
- break;
- case MESA_R5_G6_B5:
- ASSERT(dstFormat == GL_RGB);
- if (wScale == 1 && hScale == 1) {
- GLint i, n = dstWidth * dstHeight;
- const GLushort *texel = (const GLushort *) srcImage;
- for (i = 0; i < n; i++) {
- const GLushort tex = *texel++;
- *dstImage++ = R5G6B5toRed[tex];
- *dstImage++ = R5G6B5toGreen[tex];
- *dstImage++ = R5G6B5toBlue[tex];
- }
- }
- else {
- /* rescale */
- const GLushort *src16 = (const GLushort *) srcImage;
- GLint row, col;
- for (row = 0; row < dstHeight; row++) {
- GLint srcRow = row * hScale;
- for (col = 0; col < dstWidth; col++) {
- GLint srcCol = col * wScale;
- const GLushort tex = src16[srcRow * srcWidth + srcCol];
- *dstImage++ = R5G6B5toRed[tex];
- *dstImage++ = R5G6B5toGreen[tex];
- *dstImage++ = R5G6B5toBlue[tex];
- }
- }
- }
- break;
- case MESA_A4_R4_G4_B4:
- ASSERT(dstFormat == GL_RGBA);
- if (wScale == 1 && hScale == 1) {
- GLint i, n = dstWidth * dstHeight;
- const GLushort *texel = (const GLushort *) srcImage;
- for (i = 0; i < n; i++) {
- const GLushort tex = *texel++;
- *dstImage++ = A4R4G4B4toRed[tex];
- *dstImage++ = A4R4G4B4toGreen[tex];
- *dstImage++ = A4R4G4B4toBlue[tex];
- *dstImage++ = A4R4G4B4toAlpha[tex];
- }
- }
- else {
- /* rescale */
- const GLushort *src16 = (const GLushort *) srcImage;
- GLint row, col;
- for (row = 0; row < dstHeight; row++) {
- GLint srcRow = row * hScale;
- for (col = 0; col < dstWidth; col++) {
- GLint srcCol = col * wScale;
- const GLushort tex = src16[srcRow * srcWidth + srcCol];
- *dstImage++ = A4R4G4B4toRed[tex];
- *dstImage++ = A4R4G4B4toGreen[tex];
- *dstImage++ = A4R4G4B4toBlue[tex];
- *dstImage++ = A4R4G4B4toAlpha[tex];
- }
- }
- }
- break;
- case MESA_A1_R5_G5_B5:
- ASSERT(dstFormat == GL_RGBA);
- if (wScale == 1 && hScale == 1) {
- GLint i, n = dstWidth * dstHeight;
- const GLushort *texel = (const GLushort *) srcImage;
- for (i = 0; i < n; i++) {
- const GLushort tex = *texel++;
- *dstImage++ = A1R5G5B5toRed[tex];
- *dstImage++ = A1R5G5B5toGreen[tex];
- *dstImage++ = A1R5G5B5toBlue[tex];
- *dstImage++ = A1R5G5B5toAlpha[tex];
- }
- }
- else {
- /* rescale */
- const GLushort *src16 = (const GLushort *) srcImage;
- GLint row, col;
- for (row = 0; row < dstHeight; row++) {
- GLint srcRow = row * hScale;
- for (col = 0; col < dstWidth; col++) {
- GLint srcCol = col * wScale;
- const GLushort tex = src16[srcRow * srcWidth + srcCol];
- *dstImage++ = A1R5G5B5toRed[tex];
- *dstImage++ = A1R5G5B5toGreen[tex];
- *dstImage++ = A1R5G5B5toBlue[tex];
- *dstImage++ = A1R5G5B5toAlpha[tex];
- }
- }
- }
- break;
- case MESA_A8_R8_G8_B8:
- case MESA_FF_R8_G8_B8:
- ASSERT(dstFormat == GL_RGBA);
- if (wScale == 1 && hScale == 1) {
- GLint i, n = dstWidth * dstHeight;
- const GLuint *texel = (const GLuint *) srcImage;
- for (i = 0; i < n; i++) {
- const GLuint tex = *texel++;
- *dstImage++ = (tex >> 16) & 0xff; /* R */
- *dstImage++ = (tex >> 8) & 0xff; /* G */
- *dstImage++ = (tex ) & 0xff; /* B */
- *dstImage++ = (tex >> 24) & 0xff; /* A */
- }
- }
- else {
- /* rescale */
- const GLuint *src = (const GLuint *) srcImage;
- GLint row, col;
- for (row = 0; row < dstHeight; row++) {
- GLint srcRow = row * hScale;
- for (col = 0; col < dstWidth; col++) {
- GLint srcCol = col * wScale;
- const GLuint tex = src[srcRow * srcWidth + srcCol];
- *dstImage++ = (tex >> 16) & 0xff; /* R */
- *dstImage++ = (tex >> 8) & 0xff; /* G */
- *dstImage++ = (tex ) & 0xff; /* B */
- *dstImage++ = (tex >> 24) & 0xff; /* A */
- }
- }
- }
- break;
- default:
- _mesa_problem(NULL, "bad srcFormat in _mesa_uncovert_teximage()");
- }
+
+GLboolean
+_mesa_convert_texsubimage1d( GLint mesaFormat,
+ GLint xoffset,
+ GLint width,
+ GLenum format, GLenum type,
+ const struct gl_pixelstore_attrib *packing,
+ const GLvoid *srcImage, GLvoid *dstImage )
+{
+ struct gl_texture_convert convert;
+
+ ASSERT( packing );
+ ASSERT( srcImage );
+ ASSERT( dstImage );
+
+ ASSERT( mesaFormat >= MESA_FORMAT_RGBA8888 );
+ ASSERT( mesaFormat <= MESA_FORMAT_CI8 );
+
+ /* Make it easier to pass all the parameters around.
+ */
+ convert.xoffset = xoffset;
+ convert.yoffset = 0;
+ convert.width = width;
+ convert.height = 1;
+ convert.format = format;
+ convert.type = type;
+ convert.packing = packing;
+ convert.srcImage = srcImage;
+ convert.dstImage = dstImage;
+
+ convert.index = 0;
+
+ if ( convert_needs_packing( packing, format, type ) )
+ convert.index |= CONVERT_PACKING_BIT;
+
+ return gl_convert_texsubimage2d_tab[mesaFormat]( &convert );
}
+GLboolean
+_mesa_convert_texsubimage2d( GLint mesaFormat,
+ GLint xoffset, GLint yoffset,
+ GLint width, GLint height,
+ GLint imageWidth,
+ GLenum format, GLenum type,
+ const struct gl_pixelstore_attrib *packing,
+ const GLvoid *srcImage, GLvoid *dstImage )
+{
+ struct gl_texture_convert convert;
+ ASSERT( packing );
+ ASSERT( srcImage );
+ ASSERT( dstImage );
-/*
- * Given an internal Mesa driver texture format, fill in the component
- * bit sizes in the given texture image struct.
+ ASSERT( mesaFormat >= MESA_FORMAT_RGBA8888 );
+ ASSERT( mesaFormat <= MESA_FORMAT_CI8 );
+
+ /* Make it easier to pass all the parameters around.
+ */
+ convert.xoffset = xoffset;
+ convert.yoffset = yoffset;
+ convert.width = width;
+ convert.height = height;
+ convert.imageWidth = imageWidth;
+ convert.format = format;
+ convert.type = type;
+ convert.packing = packing;
+ convert.srcImage = srcImage;
+ convert.dstImage = dstImage;
+
+ convert.index = 0;
+
+ if ( convert_needs_packing( packing, format, type ) )
+ convert.index |= CONVERT_PACKING_BIT;
+
+ if ( width != imageWidth )
+ convert.index |= CONVERT_STRIDE_BIT;
+
+ return gl_convert_texsubimage2d_tab[mesaFormat]( &convert );
+}
+
+GLboolean
+_mesa_convert_texsubimage3d( GLint mesaFormat,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLint width, GLint height, GLint depth,
+ GLint imageWidth, GLint imageHeight,
+ GLenum format, GLenum type,
+ const struct gl_pixelstore_attrib *packing,
+ const GLvoid *srcImage, GLvoid *dstImage )
+{
+ struct gl_texture_convert convert;
+
+ ASSERT( packing );
+ ASSERT( srcImage );
+ ASSERT( dstImage );
+
+ ASSERT( mesaFormat >= MESA_FORMAT_RGBA8888 );
+ ASSERT( mesaFormat <= MESA_FORMAT_CI8 );
+
+ /* Make it easier to pass all the parameters around.
+ */
+ convert.xoffset = xoffset;
+ convert.yoffset = yoffset;
+ convert.zoffset = zoffset;
+ convert.width = width;
+ convert.height = height;
+ convert.depth = depth;
+ convert.imageWidth = imageWidth;
+ convert.imageHeight = imageHeight;
+ convert.format = format;
+ convert.type = type;
+ convert.packing = packing;
+ convert.srcImage = srcImage;
+ convert.dstImage = dstImage;
+
+ convert.index = 0;
+
+ if ( convert_needs_packing( packing, format, type ) )
+ convert.index |= CONVERT_PACKING_BIT;
+
+ if ( width != imageWidth || height != imageHeight )
+ convert.index |= CONVERT_STRIDE_BIT;
+
+ return gl_convert_texsubimage3d_tab[mesaFormat]( &convert );
+}
+
+
+
+/* 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_set_teximage_component_sizes(MesaIntTexFormat mesaFormat,
- struct gl_texture_image *texImage)
+void _mesa_rescale_teximage2d( const struct gl_texture_format *texFormat,
+ GLint srcWidth, GLint srcHeight,
+ GLint dstWidth, GLint dstHeight,
+ const GLvoid *srcImage, GLvoid *dstImage )
{
- static const GLint bitSizes [][8] = {
- /* format R G B A I L C */
- { MESA_I8, 0, 0, 0, 0, 8, 0, 0 },
- { MESA_L8, 0, 0, 0, 0, 0, 8, 0 },
- { MESA_A8, 0, 0, 0, 8, 0, 0, 0 },
- { MESA_C8, 0, 0, 0, 0, 0, 0, 8 },
- { MESA_A8_L8, 0, 0, 0, 8, 0, 8, 0 },
- { MESA_R5_G6_B5, 5, 6, 5, 0, 0, 0, 0 },
- { MESA_A4_R4_G4_B4, 4, 4, 4, 4, 0, 0, 0 },
- { MESA_A1_R5_G5_B5, 5, 5, 5, 1, 0, 0, 0 },
- { MESA_A8_R8_G8_B8, 8, 8, 8, 8, 0, 0, 0 },
- { MESA_FF_R8_G8_B8, 8, 8, 8, 8, 0, 0, 0 },
- { -1, 0, 0, 0, 0, 0, 0, 0 }
- };
- GLint i;
- for (i = 0; i < bitSizes[i][0] >= 0; i++) {
- if (bitSizes[i][0] == mesaFormat) {
- texImage->RedBits = bitSizes[i][1];
- texImage->GreenBits = bitSizes[i][2];
- texImage->BlueBits = bitSizes[i][3];
- texImage->AlphaBits = bitSizes[i][4];
- texImage->IntensityBits = bitSizes[i][5];
- texImage->LuminanceBits = bitSizes[i][6];
- texImage->IndexBits = bitSizes[i][7];
- return;
- }
+ GLint row, col;
+
+#define INNER_LOOP( 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++ = src[srcRow * srcWidth + srcCol]; \
+ } \
+ } \
+
+#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( /, / ); \
+ } \
+ else { \
+ const GLint wScale = srcWidth / dstWidth; \
+ INNER_LOOP( /, * ); \
+ } \
+ } \
+ else { \
+ const GLint hScale = srcHeight / dstHeight; \
+ if ( srcWidth <= dstWidth ) { \
+ const GLint wScale = dstWidth / srcWidth; \
+ INNER_LOOP( *, / ); \
+ } \
+ else { \
+ const GLint wScale = srcWidth / dstWidth; \
+ INNER_LOOP( *, * ); \
+ } \
+ } \
+} while (0)
+
+ switch ( texFormat->TexelBytes ) {
+ case 4:
+ RESCALE_IMAGE( GLuint );
+ break;
+
+ case 2:
+ RESCALE_IMAGE( GLushort );
+ break;
+
+ case 1:
+ RESCALE_IMAGE( GLubyte );
+ break;
}
- _mesa_problem(NULL, "bad format in _mesa_set_teximage_component_sizes");
}