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