u_tile.c revision 32f95f8c173155ca30e77c345a68b0d3336ddbed
1/**************************************************************************
2 *
3 * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28/**
29 * RGBA/float tile get/put functions.
30 * Usable both by drivers and state trackers.
31 */
32
33
34#include "pipe/p_defines.h"
35#include "pipe/p_inlines.h"
36
37#include "util/u_math.h"
38#include "util/u_memory.h"
39#include "util/u_rect.h"
40#include "util/u_tile.h"
41
42
43/**
44 * Move raw block of pixels from transfer object to user memory.
45 */
46void
47pipe_get_tile_raw(struct pipe_transfer *pt,
48                  uint x, uint y, uint w, uint h,
49                  void *dst, int dst_stride)
50{
51   struct pipe_screen *screen = pt->texture->screen;
52   const void *src;
53
54   if (dst_stride == 0)
55      dst_stride = pf_get_nblocksx(&pt->block, w) * pt->block.size;
56
57   if (pipe_clip_tile(x, y, &w, &h, pt))
58      return;
59
60   src = screen->transfer_map(screen, pt);
61   assert(src);
62   if(!src)
63      return;
64
65   pipe_copy_rect(dst, &pt->block, dst_stride, 0, 0, w, h, src, pt->stride, x, y);
66
67   screen->transfer_unmap(screen, pt);
68}
69
70
71/**
72 * Move raw block of pixels from user memory to transfer object.
73 */
74void
75pipe_put_tile_raw(struct pipe_transfer *pt,
76                  uint x, uint y, uint w, uint h,
77                  const void *src, int src_stride)
78{
79   struct pipe_screen *screen = pt->texture->screen;
80   void *dst;
81
82   if (src_stride == 0)
83      src_stride = pf_get_nblocksx(&pt->block, w) * pt->block.size;
84
85   if (pipe_clip_tile(x, y, &w, &h, pt))
86      return;
87
88   dst = screen->transfer_map(screen, pt);
89   assert(dst);
90   if(!dst)
91      return;
92
93   pipe_copy_rect(dst, &pt->block, pt->stride, x, y, w, h, src, src_stride, 0, 0);
94
95   screen->transfer_unmap(screen, pt);
96}
97
98
99
100
101/** Convert short in [-32768,32767] to GLfloat in [-1.0,1.0] */
102#define SHORT_TO_FLOAT(S)   ((2.0F * (S) + 1.0F) * (1.0F/65535.0F))
103
104#define UNCLAMPED_FLOAT_TO_SHORT(us, f)  \
105   us = ( (short) ( CLAMP((f), -1.0, 1.0) * 32767.0F) )
106
107
108
109/*** PIPE_FORMAT_A8R8G8B8_UNORM ***/
110
111static void
112a8r8g8b8_get_tile_rgba(const unsigned *src,
113                       unsigned w, unsigned h,
114                       float *p,
115                       unsigned dst_stride)
116{
117   unsigned i, j;
118
119   for (i = 0; i < h; i++) {
120      float *pRow = p;
121      for (j = 0; j < w; j++, pRow += 4) {
122         const unsigned pixel = *src++;
123         pRow[0] = ubyte_to_float((pixel >> 16) & 0xff);
124         pRow[1] = ubyte_to_float((pixel >>  8) & 0xff);
125         pRow[2] = ubyte_to_float((pixel >>  0) & 0xff);
126         pRow[3] = ubyte_to_float((pixel >> 24) & 0xff);
127      }
128      p += dst_stride;
129   }
130}
131
132
133static void
134a8r8g8b8_put_tile_rgba(unsigned *dst,
135                       unsigned w, unsigned h,
136                       const float *p,
137                       unsigned src_stride)
138{
139   unsigned i, j;
140
141   for (i = 0; i < h; i++) {
142      const float *pRow = p;
143      for (j = 0; j < w; j++, pRow += 4) {
144         unsigned r, g, b, a;
145         r = float_to_ubyte(pRow[0]);
146         g = float_to_ubyte(pRow[1]);
147         b = float_to_ubyte(pRow[2]);
148         a = float_to_ubyte(pRow[3]);
149         *dst++ = (a << 24) | (r << 16) | (g << 8) | b;
150      }
151      p += src_stride;
152   }
153}
154
155
156/*** PIPE_FORMAT_X8R8G8B8_UNORM ***/
157
158static void
159x8r8g8b8_get_tile_rgba(const unsigned *src,
160                       unsigned w, unsigned h,
161                       float *p,
162                       unsigned dst_stride)
163{
164   unsigned i, j;
165
166   for (i = 0; i < h; i++) {
167      float *pRow = p;
168      for (j = 0; j < w; j++, pRow += 4) {
169         const unsigned pixel = *src++;
170         pRow[0] = ubyte_to_float((pixel >> 16) & 0xff);
171         pRow[1] = ubyte_to_float((pixel >>  8) & 0xff);
172         pRow[2] = ubyte_to_float((pixel >>  0) & 0xff);
173         pRow[3] = ubyte_to_float(0xff);
174      }
175      p += dst_stride;
176   }
177}
178
179
180static void
181x8r8g8b8_put_tile_rgba(unsigned *dst,
182                       unsigned w, unsigned h,
183                       const float *p,
184                       unsigned src_stride)
185{
186   unsigned i, j;
187
188   for (i = 0; i < h; i++) {
189      const float *pRow = p;
190      for (j = 0; j < w; j++, pRow += 4) {
191         unsigned r, g, b;
192         r = float_to_ubyte(pRow[0]);
193         g = float_to_ubyte(pRow[1]);
194         b = float_to_ubyte(pRow[2]);
195         *dst++ = (0xff << 24) | (r << 16) | (g << 8) | b;
196      }
197      p += src_stride;
198   }
199}
200
201
202/*** PIPE_FORMAT_B8G8R8A8_UNORM ***/
203
204static void
205b8g8r8a8_get_tile_rgba(const unsigned *src,
206                       unsigned w, unsigned h,
207                       float *p,
208                       unsigned dst_stride)
209{
210   unsigned i, j;
211
212   for (i = 0; i < h; i++) {
213      float *pRow = p;
214      for (j = 0; j < w; j++, pRow += 4) {
215         const unsigned pixel = *src++;
216         pRow[0] = ubyte_to_float((pixel >>  8) & 0xff);
217         pRow[1] = ubyte_to_float((pixel >> 16) & 0xff);
218         pRow[2] = ubyte_to_float((pixel >> 24) & 0xff);
219         pRow[3] = ubyte_to_float((pixel >>  0) & 0xff);
220      }
221      p += dst_stride;
222   }
223}
224
225
226static void
227b8g8r8a8_put_tile_rgba(unsigned *dst,
228                       unsigned w, unsigned h,
229                       const float *p,
230                       unsigned src_stride)
231{
232   unsigned i, j;
233
234   for (i = 0; i < h; i++) {
235      const float *pRow = p;
236      for (j = 0; j < w; j++, pRow += 4) {
237         unsigned r, g, b, a;
238         r = float_to_ubyte(pRow[0]);
239         g = float_to_ubyte(pRow[1]);
240         b = float_to_ubyte(pRow[2]);
241         a = float_to_ubyte(pRow[3]);
242         *dst++ = (b << 24) | (g << 16) | (r << 8) | a;
243      }
244      p += src_stride;
245   }
246}
247
248
249/*** PIPE_FORMAT_A1R5G5B5_UNORM ***/
250
251static void
252a1r5g5b5_get_tile_rgba(const ushort *src,
253                       unsigned w, unsigned h,
254                       float *p,
255                       unsigned dst_stride)
256{
257   unsigned i, j;
258
259   for (i = 0; i < h; i++) {
260      float *pRow = p;
261      for (j = 0; j < w; j++, pRow += 4) {
262         const ushort pixel = *src++;
263         pRow[0] = ((pixel >> 10) & 0x1f) * (1.0f / 31.0f);
264         pRow[1] = ((pixel >>  5) & 0x1f) * (1.0f / 31.0f);
265         pRow[2] = ((pixel      ) & 0x1f) * (1.0f / 31.0f);
266         pRow[3] = ((pixel >> 15)       ) * 1.0f;
267      }
268      p += dst_stride;
269   }
270}
271
272
273static void
274a1r5g5b5_put_tile_rgba(ushort *dst,
275                       unsigned w, unsigned h,
276                       const float *p,
277                       unsigned src_stride)
278{
279   unsigned i, j;
280
281   for (i = 0; i < h; i++) {
282      const float *pRow = p;
283      for (j = 0; j < w; j++, pRow += 4) {
284         unsigned r, g, b, a;
285         r = float_to_ubyte(pRow[0]);
286         g = float_to_ubyte(pRow[1]);
287         b = float_to_ubyte(pRow[2]);
288         a = float_to_ubyte(pRow[3]);
289         r = r >> 3;  /* 5 bits */
290         g = g >> 3;  /* 5 bits */
291         b = b >> 3;  /* 5 bits */
292         a = a >> 7;  /* 1 bit */
293         *dst++ = (a << 15) | (r << 10) | (g << 5) | b;
294      }
295      p += src_stride;
296   }
297}
298
299
300/*** PIPE_FORMAT_A4R4G4B4_UNORM ***/
301
302static void
303a4r4g4b4_get_tile_rgba(const ushort *src,
304                       unsigned w, unsigned h,
305                       float *p,
306                       unsigned dst_stride)
307{
308   unsigned i, j;
309
310   for (i = 0; i < h; i++) {
311      float *pRow = p;
312      for (j = 0; j < w; j++, pRow += 4) {
313         const ushort pixel = *src++;
314         pRow[0] = ((pixel >>  8) & 0xf) * (1.0f / 15.0f);
315         pRow[1] = ((pixel >>  4) & 0xf) * (1.0f / 15.0f);
316         pRow[2] = ((pixel      ) & 0xf) * (1.0f / 15.0f);
317         pRow[3] = ((pixel >> 12)      ) * (1.0f / 15.0f);
318      }
319      p += dst_stride;
320   }
321}
322
323
324static void
325a4r4g4b4_put_tile_rgba(ushort *dst,
326                       unsigned w, unsigned h,
327                       const float *p,
328                       unsigned src_stride)
329{
330   unsigned i, j;
331
332   for (i = 0; i < h; i++) {
333      const float *pRow = p;
334      for (j = 0; j < w; j++, pRow += 4) {
335         unsigned r, g, b, a;
336         r = float_to_ubyte(pRow[0]);
337         g = float_to_ubyte(pRow[1]);
338         b = float_to_ubyte(pRow[2]);
339         a = float_to_ubyte(pRow[3]);
340         r >>= 4;
341         g >>= 4;
342         b >>= 4;
343         a >>= 4;
344         *dst++ = (a << 12) | (r << 16) | (g << 4) | b;
345      }
346      p += src_stride;
347   }
348}
349
350
351/*** PIPE_FORMAT_R5G6B5_UNORM ***/
352
353static void
354r5g6b5_get_tile_rgba(const ushort *src,
355                     unsigned w, unsigned h,
356                     float *p,
357                     unsigned dst_stride)
358{
359   unsigned i, j;
360
361   for (i = 0; i < h; i++) {
362      float *pRow = p;
363      for (j = 0; j < w; j++, pRow += 4) {
364         const ushort pixel = *src++;
365         pRow[0] = ((pixel >> 11) & 0x1f) * (1.0f / 31.0f);
366         pRow[1] = ((pixel >>  5) & 0x3f) * (1.0f / 63.0f);
367         pRow[2] = ((pixel      ) & 0x1f) * (1.0f / 31.0f);
368         pRow[3] = 1.0f;
369      }
370      p += dst_stride;
371   }
372}
373
374
375static void
376r5g6b5_put_tile_rgba(ushort *dst,
377                     unsigned w, unsigned h,
378                     const float *p,
379                     unsigned src_stride)
380{
381   unsigned i, j;
382
383   for (i = 0; i < h; i++) {
384      const float *pRow = p;
385      for (j = 0; j < w; j++, pRow += 4) {
386         uint r = (uint) (CLAMP(pRow[0], 0.0, 1.0) * 31.0);
387         uint g = (uint) (CLAMP(pRow[1], 0.0, 1.0) * 63.0);
388         uint b = (uint) (CLAMP(pRow[2], 0.0, 1.0) * 31.0);
389         *dst++ = (r << 11) | (g << 5) | (b);
390      }
391      p += src_stride;
392   }
393}
394
395
396
397/*** PIPE_FORMAT_Z16_UNORM ***/
398
399/**
400 * Return each Z value as four floats in [0,1].
401 */
402static void
403z16_get_tile_rgba(const ushort *src,
404                  unsigned w, unsigned h,
405                  float *p,
406                  unsigned dst_stride)
407{
408   const float scale = 1.0f / 65535.0f;
409   unsigned i, j;
410
411   for (i = 0; i < h; i++) {
412      float *pRow = p;
413      for (j = 0; j < w; j++, pRow += 4) {
414         pRow[0] =
415         pRow[1] =
416         pRow[2] =
417         pRow[3] = *src++ * scale;
418      }
419      p += dst_stride;
420   }
421}
422
423
424
425
426/*** PIPE_FORMAT_L8_UNORM ***/
427
428static void
429l8_get_tile_rgba(const ubyte *src,
430                 unsigned w, unsigned h,
431                 float *p,
432                 unsigned dst_stride)
433{
434   unsigned i, j;
435
436   for (i = 0; i < h; i++) {
437      float *pRow = p;
438      for (j = 0; j < w; j++, src++, pRow += 4) {
439         pRow[0] =
440         pRow[1] =
441         pRow[2] = ubyte_to_float(*src);
442         pRow[3] = 1.0;
443      }
444      p += dst_stride;
445   }
446}
447
448
449static void
450l8_put_tile_rgba(ubyte *dst,
451                 unsigned w, unsigned h,
452                 const float *p,
453                 unsigned src_stride)
454{
455   unsigned i, j;
456
457   for (i = 0; i < h; i++) {
458      const float *pRow = p;
459      for (j = 0; j < w; j++, pRow += 4) {
460         unsigned r;
461         r = float_to_ubyte(pRow[0]);
462         *dst++ = (ubyte) r;
463      }
464      p += src_stride;
465   }
466}
467
468
469
470/*** PIPE_FORMAT_A8_UNORM ***/
471
472static void
473a8_get_tile_rgba(const ubyte *src,
474                 unsigned w, unsigned h,
475                 float *p,
476                 unsigned dst_stride)
477{
478   unsigned i, j;
479
480   for (i = 0; i < h; i++) {
481      float *pRow = p;
482      for (j = 0; j < w; j++, src++, pRow += 4) {
483         pRow[0] =
484         pRow[1] =
485         pRow[2] = 0.0;
486         pRow[3] = ubyte_to_float(*src);
487      }
488      p += dst_stride;
489   }
490}
491
492
493static void
494a8_put_tile_rgba(ubyte *dst,
495                 unsigned w, unsigned h,
496                 const float *p,
497                 unsigned src_stride)
498{
499   unsigned i, j;
500
501   for (i = 0; i < h; i++) {
502      const float *pRow = p;
503      for (j = 0; j < w; j++, pRow += 4) {
504         unsigned a;
505         a = float_to_ubyte(pRow[3]);
506         *dst++ = (ubyte) a;
507      }
508      p += src_stride;
509   }
510}
511
512
513
514/*** PIPE_FORMAT_R16_SNORM ***/
515
516static void
517r16_get_tile_rgba(const short *src,
518                  unsigned w, unsigned h,
519                  float *p,
520                  unsigned dst_stride)
521{
522   unsigned i, j;
523
524   for (i = 0; i < h; i++) {
525      float *pRow = p;
526      for (j = 0; j < w; j++, src++, pRow += 4) {
527         pRow[0] = SHORT_TO_FLOAT(src[0]);
528         pRow[1] =
529         pRow[2] = 0.0;
530         pRow[3] = 1.0;
531      }
532      p += dst_stride;
533   }
534}
535
536
537static void
538r16_put_tile_rgba(short *dst,
539                  unsigned w, unsigned h,
540                  const float *p,
541                  unsigned src_stride)
542{
543   unsigned i, j;
544
545   for (i = 0; i < h; i++) {
546      const float *pRow = p;
547      for (j = 0; j < w; j++, dst++, pRow += 4) {
548         UNCLAMPED_FLOAT_TO_SHORT(dst[0], pRow[0]);
549      }
550      p += src_stride;
551   }
552}
553
554
555/*** PIPE_FORMAT_R16G16B16A16_SNORM ***/
556
557static void
558r16g16b16a16_get_tile_rgba(const short *src,
559                           unsigned w, unsigned h,
560                           float *p,
561                           unsigned dst_stride)
562{
563   unsigned i, j;
564
565   for (i = 0; i < h; i++) {
566      float *pRow = p;
567      for (j = 0; j < w; j++, src += 4, pRow += 4) {
568         pRow[0] = SHORT_TO_FLOAT(src[0]);
569         pRow[1] = SHORT_TO_FLOAT(src[1]);
570         pRow[2] = SHORT_TO_FLOAT(src[2]);
571         pRow[3] = SHORT_TO_FLOAT(src[3]);
572      }
573      p += dst_stride;
574   }
575}
576
577
578static void
579r16g16b16a16_put_tile_rgba(short *dst,
580                           unsigned w, unsigned h,
581                           const float *p,
582                           unsigned src_stride)
583{
584   unsigned i, j;
585
586   for (i = 0; i < h; i++) {
587      const float *pRow = p;
588      for (j = 0; j < w; j++, dst += 4, pRow += 4) {
589         UNCLAMPED_FLOAT_TO_SHORT(dst[0], pRow[0]);
590         UNCLAMPED_FLOAT_TO_SHORT(dst[1], pRow[1]);
591         UNCLAMPED_FLOAT_TO_SHORT(dst[2], pRow[2]);
592         UNCLAMPED_FLOAT_TO_SHORT(dst[3], pRow[3]);
593      }
594      p += src_stride;
595   }
596}
597
598
599/*** PIPE_FORMAT_R8G8B8A8_SRGB ***/
600
601/**
602 * Convert an 8-bit sRGB value from non-linear space to a
603 * linear RGB value in [0, 1].
604 * Implemented with a 256-entry lookup table.
605 */
606static INLINE float
607srgb_to_linear(ubyte cs8)
608{
609   static float table[256];
610   static boolean tableReady = FALSE;
611   if (!tableReady) {
612      /* compute lookup table now */
613      uint i;
614      for (i = 0; i < 256; i++) {
615         const float cs = ubyte_to_float(i);
616         if (cs <= 0.04045) {
617            table[i] = cs / 12.92f;
618         }
619         else {
620            table[i] = (float) powf((cs + 0.055) / 1.055, 2.4);
621         }
622      }
623      tableReady = TRUE;
624   }
625   return table[cs8];
626}
627
628
629/**
630 * Convert linear float in [0,1] to an srgb ubyte value in [0,255].
631 * XXX this hasn't been tested (render to srgb surface).
632 * XXX this needs optimization.
633 */
634static INLINE ubyte
635linear_to_srgb(float cl)
636{
637   if (cl >= 1.0F)
638      return 255;
639   else if (cl >= 0.0031308F)
640      return float_to_ubyte(1.055F * powf(cl, 0.41666F) - 0.055F);
641   else if (cl > 0.0F)
642      return float_to_ubyte(12.92F * cl);
643   else
644      return 0.0;
645}
646
647
648static void
649a8r8g8b8_srgb_get_tile_rgba(const unsigned *src,
650                            unsigned w, unsigned h,
651                            float *p,
652                            unsigned dst_stride)
653{
654   unsigned i, j;
655
656   for (i = 0; i < h; i++) {
657      float *pRow = p;
658      for (j = 0; j < w; j++, pRow += 4) {
659         const unsigned pixel = *src++;
660         pRow[0] = srgb_to_linear((pixel >> 16) & 0xff);
661         pRow[1] = srgb_to_linear((pixel >>  8) & 0xff);
662         pRow[2] = srgb_to_linear((pixel >>  0) & 0xff);
663         pRow[3] = ubyte_to_float((pixel >> 24) & 0xff);
664      }
665      p += dst_stride;
666   }
667}
668
669static void
670a8r8g8b8_srgb_put_tile_rgba(unsigned *dst,
671                            unsigned w, unsigned h,
672                            const float *p,
673                            unsigned src_stride)
674{
675   unsigned i, j;
676
677   for (i = 0; i < h; i++) {
678      const float *pRow = p;
679      for (j = 0; j < w; j++, pRow += 4) {
680         unsigned r, g, b, a;
681         r = linear_to_srgb(pRow[0]);
682         g = linear_to_srgb(pRow[1]);
683         b = linear_to_srgb(pRow[2]);
684         a = float_to_ubyte(pRow[3]);
685         *dst++ = (a << 24) | (r << 16) | (g << 8) | b;
686      }
687      p += src_stride;
688   }
689}
690
691
692/*** PIPE_FORMAT_A8L8_SRGB ***/
693
694static void
695a8l8_srgb_get_tile_rgba(const ushort *src,
696                        unsigned w, unsigned h,
697                        float *p,
698                        unsigned dst_stride)
699{
700   unsigned i, j;
701
702   for (i = 0; i < h; i++) {
703      float *pRow = p;
704      for (j = 0; j < w; j++, pRow += 4) {
705         ushort p = *src++;
706         pRow[0] =
707         pRow[1] =
708         pRow[2] = srgb_to_linear(p & 0xff);
709         pRow[3] = ubyte_to_float(p >> 8);
710      }
711      p += dst_stride;
712   }
713}
714
715static void
716a8l8_srgb_put_tile_rgba(ushort *dst,
717                        unsigned w, unsigned h,
718                        const float *p,
719                        unsigned src_stride)
720{
721   unsigned i, j;
722
723   for (i = 0; i < h; i++) {
724      const float *pRow = p;
725      for (j = 0; j < w; j++, pRow += 4) {
726         unsigned r, a;
727         r = linear_to_srgb(pRow[0]);
728         a = float_to_ubyte(pRow[3]);
729         *dst++ = (a << 8) | r;
730      }
731      p += src_stride;
732   }
733}
734
735
736/*** PIPE_FORMAT_L8_SRGB ***/
737
738static void
739l8_srgb_get_tile_rgba(const ubyte *src,
740                      unsigned w, unsigned h,
741                      float *p,
742                      unsigned dst_stride)
743{
744   unsigned i, j;
745
746   for (i = 0; i < h; i++) {
747      float *pRow = p;
748      for (j = 0; j < w; j++, src++, pRow += 4) {
749         pRow[0] =
750         pRow[1] =
751         pRow[2] = srgb_to_linear(*src);
752         pRow[3] = 1.0;
753      }
754      p += dst_stride;
755   }
756}
757
758static void
759l8_srgb_put_tile_rgba(ubyte *dst,
760                      unsigned w, unsigned h,
761                      const float *p,
762                      unsigned src_stride)
763{
764   unsigned i, j;
765
766   for (i = 0; i < h; i++) {
767      const float *pRow = p;
768      for (j = 0; j < w; j++, pRow += 4) {
769         unsigned r;
770         r = linear_to_srgb(pRow[0]);
771         *dst++ = (ubyte) r;
772      }
773      p += src_stride;
774   }
775}
776
777
778/*** PIPE_FORMAT_I8_UNORM ***/
779
780static void
781i8_get_tile_rgba(const ubyte *src,
782                 unsigned w, unsigned h,
783                 float *p,
784                 unsigned dst_stride)
785{
786   unsigned i, j;
787
788   for (i = 0; i < h; i++) {
789      float *pRow = p;
790      for (j = 0; j < w; j++, src++, pRow += 4) {
791         pRow[0] =
792         pRow[1] =
793         pRow[2] =
794         pRow[3] = ubyte_to_float(*src);
795      }
796      p += dst_stride;
797   }
798}
799
800
801static void
802i8_put_tile_rgba(ubyte *dst,
803                 unsigned w, unsigned h,
804                 const float *p,
805                 unsigned src_stride)
806{
807   unsigned i, j;
808
809   for (i = 0; i < h; i++) {
810      const float *pRow = p;
811      for (j = 0; j < w; j++, pRow += 4) {
812         unsigned r;
813         r = float_to_ubyte(pRow[0]);
814         *dst++ = (ubyte) r;
815      }
816      p += src_stride;
817   }
818}
819
820
821/*** PIPE_FORMAT_A8L8_UNORM ***/
822
823static void
824a8l8_get_tile_rgba(const ushort *src,
825                   unsigned w, unsigned h,
826                   float *p,
827                   unsigned dst_stride)
828{
829   unsigned i, j;
830
831   for (i = 0; i < h; i++) {
832      float *pRow = p;
833      for (j = 0; j < w; j++, pRow += 4) {
834         ushort p = *src++;
835         pRow[0] =
836         pRow[1] =
837         pRow[2] = ubyte_to_float(p & 0xff);
838         pRow[3] = ubyte_to_float(p >> 8);
839      }
840      p += dst_stride;
841   }
842}
843
844
845static void
846a8l8_put_tile_rgba(ushort *dst,
847                   unsigned w, unsigned h,
848                   const float *p,
849                   unsigned src_stride)
850{
851   unsigned i, j;
852
853   for (i = 0; i < h; i++) {
854      const float *pRow = p;
855      for (j = 0; j < w; j++, pRow += 4) {
856         unsigned r, a;
857         r = float_to_ubyte(pRow[0]);
858         a = float_to_ubyte(pRow[3]);
859         *dst++ = (a << 8) | r;
860      }
861      p += src_stride;
862   }
863}
864
865
866
867
868/*** PIPE_FORMAT_Z32_UNORM ***/
869
870/**
871 * Return each Z value as four floats in [0,1].
872 */
873static void
874z32_get_tile_rgba(const unsigned *src,
875                  unsigned w, unsigned h,
876                  float *p,
877                  unsigned dst_stride)
878{
879   const double scale = 1.0 / (double) 0xffffffff;
880   unsigned i, j;
881
882   for (i = 0; i < h; i++) {
883      float *pRow = p;
884      for (j = 0; j < w; j++, pRow += 4) {
885         pRow[0] =
886         pRow[1] =
887         pRow[2] =
888         pRow[3] = (float) (*src++ * scale);
889      }
890      p += dst_stride;
891   }
892}
893
894
895/*** PIPE_FORMAT_S8Z24_UNORM ***/
896
897/**
898 * Return Z component as four float in [0,1].  Stencil part ignored.
899 */
900static void
901s8z24_get_tile_rgba(const unsigned *src,
902                    unsigned w, unsigned h,
903                    float *p,
904                    unsigned dst_stride)
905{
906   const double scale = 1.0 / ((1 << 24) - 1);
907   unsigned i, j;
908
909   for (i = 0; i < h; i++) {
910      float *pRow = p;
911      for (j = 0; j < w; j++, pRow += 4) {
912         pRow[0] =
913         pRow[1] =
914         pRow[2] =
915         pRow[3] = (float) (scale * (*src++ & 0xffffff));
916      }
917      p += dst_stride;
918   }
919}
920
921
922/*** PIPE_FORMAT_Z24S8_UNORM ***/
923
924/**
925 * Return Z component as four float in [0,1].  Stencil part ignored.
926 */
927static void
928z24s8_get_tile_rgba(const unsigned *src,
929                    unsigned w, unsigned h,
930                    float *p,
931                    unsigned dst_stride)
932{
933   const double scale = 1.0 / ((1 << 24) - 1);
934   unsigned i, j;
935
936   for (i = 0; i < h; i++) {
937      float *pRow = p;
938      for (j = 0; j < w; j++, pRow += 4) {
939         pRow[0] =
940         pRow[1] =
941         pRow[2] =
942         pRow[3] = (float) (scale * (*src++ >> 8));
943      }
944      p += dst_stride;
945   }
946}
947
948
949/*** PIPE_FORMAT_Z32_FLOAT ***/
950
951/**
952 * Return each Z value as four floats in [0,1].
953 */
954static void
955z32f_get_tile_rgba(const float *src,
956                   unsigned w, unsigned h,
957                   float *p,
958                   unsigned dst_stride)
959{
960   unsigned i, j;
961
962   for (i = 0; i < h; i++) {
963      float *pRow = p;
964      for (j = 0; j < w; j++, pRow += 4) {
965         pRow[0] =
966         pRow[1] =
967         pRow[2] =
968         pRow[3] = *src++;
969      }
970      p += dst_stride;
971   }
972}
973
974
975/*** PIPE_FORMAT_YCBCR / PIPE_FORMAT_YCBCR_REV ***/
976
977/**
978 * Convert YCbCr (or YCrCb) to RGBA.
979 */
980static void
981ycbcr_get_tile_rgba(const ushort *src,
982                    unsigned w, unsigned h,
983                    float *p,
984                    unsigned dst_stride,
985                    boolean rev)
986{
987   const float scale = 1.0f / 255.0f;
988   unsigned i, j;
989
990   for (i = 0; i < h; i++) {
991      float *pRow = p;
992      /* do two texels at a time */
993      for (j = 0; j < (w & ~1); j += 2, src += 2) {
994         const ushort t0 = src[0];
995         const ushort t1 = src[1];
996         const ubyte y0 = (t0 >> 8) & 0xff;  /* luminance */
997         const ubyte y1 = (t1 >> 8) & 0xff;  /* luminance */
998         ubyte cb, cr;
999         float r, g, b;
1000
1001         if (rev) {
1002            cb = t1 & 0xff;         /* chroma U */
1003            cr = t0 & 0xff;         /* chroma V */
1004         }
1005         else {
1006            cb = t0 & 0xff;         /* chroma U */
1007            cr = t1 & 0xff;         /* chroma V */
1008         }
1009
1010         /* even pixel: y0,cr,cb */
1011         r = 1.164f * (y0-16) + 1.596f * (cr-128);
1012         g = 1.164f * (y0-16) - 0.813f * (cr-128) - 0.391f * (cb-128);
1013         b = 1.164f * (y0-16) + 2.018f * (cb-128);
1014         pRow[0] = r * scale;
1015         pRow[1] = g * scale;
1016         pRow[2] = b * scale;
1017         pRow[3] = 1.0f;
1018         pRow += 4;
1019
1020         /* odd pixel: use y1,cr,cb */
1021         r = 1.164f * (y1-16) + 1.596f * (cr-128);
1022         g = 1.164f * (y1-16) - 0.813f * (cr-128) - 0.391f * (cb-128);
1023         b = 1.164f * (y1-16) + 2.018f * (cb-128);
1024         pRow[0] = r * scale;
1025         pRow[1] = g * scale;
1026         pRow[2] = b * scale;
1027         pRow[3] = 1.0f;
1028         pRow += 4;
1029
1030      }
1031      /* do the last texel */
1032      if (w & 1) {
1033         const ushort t0 = src[0];
1034         const ushort t1 = src[1];
1035         const ubyte y0 = (t0 >> 8) & 0xff;  /* luminance */
1036         ubyte cb, cr;
1037         float r, g, b;
1038
1039         if (rev) {
1040            cb = t1 & 0xff;         /* chroma U */
1041            cr = t0 & 0xff;         /* chroma V */
1042         }
1043         else {
1044            cb = t0 & 0xff;         /* chroma U */
1045            cr = t1 & 0xff;         /* chroma V */
1046         }
1047
1048         /* even pixel: y0,cr,cb */
1049         r = 1.164f * (y0-16) + 1.596f * (cr-128);
1050         g = 1.164f * (y0-16) - 0.813f * (cr-128) - 0.391f * (cb-128);
1051         b = 1.164f * (y0-16) + 2.018f * (cb-128);
1052         pRow[0] = r * scale;
1053         pRow[1] = g * scale;
1054         pRow[2] = b * scale;
1055         pRow[3] = 1.0f;
1056         pRow += 4;
1057      }
1058      p += dst_stride;
1059   }
1060}
1061
1062
1063static void
1064fake_get_tile_rgba(const ushort *src,
1065                   unsigned w, unsigned h,
1066                   float *p,
1067                   unsigned dst_stride)
1068{
1069   unsigned i, j;
1070
1071   for (i = 0; i < h; i++) {
1072      float *pRow = p;
1073      for (j = 0; j < w; j++, pRow += 4) {
1074         pRow[0] =
1075         pRow[1] =
1076         pRow[2] =
1077         pRow[3] = (i ^ j) & 1 ? 1.0f : 0.0f;
1078      }
1079      p += dst_stride;
1080   }
1081}
1082
1083
1084void
1085pipe_tile_raw_to_rgba(enum pipe_format format,
1086                      void *src,
1087                      uint w, uint h,
1088                      float *dst, unsigned dst_stride)
1089{
1090   switch (format) {
1091   case PIPE_FORMAT_A8R8G8B8_UNORM:
1092      a8r8g8b8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
1093      break;
1094   case PIPE_FORMAT_X8R8G8B8_UNORM:
1095      x8r8g8b8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
1096      break;
1097   case PIPE_FORMAT_B8G8R8A8_UNORM:
1098      b8g8r8a8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
1099      break;
1100   case PIPE_FORMAT_A1R5G5B5_UNORM:
1101      a1r5g5b5_get_tile_rgba((ushort *) src, w, h, dst, dst_stride);
1102      break;
1103   case PIPE_FORMAT_A4R4G4B4_UNORM:
1104      a4r4g4b4_get_tile_rgba((ushort *) src, w, h, dst, dst_stride);
1105      break;
1106   case PIPE_FORMAT_R5G6B5_UNORM:
1107      r5g6b5_get_tile_rgba((ushort *) src, w, h, dst, dst_stride);
1108      break;
1109   case PIPE_FORMAT_L8_UNORM:
1110      l8_get_tile_rgba((ubyte *) src, w, h, dst, dst_stride);
1111      break;
1112   case PIPE_FORMAT_A8_UNORM:
1113      a8_get_tile_rgba((ubyte *) src, w, h, dst, dst_stride);
1114      break;
1115   case PIPE_FORMAT_I8_UNORM:
1116      i8_get_tile_rgba((ubyte *) src, w, h, dst, dst_stride);
1117      break;
1118   case PIPE_FORMAT_A8L8_UNORM:
1119      a8l8_get_tile_rgba((ushort *) src, w, h, dst, dst_stride);
1120      break;
1121   case PIPE_FORMAT_R16_SNORM:
1122      r16_get_tile_rgba((short *) src, w, h, dst, dst_stride);
1123      break;
1124   case PIPE_FORMAT_R16G16B16A16_SNORM:
1125      r16g16b16a16_get_tile_rgba((short *) src, w, h, dst, dst_stride);
1126      break;
1127   case PIPE_FORMAT_A8R8G8B8_SRGB:
1128      a8r8g8b8_srgb_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
1129      break;
1130   case PIPE_FORMAT_A8L8_SRGB:
1131      a8l8_srgb_get_tile_rgba((ushort *) src, w, h, dst, dst_stride);
1132      break;
1133   case PIPE_FORMAT_L8_SRGB:
1134      l8_srgb_get_tile_rgba((ubyte *) src, w, h, dst, dst_stride);
1135      break;
1136   case PIPE_FORMAT_Z16_UNORM:
1137      z16_get_tile_rgba((ushort *) src, w, h, dst, dst_stride);
1138      break;
1139   case PIPE_FORMAT_Z32_UNORM:
1140      z32_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
1141      break;
1142   case PIPE_FORMAT_S8Z24_UNORM:
1143   case PIPE_FORMAT_X8Z24_UNORM:
1144      s8z24_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
1145      break;
1146   case PIPE_FORMAT_Z24S8_UNORM:
1147   case PIPE_FORMAT_Z24X8_UNORM:
1148      z24s8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
1149      break;
1150   case PIPE_FORMAT_Z32_FLOAT:
1151      z32f_get_tile_rgba((float *) src, w, h, dst, dst_stride);
1152      break;
1153   case PIPE_FORMAT_YCBCR:
1154      ycbcr_get_tile_rgba((ushort *) src, w, h, dst, dst_stride, FALSE);
1155      break;
1156   case PIPE_FORMAT_YCBCR_REV:
1157      ycbcr_get_tile_rgba((ushort *) src, w, h, dst, dst_stride, TRUE);
1158      break;
1159   default:
1160      debug_printf("%s: unsupported format %s\n", __FUNCTION__, pf_name(format));
1161      fake_get_tile_rgba(src, w, h, dst, dst_stride);
1162   }
1163}
1164
1165
1166void
1167pipe_get_tile_rgba(struct pipe_transfer *pt,
1168                   uint x, uint y, uint w, uint h,
1169                   float *p)
1170{
1171   unsigned dst_stride = w * 4;
1172   void *packed;
1173
1174   if (pipe_clip_tile(x, y, &w, &h, pt))
1175      return;
1176
1177   packed = MALLOC(pf_get_nblocks(&pt->block, w, h) * pt->block.size);
1178
1179   if (!packed)
1180      return;
1181
1182   if(pt->format == PIPE_FORMAT_YCBCR || pt->format == PIPE_FORMAT_YCBCR_REV)
1183      assert((x & 1) == 0);
1184
1185   pipe_get_tile_raw(pt, x, y, w, h, packed, 0);
1186
1187   pipe_tile_raw_to_rgba(pt->format, packed, w, h, p, dst_stride);
1188
1189   FREE(packed);
1190}
1191
1192
1193void
1194pipe_put_tile_rgba(struct pipe_transfer *pt,
1195                   uint x, uint y, uint w, uint h,
1196                   const float *p)
1197{
1198   unsigned src_stride = w * 4;
1199   void *packed;
1200
1201   if (pipe_clip_tile(x, y, &w, &h, pt))
1202      return;
1203
1204   packed = MALLOC(pf_get_nblocks(&pt->block, w, h) * pt->block.size);
1205
1206   if (!packed)
1207      return;
1208
1209   switch (pt->format) {
1210   case PIPE_FORMAT_A8R8G8B8_UNORM:
1211      a8r8g8b8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);
1212      break;
1213   case PIPE_FORMAT_X8R8G8B8_UNORM:
1214      x8r8g8b8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);
1215      break;
1216   case PIPE_FORMAT_B8G8R8A8_UNORM:
1217      b8g8r8a8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);
1218      break;
1219   case PIPE_FORMAT_A1R5G5B5_UNORM:
1220      a1r5g5b5_put_tile_rgba((ushort *) packed, w, h, p, src_stride);
1221      break;
1222   case PIPE_FORMAT_R5G6B5_UNORM:
1223      r5g6b5_put_tile_rgba((ushort *) packed, w, h, p, src_stride);
1224      break;
1225   case PIPE_FORMAT_R8G8B8A8_UNORM:
1226      assert(0);
1227      break;
1228   case PIPE_FORMAT_A4R4G4B4_UNORM:
1229      a4r4g4b4_put_tile_rgba((ushort *) packed, w, h, p, src_stride);
1230      break;
1231   case PIPE_FORMAT_L8_UNORM:
1232      l8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);
1233      break;
1234   case PIPE_FORMAT_A8_UNORM:
1235      a8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);
1236      break;
1237   case PIPE_FORMAT_I8_UNORM:
1238      i8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);
1239      break;
1240   case PIPE_FORMAT_A8L8_UNORM:
1241      a8l8_put_tile_rgba((ushort *) packed, w, h, p, src_stride);
1242      break;
1243   case PIPE_FORMAT_R16_SNORM:
1244      r16_put_tile_rgba((short *) packed, w, h, p, src_stride);
1245      break;
1246   case PIPE_FORMAT_R16G16B16A16_SNORM:
1247      r16g16b16a16_put_tile_rgba((short *) packed, w, h, p, src_stride);
1248      break;
1249   case PIPE_FORMAT_A8R8G8B8_SRGB:
1250      a8r8g8b8_srgb_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);
1251      break;
1252   case PIPE_FORMAT_A8L8_SRGB:
1253      a8l8_srgb_put_tile_rgba((ushort *) packed, w, h, p, src_stride);
1254      break;
1255   case PIPE_FORMAT_L8_SRGB:
1256      l8_srgb_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);
1257      break;
1258   case PIPE_FORMAT_Z16_UNORM:
1259      /*z16_put_tile_rgba((ushort *) packed, w, h, p, src_stride);*/
1260      break;
1261   case PIPE_FORMAT_Z32_UNORM:
1262      /*z32_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/
1263      break;
1264   case PIPE_FORMAT_S8Z24_UNORM:
1265   case PIPE_FORMAT_X8Z24_UNORM:
1266      /*s8z24_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/
1267      break;
1268   case PIPE_FORMAT_Z24S8_UNORM:
1269   case PIPE_FORMAT_Z24X8_UNORM:
1270      /*z24s8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/
1271      break;
1272   default:
1273      debug_printf("%s: unsupported format %s\n", __FUNCTION__, pf_name(pt->format));
1274   }
1275
1276   pipe_put_tile_raw(pt, x, y, w, h, packed, 0);
1277
1278   FREE(packed);
1279}
1280
1281
1282/**
1283 * Get a block of Z values, converted to 32-bit range.
1284 */
1285void
1286pipe_get_tile_z(struct pipe_transfer *pt,
1287                uint x, uint y, uint w, uint h,
1288                uint *z)
1289{
1290   struct pipe_screen *screen = pt->texture->screen;
1291   const uint dstStride = w;
1292   ubyte *map;
1293   uint *pDest = z;
1294   uint i, j;
1295
1296   if (pipe_clip_tile(x, y, &w, &h, pt))
1297      return;
1298
1299   map = (ubyte *)screen->transfer_map(screen, pt);
1300   if (!map) {
1301      assert(0);
1302      return;
1303   }
1304
1305   switch (pt->format) {
1306   case PIPE_FORMAT_Z32_UNORM:
1307      {
1308         const uint *ptrc
1309            = (const uint *)(map  + y * pt->stride + x*4);
1310         for (i = 0; i < h; i++) {
1311            memcpy(pDest, ptrc, 4 * w);
1312            pDest += dstStride;
1313            ptrc += pt->stride/4;
1314         }
1315      }
1316      break;
1317   case PIPE_FORMAT_S8Z24_UNORM:
1318   case PIPE_FORMAT_X8Z24_UNORM:
1319      {
1320         const uint *ptrc
1321            = (const uint *)(map + y * pt->stride + x*4);
1322         for (i = 0; i < h; i++) {
1323            for (j = 0; j < w; j++) {
1324               /* convert 24-bit Z to 32-bit Z */
1325               pDest[j] = (ptrc[j] << 8) | ((ptrc[j] >> 16) & 0xff);
1326            }
1327            pDest += dstStride;
1328            ptrc += pt->stride/4;
1329         }
1330      }
1331      break;
1332   case PIPE_FORMAT_Z24S8_UNORM:
1333   case PIPE_FORMAT_Z24X8_UNORM:
1334      {
1335         const uint *ptrc
1336            = (const uint *)(map + y * pt->stride + x*4);
1337         for (i = 0; i < h; i++) {
1338            for (j = 0; j < w; j++) {
1339               /* convert 24-bit Z to 32-bit Z */
1340               pDest[j] = (ptrc[j] & 0xffffff00) | ((ptrc[j] >> 24) & 0xff);
1341            }
1342            pDest += dstStride;
1343            ptrc += pt->stride/4;
1344         }
1345      }
1346      break;
1347   case PIPE_FORMAT_Z16_UNORM:
1348      {
1349         const ushort *ptrc
1350            = (const ushort *)(map + y * pt->stride + x*2);
1351         for (i = 0; i < h; i++) {
1352            for (j = 0; j < w; j++) {
1353               /* convert 16-bit Z to 32-bit Z */
1354               pDest[j] = (ptrc[j] << 16) | ptrc[j];
1355            }
1356            pDest += dstStride;
1357            ptrc += pt->stride/2;
1358         }
1359      }
1360      break;
1361   default:
1362      assert(0);
1363   }
1364
1365   screen->transfer_unmap(screen, pt);
1366}
1367
1368
1369void
1370pipe_put_tile_z(struct pipe_transfer *pt,
1371                uint x, uint y, uint w, uint h,
1372                const uint *zSrc)
1373{
1374   struct pipe_screen *screen = pt->texture->screen;
1375   const uint srcStride = w;
1376   const uint *ptrc = zSrc;
1377   ubyte *map;
1378   uint i, j;
1379
1380   if (pipe_clip_tile(x, y, &w, &h, pt))
1381      return;
1382
1383   map = (ubyte *)screen->transfer_map(screen, pt);
1384   if (!map) {
1385      assert(0);
1386      return;
1387   }
1388
1389   switch (pt->format) {
1390   case PIPE_FORMAT_Z32_UNORM:
1391      {
1392         uint *pDest = (uint *) (map + y * pt->stride + x*4);
1393         for (i = 0; i < h; i++) {
1394            memcpy(pDest, ptrc, 4 * w);
1395            pDest += pt->stride/4;
1396            ptrc += srcStride;
1397         }
1398      }
1399      break;
1400   case PIPE_FORMAT_S8Z24_UNORM:
1401      {
1402         uint *pDest = (uint *) (map + y * pt->stride + x*4);
1403         assert(pt->usage == PIPE_TRANSFER_READ_WRITE);
1404         for (i = 0; i < h; i++) {
1405            for (j = 0; j < w; j++) {
1406               /* convert 32-bit Z to 24-bit Z, preserve stencil */
1407               pDest[j] = (pDest[j] & 0xff000000) | ptrc[j] >> 8;
1408            }
1409            pDest += pt->stride/4;
1410            ptrc += srcStride;
1411         }
1412      }
1413      break;
1414   case PIPE_FORMAT_X8Z24_UNORM:
1415      {
1416         uint *pDest = (uint *) (map + y * pt->stride + x*4);
1417         for (i = 0; i < h; i++) {
1418            for (j = 0; j < w; j++) {
1419               /* convert 32-bit Z to 24-bit Z (0 stencil) */
1420               pDest[j] = ptrc[j] >> 8;
1421            }
1422            pDest += pt->stride/4;
1423            ptrc += srcStride;
1424         }
1425      }
1426      break;
1427   case PIPE_FORMAT_Z24S8_UNORM:
1428      {
1429         uint *pDest = (uint *) (map + y * pt->stride + x*4);
1430         assert(pt->usage == PIPE_TRANSFER_READ_WRITE);
1431         for (i = 0; i < h; i++) {
1432            for (j = 0; j < w; j++) {
1433               /* convert 32-bit Z to 24-bit Z, preserve stencil */
1434               pDest[j] = (pDest[j] & 0xff) | (ptrc[j] & 0xffffff00);
1435            }
1436            pDest += pt->stride/4;
1437            ptrc += srcStride;
1438         }
1439      }
1440      break;
1441   case PIPE_FORMAT_Z24X8_UNORM:
1442      {
1443         uint *pDest = (uint *) (map + y * pt->stride + x*4);
1444         for (i = 0; i < h; i++) {
1445            for (j = 0; j < w; j++) {
1446               /* convert 32-bit Z to 24-bit Z (0 stencil) */
1447               pDest[j] = ptrc[j] & 0xffffff00;
1448            }
1449            pDest += pt->stride/4;
1450            ptrc += srcStride;
1451         }
1452      }
1453      break;
1454   case PIPE_FORMAT_Z16_UNORM:
1455      {
1456         ushort *pDest = (ushort *) (map + y * pt->stride + x*2);
1457         for (i = 0; i < h; i++) {
1458            for (j = 0; j < w; j++) {
1459               /* convert 32-bit Z to 16-bit Z */
1460               pDest[j] = ptrc[j] >> 16;
1461            }
1462            pDest += pt->stride/2;
1463            ptrc += srcStride;
1464         }
1465      }
1466      break;
1467   default:
1468      assert(0);
1469   }
1470
1471   screen->transfer_unmap(screen, pt);
1472}
1473
1474
1475