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