added Window-isms previously in gl.h
[mesa.git] / src / mesa / main / depth.c
1 /* $Id: depth.c,v 1.17 2000/04/11 20:42:22 brianp Exp $ */
2
3 /*
4 * Mesa 3-D graphics library
5 * Version: 3.3
6 *
7 * Copyright (C) 1999-2000 Brian Paul All Rights Reserved.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 */
26
27
28 #ifdef PC_HEADER
29 #include "all.h"
30 #else
31 #include "glheader.h"
32 #include "context.h"
33 #include "enums.h"
34 #include "depth.h"
35 #include "mem.h"
36 #include "pb.h"
37 #include "types.h"
38 #endif
39
40
41
42 /**********************************************************************/
43 /***** API Functions *****/
44 /**********************************************************************/
45
46
47
48 void
49 _mesa_ClearDepth( GLclampd depth )
50 {
51 GET_CURRENT_CONTEXT(ctx);
52 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glClearDepth");
53 ctx->Depth.Clear = (GLfloat) CLAMP( depth, 0.0, 1.0 );
54 if (ctx->Driver.ClearDepth)
55 (*ctx->Driver.ClearDepth)( ctx, ctx->Depth.Clear );
56 }
57
58
59
60 void
61 _mesa_DepthFunc( GLenum func )
62 {
63 GET_CURRENT_CONTEXT(ctx);
64 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glDepthFunc");
65
66 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
67 fprintf(stderr, "glDepthFunc %s\n", gl_lookup_enum_by_nr(func));
68
69 switch (func) {
70 case GL_LESS: /* (default) pass if incoming z < stored z */
71 case GL_GEQUAL:
72 case GL_LEQUAL:
73 case GL_GREATER:
74 case GL_NOTEQUAL:
75 case GL_EQUAL:
76 case GL_ALWAYS:
77 if (ctx->Depth.Func != func) {
78 ctx->Depth.Func = func;
79 ctx->NewState |= NEW_RASTER_OPS;
80 ctx->TriangleCaps &= ~DD_Z_NEVER;
81 if (ctx->Driver.DepthFunc) {
82 (*ctx->Driver.DepthFunc)( ctx, func );
83 }
84 }
85 break;
86 case GL_NEVER:
87 if (ctx->Depth.Func != func) {
88 ctx->Depth.Func = func;
89 ctx->NewState |= NEW_RASTER_OPS;
90 ctx->TriangleCaps |= DD_Z_NEVER;
91 if (ctx->Driver.DepthFunc) {
92 (*ctx->Driver.DepthFunc)( ctx, func );
93 }
94 }
95 break;
96 default:
97 gl_error( ctx, GL_INVALID_ENUM, "glDepth.Func" );
98 }
99 }
100
101
102
103 void
104 _mesa_DepthMask( GLboolean flag )
105 {
106 GET_CURRENT_CONTEXT(ctx);
107 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glDepthMask");
108
109 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
110 fprintf(stderr, "glDepthMask %d\n", flag);
111
112 /*
113 * GL_TRUE indicates depth buffer writing is enabled (default)
114 * GL_FALSE indicates depth buffer writing is disabled
115 */
116 if (ctx->Depth.Mask != flag) {
117 ctx->Depth.Mask = flag;
118 ctx->NewState |= NEW_RASTER_OPS;
119 if (ctx->Driver.DepthMask) {
120 (*ctx->Driver.DepthMask)( ctx, flag );
121 }
122 }
123 }
124
125
126
127 /**********************************************************************/
128 /***** Misc *****/
129 /**********************************************************************/
130
131 /*
132 * Return address of depth buffer value for given window coord.
133 */
134 GLvoid *
135 _mesa_zbuffer_address(GLcontext *ctx, GLint x, GLint y)
136 {
137 if (ctx->Visual->DepthBits <= 16)
138 return (GLushort *) ctx->DrawBuffer->DepthBuffer + ctx->DrawBuffer->Width * y + x;
139 else
140 return (GLuint *) ctx->DrawBuffer->DepthBuffer + ctx->DrawBuffer->Width * y + x;
141 }
142
143
144 #define Z_ADDRESS16( CTX, X, Y ) \
145 ( ((GLushort *) (CTX)->DrawBuffer->DepthBuffer) \
146 + (CTX)->DrawBuffer->Width * (Y) + (X) )
147
148 #define Z_ADDRESS32( CTX, X, Y ) \
149 ( ((GLuint *) (CTX)->DrawBuffer->DepthBuffer) \
150 + (CTX)->DrawBuffer->Width * (Y) + (X) )
151
152
153
154 /**********************************************************************/
155 /***** Depth Testing Functions *****/
156 /**********************************************************************/
157
158
159 /*
160 * Do depth test for an array of fragments. This is used both for
161 * software and hardware Z buffers.
162 * Input: zbuffer - array of z values in the zbuffer
163 * z - array of fragment z values
164 * Return: number of fragments which pass the test.
165 */
166 static GLuint
167 depth_test_span16( GLcontext *ctx, GLuint n, GLint x, GLint y,
168 GLushort zbuffer[], const GLdepth z[], GLubyte mask[] )
169 {
170 GLuint passed = 0;
171
172 /* switch cases ordered from most frequent to less frequent */
173 switch (ctx->Depth.Func) {
174 case GL_LESS:
175 if (ctx->Depth.Mask) {
176 /* Update Z buffer */
177 GLuint i;
178 for (i=0; i<n; i++) {
179 if (mask[i]) {
180 if (z[i] < zbuffer[i]) {
181 /* pass */
182 zbuffer[i] = z[i];
183 passed++;
184 }
185 else {
186 /* fail */
187 mask[i] = 0;
188 }
189 }
190 }
191 }
192 else {
193 /* Don't update Z buffer */
194 GLuint i;
195 for (i=0; i<n; i++) {
196 if (mask[i]) {
197 if (z[i] < zbuffer[i]) {
198 /* pass */
199 passed++;
200 }
201 else {
202 mask[i] = 0;
203 }
204 }
205 }
206 }
207 break;
208 case GL_LEQUAL:
209 if (ctx->Depth.Mask) {
210 /* Update Z buffer */
211 GLuint i;
212 for (i=0;i<n;i++) {
213 if (mask[i]) {
214 if (z[i] <= zbuffer[i]) {
215 zbuffer[i] = z[i];
216 passed++;
217 }
218 else {
219 mask[i] = 0;
220 }
221 }
222 }
223 }
224 else {
225 /* Don't update Z buffer */
226 GLuint i;
227 for (i=0;i<n;i++) {
228 if (mask[i]) {
229 if (z[i] <= zbuffer[i]) {
230 /* pass */
231 passed++;
232 }
233 else {
234 mask[i] = 0;
235 }
236 }
237 }
238 }
239 break;
240 case GL_GEQUAL:
241 if (ctx->Depth.Mask) {
242 /* Update Z buffer */
243 GLuint i;
244 for (i=0;i<n;i++) {
245 if (mask[i]) {
246 if (z[i] >= zbuffer[i]) {
247 zbuffer[i] = z[i];
248 passed++;
249 }
250 else {
251 mask[i] = 0;
252 }
253 }
254 }
255 }
256 else {
257 /* Don't update Z buffer */
258 GLuint i;
259 for (i=0;i<n;i++) {
260 if (mask[i]) {
261 if (z[i] >= zbuffer[i]) {
262 /* pass */
263 passed++;
264 }
265 else {
266 mask[i] = 0;
267 }
268 }
269 }
270 }
271 break;
272 case GL_GREATER:
273 if (ctx->Depth.Mask) {
274 /* Update Z buffer */
275 GLuint i;
276 for (i=0;i<n;i++) {
277 if (mask[i]) {
278 if (z[i] > zbuffer[i]) {
279 zbuffer[i] = z[i];
280 passed++;
281 }
282 else {
283 mask[i] = 0;
284 }
285 }
286 }
287 }
288 else {
289 /* Don't update Z buffer */
290 GLuint i;
291 for (i=0;i<n;i++) {
292 if (mask[i]) {
293 if (z[i] > zbuffer[i]) {
294 /* pass */
295 passed++;
296 }
297 else {
298 mask[i] = 0;
299 }
300 }
301 }
302 }
303 break;
304 case GL_NOTEQUAL:
305 if (ctx->Depth.Mask) {
306 /* Update Z buffer */
307 GLuint i;
308 for (i=0;i<n;i++) {
309 if (mask[i]) {
310 if (z[i] != zbuffer[i]) {
311 zbuffer[i] = z[i];
312 passed++;
313 }
314 else {
315 mask[i] = 0;
316 }
317 }
318 }
319 }
320 else {
321 /* Don't update Z buffer */
322 GLuint i;
323 for (i=0;i<n;i++) {
324 if (mask[i]) {
325 if (z[i] != zbuffer[i]) {
326 /* pass */
327 passed++;
328 }
329 else {
330 mask[i] = 0;
331 }
332 }
333 }
334 }
335 break;
336 case GL_EQUAL:
337 if (ctx->Depth.Mask) {
338 /* Update Z buffer */
339 GLuint i;
340 for (i=0;i<n;i++) {
341 if (mask[i]) {
342 if (z[i] == zbuffer[i]) {
343 zbuffer[i] = z[i];
344 passed++;
345 }
346 else {
347 mask[i] = 0;
348 }
349 }
350 }
351 }
352 else {
353 /* Don't update Z buffer */
354 GLuint i;
355 for (i=0;i<n;i++) {
356 if (mask[i]) {
357 if (z[i] == zbuffer[i]) {
358 /* pass */
359 passed++;
360 }
361 else {
362 mask[i] = 0;
363 }
364 }
365 }
366 }
367 break;
368 case GL_ALWAYS:
369 if (ctx->Depth.Mask) {
370 /* Update Z buffer */
371 GLuint i;
372 for (i=0;i<n;i++) {
373 if (mask[i]) {
374 zbuffer[i] = z[i];
375 passed++;
376 }
377 }
378 }
379 else {
380 /* Don't update Z buffer or mask */
381 passed = n;
382 }
383 break;
384 case GL_NEVER:
385 BZERO(mask, n * sizeof(GLubyte));
386 break;
387 default:
388 gl_problem(ctx, "Bad depth func in depth_test_span16");
389 }
390
391 return passed;
392 }
393
394
395 static GLuint
396 depth_test_span32( GLcontext *ctx, GLuint n, GLint x, GLint y,
397 GLuint zbuffer[], const GLdepth z[], GLubyte mask[] )
398 {
399 GLuint passed = 0;
400
401 /* switch cases ordered from most frequent to less frequent */
402 switch (ctx->Depth.Func) {
403 case GL_LESS:
404 if (ctx->Depth.Mask) {
405 /* Update Z buffer */
406 GLuint i;
407 for (i=0; i<n; i++) {
408 if (mask[i]) {
409 if (z[i] < zbuffer[i]) {
410 /* pass */
411 zbuffer[i] = z[i];
412 passed++;
413 }
414 else {
415 /* fail */
416 mask[i] = 0;
417 }
418 }
419 }
420 }
421 else {
422 /* Don't update Z buffer */
423 GLuint i;
424 for (i=0; i<n; i++) {
425 if (mask[i]) {
426 if (z[i] < zbuffer[i]) {
427 /* pass */
428 passed++;
429 }
430 else {
431 mask[i] = 0;
432 }
433 }
434 }
435 }
436 break;
437 case GL_LEQUAL:
438 if (ctx->Depth.Mask) {
439 /* Update Z buffer */
440 GLuint i;
441 for (i=0;i<n;i++) {
442 if (mask[i]) {
443 if (z[i] <= zbuffer[i]) {
444 zbuffer[i] = z[i];
445 passed++;
446 }
447 else {
448 mask[i] = 0;
449 }
450 }
451 }
452 }
453 else {
454 /* Don't update Z buffer */
455 GLuint i;
456 for (i=0;i<n;i++) {
457 if (mask[i]) {
458 if (z[i] <= zbuffer[i]) {
459 /* pass */
460 passed++;
461 }
462 else {
463 mask[i] = 0;
464 }
465 }
466 }
467 }
468 break;
469 case GL_GEQUAL:
470 if (ctx->Depth.Mask) {
471 /* Update Z buffer */
472 GLuint i;
473 for (i=0;i<n;i++) {
474 if (mask[i]) {
475 if (z[i] >= zbuffer[i]) {
476 zbuffer[i] = z[i];
477 passed++;
478 }
479 else {
480 mask[i] = 0;
481 }
482 }
483 }
484 }
485 else {
486 /* Don't update Z buffer */
487 GLuint i;
488 for (i=0;i<n;i++) {
489 if (mask[i]) {
490 if (z[i] >= zbuffer[i]) {
491 /* pass */
492 passed++;
493 }
494 else {
495 mask[i] = 0;
496 }
497 }
498 }
499 }
500 break;
501 case GL_GREATER:
502 if (ctx->Depth.Mask) {
503 /* Update Z buffer */
504 GLuint i;
505 for (i=0;i<n;i++) {
506 if (mask[i]) {
507 if (z[i] > zbuffer[i]) {
508 zbuffer[i] = z[i];
509 passed++;
510 }
511 else {
512 mask[i] = 0;
513 }
514 }
515 }
516 }
517 else {
518 /* Don't update Z buffer */
519 GLuint i;
520 for (i=0;i<n;i++) {
521 if (mask[i]) {
522 if (z[i] > zbuffer[i]) {
523 /* pass */
524 passed++;
525 }
526 else {
527 mask[i] = 0;
528 }
529 }
530 }
531 }
532 break;
533 case GL_NOTEQUAL:
534 if (ctx->Depth.Mask) {
535 /* Update Z buffer */
536 GLuint i;
537 for (i=0;i<n;i++) {
538 if (mask[i]) {
539 if (z[i] != zbuffer[i]) {
540 zbuffer[i] = z[i];
541 passed++;
542 }
543 else {
544 mask[i] = 0;
545 }
546 }
547 }
548 }
549 else {
550 /* Don't update Z buffer */
551 GLuint i;
552 for (i=0;i<n;i++) {
553 if (mask[i]) {
554 if (z[i] != zbuffer[i]) {
555 /* pass */
556 passed++;
557 }
558 else {
559 mask[i] = 0;
560 }
561 }
562 }
563 }
564 break;
565 case GL_EQUAL:
566 if (ctx->Depth.Mask) {
567 /* Update Z buffer */
568 GLuint i;
569 for (i=0;i<n;i++) {
570 if (mask[i]) {
571 if (z[i] == zbuffer[i]) {
572 zbuffer[i] = z[i];
573 passed++;
574 }
575 else {
576 mask[i] = 0;
577 }
578 }
579 }
580 }
581 else {
582 /* Don't update Z buffer */
583 GLuint i;
584 for (i=0;i<n;i++) {
585 if (mask[i]) {
586 if (z[i] == zbuffer[i]) {
587 /* pass */
588 passed++;
589 }
590 else {
591 mask[i] = 0;
592 }
593 }
594 }
595 }
596 break;
597 case GL_ALWAYS:
598 if (ctx->Depth.Mask) {
599 /* Update Z buffer */
600 GLuint i;
601 for (i=0;i<n;i++) {
602 if (mask[i]) {
603 zbuffer[i] = z[i];
604 passed++;
605 }
606 }
607 }
608 else {
609 /* Don't update Z buffer or mask */
610 passed = n;
611 }
612 break;
613 case GL_NEVER:
614 BZERO(mask, n * sizeof(GLubyte));
615 break;
616 default:
617 gl_problem(ctx, "Bad depth func in depth_test_span32");
618 }
619
620 return passed;
621 }
622
623
624
625 /*
626 * Apply depth test to span of fragments. Hardware or software z buffer.
627 */
628 GLuint
629 _mesa_depth_test_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
630 const GLdepth z[], GLubyte mask[] )
631 {
632 if (ctx->Driver.ReadDepthSpan) {
633 /* hardware-based depth buffer */
634 GLdepth zbuffer[MAX_WIDTH];
635 GLuint passed;
636 (*ctx->Driver.ReadDepthSpan)(ctx, n, x, y, zbuffer);
637 passed = depth_test_span32(ctx, n, x, y, zbuffer, z, mask);
638 assert(ctx->Driver.WriteDepthSpan);
639 (*ctx->Driver.WriteDepthSpan)(ctx, n, x, y, zbuffer, mask);
640 return passed;
641 }
642 else {
643 /* software depth buffer */
644 if (ctx->Visual->DepthBits <= 16) {
645 GLushort *zptr = (GLushort *) Z_ADDRESS16(ctx, x, y);
646 GLuint passed = depth_test_span16(ctx, n, x, y, zptr, z, mask);
647 return passed;
648 }
649 else {
650 GLuint *zptr = (GLuint *) Z_ADDRESS32(ctx, x, y);
651 GLuint passed = depth_test_span32(ctx, n, x, y, zptr, z, mask);
652 return passed;
653 }
654 }
655 }
656
657
658
659
660 /*
661 * Do depth testing for an array of fragments using software Z buffer.
662 */
663 static void
664 software_depth_test_pixels16( GLcontext *ctx, GLuint n,
665 const GLint x[], const GLint y[],
666 const GLdepth z[], GLubyte mask[] )
667 {
668 /* switch cases ordered from most frequent to less frequent */
669 switch (ctx->Depth.Func) {
670 case GL_LESS:
671 if (ctx->Depth.Mask) {
672 /* Update Z buffer */
673 GLuint i;
674 for (i=0; i<n; i++) {
675 if (mask[i]) {
676 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
677 if (z[i] < *zptr) {
678 /* pass */
679 *zptr = z[i];
680 }
681 else {
682 /* fail */
683 mask[i] = 0;
684 }
685 }
686 }
687 }
688 else {
689 /* Don't update Z buffer */
690 GLuint i;
691 for (i=0; i<n; i++) {
692 if (mask[i]) {
693 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
694 if (z[i] < *zptr) {
695 /* pass */
696 }
697 else {
698 /* fail */
699 mask[i] = 0;
700 }
701 }
702 }
703 }
704 break;
705 case GL_LEQUAL:
706 if (ctx->Depth.Mask) {
707 /* Update Z buffer */
708 GLuint i;
709 for (i=0; i<n; i++) {
710 if (mask[i]) {
711 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
712 if (z[i] <= *zptr) {
713 /* pass */
714 *zptr = z[i];
715 }
716 else {
717 /* fail */
718 mask[i] = 0;
719 }
720 }
721 }
722 }
723 else {
724 /* Don't update Z buffer */
725 GLuint i;
726 for (i=0; i<n; i++) {
727 if (mask[i]) {
728 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
729 if (z[i] <= *zptr) {
730 /* pass */
731 }
732 else {
733 /* fail */
734 mask[i] = 0;
735 }
736 }
737 }
738 }
739 break;
740 case GL_GEQUAL:
741 if (ctx->Depth.Mask) {
742 /* Update Z buffer */
743 GLuint i;
744 for (i=0; i<n; i++) {
745 if (mask[i]) {
746 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
747 if (z[i] >= *zptr) {
748 /* pass */
749 *zptr = z[i];
750 }
751 else {
752 /* fail */
753 mask[i] = 0;
754 }
755 }
756 }
757 }
758 else {
759 /* Don't update Z buffer */
760 GLuint i;
761 for (i=0; i<n; i++) {
762 if (mask[i]) {
763 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
764 if (z[i] >= *zptr) {
765 /* pass */
766 }
767 else {
768 /* fail */
769 mask[i] = 0;
770 }
771 }
772 }
773 }
774 break;
775 case GL_GREATER:
776 if (ctx->Depth.Mask) {
777 /* Update Z buffer */
778 GLuint i;
779 for (i=0; i<n; i++) {
780 if (mask[i]) {
781 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
782 if (z[i] > *zptr) {
783 /* pass */
784 *zptr = z[i];
785 }
786 else {
787 /* fail */
788 mask[i] = 0;
789 }
790 }
791 }
792 }
793 else {
794 /* Don't update Z buffer */
795 GLuint i;
796 for (i=0; i<n; i++) {
797 if (mask[i]) {
798 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
799 if (z[i] > *zptr) {
800 /* pass */
801 }
802 else {
803 /* fail */
804 mask[i] = 0;
805 }
806 }
807 }
808 }
809 break;
810 case GL_NOTEQUAL:
811 if (ctx->Depth.Mask) {
812 /* Update Z buffer */
813 GLuint i;
814 for (i=0; i<n; i++) {
815 if (mask[i]) {
816 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
817 if (z[i] != *zptr) {
818 /* pass */
819 *zptr = z[i];
820 }
821 else {
822 /* fail */
823 mask[i] = 0;
824 }
825 }
826 }
827 }
828 else {
829 /* Don't update Z buffer */
830 GLuint i;
831 for (i=0; i<n; i++) {
832 if (mask[i]) {
833 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
834 if (z[i] != *zptr) {
835 /* pass */
836 }
837 else {
838 /* fail */
839 mask[i] = 0;
840 }
841 }
842 }
843 }
844 break;
845 case GL_EQUAL:
846 if (ctx->Depth.Mask) {
847 /* Update Z buffer */
848 GLuint i;
849 for (i=0; i<n; i++) {
850 if (mask[i]) {
851 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
852 if (z[i] == *zptr) {
853 /* pass */
854 *zptr = z[i];
855 }
856 else {
857 /* fail */
858 mask[i] = 0;
859 }
860 }
861 }
862 }
863 else {
864 /* Don't update Z buffer */
865 GLuint i;
866 for (i=0; i<n; i++) {
867 if (mask[i]) {
868 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
869 if (z[i] == *zptr) {
870 /* pass */
871 }
872 else {
873 /* fail */
874 mask[i] = 0;
875 }
876 }
877 }
878 }
879 break;
880 case GL_ALWAYS:
881 if (ctx->Depth.Mask) {
882 /* Update Z buffer */
883 GLuint i;
884 for (i=0; i<n; i++) {
885 if (mask[i]) {
886 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
887 *zptr = z[i];
888 }
889 }
890 }
891 else {
892 /* Don't update Z buffer or mask */
893 }
894 break;
895 case GL_NEVER:
896 /* depth test never passes */
897 BZERO(mask, n * sizeof(GLubyte));
898 break;
899 default:
900 gl_problem(ctx, "Bad depth func in software_depth_test_pixels");
901 }
902 }
903
904
905
906 /*
907 * Do depth testing for an array of fragments using software Z buffer.
908 */
909 static void
910 software_depth_test_pixels32( GLcontext *ctx, GLuint n,
911 const GLint x[], const GLint y[],
912 const GLdepth z[], GLubyte mask[] )
913 {
914 /* switch cases ordered from most frequent to less frequent */
915 switch (ctx->Depth.Func) {
916 case GL_LESS:
917 if (ctx->Depth.Mask) {
918 /* Update Z buffer */
919 GLuint i;
920 for (i=0; i<n; i++) {
921 if (mask[i]) {
922 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
923 if (z[i] < *zptr) {
924 /* pass */
925 *zptr = z[i];
926 }
927 else {
928 /* fail */
929 mask[i] = 0;
930 }
931 }
932 }
933 }
934 else {
935 /* Don't update Z buffer */
936 GLuint i;
937 for (i=0; i<n; i++) {
938 if (mask[i]) {
939 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
940 if (z[i] < *zptr) {
941 /* pass */
942 }
943 else {
944 /* fail */
945 mask[i] = 0;
946 }
947 }
948 }
949 }
950 break;
951 case GL_LEQUAL:
952 if (ctx->Depth.Mask) {
953 /* Update Z buffer */
954 GLuint i;
955 for (i=0; i<n; i++) {
956 if (mask[i]) {
957 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
958 if (z[i] <= *zptr) {
959 /* pass */
960 *zptr = z[i];
961 }
962 else {
963 /* fail */
964 mask[i] = 0;
965 }
966 }
967 }
968 }
969 else {
970 /* Don't update Z buffer */
971 GLuint i;
972 for (i=0; i<n; i++) {
973 if (mask[i]) {
974 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
975 if (z[i] <= *zptr) {
976 /* pass */
977 }
978 else {
979 /* fail */
980 mask[i] = 0;
981 }
982 }
983 }
984 }
985 break;
986 case GL_GEQUAL:
987 if (ctx->Depth.Mask) {
988 /* Update Z buffer */
989 GLuint i;
990 for (i=0; i<n; i++) {
991 if (mask[i]) {
992 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
993 if (z[i] >= *zptr) {
994 /* pass */
995 *zptr = z[i];
996 }
997 else {
998 /* fail */
999 mask[i] = 0;
1000 }
1001 }
1002 }
1003 }
1004 else {
1005 /* Don't update Z buffer */
1006 GLuint i;
1007 for (i=0; i<n; i++) {
1008 if (mask[i]) {
1009 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
1010 if (z[i] >= *zptr) {
1011 /* pass */
1012 }
1013 else {
1014 /* fail */
1015 mask[i] = 0;
1016 }
1017 }
1018 }
1019 }
1020 break;
1021 case GL_GREATER:
1022 if (ctx->Depth.Mask) {
1023 /* Update Z buffer */
1024 GLuint i;
1025 for (i=0; i<n; i++) {
1026 if (mask[i]) {
1027 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
1028 if (z[i] > *zptr) {
1029 /* pass */
1030 *zptr = z[i];
1031 }
1032 else {
1033 /* fail */
1034 mask[i] = 0;
1035 }
1036 }
1037 }
1038 }
1039 else {
1040 /* Don't update Z buffer */
1041 GLuint i;
1042 for (i=0; i<n; i++) {
1043 if (mask[i]) {
1044 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
1045 if (z[i] > *zptr) {
1046 /* pass */
1047 }
1048 else {
1049 /* fail */
1050 mask[i] = 0;
1051 }
1052 }
1053 }
1054 }
1055 break;
1056 case GL_NOTEQUAL:
1057 if (ctx->Depth.Mask) {
1058 /* Update Z buffer */
1059 GLuint i;
1060 for (i=0; i<n; i++) {
1061 if (mask[i]) {
1062 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
1063 if (z[i] != *zptr) {
1064 /* pass */
1065 *zptr = z[i];
1066 }
1067 else {
1068 /* fail */
1069 mask[i] = 0;
1070 }
1071 }
1072 }
1073 }
1074 else {
1075 /* Don't update Z buffer */
1076 GLuint i;
1077 for (i=0; i<n; i++) {
1078 if (mask[i]) {
1079 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
1080 if (z[i] != *zptr) {
1081 /* pass */
1082 }
1083 else {
1084 /* fail */
1085 mask[i] = 0;
1086 }
1087 }
1088 }
1089 }
1090 break;
1091 case GL_EQUAL:
1092 if (ctx->Depth.Mask) {
1093 /* Update Z buffer */
1094 GLuint i;
1095 for (i=0; i<n; i++) {
1096 if (mask[i]) {
1097 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
1098 if (z[i] == *zptr) {
1099 /* pass */
1100 *zptr = z[i];
1101 }
1102 else {
1103 /* fail */
1104 mask[i] = 0;
1105 }
1106 }
1107 }
1108 }
1109 else {
1110 /* Don't update Z buffer */
1111 GLuint i;
1112 for (i=0; i<n; i++) {
1113 if (mask[i]) {
1114 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
1115 if (z[i] == *zptr) {
1116 /* pass */
1117 }
1118 else {
1119 /* fail */
1120 mask[i] = 0;
1121 }
1122 }
1123 }
1124 }
1125 break;
1126 case GL_ALWAYS:
1127 if (ctx->Depth.Mask) {
1128 /* Update Z buffer */
1129 GLuint i;
1130 for (i=0; i<n; i++) {
1131 if (mask[i]) {
1132 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
1133 *zptr = z[i];
1134 }
1135 }
1136 }
1137 else {
1138 /* Don't update Z buffer or mask */
1139 }
1140 break;
1141 case GL_NEVER:
1142 /* depth test never passes */
1143 BZERO(mask, n * sizeof(GLubyte));
1144 break;
1145 default:
1146 gl_problem(ctx, "Bad depth func in software_depth_test_pixels");
1147 }
1148 }
1149
1150
1151
1152 /*
1153 * Do depth testing for an array of pixels using hardware Z buffer.
1154 * Input/output: zbuffer - array of depth values from Z buffer
1155 * Input: z - array of fragment z values.
1156 */
1157 static void
1158 hardware_depth_test_pixels( GLcontext *ctx, GLuint n, GLdepth zbuffer[],
1159 const GLdepth z[], GLubyte mask[] )
1160 {
1161 /* switch cases ordered from most frequent to less frequent */
1162 switch (ctx->Depth.Func) {
1163 case GL_LESS:
1164 if (ctx->Depth.Mask) {
1165 /* Update Z buffer */
1166 GLuint i;
1167 for (i=0; i<n; i++) {
1168 if (mask[i]) {
1169 if (z[i] < zbuffer[i]) {
1170 /* pass */
1171 zbuffer[i] = z[i];
1172 }
1173 else {
1174 /* fail */
1175 mask[i] = 0;
1176 }
1177 }
1178 }
1179 }
1180 else {
1181 /* Don't update Z buffer */
1182 GLuint i;
1183 for (i=0; i<n; i++) {
1184 if (mask[i]) {
1185 if (z[i] < zbuffer[i]) {
1186 /* pass */
1187 }
1188 else {
1189 /* fail */
1190 mask[i] = 0;
1191 }
1192 }
1193 }
1194 }
1195 break;
1196 case GL_LEQUAL:
1197 if (ctx->Depth.Mask) {
1198 /* Update Z buffer */
1199 GLuint i;
1200 for (i=0; i<n; i++) {
1201 if (mask[i]) {
1202 if (z[i] <= zbuffer[i]) {
1203 /* pass */
1204 zbuffer[i] = z[i];
1205 }
1206 else {
1207 /* fail */
1208 mask[i] = 0;
1209 }
1210 }
1211 }
1212 }
1213 else {
1214 /* Don't update Z buffer */
1215 GLuint i;
1216 for (i=0; i<n; i++) {
1217 if (mask[i]) {
1218 if (z[i] <= zbuffer[i]) {
1219 /* pass */
1220 }
1221 else {
1222 /* fail */
1223 mask[i] = 0;
1224 }
1225 }
1226 }
1227 }
1228 break;
1229 case GL_GEQUAL:
1230 if (ctx->Depth.Mask) {
1231 /* Update Z buffer */
1232 GLuint i;
1233 for (i=0; i<n; i++) {
1234 if (mask[i]) {
1235 if (z[i] >= zbuffer[i]) {
1236 /* pass */
1237 zbuffer[i] = z[i];
1238 }
1239 else {
1240 /* fail */
1241 mask[i] = 0;
1242 }
1243 }
1244 }
1245 }
1246 else {
1247 /* Don't update Z buffer */
1248 GLuint i;
1249 for (i=0; i<n; i++) {
1250 if (mask[i]) {
1251 if (z[i] >= zbuffer[i]) {
1252 /* pass */
1253 }
1254 else {
1255 /* fail */
1256 mask[i] = 0;
1257 }
1258 }
1259 }
1260 }
1261 break;
1262 case GL_GREATER:
1263 if (ctx->Depth.Mask) {
1264 /* Update Z buffer */
1265 GLuint i;
1266 for (i=0; i<n; i++) {
1267 if (mask[i]) {
1268 if (z[i] > zbuffer[i]) {
1269 /* pass */
1270 zbuffer[i] = z[i];
1271 }
1272 else {
1273 /* fail */
1274 mask[i] = 0;
1275 }
1276 }
1277 }
1278 }
1279 else {
1280 /* Don't update Z buffer */
1281 GLuint i;
1282 for (i=0; i<n; i++) {
1283 if (mask[i]) {
1284 if (z[i] > zbuffer[i]) {
1285 /* pass */
1286 }
1287 else {
1288 /* fail */
1289 mask[i] = 0;
1290 }
1291 }
1292 }
1293 }
1294 break;
1295 case GL_NOTEQUAL:
1296 if (ctx->Depth.Mask) {
1297 /* Update Z buffer */
1298 GLuint i;
1299 for (i=0; i<n; i++) {
1300 if (mask[i]) {
1301 if (z[i] != zbuffer[i]) {
1302 /* pass */
1303 zbuffer[i] = z[i];
1304 }
1305 else {
1306 /* fail */
1307 mask[i] = 0;
1308 }
1309 }
1310 }
1311 }
1312 else {
1313 /* Don't update Z buffer */
1314 GLuint i;
1315 for (i=0; i<n; i++) {
1316 if (mask[i]) {
1317 if (z[i] != zbuffer[i]) {
1318 /* pass */
1319 }
1320 else {
1321 /* fail */
1322 mask[i] = 0;
1323 }
1324 }
1325 }
1326 }
1327 break;
1328 case GL_EQUAL:
1329 if (ctx->Depth.Mask) {
1330 /* Update Z buffer */
1331 GLuint i;
1332 for (i=0; i<n; i++) {
1333 if (mask[i]) {
1334 if (z[i] == zbuffer[i]) {
1335 /* pass */
1336 zbuffer[i] = z[i];
1337 }
1338 else {
1339 /* fail */
1340 mask[i] = 0;
1341 }
1342 }
1343 }
1344 }
1345 else {
1346 /* Don't update Z buffer */
1347 GLuint i;
1348 for (i=0; i<n; i++) {
1349 if (mask[i]) {
1350 if (z[i] == zbuffer[i]) {
1351 /* pass */
1352 }
1353 else {
1354 /* fail */
1355 mask[i] = 0;
1356 }
1357 }
1358 }
1359 }
1360 break;
1361 case GL_ALWAYS:
1362 if (ctx->Depth.Mask) {
1363 /* Update Z buffer */
1364 GLuint i;
1365 for (i=0; i<n; i++) {
1366 if (mask[i]) {
1367 zbuffer[i] = z[i];
1368 }
1369 }
1370 }
1371 else {
1372 /* Don't update Z buffer or mask */
1373 }
1374 break;
1375 case GL_NEVER:
1376 /* depth test never passes */
1377 BZERO(mask, n * sizeof(GLubyte));
1378 break;
1379 default:
1380 gl_problem(ctx, "Bad depth func in hardware_depth_test_pixels");
1381 }
1382 }
1383
1384
1385
1386 void
1387 _mesa_depth_test_pixels( GLcontext *ctx,
1388 GLuint n, const GLint x[], const GLint y[],
1389 const GLdepth z[], GLubyte mask[] )
1390 {
1391 if (ctx->Driver.ReadDepthPixels) {
1392 /* read depth values from hardware Z buffer */
1393 GLdepth zbuffer[PB_SIZE];
1394 (*ctx->Driver.ReadDepthPixels)(ctx, n, x, y, zbuffer);
1395
1396 hardware_depth_test_pixels( ctx, n, zbuffer, z, mask );
1397
1398 /* update hardware Z buffer with new values */
1399 assert(ctx->Driver.WriteDepthPixels);
1400 (*ctx->Driver.WriteDepthPixels)(ctx, n, x, y, zbuffer, mask );
1401 }
1402 else {
1403 /* software depth testing */
1404 if (ctx->Visual->DepthBits <= 16)
1405 software_depth_test_pixels16(ctx, n, x, y, z, mask);
1406 else
1407 software_depth_test_pixels32(ctx, n, x, y, z, mask);
1408 }
1409 }
1410
1411
1412
1413
1414
1415 /**********************************************************************/
1416 /***** Read Depth Buffer *****/
1417 /**********************************************************************/
1418
1419
1420 /*
1421 * Read a span of depth values from the depth buffer.
1422 * This function does clipping before calling the device driver function.
1423 */
1424 void
1425 _mesa_read_depth_span( GLcontext *ctx,
1426 GLint n, GLint x, GLint y, GLdepth depth[] )
1427 {
1428 if (y < 0 || y >= ctx->DrawBuffer->Height ||
1429 x + (GLint) n <= 0 || x >= ctx->DrawBuffer->Width) {
1430 /* span is completely outside framebuffer */
1431 GLint i;
1432 for (i = 0; i < n; i++)
1433 depth[i] = 0;
1434 return;
1435 }
1436
1437 if (x < 0) {
1438 GLint dx = -x;
1439 GLint i;
1440 for (i = 0; i < dx; i++)
1441 depth[i] = 0;
1442 x = 0;
1443 n -= dx;
1444 depth += dx;
1445 }
1446 if (x + n > ctx->DrawBuffer->Width) {
1447 GLint dx = x + n - ctx->DrawBuffer->Width;
1448 GLint i;
1449 for (i = 0; i < dx; i++)
1450 depth[n - i - 1] = 0;
1451 n -= dx;
1452 }
1453 if (n <= 0) {
1454 return;
1455 }
1456
1457 if (ctx->DrawBuffer->DepthBuffer) {
1458 /* read from software depth buffer */
1459 if (ctx->Visual->DepthBits <= 16) {
1460 const GLushort *zptr = Z_ADDRESS16( ctx, x, y );
1461 GLuint i;
1462 for (i = 0; i < n; i++) {
1463 depth[i] = zptr[i];
1464 }
1465 }
1466 else {
1467 const GLuint *zptr = Z_ADDRESS32( ctx, x, y );
1468 GLuint i;
1469 for (i = 0; i < n; i++) {
1470 depth[i] = zptr[i];
1471 }
1472 }
1473 }
1474 else if (ctx->Driver.ReadDepthSpan) {
1475 /* read from hardware depth buffer */
1476 (*ctx->Driver.ReadDepthSpan)( ctx, n, x, y, depth );
1477 }
1478 else {
1479 /* no depth buffer */
1480 BZERO(depth, n * sizeof(GLfloat));
1481 }
1482
1483 }
1484
1485
1486
1487
1488 /*
1489 * Return a span of depth values from the depth buffer as floats in [0,1].
1490 * This is used for both hardware and software depth buffers.
1491 * Input: n - how many pixels
1492 * x,y - location of first pixel
1493 * Output: depth - the array of depth values
1494 */
1495 void
1496 _mesa_read_depth_span_float( GLcontext *ctx,
1497 GLint n, GLint x, GLint y, GLfloat depth[] )
1498 {
1499 const GLfloat scale = 1.0F / ctx->Visual->DepthMaxF;
1500
1501 if (y < 0 || y >= ctx->DrawBuffer->Height ||
1502 x + (GLint) n <= 0 || x >= ctx->DrawBuffer->Width) {
1503 /* span is completely outside framebuffer */
1504 GLint i;
1505 for (i = 0; i < n; i++)
1506 depth[i] = 0.0F;
1507 return;
1508 }
1509
1510 if (x < 0) {
1511 GLint dx = -x;
1512 GLint i;
1513 for (i = 0; i < dx; i++)
1514 depth[i] = 0.0F;
1515 n -= dx;
1516 x = 0;
1517 }
1518 if (x + n > ctx->DrawBuffer->Width) {
1519 GLint dx = x + n - ctx->DrawBuffer->Width;
1520 GLint i;
1521 for (i = 0; i < dx; i++)
1522 depth[n - i - 1] = 0.0F;
1523 n -= dx;
1524 }
1525 if (n <= 0) {
1526 return;
1527 }
1528
1529 if (ctx->DrawBuffer->DepthBuffer) {
1530 /* read from software depth buffer */
1531 if (ctx->Visual->DepthBits <= 16) {
1532 const GLushort *zptr = Z_ADDRESS16( ctx, x, y );
1533 GLuint i;
1534 for (i = 0; i < n; i++) {
1535 depth[i] = (GLfloat) zptr[i] * scale;
1536 }
1537 }
1538 else {
1539 const GLuint *zptr = Z_ADDRESS32( ctx, x, y );
1540 GLuint i;
1541 for (i = 0; i < n; i++) {
1542 depth[i] = (GLfloat) zptr[i] * scale;
1543 }
1544 }
1545 }
1546 else if (ctx->Driver.ReadDepthSpan) {
1547 /* read from hardware depth buffer */
1548 GLdepth d[MAX_WIDTH];
1549 GLuint i;
1550 assert(n <= MAX_WIDTH);
1551 (*ctx->Driver.ReadDepthSpan)( ctx, n, x, y, d );
1552 for (i = 0; i < n; i++) {
1553 depth[i] = d[i] * scale;
1554 }
1555 }
1556 else {
1557 /* no depth buffer */
1558 BZERO(depth, n * sizeof(GLfloat));
1559 }
1560 }
1561
1562
1563
1564 /**********************************************************************/
1565 /***** Allocate and Clear Depth Buffer *****/
1566 /**********************************************************************/
1567
1568
1569
1570 /*
1571 * Allocate a new depth buffer. If there's already a depth buffer allocated
1572 * it will be free()'d. The new depth buffer will be uniniitalized.
1573 * This function is only called through Driver.alloc_depth_buffer.
1574 */
1575 void
1576 _mesa_alloc_depth_buffer( GLcontext *ctx )
1577 {
1578 /* deallocate current depth buffer if present */
1579 if (ctx->DrawBuffer->UseSoftwareDepthBuffer) {
1580 GLint bytesPerValue;
1581
1582 if (ctx->DrawBuffer->DepthBuffer) {
1583 FREE(ctx->DrawBuffer->DepthBuffer);
1584 ctx->DrawBuffer->DepthBuffer = NULL;
1585 }
1586
1587 /* allocate new depth buffer, but don't initialize it */
1588 if (ctx->Visual->DepthBits <= 16)
1589 bytesPerValue = sizeof(GLushort);
1590 else
1591 bytesPerValue = sizeof(GLuint);
1592
1593 ctx->DrawBuffer->DepthBuffer = MALLOC( ctx->DrawBuffer->Width
1594 * ctx->DrawBuffer->Height
1595 * bytesPerValue );
1596
1597 if (!ctx->DrawBuffer->DepthBuffer) {
1598 /* out of memory */
1599 ctx->Depth.Test = GL_FALSE;
1600 ctx->NewState |= NEW_RASTER_OPS;
1601 gl_error( ctx, GL_OUT_OF_MEMORY, "Couldn't allocate depth buffer" );
1602 }
1603 }
1604 }
1605
1606
1607
1608
1609 /*
1610 * Clear the depth buffer. If the depth buffer doesn't exist yet we'll
1611 * allocate it now.
1612 * This function is only called through Driver.clear_depth_buffer.
1613 */
1614 void
1615 _mesa_clear_depth_buffer( GLcontext *ctx )
1616 {
1617 if (ctx->Visual->DepthBits == 0
1618 || !ctx->DrawBuffer->DepthBuffer
1619 || !ctx->Depth.Mask) {
1620 /* no depth buffer, or writing to it is disabled */
1621 return;
1622 }
1623
1624 /* The loops in this function have been written so the IRIX 5.3
1625 * C compiler can unroll them. Hopefully other compilers can too!
1626 */
1627
1628 if (ctx->Scissor.Enabled) {
1629 /* only clear scissor region */
1630 if (ctx->Visual->DepthBits <= 16) {
1631 const GLushort clearValue = (GLushort) (ctx->Depth.Clear * ctx->Visual->DepthMax);
1632 const GLint rows = ctx->DrawBuffer->Ymax - ctx->DrawBuffer->Ymin + 1;
1633 const GLint width = ctx->DrawBuffer->Width;
1634 GLushort *dRow = (GLushort *) ctx->DrawBuffer->DepthBuffer
1635 + ctx->DrawBuffer->Ymin * width + ctx->DrawBuffer->Xmin;
1636 GLint i, j;
1637 for (i = 0; i < rows; i++) {
1638 for (j = 0; j < width; j++) {
1639 dRow[j] = clearValue;
1640 }
1641 dRow += width;
1642 }
1643 }
1644 else {
1645 const GLuint clearValue = (GLuint) (ctx->Depth.Clear * ctx->Visual->DepthMax);
1646 const GLint rows = ctx->DrawBuffer->Ymax - ctx->DrawBuffer->Ymin + 1;
1647 const GLint width = ctx->DrawBuffer->Width;
1648 GLuint *dRow = (GLuint *) ctx->DrawBuffer->DepthBuffer
1649 + ctx->DrawBuffer->Ymin * width + ctx->DrawBuffer->Xmin;
1650 GLint i, j;
1651 for (i = 0; i < rows; i++) {
1652 for (j = 0; j < width; j++) {
1653 dRow[j] = clearValue;
1654 }
1655 dRow += width;
1656 }
1657 }
1658 }
1659 else {
1660 /* clear whole buffer */
1661 if (ctx->Visual->DepthBits <= 16) {
1662 const GLushort clearValue = (GLushort) (ctx->Depth.Clear * ctx->Visual->DepthMax);
1663 if ((clearValue & 0xff) == (clearValue >> 8)) {
1664 if (clearValue == 0) {
1665 BZERO(ctx->DrawBuffer->DepthBuffer,
1666 2*ctx->DrawBuffer->Width*ctx->DrawBuffer->Height);
1667 }
1668 else {
1669 /* lower and upper bytes of clear_value are same, use MEMSET */
1670 MEMSET( ctx->DrawBuffer->DepthBuffer, clearValue & 0xff,
1671 2 * ctx->DrawBuffer->Width * ctx->DrawBuffer->Height);
1672 }
1673 }
1674 else {
1675 GLushort *d = (GLushort *) ctx->DrawBuffer->DepthBuffer;
1676 GLint n = ctx->DrawBuffer->Width * ctx->DrawBuffer->Height;
1677 while (n >= 16) {
1678 d[0] = clearValue; d[1] = clearValue;
1679 d[2] = clearValue; d[3] = clearValue;
1680 d[4] = clearValue; d[5] = clearValue;
1681 d[6] = clearValue; d[7] = clearValue;
1682 d[8] = clearValue; d[9] = clearValue;
1683 d[10] = clearValue; d[11] = clearValue;
1684 d[12] = clearValue; d[13] = clearValue;
1685 d[14] = clearValue; d[15] = clearValue;
1686 d += 16;
1687 n -= 16;
1688 }
1689 while (n > 0) {
1690 *d++ = clearValue;
1691 n--;
1692 }
1693 }
1694 }
1695 else {
1696 /* >16 bit depth buffer */
1697 const GLuint clearValue = (GLuint) (ctx->Depth.Clear * ctx->Visual->DepthMax);
1698 if (clearValue == 0) {
1699 BZERO(ctx->DrawBuffer->DepthBuffer,
1700 ctx->DrawBuffer->Width*ctx->DrawBuffer->Height*sizeof(GLuint));
1701 }
1702 else {
1703 GLint n = ctx->DrawBuffer->Width * ctx->DrawBuffer->Height;
1704 GLuint *d = (GLuint *) ctx->DrawBuffer->DepthBuffer;
1705 while (n >= 16) {
1706 d[0] = clearValue; d[1] = clearValue;
1707 d[2] = clearValue; d[3] = clearValue;
1708 d[4] = clearValue; d[5] = clearValue;
1709 d[6] = clearValue; d[7] = clearValue;
1710 d[8] = clearValue; d[9] = clearValue;
1711 d[10] = clearValue; d[11] = clearValue;
1712 d[12] = clearValue; d[13] = clearValue;
1713 d[14] = clearValue; d[15] = clearValue;
1714 d += 16;
1715 n -= 16;
1716 }
1717 while (n > 0) {
1718 *d++ = clearValue;
1719 n--;
1720 }
1721 }
1722 }
1723 }
1724 }