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