added z16/z32_git_tile(), change s8z24_get_tile() to return Z as float, ignore stencil
[mesa.git] / src / mesa / pipe / softpipe / sp_surface.c
1 /**************************************************************************
2 *
3 * Copyright 2003 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 #include "sp_context.h"
29 #include "sp_state.h"
30 #include "sp_surface.h"
31 #include "pipe/p_defines.h"
32 #include "pipe/p_util.h"
33
34
35 /**
36 * Softpipe surface functions.
37 * Basically, create surface of a particular type, then plug in default
38 * read/write_quad and get/put_tile() functions.
39 * Note that these quad funcs assume the buffer/region is in a linear
40 * layout with Y=0=top.
41 * If we had swizzled/AOS buffers the read/write quad functions could be
42 * simplified a lot....
43 */
44
45
46
47 /*** PIPE_FORMAT_U_A8_R8_G8_B8 ***/
48
49 static void
50 a8r8g8b8_read_quad_f_swz(struct softpipe_surface *sps, int x, int y,
51 float (*rrrr)[QUAD_SIZE])
52 {
53 const unsigned *src
54 = ((const unsigned *) (sps->surface.region->map + sps->surface.offset))
55 + y * sps->surface.region->pitch + x;
56 unsigned i, j;
57
58 assert(sps->surface.format == PIPE_FORMAT_U_A8_R8_G8_B8);
59 #if 0
60 assert(x < (int) sps->surface.width - 1);
61 assert(y < (int) sps->surface.height - 1);
62 #endif
63 for (i = 0; i < 2; i++) { /* loop over pixel row */
64 for (j = 0; j < 2; j++) { /* loop over pixel column */
65 const unsigned p = src[j];
66 rrrr[0][i * 2 + j] = UBYTE_TO_FLOAT((p >> 16) & 0xff); /*R*/
67 rrrr[1][i * 2 + j] = UBYTE_TO_FLOAT((p >> 8) & 0xff); /*G*/
68 rrrr[2][i * 2 + j] = UBYTE_TO_FLOAT((p ) & 0xff); /*B*/
69 rrrr[3][i * 2 + j] = UBYTE_TO_FLOAT((p >> 24) & 0xff); /*A*/
70 }
71 src += sps->surface.region->pitch;
72 }
73 }
74
75 static void
76 a8r8g8b8_write_quad_f_swz(struct softpipe_surface *sps, int x, int y,
77 float (*rrrr)[QUAD_SIZE])
78 {
79 unsigned *dst
80 = ((unsigned *) (sps->surface.region->map + sps->surface.offset))
81 + y * sps->surface.region->pitch + x;
82 unsigned i, j;
83
84 assert(sps->surface.format == PIPE_FORMAT_U_A8_R8_G8_B8);
85
86 for (i = 0; i < 2; i++) { /* loop over pixel row */
87 for (j = 0; j < 2; j++) { /* loop over pixel column */
88 ubyte r, g, b, a;
89 UNCLAMPED_FLOAT_TO_UBYTE(r, rrrr[0][i * 2 + j]); /*R*/
90 UNCLAMPED_FLOAT_TO_UBYTE(g, rrrr[1][i * 2 + j]); /*G*/
91 UNCLAMPED_FLOAT_TO_UBYTE(b, rrrr[2][i * 2 + j]); /*B*/
92 UNCLAMPED_FLOAT_TO_UBYTE(a, rrrr[3][i * 2 + j]); /*A*/
93 dst[j] = (a << 24) | (r << 16) | (g << 8) | b;
94 }
95 dst += sps->surface.region->pitch;
96 }
97 }
98
99 static void
100 a8r8g8b8_get_tile(struct pipe_surface *ps,
101 unsigned x, unsigned y, unsigned w, unsigned h, float *p)
102 {
103 const unsigned *src
104 = ((const unsigned *) (ps->region->map + ps->offset))
105 + y * ps->region->pitch + x;
106 unsigned i, j;
107 unsigned w0 = w;
108
109 assert(ps->format == PIPE_FORMAT_U_A8_R8_G8_B8);
110
111 #if 0
112 assert(x + w <= ps->width);
113 assert(y + h <= ps->height);
114 #else
115 /* temp clipping hack */
116 if (x + w > ps->width)
117 w = ps->width - x;
118 if (y + h > ps->height)
119 h = ps->height -y;
120 #endif
121 for (i = 0; i < h; i++) {
122 float *pRow = p;
123 for (j = 0; j < w; j++) {
124 const unsigned pixel = src[j];
125 pRow[0] = UBYTE_TO_FLOAT((pixel >> 16) & 0xff);
126 pRow[1] = UBYTE_TO_FLOAT((pixel >> 8) & 0xff);
127 pRow[2] = UBYTE_TO_FLOAT((pixel >> 0) & 0xff);
128 pRow[3] = UBYTE_TO_FLOAT((pixel >> 24) & 0xff);
129 pRow += 4;
130 }
131 src += ps->region->pitch;
132 p += w0 * 4;
133 }
134 }
135
136
137 static void
138 a8r8g8b8_put_tile(struct pipe_surface *ps,
139 unsigned x, unsigned y, unsigned w, unsigned h,
140 const float *p)
141 {
142 unsigned *dst
143 = ((unsigned *) (ps->region->map + ps->offset))
144 + y * ps->region->pitch + x;
145 unsigned i, j;
146 unsigned w0 = w;
147
148 assert(ps->format == PIPE_FORMAT_U_A8_R8_G8_B8);
149
150 #if 0
151 assert(x + w <= ps->width);
152 assert(y + h <= ps->height);
153 #else
154 /* temp clipping hack */
155 if (x + w > ps->width)
156 w = ps->width - x;
157 if (y + h > ps->height)
158 h = ps->height -y;
159 #endif
160 for (i = 0; i < h; i++) {
161 const float *pRow = p;
162 for (j = 0; j < w; j++) {
163 unsigned r, g, b, a;
164 UNCLAMPED_FLOAT_TO_UBYTE(r, pRow[0]);
165 UNCLAMPED_FLOAT_TO_UBYTE(g, pRow[1]);
166 UNCLAMPED_FLOAT_TO_UBYTE(b, pRow[2]);
167 UNCLAMPED_FLOAT_TO_UBYTE(a, pRow[3]);
168 dst[j] = (a << 24) | (r << 16) | (g << 8) | b;
169 pRow += 4;
170 }
171 dst += ps->region->pitch;
172 p += w0 * 4;
173 }
174 }
175
176
177 /*** PIPE_FORMAT_U_A1_R5_G5_B5 ***/
178
179 static void
180 a1r5g5b5_get_tile(struct pipe_surface *ps,
181 unsigned x, unsigned y, unsigned w, unsigned h, float *p)
182 {
183 const ushort *src
184 = ((const ushort *) (ps->region->map + ps->offset))
185 + y * ps->region->pitch + x;
186 unsigned i, j;
187
188 assert(ps->format == PIPE_FORMAT_U_A1_R5_G5_B5);
189
190 for (i = 0; i < h; i++) {
191 for (j = 0; j < w; j++) {
192 const ushort pixel = src[j];
193 p[0] = ((pixel >> 10) & 0x1f) * (1.0f / 31.0f);
194 p[1] = ((pixel >> 5) & 0x1f) * (1.0f / 31.0f);
195 p[2] = ((pixel ) & 0x1f) * (1.0f / 31.0f);
196 p[3] = ((pixel >> 15) ) * 1.0f;
197 p += 4;
198 }
199 src += ps->region->pitch;
200 }
201 }
202
203
204
205 /*** PIPE_FORMAT_U_Z16 ***/
206
207 static void
208 z16_read_quad_z(struct softpipe_surface *sps,
209 int x, int y, unsigned zzzz[QUAD_SIZE])
210 {
211 const ushort *src
212 = ((const ushort *) (sps->surface.region->map + sps->surface.offset))
213 + y * sps->surface.region->pitch + x;
214
215 assert(sps->surface.format == PIPE_FORMAT_U_Z16);
216
217 /* converting ushort to unsigned: */
218 zzzz[0] = src[0];
219 zzzz[1] = src[1];
220 src += sps->surface.region->pitch;
221 zzzz[2] = src[0];
222 zzzz[3] = src[1];
223 }
224
225 static void
226 z16_write_quad_z(struct softpipe_surface *sps,
227 int x, int y, const unsigned zzzz[QUAD_SIZE])
228 {
229 ushort *dst
230 = ((ushort *) (sps->surface.region->map + sps->surface.offset))
231 + y * sps->surface.region->pitch + x;
232
233 assert(sps->surface.format == PIPE_FORMAT_U_Z16);
234
235 /* converting unsigned to ushort: */
236 dst[0] = zzzz[0];
237 dst[1] = zzzz[1];
238 dst += sps->surface.region->pitch;
239 dst[0] = zzzz[2];
240 dst[1] = zzzz[3];
241 }
242
243 /**
244 * Return as floats in [0,1].
245 */
246 static void
247 z16_get_tile(struct pipe_surface *ps,
248 unsigned x, unsigned y, unsigned w, unsigned h, float *p)
249 {
250 const ushort *src
251 = ((const ushort *) (ps->region->map + ps->offset))
252 + y * ps->region->pitch + x;
253 const float scale = 1.0 / 65535.0;
254 unsigned i, j;
255 unsigned w0 = w;
256
257 assert(ps->format == PIPE_FORMAT_U_Z16);
258
259 #if 0
260 assert(x + w <= ps->width);
261 assert(y + h <= ps->height);
262 #else
263 /* temp clipping hack */
264 if (x + w > ps->width)
265 w = ps->width - x;
266 if (y + h > ps->height)
267 h = ps->height -y;
268 #endif
269 for (i = 0; i < h; i++) {
270 float *pRow = p;
271 for (j = 0; j < w; j++) {
272 pRow[j] = src[j] * scale;
273 }
274 src += ps->region->pitch;
275 p += w0;
276 }
277 }
278
279
280
281
282 /*** PIPE_FORMAT_U_L8 ***/
283
284 static void
285 l8_read_quad_f_swz(struct softpipe_surface *sps, int x, int y,
286 float (*rrrr)[QUAD_SIZE])
287 {
288 const ubyte *src
289 = ((const ubyte *) (sps->surface.region->map + sps->surface.offset))
290 + y * sps->surface.region->pitch + x;
291 unsigned i, j;
292
293 assert(sps->surface.format == PIPE_FORMAT_U_L8);
294 assert(x < (int) sps->surface.width - 1);
295 assert(y < (int) sps->surface.height - 1);
296
297 for (i = 0; i < 2; i++) { /* loop over pixel row */
298 for (j = 0; j < 2; j++) { /* loop over pixel column */
299 rrrr[0][i * 2 + j] =
300 rrrr[1][i * 2 + j] =
301 rrrr[2][i * 2 + j] = UBYTE_TO_FLOAT(src[j]);
302 rrrr[3][i * 2 + j] = 1.0F;
303 }
304 src += sps->surface.region->pitch;
305 }
306 }
307
308 static void
309 l8_write_quad_f_swz(struct softpipe_surface *sps, int x, int y,
310 float (*rrrr)[QUAD_SIZE])
311 {
312 ubyte *dst
313 = ((ubyte *) (sps->surface.region->map + sps->surface.offset))
314 + y * sps->surface.region->pitch + x;
315 unsigned i, j;
316
317 assert(sps->surface.format == PIPE_FORMAT_U_L8);
318
319 for (i = 0; i < 2; i++) { /* loop over pixel row */
320 for (j = 0; j < 2; j++) { /* loop over pixel column */
321 ubyte r;
322 UNCLAMPED_FLOAT_TO_UBYTE(r, rrrr[0][i * 2 + j]); /*R*/
323 dst[j] = r;
324 }
325 dst += sps->surface.region->pitch;
326 }
327 }
328
329 static void
330 l8_get_tile(struct pipe_surface *ps,
331 unsigned x, unsigned y, unsigned w, unsigned h, float *p)
332 {
333 const ubyte *src
334 = ((const ubyte *) (ps->region->map + ps->offset))
335 + y * ps->region->pitch + x;
336 unsigned i, j;
337 unsigned w0 = w;
338
339 assert(ps->format == PIPE_FORMAT_U_L8);
340
341 #if 0
342 assert(x + w <= ps->width);
343 assert(y + h <= ps->height);
344 #else
345 /* temp clipping hack */
346 if (x + w > ps->width)
347 w = ps->width - x;
348 if (y + h > ps->height)
349 h = ps->height -y;
350 #endif
351 for (i = 0; i < h; i++) {
352 float *pRow = p;
353 for (j = 0; j < w; j++) {
354 pRow[0] =
355 pRow[1] =
356 pRow[2] = UBYTE_TO_FLOAT(src[j]);
357 pRow[3] = 1.0;
358 pRow += 4;
359 }
360 src += ps->region->pitch;
361 p += w0 * 4;
362 }
363 }
364
365
366 /*** PIPE_FORMAT_U_A8 ***/
367
368 static void
369 a8_read_quad_f_swz(struct softpipe_surface *sps, int x, int y,
370 float (*rrrr)[QUAD_SIZE])
371 {
372 const ubyte *src
373 = ((const ubyte *) (sps->surface.region->map + sps->surface.offset))
374 + y * sps->surface.region->pitch + x;
375 unsigned i, j;
376
377 assert(sps->surface.format == PIPE_FORMAT_U_A8);
378 assert(x < (int) sps->surface.width - 1);
379 assert(y < (int) sps->surface.height - 1);
380
381 for (i = 0; i < 2; i++) { /* loop over pixel row */
382 for (j = 0; j < 2; j++) { /* loop over pixel column */
383 rrrr[0][i * 2 + j] =
384 rrrr[1][i * 2 + j] =
385 rrrr[2][i * 2 + j] = 0.0F;
386 rrrr[3][i * 2 + j] = UBYTE_TO_FLOAT(src[j]);
387 }
388 src += sps->surface.region->pitch;
389 }
390 }
391
392 static void
393 a8_write_quad_f_swz(struct softpipe_surface *sps, int x, int y,
394 float (*rrrr)[QUAD_SIZE])
395 {
396 ubyte *dst
397 = ((ubyte *) (sps->surface.region->map + sps->surface.offset))
398 + y * sps->surface.region->pitch + x;
399 unsigned i, j;
400
401 assert(sps->surface.format == PIPE_FORMAT_U_A8);
402
403 for (i = 0; i < 2; i++) { /* loop over pixel row */
404 for (j = 0; j < 2; j++) { /* loop over pixel column */
405 ubyte r;
406 UNCLAMPED_FLOAT_TO_UBYTE(r, rrrr[3][i * 2 + j]); /*A*/
407 dst[j] = r;
408 }
409 dst += sps->surface.region->pitch;
410 }
411 }
412
413 static void
414 a8_get_tile(struct pipe_surface *ps,
415 unsigned x, unsigned y, unsigned w, unsigned h, float *p)
416 {
417 const ubyte *src
418 = ((const ubyte *) (ps->region->map + ps->offset))
419 + y * ps->region->pitch + x;
420 unsigned i, j;
421 unsigned w0 = w;
422
423 assert(ps->format == PIPE_FORMAT_U_A8);
424
425 #if 0
426 assert(x + w <= ps->width);
427 assert(y + h <= ps->height);
428 #else
429 /* temp clipping hack */
430 if (x + w > ps->width)
431 w = ps->width - x;
432 if (y + h > ps->height)
433 h = ps->height -y;
434 #endif
435 for (i = 0; i < h; i++) {
436 float *pRow = p;
437 for (j = 0; j < w; j++) {
438 pRow[0] =
439 pRow[1] =
440 pRow[2] = 0.0;
441 pRow[3] = UBYTE_TO_FLOAT(src[j]);
442 pRow += 4;
443 }
444 src += ps->region->pitch;
445 p += w0 * 4;
446 }
447 }
448
449
450
451 /*** PIPE_FORMAT_U_I8 ***/
452
453 static void
454 i8_read_quad_f_swz(struct softpipe_surface *sps, int x, int y,
455 float (*rrrr)[QUAD_SIZE])
456 {
457 const ubyte *src
458 = ((const ubyte *) (sps->surface.region->map + sps->surface.offset))
459 + y * sps->surface.region->pitch + x;
460 unsigned i, j;
461
462 assert(sps->surface.format == PIPE_FORMAT_U_I8);
463 assert(x < (int) sps->surface.width - 1);
464 assert(y < (int) sps->surface.height - 1);
465
466 for (i = 0; i < 2; i++) { /* loop over pixel row */
467 for (j = 0; j < 2; j++) { /* loop over pixel column */
468 rrrr[0][i * 2 + j] =
469 rrrr[1][i * 2 + j] =
470 rrrr[2][i * 2 + j] =
471 rrrr[3][i * 2 + j] = UBYTE_TO_FLOAT(src[j]);
472 }
473 src += sps->surface.region->pitch;
474 }
475 }
476
477 static void
478 i8_write_quad_f_swz(struct softpipe_surface *sps, int x, int y,
479 float (*rrrr)[QUAD_SIZE])
480 {
481 ubyte *dst
482 = ((ubyte *) (sps->surface.region->map + sps->surface.offset))
483 + y * sps->surface.region->pitch + x;
484 unsigned i, j;
485
486 assert(sps->surface.format == PIPE_FORMAT_U_I8);
487
488 for (i = 0; i < 2; i++) { /* loop over pixel row */
489 for (j = 0; j < 2; j++) { /* loop over pixel column */
490 ubyte r;
491 UNCLAMPED_FLOAT_TO_UBYTE(r, rrrr[0][i * 2 + j]); /*R*/
492 dst[j] = r;
493 }
494 dst += sps->surface.region->pitch;
495 }
496 }
497
498 static void
499 i8_get_tile(struct pipe_surface *ps,
500 unsigned x, unsigned y, unsigned w, unsigned h, float *p)
501 {
502 const ubyte *src
503 = ((const ubyte *) (ps->region->map + ps->offset))
504 + y * ps->region->pitch + x;
505 unsigned i, j;
506 unsigned w0 = w;
507
508 assert(ps->format == PIPE_FORMAT_U_I8);
509
510 #if 0
511 assert(x + w <= ps->width);
512 assert(y + h <= ps->height);
513 #else
514 /* temp clipping hack */
515 if (x + w > ps->width)
516 w = ps->width - x;
517 if (y + h > ps->height)
518 h = ps->height -y;
519 #endif
520 for (i = 0; i < h; i++) {
521 float *pRow = p;
522 for (j = 0; j < w; j++) {
523 pRow[0] =
524 pRow[1] =
525 pRow[2] =
526 pRow[3] = UBYTE_TO_FLOAT(src[j]);
527 pRow += 4;
528 }
529 src += ps->region->pitch;
530 p += w0 * 4;
531 }
532 }
533
534
535 /*** PIPE_FORMAT_U_A8_L8 ***/
536
537 static void
538 a8_l8_read_quad_f_swz(struct softpipe_surface *sps, int x, int y,
539 float (*rrrr)[QUAD_SIZE])
540 {
541 const ushort *src
542 = ((const ushort *) (sps->surface.region->map + sps->surface.offset))
543 + y * sps->surface.region->pitch + x;
544 unsigned i, j;
545
546 assert(sps->surface.format == PIPE_FORMAT_U_A8_L8);
547 assert(x < (int) sps->surface.width - 1);
548 assert(y < (int) sps->surface.height - 1);
549
550 for (i = 0; i < 2; i++) { /* loop over pixel row */
551 for (j = 0; j < 2; j++) { /* loop over pixel column */
552 const ushort p = src[j];
553 rrrr[0][i * 2 + j] =
554 rrrr[1][i * 2 + j] =
555 rrrr[2][i * 2 + j] = UBYTE_TO_FLOAT(p >> 8);
556 rrrr[3][i * 2 + j] = UBYTE_TO_FLOAT(p & 0xff);
557 }
558 src += sps->surface.region->pitch;
559 }
560 }
561
562 static void
563 a8_l8_write_quad_f_swz(struct softpipe_surface *sps, int x, int y,
564 float (*rrrr)[QUAD_SIZE])
565 {
566 ushort *dst
567 = ((ushort *) (sps->surface.region->map + sps->surface.offset))
568 + y * sps->surface.region->pitch + x;
569 unsigned i, j;
570
571 assert(sps->surface.format == PIPE_FORMAT_U_A8_L8);
572
573 for (i = 0; i < 2; i++) { /* loop over pixel row */
574 for (j = 0; j < 2; j++) { /* loop over pixel column */
575 ubyte l, a;
576 UNCLAMPED_FLOAT_TO_UBYTE(l, rrrr[0][i * 2 + j]); /*R*/
577 UNCLAMPED_FLOAT_TO_UBYTE(a, rrrr[3][i * 2 + j]); /*A*/
578 dst[j] = (l << 8) | a;
579 }
580 dst += sps->surface.region->pitch;
581 }
582 }
583
584 static void
585 a8_l8_get_tile(struct pipe_surface *ps,
586 unsigned x, unsigned y, unsigned w, unsigned h, float *p)
587 {
588 const ushort *src
589 = ((const ushort *) (ps->region->map + ps->offset))
590 + y * ps->region->pitch + x;
591 unsigned i, j;
592 unsigned w0 = w;
593
594 assert(ps->format == PIPE_FORMAT_U_A8_L8);
595
596 #if 0
597 assert(x + w <= ps->width);
598 assert(y + h <= ps->height);
599 #else
600 /* temp clipping hack */
601 if (x + w > ps->width)
602 w = ps->width - x;
603 if (y + h > ps->height)
604 h = ps->height -y;
605 #endif
606 for (i = 0; i < h; i++) {
607 float *pRow = p;
608 for (j = 0; j < w; j++) {
609 const ushort p = src[j];
610 pRow[0] =
611 pRow[1] =
612 pRow[2] = UBYTE_TO_FLOAT(p & 0xff);
613 pRow[3] = UBYTE_TO_FLOAT(p >> 8);
614 pRow += 4;
615 }
616 src += ps->region->pitch;
617 p += w0 * 4;
618 }
619 }
620
621
622
623
624 /*** PIPE_FORMAT_U_Z32 ***/
625
626 static void
627 z32_read_quad_z(struct softpipe_surface *sps,
628 int x, int y, unsigned zzzz[QUAD_SIZE])
629 {
630 const unsigned *src
631 = ((unsigned *) (sps->surface.region->map + sps->surface.offset))
632 + y * sps->surface.region->pitch + x;
633
634 assert(sps->surface.format == PIPE_FORMAT_U_Z32);
635
636 zzzz[0] = src[0];
637 zzzz[1] = src[1];
638 src += sps->surface.region->pitch;
639 zzzz[2] = src[0];
640 zzzz[3] = src[1];
641 }
642
643 static void
644 z32_write_quad_z(struct softpipe_surface *sps,
645 int x, int y, const unsigned zzzz[QUAD_SIZE])
646 {
647 unsigned *dst
648 = ((unsigned *) (sps->surface.region->map + sps->surface.offset))
649 + y * sps->surface.region->pitch + x;
650
651 assert(sps->surface.format == PIPE_FORMAT_U_Z32);
652
653 dst[0] = zzzz[0];
654 dst[1] = zzzz[1];
655 dst += sps->surface.region->pitch;
656 dst[0] = zzzz[2];
657 dst[1] = zzzz[3];
658 }
659
660 /**
661 * Return as floats in [0,1].
662 */
663 static void
664 z32_get_tile(struct pipe_surface *ps,
665 unsigned x, unsigned y, unsigned w, unsigned h, float *p)
666 {
667 const uint *src
668 = ((const uint *) (ps->region->map + ps->offset))
669 + y * ps->region->pitch + x;
670 const double scale = 1.0 / (double) 0xffffffff;
671 unsigned i, j;
672 unsigned w0 = w;
673
674 assert(ps->format == PIPE_FORMAT_U_Z16);
675
676 #if 0
677 assert(x + w <= ps->width);
678 assert(y + h <= ps->height);
679 #else
680 /* temp clipping hack */
681 if (x + w > ps->width)
682 w = ps->width - x;
683 if (y + h > ps->height)
684 h = ps->height -y;
685 #endif
686 for (i = 0; i < h; i++) {
687 float *pRow = p;
688 for (j = 0; j < w; j++) {
689 pRow[j] = src[j] * scale;
690 }
691 src += ps->region->pitch;
692 p += w0;
693 }
694 }
695
696
697 /*** PIPE_FORMAT_S8_Z24 ***/
698
699 static void
700 s8z24_read_quad_z(struct softpipe_surface *sps,
701 int x, int y, unsigned zzzz[QUAD_SIZE])
702 {
703 static const unsigned mask = 0x00ffffff;
704 const unsigned *src
705 = ((unsigned *) (sps->surface.region->map + sps->surface.offset))
706 + y * sps->surface.region->pitch + x;
707
708 assert(sps->surface.format == PIPE_FORMAT_S8_Z24);
709
710 /* extract lower three bytes */
711 zzzz[0] = src[0] & mask;
712 zzzz[1] = src[1] & mask;
713 src += sps->surface.region->pitch;
714 zzzz[2] = src[0] & mask;
715 zzzz[3] = src[1] & mask;
716 }
717
718 static void
719 s8z24_write_quad_z(struct softpipe_surface *sps,
720 int x, int y, const unsigned zzzz[QUAD_SIZE])
721 {
722 static const unsigned mask = 0xff000000;
723 unsigned *dst
724 = ((unsigned *) (sps->surface.region->map + sps->surface.offset))
725 + y * sps->surface.region->pitch + x;
726
727 assert(sps->surface.format == PIPE_FORMAT_S8_Z24);
728 assert(zzzz[0] <= 0xffffff);
729
730 dst[0] = (dst[0] & mask) | zzzz[0];
731 dst[1] = (dst[1] & mask) | zzzz[1];
732 dst += sps->surface.region->pitch;
733 dst[0] = (dst[0] & mask) | zzzz[2];
734 dst[1] = (dst[1] & mask) | zzzz[3];
735 }
736
737 static void
738 s8z24_read_quad_stencil(struct softpipe_surface *sps,
739 int x, int y, ubyte ssss[QUAD_SIZE])
740 {
741 const unsigned *src
742 = ((unsigned *) (sps->surface.region->map + sps->surface.offset))
743 + y * sps->surface.region->pitch + x;
744
745 assert(sps->surface.format == PIPE_FORMAT_S8_Z24);
746
747 ssss[0] = src[0] >> 24;
748 ssss[1] = src[1] >> 24;
749 src += sps->surface.region->pitch;
750 ssss[2] = src[0] >> 24;
751 ssss[3] = src[1] >> 24;
752 }
753
754 static void
755 s8z24_write_quad_stencil(struct softpipe_surface *sps,
756 int x, int y, const ubyte ssss[QUAD_SIZE])
757 {
758 static const unsigned mask = 0x00ffffff;
759 unsigned *dst
760 = ((unsigned *) (sps->surface.region->map + sps->surface.offset))
761 + y * sps->surface.region->pitch + x;
762
763 assert(sps->surface.format == PIPE_FORMAT_S8_Z24);
764
765 dst[0] = (dst[0] & mask) | (ssss[0] << 24);
766 dst[1] = (dst[1] & mask) | (ssss[1] << 24);
767 dst += sps->surface.region->pitch;
768 dst[0] = (dst[0] & mask) | (ssss[2] << 24);
769 dst[1] = (dst[1] & mask) | (ssss[3] << 24);
770 }
771
772
773 /**
774 * Return Z component as float in [0,1]. Stencil part ignored.
775 */
776 static void
777 s8z24_get_tile(struct pipe_surface *ps,
778 unsigned x, unsigned y, unsigned w, unsigned h, float *p)
779 {
780 const uint *src
781 = ((const uint *) (ps->region->map + ps->offset))
782 + y * ps->region->pitch + x;
783 const double scale = 1.0 / ((1 << 24) - 1);
784 unsigned i, j;
785 unsigned w0 = w;
786
787 assert(ps->format == PIPE_FORMAT_S8_Z24);
788
789 #if 0
790 assert(x + w <= ps->width);
791 assert(y + h <= ps->height);
792 #else
793 /* temp clipping hack */
794 if (x + w > ps->width)
795 w = ps->width - x;
796 if (y + h > ps->height)
797 h = ps->height -y;
798 #endif
799 for (i = 0; i < h; i++) {
800 float *pRow = p;
801 for (j = 0; j < w; j++) {
802 pRow[j] = (src[j] & 0xffffff) * scale;
803 }
804 src += ps->region->pitch;
805 p += w0;
806 }
807 }
808
809
810 /*** PIPE_FORMAT_U_S8 ***/
811
812 static void
813 s8_read_quad_stencil(struct softpipe_surface *sps,
814 int x, int y, ubyte ssss[QUAD_SIZE])
815 {
816 const ubyte *src
817 = sps->surface.region->map + sps->surface.offset
818 + y * sps->surface.region->pitch + x;
819
820 assert(sps->surface.format == PIPE_FORMAT_U_S8);
821
822 ssss[0] = src[0];
823 ssss[1] = src[1];
824 src += sps->surface.region->pitch;
825 ssss[2] = src[0];
826 ssss[3] = src[1];
827 }
828
829 static void
830 s8_write_quad_stencil(struct softpipe_surface *sps,
831 int x, int y, const ubyte ssss[QUAD_SIZE])
832 {
833 ubyte *dst
834 = sps->surface.region->map + sps->surface.offset
835 + y * sps->surface.region->pitch + x;
836
837 assert(sps->surface.format == PIPE_FORMAT_U_S8);
838
839 dst[0] = ssss[0];
840 dst[1] = ssss[1];
841 dst += sps->surface.region->pitch;
842 dst[0] = ssss[2];
843 dst[1] = ssss[3];
844 }
845
846
847 /**
848 * Initialize the quad_read/write and get/put_tile() methods.
849 */
850 void
851 softpipe_init_surface_funcs(struct softpipe_surface *sps)
852 {
853 assert(sps->surface.format);
854
855 switch (sps->surface.format) {
856 case PIPE_FORMAT_U_A8_R8_G8_B8:
857 sps->read_quad_f_swz = a8r8g8b8_read_quad_f_swz;
858 sps->write_quad_f_swz = a8r8g8b8_write_quad_f_swz;
859 sps->surface.get_tile = a8r8g8b8_get_tile;
860 sps->surface.put_tile = a8r8g8b8_put_tile;
861 break;
862 case PIPE_FORMAT_U_A1_R5_G5_B5:
863 sps->surface.get_tile = a1r5g5b5_get_tile;
864 break;
865 case PIPE_FORMAT_U_L8:
866 sps->read_quad_f_swz = l8_read_quad_f_swz;
867 sps->write_quad_f_swz = l8_write_quad_f_swz;
868 sps->surface.get_tile = l8_get_tile;
869 break;
870 case PIPE_FORMAT_U_A8:
871 sps->read_quad_f_swz = a8_read_quad_f_swz;
872 sps->write_quad_f_swz = a8_write_quad_f_swz;
873 sps->surface.get_tile = a8_get_tile;
874 break;
875 case PIPE_FORMAT_U_I8:
876 sps->read_quad_f_swz = i8_read_quad_f_swz;
877 sps->write_quad_f_swz = i8_write_quad_f_swz;
878 sps->surface.get_tile = i8_get_tile;
879 break;
880 case PIPE_FORMAT_U_A8_L8:
881 sps->read_quad_f_swz = a8_l8_read_quad_f_swz;
882 sps->write_quad_f_swz = a8_l8_write_quad_f_swz;
883 sps->surface.get_tile = a8_l8_get_tile;
884 break;
885
886 case PIPE_FORMAT_U_Z16:
887 sps->read_quad_z = z16_read_quad_z;
888 sps->write_quad_z = z16_write_quad_z;
889 sps->surface.get_tile = z16_get_tile;
890 break;
891 case PIPE_FORMAT_U_Z32:
892 sps->read_quad_z = z32_read_quad_z;
893 sps->write_quad_z = z32_write_quad_z;
894 sps->surface.get_tile = z32_get_tile;
895 break;
896 case PIPE_FORMAT_S8_Z24:
897 sps->read_quad_z = s8z24_read_quad_z;
898 sps->write_quad_z = s8z24_write_quad_z;
899 sps->read_quad_stencil = s8z24_read_quad_stencil;
900 sps->write_quad_stencil = s8z24_write_quad_stencil;
901 sps->surface.get_tile = s8z24_get_tile;
902 break;
903
904 case PIPE_FORMAT_U_S8:
905 sps->read_quad_stencil = s8_read_quad_stencil;
906 sps->write_quad_stencil = s8_write_quad_stencil;
907 break;
908 default:
909 assert(0);
910 }
911 }
912
913
914 static struct pipe_surface *
915 softpipe_surface_alloc(struct pipe_context *pipe, unsigned pipeFormat)
916 {
917 struct softpipe_surface *sps = CALLOC_STRUCT(softpipe_surface);
918 if (!sps)
919 return NULL;
920
921 assert(pipeFormat < PIPE_FORMAT_COUNT);
922
923 sps->surface.format = pipeFormat;
924 sps->surface.refcount = 1;
925 softpipe_init_surface_funcs(sps);
926
927 return &sps->surface;
928 }
929
930
931
932
933
934 /**
935 * Called via pipe->get_tex_surface()
936 * XXX is this in the right place?
937 */
938 struct pipe_surface *
939 softpipe_get_tex_surface(struct pipe_context *pipe,
940 struct pipe_mipmap_tree *mt,
941 unsigned face, unsigned level, unsigned zslice)
942 {
943 struct pipe_surface *ps;
944 unsigned offset; /* in bytes */
945
946 offset = mt->level[level].level_offset;
947
948 if (mt->target == PIPE_TEXTURE_CUBE) {
949 offset += mt->level[level].image_offset[face] * mt->cpp;
950 }
951 else if (mt->target == PIPE_TEXTURE_3D) {
952 offset += mt->level[level].image_offset[zslice] * mt->cpp;
953 }
954 else {
955 assert(face == 0);
956 assert(zslice == 0);
957 }
958
959 ps = pipe->surface_alloc(pipe, mt->format);
960 if (ps) {
961 assert(ps->format);
962 assert(ps->refcount);
963 pipe_region_reference(&ps->region, mt->region);
964 ps->width = mt->level[level].width;
965 ps->height = mt->level[level].height;
966 ps->offset = offset;
967 }
968 return ps;
969 }
970
971
972 void
973 sp_init_surface_functions(struct softpipe_context *sp)
974 {
975 sp->pipe.surface_alloc = softpipe_surface_alloc;
976 }