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