Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /**************************************************************************
  2.  *
  3.  * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
  4.  * All Rights Reserved.
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person obtaining a
  7.  * copy of this software and associated documentation files (the
  8.  * "Software"), to deal in the Software without restriction, including
  9.  * without limitation the rights to use, copy, modify, merge, publish,
  10.  * distribute, sub license, and/or sell copies of the Software, and to
  11.  * permit persons to whom the Software is furnished to do so, subject to
  12.  * the following conditions:
  13.  *
  14.  * The above copyright notice and this permission notice (including the
  15.  * next paragraph) shall be included in all copies or substantial portions
  16.  * of the Software.
  17.  *
  18.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  19.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  20.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
  21.  * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
  22.  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  23.  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  24.  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25.  *
  26.  **************************************************************************/
  27.  
  28. /**
  29.  * @file
  30.  * Functions to produce packed colors/Z from floats.
  31.  */
  32.  
  33.  
  34. #ifndef U_PACK_COLOR_H
  35. #define U_PACK_COLOR_H
  36.  
  37.  
  38. #include "pipe/p_compiler.h"
  39. #include "pipe/p_format.h"
  40. #include "util/u_debug.h"
  41. #include "util/u_format.h"
  42. #include "util/u_math.h"
  43.  
  44.  
  45. /**
  46.  * Helper union for packing pixel values.
  47.  * Will often contain values in formats which are too complex to be described
  48.  * in simple terms, hence might just effectively contain a number of bytes.
  49.  * Must be big enough to hold data for all formats (currently 256 bits).
  50.  */
  51. union util_color {
  52.    ubyte ub;
  53.    ushort us;
  54.    uint ui;
  55.    ushort h[4]; /* half float */
  56.    float f[4];
  57.    double d[4];
  58. };
  59.  
  60. /**
  61.  * Pack ubyte R,G,B,A into dest pixel.
  62.  */
  63. static INLINE void
  64. util_pack_color_ub(ubyte r, ubyte g, ubyte b, ubyte a,
  65.                    enum pipe_format format, union util_color *uc)
  66. {
  67.    switch (format) {
  68.    case PIPE_FORMAT_ABGR8888_UNORM:
  69.       {
  70.          uc->ui = (r << 24) | (g << 16) | (b << 8) | a;
  71.       }
  72.       return;
  73.    case PIPE_FORMAT_XBGR8888_UNORM:
  74.       {
  75.          uc->ui = (r << 24) | (g << 16) | (b << 8) | 0xff;
  76.       }
  77.       return;
  78.    case PIPE_FORMAT_BGRA8888_UNORM:
  79.       {
  80.          uc->ui = (a << 24) | (r << 16) | (g << 8) | b;
  81.       }
  82.       return;
  83.    case PIPE_FORMAT_BGRX8888_UNORM:
  84.       {
  85.          uc->ui = (0xff << 24) | (r << 16) | (g << 8) | b;
  86.       }
  87.       return;
  88.    case PIPE_FORMAT_ARGB8888_UNORM:
  89.       {
  90.          uc->ui = (b << 24) | (g << 16) | (r << 8) | a;
  91.       }
  92.       return;
  93.    case PIPE_FORMAT_XRGB8888_UNORM:
  94.       {
  95.          uc->ui = (b << 24) | (g << 16) | (r << 8) | 0xff;
  96.       }
  97.       return;
  98.    case PIPE_FORMAT_B5G6R5_UNORM:
  99.       {
  100.          uc->us = ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | (b >> 3);
  101.       }
  102.       return;
  103.    case PIPE_FORMAT_B5G5R5X1_UNORM:
  104.       {
  105.          uc->us = ((0x80) << 8) | ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | (b >> 3);
  106.       }
  107.       return;
  108.    case PIPE_FORMAT_B5G5R5A1_UNORM:
  109.       {
  110.          uc->us = ((a & 0x80) << 8) | ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | (b >> 3);
  111.       }
  112.       return;
  113.    case PIPE_FORMAT_B4G4R4A4_UNORM:
  114.       {
  115.          uc->us = ((a & 0xf0) << 8) | ((r & 0xf0) << 4) | ((g & 0xf0) << 0) | (b >> 4);
  116.       }
  117.       return;
  118.    case PIPE_FORMAT_A8_UNORM:
  119.       {
  120.          uc->ub = a;
  121.       }
  122.       return;
  123.    case PIPE_FORMAT_L8_UNORM:
  124.    case PIPE_FORMAT_I8_UNORM:
  125.       {
  126.          uc->ub = r;
  127.       }
  128.       return;
  129.    case PIPE_FORMAT_R32G32B32A32_FLOAT:
  130.       {
  131.          uc->f[0] = (float)r / 255.0f;
  132.          uc->f[1] = (float)g / 255.0f;
  133.          uc->f[2] = (float)b / 255.0f;
  134.          uc->f[3] = (float)a / 255.0f;
  135.       }
  136.       return;
  137.    case PIPE_FORMAT_R32G32B32_FLOAT:
  138.       {
  139.          uc->f[0] = (float)r / 255.0f;
  140.          uc->f[1] = (float)g / 255.0f;
  141.          uc->f[2] = (float)b / 255.0f;
  142.       }
  143.       return;
  144.  
  145.    /* Handle other cases with a generic function.
  146.     */
  147.    default:
  148.       {
  149.          ubyte src[4];
  150.  
  151.          src[0] = r;
  152.          src[1] = g;
  153.          src[2] = b;
  154.          src[3] = a;
  155.          util_format_write_4ub(format, src, 0, uc, 0, 0, 0, 1, 1);
  156.       }
  157.    }
  158. }
  159.  
  160.  
  161. /**
  162.  * Unpack RGBA from a packed pixel, returning values as ubytes in [0,255].
  163.  */
  164. static INLINE void
  165. util_unpack_color_ub(enum pipe_format format, union util_color *uc,
  166.                      ubyte *r, ubyte *g, ubyte *b, ubyte *a)
  167. {
  168.    switch (format) {
  169.    case PIPE_FORMAT_ABGR8888_UNORM:
  170.       {
  171.          uint p = uc->ui;
  172.          *r = (ubyte) ((p >> 24) & 0xff);
  173.          *g = (ubyte) ((p >> 16) & 0xff);
  174.          *b = (ubyte) ((p >>  8) & 0xff);
  175.          *a = (ubyte) ((p >>  0) & 0xff);
  176.       }
  177.       return;
  178.    case PIPE_FORMAT_XBGR8888_UNORM:
  179.       {
  180.          uint p = uc->ui;
  181.          *r = (ubyte) ((p >> 24) & 0xff);
  182.          *g = (ubyte) ((p >> 16) & 0xff);
  183.          *b = (ubyte) ((p >>  8) & 0xff);
  184.          *a = (ubyte) 0xff;
  185.       }
  186.       return;
  187.    case PIPE_FORMAT_BGRA8888_UNORM:
  188.       {
  189.          uint p = uc->ui;
  190.          *r = (ubyte) ((p >> 16) & 0xff);
  191.          *g = (ubyte) ((p >>  8) & 0xff);
  192.          *b = (ubyte) ((p >>  0) & 0xff);
  193.          *a = (ubyte) ((p >> 24) & 0xff);
  194.       }
  195.       return;
  196.    case PIPE_FORMAT_BGRX8888_UNORM:
  197.       {
  198.          uint p = uc->ui;
  199.          *r = (ubyte) ((p >> 16) & 0xff);
  200.          *g = (ubyte) ((p >>  8) & 0xff);
  201.          *b = (ubyte) ((p >>  0) & 0xff);
  202.          *a = (ubyte) 0xff;
  203.       }
  204.       return;
  205.    case PIPE_FORMAT_ARGB8888_UNORM:
  206.       {
  207.          uint p = uc->ui;
  208.          *r = (ubyte) ((p >>  8) & 0xff);
  209.          *g = (ubyte) ((p >> 16) & 0xff);
  210.          *b = (ubyte) ((p >> 24) & 0xff);
  211.          *a = (ubyte) ((p >>  0) & 0xff);
  212.       }
  213.       return;
  214.    case PIPE_FORMAT_XRGB8888_UNORM:
  215.       {
  216.          uint p = uc->ui;
  217.          *r = (ubyte) ((p >>  8) & 0xff);
  218.          *g = (ubyte) ((p >> 16) & 0xff);
  219.          *b = (ubyte) ((p >> 24) & 0xff);
  220.          *a = (ubyte) 0xff;
  221.       }
  222.       return;
  223.    case PIPE_FORMAT_B5G6R5_UNORM:
  224.       {
  225.          ushort p = uc->us;
  226.          *r = (ubyte) (((p >> 8) & 0xf8) | ((p >> 13) & 0x7));
  227.          *g = (ubyte) (((p >> 3) & 0xfc) | ((p >>  9) & 0x3));
  228.          *b = (ubyte) (((p << 3) & 0xf8) | ((p >>  2) & 0x7));
  229.          *a = (ubyte) 0xff;
  230.       }
  231.       return;
  232.    case PIPE_FORMAT_B5G5R5X1_UNORM:
  233.       {
  234.          ushort p = uc->us;
  235.          *r = (ubyte) (((p >>  7) & 0xf8) | ((p >> 12) & 0x7));
  236.          *g = (ubyte) (((p >>  2) & 0xf8) | ((p >>  7) & 0x7));
  237.          *b = (ubyte) (((p <<  3) & 0xf8) | ((p >>  2) & 0x7));
  238.          *a = (ubyte) 0xff;
  239.       }
  240.       return;
  241.    case PIPE_FORMAT_B5G5R5A1_UNORM:
  242.       {
  243.          ushort p = uc->us;
  244.          *r = (ubyte) (((p >>  7) & 0xf8) | ((p >> 12) & 0x7));
  245.          *g = (ubyte) (((p >>  2) & 0xf8) | ((p >>  7) & 0x7));
  246.          *b = (ubyte) (((p <<  3) & 0xf8) | ((p >>  2) & 0x7));
  247.          *a = (ubyte) (0xff * (p >> 15));
  248.       }
  249.       return;
  250.    case PIPE_FORMAT_B4G4R4A4_UNORM:
  251.       {
  252.          ushort p = uc->us;
  253.          *r = (ubyte) (((p >> 4) & 0xf0) | ((p >>  8) & 0xf));
  254.          *g = (ubyte) (((p >> 0) & 0xf0) | ((p >>  4) & 0xf));
  255.          *b = (ubyte) (((p << 4) & 0xf0) | ((p >>  0) & 0xf));
  256.          *a = (ubyte) (((p >> 8) & 0xf0) | ((p >> 12) & 0xf));
  257.       }
  258.       return;
  259.    case PIPE_FORMAT_A8_UNORM:
  260.       {
  261.          ubyte p = uc->ub;
  262.          *r = *g = *b = (ubyte) 0xff;
  263.          *a = p;
  264.       }
  265.       return;
  266.    case PIPE_FORMAT_L8_UNORM:
  267.       {
  268.          ubyte p = uc->ub;
  269.          *r = *g = *b = p;
  270.          *a = (ubyte) 0xff;
  271.       }
  272.       return;
  273.    case PIPE_FORMAT_I8_UNORM:
  274.       {
  275.          ubyte p = uc->ub;
  276.          *r = *g = *b = *a = p;
  277.       }
  278.       return;
  279.    case PIPE_FORMAT_R32G32B32A32_FLOAT:
  280.       {
  281.          const float *p = &uc->f[0];
  282.          *r = float_to_ubyte(p[0]);
  283.          *g = float_to_ubyte(p[1]);
  284.          *b = float_to_ubyte(p[2]);
  285.          *a = float_to_ubyte(p[3]);
  286.       }
  287.       return;
  288.    case PIPE_FORMAT_R32G32B32_FLOAT:
  289.       {
  290.          const float *p = &uc->f[0];
  291.          *r = float_to_ubyte(p[0]);
  292.          *g = float_to_ubyte(p[1]);
  293.          *b = float_to_ubyte(p[2]);
  294.          *a = (ubyte) 0xff;
  295.       }
  296.       return;
  297.  
  298.    case PIPE_FORMAT_R32G32_FLOAT:
  299.       {
  300.          const float *p = &uc->f[0];
  301.          *r = float_to_ubyte(p[0]);
  302.          *g = float_to_ubyte(p[1]);
  303.          *b = *a = (ubyte) 0xff;
  304.       }
  305.       return;
  306.  
  307.    case PIPE_FORMAT_R32_FLOAT:
  308.       {
  309.          const float *p = &uc->f[0];
  310.          *r = float_to_ubyte(p[0]);
  311.          *g = *b = *a = (ubyte) 0xff;
  312.       }
  313.       return;
  314.  
  315.    /* Handle other cases with a generic function.
  316.     */
  317.    default:
  318.       {
  319.          ubyte dst[4];
  320.  
  321.          util_format_read_4ub(format, dst, 0, uc, 0, 0, 0, 1, 1);
  322.          *r = dst[0];
  323.          *g = dst[1];
  324.          *b = dst[2];
  325.          *a = dst[3];
  326.       }
  327.    }
  328. }
  329.  
  330.  
  331. /**
  332.  * Note rgba outside [0,1] will be clamped for int pixel formats.
  333.  * This will not work (and might not really be useful with float input)
  334.  * for pure integer formats (which lack the pack_rgba_float function).
  335.  */
  336. static INLINE void
  337. util_pack_color(const float rgba[4], enum pipe_format format, union util_color *uc)
  338. {
  339.    ubyte r = 0;
  340.    ubyte g = 0;
  341.    ubyte b = 0;
  342.    ubyte a = 0;
  343.  
  344.    if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 0) <= 8) {
  345.       /* format uses 8-bit components or less */
  346.       r = float_to_ubyte(rgba[0]);
  347.       g = float_to_ubyte(rgba[1]);
  348.       b = float_to_ubyte(rgba[2]);
  349.       a = float_to_ubyte(rgba[3]);
  350.    }
  351.  
  352.    switch (format) {
  353.    case PIPE_FORMAT_ABGR8888_UNORM:
  354.       {
  355.          uc->ui = (r << 24) | (g << 16) | (b << 8) | a;
  356.       }
  357.       return;
  358.    case PIPE_FORMAT_XBGR8888_UNORM:
  359.       {
  360.          uc->ui = (r << 24) | (g << 16) | (b << 8) | 0xff;
  361.       }
  362.       return;
  363.    case PIPE_FORMAT_BGRA8888_UNORM:
  364.       {
  365.          uc->ui = (a << 24) | (r << 16) | (g << 8) | b;
  366.       }
  367.       return;
  368.    case PIPE_FORMAT_BGRX8888_UNORM:
  369.       {
  370.          uc->ui = (0xff << 24) | (r << 16) | (g << 8) | b;
  371.       }
  372.       return;
  373.    case PIPE_FORMAT_ARGB8888_UNORM:
  374.       {
  375.          uc->ui = (b << 24) | (g << 16) | (r << 8) | a;
  376.       }
  377.       return;
  378.    case PIPE_FORMAT_XRGB8888_UNORM:
  379.       {
  380.          uc->ui = (b << 24) | (g << 16) | (r << 8) | 0xff;
  381.       }
  382.       return;
  383.    case PIPE_FORMAT_B5G6R5_UNORM:
  384.       {
  385.          uc->us = ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | (b >> 3);
  386.       }
  387.       return;
  388.    case PIPE_FORMAT_B5G5R5X1_UNORM:
  389.       {
  390.          uc->us = ((0x80) << 8) | ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | (b >> 3);
  391.       }
  392.       return;
  393.    case PIPE_FORMAT_B5G5R5A1_UNORM:
  394.       {
  395.          uc->us = ((a & 0x80) << 8) | ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | (b >> 3);
  396.       }
  397.       return;
  398.    case PIPE_FORMAT_B4G4R4A4_UNORM:
  399.       {
  400.          uc->us = ((a & 0xf0) << 8) | ((r & 0xf0) << 4) | ((g & 0xf0) << 0) | (b >> 4);
  401.       }
  402.       return;
  403.    case PIPE_FORMAT_A8_UNORM:
  404.       {
  405.          uc->ub = a;
  406.       }
  407.       return;
  408.    case PIPE_FORMAT_L8_UNORM:
  409.    case PIPE_FORMAT_I8_UNORM:
  410.       {
  411.          uc->ub = r;
  412.       }
  413.       return;
  414.    case PIPE_FORMAT_R32G32B32A32_FLOAT:
  415.       {
  416.          uc->f[0] = rgba[0];
  417.          uc->f[1] = rgba[1];
  418.          uc->f[2] = rgba[2];
  419.          uc->f[3] = rgba[3];
  420.       }
  421.       return;
  422.    case PIPE_FORMAT_R32G32B32_FLOAT:
  423.       {
  424.          uc->f[0] = rgba[0];
  425.          uc->f[1] = rgba[1];
  426.          uc->f[2] = rgba[2];
  427.       }
  428.       return;
  429.  
  430.    /* Handle other cases with a generic function.
  431.     */
  432.    default:
  433.       util_format_write_4f(format, rgba, 0, uc, 0, 0, 0, 1, 1);
  434.    }
  435. }
  436.  
  437. /* Integer versions of util_pack_z and util_pack_z_stencil - useful for
  438.  * constructing clear masks.
  439.  */
  440. static INLINE uint32_t
  441. util_pack_mask_z(enum pipe_format format, uint32_t z)
  442. {
  443.    switch (format) {
  444.    case PIPE_FORMAT_Z16_UNORM:
  445.       return z & 0xffff;
  446.    case PIPE_FORMAT_Z32_UNORM:
  447.    case PIPE_FORMAT_Z32_FLOAT:
  448.       return z;
  449.    case PIPE_FORMAT_Z24_UNORM_S8_UINT:
  450.    case PIPE_FORMAT_Z24X8_UNORM:
  451.       return z & 0xffffff;
  452.    case PIPE_FORMAT_S8_UINT_Z24_UNORM:
  453.    case PIPE_FORMAT_X8Z24_UNORM:
  454.       return (z & 0xffffff) << 8;
  455.    case PIPE_FORMAT_S8_UINT:
  456.       return 0;
  457.    default:
  458.       debug_print_format("gallium: unhandled format in util_pack_mask_z()", format);
  459.       assert(0);
  460.       return 0;
  461.    }
  462. }
  463.  
  464.  
  465. static INLINE uint64_t
  466. util_pack64_mask_z(enum pipe_format format, uint32_t z)
  467. {
  468.    switch (format) {
  469.    case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
  470.       return z;
  471.    default:
  472.       return util_pack_mask_z(format, z);
  473.    }
  474. }
  475.  
  476.  
  477. static INLINE uint32_t
  478. util_pack_mask_z_stencil(enum pipe_format format, uint32_t z, uint8_t s)
  479. {
  480.    uint32_t packed = util_pack_mask_z(format, z);
  481.  
  482.    switch (format) {
  483.    case PIPE_FORMAT_Z24_UNORM_S8_UINT:
  484.       packed |= (uint32_t)s << 24;
  485.       break;
  486.    case PIPE_FORMAT_S8_UINT_Z24_UNORM:
  487.       packed |= s;
  488.       break;
  489.    case PIPE_FORMAT_S8_UINT:
  490.       packed |= s;
  491.       break;
  492.    default:
  493.       break;
  494.    }
  495.  
  496.    return packed;
  497. }
  498.  
  499.  
  500. static INLINE uint64_t
  501. util_pack64_mask_z_stencil(enum pipe_format format, uint32_t z, uint8_t s)
  502. {
  503.    uint64_t packed;
  504.  
  505.    switch (format) {
  506.    case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
  507.       packed = util_pack64_mask_z(format, z);
  508.       packed |= (uint64_t)s << 32ull;
  509.       return packed;
  510.    default:
  511.       return util_pack_mask_z_stencil(format, z, s);
  512.    }
  513. }
  514.  
  515.  
  516. /**
  517.  * Note: it's assumed that z is in [0,1]
  518.  */
  519. static INLINE uint32_t
  520. util_pack_z(enum pipe_format format, double z)
  521. {
  522.    union fi fui;
  523.  
  524.    if (z == 0.0)
  525.       return 0;
  526.  
  527.    switch (format) {
  528.    case PIPE_FORMAT_Z16_UNORM:
  529.       if (z == 1.0)
  530.          return 0xffff;
  531.       return (uint32_t) (z * 0xffff);
  532.    case PIPE_FORMAT_Z32_UNORM:
  533.       /* special-case to avoid overflow */
  534.       if (z == 1.0)
  535.          return 0xffffffff;
  536.       return (uint32_t) (z * 0xffffffff);
  537.    case PIPE_FORMAT_Z32_FLOAT:
  538.       fui.f = (float)z;
  539.       return fui.ui;
  540.    case PIPE_FORMAT_Z24_UNORM_S8_UINT:
  541.    case PIPE_FORMAT_Z24X8_UNORM:
  542.       if (z == 1.0)
  543.          return 0xffffff;
  544.       return (uint32_t) (z * 0xffffff);
  545.    case PIPE_FORMAT_S8_UINT_Z24_UNORM:
  546.    case PIPE_FORMAT_X8Z24_UNORM:
  547.       if (z == 1.0)
  548.          return 0xffffff00;
  549.       return ((uint32_t) (z * 0xffffff)) << 8;
  550.    case PIPE_FORMAT_S8_UINT:
  551.       /* this case can get it via util_pack_z_stencil() */
  552.       return 0;
  553.    default:
  554.       debug_print_format("gallium: unhandled format in util_pack_z()", format);
  555.       assert(0);
  556.       return 0;
  557.    }
  558. }
  559.  
  560.  
  561. static INLINE uint64_t
  562. util_pack64_z(enum pipe_format format, double z)
  563. {
  564.    union fi fui;
  565.  
  566.    if (z == 0)
  567.       return 0;
  568.  
  569.    switch (format) {
  570.    case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
  571.       fui.f = (float)z;
  572.       return fui.ui;
  573.    default:
  574.       return util_pack_z(format, z);
  575.    }
  576. }
  577.  
  578.  
  579. /**
  580.  * Pack Z and/or stencil values into a 32-bit value described by format.
  581.  * Note: it's assumed that z is in [0,1] and s in [0,255]
  582.  */
  583. static INLINE uint32_t
  584. util_pack_z_stencil(enum pipe_format format, double z, uint8_t s)
  585. {
  586.    uint32_t packed = util_pack_z(format, z);
  587.  
  588.    switch (format) {
  589.    case PIPE_FORMAT_Z24_UNORM_S8_UINT:
  590.       packed |= (uint32_t)s << 24;
  591.       break;
  592.    case PIPE_FORMAT_S8_UINT_Z24_UNORM:
  593.       packed |= s;
  594.       break;
  595.    case PIPE_FORMAT_S8_UINT:
  596.       packed |= s;
  597.       break;
  598.    default:
  599.       break;
  600.    }
  601.  
  602.    return packed;
  603. }
  604.  
  605.  
  606. static INLINE uint64_t
  607. util_pack64_z_stencil(enum pipe_format format, double z, uint8_t s)
  608. {
  609.    uint64_t packed;
  610.  
  611.    switch (format) {
  612.    case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
  613.       packed = util_pack64_z(format, z);
  614.       packed |= (uint64_t)s << 32ull;
  615.       break;
  616.    default:
  617.       return util_pack_z_stencil(format, z, s);
  618.    }
  619.  
  620.    return packed;
  621. }
  622.  
  623.  
  624. /**
  625.  * Pack 4 ubytes into a 4-byte word
  626.  */
  627. static INLINE unsigned
  628. pack_ub4(ubyte b0, ubyte b1, ubyte b2, ubyte b3)
  629. {
  630.    return ((((unsigned int)b0) << 0) |
  631.            (((unsigned int)b1) << 8) |
  632.            (((unsigned int)b2) << 16) |
  633.            (((unsigned int)b3) << 24));
  634. }
  635.  
  636.  
  637. /**
  638.  * Pack/convert 4 floats into one 4-byte word.
  639.  */
  640. static INLINE unsigned
  641. pack_ui32_float4(float a, float b, float c, float d)
  642. {
  643.    return pack_ub4( float_to_ubyte(a),
  644.                     float_to_ubyte(b),
  645.                     float_to_ubyte(c),
  646.                     float_to_ubyte(d) );
  647. }
  648.  
  649.  
  650.  
  651. #endif /* U_PACK_COLOR_H */
  652.