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