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 */
47 void
pipe_get_tile_raw(struct pipe_transfer * pt,const void * src,uint x,uint y,uint w,uint h,void * dst,int dst_stride)48 pipe_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 */
66 void
pipe_put_tile_raw(struct pipe_transfer * pt,void * dst,uint x,uint y,uint w,uint h,const void * src,int src_stride)67 pipe_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 */
99 static void
z16_get_tile_rgba(const ushort * src,unsigned w,unsigned h,float * p,unsigned dst_stride)100 z16_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 */
128 static void
z32_get_tile_rgba(const unsigned * src,unsigned w,unsigned h,float * p,unsigned dst_stride)129 z32_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 */
155 static void
s8z24_get_tile_rgba(const unsigned * src,unsigned w,unsigned h,float * p,unsigned dst_stride)156 s8z24_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 */
182 static void
z24s8_get_tile_rgba(const unsigned * src,unsigned w,unsigned h,float * p,unsigned dst_stride)183 z24s8_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 */
208 static void
s8x24_get_tile_rgba(const unsigned * src,unsigned w,unsigned h,float * p,unsigned dst_stride)209 s8x24_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 = (uint32_t *)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 */
235 static void
x24s8_get_tile_rgba(const unsigned * src,unsigned w,unsigned h,float * p,unsigned dst_stride)236 x24s8_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 = (uint32_t *)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 */
259 static void
s8_get_tile_rgba(const unsigned char * src,unsigned w,unsigned h,float * p,unsigned dst_stride)260 s8_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 = (uint32_t *)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 */
284 static void
z32f_get_tile_rgba(const float * src,unsigned w,unsigned h,float * p,unsigned dst_stride)285 z32f_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 */
309 static void
z32f_x24s8_get_tile_rgba(const float * src,unsigned w,unsigned h,float * p,unsigned dst_stride)310 z32f_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 */
335 static void
x32_s8_get_tile_rgba(const unsigned * src,unsigned w,unsigned h,float * p,unsigned dst_stride)336 x32_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 uint32_t *pRow = (uint32_t *)p;
345 for (j = 0; j < w; j++, pRow += 4) {
346 src++;
347 pRow[0] =
348 pRow[1] =
349 pRow[2] =
350 pRow[3] = (*src++ & 0xff);
351 }
352 p += dst_stride;
353 }
354 }
355
356 void
pipe_tile_raw_to_rgba(enum pipe_format format,const void * src,uint w,uint h,float * dst,unsigned dst_stride)357 pipe_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
403 void
pipe_tile_raw_to_unsigned(enum pipe_format format,const void * src,uint w,uint h,unsigned * dst,unsigned dst_stride)404 pipe_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
415 void
pipe_tile_raw_to_signed(enum pipe_format format,void * src,uint w,uint h,int * dst,unsigned dst_stride)416 pipe_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
427 void
pipe_get_tile_rgba(struct pipe_transfer * pt,const void * src,uint x,uint y,uint w,uint h,float * p)428 pipe_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
437 void
pipe_get_tile_rgba_format(struct pipe_transfer * pt,const void * src,uint x,uint y,uint w,uint h,enum pipe_format format,float * p)438 pipe_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
468 void
pipe_put_tile_rgba(struct pipe_transfer * pt,void * dst,uint x,uint y,uint w,uint h,const float * p)469 pipe_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
478 void
pipe_put_tile_rgba_format(struct pipe_transfer * pt,void * dst,uint x,uint y,uint w,uint h,enum pipe_format format,const float * p)479 pipe_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
529 void
pipe_put_tile_i_format(struct pipe_transfer * pt,void * dst,uint x,uint y,uint w,uint h,enum pipe_format format,const int * p)530 pipe_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
557 void
pipe_put_tile_ui_format(struct pipe_transfer * pt,void * dst,uint x,uint y,uint w,uint h,enum pipe_format format,const unsigned int * p)558 pipe_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 */
588 void
pipe_get_tile_z(struct pipe_transfer * pt,const void * src,uint x,uint y,uint w,uint h,uint * z)589 pipe_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
709 void
pipe_put_tile_z(struct pipe_transfer * pt,void * dst,uint x,uint y,uint w,uint h,const uint * zSrc)710 pipe_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
836 void
pipe_get_tile_ui_format(struct pipe_transfer * pt,const void * src,uint x,uint y,uint w,uint h,enum pipe_format format,unsigned int * p)837 pipe_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
867 void
pipe_get_tile_i_format(struct pipe_transfer * pt,const void * src,uint x,uint y,uint w,uint h,enum pipe_format format,int * p)868 pipe_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