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   case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
705      {
706         const float *ptrc = (const float *)(map + y * pt->stride + x*8);
707         for (i = 0; i < h; i++) {
708            for (j = 0; j < w; j++) {
709               /* convert float Z to 32-bit Z */
710               if (ptrc[j] <= 0.0) {
711                  pDest[j*2] = 0;
712               }
713               else if (ptrc[j] >= 1.0) {
714                  pDest[j*2] = 0xffffffff;
715               }
716               else {
717                  double z = ptrc[j] * 0xffffffff;
718                  pDest[j*2] = (uint) z;
719               }
720            }
721            pDest += dstStride;
722            ptrc += pt->stride/4;
723         }
724      }
725      break;
726   default:
727      assert(0);
728   }
729
730   pipe->transfer_unmap(pipe, pt);
731}
732
733
734void
735pipe_put_tile_z(struct pipe_context *pipe,
736                struct pipe_transfer *pt,
737                uint x, uint y, uint w, uint h,
738                const uint *zSrc)
739{
740   const uint srcStride = w;
741   const uint *ptrc = zSrc;
742   ubyte *map;
743   uint i, j;
744   enum pipe_format format = pt->resource->format;
745
746   if (u_clip_tile(x, y, &w, &h, &pt->box))
747      return;
748
749   map = (ubyte *)pipe->transfer_map(pipe, pt);
750   if (!map) {
751      assert(0);
752      return;
753   }
754
755   switch (format) {
756   case PIPE_FORMAT_Z32_UNORM:
757      {
758         uint *pDest = (uint *) (map + y * pt->stride + x*4);
759         for (i = 0; i < h; i++) {
760            memcpy(pDest, ptrc, 4 * w);
761            pDest += pt->stride/4;
762            ptrc += srcStride;
763         }
764      }
765      break;
766   case PIPE_FORMAT_Z24_UNORM_S8_UINT:
767      {
768         uint *pDest = (uint *) (map + y * pt->stride + x*4);
769         /*assert((pt->usage & PIPE_TRANSFER_READ_WRITE) == PIPE_TRANSFER_READ_WRITE);*/
770         for (i = 0; i < h; i++) {
771            for (j = 0; j < w; j++) {
772               /* convert 32-bit Z to 24-bit Z, preserve stencil */
773               pDest[j] = (pDest[j] & 0xff000000) | ptrc[j] >> 8;
774            }
775            pDest += pt->stride/4;
776            ptrc += srcStride;
777         }
778      }
779      break;
780   case PIPE_FORMAT_Z24X8_UNORM:
781      {
782         uint *pDest = (uint *) (map + y * pt->stride + x*4);
783         for (i = 0; i < h; i++) {
784            for (j = 0; j < w; j++) {
785               /* convert 32-bit Z to 24-bit Z (0 stencil) */
786               pDest[j] = ptrc[j] >> 8;
787            }
788            pDest += pt->stride/4;
789            ptrc += srcStride;
790         }
791      }
792      break;
793   case PIPE_FORMAT_S8_UINT_Z24_UNORM:
794      {
795         uint *pDest = (uint *) (map + y * pt->stride + x*4);
796         /*assert((pt->usage & PIPE_TRANSFER_READ_WRITE) == PIPE_TRANSFER_READ_WRITE);*/
797         for (i = 0; i < h; i++) {
798            for (j = 0; j < w; j++) {
799               /* convert 32-bit Z to 24-bit Z, preserve stencil */
800               pDest[j] = (pDest[j] & 0xff) | (ptrc[j] & 0xffffff00);
801            }
802            pDest += pt->stride/4;
803            ptrc += srcStride;
804         }
805      }
806      break;
807   case PIPE_FORMAT_X8Z24_UNORM:
808      {
809         uint *pDest = (uint *) (map + y * pt->stride + x*4);
810         for (i = 0; i < h; i++) {
811            for (j = 0; j < w; j++) {
812               /* convert 32-bit Z to 24-bit Z (0 stencil) */
813               pDest[j] = ptrc[j] & 0xffffff00;
814            }
815            pDest += pt->stride/4;
816            ptrc += srcStride;
817         }
818      }
819      break;
820   case PIPE_FORMAT_Z16_UNORM:
821      {
822         ushort *pDest = (ushort *) (map + y * pt->stride + x*2);
823         for (i = 0; i < h; i++) {
824            for (j = 0; j < w; j++) {
825               /* convert 32-bit Z to 16-bit Z */
826               pDest[j] = ptrc[j] >> 16;
827            }
828            pDest += pt->stride/2;
829            ptrc += srcStride;
830         }
831      }
832      break;
833   case PIPE_FORMAT_Z32_FLOAT:
834      {
835         float *pDest = (float *) (map + y * pt->stride + x*4);
836         for (i = 0; i < h; i++) {
837            for (j = 0; j < w; j++) {
838               /* convert 32-bit integer Z to float Z */
839               const double scale = 1.0 / 0xffffffffU;
840               pDest[j] = ptrc[j] * scale;
841            }
842            pDest += pt->stride/4;
843            ptrc += srcStride;
844         }
845      }
846      break;
847   case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
848      {
849         float *pDest = (float *) (map + y * pt->stride + x*8);
850         for (i = 0; i < h; i++) {
851            for (j = 0; j < w; j++) {
852               /* convert 32-bit integer Z to float Z */
853               const double scale = 1.0 / 0xffffffffU;
854               pDest[j*2] = ptrc[j] * scale;
855            }
856            pDest += pt->stride/4;
857            ptrc += srcStride;
858         }
859      }
860      break;
861   default:
862      assert(0);
863   }
864
865   pipe->transfer_unmap(pipe, pt);
866}
867
868
869void
870pipe_get_tile_ui_format(struct pipe_context *pipe,
871                        struct pipe_transfer *pt,
872                        uint x, uint y, uint w, uint h,
873                        enum pipe_format format,
874                        unsigned int *p)
875{
876   unsigned dst_stride = w * 4;
877   void *packed;
878
879   if (u_clip_tile(x, y, &w, &h, &pt->box)) {
880      return;
881   }
882
883   packed = MALLOC(util_format_get_nblocks(format, w, h) * util_format_get_blocksize(format));
884   if (!packed) {
885      return;
886   }
887
888   if (format == PIPE_FORMAT_UYVY || format == PIPE_FORMAT_YUYV) {
889      assert((x & 1) == 0);
890   }
891
892   pipe_get_tile_raw(pipe, pt, x, y, w, h, packed, 0);
893
894   pipe_tile_raw_to_unsigned(format, packed, w, h, p, dst_stride);
895
896   FREE(packed);
897}
898
899
900void
901pipe_get_tile_i_format(struct pipe_context *pipe,
902                       struct pipe_transfer *pt,
903                       uint x, uint y, uint w, uint h,
904                       enum pipe_format format,
905                       int *p)
906{
907   unsigned dst_stride = w * 4;
908   void *packed;
909
910   if (u_clip_tile(x, y, &w, &h, &pt->box)) {
911      return;
912   }
913
914   packed = MALLOC(util_format_get_nblocks(format, w, h) * util_format_get_blocksize(format));
915   if (!packed) {
916      return;
917   }
918
919   if (format == PIPE_FORMAT_UYVY || format == PIPE_FORMAT_YUYV) {
920      assert((x & 1) == 0);
921   }
922
923   pipe_get_tile_raw(pipe, pt, x, y, w, h, packed, 0);
924
925   pipe_tile_raw_to_signed(format, packed, w, h, p, dst_stride);
926
927   FREE(packed);
928}
929