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