1/**************************************************************************
2 *
3 * Copyright 2007 VMware, Inc.
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 VMWARE 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 "util/u_inlines.h"
36
37#include "util/u_format.h"
38#include "util/u_format_bptc.h"
39#include "util/u_math.h"
40#include "util/u_memory.h"
41#include "util/u_surface.h"
42#include "util/u_tile.h"
43
44
45/**
46 * Move raw block of pixels from transfer object to user memory.
47 */
48void
49pipe_get_tile_raw(struct pipe_transfer *pt,
50                  const void *src,
51                  uint x, uint y, uint w, uint h,
52                  void *dst, int dst_stride)
53{
54   if (dst_stride == 0)
55      dst_stride = util_format_get_stride(pt->resource->format, w);
56
57   if (u_clip_tile(x, y, &w, &h, &pt->box))
58      return;
59
60   util_copy_rect(dst, pt->resource->format, dst_stride, 0, 0, w, h, src, pt->stride, x, y);
61}
62
63
64/**
65 * Move raw block of pixels from user memory to transfer object.
66 */
67void
68pipe_put_tile_raw(struct pipe_transfer *pt,
69                  void *dst,
70                  uint x, uint y, uint w, uint h,
71                  const void *src, int src_stride)
72{
73   enum pipe_format format = pt->resource->format;
74
75   if (src_stride == 0)
76      src_stride = util_format_get_stride(format, w);
77
78   if (u_clip_tile(x, y, &w, &h, &pt->box))
79      return;
80
81   util_copy_rect(dst, format, pt->stride, x, y, w, h, src, src_stride, 0, 0);
82}
83
84
85
86
87/** Convert short in [-32768,32767] to GLfloat in [-1.0,1.0] */
88#define SHORT_TO_FLOAT(S)   ((2.0F * (S) + 1.0F) * (1.0F/65535.0F))
89
90#define UNCLAMPED_FLOAT_TO_SHORT(us, f)  \
91   us = ( (short) ( CLAMP((f), -1.0, 1.0) * 32767.0F) )
92
93
94
95/*** PIPE_FORMAT_Z16_UNORM ***/
96
97/**
98 * Return each Z value as four floats in [0,1].
99 */
100static void
101z16_get_tile_rgba(const ushort *src,
102                  unsigned w, unsigned h,
103                  float *p,
104                  unsigned dst_stride)
105{
106   const float scale = 1.0f / 65535.0f;
107   unsigned i, j;
108
109   for (i = 0; i < h; i++) {
110      float *pRow = p;
111      for (j = 0; j < w; j++, pRow += 4) {
112         pRow[0] =
113         pRow[1] =
114         pRow[2] =
115         pRow[3] = *src++ * scale;
116      }
117      p += dst_stride;
118   }
119}
120
121
122
123
124/*** PIPE_FORMAT_Z32_UNORM ***/
125
126/**
127 * Return each Z value as four floats in [0,1].
128 */
129static void
130z32_get_tile_rgba(const unsigned *src,
131                  unsigned w, unsigned h,
132                  float *p,
133                  unsigned dst_stride)
134{
135   const double scale = 1.0 / (double) 0xffffffff;
136   unsigned i, j;
137
138   for (i = 0; i < h; i++) {
139      float *pRow = p;
140      for (j = 0; j < w; j++, pRow += 4) {
141         pRow[0] =
142         pRow[1] =
143         pRow[2] =
144         pRow[3] = (float) (*src++ * scale);
145      }
146      p += dst_stride;
147   }
148}
149
150
151/*** PIPE_FORMAT_Z24_UNORM_S8_UINT ***/
152
153/**
154 * Return Z component as four float in [0,1].  Stencil part ignored.
155 */
156static void
157s8z24_get_tile_rgba(const unsigned *src,
158                    unsigned w, unsigned h,
159                    float *p,
160                    unsigned dst_stride)
161{
162   const double scale = 1.0 / ((1 << 24) - 1);
163   unsigned i, j;
164
165   for (i = 0; i < h; i++) {
166      float *pRow = p;
167      for (j = 0; j < w; j++, pRow += 4) {
168         pRow[0] =
169         pRow[1] =
170         pRow[2] =
171         pRow[3] = (float) (scale * (*src++ & 0xffffff));
172      }
173      p += dst_stride;
174   }
175}
176
177
178/*** PIPE_FORMAT_S8_UINT_Z24_UNORM ***/
179
180/**
181 * Return Z component as four float in [0,1].  Stencil part ignored.
182 */
183static void
184z24s8_get_tile_rgba(const unsigned *src,
185                    unsigned w, unsigned h,
186                    float *p,
187                    unsigned dst_stride)
188{
189   const double scale = 1.0 / ((1 << 24) - 1);
190   unsigned i, j;
191
192   for (i = 0; i < h; i++) {
193      float *pRow = p;
194      for (j = 0; j < w; j++, pRow += 4) {
195         pRow[0] =
196         pRow[1] =
197         pRow[2] =
198         pRow[3] = (float) (scale * (*src++ >> 8));
199      }
200      p += dst_stride;
201   }
202}
203
204/*** PIPE_FORMAT_S8X24_UINT ***/
205
206/**
207 * Return S component as four uint32_t in [0..255].  Z part ignored.
208 */
209static void
210s8x24_get_tile_rgba(const unsigned *src,
211                    unsigned w, unsigned h,
212                    float *p,
213                    unsigned dst_stride)
214{
215   unsigned i, j;
216
217   for (i = 0; i < h; i++) {
218      uint32_t *pRow = (uint32_t *)p;
219
220      for (j = 0; j < w; j++, pRow += 4) {
221         pRow[0] =
222         pRow[1] =
223         pRow[2] =
224         pRow[3] = ((*src++ >> 24) & 0xff);
225      }
226
227      p += dst_stride;
228   }
229}
230
231/*** PIPE_FORMAT_X24S8_UINT ***/
232
233/**
234 * Return S component as four uint32_t in [0..255].  Z part ignored.
235 */
236static void
237x24s8_get_tile_rgba(const unsigned *src,
238                    unsigned w, unsigned h,
239                    float *p,
240                    unsigned dst_stride)
241{
242   unsigned i, j;
243
244   for (i = 0; i < h; i++) {
245      uint32_t *pRow = (uint32_t *)p;
246      for (j = 0; j < w; j++, pRow += 4) {
247         pRow[0] =
248         pRow[1] =
249         pRow[2] =
250         pRow[3] = (*src++ & 0xff);
251      }
252      p += dst_stride;
253   }
254}
255
256
257/**
258 * Return S component as four uint32_t in [0..255].  Z part ignored.
259 */
260static void
261s8_get_tile_rgba(const unsigned char *src,
262		 unsigned w, unsigned h,
263		 float *p,
264		 unsigned dst_stride)
265{
266   unsigned i, j;
267
268   for (i = 0; i < h; i++) {
269      uint32_t *pRow = (uint32_t *)p;
270      for (j = 0; j < w; j++, pRow += 4) {
271         pRow[0] =
272         pRow[1] =
273         pRow[2] =
274         pRow[3] = (*src++ & 0xff);
275      }
276      p += dst_stride;
277   }
278}
279
280/*** PIPE_FORMAT_Z32_FLOAT ***/
281
282/**
283 * Return each Z value as four floats in [0,1].
284 */
285static void
286z32f_get_tile_rgba(const float *src,
287                   unsigned w, unsigned h,
288                   float *p,
289                   unsigned dst_stride)
290{
291   unsigned i, j;
292
293   for (i = 0; i < h; i++) {
294      float *pRow = p;
295      for (j = 0; j < w; j++, pRow += 4) {
296         pRow[0] =
297         pRow[1] =
298         pRow[2] =
299         pRow[3] = *src++;
300      }
301      p += dst_stride;
302   }
303}
304
305/*** PIPE_FORMAT_Z32_FLOAT_S8X24_UINT ***/
306
307/**
308 * Return each Z value as four floats in [0,1].
309 */
310static void
311z32f_x24s8_get_tile_rgba(const float *src,
312                         unsigned w, unsigned h,
313                         float *p,
314                         unsigned dst_stride)
315{
316   unsigned i, j;
317
318   for (i = 0; i < h; i++) {
319      float *pRow = p;
320      for (j = 0; j < w; j++, pRow += 4) {
321         pRow[0] =
322         pRow[1] =
323         pRow[2] =
324         pRow[3] = *src;
325         src += 2;
326      }
327      p += dst_stride;
328   }
329}
330
331/*** PIPE_FORMAT_X32_S8X24_UINT ***/
332
333/**
334 * Return S component as four uint32_t in [0..255].  Z part ignored.
335 */
336static void
337x32_s8_get_tile_rgba(const unsigned *src,
338                     unsigned w, unsigned h,
339                     float *p,
340                     unsigned dst_stride)
341{
342   unsigned i, j;
343
344   for (i = 0; i < h; i++) {
345      uint32_t *pRow = (uint32_t *)p;
346      for (j = 0; j < w; j++, pRow += 4) {
347         src++;
348         pRow[0] =
349         pRow[1] =
350         pRow[2] =
351         pRow[3] = (*src++ & 0xff);
352      }
353      p += dst_stride;
354   }
355}
356
357void
358pipe_tile_raw_to_rgba(enum pipe_format format,
359                      const void *src,
360                      uint w, uint h,
361                      float *dst, unsigned dst_stride)
362{
363   switch (format) {
364   case PIPE_FORMAT_Z16_UNORM:
365      z16_get_tile_rgba((ushort *) src, w, h, dst, dst_stride);
366      break;
367   case PIPE_FORMAT_Z32_UNORM:
368      z32_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
369      break;
370   case PIPE_FORMAT_Z24_UNORM_S8_UINT:
371   case PIPE_FORMAT_Z24X8_UNORM:
372      s8z24_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
373      break;
374   case PIPE_FORMAT_S8_UINT:
375      s8_get_tile_rgba((unsigned char *) src, w, h, dst, dst_stride);
376      break;
377   case PIPE_FORMAT_X24S8_UINT:
378      s8x24_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
379      break;
380   case PIPE_FORMAT_S8_UINT_Z24_UNORM:
381   case PIPE_FORMAT_X8Z24_UNORM:
382      z24s8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
383      break;
384   case PIPE_FORMAT_S8X24_UINT:
385      x24s8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
386      break;
387   case PIPE_FORMAT_Z32_FLOAT:
388      z32f_get_tile_rgba((float *) src, w, h, dst, dst_stride);
389      break;
390   case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
391      z32f_x24s8_get_tile_rgba((float *) src, w, h, dst, dst_stride);
392      break;
393   case PIPE_FORMAT_X32_S8X24_UINT:
394      x32_s8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
395      break;
396   default:
397      util_format_read_4f(format,
398                          dst, dst_stride * sizeof(float),
399                          src, util_format_get_stride(format, w),
400                          0, 0, w, h);
401   }
402}
403
404void
405pipe_tile_raw_to_unsigned(enum pipe_format format,
406                          const void *src,
407                          uint w, uint h,
408                          unsigned *dst, unsigned dst_stride)
409{
410  util_format_read_4ui(format,
411                       dst, dst_stride * sizeof(float),
412                       src, util_format_get_stride(format, w),
413                       0, 0, w, h);
414}
415
416void
417pipe_tile_raw_to_signed(enum pipe_format format,
418                          void *src,
419                          uint w, uint h,
420                          int *dst, unsigned dst_stride)
421{
422  util_format_read_4i(format,
423                      dst, dst_stride * sizeof(float),
424                      src, util_format_get_stride(format, w),
425                      0, 0, w, h);
426}
427
428void
429pipe_get_tile_rgba(struct pipe_transfer *pt,
430                   const void *src,
431                   uint x, uint y, uint w, uint h,
432                   float *p)
433{
434   pipe_get_tile_rgba_format(pt, src, x, y, w, h, pt->resource->format, p);
435}
436
437
438void
439pipe_get_tile_rgba_format(struct pipe_transfer *pt,
440                          const void *src,
441                          uint x, uint y, uint w, uint h,
442                          enum pipe_format format,
443                          float *p)
444{
445   unsigned dst_stride = w * 4;
446   void *packed;
447
448   if (u_clip_tile(x, y, &w, &h, &pt->box)) {
449      return;
450   }
451
452   packed = MALLOC(util_format_get_nblocks(format, w, h) * util_format_get_blocksize(format));
453   if (!packed) {
454      return;
455   }
456
457   if (format == PIPE_FORMAT_UYVY || format == PIPE_FORMAT_YUYV) {
458      assert((x & 1) == 0);
459   }
460
461   pipe_get_tile_raw(pt, src, x, y, w, h, packed, 0);
462
463   pipe_tile_raw_to_rgba(format, packed, w, h, p, dst_stride);
464
465   FREE(packed);
466}
467
468
469void
470pipe_put_tile_rgba(struct pipe_transfer *pt,
471                   void *dst,
472                   uint x, uint y, uint w, uint h,
473                   const float *p)
474{
475   pipe_put_tile_rgba_format(pt, dst, x, y, w, h, pt->resource->format, p);
476}
477
478
479void
480pipe_put_tile_rgba_format(struct pipe_transfer *pt,
481                          void *dst,
482                          uint x, uint y, uint w, uint h,
483                          enum pipe_format format,
484                          const float *p)
485{
486   unsigned src_stride = w * 4;
487   void *packed;
488
489   if (u_clip_tile(x, y, &w, &h, &pt->box))
490      return;
491
492   packed = MALLOC(util_format_get_nblocks(format, w, h) * util_format_get_blocksize(format));
493
494   if (!packed)
495      return;
496
497   switch (format) {
498   case PIPE_FORMAT_Z16_UNORM:
499      /*z16_put_tile_rgba((ushort *) packed, w, h, p, src_stride);*/
500      break;
501   case PIPE_FORMAT_Z32_UNORM:
502      /*z32_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/
503      break;
504   case PIPE_FORMAT_Z24_UNORM_S8_UINT:
505   case PIPE_FORMAT_Z24X8_UNORM:
506      /*s8z24_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/
507      break;
508   case PIPE_FORMAT_S8_UINT_Z24_UNORM:
509   case PIPE_FORMAT_X8Z24_UNORM:
510      /*z24s8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/
511      break;
512   case PIPE_FORMAT_Z32_FLOAT:
513      /*z32f_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/
514      break;
515   case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
516      /*z32f_s8x24_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/
517      break;
518   default:
519      util_format_write_4f(format,
520                           p, src_stride * sizeof(float),
521                           packed, util_format_get_stride(format, w),
522                           0, 0, w, h);
523   }
524
525   pipe_put_tile_raw(pt, dst, x, y, w, h, packed, 0);
526
527   FREE(packed);
528}
529
530void
531pipe_put_tile_i_format(struct pipe_transfer *pt,
532                       void *dst,
533                       uint x, uint y, uint w, uint h,
534                       enum pipe_format format,
535                       const int *p)
536{
537   unsigned src_stride = w * 4;
538   void *packed;
539
540   if (u_clip_tile(x, y, &w, &h, &pt->box))
541      return;
542
543   packed = MALLOC(util_format_get_nblocks(format, w, h) * util_format_get_blocksize(format));
544
545   if (!packed)
546      return;
547
548   util_format_write_4i(format,
549                        p, src_stride * sizeof(float),
550                        packed, util_format_get_stride(format, w),
551                        0, 0, w, h);
552
553   pipe_put_tile_raw(pt, dst, x, y, w, h, packed, 0);
554
555   FREE(packed);
556}
557
558void
559pipe_put_tile_ui_format(struct pipe_transfer *pt,
560                        void *dst,
561                        uint x, uint y, uint w, uint h,
562                        enum pipe_format format,
563                        const unsigned int *p)
564{
565   unsigned src_stride = w * 4;
566   void *packed;
567
568   if (u_clip_tile(x, y, &w, &h, &pt->box))
569      return;
570
571   packed = MALLOC(util_format_get_nblocks(format, w, h) * util_format_get_blocksize(format));
572
573   if (!packed)
574      return;
575
576   util_format_write_4ui(format,
577                         p, src_stride * sizeof(float),
578                         packed, util_format_get_stride(format, w),
579                         0, 0, w, h);
580
581   pipe_put_tile_raw(pt, dst, x, y, w, h, packed, 0);
582
583   FREE(packed);
584}
585
586/**
587 * Get a block of Z values, converted to 32-bit range.
588 */
589void
590pipe_get_tile_z(struct pipe_transfer *pt,
591                const void *src,
592                uint x, uint y, uint w, uint h,
593                uint *z)
594{
595   const uint dstStride = w;
596   const ubyte *map = src;
597   uint *pDest = z;
598   uint i, j;
599   enum pipe_format format = pt->resource->format;
600
601   if (u_clip_tile(x, y, &w, &h, &pt->box))
602      return;
603
604   switch (format) {
605   case PIPE_FORMAT_Z32_UNORM:
606      {
607         const uint *ptrc
608            = (const uint *)(map  + y * pt->stride + x*4);
609         for (i = 0; i < h; i++) {
610            memcpy(pDest, ptrc, 4 * w);
611            pDest += dstStride;
612            ptrc += pt->stride/4;
613         }
614      }
615      break;
616   case PIPE_FORMAT_Z24_UNORM_S8_UINT:
617   case PIPE_FORMAT_Z24X8_UNORM:
618      {
619         const uint *ptrc
620            = (const uint *)(map + y * pt->stride + x*4);
621         for (i = 0; i < h; i++) {
622            for (j = 0; j < w; j++) {
623               /* convert 24-bit Z to 32-bit Z */
624               pDest[j] = (ptrc[j] << 8) | ((ptrc[j] >> 16) & 0xff);
625            }
626            pDest += dstStride;
627            ptrc += pt->stride/4;
628         }
629      }
630      break;
631   case PIPE_FORMAT_S8_UINT_Z24_UNORM:
632   case PIPE_FORMAT_X8Z24_UNORM:
633      {
634         const uint *ptrc
635            = (const uint *)(map + y * pt->stride + x*4);
636         for (i = 0; i < h; i++) {
637            for (j = 0; j < w; j++) {
638               /* convert 24-bit Z to 32-bit Z */
639               pDest[j] = (ptrc[j] & 0xffffff00) | ((ptrc[j] >> 24) & 0xff);
640            }
641            pDest += dstStride;
642            ptrc += pt->stride/4;
643         }
644      }
645      break;
646   case PIPE_FORMAT_Z16_UNORM:
647      {
648         const ushort *ptrc
649            = (const ushort *)(map + y * pt->stride + x*2);
650         for (i = 0; i < h; i++) {
651            for (j = 0; j < w; j++) {
652               /* convert 16-bit Z to 32-bit Z */
653               pDest[j] = (ptrc[j] << 16) | ptrc[j];
654            }
655            pDest += dstStride;
656            ptrc += pt->stride/2;
657         }
658      }
659      break;
660   case PIPE_FORMAT_Z32_FLOAT:
661      {
662         const float *ptrc = (const float *)(map + y * pt->stride + x*4);
663         for (i = 0; i < h; i++) {
664            for (j = 0; j < w; j++) {
665               /* convert float Z to 32-bit Z */
666               if (ptrc[j] <= 0.0) {
667                  pDest[j] = 0;
668               }
669               else if (ptrc[j] >= 1.0) {
670                  pDest[j] = 0xffffffff;
671               }
672               else {
673                  double z = ptrc[j] * 0xffffffff;
674                  pDest[j] = (uint) z;
675               }
676            }
677            pDest += dstStride;
678            ptrc += pt->stride/4;
679         }
680      }
681      break;
682   case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
683      {
684         const float *ptrc = (const float *)(map + y * pt->stride + x*8);
685         for (i = 0; i < h; i++) {
686            for (j = 0; j < w; j++) {
687               /* convert float Z to 32-bit Z */
688               if (ptrc[j] <= 0.0) {
689                  pDest[j*2] = 0;
690               }
691               else if (ptrc[j] >= 1.0) {
692                  pDest[j*2] = 0xffffffff;
693               }
694               else {
695                  double z = ptrc[j] * 0xffffffff;
696                  pDest[j*2] = (uint) z;
697               }
698            }
699            pDest += dstStride;
700            ptrc += pt->stride/4;
701         }
702      }
703      break;
704   default:
705      assert(0);
706   }
707}
708
709
710void
711pipe_put_tile_z(struct pipe_transfer *pt,
712                void *dst,
713                uint x, uint y, uint w, uint h,
714                const uint *zSrc)
715{
716   const uint srcStride = w;
717   const uint *ptrc = zSrc;
718   ubyte *map = dst;
719   uint i, j;
720   enum pipe_format format = pt->resource->format;
721
722   if (u_clip_tile(x, y, &w, &h, &pt->box))
723      return;
724
725   switch (format) {
726   case PIPE_FORMAT_Z32_UNORM:
727      {
728         uint *pDest = (uint *) (map + y * pt->stride + x*4);
729         for (i = 0; i < h; i++) {
730            memcpy(pDest, ptrc, 4 * w);
731            pDest += pt->stride/4;
732            ptrc += srcStride;
733         }
734      }
735      break;
736   case PIPE_FORMAT_Z24_UNORM_S8_UINT:
737      {
738         uint *pDest = (uint *) (map + y * pt->stride + x*4);
739         /*assert((pt->usage & PIPE_TRANSFER_READ_WRITE) == PIPE_TRANSFER_READ_WRITE);*/
740         for (i = 0; i < h; i++) {
741            for (j = 0; j < w; j++) {
742               /* convert 32-bit Z to 24-bit Z, preserve stencil */
743               pDest[j] = (pDest[j] & 0xff000000) | ptrc[j] >> 8;
744            }
745            pDest += pt->stride/4;
746            ptrc += srcStride;
747         }
748      }
749      break;
750   case PIPE_FORMAT_Z24X8_UNORM:
751      {
752         uint *pDest = (uint *) (map + y * pt->stride + x*4);
753         for (i = 0; i < h; i++) {
754            for (j = 0; j < w; j++) {
755               /* convert 32-bit Z to 24-bit Z (0 stencil) */
756               pDest[j] = ptrc[j] >> 8;
757            }
758            pDest += pt->stride/4;
759            ptrc += srcStride;
760         }
761      }
762      break;
763   case PIPE_FORMAT_S8_UINT_Z24_UNORM:
764      {
765         uint *pDest = (uint *) (map + y * pt->stride + x*4);
766         /*assert((pt->usage & PIPE_TRANSFER_READ_WRITE) == PIPE_TRANSFER_READ_WRITE);*/
767         for (i = 0; i < h; i++) {
768            for (j = 0; j < w; j++) {
769               /* convert 32-bit Z to 24-bit Z, preserve stencil */
770               pDest[j] = (pDest[j] & 0xff) | (ptrc[j] & 0xffffff00);
771            }
772            pDest += pt->stride/4;
773            ptrc += srcStride;
774         }
775      }
776      break;
777   case PIPE_FORMAT_X8Z24_UNORM:
778      {
779         uint *pDest = (uint *) (map + y * pt->stride + x*4);
780         for (i = 0; i < h; i++) {
781            for (j = 0; j < w; j++) {
782               /* convert 32-bit Z to 24-bit Z (0 stencil) */
783               pDest[j] = ptrc[j] & 0xffffff00;
784            }
785            pDest += pt->stride/4;
786            ptrc += srcStride;
787         }
788      }
789      break;
790   case PIPE_FORMAT_Z16_UNORM:
791      {
792         ushort *pDest = (ushort *) (map + y * pt->stride + x*2);
793         for (i = 0; i < h; i++) {
794            for (j = 0; j < w; j++) {
795               /* convert 32-bit Z to 16-bit Z */
796               pDest[j] = ptrc[j] >> 16;
797            }
798            pDest += pt->stride/2;
799            ptrc += srcStride;
800         }
801      }
802      break;
803   case PIPE_FORMAT_Z32_FLOAT:
804      {
805         float *pDest = (float *) (map + y * pt->stride + x*4);
806         for (i = 0; i < h; i++) {
807            for (j = 0; j < w; j++) {
808               /* convert 32-bit integer Z to float Z */
809               const double scale = 1.0 / 0xffffffffU;
810               pDest[j] = (float) (ptrc[j] * scale);
811            }
812            pDest += pt->stride/4;
813            ptrc += srcStride;
814         }
815      }
816      break;
817   case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
818      {
819         float *pDest = (float *) (map + y * pt->stride + x*8);
820         for (i = 0; i < h; i++) {
821            for (j = 0; j < w; j++) {
822               /* convert 32-bit integer Z to float Z */
823               const double scale = 1.0 / 0xffffffffU;
824               pDest[j*2] = (float) (ptrc[j] * scale);
825            }
826            pDest += pt->stride/4;
827            ptrc += srcStride;
828         }
829      }
830      break;
831   default:
832      assert(0);
833   }
834}
835
836
837void
838pipe_get_tile_ui_format(struct pipe_transfer *pt,
839                        const void *src,
840                        uint x, uint y, uint w, uint h,
841                        enum pipe_format format,
842                        unsigned int *p)
843{
844   unsigned dst_stride = w * 4;
845   void *packed;
846
847   if (u_clip_tile(x, y, &w, &h, &pt->box)) {
848      return;
849   }
850
851   packed = MALLOC(util_format_get_nblocks(format, w, h) * util_format_get_blocksize(format));
852   if (!packed) {
853      return;
854   }
855
856   if (format == PIPE_FORMAT_UYVY || format == PIPE_FORMAT_YUYV) {
857      assert((x & 1) == 0);
858   }
859
860   pipe_get_tile_raw(pt, src, x, y, w, h, packed, 0);
861
862   pipe_tile_raw_to_unsigned(format, packed, w, h, p, dst_stride);
863
864   FREE(packed);
865}
866
867
868void
869pipe_get_tile_i_format(struct pipe_transfer *pt,
870                       const void *src,
871                       uint x, uint y, uint w, uint h,
872                       enum pipe_format format,
873                       int *p)
874{
875   unsigned dst_stride = w * 4;
876   void *packed;
877
878   if (u_clip_tile(x, y, &w, &h, &pt->box)) {
879      return;
880   }
881
882   packed = MALLOC(util_format_get_nblocks(format, w, h) * util_format_get_blocksize(format));
883   if (!packed) {
884      return;
885   }
886
887   if (format == PIPE_FORMAT_UYVY || format == PIPE_FORMAT_YUYV) {
888      assert((x & 1) == 0);
889   }
890
891   pipe_get_tile_raw(pt, src, x, y, w, h, packed, 0);
892
893   pipe_tile_raw_to_signed(format, packed, w, h, p, dst_stride);
894
895   FREE(packed);
896}
897