Use MESA_PBUFFER_ALLOC/FREE macros to allocate all framebuffer and texture
[mesa.git] / src / mesa / swrast / s_depth.c
1 /* $Id: s_depth.c,v 1.19 2002/03/19 16:47:05 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 "mem.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->zArray, span->mask);
553 ASSERT(swrast->Driver.WriteDepthSpan);
554 (*swrast->Driver.WriteDepthSpan)(ctx, n, x, y, zbuffer, span->mask);
555 if (passed < n)
556 span->writeAll = GL_FALSE;
557 return passed;
558 }
559 else {
560 GLuint passed;
561 /* software depth buffer */
562 if (ctx->Visual.depthBits <= 16) {
563 GLushort *zptr = (GLushort *) Z_ADDRESS16(ctx, x, y);
564 passed = depth_test_span16(ctx, n, zptr, span->zArray, span->mask);
565 }
566 else {
567 GLuint *zptr = (GLuint *) Z_ADDRESS32(ctx, x, y);
568 passed = depth_test_span32(ctx, n, zptr, span->zArray, span->mask);
569 }
570 if (passed < span->end)
571 span->writeAll = GL_FALSE;
572 return passed;
573 }
574 }
575
576
577
578
579 /*
580 * Do depth testing for an array of fragments using software Z buffer.
581 */
582 static void
583 software_depth_test_pixels16( GLcontext *ctx, GLuint n,
584 const GLint x[], const GLint y[],
585 const GLdepth z[], GLubyte mask[] )
586 {
587 /* switch cases ordered from most frequent to less frequent */
588 switch (ctx->Depth.Func) {
589 case GL_LESS:
590 if (ctx->Depth.Mask) {
591 /* Update Z buffer */
592 GLuint i;
593 for (i=0; i<n; i++) {
594 if (mask[i]) {
595 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
596 if (z[i] < *zptr) {
597 /* pass */
598 *zptr = z[i];
599 }
600 else {
601 /* fail */
602 mask[i] = 0;
603 }
604 }
605 }
606 }
607 else {
608 /* Don't update Z buffer */
609 GLuint i;
610 for (i=0; i<n; i++) {
611 if (mask[i]) {
612 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
613 if (z[i] < *zptr) {
614 /* pass */
615 }
616 else {
617 /* fail */
618 mask[i] = 0;
619 }
620 }
621 }
622 }
623 break;
624 case GL_LEQUAL:
625 if (ctx->Depth.Mask) {
626 /* Update Z buffer */
627 GLuint i;
628 for (i=0; i<n; i++) {
629 if (mask[i]) {
630 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
631 if (z[i] <= *zptr) {
632 /* pass */
633 *zptr = z[i];
634 }
635 else {
636 /* fail */
637 mask[i] = 0;
638 }
639 }
640 }
641 }
642 else {
643 /* Don't update Z buffer */
644 GLuint i;
645 for (i=0; i<n; i++) {
646 if (mask[i]) {
647 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
648 if (z[i] <= *zptr) {
649 /* pass */
650 }
651 else {
652 /* fail */
653 mask[i] = 0;
654 }
655 }
656 }
657 }
658 break;
659 case GL_GEQUAL:
660 if (ctx->Depth.Mask) {
661 /* Update Z buffer */
662 GLuint i;
663 for (i=0; i<n; i++) {
664 if (mask[i]) {
665 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
666 if (z[i] >= *zptr) {
667 /* pass */
668 *zptr = z[i];
669 }
670 else {
671 /* fail */
672 mask[i] = 0;
673 }
674 }
675 }
676 }
677 else {
678 /* Don't update Z buffer */
679 GLuint i;
680 for (i=0; i<n; i++) {
681 if (mask[i]) {
682 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
683 if (z[i] >= *zptr) {
684 /* pass */
685 }
686 else {
687 /* fail */
688 mask[i] = 0;
689 }
690 }
691 }
692 }
693 break;
694 case GL_GREATER:
695 if (ctx->Depth.Mask) {
696 /* Update Z buffer */
697 GLuint i;
698 for (i=0; i<n; i++) {
699 if (mask[i]) {
700 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
701 if (z[i] > *zptr) {
702 /* pass */
703 *zptr = z[i];
704 }
705 else {
706 /* fail */
707 mask[i] = 0;
708 }
709 }
710 }
711 }
712 else {
713 /* Don't update Z buffer */
714 GLuint i;
715 for (i=0; i<n; i++) {
716 if (mask[i]) {
717 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
718 if (z[i] > *zptr) {
719 /* pass */
720 }
721 else {
722 /* fail */
723 mask[i] = 0;
724 }
725 }
726 }
727 }
728 break;
729 case GL_NOTEQUAL:
730 if (ctx->Depth.Mask) {
731 /* Update Z buffer */
732 GLuint i;
733 for (i=0; i<n; i++) {
734 if (mask[i]) {
735 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
736 if (z[i] != *zptr) {
737 /* pass */
738 *zptr = z[i];
739 }
740 else {
741 /* fail */
742 mask[i] = 0;
743 }
744 }
745 }
746 }
747 else {
748 /* Don't update Z buffer */
749 GLuint i;
750 for (i=0; i<n; i++) {
751 if (mask[i]) {
752 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
753 if (z[i] != *zptr) {
754 /* pass */
755 }
756 else {
757 /* fail */
758 mask[i] = 0;
759 }
760 }
761 }
762 }
763 break;
764 case GL_EQUAL:
765 if (ctx->Depth.Mask) {
766 /* Update Z buffer */
767 GLuint i;
768 for (i=0; i<n; i++) {
769 if (mask[i]) {
770 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
771 if (z[i] == *zptr) {
772 /* pass */
773 *zptr = z[i];
774 }
775 else {
776 /* fail */
777 mask[i] = 0;
778 }
779 }
780 }
781 }
782 else {
783 /* Don't update Z buffer */
784 GLuint i;
785 for (i=0; i<n; i++) {
786 if (mask[i]) {
787 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
788 if (z[i] == *zptr) {
789 /* pass */
790 }
791 else {
792 /* fail */
793 mask[i] = 0;
794 }
795 }
796 }
797 }
798 break;
799 case GL_ALWAYS:
800 if (ctx->Depth.Mask) {
801 /* Update Z buffer */
802 GLuint i;
803 for (i=0; i<n; i++) {
804 if (mask[i]) {
805 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
806 *zptr = z[i];
807 }
808 }
809 }
810 else {
811 /* Don't update Z buffer or mask */
812 }
813 break;
814 case GL_NEVER:
815 /* depth test never passes */
816 BZERO(mask, n * sizeof(GLubyte));
817 break;
818 default:
819 _mesa_problem(ctx, "Bad depth func in software_depth_test_pixels");
820 }
821 }
822
823
824
825 /*
826 * Do depth testing for an array of fragments using software Z buffer.
827 */
828 static void
829 software_depth_test_pixels32( GLcontext *ctx, GLuint n,
830 const GLint x[], const GLint y[],
831 const GLdepth z[], GLubyte mask[] )
832 {
833 /* switch cases ordered from most frequent to less frequent */
834 switch (ctx->Depth.Func) {
835 case GL_LESS:
836 if (ctx->Depth.Mask) {
837 /* Update Z buffer */
838 GLuint i;
839 for (i=0; i<n; i++) {
840 if (mask[i]) {
841 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
842 if (z[i] < *zptr) {
843 /* pass */
844 *zptr = z[i];
845 }
846 else {
847 /* fail */
848 mask[i] = 0;
849 }
850 }
851 }
852 }
853 else {
854 /* Don't update Z buffer */
855 GLuint i;
856 for (i=0; i<n; i++) {
857 if (mask[i]) {
858 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
859 if (z[i] < *zptr) {
860 /* pass */
861 }
862 else {
863 /* fail */
864 mask[i] = 0;
865 }
866 }
867 }
868 }
869 break;
870 case GL_LEQUAL:
871 if (ctx->Depth.Mask) {
872 /* Update Z buffer */
873 GLuint i;
874 for (i=0; i<n; i++) {
875 if (mask[i]) {
876 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
877 if (z[i] <= *zptr) {
878 /* pass */
879 *zptr = z[i];
880 }
881 else {
882 /* fail */
883 mask[i] = 0;
884 }
885 }
886 }
887 }
888 else {
889 /* Don't update Z buffer */
890 GLuint i;
891 for (i=0; i<n; i++) {
892 if (mask[i]) {
893 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
894 if (z[i] <= *zptr) {
895 /* pass */
896 }
897 else {
898 /* fail */
899 mask[i] = 0;
900 }
901 }
902 }
903 }
904 break;
905 case GL_GEQUAL:
906 if (ctx->Depth.Mask) {
907 /* Update Z buffer */
908 GLuint i;
909 for (i=0; i<n; i++) {
910 if (mask[i]) {
911 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
912 if (z[i] >= *zptr) {
913 /* pass */
914 *zptr = z[i];
915 }
916 else {
917 /* fail */
918 mask[i] = 0;
919 }
920 }
921 }
922 }
923 else {
924 /* Don't update Z buffer */
925 GLuint i;
926 for (i=0; i<n; i++) {
927 if (mask[i]) {
928 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
929 if (z[i] >= *zptr) {
930 /* pass */
931 }
932 else {
933 /* fail */
934 mask[i] = 0;
935 }
936 }
937 }
938 }
939 break;
940 case GL_GREATER:
941 if (ctx->Depth.Mask) {
942 /* Update Z buffer */
943 GLuint i;
944 for (i=0; i<n; i++) {
945 if (mask[i]) {
946 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
947 if (z[i] > *zptr) {
948 /* pass */
949 *zptr = z[i];
950 }
951 else {
952 /* fail */
953 mask[i] = 0;
954 }
955 }
956 }
957 }
958 else {
959 /* Don't update Z buffer */
960 GLuint i;
961 for (i=0; i<n; i++) {
962 if (mask[i]) {
963 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
964 if (z[i] > *zptr) {
965 /* pass */
966 }
967 else {
968 /* fail */
969 mask[i] = 0;
970 }
971 }
972 }
973 }
974 break;
975 case GL_NOTEQUAL:
976 if (ctx->Depth.Mask) {
977 /* Update Z buffer */
978 GLuint i;
979 for (i=0; i<n; i++) {
980 if (mask[i]) {
981 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
982 if (z[i] != *zptr) {
983 /* pass */
984 *zptr = z[i];
985 }
986 else {
987 /* fail */
988 mask[i] = 0;
989 }
990 }
991 }
992 }
993 else {
994 /* Don't update Z buffer */
995 GLuint i;
996 for (i=0; i<n; i++) {
997 if (mask[i]) {
998 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
999 if (z[i] != *zptr) {
1000 /* pass */
1001 }
1002 else {
1003 /* fail */
1004 mask[i] = 0;
1005 }
1006 }
1007 }
1008 }
1009 break;
1010 case GL_EQUAL:
1011 if (ctx->Depth.Mask) {
1012 /* Update Z buffer */
1013 GLuint i;
1014 for (i=0; i<n; i++) {
1015 if (mask[i]) {
1016 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
1017 if (z[i] == *zptr) {
1018 /* pass */
1019 *zptr = z[i];
1020 }
1021 else {
1022 /* fail */
1023 mask[i] = 0;
1024 }
1025 }
1026 }
1027 }
1028 else {
1029 /* Don't update Z buffer */
1030 GLuint i;
1031 for (i=0; i<n; i++) {
1032 if (mask[i]) {
1033 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
1034 if (z[i] == *zptr) {
1035 /* pass */
1036 }
1037 else {
1038 /* fail */
1039 mask[i] = 0;
1040 }
1041 }
1042 }
1043 }
1044 break;
1045 case GL_ALWAYS:
1046 if (ctx->Depth.Mask) {
1047 /* Update Z buffer */
1048 GLuint i;
1049 for (i=0; i<n; i++) {
1050 if (mask[i]) {
1051 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
1052 *zptr = z[i];
1053 }
1054 }
1055 }
1056 else {
1057 /* Don't update Z buffer or mask */
1058 }
1059 break;
1060 case GL_NEVER:
1061 /* depth test never passes */
1062 BZERO(mask, n * sizeof(GLubyte));
1063 break;
1064 default:
1065 _mesa_problem(ctx, "Bad depth func in software_depth_test_pixels");
1066 }
1067 }
1068
1069
1070
1071 /*
1072 * Do depth testing for an array of pixels using hardware Z buffer.
1073 * Input/output: zbuffer - array of depth values from Z buffer
1074 * Input: z - array of fragment z values.
1075 */
1076 static void
1077 hardware_depth_test_pixels( GLcontext *ctx, GLuint n, GLdepth zbuffer[],
1078 const GLdepth z[], GLubyte mask[] )
1079 {
1080 /* switch cases ordered from most frequent to less frequent */
1081 switch (ctx->Depth.Func) {
1082 case GL_LESS:
1083 if (ctx->Depth.Mask) {
1084 /* Update Z buffer */
1085 GLuint i;
1086 for (i=0; i<n; i++) {
1087 if (mask[i]) {
1088 if (z[i] < zbuffer[i]) {
1089 /* pass */
1090 zbuffer[i] = z[i];
1091 }
1092 else {
1093 /* fail */
1094 mask[i] = 0;
1095 }
1096 }
1097 }
1098 }
1099 else {
1100 /* Don't 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 }
1107 else {
1108 /* fail */
1109 mask[i] = 0;
1110 }
1111 }
1112 }
1113 }
1114 break;
1115 case GL_LEQUAL:
1116 if (ctx->Depth.Mask) {
1117 /* Update Z buffer */
1118 GLuint i;
1119 for (i=0; i<n; i++) {
1120 if (mask[i]) {
1121 if (z[i] <= zbuffer[i]) {
1122 /* pass */
1123 zbuffer[i] = z[i];
1124 }
1125 else {
1126 /* fail */
1127 mask[i] = 0;
1128 }
1129 }
1130 }
1131 }
1132 else {
1133 /* Don't 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 }
1140 else {
1141 /* fail */
1142 mask[i] = 0;
1143 }
1144 }
1145 }
1146 }
1147 break;
1148 case GL_GEQUAL:
1149 if (ctx->Depth.Mask) {
1150 /* Update Z buffer */
1151 GLuint i;
1152 for (i=0; i<n; i++) {
1153 if (mask[i]) {
1154 if (z[i] >= zbuffer[i]) {
1155 /* pass */
1156 zbuffer[i] = z[i];
1157 }
1158 else {
1159 /* fail */
1160 mask[i] = 0;
1161 }
1162 }
1163 }
1164 }
1165 else {
1166 /* Don't 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 }
1173 else {
1174 /* fail */
1175 mask[i] = 0;
1176 }
1177 }
1178 }
1179 }
1180 break;
1181 case GL_GREATER:
1182 if (ctx->Depth.Mask) {
1183 /* Update Z buffer */
1184 GLuint i;
1185 for (i=0; i<n; i++) {
1186 if (mask[i]) {
1187 if (z[i] > zbuffer[i]) {
1188 /* pass */
1189 zbuffer[i] = z[i];
1190 }
1191 else {
1192 /* fail */
1193 mask[i] = 0;
1194 }
1195 }
1196 }
1197 }
1198 else {
1199 /* Don't 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 }
1206 else {
1207 /* fail */
1208 mask[i] = 0;
1209 }
1210 }
1211 }
1212 }
1213 break;
1214 case GL_NOTEQUAL:
1215 if (ctx->Depth.Mask) {
1216 /* Update Z buffer */
1217 GLuint i;
1218 for (i=0; i<n; i++) {
1219 if (mask[i]) {
1220 if (z[i] != zbuffer[i]) {
1221 /* pass */
1222 zbuffer[i] = z[i];
1223 }
1224 else {
1225 /* fail */
1226 mask[i] = 0;
1227 }
1228 }
1229 }
1230 }
1231 else {
1232 /* Don't 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 }
1239 else {
1240 /* fail */
1241 mask[i] = 0;
1242 }
1243 }
1244 }
1245 }
1246 break;
1247 case GL_EQUAL:
1248 if (ctx->Depth.Mask) {
1249 /* Update Z buffer */
1250 GLuint i;
1251 for (i=0; i<n; i++) {
1252 if (mask[i]) {
1253 if (z[i] == zbuffer[i]) {
1254 /* pass */
1255 zbuffer[i] = z[i];
1256 }
1257 else {
1258 /* fail */
1259 mask[i] = 0;
1260 }
1261 }
1262 }
1263 }
1264 else {
1265 /* Don't 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 }
1272 else {
1273 /* fail */
1274 mask[i] = 0;
1275 }
1276 }
1277 }
1278 }
1279 break;
1280 case GL_ALWAYS:
1281 if (ctx->Depth.Mask) {
1282 /* Update Z buffer */
1283 GLuint i;
1284 for (i=0; i<n; i++) {
1285 if (mask[i]) {
1286 zbuffer[i] = z[i];
1287 }
1288 }
1289 }
1290 else {
1291 /* Don't update Z buffer or mask */
1292 }
1293 break;
1294 case GL_NEVER:
1295 /* depth test never passes */
1296 BZERO(mask, n * sizeof(GLubyte));
1297 break;
1298 default:
1299 _mesa_problem(ctx, "Bad depth func in hardware_depth_test_pixels");
1300 }
1301 }
1302
1303
1304
1305 static GLuint
1306 depth_test_pixels( GLcontext *ctx, struct sw_span *span )
1307 {
1308 SWcontext *swrast = SWRAST_CONTEXT(ctx);
1309 const GLuint n = span->end;
1310 const GLint *x = span->xArray;
1311 const GLint *y = span->yArray;
1312 const GLdepth *z = span->zArray;
1313 GLubyte *mask = span->mask;
1314
1315 if (swrast->Driver.ReadDepthPixels) {
1316 /* read depth values from hardware Z buffer */
1317 GLdepth zbuffer[MAX_WIDTH];
1318 (*swrast->Driver.ReadDepthPixels)(ctx, n, x, y, zbuffer);
1319
1320 hardware_depth_test_pixels( ctx, n, zbuffer, z, mask );
1321
1322 /* update hardware Z buffer with new values */
1323 assert(swrast->Driver.WriteDepthPixels);
1324 (*swrast->Driver.WriteDepthPixels)(ctx, n, x, y, zbuffer, mask );
1325 }
1326 else {
1327 /* software depth testing */
1328 if (ctx->Visual.depthBits <= 16)
1329 software_depth_test_pixels16(ctx, n, x, y, z, mask);
1330 else
1331 software_depth_test_pixels32(ctx, n, x, y, z, mask);
1332 }
1333 return n; /* not really correct, but OK */
1334 }
1335
1336
1337 /**
1338 * Apply depth (Z) buffer testing to the span.
1339 * \return approx number of pixels that passed (only zero is reliable)
1340 */
1341 GLuint
1342 _mesa_depth_test_span( GLcontext *ctx, struct sw_span *span)
1343 {
1344 if (span->arrayMask & SPAN_XY)
1345 return depth_test_pixels(ctx, span);
1346 else
1347 return depth_test_span(ctx, span);
1348 }
1349
1350
1351
1352 /**********************************************************************/
1353 /***** Read Depth Buffer *****/
1354 /**********************************************************************/
1355
1356
1357 /**
1358 * Read a span of depth values from the depth buffer.
1359 * This function does clipping before calling the device driver function.
1360 */
1361 void
1362 _mesa_read_depth_span( GLcontext *ctx,
1363 GLint n, GLint x, GLint y, GLdepth depth[] )
1364 {
1365 SWcontext *swrast = SWRAST_CONTEXT(ctx);
1366
1367 if (y < 0 || y >= ctx->DrawBuffer->Height ||
1368 x + (GLint) n <= 0 || x >= ctx->DrawBuffer->Width) {
1369 /* span is completely outside framebuffer */
1370 GLint i;
1371 for (i = 0; i < n; i++)
1372 depth[i] = 0;
1373 return;
1374 }
1375
1376 if (x < 0) {
1377 GLint dx = -x;
1378 GLint i;
1379 for (i = 0; i < dx; i++)
1380 depth[i] = 0;
1381 x = 0;
1382 n -= dx;
1383 depth += dx;
1384 }
1385 if (x + n > ctx->DrawBuffer->Width) {
1386 GLint dx = x + n - ctx->DrawBuffer->Width;
1387 GLint i;
1388 for (i = 0; i < dx; i++)
1389 depth[n - i - 1] = 0;
1390 n -= dx;
1391 }
1392 if (n <= 0) {
1393 return;
1394 }
1395
1396 if (ctx->DrawBuffer->DepthBuffer) {
1397 /* read from software depth buffer */
1398 if (ctx->Visual.depthBits <= 16) {
1399 const GLushort *zptr = Z_ADDRESS16( ctx, x, y );
1400 GLint i;
1401 for (i = 0; i < n; i++) {
1402 depth[i] = zptr[i];
1403 }
1404 }
1405 else {
1406 const GLuint *zptr = Z_ADDRESS32( ctx, x, y );
1407 GLint i;
1408 for (i = 0; i < n; i++) {
1409 depth[i] = zptr[i];
1410 }
1411 }
1412 }
1413 else if (swrast->Driver.ReadDepthSpan) {
1414 /* read from hardware depth buffer */
1415 (*swrast->Driver.ReadDepthSpan)( ctx, n, x, y, depth );
1416 }
1417 else {
1418 /* no depth buffer */
1419 BZERO(depth, n * sizeof(GLfloat));
1420 }
1421
1422 }
1423
1424
1425
1426
1427 /**
1428 * Return a span of depth values from the depth buffer as floats in [0,1].
1429 * This is used for both hardware and software depth buffers.
1430 * Input: n - how many pixels
1431 * x,y - location of first pixel
1432 * Output: depth - the array of depth values
1433 */
1434 void
1435 _mesa_read_depth_span_float( GLcontext *ctx,
1436 GLint n, GLint x, GLint y, GLfloat depth[] )
1437 {
1438 SWcontext *swrast = SWRAST_CONTEXT(ctx);
1439 const GLfloat scale = 1.0F / ctx->DepthMaxF;
1440
1441 if (y < 0 || y >= ctx->DrawBuffer->Height ||
1442 x + (GLint) n <= 0 || x >= ctx->DrawBuffer->Width) {
1443 /* span is completely outside framebuffer */
1444 GLint i;
1445 for (i = 0; i < n; i++)
1446 depth[i] = 0.0F;
1447 return;
1448 }
1449
1450 if (x < 0) {
1451 GLint dx = -x;
1452 GLint i;
1453 for (i = 0; i < dx; i++)
1454 depth[i] = 0.0F;
1455 n -= dx;
1456 x = 0;
1457 }
1458 if (x + n > ctx->DrawBuffer->Width) {
1459 GLint dx = x + n - ctx->DrawBuffer->Width;
1460 GLint i;
1461 for (i = 0; i < dx; i++)
1462 depth[n - i - 1] = 0.0F;
1463 n -= dx;
1464 }
1465 if (n <= 0) {
1466 return;
1467 }
1468
1469 if (ctx->DrawBuffer->DepthBuffer) {
1470 /* read from software depth buffer */
1471 if (ctx->Visual.depthBits <= 16) {
1472 const GLushort *zptr = Z_ADDRESS16( ctx, x, y );
1473 GLint i;
1474 for (i = 0; i < n; i++) {
1475 depth[i] = (GLfloat) zptr[i] * scale;
1476 }
1477 }
1478 else {
1479 const GLuint *zptr = Z_ADDRESS32( ctx, x, y );
1480 GLint i;
1481 for (i = 0; i < n; i++) {
1482 depth[i] = (GLfloat) zptr[i] * scale;
1483 }
1484 }
1485 }
1486 else if (swrast->Driver.ReadDepthSpan) {
1487 /* read from hardware depth buffer */
1488 GLdepth d[MAX_WIDTH];
1489 GLint i;
1490 assert(n <= MAX_WIDTH);
1491 (*swrast->Driver.ReadDepthSpan)( ctx, n, x, y, d );
1492 for (i = 0; i < n; i++) {
1493 depth[i] = d[i] * scale;
1494 }
1495 }
1496 else {
1497 /* no depth buffer */
1498 BZERO(depth, n * sizeof(GLfloat));
1499 }
1500 }
1501
1502
1503
1504 /**********************************************************************/
1505 /***** Allocate and Clear Depth Buffer *****/
1506 /**********************************************************************/
1507
1508
1509
1510 /**
1511 * Allocate a new depth buffer. If there's already a depth buffer allocated
1512 * it will be free()'d. The new depth buffer will be uniniitalized.
1513 * This function is only called through Driver.alloc_depth_buffer.
1514 */
1515 void
1516 _mesa_alloc_depth_buffer( GLframebuffer *buffer )
1517 {
1518 GLint bytesPerValue;
1519
1520 ASSERT(buffer->UseSoftwareDepthBuffer);
1521
1522 /* deallocate current depth buffer if present */
1523 if (buffer->DepthBuffer) {
1524 MESA_PBUFFER_FREE(buffer->DepthBuffer);
1525 buffer->DepthBuffer = NULL;
1526 }
1527
1528 /* allocate new depth buffer, but don't initialize it */
1529 if (buffer->Visual.depthBits <= 16)
1530 bytesPerValue = sizeof(GLushort);
1531 else
1532 bytesPerValue = sizeof(GLuint);
1533
1534 buffer->DepthBuffer = MESA_PBUFFER_ALLOC(buffer->Width * buffer->Height
1535 * bytesPerValue);
1536
1537 if (!buffer->DepthBuffer) {
1538 /* out of memory */
1539 GET_CURRENT_CONTEXT(ctx);
1540 if (ctx) {
1541 ctx->Depth.Test = GL_FALSE;
1542 ctx->NewState |= _NEW_DEPTH;
1543 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Couldn't allocate depth buffer");
1544 }
1545 }
1546 }
1547
1548
1549 /**
1550 * Clear the depth buffer. If the depth buffer doesn't exist yet we'll
1551 * allocate it now.
1552 * This function is only called through Driver.clear_depth_buffer.
1553 */
1554 void
1555 _mesa_clear_depth_buffer( GLcontext *ctx )
1556 {
1557 if (ctx->Visual.depthBits == 0
1558 || !ctx->DrawBuffer->DepthBuffer
1559 || !ctx->Depth.Mask) {
1560 /* no depth buffer, or writing to it is disabled */
1561 return;
1562 }
1563
1564 /* The loops in this function have been written so the IRIX 5.3
1565 * C compiler can unroll them. Hopefully other compilers can too!
1566 */
1567
1568 if (ctx->Scissor.Enabled) {
1569 /* only clear scissor region */
1570 if (ctx->Visual.depthBits <= 16) {
1571 const GLushort clearValue = (GLushort) (ctx->Depth.Clear * ctx->DepthMax);
1572 const GLint rows = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin;
1573 const GLint cols = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin;
1574 const GLint rowStride = ctx->DrawBuffer->Width;
1575 GLushort *dRow = (GLushort *) ctx->DrawBuffer->DepthBuffer
1576 + ctx->DrawBuffer->_Ymin * rowStride + ctx->DrawBuffer->_Xmin;
1577 GLint i, j;
1578 for (i = 0; i < rows; i++) {
1579 for (j = 0; j < cols; j++) {
1580 dRow[j] = clearValue;
1581 }
1582 dRow += rowStride;
1583 }
1584 }
1585 else {
1586 const GLuint clearValue = (GLuint) (ctx->Depth.Clear * ctx->DepthMax);
1587 const GLint rows = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin;
1588 const GLint cols = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin;
1589 const GLint rowStride = ctx->DrawBuffer->Width;
1590 GLuint *dRow = (GLuint *) ctx->DrawBuffer->DepthBuffer
1591 + ctx->DrawBuffer->_Ymin * rowStride + ctx->DrawBuffer->_Xmin;
1592 GLint i, j;
1593 for (i = 0; i < rows; i++) {
1594 for (j = 0; j < cols; j++) {
1595 dRow[j] = clearValue;
1596 }
1597 dRow += rowStride;
1598 }
1599 }
1600 }
1601 else {
1602 /* clear whole buffer */
1603 if (ctx->Visual.depthBits <= 16) {
1604 const GLushort clearValue = (GLushort) (ctx->Depth.Clear * ctx->DepthMax);
1605 if ((clearValue & 0xff) == (clearValue >> 8)) {
1606 if (clearValue == 0) {
1607 BZERO(ctx->DrawBuffer->DepthBuffer,
1608 2*ctx->DrawBuffer->Width*ctx->DrawBuffer->Height);
1609 }
1610 else {
1611 /* lower and upper bytes of clear_value are same, use MEMSET */
1612 MEMSET( ctx->DrawBuffer->DepthBuffer, clearValue & 0xff,
1613 2 * ctx->DrawBuffer->Width * ctx->DrawBuffer->Height);
1614 }
1615 }
1616 else {
1617 GLushort *d = (GLushort *) ctx->DrawBuffer->DepthBuffer;
1618 GLint n = ctx->DrawBuffer->Width * ctx->DrawBuffer->Height;
1619 while (n >= 16) {
1620 d[0] = clearValue; d[1] = clearValue;
1621 d[2] = clearValue; d[3] = clearValue;
1622 d[4] = clearValue; d[5] = clearValue;
1623 d[6] = clearValue; d[7] = clearValue;
1624 d[8] = clearValue; d[9] = clearValue;
1625 d[10] = clearValue; d[11] = clearValue;
1626 d[12] = clearValue; d[13] = clearValue;
1627 d[14] = clearValue; d[15] = clearValue;
1628 d += 16;
1629 n -= 16;
1630 }
1631 while (n > 0) {
1632 *d++ = clearValue;
1633 n--;
1634 }
1635 }
1636 }
1637 else {
1638 /* >16 bit depth buffer */
1639 const GLuint clearValue = (GLuint) (ctx->Depth.Clear * ctx->DepthMax);
1640 if (clearValue == 0) {
1641 BZERO(ctx->DrawBuffer->DepthBuffer,
1642 ctx->DrawBuffer->Width*ctx->DrawBuffer->Height*sizeof(GLuint));
1643 }
1644 else {
1645 GLint n = ctx->DrawBuffer->Width * ctx->DrawBuffer->Height;
1646 GLuint *d = (GLuint *) ctx->DrawBuffer->DepthBuffer;
1647 while (n >= 16) {
1648 d[0] = clearValue; d[1] = clearValue;
1649 d[2] = clearValue; d[3] = clearValue;
1650 d[4] = clearValue; d[5] = clearValue;
1651 d[6] = clearValue; d[7] = clearValue;
1652 d[8] = clearValue; d[9] = clearValue;
1653 d[10] = clearValue; d[11] = clearValue;
1654 d[12] = clearValue; d[13] = clearValue;
1655 d[14] = clearValue; d[15] = clearValue;
1656 d += 16;
1657 n -= 16;
1658 }
1659 while (n > 0) {
1660 *d++ = clearValue;
1661 n--;
1662 }
1663 }
1664 }
1665 }
1666 }