1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Mesa 3-D graphics library 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 5bf215546Sopenharmony_ci * Copyright (C) 2009-2010 VMware, Inc. All Rights Reserved. 6bf215546Sopenharmony_ci * 7bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 8bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 9bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 10bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 12bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 13bf215546Sopenharmony_ci * 14bf215546Sopenharmony_ci * The above copyright notice and this permission notice shall be included 15bf215546Sopenharmony_ci * in all copies or substantial portions of the Software. 16bf215546Sopenharmony_ci * 17bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20bf215546Sopenharmony_ci * THEA AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 21bf215546Sopenharmony_ci * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22bf215546Sopenharmony_ci * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23bf215546Sopenharmony_ci */ 24bf215546Sopenharmony_ci 25bf215546Sopenharmony_ci 26bf215546Sopenharmony_ci/** 27bf215546Sopenharmony_ci * \file pack.c 28bf215546Sopenharmony_ci * Image and pixel span packing and unpacking. 29bf215546Sopenharmony_ci */ 30bf215546Sopenharmony_ci 31bf215546Sopenharmony_ci 32bf215546Sopenharmony_ci/* 33bf215546Sopenharmony_ci * XXX: MSVC takes forever to compile this module for x86_64 unless we disable 34bf215546Sopenharmony_ci * this global optimization. 35bf215546Sopenharmony_ci * 36bf215546Sopenharmony_ci * See also: 37bf215546Sopenharmony_ci * - http://msdn.microsoft.com/en-us/library/1yk3ydd7.aspx 38bf215546Sopenharmony_ci * - http://msdn.microsoft.com/en-us/library/chh3fb0k.aspx 39bf215546Sopenharmony_ci */ 40bf215546Sopenharmony_ci#if defined(_MSC_VER) && defined(_M_X64) 41bf215546Sopenharmony_ci# pragma optimize( "g", off ) 42bf215546Sopenharmony_ci#endif 43bf215546Sopenharmony_ci 44bf215546Sopenharmony_ci 45bf215546Sopenharmony_ci#include "errors.h" 46bf215546Sopenharmony_ci#include "glheader.h" 47bf215546Sopenharmony_ci#include "enums.h" 48bf215546Sopenharmony_ci#include "image.h" 49bf215546Sopenharmony_ci 50bf215546Sopenharmony_ci#include "macros.h" 51bf215546Sopenharmony_ci#include "mtypes.h" 52bf215546Sopenharmony_ci#include "pack.h" 53bf215546Sopenharmony_ci#include "pixeltransfer.h" 54bf215546Sopenharmony_ci 55bf215546Sopenharmony_ci#include "glformats.h" 56bf215546Sopenharmony_ci#include "format_utils.h" 57bf215546Sopenharmony_ci#include "format_pack.h" 58bf215546Sopenharmony_ci#include "format_unpack.h" 59bf215546Sopenharmony_ci#include "util/format/u_format.h" 60bf215546Sopenharmony_ci 61bf215546Sopenharmony_ci/** 62bf215546Sopenharmony_ci * Flip the 8 bits in each byte of the given array. 63bf215546Sopenharmony_ci * 64bf215546Sopenharmony_ci * \param p array. 65bf215546Sopenharmony_ci * \param n number of bytes. 66bf215546Sopenharmony_ci * 67bf215546Sopenharmony_ci * \todo try this trick to flip bytes someday: 68bf215546Sopenharmony_ci * \code 69bf215546Sopenharmony_ci * v = ((v & 0x55555555) << 1) | ((v >> 1) & 0x55555555); 70bf215546Sopenharmony_ci * v = ((v & 0x33333333) << 2) | ((v >> 2) & 0x33333333); 71bf215546Sopenharmony_ci * v = ((v & 0x0f0f0f0f) << 4) | ((v >> 4) & 0x0f0f0f0f); 72bf215546Sopenharmony_ci * \endcode 73bf215546Sopenharmony_ci */ 74bf215546Sopenharmony_cistatic void 75bf215546Sopenharmony_ciflip_bytes( GLubyte *p, GLuint n ) 76bf215546Sopenharmony_ci{ 77bf215546Sopenharmony_ci GLuint i, a, b; 78bf215546Sopenharmony_ci for (i = 0; i < n; i++) { 79bf215546Sopenharmony_ci b = (GLuint) p[i]; /* words are often faster than bytes */ 80bf215546Sopenharmony_ci a = ((b & 0x01) << 7) | 81bf215546Sopenharmony_ci ((b & 0x02) << 5) | 82bf215546Sopenharmony_ci ((b & 0x04) << 3) | 83bf215546Sopenharmony_ci ((b & 0x08) << 1) | 84bf215546Sopenharmony_ci ((b & 0x10) >> 1) | 85bf215546Sopenharmony_ci ((b & 0x20) >> 3) | 86bf215546Sopenharmony_ci ((b & 0x40) >> 5) | 87bf215546Sopenharmony_ci ((b & 0x80) >> 7); 88bf215546Sopenharmony_ci p[i] = (GLubyte) a; 89bf215546Sopenharmony_ci } 90bf215546Sopenharmony_ci} 91bf215546Sopenharmony_ci 92bf215546Sopenharmony_ci 93bf215546Sopenharmony_ci 94bf215546Sopenharmony_ci/* 95bf215546Sopenharmony_ci * Unpack a 32x32 pixel polygon stipple from user memory using the 96bf215546Sopenharmony_ci * current pixel unpack settings. 97bf215546Sopenharmony_ci */ 98bf215546Sopenharmony_civoid 99bf215546Sopenharmony_ci_mesa_unpack_polygon_stipple( const GLubyte *pattern, GLuint dest[32], 100bf215546Sopenharmony_ci const struct gl_pixelstore_attrib *unpacking ) 101bf215546Sopenharmony_ci{ 102bf215546Sopenharmony_ci GLubyte *ptrn = (GLubyte *) _mesa_unpack_image(2, 32, 32, 1, GL_COLOR_INDEX, 103bf215546Sopenharmony_ci GL_BITMAP, pattern, unpacking); 104bf215546Sopenharmony_ci if (ptrn) { 105bf215546Sopenharmony_ci /* Convert pattern from GLubytes to GLuints and handle big/little 106bf215546Sopenharmony_ci * endian differences 107bf215546Sopenharmony_ci */ 108bf215546Sopenharmony_ci GLubyte *p = ptrn; 109bf215546Sopenharmony_ci GLint i; 110bf215546Sopenharmony_ci for (i = 0; i < 32; i++) { 111bf215546Sopenharmony_ci dest[i] = (p[0] << 24) 112bf215546Sopenharmony_ci | (p[1] << 16) 113bf215546Sopenharmony_ci | (p[2] << 8) 114bf215546Sopenharmony_ci | (p[3] ); 115bf215546Sopenharmony_ci p += 4; 116bf215546Sopenharmony_ci } 117bf215546Sopenharmony_ci free(ptrn); 118bf215546Sopenharmony_ci } 119bf215546Sopenharmony_ci} 120bf215546Sopenharmony_ci 121bf215546Sopenharmony_ci 122bf215546Sopenharmony_ci/* 123bf215546Sopenharmony_ci * Pack polygon stipple into user memory given current pixel packing 124bf215546Sopenharmony_ci * settings. 125bf215546Sopenharmony_ci */ 126bf215546Sopenharmony_civoid 127bf215546Sopenharmony_ci_mesa_pack_polygon_stipple( const GLuint pattern[32], GLubyte *dest, 128bf215546Sopenharmony_ci const struct gl_pixelstore_attrib *packing ) 129bf215546Sopenharmony_ci{ 130bf215546Sopenharmony_ci /* Convert pattern from GLuints to GLubytes to handle big/little 131bf215546Sopenharmony_ci * endian differences. 132bf215546Sopenharmony_ci */ 133bf215546Sopenharmony_ci GLubyte ptrn[32*4]; 134bf215546Sopenharmony_ci GLint i; 135bf215546Sopenharmony_ci for (i = 0; i < 32; i++) { 136bf215546Sopenharmony_ci ptrn[i * 4 + 0] = (GLubyte) ((pattern[i] >> 24) & 0xff); 137bf215546Sopenharmony_ci ptrn[i * 4 + 1] = (GLubyte) ((pattern[i] >> 16) & 0xff); 138bf215546Sopenharmony_ci ptrn[i * 4 + 2] = (GLubyte) ((pattern[i] >> 8 ) & 0xff); 139bf215546Sopenharmony_ci ptrn[i * 4 + 3] = (GLubyte) ((pattern[i] ) & 0xff); 140bf215546Sopenharmony_ci } 141bf215546Sopenharmony_ci 142bf215546Sopenharmony_ci _mesa_pack_bitmap(32, 32, ptrn, dest, packing); 143bf215546Sopenharmony_ci} 144bf215546Sopenharmony_ci 145bf215546Sopenharmony_ci 146bf215546Sopenharmony_ci/* 147bf215546Sopenharmony_ci * Pack bitmap data. 148bf215546Sopenharmony_ci */ 149bf215546Sopenharmony_civoid 150bf215546Sopenharmony_ci_mesa_pack_bitmap( GLint width, GLint height, const GLubyte *source, 151bf215546Sopenharmony_ci GLubyte *dest, const struct gl_pixelstore_attrib *packing ) 152bf215546Sopenharmony_ci{ 153bf215546Sopenharmony_ci GLint row, width_in_bytes; 154bf215546Sopenharmony_ci const GLubyte *src; 155bf215546Sopenharmony_ci 156bf215546Sopenharmony_ci if (!source) 157bf215546Sopenharmony_ci return; 158bf215546Sopenharmony_ci 159bf215546Sopenharmony_ci width_in_bytes = DIV_ROUND_UP( width, 8 ); 160bf215546Sopenharmony_ci src = source; 161bf215546Sopenharmony_ci for (row = 0; row < height; row++) { 162bf215546Sopenharmony_ci GLubyte *dst = (GLubyte *) _mesa_image_address2d(packing, dest, 163bf215546Sopenharmony_ci width, height, GL_COLOR_INDEX, GL_BITMAP, row, 0); 164bf215546Sopenharmony_ci if (!dst) 165bf215546Sopenharmony_ci return; 166bf215546Sopenharmony_ci 167bf215546Sopenharmony_ci if ((packing->SkipPixels & 7) == 0) { 168bf215546Sopenharmony_ci memcpy( dst, src, width_in_bytes ); 169bf215546Sopenharmony_ci if (packing->LsbFirst) { 170bf215546Sopenharmony_ci flip_bytes( dst, width_in_bytes ); 171bf215546Sopenharmony_ci } 172bf215546Sopenharmony_ci } 173bf215546Sopenharmony_ci else { 174bf215546Sopenharmony_ci /* handling SkipPixels is a bit tricky (no pun intended!) */ 175bf215546Sopenharmony_ci GLint i; 176bf215546Sopenharmony_ci if (packing->LsbFirst) { 177bf215546Sopenharmony_ci GLubyte srcMask = 128; 178bf215546Sopenharmony_ci GLubyte dstMask = 1 << (packing->SkipPixels & 0x7); 179bf215546Sopenharmony_ci const GLubyte *s = src; 180bf215546Sopenharmony_ci GLubyte *d = dst; 181bf215546Sopenharmony_ci *d = 0; 182bf215546Sopenharmony_ci for (i = 0; i < width; i++) { 183bf215546Sopenharmony_ci if (*s & srcMask) { 184bf215546Sopenharmony_ci *d |= dstMask; 185bf215546Sopenharmony_ci } 186bf215546Sopenharmony_ci if (srcMask == 1) { 187bf215546Sopenharmony_ci srcMask = 128; 188bf215546Sopenharmony_ci s++; 189bf215546Sopenharmony_ci } 190bf215546Sopenharmony_ci else { 191bf215546Sopenharmony_ci srcMask = srcMask >> 1; 192bf215546Sopenharmony_ci } 193bf215546Sopenharmony_ci if (dstMask == 128) { 194bf215546Sopenharmony_ci dstMask = 1; 195bf215546Sopenharmony_ci d++; 196bf215546Sopenharmony_ci *d = 0; 197bf215546Sopenharmony_ci } 198bf215546Sopenharmony_ci else { 199bf215546Sopenharmony_ci dstMask = dstMask << 1; 200bf215546Sopenharmony_ci } 201bf215546Sopenharmony_ci } 202bf215546Sopenharmony_ci } 203bf215546Sopenharmony_ci else { 204bf215546Sopenharmony_ci GLubyte srcMask = 128; 205bf215546Sopenharmony_ci GLubyte dstMask = 128 >> (packing->SkipPixels & 0x7); 206bf215546Sopenharmony_ci const GLubyte *s = src; 207bf215546Sopenharmony_ci GLubyte *d = dst; 208bf215546Sopenharmony_ci *d = 0; 209bf215546Sopenharmony_ci for (i = 0; i < width; i++) { 210bf215546Sopenharmony_ci if (*s & srcMask) { 211bf215546Sopenharmony_ci *d |= dstMask; 212bf215546Sopenharmony_ci } 213bf215546Sopenharmony_ci if (srcMask == 1) { 214bf215546Sopenharmony_ci srcMask = 128; 215bf215546Sopenharmony_ci s++; 216bf215546Sopenharmony_ci } 217bf215546Sopenharmony_ci else { 218bf215546Sopenharmony_ci srcMask = srcMask >> 1; 219bf215546Sopenharmony_ci } 220bf215546Sopenharmony_ci if (dstMask == 1) { 221bf215546Sopenharmony_ci dstMask = 128; 222bf215546Sopenharmony_ci d++; 223bf215546Sopenharmony_ci *d = 0; 224bf215546Sopenharmony_ci } 225bf215546Sopenharmony_ci else { 226bf215546Sopenharmony_ci dstMask = dstMask >> 1; 227bf215546Sopenharmony_ci } 228bf215546Sopenharmony_ci } 229bf215546Sopenharmony_ci } 230bf215546Sopenharmony_ci } 231bf215546Sopenharmony_ci src += width_in_bytes; 232bf215546Sopenharmony_ci } 233bf215546Sopenharmony_ci} 234bf215546Sopenharmony_ci 235bf215546Sopenharmony_ci 236bf215546Sopenharmony_ci#define SWAP2BYTE(VALUE) \ 237bf215546Sopenharmony_ci { \ 238bf215546Sopenharmony_ci GLubyte *bytes = (GLubyte *) &(VALUE); \ 239bf215546Sopenharmony_ci GLubyte tmp = bytes[0]; \ 240bf215546Sopenharmony_ci bytes[0] = bytes[1]; \ 241bf215546Sopenharmony_ci bytes[1] = tmp; \ 242bf215546Sopenharmony_ci } 243bf215546Sopenharmony_ci 244bf215546Sopenharmony_ci#define SWAP4BYTE(VALUE) \ 245bf215546Sopenharmony_ci { \ 246bf215546Sopenharmony_ci GLubyte *bytes = (GLubyte *) &(VALUE); \ 247bf215546Sopenharmony_ci GLubyte tmp = bytes[0]; \ 248bf215546Sopenharmony_ci bytes[0] = bytes[3]; \ 249bf215546Sopenharmony_ci bytes[3] = tmp; \ 250bf215546Sopenharmony_ci tmp = bytes[1]; \ 251bf215546Sopenharmony_ci bytes[1] = bytes[2]; \ 252bf215546Sopenharmony_ci bytes[2] = tmp; \ 253bf215546Sopenharmony_ci } 254bf215546Sopenharmony_ci 255bf215546Sopenharmony_ci 256bf215546Sopenharmony_cistatic void 257bf215546Sopenharmony_ciextract_uint_indexes(GLuint n, GLuint indexes[], 258bf215546Sopenharmony_ci GLenum srcFormat, GLenum srcType, const GLvoid *src, 259bf215546Sopenharmony_ci const struct gl_pixelstore_attrib *unpack ) 260bf215546Sopenharmony_ci{ 261bf215546Sopenharmony_ci assert(srcFormat == GL_COLOR_INDEX || srcFormat == GL_STENCIL_INDEX); 262bf215546Sopenharmony_ci 263bf215546Sopenharmony_ci assert(srcType == GL_BITMAP || 264bf215546Sopenharmony_ci srcType == GL_UNSIGNED_BYTE || 265bf215546Sopenharmony_ci srcType == GL_BYTE || 266bf215546Sopenharmony_ci srcType == GL_UNSIGNED_SHORT || 267bf215546Sopenharmony_ci srcType == GL_SHORT || 268bf215546Sopenharmony_ci srcType == GL_UNSIGNED_INT || 269bf215546Sopenharmony_ci srcType == GL_INT || 270bf215546Sopenharmony_ci srcType == GL_UNSIGNED_INT_24_8_EXT || 271bf215546Sopenharmony_ci srcType == GL_HALF_FLOAT_ARB || 272bf215546Sopenharmony_ci srcType == GL_HALF_FLOAT_OES || 273bf215546Sopenharmony_ci srcType == GL_FLOAT || 274bf215546Sopenharmony_ci srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV); 275bf215546Sopenharmony_ci 276bf215546Sopenharmony_ci switch (srcType) { 277bf215546Sopenharmony_ci case GL_BITMAP: 278bf215546Sopenharmony_ci { 279bf215546Sopenharmony_ci GLubyte *ubsrc = (GLubyte *) src; 280bf215546Sopenharmony_ci if (unpack->LsbFirst) { 281bf215546Sopenharmony_ci GLubyte mask = 1 << (unpack->SkipPixels & 0x7); 282bf215546Sopenharmony_ci GLuint i; 283bf215546Sopenharmony_ci for (i = 0; i < n; i++) { 284bf215546Sopenharmony_ci indexes[i] = (*ubsrc & mask) ? 1 : 0; 285bf215546Sopenharmony_ci if (mask == 128) { 286bf215546Sopenharmony_ci mask = 1; 287bf215546Sopenharmony_ci ubsrc++; 288bf215546Sopenharmony_ci } 289bf215546Sopenharmony_ci else { 290bf215546Sopenharmony_ci mask = mask << 1; 291bf215546Sopenharmony_ci } 292bf215546Sopenharmony_ci } 293bf215546Sopenharmony_ci } 294bf215546Sopenharmony_ci else { 295bf215546Sopenharmony_ci GLubyte mask = 128 >> (unpack->SkipPixels & 0x7); 296bf215546Sopenharmony_ci GLuint i; 297bf215546Sopenharmony_ci for (i = 0; i < n; i++) { 298bf215546Sopenharmony_ci indexes[i] = (*ubsrc & mask) ? 1 : 0; 299bf215546Sopenharmony_ci if (mask == 1) { 300bf215546Sopenharmony_ci mask = 128; 301bf215546Sopenharmony_ci ubsrc++; 302bf215546Sopenharmony_ci } 303bf215546Sopenharmony_ci else { 304bf215546Sopenharmony_ci mask = mask >> 1; 305bf215546Sopenharmony_ci } 306bf215546Sopenharmony_ci } 307bf215546Sopenharmony_ci } 308bf215546Sopenharmony_ci } 309bf215546Sopenharmony_ci break; 310bf215546Sopenharmony_ci case GL_UNSIGNED_BYTE: 311bf215546Sopenharmony_ci { 312bf215546Sopenharmony_ci GLuint i; 313bf215546Sopenharmony_ci const GLubyte *s = (const GLubyte *) src; 314bf215546Sopenharmony_ci for (i = 0; i < n; i++) 315bf215546Sopenharmony_ci indexes[i] = s[i]; 316bf215546Sopenharmony_ci } 317bf215546Sopenharmony_ci break; 318bf215546Sopenharmony_ci case GL_BYTE: 319bf215546Sopenharmony_ci { 320bf215546Sopenharmony_ci GLuint i; 321bf215546Sopenharmony_ci const GLbyte *s = (const GLbyte *) src; 322bf215546Sopenharmony_ci for (i = 0; i < n; i++) 323bf215546Sopenharmony_ci indexes[i] = s[i]; 324bf215546Sopenharmony_ci } 325bf215546Sopenharmony_ci break; 326bf215546Sopenharmony_ci case GL_UNSIGNED_SHORT: 327bf215546Sopenharmony_ci { 328bf215546Sopenharmony_ci GLuint i; 329bf215546Sopenharmony_ci const GLushort *s = (const GLushort *) src; 330bf215546Sopenharmony_ci if (unpack->SwapBytes) { 331bf215546Sopenharmony_ci for (i = 0; i < n; i++) { 332bf215546Sopenharmony_ci GLushort value = s[i]; 333bf215546Sopenharmony_ci SWAP2BYTE(value); 334bf215546Sopenharmony_ci indexes[i] = value; 335bf215546Sopenharmony_ci } 336bf215546Sopenharmony_ci } 337bf215546Sopenharmony_ci else { 338bf215546Sopenharmony_ci for (i = 0; i < n; i++) 339bf215546Sopenharmony_ci indexes[i] = s[i]; 340bf215546Sopenharmony_ci } 341bf215546Sopenharmony_ci } 342bf215546Sopenharmony_ci break; 343bf215546Sopenharmony_ci case GL_SHORT: 344bf215546Sopenharmony_ci { 345bf215546Sopenharmony_ci GLuint i; 346bf215546Sopenharmony_ci const GLshort *s = (const GLshort *) src; 347bf215546Sopenharmony_ci if (unpack->SwapBytes) { 348bf215546Sopenharmony_ci for (i = 0; i < n; i++) { 349bf215546Sopenharmony_ci GLshort value = s[i]; 350bf215546Sopenharmony_ci SWAP2BYTE(value); 351bf215546Sopenharmony_ci indexes[i] = value; 352bf215546Sopenharmony_ci } 353bf215546Sopenharmony_ci } 354bf215546Sopenharmony_ci else { 355bf215546Sopenharmony_ci for (i = 0; i < n; i++) 356bf215546Sopenharmony_ci indexes[i] = s[i]; 357bf215546Sopenharmony_ci } 358bf215546Sopenharmony_ci } 359bf215546Sopenharmony_ci break; 360bf215546Sopenharmony_ci case GL_UNSIGNED_INT: 361bf215546Sopenharmony_ci { 362bf215546Sopenharmony_ci GLuint i; 363bf215546Sopenharmony_ci const GLuint *s = (const GLuint *) src; 364bf215546Sopenharmony_ci if (unpack->SwapBytes) { 365bf215546Sopenharmony_ci for (i = 0; i < n; i++) { 366bf215546Sopenharmony_ci GLuint value = s[i]; 367bf215546Sopenharmony_ci SWAP4BYTE(value); 368bf215546Sopenharmony_ci indexes[i] = value; 369bf215546Sopenharmony_ci } 370bf215546Sopenharmony_ci } 371bf215546Sopenharmony_ci else { 372bf215546Sopenharmony_ci for (i = 0; i < n; i++) 373bf215546Sopenharmony_ci indexes[i] = s[i]; 374bf215546Sopenharmony_ci } 375bf215546Sopenharmony_ci } 376bf215546Sopenharmony_ci break; 377bf215546Sopenharmony_ci case GL_INT: 378bf215546Sopenharmony_ci { 379bf215546Sopenharmony_ci GLuint i; 380bf215546Sopenharmony_ci const GLint *s = (const GLint *) src; 381bf215546Sopenharmony_ci if (unpack->SwapBytes) { 382bf215546Sopenharmony_ci for (i = 0; i < n; i++) { 383bf215546Sopenharmony_ci GLint value = s[i]; 384bf215546Sopenharmony_ci SWAP4BYTE(value); 385bf215546Sopenharmony_ci indexes[i] = value; 386bf215546Sopenharmony_ci } 387bf215546Sopenharmony_ci } 388bf215546Sopenharmony_ci else { 389bf215546Sopenharmony_ci for (i = 0; i < n; i++) 390bf215546Sopenharmony_ci indexes[i] = s[i]; 391bf215546Sopenharmony_ci } 392bf215546Sopenharmony_ci } 393bf215546Sopenharmony_ci break; 394bf215546Sopenharmony_ci case GL_FLOAT: 395bf215546Sopenharmony_ci { 396bf215546Sopenharmony_ci GLuint i; 397bf215546Sopenharmony_ci const GLfloat *s = (const GLfloat *) src; 398bf215546Sopenharmony_ci if (unpack->SwapBytes) { 399bf215546Sopenharmony_ci for (i = 0; i < n; i++) { 400bf215546Sopenharmony_ci GLfloat value = s[i]; 401bf215546Sopenharmony_ci SWAP4BYTE(value); 402bf215546Sopenharmony_ci indexes[i] = (GLuint) value; 403bf215546Sopenharmony_ci } 404bf215546Sopenharmony_ci } 405bf215546Sopenharmony_ci else { 406bf215546Sopenharmony_ci for (i = 0; i < n; i++) 407bf215546Sopenharmony_ci indexes[i] = (GLuint) s[i]; 408bf215546Sopenharmony_ci } 409bf215546Sopenharmony_ci } 410bf215546Sopenharmony_ci break; 411bf215546Sopenharmony_ci case GL_HALF_FLOAT_ARB: 412bf215546Sopenharmony_ci case GL_HALF_FLOAT_OES: 413bf215546Sopenharmony_ci { 414bf215546Sopenharmony_ci GLuint i; 415bf215546Sopenharmony_ci const GLhalfARB *s = (const GLhalfARB *) src; 416bf215546Sopenharmony_ci if (unpack->SwapBytes) { 417bf215546Sopenharmony_ci for (i = 0; i < n; i++) { 418bf215546Sopenharmony_ci GLhalfARB value = s[i]; 419bf215546Sopenharmony_ci SWAP2BYTE(value); 420bf215546Sopenharmony_ci indexes[i] = (GLuint) _mesa_half_to_float(value); 421bf215546Sopenharmony_ci } 422bf215546Sopenharmony_ci } 423bf215546Sopenharmony_ci else { 424bf215546Sopenharmony_ci for (i = 0; i < n; i++) 425bf215546Sopenharmony_ci indexes[i] = (GLuint) _mesa_half_to_float(s[i]); 426bf215546Sopenharmony_ci } 427bf215546Sopenharmony_ci } 428bf215546Sopenharmony_ci break; 429bf215546Sopenharmony_ci case GL_UNSIGNED_INT_24_8_EXT: 430bf215546Sopenharmony_ci { 431bf215546Sopenharmony_ci GLuint i; 432bf215546Sopenharmony_ci const GLuint *s = (const GLuint *) src; 433bf215546Sopenharmony_ci if (unpack->SwapBytes) { 434bf215546Sopenharmony_ci for (i = 0; i < n; i++) { 435bf215546Sopenharmony_ci GLuint value = s[i]; 436bf215546Sopenharmony_ci SWAP4BYTE(value); 437bf215546Sopenharmony_ci indexes[i] = value & 0xff; /* lower 8 bits */ 438bf215546Sopenharmony_ci } 439bf215546Sopenharmony_ci } 440bf215546Sopenharmony_ci else { 441bf215546Sopenharmony_ci for (i = 0; i < n; i++) 442bf215546Sopenharmony_ci indexes[i] = s[i] & 0xff; /* lower 8 bits */ 443bf215546Sopenharmony_ci } 444bf215546Sopenharmony_ci } 445bf215546Sopenharmony_ci break; 446bf215546Sopenharmony_ci case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: 447bf215546Sopenharmony_ci { 448bf215546Sopenharmony_ci GLuint i; 449bf215546Sopenharmony_ci const GLuint *s = (const GLuint *) src; 450bf215546Sopenharmony_ci if (unpack->SwapBytes) { 451bf215546Sopenharmony_ci for (i = 0; i < n; i++) { 452bf215546Sopenharmony_ci GLuint value = s[i*2+1]; 453bf215546Sopenharmony_ci SWAP4BYTE(value); 454bf215546Sopenharmony_ci indexes[i] = value & 0xff; /* lower 8 bits */ 455bf215546Sopenharmony_ci } 456bf215546Sopenharmony_ci } 457bf215546Sopenharmony_ci else { 458bf215546Sopenharmony_ci for (i = 0; i < n; i++) 459bf215546Sopenharmony_ci indexes[i] = s[i*2+1] & 0xff; /* lower 8 bits */ 460bf215546Sopenharmony_ci } 461bf215546Sopenharmony_ci } 462bf215546Sopenharmony_ci break; 463bf215546Sopenharmony_ci 464bf215546Sopenharmony_ci default: 465bf215546Sopenharmony_ci unreachable("bad srcType in extract_uint_indexes"); 466bf215546Sopenharmony_ci } 467bf215546Sopenharmony_ci} 468bf215546Sopenharmony_ci 469bf215546Sopenharmony_ci 470bf215546Sopenharmony_ci/* 471bf215546Sopenharmony_ci * Unpack a row of stencil data from a client buffer according to 472bf215546Sopenharmony_ci * the pixel unpacking parameters. 473bf215546Sopenharmony_ci * This is (or will be) used by glDrawPixels 474bf215546Sopenharmony_ci * 475bf215546Sopenharmony_ci * Args: ctx - the context 476bf215546Sopenharmony_ci * n - number of pixels 477bf215546Sopenharmony_ci * dstType - destination data type 478bf215546Sopenharmony_ci * dest - destination array 479bf215546Sopenharmony_ci * srcType - source pixel type 480bf215546Sopenharmony_ci * source - source data pointer 481bf215546Sopenharmony_ci * srcPacking - pixel unpacking parameters 482bf215546Sopenharmony_ci * transferOps - apply offset/bias/lookup ops? 483bf215546Sopenharmony_ci */ 484bf215546Sopenharmony_civoid 485bf215546Sopenharmony_ci_mesa_unpack_stencil_span( struct gl_context *ctx, GLuint n, 486bf215546Sopenharmony_ci GLenum dstType, GLvoid *dest, 487bf215546Sopenharmony_ci GLenum srcType, const GLvoid *source, 488bf215546Sopenharmony_ci const struct gl_pixelstore_attrib *srcPacking, 489bf215546Sopenharmony_ci GLbitfield transferOps ) 490bf215546Sopenharmony_ci{ 491bf215546Sopenharmony_ci assert(srcType == GL_BITMAP || 492bf215546Sopenharmony_ci srcType == GL_UNSIGNED_BYTE || 493bf215546Sopenharmony_ci srcType == GL_BYTE || 494bf215546Sopenharmony_ci srcType == GL_UNSIGNED_SHORT || 495bf215546Sopenharmony_ci srcType == GL_SHORT || 496bf215546Sopenharmony_ci srcType == GL_UNSIGNED_INT || 497bf215546Sopenharmony_ci srcType == GL_INT || 498bf215546Sopenharmony_ci srcType == GL_UNSIGNED_INT_24_8_EXT || 499bf215546Sopenharmony_ci srcType == GL_HALF_FLOAT_ARB || 500bf215546Sopenharmony_ci srcType == GL_HALF_FLOAT_OES || 501bf215546Sopenharmony_ci srcType == GL_FLOAT || 502bf215546Sopenharmony_ci srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV); 503bf215546Sopenharmony_ci 504bf215546Sopenharmony_ci assert(dstType == GL_UNSIGNED_BYTE || 505bf215546Sopenharmony_ci dstType == GL_UNSIGNED_SHORT || 506bf215546Sopenharmony_ci dstType == GL_UNSIGNED_INT || 507bf215546Sopenharmony_ci dstType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV); 508bf215546Sopenharmony_ci 509bf215546Sopenharmony_ci /* only shift and offset apply to stencil */ 510bf215546Sopenharmony_ci transferOps &= IMAGE_SHIFT_OFFSET_BIT; 511bf215546Sopenharmony_ci 512bf215546Sopenharmony_ci /* 513bf215546Sopenharmony_ci * Try simple cases first 514bf215546Sopenharmony_ci */ 515bf215546Sopenharmony_ci if (transferOps == 0 && 516bf215546Sopenharmony_ci !ctx->Pixel.MapStencilFlag && 517bf215546Sopenharmony_ci srcType == GL_UNSIGNED_BYTE && 518bf215546Sopenharmony_ci dstType == GL_UNSIGNED_BYTE) { 519bf215546Sopenharmony_ci memcpy(dest, source, n * sizeof(GLubyte)); 520bf215546Sopenharmony_ci } 521bf215546Sopenharmony_ci else if (transferOps == 0 && 522bf215546Sopenharmony_ci !ctx->Pixel.MapStencilFlag && 523bf215546Sopenharmony_ci srcType == GL_UNSIGNED_INT && 524bf215546Sopenharmony_ci dstType == GL_UNSIGNED_INT && 525bf215546Sopenharmony_ci !srcPacking->SwapBytes) { 526bf215546Sopenharmony_ci memcpy(dest, source, n * sizeof(GLuint)); 527bf215546Sopenharmony_ci } 528bf215546Sopenharmony_ci else { 529bf215546Sopenharmony_ci /* 530bf215546Sopenharmony_ci * general solution 531bf215546Sopenharmony_ci */ 532bf215546Sopenharmony_ci GLuint *indexes = malloc(n * sizeof(GLuint)); 533bf215546Sopenharmony_ci 534bf215546Sopenharmony_ci if (!indexes) { 535bf215546Sopenharmony_ci _mesa_error(ctx, GL_OUT_OF_MEMORY, "stencil unpacking"); 536bf215546Sopenharmony_ci return; 537bf215546Sopenharmony_ci } 538bf215546Sopenharmony_ci 539bf215546Sopenharmony_ci extract_uint_indexes(n, indexes, GL_STENCIL_INDEX, srcType, source, 540bf215546Sopenharmony_ci srcPacking); 541bf215546Sopenharmony_ci 542bf215546Sopenharmony_ci if (transferOps & IMAGE_SHIFT_OFFSET_BIT) { 543bf215546Sopenharmony_ci /* shift and offset indexes */ 544bf215546Sopenharmony_ci _mesa_shift_and_offset_ci(ctx, n, indexes); 545bf215546Sopenharmony_ci } 546bf215546Sopenharmony_ci 547bf215546Sopenharmony_ci if (ctx->Pixel.MapStencilFlag) { 548bf215546Sopenharmony_ci /* Apply stencil lookup table */ 549bf215546Sopenharmony_ci const GLuint mask = ctx->PixelMaps.StoS.Size - 1; 550bf215546Sopenharmony_ci GLuint i; 551bf215546Sopenharmony_ci for (i = 0; i < n; i++) { 552bf215546Sopenharmony_ci indexes[i] = (GLuint)ctx->PixelMaps.StoS.Map[ indexes[i] & mask ]; 553bf215546Sopenharmony_ci } 554bf215546Sopenharmony_ci } 555bf215546Sopenharmony_ci 556bf215546Sopenharmony_ci /* convert to dest type */ 557bf215546Sopenharmony_ci switch (dstType) { 558bf215546Sopenharmony_ci case GL_UNSIGNED_BYTE: 559bf215546Sopenharmony_ci { 560bf215546Sopenharmony_ci GLubyte *dst = (GLubyte *) dest; 561bf215546Sopenharmony_ci GLuint i; 562bf215546Sopenharmony_ci for (i = 0; i < n; i++) { 563bf215546Sopenharmony_ci dst[i] = (GLubyte) (indexes[i] & 0xff); 564bf215546Sopenharmony_ci } 565bf215546Sopenharmony_ci } 566bf215546Sopenharmony_ci break; 567bf215546Sopenharmony_ci case GL_UNSIGNED_SHORT: 568bf215546Sopenharmony_ci { 569bf215546Sopenharmony_ci GLuint *dst = (GLuint *) dest; 570bf215546Sopenharmony_ci GLuint i; 571bf215546Sopenharmony_ci for (i = 0; i < n; i++) { 572bf215546Sopenharmony_ci dst[i] = (GLushort) (indexes[i] & 0xffff); 573bf215546Sopenharmony_ci } 574bf215546Sopenharmony_ci } 575bf215546Sopenharmony_ci break; 576bf215546Sopenharmony_ci case GL_UNSIGNED_INT: 577bf215546Sopenharmony_ci memcpy(dest, indexes, n * sizeof(GLuint)); 578bf215546Sopenharmony_ci break; 579bf215546Sopenharmony_ci case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: 580bf215546Sopenharmony_ci { 581bf215546Sopenharmony_ci GLuint *dst = (GLuint *) dest; 582bf215546Sopenharmony_ci GLuint i; 583bf215546Sopenharmony_ci for (i = 0; i < n; i++) { 584bf215546Sopenharmony_ci dst[i*2+1] = indexes[i] & 0xff; /* lower 8 bits */ 585bf215546Sopenharmony_ci } 586bf215546Sopenharmony_ci } 587bf215546Sopenharmony_ci break; 588bf215546Sopenharmony_ci default: 589bf215546Sopenharmony_ci unreachable("bad dstType in _mesa_unpack_stencil_span"); 590bf215546Sopenharmony_ci } 591bf215546Sopenharmony_ci 592bf215546Sopenharmony_ci free(indexes); 593bf215546Sopenharmony_ci } 594bf215546Sopenharmony_ci} 595bf215546Sopenharmony_ci 596bf215546Sopenharmony_ci 597bf215546Sopenharmony_civoid 598bf215546Sopenharmony_ci_mesa_pack_stencil_span( struct gl_context *ctx, GLuint n, 599bf215546Sopenharmony_ci GLenum dstType, GLvoid *dest, const GLubyte *source, 600bf215546Sopenharmony_ci const struct gl_pixelstore_attrib *dstPacking ) 601bf215546Sopenharmony_ci{ 602bf215546Sopenharmony_ci GLubyte *stencil = malloc(n * sizeof(GLubyte)); 603bf215546Sopenharmony_ci 604bf215546Sopenharmony_ci if (!stencil) { 605bf215546Sopenharmony_ci _mesa_error(ctx, GL_OUT_OF_MEMORY, "stencil packing"); 606bf215546Sopenharmony_ci return; 607bf215546Sopenharmony_ci } 608bf215546Sopenharmony_ci 609bf215546Sopenharmony_ci if (ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset || 610bf215546Sopenharmony_ci ctx->Pixel.MapStencilFlag) { 611bf215546Sopenharmony_ci /* make a copy of input */ 612bf215546Sopenharmony_ci memcpy(stencil, source, n * sizeof(GLubyte)); 613bf215546Sopenharmony_ci _mesa_apply_stencil_transfer_ops(ctx, n, stencil); 614bf215546Sopenharmony_ci source = stencil; 615bf215546Sopenharmony_ci } 616bf215546Sopenharmony_ci 617bf215546Sopenharmony_ci switch (dstType) { 618bf215546Sopenharmony_ci case GL_UNSIGNED_BYTE: 619bf215546Sopenharmony_ci memcpy(dest, source, n); 620bf215546Sopenharmony_ci break; 621bf215546Sopenharmony_ci case GL_BYTE: 622bf215546Sopenharmony_ci { 623bf215546Sopenharmony_ci GLbyte *dst = (GLbyte *) dest; 624bf215546Sopenharmony_ci GLuint i; 625bf215546Sopenharmony_ci for (i=0;i<n;i++) { 626bf215546Sopenharmony_ci dst[i] = (GLbyte) (source[i] & 0x7f); 627bf215546Sopenharmony_ci } 628bf215546Sopenharmony_ci } 629bf215546Sopenharmony_ci break; 630bf215546Sopenharmony_ci case GL_UNSIGNED_SHORT: 631bf215546Sopenharmony_ci { 632bf215546Sopenharmony_ci GLushort *dst = (GLushort *) dest; 633bf215546Sopenharmony_ci GLuint i; 634bf215546Sopenharmony_ci for (i=0;i<n;i++) { 635bf215546Sopenharmony_ci dst[i] = (GLushort) source[i]; 636bf215546Sopenharmony_ci } 637bf215546Sopenharmony_ci if (dstPacking->SwapBytes) { 638bf215546Sopenharmony_ci _mesa_swap2( (GLushort *) dst, n ); 639bf215546Sopenharmony_ci } 640bf215546Sopenharmony_ci } 641bf215546Sopenharmony_ci break; 642bf215546Sopenharmony_ci case GL_SHORT: 643bf215546Sopenharmony_ci { 644bf215546Sopenharmony_ci GLshort *dst = (GLshort *) dest; 645bf215546Sopenharmony_ci GLuint i; 646bf215546Sopenharmony_ci for (i=0;i<n;i++) { 647bf215546Sopenharmony_ci dst[i] = (GLshort) source[i]; 648bf215546Sopenharmony_ci } 649bf215546Sopenharmony_ci if (dstPacking->SwapBytes) { 650bf215546Sopenharmony_ci _mesa_swap2( (GLushort *) dst, n ); 651bf215546Sopenharmony_ci } 652bf215546Sopenharmony_ci } 653bf215546Sopenharmony_ci break; 654bf215546Sopenharmony_ci case GL_UNSIGNED_INT: 655bf215546Sopenharmony_ci { 656bf215546Sopenharmony_ci GLuint *dst = (GLuint *) dest; 657bf215546Sopenharmony_ci GLuint i; 658bf215546Sopenharmony_ci for (i=0;i<n;i++) { 659bf215546Sopenharmony_ci dst[i] = (GLuint) source[i]; 660bf215546Sopenharmony_ci } 661bf215546Sopenharmony_ci if (dstPacking->SwapBytes) { 662bf215546Sopenharmony_ci _mesa_swap4( (GLuint *) dst, n ); 663bf215546Sopenharmony_ci } 664bf215546Sopenharmony_ci } 665bf215546Sopenharmony_ci break; 666bf215546Sopenharmony_ci case GL_INT: 667bf215546Sopenharmony_ci { 668bf215546Sopenharmony_ci GLint *dst = (GLint *) dest; 669bf215546Sopenharmony_ci GLuint i; 670bf215546Sopenharmony_ci for (i=0;i<n;i++) { 671bf215546Sopenharmony_ci dst[i] = (GLint) source[i]; 672bf215546Sopenharmony_ci } 673bf215546Sopenharmony_ci if (dstPacking->SwapBytes) { 674bf215546Sopenharmony_ci _mesa_swap4( (GLuint *) dst, n ); 675bf215546Sopenharmony_ci } 676bf215546Sopenharmony_ci } 677bf215546Sopenharmony_ci break; 678bf215546Sopenharmony_ci case GL_FLOAT: 679bf215546Sopenharmony_ci { 680bf215546Sopenharmony_ci GLfloat *dst = (GLfloat *) dest; 681bf215546Sopenharmony_ci GLuint i; 682bf215546Sopenharmony_ci for (i=0;i<n;i++) { 683bf215546Sopenharmony_ci dst[i] = (GLfloat) source[i]; 684bf215546Sopenharmony_ci } 685bf215546Sopenharmony_ci if (dstPacking->SwapBytes) { 686bf215546Sopenharmony_ci _mesa_swap4( (GLuint *) dst, n ); 687bf215546Sopenharmony_ci } 688bf215546Sopenharmony_ci } 689bf215546Sopenharmony_ci break; 690bf215546Sopenharmony_ci case GL_HALF_FLOAT_ARB: 691bf215546Sopenharmony_ci case GL_HALF_FLOAT_OES: 692bf215546Sopenharmony_ci { 693bf215546Sopenharmony_ci GLhalfARB *dst = (GLhalfARB *) dest; 694bf215546Sopenharmony_ci GLuint i; 695bf215546Sopenharmony_ci for (i=0;i<n;i++) { 696bf215546Sopenharmony_ci dst[i] = _mesa_float_to_half( (float) source[i] ); 697bf215546Sopenharmony_ci } 698bf215546Sopenharmony_ci if (dstPacking->SwapBytes) { 699bf215546Sopenharmony_ci _mesa_swap2( (GLushort *) dst, n ); 700bf215546Sopenharmony_ci } 701bf215546Sopenharmony_ci } 702bf215546Sopenharmony_ci break; 703bf215546Sopenharmony_ci case GL_BITMAP: 704bf215546Sopenharmony_ci if (dstPacking->LsbFirst) { 705bf215546Sopenharmony_ci GLubyte *dst = (GLubyte *) dest; 706bf215546Sopenharmony_ci GLint shift = 0; 707bf215546Sopenharmony_ci GLuint i; 708bf215546Sopenharmony_ci for (i = 0; i < n; i++) { 709bf215546Sopenharmony_ci if (shift == 0) 710bf215546Sopenharmony_ci *dst = 0; 711bf215546Sopenharmony_ci *dst |= ((source[i] != 0) << shift); 712bf215546Sopenharmony_ci shift++; 713bf215546Sopenharmony_ci if (shift == 8) { 714bf215546Sopenharmony_ci shift = 0; 715bf215546Sopenharmony_ci dst++; 716bf215546Sopenharmony_ci } 717bf215546Sopenharmony_ci } 718bf215546Sopenharmony_ci } 719bf215546Sopenharmony_ci else { 720bf215546Sopenharmony_ci GLubyte *dst = (GLubyte *) dest; 721bf215546Sopenharmony_ci GLint shift = 7; 722bf215546Sopenharmony_ci GLuint i; 723bf215546Sopenharmony_ci for (i = 0; i < n; i++) { 724bf215546Sopenharmony_ci if (shift == 7) 725bf215546Sopenharmony_ci *dst = 0; 726bf215546Sopenharmony_ci *dst |= ((source[i] != 0) << shift); 727bf215546Sopenharmony_ci shift--; 728bf215546Sopenharmony_ci if (shift < 0) { 729bf215546Sopenharmony_ci shift = 7; 730bf215546Sopenharmony_ci dst++; 731bf215546Sopenharmony_ci } 732bf215546Sopenharmony_ci } 733bf215546Sopenharmony_ci } 734bf215546Sopenharmony_ci break; 735bf215546Sopenharmony_ci default: 736bf215546Sopenharmony_ci unreachable("bad type in _mesa_pack_index_span"); 737bf215546Sopenharmony_ci } 738bf215546Sopenharmony_ci 739bf215546Sopenharmony_ci free(stencil); 740bf215546Sopenharmony_ci} 741bf215546Sopenharmony_ci 742bf215546Sopenharmony_ci#define DEPTH_VALUES(GLTYPE, GLTYPE2FLOAT) \ 743bf215546Sopenharmony_ci do { \ 744bf215546Sopenharmony_ci GLuint i; \ 745bf215546Sopenharmony_ci const GLTYPE *src = (const GLTYPE *)source; \ 746bf215546Sopenharmony_ci for (i = 0; i < n; i++) { \ 747bf215546Sopenharmony_ci GLTYPE value = src[i]; \ 748bf215546Sopenharmony_ci if (srcPacking->SwapBytes) { \ 749bf215546Sopenharmony_ci if (sizeof(GLTYPE) == 2) { \ 750bf215546Sopenharmony_ci SWAP2BYTE(value); \ 751bf215546Sopenharmony_ci } else if (sizeof(GLTYPE) == 4) { \ 752bf215546Sopenharmony_ci SWAP4BYTE(value); \ 753bf215546Sopenharmony_ci } \ 754bf215546Sopenharmony_ci } \ 755bf215546Sopenharmony_ci depthValues[i] = GLTYPE2FLOAT(value); \ 756bf215546Sopenharmony_ci } \ 757bf215546Sopenharmony_ci } while (0) 758bf215546Sopenharmony_ci 759bf215546Sopenharmony_ci 760bf215546Sopenharmony_ci/** 761bf215546Sopenharmony_ci * Unpack a row of depth/z values from memory, returning GLushort, GLuint 762bf215546Sopenharmony_ci * or GLfloat values. 763bf215546Sopenharmony_ci * The glPixelTransfer (scale/bias) params will be applied. 764bf215546Sopenharmony_ci * 765bf215546Sopenharmony_ci * \param dstType one of GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, GL_FLOAT 766bf215546Sopenharmony_ci * \param depthMax max value for returned GLushort or GLuint values 767bf215546Sopenharmony_ci * (ignored for GLfloat). 768bf215546Sopenharmony_ci */ 769bf215546Sopenharmony_civoid 770bf215546Sopenharmony_ci_mesa_unpack_depth_span( struct gl_context *ctx, GLuint n, 771bf215546Sopenharmony_ci GLenum dstType, GLvoid *dest, GLuint depthMax, 772bf215546Sopenharmony_ci GLenum srcType, const GLvoid *source, 773bf215546Sopenharmony_ci const struct gl_pixelstore_attrib *srcPacking ) 774bf215546Sopenharmony_ci{ 775bf215546Sopenharmony_ci GLfloat *depthTemp = NULL, *depthValues; 776bf215546Sopenharmony_ci GLboolean needClamp = GL_FALSE; 777bf215546Sopenharmony_ci 778bf215546Sopenharmony_ci /* Look for special cases first. 779bf215546Sopenharmony_ci * Not only are these faster, they're less prone to numeric conversion 780bf215546Sopenharmony_ci * problems. Otherwise, converting from an int type to a float then 781bf215546Sopenharmony_ci * back to an int type can introduce errors that will show up as 782bf215546Sopenharmony_ci * artifacts in things like depth peeling which uses glCopyTexImage. 783bf215546Sopenharmony_ci */ 784bf215546Sopenharmony_ci if (ctx->Pixel.DepthScale == 1.0F && ctx->Pixel.DepthBias == 0.0F) { 785bf215546Sopenharmony_ci if (srcType == GL_UNSIGNED_INT && dstType == GL_UNSIGNED_SHORT) { 786bf215546Sopenharmony_ci const GLuint *src = (const GLuint *) source; 787bf215546Sopenharmony_ci GLushort *dst = (GLushort *) dest; 788bf215546Sopenharmony_ci GLuint i; 789bf215546Sopenharmony_ci for (i = 0; i < n; i++) { 790bf215546Sopenharmony_ci dst[i] = src[i] >> 16; 791bf215546Sopenharmony_ci } 792bf215546Sopenharmony_ci return; 793bf215546Sopenharmony_ci } 794bf215546Sopenharmony_ci if (srcType == GL_UNSIGNED_SHORT 795bf215546Sopenharmony_ci && dstType == GL_UNSIGNED_INT 796bf215546Sopenharmony_ci && depthMax == 0xffffffff) { 797bf215546Sopenharmony_ci const GLushort *src = (const GLushort *) source; 798bf215546Sopenharmony_ci GLuint *dst = (GLuint *) dest; 799bf215546Sopenharmony_ci GLuint i; 800bf215546Sopenharmony_ci for (i = 0; i < n; i++) { 801bf215546Sopenharmony_ci dst[i] = src[i] | (src[i] << 16); 802bf215546Sopenharmony_ci } 803bf215546Sopenharmony_ci return; 804bf215546Sopenharmony_ci } 805bf215546Sopenharmony_ci if (srcType == GL_UNSIGNED_INT_24_8 806bf215546Sopenharmony_ci && dstType == GL_UNSIGNED_INT 807bf215546Sopenharmony_ci && depthMax == 0xffffff) { 808bf215546Sopenharmony_ci const GLuint *src = (const GLuint *) source; 809bf215546Sopenharmony_ci GLuint *dst = (GLuint *) dest; 810bf215546Sopenharmony_ci GLuint i; 811bf215546Sopenharmony_ci for (i = 0; i < n; i++) { 812bf215546Sopenharmony_ci dst[i] = src[i] >> 8; 813bf215546Sopenharmony_ci } 814bf215546Sopenharmony_ci return; 815bf215546Sopenharmony_ci } 816bf215546Sopenharmony_ci /* XXX may want to add additional cases here someday */ 817bf215546Sopenharmony_ci } 818bf215546Sopenharmony_ci 819bf215546Sopenharmony_ci /* general case path follows */ 820bf215546Sopenharmony_ci 821bf215546Sopenharmony_ci if (dstType == GL_FLOAT) { 822bf215546Sopenharmony_ci depthValues = (GLfloat *) dest; 823bf215546Sopenharmony_ci } 824bf215546Sopenharmony_ci else { 825bf215546Sopenharmony_ci depthTemp = malloc(n * sizeof(GLfloat)); 826bf215546Sopenharmony_ci if (!depthTemp) { 827bf215546Sopenharmony_ci _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking"); 828bf215546Sopenharmony_ci return; 829bf215546Sopenharmony_ci } 830bf215546Sopenharmony_ci 831bf215546Sopenharmony_ci depthValues = depthTemp; 832bf215546Sopenharmony_ci } 833bf215546Sopenharmony_ci 834bf215546Sopenharmony_ci /* Convert incoming values to GLfloat. Some conversions will require 835bf215546Sopenharmony_ci * clamping, below. 836bf215546Sopenharmony_ci */ 837bf215546Sopenharmony_ci switch (srcType) { 838bf215546Sopenharmony_ci case GL_BYTE: 839bf215546Sopenharmony_ci DEPTH_VALUES(GLbyte, BYTE_TO_FLOATZ); 840bf215546Sopenharmony_ci needClamp = GL_TRUE; 841bf215546Sopenharmony_ci break; 842bf215546Sopenharmony_ci case GL_UNSIGNED_BYTE: 843bf215546Sopenharmony_ci DEPTH_VALUES(GLubyte, UBYTE_TO_FLOAT); 844bf215546Sopenharmony_ci break; 845bf215546Sopenharmony_ci case GL_SHORT: 846bf215546Sopenharmony_ci DEPTH_VALUES(GLshort, SHORT_TO_FLOATZ); 847bf215546Sopenharmony_ci needClamp = GL_TRUE; 848bf215546Sopenharmony_ci break; 849bf215546Sopenharmony_ci case GL_UNSIGNED_SHORT: 850bf215546Sopenharmony_ci DEPTH_VALUES(GLushort, USHORT_TO_FLOAT); 851bf215546Sopenharmony_ci break; 852bf215546Sopenharmony_ci case GL_INT: 853bf215546Sopenharmony_ci DEPTH_VALUES(GLint, INT_TO_FLOAT); 854bf215546Sopenharmony_ci needClamp = GL_TRUE; 855bf215546Sopenharmony_ci break; 856bf215546Sopenharmony_ci case GL_UNSIGNED_INT: 857bf215546Sopenharmony_ci DEPTH_VALUES(GLuint, UINT_TO_FLOAT); 858bf215546Sopenharmony_ci break; 859bf215546Sopenharmony_ci case GL_UNSIGNED_INT_24_8_EXT: /* GL_EXT_packed_depth_stencil */ 860bf215546Sopenharmony_ci if (dstType == GL_UNSIGNED_INT_24_8_EXT && 861bf215546Sopenharmony_ci depthMax == 0xffffff && 862bf215546Sopenharmony_ci ctx->Pixel.DepthScale == 1.0F && 863bf215546Sopenharmony_ci ctx->Pixel.DepthBias == 0.0F) { 864bf215546Sopenharmony_ci const GLuint *src = (const GLuint *) source; 865bf215546Sopenharmony_ci GLuint *zValues = (GLuint *) dest; 866bf215546Sopenharmony_ci GLuint i; 867bf215546Sopenharmony_ci for (i = 0; i < n; i++) { 868bf215546Sopenharmony_ci GLuint value = src[i]; 869bf215546Sopenharmony_ci if (srcPacking->SwapBytes) { 870bf215546Sopenharmony_ci SWAP4BYTE(value); 871bf215546Sopenharmony_ci } 872bf215546Sopenharmony_ci zValues[i] = value & 0xffffff00; 873bf215546Sopenharmony_ci } 874bf215546Sopenharmony_ci free(depthTemp); 875bf215546Sopenharmony_ci return; 876bf215546Sopenharmony_ci } 877bf215546Sopenharmony_ci else { 878bf215546Sopenharmony_ci const GLuint *src = (const GLuint *) source; 879bf215546Sopenharmony_ci const GLfloat scale = 1.0f / 0xffffff; 880bf215546Sopenharmony_ci GLuint i; 881bf215546Sopenharmony_ci for (i = 0; i < n; i++) { 882bf215546Sopenharmony_ci GLuint value = src[i]; 883bf215546Sopenharmony_ci if (srcPacking->SwapBytes) { 884bf215546Sopenharmony_ci SWAP4BYTE(value); 885bf215546Sopenharmony_ci } 886bf215546Sopenharmony_ci depthValues[i] = (value >> 8) * scale; 887bf215546Sopenharmony_ci } 888bf215546Sopenharmony_ci } 889bf215546Sopenharmony_ci break; 890bf215546Sopenharmony_ci case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: 891bf215546Sopenharmony_ci { 892bf215546Sopenharmony_ci GLuint i; 893bf215546Sopenharmony_ci const GLfloat *src = (const GLfloat *)source; 894bf215546Sopenharmony_ci for (i = 0; i < n; i++) { 895bf215546Sopenharmony_ci GLfloat value = src[i * 2]; 896bf215546Sopenharmony_ci if (srcPacking->SwapBytes) { 897bf215546Sopenharmony_ci SWAP4BYTE(value); 898bf215546Sopenharmony_ci } 899bf215546Sopenharmony_ci depthValues[i] = value; 900bf215546Sopenharmony_ci } 901bf215546Sopenharmony_ci needClamp = GL_TRUE; 902bf215546Sopenharmony_ci } 903bf215546Sopenharmony_ci break; 904bf215546Sopenharmony_ci case GL_FLOAT: 905bf215546Sopenharmony_ci DEPTH_VALUES(GLfloat, 1*); 906bf215546Sopenharmony_ci needClamp = GL_TRUE; 907bf215546Sopenharmony_ci break; 908bf215546Sopenharmony_ci case GL_HALF_FLOAT_ARB: 909bf215546Sopenharmony_ci case GL_HALF_FLOAT_OES: 910bf215546Sopenharmony_ci { 911bf215546Sopenharmony_ci GLuint i; 912bf215546Sopenharmony_ci const GLhalfARB *src = (const GLhalfARB *) source; 913bf215546Sopenharmony_ci for (i = 0; i < n; i++) { 914bf215546Sopenharmony_ci GLhalfARB value = src[i]; 915bf215546Sopenharmony_ci if (srcPacking->SwapBytes) { 916bf215546Sopenharmony_ci SWAP2BYTE(value); 917bf215546Sopenharmony_ci } 918bf215546Sopenharmony_ci depthValues[i] = _mesa_half_to_float(value); 919bf215546Sopenharmony_ci } 920bf215546Sopenharmony_ci needClamp = GL_TRUE; 921bf215546Sopenharmony_ci } 922bf215546Sopenharmony_ci break; 923bf215546Sopenharmony_ci default: 924bf215546Sopenharmony_ci _mesa_problem(NULL, "bad type in _mesa_unpack_depth_span()"); 925bf215546Sopenharmony_ci free(depthTemp); 926bf215546Sopenharmony_ci return; 927bf215546Sopenharmony_ci } 928bf215546Sopenharmony_ci 929bf215546Sopenharmony_ci /* apply depth scale and bias */ 930bf215546Sopenharmony_ci { 931bf215546Sopenharmony_ci const GLfloat scale = ctx->Pixel.DepthScale; 932bf215546Sopenharmony_ci const GLfloat bias = ctx->Pixel.DepthBias; 933bf215546Sopenharmony_ci if (scale != 1.0F || bias != 0.0F) { 934bf215546Sopenharmony_ci GLuint i; 935bf215546Sopenharmony_ci for (i = 0; i < n; i++) { 936bf215546Sopenharmony_ci depthValues[i] = depthValues[i] * scale + bias; 937bf215546Sopenharmony_ci } 938bf215546Sopenharmony_ci needClamp = GL_TRUE; 939bf215546Sopenharmony_ci } 940bf215546Sopenharmony_ci } 941bf215546Sopenharmony_ci 942bf215546Sopenharmony_ci /* clamp to [0, 1] */ 943bf215546Sopenharmony_ci if (needClamp) { 944bf215546Sopenharmony_ci GLuint i; 945bf215546Sopenharmony_ci for (i = 0; i < n; i++) { 946bf215546Sopenharmony_ci depthValues[i] = CLAMP(depthValues[i], 0.0F, 1.0F); 947bf215546Sopenharmony_ci } 948bf215546Sopenharmony_ci } 949bf215546Sopenharmony_ci 950bf215546Sopenharmony_ci /* 951bf215546Sopenharmony_ci * Convert values to dstType 952bf215546Sopenharmony_ci */ 953bf215546Sopenharmony_ci if (dstType == GL_UNSIGNED_INT) { 954bf215546Sopenharmony_ci GLuint *zValues = (GLuint *) dest; 955bf215546Sopenharmony_ci GLuint i; 956bf215546Sopenharmony_ci if (depthMax <= 0xffffff) { 957bf215546Sopenharmony_ci /* no overflow worries */ 958bf215546Sopenharmony_ci for (i = 0; i < n; i++) { 959bf215546Sopenharmony_ci zValues[i] = (GLuint) (depthValues[i] * (GLfloat) depthMax); 960bf215546Sopenharmony_ci } 961bf215546Sopenharmony_ci } 962bf215546Sopenharmony_ci else { 963bf215546Sopenharmony_ci /* need to use double precision to prevent overflow problems */ 964bf215546Sopenharmony_ci for (i = 0; i < n; i++) { 965bf215546Sopenharmony_ci GLdouble z = depthValues[i] * (GLdouble) depthMax; 966bf215546Sopenharmony_ci if (z >= (GLdouble) 0xffffffff) 967bf215546Sopenharmony_ci zValues[i] = 0xffffffff; 968bf215546Sopenharmony_ci else 969bf215546Sopenharmony_ci zValues[i] = (GLuint) z; 970bf215546Sopenharmony_ci } 971bf215546Sopenharmony_ci } 972bf215546Sopenharmony_ci } 973bf215546Sopenharmony_ci else if (dstType == GL_UNSIGNED_SHORT) { 974bf215546Sopenharmony_ci GLushort *zValues = (GLushort *) dest; 975bf215546Sopenharmony_ci GLuint i; 976bf215546Sopenharmony_ci assert(depthMax <= 0xffff); 977bf215546Sopenharmony_ci for (i = 0; i < n; i++) { 978bf215546Sopenharmony_ci zValues[i] = (GLushort) (depthValues[i] * (GLfloat) depthMax); 979bf215546Sopenharmony_ci } 980bf215546Sopenharmony_ci } 981bf215546Sopenharmony_ci else if (dstType == GL_FLOAT) { 982bf215546Sopenharmony_ci /* Nothing to do. depthValues is pointing to dest. */ 983bf215546Sopenharmony_ci } 984bf215546Sopenharmony_ci else if (dstType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV) { 985bf215546Sopenharmony_ci GLfloat *zValues = (GLfloat*) dest; 986bf215546Sopenharmony_ci GLuint i; 987bf215546Sopenharmony_ci for (i = 0; i < n; i++) { 988bf215546Sopenharmony_ci zValues[i*2] = depthValues[i]; 989bf215546Sopenharmony_ci } 990bf215546Sopenharmony_ci } 991bf215546Sopenharmony_ci else { 992bf215546Sopenharmony_ci assert(0); 993bf215546Sopenharmony_ci } 994bf215546Sopenharmony_ci 995bf215546Sopenharmony_ci free(depthTemp); 996bf215546Sopenharmony_ci} 997bf215546Sopenharmony_ci 998bf215546Sopenharmony_ci 999bf215546Sopenharmony_ci/* 1000bf215546Sopenharmony_ci * Pack an array of depth values. The values are floats in [0,1]. 1001bf215546Sopenharmony_ci */ 1002bf215546Sopenharmony_civoid 1003bf215546Sopenharmony_ci_mesa_pack_depth_span( struct gl_context *ctx, GLuint n, GLvoid *dest, 1004bf215546Sopenharmony_ci GLenum dstType, const GLfloat *depthSpan, 1005bf215546Sopenharmony_ci const struct gl_pixelstore_attrib *dstPacking ) 1006bf215546Sopenharmony_ci{ 1007bf215546Sopenharmony_ci GLfloat *depthCopy = malloc(n * sizeof(GLfloat)); 1008bf215546Sopenharmony_ci if (!depthCopy) { 1009bf215546Sopenharmony_ci _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel packing"); 1010bf215546Sopenharmony_ci return; 1011bf215546Sopenharmony_ci } 1012bf215546Sopenharmony_ci 1013bf215546Sopenharmony_ci if (ctx->Pixel.DepthScale != 1.0F || ctx->Pixel.DepthBias != 0.0F) { 1014bf215546Sopenharmony_ci memcpy(depthCopy, depthSpan, n * sizeof(GLfloat)); 1015bf215546Sopenharmony_ci _mesa_scale_and_bias_depth(ctx, n, depthCopy); 1016bf215546Sopenharmony_ci depthSpan = depthCopy; 1017bf215546Sopenharmony_ci } 1018bf215546Sopenharmony_ci 1019bf215546Sopenharmony_ci switch (dstType) { 1020bf215546Sopenharmony_ci case GL_UNSIGNED_BYTE: 1021bf215546Sopenharmony_ci { 1022bf215546Sopenharmony_ci GLubyte *dst = (GLubyte *) dest; 1023bf215546Sopenharmony_ci GLuint i; 1024bf215546Sopenharmony_ci for (i = 0; i < n; i++) { 1025bf215546Sopenharmony_ci dst[i] = FLOAT_TO_UBYTE( depthSpan[i] ); 1026bf215546Sopenharmony_ci } 1027bf215546Sopenharmony_ci } 1028bf215546Sopenharmony_ci break; 1029bf215546Sopenharmony_ci case GL_BYTE: 1030bf215546Sopenharmony_ci { 1031bf215546Sopenharmony_ci GLbyte *dst = (GLbyte *) dest; 1032bf215546Sopenharmony_ci GLuint i; 1033bf215546Sopenharmony_ci for (i = 0; i < n; i++) { 1034bf215546Sopenharmony_ci dst[i] = FLOAT_TO_BYTE( depthSpan[i] ); 1035bf215546Sopenharmony_ci } 1036bf215546Sopenharmony_ci } 1037bf215546Sopenharmony_ci break; 1038bf215546Sopenharmony_ci case GL_UNSIGNED_SHORT: 1039bf215546Sopenharmony_ci { 1040bf215546Sopenharmony_ci GLushort *dst = (GLushort *) dest; 1041bf215546Sopenharmony_ci GLuint i; 1042bf215546Sopenharmony_ci for (i = 0; i < n; i++) { 1043bf215546Sopenharmony_ci CLAMPED_FLOAT_TO_USHORT(dst[i], depthSpan[i]); 1044bf215546Sopenharmony_ci } 1045bf215546Sopenharmony_ci if (dstPacking->SwapBytes) { 1046bf215546Sopenharmony_ci _mesa_swap2( (GLushort *) dst, n ); 1047bf215546Sopenharmony_ci } 1048bf215546Sopenharmony_ci } 1049bf215546Sopenharmony_ci break; 1050bf215546Sopenharmony_ci case GL_SHORT: 1051bf215546Sopenharmony_ci { 1052bf215546Sopenharmony_ci GLshort *dst = (GLshort *) dest; 1053bf215546Sopenharmony_ci GLuint i; 1054bf215546Sopenharmony_ci for (i = 0; i < n; i++) { 1055bf215546Sopenharmony_ci dst[i] = FLOAT_TO_SHORT( depthSpan[i] ); 1056bf215546Sopenharmony_ci } 1057bf215546Sopenharmony_ci if (dstPacking->SwapBytes) { 1058bf215546Sopenharmony_ci _mesa_swap2( (GLushort *) dst, n ); 1059bf215546Sopenharmony_ci } 1060bf215546Sopenharmony_ci } 1061bf215546Sopenharmony_ci break; 1062bf215546Sopenharmony_ci case GL_UNSIGNED_INT_24_8: 1063bf215546Sopenharmony_ci { 1064bf215546Sopenharmony_ci const GLdouble scale = (GLdouble) 0xffffff; 1065bf215546Sopenharmony_ci GLuint *dst = (GLuint *) dest; 1066bf215546Sopenharmony_ci GLuint i; 1067bf215546Sopenharmony_ci for (i = 0; i < n; i++) { 1068bf215546Sopenharmony_ci GLuint z = (GLuint) (depthSpan[i] * scale); 1069bf215546Sopenharmony_ci assert(z <= 0xffffff); 1070bf215546Sopenharmony_ci dst[i] = (z << 8); 1071bf215546Sopenharmony_ci } 1072bf215546Sopenharmony_ci if (dstPacking->SwapBytes) { 1073bf215546Sopenharmony_ci _mesa_swap4( (GLuint *) dst, n ); 1074bf215546Sopenharmony_ci } 1075bf215546Sopenharmony_ci break; 1076bf215546Sopenharmony_ci } 1077bf215546Sopenharmony_ci case GL_UNSIGNED_INT: 1078bf215546Sopenharmony_ci { 1079bf215546Sopenharmony_ci GLuint *dst = (GLuint *) dest; 1080bf215546Sopenharmony_ci GLuint i; 1081bf215546Sopenharmony_ci for (i = 0; i < n; i++) { 1082bf215546Sopenharmony_ci dst[i] = FLOAT_TO_UINT( depthSpan[i] ); 1083bf215546Sopenharmony_ci } 1084bf215546Sopenharmony_ci if (dstPacking->SwapBytes) { 1085bf215546Sopenharmony_ci _mesa_swap4( (GLuint *) dst, n ); 1086bf215546Sopenharmony_ci } 1087bf215546Sopenharmony_ci } 1088bf215546Sopenharmony_ci break; 1089bf215546Sopenharmony_ci case GL_INT: 1090bf215546Sopenharmony_ci { 1091bf215546Sopenharmony_ci GLint *dst = (GLint *) dest; 1092bf215546Sopenharmony_ci GLuint i; 1093bf215546Sopenharmony_ci for (i = 0; i < n; i++) { 1094bf215546Sopenharmony_ci dst[i] = FLOAT_TO_INT( depthSpan[i] ); 1095bf215546Sopenharmony_ci } 1096bf215546Sopenharmony_ci if (dstPacking->SwapBytes) { 1097bf215546Sopenharmony_ci _mesa_swap4( (GLuint *) dst, n ); 1098bf215546Sopenharmony_ci } 1099bf215546Sopenharmony_ci } 1100bf215546Sopenharmony_ci break; 1101bf215546Sopenharmony_ci case GL_FLOAT: 1102bf215546Sopenharmony_ci { 1103bf215546Sopenharmony_ci GLfloat *dst = (GLfloat *) dest; 1104bf215546Sopenharmony_ci GLuint i; 1105bf215546Sopenharmony_ci for (i = 0; i < n; i++) { 1106bf215546Sopenharmony_ci dst[i] = depthSpan[i]; 1107bf215546Sopenharmony_ci } 1108bf215546Sopenharmony_ci if (dstPacking->SwapBytes) { 1109bf215546Sopenharmony_ci _mesa_swap4( (GLuint *) dst, n ); 1110bf215546Sopenharmony_ci } 1111bf215546Sopenharmony_ci } 1112bf215546Sopenharmony_ci break; 1113bf215546Sopenharmony_ci case GL_HALF_FLOAT_ARB: 1114bf215546Sopenharmony_ci case GL_HALF_FLOAT_OES: 1115bf215546Sopenharmony_ci { 1116bf215546Sopenharmony_ci GLhalfARB *dst = (GLhalfARB *) dest; 1117bf215546Sopenharmony_ci GLuint i; 1118bf215546Sopenharmony_ci for (i = 0; i < n; i++) { 1119bf215546Sopenharmony_ci dst[i] = _mesa_float_to_half(depthSpan[i]); 1120bf215546Sopenharmony_ci } 1121bf215546Sopenharmony_ci if (dstPacking->SwapBytes) { 1122bf215546Sopenharmony_ci _mesa_swap2( (GLushort *) dst, n ); 1123bf215546Sopenharmony_ci } 1124bf215546Sopenharmony_ci } 1125bf215546Sopenharmony_ci break; 1126bf215546Sopenharmony_ci default: 1127bf215546Sopenharmony_ci unreachable("bad type in _mesa_pack_depth_span()"); 1128bf215546Sopenharmony_ci } 1129bf215546Sopenharmony_ci 1130bf215546Sopenharmony_ci free(depthCopy); 1131bf215546Sopenharmony_ci} 1132bf215546Sopenharmony_ci 1133bf215546Sopenharmony_ci 1134bf215546Sopenharmony_ci 1135bf215546Sopenharmony_ci/** 1136bf215546Sopenharmony_ci * Pack depth and stencil values as GL_DEPTH_STENCIL (GL_UNSIGNED_INT_24_8 etc) 1137bf215546Sopenharmony_ci */ 1138bf215546Sopenharmony_civoid 1139bf215546Sopenharmony_ci_mesa_pack_depth_stencil_span(struct gl_context *ctx,GLuint n, 1140bf215546Sopenharmony_ci GLenum dstType, GLuint *dest, 1141bf215546Sopenharmony_ci const GLfloat *depthVals, 1142bf215546Sopenharmony_ci const GLubyte *stencilVals, 1143bf215546Sopenharmony_ci const struct gl_pixelstore_attrib *dstPacking) 1144bf215546Sopenharmony_ci{ 1145bf215546Sopenharmony_ci GLfloat *depthCopy = malloc(n * sizeof(GLfloat)); 1146bf215546Sopenharmony_ci GLubyte *stencilCopy = malloc(n * sizeof(GLubyte)); 1147bf215546Sopenharmony_ci GLuint i; 1148bf215546Sopenharmony_ci 1149bf215546Sopenharmony_ci if (!depthCopy || !stencilCopy) { 1150bf215546Sopenharmony_ci _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel packing"); 1151bf215546Sopenharmony_ci free(depthCopy); 1152bf215546Sopenharmony_ci free(stencilCopy); 1153bf215546Sopenharmony_ci return; 1154bf215546Sopenharmony_ci } 1155bf215546Sopenharmony_ci 1156bf215546Sopenharmony_ci if (ctx->Pixel.DepthScale != 1.0F || ctx->Pixel.DepthBias != 0.0F) { 1157bf215546Sopenharmony_ci memcpy(depthCopy, depthVals, n * sizeof(GLfloat)); 1158bf215546Sopenharmony_ci _mesa_scale_and_bias_depth(ctx, n, depthCopy); 1159bf215546Sopenharmony_ci depthVals = depthCopy; 1160bf215546Sopenharmony_ci } 1161bf215546Sopenharmony_ci 1162bf215546Sopenharmony_ci if (ctx->Pixel.IndexShift || 1163bf215546Sopenharmony_ci ctx->Pixel.IndexOffset || 1164bf215546Sopenharmony_ci ctx->Pixel.MapStencilFlag) { 1165bf215546Sopenharmony_ci memcpy(stencilCopy, stencilVals, n * sizeof(GLubyte)); 1166bf215546Sopenharmony_ci _mesa_apply_stencil_transfer_ops(ctx, n, stencilCopy); 1167bf215546Sopenharmony_ci stencilVals = stencilCopy; 1168bf215546Sopenharmony_ci } 1169bf215546Sopenharmony_ci 1170bf215546Sopenharmony_ci switch (dstType) { 1171bf215546Sopenharmony_ci case GL_UNSIGNED_INT_24_8: 1172bf215546Sopenharmony_ci for (i = 0; i < n; i++) { 1173bf215546Sopenharmony_ci GLuint z = (GLuint) (depthVals[i] * 0xffffff); 1174bf215546Sopenharmony_ci dest[i] = (z << 8) | (stencilVals[i] & 0xff); 1175bf215546Sopenharmony_ci } 1176bf215546Sopenharmony_ci break; 1177bf215546Sopenharmony_ci case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: 1178bf215546Sopenharmony_ci for (i = 0; i < n; i++) { 1179bf215546Sopenharmony_ci ((GLfloat*)dest)[i*2] = depthVals[i]; 1180bf215546Sopenharmony_ci dest[i*2+1] = stencilVals[i] & 0xff; 1181bf215546Sopenharmony_ci } 1182bf215546Sopenharmony_ci break; 1183bf215546Sopenharmony_ci } 1184bf215546Sopenharmony_ci 1185bf215546Sopenharmony_ci if (dstPacking->SwapBytes) { 1186bf215546Sopenharmony_ci _mesa_swap4(dest, n); 1187bf215546Sopenharmony_ci } 1188bf215546Sopenharmony_ci 1189bf215546Sopenharmony_ci free(depthCopy); 1190bf215546Sopenharmony_ci free(stencilCopy); 1191bf215546Sopenharmony_ci} 1192bf215546Sopenharmony_ci 1193bf215546Sopenharmony_ci 1194bf215546Sopenharmony_ci 1195bf215546Sopenharmony_ci/** 1196bf215546Sopenharmony_ci * Unpack image data. Apply byte swapping, byte flipping (bitmap). 1197bf215546Sopenharmony_ci * Return all image data in a contiguous block. This is used when we 1198bf215546Sopenharmony_ci * compile glDrawPixels, glTexImage, etc into a display list. We 1199bf215546Sopenharmony_ci * need a copy of the data in a standard format. 1200bf215546Sopenharmony_ci */ 1201bf215546Sopenharmony_civoid * 1202bf215546Sopenharmony_ci_mesa_unpack_image( GLuint dimensions, 1203bf215546Sopenharmony_ci GLsizei width, GLsizei height, GLsizei depth, 1204bf215546Sopenharmony_ci GLenum format, GLenum type, const GLvoid *pixels, 1205bf215546Sopenharmony_ci const struct gl_pixelstore_attrib *unpack ) 1206bf215546Sopenharmony_ci{ 1207bf215546Sopenharmony_ci GLint bytesPerRow, compsPerRow; 1208bf215546Sopenharmony_ci GLboolean flipBytes, swap2, swap4; 1209bf215546Sopenharmony_ci 1210bf215546Sopenharmony_ci if (!pixels) 1211bf215546Sopenharmony_ci return NULL; /* not necessarily an error */ 1212bf215546Sopenharmony_ci 1213bf215546Sopenharmony_ci if (width <= 0 || height <= 0 || depth <= 0) 1214bf215546Sopenharmony_ci return NULL; /* generate error later */ 1215bf215546Sopenharmony_ci 1216bf215546Sopenharmony_ci if (type == GL_BITMAP) { 1217bf215546Sopenharmony_ci bytesPerRow = (width + 7) >> 3; 1218bf215546Sopenharmony_ci flipBytes = unpack->LsbFirst; 1219bf215546Sopenharmony_ci swap2 = swap4 = GL_FALSE; 1220bf215546Sopenharmony_ci compsPerRow = 0; 1221bf215546Sopenharmony_ci } 1222bf215546Sopenharmony_ci else { 1223bf215546Sopenharmony_ci const GLint bytesPerPixel = _mesa_bytes_per_pixel(format, type); 1224bf215546Sopenharmony_ci GLint components = _mesa_components_in_format(format); 1225bf215546Sopenharmony_ci GLint bytesPerComp; 1226bf215546Sopenharmony_ci 1227bf215546Sopenharmony_ci if (_mesa_type_is_packed(type)) 1228bf215546Sopenharmony_ci components = 1; 1229bf215546Sopenharmony_ci 1230bf215546Sopenharmony_ci if (bytesPerPixel <= 0 || components <= 0) 1231bf215546Sopenharmony_ci return NULL; /* bad format or type. generate error later */ 1232bf215546Sopenharmony_ci bytesPerRow = bytesPerPixel * width; 1233bf215546Sopenharmony_ci bytesPerComp = bytesPerPixel / components; 1234bf215546Sopenharmony_ci flipBytes = GL_FALSE; 1235bf215546Sopenharmony_ci swap2 = (bytesPerComp == 2) && unpack->SwapBytes; 1236bf215546Sopenharmony_ci swap4 = (bytesPerComp == 4) && unpack->SwapBytes; 1237bf215546Sopenharmony_ci compsPerRow = components * width; 1238bf215546Sopenharmony_ci assert(compsPerRow >= width); 1239bf215546Sopenharmony_ci } 1240bf215546Sopenharmony_ci 1241bf215546Sopenharmony_ci { 1242bf215546Sopenharmony_ci GLubyte *destBuffer 1243bf215546Sopenharmony_ci = malloc(bytesPerRow * height * depth); 1244bf215546Sopenharmony_ci GLubyte *dst; 1245bf215546Sopenharmony_ci GLint img, row; 1246bf215546Sopenharmony_ci if (!destBuffer) 1247bf215546Sopenharmony_ci return NULL; /* generate GL_OUT_OF_MEMORY later */ 1248bf215546Sopenharmony_ci 1249bf215546Sopenharmony_ci dst = destBuffer; 1250bf215546Sopenharmony_ci for (img = 0; img < depth; img++) { 1251bf215546Sopenharmony_ci for (row = 0; row < height; row++) { 1252bf215546Sopenharmony_ci const GLvoid *src = _mesa_image_address(dimensions, unpack, pixels, 1253bf215546Sopenharmony_ci width, height, format, type, img, row, 0); 1254bf215546Sopenharmony_ci 1255bf215546Sopenharmony_ci if ((type == GL_BITMAP) && (unpack->SkipPixels & 0x7)) { 1256bf215546Sopenharmony_ci GLint i; 1257bf215546Sopenharmony_ci flipBytes = GL_FALSE; 1258bf215546Sopenharmony_ci if (unpack->LsbFirst) { 1259bf215546Sopenharmony_ci GLubyte srcMask = 1 << (unpack->SkipPixels & 0x7); 1260bf215546Sopenharmony_ci GLubyte dstMask = 128; 1261bf215546Sopenharmony_ci const GLubyte *s = src; 1262bf215546Sopenharmony_ci GLubyte *d = dst; 1263bf215546Sopenharmony_ci *d = 0; 1264bf215546Sopenharmony_ci for (i = 0; i < width; i++) { 1265bf215546Sopenharmony_ci if (*s & srcMask) { 1266bf215546Sopenharmony_ci *d |= dstMask; 1267bf215546Sopenharmony_ci } 1268bf215546Sopenharmony_ci if (srcMask == 128) { 1269bf215546Sopenharmony_ci srcMask = 1; 1270bf215546Sopenharmony_ci s++; 1271bf215546Sopenharmony_ci } 1272bf215546Sopenharmony_ci else { 1273bf215546Sopenharmony_ci srcMask = srcMask << 1; 1274bf215546Sopenharmony_ci } 1275bf215546Sopenharmony_ci if (dstMask == 1) { 1276bf215546Sopenharmony_ci dstMask = 128; 1277bf215546Sopenharmony_ci d++; 1278bf215546Sopenharmony_ci *d = 0; 1279bf215546Sopenharmony_ci } 1280bf215546Sopenharmony_ci else { 1281bf215546Sopenharmony_ci dstMask = dstMask >> 1; 1282bf215546Sopenharmony_ci } 1283bf215546Sopenharmony_ci } 1284bf215546Sopenharmony_ci } 1285bf215546Sopenharmony_ci else { 1286bf215546Sopenharmony_ci GLubyte srcMask = 128 >> (unpack->SkipPixels & 0x7); 1287bf215546Sopenharmony_ci GLubyte dstMask = 128; 1288bf215546Sopenharmony_ci const GLubyte *s = src; 1289bf215546Sopenharmony_ci GLubyte *d = dst; 1290bf215546Sopenharmony_ci *d = 0; 1291bf215546Sopenharmony_ci for (i = 0; i < width; i++) { 1292bf215546Sopenharmony_ci if (*s & srcMask) { 1293bf215546Sopenharmony_ci *d |= dstMask; 1294bf215546Sopenharmony_ci } 1295bf215546Sopenharmony_ci if (srcMask == 1) { 1296bf215546Sopenharmony_ci srcMask = 128; 1297bf215546Sopenharmony_ci s++; 1298bf215546Sopenharmony_ci } 1299bf215546Sopenharmony_ci else { 1300bf215546Sopenharmony_ci srcMask = srcMask >> 1; 1301bf215546Sopenharmony_ci } 1302bf215546Sopenharmony_ci if (dstMask == 1) { 1303bf215546Sopenharmony_ci dstMask = 128; 1304bf215546Sopenharmony_ci d++; 1305bf215546Sopenharmony_ci *d = 0; 1306bf215546Sopenharmony_ci } 1307bf215546Sopenharmony_ci else { 1308bf215546Sopenharmony_ci dstMask = dstMask >> 1; 1309bf215546Sopenharmony_ci } 1310bf215546Sopenharmony_ci } 1311bf215546Sopenharmony_ci } 1312bf215546Sopenharmony_ci } 1313bf215546Sopenharmony_ci else { 1314bf215546Sopenharmony_ci memcpy(dst, src, bytesPerRow); 1315bf215546Sopenharmony_ci } 1316bf215546Sopenharmony_ci 1317bf215546Sopenharmony_ci /* byte flipping/swapping */ 1318bf215546Sopenharmony_ci if (flipBytes) { 1319bf215546Sopenharmony_ci flip_bytes((GLubyte *) dst, bytesPerRow); 1320bf215546Sopenharmony_ci } 1321bf215546Sopenharmony_ci else if (swap2) { 1322bf215546Sopenharmony_ci _mesa_swap2((GLushort*) dst, compsPerRow); 1323bf215546Sopenharmony_ci } 1324bf215546Sopenharmony_ci else if (swap4) { 1325bf215546Sopenharmony_ci _mesa_swap4((GLuint*) dst, compsPerRow); 1326bf215546Sopenharmony_ci } 1327bf215546Sopenharmony_ci dst += bytesPerRow; 1328bf215546Sopenharmony_ci } 1329bf215546Sopenharmony_ci } 1330bf215546Sopenharmony_ci return destBuffer; 1331bf215546Sopenharmony_ci } 1332bf215546Sopenharmony_ci} 1333bf215546Sopenharmony_ci 1334bf215546Sopenharmony_civoid 1335bf215546Sopenharmony_ci_mesa_pack_luminance_from_rgba_float(GLuint n, GLfloat rgba[][4], 1336bf215546Sopenharmony_ci GLvoid *dstAddr, GLenum dst_format, 1337bf215546Sopenharmony_ci GLbitfield transferOps) 1338bf215546Sopenharmony_ci{ 1339bf215546Sopenharmony_ci int i; 1340bf215546Sopenharmony_ci GLfloat *dst = (GLfloat *) dstAddr; 1341bf215546Sopenharmony_ci 1342bf215546Sopenharmony_ci switch (dst_format) { 1343bf215546Sopenharmony_ci case GL_LUMINANCE: 1344bf215546Sopenharmony_ci if (transferOps & IMAGE_CLAMP_BIT) { 1345bf215546Sopenharmony_ci for (i = 0; i < n; i++) { 1346bf215546Sopenharmony_ci GLfloat sum = rgba[i][RCOMP] + rgba[i][GCOMP] + rgba[i][BCOMP]; 1347bf215546Sopenharmony_ci dst[i] = CLAMP(sum, 0.0F, 1.0F); 1348bf215546Sopenharmony_ci } 1349bf215546Sopenharmony_ci } else { 1350bf215546Sopenharmony_ci for (i = 0; i < n; i++) { 1351bf215546Sopenharmony_ci dst[i] = rgba[i][RCOMP] + rgba[i][GCOMP] + rgba[i][BCOMP]; 1352bf215546Sopenharmony_ci } 1353bf215546Sopenharmony_ci } 1354bf215546Sopenharmony_ci return; 1355bf215546Sopenharmony_ci case GL_LUMINANCE_ALPHA: 1356bf215546Sopenharmony_ci if (transferOps & IMAGE_CLAMP_BIT) { 1357bf215546Sopenharmony_ci for (i = 0; i < n; i++) { 1358bf215546Sopenharmony_ci GLfloat sum = rgba[i][RCOMP] + rgba[i][GCOMP] + rgba[i][BCOMP]; 1359bf215546Sopenharmony_ci dst[2*i] = CLAMP(sum, 0.0F, 1.0F); 1360bf215546Sopenharmony_ci dst[2*i+1] = rgba[i][ACOMP]; 1361bf215546Sopenharmony_ci } 1362bf215546Sopenharmony_ci } else { 1363bf215546Sopenharmony_ci for (i = 0; i < n; i++) { 1364bf215546Sopenharmony_ci dst[2*i] = rgba[i][RCOMP] + rgba[i][GCOMP] + rgba[i][BCOMP]; 1365bf215546Sopenharmony_ci dst[2*i+1] = rgba[i][ACOMP]; 1366bf215546Sopenharmony_ci } 1367bf215546Sopenharmony_ci } 1368bf215546Sopenharmony_ci return; 1369bf215546Sopenharmony_ci default: 1370bf215546Sopenharmony_ci assert(!"Unsupported format"); 1371bf215546Sopenharmony_ci } 1372bf215546Sopenharmony_ci} 1373bf215546Sopenharmony_ci 1374bf215546Sopenharmony_cistatic int32_t 1375bf215546Sopenharmony_ciclamp_sint64_to_sint32(int64_t src) 1376bf215546Sopenharmony_ci{ 1377bf215546Sopenharmony_ci return CLAMP(src, INT32_MIN, INT32_MAX); 1378bf215546Sopenharmony_ci} 1379bf215546Sopenharmony_ci 1380bf215546Sopenharmony_cistatic int32_t 1381bf215546Sopenharmony_ciclamp_sint64_to_uint32(int64_t src) 1382bf215546Sopenharmony_ci{ 1383bf215546Sopenharmony_ci return CLAMP(src, 0, UINT32_MAX); 1384bf215546Sopenharmony_ci} 1385bf215546Sopenharmony_ci 1386bf215546Sopenharmony_cistatic int32_t 1387bf215546Sopenharmony_ciclamp_uint64_to_uint32(uint64_t src) 1388bf215546Sopenharmony_ci{ 1389bf215546Sopenharmony_ci return MIN2(src, UINT32_MAX); 1390bf215546Sopenharmony_ci} 1391bf215546Sopenharmony_ci 1392bf215546Sopenharmony_cistatic int32_t 1393bf215546Sopenharmony_ciclamp_uint64_to_sint32(uint64_t src) 1394bf215546Sopenharmony_ci{ 1395bf215546Sopenharmony_ci return MIN2(src, INT32_MAX); 1396bf215546Sopenharmony_ci} 1397bf215546Sopenharmony_ci 1398bf215546Sopenharmony_cistatic int32_t 1399bf215546Sopenharmony_ciconvert_integer_luminance64(int64_t src64, int bits, 1400bf215546Sopenharmony_ci bool dst_is_signed, bool src_is_signed) 1401bf215546Sopenharmony_ci{ 1402bf215546Sopenharmony_ci int32_t src32; 1403bf215546Sopenharmony_ci 1404bf215546Sopenharmony_ci /* Clamp Luminance value from 64-bit to 32-bit. Consider if we need 1405bf215546Sopenharmony_ci * any signed<->unsigned conversion too. 1406bf215546Sopenharmony_ci */ 1407bf215546Sopenharmony_ci if (src_is_signed && dst_is_signed) 1408bf215546Sopenharmony_ci src32 = clamp_sint64_to_sint32(src64); 1409bf215546Sopenharmony_ci else if (src_is_signed && !dst_is_signed) 1410bf215546Sopenharmony_ci src32 = clamp_sint64_to_uint32(src64); 1411bf215546Sopenharmony_ci else if (!src_is_signed && dst_is_signed) 1412bf215546Sopenharmony_ci src32 = clamp_uint64_to_sint32(src64); 1413bf215546Sopenharmony_ci else 1414bf215546Sopenharmony_ci src32 = clamp_uint64_to_uint32(src64); 1415bf215546Sopenharmony_ci 1416bf215546Sopenharmony_ci /* If the dst type is < 32-bit, we need an extra clamp */ 1417bf215546Sopenharmony_ci if (bits == 32) { 1418bf215546Sopenharmony_ci return src32; 1419bf215546Sopenharmony_ci } else { 1420bf215546Sopenharmony_ci if (dst_is_signed) 1421bf215546Sopenharmony_ci return _mesa_signed_to_signed(src32, bits); 1422bf215546Sopenharmony_ci else 1423bf215546Sopenharmony_ci return _mesa_unsigned_to_unsigned(src32, bits); 1424bf215546Sopenharmony_ci } 1425bf215546Sopenharmony_ci} 1426bf215546Sopenharmony_ci 1427bf215546Sopenharmony_cistatic int32_t 1428bf215546Sopenharmony_ciconvert_integer(int32_t src, int bits, bool dst_is_signed, bool src_is_signed) 1429bf215546Sopenharmony_ci{ 1430bf215546Sopenharmony_ci if (src_is_signed && dst_is_signed) 1431bf215546Sopenharmony_ci return _mesa_signed_to_signed(src, bits); 1432bf215546Sopenharmony_ci else if (src_is_signed && !dst_is_signed) 1433bf215546Sopenharmony_ci return _mesa_signed_to_unsigned(src, bits); 1434bf215546Sopenharmony_ci else if (!src_is_signed && dst_is_signed) 1435bf215546Sopenharmony_ci return _mesa_unsigned_to_signed(src, bits); 1436bf215546Sopenharmony_ci else 1437bf215546Sopenharmony_ci return _mesa_unsigned_to_unsigned(src, bits); 1438bf215546Sopenharmony_ci} 1439bf215546Sopenharmony_ci 1440bf215546Sopenharmony_civoid 1441bf215546Sopenharmony_ci_mesa_pack_luminance_from_rgba_integer(GLuint n, 1442bf215546Sopenharmony_ci GLuint rgba[][4], bool rgba_is_signed, 1443bf215546Sopenharmony_ci GLvoid *dstAddr, 1444bf215546Sopenharmony_ci GLenum dst_format, 1445bf215546Sopenharmony_ci GLenum dst_type) 1446bf215546Sopenharmony_ci{ 1447bf215546Sopenharmony_ci int i; 1448bf215546Sopenharmony_ci int64_t lum64; 1449bf215546Sopenharmony_ci int32_t lum32, alpha; 1450bf215546Sopenharmony_ci bool dst_is_signed; 1451bf215546Sopenharmony_ci int dst_bits; 1452bf215546Sopenharmony_ci 1453bf215546Sopenharmony_ci assert(dst_format == GL_LUMINANCE_INTEGER_EXT || 1454bf215546Sopenharmony_ci dst_format == GL_LUMINANCE_ALPHA_INTEGER_EXT); 1455bf215546Sopenharmony_ci 1456bf215546Sopenharmony_ci /* We first compute luminance values as a 64-bit addition of the 1457bf215546Sopenharmony_ci * 32-bit R,G,B components, then we clamp the result to the dst type size. 1458bf215546Sopenharmony_ci * 1459bf215546Sopenharmony_ci * Notice that this operation involves casting the 32-bit R,G,B components 1460bf215546Sopenharmony_ci * to 64-bit before the addition. Since rgba is defined as a GLuint array 1461bf215546Sopenharmony_ci * we need to be careful when rgba packs signed data and make sure 1462bf215546Sopenharmony_ci * that we cast to a 32-bit signed integer values before casting them to 1463bf215546Sopenharmony_ci * 64-bit signed integers. 1464bf215546Sopenharmony_ci */ 1465bf215546Sopenharmony_ci dst_is_signed = (dst_type == GL_BYTE || dst_type == GL_SHORT || 1466bf215546Sopenharmony_ci dst_type == GL_INT); 1467bf215546Sopenharmony_ci 1468bf215546Sopenharmony_ci dst_bits = _mesa_sizeof_type(dst_type) * 8; 1469bf215546Sopenharmony_ci assert(dst_bits > 0); 1470bf215546Sopenharmony_ci 1471bf215546Sopenharmony_ci switch (dst_format) { 1472bf215546Sopenharmony_ci case GL_LUMINANCE_INTEGER_EXT: 1473bf215546Sopenharmony_ci for (i = 0; i < n; i++) { 1474bf215546Sopenharmony_ci if (!rgba_is_signed) { 1475bf215546Sopenharmony_ci lum64 = (uint64_t) rgba[i][RCOMP] + 1476bf215546Sopenharmony_ci (uint64_t) rgba[i][GCOMP] + 1477bf215546Sopenharmony_ci (uint64_t) rgba[i][BCOMP]; 1478bf215546Sopenharmony_ci } else { 1479bf215546Sopenharmony_ci lum64 = (int64_t) ((int32_t) rgba[i][RCOMP]) + 1480bf215546Sopenharmony_ci (int64_t) ((int32_t) rgba[i][GCOMP]) + 1481bf215546Sopenharmony_ci (int64_t) ((int32_t) rgba[i][BCOMP]); 1482bf215546Sopenharmony_ci } 1483bf215546Sopenharmony_ci lum32 = convert_integer_luminance64(lum64, dst_bits, 1484bf215546Sopenharmony_ci dst_is_signed, rgba_is_signed); 1485bf215546Sopenharmony_ci switch (dst_type) { 1486bf215546Sopenharmony_ci case GL_BYTE: 1487bf215546Sopenharmony_ci case GL_UNSIGNED_BYTE: { 1488bf215546Sopenharmony_ci GLbyte *dst = (GLbyte *) dstAddr; 1489bf215546Sopenharmony_ci dst[i] = lum32; 1490bf215546Sopenharmony_ci break; 1491bf215546Sopenharmony_ci } 1492bf215546Sopenharmony_ci case GL_SHORT: 1493bf215546Sopenharmony_ci case GL_UNSIGNED_SHORT: { 1494bf215546Sopenharmony_ci GLshort *dst = (GLshort *) dstAddr; 1495bf215546Sopenharmony_ci dst[i] = lum32; 1496bf215546Sopenharmony_ci break; 1497bf215546Sopenharmony_ci } 1498bf215546Sopenharmony_ci case GL_INT: 1499bf215546Sopenharmony_ci case GL_UNSIGNED_INT: { 1500bf215546Sopenharmony_ci GLint *dst = (GLint *) dstAddr; 1501bf215546Sopenharmony_ci dst[i] = lum32; 1502bf215546Sopenharmony_ci break; 1503bf215546Sopenharmony_ci } 1504bf215546Sopenharmony_ci } 1505bf215546Sopenharmony_ci } 1506bf215546Sopenharmony_ci return; 1507bf215546Sopenharmony_ci case GL_LUMINANCE_ALPHA_INTEGER_EXT: 1508bf215546Sopenharmony_ci for (i = 0; i < n; i++) { 1509bf215546Sopenharmony_ci if (!rgba_is_signed) { 1510bf215546Sopenharmony_ci lum64 = (uint64_t) rgba[i][RCOMP] + 1511bf215546Sopenharmony_ci (uint64_t) rgba[i][GCOMP] + 1512bf215546Sopenharmony_ci (uint64_t) rgba[i][BCOMP]; 1513bf215546Sopenharmony_ci } else { 1514bf215546Sopenharmony_ci lum64 = (int64_t) ((int32_t) rgba[i][RCOMP]) + 1515bf215546Sopenharmony_ci (int64_t) ((int32_t) rgba[i][GCOMP]) + 1516bf215546Sopenharmony_ci (int64_t) ((int32_t) rgba[i][BCOMP]); 1517bf215546Sopenharmony_ci } 1518bf215546Sopenharmony_ci lum32 = convert_integer_luminance64(lum64, dst_bits, 1519bf215546Sopenharmony_ci dst_is_signed, rgba_is_signed); 1520bf215546Sopenharmony_ci alpha = convert_integer(rgba[i][ACOMP], dst_bits, 1521bf215546Sopenharmony_ci dst_is_signed, rgba_is_signed); 1522bf215546Sopenharmony_ci switch (dst_type) { 1523bf215546Sopenharmony_ci case GL_BYTE: 1524bf215546Sopenharmony_ci case GL_UNSIGNED_BYTE: { 1525bf215546Sopenharmony_ci GLbyte *dst = (GLbyte *) dstAddr; 1526bf215546Sopenharmony_ci dst[2*i] = lum32; 1527bf215546Sopenharmony_ci dst[2*i+1] = alpha; 1528bf215546Sopenharmony_ci break; 1529bf215546Sopenharmony_ci } 1530bf215546Sopenharmony_ci case GL_SHORT: 1531bf215546Sopenharmony_ci case GL_UNSIGNED_SHORT: { 1532bf215546Sopenharmony_ci GLshort *dst = (GLshort *) dstAddr; 1533bf215546Sopenharmony_ci dst[i] = lum32; 1534bf215546Sopenharmony_ci dst[2*i+1] = alpha; 1535bf215546Sopenharmony_ci break; 1536bf215546Sopenharmony_ci } 1537bf215546Sopenharmony_ci case GL_INT: 1538bf215546Sopenharmony_ci case GL_UNSIGNED_INT: { 1539bf215546Sopenharmony_ci GLint *dst = (GLint *) dstAddr; 1540bf215546Sopenharmony_ci dst[i] = lum32; 1541bf215546Sopenharmony_ci dst[2*i+1] = alpha; 1542bf215546Sopenharmony_ci break; 1543bf215546Sopenharmony_ci } 1544bf215546Sopenharmony_ci } 1545bf215546Sopenharmony_ci } 1546bf215546Sopenharmony_ci return; 1547bf215546Sopenharmony_ci } 1548bf215546Sopenharmony_ci} 1549bf215546Sopenharmony_ci 1550bf215546Sopenharmony_ciGLfloat * 1551bf215546Sopenharmony_ci_mesa_unpack_color_index_to_rgba_float(struct gl_context *ctx, GLuint dims, 1552bf215546Sopenharmony_ci const void *src, GLenum srcFormat, GLenum srcType, 1553bf215546Sopenharmony_ci int srcWidth, int srcHeight, int srcDepth, 1554bf215546Sopenharmony_ci const struct gl_pixelstore_attrib *srcPacking, 1555bf215546Sopenharmony_ci GLbitfield transferOps) 1556bf215546Sopenharmony_ci{ 1557bf215546Sopenharmony_ci int count, img; 1558bf215546Sopenharmony_ci GLuint *indexes; 1559bf215546Sopenharmony_ci GLfloat *rgba, *dstPtr; 1560bf215546Sopenharmony_ci 1561bf215546Sopenharmony_ci count = srcWidth * srcHeight; 1562bf215546Sopenharmony_ci indexes = malloc(count * sizeof(GLuint)); 1563bf215546Sopenharmony_ci if (!indexes) { 1564bf215546Sopenharmony_ci _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking"); 1565bf215546Sopenharmony_ci return NULL; 1566bf215546Sopenharmony_ci } 1567bf215546Sopenharmony_ci 1568bf215546Sopenharmony_ci rgba = malloc(4 * count * srcDepth * sizeof(GLfloat)); 1569bf215546Sopenharmony_ci if (!rgba) { 1570bf215546Sopenharmony_ci free(indexes); 1571bf215546Sopenharmony_ci _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking"); 1572bf215546Sopenharmony_ci return NULL; 1573bf215546Sopenharmony_ci } 1574bf215546Sopenharmony_ci 1575bf215546Sopenharmony_ci /* Convert indexes to RGBA float */ 1576bf215546Sopenharmony_ci dstPtr = rgba; 1577bf215546Sopenharmony_ci for (img = 0; img < srcDepth; img++) { 1578bf215546Sopenharmony_ci const GLubyte *srcPtr = 1579bf215546Sopenharmony_ci (const GLubyte *) _mesa_image_address(dims, srcPacking, src, 1580bf215546Sopenharmony_ci srcWidth, srcHeight, 1581bf215546Sopenharmony_ci srcFormat, srcType, 1582bf215546Sopenharmony_ci img, 0, 0); 1583bf215546Sopenharmony_ci 1584bf215546Sopenharmony_ci extract_uint_indexes(count, indexes, srcFormat, srcType, srcPtr, srcPacking); 1585bf215546Sopenharmony_ci 1586bf215546Sopenharmony_ci if (transferOps & IMAGE_SHIFT_OFFSET_BIT) 1587bf215546Sopenharmony_ci _mesa_shift_and_offset_ci(ctx, count, indexes); 1588bf215546Sopenharmony_ci 1589bf215546Sopenharmony_ci _mesa_map_ci_to_rgba(ctx, count, indexes, (float (*)[4])dstPtr); 1590bf215546Sopenharmony_ci 1591bf215546Sopenharmony_ci /* Don't do RGBA scale/bias or RGBA->RGBA mapping if starting 1592bf215546Sopenharmony_ci * with color indexes. 1593bf215546Sopenharmony_ci */ 1594bf215546Sopenharmony_ci transferOps &= ~(IMAGE_SCALE_BIAS_BIT | IMAGE_MAP_COLOR_BIT); 1595bf215546Sopenharmony_ci _mesa_apply_rgba_transfer_ops(ctx, transferOps, count, (float (*)[4])dstPtr); 1596bf215546Sopenharmony_ci 1597bf215546Sopenharmony_ci dstPtr += srcHeight * srcWidth * 4; 1598bf215546Sopenharmony_ci } 1599bf215546Sopenharmony_ci 1600bf215546Sopenharmony_ci free(indexes); 1601bf215546Sopenharmony_ci 1602bf215546Sopenharmony_ci return rgba; 1603bf215546Sopenharmony_ci} 1604bf215546Sopenharmony_ci 1605bf215546Sopenharmony_ciGLubyte * 1606bf215546Sopenharmony_ci_mesa_unpack_color_index_to_rgba_ubyte(struct gl_context *ctx, GLuint dims, 1607bf215546Sopenharmony_ci const void *src, GLenum srcFormat, GLenum srcType, 1608bf215546Sopenharmony_ci int srcWidth, int srcHeight, int srcDepth, 1609bf215546Sopenharmony_ci const struct gl_pixelstore_attrib *srcPacking, 1610bf215546Sopenharmony_ci GLbitfield transferOps) 1611bf215546Sopenharmony_ci{ 1612bf215546Sopenharmony_ci GLfloat *rgba; 1613bf215546Sopenharmony_ci GLubyte *dst; 1614bf215546Sopenharmony_ci int count, i; 1615bf215546Sopenharmony_ci 1616bf215546Sopenharmony_ci transferOps |= IMAGE_CLAMP_BIT; 1617bf215546Sopenharmony_ci rgba = _mesa_unpack_color_index_to_rgba_float(ctx, dims, 1618bf215546Sopenharmony_ci src, srcFormat, srcType, 1619bf215546Sopenharmony_ci srcWidth, srcHeight, srcDepth, 1620bf215546Sopenharmony_ci srcPacking, transferOps); 1621bf215546Sopenharmony_ci 1622bf215546Sopenharmony_ci count = srcWidth * srcHeight * srcDepth; 1623bf215546Sopenharmony_ci dst = malloc(count * 4 * sizeof(GLubyte)); 1624bf215546Sopenharmony_ci for (i = 0; i < count; i++) { 1625bf215546Sopenharmony_ci CLAMPED_FLOAT_TO_UBYTE(dst[i * 4 + 0], rgba[i * 4 + 0]); 1626bf215546Sopenharmony_ci CLAMPED_FLOAT_TO_UBYTE(dst[i * 4 + 1], rgba[i * 4 + 1]); 1627bf215546Sopenharmony_ci CLAMPED_FLOAT_TO_UBYTE(dst[i * 4 + 2], rgba[i * 4 + 2]); 1628bf215546Sopenharmony_ci CLAMPED_FLOAT_TO_UBYTE(dst[i * 4 + 3], rgba[i * 4 + 3]); 1629bf215546Sopenharmony_ci } 1630bf215546Sopenharmony_ci 1631bf215546Sopenharmony_ci free(rgba); 1632bf215546Sopenharmony_ci 1633bf215546Sopenharmony_ci return dst; 1634bf215546Sopenharmony_ci} 1635bf215546Sopenharmony_ci 1636bf215546Sopenharmony_civoid 1637bf215546Sopenharmony_ci_mesa_unpack_ubyte_rgba_row(mesa_format format, uint32_t n, 1638bf215546Sopenharmony_ci const void *src, uint8_t dst[][4]) 1639bf215546Sopenharmony_ci{ 1640bf215546Sopenharmony_ci const struct util_format_unpack_description *unpack = 1641bf215546Sopenharmony_ci util_format_unpack_description((enum pipe_format)format); 1642bf215546Sopenharmony_ci 1643bf215546Sopenharmony_ci if (unpack->unpack_rgba_8unorm) { 1644bf215546Sopenharmony_ci unpack->unpack_rgba_8unorm((uint8_t *)dst, src, n); 1645bf215546Sopenharmony_ci } else { 1646bf215546Sopenharmony_ci /* get float values, convert to ubyte */ 1647bf215546Sopenharmony_ci { 1648bf215546Sopenharmony_ci float *tmp = malloc(n * 4 * sizeof(float)); 1649bf215546Sopenharmony_ci if (tmp) { 1650bf215546Sopenharmony_ci uint32_t i; 1651bf215546Sopenharmony_ci _mesa_unpack_rgba_row(format, n, src, (float (*)[4]) tmp); 1652bf215546Sopenharmony_ci for (i = 0; i < n; i++) { 1653bf215546Sopenharmony_ci dst[i][0] = _mesa_float_to_unorm(tmp[i*4+0], 8); 1654bf215546Sopenharmony_ci dst[i][1] = _mesa_float_to_unorm(tmp[i*4+1], 8); 1655bf215546Sopenharmony_ci dst[i][2] = _mesa_float_to_unorm(tmp[i*4+2], 8); 1656bf215546Sopenharmony_ci dst[i][3] = _mesa_float_to_unorm(tmp[i*4+3], 8); 1657bf215546Sopenharmony_ci } 1658bf215546Sopenharmony_ci free(tmp); 1659bf215546Sopenharmony_ci } 1660bf215546Sopenharmony_ci } 1661bf215546Sopenharmony_ci } 1662bf215546Sopenharmony_ci} 1663bf215546Sopenharmony_ci 1664bf215546Sopenharmony_ci/** Helper struct for MESA_FORMAT_Z32_FLOAT_S8X24_UINT */ 1665bf215546Sopenharmony_cistruct z32f_x24s8 1666bf215546Sopenharmony_ci{ 1667bf215546Sopenharmony_ci float z; 1668bf215546Sopenharmony_ci uint32_t x24s8; 1669bf215546Sopenharmony_ci}; 1670bf215546Sopenharmony_ci 1671bf215546Sopenharmony_ci 1672bf215546Sopenharmony_cistatic void 1673bf215546Sopenharmony_ciunpack_uint_24_8_depth_stencil_Z24_UNORM_S8_UINT(const uint32_t *src, uint32_t *dst, uint32_t n) 1674bf215546Sopenharmony_ci{ 1675bf215546Sopenharmony_ci uint32_t i; 1676bf215546Sopenharmony_ci 1677bf215546Sopenharmony_ci for (i = 0; i < n; i++) { 1678bf215546Sopenharmony_ci uint32_t val = src[i]; 1679bf215546Sopenharmony_ci dst[i] = val >> 24 | val << 8; 1680bf215546Sopenharmony_ci } 1681bf215546Sopenharmony_ci} 1682bf215546Sopenharmony_ci 1683bf215546Sopenharmony_cistatic void 1684bf215546Sopenharmony_ciunpack_uint_24_8_depth_stencil_Z32_S8X24(const uint32_t *src, 1685bf215546Sopenharmony_ci uint32_t *dst, uint32_t n) 1686bf215546Sopenharmony_ci{ 1687bf215546Sopenharmony_ci uint32_t i; 1688bf215546Sopenharmony_ci 1689bf215546Sopenharmony_ci for (i = 0; i < n; i++) { 1690bf215546Sopenharmony_ci /* 8 bytes per pixel (float + uint32) */ 1691bf215546Sopenharmony_ci float zf = ((float *) src)[i * 2 + 0]; 1692bf215546Sopenharmony_ci uint32_t z24 = (uint32_t) (zf * (float) 0xffffff); 1693bf215546Sopenharmony_ci uint32_t s = src[i * 2 + 1] & 0xff; 1694bf215546Sopenharmony_ci dst[i] = (z24 << 8) | s; 1695bf215546Sopenharmony_ci } 1696bf215546Sopenharmony_ci} 1697bf215546Sopenharmony_ci 1698bf215546Sopenharmony_cistatic void 1699bf215546Sopenharmony_ciunpack_uint_24_8_depth_stencil_S8_UINT_Z24_UNORM(const uint32_t *src, uint32_t *dst, uint32_t n) 1700bf215546Sopenharmony_ci{ 1701bf215546Sopenharmony_ci memcpy(dst, src, n * 4); 1702bf215546Sopenharmony_ci} 1703bf215546Sopenharmony_ci 1704bf215546Sopenharmony_ci/** 1705bf215546Sopenharmony_ci * Unpack depth/stencil returning as GL_UNSIGNED_INT_24_8. 1706bf215546Sopenharmony_ci * \param format the source data format 1707bf215546Sopenharmony_ci */ 1708bf215546Sopenharmony_civoid 1709bf215546Sopenharmony_ci_mesa_unpack_uint_24_8_depth_stencil_row(mesa_format format, uint32_t n, 1710bf215546Sopenharmony_ci const void *src, uint32_t *dst) 1711bf215546Sopenharmony_ci{ 1712bf215546Sopenharmony_ci switch (format) { 1713bf215546Sopenharmony_ci case MESA_FORMAT_S8_UINT_Z24_UNORM: 1714bf215546Sopenharmony_ci unpack_uint_24_8_depth_stencil_S8_UINT_Z24_UNORM(src, dst, n); 1715bf215546Sopenharmony_ci break; 1716bf215546Sopenharmony_ci case MESA_FORMAT_Z24_UNORM_S8_UINT: 1717bf215546Sopenharmony_ci unpack_uint_24_8_depth_stencil_Z24_UNORM_S8_UINT(src, dst, n); 1718bf215546Sopenharmony_ci break; 1719bf215546Sopenharmony_ci case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: 1720bf215546Sopenharmony_ci unpack_uint_24_8_depth_stencil_Z32_S8X24(src, dst, n); 1721bf215546Sopenharmony_ci break; 1722bf215546Sopenharmony_ci default: 1723bf215546Sopenharmony_ci unreachable("bad format %s in _mesa_unpack_uint_24_8_depth_stencil_row"); 1724bf215546Sopenharmony_ci } 1725bf215546Sopenharmony_ci} 1726bf215546Sopenharmony_ci 1727bf215546Sopenharmony_cistatic void 1728bf215546Sopenharmony_ciunpack_float_32_uint_24_8_Z24_UNORM_S8_UINT(const uint32_t *src, 1729bf215546Sopenharmony_ci uint32_t *dst, uint32_t n) 1730bf215546Sopenharmony_ci{ 1731bf215546Sopenharmony_ci uint32_t i; 1732bf215546Sopenharmony_ci struct z32f_x24s8 *d = (struct z32f_x24s8 *) dst; 1733bf215546Sopenharmony_ci const double scale = 1.0 / (double) 0xffffff; 1734bf215546Sopenharmony_ci 1735bf215546Sopenharmony_ci for (i = 0; i < n; i++) { 1736bf215546Sopenharmony_ci const uint32_t z24 = src[i] & 0xffffff; 1737bf215546Sopenharmony_ci d[i].z = z24 * scale; 1738bf215546Sopenharmony_ci d[i].x24s8 = src[i] >> 24; 1739bf215546Sopenharmony_ci assert(d[i].z >= 0.0f); 1740bf215546Sopenharmony_ci assert(d[i].z <= 1.0f); 1741bf215546Sopenharmony_ci } 1742bf215546Sopenharmony_ci} 1743bf215546Sopenharmony_ci 1744bf215546Sopenharmony_cistatic void 1745bf215546Sopenharmony_ciunpack_float_32_uint_24_8_Z32_FLOAT_S8X24_UINT(const uint32_t *src, 1746bf215546Sopenharmony_ci uint32_t *dst, uint32_t n) 1747bf215546Sopenharmony_ci{ 1748bf215546Sopenharmony_ci memcpy(dst, src, n * sizeof(struct z32f_x24s8)); 1749bf215546Sopenharmony_ci} 1750bf215546Sopenharmony_ci 1751bf215546Sopenharmony_cistatic void 1752bf215546Sopenharmony_ciunpack_float_32_uint_24_8_S8_UINT_Z24_UNORM(const uint32_t *src, 1753bf215546Sopenharmony_ci uint32_t *dst, uint32_t n) 1754bf215546Sopenharmony_ci{ 1755bf215546Sopenharmony_ci uint32_t i; 1756bf215546Sopenharmony_ci struct z32f_x24s8 *d = (struct z32f_x24s8 *) dst; 1757bf215546Sopenharmony_ci const double scale = 1.0 / (double) 0xffffff; 1758bf215546Sopenharmony_ci 1759bf215546Sopenharmony_ci for (i = 0; i < n; i++) { 1760bf215546Sopenharmony_ci const uint32_t z24 = src[i] >> 8; 1761bf215546Sopenharmony_ci d[i].z = z24 * scale; 1762bf215546Sopenharmony_ci d[i].x24s8 = src[i] & 0xff; 1763bf215546Sopenharmony_ci assert(d[i].z >= 0.0f); 1764bf215546Sopenharmony_ci assert(d[i].z <= 1.0f); 1765bf215546Sopenharmony_ci } 1766bf215546Sopenharmony_ci} 1767bf215546Sopenharmony_ci 1768bf215546Sopenharmony_ci/** 1769bf215546Sopenharmony_ci * Unpack depth/stencil returning as GL_FLOAT_32_UNSIGNED_INT_24_8_REV. 1770bf215546Sopenharmony_ci * \param format the source data format 1771bf215546Sopenharmony_ci * 1772bf215546Sopenharmony_ci * In GL_FLOAT_32_UNSIGNED_INT_24_8_REV lower 4 bytes contain float 1773bf215546Sopenharmony_ci * component and higher 4 bytes contain packed 24-bit and 8-bit 1774bf215546Sopenharmony_ci * components. 1775bf215546Sopenharmony_ci * 1776bf215546Sopenharmony_ci * 31 30 29 28 ... 4 3 2 1 0 31 30 29 ... 9 8 7 6 5 ... 2 1 0 1777bf215546Sopenharmony_ci * +-------------------------+ +--------------------------------+ 1778bf215546Sopenharmony_ci * | Float Component | | Unused | 8 bit stencil | 1779bf215546Sopenharmony_ci * +-------------------------+ +--------------------------------+ 1780bf215546Sopenharmony_ci * lower 4 bytes higher 4 bytes 1781bf215546Sopenharmony_ci */ 1782bf215546Sopenharmony_civoid 1783bf215546Sopenharmony_ci_mesa_unpack_float_32_uint_24_8_depth_stencil_row(mesa_format format, uint32_t n, 1784bf215546Sopenharmony_ci const void *src, uint32_t *dst) 1785bf215546Sopenharmony_ci{ 1786bf215546Sopenharmony_ci switch (format) { 1787bf215546Sopenharmony_ci case MESA_FORMAT_S8_UINT_Z24_UNORM: 1788bf215546Sopenharmony_ci unpack_float_32_uint_24_8_S8_UINT_Z24_UNORM(src, dst, n); 1789bf215546Sopenharmony_ci break; 1790bf215546Sopenharmony_ci case MESA_FORMAT_Z24_UNORM_S8_UINT: 1791bf215546Sopenharmony_ci unpack_float_32_uint_24_8_Z24_UNORM_S8_UINT(src, dst, n); 1792bf215546Sopenharmony_ci break; 1793bf215546Sopenharmony_ci case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: 1794bf215546Sopenharmony_ci unpack_float_32_uint_24_8_Z32_FLOAT_S8X24_UINT(src, dst, n); 1795bf215546Sopenharmony_ci break; 1796bf215546Sopenharmony_ci default: 1797bf215546Sopenharmony_ci unreachable("bad format %s in _mesa_unpack_uint_24_8_depth_stencil_row"); 1798bf215546Sopenharmony_ci } 1799bf215546Sopenharmony_ci} 1800