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