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