u_tile.c revision 5e78903952961fc207b8da1f7b2d0c6ddfd49881
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   util_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   util_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] = 1.0F;
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 << 8) | (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_R8G8B8_UNORM ***/
398
399static void
400r8g8b8_get_tile_rgba(const ubyte *src,
401                     unsigned w, unsigned h,
402                     float *p,
403                     unsigned dst_stride)
404{
405   unsigned i, j;
406
407   for (i = 0; i < h; i++) {
408      float *pRow = p;
409      for (j = 0; j < w; j++, pRow += 4) {
410         pRow[0] = ubyte_to_float(src[0]);
411         pRow[1] = ubyte_to_float(src[1]);
412         pRow[2] = ubyte_to_float(src[2]);
413         pRow[3] = 1.0f;
414         src += 3;
415      }
416      p += dst_stride;
417   }
418}
419
420
421static void
422r8g8b8_put_tile_rgba(ubyte *dst,
423                     unsigned w, unsigned h,
424                     const float *p,
425                     unsigned src_stride)
426{
427   unsigned i, j;
428
429   for (i = 0; i < h; i++) {
430      const float *pRow = p;
431      for (j = 0; j < w; j++, pRow += 4) {
432         dst[0] = float_to_ubyte(pRow[0]);
433         dst[1] = float_to_ubyte(pRow[1]);
434         dst[2] = float_to_ubyte(pRow[2]);
435         dst += 3;
436      }
437      p += src_stride;
438   }
439}
440
441
442
443/*** PIPE_FORMAT_Z16_UNORM ***/
444
445/**
446 * Return each Z value as four floats in [0,1].
447 */
448static void
449z16_get_tile_rgba(const ushort *src,
450                  unsigned w, unsigned h,
451                  float *p,
452                  unsigned dst_stride)
453{
454   const float scale = 1.0f / 65535.0f;
455   unsigned i, j;
456
457   for (i = 0; i < h; i++) {
458      float *pRow = p;
459      for (j = 0; j < w; j++, pRow += 4) {
460         pRow[0] =
461         pRow[1] =
462         pRow[2] =
463         pRow[3] = *src++ * scale;
464      }
465      p += dst_stride;
466   }
467}
468
469
470
471
472/*** PIPE_FORMAT_L8_UNORM ***/
473
474static void
475l8_get_tile_rgba(const ubyte *src,
476                 unsigned w, unsigned h,
477                 float *p,
478                 unsigned dst_stride)
479{
480   unsigned i, j;
481
482   for (i = 0; i < h; i++) {
483      float *pRow = p;
484      for (j = 0; j < w; j++, src++, pRow += 4) {
485         pRow[0] =
486         pRow[1] =
487         pRow[2] = ubyte_to_float(*src);
488         pRow[3] = 1.0;
489      }
490      p += dst_stride;
491   }
492}
493
494
495static void
496l8_put_tile_rgba(ubyte *dst,
497                 unsigned w, unsigned h,
498                 const float *p,
499                 unsigned src_stride)
500{
501   unsigned i, j;
502
503   for (i = 0; i < h; i++) {
504      const float *pRow = p;
505      for (j = 0; j < w; j++, pRow += 4) {
506         unsigned r;
507         r = float_to_ubyte(pRow[0]);
508         *dst++ = (ubyte) r;
509      }
510      p += src_stride;
511   }
512}
513
514
515
516/*** PIPE_FORMAT_A8_UNORM ***/
517
518static void
519a8_get_tile_rgba(const ubyte *src,
520                 unsigned w, unsigned h,
521                 float *p,
522                 unsigned dst_stride)
523{
524   unsigned i, j;
525
526   for (i = 0; i < h; i++) {
527      float *pRow = p;
528      for (j = 0; j < w; j++, src++, pRow += 4) {
529         pRow[0] =
530         pRow[1] =
531         pRow[2] = 0.0;
532         pRow[3] = ubyte_to_float(*src);
533      }
534      p += dst_stride;
535   }
536}
537
538
539static void
540a8_put_tile_rgba(ubyte *dst,
541                 unsigned w, unsigned h,
542                 const float *p,
543                 unsigned src_stride)
544{
545   unsigned i, j;
546
547   for (i = 0; i < h; i++) {
548      const float *pRow = p;
549      for (j = 0; j < w; j++, pRow += 4) {
550         unsigned a;
551         a = float_to_ubyte(pRow[3]);
552         *dst++ = (ubyte) a;
553      }
554      p += src_stride;
555   }
556}
557
558
559
560/*** PIPE_FORMAT_R16_SNORM ***/
561
562static void
563r16_get_tile_rgba(const short *src,
564                  unsigned w, unsigned h,
565                  float *p,
566                  unsigned dst_stride)
567{
568   unsigned i, j;
569
570   for (i = 0; i < h; i++) {
571      float *pRow = p;
572      for (j = 0; j < w; j++, src++, pRow += 4) {
573         pRow[0] = SHORT_TO_FLOAT(src[0]);
574         pRow[1] =
575         pRow[2] = 0.0;
576         pRow[3] = 1.0;
577      }
578      p += dst_stride;
579   }
580}
581
582
583static void
584r16_put_tile_rgba(short *dst,
585                  unsigned w, unsigned h,
586                  const float *p,
587                  unsigned src_stride)
588{
589   unsigned i, j;
590
591   for (i = 0; i < h; i++) {
592      const float *pRow = p;
593      for (j = 0; j < w; j++, dst++, pRow += 4) {
594         UNCLAMPED_FLOAT_TO_SHORT(dst[0], pRow[0]);
595      }
596      p += src_stride;
597   }
598}
599
600
601/*** PIPE_FORMAT_R16G16B16A16_SNORM ***/
602
603static void
604r16g16b16a16_get_tile_rgba(const short *src,
605                           unsigned w, unsigned h,
606                           float *p,
607                           unsigned dst_stride)
608{
609   unsigned i, j;
610
611   for (i = 0; i < h; i++) {
612      float *pRow = p;
613      for (j = 0; j < w; j++, src += 4, pRow += 4) {
614         pRow[0] = SHORT_TO_FLOAT(src[0]);
615         pRow[1] = SHORT_TO_FLOAT(src[1]);
616         pRow[2] = SHORT_TO_FLOAT(src[2]);
617         pRow[3] = SHORT_TO_FLOAT(src[3]);
618      }
619      p += dst_stride;
620   }
621}
622
623
624static void
625r16g16b16a16_put_tile_rgba(short *dst,
626                           unsigned w, unsigned h,
627                           const float *p,
628                           unsigned src_stride)
629{
630   unsigned i, j;
631
632   for (i = 0; i < h; i++) {
633      const float *pRow = p;
634      for (j = 0; j < w; j++, dst += 4, pRow += 4) {
635         UNCLAMPED_FLOAT_TO_SHORT(dst[0], pRow[0]);
636         UNCLAMPED_FLOAT_TO_SHORT(dst[1], pRow[1]);
637         UNCLAMPED_FLOAT_TO_SHORT(dst[2], pRow[2]);
638         UNCLAMPED_FLOAT_TO_SHORT(dst[3], pRow[3]);
639      }
640      p += src_stride;
641   }
642}
643
644
645/*** PIPE_FORMAT_R8G8B8A8_SRGB ***/
646
647/**
648 * Convert an 8-bit sRGB value from non-linear space to a
649 * linear RGB value in [0, 1].
650 * Implemented with a 256-entry lookup table.
651 */
652static INLINE float
653srgb_to_linear(ubyte cs8)
654{
655   static float table[256];
656   static boolean tableReady = FALSE;
657   if (!tableReady) {
658      /* compute lookup table now */
659      uint i;
660      for (i = 0; i < 256; i++) {
661         const float cs = ubyte_to_float(i);
662         if (cs <= 0.04045) {
663            table[i] = cs / 12.92f;
664         }
665         else {
666            table[i] = (float) powf((cs + 0.055) / 1.055, 2.4);
667         }
668      }
669      tableReady = TRUE;
670   }
671   return table[cs8];
672}
673
674
675/**
676 * Convert linear float in [0,1] to an srgb ubyte value in [0,255].
677 * XXX this hasn't been tested (render to srgb surface).
678 * XXX this needs optimization.
679 */
680static INLINE ubyte
681linear_to_srgb(float cl)
682{
683   if (cl >= 1.0F)
684      return 255;
685   else if (cl >= 0.0031308F)
686      return float_to_ubyte(1.055F * powf(cl, 0.41666F) - 0.055F);
687   else if (cl > 0.0F)
688      return float_to_ubyte(12.92F * cl);
689   else
690      return 0.0;
691}
692
693
694static void
695a8r8g8b8_srgb_get_tile_rgba(const unsigned *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         const unsigned pixel = *src++;
706         pRow[0] = srgb_to_linear((pixel >> 16) & 0xff);
707         pRow[1] = srgb_to_linear((pixel >>  8) & 0xff);
708         pRow[2] = srgb_to_linear((pixel >>  0) & 0xff);
709         pRow[3] = ubyte_to_float((pixel >> 24) & 0xff);
710      }
711      p += dst_stride;
712   }
713}
714
715static void
716a8r8g8b8_srgb_put_tile_rgba(unsigned *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, g, b, a;
727         r = linear_to_srgb(pRow[0]);
728         g = linear_to_srgb(pRow[1]);
729         b = linear_to_srgb(pRow[2]);
730         a = float_to_ubyte(pRow[3]);
731         *dst++ = (a << 24) | (r << 16) | (g << 8) | b;
732      }
733      p += src_stride;
734   }
735}
736
737
738/*** PIPE_FORMAT_A8L8_SRGB ***/
739
740static void
741a8l8_srgb_get_tile_rgba(const ushort *src,
742                        unsigned w, unsigned h,
743                        float *p,
744                        unsigned dst_stride)
745{
746   unsigned i, j;
747
748   for (i = 0; i < h; i++) {
749      float *pRow = p;
750      for (j = 0; j < w; j++, pRow += 4) {
751         ushort p = *src++;
752         pRow[0] =
753         pRow[1] =
754         pRow[2] = srgb_to_linear(p & 0xff);
755         pRow[3] = ubyte_to_float(p >> 8);
756      }
757      p += dst_stride;
758   }
759}
760
761static void
762a8l8_srgb_put_tile_rgba(ushort *dst,
763                        unsigned w, unsigned h,
764                        const float *p,
765                        unsigned src_stride)
766{
767   unsigned i, j;
768
769   for (i = 0; i < h; i++) {
770      const float *pRow = p;
771      for (j = 0; j < w; j++, pRow += 4) {
772         unsigned r, a;
773         r = linear_to_srgb(pRow[0]);
774         a = float_to_ubyte(pRow[3]);
775         *dst++ = (a << 8) | r;
776      }
777      p += src_stride;
778   }
779}
780
781
782/*** PIPE_FORMAT_L8_SRGB ***/
783
784static void
785l8_srgb_get_tile_rgba(const ubyte *src,
786                      unsigned w, unsigned h,
787                      float *p,
788                      unsigned dst_stride)
789{
790   unsigned i, j;
791
792   for (i = 0; i < h; i++) {
793      float *pRow = p;
794      for (j = 0; j < w; j++, src++, pRow += 4) {
795         pRow[0] =
796         pRow[1] =
797         pRow[2] = srgb_to_linear(*src);
798         pRow[3] = 1.0;
799      }
800      p += dst_stride;
801   }
802}
803
804static void
805l8_srgb_put_tile_rgba(ubyte *dst,
806                      unsigned w, unsigned h,
807                      const float *p,
808                      unsigned src_stride)
809{
810   unsigned i, j;
811
812   for (i = 0; i < h; i++) {
813      const float *pRow = p;
814      for (j = 0; j < w; j++, pRow += 4) {
815         unsigned r;
816         r = linear_to_srgb(pRow[0]);
817         *dst++ = (ubyte) r;
818      }
819      p += src_stride;
820   }
821}
822
823
824/*** PIPE_FORMAT_I8_UNORM ***/
825
826static void
827i8_get_tile_rgba(const ubyte *src,
828                 unsigned w, unsigned h,
829                 float *p,
830                 unsigned dst_stride)
831{
832   unsigned i, j;
833
834   for (i = 0; i < h; i++) {
835      float *pRow = p;
836      for (j = 0; j < w; j++, src++, pRow += 4) {
837         pRow[0] =
838         pRow[1] =
839         pRow[2] =
840         pRow[3] = ubyte_to_float(*src);
841      }
842      p += dst_stride;
843   }
844}
845
846
847static void
848i8_put_tile_rgba(ubyte *dst,
849                 unsigned w, unsigned h,
850                 const float *p,
851                 unsigned src_stride)
852{
853   unsigned i, j;
854
855   for (i = 0; i < h; i++) {
856      const float *pRow = p;
857      for (j = 0; j < w; j++, pRow += 4) {
858         unsigned r;
859         r = float_to_ubyte(pRow[0]);
860         *dst++ = (ubyte) r;
861      }
862      p += src_stride;
863   }
864}
865
866
867/*** PIPE_FORMAT_A8L8_UNORM ***/
868
869static void
870a8l8_get_tile_rgba(const ushort *src,
871                   unsigned w, unsigned h,
872                   float *p,
873                   unsigned dst_stride)
874{
875   unsigned i, j;
876
877   for (i = 0; i < h; i++) {
878      float *pRow = p;
879      for (j = 0; j < w; j++, pRow += 4) {
880         ushort p = *src++;
881         pRow[0] =
882         pRow[1] =
883         pRow[2] = ubyte_to_float(p & 0xff);
884         pRow[3] = ubyte_to_float(p >> 8);
885      }
886      p += dst_stride;
887   }
888}
889
890
891static void
892a8l8_put_tile_rgba(ushort *dst,
893                   unsigned w, unsigned h,
894                   const float *p,
895                   unsigned src_stride)
896{
897   unsigned i, j;
898
899   for (i = 0; i < h; i++) {
900      const float *pRow = p;
901      for (j = 0; j < w; j++, pRow += 4) {
902         unsigned r, a;
903         r = float_to_ubyte(pRow[0]);
904         a = float_to_ubyte(pRow[3]);
905         *dst++ = (a << 8) | r;
906      }
907      p += src_stride;
908   }
909}
910
911
912
913
914/*** PIPE_FORMAT_Z32_UNORM ***/
915
916/**
917 * Return each Z value as four floats in [0,1].
918 */
919static void
920z32_get_tile_rgba(const unsigned *src,
921                  unsigned w, unsigned h,
922                  float *p,
923                  unsigned dst_stride)
924{
925   const double scale = 1.0 / (double) 0xffffffff;
926   unsigned i, j;
927
928   for (i = 0; i < h; i++) {
929      float *pRow = p;
930      for (j = 0; j < w; j++, pRow += 4) {
931         pRow[0] =
932         pRow[1] =
933         pRow[2] =
934         pRow[3] = (float) (*src++ * scale);
935      }
936      p += dst_stride;
937   }
938}
939
940
941/*** PIPE_FORMAT_S8Z24_UNORM ***/
942
943/**
944 * Return Z component as four float in [0,1].  Stencil part ignored.
945 */
946static void
947s8z24_get_tile_rgba(const unsigned *src,
948                    unsigned w, unsigned h,
949                    float *p,
950                    unsigned dst_stride)
951{
952   const double scale = 1.0 / ((1 << 24) - 1);
953   unsigned i, j;
954
955   for (i = 0; i < h; i++) {
956      float *pRow = p;
957      for (j = 0; j < w; j++, pRow += 4) {
958         pRow[0] =
959         pRow[1] =
960         pRow[2] =
961         pRow[3] = (float) (scale * (*src++ & 0xffffff));
962      }
963      p += dst_stride;
964   }
965}
966
967
968/*** PIPE_FORMAT_Z24S8_UNORM ***/
969
970/**
971 * Return Z component as four float in [0,1].  Stencil part ignored.
972 */
973static void
974z24s8_get_tile_rgba(const unsigned *src,
975                    unsigned w, unsigned h,
976                    float *p,
977                    unsigned dst_stride)
978{
979   const double scale = 1.0 / ((1 << 24) - 1);
980   unsigned i, j;
981
982   for (i = 0; i < h; i++) {
983      float *pRow = p;
984      for (j = 0; j < w; j++, pRow += 4) {
985         pRow[0] =
986         pRow[1] =
987         pRow[2] =
988         pRow[3] = (float) (scale * (*src++ >> 8));
989      }
990      p += dst_stride;
991   }
992}
993
994
995/*** PIPE_FORMAT_Z32_FLOAT ***/
996
997/**
998 * Return each Z value as four floats in [0,1].
999 */
1000static void
1001z32f_get_tile_rgba(const float *src,
1002                   unsigned w, unsigned h,
1003                   float *p,
1004                   unsigned dst_stride)
1005{
1006   unsigned i, j;
1007
1008   for (i = 0; i < h; i++) {
1009      float *pRow = p;
1010      for (j = 0; j < w; j++, pRow += 4) {
1011         pRow[0] =
1012         pRow[1] =
1013         pRow[2] =
1014         pRow[3] = *src++;
1015      }
1016      p += dst_stride;
1017   }
1018}
1019
1020
1021/*** PIPE_FORMAT_YCBCR / PIPE_FORMAT_YCBCR_REV ***/
1022
1023/**
1024 * Convert YCbCr (or YCrCb) to RGBA.
1025 */
1026static void
1027ycbcr_get_tile_rgba(const ushort *src,
1028                    unsigned w, unsigned h,
1029                    float *p,
1030                    unsigned dst_stride,
1031                    boolean rev)
1032{
1033   const float scale = 1.0f / 255.0f;
1034   unsigned i, j;
1035
1036   for (i = 0; i < h; i++) {
1037      float *pRow = p;
1038      /* do two texels at a time */
1039      for (j = 0; j < (w & ~1); j += 2, src += 2) {
1040         const ushort t0 = src[0];
1041         const ushort t1 = src[1];
1042         const ubyte y0 = (t0 >> 8) & 0xff;  /* luminance */
1043         const ubyte y1 = (t1 >> 8) & 0xff;  /* luminance */
1044         ubyte cb, cr;
1045         float r, g, b;
1046
1047         if (rev) {
1048            cb = t1 & 0xff;         /* chroma U */
1049            cr = t0 & 0xff;         /* chroma V */
1050         }
1051         else {
1052            cb = t0 & 0xff;         /* chroma U */
1053            cr = t1 & 0xff;         /* chroma V */
1054         }
1055
1056         /* even pixel: y0,cr,cb */
1057         r = 1.164f * (y0-16) + 1.596f * (cr-128);
1058         g = 1.164f * (y0-16) - 0.813f * (cr-128) - 0.391f * (cb-128);
1059         b = 1.164f * (y0-16) + 2.018f * (cb-128);
1060         pRow[0] = r * scale;
1061         pRow[1] = g * scale;
1062         pRow[2] = b * scale;
1063         pRow[3] = 1.0f;
1064         pRow += 4;
1065
1066         /* odd pixel: use y1,cr,cb */
1067         r = 1.164f * (y1-16) + 1.596f * (cr-128);
1068         g = 1.164f * (y1-16) - 0.813f * (cr-128) - 0.391f * (cb-128);
1069         b = 1.164f * (y1-16) + 2.018f * (cb-128);
1070         pRow[0] = r * scale;
1071         pRow[1] = g * scale;
1072         pRow[2] = b * scale;
1073         pRow[3] = 1.0f;
1074         pRow += 4;
1075
1076      }
1077      /* do the last texel */
1078      if (w & 1) {
1079         const ushort t0 = src[0];
1080         const ushort t1 = src[1];
1081         const ubyte y0 = (t0 >> 8) & 0xff;  /* luminance */
1082         ubyte cb, cr;
1083         float r, g, b;
1084
1085         if (rev) {
1086            cb = t1 & 0xff;         /* chroma U */
1087            cr = t0 & 0xff;         /* chroma V */
1088         }
1089         else {
1090            cb = t0 & 0xff;         /* chroma U */
1091            cr = t1 & 0xff;         /* chroma V */
1092         }
1093
1094         /* even pixel: y0,cr,cb */
1095         r = 1.164f * (y0-16) + 1.596f * (cr-128);
1096         g = 1.164f * (y0-16) - 0.813f * (cr-128) - 0.391f * (cb-128);
1097         b = 1.164f * (y0-16) + 2.018f * (cb-128);
1098         pRow[0] = r * scale;
1099         pRow[1] = g * scale;
1100         pRow[2] = b * scale;
1101         pRow[3] = 1.0f;
1102         pRow += 4;
1103      }
1104      p += dst_stride;
1105   }
1106}
1107
1108
1109static void
1110fake_get_tile_rgba(const ushort *src,
1111                   unsigned w, unsigned h,
1112                   float *p,
1113                   unsigned dst_stride)
1114{
1115   unsigned i, j;
1116
1117   for (i = 0; i < h; i++) {
1118      float *pRow = p;
1119      for (j = 0; j < w; j++, pRow += 4) {
1120         pRow[0] =
1121         pRow[1] =
1122         pRow[2] =
1123         pRow[3] = (i ^ j) & 1 ? 1.0f : 0.0f;
1124      }
1125      p += dst_stride;
1126   }
1127}
1128
1129
1130void
1131pipe_tile_raw_to_rgba(enum pipe_format format,
1132                      void *src,
1133                      uint w, uint h,
1134                      float *dst, unsigned dst_stride)
1135{
1136   switch (format) {
1137   case PIPE_FORMAT_A8R8G8B8_UNORM:
1138      a8r8g8b8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
1139      break;
1140   case PIPE_FORMAT_X8R8G8B8_UNORM:
1141      x8r8g8b8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
1142      break;
1143   case PIPE_FORMAT_B8G8R8A8_UNORM:
1144      b8g8r8a8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
1145      break;
1146   case PIPE_FORMAT_A1R5G5B5_UNORM:
1147      a1r5g5b5_get_tile_rgba((ushort *) src, w, h, dst, dst_stride);
1148      break;
1149   case PIPE_FORMAT_A4R4G4B4_UNORM:
1150      a4r4g4b4_get_tile_rgba((ushort *) src, w, h, dst, dst_stride);
1151      break;
1152   case PIPE_FORMAT_R5G6B5_UNORM:
1153      r5g6b5_get_tile_rgba((ushort *) src, w, h, dst, dst_stride);
1154      break;
1155   case PIPE_FORMAT_R8G8B8_UNORM:
1156      r8g8b8_get_tile_rgba((ubyte *) src, w, h, dst, dst_stride);
1157      break;
1158   case PIPE_FORMAT_L8_UNORM:
1159      l8_get_tile_rgba((ubyte *) src, w, h, dst, dst_stride);
1160      break;
1161   case PIPE_FORMAT_A8_UNORM:
1162      a8_get_tile_rgba((ubyte *) src, w, h, dst, dst_stride);
1163      break;
1164   case PIPE_FORMAT_I8_UNORM:
1165      i8_get_tile_rgba((ubyte *) src, w, h, dst, dst_stride);
1166      break;
1167   case PIPE_FORMAT_A8L8_UNORM:
1168      a8l8_get_tile_rgba((ushort *) src, w, h, dst, dst_stride);
1169      break;
1170   case PIPE_FORMAT_R16_SNORM:
1171      r16_get_tile_rgba((short *) src, w, h, dst, dst_stride);
1172      break;
1173   case PIPE_FORMAT_R16G16B16A16_SNORM:
1174      r16g16b16a16_get_tile_rgba((short *) src, w, h, dst, dst_stride);
1175      break;
1176   case PIPE_FORMAT_A8R8G8B8_SRGB:
1177      a8r8g8b8_srgb_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
1178      break;
1179   case PIPE_FORMAT_A8L8_SRGB:
1180      a8l8_srgb_get_tile_rgba((ushort *) src, w, h, dst, dst_stride);
1181      break;
1182   case PIPE_FORMAT_L8_SRGB:
1183      l8_srgb_get_tile_rgba((ubyte *) src, w, h, dst, dst_stride);
1184      break;
1185   case PIPE_FORMAT_Z16_UNORM:
1186      z16_get_tile_rgba((ushort *) src, w, h, dst, dst_stride);
1187      break;
1188   case PIPE_FORMAT_Z32_UNORM:
1189      z32_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
1190      break;
1191   case PIPE_FORMAT_S8Z24_UNORM:
1192   case PIPE_FORMAT_X8Z24_UNORM:
1193      s8z24_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
1194      break;
1195   case PIPE_FORMAT_Z24S8_UNORM:
1196   case PIPE_FORMAT_Z24X8_UNORM:
1197      z24s8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
1198      break;
1199   case PIPE_FORMAT_Z32_FLOAT:
1200      z32f_get_tile_rgba((float *) src, w, h, dst, dst_stride);
1201      break;
1202   case PIPE_FORMAT_YCBCR:
1203      ycbcr_get_tile_rgba((ushort *) src, w, h, dst, dst_stride, FALSE);
1204      break;
1205   case PIPE_FORMAT_YCBCR_REV:
1206      ycbcr_get_tile_rgba((ushort *) src, w, h, dst, dst_stride, TRUE);
1207      break;
1208   default:
1209      debug_printf("%s: unsupported format %s\n", __FUNCTION__, pf_name(format));
1210      fake_get_tile_rgba(src, w, h, dst, dst_stride);
1211   }
1212}
1213
1214
1215void
1216pipe_get_tile_rgba(struct pipe_transfer *pt,
1217                   uint x, uint y, uint w, uint h,
1218                   float *p)
1219{
1220   unsigned dst_stride = w * 4;
1221   void *packed;
1222
1223   if (pipe_clip_tile(x, y, &w, &h, pt))
1224      return;
1225
1226   packed = MALLOC(pf_get_nblocks(&pt->block, w, h) * pt->block.size);
1227
1228   if (!packed)
1229      return;
1230
1231   if(pt->format == PIPE_FORMAT_YCBCR || pt->format == PIPE_FORMAT_YCBCR_REV)
1232      assert((x & 1) == 0);
1233
1234   pipe_get_tile_raw(pt, x, y, w, h, packed, 0);
1235
1236   pipe_tile_raw_to_rgba(pt->format, packed, w, h, p, dst_stride);
1237
1238   FREE(packed);
1239}
1240
1241
1242void
1243pipe_put_tile_rgba(struct pipe_transfer *pt,
1244                   uint x, uint y, uint w, uint h,
1245                   const float *p)
1246{
1247   unsigned src_stride = w * 4;
1248   void *packed;
1249
1250   if (pipe_clip_tile(x, y, &w, &h, pt))
1251      return;
1252
1253   packed = MALLOC(pf_get_nblocks(&pt->block, w, h) * pt->block.size);
1254
1255   if (!packed)
1256      return;
1257
1258   switch (pt->format) {
1259   case PIPE_FORMAT_A8R8G8B8_UNORM:
1260      a8r8g8b8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);
1261      break;
1262   case PIPE_FORMAT_X8R8G8B8_UNORM:
1263      x8r8g8b8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);
1264      break;
1265   case PIPE_FORMAT_B8G8R8A8_UNORM:
1266      b8g8r8a8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);
1267      break;
1268   case PIPE_FORMAT_A1R5G5B5_UNORM:
1269      a1r5g5b5_put_tile_rgba((ushort *) packed, w, h, p, src_stride);
1270      break;
1271   case PIPE_FORMAT_R5G6B5_UNORM:
1272      r5g6b5_put_tile_rgba((ushort *) packed, w, h, p, src_stride);
1273      break;
1274   case PIPE_FORMAT_R8G8B8_UNORM:
1275      r8g8b8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);
1276      break;
1277   case PIPE_FORMAT_R8G8B8A8_UNORM:
1278      assert(0);
1279      break;
1280   case PIPE_FORMAT_A4R4G4B4_UNORM:
1281      a4r4g4b4_put_tile_rgba((ushort *) packed, w, h, p, src_stride);
1282      break;
1283   case PIPE_FORMAT_L8_UNORM:
1284      l8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);
1285      break;
1286   case PIPE_FORMAT_A8_UNORM:
1287      a8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);
1288      break;
1289   case PIPE_FORMAT_I8_UNORM:
1290      i8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);
1291      break;
1292   case PIPE_FORMAT_A8L8_UNORM:
1293      a8l8_put_tile_rgba((ushort *) packed, w, h, p, src_stride);
1294      break;
1295   case PIPE_FORMAT_R16_SNORM:
1296      r16_put_tile_rgba((short *) packed, w, h, p, src_stride);
1297      break;
1298   case PIPE_FORMAT_R16G16B16A16_SNORM:
1299      r16g16b16a16_put_tile_rgba((short *) packed, w, h, p, src_stride);
1300      break;
1301   case PIPE_FORMAT_A8R8G8B8_SRGB:
1302      a8r8g8b8_srgb_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);
1303      break;
1304   case PIPE_FORMAT_A8L8_SRGB:
1305      a8l8_srgb_put_tile_rgba((ushort *) packed, w, h, p, src_stride);
1306      break;
1307   case PIPE_FORMAT_L8_SRGB:
1308      l8_srgb_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);
1309      break;
1310   case PIPE_FORMAT_Z16_UNORM:
1311      /*z16_put_tile_rgba((ushort *) packed, w, h, p, src_stride);*/
1312      break;
1313   case PIPE_FORMAT_Z32_UNORM:
1314      /*z32_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/
1315      break;
1316   case PIPE_FORMAT_S8Z24_UNORM:
1317   case PIPE_FORMAT_X8Z24_UNORM:
1318      /*s8z24_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/
1319      break;
1320   case PIPE_FORMAT_Z24S8_UNORM:
1321   case PIPE_FORMAT_Z24X8_UNORM:
1322      /*z24s8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/
1323      break;
1324   default:
1325      debug_printf("%s: unsupported format %s\n", __FUNCTION__, pf_name(pt->format));
1326   }
1327
1328   pipe_put_tile_raw(pt, x, y, w, h, packed, 0);
1329
1330   FREE(packed);
1331}
1332
1333
1334/**
1335 * Get a block of Z values, converted to 32-bit range.
1336 */
1337void
1338pipe_get_tile_z(struct pipe_transfer *pt,
1339                uint x, uint y, uint w, uint h,
1340                uint *z)
1341{
1342   struct pipe_screen *screen = pt->texture->screen;
1343   const uint dstStride = w;
1344   ubyte *map;
1345   uint *pDest = z;
1346   uint i, j;
1347
1348   if (pipe_clip_tile(x, y, &w, &h, pt))
1349      return;
1350
1351   map = (ubyte *)screen->transfer_map(screen, pt);
1352   if (!map) {
1353      assert(0);
1354      return;
1355   }
1356
1357   switch (pt->format) {
1358   case PIPE_FORMAT_Z32_UNORM:
1359      {
1360         const uint *ptrc
1361            = (const uint *)(map  + y * pt->stride + x*4);
1362         for (i = 0; i < h; i++) {
1363            memcpy(pDest, ptrc, 4 * w);
1364            pDest += dstStride;
1365            ptrc += pt->stride/4;
1366         }
1367      }
1368      break;
1369   case PIPE_FORMAT_S8Z24_UNORM:
1370   case PIPE_FORMAT_X8Z24_UNORM:
1371      {
1372         const uint *ptrc
1373            = (const uint *)(map + y * pt->stride + x*4);
1374         for (i = 0; i < h; i++) {
1375            for (j = 0; j < w; j++) {
1376               /* convert 24-bit Z to 32-bit Z */
1377               pDest[j] = (ptrc[j] << 8) | ((ptrc[j] >> 16) & 0xff);
1378            }
1379            pDest += dstStride;
1380            ptrc += pt->stride/4;
1381         }
1382      }
1383      break;
1384   case PIPE_FORMAT_Z24S8_UNORM:
1385   case PIPE_FORMAT_Z24X8_UNORM:
1386      {
1387         const uint *ptrc
1388            = (const uint *)(map + y * pt->stride + x*4);
1389         for (i = 0; i < h; i++) {
1390            for (j = 0; j < w; j++) {
1391               /* convert 24-bit Z to 32-bit Z */
1392               pDest[j] = (ptrc[j] & 0xffffff00) | ((ptrc[j] >> 24) & 0xff);
1393            }
1394            pDest += dstStride;
1395            ptrc += pt->stride/4;
1396         }
1397      }
1398      break;
1399   case PIPE_FORMAT_Z16_UNORM:
1400      {
1401         const ushort *ptrc
1402            = (const ushort *)(map + y * pt->stride + x*2);
1403         for (i = 0; i < h; i++) {
1404            for (j = 0; j < w; j++) {
1405               /* convert 16-bit Z to 32-bit Z */
1406               pDest[j] = (ptrc[j] << 16) | ptrc[j];
1407            }
1408            pDest += dstStride;
1409            ptrc += pt->stride/2;
1410         }
1411      }
1412      break;
1413   default:
1414      assert(0);
1415   }
1416
1417   screen->transfer_unmap(screen, pt);
1418}
1419
1420
1421void
1422pipe_put_tile_z(struct pipe_transfer *pt,
1423                uint x, uint y, uint w, uint h,
1424                const uint *zSrc)
1425{
1426   struct pipe_screen *screen = pt->texture->screen;
1427   const uint srcStride = w;
1428   const uint *ptrc = zSrc;
1429   ubyte *map;
1430   uint i, j;
1431
1432   if (pipe_clip_tile(x, y, &w, &h, pt))
1433      return;
1434
1435   map = (ubyte *)screen->transfer_map(screen, pt);
1436   if (!map) {
1437      assert(0);
1438      return;
1439   }
1440
1441   switch (pt->format) {
1442   case PIPE_FORMAT_Z32_UNORM:
1443      {
1444         uint *pDest = (uint *) (map + y * pt->stride + x*4);
1445         for (i = 0; i < h; i++) {
1446            memcpy(pDest, ptrc, 4 * w);
1447            pDest += pt->stride/4;
1448            ptrc += srcStride;
1449         }
1450      }
1451      break;
1452   case PIPE_FORMAT_S8Z24_UNORM:
1453      {
1454         uint *pDest = (uint *) (map + y * pt->stride + x*4);
1455         assert((pt->usage & PIPE_TRANSFER_READ_WRITE) == PIPE_TRANSFER_READ_WRITE);
1456         for (i = 0; i < h; i++) {
1457            for (j = 0; j < w; j++) {
1458               /* convert 32-bit Z to 24-bit Z, preserve stencil */
1459               pDest[j] = (pDest[j] & 0xff000000) | ptrc[j] >> 8;
1460            }
1461            pDest += pt->stride/4;
1462            ptrc += srcStride;
1463         }
1464      }
1465      break;
1466   case PIPE_FORMAT_X8Z24_UNORM:
1467      {
1468         uint *pDest = (uint *) (map + y * pt->stride + x*4);
1469         for (i = 0; i < h; i++) {
1470            for (j = 0; j < w; j++) {
1471               /* convert 32-bit Z to 24-bit Z (0 stencil) */
1472               pDest[j] = ptrc[j] >> 8;
1473            }
1474            pDest += pt->stride/4;
1475            ptrc += srcStride;
1476         }
1477      }
1478      break;
1479   case PIPE_FORMAT_Z24S8_UNORM:
1480      {
1481         uint *pDest = (uint *) (map + y * pt->stride + x*4);
1482         assert((pt->usage & PIPE_TRANSFER_READ_WRITE) == PIPE_TRANSFER_READ_WRITE);
1483         for (i = 0; i < h; i++) {
1484            for (j = 0; j < w; j++) {
1485               /* convert 32-bit Z to 24-bit Z, preserve stencil */
1486               pDest[j] = (pDest[j] & 0xff) | (ptrc[j] & 0xffffff00);
1487            }
1488            pDest += pt->stride/4;
1489            ptrc += srcStride;
1490         }
1491      }
1492      break;
1493   case PIPE_FORMAT_Z24X8_UNORM:
1494      {
1495         uint *pDest = (uint *) (map + y * pt->stride + x*4);
1496         for (i = 0; i < h; i++) {
1497            for (j = 0; j < w; j++) {
1498               /* convert 32-bit Z to 24-bit Z (0 stencil) */
1499               pDest[j] = ptrc[j] & 0xffffff00;
1500            }
1501            pDest += pt->stride/4;
1502            ptrc += srcStride;
1503         }
1504      }
1505      break;
1506   case PIPE_FORMAT_Z16_UNORM:
1507      {
1508         ushort *pDest = (ushort *) (map + y * pt->stride + x*2);
1509         for (i = 0; i < h; i++) {
1510            for (j = 0; j < w; j++) {
1511               /* convert 32-bit Z to 16-bit Z */
1512               pDest[j] = ptrc[j] >> 16;
1513            }
1514            pDest += pt->stride/2;
1515            ptrc += srcStride;
1516         }
1517      }
1518      break;
1519   default:
1520      assert(0);
1521   }
1522
1523   screen->transfer_unmap(screen, pt);
1524}
1525
1526
1527