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