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