93abef987925327b8217873e750122804003571a
[mesa.git] / src / gallium / auxiliary / util / p_tile.c
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 * Surfaces should already be in a mapped state.
32 */
33
34
35 #include "pipe/p_defines.h"
36 #include "pipe/p_util.h"
37 #include "pipe/p_inlines.h"
38
39 #include "p_tile.h"
40
41
42
43 /**
44 * Move raw block of pixels from surface to user memory.
45 * This should be usable by any hw driver that has mappable surfaces.
46 */
47 void
48 pipe_get_tile_raw(struct pipe_context *pipe,
49 struct pipe_surface *ps,
50 uint x, uint y, uint w, uint h,
51 void *dst, int dst_stride)
52 {
53 struct pipe_screen *screen = pipe->screen;
54 const void *src;
55
56 if (pipe_clip_tile(x, y, &w, &h, ps))
57 return;
58
59 if (dst_stride == 0)
60 dst_stride = pf_get_nblocksx(&ps->block, w) * ps->block.size;
61
62 src = screen->surface_map(screen, ps, PIPE_BUFFER_USAGE_CPU_READ);
63 assert(src);
64 if(!src)
65 return;
66
67 pipe_copy_rect(dst, &ps->block, dst_stride, 0, 0, w, h, src, ps->stride, x, y);
68
69 screen->surface_unmap(screen, ps);
70 }
71
72
73 /**
74 * Move raw block of pixels from user memory to surface.
75 * This should be usable by any hw driver that has mappable surfaces.
76 */
77 void
78 pipe_put_tile_raw(struct pipe_context *pipe,
79 struct pipe_surface *ps,
80 uint x, uint y, uint w, uint h,
81 const void *src, int src_stride)
82 {
83 struct pipe_screen *screen = pipe->screen;
84 void *dst;
85
86 if (pipe_clip_tile(x, y, &w, &h, ps))
87 return;
88
89 if (src_stride == 0)
90 src_stride = pf_get_nblocksx(&ps->block, w) * ps->block.size;
91
92 dst = screen->surface_map(screen, ps, PIPE_BUFFER_USAGE_CPU_WRITE);
93 assert(dst);
94 if(!dst)
95 return;
96
97 pipe_copy_rect(dst, &ps->block, ps->stride, x, y, w, h, src, src_stride, 0, 0);
98
99 screen->surface_unmap(screen, ps);
100 }
101
102
103
104
105 /** Convert short in [-32768,32767] to GLfloat in [-1.0,1.0] */
106 #define SHORT_TO_FLOAT(S) ((2.0F * (S) + 1.0F) * (1.0F/65535.0F))
107
108 #define UNCLAMPED_FLOAT_TO_SHORT(us, f) \
109 us = ( (short) ( CLAMP((f), -1.0, 1.0) * 32767.0F) )
110
111
112
113 /*** PIPE_FORMAT_A8R8G8B8_UNORM ***/
114
115 static void
116 a8r8g8b8_get_tile_rgba(unsigned *src,
117 unsigned w, unsigned h,
118 float *p,
119 unsigned dst_stride)
120 {
121 unsigned i, j;
122
123 for (i = 0; i < h; i++) {
124 float *pRow = p;
125 for (j = 0; j < w; j++, pRow += 4) {
126 const unsigned pixel = *src++;
127 pRow[0] = UBYTE_TO_FLOAT((pixel >> 16) & 0xff);
128 pRow[1] = UBYTE_TO_FLOAT((pixel >> 8) & 0xff);
129 pRow[2] = UBYTE_TO_FLOAT((pixel >> 0) & 0xff);
130 pRow[3] = UBYTE_TO_FLOAT((pixel >> 24) & 0xff);
131 }
132 p += dst_stride;
133 }
134 }
135
136
137 static void
138 a8r8g8b8_put_tile_rgba(unsigned *dst,
139 unsigned w, unsigned h,
140 const float *p,
141 unsigned src_stride)
142 {
143 unsigned i, j;
144
145 for (i = 0; i < h; i++) {
146 const float *pRow = p;
147 for (j = 0; j < w; j++, pRow += 4) {
148 unsigned r, g, b, a;
149 UNCLAMPED_FLOAT_TO_UBYTE(r, pRow[0]);
150 UNCLAMPED_FLOAT_TO_UBYTE(g, pRow[1]);
151 UNCLAMPED_FLOAT_TO_UBYTE(b, pRow[2]);
152 UNCLAMPED_FLOAT_TO_UBYTE(a, pRow[3]);
153 *dst++ = (a << 24) | (r << 16) | (g << 8) | b;
154 }
155 p += src_stride;
156 }
157 }
158
159
160 /*** PIPE_FORMAT_A8R8G8B8_UNORM ***/
161
162 static void
163 x8r8g8b8_get_tile_rgba(unsigned *src,
164 unsigned w, unsigned h,
165 float *p,
166 unsigned dst_stride)
167 {
168 unsigned i, j;
169
170 for (i = 0; i < h; i++) {
171 float *pRow = p;
172 for (j = 0; j < w; j++, pRow += 4) {
173 const unsigned pixel = *src++;
174 pRow[0] = UBYTE_TO_FLOAT((pixel >> 16) & 0xff);
175 pRow[1] = UBYTE_TO_FLOAT((pixel >> 8) & 0xff);
176 pRow[2] = UBYTE_TO_FLOAT((pixel >> 0) & 0xff);
177 pRow[3] = UBYTE_TO_FLOAT(0xff);
178 }
179 p += dst_stride;
180 }
181 }
182
183
184 static void
185 x8r8g8b8_put_tile_rgba(unsigned *dst,
186 unsigned w, unsigned h,
187 const float *p,
188 unsigned src_stride)
189 {
190 unsigned i, j;
191
192 for (i = 0; i < h; i++) {
193 const float *pRow = p;
194 for (j = 0; j < w; j++, pRow += 4) {
195 unsigned r, g, b;
196 UNCLAMPED_FLOAT_TO_UBYTE(r, pRow[0]);
197 UNCLAMPED_FLOAT_TO_UBYTE(g, pRow[1]);
198 UNCLAMPED_FLOAT_TO_UBYTE(b, pRow[2]);
199 *dst++ = (0xff << 24) | (r << 16) | (g << 8) | b;
200 }
201 p += src_stride;
202 }
203 }
204
205
206 /*** PIPE_FORMAT_B8G8R8A8_UNORM ***/
207
208 static void
209 b8g8r8a8_get_tile_rgba(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 float *pRow = p;
218 for (j = 0; j < w; j++, pRow += 4) {
219 const unsigned pixel = *src++;
220 pRow[0] = UBYTE_TO_FLOAT((pixel >> 8) & 0xff);
221 pRow[1] = UBYTE_TO_FLOAT((pixel >> 16) & 0xff);
222 pRow[2] = UBYTE_TO_FLOAT((pixel >> 24) & 0xff);
223 pRow[3] = UBYTE_TO_FLOAT((pixel >> 0) & 0xff);
224 }
225 p += dst_stride;
226 }
227 }
228
229
230 static void
231 b8g8r8a8_put_tile_rgba(unsigned *dst,
232 unsigned w, unsigned h,
233 const float *p,
234 unsigned src_stride)
235 {
236 unsigned i, j;
237
238 for (i = 0; i < h; i++) {
239 const float *pRow = p;
240 for (j = 0; j < w; j++, pRow += 4) {
241 unsigned r, g, b, a;
242 UNCLAMPED_FLOAT_TO_UBYTE(r, pRow[0]);
243 UNCLAMPED_FLOAT_TO_UBYTE(g, pRow[1]);
244 UNCLAMPED_FLOAT_TO_UBYTE(b, pRow[2]);
245 UNCLAMPED_FLOAT_TO_UBYTE(a, pRow[3]);
246 *dst++ = (b << 24) | (g << 16) | (r << 8) | a;
247 }
248 p += src_stride;
249 }
250 }
251
252
253 /*** PIPE_FORMAT_A1R5G5B5_UNORM ***/
254
255 static void
256 a1r5g5b5_get_tile_rgba(ushort *src,
257 unsigned w, unsigned h,
258 float *p,
259 unsigned dst_stride)
260 {
261 unsigned i, j;
262
263 for (i = 0; i < h; i++) {
264 float *pRow = p;
265 for (j = 0; j < w; j++, pRow += 4) {
266 const ushort pixel = *src++;
267 pRow[0] = ((pixel >> 10) & 0x1f) * (1.0f / 31.0f);
268 pRow[1] = ((pixel >> 5) & 0x1f) * (1.0f / 31.0f);
269 pRow[2] = ((pixel ) & 0x1f) * (1.0f / 31.0f);
270 pRow[3] = ((pixel >> 15) ) * 1.0f;
271 }
272 p += dst_stride;
273 }
274 }
275
276
277 /*** PIPE_FORMAT_A4R4G4B4_UNORM ***/
278
279 static void
280 a4r4g4b4_get_tile_rgba(ushort *src,
281 unsigned w, unsigned h,
282 float *p,
283 unsigned dst_stride)
284 {
285 unsigned i, j;
286
287 for (i = 0; i < h; i++) {
288 float *pRow = p;
289 for (j = 0; j < w; j++, pRow += 4) {
290 const ushort pixel = *src++;
291 pRow[0] = ((pixel >> 8) & 0xf) * (1.0f / 15.0f);
292 pRow[1] = ((pixel >> 4) & 0xf) * (1.0f / 15.0f);
293 pRow[2] = ((pixel ) & 0xf) * (1.0f / 15.0f);
294 pRow[3] = ((pixel >> 12) ) * (1.0f / 15.0f);
295 }
296 p += dst_stride;
297 }
298 }
299
300
301 static void
302 a4r4g4b4_put_tile_rgba(ushort *dst,
303 unsigned w, unsigned h,
304 const float *p,
305 unsigned src_stride)
306 {
307 unsigned i, j;
308
309 for (i = 0; i < h; i++) {
310 const float *pRow = p;
311 for (j = 0; j < w; j++, pRow += 4) {
312 unsigned r, g, b, a;
313 UNCLAMPED_FLOAT_TO_UBYTE(r, pRow[0]);
314 UNCLAMPED_FLOAT_TO_UBYTE(g, pRow[1]);
315 UNCLAMPED_FLOAT_TO_UBYTE(b, pRow[2]);
316 UNCLAMPED_FLOAT_TO_UBYTE(a, pRow[3]);
317 r >>= 4;
318 g >>= 4;
319 b >>= 4;
320 a >>= 4;
321 *dst++ = (a << 12) | (r << 16) | (g << 4) | b;
322 }
323 p += src_stride;
324 }
325 }
326
327
328 /*** PIPE_FORMAT_R5G6B5_UNORM ***/
329
330 static void
331 r5g6b5_get_tile_rgba(ushort *src,
332 unsigned w, unsigned h,
333 float *p,
334 unsigned dst_stride)
335 {
336 unsigned i, j;
337
338 for (i = 0; i < h; i++) {
339 float *pRow = p;
340 for (j = 0; j < w; j++, pRow += 4) {
341 const ushort pixel = *src++;
342 pRow[0] = ((pixel >> 11) & 0x1f) * (1.0f / 31.0f);
343 pRow[1] = ((pixel >> 5) & 0x3f) * (1.0f / 63.0f);
344 pRow[2] = ((pixel ) & 0x1f) * (1.0f / 31.0f);
345 pRow[3] = 1.0f;
346 }
347 p += dst_stride;
348 }
349 }
350
351
352 static void
353 r5g5b5_put_tile_rgba(ushort *dst,
354 unsigned w, unsigned h,
355 const float *p,
356 unsigned src_stride)
357 {
358 unsigned i, j;
359
360 for (i = 0; i < h; i++) {
361 const float *pRow = p;
362 for (j = 0; j < w; j++, pRow += 4) {
363 uint r = (uint) (CLAMP(pRow[0], 0.0, 1.0) * 31.0);
364 uint g = (uint) (CLAMP(pRow[1], 0.0, 1.0) * 63.0);
365 uint b = (uint) (CLAMP(pRow[2], 0.0, 1.0) * 31.0);
366 *dst++ = (r << 11) | (g << 5) | (b);
367 }
368 p += src_stride;
369 }
370 }
371
372
373
374 /*** PIPE_FORMAT_Z16_UNORM ***/
375
376 /**
377 * Return each Z value as four floats in [0,1].
378 */
379 static void
380 z16_get_tile_rgba(ushort *src,
381 unsigned w, unsigned h,
382 float *p,
383 unsigned dst_stride)
384 {
385 const float scale = 1.0f / 65535.0f;
386 unsigned i, j;
387
388 for (i = 0; i < h; i++) {
389 float *pRow = p;
390 for (j = 0; j < w; j++, pRow += 4) {
391 pRow[0] =
392 pRow[1] =
393 pRow[2] =
394 pRow[3] = *src++ * scale;
395 }
396 p += dst_stride;
397 }
398 }
399
400
401
402
403 /*** PIPE_FORMAT_L8_UNORM ***/
404
405 static void
406 l8_get_tile_rgba(ubyte *src,
407 unsigned w, unsigned h,
408 float *p,
409 unsigned dst_stride)
410 {
411 unsigned i, j;
412
413 for (i = 0; i < h; i++) {
414 float *pRow = p;
415 for (j = 0; j < w; j++, src++, pRow += 4) {
416 pRow[0] =
417 pRow[1] =
418 pRow[2] = UBYTE_TO_FLOAT(*src);
419 pRow[3] = 1.0;
420 }
421 p += dst_stride;
422 }
423 }
424
425
426 /*** PIPE_FORMAT_A8_UNORM ***/
427
428 static void
429 a8_get_tile_rgba(ubyte *src,
430 unsigned w, unsigned h,
431 float *p,
432 unsigned dst_stride)
433 {
434 unsigned i, j;
435
436 for (i = 0; i < h; i++) {
437 float *pRow = p;
438 for (j = 0; j < w; j++, src++, pRow += 4) {
439 pRow[0] =
440 pRow[1] =
441 pRow[2] = 0.0;
442 pRow[3] = UBYTE_TO_FLOAT(*src);
443 }
444 p += dst_stride;
445 }
446 }
447
448
449 /*** PIPE_FORMAT_R16G16B16A16_SNORM ***/
450
451 static void
452 r16g16b16a16_get_tile_rgba(short *src,
453 unsigned w, unsigned h,
454 float *p,
455 unsigned dst_stride)
456 {
457 unsigned i, j;
458
459 for (i = 0; i < h; i++) {
460 float *pRow = p;
461 for (j = 0; j < w; j++, src += 4, pRow += 4) {
462 pRow[0] = SHORT_TO_FLOAT(src[0]);
463 pRow[1] = SHORT_TO_FLOAT(src[1]);
464 pRow[2] = SHORT_TO_FLOAT(src[2]);
465 pRow[3] = SHORT_TO_FLOAT(src[3]);
466 }
467 p += dst_stride;
468 }
469 }
470
471
472 static void
473 r16g16b16a16_put_tile_rgba(short *dst,
474 unsigned w, unsigned h,
475 const float *p,
476 unsigned src_stride)
477 {
478 unsigned i, j;
479
480 for (i = 0; i < h; i++) {
481 const float *pRow = p;
482 for (j = 0; j < w; j++, dst += 4, pRow += 4) {
483 UNCLAMPED_FLOAT_TO_SHORT(dst[0], pRow[0]);
484 UNCLAMPED_FLOAT_TO_SHORT(dst[1], pRow[1]);
485 UNCLAMPED_FLOAT_TO_SHORT(dst[2], pRow[2]);
486 UNCLAMPED_FLOAT_TO_SHORT(dst[3], pRow[3]);
487 }
488 p += src_stride;
489 }
490 }
491
492
493
494 /*** PIPE_FORMAT_I8_UNORM ***/
495
496 static void
497 i8_get_tile_rgba(ubyte *src,
498 unsigned w, unsigned h,
499 float *p,
500 unsigned dst_stride)
501 {
502 unsigned i, j;
503
504 for (i = 0; i < h; i++) {
505 float *pRow = p;
506 for (j = 0; j < w; j++, src++, pRow += 4) {
507 pRow[0] =
508 pRow[1] =
509 pRow[2] =
510 pRow[3] = UBYTE_TO_FLOAT(*src);
511 }
512 p += dst_stride;
513 }
514 }
515
516
517 /*** PIPE_FORMAT_A8L8_UNORM ***/
518
519 static void
520 a8_l8_get_tile_rgba(ushort *src,
521 unsigned w, unsigned h,
522 float *p,
523 unsigned dst_stride)
524 {
525 unsigned i, j;
526
527 for (i = 0; i < h; i++) {
528 float *pRow = p;
529 for (j = 0; j < w; j++, pRow += 4) {
530 ushort p = *src++;
531 pRow[0] =
532 pRow[1] =
533 pRow[2] = UBYTE_TO_FLOAT(p & 0xff);
534 pRow[3] = UBYTE_TO_FLOAT(p >> 8);
535 }
536 p += dst_stride;
537 }
538 }
539
540
541
542
543 /*** PIPE_FORMAT_Z32_UNORM ***/
544
545 /**
546 * Return each Z value as four floats in [0,1].
547 */
548 static void
549 z32_get_tile_rgba(unsigned *src,
550 unsigned w, unsigned h,
551 float *p,
552 unsigned dst_stride)
553 {
554 const double scale = 1.0 / (double) 0xffffffff;
555 unsigned i, j;
556
557 for (i = 0; i < h; i++) {
558 float *pRow = p;
559 for (j = 0; j < w; j++, pRow += 4) {
560 pRow[0] =
561 pRow[1] =
562 pRow[2] =
563 pRow[3] = (float) (*src++ * scale);
564 }
565 p += dst_stride;
566 }
567 }
568
569
570 /*** PIPE_FORMAT_S8Z24_UNORM ***/
571
572 /**
573 * Return Z component as four float in [0,1]. Stencil part ignored.
574 */
575 static void
576 s8z24_get_tile_rgba(unsigned *src,
577 unsigned w, unsigned h,
578 float *p,
579 unsigned dst_stride)
580 {
581 const double scale = 1.0 / ((1 << 24) - 1);
582 unsigned i, j;
583
584 for (i = 0; i < h; i++) {
585 float *pRow = p;
586 for (j = 0; j < w; j++, pRow += 4) {
587 pRow[0] =
588 pRow[1] =
589 pRow[2] =
590 pRow[3] = (float) (scale * (*src++ & 0xffffff));
591 }
592 p += dst_stride;
593 }
594 }
595
596
597 /*** PIPE_FORMAT_Z24S8_UNORM ***/
598
599 /**
600 * Return Z component as four float in [0,1]. Stencil part ignored.
601 */
602 static void
603 z24s8_get_tile_rgba(unsigned *src,
604 unsigned w, unsigned h,
605 float *p,
606 unsigned dst_stride)
607 {
608 const double scale = 1.0 / ((1 << 24) - 1);
609 unsigned i, j;
610
611 for (i = 0; i < h; i++) {
612 float *pRow = p;
613 for (j = 0; j < w; j++, pRow += 4) {
614 pRow[0] =
615 pRow[1] =
616 pRow[2] =
617 pRow[3] = (float) (scale * (*src++ >> 8));
618 }
619 p += dst_stride;
620 }
621 }
622
623
624 /*** PIPE_FORMAT_YCBCR / PIPE_FORMAT_YCBCR_REV ***/
625
626 /**
627 * Convert YCbCr (or YCrCb) to RGBA.
628 */
629 static void
630 ycbcr_get_tile_rgba(ushort *src,
631 unsigned w, unsigned h,
632 float *p,
633 unsigned dst_stride,
634 boolean rev)
635 {
636 const float scale = 1.0f / 255.0f;
637 unsigned i, j;
638
639 /* we're assuming we're being asked for an even number of texels */
640 assert((w & 1) == 0);
641
642 for (i = 0; i < h; i++) {
643 float *pRow = p;
644 /* do two texels at a time */
645 for (j = 0; j < w; j += 2, src += 2) {
646 const ushort t0 = src[0];
647 const ushort t1 = src[1];
648 const ubyte y0 = (t0 >> 8) & 0xff; /* luminance */
649 const ubyte y1 = (t1 >> 8) & 0xff; /* luminance */
650 ubyte cb, cr;
651 float r, g, b;
652
653 if (rev) {
654 cb = t1 & 0xff; /* chroma U */
655 cr = t0 & 0xff; /* chroma V */
656 }
657 else {
658 cb = t0 & 0xff; /* chroma U */
659 cr = t1 & 0xff; /* chroma V */
660 }
661
662 /* even pixel: y0,cr,cb */
663 r = 1.164f * (y0-16) + 1.596f * (cr-128);
664 g = 1.164f * (y0-16) - 0.813f * (cr-128) - 0.391f * (cb-128);
665 b = 1.164f * (y0-16) + 2.018f * (cb-128);
666 pRow[0] = r * scale;
667 pRow[1] = g * scale;
668 pRow[2] = b * scale;
669 pRow[3] = 1.0f;
670 pRow += 4;
671
672 /* odd pixel: use y1,cr,cb */
673 r = 1.164f * (y1-16) + 1.596f * (cr-128);
674 g = 1.164f * (y1-16) - 0.813f * (cr-128) - 0.391f * (cb-128);
675 b = 1.164f * (y1-16) + 2.018f * (cb-128);
676 pRow[0] = r * scale;
677 pRow[1] = g * scale;
678 pRow[2] = b * scale;
679 pRow[3] = 1.0f;
680 pRow += 4;
681
682 }
683 p += dst_stride;
684 }
685 }
686
687
688 void
689 pipe_get_tile_rgba(struct pipe_context *pipe,
690 struct pipe_surface *ps,
691 uint x, uint y, uint w, uint h,
692 float *p)
693 {
694 unsigned dst_stride = w * 4;
695 void *packed;
696
697 if (pipe_clip_tile(x, y, &w, &h, ps))
698 return;
699
700 packed = MALLOC(pf_get_nblocks(&ps->block, w, h) * ps->block.size);
701
702 if (!packed)
703 return;
704
705 pipe_get_tile_raw(pipe, ps, x, y, w, h, packed, 0);
706
707 switch (ps->format) {
708 case PIPE_FORMAT_A8R8G8B8_UNORM:
709 a8r8g8b8_get_tile_rgba((unsigned *) packed, w, h, p, dst_stride);
710 break;
711 case PIPE_FORMAT_X8R8G8B8_UNORM:
712 x8r8g8b8_get_tile_rgba((unsigned *) packed, w, h, p, dst_stride);
713 break;
714 case PIPE_FORMAT_B8G8R8A8_UNORM:
715 b8g8r8a8_get_tile_rgba((unsigned *) packed, w, h, p, dst_stride);
716 break;
717 case PIPE_FORMAT_A1R5G5B5_UNORM:
718 a1r5g5b5_get_tile_rgba((ushort *) packed, w, h, p, dst_stride);
719 break;
720 case PIPE_FORMAT_A4R4G4B4_UNORM:
721 a4r4g4b4_get_tile_rgba((ushort *) packed, w, h, p, dst_stride);
722 break;
723 case PIPE_FORMAT_R5G6B5_UNORM:
724 r5g6b5_get_tile_rgba((ushort *) packed, w, h, p, dst_stride);
725 break;
726 case PIPE_FORMAT_L8_UNORM:
727 l8_get_tile_rgba((ubyte *) packed, w, h, p, dst_stride);
728 break;
729 case PIPE_FORMAT_A8_UNORM:
730 a8_get_tile_rgba((ubyte *) packed, w, h, p, dst_stride);
731 break;
732 case PIPE_FORMAT_I8_UNORM:
733 i8_get_tile_rgba((ubyte *) packed, w, h, p, dst_stride);
734 break;
735 case PIPE_FORMAT_A8L8_UNORM:
736 a8_l8_get_tile_rgba((ushort *) packed, w, h, p, dst_stride);
737 break;
738 case PIPE_FORMAT_R16G16B16A16_SNORM:
739 r16g16b16a16_get_tile_rgba((short *) packed, w, h, p, dst_stride);
740 break;
741 case PIPE_FORMAT_Z16_UNORM:
742 z16_get_tile_rgba((ushort *) packed, w, h, p, dst_stride);
743 break;
744 case PIPE_FORMAT_Z32_UNORM:
745 z32_get_tile_rgba((unsigned *) packed, w, h, p, dst_stride);
746 break;
747 case PIPE_FORMAT_S8Z24_UNORM:
748 case PIPE_FORMAT_X8Z24_UNORM:
749 s8z24_get_tile_rgba((unsigned *) packed, w, h, p, dst_stride);
750 break;
751 case PIPE_FORMAT_Z24S8_UNORM:
752 z24s8_get_tile_rgba((unsigned *) packed, w, h, p, dst_stride);
753 break;
754 case PIPE_FORMAT_YCBCR:
755 assert((x & 1) == 0);
756 ycbcr_get_tile_rgba((ushort *) packed, w, h, p, dst_stride, FALSE);
757 break;
758 case PIPE_FORMAT_YCBCR_REV:
759 assert((x & 1) == 0);
760 ycbcr_get_tile_rgba((ushort *) packed, w, h, p, dst_stride, TRUE);
761 break;
762 default:
763 assert(0);
764 }
765
766 FREE(packed);
767 }
768
769
770 void
771 pipe_put_tile_rgba(struct pipe_context *pipe,
772 struct pipe_surface *ps,
773 uint x, uint y, uint w, uint h,
774 const float *p)
775 {
776 unsigned src_stride = w * 4;
777 void *packed;
778
779 if (pipe_clip_tile(x, y, &w, &h, ps))
780 return;
781
782 packed = MALLOC(pf_get_nblocks(&ps->block, w, h) * ps->block.size);
783
784 if (!packed)
785 return;
786
787 switch (ps->format) {
788 case PIPE_FORMAT_A8R8G8B8_UNORM:
789 a8r8g8b8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);
790 break;
791 case PIPE_FORMAT_X8R8G8B8_UNORM:
792 x8r8g8b8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);
793 break;
794 case PIPE_FORMAT_B8G8R8A8_UNORM:
795 b8g8r8a8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);
796 break;
797 case PIPE_FORMAT_A1R5G5B5_UNORM:
798 /*a1r5g5b5_put_tile_rgba((ushort *) packed, w, h, p, src_stride);*/
799 break;
800 case PIPE_FORMAT_R5G6B5_UNORM:
801 r5g5b5_put_tile_rgba((ushort *) packed, w, h, p, src_stride);
802 break;
803 case PIPE_FORMAT_R8G8B8A8_UNORM:
804 assert(0);
805 break;
806 case PIPE_FORMAT_A4R4G4B4_UNORM:
807 a4r4g4b4_put_tile_rgba((ushort *) packed, w, h, p, src_stride);
808 break;
809 case PIPE_FORMAT_L8_UNORM:
810 /*l8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);*/
811 break;
812 case PIPE_FORMAT_A8_UNORM:
813 /*a8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);*/
814 break;
815 case PIPE_FORMAT_I8_UNORM:
816 /*i8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);*/
817 break;
818 case PIPE_FORMAT_A8L8_UNORM:
819 /*a8_l8_put_tile_rgba((ushort *) packed, w, h, p, src_stride);*/
820 break;
821 case PIPE_FORMAT_R16G16B16A16_SNORM:
822 r16g16b16a16_put_tile_rgba((short *) packed, w, h, p, src_stride);
823 break;
824 case PIPE_FORMAT_Z16_UNORM:
825 /*z16_put_tile_rgba((ushort *) packed, w, h, p, src_stride);*/
826 break;
827 case PIPE_FORMAT_Z32_UNORM:
828 /*z32_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/
829 break;
830 case PIPE_FORMAT_S8Z24_UNORM:
831 case PIPE_FORMAT_X8Z24_UNORM:
832 /*s8z24_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/
833 break;
834 case PIPE_FORMAT_Z24S8_UNORM:
835 /*z24s8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/
836 break;
837 default:
838 assert(0);
839 }
840
841 pipe_put_tile_raw(pipe, ps, x, y, w, h, packed, 0);
842
843 FREE(packed);
844 }
845
846
847 /**
848 * Get a block of Z values, converted to 32-bit range.
849 */
850 void
851 pipe_get_tile_z(struct pipe_context *pipe,
852 struct pipe_surface *ps,
853 uint x, uint y, uint w, uint h,
854 uint *z)
855 {
856 struct pipe_screen *screen = pipe->screen;
857 const uint dstStride = w;
858 ubyte *map;
859 uint *pDest = z;
860 uint i, j;
861
862 if (pipe_clip_tile(x, y, &w, &h, ps))
863 return;
864
865 map = (ubyte *)screen->surface_map(screen, ps, PIPE_BUFFER_USAGE_CPU_READ);
866 if (!map) {
867 assert(0);
868 return;
869 }
870
871 switch (ps->format) {
872 case PIPE_FORMAT_Z32_UNORM:
873 {
874 const uint *pSrc
875 = (const uint *)(map + y * ps->stride + x*4);
876 for (i = 0; i < h; i++) {
877 memcpy(pDest, pSrc, 4 * w);
878 pDest += dstStride;
879 pSrc += ps->stride/4;
880 }
881 }
882 break;
883 case PIPE_FORMAT_S8Z24_UNORM:
884 case PIPE_FORMAT_X8Z24_UNORM:
885 {
886 const uint *pSrc
887 = (const uint *)(map + y * ps->stride + x*4);
888 for (i = 0; i < h; i++) {
889 for (j = 0; j < w; j++) {
890 /* convert 24-bit Z to 32-bit Z */
891 pDest[j] = (pSrc[j] << 8) | (pSrc[j] & 0xff);
892 }
893 pDest += dstStride;
894 pSrc += ps->stride/4;
895 }
896 }
897 break;
898 case PIPE_FORMAT_Z16_UNORM:
899 {
900 const ushort *pSrc
901 = (const ushort *)(map + y * ps->stride + x*2);
902 for (i = 0; i < h; i++) {
903 for (j = 0; j < w; j++) {
904 /* convert 16-bit Z to 32-bit Z */
905 pDest[j] = (pSrc[j] << 16) | pSrc[j];
906 }
907 pDest += dstStride;
908 pSrc += ps->stride/2;
909 }
910 }
911 break;
912 default:
913 assert(0);
914 }
915
916 screen->surface_unmap(screen, ps);
917 }
918
919
920 void
921 pipe_put_tile_z(struct pipe_context *pipe,
922 struct pipe_surface *ps,
923 uint x, uint y, uint w, uint h,
924 const uint *zSrc)
925 {
926 struct pipe_screen *screen = pipe->screen;
927 const uint srcStride = w;
928 const uint *pSrc = zSrc;
929 ubyte *map;
930 uint i, j;
931
932 if (pipe_clip_tile(x, y, &w, &h, ps))
933 return;
934
935 map = (ubyte *)screen->surface_map(screen, ps, PIPE_BUFFER_USAGE_CPU_WRITE);
936 if (!map) {
937 assert(0);
938 return;
939 }
940
941 switch (ps->format) {
942 case PIPE_FORMAT_Z32_UNORM:
943 {
944 uint *pDest = (uint *) (map + y * ps->stride + x*4);
945 for (i = 0; i < h; i++) {
946 memcpy(pDest, pSrc, 4 * w);
947 pDest += ps->stride/4;
948 pSrc += srcStride;
949 }
950 }
951 break;
952 case PIPE_FORMAT_S8Z24_UNORM:
953 case PIPE_FORMAT_X8Z24_UNORM:
954 {
955 uint *pDest = (uint *) (map + y * ps->stride + x*4);
956 for (i = 0; i < h; i++) {
957 for (j = 0; j < w; j++) {
958 /* convert 32-bit Z to 24-bit Z (0 stencil) */
959 pDest[j] = pSrc[j] >> 8;
960 }
961 pDest += ps->stride/4;
962 pSrc += srcStride;
963 }
964 }
965 break;
966 case PIPE_FORMAT_Z16_UNORM:
967 {
968 ushort *pDest = (ushort *) (map + y * ps->stride + x*2);
969 for (i = 0; i < h; i++) {
970 for (j = 0; j < w; j++) {
971 /* convert 32-bit Z to 16-bit Z */
972 pDest[j] = pSrc[j] >> 16;
973 }
974 pDest += ps->stride/2;
975 pSrc += srcStride;
976 }
977 }
978 break;
979 default:
980 assert(0);
981 }
982
983 screen->surface_unmap(screen, ps);
984 }
985
986