1b8e80941Smrgfrom __future__ import print_function 2b8e80941Smrg 3b8e80941Smrgfrom mako.template import Template 4b8e80941Smrgfrom sys import argv 5b8e80941Smrg 6b8e80941Smrgstring = """/* 7b8e80941Smrg * Mesa 3-D graphics library 8b8e80941Smrg * 9b8e80941Smrg * Copyright (c) 2011 VMware, Inc. 10b8e80941Smrg * Copyright (c) 2014 Intel Corporation. 11b8e80941Smrg * 12b8e80941Smrg * Permission is hereby granted, free of charge, to any person obtaining a 13b8e80941Smrg * copy of this software and associated documentation files (the "Software"), 14b8e80941Smrg * to deal in the Software without restriction, including without limitation 15b8e80941Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 16b8e80941Smrg * and/or sell copies of the Software, and to permit persons to whom the 17b8e80941Smrg * Software is furnished to do so, subject to the following conditions: 18b8e80941Smrg * 19b8e80941Smrg * The above copyright notice and this permission notice shall be included 20b8e80941Smrg * in all copies or substantial portions of the Software. 21b8e80941Smrg * 22b8e80941Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 23b8e80941Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24b8e80941Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 25b8e80941Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 26b8e80941Smrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 27b8e80941Smrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 28b8e80941Smrg * OTHER DEALINGS IN THE SOFTWARE. 29b8e80941Smrg */ 30b8e80941Smrg 31b8e80941Smrg 32b8e80941Smrg/** 33b8e80941Smrg * Color, depth, stencil packing functions. 34b8e80941Smrg * Used to pack basic color, depth and stencil formats to specific 35b8e80941Smrg * hardware formats. 36b8e80941Smrg * 37b8e80941Smrg * There are both per-pixel and per-row packing functions: 38b8e80941Smrg * - The former will be used by swrast to write values to the color, depth, 39b8e80941Smrg * stencil buffers when drawing points, lines and masked spans. 40b8e80941Smrg * - The later will be used for image-oriented functions like glDrawPixels, 41b8e80941Smrg * glAccum, and glTexImage. 42b8e80941Smrg */ 43b8e80941Smrg 44b8e80941Smrg#include <stdint.h> 45b8e80941Smrg 46b8e80941Smrg#include "config.h" 47b8e80941Smrg#include "errors.h" 48b8e80941Smrg#include "format_pack.h" 49b8e80941Smrg#include "format_utils.h" 50b8e80941Smrg#include "macros.h" 51b8e80941Smrg#include "util/format_rgb9e5.h" 52b8e80941Smrg#include "util/format_r11g11b10f.h" 53b8e80941Smrg#include "util/format_srgb.h" 54b8e80941Smrg 55b8e80941Smrg#define UNPACK(SRC, OFFSET, BITS) (((SRC) >> (OFFSET)) & MAX_UINT(BITS)) 56b8e80941Smrg#define PACK(SRC, OFFSET, BITS) (((SRC) & MAX_UINT(BITS)) << (OFFSET)) 57b8e80941Smrg 58b8e80941Smrg<% 59b8e80941Smrgimport format_parser as parser 60b8e80941Smrg 61b8e80941Smrgformats = parser.parse(argv[1]) 62b8e80941Smrg 63b8e80941Smrgrgb_formats = [] 64b8e80941Smrgfor f in formats: 65b8e80941Smrg if f.name == 'MESA_FORMAT_NONE': 66b8e80941Smrg continue 67b8e80941Smrg if f.colorspace not in ('rgb', 'srgb'): 68b8e80941Smrg continue 69b8e80941Smrg 70b8e80941Smrg rgb_formats.append(f) 71b8e80941Smrg%> 72b8e80941Smrg 73b8e80941Smrg/* ubyte packing functions */ 74b8e80941Smrg 75b8e80941Smrg%for f in rgb_formats: 76b8e80941Smrg %if f.name in ('MESA_FORMAT_R9G9B9E5_FLOAT', 'MESA_FORMAT_R11G11B10_FLOAT'): 77b8e80941Smrg <% continue %> 78b8e80941Smrg %elif f.is_compressed(): 79b8e80941Smrg <% continue %> 80b8e80941Smrg %endif 81b8e80941Smrg 82b8e80941Smrgstatic inline void 83b8e80941Smrgpack_ubyte_${f.short_name()}(const GLubyte src[4], void *dst) 84b8e80941Smrg{ 85b8e80941Smrg %for (i, c) in enumerate(f.channels): 86b8e80941Smrg <% i = f.swizzle.inverse()[i] %> 87b8e80941Smrg %if c.type == 'x': 88b8e80941Smrg <% continue %> 89b8e80941Smrg %endif 90b8e80941Smrg 91b8e80941Smrg ${c.datatype()} ${c.name} = 92b8e80941Smrg %if not f.is_normalized() and f.is_int(): 93b8e80941Smrg %if c.type == parser.SIGNED: 94b8e80941Smrg _mesa_unsigned_to_signed(src[${i}], ${c.size}); 95b8e80941Smrg %else: 96b8e80941Smrg _mesa_unsigned_to_unsigned(src[${i}], ${c.size}); 97b8e80941Smrg %endif 98b8e80941Smrg %elif c.type == parser.UNSIGNED: 99b8e80941Smrg %if f.colorspace == 'srgb' and c.name in 'rgb': 100b8e80941Smrg <% assert c.size == 8 %> 101b8e80941Smrg util_format_linear_to_srgb_8unorm(src[${i}]); 102b8e80941Smrg %else: 103b8e80941Smrg _mesa_unorm_to_unorm(src[${i}], 8, ${c.size}); 104b8e80941Smrg %endif 105b8e80941Smrg %elif c.type == parser.SIGNED: 106b8e80941Smrg _mesa_unorm_to_snorm(src[${i}], 8, ${c.size}); 107b8e80941Smrg %elif c.type == parser.FLOAT: 108b8e80941Smrg %if c.size == 32: 109b8e80941Smrg _mesa_unorm_to_float(src[${i}], 8); 110b8e80941Smrg %elif c.size == 16: 111b8e80941Smrg _mesa_unorm_to_half(src[${i}], 8); 112b8e80941Smrg %else: 113b8e80941Smrg <% assert False %> 114b8e80941Smrg %endif 115b8e80941Smrg %else: 116b8e80941Smrg <% assert False %> 117b8e80941Smrg %endif 118b8e80941Smrg %endfor 119b8e80941Smrg 120b8e80941Smrg %if f.layout == parser.ARRAY: 121b8e80941Smrg ${f.datatype()} *d = (${f.datatype()} *)dst; 122b8e80941Smrg %for (i, c) in enumerate(f.channels): 123b8e80941Smrg %if c.type == 'x': 124b8e80941Smrg <% continue %> 125b8e80941Smrg %endif 126b8e80941Smrg d[${i}] = ${c.name}; 127b8e80941Smrg %endfor 128b8e80941Smrg %elif f.layout == parser.PACKED: 129b8e80941Smrg ${f.datatype()} d = 0; 130b8e80941Smrg %for (i, c) in enumerate(f.channels): 131b8e80941Smrg %if c.type == 'x': 132b8e80941Smrg <% continue %> 133b8e80941Smrg %endif 134b8e80941Smrg d |= PACK(${c.name}, ${c.shift}, ${c.size}); 135b8e80941Smrg %endfor 136b8e80941Smrg (*(${f.datatype()} *)dst) = d; 137b8e80941Smrg %else: 138b8e80941Smrg <% assert False %> 139b8e80941Smrg %endif 140b8e80941Smrg} 141b8e80941Smrg%endfor 142b8e80941Smrg 143b8e80941Smrgstatic inline void 144b8e80941Smrgpack_ubyte_r9g9b9e5_float(const GLubyte src[4], void *dst) 145b8e80941Smrg{ 146b8e80941Smrg GLuint *d = (GLuint *) dst; 147b8e80941Smrg GLfloat rgb[3]; 148b8e80941Smrg rgb[0] = _mesa_unorm_to_float(src[RCOMP], 8); 149b8e80941Smrg rgb[1] = _mesa_unorm_to_float(src[GCOMP], 8); 150b8e80941Smrg rgb[2] = _mesa_unorm_to_float(src[BCOMP], 8); 151b8e80941Smrg *d = float3_to_rgb9e5(rgb); 152b8e80941Smrg} 153b8e80941Smrg 154b8e80941Smrgstatic inline void 155b8e80941Smrgpack_ubyte_r11g11b10_float(const GLubyte src[4], void *dst) 156b8e80941Smrg{ 157b8e80941Smrg GLuint *d = (GLuint *) dst; 158b8e80941Smrg GLfloat rgb[3]; 159b8e80941Smrg rgb[0] = _mesa_unorm_to_float(src[RCOMP], 8); 160b8e80941Smrg rgb[1] = _mesa_unorm_to_float(src[GCOMP], 8); 161b8e80941Smrg rgb[2] = _mesa_unorm_to_float(src[BCOMP], 8); 162b8e80941Smrg *d = float3_to_r11g11b10f(rgb); 163b8e80941Smrg} 164b8e80941Smrg 165b8e80941Smrg/* uint packing functions */ 166b8e80941Smrg 167b8e80941Smrg%for f in rgb_formats: 168b8e80941Smrg %if not f.is_int(): 169b8e80941Smrg <% continue %> 170b8e80941Smrg %elif f.is_normalized(): 171b8e80941Smrg <% continue %> 172b8e80941Smrg %elif f.is_compressed(): 173b8e80941Smrg <% continue %> 174b8e80941Smrg %endif 175b8e80941Smrg 176b8e80941Smrgstatic inline void 177b8e80941Smrgpack_uint_${f.short_name()}(const GLuint src[4], void *dst) 178b8e80941Smrg{ 179b8e80941Smrg %for (i, c) in enumerate(f.channels): 180b8e80941Smrg <% i = f.swizzle.inverse()[i] %> 181b8e80941Smrg %if c.type == 'x': 182b8e80941Smrg <% continue %> 183b8e80941Smrg %endif 184b8e80941Smrg 185b8e80941Smrg ${c.datatype()} ${c.name} = 186b8e80941Smrg %if c.type == parser.SIGNED: 187b8e80941Smrg _mesa_signed_to_signed(src[${i}], ${c.size}); 188b8e80941Smrg %elif c.type == parser.UNSIGNED: 189b8e80941Smrg _mesa_unsigned_to_unsigned(src[${i}], ${c.size}); 190b8e80941Smrg %else: 191b8e80941Smrg assert(!"Invalid type: only integer types are allowed"); 192b8e80941Smrg %endif 193b8e80941Smrg %endfor 194b8e80941Smrg 195b8e80941Smrg %if f.layout == parser.ARRAY: 196b8e80941Smrg ${f.datatype()} *d = (${f.datatype()} *)dst; 197b8e80941Smrg %for (i, c) in enumerate(f.channels): 198b8e80941Smrg %if c.type == 'x': 199b8e80941Smrg <% continue %> 200b8e80941Smrg %endif 201b8e80941Smrg d[${i}] = ${c.name}; 202b8e80941Smrg %endfor 203b8e80941Smrg %elif f.layout == parser.PACKED: 204b8e80941Smrg ${f.datatype()} d = 0; 205b8e80941Smrg %for (i, c) in enumerate(f.channels): 206b8e80941Smrg %if c.type == 'x': 207b8e80941Smrg <% continue %> 208b8e80941Smrg %endif 209b8e80941Smrg d |= PACK(${c.name}, ${c.shift}, ${c.size}); 210b8e80941Smrg %endfor 211b8e80941Smrg (*(${f.datatype()} *)dst) = d; 212b8e80941Smrg %else: 213b8e80941Smrg <% assert False %> 214b8e80941Smrg %endif 215b8e80941Smrg} 216b8e80941Smrg%endfor 217b8e80941Smrg 218b8e80941Smrg/* float packing functions */ 219b8e80941Smrg 220b8e80941Smrg%for f in rgb_formats: 221b8e80941Smrg %if f.name in ('MESA_FORMAT_R9G9B9E5_FLOAT', 'MESA_FORMAT_R11G11B10_FLOAT'): 222b8e80941Smrg <% continue %> 223b8e80941Smrg %elif f.is_int() and not f.is_normalized(): 224b8e80941Smrg <% continue %> 225b8e80941Smrg %elif f.is_compressed(): 226b8e80941Smrg <% continue %> 227b8e80941Smrg %endif 228b8e80941Smrg 229b8e80941Smrgstatic inline void 230b8e80941Smrgpack_float_${f.short_name()}(const GLfloat src[4], void *dst) 231b8e80941Smrg{ 232b8e80941Smrg %for (i, c) in enumerate(f.channels): 233b8e80941Smrg <% i = f.swizzle.inverse()[i] %> 234b8e80941Smrg %if c.type == 'x': 235b8e80941Smrg <% continue %> 236b8e80941Smrg %endif 237b8e80941Smrg 238b8e80941Smrg ${c.datatype()} ${c.name} = 239b8e80941Smrg %if c.type == parser.UNSIGNED: 240b8e80941Smrg %if f.colorspace == 'srgb' and c.name in 'rgb': 241b8e80941Smrg <% assert c.size == 8 %> 242b8e80941Smrg util_format_linear_float_to_srgb_8unorm(src[${i}]); 243b8e80941Smrg %else: 244b8e80941Smrg _mesa_float_to_unorm(src[${i}], ${c.size}); 245b8e80941Smrg %endif 246b8e80941Smrg %elif c.type == parser.SIGNED: 247b8e80941Smrg _mesa_float_to_snorm(src[${i}], ${c.size}); 248b8e80941Smrg %elif c.type == parser.FLOAT: 249b8e80941Smrg %if c.size == 32: 250b8e80941Smrg src[${i}]; 251b8e80941Smrg %elif c.size == 16: 252b8e80941Smrg _mesa_float_to_half(src[${i}]); 253b8e80941Smrg %else: 254b8e80941Smrg <% assert False %> 255b8e80941Smrg %endif 256b8e80941Smrg %else: 257b8e80941Smrg <% assert False %> 258b8e80941Smrg %endif 259b8e80941Smrg %endfor 260b8e80941Smrg 261b8e80941Smrg %if f.layout == parser.ARRAY: 262b8e80941Smrg ${f.datatype()} *d = (${f.datatype()} *)dst; 263b8e80941Smrg %for (i, c) in enumerate(f.channels): 264b8e80941Smrg %if c.type == 'x': 265b8e80941Smrg <% continue %> 266b8e80941Smrg %endif 267b8e80941Smrg d[${i}] = ${c.name}; 268b8e80941Smrg %endfor 269b8e80941Smrg %elif f.layout == parser.PACKED: 270b8e80941Smrg ${f.datatype()} d = 0; 271b8e80941Smrg %for (i, c) in enumerate(f.channels): 272b8e80941Smrg %if c.type == 'x': 273b8e80941Smrg <% continue %> 274b8e80941Smrg %endif 275b8e80941Smrg d |= PACK(${c.name}, ${c.shift}, ${c.size}); 276b8e80941Smrg %endfor 277b8e80941Smrg (*(${f.datatype()} *)dst) = d; 278b8e80941Smrg %else: 279b8e80941Smrg <% assert False %> 280b8e80941Smrg %endif 281b8e80941Smrg} 282b8e80941Smrg%endfor 283b8e80941Smrg 284b8e80941Smrgstatic inline void 285b8e80941Smrgpack_float_r9g9b9e5_float(const GLfloat src[4], void *dst) 286b8e80941Smrg{ 287b8e80941Smrg GLuint *d = (GLuint *) dst; 288b8e80941Smrg *d = float3_to_rgb9e5(src); 289b8e80941Smrg} 290b8e80941Smrg 291b8e80941Smrgstatic inline void 292b8e80941Smrgpack_float_r11g11b10_float(const GLfloat src[4], void *dst) 293b8e80941Smrg{ 294b8e80941Smrg GLuint *d = (GLuint *) dst; 295b8e80941Smrg *d = float3_to_r11g11b10f(src); 296b8e80941Smrg} 297b8e80941Smrg 298b8e80941Smrg/** 299b8e80941Smrg * Return a function that can pack a GLubyte rgba[4] color. 300b8e80941Smrg */ 301b8e80941Smrggl_pack_ubyte_rgba_func 302b8e80941Smrg_mesa_get_pack_ubyte_rgba_function(mesa_format format) 303b8e80941Smrg{ 304b8e80941Smrg switch (format) { 305b8e80941Smrg%for f in rgb_formats: 306b8e80941Smrg %if f.is_compressed(): 307b8e80941Smrg <% continue %> 308b8e80941Smrg %endif 309b8e80941Smrg 310b8e80941Smrg case ${f.name}: 311b8e80941Smrg return pack_ubyte_${f.short_name()}; 312b8e80941Smrg%endfor 313b8e80941Smrg default: 314b8e80941Smrg return NULL; 315b8e80941Smrg } 316b8e80941Smrg} 317b8e80941Smrg 318b8e80941Smrg/** 319b8e80941Smrg * Return a function that can pack a GLfloat rgba[4] color. 320b8e80941Smrg */ 321b8e80941Smrggl_pack_float_rgba_func 322b8e80941Smrg_mesa_get_pack_float_rgba_function(mesa_format format) 323b8e80941Smrg{ 324b8e80941Smrg switch (format) { 325b8e80941Smrg%for f in rgb_formats: 326b8e80941Smrg %if f.is_compressed(): 327b8e80941Smrg <% continue %> 328b8e80941Smrg %elif f.is_int() and not f.is_normalized(): 329b8e80941Smrg <% continue %> 330b8e80941Smrg %endif 331b8e80941Smrg 332b8e80941Smrg case ${f.name}: 333b8e80941Smrg return pack_float_${f.short_name()}; 334b8e80941Smrg%endfor 335b8e80941Smrg default: 336b8e80941Smrg return NULL; 337b8e80941Smrg } 338b8e80941Smrg} 339b8e80941Smrg 340b8e80941Smrg/** 341b8e80941Smrg * Pack a row of GLubyte rgba[4] values to the destination. 342b8e80941Smrg */ 343b8e80941Smrgvoid 344b8e80941Smrg_mesa_pack_ubyte_rgba_row(mesa_format format, GLuint n, 345b8e80941Smrg const GLubyte src[][4], void *dst) 346b8e80941Smrg{ 347b8e80941Smrg GLuint i; 348b8e80941Smrg GLubyte *d = dst; 349b8e80941Smrg 350b8e80941Smrg switch (format) { 351b8e80941Smrg%for f in rgb_formats: 352b8e80941Smrg %if f.is_compressed(): 353b8e80941Smrg <% continue %> 354b8e80941Smrg %endif 355b8e80941Smrg 356b8e80941Smrg case ${f.name}: 357b8e80941Smrg for (i = 0; i < n; ++i) { 358b8e80941Smrg pack_ubyte_${f.short_name()}(src[i], d); 359b8e80941Smrg d += ${f.block_size() // 8}; 360b8e80941Smrg } 361b8e80941Smrg break; 362b8e80941Smrg%endfor 363b8e80941Smrg default: 364b8e80941Smrg assert(!"Invalid format"); 365b8e80941Smrg } 366b8e80941Smrg} 367b8e80941Smrg 368b8e80941Smrg/** 369b8e80941Smrg * Pack a row of GLuint rgba[4] values to the destination. 370b8e80941Smrg */ 371b8e80941Smrgvoid 372b8e80941Smrg_mesa_pack_uint_rgba_row(mesa_format format, GLuint n, 373b8e80941Smrg const GLuint src[][4], void *dst) 374b8e80941Smrg{ 375b8e80941Smrg GLuint i; 376b8e80941Smrg GLubyte *d = dst; 377b8e80941Smrg 378b8e80941Smrg switch (format) { 379b8e80941Smrg%for f in rgb_formats: 380b8e80941Smrg %if not f.is_int(): 381b8e80941Smrg <% continue %> 382b8e80941Smrg %elif f.is_normalized(): 383b8e80941Smrg <% continue %> 384b8e80941Smrg %elif f.is_compressed(): 385b8e80941Smrg <% continue %> 386b8e80941Smrg %endif 387b8e80941Smrg 388b8e80941Smrg case ${f.name}: 389b8e80941Smrg for (i = 0; i < n; ++i) { 390b8e80941Smrg pack_uint_${f.short_name()}(src[i], d); 391b8e80941Smrg d += ${f.block_size() // 8}; 392b8e80941Smrg } 393b8e80941Smrg break; 394b8e80941Smrg%endfor 395b8e80941Smrg default: 396b8e80941Smrg assert(!"Invalid format"); 397b8e80941Smrg } 398b8e80941Smrg} 399b8e80941Smrg 400b8e80941Smrg/** 401b8e80941Smrg * Pack a row of GLfloat rgba[4] values to the destination. 402b8e80941Smrg */ 403b8e80941Smrgvoid 404b8e80941Smrg_mesa_pack_float_rgba_row(mesa_format format, GLuint n, 405b8e80941Smrg const GLfloat src[][4], void *dst) 406b8e80941Smrg{ 407b8e80941Smrg GLuint i; 408b8e80941Smrg GLubyte *d = dst; 409b8e80941Smrg 410b8e80941Smrg switch (format) { 411b8e80941Smrg%for f in rgb_formats: 412b8e80941Smrg %if f.is_compressed(): 413b8e80941Smrg <% continue %> 414b8e80941Smrg %elif f.is_int() and not f.is_normalized(): 415b8e80941Smrg <% continue %> 416b8e80941Smrg %endif 417b8e80941Smrg 418b8e80941Smrg case ${f.name}: 419b8e80941Smrg for (i = 0; i < n; ++i) { 420b8e80941Smrg pack_float_${f.short_name()}(src[i], d); 421b8e80941Smrg d += ${f.block_size() // 8}; 422b8e80941Smrg } 423b8e80941Smrg break; 424b8e80941Smrg%endfor 425b8e80941Smrg default: 426b8e80941Smrg assert(!"Invalid format"); 427b8e80941Smrg } 428b8e80941Smrg} 429b8e80941Smrg 430b8e80941Smrg/** 431b8e80941Smrg * Pack a 2D image of ubyte RGBA pixels in the given format. 432b8e80941Smrg * \param srcRowStride source image row stride in bytes 433b8e80941Smrg * \param dstRowStride destination image row stride in bytes 434b8e80941Smrg */ 435b8e80941Smrgvoid 436b8e80941Smrg_mesa_pack_ubyte_rgba_rect(mesa_format format, GLuint width, GLuint height, 437b8e80941Smrg const GLubyte *src, GLint srcRowStride, 438b8e80941Smrg void *dst, GLint dstRowStride) 439b8e80941Smrg{ 440b8e80941Smrg GLubyte *dstUB = dst; 441b8e80941Smrg GLuint i; 442b8e80941Smrg 443b8e80941Smrg if (srcRowStride == width * 4 * sizeof(GLubyte) && 444b8e80941Smrg dstRowStride == _mesa_format_row_stride(format, width)) { 445b8e80941Smrg /* do whole image at once */ 446b8e80941Smrg _mesa_pack_ubyte_rgba_row(format, width * height, 447b8e80941Smrg (const GLubyte (*)[4]) src, dst); 448b8e80941Smrg } 449b8e80941Smrg else { 450b8e80941Smrg /* row by row */ 451b8e80941Smrg for (i = 0; i < height; i++) { 452b8e80941Smrg _mesa_pack_ubyte_rgba_row(format, width, 453b8e80941Smrg (const GLubyte (*)[4]) src, dstUB); 454b8e80941Smrg src += srcRowStride; 455b8e80941Smrg dstUB += dstRowStride; 456b8e80941Smrg } 457b8e80941Smrg } 458b8e80941Smrg} 459b8e80941Smrg 460b8e80941Smrg 461b8e80941Smrg/** Helper struct for MESA_FORMAT_Z32_FLOAT_S8X24_UINT */ 462b8e80941Smrgstruct z32f_x24s8 463b8e80941Smrg{ 464b8e80941Smrg float z; 465b8e80941Smrg uint32_t x24s8; 466b8e80941Smrg}; 467b8e80941Smrg 468b8e80941Smrg 469b8e80941Smrg/** 470b8e80941Smrg ** Pack float Z pixels 471b8e80941Smrg **/ 472b8e80941Smrg 473b8e80941Smrgstatic void 474b8e80941Smrgpack_float_S8_UINT_Z24_UNORM(const GLfloat *src, void *dst) 475b8e80941Smrg{ 476b8e80941Smrg /* don't disturb the stencil values */ 477b8e80941Smrg GLuint *d = ((GLuint *) dst); 478b8e80941Smrg const GLdouble scale = (GLdouble) 0xffffff; 479b8e80941Smrg GLuint s = *d & 0xff; 480b8e80941Smrg GLuint z = (GLuint) (*src * scale); 481b8e80941Smrg assert(z <= 0xffffff); 482b8e80941Smrg *d = (z << 8) | s; 483b8e80941Smrg} 484b8e80941Smrg 485b8e80941Smrgstatic void 486b8e80941Smrgpack_float_Z24_UNORM_S8_UINT(const GLfloat *src, void *dst) 487b8e80941Smrg{ 488b8e80941Smrg /* don't disturb the stencil values */ 489b8e80941Smrg GLuint *d = ((GLuint *) dst); 490b8e80941Smrg const GLdouble scale = (GLdouble) 0xffffff; 491b8e80941Smrg GLuint s = *d & 0xff000000; 492b8e80941Smrg GLuint z = (GLuint) (*src * scale); 493b8e80941Smrg assert(z <= 0xffffff); 494b8e80941Smrg *d = s | z; 495b8e80941Smrg} 496b8e80941Smrg 497b8e80941Smrgstatic void 498b8e80941Smrgpack_float_Z_UNORM16(const GLfloat *src, void *dst) 499b8e80941Smrg{ 500b8e80941Smrg GLushort *d = ((GLushort *) dst); 501b8e80941Smrg const GLfloat scale = (GLfloat) 0xffff; 502b8e80941Smrg *d = (GLushort) (*src * scale); 503b8e80941Smrg} 504b8e80941Smrg 505b8e80941Smrgstatic void 506b8e80941Smrgpack_float_Z_UNORM32(const GLfloat *src, void *dst) 507b8e80941Smrg{ 508b8e80941Smrg GLuint *d = ((GLuint *) dst); 509b8e80941Smrg const GLdouble scale = (GLdouble) 0xffffffff; 510b8e80941Smrg *d = (GLuint) (*src * scale); 511b8e80941Smrg} 512b8e80941Smrg 513b8e80941Smrg/** 514b8e80941Smrg ** Pack float to Z_FLOAT32 or Z_FLOAT32_X24S8. 515b8e80941Smrg **/ 516b8e80941Smrg 517b8e80941Smrgstatic void 518b8e80941Smrgpack_float_Z_FLOAT32(const GLfloat *src, void *dst) 519b8e80941Smrg{ 520b8e80941Smrg GLfloat *d = (GLfloat *) dst; 521b8e80941Smrg *d = *src; 522b8e80941Smrg} 523b8e80941Smrg 524b8e80941Smrggl_pack_float_z_func 525b8e80941Smrg_mesa_get_pack_float_z_func(mesa_format format) 526b8e80941Smrg{ 527b8e80941Smrg switch (format) { 528b8e80941Smrg case MESA_FORMAT_S8_UINT_Z24_UNORM: 529b8e80941Smrg case MESA_FORMAT_X8_UINT_Z24_UNORM: 530b8e80941Smrg return pack_float_S8_UINT_Z24_UNORM; 531b8e80941Smrg case MESA_FORMAT_Z24_UNORM_S8_UINT: 532b8e80941Smrg case MESA_FORMAT_Z24_UNORM_X8_UINT: 533b8e80941Smrg return pack_float_Z24_UNORM_S8_UINT; 534b8e80941Smrg case MESA_FORMAT_Z_UNORM16: 535b8e80941Smrg return pack_float_Z_UNORM16; 536b8e80941Smrg case MESA_FORMAT_Z_UNORM32: 537b8e80941Smrg return pack_float_Z_UNORM32; 538b8e80941Smrg case MESA_FORMAT_Z_FLOAT32: 539b8e80941Smrg case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: 540b8e80941Smrg return pack_float_Z_FLOAT32; 541b8e80941Smrg default: 542b8e80941Smrg _mesa_problem(NULL, 543b8e80941Smrg "unexpected format in _mesa_get_pack_float_z_func()"); 544b8e80941Smrg return NULL; 545b8e80941Smrg } 546b8e80941Smrg} 547b8e80941Smrg 548b8e80941Smrg 549b8e80941Smrg 550b8e80941Smrg/** 551b8e80941Smrg ** Pack uint Z pixels. The incoming src value is always in 552b8e80941Smrg ** the range [0, 2^32-1]. 553b8e80941Smrg **/ 554b8e80941Smrg 555b8e80941Smrgstatic void 556b8e80941Smrgpack_uint_S8_UINT_Z24_UNORM(const GLuint *src, void *dst) 557b8e80941Smrg{ 558b8e80941Smrg /* don't disturb the stencil values */ 559b8e80941Smrg GLuint *d = ((GLuint *) dst); 560b8e80941Smrg GLuint s = *d & 0xff; 561b8e80941Smrg GLuint z = *src & 0xffffff00; 562b8e80941Smrg *d = z | s; 563b8e80941Smrg} 564b8e80941Smrg 565b8e80941Smrgstatic void 566b8e80941Smrgpack_uint_Z24_UNORM_S8_UINT(const GLuint *src, void *dst) 567b8e80941Smrg{ 568b8e80941Smrg /* don't disturb the stencil values */ 569b8e80941Smrg GLuint *d = ((GLuint *) dst); 570b8e80941Smrg GLuint s = *d & 0xff000000; 571b8e80941Smrg GLuint z = *src >> 8; 572b8e80941Smrg *d = s | z; 573b8e80941Smrg} 574b8e80941Smrg 575b8e80941Smrgstatic void 576b8e80941Smrgpack_uint_Z_UNORM16(const GLuint *src, void *dst) 577b8e80941Smrg{ 578b8e80941Smrg GLushort *d = ((GLushort *) dst); 579b8e80941Smrg *d = *src >> 16; 580b8e80941Smrg} 581b8e80941Smrg 582b8e80941Smrgstatic void 583b8e80941Smrgpack_uint_Z_UNORM32(const GLuint *src, void *dst) 584b8e80941Smrg{ 585b8e80941Smrg GLuint *d = ((GLuint *) dst); 586b8e80941Smrg *d = *src; 587b8e80941Smrg} 588b8e80941Smrg 589b8e80941Smrg/** 590b8e80941Smrg ** Pack uint to Z_FLOAT32 or Z_FLOAT32_X24S8. 591b8e80941Smrg **/ 592b8e80941Smrg 593b8e80941Smrgstatic void 594b8e80941Smrgpack_uint_Z_FLOAT32(const GLuint *src, void *dst) 595b8e80941Smrg{ 596b8e80941Smrg GLfloat *d = ((GLfloat *) dst); 597b8e80941Smrg const GLdouble scale = 1.0 / (GLdouble) 0xffffffff; 598b8e80941Smrg *d = (GLfloat) (*src * scale); 599b8e80941Smrg assert(*d >= 0.0f); 600b8e80941Smrg assert(*d <= 1.0f); 601b8e80941Smrg} 602b8e80941Smrg 603b8e80941Smrggl_pack_uint_z_func 604b8e80941Smrg_mesa_get_pack_uint_z_func(mesa_format format) 605b8e80941Smrg{ 606b8e80941Smrg switch (format) { 607b8e80941Smrg case MESA_FORMAT_S8_UINT_Z24_UNORM: 608b8e80941Smrg case MESA_FORMAT_X8_UINT_Z24_UNORM: 609b8e80941Smrg return pack_uint_S8_UINT_Z24_UNORM; 610b8e80941Smrg case MESA_FORMAT_Z24_UNORM_S8_UINT: 611b8e80941Smrg case MESA_FORMAT_Z24_UNORM_X8_UINT: 612b8e80941Smrg return pack_uint_Z24_UNORM_S8_UINT; 613b8e80941Smrg case MESA_FORMAT_Z_UNORM16: 614b8e80941Smrg return pack_uint_Z_UNORM16; 615b8e80941Smrg case MESA_FORMAT_Z_UNORM32: 616b8e80941Smrg return pack_uint_Z_UNORM32; 617b8e80941Smrg case MESA_FORMAT_Z_FLOAT32: 618b8e80941Smrg case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: 619b8e80941Smrg return pack_uint_Z_FLOAT32; 620b8e80941Smrg default: 621b8e80941Smrg _mesa_problem(NULL, "unexpected format in _mesa_get_pack_uint_z_func()"); 622b8e80941Smrg return NULL; 623b8e80941Smrg } 624b8e80941Smrg} 625b8e80941Smrg 626b8e80941Smrg 627b8e80941Smrg/** 628b8e80941Smrg ** Pack ubyte stencil pixels 629b8e80941Smrg **/ 630b8e80941Smrg 631b8e80941Smrgstatic void 632b8e80941Smrgpack_ubyte_stencil_Z24_S8(const GLubyte *src, void *dst) 633b8e80941Smrg{ 634b8e80941Smrg /* don't disturb the Z values */ 635b8e80941Smrg GLuint *d = ((GLuint *) dst); 636b8e80941Smrg GLuint s = *src; 637b8e80941Smrg GLuint z = *d & 0xffffff00; 638b8e80941Smrg *d = z | s; 639b8e80941Smrg} 640b8e80941Smrg 641b8e80941Smrgstatic void 642b8e80941Smrgpack_ubyte_stencil_S8_Z24(const GLubyte *src, void *dst) 643b8e80941Smrg{ 644b8e80941Smrg /* don't disturb the Z values */ 645b8e80941Smrg GLuint *d = ((GLuint *) dst); 646b8e80941Smrg GLuint s = *src << 24; 647b8e80941Smrg GLuint z = *d & 0xffffff; 648b8e80941Smrg *d = s | z; 649b8e80941Smrg} 650b8e80941Smrg 651b8e80941Smrgstatic void 652b8e80941Smrgpack_ubyte_stencil_S8(const GLubyte *src, void *dst) 653b8e80941Smrg{ 654b8e80941Smrg GLubyte *d = (GLubyte *) dst; 655b8e80941Smrg *d = *src; 656b8e80941Smrg} 657b8e80941Smrg 658b8e80941Smrgstatic void 659b8e80941Smrgpack_ubyte_stencil_Z32_FLOAT_X24S8(const GLubyte *src, void *dst) 660b8e80941Smrg{ 661b8e80941Smrg GLfloat *d = ((GLfloat *) dst); 662b8e80941Smrg d[1] = *src; 663b8e80941Smrg} 664b8e80941Smrg 665b8e80941Smrg 666b8e80941Smrggl_pack_ubyte_stencil_func 667b8e80941Smrg_mesa_get_pack_ubyte_stencil_func(mesa_format format) 668b8e80941Smrg{ 669b8e80941Smrg switch (format) { 670b8e80941Smrg case MESA_FORMAT_S8_UINT_Z24_UNORM: 671b8e80941Smrg return pack_ubyte_stencil_Z24_S8; 672b8e80941Smrg case MESA_FORMAT_Z24_UNORM_S8_UINT: 673b8e80941Smrg return pack_ubyte_stencil_S8_Z24; 674b8e80941Smrg case MESA_FORMAT_S_UINT8: 675b8e80941Smrg return pack_ubyte_stencil_S8; 676b8e80941Smrg case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: 677b8e80941Smrg return pack_ubyte_stencil_Z32_FLOAT_X24S8; 678b8e80941Smrg default: 679b8e80941Smrg _mesa_problem(NULL, 680b8e80941Smrg "unexpected format in _mesa_pack_ubyte_stencil_func()"); 681b8e80941Smrg return NULL; 682b8e80941Smrg } 683b8e80941Smrg} 684b8e80941Smrg 685b8e80941Smrg 686b8e80941Smrg 687b8e80941Smrgvoid 688b8e80941Smrg_mesa_pack_float_z_row(mesa_format format, GLuint n, 689b8e80941Smrg const GLfloat *src, void *dst) 690b8e80941Smrg{ 691b8e80941Smrg switch (format) { 692b8e80941Smrg case MESA_FORMAT_S8_UINT_Z24_UNORM: 693b8e80941Smrg case MESA_FORMAT_X8_UINT_Z24_UNORM: 694b8e80941Smrg { 695b8e80941Smrg /* don't disturb the stencil values */ 696b8e80941Smrg GLuint *d = ((GLuint *) dst); 697b8e80941Smrg const GLdouble scale = (GLdouble) 0xffffff; 698b8e80941Smrg GLuint i; 699b8e80941Smrg for (i = 0; i < n; i++) { 700b8e80941Smrg GLuint s = d[i] & 0xff; 701b8e80941Smrg GLuint z = (GLuint) (src[i] * scale); 702b8e80941Smrg assert(z <= 0xffffff); 703b8e80941Smrg d[i] = (z << 8) | s; 704b8e80941Smrg } 705b8e80941Smrg } 706b8e80941Smrg break; 707b8e80941Smrg case MESA_FORMAT_Z24_UNORM_S8_UINT: 708b8e80941Smrg case MESA_FORMAT_Z24_UNORM_X8_UINT: 709b8e80941Smrg { 710b8e80941Smrg /* don't disturb the stencil values */ 711b8e80941Smrg GLuint *d = ((GLuint *) dst); 712b8e80941Smrg const GLdouble scale = (GLdouble) 0xffffff; 713b8e80941Smrg GLuint i; 714b8e80941Smrg for (i = 0; i < n; i++) { 715b8e80941Smrg GLuint s = d[i] & 0xff000000; 716b8e80941Smrg GLuint z = (GLuint) (src[i] * scale); 717b8e80941Smrg assert(z <= 0xffffff); 718b8e80941Smrg d[i] = s | z; 719b8e80941Smrg } 720b8e80941Smrg } 721b8e80941Smrg break; 722b8e80941Smrg case MESA_FORMAT_Z_UNORM16: 723b8e80941Smrg { 724b8e80941Smrg GLushort *d = ((GLushort *) dst); 725b8e80941Smrg const GLfloat scale = (GLfloat) 0xffff; 726b8e80941Smrg GLuint i; 727b8e80941Smrg for (i = 0; i < n; i++) { 728b8e80941Smrg d[i] = (GLushort) (src[i] * scale); 729b8e80941Smrg } 730b8e80941Smrg } 731b8e80941Smrg break; 732b8e80941Smrg case MESA_FORMAT_Z_UNORM32: 733b8e80941Smrg { 734b8e80941Smrg GLuint *d = ((GLuint *) dst); 735b8e80941Smrg const GLdouble scale = (GLdouble) 0xffffffff; 736b8e80941Smrg GLuint i; 737b8e80941Smrg for (i = 0; i < n; i++) { 738b8e80941Smrg d[i] = (GLuint) (src[i] * scale); 739b8e80941Smrg } 740b8e80941Smrg } 741b8e80941Smrg break; 742b8e80941Smrg case MESA_FORMAT_Z_FLOAT32: 743b8e80941Smrg memcpy(dst, src, n * sizeof(GLfloat)); 744b8e80941Smrg break; 745b8e80941Smrg case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: 746b8e80941Smrg { 747b8e80941Smrg struct z32f_x24s8 *d = (struct z32f_x24s8 *) dst; 748b8e80941Smrg GLuint i; 749b8e80941Smrg for (i = 0; i < n; i++) { 750b8e80941Smrg d[i].z = src[i]; 751b8e80941Smrg } 752b8e80941Smrg } 753b8e80941Smrg break; 754b8e80941Smrg default: 755b8e80941Smrg _mesa_problem(NULL, "unexpected format in _mesa_pack_float_z_row()"); 756b8e80941Smrg } 757b8e80941Smrg} 758b8e80941Smrg 759b8e80941Smrg 760b8e80941Smrg/** 761b8e80941Smrg * The incoming Z values are always in the range [0, 0xffffffff]. 762b8e80941Smrg */ 763b8e80941Smrgvoid 764b8e80941Smrg_mesa_pack_uint_z_row(mesa_format format, GLuint n, 765b8e80941Smrg const GLuint *src, void *dst) 766b8e80941Smrg{ 767b8e80941Smrg switch (format) { 768b8e80941Smrg case MESA_FORMAT_S8_UINT_Z24_UNORM: 769b8e80941Smrg case MESA_FORMAT_X8_UINT_Z24_UNORM: 770b8e80941Smrg { 771b8e80941Smrg /* don't disturb the stencil values */ 772b8e80941Smrg GLuint *d = ((GLuint *) dst); 773b8e80941Smrg GLuint i; 774b8e80941Smrg for (i = 0; i < n; i++) { 775b8e80941Smrg GLuint s = d[i] & 0xff; 776b8e80941Smrg GLuint z = src[i] & 0xffffff00; 777b8e80941Smrg d[i] = z | s; 778b8e80941Smrg } 779b8e80941Smrg } 780b8e80941Smrg break; 781b8e80941Smrg case MESA_FORMAT_Z24_UNORM_S8_UINT: 782b8e80941Smrg case MESA_FORMAT_Z24_UNORM_X8_UINT: 783b8e80941Smrg { 784b8e80941Smrg /* don't disturb the stencil values */ 785b8e80941Smrg GLuint *d = ((GLuint *) dst); 786b8e80941Smrg GLuint i; 787b8e80941Smrg for (i = 0; i < n; i++) { 788b8e80941Smrg GLuint s = d[i] & 0xff000000; 789b8e80941Smrg GLuint z = src[i] >> 8; 790b8e80941Smrg d[i] = s | z; 791b8e80941Smrg } 792b8e80941Smrg } 793b8e80941Smrg break; 794b8e80941Smrg case MESA_FORMAT_Z_UNORM16: 795b8e80941Smrg { 796b8e80941Smrg GLushort *d = ((GLushort *) dst); 797b8e80941Smrg GLuint i; 798b8e80941Smrg for (i = 0; i < n; i++) { 799b8e80941Smrg d[i] = src[i] >> 16; 800b8e80941Smrg } 801b8e80941Smrg } 802b8e80941Smrg break; 803b8e80941Smrg case MESA_FORMAT_Z_UNORM32: 804b8e80941Smrg memcpy(dst, src, n * sizeof(GLfloat)); 805b8e80941Smrg break; 806b8e80941Smrg case MESA_FORMAT_Z_FLOAT32: 807b8e80941Smrg { 808b8e80941Smrg GLuint *d = ((GLuint *) dst); 809b8e80941Smrg const GLdouble scale = 1.0 / (GLdouble) 0xffffffff; 810b8e80941Smrg GLuint i; 811b8e80941Smrg for (i = 0; i < n; i++) { 812b8e80941Smrg d[i] = (GLuint) (src[i] * scale); 813b8e80941Smrg assert(d[i] >= 0.0f); 814b8e80941Smrg assert(d[i] <= 1.0f); 815b8e80941Smrg } 816b8e80941Smrg } 817b8e80941Smrg break; 818b8e80941Smrg case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: 819b8e80941Smrg { 820b8e80941Smrg struct z32f_x24s8 *d = (struct z32f_x24s8 *) dst; 821b8e80941Smrg const GLdouble scale = 1.0 / (GLdouble) 0xffffffff; 822b8e80941Smrg GLuint i; 823b8e80941Smrg for (i = 0; i < n; i++) { 824b8e80941Smrg d[i].z = (GLfloat) (src[i] * scale); 825b8e80941Smrg assert(d[i].z >= 0.0f); 826b8e80941Smrg assert(d[i].z <= 1.0f); 827b8e80941Smrg } 828b8e80941Smrg } 829b8e80941Smrg break; 830b8e80941Smrg default: 831b8e80941Smrg _mesa_problem(NULL, "unexpected format in _mesa_pack_uint_z_row()"); 832b8e80941Smrg } 833b8e80941Smrg} 834b8e80941Smrg 835b8e80941Smrg 836b8e80941Smrgvoid 837b8e80941Smrg_mesa_pack_ubyte_stencil_row(mesa_format format, GLuint n, 838b8e80941Smrg const GLubyte *src, void *dst) 839b8e80941Smrg{ 840b8e80941Smrg switch (format) { 841b8e80941Smrg case MESA_FORMAT_S8_UINT_Z24_UNORM: 842b8e80941Smrg { 843b8e80941Smrg /* don't disturb the Z values */ 844b8e80941Smrg GLuint *d = ((GLuint *) dst); 845b8e80941Smrg GLuint i; 846b8e80941Smrg for (i = 0; i < n; i++) { 847b8e80941Smrg GLuint s = src[i]; 848b8e80941Smrg GLuint z = d[i] & 0xffffff00; 849b8e80941Smrg d[i] = z | s; 850b8e80941Smrg } 851b8e80941Smrg } 852b8e80941Smrg break; 853b8e80941Smrg case MESA_FORMAT_Z24_UNORM_S8_UINT: 854b8e80941Smrg { 855b8e80941Smrg /* don't disturb the Z values */ 856b8e80941Smrg GLuint *d = ((GLuint *) dst); 857b8e80941Smrg GLuint i; 858b8e80941Smrg for (i = 0; i < n; i++) { 859b8e80941Smrg GLuint s = src[i] << 24; 860b8e80941Smrg GLuint z = d[i] & 0xffffff; 861b8e80941Smrg d[i] = s | z; 862b8e80941Smrg } 863b8e80941Smrg } 864b8e80941Smrg break; 865b8e80941Smrg case MESA_FORMAT_S_UINT8: 866b8e80941Smrg memcpy(dst, src, n * sizeof(GLubyte)); 867b8e80941Smrg break; 868b8e80941Smrg case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: 869b8e80941Smrg { 870b8e80941Smrg struct z32f_x24s8 *d = (struct z32f_x24s8 *) dst; 871b8e80941Smrg GLuint i; 872b8e80941Smrg for (i = 0; i < n; i++) { 873b8e80941Smrg d[i].x24s8 = src[i]; 874b8e80941Smrg } 875b8e80941Smrg } 876b8e80941Smrg break; 877b8e80941Smrg default: 878b8e80941Smrg _mesa_problem(NULL, "unexpected format in _mesa_pack_ubyte_stencil_row()"); 879b8e80941Smrg } 880b8e80941Smrg} 881b8e80941Smrg 882b8e80941Smrg 883b8e80941Smrg/** 884b8e80941Smrg * Incoming Z/stencil values are always in uint_24_8 format. 885b8e80941Smrg */ 886b8e80941Smrgvoid 887b8e80941Smrg_mesa_pack_uint_24_8_depth_stencil_row(mesa_format format, GLuint n, 888b8e80941Smrg const GLuint *src, void *dst) 889b8e80941Smrg{ 890b8e80941Smrg switch (format) { 891b8e80941Smrg case MESA_FORMAT_S8_UINT_Z24_UNORM: 892b8e80941Smrg memcpy(dst, src, n * sizeof(GLuint)); 893b8e80941Smrg break; 894b8e80941Smrg case MESA_FORMAT_Z24_UNORM_S8_UINT: 895b8e80941Smrg { 896b8e80941Smrg GLuint *d = ((GLuint *) dst); 897b8e80941Smrg GLuint i; 898b8e80941Smrg for (i = 0; i < n; i++) { 899b8e80941Smrg GLuint s = src[i] << 24; 900b8e80941Smrg GLuint z = src[i] >> 8; 901b8e80941Smrg d[i] = s | z; 902b8e80941Smrg } 903b8e80941Smrg } 904b8e80941Smrg break; 905b8e80941Smrg case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: 906b8e80941Smrg { 907b8e80941Smrg const GLdouble scale = 1.0 / (GLdouble) 0xffffff; 908b8e80941Smrg struct z32f_x24s8 *d = (struct z32f_x24s8 *) dst; 909b8e80941Smrg GLuint i; 910b8e80941Smrg for (i = 0; i < n; i++) { 911b8e80941Smrg GLfloat z = (GLfloat) ((src[i] >> 8) * scale); 912b8e80941Smrg d[i].z = z; 913b8e80941Smrg d[i].x24s8 = src[i]; 914b8e80941Smrg } 915b8e80941Smrg } 916b8e80941Smrg break; 917b8e80941Smrg default: 918b8e80941Smrg _mesa_problem(NULL, "bad format %s in _mesa_pack_ubyte_s_row", 919b8e80941Smrg _mesa_get_format_name(format)); 920b8e80941Smrg return; 921b8e80941Smrg } 922b8e80941Smrg} 923b8e80941Smrg 924b8e80941Smrg 925b8e80941Smrg 926b8e80941Smrg/** 927b8e80941Smrg * Convert a boolean color mask to a packed color where each channel of 928b8e80941Smrg * the packed value at dst will be 0 or ~0 depending on the colorMask. 929b8e80941Smrg */ 930b8e80941Smrgvoid 931b8e80941Smrg_mesa_pack_colormask(mesa_format format, const GLubyte colorMask[4], void *dst) 932b8e80941Smrg{ 933b8e80941Smrg GLfloat maskColor[4]; 934b8e80941Smrg 935b8e80941Smrg switch (_mesa_get_format_datatype(format)) { 936b8e80941Smrg case GL_UNSIGNED_NORMALIZED: 937b8e80941Smrg /* simple: 1.0 will convert to ~0 in the right bit positions */ 938b8e80941Smrg maskColor[0] = colorMask[0] ? 1.0f : 0.0f; 939b8e80941Smrg maskColor[1] = colorMask[1] ? 1.0f : 0.0f; 940b8e80941Smrg maskColor[2] = colorMask[2] ? 1.0f : 0.0f; 941b8e80941Smrg maskColor[3] = colorMask[3] ? 1.0f : 0.0f; 942b8e80941Smrg _mesa_pack_float_rgba_row(format, 1, 943b8e80941Smrg (const GLfloat (*)[4]) maskColor, dst); 944b8e80941Smrg break; 945b8e80941Smrg case GL_SIGNED_NORMALIZED: 946b8e80941Smrg case GL_FLOAT: 947b8e80941Smrg /* These formats are harder because it's hard to know the floating 948b8e80941Smrg * point values that will convert to ~0 for each color channel's bits. 949b8e80941Smrg * This solution just generates a non-zero value for each color channel 950b8e80941Smrg * then fixes up the non-zero values to be ~0. 951b8e80941Smrg * Note: we'll need to add special case code if we ever have to deal 952b8e80941Smrg * with formats with unequal color channel sizes, like R11_G11_B10. 953b8e80941Smrg * We issue a warning below for channel sizes other than 8,16,32. 954b8e80941Smrg */ 955b8e80941Smrg { 956b8e80941Smrg GLuint bits = _mesa_get_format_max_bits(format); /* bits per chan */ 957b8e80941Smrg GLuint bytes = _mesa_get_format_bytes(format); 958b8e80941Smrg GLuint i; 959b8e80941Smrg 960b8e80941Smrg /* this should put non-zero values into the channels of dst */ 961b8e80941Smrg maskColor[0] = colorMask[0] ? -1.0f : 0.0f; 962b8e80941Smrg maskColor[1] = colorMask[1] ? -1.0f : 0.0f; 963b8e80941Smrg maskColor[2] = colorMask[2] ? -1.0f : 0.0f; 964b8e80941Smrg maskColor[3] = colorMask[3] ? -1.0f : 0.0f; 965b8e80941Smrg _mesa_pack_float_rgba_row(format, 1, 966b8e80941Smrg (const GLfloat (*)[4]) maskColor, dst); 967b8e80941Smrg 968b8e80941Smrg /* fix-up the dst channels by converting non-zero values to ~0 */ 969b8e80941Smrg if (bits == 8) { 970b8e80941Smrg GLubyte *d = (GLubyte *) dst; 971b8e80941Smrg for (i = 0; i < bytes; i++) { 972b8e80941Smrg d[i] = d[i] ? 0xff : 0x0; 973b8e80941Smrg } 974b8e80941Smrg } 975b8e80941Smrg else if (bits == 16) { 976b8e80941Smrg GLushort *d = (GLushort *) dst; 977b8e80941Smrg for (i = 0; i < bytes / 2; i++) { 978b8e80941Smrg d[i] = d[i] ? 0xffff : 0x0; 979b8e80941Smrg } 980b8e80941Smrg } 981b8e80941Smrg else if (bits == 32) { 982b8e80941Smrg GLuint *d = (GLuint *) dst; 983b8e80941Smrg for (i = 0; i < bytes / 4; i++) { 984b8e80941Smrg d[i] = d[i] ? 0xffffffffU : 0x0; 985b8e80941Smrg } 986b8e80941Smrg } 987b8e80941Smrg else { 988b8e80941Smrg _mesa_problem(NULL, "unexpected size in _mesa_pack_colormask()"); 989b8e80941Smrg return; 990b8e80941Smrg } 991b8e80941Smrg } 992b8e80941Smrg break; 993b8e80941Smrg default: 994b8e80941Smrg _mesa_problem(NULL, "unexpected format data type in gen_color_mask()"); 995b8e80941Smrg return; 996b8e80941Smrg } 997b8e80941Smrg} 998b8e80941Smrg""" 999b8e80941Smrg 1000b8e80941Smrgtemplate = Template(string, future_imports=['division']); 1001b8e80941Smrg 1002b8e80941Smrgprint(template.render(argv = argv[0:])) 1003