/* * $Id$ * * $Date$ * $Revision$ * * (C) 1999 by Hyperion * All rights reserved * * This file is part of the MiniGL library project * See the file Licence.txt for more details * */ #include "displaylists.h" #include "sysinc.h" #include #include #include #include extern char *format_to_string(GLenum format); extern char *type_to_string(GLenum type); /* * This file implements span unpackers that unpack from a given format/datatype * combination to a 32 bit ARGB buffer (color), 32 bit float (depth) buffer, or * 32 bit integer (stencil) buffer. * * NOTE: This functionality duplicates some of textureconvert.c, however, this is * goint to replace that functionality later on. */ #define REDBYTE(rgb) (((UWORD)rgb & 0xF800) >> 8) #define GREENBYTE(rgb) (((UWORD)rgb & 0x07E0) >> 3) #define BLUEBYTE(rgb) (((UWORD)rgb & 0x001F) << 3) #define REDBYTEA(rgba) (((UWORD)rgba & 0x0f00) >> 4) #define GREENBYTEA(rgba) (((UWORD)rgba & 0x00f0)) #define BLUEBYTEA(rgba) (((UWORD)rgba & 0x000f) << 4) #define ALPHABYTEA(rgba) (((UWORD)rgba & 0xf000) >> 8) #define REDBYTE5551(rgba) (((UWORD)rgba & 0x7C00) >> 7) #define GREENBYTE5551(rgba) (((UWORD)rgba & 0x03e0) >> 2) #define BLUEBYTE5551(rgba) (((UWORD)rgba & 0x001F) << 3) #define ALPHABYTE5551(rgba) (((UWORD)rgba & 0x8000) ? 0xff : 0x00) static inline uint16 load_16_little(uint16 *addr) { uint16 x; __asm volatile ("lhbrx %0, 0, %1" : "=r" (x) : "r" (addr)); return x; } static inline void store_16_little(uint16 *addr, uint16 val) { __asm volatile ("sthbrx %0, 0, %1" :: "r" (val), "r" (addr)); } static inline uint32 load_32_little(uint32 *addr) { uint32 x; __asm volatile ("lwbrx %0, 0, %1" : "=r" (x) : "r" (addr)); return x; } static inline void store_32_little(uint32 *addr, uint32 val) { __asm volatile ("stwbrx %0, 0, %1" :: "r" (val), "r" (addr)); } #define R_COMPONENT 0 #define G_COMPONENT 1 #define B_COMPONENT 2 #define A_COMPONENT 3 static void _unpack_rgb_b(GLcontext context, int num_pixels, GLimage_info *src, GLpixel_store *unpack, void *dst) { uint8 *to = (uint8 *)dst; uint8 *from = (uint8 *)src->current; /* Note: swap_bytes not defined for three-byte pixels */ while (num_pixels--) { to[R_COMPONENT] = *from++; to[G_COMPONENT] = *from++; to[B_COMPONENT] = *from++; to[A_COMPONENT] = 0xff; to += 4; } } static void _unpack_rgba_b(GLcontext context, int num_pixels, GLimage_info *src, GLpixel_store *unpack, void *dst) { uint32 *to = (uint32 *)dst; uint32 *from = (uint32 *)src->current; if (unpack->swap_bytes) { while (num_pixels--) *to++ = load_32_little(from++); } else { while (num_pixels--) *to++ = *from++; } } static void _unpack_argb_b(GLcontext context, int num_pixels, GLimage_info *src, GLpixel_store *unpack, void *dst) { uint32 *to = (uint32 *)dst; uint32 *from = (uint32 *)src->current; if (unpack->swap_bytes) { while (num_pixels--) *to++ = *from++; } else { while (num_pixels--) *to++ = load_32_little(from++); } } static void _unpack_a_b(GLcontext context, int num_pixels, GLimage_info *src, GLpixel_store *unpack, void *dst) { uint8 *to = (uint8 *)dst; uint8 *from = (uint8 *)src->current; /* Note: swap_bytes not defined for one-byte pixels */ while (num_pixels--) { to[R_COMPONENT] = 0; to[G_COMPONENT] = 0; to[B_COMPONENT] = 0; to[A_COMPONENT] = *from++; to += 4; } } static void _unpack_ci_b(GLcontext context, int num_pixels, GLimage_info *src, GLpixel_store *unpack, void *dst) { uint8 *to = (uint8 *)dst; uint8 *from = (uint8 *)src->current; uint8 *pal = (uint8 *)context->PaletteData; if (context->PaletteFormat == GL_RGB) { while (num_pixels--) { uint32 idx = *from++; to[R_COMPONENT] = pal[idx*3]; to[G_COMPONENT] = pal[idx*3+1]; to[B_COMPONENT] = pal[idx*3+2]; to[A_COMPONENT] = 0xff; to += 4; } } else { while (num_pixels--) { uint32 idx = *from++; to[R_COMPONENT] = pal[idx*4]; to[G_COMPONENT] = pal[idx*4+1]; to[B_COMPONENT] = pal[idx*4+2]; to[A_COMPONENT] = pal[idx*4+3]; to += 4; } } } static void _unpack_rgb_us565(GLcontext context, int num_pixels, GLimage_info *src, GLpixel_store *unpack, void *dst) { uint32 *to = (uint32 *)dst; uint16 *from = (uint16 *)src->current; if (unpack->swap_bytes) { while (num_pixels--) { GLushort rgb = load_16_little(from); from++; to[R_COMPONENT] = REDBYTE(rgb); to[G_COMPONENT] = GREENBYTE(rgb); to[B_COMPONENT] = BLUEBYTE(rgb); to[A_COMPONENT] = 0xff; to += 4; } } else { while (num_pixels--) { GLushort rgb = *from++; to[R_COMPONENT] = REDBYTE(rgb); to[G_COMPONENT] = GREENBYTE(rgb); to[B_COMPONENT] = BLUEBYTE(rgb); to[A_COMPONENT] = 0xff; to += 4; } } } static void _unpack_rgba_us444(GLcontext context, int num_pixels, GLimage_info *src, GLpixel_store *unpack, void *dst) { uint32 *to = (uint32 *)dst; uint16 *from = (uint16 *)src->current; if (unpack->swap_bytes) { while (num_pixels--) { GLushort rgb = load_16_little(from); from++; to[R_COMPONENT] = REDBYTEA(rgb); to[G_COMPONENT] = GREENBYTEA(rgb); to[B_COMPONENT] = BLUEBYTEA(rgb); to[A_COMPONENT] = ALPHABYTEA(rgb); to += 4; } } else { while (num_pixels--) { GLushort rgb = *from++; to[R_COMPONENT] = REDBYTEA(rgb); to[G_COMPONENT] = GREENBYTEA(rgb); to[B_COMPONENT] = BLUEBYTEA(rgb); to[A_COMPONENT] = ALPHABYTEA(rgb); to += 4; } } } static void _unpack_bgr_b(GLcontext context, int num_pixels, GLimage_info *src, GLpixel_store *unpack, void *dst) { uint8 *to = (uint8 *)dst; uint8 *from = (uint8 *)src->current; /* Note: swap_bytes not defined for three-byte pixels */ while (num_pixels--) { to[B_COMPONENT] = *from++; to[G_COMPONENT] = *from++; to[R_COMPONENT] = *from++; to[A_COMPONENT] = 0xff; to += 4; } } static void _unpack_bgra_b(GLcontext context, int num_pixels, GLimage_info *src, GLpixel_store *unpack, void *dst) { uint8 *to = (uint8 *)dst; uint8 *from = (uint8 *)src->current; if (unpack->swap_bytes) { while (num_pixels--) { to[A_COMPONENT] = *from++; to[R_COMPONENT] = *from++; to[G_COMPONENT] = *from++; to[B_COMPONENT] = *from++; to += 4; } } else { while (num_pixels--) { to[B_COMPONENT] = *from++; to[G_COMPONENT] = *from++; to[R_COMPONENT] = *from++; to[A_COMPONENT] = *from++; to += 4; } } } static void _unpack_bgra_us1555rev(GLcontext context, int num_pixels, GLimage_info *src, GLpixel_store *unpack, void *dst) { uint32 *to = (uint32 *)dst; uint16 *from = (uint16 *)src->current; if (unpack->swap_bytes) { while (num_pixels--) { GLushort rgb = load_16_little(from); from++; to[R_COMPONENT] = REDBYTE5551(rgb); to[G_COMPONENT] = GREENBYTE5551(rgb); to[B_COMPONENT] = BLUEBYTE5551(rgb); to[A_COMPONENT] = ALPHABYTE5551(rgb); to += 4; } } else { while (num_pixels--) { GLushort rgb = *from++; to[R_COMPONENT] = REDBYTE5551(rgb); to[G_COMPONENT] = GREENBYTE5551(rgb); to[B_COMPONENT] = BLUEBYTE5551(rgb); to[A_COMPONENT] = ALPHABYTE5551(rgb); to += 4; } } } static void _unpack_l_b(GLcontext context, int num_pixels, GLimage_info *src, GLpixel_store *unpack, void *dst) { uint8 *to = (uint8 *)dst; uint8 *from = (uint8 *)src->current; /* Note: swap_bytes not defined for one-byte pixels */ while (num_pixels--) { uint8 val = *from++; to[R_COMPONENT] = val; to[G_COMPONENT] = val; to[B_COMPONENT] = val; to[A_COMPONENT] = 0xff; to += 4; } } static void _unpack_la_b(GLcontext context, int num_pixels, GLimage_info *src, GLpixel_store *unpack, void *dst) { uint8 *to = (uint8 *)dst; uint8 *from = (uint8 *)src->current; if (unpack->swap_bytes) { while (num_pixels--) { uint8 a = *from++; uint8 l = *from++; to[R_COMPONENT] = l; to[G_COMPONENT] = l; to[B_COMPONENT] = l; to[A_COMPONENT] = a; to += 4; } } else { while (num_pixels--) { uint8 l = *from++; uint8 a = *from++; to[R_COMPONENT] = l; to[G_COMPONENT] = l; to[B_COMPONENT] = l; to[A_COMPONENT] = a; to += 4; } } } static void _unpack_i_b(GLcontext context, int num_pixels, GLimage_info *src, GLpixel_store *unpack, void *dst) { uint8 *to = (uint8 *)dst; uint8 *from = (uint8 *)src->current; /* Note: swap_bytes not defined for one-byte pixels */ while (num_pixels--) { uint8 val = *from++; to[R_COMPONENT] = val; to[G_COMPONENT] = val; to[B_COMPONENT] = val; to[A_COMPONENT] = val; to += 4; } } static void _unpack_l_ui(GLcontext context, int num_pixels, GLimage_info *src, GLpixel_store *unpack, void *dst) { uint8 *to = (uint8 *)dst; uint32 *from = (uint32 *)src->current; if(unpack->swap_bytes) { while (num_pixels--) { GLuint l = load_32_little(from); from++; uint8 val = (l)>>24; to[R_COMPONENT] = val; to[G_COMPONENT] = val; to[B_COMPONENT] = val; to[A_COMPONENT] = 0xff; to += 4; } } else { while (num_pixels--) { uint8 val = (*from++)>>24; to[R_COMPONENT] = val; to[G_COMPONENT] = val; to[B_COMPONENT] = val; to[A_COMPONENT] = 0xff; to += 4; } } } GLunpack mglUnpackers[] = { {GL_RGB, GL_UNSIGNED_BYTE, _unpack_rgb_b, 3}, {GL_RGBA, GL_UNSIGNED_BYTE, _unpack_rgba_b, 4}, {GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, _unpack_argb_b, 4}, // ##### FIXME! ##### missing GL_ABGR {GL_ALPHA, GL_UNSIGNED_BYTE, _unpack_a_b, 1}, {GL_COLOR_INDEX, GL_UNSIGNED_BYTE, _unpack_ci_b, 1}, {GL_RGB, GL_UNSIGNED_SHORT_5_6_5, _unpack_rgb_us565, 2}, {GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, _unpack_rgba_us444, 2}, {GL_BGR, GL_UNSIGNED_BYTE, _unpack_bgr_b, 3}, {GL_BGRA, GL_UNSIGNED_BYTE, _unpack_bgra_b, 4}, {GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, _unpack_bgra_us1555rev, 2}, {GL_LUMINANCE, GL_UNSIGNED_BYTE, _unpack_l_b, 1}, {GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, _unpack_la_b, 2}, {GL_INTENSITY, GL_UNSIGNED_BYTE, _unpack_i_b, 3}, {GL_LUMINANCE, GL_UNSIGNED_INT, _unpack_l_ui, 4}, {GL_NONE, GL_NONE, NULL, 0}, }; _glUnpackFn MGLSelectUnpacker(GLenum format, GLenum type, GLuint *pixelStride) { int i = 0; while (mglUnpackers[i].format != GL_NONE) { if (format == mglUnpackers[i].format && type == mglUnpackers[i].type) { if (pixelStride) *pixelStride = mglUnpackers[i].stride; return mglUnpackers[i].unpack; } i++; } IExec->DebugPrintF("Missing unpack support for %s/%s\n", format_to_string(format), type_to_string(type)); return NULL; }