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