1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Mesa 3-D graphics library
3bf215546Sopenharmony_ci *
4bf215546Sopenharmony_ci * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
5bf215546Sopenharmony_ci * Copyright (C) 2009-2010  VMware, Inc.  All Rights Reserved.
6bf215546Sopenharmony_ci *
7bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
8bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
9bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation
10bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
12bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
13bf215546Sopenharmony_ci *
14bf215546Sopenharmony_ci * The above copyright notice and this permission notice shall be included
15bf215546Sopenharmony_ci * in all copies or substantial portions of the Software.
16bf215546Sopenharmony_ci *
17bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20bf215546Sopenharmony_ci * THEA AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21bf215546Sopenharmony_ci * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22bf215546Sopenharmony_ci * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23bf215546Sopenharmony_ci */
24bf215546Sopenharmony_ci
25bf215546Sopenharmony_ci
26bf215546Sopenharmony_ci/**
27bf215546Sopenharmony_ci * \file pack.c
28bf215546Sopenharmony_ci * Image and pixel span packing and unpacking.
29bf215546Sopenharmony_ci */
30bf215546Sopenharmony_ci
31bf215546Sopenharmony_ci
32bf215546Sopenharmony_ci/*
33bf215546Sopenharmony_ci * XXX: MSVC takes forever to compile this module for x86_64 unless we disable
34bf215546Sopenharmony_ci * this global optimization.
35bf215546Sopenharmony_ci *
36bf215546Sopenharmony_ci * See also:
37bf215546Sopenharmony_ci * - http://msdn.microsoft.com/en-us/library/1yk3ydd7.aspx
38bf215546Sopenharmony_ci * - http://msdn.microsoft.com/en-us/library/chh3fb0k.aspx
39bf215546Sopenharmony_ci */
40bf215546Sopenharmony_ci#if defined(_MSC_VER) && defined(_M_X64)
41bf215546Sopenharmony_ci#  pragma optimize( "g", off )
42bf215546Sopenharmony_ci#endif
43bf215546Sopenharmony_ci
44bf215546Sopenharmony_ci
45bf215546Sopenharmony_ci#include "errors.h"
46bf215546Sopenharmony_ci#include "glheader.h"
47bf215546Sopenharmony_ci#include "enums.h"
48bf215546Sopenharmony_ci#include "image.h"
49bf215546Sopenharmony_ci
50bf215546Sopenharmony_ci#include "macros.h"
51bf215546Sopenharmony_ci#include "mtypes.h"
52bf215546Sopenharmony_ci#include "pack.h"
53bf215546Sopenharmony_ci#include "pixeltransfer.h"
54bf215546Sopenharmony_ci
55bf215546Sopenharmony_ci#include "glformats.h"
56bf215546Sopenharmony_ci#include "format_utils.h"
57bf215546Sopenharmony_ci#include "format_pack.h"
58bf215546Sopenharmony_ci#include "format_unpack.h"
59bf215546Sopenharmony_ci#include "util/format/u_format.h"
60bf215546Sopenharmony_ci
61bf215546Sopenharmony_ci/**
62bf215546Sopenharmony_ci * Flip the 8 bits in each byte of the given array.
63bf215546Sopenharmony_ci *
64bf215546Sopenharmony_ci * \param p array.
65bf215546Sopenharmony_ci * \param n number of bytes.
66bf215546Sopenharmony_ci *
67bf215546Sopenharmony_ci * \todo try this trick to flip bytes someday:
68bf215546Sopenharmony_ci * \code
69bf215546Sopenharmony_ci *  v = ((v & 0x55555555) << 1) | ((v >> 1) & 0x55555555);
70bf215546Sopenharmony_ci *  v = ((v & 0x33333333) << 2) | ((v >> 2) & 0x33333333);
71bf215546Sopenharmony_ci *  v = ((v & 0x0f0f0f0f) << 4) | ((v >> 4) & 0x0f0f0f0f);
72bf215546Sopenharmony_ci * \endcode
73bf215546Sopenharmony_ci */
74bf215546Sopenharmony_cistatic void
75bf215546Sopenharmony_ciflip_bytes( GLubyte *p, GLuint n )
76bf215546Sopenharmony_ci{
77bf215546Sopenharmony_ci   GLuint i, a, b;
78bf215546Sopenharmony_ci   for (i = 0; i < n; i++) {
79bf215546Sopenharmony_ci      b = (GLuint) p[i];        /* words are often faster than bytes */
80bf215546Sopenharmony_ci      a = ((b & 0x01) << 7) |
81bf215546Sopenharmony_ci	  ((b & 0x02) << 5) |
82bf215546Sopenharmony_ci	  ((b & 0x04) << 3) |
83bf215546Sopenharmony_ci	  ((b & 0x08) << 1) |
84bf215546Sopenharmony_ci	  ((b & 0x10) >> 1) |
85bf215546Sopenharmony_ci	  ((b & 0x20) >> 3) |
86bf215546Sopenharmony_ci	  ((b & 0x40) >> 5) |
87bf215546Sopenharmony_ci	  ((b & 0x80) >> 7);
88bf215546Sopenharmony_ci      p[i] = (GLubyte) a;
89bf215546Sopenharmony_ci   }
90bf215546Sopenharmony_ci}
91bf215546Sopenharmony_ci
92bf215546Sopenharmony_ci
93bf215546Sopenharmony_ci
94bf215546Sopenharmony_ci/*
95bf215546Sopenharmony_ci * Unpack a 32x32 pixel polygon stipple from user memory using the
96bf215546Sopenharmony_ci * current pixel unpack settings.
97bf215546Sopenharmony_ci */
98bf215546Sopenharmony_civoid
99bf215546Sopenharmony_ci_mesa_unpack_polygon_stipple( const GLubyte *pattern, GLuint dest[32],
100bf215546Sopenharmony_ci                              const struct gl_pixelstore_attrib *unpacking )
101bf215546Sopenharmony_ci{
102bf215546Sopenharmony_ci   GLubyte *ptrn = (GLubyte *) _mesa_unpack_image(2, 32, 32, 1, GL_COLOR_INDEX,
103bf215546Sopenharmony_ci                                                  GL_BITMAP, pattern, unpacking);
104bf215546Sopenharmony_ci   if (ptrn) {
105bf215546Sopenharmony_ci      /* Convert pattern from GLubytes to GLuints and handle big/little
106bf215546Sopenharmony_ci       * endian differences
107bf215546Sopenharmony_ci       */
108bf215546Sopenharmony_ci      GLubyte *p = ptrn;
109bf215546Sopenharmony_ci      GLint i;
110bf215546Sopenharmony_ci      for (i = 0; i < 32; i++) {
111bf215546Sopenharmony_ci         dest[i] = (p[0] << 24)
112bf215546Sopenharmony_ci                 | (p[1] << 16)
113bf215546Sopenharmony_ci                 | (p[2] <<  8)
114bf215546Sopenharmony_ci                 | (p[3]      );
115bf215546Sopenharmony_ci         p += 4;
116bf215546Sopenharmony_ci      }
117bf215546Sopenharmony_ci      free(ptrn);
118bf215546Sopenharmony_ci   }
119bf215546Sopenharmony_ci}
120bf215546Sopenharmony_ci
121bf215546Sopenharmony_ci
122bf215546Sopenharmony_ci/*
123bf215546Sopenharmony_ci * Pack polygon stipple into user memory given current pixel packing
124bf215546Sopenharmony_ci * settings.
125bf215546Sopenharmony_ci */
126bf215546Sopenharmony_civoid
127bf215546Sopenharmony_ci_mesa_pack_polygon_stipple( const GLuint pattern[32], GLubyte *dest,
128bf215546Sopenharmony_ci                            const struct gl_pixelstore_attrib *packing )
129bf215546Sopenharmony_ci{
130bf215546Sopenharmony_ci   /* Convert pattern from GLuints to GLubytes to handle big/little
131bf215546Sopenharmony_ci    * endian differences.
132bf215546Sopenharmony_ci    */
133bf215546Sopenharmony_ci   GLubyte ptrn[32*4];
134bf215546Sopenharmony_ci   GLint i;
135bf215546Sopenharmony_ci   for (i = 0; i < 32; i++) {
136bf215546Sopenharmony_ci      ptrn[i * 4 + 0] = (GLubyte) ((pattern[i] >> 24) & 0xff);
137bf215546Sopenharmony_ci      ptrn[i * 4 + 1] = (GLubyte) ((pattern[i] >> 16) & 0xff);
138bf215546Sopenharmony_ci      ptrn[i * 4 + 2] = (GLubyte) ((pattern[i] >> 8 ) & 0xff);
139bf215546Sopenharmony_ci      ptrn[i * 4 + 3] = (GLubyte) ((pattern[i]      ) & 0xff);
140bf215546Sopenharmony_ci   }
141bf215546Sopenharmony_ci
142bf215546Sopenharmony_ci   _mesa_pack_bitmap(32, 32, ptrn, dest, packing);
143bf215546Sopenharmony_ci}
144bf215546Sopenharmony_ci
145bf215546Sopenharmony_ci
146bf215546Sopenharmony_ci/*
147bf215546Sopenharmony_ci * Pack bitmap data.
148bf215546Sopenharmony_ci */
149bf215546Sopenharmony_civoid
150bf215546Sopenharmony_ci_mesa_pack_bitmap( GLint width, GLint height, const GLubyte *source,
151bf215546Sopenharmony_ci                   GLubyte *dest, const struct gl_pixelstore_attrib *packing )
152bf215546Sopenharmony_ci{
153bf215546Sopenharmony_ci   GLint row, width_in_bytes;
154bf215546Sopenharmony_ci   const GLubyte *src;
155bf215546Sopenharmony_ci
156bf215546Sopenharmony_ci   if (!source)
157bf215546Sopenharmony_ci      return;
158bf215546Sopenharmony_ci
159bf215546Sopenharmony_ci   width_in_bytes = DIV_ROUND_UP( width, 8 );
160bf215546Sopenharmony_ci   src = source;
161bf215546Sopenharmony_ci   for (row = 0; row < height; row++) {
162bf215546Sopenharmony_ci      GLubyte *dst = (GLubyte *) _mesa_image_address2d(packing, dest,
163bf215546Sopenharmony_ci                       width, height, GL_COLOR_INDEX, GL_BITMAP, row, 0);
164bf215546Sopenharmony_ci      if (!dst)
165bf215546Sopenharmony_ci         return;
166bf215546Sopenharmony_ci
167bf215546Sopenharmony_ci      if ((packing->SkipPixels & 7) == 0) {
168bf215546Sopenharmony_ci         memcpy( dst, src, width_in_bytes );
169bf215546Sopenharmony_ci         if (packing->LsbFirst) {
170bf215546Sopenharmony_ci            flip_bytes( dst, width_in_bytes );
171bf215546Sopenharmony_ci         }
172bf215546Sopenharmony_ci      }
173bf215546Sopenharmony_ci      else {
174bf215546Sopenharmony_ci         /* handling SkipPixels is a bit tricky (no pun intended!) */
175bf215546Sopenharmony_ci         GLint i;
176bf215546Sopenharmony_ci         if (packing->LsbFirst) {
177bf215546Sopenharmony_ci            GLubyte srcMask = 128;
178bf215546Sopenharmony_ci            GLubyte dstMask = 1 << (packing->SkipPixels & 0x7);
179bf215546Sopenharmony_ci            const GLubyte *s = src;
180bf215546Sopenharmony_ci            GLubyte *d = dst;
181bf215546Sopenharmony_ci            *d = 0;
182bf215546Sopenharmony_ci            for (i = 0; i < width; i++) {
183bf215546Sopenharmony_ci               if (*s & srcMask) {
184bf215546Sopenharmony_ci                  *d |= dstMask;
185bf215546Sopenharmony_ci               }
186bf215546Sopenharmony_ci               if (srcMask == 1) {
187bf215546Sopenharmony_ci                  srcMask = 128;
188bf215546Sopenharmony_ci                  s++;
189bf215546Sopenharmony_ci               }
190bf215546Sopenharmony_ci               else {
191bf215546Sopenharmony_ci                  srcMask = srcMask >> 1;
192bf215546Sopenharmony_ci               }
193bf215546Sopenharmony_ci               if (dstMask == 128) {
194bf215546Sopenharmony_ci                  dstMask = 1;
195bf215546Sopenharmony_ci                  d++;
196bf215546Sopenharmony_ci                  *d = 0;
197bf215546Sopenharmony_ci               }
198bf215546Sopenharmony_ci               else {
199bf215546Sopenharmony_ci                  dstMask = dstMask << 1;
200bf215546Sopenharmony_ci               }
201bf215546Sopenharmony_ci            }
202bf215546Sopenharmony_ci         }
203bf215546Sopenharmony_ci         else {
204bf215546Sopenharmony_ci            GLubyte srcMask = 128;
205bf215546Sopenharmony_ci            GLubyte dstMask = 128 >> (packing->SkipPixels & 0x7);
206bf215546Sopenharmony_ci            const GLubyte *s = src;
207bf215546Sopenharmony_ci            GLubyte *d = dst;
208bf215546Sopenharmony_ci            *d = 0;
209bf215546Sopenharmony_ci            for (i = 0; i < width; i++) {
210bf215546Sopenharmony_ci               if (*s & srcMask) {
211bf215546Sopenharmony_ci                  *d |= dstMask;
212bf215546Sopenharmony_ci               }
213bf215546Sopenharmony_ci               if (srcMask == 1) {
214bf215546Sopenharmony_ci                  srcMask = 128;
215bf215546Sopenharmony_ci                  s++;
216bf215546Sopenharmony_ci               }
217bf215546Sopenharmony_ci               else {
218bf215546Sopenharmony_ci                  srcMask = srcMask >> 1;
219bf215546Sopenharmony_ci               }
220bf215546Sopenharmony_ci               if (dstMask == 1) {
221bf215546Sopenharmony_ci                  dstMask = 128;
222bf215546Sopenharmony_ci                  d++;
223bf215546Sopenharmony_ci                  *d = 0;
224bf215546Sopenharmony_ci               }
225bf215546Sopenharmony_ci               else {
226bf215546Sopenharmony_ci                  dstMask = dstMask >> 1;
227bf215546Sopenharmony_ci               }
228bf215546Sopenharmony_ci            }
229bf215546Sopenharmony_ci         }
230bf215546Sopenharmony_ci      }
231bf215546Sopenharmony_ci      src += width_in_bytes;
232bf215546Sopenharmony_ci   }
233bf215546Sopenharmony_ci}
234bf215546Sopenharmony_ci
235bf215546Sopenharmony_ci
236bf215546Sopenharmony_ci#define SWAP2BYTE(VALUE)			\
237bf215546Sopenharmony_ci   {						\
238bf215546Sopenharmony_ci      GLubyte *bytes = (GLubyte *) &(VALUE);	\
239bf215546Sopenharmony_ci      GLubyte tmp = bytes[0];			\
240bf215546Sopenharmony_ci      bytes[0] = bytes[1];			\
241bf215546Sopenharmony_ci      bytes[1] = tmp;				\
242bf215546Sopenharmony_ci   }
243bf215546Sopenharmony_ci
244bf215546Sopenharmony_ci#define SWAP4BYTE(VALUE)			\
245bf215546Sopenharmony_ci   {						\
246bf215546Sopenharmony_ci      GLubyte *bytes = (GLubyte *) &(VALUE);	\
247bf215546Sopenharmony_ci      GLubyte tmp = bytes[0];			\
248bf215546Sopenharmony_ci      bytes[0] = bytes[3];			\
249bf215546Sopenharmony_ci      bytes[3] = tmp;				\
250bf215546Sopenharmony_ci      tmp = bytes[1];				\
251bf215546Sopenharmony_ci      bytes[1] = bytes[2];			\
252bf215546Sopenharmony_ci      bytes[2] = tmp;				\
253bf215546Sopenharmony_ci   }
254bf215546Sopenharmony_ci
255bf215546Sopenharmony_ci
256bf215546Sopenharmony_cistatic void
257bf215546Sopenharmony_ciextract_uint_indexes(GLuint n, GLuint indexes[],
258bf215546Sopenharmony_ci                     GLenum srcFormat, GLenum srcType, const GLvoid *src,
259bf215546Sopenharmony_ci                     const struct gl_pixelstore_attrib *unpack )
260bf215546Sopenharmony_ci{
261bf215546Sopenharmony_ci   assert(srcFormat == GL_COLOR_INDEX || srcFormat == GL_STENCIL_INDEX);
262bf215546Sopenharmony_ci
263bf215546Sopenharmony_ci   assert(srcType == GL_BITMAP ||
264bf215546Sopenharmony_ci          srcType == GL_UNSIGNED_BYTE ||
265bf215546Sopenharmony_ci          srcType == GL_BYTE ||
266bf215546Sopenharmony_ci          srcType == GL_UNSIGNED_SHORT ||
267bf215546Sopenharmony_ci          srcType == GL_SHORT ||
268bf215546Sopenharmony_ci          srcType == GL_UNSIGNED_INT ||
269bf215546Sopenharmony_ci          srcType == GL_INT ||
270bf215546Sopenharmony_ci          srcType == GL_UNSIGNED_INT_24_8_EXT ||
271bf215546Sopenharmony_ci          srcType == GL_HALF_FLOAT_ARB ||
272bf215546Sopenharmony_ci          srcType == GL_HALF_FLOAT_OES ||
273bf215546Sopenharmony_ci          srcType == GL_FLOAT ||
274bf215546Sopenharmony_ci          srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
275bf215546Sopenharmony_ci
276bf215546Sopenharmony_ci   switch (srcType) {
277bf215546Sopenharmony_ci      case GL_BITMAP:
278bf215546Sopenharmony_ci         {
279bf215546Sopenharmony_ci            GLubyte *ubsrc = (GLubyte *) src;
280bf215546Sopenharmony_ci            if (unpack->LsbFirst) {
281bf215546Sopenharmony_ci               GLubyte mask = 1 << (unpack->SkipPixels & 0x7);
282bf215546Sopenharmony_ci               GLuint i;
283bf215546Sopenharmony_ci               for (i = 0; i < n; i++) {
284bf215546Sopenharmony_ci                  indexes[i] = (*ubsrc & mask) ? 1 : 0;
285bf215546Sopenharmony_ci                  if (mask == 128) {
286bf215546Sopenharmony_ci                     mask = 1;
287bf215546Sopenharmony_ci                     ubsrc++;
288bf215546Sopenharmony_ci                  }
289bf215546Sopenharmony_ci                  else {
290bf215546Sopenharmony_ci                     mask = mask << 1;
291bf215546Sopenharmony_ci                  }
292bf215546Sopenharmony_ci               }
293bf215546Sopenharmony_ci            }
294bf215546Sopenharmony_ci            else {
295bf215546Sopenharmony_ci               GLubyte mask = 128 >> (unpack->SkipPixels & 0x7);
296bf215546Sopenharmony_ci               GLuint i;
297bf215546Sopenharmony_ci               for (i = 0; i < n; i++) {
298bf215546Sopenharmony_ci                  indexes[i] = (*ubsrc & mask) ? 1 : 0;
299bf215546Sopenharmony_ci                  if (mask == 1) {
300bf215546Sopenharmony_ci                     mask = 128;
301bf215546Sopenharmony_ci                     ubsrc++;
302bf215546Sopenharmony_ci                  }
303bf215546Sopenharmony_ci                  else {
304bf215546Sopenharmony_ci                     mask = mask >> 1;
305bf215546Sopenharmony_ci                  }
306bf215546Sopenharmony_ci               }
307bf215546Sopenharmony_ci            }
308bf215546Sopenharmony_ci         }
309bf215546Sopenharmony_ci         break;
310bf215546Sopenharmony_ci      case GL_UNSIGNED_BYTE:
311bf215546Sopenharmony_ci         {
312bf215546Sopenharmony_ci            GLuint i;
313bf215546Sopenharmony_ci            const GLubyte *s = (const GLubyte *) src;
314bf215546Sopenharmony_ci            for (i = 0; i < n; i++)
315bf215546Sopenharmony_ci               indexes[i] = s[i];
316bf215546Sopenharmony_ci         }
317bf215546Sopenharmony_ci         break;
318bf215546Sopenharmony_ci      case GL_BYTE:
319bf215546Sopenharmony_ci         {
320bf215546Sopenharmony_ci            GLuint i;
321bf215546Sopenharmony_ci            const GLbyte *s = (const GLbyte *) src;
322bf215546Sopenharmony_ci            for (i = 0; i < n; i++)
323bf215546Sopenharmony_ci               indexes[i] = s[i];
324bf215546Sopenharmony_ci         }
325bf215546Sopenharmony_ci         break;
326bf215546Sopenharmony_ci      case GL_UNSIGNED_SHORT:
327bf215546Sopenharmony_ci         {
328bf215546Sopenharmony_ci            GLuint i;
329bf215546Sopenharmony_ci            const GLushort *s = (const GLushort *) src;
330bf215546Sopenharmony_ci            if (unpack->SwapBytes) {
331bf215546Sopenharmony_ci               for (i = 0; i < n; i++) {
332bf215546Sopenharmony_ci                  GLushort value = s[i];
333bf215546Sopenharmony_ci                  SWAP2BYTE(value);
334bf215546Sopenharmony_ci                  indexes[i] = value;
335bf215546Sopenharmony_ci               }
336bf215546Sopenharmony_ci            }
337bf215546Sopenharmony_ci            else {
338bf215546Sopenharmony_ci               for (i = 0; i < n; i++)
339bf215546Sopenharmony_ci                  indexes[i] = s[i];
340bf215546Sopenharmony_ci            }
341bf215546Sopenharmony_ci         }
342bf215546Sopenharmony_ci         break;
343bf215546Sopenharmony_ci      case GL_SHORT:
344bf215546Sopenharmony_ci         {
345bf215546Sopenharmony_ci            GLuint i;
346bf215546Sopenharmony_ci            const GLshort *s = (const GLshort *) src;
347bf215546Sopenharmony_ci            if (unpack->SwapBytes) {
348bf215546Sopenharmony_ci               for (i = 0; i < n; i++) {
349bf215546Sopenharmony_ci                  GLshort value = s[i];
350bf215546Sopenharmony_ci                  SWAP2BYTE(value);
351bf215546Sopenharmony_ci                  indexes[i] = value;
352bf215546Sopenharmony_ci               }
353bf215546Sopenharmony_ci            }
354bf215546Sopenharmony_ci            else {
355bf215546Sopenharmony_ci               for (i = 0; i < n; i++)
356bf215546Sopenharmony_ci                  indexes[i] = s[i];
357bf215546Sopenharmony_ci            }
358bf215546Sopenharmony_ci         }
359bf215546Sopenharmony_ci         break;
360bf215546Sopenharmony_ci      case GL_UNSIGNED_INT:
361bf215546Sopenharmony_ci         {
362bf215546Sopenharmony_ci            GLuint i;
363bf215546Sopenharmony_ci            const GLuint *s = (const GLuint *) src;
364bf215546Sopenharmony_ci            if (unpack->SwapBytes) {
365bf215546Sopenharmony_ci               for (i = 0; i < n; i++) {
366bf215546Sopenharmony_ci                  GLuint value = s[i];
367bf215546Sopenharmony_ci                  SWAP4BYTE(value);
368bf215546Sopenharmony_ci                  indexes[i] = value;
369bf215546Sopenharmony_ci               }
370bf215546Sopenharmony_ci            }
371bf215546Sopenharmony_ci            else {
372bf215546Sopenharmony_ci               for (i = 0; i < n; i++)
373bf215546Sopenharmony_ci                  indexes[i] = s[i];
374bf215546Sopenharmony_ci            }
375bf215546Sopenharmony_ci         }
376bf215546Sopenharmony_ci         break;
377bf215546Sopenharmony_ci      case GL_INT:
378bf215546Sopenharmony_ci         {
379bf215546Sopenharmony_ci            GLuint i;
380bf215546Sopenharmony_ci            const GLint *s = (const GLint *) src;
381bf215546Sopenharmony_ci            if (unpack->SwapBytes) {
382bf215546Sopenharmony_ci               for (i = 0; i < n; i++) {
383bf215546Sopenharmony_ci                  GLint value = s[i];
384bf215546Sopenharmony_ci                  SWAP4BYTE(value);
385bf215546Sopenharmony_ci                  indexes[i] = value;
386bf215546Sopenharmony_ci               }
387bf215546Sopenharmony_ci            }
388bf215546Sopenharmony_ci            else {
389bf215546Sopenharmony_ci               for (i = 0; i < n; i++)
390bf215546Sopenharmony_ci                  indexes[i] = s[i];
391bf215546Sopenharmony_ci            }
392bf215546Sopenharmony_ci         }
393bf215546Sopenharmony_ci         break;
394bf215546Sopenharmony_ci      case GL_FLOAT:
395bf215546Sopenharmony_ci         {
396bf215546Sopenharmony_ci            GLuint i;
397bf215546Sopenharmony_ci            const GLfloat *s = (const GLfloat *) src;
398bf215546Sopenharmony_ci            if (unpack->SwapBytes) {
399bf215546Sopenharmony_ci               for (i = 0; i < n; i++) {
400bf215546Sopenharmony_ci                  GLfloat value = s[i];
401bf215546Sopenharmony_ci                  SWAP4BYTE(value);
402bf215546Sopenharmony_ci                  indexes[i] = (GLuint) value;
403bf215546Sopenharmony_ci               }
404bf215546Sopenharmony_ci            }
405bf215546Sopenharmony_ci            else {
406bf215546Sopenharmony_ci               for (i = 0; i < n; i++)
407bf215546Sopenharmony_ci                  indexes[i] = (GLuint) s[i];
408bf215546Sopenharmony_ci            }
409bf215546Sopenharmony_ci         }
410bf215546Sopenharmony_ci         break;
411bf215546Sopenharmony_ci      case GL_HALF_FLOAT_ARB:
412bf215546Sopenharmony_ci      case GL_HALF_FLOAT_OES:
413bf215546Sopenharmony_ci         {
414bf215546Sopenharmony_ci            GLuint i;
415bf215546Sopenharmony_ci            const GLhalfARB *s = (const GLhalfARB *) src;
416bf215546Sopenharmony_ci            if (unpack->SwapBytes) {
417bf215546Sopenharmony_ci               for (i = 0; i < n; i++) {
418bf215546Sopenharmony_ci                  GLhalfARB value = s[i];
419bf215546Sopenharmony_ci                  SWAP2BYTE(value);
420bf215546Sopenharmony_ci                  indexes[i] = (GLuint) _mesa_half_to_float(value);
421bf215546Sopenharmony_ci               }
422bf215546Sopenharmony_ci            }
423bf215546Sopenharmony_ci            else {
424bf215546Sopenharmony_ci               for (i = 0; i < n; i++)
425bf215546Sopenharmony_ci                  indexes[i] = (GLuint) _mesa_half_to_float(s[i]);
426bf215546Sopenharmony_ci            }
427bf215546Sopenharmony_ci         }
428bf215546Sopenharmony_ci         break;
429bf215546Sopenharmony_ci      case GL_UNSIGNED_INT_24_8_EXT:
430bf215546Sopenharmony_ci         {
431bf215546Sopenharmony_ci            GLuint i;
432bf215546Sopenharmony_ci            const GLuint *s = (const GLuint *) src;
433bf215546Sopenharmony_ci            if (unpack->SwapBytes) {
434bf215546Sopenharmony_ci               for (i = 0; i < n; i++) {
435bf215546Sopenharmony_ci                  GLuint value = s[i];
436bf215546Sopenharmony_ci                  SWAP4BYTE(value);
437bf215546Sopenharmony_ci                  indexes[i] = value & 0xff;  /* lower 8 bits */
438bf215546Sopenharmony_ci               }
439bf215546Sopenharmony_ci            }
440bf215546Sopenharmony_ci            else {
441bf215546Sopenharmony_ci               for (i = 0; i < n; i++)
442bf215546Sopenharmony_ci                  indexes[i] = s[i] & 0xff;  /* lower 8 bits */
443bf215546Sopenharmony_ci            }
444bf215546Sopenharmony_ci         }
445bf215546Sopenharmony_ci         break;
446bf215546Sopenharmony_ci      case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
447bf215546Sopenharmony_ci         {
448bf215546Sopenharmony_ci            GLuint i;
449bf215546Sopenharmony_ci            const GLuint *s = (const GLuint *) src;
450bf215546Sopenharmony_ci            if (unpack->SwapBytes) {
451bf215546Sopenharmony_ci               for (i = 0; i < n; i++) {
452bf215546Sopenharmony_ci                  GLuint value = s[i*2+1];
453bf215546Sopenharmony_ci                  SWAP4BYTE(value);
454bf215546Sopenharmony_ci                  indexes[i] = value & 0xff;  /* lower 8 bits */
455bf215546Sopenharmony_ci               }
456bf215546Sopenharmony_ci            }
457bf215546Sopenharmony_ci            else {
458bf215546Sopenharmony_ci               for (i = 0; i < n; i++)
459bf215546Sopenharmony_ci                  indexes[i] = s[i*2+1] & 0xff;  /* lower 8 bits */
460bf215546Sopenharmony_ci            }
461bf215546Sopenharmony_ci         }
462bf215546Sopenharmony_ci         break;
463bf215546Sopenharmony_ci
464bf215546Sopenharmony_ci      default:
465bf215546Sopenharmony_ci         unreachable("bad srcType in extract_uint_indexes");
466bf215546Sopenharmony_ci   }
467bf215546Sopenharmony_ci}
468bf215546Sopenharmony_ci
469bf215546Sopenharmony_ci
470bf215546Sopenharmony_ci/*
471bf215546Sopenharmony_ci * Unpack a row of stencil data from a client buffer according to
472bf215546Sopenharmony_ci * the pixel unpacking parameters.
473bf215546Sopenharmony_ci * This is (or will be) used by glDrawPixels
474bf215546Sopenharmony_ci *
475bf215546Sopenharmony_ci * Args:  ctx - the context
476bf215546Sopenharmony_ci *        n - number of pixels
477bf215546Sopenharmony_ci *        dstType - destination data type
478bf215546Sopenharmony_ci *        dest - destination array
479bf215546Sopenharmony_ci *        srcType - source pixel type
480bf215546Sopenharmony_ci *        source - source data pointer
481bf215546Sopenharmony_ci *        srcPacking - pixel unpacking parameters
482bf215546Sopenharmony_ci *        transferOps - apply offset/bias/lookup ops?
483bf215546Sopenharmony_ci */
484bf215546Sopenharmony_civoid
485bf215546Sopenharmony_ci_mesa_unpack_stencil_span( struct gl_context *ctx, GLuint n,
486bf215546Sopenharmony_ci                           GLenum dstType, GLvoid *dest,
487bf215546Sopenharmony_ci                           GLenum srcType, const GLvoid *source,
488bf215546Sopenharmony_ci                           const struct gl_pixelstore_attrib *srcPacking,
489bf215546Sopenharmony_ci                           GLbitfield transferOps )
490bf215546Sopenharmony_ci{
491bf215546Sopenharmony_ci   assert(srcType == GL_BITMAP ||
492bf215546Sopenharmony_ci          srcType == GL_UNSIGNED_BYTE ||
493bf215546Sopenharmony_ci          srcType == GL_BYTE ||
494bf215546Sopenharmony_ci          srcType == GL_UNSIGNED_SHORT ||
495bf215546Sopenharmony_ci          srcType == GL_SHORT ||
496bf215546Sopenharmony_ci          srcType == GL_UNSIGNED_INT ||
497bf215546Sopenharmony_ci          srcType == GL_INT ||
498bf215546Sopenharmony_ci          srcType == GL_UNSIGNED_INT_24_8_EXT ||
499bf215546Sopenharmony_ci          srcType == GL_HALF_FLOAT_ARB ||
500bf215546Sopenharmony_ci          srcType == GL_HALF_FLOAT_OES ||
501bf215546Sopenharmony_ci          srcType == GL_FLOAT ||
502bf215546Sopenharmony_ci          srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
503bf215546Sopenharmony_ci
504bf215546Sopenharmony_ci   assert(dstType == GL_UNSIGNED_BYTE ||
505bf215546Sopenharmony_ci          dstType == GL_UNSIGNED_SHORT ||
506bf215546Sopenharmony_ci          dstType == GL_UNSIGNED_INT ||
507bf215546Sopenharmony_ci          dstType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
508bf215546Sopenharmony_ci
509bf215546Sopenharmony_ci   /* only shift and offset apply to stencil */
510bf215546Sopenharmony_ci   transferOps &= IMAGE_SHIFT_OFFSET_BIT;
511bf215546Sopenharmony_ci
512bf215546Sopenharmony_ci   /*
513bf215546Sopenharmony_ci    * Try simple cases first
514bf215546Sopenharmony_ci    */
515bf215546Sopenharmony_ci   if (transferOps == 0 &&
516bf215546Sopenharmony_ci       !ctx->Pixel.MapStencilFlag &&
517bf215546Sopenharmony_ci       srcType == GL_UNSIGNED_BYTE &&
518bf215546Sopenharmony_ci       dstType == GL_UNSIGNED_BYTE) {
519bf215546Sopenharmony_ci      memcpy(dest, source, n * sizeof(GLubyte));
520bf215546Sopenharmony_ci   }
521bf215546Sopenharmony_ci   else if (transferOps == 0 &&
522bf215546Sopenharmony_ci            !ctx->Pixel.MapStencilFlag &&
523bf215546Sopenharmony_ci            srcType == GL_UNSIGNED_INT &&
524bf215546Sopenharmony_ci            dstType == GL_UNSIGNED_INT &&
525bf215546Sopenharmony_ci            !srcPacking->SwapBytes) {
526bf215546Sopenharmony_ci      memcpy(dest, source, n * sizeof(GLuint));
527bf215546Sopenharmony_ci   }
528bf215546Sopenharmony_ci   else {
529bf215546Sopenharmony_ci      /*
530bf215546Sopenharmony_ci       * general solution
531bf215546Sopenharmony_ci       */
532bf215546Sopenharmony_ci      GLuint *indexes = malloc(n * sizeof(GLuint));
533bf215546Sopenharmony_ci
534bf215546Sopenharmony_ci      if (!indexes) {
535bf215546Sopenharmony_ci         _mesa_error(ctx, GL_OUT_OF_MEMORY, "stencil unpacking");
536bf215546Sopenharmony_ci         return;
537bf215546Sopenharmony_ci      }
538bf215546Sopenharmony_ci
539bf215546Sopenharmony_ci      extract_uint_indexes(n, indexes, GL_STENCIL_INDEX, srcType, source,
540bf215546Sopenharmony_ci                           srcPacking);
541bf215546Sopenharmony_ci
542bf215546Sopenharmony_ci      if (transferOps & IMAGE_SHIFT_OFFSET_BIT) {
543bf215546Sopenharmony_ci         /* shift and offset indexes */
544bf215546Sopenharmony_ci         _mesa_shift_and_offset_ci(ctx, n, indexes);
545bf215546Sopenharmony_ci      }
546bf215546Sopenharmony_ci
547bf215546Sopenharmony_ci      if (ctx->Pixel.MapStencilFlag) {
548bf215546Sopenharmony_ci         /* Apply stencil lookup table */
549bf215546Sopenharmony_ci         const GLuint mask = ctx->PixelMaps.StoS.Size - 1;
550bf215546Sopenharmony_ci         GLuint i;
551bf215546Sopenharmony_ci         for (i = 0; i < n; i++) {
552bf215546Sopenharmony_ci            indexes[i] = (GLuint)ctx->PixelMaps.StoS.Map[ indexes[i] & mask ];
553bf215546Sopenharmony_ci         }
554bf215546Sopenharmony_ci      }
555bf215546Sopenharmony_ci
556bf215546Sopenharmony_ci      /* convert to dest type */
557bf215546Sopenharmony_ci      switch (dstType) {
558bf215546Sopenharmony_ci         case GL_UNSIGNED_BYTE:
559bf215546Sopenharmony_ci            {
560bf215546Sopenharmony_ci               GLubyte *dst = (GLubyte *) dest;
561bf215546Sopenharmony_ci               GLuint i;
562bf215546Sopenharmony_ci               for (i = 0; i < n; i++) {
563bf215546Sopenharmony_ci                  dst[i] = (GLubyte) (indexes[i] & 0xff);
564bf215546Sopenharmony_ci               }
565bf215546Sopenharmony_ci            }
566bf215546Sopenharmony_ci            break;
567bf215546Sopenharmony_ci         case GL_UNSIGNED_SHORT:
568bf215546Sopenharmony_ci            {
569bf215546Sopenharmony_ci               GLuint *dst = (GLuint *) dest;
570bf215546Sopenharmony_ci               GLuint i;
571bf215546Sopenharmony_ci               for (i = 0; i < n; i++) {
572bf215546Sopenharmony_ci                  dst[i] = (GLushort) (indexes[i] & 0xffff);
573bf215546Sopenharmony_ci               }
574bf215546Sopenharmony_ci            }
575bf215546Sopenharmony_ci            break;
576bf215546Sopenharmony_ci         case GL_UNSIGNED_INT:
577bf215546Sopenharmony_ci            memcpy(dest, indexes, n * sizeof(GLuint));
578bf215546Sopenharmony_ci            break;
579bf215546Sopenharmony_ci         case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
580bf215546Sopenharmony_ci            {
581bf215546Sopenharmony_ci               GLuint *dst = (GLuint *) dest;
582bf215546Sopenharmony_ci               GLuint i;
583bf215546Sopenharmony_ci               for (i = 0; i < n; i++) {
584bf215546Sopenharmony_ci                  dst[i*2+1] = indexes[i] & 0xff; /* lower 8 bits */
585bf215546Sopenharmony_ci               }
586bf215546Sopenharmony_ci            }
587bf215546Sopenharmony_ci            break;
588bf215546Sopenharmony_ci         default:
589bf215546Sopenharmony_ci            unreachable("bad dstType in _mesa_unpack_stencil_span");
590bf215546Sopenharmony_ci      }
591bf215546Sopenharmony_ci
592bf215546Sopenharmony_ci      free(indexes);
593bf215546Sopenharmony_ci   }
594bf215546Sopenharmony_ci}
595bf215546Sopenharmony_ci
596bf215546Sopenharmony_ci
597bf215546Sopenharmony_civoid
598bf215546Sopenharmony_ci_mesa_pack_stencil_span( struct gl_context *ctx, GLuint n,
599bf215546Sopenharmony_ci                         GLenum dstType, GLvoid *dest, const GLubyte *source,
600bf215546Sopenharmony_ci                         const struct gl_pixelstore_attrib *dstPacking )
601bf215546Sopenharmony_ci{
602bf215546Sopenharmony_ci   GLubyte *stencil = malloc(n * sizeof(GLubyte));
603bf215546Sopenharmony_ci
604bf215546Sopenharmony_ci   if (!stencil) {
605bf215546Sopenharmony_ci      _mesa_error(ctx, GL_OUT_OF_MEMORY, "stencil packing");
606bf215546Sopenharmony_ci      return;
607bf215546Sopenharmony_ci   }
608bf215546Sopenharmony_ci
609bf215546Sopenharmony_ci   if (ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset ||
610bf215546Sopenharmony_ci       ctx->Pixel.MapStencilFlag) {
611bf215546Sopenharmony_ci      /* make a copy of input */
612bf215546Sopenharmony_ci      memcpy(stencil, source, n * sizeof(GLubyte));
613bf215546Sopenharmony_ci      _mesa_apply_stencil_transfer_ops(ctx, n, stencil);
614bf215546Sopenharmony_ci      source = stencil;
615bf215546Sopenharmony_ci   }
616bf215546Sopenharmony_ci
617bf215546Sopenharmony_ci   switch (dstType) {
618bf215546Sopenharmony_ci   case GL_UNSIGNED_BYTE:
619bf215546Sopenharmony_ci      memcpy(dest, source, n);
620bf215546Sopenharmony_ci      break;
621bf215546Sopenharmony_ci   case GL_BYTE:
622bf215546Sopenharmony_ci      {
623bf215546Sopenharmony_ci         GLbyte *dst = (GLbyte *) dest;
624bf215546Sopenharmony_ci         GLuint i;
625bf215546Sopenharmony_ci         for (i=0;i<n;i++) {
626bf215546Sopenharmony_ci            dst[i] = (GLbyte) (source[i] & 0x7f);
627bf215546Sopenharmony_ci         }
628bf215546Sopenharmony_ci      }
629bf215546Sopenharmony_ci      break;
630bf215546Sopenharmony_ci   case GL_UNSIGNED_SHORT:
631bf215546Sopenharmony_ci      {
632bf215546Sopenharmony_ci         GLushort *dst = (GLushort *) dest;
633bf215546Sopenharmony_ci         GLuint i;
634bf215546Sopenharmony_ci         for (i=0;i<n;i++) {
635bf215546Sopenharmony_ci            dst[i] = (GLushort) source[i];
636bf215546Sopenharmony_ci         }
637bf215546Sopenharmony_ci         if (dstPacking->SwapBytes) {
638bf215546Sopenharmony_ci            _mesa_swap2( (GLushort *) dst, n );
639bf215546Sopenharmony_ci         }
640bf215546Sopenharmony_ci      }
641bf215546Sopenharmony_ci      break;
642bf215546Sopenharmony_ci   case GL_SHORT:
643bf215546Sopenharmony_ci      {
644bf215546Sopenharmony_ci         GLshort *dst = (GLshort *) dest;
645bf215546Sopenharmony_ci         GLuint i;
646bf215546Sopenharmony_ci         for (i=0;i<n;i++) {
647bf215546Sopenharmony_ci            dst[i] = (GLshort) source[i];
648bf215546Sopenharmony_ci         }
649bf215546Sopenharmony_ci         if (dstPacking->SwapBytes) {
650bf215546Sopenharmony_ci            _mesa_swap2( (GLushort *) dst, n );
651bf215546Sopenharmony_ci         }
652bf215546Sopenharmony_ci      }
653bf215546Sopenharmony_ci      break;
654bf215546Sopenharmony_ci   case GL_UNSIGNED_INT:
655bf215546Sopenharmony_ci      {
656bf215546Sopenharmony_ci         GLuint *dst = (GLuint *) dest;
657bf215546Sopenharmony_ci         GLuint i;
658bf215546Sopenharmony_ci         for (i=0;i<n;i++) {
659bf215546Sopenharmony_ci            dst[i] = (GLuint) source[i];
660bf215546Sopenharmony_ci         }
661bf215546Sopenharmony_ci         if (dstPacking->SwapBytes) {
662bf215546Sopenharmony_ci            _mesa_swap4( (GLuint *) dst, n );
663bf215546Sopenharmony_ci         }
664bf215546Sopenharmony_ci      }
665bf215546Sopenharmony_ci      break;
666bf215546Sopenharmony_ci   case GL_INT:
667bf215546Sopenharmony_ci      {
668bf215546Sopenharmony_ci         GLint *dst = (GLint *) dest;
669bf215546Sopenharmony_ci         GLuint i;
670bf215546Sopenharmony_ci         for (i=0;i<n;i++) {
671bf215546Sopenharmony_ci            dst[i] = (GLint) source[i];
672bf215546Sopenharmony_ci         }
673bf215546Sopenharmony_ci         if (dstPacking->SwapBytes) {
674bf215546Sopenharmony_ci            _mesa_swap4( (GLuint *) dst, n );
675bf215546Sopenharmony_ci         }
676bf215546Sopenharmony_ci      }
677bf215546Sopenharmony_ci      break;
678bf215546Sopenharmony_ci   case GL_FLOAT:
679bf215546Sopenharmony_ci      {
680bf215546Sopenharmony_ci         GLfloat *dst = (GLfloat *) dest;
681bf215546Sopenharmony_ci         GLuint i;
682bf215546Sopenharmony_ci         for (i=0;i<n;i++) {
683bf215546Sopenharmony_ci            dst[i] = (GLfloat) source[i];
684bf215546Sopenharmony_ci         }
685bf215546Sopenharmony_ci         if (dstPacking->SwapBytes) {
686bf215546Sopenharmony_ci            _mesa_swap4( (GLuint *) dst, n );
687bf215546Sopenharmony_ci         }
688bf215546Sopenharmony_ci      }
689bf215546Sopenharmony_ci      break;
690bf215546Sopenharmony_ci   case GL_HALF_FLOAT_ARB:
691bf215546Sopenharmony_ci   case GL_HALF_FLOAT_OES:
692bf215546Sopenharmony_ci      {
693bf215546Sopenharmony_ci         GLhalfARB *dst = (GLhalfARB *) dest;
694bf215546Sopenharmony_ci         GLuint i;
695bf215546Sopenharmony_ci         for (i=0;i<n;i++) {
696bf215546Sopenharmony_ci            dst[i] = _mesa_float_to_half( (float) source[i] );
697bf215546Sopenharmony_ci         }
698bf215546Sopenharmony_ci         if (dstPacking->SwapBytes) {
699bf215546Sopenharmony_ci            _mesa_swap2( (GLushort *) dst, n );
700bf215546Sopenharmony_ci         }
701bf215546Sopenharmony_ci      }
702bf215546Sopenharmony_ci      break;
703bf215546Sopenharmony_ci   case GL_BITMAP:
704bf215546Sopenharmony_ci      if (dstPacking->LsbFirst) {
705bf215546Sopenharmony_ci         GLubyte *dst = (GLubyte *) dest;
706bf215546Sopenharmony_ci         GLint shift = 0;
707bf215546Sopenharmony_ci         GLuint i;
708bf215546Sopenharmony_ci         for (i = 0; i < n; i++) {
709bf215546Sopenharmony_ci            if (shift == 0)
710bf215546Sopenharmony_ci               *dst = 0;
711bf215546Sopenharmony_ci            *dst |= ((source[i] != 0) << shift);
712bf215546Sopenharmony_ci            shift++;
713bf215546Sopenharmony_ci            if (shift == 8) {
714bf215546Sopenharmony_ci               shift = 0;
715bf215546Sopenharmony_ci               dst++;
716bf215546Sopenharmony_ci            }
717bf215546Sopenharmony_ci         }
718bf215546Sopenharmony_ci      }
719bf215546Sopenharmony_ci      else {
720bf215546Sopenharmony_ci         GLubyte *dst = (GLubyte *) dest;
721bf215546Sopenharmony_ci         GLint shift = 7;
722bf215546Sopenharmony_ci         GLuint i;
723bf215546Sopenharmony_ci         for (i = 0; i < n; i++) {
724bf215546Sopenharmony_ci            if (shift == 7)
725bf215546Sopenharmony_ci               *dst = 0;
726bf215546Sopenharmony_ci            *dst |= ((source[i] != 0) << shift);
727bf215546Sopenharmony_ci            shift--;
728bf215546Sopenharmony_ci            if (shift < 0) {
729bf215546Sopenharmony_ci               shift = 7;
730bf215546Sopenharmony_ci               dst++;
731bf215546Sopenharmony_ci            }
732bf215546Sopenharmony_ci         }
733bf215546Sopenharmony_ci      }
734bf215546Sopenharmony_ci      break;
735bf215546Sopenharmony_ci   default:
736bf215546Sopenharmony_ci      unreachable("bad type in _mesa_pack_index_span");
737bf215546Sopenharmony_ci   }
738bf215546Sopenharmony_ci
739bf215546Sopenharmony_ci   free(stencil);
740bf215546Sopenharmony_ci}
741bf215546Sopenharmony_ci
742bf215546Sopenharmony_ci#define DEPTH_VALUES(GLTYPE, GLTYPE2FLOAT)                              \
743bf215546Sopenharmony_ci    do {                                                                \
744bf215546Sopenharmony_ci        GLuint i;                                                       \
745bf215546Sopenharmony_ci        const GLTYPE *src = (const GLTYPE *)source;                     \
746bf215546Sopenharmony_ci        for (i = 0; i < n; i++) {                                       \
747bf215546Sopenharmony_ci            GLTYPE value = src[i];                                      \
748bf215546Sopenharmony_ci            if (srcPacking->SwapBytes) {                                \
749bf215546Sopenharmony_ci                if (sizeof(GLTYPE) == 2) {                              \
750bf215546Sopenharmony_ci                    SWAP2BYTE(value);                                   \
751bf215546Sopenharmony_ci                } else if (sizeof(GLTYPE) == 4) {                       \
752bf215546Sopenharmony_ci                    SWAP4BYTE(value);                                   \
753bf215546Sopenharmony_ci                }                                                       \
754bf215546Sopenharmony_ci            }                                                           \
755bf215546Sopenharmony_ci            depthValues[i] = GLTYPE2FLOAT(value);                       \
756bf215546Sopenharmony_ci        }                                                               \
757bf215546Sopenharmony_ci    } while (0)
758bf215546Sopenharmony_ci
759bf215546Sopenharmony_ci
760bf215546Sopenharmony_ci/**
761bf215546Sopenharmony_ci * Unpack a row of depth/z values from memory, returning GLushort, GLuint
762bf215546Sopenharmony_ci * or GLfloat values.
763bf215546Sopenharmony_ci * The glPixelTransfer (scale/bias) params will be applied.
764bf215546Sopenharmony_ci *
765bf215546Sopenharmony_ci * \param dstType  one of GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, GL_FLOAT
766bf215546Sopenharmony_ci * \param depthMax  max value for returned GLushort or GLuint values
767bf215546Sopenharmony_ci *                  (ignored for GLfloat).
768bf215546Sopenharmony_ci */
769bf215546Sopenharmony_civoid
770bf215546Sopenharmony_ci_mesa_unpack_depth_span( struct gl_context *ctx, GLuint n,
771bf215546Sopenharmony_ci                         GLenum dstType, GLvoid *dest, GLuint depthMax,
772bf215546Sopenharmony_ci                         GLenum srcType, const GLvoid *source,
773bf215546Sopenharmony_ci                         const struct gl_pixelstore_attrib *srcPacking )
774bf215546Sopenharmony_ci{
775bf215546Sopenharmony_ci   GLfloat *depthTemp = NULL, *depthValues;
776bf215546Sopenharmony_ci   GLboolean needClamp = GL_FALSE;
777bf215546Sopenharmony_ci
778bf215546Sopenharmony_ci   /* Look for special cases first.
779bf215546Sopenharmony_ci    * Not only are these faster, they're less prone to numeric conversion
780bf215546Sopenharmony_ci    * problems.  Otherwise, converting from an int type to a float then
781bf215546Sopenharmony_ci    * back to an int type can introduce errors that will show up as
782bf215546Sopenharmony_ci    * artifacts in things like depth peeling which uses glCopyTexImage.
783bf215546Sopenharmony_ci    */
784bf215546Sopenharmony_ci   if (ctx->Pixel.DepthScale == 1.0F && ctx->Pixel.DepthBias == 0.0F) {
785bf215546Sopenharmony_ci      if (srcType == GL_UNSIGNED_INT && dstType == GL_UNSIGNED_SHORT) {
786bf215546Sopenharmony_ci         const GLuint *src = (const GLuint *) source;
787bf215546Sopenharmony_ci         GLushort *dst = (GLushort *) dest;
788bf215546Sopenharmony_ci         GLuint i;
789bf215546Sopenharmony_ci         for (i = 0; i < n; i++) {
790bf215546Sopenharmony_ci            dst[i] = src[i] >> 16;
791bf215546Sopenharmony_ci         }
792bf215546Sopenharmony_ci         return;
793bf215546Sopenharmony_ci      }
794bf215546Sopenharmony_ci      if (srcType == GL_UNSIGNED_SHORT
795bf215546Sopenharmony_ci          && dstType == GL_UNSIGNED_INT
796bf215546Sopenharmony_ci          && depthMax == 0xffffffff) {
797bf215546Sopenharmony_ci         const GLushort *src = (const GLushort *) source;
798bf215546Sopenharmony_ci         GLuint *dst = (GLuint *) dest;
799bf215546Sopenharmony_ci         GLuint i;
800bf215546Sopenharmony_ci         for (i = 0; i < n; i++) {
801bf215546Sopenharmony_ci            dst[i] = src[i] | (src[i] << 16);
802bf215546Sopenharmony_ci         }
803bf215546Sopenharmony_ci         return;
804bf215546Sopenharmony_ci      }
805bf215546Sopenharmony_ci      if (srcType == GL_UNSIGNED_INT_24_8
806bf215546Sopenharmony_ci          && dstType == GL_UNSIGNED_INT
807bf215546Sopenharmony_ci          && depthMax == 0xffffff) {
808bf215546Sopenharmony_ci         const GLuint *src = (const GLuint *) source;
809bf215546Sopenharmony_ci         GLuint *dst = (GLuint *) dest;
810bf215546Sopenharmony_ci         GLuint i;
811bf215546Sopenharmony_ci         for (i = 0; i < n; i++) {
812bf215546Sopenharmony_ci            dst[i] = src[i] >> 8;
813bf215546Sopenharmony_ci         }
814bf215546Sopenharmony_ci         return;
815bf215546Sopenharmony_ci      }
816bf215546Sopenharmony_ci      /* XXX may want to add additional cases here someday */
817bf215546Sopenharmony_ci   }
818bf215546Sopenharmony_ci
819bf215546Sopenharmony_ci   /* general case path follows */
820bf215546Sopenharmony_ci
821bf215546Sopenharmony_ci   if (dstType == GL_FLOAT) {
822bf215546Sopenharmony_ci      depthValues = (GLfloat *) dest;
823bf215546Sopenharmony_ci   }
824bf215546Sopenharmony_ci   else {
825bf215546Sopenharmony_ci      depthTemp = malloc(n * sizeof(GLfloat));
826bf215546Sopenharmony_ci      if (!depthTemp) {
827bf215546Sopenharmony_ci         _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking");
828bf215546Sopenharmony_ci         return;
829bf215546Sopenharmony_ci      }
830bf215546Sopenharmony_ci
831bf215546Sopenharmony_ci      depthValues = depthTemp;
832bf215546Sopenharmony_ci   }
833bf215546Sopenharmony_ci
834bf215546Sopenharmony_ci   /* Convert incoming values to GLfloat.  Some conversions will require
835bf215546Sopenharmony_ci    * clamping, below.
836bf215546Sopenharmony_ci    */
837bf215546Sopenharmony_ci   switch (srcType) {
838bf215546Sopenharmony_ci      case GL_BYTE:
839bf215546Sopenharmony_ci         DEPTH_VALUES(GLbyte, BYTE_TO_FLOATZ);
840bf215546Sopenharmony_ci         needClamp = GL_TRUE;
841bf215546Sopenharmony_ci         break;
842bf215546Sopenharmony_ci      case GL_UNSIGNED_BYTE:
843bf215546Sopenharmony_ci         DEPTH_VALUES(GLubyte, UBYTE_TO_FLOAT);
844bf215546Sopenharmony_ci         break;
845bf215546Sopenharmony_ci      case GL_SHORT:
846bf215546Sopenharmony_ci         DEPTH_VALUES(GLshort, SHORT_TO_FLOATZ);
847bf215546Sopenharmony_ci         needClamp = GL_TRUE;
848bf215546Sopenharmony_ci         break;
849bf215546Sopenharmony_ci      case GL_UNSIGNED_SHORT:
850bf215546Sopenharmony_ci         DEPTH_VALUES(GLushort, USHORT_TO_FLOAT);
851bf215546Sopenharmony_ci         break;
852bf215546Sopenharmony_ci      case GL_INT:
853bf215546Sopenharmony_ci         DEPTH_VALUES(GLint, INT_TO_FLOAT);
854bf215546Sopenharmony_ci         needClamp = GL_TRUE;
855bf215546Sopenharmony_ci         break;
856bf215546Sopenharmony_ci      case GL_UNSIGNED_INT:
857bf215546Sopenharmony_ci         DEPTH_VALUES(GLuint, UINT_TO_FLOAT);
858bf215546Sopenharmony_ci         break;
859bf215546Sopenharmony_ci      case GL_UNSIGNED_INT_24_8_EXT: /* GL_EXT_packed_depth_stencil */
860bf215546Sopenharmony_ci         if (dstType == GL_UNSIGNED_INT_24_8_EXT &&
861bf215546Sopenharmony_ci             depthMax == 0xffffff &&
862bf215546Sopenharmony_ci             ctx->Pixel.DepthScale == 1.0F &&
863bf215546Sopenharmony_ci             ctx->Pixel.DepthBias == 0.0F) {
864bf215546Sopenharmony_ci            const GLuint *src = (const GLuint *) source;
865bf215546Sopenharmony_ci            GLuint *zValues = (GLuint *) dest;
866bf215546Sopenharmony_ci            GLuint i;
867bf215546Sopenharmony_ci            for (i = 0; i < n; i++) {
868bf215546Sopenharmony_ci                GLuint value = src[i];
869bf215546Sopenharmony_ci                if (srcPacking->SwapBytes) {
870bf215546Sopenharmony_ci                    SWAP4BYTE(value);
871bf215546Sopenharmony_ci                }
872bf215546Sopenharmony_ci                zValues[i] = value & 0xffffff00;
873bf215546Sopenharmony_ci            }
874bf215546Sopenharmony_ci            free(depthTemp);
875bf215546Sopenharmony_ci            return;
876bf215546Sopenharmony_ci         }
877bf215546Sopenharmony_ci         else {
878bf215546Sopenharmony_ci            const GLuint *src = (const GLuint *) source;
879bf215546Sopenharmony_ci            const GLfloat scale = 1.0f / 0xffffff;
880bf215546Sopenharmony_ci            GLuint i;
881bf215546Sopenharmony_ci            for (i = 0; i < n; i++) {
882bf215546Sopenharmony_ci                GLuint value = src[i];
883bf215546Sopenharmony_ci                if (srcPacking->SwapBytes) {
884bf215546Sopenharmony_ci                    SWAP4BYTE(value);
885bf215546Sopenharmony_ci                }
886bf215546Sopenharmony_ci                depthValues[i] = (value >> 8) * scale;
887bf215546Sopenharmony_ci            }
888bf215546Sopenharmony_ci         }
889bf215546Sopenharmony_ci         break;
890bf215546Sopenharmony_ci      case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
891bf215546Sopenharmony_ci         {
892bf215546Sopenharmony_ci            GLuint i;
893bf215546Sopenharmony_ci            const GLfloat *src = (const GLfloat *)source;
894bf215546Sopenharmony_ci            for (i = 0; i < n; i++) {
895bf215546Sopenharmony_ci               GLfloat value = src[i * 2];
896bf215546Sopenharmony_ci               if (srcPacking->SwapBytes) {
897bf215546Sopenharmony_ci                  SWAP4BYTE(value);
898bf215546Sopenharmony_ci               }
899bf215546Sopenharmony_ci               depthValues[i] = value;
900bf215546Sopenharmony_ci            }
901bf215546Sopenharmony_ci            needClamp = GL_TRUE;
902bf215546Sopenharmony_ci         }
903bf215546Sopenharmony_ci         break;
904bf215546Sopenharmony_ci      case GL_FLOAT:
905bf215546Sopenharmony_ci         DEPTH_VALUES(GLfloat, 1*);
906bf215546Sopenharmony_ci         needClamp = GL_TRUE;
907bf215546Sopenharmony_ci         break;
908bf215546Sopenharmony_ci      case GL_HALF_FLOAT_ARB:
909bf215546Sopenharmony_ci      case GL_HALF_FLOAT_OES:
910bf215546Sopenharmony_ci         {
911bf215546Sopenharmony_ci            GLuint i;
912bf215546Sopenharmony_ci            const GLhalfARB *src = (const GLhalfARB *) source;
913bf215546Sopenharmony_ci            for (i = 0; i < n; i++) {
914bf215546Sopenharmony_ci               GLhalfARB value = src[i];
915bf215546Sopenharmony_ci               if (srcPacking->SwapBytes) {
916bf215546Sopenharmony_ci                  SWAP2BYTE(value);
917bf215546Sopenharmony_ci               }
918bf215546Sopenharmony_ci               depthValues[i] = _mesa_half_to_float(value);
919bf215546Sopenharmony_ci            }
920bf215546Sopenharmony_ci            needClamp = GL_TRUE;
921bf215546Sopenharmony_ci         }
922bf215546Sopenharmony_ci         break;
923bf215546Sopenharmony_ci      default:
924bf215546Sopenharmony_ci         _mesa_problem(NULL, "bad type in _mesa_unpack_depth_span()");
925bf215546Sopenharmony_ci         free(depthTemp);
926bf215546Sopenharmony_ci         return;
927bf215546Sopenharmony_ci   }
928bf215546Sopenharmony_ci
929bf215546Sopenharmony_ci   /* apply depth scale and bias */
930bf215546Sopenharmony_ci   {
931bf215546Sopenharmony_ci      const GLfloat scale = ctx->Pixel.DepthScale;
932bf215546Sopenharmony_ci      const GLfloat bias = ctx->Pixel.DepthBias;
933bf215546Sopenharmony_ci      if (scale != 1.0F || bias != 0.0F) {
934bf215546Sopenharmony_ci         GLuint i;
935bf215546Sopenharmony_ci         for (i = 0; i < n; i++) {
936bf215546Sopenharmony_ci            depthValues[i] = depthValues[i] * scale + bias;
937bf215546Sopenharmony_ci         }
938bf215546Sopenharmony_ci         needClamp = GL_TRUE;
939bf215546Sopenharmony_ci      }
940bf215546Sopenharmony_ci   }
941bf215546Sopenharmony_ci
942bf215546Sopenharmony_ci   /* clamp to [0, 1] */
943bf215546Sopenharmony_ci   if (needClamp) {
944bf215546Sopenharmony_ci      GLuint i;
945bf215546Sopenharmony_ci      for (i = 0; i < n; i++) {
946bf215546Sopenharmony_ci         depthValues[i] = CLAMP(depthValues[i], 0.0F, 1.0F);
947bf215546Sopenharmony_ci      }
948bf215546Sopenharmony_ci   }
949bf215546Sopenharmony_ci
950bf215546Sopenharmony_ci   /*
951bf215546Sopenharmony_ci    * Convert values to dstType
952bf215546Sopenharmony_ci    */
953bf215546Sopenharmony_ci   if (dstType == GL_UNSIGNED_INT) {
954bf215546Sopenharmony_ci      GLuint *zValues = (GLuint *) dest;
955bf215546Sopenharmony_ci      GLuint i;
956bf215546Sopenharmony_ci      if (depthMax <= 0xffffff) {
957bf215546Sopenharmony_ci         /* no overflow worries */
958bf215546Sopenharmony_ci         for (i = 0; i < n; i++) {
959bf215546Sopenharmony_ci            zValues[i] = (GLuint) (depthValues[i] * (GLfloat) depthMax);
960bf215546Sopenharmony_ci         }
961bf215546Sopenharmony_ci      }
962bf215546Sopenharmony_ci      else {
963bf215546Sopenharmony_ci         /* need to use double precision to prevent overflow problems */
964bf215546Sopenharmony_ci         for (i = 0; i < n; i++) {
965bf215546Sopenharmony_ci            GLdouble z = depthValues[i] * (GLdouble) depthMax;
966bf215546Sopenharmony_ci            if (z >= (GLdouble) 0xffffffff)
967bf215546Sopenharmony_ci               zValues[i] = 0xffffffff;
968bf215546Sopenharmony_ci            else
969bf215546Sopenharmony_ci               zValues[i] = (GLuint) z;
970bf215546Sopenharmony_ci         }
971bf215546Sopenharmony_ci      }
972bf215546Sopenharmony_ci   }
973bf215546Sopenharmony_ci   else if (dstType == GL_UNSIGNED_SHORT) {
974bf215546Sopenharmony_ci      GLushort *zValues = (GLushort *) dest;
975bf215546Sopenharmony_ci      GLuint i;
976bf215546Sopenharmony_ci      assert(depthMax <= 0xffff);
977bf215546Sopenharmony_ci      for (i = 0; i < n; i++) {
978bf215546Sopenharmony_ci         zValues[i] = (GLushort) (depthValues[i] * (GLfloat) depthMax);
979bf215546Sopenharmony_ci      }
980bf215546Sopenharmony_ci   }
981bf215546Sopenharmony_ci   else if (dstType == GL_FLOAT) {
982bf215546Sopenharmony_ci      /* Nothing to do. depthValues is pointing to dest. */
983bf215546Sopenharmony_ci   }
984bf215546Sopenharmony_ci   else if (dstType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV) {
985bf215546Sopenharmony_ci      GLfloat *zValues = (GLfloat*) dest;
986bf215546Sopenharmony_ci      GLuint i;
987bf215546Sopenharmony_ci      for (i = 0; i < n; i++) {
988bf215546Sopenharmony_ci         zValues[i*2] = depthValues[i];
989bf215546Sopenharmony_ci      }
990bf215546Sopenharmony_ci   }
991bf215546Sopenharmony_ci   else {
992bf215546Sopenharmony_ci      assert(0);
993bf215546Sopenharmony_ci   }
994bf215546Sopenharmony_ci
995bf215546Sopenharmony_ci   free(depthTemp);
996bf215546Sopenharmony_ci}
997bf215546Sopenharmony_ci
998bf215546Sopenharmony_ci
999bf215546Sopenharmony_ci/*
1000bf215546Sopenharmony_ci * Pack an array of depth values.  The values are floats in [0,1].
1001bf215546Sopenharmony_ci */
1002bf215546Sopenharmony_civoid
1003bf215546Sopenharmony_ci_mesa_pack_depth_span( struct gl_context *ctx, GLuint n, GLvoid *dest,
1004bf215546Sopenharmony_ci                       GLenum dstType, const GLfloat *depthSpan,
1005bf215546Sopenharmony_ci                       const struct gl_pixelstore_attrib *dstPacking )
1006bf215546Sopenharmony_ci{
1007bf215546Sopenharmony_ci   GLfloat *depthCopy = malloc(n * sizeof(GLfloat));
1008bf215546Sopenharmony_ci   if (!depthCopy) {
1009bf215546Sopenharmony_ci      _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel packing");
1010bf215546Sopenharmony_ci      return;
1011bf215546Sopenharmony_ci   }
1012bf215546Sopenharmony_ci
1013bf215546Sopenharmony_ci   if (ctx->Pixel.DepthScale != 1.0F || ctx->Pixel.DepthBias != 0.0F) {
1014bf215546Sopenharmony_ci      memcpy(depthCopy, depthSpan, n * sizeof(GLfloat));
1015bf215546Sopenharmony_ci      _mesa_scale_and_bias_depth(ctx, n, depthCopy);
1016bf215546Sopenharmony_ci      depthSpan = depthCopy;
1017bf215546Sopenharmony_ci   }
1018bf215546Sopenharmony_ci
1019bf215546Sopenharmony_ci   switch (dstType) {
1020bf215546Sopenharmony_ci   case GL_UNSIGNED_BYTE:
1021bf215546Sopenharmony_ci      {
1022bf215546Sopenharmony_ci         GLubyte *dst = (GLubyte *) dest;
1023bf215546Sopenharmony_ci         GLuint i;
1024bf215546Sopenharmony_ci         for (i = 0; i < n; i++) {
1025bf215546Sopenharmony_ci            dst[i] = FLOAT_TO_UBYTE( depthSpan[i] );
1026bf215546Sopenharmony_ci         }
1027bf215546Sopenharmony_ci      }
1028bf215546Sopenharmony_ci      break;
1029bf215546Sopenharmony_ci   case GL_BYTE:
1030bf215546Sopenharmony_ci      {
1031bf215546Sopenharmony_ci         GLbyte *dst = (GLbyte *) dest;
1032bf215546Sopenharmony_ci         GLuint i;
1033bf215546Sopenharmony_ci         for (i = 0; i < n; i++) {
1034bf215546Sopenharmony_ci            dst[i] = FLOAT_TO_BYTE( depthSpan[i] );
1035bf215546Sopenharmony_ci         }
1036bf215546Sopenharmony_ci      }
1037bf215546Sopenharmony_ci      break;
1038bf215546Sopenharmony_ci   case GL_UNSIGNED_SHORT:
1039bf215546Sopenharmony_ci      {
1040bf215546Sopenharmony_ci         GLushort *dst = (GLushort *) dest;
1041bf215546Sopenharmony_ci         GLuint i;
1042bf215546Sopenharmony_ci         for (i = 0; i < n; i++) {
1043bf215546Sopenharmony_ci            CLAMPED_FLOAT_TO_USHORT(dst[i], depthSpan[i]);
1044bf215546Sopenharmony_ci         }
1045bf215546Sopenharmony_ci         if (dstPacking->SwapBytes) {
1046bf215546Sopenharmony_ci            _mesa_swap2( (GLushort *) dst, n );
1047bf215546Sopenharmony_ci         }
1048bf215546Sopenharmony_ci      }
1049bf215546Sopenharmony_ci      break;
1050bf215546Sopenharmony_ci   case GL_SHORT:
1051bf215546Sopenharmony_ci      {
1052bf215546Sopenharmony_ci         GLshort *dst = (GLshort *) dest;
1053bf215546Sopenharmony_ci         GLuint i;
1054bf215546Sopenharmony_ci         for (i = 0; i < n; i++) {
1055bf215546Sopenharmony_ci            dst[i] = FLOAT_TO_SHORT( depthSpan[i] );
1056bf215546Sopenharmony_ci         }
1057bf215546Sopenharmony_ci         if (dstPacking->SwapBytes) {
1058bf215546Sopenharmony_ci            _mesa_swap2( (GLushort *) dst, n );
1059bf215546Sopenharmony_ci         }
1060bf215546Sopenharmony_ci      }
1061bf215546Sopenharmony_ci      break;
1062bf215546Sopenharmony_ci   case GL_UNSIGNED_INT_24_8:
1063bf215546Sopenharmony_ci      {
1064bf215546Sopenharmony_ci         const GLdouble scale = (GLdouble) 0xffffff;
1065bf215546Sopenharmony_ci         GLuint *dst = (GLuint *) dest;
1066bf215546Sopenharmony_ci         GLuint i;
1067bf215546Sopenharmony_ci         for (i = 0; i < n; i++) {
1068bf215546Sopenharmony_ci            GLuint z = (GLuint) (depthSpan[i] * scale);
1069bf215546Sopenharmony_ci            assert(z <= 0xffffff);
1070bf215546Sopenharmony_ci            dst[i] = (z << 8);
1071bf215546Sopenharmony_ci         }
1072bf215546Sopenharmony_ci         if (dstPacking->SwapBytes) {
1073bf215546Sopenharmony_ci            _mesa_swap4( (GLuint *) dst, n );
1074bf215546Sopenharmony_ci         }
1075bf215546Sopenharmony_ci         break;
1076bf215546Sopenharmony_ci      }
1077bf215546Sopenharmony_ci   case GL_UNSIGNED_INT:
1078bf215546Sopenharmony_ci      {
1079bf215546Sopenharmony_ci         GLuint *dst = (GLuint *) dest;
1080bf215546Sopenharmony_ci         GLuint i;
1081bf215546Sopenharmony_ci         for (i = 0; i < n; i++) {
1082bf215546Sopenharmony_ci            dst[i] = FLOAT_TO_UINT( depthSpan[i] );
1083bf215546Sopenharmony_ci         }
1084bf215546Sopenharmony_ci         if (dstPacking->SwapBytes) {
1085bf215546Sopenharmony_ci            _mesa_swap4( (GLuint *) dst, n );
1086bf215546Sopenharmony_ci         }
1087bf215546Sopenharmony_ci      }
1088bf215546Sopenharmony_ci      break;
1089bf215546Sopenharmony_ci   case GL_INT:
1090bf215546Sopenharmony_ci      {
1091bf215546Sopenharmony_ci         GLint *dst = (GLint *) dest;
1092bf215546Sopenharmony_ci         GLuint i;
1093bf215546Sopenharmony_ci         for (i = 0; i < n; i++) {
1094bf215546Sopenharmony_ci            dst[i] = FLOAT_TO_INT( depthSpan[i] );
1095bf215546Sopenharmony_ci         }
1096bf215546Sopenharmony_ci         if (dstPacking->SwapBytes) {
1097bf215546Sopenharmony_ci            _mesa_swap4( (GLuint *) dst, n );
1098bf215546Sopenharmony_ci         }
1099bf215546Sopenharmony_ci      }
1100bf215546Sopenharmony_ci      break;
1101bf215546Sopenharmony_ci   case GL_FLOAT:
1102bf215546Sopenharmony_ci      {
1103bf215546Sopenharmony_ci         GLfloat *dst = (GLfloat *) dest;
1104bf215546Sopenharmony_ci         GLuint i;
1105bf215546Sopenharmony_ci         for (i = 0; i < n; i++) {
1106bf215546Sopenharmony_ci            dst[i] = depthSpan[i];
1107bf215546Sopenharmony_ci         }
1108bf215546Sopenharmony_ci         if (dstPacking->SwapBytes) {
1109bf215546Sopenharmony_ci            _mesa_swap4( (GLuint *) dst, n );
1110bf215546Sopenharmony_ci         }
1111bf215546Sopenharmony_ci      }
1112bf215546Sopenharmony_ci      break;
1113bf215546Sopenharmony_ci   case GL_HALF_FLOAT_ARB:
1114bf215546Sopenharmony_ci   case GL_HALF_FLOAT_OES:
1115bf215546Sopenharmony_ci      {
1116bf215546Sopenharmony_ci         GLhalfARB *dst = (GLhalfARB *) dest;
1117bf215546Sopenharmony_ci         GLuint i;
1118bf215546Sopenharmony_ci         for (i = 0; i < n; i++) {
1119bf215546Sopenharmony_ci            dst[i] = _mesa_float_to_half(depthSpan[i]);
1120bf215546Sopenharmony_ci         }
1121bf215546Sopenharmony_ci         if (dstPacking->SwapBytes) {
1122bf215546Sopenharmony_ci            _mesa_swap2( (GLushort *) dst, n );
1123bf215546Sopenharmony_ci         }
1124bf215546Sopenharmony_ci      }
1125bf215546Sopenharmony_ci      break;
1126bf215546Sopenharmony_ci   default:
1127bf215546Sopenharmony_ci      unreachable("bad type in _mesa_pack_depth_span()");
1128bf215546Sopenharmony_ci   }
1129bf215546Sopenharmony_ci
1130bf215546Sopenharmony_ci   free(depthCopy);
1131bf215546Sopenharmony_ci}
1132bf215546Sopenharmony_ci
1133bf215546Sopenharmony_ci
1134bf215546Sopenharmony_ci
1135bf215546Sopenharmony_ci/**
1136bf215546Sopenharmony_ci * Pack depth and stencil values as GL_DEPTH_STENCIL (GL_UNSIGNED_INT_24_8 etc)
1137bf215546Sopenharmony_ci */
1138bf215546Sopenharmony_civoid
1139bf215546Sopenharmony_ci_mesa_pack_depth_stencil_span(struct gl_context *ctx,GLuint n,
1140bf215546Sopenharmony_ci                              GLenum dstType, GLuint *dest,
1141bf215546Sopenharmony_ci                              const GLfloat *depthVals,
1142bf215546Sopenharmony_ci                              const GLubyte *stencilVals,
1143bf215546Sopenharmony_ci                              const struct gl_pixelstore_attrib *dstPacking)
1144bf215546Sopenharmony_ci{
1145bf215546Sopenharmony_ci   GLfloat *depthCopy = malloc(n * sizeof(GLfloat));
1146bf215546Sopenharmony_ci   GLubyte *stencilCopy = malloc(n * sizeof(GLubyte));
1147bf215546Sopenharmony_ci   GLuint i;
1148bf215546Sopenharmony_ci
1149bf215546Sopenharmony_ci   if (!depthCopy || !stencilCopy) {
1150bf215546Sopenharmony_ci      _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel packing");
1151bf215546Sopenharmony_ci      free(depthCopy);
1152bf215546Sopenharmony_ci      free(stencilCopy);
1153bf215546Sopenharmony_ci      return;
1154bf215546Sopenharmony_ci   }
1155bf215546Sopenharmony_ci
1156bf215546Sopenharmony_ci   if (ctx->Pixel.DepthScale != 1.0F || ctx->Pixel.DepthBias != 0.0F) {
1157bf215546Sopenharmony_ci      memcpy(depthCopy, depthVals, n * sizeof(GLfloat));
1158bf215546Sopenharmony_ci      _mesa_scale_and_bias_depth(ctx, n, depthCopy);
1159bf215546Sopenharmony_ci      depthVals = depthCopy;
1160bf215546Sopenharmony_ci   }
1161bf215546Sopenharmony_ci
1162bf215546Sopenharmony_ci   if (ctx->Pixel.IndexShift ||
1163bf215546Sopenharmony_ci       ctx->Pixel.IndexOffset ||
1164bf215546Sopenharmony_ci       ctx->Pixel.MapStencilFlag) {
1165bf215546Sopenharmony_ci      memcpy(stencilCopy, stencilVals, n * sizeof(GLubyte));
1166bf215546Sopenharmony_ci      _mesa_apply_stencil_transfer_ops(ctx, n, stencilCopy);
1167bf215546Sopenharmony_ci      stencilVals = stencilCopy;
1168bf215546Sopenharmony_ci   }
1169bf215546Sopenharmony_ci
1170bf215546Sopenharmony_ci   switch (dstType) {
1171bf215546Sopenharmony_ci   case GL_UNSIGNED_INT_24_8:
1172bf215546Sopenharmony_ci      for (i = 0; i < n; i++) {
1173bf215546Sopenharmony_ci         GLuint z = (GLuint) (depthVals[i] * 0xffffff);
1174bf215546Sopenharmony_ci         dest[i] = (z << 8) | (stencilVals[i] & 0xff);
1175bf215546Sopenharmony_ci      }
1176bf215546Sopenharmony_ci      break;
1177bf215546Sopenharmony_ci   case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
1178bf215546Sopenharmony_ci      for (i = 0; i < n; i++) {
1179bf215546Sopenharmony_ci         ((GLfloat*)dest)[i*2] = depthVals[i];
1180bf215546Sopenharmony_ci         dest[i*2+1] = stencilVals[i] & 0xff;
1181bf215546Sopenharmony_ci      }
1182bf215546Sopenharmony_ci      break;
1183bf215546Sopenharmony_ci   }
1184bf215546Sopenharmony_ci
1185bf215546Sopenharmony_ci   if (dstPacking->SwapBytes) {
1186bf215546Sopenharmony_ci      _mesa_swap4(dest, n);
1187bf215546Sopenharmony_ci   }
1188bf215546Sopenharmony_ci
1189bf215546Sopenharmony_ci   free(depthCopy);
1190bf215546Sopenharmony_ci   free(stencilCopy);
1191bf215546Sopenharmony_ci}
1192bf215546Sopenharmony_ci
1193bf215546Sopenharmony_ci
1194bf215546Sopenharmony_ci
1195bf215546Sopenharmony_ci/**
1196bf215546Sopenharmony_ci * Unpack image data.  Apply byte swapping, byte flipping (bitmap).
1197bf215546Sopenharmony_ci * Return all image data in a contiguous block.  This is used when we
1198bf215546Sopenharmony_ci * compile glDrawPixels, glTexImage, etc into a display list.  We
1199bf215546Sopenharmony_ci * need a copy of the data in a standard format.
1200bf215546Sopenharmony_ci */
1201bf215546Sopenharmony_civoid *
1202bf215546Sopenharmony_ci_mesa_unpack_image( GLuint dimensions,
1203bf215546Sopenharmony_ci                    GLsizei width, GLsizei height, GLsizei depth,
1204bf215546Sopenharmony_ci                    GLenum format, GLenum type, const GLvoid *pixels,
1205bf215546Sopenharmony_ci                    const struct gl_pixelstore_attrib *unpack )
1206bf215546Sopenharmony_ci{
1207bf215546Sopenharmony_ci   GLint bytesPerRow, compsPerRow;
1208bf215546Sopenharmony_ci   GLboolean flipBytes, swap2, swap4;
1209bf215546Sopenharmony_ci
1210bf215546Sopenharmony_ci   if (!pixels)
1211bf215546Sopenharmony_ci      return NULL;  /* not necessarily an error */
1212bf215546Sopenharmony_ci
1213bf215546Sopenharmony_ci   if (width <= 0 || height <= 0 || depth <= 0)
1214bf215546Sopenharmony_ci      return NULL;  /* generate error later */
1215bf215546Sopenharmony_ci
1216bf215546Sopenharmony_ci   if (type == GL_BITMAP) {
1217bf215546Sopenharmony_ci      bytesPerRow = (width + 7) >> 3;
1218bf215546Sopenharmony_ci      flipBytes = unpack->LsbFirst;
1219bf215546Sopenharmony_ci      swap2 = swap4 = GL_FALSE;
1220bf215546Sopenharmony_ci      compsPerRow = 0;
1221bf215546Sopenharmony_ci   }
1222bf215546Sopenharmony_ci   else {
1223bf215546Sopenharmony_ci      const GLint bytesPerPixel = _mesa_bytes_per_pixel(format, type);
1224bf215546Sopenharmony_ci      GLint components = _mesa_components_in_format(format);
1225bf215546Sopenharmony_ci      GLint bytesPerComp;
1226bf215546Sopenharmony_ci
1227bf215546Sopenharmony_ci      if (_mesa_type_is_packed(type))
1228bf215546Sopenharmony_ci          components = 1;
1229bf215546Sopenharmony_ci
1230bf215546Sopenharmony_ci      if (bytesPerPixel <= 0 || components <= 0)
1231bf215546Sopenharmony_ci         return NULL;   /* bad format or type.  generate error later */
1232bf215546Sopenharmony_ci      bytesPerRow = bytesPerPixel * width;
1233bf215546Sopenharmony_ci      bytesPerComp = bytesPerPixel / components;
1234bf215546Sopenharmony_ci      flipBytes = GL_FALSE;
1235bf215546Sopenharmony_ci      swap2 = (bytesPerComp == 2) && unpack->SwapBytes;
1236bf215546Sopenharmony_ci      swap4 = (bytesPerComp == 4) && unpack->SwapBytes;
1237bf215546Sopenharmony_ci      compsPerRow = components * width;
1238bf215546Sopenharmony_ci      assert(compsPerRow >= width);
1239bf215546Sopenharmony_ci   }
1240bf215546Sopenharmony_ci
1241bf215546Sopenharmony_ci   {
1242bf215546Sopenharmony_ci      GLubyte *destBuffer
1243bf215546Sopenharmony_ci         = malloc(bytesPerRow * height * depth);
1244bf215546Sopenharmony_ci      GLubyte *dst;
1245bf215546Sopenharmony_ci      GLint img, row;
1246bf215546Sopenharmony_ci      if (!destBuffer)
1247bf215546Sopenharmony_ci         return NULL;   /* generate GL_OUT_OF_MEMORY later */
1248bf215546Sopenharmony_ci
1249bf215546Sopenharmony_ci      dst = destBuffer;
1250bf215546Sopenharmony_ci      for (img = 0; img < depth; img++) {
1251bf215546Sopenharmony_ci         for (row = 0; row < height; row++) {
1252bf215546Sopenharmony_ci            const GLvoid *src = _mesa_image_address(dimensions, unpack, pixels,
1253bf215546Sopenharmony_ci                               width, height, format, type, img, row, 0);
1254bf215546Sopenharmony_ci
1255bf215546Sopenharmony_ci            if ((type == GL_BITMAP) && (unpack->SkipPixels & 0x7)) {
1256bf215546Sopenharmony_ci               GLint i;
1257bf215546Sopenharmony_ci               flipBytes = GL_FALSE;
1258bf215546Sopenharmony_ci               if (unpack->LsbFirst) {
1259bf215546Sopenharmony_ci                  GLubyte srcMask = 1 << (unpack->SkipPixels & 0x7);
1260bf215546Sopenharmony_ci                  GLubyte dstMask = 128;
1261bf215546Sopenharmony_ci                  const GLubyte *s = src;
1262bf215546Sopenharmony_ci                  GLubyte *d = dst;
1263bf215546Sopenharmony_ci                  *d = 0;
1264bf215546Sopenharmony_ci                  for (i = 0; i < width; i++) {
1265bf215546Sopenharmony_ci                     if (*s & srcMask) {
1266bf215546Sopenharmony_ci                        *d |= dstMask;
1267bf215546Sopenharmony_ci                     }
1268bf215546Sopenharmony_ci                     if (srcMask == 128) {
1269bf215546Sopenharmony_ci                        srcMask = 1;
1270bf215546Sopenharmony_ci                        s++;
1271bf215546Sopenharmony_ci                     }
1272bf215546Sopenharmony_ci                     else {
1273bf215546Sopenharmony_ci                        srcMask = srcMask << 1;
1274bf215546Sopenharmony_ci                     }
1275bf215546Sopenharmony_ci                     if (dstMask == 1) {
1276bf215546Sopenharmony_ci                        dstMask = 128;
1277bf215546Sopenharmony_ci                        d++;
1278bf215546Sopenharmony_ci                        *d = 0;
1279bf215546Sopenharmony_ci                     }
1280bf215546Sopenharmony_ci                     else {
1281bf215546Sopenharmony_ci                        dstMask = dstMask >> 1;
1282bf215546Sopenharmony_ci                     }
1283bf215546Sopenharmony_ci                  }
1284bf215546Sopenharmony_ci               }
1285bf215546Sopenharmony_ci               else {
1286bf215546Sopenharmony_ci                  GLubyte srcMask = 128 >> (unpack->SkipPixels & 0x7);
1287bf215546Sopenharmony_ci                  GLubyte dstMask = 128;
1288bf215546Sopenharmony_ci                  const GLubyte *s = src;
1289bf215546Sopenharmony_ci                  GLubyte *d = dst;
1290bf215546Sopenharmony_ci                  *d = 0;
1291bf215546Sopenharmony_ci                  for (i = 0; i < width; i++) {
1292bf215546Sopenharmony_ci                     if (*s & srcMask) {
1293bf215546Sopenharmony_ci                        *d |= dstMask;
1294bf215546Sopenharmony_ci                     }
1295bf215546Sopenharmony_ci                     if (srcMask == 1) {
1296bf215546Sopenharmony_ci                        srcMask = 128;
1297bf215546Sopenharmony_ci                        s++;
1298bf215546Sopenharmony_ci                     }
1299bf215546Sopenharmony_ci                     else {
1300bf215546Sopenharmony_ci                        srcMask = srcMask >> 1;
1301bf215546Sopenharmony_ci                     }
1302bf215546Sopenharmony_ci                     if (dstMask == 1) {
1303bf215546Sopenharmony_ci                        dstMask = 128;
1304bf215546Sopenharmony_ci                        d++;
1305bf215546Sopenharmony_ci                        *d = 0;
1306bf215546Sopenharmony_ci                     }
1307bf215546Sopenharmony_ci                     else {
1308bf215546Sopenharmony_ci                        dstMask = dstMask >> 1;
1309bf215546Sopenharmony_ci                     }
1310bf215546Sopenharmony_ci                  }
1311bf215546Sopenharmony_ci               }
1312bf215546Sopenharmony_ci            }
1313bf215546Sopenharmony_ci            else {
1314bf215546Sopenharmony_ci               memcpy(dst, src, bytesPerRow);
1315bf215546Sopenharmony_ci            }
1316bf215546Sopenharmony_ci
1317bf215546Sopenharmony_ci            /* byte flipping/swapping */
1318bf215546Sopenharmony_ci            if (flipBytes) {
1319bf215546Sopenharmony_ci               flip_bytes((GLubyte *) dst, bytesPerRow);
1320bf215546Sopenharmony_ci            }
1321bf215546Sopenharmony_ci            else if (swap2) {
1322bf215546Sopenharmony_ci               _mesa_swap2((GLushort*) dst, compsPerRow);
1323bf215546Sopenharmony_ci            }
1324bf215546Sopenharmony_ci            else if (swap4) {
1325bf215546Sopenharmony_ci               _mesa_swap4((GLuint*) dst, compsPerRow);
1326bf215546Sopenharmony_ci            }
1327bf215546Sopenharmony_ci            dst += bytesPerRow;
1328bf215546Sopenharmony_ci         }
1329bf215546Sopenharmony_ci      }
1330bf215546Sopenharmony_ci      return destBuffer;
1331bf215546Sopenharmony_ci   }
1332bf215546Sopenharmony_ci}
1333bf215546Sopenharmony_ci
1334bf215546Sopenharmony_civoid
1335bf215546Sopenharmony_ci_mesa_pack_luminance_from_rgba_float(GLuint n, GLfloat rgba[][4],
1336bf215546Sopenharmony_ci                                     GLvoid *dstAddr, GLenum dst_format,
1337bf215546Sopenharmony_ci                                     GLbitfield transferOps)
1338bf215546Sopenharmony_ci{
1339bf215546Sopenharmony_ci   int i;
1340bf215546Sopenharmony_ci   GLfloat *dst = (GLfloat *) dstAddr;
1341bf215546Sopenharmony_ci
1342bf215546Sopenharmony_ci   switch (dst_format) {
1343bf215546Sopenharmony_ci   case GL_LUMINANCE:
1344bf215546Sopenharmony_ci      if (transferOps & IMAGE_CLAMP_BIT) {
1345bf215546Sopenharmony_ci         for (i = 0; i < n; i++) {
1346bf215546Sopenharmony_ci            GLfloat sum = rgba[i][RCOMP] + rgba[i][GCOMP] + rgba[i][BCOMP];
1347bf215546Sopenharmony_ci            dst[i] = CLAMP(sum, 0.0F, 1.0F);
1348bf215546Sopenharmony_ci         }
1349bf215546Sopenharmony_ci      } else {
1350bf215546Sopenharmony_ci         for (i = 0; i < n; i++) {
1351bf215546Sopenharmony_ci            dst[i] = rgba[i][RCOMP] + rgba[i][GCOMP] + rgba[i][BCOMP];
1352bf215546Sopenharmony_ci         }
1353bf215546Sopenharmony_ci      }
1354bf215546Sopenharmony_ci      return;
1355bf215546Sopenharmony_ci   case GL_LUMINANCE_ALPHA:
1356bf215546Sopenharmony_ci      if (transferOps & IMAGE_CLAMP_BIT) {
1357bf215546Sopenharmony_ci         for (i = 0; i < n; i++) {
1358bf215546Sopenharmony_ci            GLfloat sum = rgba[i][RCOMP] + rgba[i][GCOMP] + rgba[i][BCOMP];
1359bf215546Sopenharmony_ci            dst[2*i] = CLAMP(sum, 0.0F, 1.0F);
1360bf215546Sopenharmony_ci            dst[2*i+1] = rgba[i][ACOMP];
1361bf215546Sopenharmony_ci         }
1362bf215546Sopenharmony_ci      } else {
1363bf215546Sopenharmony_ci         for (i = 0; i < n; i++) {
1364bf215546Sopenharmony_ci            dst[2*i] = rgba[i][RCOMP] + rgba[i][GCOMP] + rgba[i][BCOMP];
1365bf215546Sopenharmony_ci            dst[2*i+1] = rgba[i][ACOMP];
1366bf215546Sopenharmony_ci         }
1367bf215546Sopenharmony_ci      }
1368bf215546Sopenharmony_ci      return;
1369bf215546Sopenharmony_ci   default:
1370bf215546Sopenharmony_ci      assert(!"Unsupported format");
1371bf215546Sopenharmony_ci   }
1372bf215546Sopenharmony_ci}
1373bf215546Sopenharmony_ci
1374bf215546Sopenharmony_cistatic int32_t
1375bf215546Sopenharmony_ciclamp_sint64_to_sint32(int64_t src)
1376bf215546Sopenharmony_ci{
1377bf215546Sopenharmony_ci   return CLAMP(src, INT32_MIN, INT32_MAX);
1378bf215546Sopenharmony_ci}
1379bf215546Sopenharmony_ci
1380bf215546Sopenharmony_cistatic int32_t
1381bf215546Sopenharmony_ciclamp_sint64_to_uint32(int64_t src)
1382bf215546Sopenharmony_ci{
1383bf215546Sopenharmony_ci   return CLAMP(src, 0, UINT32_MAX);
1384bf215546Sopenharmony_ci}
1385bf215546Sopenharmony_ci
1386bf215546Sopenharmony_cistatic int32_t
1387bf215546Sopenharmony_ciclamp_uint64_to_uint32(uint64_t src)
1388bf215546Sopenharmony_ci{
1389bf215546Sopenharmony_ci   return MIN2(src, UINT32_MAX);
1390bf215546Sopenharmony_ci}
1391bf215546Sopenharmony_ci
1392bf215546Sopenharmony_cistatic int32_t
1393bf215546Sopenharmony_ciclamp_uint64_to_sint32(uint64_t src)
1394bf215546Sopenharmony_ci{
1395bf215546Sopenharmony_ci   return MIN2(src, INT32_MAX);
1396bf215546Sopenharmony_ci}
1397bf215546Sopenharmony_ci
1398bf215546Sopenharmony_cistatic int32_t
1399bf215546Sopenharmony_ciconvert_integer_luminance64(int64_t src64, int bits,
1400bf215546Sopenharmony_ci                            bool dst_is_signed, bool src_is_signed)
1401bf215546Sopenharmony_ci{
1402bf215546Sopenharmony_ci   int32_t src32;
1403bf215546Sopenharmony_ci
1404bf215546Sopenharmony_ci   /* Clamp Luminance value from 64-bit to 32-bit. Consider if we need
1405bf215546Sopenharmony_ci    * any signed<->unsigned conversion too.
1406bf215546Sopenharmony_ci    */
1407bf215546Sopenharmony_ci   if (src_is_signed && dst_is_signed)
1408bf215546Sopenharmony_ci      src32 = clamp_sint64_to_sint32(src64);
1409bf215546Sopenharmony_ci   else if (src_is_signed && !dst_is_signed)
1410bf215546Sopenharmony_ci      src32 = clamp_sint64_to_uint32(src64);
1411bf215546Sopenharmony_ci   else if (!src_is_signed && dst_is_signed)
1412bf215546Sopenharmony_ci      src32 = clamp_uint64_to_sint32(src64);
1413bf215546Sopenharmony_ci   else
1414bf215546Sopenharmony_ci      src32 = clamp_uint64_to_uint32(src64);
1415bf215546Sopenharmony_ci
1416bf215546Sopenharmony_ci   /* If the dst type is < 32-bit, we need an extra clamp */
1417bf215546Sopenharmony_ci   if (bits == 32) {
1418bf215546Sopenharmony_ci      return src32;
1419bf215546Sopenharmony_ci   } else {
1420bf215546Sopenharmony_ci      if (dst_is_signed)
1421bf215546Sopenharmony_ci         return _mesa_signed_to_signed(src32, bits);
1422bf215546Sopenharmony_ci      else
1423bf215546Sopenharmony_ci         return _mesa_unsigned_to_unsigned(src32, bits);
1424bf215546Sopenharmony_ci   }
1425bf215546Sopenharmony_ci}
1426bf215546Sopenharmony_ci
1427bf215546Sopenharmony_cistatic int32_t
1428bf215546Sopenharmony_ciconvert_integer(int32_t src, int bits, bool dst_is_signed, bool src_is_signed)
1429bf215546Sopenharmony_ci{
1430bf215546Sopenharmony_ci   if (src_is_signed && dst_is_signed)
1431bf215546Sopenharmony_ci      return _mesa_signed_to_signed(src, bits);
1432bf215546Sopenharmony_ci   else if (src_is_signed && !dst_is_signed)
1433bf215546Sopenharmony_ci      return _mesa_signed_to_unsigned(src, bits);
1434bf215546Sopenharmony_ci   else if (!src_is_signed && dst_is_signed)
1435bf215546Sopenharmony_ci      return _mesa_unsigned_to_signed(src, bits);
1436bf215546Sopenharmony_ci   else
1437bf215546Sopenharmony_ci      return _mesa_unsigned_to_unsigned(src, bits);
1438bf215546Sopenharmony_ci}
1439bf215546Sopenharmony_ci
1440bf215546Sopenharmony_civoid
1441bf215546Sopenharmony_ci_mesa_pack_luminance_from_rgba_integer(GLuint n,
1442bf215546Sopenharmony_ci                                       GLuint rgba[][4], bool rgba_is_signed,
1443bf215546Sopenharmony_ci                                       GLvoid *dstAddr,
1444bf215546Sopenharmony_ci                                       GLenum dst_format,
1445bf215546Sopenharmony_ci                                       GLenum dst_type)
1446bf215546Sopenharmony_ci{
1447bf215546Sopenharmony_ci   int i;
1448bf215546Sopenharmony_ci   int64_t lum64;
1449bf215546Sopenharmony_ci   int32_t lum32, alpha;
1450bf215546Sopenharmony_ci   bool dst_is_signed;
1451bf215546Sopenharmony_ci   int dst_bits;
1452bf215546Sopenharmony_ci
1453bf215546Sopenharmony_ci   assert(dst_format == GL_LUMINANCE_INTEGER_EXT ||
1454bf215546Sopenharmony_ci          dst_format == GL_LUMINANCE_ALPHA_INTEGER_EXT);
1455bf215546Sopenharmony_ci
1456bf215546Sopenharmony_ci   /* We first compute luminance values as a 64-bit addition of the
1457bf215546Sopenharmony_ci    * 32-bit R,G,B components, then we clamp the result to the dst type size.
1458bf215546Sopenharmony_ci    *
1459bf215546Sopenharmony_ci    * Notice that this operation involves casting the 32-bit R,G,B components
1460bf215546Sopenharmony_ci    * to 64-bit before the addition. Since rgba is defined as a GLuint array
1461bf215546Sopenharmony_ci    * we need to be careful when rgba packs signed data and make sure
1462bf215546Sopenharmony_ci    * that we cast to a 32-bit signed integer values before casting them to
1463bf215546Sopenharmony_ci    * 64-bit signed integers.
1464bf215546Sopenharmony_ci    */
1465bf215546Sopenharmony_ci   dst_is_signed = (dst_type == GL_BYTE || dst_type == GL_SHORT ||
1466bf215546Sopenharmony_ci                    dst_type == GL_INT);
1467bf215546Sopenharmony_ci
1468bf215546Sopenharmony_ci   dst_bits = _mesa_sizeof_type(dst_type) * 8;
1469bf215546Sopenharmony_ci   assert(dst_bits > 0);
1470bf215546Sopenharmony_ci
1471bf215546Sopenharmony_ci   switch (dst_format) {
1472bf215546Sopenharmony_ci   case GL_LUMINANCE_INTEGER_EXT:
1473bf215546Sopenharmony_ci      for (i = 0; i < n; i++) {
1474bf215546Sopenharmony_ci         if (!rgba_is_signed) {
1475bf215546Sopenharmony_ci            lum64 = (uint64_t) rgba[i][RCOMP] +
1476bf215546Sopenharmony_ci                    (uint64_t) rgba[i][GCOMP] +
1477bf215546Sopenharmony_ci                    (uint64_t) rgba[i][BCOMP];
1478bf215546Sopenharmony_ci         } else {
1479bf215546Sopenharmony_ci            lum64 = (int64_t) ((int32_t) rgba[i][RCOMP]) +
1480bf215546Sopenharmony_ci                    (int64_t) ((int32_t) rgba[i][GCOMP]) +
1481bf215546Sopenharmony_ci                    (int64_t) ((int32_t) rgba[i][BCOMP]);
1482bf215546Sopenharmony_ci         }
1483bf215546Sopenharmony_ci         lum32 = convert_integer_luminance64(lum64, dst_bits,
1484bf215546Sopenharmony_ci                                             dst_is_signed, rgba_is_signed);
1485bf215546Sopenharmony_ci         switch (dst_type) {
1486bf215546Sopenharmony_ci         case GL_BYTE:
1487bf215546Sopenharmony_ci         case GL_UNSIGNED_BYTE: {
1488bf215546Sopenharmony_ci            GLbyte *dst = (GLbyte *) dstAddr;
1489bf215546Sopenharmony_ci            dst[i] = lum32;
1490bf215546Sopenharmony_ci            break;
1491bf215546Sopenharmony_ci         }
1492bf215546Sopenharmony_ci         case GL_SHORT:
1493bf215546Sopenharmony_ci         case GL_UNSIGNED_SHORT: {
1494bf215546Sopenharmony_ci            GLshort *dst = (GLshort *) dstAddr;
1495bf215546Sopenharmony_ci            dst[i] = lum32;
1496bf215546Sopenharmony_ci            break;
1497bf215546Sopenharmony_ci         }
1498bf215546Sopenharmony_ci         case GL_INT:
1499bf215546Sopenharmony_ci         case GL_UNSIGNED_INT: {
1500bf215546Sopenharmony_ci            GLint *dst = (GLint *) dstAddr;
1501bf215546Sopenharmony_ci            dst[i] = lum32;
1502bf215546Sopenharmony_ci            break;
1503bf215546Sopenharmony_ci         }
1504bf215546Sopenharmony_ci         }
1505bf215546Sopenharmony_ci      }
1506bf215546Sopenharmony_ci      return;
1507bf215546Sopenharmony_ci   case GL_LUMINANCE_ALPHA_INTEGER_EXT:
1508bf215546Sopenharmony_ci      for (i = 0; i < n; i++) {
1509bf215546Sopenharmony_ci         if (!rgba_is_signed) {
1510bf215546Sopenharmony_ci            lum64 = (uint64_t) rgba[i][RCOMP] +
1511bf215546Sopenharmony_ci                    (uint64_t) rgba[i][GCOMP] +
1512bf215546Sopenharmony_ci                    (uint64_t) rgba[i][BCOMP];
1513bf215546Sopenharmony_ci         } else {
1514bf215546Sopenharmony_ci            lum64 = (int64_t) ((int32_t) rgba[i][RCOMP]) +
1515bf215546Sopenharmony_ci                    (int64_t) ((int32_t) rgba[i][GCOMP]) +
1516bf215546Sopenharmony_ci                    (int64_t) ((int32_t) rgba[i][BCOMP]);
1517bf215546Sopenharmony_ci         }
1518bf215546Sopenharmony_ci         lum32 = convert_integer_luminance64(lum64, dst_bits,
1519bf215546Sopenharmony_ci                                             dst_is_signed, rgba_is_signed);
1520bf215546Sopenharmony_ci         alpha = convert_integer(rgba[i][ACOMP], dst_bits,
1521bf215546Sopenharmony_ci                                 dst_is_signed, rgba_is_signed);
1522bf215546Sopenharmony_ci         switch (dst_type) {
1523bf215546Sopenharmony_ci         case GL_BYTE:
1524bf215546Sopenharmony_ci         case GL_UNSIGNED_BYTE: {
1525bf215546Sopenharmony_ci            GLbyte *dst = (GLbyte *) dstAddr;
1526bf215546Sopenharmony_ci            dst[2*i] = lum32;
1527bf215546Sopenharmony_ci            dst[2*i+1] = alpha;
1528bf215546Sopenharmony_ci            break;
1529bf215546Sopenharmony_ci         }
1530bf215546Sopenharmony_ci         case GL_SHORT:
1531bf215546Sopenharmony_ci         case GL_UNSIGNED_SHORT: {
1532bf215546Sopenharmony_ci            GLshort *dst = (GLshort *) dstAddr;
1533bf215546Sopenharmony_ci            dst[i] = lum32;
1534bf215546Sopenharmony_ci            dst[2*i+1] = alpha;
1535bf215546Sopenharmony_ci            break;
1536bf215546Sopenharmony_ci         }
1537bf215546Sopenharmony_ci         case GL_INT:
1538bf215546Sopenharmony_ci         case GL_UNSIGNED_INT: {
1539bf215546Sopenharmony_ci            GLint *dst = (GLint *) dstAddr;
1540bf215546Sopenharmony_ci            dst[i] = lum32;
1541bf215546Sopenharmony_ci            dst[2*i+1] = alpha;
1542bf215546Sopenharmony_ci            break;
1543bf215546Sopenharmony_ci         }
1544bf215546Sopenharmony_ci         }
1545bf215546Sopenharmony_ci      }
1546bf215546Sopenharmony_ci      return;
1547bf215546Sopenharmony_ci   }
1548bf215546Sopenharmony_ci}
1549bf215546Sopenharmony_ci
1550bf215546Sopenharmony_ciGLfloat *
1551bf215546Sopenharmony_ci_mesa_unpack_color_index_to_rgba_float(struct gl_context *ctx, GLuint dims,
1552bf215546Sopenharmony_ci                                       const void *src, GLenum srcFormat, GLenum srcType,
1553bf215546Sopenharmony_ci                                       int srcWidth, int srcHeight, int srcDepth,
1554bf215546Sopenharmony_ci                                       const struct gl_pixelstore_attrib *srcPacking,
1555bf215546Sopenharmony_ci                                       GLbitfield transferOps)
1556bf215546Sopenharmony_ci{
1557bf215546Sopenharmony_ci   int count, img;
1558bf215546Sopenharmony_ci   GLuint *indexes;
1559bf215546Sopenharmony_ci   GLfloat *rgba, *dstPtr;
1560bf215546Sopenharmony_ci
1561bf215546Sopenharmony_ci   count = srcWidth * srcHeight;
1562bf215546Sopenharmony_ci   indexes = malloc(count * sizeof(GLuint));
1563bf215546Sopenharmony_ci   if (!indexes) {
1564bf215546Sopenharmony_ci      _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking");
1565bf215546Sopenharmony_ci      return NULL;
1566bf215546Sopenharmony_ci   }
1567bf215546Sopenharmony_ci
1568bf215546Sopenharmony_ci   rgba = malloc(4 * count * srcDepth * sizeof(GLfloat));
1569bf215546Sopenharmony_ci   if (!rgba) {
1570bf215546Sopenharmony_ci      free(indexes);
1571bf215546Sopenharmony_ci      _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking");
1572bf215546Sopenharmony_ci      return NULL;
1573bf215546Sopenharmony_ci   }
1574bf215546Sopenharmony_ci
1575bf215546Sopenharmony_ci   /* Convert indexes to RGBA float */
1576bf215546Sopenharmony_ci   dstPtr = rgba;
1577bf215546Sopenharmony_ci   for (img = 0; img < srcDepth; img++) {
1578bf215546Sopenharmony_ci      const GLubyte *srcPtr =
1579bf215546Sopenharmony_ci         (const GLubyte *) _mesa_image_address(dims, srcPacking, src,
1580bf215546Sopenharmony_ci                                               srcWidth, srcHeight,
1581bf215546Sopenharmony_ci                                               srcFormat, srcType,
1582bf215546Sopenharmony_ci                                               img, 0, 0);
1583bf215546Sopenharmony_ci
1584bf215546Sopenharmony_ci      extract_uint_indexes(count, indexes, srcFormat, srcType, srcPtr, srcPacking);
1585bf215546Sopenharmony_ci
1586bf215546Sopenharmony_ci      if (transferOps & IMAGE_SHIFT_OFFSET_BIT)
1587bf215546Sopenharmony_ci         _mesa_shift_and_offset_ci(ctx, count, indexes);
1588bf215546Sopenharmony_ci
1589bf215546Sopenharmony_ci      _mesa_map_ci_to_rgba(ctx, count, indexes, (float (*)[4])dstPtr);
1590bf215546Sopenharmony_ci
1591bf215546Sopenharmony_ci      /* Don't do RGBA scale/bias or RGBA->RGBA mapping if starting
1592bf215546Sopenharmony_ci       * with color indexes.
1593bf215546Sopenharmony_ci       */
1594bf215546Sopenharmony_ci      transferOps &= ~(IMAGE_SCALE_BIAS_BIT | IMAGE_MAP_COLOR_BIT);
1595bf215546Sopenharmony_ci      _mesa_apply_rgba_transfer_ops(ctx, transferOps, count, (float (*)[4])dstPtr);
1596bf215546Sopenharmony_ci
1597bf215546Sopenharmony_ci      dstPtr += srcHeight * srcWidth * 4;
1598bf215546Sopenharmony_ci   }
1599bf215546Sopenharmony_ci
1600bf215546Sopenharmony_ci   free(indexes);
1601bf215546Sopenharmony_ci
1602bf215546Sopenharmony_ci   return rgba;
1603bf215546Sopenharmony_ci}
1604bf215546Sopenharmony_ci
1605bf215546Sopenharmony_ciGLubyte *
1606bf215546Sopenharmony_ci_mesa_unpack_color_index_to_rgba_ubyte(struct gl_context *ctx, GLuint dims,
1607bf215546Sopenharmony_ci                                       const void *src, GLenum srcFormat, GLenum srcType,
1608bf215546Sopenharmony_ci                                       int srcWidth, int srcHeight, int srcDepth,
1609bf215546Sopenharmony_ci                                       const struct gl_pixelstore_attrib *srcPacking,
1610bf215546Sopenharmony_ci                                       GLbitfield transferOps)
1611bf215546Sopenharmony_ci{
1612bf215546Sopenharmony_ci   GLfloat *rgba;
1613bf215546Sopenharmony_ci   GLubyte *dst;
1614bf215546Sopenharmony_ci   int count, i;
1615bf215546Sopenharmony_ci
1616bf215546Sopenharmony_ci   transferOps |= IMAGE_CLAMP_BIT;
1617bf215546Sopenharmony_ci   rgba = _mesa_unpack_color_index_to_rgba_float(ctx, dims,
1618bf215546Sopenharmony_ci                                                 src, srcFormat, srcType,
1619bf215546Sopenharmony_ci                                                 srcWidth, srcHeight, srcDepth,
1620bf215546Sopenharmony_ci                                                 srcPacking, transferOps);
1621bf215546Sopenharmony_ci
1622bf215546Sopenharmony_ci   count = srcWidth * srcHeight * srcDepth;
1623bf215546Sopenharmony_ci   dst = malloc(count * 4 * sizeof(GLubyte));
1624bf215546Sopenharmony_ci   for (i = 0; i < count; i++) {
1625bf215546Sopenharmony_ci      CLAMPED_FLOAT_TO_UBYTE(dst[i * 4 + 0], rgba[i * 4 + 0]);
1626bf215546Sopenharmony_ci      CLAMPED_FLOAT_TO_UBYTE(dst[i * 4 + 1], rgba[i * 4 + 1]);
1627bf215546Sopenharmony_ci      CLAMPED_FLOAT_TO_UBYTE(dst[i * 4 + 2], rgba[i * 4 + 2]);
1628bf215546Sopenharmony_ci      CLAMPED_FLOAT_TO_UBYTE(dst[i * 4 + 3], rgba[i * 4 + 3]);
1629bf215546Sopenharmony_ci   }
1630bf215546Sopenharmony_ci
1631bf215546Sopenharmony_ci   free(rgba);
1632bf215546Sopenharmony_ci
1633bf215546Sopenharmony_ci   return dst;
1634bf215546Sopenharmony_ci}
1635bf215546Sopenharmony_ci
1636bf215546Sopenharmony_civoid
1637bf215546Sopenharmony_ci_mesa_unpack_ubyte_rgba_row(mesa_format format, uint32_t n,
1638bf215546Sopenharmony_ci                            const void *src, uint8_t dst[][4])
1639bf215546Sopenharmony_ci{
1640bf215546Sopenharmony_ci   const struct util_format_unpack_description *unpack =
1641bf215546Sopenharmony_ci      util_format_unpack_description((enum pipe_format)format);
1642bf215546Sopenharmony_ci
1643bf215546Sopenharmony_ci   if (unpack->unpack_rgba_8unorm) {
1644bf215546Sopenharmony_ci      unpack->unpack_rgba_8unorm((uint8_t *)dst, src, n);
1645bf215546Sopenharmony_ci   } else {
1646bf215546Sopenharmony_ci      /* get float values, convert to ubyte */
1647bf215546Sopenharmony_ci      {
1648bf215546Sopenharmony_ci         float *tmp = malloc(n * 4 * sizeof(float));
1649bf215546Sopenharmony_ci         if (tmp) {
1650bf215546Sopenharmony_ci            uint32_t i;
1651bf215546Sopenharmony_ci            _mesa_unpack_rgba_row(format, n, src, (float (*)[4]) tmp);
1652bf215546Sopenharmony_ci            for (i = 0; i < n; i++) {
1653bf215546Sopenharmony_ci               dst[i][0] = _mesa_float_to_unorm(tmp[i*4+0], 8);
1654bf215546Sopenharmony_ci               dst[i][1] = _mesa_float_to_unorm(tmp[i*4+1], 8);
1655bf215546Sopenharmony_ci               dst[i][2] = _mesa_float_to_unorm(tmp[i*4+2], 8);
1656bf215546Sopenharmony_ci               dst[i][3] = _mesa_float_to_unorm(tmp[i*4+3], 8);
1657bf215546Sopenharmony_ci            }
1658bf215546Sopenharmony_ci            free(tmp);
1659bf215546Sopenharmony_ci         }
1660bf215546Sopenharmony_ci      }
1661bf215546Sopenharmony_ci   }
1662bf215546Sopenharmony_ci}
1663bf215546Sopenharmony_ci
1664bf215546Sopenharmony_ci/** Helper struct for MESA_FORMAT_Z32_FLOAT_S8X24_UINT */
1665bf215546Sopenharmony_cistruct z32f_x24s8
1666bf215546Sopenharmony_ci{
1667bf215546Sopenharmony_ci   float z;
1668bf215546Sopenharmony_ci   uint32_t x24s8;
1669bf215546Sopenharmony_ci};
1670bf215546Sopenharmony_ci
1671bf215546Sopenharmony_ci
1672bf215546Sopenharmony_cistatic void
1673bf215546Sopenharmony_ciunpack_uint_24_8_depth_stencil_Z24_UNORM_S8_UINT(const uint32_t *src, uint32_t *dst, uint32_t n)
1674bf215546Sopenharmony_ci{
1675bf215546Sopenharmony_ci   uint32_t i;
1676bf215546Sopenharmony_ci
1677bf215546Sopenharmony_ci   for (i = 0; i < n; i++) {
1678bf215546Sopenharmony_ci      uint32_t val = src[i];
1679bf215546Sopenharmony_ci      dst[i] = val >> 24 | val << 8;
1680bf215546Sopenharmony_ci   }
1681bf215546Sopenharmony_ci}
1682bf215546Sopenharmony_ci
1683bf215546Sopenharmony_cistatic void
1684bf215546Sopenharmony_ciunpack_uint_24_8_depth_stencil_Z32_S8X24(const uint32_t *src,
1685bf215546Sopenharmony_ci                                         uint32_t *dst, uint32_t n)
1686bf215546Sopenharmony_ci{
1687bf215546Sopenharmony_ci   uint32_t i;
1688bf215546Sopenharmony_ci
1689bf215546Sopenharmony_ci   for (i = 0; i < n; i++) {
1690bf215546Sopenharmony_ci      /* 8 bytes per pixel (float + uint32) */
1691bf215546Sopenharmony_ci      float zf = ((float *) src)[i * 2 + 0];
1692bf215546Sopenharmony_ci      uint32_t z24 = (uint32_t) (zf * (float) 0xffffff);
1693bf215546Sopenharmony_ci      uint32_t s = src[i * 2 + 1] & 0xff;
1694bf215546Sopenharmony_ci      dst[i] = (z24 << 8) | s;
1695bf215546Sopenharmony_ci   }
1696bf215546Sopenharmony_ci}
1697bf215546Sopenharmony_ci
1698bf215546Sopenharmony_cistatic void
1699bf215546Sopenharmony_ciunpack_uint_24_8_depth_stencil_S8_UINT_Z24_UNORM(const uint32_t *src, uint32_t *dst, uint32_t n)
1700bf215546Sopenharmony_ci{
1701bf215546Sopenharmony_ci   memcpy(dst, src, n * 4);
1702bf215546Sopenharmony_ci}
1703bf215546Sopenharmony_ci
1704bf215546Sopenharmony_ci/**
1705bf215546Sopenharmony_ci * Unpack depth/stencil returning as GL_UNSIGNED_INT_24_8.
1706bf215546Sopenharmony_ci * \param format  the source data format
1707bf215546Sopenharmony_ci */
1708bf215546Sopenharmony_civoid
1709bf215546Sopenharmony_ci_mesa_unpack_uint_24_8_depth_stencil_row(mesa_format format, uint32_t n,
1710bf215546Sopenharmony_ci                                         const void *src, uint32_t *dst)
1711bf215546Sopenharmony_ci{
1712bf215546Sopenharmony_ci   switch (format) {
1713bf215546Sopenharmony_ci   case MESA_FORMAT_S8_UINT_Z24_UNORM:
1714bf215546Sopenharmony_ci      unpack_uint_24_8_depth_stencil_S8_UINT_Z24_UNORM(src, dst, n);
1715bf215546Sopenharmony_ci      break;
1716bf215546Sopenharmony_ci   case MESA_FORMAT_Z24_UNORM_S8_UINT:
1717bf215546Sopenharmony_ci      unpack_uint_24_8_depth_stencil_Z24_UNORM_S8_UINT(src, dst, n);
1718bf215546Sopenharmony_ci      break;
1719bf215546Sopenharmony_ci   case MESA_FORMAT_Z32_FLOAT_S8X24_UINT:
1720bf215546Sopenharmony_ci      unpack_uint_24_8_depth_stencil_Z32_S8X24(src, dst, n);
1721bf215546Sopenharmony_ci      break;
1722bf215546Sopenharmony_ci   default:
1723bf215546Sopenharmony_ci      unreachable("bad format %s in _mesa_unpack_uint_24_8_depth_stencil_row");
1724bf215546Sopenharmony_ci   }
1725bf215546Sopenharmony_ci}
1726bf215546Sopenharmony_ci
1727bf215546Sopenharmony_cistatic void
1728bf215546Sopenharmony_ciunpack_float_32_uint_24_8_Z24_UNORM_S8_UINT(const uint32_t *src,
1729bf215546Sopenharmony_ci                                            uint32_t *dst, uint32_t n)
1730bf215546Sopenharmony_ci{
1731bf215546Sopenharmony_ci   uint32_t i;
1732bf215546Sopenharmony_ci   struct z32f_x24s8 *d = (struct z32f_x24s8 *) dst;
1733bf215546Sopenharmony_ci   const double scale = 1.0 / (double) 0xffffff;
1734bf215546Sopenharmony_ci
1735bf215546Sopenharmony_ci   for (i = 0; i < n; i++) {
1736bf215546Sopenharmony_ci      const uint32_t z24 = src[i] & 0xffffff;
1737bf215546Sopenharmony_ci      d[i].z = z24 * scale;
1738bf215546Sopenharmony_ci      d[i].x24s8 = src[i] >> 24;
1739bf215546Sopenharmony_ci      assert(d[i].z >= 0.0f);
1740bf215546Sopenharmony_ci      assert(d[i].z <= 1.0f);
1741bf215546Sopenharmony_ci   }
1742bf215546Sopenharmony_ci}
1743bf215546Sopenharmony_ci
1744bf215546Sopenharmony_cistatic void
1745bf215546Sopenharmony_ciunpack_float_32_uint_24_8_Z32_FLOAT_S8X24_UINT(const uint32_t *src,
1746bf215546Sopenharmony_ci                                               uint32_t *dst, uint32_t n)
1747bf215546Sopenharmony_ci{
1748bf215546Sopenharmony_ci   memcpy(dst, src, n * sizeof(struct z32f_x24s8));
1749bf215546Sopenharmony_ci}
1750bf215546Sopenharmony_ci
1751bf215546Sopenharmony_cistatic void
1752bf215546Sopenharmony_ciunpack_float_32_uint_24_8_S8_UINT_Z24_UNORM(const uint32_t *src,
1753bf215546Sopenharmony_ci                                            uint32_t *dst, uint32_t n)
1754bf215546Sopenharmony_ci{
1755bf215546Sopenharmony_ci   uint32_t i;
1756bf215546Sopenharmony_ci   struct z32f_x24s8 *d = (struct z32f_x24s8 *) dst;
1757bf215546Sopenharmony_ci   const double scale = 1.0 / (double) 0xffffff;
1758bf215546Sopenharmony_ci
1759bf215546Sopenharmony_ci   for (i = 0; i < n; i++) {
1760bf215546Sopenharmony_ci      const uint32_t z24 = src[i] >> 8;
1761bf215546Sopenharmony_ci      d[i].z = z24 * scale;
1762bf215546Sopenharmony_ci      d[i].x24s8 = src[i] & 0xff;
1763bf215546Sopenharmony_ci      assert(d[i].z >= 0.0f);
1764bf215546Sopenharmony_ci      assert(d[i].z <= 1.0f);
1765bf215546Sopenharmony_ci   }
1766bf215546Sopenharmony_ci}
1767bf215546Sopenharmony_ci
1768bf215546Sopenharmony_ci/**
1769bf215546Sopenharmony_ci * Unpack depth/stencil returning as GL_FLOAT_32_UNSIGNED_INT_24_8_REV.
1770bf215546Sopenharmony_ci * \param format  the source data format
1771bf215546Sopenharmony_ci *
1772bf215546Sopenharmony_ci * In GL_FLOAT_32_UNSIGNED_INT_24_8_REV lower 4 bytes contain float
1773bf215546Sopenharmony_ci * component and higher 4 bytes contain packed 24-bit and 8-bit
1774bf215546Sopenharmony_ci * components.
1775bf215546Sopenharmony_ci *
1776bf215546Sopenharmony_ci *    31 30 29 28 ... 4 3 2 1 0    31 30 29 ... 9 8 7 6 5 ... 2 1 0
1777bf215546Sopenharmony_ci *    +-------------------------+  +--------------------------------+
1778bf215546Sopenharmony_ci *    |    Float Component      |  | Unused         | 8 bit stencil |
1779bf215546Sopenharmony_ci *    +-------------------------+  +--------------------------------+
1780bf215546Sopenharmony_ci *          lower 4 bytes                  higher 4 bytes
1781bf215546Sopenharmony_ci */
1782bf215546Sopenharmony_civoid
1783bf215546Sopenharmony_ci_mesa_unpack_float_32_uint_24_8_depth_stencil_row(mesa_format format, uint32_t n,
1784bf215546Sopenharmony_ci                                                  const void *src, uint32_t *dst)
1785bf215546Sopenharmony_ci{
1786bf215546Sopenharmony_ci   switch (format) {
1787bf215546Sopenharmony_ci   case MESA_FORMAT_S8_UINT_Z24_UNORM:
1788bf215546Sopenharmony_ci      unpack_float_32_uint_24_8_S8_UINT_Z24_UNORM(src, dst, n);
1789bf215546Sopenharmony_ci      break;
1790bf215546Sopenharmony_ci   case MESA_FORMAT_Z24_UNORM_S8_UINT:
1791bf215546Sopenharmony_ci      unpack_float_32_uint_24_8_Z24_UNORM_S8_UINT(src, dst, n);
1792bf215546Sopenharmony_ci      break;
1793bf215546Sopenharmony_ci   case MESA_FORMAT_Z32_FLOAT_S8X24_UINT:
1794bf215546Sopenharmony_ci      unpack_float_32_uint_24_8_Z32_FLOAT_S8X24_UINT(src, dst, n);
1795bf215546Sopenharmony_ci      break;
1796bf215546Sopenharmony_ci   default:
1797bf215546Sopenharmony_ci      unreachable("bad format %s in _mesa_unpack_uint_24_8_depth_stencil_row");
1798bf215546Sopenharmony_ci   }
1799bf215546Sopenharmony_ci}
1800