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