1from __future__ import print_function 2 3from mako.template import Template 4from sys import argv 5 6string = """/* 7 * Mesa 3-D graphics library 8 * 9 * Copyright (c) 2011 VMware, Inc. 10 * Copyright (c) 2014 Intel Corporation. 11 * 12 * Permission is hereby granted, free of charge, to any person obtaining a 13 * copy of this software and associated documentation files (the "Software"), 14 * to deal in the Software without restriction, including without limitation 15 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 16 * and/or sell copies of the Software, and to permit persons to whom the 17 * Software is furnished to do so, subject to the following conditions: 18 * 19 * The above copyright notice and this permission notice shall be included 20 * in all copies or substantial portions of the Software. 21 * 22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 23 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 25 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 26 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 27 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 28 * OTHER DEALINGS IN THE SOFTWARE. 29 */ 30 31 32/** 33 * Color, depth, stencil packing functions. 34 * Used to pack basic color, depth and stencil formats to specific 35 * hardware formats. 36 * 37 * There are both per-pixel and per-row packing functions: 38 * - The former will be used by swrast to write values to the color, depth, 39 * stencil buffers when drawing points, lines and masked spans. 40 * - The later will be used for image-oriented functions like glDrawPixels, 41 * glAccum, and glTexImage. 42 */ 43 44#include <stdint.h> 45 46#include "errors.h" 47#include "format_unpack.h" 48#include "format_utils.h" 49#include "macros.h" 50#include "util/format_rgb9e5.h" 51#include "util/format_r11g11b10f.h" 52#include "util/format_srgb.h" 53 54#define UNPACK(SRC, OFFSET, BITS) (((SRC) >> (OFFSET)) & MAX_UINT(BITS)) 55 56<% 57import format_parser as parser 58 59formats = parser.parse(argv[1]) 60 61rgb_formats = [] 62for f in formats: 63 if f.name == 'MESA_FORMAT_NONE': 64 continue 65 if f.colorspace not in ('rgb', 'srgb'): 66 continue 67 68 rgb_formats.append(f) 69%> 70 71/* float unpacking functions */ 72 73%for f in rgb_formats: 74 %if f.name in ('MESA_FORMAT_R9G9B9E5_FLOAT', 'MESA_FORMAT_R11G11B10_FLOAT'): 75 <% continue %> 76 %elif f.is_int() and not f.is_normalized(): 77 <% continue %> 78 %elif f.is_compressed(): 79 <% continue %> 80 %endif 81 82static inline void 83unpack_float_${f.short_name()}(const void *void_src, GLfloat dst[4]) 84{ 85 ${f.datatype()} *src = (${f.datatype()} *)void_src; 86 %if f.layout == parser.PACKED: 87 %for c in f.channels: 88 %if c.type != 'x': 89 ${c.datatype()} ${c.name} = UNPACK(*src, ${c.shift}, ${c.size}); 90 %endif 91 %endfor 92 %elif f.layout == parser.ARRAY: 93 %for (i, c) in enumerate(f.channels): 94 %if c.type != 'x': 95 ${c.datatype()} ${c.name} = src[${i}]; 96 %endif 97 %endfor 98 %else: 99 <% assert False %> 100 %endif 101 102 %for i in range(4): 103 <% s = f.swizzle[i] %> 104 %if 0 <= s and s <= parser.Swizzle.SWIZZLE_W: 105 <% c = f.channels[s] %> 106 %if c.type == parser.UNSIGNED: 107 %if f.colorspace == 'srgb' and c.name in 'rgb': 108 <% assert c.size == 8 %> 109 dst[${i}] = util_format_srgb_8unorm_to_linear_float(${c.name}); 110 %else: 111 dst[${i}] = _mesa_unorm_to_float(${c.name}, ${c.size}); 112 %endif 113 %elif c.type == parser.SIGNED: 114 dst[${i}] = _mesa_snorm_to_float(${c.name}, ${c.size}); 115 %elif c.type == parser.FLOAT: 116 %if c.size == 32: 117 dst[${i}] = ${c.name}; 118 %elif c.size == 16: 119 dst[${i}] = _mesa_half_to_float(${c.name}); 120 %else: 121 <% assert False %> 122 %endif 123 %else: 124 <% assert False %> 125 %endif 126 %elif s == parser.Swizzle.SWIZZLE_ZERO: 127 dst[${i}] = 0.0f; 128 %elif s == parser.Swizzle.SWIZZLE_ONE: 129 dst[${i}] = 1.0f; 130 %else: 131 <% assert False %> 132 %endif 133 %endfor 134} 135%endfor 136 137static void 138unpack_float_r9g9b9e5_float(const void *src, GLfloat dst[4]) 139{ 140 rgb9e5_to_float3(*(const GLuint *)src, dst); 141 dst[3] = 1.0f; 142} 143 144static void 145unpack_float_r11g11b10_float(const void *src, GLfloat dst[4]) 146{ 147 r11g11b10f_to_float3(*(const GLuint *)src, dst); 148 dst[3] = 1.0f; 149} 150 151static void 152unpack_float_ycbcr(const void *src, GLfloat dst[][4], GLuint n) 153{ 154 GLuint i; 155 for (i = 0; i < n; i++) { 156 const GLushort *src0 = ((const GLushort *) src) + i * 2; /* even */ 157 const GLushort *src1 = src0 + 1; /* odd */ 158 const GLubyte y0 = (*src0 >> 8) & 0xff; /* luminance */ 159 const GLubyte cb = *src0 & 0xff; /* chroma U */ 160 const GLubyte y1 = (*src1 >> 8) & 0xff; /* luminance */ 161 const GLubyte cr = *src1 & 0xff; /* chroma V */ 162 const GLubyte y = (i & 1) ? y1 : y0; /* choose even/odd luminance */ 163 GLfloat r = 1.164F * (y - 16) + 1.596F * (cr - 128); 164 GLfloat g = 1.164F * (y - 16) - 0.813F * (cr - 128) - 0.391F * (cb - 128); 165 GLfloat b = 1.164F * (y - 16) + 2.018F * (cb - 128); 166 r *= (1.0F / 255.0F); 167 g *= (1.0F / 255.0F); 168 b *= (1.0F / 255.0F); 169 dst[i][0] = CLAMP(r, 0.0F, 1.0F); 170 dst[i][1] = CLAMP(g, 0.0F, 1.0F); 171 dst[i][2] = CLAMP(b, 0.0F, 1.0F); 172 dst[i][3] = 1.0F; 173 } 174} 175 176static void 177unpack_float_ycbcr_rev(const void *src, GLfloat dst[][4], GLuint n) 178{ 179 GLuint i; 180 for (i = 0; i < n; i++) { 181 const GLushort *src0 = ((const GLushort *) src) + i * 2; /* even */ 182 const GLushort *src1 = src0 + 1; /* odd */ 183 const GLubyte y0 = *src0 & 0xff; /* luminance */ 184 const GLubyte cr = (*src0 >> 8) & 0xff; /* chroma V */ 185 const GLubyte y1 = *src1 & 0xff; /* luminance */ 186 const GLubyte cb = (*src1 >> 8) & 0xff; /* chroma U */ 187 const GLubyte y = (i & 1) ? y1 : y0; /* choose even/odd luminance */ 188 GLfloat r = 1.164F * (y - 16) + 1.596F * (cr - 128); 189 GLfloat g = 1.164F * (y - 16) - 0.813F * (cr - 128) - 0.391F * (cb - 128); 190 GLfloat b = 1.164F * (y - 16) + 2.018F * (cb - 128); 191 r *= (1.0F / 255.0F); 192 g *= (1.0F / 255.0F); 193 b *= (1.0F / 255.0F); 194 dst[i][0] = CLAMP(r, 0.0F, 1.0F); 195 dst[i][1] = CLAMP(g, 0.0F, 1.0F); 196 dst[i][2] = CLAMP(b, 0.0F, 1.0F); 197 dst[i][3] = 1.0F; 198 } 199} 200 201/* ubyte packing functions */ 202 203%for f in rgb_formats: 204 %if not f.is_normalized(): 205 <% continue %> 206 %endif 207 208static inline void 209unpack_ubyte_${f.short_name()}(const void *void_src, GLubyte dst[4]) 210{ 211 ${f.datatype()} *src = (${f.datatype()} *)void_src; 212 %if f.layout == parser.PACKED: 213 %for c in f.channels: 214 %if c.type != 'x': 215 ${c.datatype()} ${c.name} = UNPACK(*src, ${c.shift}, ${c.size}); 216 %endif 217 %endfor 218 %elif f.layout == parser.ARRAY: 219 %for (i, c) in enumerate(f.channels): 220 %if c.type != 'x': 221 ${c.datatype()} ${c.name} = src[${i}]; 222 %endif 223 %endfor 224 %else: 225 <% assert False %> 226 %endif 227 228 %for i in range(4): 229 <% s = f.swizzle[i] %> 230 %if 0 <= s and s <= parser.Swizzle.SWIZZLE_W: 231 <% c = f.channels[s] %> 232 %if c.type == parser.UNSIGNED: 233 %if f.colorspace == 'srgb' and c.name in 'rgb': 234 <% assert c.size == 8 %> 235 dst[${i}] = util_format_srgb_to_linear_8unorm(${c.name}); 236 %else: 237 dst[${i}] = _mesa_unorm_to_unorm(${c.name}, ${c.size}, 8); 238 %endif 239 %elif c.type == parser.SIGNED: 240 dst[${i}] = _mesa_snorm_to_unorm(${c.name}, ${c.size}, 8); 241 %elif c.type == parser.FLOAT: 242 %if c.size == 32: 243 dst[${i}] = _mesa_float_to_unorm(${c.name}, 8); 244 %elif c.size == 16: 245 dst[${i}] = _mesa_half_to_unorm(${c.name}, 8); 246 %else: 247 <% assert False %> 248 %endif 249 %else: 250 <% assert False %> 251 %endif 252 %elif s == parser.Swizzle.SWIZZLE_ZERO: 253 dst[${i}] = 0; 254 %elif s == parser.Swizzle.SWIZZLE_ONE: 255 dst[${i}] = 255; 256 %else: 257 <% assert False %> 258 %endif 259 %endfor 260} 261%endfor 262 263/* integer packing functions */ 264 265%for f in rgb_formats: 266 %if not f.is_int(): 267 <% continue %> 268 %elif f.is_normalized(): 269 <% continue %> 270 %endif 271 272static inline void 273unpack_int_${f.short_name()}(const void *void_src, GLuint dst[4]) 274{ 275 ${f.datatype()} *src = (${f.datatype()} *)void_src; 276 %if f.layout == parser.PACKED: 277 %for c in f.channels: 278 %if c.type != 'x': 279 ${c.datatype()} ${c.name} = UNPACK(*src, ${c.shift}, ${c.size}); 280 %endif 281 %endfor 282 %elif f.layout == parser.ARRAY: 283 %for (i, c) in enumerate(f.channels): 284 %if c.type != 'x': 285 ${c.datatype()} ${c.name} = src[${i}]; 286 %endif 287 %endfor 288 %else: 289 <% assert False %> 290 %endif 291 292 %for i in range(4): 293 <% s = f.swizzle[i] %> 294 %if 0 <= s and s <= parser.Swizzle.SWIZZLE_W: 295 dst[${i}] = ${f.channels[s].name}; 296 %elif s == parser.Swizzle.SWIZZLE_ZERO: 297 dst[${i}] = 0; 298 %elif s == parser.Swizzle.SWIZZLE_ONE: 299 dst[${i}] = 1; 300 %else: 301 <% assert False %> 302 %endif 303 %endfor 304} 305%endfor 306 307 308void 309_mesa_unpack_rgba_row(mesa_format format, GLuint n, 310 const void *src, GLfloat dst[][4]) 311{ 312 GLubyte *s = (GLubyte *)src; 313 GLuint i; 314 315 switch (format) { 316%for f in rgb_formats: 317 %if f.is_compressed(): 318 <% continue %> 319 %elif f.is_int() and not f.is_normalized(): 320 <% continue %> 321 %endif 322 case ${f.name}: 323 for (i = 0; i < n; ++i) { 324 unpack_float_${f.short_name()}(s, dst[i]); 325 s += ${f.block_size() // 8}; 326 } 327 break; 328%endfor 329 case MESA_FORMAT_YCBCR: 330 unpack_float_ycbcr(src, dst, n); 331 break; 332 case MESA_FORMAT_YCBCR_REV: 333 unpack_float_ycbcr_rev(src, dst, n); 334 break; 335 default: 336 _mesa_problem(NULL, "%s: bad format %s", __func__, 337 _mesa_get_format_name(format)); 338 return; 339 } 340} 341 342void 343_mesa_unpack_ubyte_rgba_row(mesa_format format, GLuint n, 344 const void *src, GLubyte dst[][4]) 345{ 346 GLubyte *s = (GLubyte *)src; 347 GLuint i; 348 349 switch (format) { 350%for f in rgb_formats: 351 %if not f.is_normalized(): 352 <% continue %> 353 %endif 354 355 case ${f.name}: 356 for (i = 0; i < n; ++i) { 357 unpack_ubyte_${f.short_name()}(s, dst[i]); 358 s += ${f.block_size() // 8}; 359 } 360 break; 361%endfor 362 default: 363 /* get float values, convert to ubyte */ 364 { 365 GLfloat *tmp = malloc(n * 4 * sizeof(GLfloat)); 366 if (tmp) { 367 GLuint i; 368 _mesa_unpack_rgba_row(format, n, src, (GLfloat (*)[4]) tmp); 369 for (i = 0; i < n; i++) { 370 dst[i][0] = _mesa_float_to_unorm(tmp[i*4+0], 8); 371 dst[i][1] = _mesa_float_to_unorm(tmp[i*4+1], 8); 372 dst[i][2] = _mesa_float_to_unorm(tmp[i*4+2], 8); 373 dst[i][3] = _mesa_float_to_unorm(tmp[i*4+3], 8); 374 } 375 free(tmp); 376 } 377 } 378 break; 379 } 380} 381 382void 383_mesa_unpack_uint_rgba_row(mesa_format format, GLuint n, 384 const void *src, GLuint dst[][4]) 385{ 386 GLubyte *s = (GLubyte *)src; 387 GLuint i; 388 389 switch (format) { 390%for f in rgb_formats: 391 %if not f.is_int(): 392 <% continue %> 393 %elif f.is_normalized(): 394 <% continue %> 395 %endif 396 397 case ${f.name}: 398 for (i = 0; i < n; ++i) { 399 unpack_int_${f.short_name()}(s, dst[i]); 400 s += ${f.block_size() // 8}; 401 } 402 break; 403%endfor 404 default: 405 _mesa_problem(NULL, "%s: bad format %s", __func__, 406 _mesa_get_format_name(format)); 407 return; 408 } 409} 410 411/** 412 * Unpack a 2D rect of pixels returning float RGBA colors. 413 * \param format the source image format 414 * \param src start address of the source image 415 * \param srcRowStride source image row stride in bytes 416 * \param dst start address of the dest image 417 * \param dstRowStride dest image row stride in bytes 418 * \param x source image start X pos 419 * \param y source image start Y pos 420 * \param width width of rect region to convert 421 * \param height height of rect region to convert 422 */ 423void 424_mesa_unpack_rgba_block(mesa_format format, 425 const void *src, GLint srcRowStride, 426 GLfloat dst[][4], GLint dstRowStride, 427 GLuint x, GLuint y, GLuint width, GLuint height) 428{ 429 const GLuint srcPixStride = _mesa_get_format_bytes(format); 430 const GLuint dstPixStride = 4 * sizeof(GLfloat); 431 const GLubyte *srcRow; 432 GLubyte *dstRow; 433 GLuint i; 434 435 /* XXX needs to be fixed for compressed formats */ 436 437 srcRow = ((const GLubyte *) src) + srcRowStride * y + srcPixStride * x; 438 dstRow = ((GLubyte *) dst) + dstRowStride * y + dstPixStride * x; 439 440 for (i = 0; i < height; i++) { 441 _mesa_unpack_rgba_row(format, width, srcRow, (GLfloat (*)[4]) dstRow); 442 443 dstRow += dstRowStride; 444 srcRow += srcRowStride; 445 } 446} 447 448/** Helper struct for MESA_FORMAT_Z32_FLOAT_S8X24_UINT */ 449struct z32f_x24s8 450{ 451 float z; 452 uint32_t x24s8; 453}; 454 455typedef void (*unpack_float_z_func)(GLuint n, const void *src, GLfloat *dst); 456 457static void 458unpack_float_z_X8_UINT_Z24_UNORM(GLuint n, const void *src, GLfloat *dst) 459{ 460 /* only return Z, not stencil data */ 461 const GLuint *s = ((const GLuint *) src); 462 const GLdouble scale = 1.0 / (GLdouble) 0xffffff; 463 GLuint i; 464 for (i = 0; i < n; i++) { 465 dst[i] = (GLfloat) ((s[i] >> 8) * scale); 466 assert(dst[i] >= 0.0F); 467 assert(dst[i] <= 1.0F); 468 } 469} 470 471static void 472unpack_float_z_Z24_UNORM_X8_UINT(GLuint n, const void *src, GLfloat *dst) 473{ 474 /* only return Z, not stencil data */ 475 const GLuint *s = ((const GLuint *) src); 476 const GLdouble scale = 1.0 / (GLdouble) 0xffffff; 477 GLuint i; 478 for (i = 0; i < n; i++) { 479 dst[i] = (GLfloat) ((s[i] & 0x00ffffff) * scale); 480 assert(dst[i] >= 0.0F); 481 assert(dst[i] <= 1.0F); 482 } 483} 484 485static void 486unpack_float_Z_UNORM16(GLuint n, const void *src, GLfloat *dst) 487{ 488 const GLushort *s = ((const GLushort *) src); 489 GLuint i; 490 for (i = 0; i < n; i++) { 491 dst[i] = s[i] * (1.0F / 65535.0F); 492 } 493} 494 495static void 496unpack_float_Z_UNORM32(GLuint n, const void *src, GLfloat *dst) 497{ 498 const GLuint *s = ((const GLuint *) src); 499 GLuint i; 500 for (i = 0; i < n; i++) { 501 dst[i] = s[i] * (1.0F / 0xffffffff); 502 } 503} 504 505static void 506unpack_float_Z_FLOAT32(GLuint n, const void *src, GLfloat *dst) 507{ 508 memcpy(dst, src, n * sizeof(float)); 509} 510 511static void 512unpack_float_z_Z32X24S8(GLuint n, const void *src, GLfloat *dst) 513{ 514 const struct z32f_x24s8 *s = (const struct z32f_x24s8 *) src; 515 GLuint i; 516 for (i = 0; i < n; i++) { 517 dst[i] = s[i].z; 518 } 519} 520 521 522 523/** 524 * Unpack Z values. 525 * The returned values will always be in the range [0.0, 1.0]. 526 */ 527void 528_mesa_unpack_float_z_row(mesa_format format, GLuint n, 529 const void *src, GLfloat *dst) 530{ 531 unpack_float_z_func unpack; 532 533 switch (format) { 534 case MESA_FORMAT_S8_UINT_Z24_UNORM: 535 case MESA_FORMAT_X8_UINT_Z24_UNORM: 536 unpack = unpack_float_z_X8_UINT_Z24_UNORM; 537 break; 538 case MESA_FORMAT_Z24_UNORM_S8_UINT: 539 case MESA_FORMAT_Z24_UNORM_X8_UINT: 540 unpack = unpack_float_z_Z24_UNORM_X8_UINT; 541 break; 542 case MESA_FORMAT_Z_UNORM16: 543 unpack = unpack_float_Z_UNORM16; 544 break; 545 case MESA_FORMAT_Z_UNORM32: 546 unpack = unpack_float_Z_UNORM32; 547 break; 548 case MESA_FORMAT_Z_FLOAT32: 549 unpack = unpack_float_Z_FLOAT32; 550 break; 551 case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: 552 unpack = unpack_float_z_Z32X24S8; 553 break; 554 default: 555 _mesa_problem(NULL, "bad format %s in _mesa_unpack_float_z_row", 556 _mesa_get_format_name(format)); 557 return; 558 } 559 560 unpack(n, src, dst); 561} 562 563 564 565typedef void (*unpack_uint_z_func)(const void *src, GLuint *dst, GLuint n); 566 567static void 568unpack_uint_z_X8_UINT_Z24_UNORM(const void *src, GLuint *dst, GLuint n) 569{ 570 /* only return Z, not stencil data */ 571 const GLuint *s = ((const GLuint *) src); 572 GLuint i; 573 for (i = 0; i < n; i++) { 574 dst[i] = (s[i] & 0xffffff00) | (s[i] >> 24); 575 } 576} 577 578static void 579unpack_uint_z_Z24_UNORM_X8_UINT(const void *src, GLuint *dst, GLuint n) 580{ 581 /* only return Z, not stencil data */ 582 const GLuint *s = ((const GLuint *) src); 583 GLuint i; 584 for (i = 0; i < n; i++) { 585 dst[i] = (s[i] << 8) | ((s[i] >> 16) & 0xff); 586 } 587} 588 589static void 590unpack_uint_Z_UNORM16(const void *src, GLuint *dst, GLuint n) 591{ 592 const GLushort *s = ((const GLushort *)src); 593 GLuint i; 594 for (i = 0; i < n; i++) { 595 dst[i] = (s[i] << 16) | s[i]; 596 } 597} 598 599static void 600unpack_uint_Z_UNORM32(const void *src, GLuint *dst, GLuint n) 601{ 602 memcpy(dst, src, n * sizeof(GLuint)); 603} 604 605static void 606unpack_uint_Z_FLOAT32(const void *src, GLuint *dst, GLuint n) 607{ 608 const float *s = (const float *)src; 609 GLuint i; 610 for (i = 0; i < n; i++) { 611 dst[i] = FLOAT_TO_UINT(CLAMP(s[i], 0.0F, 1.0F)); 612 } 613} 614 615static void 616unpack_uint_Z_FLOAT32_X24S8(const void *src, GLuint *dst, GLuint n) 617{ 618 const struct z32f_x24s8 *s = (const struct z32f_x24s8 *) src; 619 GLuint i; 620 621 for (i = 0; i < n; i++) { 622 dst[i] = FLOAT_TO_UINT(CLAMP(s[i].z, 0.0F, 1.0F)); 623 } 624} 625 626 627/** 628 * Unpack Z values. 629 * The returned values will always be in the range [0, 0xffffffff]. 630 */ 631void 632_mesa_unpack_uint_z_row(mesa_format format, GLuint n, 633 const void *src, GLuint *dst) 634{ 635 unpack_uint_z_func unpack; 636 const GLubyte *srcPtr = (GLubyte *) src; 637 638 switch (format) { 639 case MESA_FORMAT_S8_UINT_Z24_UNORM: 640 case MESA_FORMAT_X8_UINT_Z24_UNORM: 641 unpack = unpack_uint_z_X8_UINT_Z24_UNORM; 642 break; 643 case MESA_FORMAT_Z24_UNORM_S8_UINT: 644 case MESA_FORMAT_Z24_UNORM_X8_UINT: 645 unpack = unpack_uint_z_Z24_UNORM_X8_UINT; 646 break; 647 case MESA_FORMAT_Z_UNORM16: 648 unpack = unpack_uint_Z_UNORM16; 649 break; 650 case MESA_FORMAT_Z_UNORM32: 651 unpack = unpack_uint_Z_UNORM32; 652 break; 653 case MESA_FORMAT_Z_FLOAT32: 654 unpack = unpack_uint_Z_FLOAT32; 655 break; 656 case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: 657 unpack = unpack_uint_Z_FLOAT32_X24S8; 658 break; 659 default: 660 _mesa_problem(NULL, "bad format %s in _mesa_unpack_uint_z_row", 661 _mesa_get_format_name(format)); 662 return; 663 } 664 665 unpack(srcPtr, dst, n); 666} 667 668 669static void 670unpack_ubyte_s_S_UINT8(const void *src, GLubyte *dst, GLuint n) 671{ 672 memcpy(dst, src, n); 673} 674 675static void 676unpack_ubyte_s_S8_UINT_Z24_UNORM(const void *src, GLubyte *dst, GLuint n) 677{ 678 GLuint i; 679 const GLuint *src32 = src; 680 681 for (i = 0; i < n; i++) 682 dst[i] = src32[i] & 0xff; 683} 684 685static void 686unpack_ubyte_s_Z24_UNORM_S8_UINT(const void *src, GLubyte *dst, GLuint n) 687{ 688 GLuint i; 689 const GLuint *src32 = src; 690 691 for (i = 0; i < n; i++) 692 dst[i] = src32[i] >> 24; 693} 694 695static void 696unpack_ubyte_s_Z32_FLOAT_S8X24_UINT(const void *src, GLubyte *dst, GLuint n) 697{ 698 GLuint i; 699 const struct z32f_x24s8 *s = (const struct z32f_x24s8 *) src; 700 701 for (i = 0; i < n; i++) 702 dst[i] = s[i].x24s8 & 0xff; 703} 704 705void 706_mesa_unpack_ubyte_stencil_row(mesa_format format, GLuint n, 707 const void *src, GLubyte *dst) 708{ 709 switch (format) { 710 case MESA_FORMAT_S_UINT8: 711 unpack_ubyte_s_S_UINT8(src, dst, n); 712 break; 713 case MESA_FORMAT_S8_UINT_Z24_UNORM: 714 unpack_ubyte_s_S8_UINT_Z24_UNORM(src, dst, n); 715 break; 716 case MESA_FORMAT_Z24_UNORM_S8_UINT: 717 unpack_ubyte_s_Z24_UNORM_S8_UINT(src, dst, n); 718 break; 719 case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: 720 unpack_ubyte_s_Z32_FLOAT_S8X24_UINT(src, dst, n); 721 break; 722 default: 723 _mesa_problem(NULL, "bad format %s in _mesa_unpack_ubyte_s_row", 724 _mesa_get_format_name(format)); 725 return; 726 } 727} 728 729static void 730unpack_uint_24_8_depth_stencil_Z24_UNORM_S8_UINT(const GLuint *src, GLuint *dst, GLuint n) 731{ 732 GLuint i; 733 734 for (i = 0; i < n; i++) { 735 GLuint val = src[i]; 736 dst[i] = val >> 24 | val << 8; 737 } 738} 739 740static void 741unpack_uint_24_8_depth_stencil_Z32_S8X24(const GLuint *src, 742 GLuint *dst, GLuint n) 743{ 744 GLuint i; 745 746 for (i = 0; i < n; i++) { 747 /* 8 bytes per pixel (float + uint32) */ 748 GLfloat zf = ((GLfloat *) src)[i * 2 + 0]; 749 GLuint z24 = (GLuint) (zf * (GLfloat) 0xffffff); 750 GLuint s = src[i * 2 + 1] & 0xff; 751 dst[i] = (z24 << 8) | s; 752 } 753} 754 755static void 756unpack_uint_24_8_depth_stencil_S8_UINT_Z24_UNORM(const GLuint *src, GLuint *dst, GLuint n) 757{ 758 memcpy(dst, src, n * 4); 759} 760 761/** 762 * Unpack depth/stencil returning as GL_UNSIGNED_INT_24_8. 763 * \param format the source data format 764 */ 765void 766_mesa_unpack_uint_24_8_depth_stencil_row(mesa_format format, GLuint n, 767 const void *src, GLuint *dst) 768{ 769 switch (format) { 770 case MESA_FORMAT_S8_UINT_Z24_UNORM: 771 unpack_uint_24_8_depth_stencil_S8_UINT_Z24_UNORM(src, dst, n); 772 break; 773 case MESA_FORMAT_Z24_UNORM_S8_UINT: 774 unpack_uint_24_8_depth_stencil_Z24_UNORM_S8_UINT(src, dst, n); 775 break; 776 case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: 777 unpack_uint_24_8_depth_stencil_Z32_S8X24(src, dst, n); 778 break; 779 default: 780 _mesa_problem(NULL, 781 "bad format %s in _mesa_unpack_uint_24_8_depth_stencil_row", 782 _mesa_get_format_name(format)); 783 return; 784 } 785} 786 787static void 788unpack_float_32_uint_24_8_Z24_UNORM_S8_UINT(const GLuint *src, 789 GLuint *dst, GLuint n) 790{ 791 GLuint i; 792 struct z32f_x24s8 *d = (struct z32f_x24s8 *) dst; 793 const GLdouble scale = 1.0 / (GLdouble) 0xffffff; 794 795 for (i = 0; i < n; i++) { 796 const GLuint z24 = src[i] & 0xffffff; 797 d[i].z = z24 * scale; 798 d[i].x24s8 = src[i] >> 24; 799 assert(d[i].z >= 0.0f); 800 assert(d[i].z <= 1.0f); 801 } 802} 803 804static void 805unpack_float_32_uint_24_8_Z32_FLOAT_S8X24_UINT(const GLuint *src, 806 GLuint *dst, GLuint n) 807{ 808 memcpy(dst, src, n * sizeof(struct z32f_x24s8)); 809} 810 811static void 812unpack_float_32_uint_24_8_S8_UINT_Z24_UNORM(const GLuint *src, 813 GLuint *dst, GLuint n) 814{ 815 GLuint i; 816 struct z32f_x24s8 *d = (struct z32f_x24s8 *) dst; 817 const GLdouble scale = 1.0 / (GLdouble) 0xffffff; 818 819 for (i = 0; i < n; i++) { 820 const GLuint z24 = src[i] >> 8; 821 d[i].z = z24 * scale; 822 d[i].x24s8 = src[i] & 0xff; 823 assert(d[i].z >= 0.0f); 824 assert(d[i].z <= 1.0f); 825 } 826} 827 828/** 829 * Unpack depth/stencil returning as GL_FLOAT_32_UNSIGNED_INT_24_8_REV. 830 * \param format the source data format 831 * 832 * In GL_FLOAT_32_UNSIGNED_INT_24_8_REV lower 4 bytes contain float 833 * component and higher 4 bytes contain packed 24-bit and 8-bit 834 * components. 835 * 836 * 31 30 29 28 ... 4 3 2 1 0 31 30 29 ... 9 8 7 6 5 ... 2 1 0 837 * +-------------------------+ +--------------------------------+ 838 * | Float Component | | Unused | 8 bit stencil | 839 * +-------------------------+ +--------------------------------+ 840 * lower 4 bytes higher 4 bytes 841 */ 842void 843_mesa_unpack_float_32_uint_24_8_depth_stencil_row(mesa_format format, GLuint n, 844 const void *src, GLuint *dst) 845{ 846 switch (format) { 847 case MESA_FORMAT_S8_UINT_Z24_UNORM: 848 unpack_float_32_uint_24_8_S8_UINT_Z24_UNORM(src, dst, n); 849 break; 850 case MESA_FORMAT_Z24_UNORM_S8_UINT: 851 unpack_float_32_uint_24_8_Z24_UNORM_S8_UINT(src, dst, n); 852 break; 853 case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: 854 unpack_float_32_uint_24_8_Z32_FLOAT_S8X24_UINT(src, dst, n); 855 break; 856 default: 857 _mesa_problem(NULL, 858 "bad format %s in _mesa_unpack_uint_24_8_depth_stencil_row", 859 _mesa_get_format_name(format)); 860 return; 861 } 862} 863 864/** 865 * Unpack depth/stencil 866 * \param format the source data format 867 * \param type the destination data type 868 */ 869void 870_mesa_unpack_depth_stencil_row(mesa_format format, GLuint n, 871 const void *src, GLenum type, 872 GLuint *dst) 873{ 874 assert(type == GL_UNSIGNED_INT_24_8 || 875 type == GL_FLOAT_32_UNSIGNED_INT_24_8_REV); 876 877 switch (type) { 878 case GL_UNSIGNED_INT_24_8: 879 _mesa_unpack_uint_24_8_depth_stencil_row(format, n, src, dst); 880 break; 881 case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: 882 _mesa_unpack_float_32_uint_24_8_depth_stencil_row(format, n, src, dst); 883 break; 884 default: 885 _mesa_problem(NULL, 886 "bad type 0x%x in _mesa_unpack_depth_stencil_row", 887 type); 888 return; 889 } 890} 891""" 892 893template = Template(string, future_imports=['division']); 894 895print(template.render(argv = argv[0:])) 896