Merge branch 'gallium-noconstbuf'
[mesa.git] / src / mesa / swrast / s_depth.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 7.2.1
4 *
5 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25
26 #include "main/glheader.h"
27 #include "main/context.h"
28 #include "main/formats.h"
29 #include "main/macros.h"
30 #include "main/imports.h"
31
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 min, max;
509 GLfloat min_f, max_f;
510 int i;
511
512 if (ctx->Viewport.Near < ctx->Viewport.Far) {
513 min_f = ctx->Viewport.Near;
514 max_f = ctx->Viewport.Far;
515 } else {
516 min_f = ctx->Viewport.Far;
517 max_f = ctx->Viewport.Near;
518 }
519
520 if (rb->DataType == GL_UNSIGNED_SHORT) {
521 CLAMPED_FLOAT_TO_USHORT(min, min_f);
522 CLAMPED_FLOAT_TO_USHORT(max, max_f);
523 } else {
524 assert(rb->DataType == GL_UNSIGNED_INT);
525 min = FLOAT_TO_UINT(min_f);
526 max = FLOAT_TO_UINT(max_f);
527 }
528
529 for (i = 0; i < count; i++) {
530 if (zValues[i] < min)
531 zValues[i] = min;
532 if (zValues[i] > max)
533 zValues[i] = max;
534 }
535 }
536
537
538
539 /*
540 * Apply depth test to span of fragments.
541 */
542 static GLuint
543 depth_test_span( GLcontext *ctx, SWspan *span)
544 {
545 struct gl_framebuffer *fb = ctx->DrawBuffer;
546 struct gl_renderbuffer *rb = fb->_DepthBuffer;
547 const GLint x = span->x;
548 const GLint y = span->y;
549 const GLuint count = span->end;
550 const GLuint *zValues = span->array->z;
551 GLubyte *mask = span->array->mask;
552 GLuint passed;
553
554 ASSERT((span->arrayMask & SPAN_XY) == 0);
555 ASSERT(span->arrayMask & SPAN_Z);
556
557 if (rb->GetPointer(ctx, rb, 0, 0)) {
558 /* Directly access buffer */
559 if (rb->DataType == GL_UNSIGNED_SHORT) {
560 GLushort *zbuffer = (GLushort *) rb->GetPointer(ctx, rb, x, y);
561 passed = depth_test_span16(ctx, count, zbuffer, zValues, mask);
562 }
563 else {
564 GLuint *zbuffer = (GLuint *) rb->GetPointer(ctx, rb, x, y);
565 ASSERT(rb->DataType == GL_UNSIGNED_INT);
566 passed = depth_test_span32(ctx, count, zbuffer, zValues, mask);
567 }
568 }
569 else {
570 /* read depth values from buffer, test, write back */
571 if (rb->DataType == GL_UNSIGNED_SHORT) {
572 GLushort zbuffer[MAX_WIDTH];
573 rb->GetRow(ctx, rb, count, x, y, zbuffer);
574 passed = depth_test_span16(ctx, count, zbuffer, zValues, mask);
575 rb->PutRow(ctx, rb, count, x, y, zbuffer, mask);
576 }
577 else {
578 GLuint zbuffer[MAX_WIDTH];
579 ASSERT(rb->DataType == GL_UNSIGNED_INT);
580 rb->GetRow(ctx, rb, count, x, y, zbuffer);
581 passed = depth_test_span32(ctx, count, zbuffer, zValues, mask);
582 rb->PutRow(ctx, rb, count, x, y, zbuffer, mask);
583 }
584 }
585
586 if (passed < count) {
587 span->writeAll = GL_FALSE;
588 }
589 return passed;
590 }
591
592
593
594 #define Z_ADDRESS(X, Y) (zStart + (Y) * stride + (X))
595
596
597 /*
598 * Do depth testing for an array of fragments at assorted locations.
599 */
600 static void
601 direct_depth_test_pixels16(GLcontext *ctx, GLushort *zStart, GLuint stride,
602 GLuint n, const GLint x[], const GLint y[],
603 const GLuint z[], GLubyte mask[] )
604 {
605 /* switch cases ordered from most frequent to less frequent */
606 switch (ctx->Depth.Func) {
607 case GL_LESS:
608 if (ctx->Depth.Mask) {
609 /* Update Z buffer */
610 GLuint i;
611 for (i=0; i<n; i++) {
612 if (mask[i]) {
613 GLushort *zptr = Z_ADDRESS(x[i], y[i]);
614 if (z[i] < *zptr) {
615 /* pass */
616 *zptr = z[i];
617 }
618 else {
619 /* fail */
620 mask[i] = 0;
621 }
622 }
623 }
624 }
625 else {
626 /* Don't update Z buffer */
627 GLuint i;
628 for (i=0; i<n; i++) {
629 if (mask[i]) {
630 GLushort *zptr = Z_ADDRESS(x[i], y[i]);
631 if (z[i] < *zptr) {
632 /* pass */
633 }
634 else {
635 /* fail */
636 mask[i] = 0;
637 }
638 }
639 }
640 }
641 break;
642 case GL_LEQUAL:
643 if (ctx->Depth.Mask) {
644 /* Update Z buffer */
645 GLuint i;
646 for (i=0; i<n; i++) {
647 if (mask[i]) {
648 GLushort *zptr = Z_ADDRESS(x[i], y[i]);
649 if (z[i] <= *zptr) {
650 /* pass */
651 *zptr = z[i];
652 }
653 else {
654 /* fail */
655 mask[i] = 0;
656 }
657 }
658 }
659 }
660 else {
661 /* Don't update Z buffer */
662 GLuint i;
663 for (i=0; i<n; i++) {
664 if (mask[i]) {
665 GLushort *zptr = Z_ADDRESS(x[i], y[i]);
666 if (z[i] <= *zptr) {
667 /* pass */
668 }
669 else {
670 /* fail */
671 mask[i] = 0;
672 }
673 }
674 }
675 }
676 break;
677 case GL_GEQUAL:
678 if (ctx->Depth.Mask) {
679 /* Update Z buffer */
680 GLuint i;
681 for (i=0; i<n; i++) {
682 if (mask[i]) {
683 GLushort *zptr = Z_ADDRESS(x[i], y[i]);
684 if (z[i] >= *zptr) {
685 /* pass */
686 *zptr = z[i];
687 }
688 else {
689 /* fail */
690 mask[i] = 0;
691 }
692 }
693 }
694 }
695 else {
696 /* Don't update Z buffer */
697 GLuint i;
698 for (i=0; i<n; i++) {
699 if (mask[i]) {
700 GLushort *zptr = Z_ADDRESS(x[i], y[i]);
701 if (z[i] >= *zptr) {
702 /* pass */
703 }
704 else {
705 /* fail */
706 mask[i] = 0;
707 }
708 }
709 }
710 }
711 break;
712 case GL_GREATER:
713 if (ctx->Depth.Mask) {
714 /* Update Z buffer */
715 GLuint i;
716 for (i=0; i<n; i++) {
717 if (mask[i]) {
718 GLushort *zptr = Z_ADDRESS(x[i], y[i]);
719 if (z[i] > *zptr) {
720 /* pass */
721 *zptr = z[i];
722 }
723 else {
724 /* fail */
725 mask[i] = 0;
726 }
727 }
728 }
729 }
730 else {
731 /* Don't update Z buffer */
732 GLuint i;
733 for (i=0; i<n; i++) {
734 if (mask[i]) {
735 GLushort *zptr = Z_ADDRESS(x[i], y[i]);
736 if (z[i] > *zptr) {
737 /* pass */
738 }
739 else {
740 /* fail */
741 mask[i] = 0;
742 }
743 }
744 }
745 }
746 break;
747 case GL_NOTEQUAL:
748 if (ctx->Depth.Mask) {
749 /* Update Z buffer */
750 GLuint i;
751 for (i=0; i<n; i++) {
752 if (mask[i]) {
753 GLushort *zptr = Z_ADDRESS(x[i], y[i]);
754 if (z[i] != *zptr) {
755 /* pass */
756 *zptr = z[i];
757 }
758 else {
759 /* fail */
760 mask[i] = 0;
761 }
762 }
763 }
764 }
765 else {
766 /* Don't update Z buffer */
767 GLuint i;
768 for (i=0; i<n; i++) {
769 if (mask[i]) {
770 GLushort *zptr = Z_ADDRESS(x[i], y[i]);
771 if (z[i] != *zptr) {
772 /* pass */
773 }
774 else {
775 /* fail */
776 mask[i] = 0;
777 }
778 }
779 }
780 }
781 break;
782 case GL_EQUAL:
783 if (ctx->Depth.Mask) {
784 /* Update Z buffer */
785 GLuint i;
786 for (i=0; i<n; i++) {
787 if (mask[i]) {
788 GLushort *zptr = Z_ADDRESS(x[i], y[i]);
789 if (z[i] == *zptr) {
790 /* pass */
791 *zptr = z[i];
792 }
793 else {
794 /* fail */
795 mask[i] = 0;
796 }
797 }
798 }
799 }
800 else {
801 /* Don't update Z buffer */
802 GLuint i;
803 for (i=0; i<n; i++) {
804 if (mask[i]) {
805 GLushort *zptr = Z_ADDRESS(x[i], y[i]);
806 if (z[i] == *zptr) {
807 /* pass */
808 }
809 else {
810 /* fail */
811 mask[i] = 0;
812 }
813 }
814 }
815 }
816 break;
817 case GL_ALWAYS:
818 if (ctx->Depth.Mask) {
819 /* Update Z buffer */
820 GLuint i;
821 for (i=0; i<n; i++) {
822 if (mask[i]) {
823 GLushort *zptr = Z_ADDRESS(x[i], y[i]);
824 *zptr = z[i];
825 }
826 }
827 }
828 else {
829 /* Don't update Z buffer or mask */
830 }
831 break;
832 case GL_NEVER:
833 /* depth test never passes */
834 _mesa_bzero(mask, n * sizeof(GLubyte));
835 break;
836 default:
837 _mesa_problem(ctx, "Bad depth func in direct_depth_test_pixels");
838 }
839 }
840
841
842
843 /*
844 * Do depth testing for an array of fragments with direct access to zbuffer.
845 */
846 static void
847 direct_depth_test_pixels32(GLcontext *ctx, GLuint *zStart, GLuint stride,
848 GLuint n, const GLint x[], const GLint y[],
849 const GLuint z[], GLubyte mask[] )
850 {
851 /* switch cases ordered from most frequent to less frequent */
852 switch (ctx->Depth.Func) {
853 case GL_LESS:
854 if (ctx->Depth.Mask) {
855 /* Update Z buffer */
856 GLuint i;
857 for (i=0; i<n; i++) {
858 if (mask[i]) {
859 GLuint *zptr = Z_ADDRESS(x[i], y[i]);
860 if (z[i] < *zptr) {
861 /* pass */
862 *zptr = z[i];
863 }
864 else {
865 /* fail */
866 mask[i] = 0;
867 }
868 }
869 }
870 }
871 else {
872 /* Don't update Z buffer */
873 GLuint i;
874 for (i=0; i<n; i++) {
875 if (mask[i]) {
876 GLuint *zptr = Z_ADDRESS(x[i], y[i]);
877 if (z[i] < *zptr) {
878 /* pass */
879 }
880 else {
881 /* fail */
882 mask[i] = 0;
883 }
884 }
885 }
886 }
887 break;
888 case GL_LEQUAL:
889 if (ctx->Depth.Mask) {
890 /* Update Z buffer */
891 GLuint i;
892 for (i=0; i<n; i++) {
893 if (mask[i]) {
894 GLuint *zptr = Z_ADDRESS(x[i], y[i]);
895 if (z[i] <= *zptr) {
896 /* pass */
897 *zptr = z[i];
898 }
899 else {
900 /* fail */
901 mask[i] = 0;
902 }
903 }
904 }
905 }
906 else {
907 /* Don't update Z buffer */
908 GLuint i;
909 for (i=0; i<n; i++) {
910 if (mask[i]) {
911 GLuint *zptr = Z_ADDRESS(x[i], y[i]);
912 if (z[i] <= *zptr) {
913 /* pass */
914 }
915 else {
916 /* fail */
917 mask[i] = 0;
918 }
919 }
920 }
921 }
922 break;
923 case GL_GEQUAL:
924 if (ctx->Depth.Mask) {
925 /* Update Z buffer */
926 GLuint i;
927 for (i=0; i<n; i++) {
928 if (mask[i]) {
929 GLuint *zptr = Z_ADDRESS(x[i], y[i]);
930 if (z[i] >= *zptr) {
931 /* pass */
932 *zptr = z[i];
933 }
934 else {
935 /* fail */
936 mask[i] = 0;
937 }
938 }
939 }
940 }
941 else {
942 /* Don't update Z buffer */
943 GLuint i;
944 for (i=0; i<n; i++) {
945 if (mask[i]) {
946 GLuint *zptr = Z_ADDRESS(x[i], y[i]);
947 if (z[i] >= *zptr) {
948 /* pass */
949 }
950 else {
951 /* fail */
952 mask[i] = 0;
953 }
954 }
955 }
956 }
957 break;
958 case GL_GREATER:
959 if (ctx->Depth.Mask) {
960 /* Update Z buffer */
961 GLuint i;
962 for (i=0; i<n; i++) {
963 if (mask[i]) {
964 GLuint *zptr = Z_ADDRESS(x[i], y[i]);
965 if (z[i] > *zptr) {
966 /* pass */
967 *zptr = z[i];
968 }
969 else {
970 /* fail */
971 mask[i] = 0;
972 }
973 }
974 }
975 }
976 else {
977 /* Don't update Z buffer */
978 GLuint i;
979 for (i=0; i<n; i++) {
980 if (mask[i]) {
981 GLuint *zptr = Z_ADDRESS(x[i], y[i]);
982 if (z[i] > *zptr) {
983 /* pass */
984 }
985 else {
986 /* fail */
987 mask[i] = 0;
988 }
989 }
990 }
991 }
992 break;
993 case GL_NOTEQUAL:
994 if (ctx->Depth.Mask) {
995 /* Update Z buffer */
996 GLuint i;
997 for (i=0; i<n; i++) {
998 if (mask[i]) {
999 GLuint *zptr = Z_ADDRESS(x[i], y[i]);
1000 if (z[i] != *zptr) {
1001 /* pass */
1002 *zptr = z[i];
1003 }
1004 else {
1005 /* fail */
1006 mask[i] = 0;
1007 }
1008 }
1009 }
1010 }
1011 else {
1012 /* Don't update Z buffer */
1013 GLuint i;
1014 for (i=0; i<n; i++) {
1015 if (mask[i]) {
1016 GLuint *zptr = Z_ADDRESS(x[i], y[i]);
1017 if (z[i] != *zptr) {
1018 /* pass */
1019 }
1020 else {
1021 /* fail */
1022 mask[i] = 0;
1023 }
1024 }
1025 }
1026 }
1027 break;
1028 case GL_EQUAL:
1029 if (ctx->Depth.Mask) {
1030 /* Update Z buffer */
1031 GLuint i;
1032 for (i=0; i<n; i++) {
1033 if (mask[i]) {
1034 GLuint *zptr = Z_ADDRESS(x[i], y[i]);
1035 if (z[i] == *zptr) {
1036 /* pass */
1037 *zptr = z[i];
1038 }
1039 else {
1040 /* fail */
1041 mask[i] = 0;
1042 }
1043 }
1044 }
1045 }
1046 else {
1047 /* Don't update Z buffer */
1048 GLuint i;
1049 for (i=0; i<n; i++) {
1050 if (mask[i]) {
1051 GLuint *zptr = Z_ADDRESS(x[i], y[i]);
1052 if (z[i] == *zptr) {
1053 /* pass */
1054 }
1055 else {
1056 /* fail */
1057 mask[i] = 0;
1058 }
1059 }
1060 }
1061 }
1062 break;
1063 case GL_ALWAYS:
1064 if (ctx->Depth.Mask) {
1065 /* Update Z buffer */
1066 GLuint i;
1067 for (i=0; i<n; i++) {
1068 if (mask[i]) {
1069 GLuint *zptr = Z_ADDRESS(x[i], y[i]);
1070 *zptr = z[i];
1071 }
1072 }
1073 }
1074 else {
1075 /* Don't update Z buffer or mask */
1076 }
1077 break;
1078 case GL_NEVER:
1079 /* depth test never passes */
1080 _mesa_bzero(mask, n * sizeof(GLubyte));
1081 break;
1082 default:
1083 _mesa_problem(ctx, "Bad depth func in direct_depth_test_pixels");
1084 }
1085 }
1086
1087
1088
1089
1090 static GLuint
1091 depth_test_pixels( GLcontext *ctx, SWspan *span )
1092 {
1093 struct gl_framebuffer *fb = ctx->DrawBuffer;
1094 struct gl_renderbuffer *rb = fb->_DepthBuffer;
1095 const GLuint count = span->end;
1096 const GLint *x = span->array->x;
1097 const GLint *y = span->array->y;
1098 const GLuint *z = span->array->z;
1099 GLubyte *mask = span->array->mask;
1100
1101 if (rb->GetPointer(ctx, rb, 0, 0)) {
1102 /* Directly access values */
1103 if (rb->DataType == GL_UNSIGNED_SHORT) {
1104 GLushort *zStart = (GLushort *) rb->Data;
1105 GLuint stride = rb->Width;
1106 direct_depth_test_pixels16(ctx, zStart, stride, count, x, y, z, mask);
1107 }
1108 else {
1109 GLuint *zStart = (GLuint *) rb->Data;
1110 GLuint stride = rb->Width;
1111 ASSERT(rb->DataType == GL_UNSIGNED_INT);
1112 direct_depth_test_pixels32(ctx, zStart, stride, count, x, y, z, mask);
1113 }
1114 }
1115 else {
1116 /* read depth values from buffer, test, write back */
1117 if (rb->DataType == GL_UNSIGNED_SHORT) {
1118 GLushort zbuffer[MAX_WIDTH];
1119 _swrast_get_values(ctx, rb, count, x, y, zbuffer, sizeof(GLushort));
1120 depth_test_span16(ctx, count, zbuffer, z, mask);
1121 rb->PutValues(ctx, rb, count, x, y, zbuffer, mask);
1122 }
1123 else {
1124 GLuint zbuffer[MAX_WIDTH];
1125 ASSERT(rb->DataType == GL_UNSIGNED_INT);
1126 _swrast_get_values(ctx, rb, count, x, y, zbuffer, sizeof(GLuint));
1127 depth_test_span32(ctx, count, zbuffer, z, mask);
1128 rb->PutValues(ctx, rb, count, x, y, zbuffer, mask);
1129 }
1130 }
1131
1132 return count; /* not really correct, but OK */
1133 }
1134
1135
1136 /**
1137 * Apply depth (Z) buffer testing to the span.
1138 * \return approx number of pixels that passed (only zero is reliable)
1139 */
1140 GLuint
1141 _swrast_depth_test_span( GLcontext *ctx, SWspan *span)
1142 {
1143 if (span->arrayMask & SPAN_XY)
1144 return depth_test_pixels(ctx, span);
1145 else
1146 return depth_test_span(ctx, span);
1147 }
1148
1149
1150 /**
1151 * GL_EXT_depth_bounds_test extension.
1152 * Discard fragments depending on whether the corresponding Z-buffer
1153 * values are outside the depth bounds test range.
1154 * Note: we test the Z buffer values, not the fragment Z values!
1155 * \return GL_TRUE if any fragments pass, GL_FALSE if no fragments pass
1156 */
1157 GLboolean
1158 _swrast_depth_bounds_test( GLcontext *ctx, SWspan *span )
1159 {
1160 struct gl_framebuffer *fb = ctx->DrawBuffer;
1161 struct gl_renderbuffer *rb = fb->_DepthBuffer;
1162 GLuint zMin = (GLuint) (ctx->Depth.BoundsMin * fb->_DepthMaxF + 0.5F);
1163 GLuint zMax = (GLuint) (ctx->Depth.BoundsMax * fb->_DepthMaxF + 0.5F);
1164 GLubyte *mask = span->array->mask;
1165 const GLuint count = span->end;
1166 GLuint i;
1167 GLboolean anyPass = GL_FALSE;
1168
1169 if (rb->DataType == GL_UNSIGNED_SHORT) {
1170 /* get 16-bit values */
1171 GLushort zbuffer16[MAX_WIDTH], *zbuffer;
1172 if (span->arrayMask & SPAN_XY) {
1173 _swrast_get_values(ctx, rb, count, span->array->x, span->array->y,
1174 zbuffer16, sizeof(GLushort));
1175 zbuffer = zbuffer16;
1176 }
1177 else {
1178 zbuffer = (GLushort*) rb->GetPointer(ctx, rb, span->x, span->y);
1179 if (!zbuffer) {
1180 rb->GetRow(ctx, rb, count, span->x, span->y, zbuffer16);
1181 zbuffer = zbuffer16;
1182 }
1183 }
1184 assert(zbuffer);
1185
1186 /* Now do the tests */
1187 for (i = 0; i < count; i++) {
1188 if (mask[i]) {
1189 if (zbuffer[i] < zMin || zbuffer[i] > zMax)
1190 mask[i] = GL_FALSE;
1191 else
1192 anyPass = GL_TRUE;
1193 }
1194 }
1195 }
1196 else {
1197 /* get 32-bit values */
1198 GLuint zbuffer32[MAX_WIDTH], *zbuffer;
1199 ASSERT(rb->DataType == GL_UNSIGNED_INT);
1200 if (span->arrayMask & SPAN_XY) {
1201 _swrast_get_values(ctx, rb, count, span->array->x, span->array->y,
1202 zbuffer32, sizeof(GLuint));
1203 zbuffer = zbuffer32;
1204 }
1205 else {
1206 zbuffer = (GLuint*) rb->GetPointer(ctx, rb, span->x, span->y);
1207 if (!zbuffer) {
1208 rb->GetRow(ctx, rb, count, span->x, span->y, zbuffer32);
1209 zbuffer = zbuffer32;
1210 }
1211 }
1212 assert(zbuffer);
1213
1214 /* Now do the tests */
1215 for (i = 0; i < count; i++) {
1216 if (mask[i]) {
1217 if (zbuffer[i] < zMin || zbuffer[i] > zMax)
1218 mask[i] = GL_FALSE;
1219 else
1220 anyPass = GL_TRUE;
1221 }
1222 }
1223 }
1224
1225 return anyPass;
1226 }
1227
1228
1229
1230 /**********************************************************************/
1231 /***** Read Depth Buffer *****/
1232 /**********************************************************************/
1233
1234
1235 /**
1236 * Read a span of depth values from the given depth renderbuffer, returning
1237 * the values as GLfloats.
1238 * This function does clipping to prevent reading outside the depth buffer's
1239 * bounds. Though the clipping is redundant when we're called from
1240 * _swrast_ReadPixels.
1241 */
1242 void
1243 _swrast_read_depth_span_float( GLcontext *ctx, struct gl_renderbuffer *rb,
1244 GLint n, GLint x, GLint y, GLfloat depth[] )
1245 {
1246 const GLfloat scale = 1.0F / ctx->DrawBuffer->_DepthMaxF;
1247
1248 if (!rb) {
1249 /* really only doing this to prevent FP exceptions later */
1250 _mesa_bzero(depth, n * sizeof(GLfloat));
1251 return;
1252 }
1253
1254 ASSERT(rb->_BaseFormat == GL_DEPTH_COMPONENT);
1255
1256 if (y < 0 || y >= (GLint) rb->Height ||
1257 x + n <= 0 || x >= (GLint) rb->Width) {
1258 /* span is completely outside framebuffer */
1259 _mesa_bzero(depth, n * sizeof(GLfloat));
1260 return;
1261 }
1262
1263 if (x < 0) {
1264 GLint dx = -x;
1265 GLint i;
1266 for (i = 0; i < dx; i++)
1267 depth[i] = 0.0;
1268 x = 0;
1269 n -= dx;
1270 depth += dx;
1271 }
1272 if (x + n > (GLint) rb->Width) {
1273 GLint dx = x + n - (GLint) rb->Width;
1274 GLint i;
1275 for (i = 0; i < dx; i++)
1276 depth[n - i - 1] = 0.0;
1277 n -= dx;
1278 }
1279 if (n <= 0) {
1280 return;
1281 }
1282
1283 if (rb->DataType == GL_UNSIGNED_INT) {
1284 GLuint temp[MAX_WIDTH];
1285 GLint i;
1286 rb->GetRow(ctx, rb, n, x, y, temp);
1287 for (i = 0; i < n; i++) {
1288 depth[i] = temp[i] * scale;
1289 }
1290 }
1291 else if (rb->DataType == GL_UNSIGNED_SHORT) {
1292 GLushort temp[MAX_WIDTH];
1293 GLint i;
1294 rb->GetRow(ctx, rb, n, x, y, temp);
1295 for (i = 0; i < n; i++) {
1296 depth[i] = temp[i] * scale;
1297 }
1298 }
1299 else {
1300 _mesa_problem(ctx, "Invalid depth renderbuffer data type");
1301 }
1302 }
1303
1304
1305 /**
1306 * As above, but return 32-bit GLuint values.
1307 */
1308 void
1309 _swrast_read_depth_span_uint( GLcontext *ctx, struct gl_renderbuffer *rb,
1310 GLint n, GLint x, GLint y, GLuint depth[] )
1311 {
1312 GLuint depthBits;
1313
1314 if (!rb) {
1315 /* really only doing this to prevent FP exceptions later */
1316 _mesa_bzero(depth, n * sizeof(GLuint));
1317 return;
1318 }
1319
1320 depthBits = _mesa_get_format_bits(rb->Format, GL_DEPTH_BITS);
1321
1322 ASSERT(rb->_BaseFormat == GL_DEPTH_COMPONENT);
1323
1324 if (y < 0 || y >= (GLint) rb->Height ||
1325 x + n <= 0 || x >= (GLint) rb->Width) {
1326 /* span is completely outside framebuffer */
1327 _mesa_bzero(depth, n * sizeof(GLfloat));
1328 return;
1329 }
1330
1331 if (x < 0) {
1332 GLint dx = -x;
1333 GLint i;
1334 for (i = 0; i < dx; i++)
1335 depth[i] = 0;
1336 x = 0;
1337 n -= dx;
1338 depth += dx;
1339 }
1340 if (x + n > (GLint) rb->Width) {
1341 GLint dx = x + n - (GLint) rb->Width;
1342 GLint i;
1343 for (i = 0; i < dx; i++)
1344 depth[n - i - 1] = 0;
1345 n -= dx;
1346 }
1347 if (n <= 0) {
1348 return;
1349 }
1350
1351 if (rb->DataType == GL_UNSIGNED_INT) {
1352 rb->GetRow(ctx, rb, n, x, y, depth);
1353 if (depthBits < 32) {
1354 GLuint shift = 32 - depthBits;
1355 GLint i;
1356 for (i = 0; i < n; i++) {
1357 GLuint z = depth[i];
1358 depth[i] = z << shift; /* XXX lsb bits? */
1359 }
1360 }
1361 }
1362 else if (rb->DataType == GL_UNSIGNED_SHORT) {
1363 GLushort temp[MAX_WIDTH];
1364 GLint i;
1365 rb->GetRow(ctx, rb, n, x, y, temp);
1366 if (depthBits == 16) {
1367 for (i = 0; i < n; i++) {
1368 GLuint z = temp[i];
1369 depth[i] = (z << 16) | z;
1370 }
1371 }
1372 else {
1373 GLuint shift = 16 - depthBits;
1374 for (i = 0; i < n; i++) {
1375 GLuint z = temp[i];
1376 depth[i] = (z << (shift + 16)) | (z << shift); /* XXX lsb bits? */
1377 }
1378 }
1379 }
1380 else {
1381 _mesa_problem(ctx, "Invalid depth renderbuffer data type");
1382 }
1383 }
1384
1385
1386
1387 /**
1388 * Clear the given z/depth renderbuffer.
1389 */
1390 void
1391 _swrast_clear_depth_buffer( GLcontext *ctx, struct gl_renderbuffer *rb )
1392 {
1393 GLuint clearValue;
1394 GLint x, y, width, height;
1395
1396 if (!rb || !ctx->Depth.Mask) {
1397 /* no depth buffer, or writing to it is disabled */
1398 return;
1399 }
1400
1401 /* compute integer clearing value */
1402 if (ctx->Depth.Clear == 1.0) {
1403 clearValue = ctx->DrawBuffer->_DepthMax;
1404 }
1405 else {
1406 clearValue = (GLuint) (ctx->Depth.Clear * ctx->DrawBuffer->_DepthMaxF);
1407 }
1408
1409 assert(rb->_BaseFormat == GL_DEPTH_COMPONENT);
1410
1411 /* compute region to clear */
1412 x = ctx->DrawBuffer->_Xmin;
1413 y = ctx->DrawBuffer->_Ymin;
1414 width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin;
1415 height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin;
1416
1417 if (rb->GetPointer(ctx, rb, 0, 0)) {
1418 /* Direct buffer access is possible. Either this is just malloc'd
1419 * memory, or perhaps the driver mmap'd the zbuffer memory.
1420 */
1421 if (rb->DataType == GL_UNSIGNED_SHORT) {
1422 if ((clearValue & 0xff) == ((clearValue >> 8) & 0xff) &&
1423 ((GLushort *) rb->GetPointer(ctx, rb, 0, 0) + width ==
1424 (GLushort *) rb->GetPointer(ctx, rb, 0, 1))) {
1425 /* optimized case */
1426 GLushort *dst = (GLushort *) rb->GetPointer(ctx, rb, x, y);
1427 GLuint len = width * height * sizeof(GLushort);
1428 _mesa_memset(dst, (clearValue & 0xff), len);
1429 }
1430 else {
1431 /* general case */
1432 GLint i, j;
1433 for (i = 0; i < height; i++) {
1434 GLushort *dst = (GLushort *) rb->GetPointer(ctx, rb, x, y + i);
1435 for (j = 0; j < width; j++) {
1436 dst[j] = clearValue;
1437 }
1438 }
1439 }
1440 }
1441 else {
1442 GLint i, j;
1443 ASSERT(rb->DataType == GL_UNSIGNED_INT);
1444 for (i = 0; i < height; i++) {
1445 GLuint *dst = (GLuint *) rb->GetPointer(ctx, rb, x, y + i);
1446 for (j = 0; j < width; j++) {
1447 dst[j] = clearValue;
1448 }
1449 }
1450 }
1451 }
1452 else {
1453 /* Direct access not possible. Use PutRow to write new values. */
1454 if (rb->DataType == GL_UNSIGNED_SHORT) {
1455 GLushort clearVal16 = (GLushort) (clearValue & 0xffff);
1456 GLint i;
1457 for (i = 0; i < height; i++) {
1458 rb->PutMonoRow(ctx, rb, width, x, y + i, &clearVal16, NULL);
1459 }
1460 }
1461 else if (rb->DataType == GL_UNSIGNED_INT) {
1462 GLint i;
1463 ASSERT(sizeof(clearValue) == sizeof(GLuint));
1464 for (i = 0; i < height; i++) {
1465 rb->PutMonoRow(ctx, rb, width, x, y + i, &clearValue, NULL);
1466 }
1467 }
1468 else {
1469 _mesa_problem(ctx, "bad depth renderbuffer DataType");
1470 }
1471 }
1472 }