Merge branch 'mesa_7_6_branch'
[mesa.git] / src / mesa / swrast / s_depth.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 7.2.1
4 *
5 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25
26 #include "main/glheader.h"
27 #include "main/context.h"
28 #include "main/formats.h"
29 #include "main/macros.h"
30 #include "main/imports.h"
31 #include "main/fbobject.h"
32
33 #include "s_depth.h"
34 #include "s_context.h"
35 #include "s_span.h"
36
37
38 /**
39 * Do depth test for a horizontal span of fragments.
40 * Input: zbuffer - array of z values in the zbuffer
41 * z - array of fragment z values
42 * Return: number of fragments which pass the test.
43 */
44 static GLuint
45 depth_test_span16( GLcontext *ctx, GLuint n,
46 GLushort zbuffer[], const GLuint z[], GLubyte mask[] )
47 {
48 GLuint passed = 0;
49
50 /* switch cases ordered from most frequent to less frequent */
51 switch (ctx->Depth.Func) {
52 case GL_LESS:
53 if (ctx->Depth.Mask) {
54 /* Update Z buffer */
55 GLuint i;
56 for (i=0; i<n; i++) {
57 if (mask[i]) {
58 if (z[i] < zbuffer[i]) {
59 /* pass */
60 zbuffer[i] = z[i];
61 passed++;
62 }
63 else {
64 /* fail */
65 mask[i] = 0;
66 }
67 }
68 }
69 }
70 else {
71 /* Don't update Z buffer */
72 GLuint i;
73 for (i=0; i<n; i++) {
74 if (mask[i]) {
75 if (z[i] < zbuffer[i]) {
76 /* pass */
77 passed++;
78 }
79 else {
80 mask[i] = 0;
81 }
82 }
83 }
84 }
85 break;
86 case GL_LEQUAL:
87 if (ctx->Depth.Mask) {
88 /* Update Z buffer */
89 GLuint i;
90 for (i=0;i<n;i++) {
91 if (mask[i]) {
92 if (z[i] <= zbuffer[i]) {
93 zbuffer[i] = z[i];
94 passed++;
95 }
96 else {
97 mask[i] = 0;
98 }
99 }
100 }
101 }
102 else {
103 /* Don't update Z buffer */
104 GLuint i;
105 for (i=0;i<n;i++) {
106 if (mask[i]) {
107 if (z[i] <= zbuffer[i]) {
108 /* pass */
109 passed++;
110 }
111 else {
112 mask[i] = 0;
113 }
114 }
115 }
116 }
117 break;
118 case GL_GEQUAL:
119 if (ctx->Depth.Mask) {
120 /* Update Z buffer */
121 GLuint i;
122 for (i=0;i<n;i++) {
123 if (mask[i]) {
124 if (z[i] >= zbuffer[i]) {
125 zbuffer[i] = z[i];
126 passed++;
127 }
128 else {
129 mask[i] = 0;
130 }
131 }
132 }
133 }
134 else {
135 /* Don't update Z buffer */
136 GLuint i;
137 for (i=0;i<n;i++) {
138 if (mask[i]) {
139 if (z[i] >= zbuffer[i]) {
140 /* pass */
141 passed++;
142 }
143 else {
144 mask[i] = 0;
145 }
146 }
147 }
148 }
149 break;
150 case GL_GREATER:
151 if (ctx->Depth.Mask) {
152 /* Update Z buffer */
153 GLuint i;
154 for (i=0;i<n;i++) {
155 if (mask[i]) {
156 if (z[i] > zbuffer[i]) {
157 zbuffer[i] = z[i];
158 passed++;
159 }
160 else {
161 mask[i] = 0;
162 }
163 }
164 }
165 }
166 else {
167 /* Don't update Z buffer */
168 GLuint i;
169 for (i=0;i<n;i++) {
170 if (mask[i]) {
171 if (z[i] > zbuffer[i]) {
172 /* pass */
173 passed++;
174 }
175 else {
176 mask[i] = 0;
177 }
178 }
179 }
180 }
181 break;
182 case GL_NOTEQUAL:
183 if (ctx->Depth.Mask) {
184 /* Update Z buffer */
185 GLuint i;
186 for (i=0;i<n;i++) {
187 if (mask[i]) {
188 if (z[i] != zbuffer[i]) {
189 zbuffer[i] = z[i];
190 passed++;
191 }
192 else {
193 mask[i] = 0;
194 }
195 }
196 }
197 }
198 else {
199 /* Don't update Z buffer */
200 GLuint i;
201 for (i=0;i<n;i++) {
202 if (mask[i]) {
203 if (z[i] != zbuffer[i]) {
204 /* pass */
205 passed++;
206 }
207 else {
208 mask[i] = 0;
209 }
210 }
211 }
212 }
213 break;
214 case GL_EQUAL:
215 if (ctx->Depth.Mask) {
216 /* Update Z buffer */
217 GLuint i;
218 for (i=0;i<n;i++) {
219 if (mask[i]) {
220 if (z[i] == zbuffer[i]) {
221 zbuffer[i] = z[i];
222 passed++;
223 }
224 else {
225 mask[i] = 0;
226 }
227 }
228 }
229 }
230 else {
231 /* Don't update Z buffer */
232 GLuint i;
233 for (i=0;i<n;i++) {
234 if (mask[i]) {
235 if (z[i] == zbuffer[i]) {
236 /* pass */
237 passed++;
238 }
239 else {
240 mask[i] = 0;
241 }
242 }
243 }
244 }
245 break;
246 case GL_ALWAYS:
247 if (ctx->Depth.Mask) {
248 /* Update Z buffer */
249 GLuint i;
250 for (i=0;i<n;i++) {
251 if (mask[i]) {
252 zbuffer[i] = z[i];
253 passed++;
254 }
255 }
256 }
257 else {
258 /* Don't update Z buffer or mask */
259 passed = n;
260 }
261 break;
262 case GL_NEVER:
263 _mesa_bzero(mask, n * sizeof(GLubyte));
264 break;
265 default:
266 _mesa_problem(ctx, "Bad depth func in depth_test_span16");
267 }
268
269 return passed;
270 }
271
272
273 static GLuint
274 depth_test_span32( GLcontext *ctx, GLuint n,
275 GLuint zbuffer[], const GLuint z[], GLubyte mask[] )
276 {
277 GLuint passed = 0;
278
279 /* switch cases ordered from most frequent to less frequent */
280 switch (ctx->Depth.Func) {
281 case GL_LESS:
282 if (ctx->Depth.Mask) {
283 /* Update Z buffer */
284 GLuint i;
285 for (i=0; i<n; i++) {
286 if (mask[i]) {
287 if (z[i] < zbuffer[i]) {
288 /* pass */
289 zbuffer[i] = z[i];
290 passed++;
291 }
292 else {
293 /* fail */
294 mask[i] = 0;
295 }
296 }
297 }
298 }
299 else {
300 /* Don't update Z buffer */
301 GLuint i;
302 for (i=0; i<n; i++) {
303 if (mask[i]) {
304 if (z[i] < zbuffer[i]) {
305 /* pass */
306 passed++;
307 }
308 else {
309 mask[i] = 0;
310 }
311 }
312 }
313 }
314 break;
315 case GL_LEQUAL:
316 if (ctx->Depth.Mask) {
317 /* Update Z buffer */
318 GLuint i;
319 for (i=0;i<n;i++) {
320 if (mask[i]) {
321 if (z[i] <= zbuffer[i]) {
322 zbuffer[i] = z[i];
323 passed++;
324 }
325 else {
326 mask[i] = 0;
327 }
328 }
329 }
330 }
331 else {
332 /* Don't update Z buffer */
333 GLuint i;
334 for (i=0;i<n;i++) {
335 if (mask[i]) {
336 if (z[i] <= zbuffer[i]) {
337 /* pass */
338 passed++;
339 }
340 else {
341 mask[i] = 0;
342 }
343 }
344 }
345 }
346 break;
347 case GL_GEQUAL:
348 if (ctx->Depth.Mask) {
349 /* Update Z buffer */
350 GLuint i;
351 for (i=0;i<n;i++) {
352 if (mask[i]) {
353 if (z[i] >= zbuffer[i]) {
354 zbuffer[i] = z[i];
355 passed++;
356 }
357 else {
358 mask[i] = 0;
359 }
360 }
361 }
362 }
363 else {
364 /* Don't update Z buffer */
365 GLuint i;
366 for (i=0;i<n;i++) {
367 if (mask[i]) {
368 if (z[i] >= zbuffer[i]) {
369 /* pass */
370 passed++;
371 }
372 else {
373 mask[i] = 0;
374 }
375 }
376 }
377 }
378 break;
379 case GL_GREATER:
380 if (ctx->Depth.Mask) {
381 /* Update Z buffer */
382 GLuint i;
383 for (i=0;i<n;i++) {
384 if (mask[i]) {
385 if (z[i] > zbuffer[i]) {
386 zbuffer[i] = z[i];
387 passed++;
388 }
389 else {
390 mask[i] = 0;
391 }
392 }
393 }
394 }
395 else {
396 /* Don't update Z buffer */
397 GLuint i;
398 for (i=0;i<n;i++) {
399 if (mask[i]) {
400 if (z[i] > zbuffer[i]) {
401 /* pass */
402 passed++;
403 }
404 else {
405 mask[i] = 0;
406 }
407 }
408 }
409 }
410 break;
411 case GL_NOTEQUAL:
412 if (ctx->Depth.Mask) {
413 /* Update Z buffer */
414 GLuint i;
415 for (i=0;i<n;i++) {
416 if (mask[i]) {
417 if (z[i] != zbuffer[i]) {
418 zbuffer[i] = z[i];
419 passed++;
420 }
421 else {
422 mask[i] = 0;
423 }
424 }
425 }
426 }
427 else {
428 /* Don't update Z buffer */
429 GLuint i;
430 for (i=0;i<n;i++) {
431 if (mask[i]) {
432 if (z[i] != zbuffer[i]) {
433 /* pass */
434 passed++;
435 }
436 else {
437 mask[i] = 0;
438 }
439 }
440 }
441 }
442 break;
443 case GL_EQUAL:
444 if (ctx->Depth.Mask) {
445 /* Update Z buffer */
446 GLuint i;
447 for (i=0;i<n;i++) {
448 if (mask[i]) {
449 if (z[i] == zbuffer[i]) {
450 zbuffer[i] = z[i];
451 passed++;
452 }
453 else {
454 mask[i] = 0;
455 }
456 }
457 }
458 }
459 else {
460 /* Don't update Z buffer */
461 GLuint i;
462 for (i=0;i<n;i++) {
463 if (mask[i]) {
464 if (z[i] == zbuffer[i]) {
465 /* pass */
466 passed++;
467 }
468 else {
469 mask[i] = 0;
470 }
471 }
472 }
473 }
474 break;
475 case GL_ALWAYS:
476 if (ctx->Depth.Mask) {
477 /* Update Z buffer */
478 GLuint i;
479 for (i=0;i<n;i++) {
480 if (mask[i]) {
481 zbuffer[i] = z[i];
482 passed++;
483 }
484 }
485 }
486 else {
487 /* Don't update Z buffer or mask */
488 passed = n;
489 }
490 break;
491 case GL_NEVER:
492 _mesa_bzero(mask, n * sizeof(GLubyte));
493 break;
494 default:
495 _mesa_problem(ctx, "Bad depth func in depth_test_span32");
496 }
497
498 return passed;
499 }
500
501 /* Apply ARB_depth_clamp to span of fragments. */
502 void
503 _swrast_depth_clamp_span( GLcontext *ctx, SWspan *span )
504 {
505 struct gl_framebuffer *fb = ctx->DrawBuffer;
506 struct gl_renderbuffer *rb = fb->_DepthBuffer;
507 const GLuint count = span->end;
508 GLuint *zValues = span->array->z;
509 GLuint min, max;
510 GLfloat min_f, max_f;
511 int i;
512
513 if (ctx->Viewport.Near < ctx->Viewport.Far) {
514 min_f = ctx->Viewport.Near;
515 max_f = ctx->Viewport.Far;
516 } else {
517 min_f = ctx->Viewport.Far;
518 max_f = ctx->Viewport.Near;
519 }
520
521 if (rb->DataType == GL_UNSIGNED_SHORT) {
522 CLAMPED_FLOAT_TO_USHORT(min, min_f);
523 CLAMPED_FLOAT_TO_USHORT(max, max_f);
524 } else {
525 assert(rb->DataType == GL_UNSIGNED_INT);
526 min = FLOAT_TO_UINT(min_f);
527 max = FLOAT_TO_UINT(max_f);
528 }
529
530 for (i = 0; i < count; i++) {
531 if (zValues[i] < min)
532 zValues[i] = min;
533 if (zValues[i] > max)
534 zValues[i] = max;
535 }
536 }
537
538
539
540 /*
541 * Apply depth test to span of fragments.
542 */
543 static GLuint
544 depth_test_span( GLcontext *ctx, SWspan *span)
545 {
546 struct gl_framebuffer *fb = ctx->DrawBuffer;
547 struct gl_renderbuffer *rb = fb->_DepthBuffer;
548 const GLint x = span->x;
549 const GLint y = span->y;
550 const GLuint count = span->end;
551 const GLuint *zValues = span->array->z;
552 GLubyte *mask = span->array->mask;
553 GLuint passed;
554
555 ASSERT((span->arrayMask & SPAN_XY) == 0);
556 ASSERT(span->arrayMask & SPAN_Z);
557
558 if (rb->GetPointer(ctx, rb, 0, 0)) {
559 /* Directly access buffer */
560 if (rb->DataType == GL_UNSIGNED_SHORT) {
561 GLushort *zbuffer = (GLushort *) rb->GetPointer(ctx, rb, x, y);
562 passed = depth_test_span16(ctx, count, zbuffer, zValues, mask);
563 }
564 else {
565 GLuint *zbuffer = (GLuint *) rb->GetPointer(ctx, rb, x, y);
566 ASSERT(rb->DataType == GL_UNSIGNED_INT);
567 passed = depth_test_span32(ctx, count, zbuffer, zValues, mask);
568 }
569 }
570 else {
571 /* read depth values from buffer, test, write back */
572 if (rb->DataType == GL_UNSIGNED_SHORT) {
573 GLushort zbuffer[MAX_WIDTH];
574 rb->GetRow(ctx, rb, count, x, y, zbuffer);
575 passed = depth_test_span16(ctx, count, zbuffer, zValues, mask);
576 rb->PutRow(ctx, rb, count, x, y, zbuffer, mask);
577 }
578 else {
579 GLuint zbuffer[MAX_WIDTH];
580 ASSERT(rb->DataType == GL_UNSIGNED_INT);
581 rb->GetRow(ctx, rb, count, x, y, zbuffer);
582 passed = depth_test_span32(ctx, count, zbuffer, zValues, mask);
583 rb->PutRow(ctx, rb, count, x, y, zbuffer, mask);
584 }
585 }
586
587 if (passed < count) {
588 span->writeAll = GL_FALSE;
589 }
590 return passed;
591 }
592
593
594
595 #define Z_ADDRESS(X, Y) (zStart + (Y) * stride + (X))
596
597
598 /*
599 * Do depth testing for an array of fragments at assorted locations.
600 */
601 static void
602 direct_depth_test_pixels16(GLcontext *ctx, GLushort *zStart, GLuint stride,
603 GLuint n, const GLint x[], const GLint y[],
604 const GLuint z[], GLubyte mask[] )
605 {
606 /* switch cases ordered from most frequent to less frequent */
607 switch (ctx->Depth.Func) {
608 case GL_LESS:
609 if (ctx->Depth.Mask) {
610 /* Update Z buffer */
611 GLuint i;
612 for (i=0; i<n; i++) {
613 if (mask[i]) {
614 GLushort *zptr = Z_ADDRESS(x[i], y[i]);
615 if (z[i] < *zptr) {
616 /* pass */
617 *zptr = z[i];
618 }
619 else {
620 /* fail */
621 mask[i] = 0;
622 }
623 }
624 }
625 }
626 else {
627 /* Don't update Z buffer */
628 GLuint i;
629 for (i=0; i<n; i++) {
630 if (mask[i]) {
631 GLushort *zptr = Z_ADDRESS(x[i], y[i]);
632 if (z[i] < *zptr) {
633 /* pass */
634 }
635 else {
636 /* fail */
637 mask[i] = 0;
638 }
639 }
640 }
641 }
642 break;
643 case GL_LEQUAL:
644 if (ctx->Depth.Mask) {
645 /* Update Z buffer */
646 GLuint i;
647 for (i=0; i<n; i++) {
648 if (mask[i]) {
649 GLushort *zptr = Z_ADDRESS(x[i], y[i]);
650 if (z[i] <= *zptr) {
651 /* pass */
652 *zptr = z[i];
653 }
654 else {
655 /* fail */
656 mask[i] = 0;
657 }
658 }
659 }
660 }
661 else {
662 /* Don't update Z buffer */
663 GLuint i;
664 for (i=0; i<n; i++) {
665 if (mask[i]) {
666 GLushort *zptr = Z_ADDRESS(x[i], y[i]);
667 if (z[i] <= *zptr) {
668 /* pass */
669 }
670 else {
671 /* fail */
672 mask[i] = 0;
673 }
674 }
675 }
676 }
677 break;
678 case GL_GEQUAL:
679 if (ctx->Depth.Mask) {
680 /* Update Z buffer */
681 GLuint i;
682 for (i=0; i<n; i++) {
683 if (mask[i]) {
684 GLushort *zptr = Z_ADDRESS(x[i], y[i]);
685 if (z[i] >= *zptr) {
686 /* pass */
687 *zptr = z[i];
688 }
689 else {
690 /* fail */
691 mask[i] = 0;
692 }
693 }
694 }
695 }
696 else {
697 /* Don't update Z buffer */
698 GLuint i;
699 for (i=0; i<n; i++) {
700 if (mask[i]) {
701 GLushort *zptr = Z_ADDRESS(x[i], y[i]);
702 if (z[i] >= *zptr) {
703 /* pass */
704 }
705 else {
706 /* fail */
707 mask[i] = 0;
708 }
709 }
710 }
711 }
712 break;
713 case GL_GREATER:
714 if (ctx->Depth.Mask) {
715 /* Update Z buffer */
716 GLuint i;
717 for (i=0; i<n; i++) {
718 if (mask[i]) {
719 GLushort *zptr = Z_ADDRESS(x[i], y[i]);
720 if (z[i] > *zptr) {
721 /* pass */
722 *zptr = z[i];
723 }
724 else {
725 /* fail */
726 mask[i] = 0;
727 }
728 }
729 }
730 }
731 else {
732 /* Don't update Z buffer */
733 GLuint i;
734 for (i=0; i<n; i++) {
735 if (mask[i]) {
736 GLushort *zptr = Z_ADDRESS(x[i], y[i]);
737 if (z[i] > *zptr) {
738 /* pass */
739 }
740 else {
741 /* fail */
742 mask[i] = 0;
743 }
744 }
745 }
746 }
747 break;
748 case GL_NOTEQUAL:
749 if (ctx->Depth.Mask) {
750 /* Update Z buffer */
751 GLuint i;
752 for (i=0; i<n; i++) {
753 if (mask[i]) {
754 GLushort *zptr = Z_ADDRESS(x[i], y[i]);
755 if (z[i] != *zptr) {
756 /* pass */
757 *zptr = z[i];
758 }
759 else {
760 /* fail */
761 mask[i] = 0;
762 }
763 }
764 }
765 }
766 else {
767 /* Don't update Z buffer */
768 GLuint i;
769 for (i=0; i<n; i++) {
770 if (mask[i]) {
771 GLushort *zptr = Z_ADDRESS(x[i], y[i]);
772 if (z[i] != *zptr) {
773 /* pass */
774 }
775 else {
776 /* fail */
777 mask[i] = 0;
778 }
779 }
780 }
781 }
782 break;
783 case GL_EQUAL:
784 if (ctx->Depth.Mask) {
785 /* Update Z buffer */
786 GLuint i;
787 for (i=0; i<n; i++) {
788 if (mask[i]) {
789 GLushort *zptr = Z_ADDRESS(x[i], y[i]);
790 if (z[i] == *zptr) {
791 /* pass */
792 *zptr = z[i];
793 }
794 else {
795 /* fail */
796 mask[i] = 0;
797 }
798 }
799 }
800 }
801 else {
802 /* Don't update Z buffer */
803 GLuint i;
804 for (i=0; i<n; i++) {
805 if (mask[i]) {
806 GLushort *zptr = Z_ADDRESS(x[i], y[i]);
807 if (z[i] == *zptr) {
808 /* pass */
809 }
810 else {
811 /* fail */
812 mask[i] = 0;
813 }
814 }
815 }
816 }
817 break;
818 case GL_ALWAYS:
819 if (ctx->Depth.Mask) {
820 /* Update Z buffer */
821 GLuint i;
822 for (i=0; i<n; i++) {
823 if (mask[i]) {
824 GLushort *zptr = Z_ADDRESS(x[i], y[i]);
825 *zptr = z[i];
826 }
827 }
828 }
829 else {
830 /* Don't update Z buffer or mask */
831 }
832 break;
833 case GL_NEVER:
834 /* depth test never passes */
835 _mesa_bzero(mask, n * sizeof(GLubyte));
836 break;
837 default:
838 _mesa_problem(ctx, "Bad depth func in direct_depth_test_pixels");
839 }
840 }
841
842
843
844 /*
845 * Do depth testing for an array of fragments with direct access to zbuffer.
846 */
847 static void
848 direct_depth_test_pixels32(GLcontext *ctx, GLuint *zStart, GLuint stride,
849 GLuint n, const GLint x[], const GLint y[],
850 const GLuint z[], GLubyte mask[] )
851 {
852 /* switch cases ordered from most frequent to less frequent */
853 switch (ctx->Depth.Func) {
854 case GL_LESS:
855 if (ctx->Depth.Mask) {
856 /* Update Z buffer */
857 GLuint i;
858 for (i=0; i<n; i++) {
859 if (mask[i]) {
860 GLuint *zptr = Z_ADDRESS(x[i], y[i]);
861 if (z[i] < *zptr) {
862 /* pass */
863 *zptr = z[i];
864 }
865 else {
866 /* fail */
867 mask[i] = 0;
868 }
869 }
870 }
871 }
872 else {
873 /* Don't update Z buffer */
874 GLuint i;
875 for (i=0; i<n; i++) {
876 if (mask[i]) {
877 GLuint *zptr = Z_ADDRESS(x[i], y[i]);
878 if (z[i] < *zptr) {
879 /* pass */
880 }
881 else {
882 /* fail */
883 mask[i] = 0;
884 }
885 }
886 }
887 }
888 break;
889 case GL_LEQUAL:
890 if (ctx->Depth.Mask) {
891 /* Update Z buffer */
892 GLuint i;
893 for (i=0; i<n; i++) {
894 if (mask[i]) {
895 GLuint *zptr = Z_ADDRESS(x[i], y[i]);
896 if (z[i] <= *zptr) {
897 /* pass */
898 *zptr = z[i];
899 }
900 else {
901 /* fail */
902 mask[i] = 0;
903 }
904 }
905 }
906 }
907 else {
908 /* Don't update Z buffer */
909 GLuint i;
910 for (i=0; i<n; i++) {
911 if (mask[i]) {
912 GLuint *zptr = Z_ADDRESS(x[i], y[i]);
913 if (z[i] <= *zptr) {
914 /* pass */
915 }
916 else {
917 /* fail */
918 mask[i] = 0;
919 }
920 }
921 }
922 }
923 break;
924 case GL_GEQUAL:
925 if (ctx->Depth.Mask) {
926 /* Update Z buffer */
927 GLuint i;
928 for (i=0; i<n; i++) {
929 if (mask[i]) {
930 GLuint *zptr = Z_ADDRESS(x[i], y[i]);
931 if (z[i] >= *zptr) {
932 /* pass */
933 *zptr = z[i];
934 }
935 else {
936 /* fail */
937 mask[i] = 0;
938 }
939 }
940 }
941 }
942 else {
943 /* Don't update Z buffer */
944 GLuint i;
945 for (i=0; i<n; i++) {
946 if (mask[i]) {
947 GLuint *zptr = Z_ADDRESS(x[i], y[i]);
948 if (z[i] >= *zptr) {
949 /* pass */
950 }
951 else {
952 /* fail */
953 mask[i] = 0;
954 }
955 }
956 }
957 }
958 break;
959 case GL_GREATER:
960 if (ctx->Depth.Mask) {
961 /* Update Z buffer */
962 GLuint i;
963 for (i=0; i<n; i++) {
964 if (mask[i]) {
965 GLuint *zptr = Z_ADDRESS(x[i], y[i]);
966 if (z[i] > *zptr) {
967 /* pass */
968 *zptr = z[i];
969 }
970 else {
971 /* fail */
972 mask[i] = 0;
973 }
974 }
975 }
976 }
977 else {
978 /* Don't update Z buffer */
979 GLuint i;
980 for (i=0; i<n; i++) {
981 if (mask[i]) {
982 GLuint *zptr = Z_ADDRESS(x[i], y[i]);
983 if (z[i] > *zptr) {
984 /* pass */
985 }
986 else {
987 /* fail */
988 mask[i] = 0;
989 }
990 }
991 }
992 }
993 break;
994 case GL_NOTEQUAL:
995 if (ctx->Depth.Mask) {
996 /* Update Z buffer */
997 GLuint i;
998 for (i=0; i<n; i++) {
999 if (mask[i]) {
1000 GLuint *zptr = Z_ADDRESS(x[i], y[i]);
1001 if (z[i] != *zptr) {
1002 /* pass */
1003 *zptr = z[i];
1004 }
1005 else {
1006 /* fail */
1007 mask[i] = 0;
1008 }
1009 }
1010 }
1011 }
1012 else {
1013 /* Don't update Z buffer */
1014 GLuint i;
1015 for (i=0; i<n; i++) {
1016 if (mask[i]) {
1017 GLuint *zptr = Z_ADDRESS(x[i], y[i]);
1018 if (z[i] != *zptr) {
1019 /* pass */
1020 }
1021 else {
1022 /* fail */
1023 mask[i] = 0;
1024 }
1025 }
1026 }
1027 }
1028 break;
1029 case GL_EQUAL:
1030 if (ctx->Depth.Mask) {
1031 /* Update Z buffer */
1032 GLuint i;
1033 for (i=0; i<n; i++) {
1034 if (mask[i]) {
1035 GLuint *zptr = Z_ADDRESS(x[i], y[i]);
1036 if (z[i] == *zptr) {
1037 /* pass */
1038 *zptr = z[i];
1039 }
1040 else {
1041 /* fail */
1042 mask[i] = 0;
1043 }
1044 }
1045 }
1046 }
1047 else {
1048 /* Don't update Z buffer */
1049 GLuint i;
1050 for (i=0; i<n; i++) {
1051 if (mask[i]) {
1052 GLuint *zptr = Z_ADDRESS(x[i], y[i]);
1053 if (z[i] == *zptr) {
1054 /* pass */
1055 }
1056 else {
1057 /* fail */
1058 mask[i] = 0;
1059 }
1060 }
1061 }
1062 }
1063 break;
1064 case GL_ALWAYS:
1065 if (ctx->Depth.Mask) {
1066 /* Update Z buffer */
1067 GLuint i;
1068 for (i=0; i<n; i++) {
1069 if (mask[i]) {
1070 GLuint *zptr = Z_ADDRESS(x[i], y[i]);
1071 *zptr = z[i];
1072 }
1073 }
1074 }
1075 else {
1076 /* Don't update Z buffer or mask */
1077 }
1078 break;
1079 case GL_NEVER:
1080 /* depth test never passes */
1081 _mesa_bzero(mask, n * sizeof(GLubyte));
1082 break;
1083 default:
1084 _mesa_problem(ctx, "Bad depth func in direct_depth_test_pixels");
1085 }
1086 }
1087
1088
1089
1090
1091 static GLuint
1092 depth_test_pixels( GLcontext *ctx, SWspan *span )
1093 {
1094 struct gl_framebuffer *fb = ctx->DrawBuffer;
1095 struct gl_renderbuffer *rb = fb->_DepthBuffer;
1096 const GLuint count = span->end;
1097 const GLint *x = span->array->x;
1098 const GLint *y = span->array->y;
1099 const GLuint *z = span->array->z;
1100 GLubyte *mask = span->array->mask;
1101
1102 if (rb->GetPointer(ctx, rb, 0, 0)) {
1103 /* Directly access values */
1104 if (rb->DataType == GL_UNSIGNED_SHORT) {
1105 GLushort *zStart = (GLushort *) rb->Data;
1106 GLuint stride = rb->Width;
1107 direct_depth_test_pixels16(ctx, zStart, stride, count, x, y, z, mask);
1108 }
1109 else {
1110 GLuint *zStart = (GLuint *) rb->Data;
1111 GLuint stride = rb->Width;
1112 ASSERT(rb->DataType == GL_UNSIGNED_INT);
1113 direct_depth_test_pixels32(ctx, zStart, stride, count, x, y, z, mask);
1114 }
1115 }
1116 else {
1117 /* read depth values from buffer, test, write back */
1118 if (rb->DataType == GL_UNSIGNED_SHORT) {
1119 GLushort zbuffer[MAX_WIDTH];
1120 _swrast_get_values(ctx, rb, count, x, y, zbuffer, sizeof(GLushort));
1121 depth_test_span16(ctx, count, zbuffer, z, mask);
1122 rb->PutValues(ctx, rb, count, x, y, zbuffer, mask);
1123 }
1124 else {
1125 GLuint zbuffer[MAX_WIDTH];
1126 ASSERT(rb->DataType == GL_UNSIGNED_INT);
1127 _swrast_get_values(ctx, rb, count, x, y, zbuffer, sizeof(GLuint));
1128 depth_test_span32(ctx, count, zbuffer, z, mask);
1129 rb->PutValues(ctx, rb, count, x, y, zbuffer, mask);
1130 }
1131 }
1132
1133 return count; /* not really correct, but OK */
1134 }
1135
1136
1137 /**
1138 * Apply depth (Z) buffer testing to the span.
1139 * \return approx number of pixels that passed (only zero is reliable)
1140 */
1141 GLuint
1142 _swrast_depth_test_span( GLcontext *ctx, SWspan *span)
1143 {
1144 if (span->arrayMask & SPAN_XY)
1145 return depth_test_pixels(ctx, span);
1146 else
1147 return depth_test_span(ctx, span);
1148 }
1149
1150
1151 /**
1152 * GL_EXT_depth_bounds_test extension.
1153 * Discard fragments depending on whether the corresponding Z-buffer
1154 * values are outside the depth bounds test range.
1155 * Note: we test the Z buffer values, not the fragment Z values!
1156 * \return GL_TRUE if any fragments pass, GL_FALSE if no fragments pass
1157 */
1158 GLboolean
1159 _swrast_depth_bounds_test( GLcontext *ctx, SWspan *span )
1160 {
1161 struct gl_framebuffer *fb = ctx->DrawBuffer;
1162 struct gl_renderbuffer *rb = fb->_DepthBuffer;
1163 GLuint zMin = (GLuint) (ctx->Depth.BoundsMin * fb->_DepthMaxF + 0.5F);
1164 GLuint zMax = (GLuint) (ctx->Depth.BoundsMax * fb->_DepthMaxF + 0.5F);
1165 GLubyte *mask = span->array->mask;
1166 const GLuint count = span->end;
1167 GLuint i;
1168 GLboolean anyPass = GL_FALSE;
1169
1170 if (rb->DataType == GL_UNSIGNED_SHORT) {
1171 /* get 16-bit values */
1172 GLushort zbuffer16[MAX_WIDTH], *zbuffer;
1173 if (span->arrayMask & SPAN_XY) {
1174 _swrast_get_values(ctx, rb, count, span->array->x, span->array->y,
1175 zbuffer16, sizeof(GLushort));
1176 zbuffer = zbuffer16;
1177 }
1178 else {
1179 zbuffer = (GLushort*) rb->GetPointer(ctx, rb, span->x, span->y);
1180 if (!zbuffer) {
1181 rb->GetRow(ctx, rb, count, span->x, span->y, zbuffer16);
1182 zbuffer = zbuffer16;
1183 }
1184 }
1185 assert(zbuffer);
1186
1187 /* Now do the tests */
1188 for (i = 0; i < count; i++) {
1189 if (mask[i]) {
1190 if (zbuffer[i] < zMin || zbuffer[i] > zMax)
1191 mask[i] = GL_FALSE;
1192 else
1193 anyPass = GL_TRUE;
1194 }
1195 }
1196 }
1197 else {
1198 /* get 32-bit values */
1199 GLuint zbuffer32[MAX_WIDTH], *zbuffer;
1200 ASSERT(rb->DataType == GL_UNSIGNED_INT);
1201 if (span->arrayMask & SPAN_XY) {
1202 _swrast_get_values(ctx, rb, count, span->array->x, span->array->y,
1203 zbuffer32, sizeof(GLuint));
1204 zbuffer = zbuffer32;
1205 }
1206 else {
1207 zbuffer = (GLuint*) rb->GetPointer(ctx, rb, span->x, span->y);
1208 if (!zbuffer) {
1209 rb->GetRow(ctx, rb, count, span->x, span->y, zbuffer32);
1210 zbuffer = zbuffer32;
1211 }
1212 }
1213 assert(zbuffer);
1214
1215 /* Now do the tests */
1216 for (i = 0; i < count; i++) {
1217 if (mask[i]) {
1218 if (zbuffer[i] < zMin || zbuffer[i] > zMax)
1219 mask[i] = GL_FALSE;
1220 else
1221 anyPass = GL_TRUE;
1222 }
1223 }
1224 }
1225
1226 return anyPass;
1227 }
1228
1229
1230
1231 /**********************************************************************/
1232 /***** Read Depth Buffer *****/
1233 /**********************************************************************/
1234
1235
1236 /**
1237 * Read a span of depth values from the given depth renderbuffer, returning
1238 * the values as GLfloats.
1239 * This function does clipping to prevent reading outside the depth buffer's
1240 * bounds. Though the clipping is redundant when we're called from
1241 * _swrast_ReadPixels.
1242 */
1243 void
1244 _swrast_read_depth_span_float( GLcontext *ctx, struct gl_renderbuffer *rb,
1245 GLint n, GLint x, GLint y, GLfloat depth[] )
1246 {
1247 const GLfloat scale = 1.0F / ctx->DrawBuffer->_DepthMaxF;
1248
1249 if (!rb) {
1250 /* really only doing this to prevent FP exceptions later */
1251 _mesa_bzero(depth, n * sizeof(GLfloat));
1252 return;
1253 }
1254
1255 ASSERT(rb->_BaseFormat == GL_DEPTH_COMPONENT);
1256
1257 if (y < 0 || y >= (GLint) rb->Height ||
1258 x + n <= 0 || x >= (GLint) rb->Width) {
1259 /* span is completely outside framebuffer */
1260 _mesa_bzero(depth, n * sizeof(GLfloat));
1261 return;
1262 }
1263
1264 if (x < 0) {
1265 GLint dx = -x;
1266 GLint i;
1267 for (i = 0; i < dx; i++)
1268 depth[i] = 0.0;
1269 x = 0;
1270 n -= dx;
1271 depth += dx;
1272 }
1273 if (x + n > (GLint) rb->Width) {
1274 GLint dx = x + n - (GLint) rb->Width;
1275 GLint i;
1276 for (i = 0; i < dx; i++)
1277 depth[n - i - 1] = 0.0;
1278 n -= dx;
1279 }
1280 if (n <= 0) {
1281 return;
1282 }
1283
1284 if (rb->DataType == GL_UNSIGNED_INT) {
1285 GLuint temp[MAX_WIDTH];
1286 GLint i;
1287 rb->GetRow(ctx, rb, n, x, y, temp);
1288 for (i = 0; i < n; i++) {
1289 depth[i] = temp[i] * scale;
1290 }
1291 }
1292 else if (rb->DataType == GL_UNSIGNED_SHORT) {
1293 GLushort temp[MAX_WIDTH];
1294 GLint i;
1295 rb->GetRow(ctx, rb, n, x, y, temp);
1296 for (i = 0; i < n; i++) {
1297 depth[i] = temp[i] * scale;
1298 }
1299 }
1300 else {
1301 _mesa_problem(ctx, "Invalid depth renderbuffer data type");
1302 }
1303 }
1304
1305
1306 /**
1307 * As above, but return 32-bit GLuint values.
1308 */
1309 void
1310 _swrast_read_depth_span_uint( GLcontext *ctx, struct gl_renderbuffer *rb,
1311 GLint n, GLint x, GLint y, GLuint depth[] )
1312 {
1313 GLuint depthBits;
1314
1315 if (!rb) {
1316 /* really only doing this to prevent FP exceptions later */
1317 _mesa_bzero(depth, n * sizeof(GLuint));
1318 return;
1319 }
1320
1321 depthBits = _mesa_get_format_bits(rb->Format, GL_DEPTH_BITS);
1322
1323 ASSERT(rb->_BaseFormat == GL_DEPTH_COMPONENT);
1324
1325 if (y < 0 || y >= (GLint) rb->Height ||
1326 x + n <= 0 || x >= (GLint) rb->Width) {
1327 /* span is completely outside framebuffer */
1328 _mesa_bzero(depth, n * sizeof(GLfloat));
1329 return;
1330 }
1331
1332 if (x < 0) {
1333 GLint dx = -x;
1334 GLint i;
1335 for (i = 0; i < dx; i++)
1336 depth[i] = 0;
1337 x = 0;
1338 n -= dx;
1339 depth += dx;
1340 }
1341 if (x + n > (GLint) rb->Width) {
1342 GLint dx = x + n - (GLint) rb->Width;
1343 GLint i;
1344 for (i = 0; i < dx; i++)
1345 depth[n - i - 1] = 0;
1346 n -= dx;
1347 }
1348 if (n <= 0) {
1349 return;
1350 }
1351
1352 if (rb->DataType == GL_UNSIGNED_INT) {
1353 rb->GetRow(ctx, rb, n, x, y, depth);
1354 if (depthBits < 32) {
1355 GLuint shift = 32 - depthBits;
1356 GLint i;
1357 for (i = 0; i < n; i++) {
1358 GLuint z = depth[i];
1359 depth[i] = z << shift; /* XXX lsb bits? */
1360 }
1361 }
1362 }
1363 else if (rb->DataType == GL_UNSIGNED_SHORT) {
1364 GLushort temp[MAX_WIDTH];
1365 GLint i;
1366 rb->GetRow(ctx, rb, n, x, y, temp);
1367 if (depthBits == 16) {
1368 for (i = 0; i < n; i++) {
1369 GLuint z = temp[i];
1370 depth[i] = (z << 16) | z;
1371 }
1372 }
1373 else {
1374 GLuint shift = 16 - depthBits;
1375 for (i = 0; i < n; i++) {
1376 GLuint z = temp[i];
1377 depth[i] = (z << (shift + 16)) | (z << shift); /* XXX lsb bits? */
1378 }
1379 }
1380 }
1381 else {
1382 _mesa_problem(ctx, "Invalid depth renderbuffer data type");
1383 }
1384 }
1385
1386
1387
1388 /**
1389 * Clear the given z/depth renderbuffer.
1390 */
1391 void
1392 _swrast_clear_depth_buffer( GLcontext *ctx, struct gl_renderbuffer *rb )
1393 {
1394 GLuint clearValue;
1395 GLint x, y, width, height;
1396
1397 if (!rb || !ctx->Depth.Mask) {
1398 /* no depth buffer, or writing to it is disabled */
1399 return;
1400 }
1401
1402 /* compute integer clearing value */
1403 if (ctx->Depth.Clear == 1.0) {
1404 clearValue = ctx->DrawBuffer->_DepthMax;
1405 }
1406 else {
1407 clearValue = (GLuint) (ctx->Depth.Clear * ctx->DrawBuffer->_DepthMaxF);
1408 }
1409
1410 assert(rb->_BaseFormat == GL_DEPTH_COMPONENT);
1411
1412 /* compute region to clear */
1413 x = ctx->DrawBuffer->_Xmin;
1414 y = ctx->DrawBuffer->_Ymin;
1415 width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin;
1416 height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin;
1417
1418 if (rb->GetPointer(ctx, rb, 0, 0)) {
1419 /* Direct buffer access is possible. Either this is just malloc'd
1420 * memory, or perhaps the driver mmap'd the zbuffer memory.
1421 */
1422 if (rb->DataType == GL_UNSIGNED_SHORT) {
1423 if ((clearValue & 0xff) == ((clearValue >> 8) & 0xff) &&
1424 ((GLushort *) rb->GetPointer(ctx, rb, 0, 0) + width ==
1425 (GLushort *) rb->GetPointer(ctx, rb, 0, 1))) {
1426 /* optimized case */
1427 GLushort *dst = (GLushort *) rb->GetPointer(ctx, rb, x, y);
1428 GLuint len = width * height * sizeof(GLushort);
1429 _mesa_memset(dst, (clearValue & 0xff), len);
1430 }
1431 else {
1432 /* general case */
1433 GLint i, j;
1434 for (i = 0; i < height; i++) {
1435 GLushort *dst = (GLushort *) rb->GetPointer(ctx, rb, x, y + i);
1436 for (j = 0; j < width; j++) {
1437 dst[j] = clearValue;
1438 }
1439 }
1440 }
1441 }
1442 else {
1443 GLint i, j;
1444 ASSERT(rb->DataType == GL_UNSIGNED_INT);
1445 for (i = 0; i < height; i++) {
1446 GLuint *dst = (GLuint *) rb->GetPointer(ctx, rb, x, y + i);
1447 for (j = 0; j < width; j++) {
1448 dst[j] = clearValue;
1449 }
1450 }
1451 }
1452 }
1453 else {
1454 /* Direct access not possible. Use PutRow to write new values. */
1455 if (rb->DataType == GL_UNSIGNED_SHORT) {
1456 GLushort clearVal16 = (GLushort) (clearValue & 0xffff);
1457 GLint i;
1458 for (i = 0; i < height; i++) {
1459 rb->PutMonoRow(ctx, rb, width, x, y + i, &clearVal16, NULL);
1460 }
1461 }
1462 else if (rb->DataType == GL_UNSIGNED_INT) {
1463 GLint i;
1464 ASSERT(sizeof(clearValue) == sizeof(GLuint));
1465 for (i = 0; i < height; i++) {
1466 rb->PutMonoRow(ctx, rb, width, x, y + i, &clearValue, NULL);
1467 }
1468 }
1469 else {
1470 _mesa_problem(ctx, "bad depth renderbuffer DataType");
1471 }
1472 }
1473 }