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