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