Header file clean-up:
[mesa.git] / src / mesa / swrast / s_depth.c
1 /* $Id: s_depth.c,v 1.24 2002/10/24 23:57:24 brianp Exp $ */
2
3 /*
4 * Mesa 3-D graphics library
5 * Version: 4.1
6 *
7 * Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 */
26
27
28 #include "glheader.h"
29 #include "context.h"
30 #include "macros.h"
31 #include "imports.h"
32
33 #include "s_depth.h"
34 #include "s_context.h"
35
36
37 /**
38 * Return address of depth buffer value for given window coord.
39 */
40 GLvoid *
41 _mesa_zbuffer_address(GLcontext *ctx, GLint x, GLint y)
42 {
43 if (ctx->Visual.depthBits <= 16)
44 return (GLushort *) ctx->DrawBuffer->DepthBuffer
45 + ctx->DrawBuffer->Width * y + x;
46 else
47 return (GLuint *) ctx->DrawBuffer->DepthBuffer
48 + ctx->DrawBuffer->Width * y + x;
49 }
50
51
52 #define Z_ADDRESS16( CTX, X, Y ) \
53 ( ((GLushort *) (CTX)->DrawBuffer->DepthBuffer) \
54 + (CTX)->DrawBuffer->Width * (Y) + (X) )
55
56 #define Z_ADDRESS32( CTX, X, Y ) \
57 ( ((GLuint *) (CTX)->DrawBuffer->DepthBuffer) \
58 + (CTX)->DrawBuffer->Width * (Y) + (X) )
59
60
61
62 /**********************************************************************/
63 /***** Depth Testing Functions *****/
64 /**********************************************************************/
65
66
67 /*
68 * Do depth test for an array of fragments. This is used both for
69 * software and hardware Z buffers.
70 * Input: zbuffer - array of z values in the zbuffer
71 * z - array of fragment z values
72 * Return: number of fragments which pass the test.
73 */
74 static GLuint
75 depth_test_span16( GLcontext *ctx, GLuint n,
76 GLushort zbuffer[], const GLdepth z[], GLubyte mask[] )
77 {
78 GLuint passed = 0;
79
80 /* switch cases ordered from most frequent to less frequent */
81 switch (ctx->Depth.Func) {
82 case GL_LESS:
83 if (ctx->Depth.Mask) {
84 /* Update Z buffer */
85 GLuint i;
86 for (i=0; i<n; i++) {
87 if (mask[i]) {
88 if (z[i] < zbuffer[i]) {
89 /* pass */
90 zbuffer[i] = z[i];
91 passed++;
92 }
93 else {
94 /* fail */
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_LEQUAL:
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_GEQUAL:
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_GREATER:
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_NOTEQUAL:
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_EQUAL:
245 if (ctx->Depth.Mask) {
246 /* Update Z buffer */
247 GLuint i;
248 for (i=0;i<n;i++) {
249 if (mask[i]) {
250 if (z[i] == zbuffer[i]) {
251 zbuffer[i] = z[i];
252 passed++;
253 }
254 else {
255 mask[i] = 0;
256 }
257 }
258 }
259 }
260 else {
261 /* Don't update Z buffer */
262 GLuint i;
263 for (i=0;i<n;i++) {
264 if (mask[i]) {
265 if (z[i] == zbuffer[i]) {
266 /* pass */
267 passed++;
268 }
269 else {
270 mask[i] = 0;
271 }
272 }
273 }
274 }
275 break;
276 case GL_ALWAYS:
277 if (ctx->Depth.Mask) {
278 /* Update Z buffer */
279 GLuint i;
280 for (i=0;i<n;i++) {
281 if (mask[i]) {
282 zbuffer[i] = z[i];
283 passed++;
284 }
285 }
286 }
287 else {
288 /* Don't update Z buffer or mask */
289 passed = n;
290 }
291 break;
292 case GL_NEVER:
293 BZERO(mask, n * sizeof(GLubyte));
294 break;
295 default:
296 _mesa_problem(ctx, "Bad depth func in depth_test_span16");
297 }
298
299 return passed;
300 }
301
302
303 static GLuint
304 depth_test_span32( GLcontext *ctx, GLuint n,
305 GLuint zbuffer[], const GLdepth z[], GLubyte mask[] )
306 {
307 GLuint passed = 0;
308
309 /* switch cases ordered from most frequent to less frequent */
310 switch (ctx->Depth.Func) {
311 case GL_LESS:
312 if (ctx->Depth.Mask) {
313 /* Update Z buffer */
314 GLuint i;
315 for (i=0; i<n; i++) {
316 if (mask[i]) {
317 if (z[i] < zbuffer[i]) {
318 /* pass */
319 zbuffer[i] = z[i];
320 passed++;
321 }
322 else {
323 /* fail */
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_LEQUAL:
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_GEQUAL:
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_GREATER:
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_NOTEQUAL:
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_EQUAL:
474 if (ctx->Depth.Mask) {
475 /* Update Z buffer */
476 GLuint i;
477 for (i=0;i<n;i++) {
478 if (mask[i]) {
479 if (z[i] == zbuffer[i]) {
480 zbuffer[i] = z[i];
481 passed++;
482 }
483 else {
484 mask[i] = 0;
485 }
486 }
487 }
488 }
489 else {
490 /* Don't update Z buffer */
491 GLuint i;
492 for (i=0;i<n;i++) {
493 if (mask[i]) {
494 if (z[i] == zbuffer[i]) {
495 /* pass */
496 passed++;
497 }
498 else {
499 mask[i] = 0;
500 }
501 }
502 }
503 }
504 break;
505 case GL_ALWAYS:
506 if (ctx->Depth.Mask) {
507 /* Update Z buffer */
508 GLuint i;
509 for (i=0;i<n;i++) {
510 if (mask[i]) {
511 zbuffer[i] = z[i];
512 passed++;
513 }
514 }
515 }
516 else {
517 /* Don't update Z buffer or mask */
518 passed = n;
519 }
520 break;
521 case GL_NEVER:
522 BZERO(mask, n * sizeof(GLubyte));
523 break;
524 default:
525 _mesa_problem(ctx, "Bad depth func in depth_test_span32");
526 }
527
528 return passed;
529 }
530
531
532
533 /*
534 * Apply depth test to span of fragments. Hardware or software z buffer.
535 */
536 static GLuint
537 depth_test_span( GLcontext *ctx, struct sw_span *span)
538 {
539 const GLint x = span->x;
540 const GLint y = span->y;
541 const GLuint n = span->end;
542 SWcontext *swrast = SWRAST_CONTEXT(ctx);
543
544 ASSERT((span->arrayMask & SPAN_XY) == 0);
545 ASSERT(span->arrayMask & SPAN_Z);
546
547 if (swrast->Driver.ReadDepthSpan) {
548 /* hardware-based depth buffer */
549 GLdepth zbuffer[MAX_WIDTH];
550 GLuint passed;
551 (*swrast->Driver.ReadDepthSpan)(ctx, n, x, y, zbuffer);
552 passed = depth_test_span32(ctx, n, zbuffer, span->array->z,
553 span->array->mask);
554 ASSERT(swrast->Driver.WriteDepthSpan);
555 (*swrast->Driver.WriteDepthSpan)(ctx, n, x, y, zbuffer,
556 span->array->mask);
557 if (passed < n)
558 span->writeAll = GL_FALSE;
559 return passed;
560 }
561 else {
562 GLuint passed;
563 /* software depth buffer */
564 if (ctx->Visual.depthBits <= 16) {
565 GLushort *zptr = (GLushort *) Z_ADDRESS16(ctx, x, y);
566 passed = depth_test_span16(ctx, n, zptr, span->array->z, span->array->mask);
567 }
568 else {
569 GLuint *zptr = (GLuint *) Z_ADDRESS32(ctx, x, y);
570 passed = depth_test_span32(ctx, n, zptr, span->array->z, span->array->mask);
571 }
572 #if 1
573 if (passed < span->end) {
574 span->writeAll = GL_FALSE;
575 }
576 #else
577 /* this causes a glDrawPixels(GL_DEPTH_COMPONENT) conformance failure */
578 if (passed < span->end) {
579 span->writeAll = GL_FALSE;
580 if (passed == 0) {
581 span->end = 0;
582 return 0;
583 }
584 while (span->end > 0 && span->mask[span->end - 1] == 0)
585 span->end --;
586 }
587 #endif
588 return passed;
589 }
590 }
591
592
593
594
595 /*
596 * Do depth testing for an array of fragments using software Z buffer.
597 */
598 static void
599 software_depth_test_pixels16( GLcontext *ctx, GLuint n,
600 const GLint x[], const GLint y[],
601 const GLdepth z[], GLubyte mask[] )
602 {
603 /* switch cases ordered from most frequent to less frequent */
604 switch (ctx->Depth.Func) {
605 case GL_LESS:
606 if (ctx->Depth.Mask) {
607 /* Update Z buffer */
608 GLuint i;
609 for (i=0; i<n; i++) {
610 if (mask[i]) {
611 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
612 if (z[i] < *zptr) {
613 /* pass */
614 *zptr = z[i];
615 }
616 else {
617 /* fail */
618 mask[i] = 0;
619 }
620 }
621 }
622 }
623 else {
624 /* Don't update Z buffer */
625 GLuint i;
626 for (i=0; i<n; i++) {
627 if (mask[i]) {
628 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
629 if (z[i] < *zptr) {
630 /* pass */
631 }
632 else {
633 /* fail */
634 mask[i] = 0;
635 }
636 }
637 }
638 }
639 break;
640 case GL_LEQUAL:
641 if (ctx->Depth.Mask) {
642 /* Update Z buffer */
643 GLuint i;
644 for (i=0; i<n; i++) {
645 if (mask[i]) {
646 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
647 if (z[i] <= *zptr) {
648 /* pass */
649 *zptr = z[i];
650 }
651 else {
652 /* fail */
653 mask[i] = 0;
654 }
655 }
656 }
657 }
658 else {
659 /* Don't update Z buffer */
660 GLuint i;
661 for (i=0; i<n; i++) {
662 if (mask[i]) {
663 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
664 if (z[i] <= *zptr) {
665 /* pass */
666 }
667 else {
668 /* fail */
669 mask[i] = 0;
670 }
671 }
672 }
673 }
674 break;
675 case GL_GEQUAL:
676 if (ctx->Depth.Mask) {
677 /* Update Z buffer */
678 GLuint i;
679 for (i=0; i<n; i++) {
680 if (mask[i]) {
681 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
682 if (z[i] >= *zptr) {
683 /* pass */
684 *zptr = z[i];
685 }
686 else {
687 /* fail */
688 mask[i] = 0;
689 }
690 }
691 }
692 }
693 else {
694 /* Don't update Z buffer */
695 GLuint i;
696 for (i=0; i<n; i++) {
697 if (mask[i]) {
698 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
699 if (z[i] >= *zptr) {
700 /* pass */
701 }
702 else {
703 /* fail */
704 mask[i] = 0;
705 }
706 }
707 }
708 }
709 break;
710 case GL_GREATER:
711 if (ctx->Depth.Mask) {
712 /* Update Z buffer */
713 GLuint i;
714 for (i=0; i<n; i++) {
715 if (mask[i]) {
716 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
717 if (z[i] > *zptr) {
718 /* pass */
719 *zptr = z[i];
720 }
721 else {
722 /* fail */
723 mask[i] = 0;
724 }
725 }
726 }
727 }
728 else {
729 /* Don't update Z buffer */
730 GLuint i;
731 for (i=0; i<n; i++) {
732 if (mask[i]) {
733 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
734 if (z[i] > *zptr) {
735 /* pass */
736 }
737 else {
738 /* fail */
739 mask[i] = 0;
740 }
741 }
742 }
743 }
744 break;
745 case GL_NOTEQUAL:
746 if (ctx->Depth.Mask) {
747 /* Update Z buffer */
748 GLuint i;
749 for (i=0; i<n; i++) {
750 if (mask[i]) {
751 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
752 if (z[i] != *zptr) {
753 /* pass */
754 *zptr = z[i];
755 }
756 else {
757 /* fail */
758 mask[i] = 0;
759 }
760 }
761 }
762 }
763 else {
764 /* Don't update Z buffer */
765 GLuint i;
766 for (i=0; i<n; i++) {
767 if (mask[i]) {
768 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
769 if (z[i] != *zptr) {
770 /* pass */
771 }
772 else {
773 /* fail */
774 mask[i] = 0;
775 }
776 }
777 }
778 }
779 break;
780 case GL_EQUAL:
781 if (ctx->Depth.Mask) {
782 /* Update Z buffer */
783 GLuint i;
784 for (i=0; i<n; i++) {
785 if (mask[i]) {
786 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
787 if (z[i] == *zptr) {
788 /* pass */
789 *zptr = z[i];
790 }
791 else {
792 /* fail */
793 mask[i] = 0;
794 }
795 }
796 }
797 }
798 else {
799 /* Don't update Z buffer */
800 GLuint i;
801 for (i=0; i<n; i++) {
802 if (mask[i]) {
803 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
804 if (z[i] == *zptr) {
805 /* pass */
806 }
807 else {
808 /* fail */
809 mask[i] = 0;
810 }
811 }
812 }
813 }
814 break;
815 case GL_ALWAYS:
816 if (ctx->Depth.Mask) {
817 /* Update Z buffer */
818 GLuint i;
819 for (i=0; i<n; i++) {
820 if (mask[i]) {
821 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
822 *zptr = z[i];
823 }
824 }
825 }
826 else {
827 /* Don't update Z buffer or mask */
828 }
829 break;
830 case GL_NEVER:
831 /* depth test never passes */
832 BZERO(mask, n * sizeof(GLubyte));
833 break;
834 default:
835 _mesa_problem(ctx, "Bad depth func in software_depth_test_pixels");
836 }
837 }
838
839
840
841 /*
842 * Do depth testing for an array of fragments using software Z buffer.
843 */
844 static void
845 software_depth_test_pixels32( GLcontext *ctx, GLuint n,
846 const GLint x[], const GLint y[],
847 const GLdepth z[], GLubyte mask[] )
848 {
849 /* switch cases ordered from most frequent to less frequent */
850 switch (ctx->Depth.Func) {
851 case GL_LESS:
852 if (ctx->Depth.Mask) {
853 /* Update Z buffer */
854 GLuint i;
855 for (i=0; i<n; i++) {
856 if (mask[i]) {
857 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
858 if (z[i] < *zptr) {
859 /* pass */
860 *zptr = z[i];
861 }
862 else {
863 /* fail */
864 mask[i] = 0;
865 }
866 }
867 }
868 }
869 else {
870 /* Don't update Z buffer */
871 GLuint i;
872 for (i=0; i<n; i++) {
873 if (mask[i]) {
874 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
875 if (z[i] < *zptr) {
876 /* pass */
877 }
878 else {
879 /* fail */
880 mask[i] = 0;
881 }
882 }
883 }
884 }
885 break;
886 case GL_LEQUAL:
887 if (ctx->Depth.Mask) {
888 /* Update Z buffer */
889 GLuint i;
890 for (i=0; i<n; i++) {
891 if (mask[i]) {
892 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
893 if (z[i] <= *zptr) {
894 /* pass */
895 *zptr = z[i];
896 }
897 else {
898 /* fail */
899 mask[i] = 0;
900 }
901 }
902 }
903 }
904 else {
905 /* Don't update Z buffer */
906 GLuint i;
907 for (i=0; i<n; i++) {
908 if (mask[i]) {
909 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
910 if (z[i] <= *zptr) {
911 /* pass */
912 }
913 else {
914 /* fail */
915 mask[i] = 0;
916 }
917 }
918 }
919 }
920 break;
921 case GL_GEQUAL:
922 if (ctx->Depth.Mask) {
923 /* Update Z buffer */
924 GLuint i;
925 for (i=0; i<n; i++) {
926 if (mask[i]) {
927 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
928 if (z[i] >= *zptr) {
929 /* pass */
930 *zptr = z[i];
931 }
932 else {
933 /* fail */
934 mask[i] = 0;
935 }
936 }
937 }
938 }
939 else {
940 /* Don't update Z buffer */
941 GLuint i;
942 for (i=0; i<n; i++) {
943 if (mask[i]) {
944 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
945 if (z[i] >= *zptr) {
946 /* pass */
947 }
948 else {
949 /* fail */
950 mask[i] = 0;
951 }
952 }
953 }
954 }
955 break;
956 case GL_GREATER:
957 if (ctx->Depth.Mask) {
958 /* Update Z buffer */
959 GLuint i;
960 for (i=0; i<n; i++) {
961 if (mask[i]) {
962 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
963 if (z[i] > *zptr) {
964 /* pass */
965 *zptr = z[i];
966 }
967 else {
968 /* fail */
969 mask[i] = 0;
970 }
971 }
972 }
973 }
974 else {
975 /* Don't update Z buffer */
976 GLuint i;
977 for (i=0; i<n; i++) {
978 if (mask[i]) {
979 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
980 if (z[i] > *zptr) {
981 /* pass */
982 }
983 else {
984 /* fail */
985 mask[i] = 0;
986 }
987 }
988 }
989 }
990 break;
991 case GL_NOTEQUAL:
992 if (ctx->Depth.Mask) {
993 /* Update Z buffer */
994 GLuint i;
995 for (i=0; i<n; i++) {
996 if (mask[i]) {
997 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
998 if (z[i] != *zptr) {
999 /* pass */
1000 *zptr = z[i];
1001 }
1002 else {
1003 /* fail */
1004 mask[i] = 0;
1005 }
1006 }
1007 }
1008 }
1009 else {
1010 /* Don't update Z buffer */
1011 GLuint i;
1012 for (i=0; i<n; i++) {
1013 if (mask[i]) {
1014 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
1015 if (z[i] != *zptr) {
1016 /* pass */
1017 }
1018 else {
1019 /* fail */
1020 mask[i] = 0;
1021 }
1022 }
1023 }
1024 }
1025 break;
1026 case GL_EQUAL:
1027 if (ctx->Depth.Mask) {
1028 /* Update Z buffer */
1029 GLuint i;
1030 for (i=0; i<n; i++) {
1031 if (mask[i]) {
1032 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
1033 if (z[i] == *zptr) {
1034 /* pass */
1035 *zptr = z[i];
1036 }
1037 else {
1038 /* fail */
1039 mask[i] = 0;
1040 }
1041 }
1042 }
1043 }
1044 else {
1045 /* Don't update Z buffer */
1046 GLuint i;
1047 for (i=0; i<n; i++) {
1048 if (mask[i]) {
1049 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
1050 if (z[i] == *zptr) {
1051 /* pass */
1052 }
1053 else {
1054 /* fail */
1055 mask[i] = 0;
1056 }
1057 }
1058 }
1059 }
1060 break;
1061 case GL_ALWAYS:
1062 if (ctx->Depth.Mask) {
1063 /* Update Z buffer */
1064 GLuint i;
1065 for (i=0; i<n; i++) {
1066 if (mask[i]) {
1067 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
1068 *zptr = z[i];
1069 }
1070 }
1071 }
1072 else {
1073 /* Don't update Z buffer or mask */
1074 }
1075 break;
1076 case GL_NEVER:
1077 /* depth test never passes */
1078 BZERO(mask, n * sizeof(GLubyte));
1079 break;
1080 default:
1081 _mesa_problem(ctx, "Bad depth func in software_depth_test_pixels");
1082 }
1083 }
1084
1085
1086
1087 /*
1088 * Do depth testing for an array of pixels using hardware Z buffer.
1089 * Input/output: zbuffer - array of depth values from Z buffer
1090 * Input: z - array of fragment z values.
1091 */
1092 static void
1093 hardware_depth_test_pixels( GLcontext *ctx, GLuint n, GLdepth zbuffer[],
1094 const GLdepth z[], GLubyte mask[] )
1095 {
1096 /* switch cases ordered from most frequent to less frequent */
1097 switch (ctx->Depth.Func) {
1098 case GL_LESS:
1099 if (ctx->Depth.Mask) {
1100 /* Update Z buffer */
1101 GLuint i;
1102 for (i=0; i<n; i++) {
1103 if (mask[i]) {
1104 if (z[i] < zbuffer[i]) {
1105 /* pass */
1106 zbuffer[i] = z[i];
1107 }
1108 else {
1109 /* fail */
1110 mask[i] = 0;
1111 }
1112 }
1113 }
1114 }
1115 else {
1116 /* Don't update Z buffer */
1117 GLuint i;
1118 for (i=0; i<n; i++) {
1119 if (mask[i]) {
1120 if (z[i] < zbuffer[i]) {
1121 /* pass */
1122 }
1123 else {
1124 /* fail */
1125 mask[i] = 0;
1126 }
1127 }
1128 }
1129 }
1130 break;
1131 case GL_LEQUAL:
1132 if (ctx->Depth.Mask) {
1133 /* Update Z buffer */
1134 GLuint i;
1135 for (i=0; i<n; i++) {
1136 if (mask[i]) {
1137 if (z[i] <= zbuffer[i]) {
1138 /* pass */
1139 zbuffer[i] = z[i];
1140 }
1141 else {
1142 /* fail */
1143 mask[i] = 0;
1144 }
1145 }
1146 }
1147 }
1148 else {
1149 /* Don't update Z buffer */
1150 GLuint i;
1151 for (i=0; i<n; i++) {
1152 if (mask[i]) {
1153 if (z[i] <= zbuffer[i]) {
1154 /* pass */
1155 }
1156 else {
1157 /* fail */
1158 mask[i] = 0;
1159 }
1160 }
1161 }
1162 }
1163 break;
1164 case GL_GEQUAL:
1165 if (ctx->Depth.Mask) {
1166 /* Update Z buffer */
1167 GLuint i;
1168 for (i=0; i<n; i++) {
1169 if (mask[i]) {
1170 if (z[i] >= zbuffer[i]) {
1171 /* pass */
1172 zbuffer[i] = z[i];
1173 }
1174 else {
1175 /* fail */
1176 mask[i] = 0;
1177 }
1178 }
1179 }
1180 }
1181 else {
1182 /* Don't update Z buffer */
1183 GLuint i;
1184 for (i=0; i<n; i++) {
1185 if (mask[i]) {
1186 if (z[i] >= zbuffer[i]) {
1187 /* pass */
1188 }
1189 else {
1190 /* fail */
1191 mask[i] = 0;
1192 }
1193 }
1194 }
1195 }
1196 break;
1197 case GL_GREATER:
1198 if (ctx->Depth.Mask) {
1199 /* Update Z buffer */
1200 GLuint i;
1201 for (i=0; i<n; i++) {
1202 if (mask[i]) {
1203 if (z[i] > zbuffer[i]) {
1204 /* pass */
1205 zbuffer[i] = z[i];
1206 }
1207 else {
1208 /* fail */
1209 mask[i] = 0;
1210 }
1211 }
1212 }
1213 }
1214 else {
1215 /* Don't update Z buffer */
1216 GLuint i;
1217 for (i=0; i<n; i++) {
1218 if (mask[i]) {
1219 if (z[i] > zbuffer[i]) {
1220 /* pass */
1221 }
1222 else {
1223 /* fail */
1224 mask[i] = 0;
1225 }
1226 }
1227 }
1228 }
1229 break;
1230 case GL_NOTEQUAL:
1231 if (ctx->Depth.Mask) {
1232 /* Update Z buffer */
1233 GLuint i;
1234 for (i=0; i<n; i++) {
1235 if (mask[i]) {
1236 if (z[i] != zbuffer[i]) {
1237 /* pass */
1238 zbuffer[i] = z[i];
1239 }
1240 else {
1241 /* fail */
1242 mask[i] = 0;
1243 }
1244 }
1245 }
1246 }
1247 else {
1248 /* Don't update Z buffer */
1249 GLuint i;
1250 for (i=0; i<n; i++) {
1251 if (mask[i]) {
1252 if (z[i] != zbuffer[i]) {
1253 /* pass */
1254 }
1255 else {
1256 /* fail */
1257 mask[i] = 0;
1258 }
1259 }
1260 }
1261 }
1262 break;
1263 case GL_EQUAL:
1264 if (ctx->Depth.Mask) {
1265 /* Update Z buffer */
1266 GLuint i;
1267 for (i=0; i<n; i++) {
1268 if (mask[i]) {
1269 if (z[i] == zbuffer[i]) {
1270 /* pass */
1271 zbuffer[i] = z[i];
1272 }
1273 else {
1274 /* fail */
1275 mask[i] = 0;
1276 }
1277 }
1278 }
1279 }
1280 else {
1281 /* Don't update Z buffer */
1282 GLuint i;
1283 for (i=0; i<n; i++) {
1284 if (mask[i]) {
1285 if (z[i] == zbuffer[i]) {
1286 /* pass */
1287 }
1288 else {
1289 /* fail */
1290 mask[i] = 0;
1291 }
1292 }
1293 }
1294 }
1295 break;
1296 case GL_ALWAYS:
1297 if (ctx->Depth.Mask) {
1298 /* Update Z buffer */
1299 GLuint i;
1300 for (i=0; i<n; i++) {
1301 if (mask[i]) {
1302 zbuffer[i] = z[i];
1303 }
1304 }
1305 }
1306 else {
1307 /* Don't update Z buffer or mask */
1308 }
1309 break;
1310 case GL_NEVER:
1311 /* depth test never passes */
1312 BZERO(mask, n * sizeof(GLubyte));
1313 break;
1314 default:
1315 _mesa_problem(ctx, "Bad depth func in hardware_depth_test_pixels");
1316 }
1317 }
1318
1319
1320
1321 static GLuint
1322 depth_test_pixels( GLcontext *ctx, struct sw_span *span )
1323 {
1324 SWcontext *swrast = SWRAST_CONTEXT(ctx);
1325 const GLuint n = span->end;
1326 const GLint *x = span->array->x;
1327 const GLint *y = span->array->y;
1328 const GLdepth *z = span->array->z;
1329 GLubyte *mask = span->array->mask;
1330
1331 if (swrast->Driver.ReadDepthPixels) {
1332 /* read depth values from hardware Z buffer */
1333 GLdepth zbuffer[MAX_WIDTH];
1334 (*swrast->Driver.ReadDepthPixels)(ctx, n, x, y, zbuffer);
1335
1336 hardware_depth_test_pixels( ctx, n, zbuffer, z, mask );
1337
1338 /* update hardware Z buffer with new values */
1339 assert(swrast->Driver.WriteDepthPixels);
1340 (*swrast->Driver.WriteDepthPixels)(ctx, n, x, y, zbuffer, mask );
1341 }
1342 else {
1343 /* software depth testing */
1344 if (ctx->Visual.depthBits <= 16)
1345 software_depth_test_pixels16(ctx, n, x, y, z, mask);
1346 else
1347 software_depth_test_pixels32(ctx, n, x, y, z, mask);
1348 }
1349 return n; /* not really correct, but OK */
1350 }
1351
1352
1353 /**
1354 * Apply depth (Z) buffer testing to the span.
1355 * \return approx number of pixels that passed (only zero is reliable)
1356 */
1357 GLuint
1358 _mesa_depth_test_span( GLcontext *ctx, struct sw_span *span)
1359 {
1360 if (span->arrayMask & SPAN_XY)
1361 return depth_test_pixels(ctx, span);
1362 else
1363 return depth_test_span(ctx, span);
1364 }
1365
1366
1367
1368 /**********************************************************************/
1369 /***** Read Depth Buffer *****/
1370 /**********************************************************************/
1371
1372
1373 /**
1374 * Read a span of depth values from the depth buffer.
1375 * This function does clipping before calling the device driver function.
1376 */
1377 void
1378 _mesa_read_depth_span( GLcontext *ctx,
1379 GLint n, GLint x, GLint y, GLdepth depth[] )
1380 {
1381 SWcontext *swrast = SWRAST_CONTEXT(ctx);
1382
1383 if (y < 0 || y >= (GLint) ctx->DrawBuffer->Height ||
1384 x + (GLint) n <= 0 || x >= (GLint) ctx->DrawBuffer->Width) {
1385 /* span is completely outside framebuffer */
1386 GLint i;
1387 for (i = 0; i < n; i++)
1388 depth[i] = 0;
1389 return;
1390 }
1391
1392 if (x < 0) {
1393 GLint dx = -x;
1394 GLint i;
1395 for (i = 0; i < dx; i++)
1396 depth[i] = 0;
1397 x = 0;
1398 n -= dx;
1399 depth += dx;
1400 }
1401 if (x + n > (GLint) ctx->DrawBuffer->Width) {
1402 GLint dx = x + n - (GLint) ctx->DrawBuffer->Width;
1403 GLint i;
1404 for (i = 0; i < dx; i++)
1405 depth[n - i - 1] = 0;
1406 n -= dx;
1407 }
1408 if (n <= 0) {
1409 return;
1410 }
1411
1412 if (ctx->DrawBuffer->DepthBuffer) {
1413 /* read from software depth buffer */
1414 if (ctx->Visual.depthBits <= 16) {
1415 const GLushort *zptr = Z_ADDRESS16( ctx, x, y );
1416 GLint i;
1417 for (i = 0; i < n; i++) {
1418 depth[i] = zptr[i];
1419 }
1420 }
1421 else {
1422 const GLuint *zptr = Z_ADDRESS32( ctx, x, y );
1423 GLint i;
1424 for (i = 0; i < n; i++) {
1425 depth[i] = zptr[i];
1426 }
1427 }
1428 }
1429 else if (swrast->Driver.ReadDepthSpan) {
1430 /* read from hardware depth buffer */
1431 (*swrast->Driver.ReadDepthSpan)( ctx, n, x, y, depth );
1432 }
1433 else {
1434 /* no depth buffer */
1435 BZERO(depth, n * sizeof(GLfloat));
1436 }
1437
1438 }
1439
1440
1441
1442
1443 /**
1444 * Return a span of depth values from the depth buffer as floats in [0,1].
1445 * This is used for both hardware and software depth buffers.
1446 * Input: n - how many pixels
1447 * x,y - location of first pixel
1448 * Output: depth - the array of depth values
1449 */
1450 void
1451 _mesa_read_depth_span_float( GLcontext *ctx,
1452 GLint n, GLint x, GLint y, GLfloat depth[] )
1453 {
1454 SWcontext *swrast = SWRAST_CONTEXT(ctx);
1455 const GLfloat scale = 1.0F / ctx->DepthMaxF;
1456
1457 if (y < 0 || y >= (GLint) ctx->DrawBuffer->Height ||
1458 x + (GLint) n <= 0 || x >= (GLint) ctx->DrawBuffer->Width) {
1459 /* span is completely outside framebuffer */
1460 GLint i;
1461 for (i = 0; i < n; i++)
1462 depth[i] = 0.0F;
1463 return;
1464 }
1465
1466 if (x < 0) {
1467 GLint dx = -x;
1468 GLint i;
1469 for (i = 0; i < dx; i++)
1470 depth[i] = 0.0F;
1471 n -= dx;
1472 x = 0;
1473 }
1474 if (x + n > (GLint) ctx->DrawBuffer->Width) {
1475 GLint dx = x + n - (GLint) ctx->DrawBuffer->Width;
1476 GLint i;
1477 for (i = 0; i < dx; i++)
1478 depth[n - i - 1] = 0.0F;
1479 n -= dx;
1480 }
1481 if (n <= 0) {
1482 return;
1483 }
1484
1485 if (ctx->DrawBuffer->DepthBuffer) {
1486 /* read from software depth buffer */
1487 if (ctx->Visual.depthBits <= 16) {
1488 const GLushort *zptr = Z_ADDRESS16( ctx, x, y );
1489 GLint i;
1490 for (i = 0; i < n; i++) {
1491 depth[i] = (GLfloat) zptr[i] * scale;
1492 }
1493 }
1494 else {
1495 const GLuint *zptr = Z_ADDRESS32( ctx, x, y );
1496 GLint i;
1497 for (i = 0; i < n; i++) {
1498 depth[i] = (GLfloat) zptr[i] * scale;
1499 }
1500 }
1501 }
1502 else if (swrast->Driver.ReadDepthSpan) {
1503 /* read from hardware depth buffer */
1504 GLdepth d[MAX_WIDTH];
1505 GLint i;
1506 assert(n <= MAX_WIDTH);
1507 (*swrast->Driver.ReadDepthSpan)( ctx, n, x, y, d );
1508 for (i = 0; i < n; i++) {
1509 depth[i] = d[i] * scale;
1510 }
1511 }
1512 else {
1513 /* no depth buffer */
1514 BZERO(depth, n * sizeof(GLfloat));
1515 }
1516 }
1517
1518
1519
1520 /**********************************************************************/
1521 /***** Allocate and Clear Depth Buffer *****/
1522 /**********************************************************************/
1523
1524
1525
1526 /**
1527 * Allocate a new depth buffer. If there's already a depth buffer allocated
1528 * it will be free()'d. The new depth buffer will be uniniitalized.
1529 * This function is only called through Driver.alloc_depth_buffer.
1530 */
1531 void
1532 _mesa_alloc_depth_buffer( GLframebuffer *buffer )
1533 {
1534 GLint bytesPerValue;
1535
1536 ASSERT(buffer->UseSoftwareDepthBuffer);
1537
1538 /* deallocate current depth buffer if present */
1539 if (buffer->DepthBuffer) {
1540 MESA_PBUFFER_FREE(buffer->DepthBuffer);
1541 buffer->DepthBuffer = NULL;
1542 }
1543
1544 /* allocate new depth buffer, but don't initialize it */
1545 if (buffer->Visual.depthBits <= 16)
1546 bytesPerValue = sizeof(GLushort);
1547 else
1548 bytesPerValue = sizeof(GLuint);
1549
1550 buffer->DepthBuffer = MESA_PBUFFER_ALLOC(buffer->Width * buffer->Height
1551 * bytesPerValue);
1552
1553 if (!buffer->DepthBuffer) {
1554 /* out of memory */
1555 GET_CURRENT_CONTEXT(ctx);
1556 if (ctx) {
1557 ctx->Depth.Test = GL_FALSE;
1558 ctx->NewState |= _NEW_DEPTH;
1559 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Couldn't allocate depth buffer");
1560 }
1561 }
1562 }
1563
1564
1565 /**
1566 * Clear the depth buffer. If the depth buffer doesn't exist yet we'll
1567 * allocate it now.
1568 * This function is only called through Driver.clear_depth_buffer.
1569 */
1570 void
1571 _mesa_clear_depth_buffer( GLcontext *ctx )
1572 {
1573 if (ctx->Visual.depthBits == 0
1574 || !ctx->DrawBuffer->DepthBuffer
1575 || !ctx->Depth.Mask) {
1576 /* no depth buffer, or writing to it is disabled */
1577 return;
1578 }
1579
1580 /* The loops in this function have been written so the IRIX 5.3
1581 * C compiler can unroll them. Hopefully other compilers can too!
1582 */
1583
1584 if (ctx->Scissor.Enabled) {
1585 /* only clear scissor region */
1586 if (ctx->Visual.depthBits <= 16) {
1587 const GLushort clearValue = (GLushort) (ctx->Depth.Clear * ctx->DepthMax);
1588 const GLint rows = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin;
1589 const GLint cols = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin;
1590 const GLint rowStride = ctx->DrawBuffer->Width;
1591 GLushort *dRow = (GLushort *) ctx->DrawBuffer->DepthBuffer
1592 + ctx->DrawBuffer->_Ymin * rowStride + ctx->DrawBuffer->_Xmin;
1593 GLint i, j;
1594 for (i = 0; i < rows; i++) {
1595 for (j = 0; j < cols; j++) {
1596 dRow[j] = clearValue;
1597 }
1598 dRow += rowStride;
1599 }
1600 }
1601 else {
1602 const GLuint clearValue = (GLuint) (ctx->Depth.Clear * ctx->DepthMax);
1603 const GLint rows = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin;
1604 const GLint cols = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin;
1605 const GLint rowStride = ctx->DrawBuffer->Width;
1606 GLuint *dRow = (GLuint *) ctx->DrawBuffer->DepthBuffer
1607 + ctx->DrawBuffer->_Ymin * rowStride + ctx->DrawBuffer->_Xmin;
1608 GLint i, j;
1609 for (i = 0; i < rows; i++) {
1610 for (j = 0; j < cols; j++) {
1611 dRow[j] = clearValue;
1612 }
1613 dRow += rowStride;
1614 }
1615 }
1616 }
1617 else {
1618 /* clear whole buffer */
1619 if (ctx->Visual.depthBits <= 16) {
1620 const GLushort clearValue = (GLushort) (ctx->Depth.Clear * ctx->DepthMax);
1621 if ((clearValue & 0xff) == (clearValue >> 8)) {
1622 if (clearValue == 0) {
1623 BZERO(ctx->DrawBuffer->DepthBuffer,
1624 2*ctx->DrawBuffer->Width*ctx->DrawBuffer->Height);
1625 }
1626 else {
1627 /* lower and upper bytes of clear_value are same, use MEMSET */
1628 MEMSET( ctx->DrawBuffer->DepthBuffer, clearValue & 0xff,
1629 2 * ctx->DrawBuffer->Width * ctx->DrawBuffer->Height);
1630 }
1631 }
1632 else {
1633 GLushort *d = (GLushort *) ctx->DrawBuffer->DepthBuffer;
1634 GLint n = ctx->DrawBuffer->Width * ctx->DrawBuffer->Height;
1635 while (n >= 16) {
1636 d[0] = clearValue; d[1] = clearValue;
1637 d[2] = clearValue; d[3] = clearValue;
1638 d[4] = clearValue; d[5] = clearValue;
1639 d[6] = clearValue; d[7] = clearValue;
1640 d[8] = clearValue; d[9] = clearValue;
1641 d[10] = clearValue; d[11] = clearValue;
1642 d[12] = clearValue; d[13] = clearValue;
1643 d[14] = clearValue; d[15] = clearValue;
1644 d += 16;
1645 n -= 16;
1646 }
1647 while (n > 0) {
1648 *d++ = clearValue;
1649 n--;
1650 }
1651 }
1652 }
1653 else {
1654 /* >16 bit depth buffer */
1655 const GLuint clearValue = (GLuint) (ctx->Depth.Clear * ctx->DepthMax);
1656 if (clearValue == 0) {
1657 BZERO(ctx->DrawBuffer->DepthBuffer,
1658 ctx->DrawBuffer->Width*ctx->DrawBuffer->Height*sizeof(GLuint));
1659 }
1660 else {
1661 GLint n = ctx->DrawBuffer->Width * ctx->DrawBuffer->Height;
1662 GLuint *d = (GLuint *) ctx->DrawBuffer->DepthBuffer;
1663 while (n >= 16) {
1664 d[0] = clearValue; d[1] = clearValue;
1665 d[2] = clearValue; d[3] = clearValue;
1666 d[4] = clearValue; d[5] = clearValue;
1667 d[6] = clearValue; d[7] = clearValue;
1668 d[8] = clearValue; d[9] = clearValue;
1669 d[10] = clearValue; d[11] = clearValue;
1670 d[12] = clearValue; d[13] = clearValue;
1671 d[14] = clearValue; d[15] = clearValue;
1672 d += 16;
1673 n -= 16;
1674 }
1675 while (n > 0) {
1676 *d++ = clearValue;
1677 n--;
1678 }
1679 }
1680 }
1681 }
1682 }