b2fa94757e3afd6f5df6bb21f3e939994a93282d
[mesa.git] / src / mesa / main / depth.c
1 /* $Id: depth.c,v 1.11 1999/12/10 19:09:22 brianp Exp $ */
2
3 /*
4 * Mesa 3-D graphics library
5 * Version: 3.3
6 *
7 * Copyright (C) 1999 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 /***** Depth Testing Functions *****/
129 /**********************************************************************/
130
131
132 /*
133 * Do depth test for an array of fragments. This is used both for
134 * software and hardware Z buffers.
135 * Input: zbuffer - array of z values in the zbuffer
136 * z - array of fragment z values
137 * Return: number of fragments which pass the test.
138 */
139 static GLuint
140 depth_test_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
141 GLdepth zbuffer[], const GLdepth z[], GLubyte mask[] )
142 {
143 GLuint passed = 0;
144
145 /* switch cases ordered from most frequent to less frequent */
146 switch (ctx->Depth.Func) {
147 case GL_LESS:
148 if (ctx->Depth.Mask) {
149 /* Update Z buffer */
150 GLuint i;
151 for (i=0; i<n; i++) {
152 if (mask[i]) {
153 if (z[i] < zbuffer[i]) {
154 /* pass */
155 zbuffer[i] = z[i];
156 passed++;
157 }
158 else {
159 /* fail */
160 mask[i] = 0;
161 }
162 }
163 }
164 }
165 else {
166 /* Don't update Z buffer */
167 GLuint i;
168 for (i=0; i<n; i++) {
169 if (mask[i]) {
170 if (z[i] < zbuffer[i]) {
171 /* pass */
172 passed++;
173 }
174 else {
175 mask[i] = 0;
176 }
177 }
178 }
179 }
180 break;
181 case GL_LEQUAL:
182 if (ctx->Depth.Mask) {
183 /* Update Z buffer */
184 GLuint i;
185 for (i=0;i<n;i++) {
186 if (mask[i]) {
187 if (z[i] <= zbuffer[i]) {
188 zbuffer[i] = z[i];
189 passed++;
190 }
191 else {
192 mask[i] = 0;
193 }
194 }
195 }
196 }
197 else {
198 /* Don't update Z buffer */
199 GLuint i;
200 for (i=0;i<n;i++) {
201 if (mask[i]) {
202 if (z[i] <= zbuffer[i]) {
203 /* pass */
204 passed++;
205 }
206 else {
207 mask[i] = 0;
208 }
209 }
210 }
211 }
212 break;
213 case GL_GEQUAL:
214 if (ctx->Depth.Mask) {
215 /* Update Z buffer */
216 GLuint i;
217 for (i=0;i<n;i++) {
218 if (mask[i]) {
219 if (z[i] >= zbuffer[i]) {
220 zbuffer[i] = z[i];
221 passed++;
222 }
223 else {
224 mask[i] = 0;
225 }
226 }
227 }
228 }
229 else {
230 /* Don't update Z buffer */
231 GLuint i;
232 for (i=0;i<n;i++) {
233 if (mask[i]) {
234 if (z[i] >= zbuffer[i]) {
235 /* pass */
236 passed++;
237 }
238 else {
239 mask[i] = 0;
240 }
241 }
242 }
243 }
244 break;
245 case GL_GREATER:
246 if (ctx->Depth.Mask) {
247 /* Update Z buffer */
248 GLuint i;
249 for (i=0;i<n;i++) {
250 if (mask[i]) {
251 if (z[i] > zbuffer[i]) {
252 zbuffer[i] = z[i];
253 passed++;
254 }
255 else {
256 mask[i] = 0;
257 }
258 }
259 }
260 }
261 else {
262 /* Don't update Z buffer */
263 GLuint i;
264 for (i=0;i<n;i++) {
265 if (mask[i]) {
266 if (z[i] > zbuffer[i]) {
267 /* pass */
268 passed++;
269 }
270 else {
271 mask[i] = 0;
272 }
273 }
274 }
275 }
276 break;
277 case GL_NOTEQUAL:
278 if (ctx->Depth.Mask) {
279 /* Update Z buffer */
280 GLuint i;
281 for (i=0;i<n;i++) {
282 if (mask[i]) {
283 if (z[i] != zbuffer[i]) {
284 zbuffer[i] = z[i];
285 passed++;
286 }
287 else {
288 mask[i] = 0;
289 }
290 }
291 }
292 }
293 else {
294 /* Don't update Z buffer */
295 GLuint i;
296 for (i=0;i<n;i++) {
297 if (mask[i]) {
298 if (z[i] != zbuffer[i]) {
299 /* pass */
300 passed++;
301 }
302 else {
303 mask[i] = 0;
304 }
305 }
306 }
307 }
308 break;
309 case GL_EQUAL:
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 zbuffer[i] = z[i];
317 passed++;
318 }
319 else {
320 mask[i] = 0;
321 }
322 }
323 }
324 }
325 else {
326 /* Don't update Z buffer */
327 GLuint i;
328 for (i=0;i<n;i++) {
329 if (mask[i]) {
330 if (z[i] == zbuffer[i]) {
331 /* pass */
332 passed++;
333 }
334 else {
335 mask[i] = 0;
336 }
337 }
338 }
339 }
340 break;
341 case GL_ALWAYS:
342 if (ctx->Depth.Mask) {
343 /* Update Z buffer */
344 GLuint i;
345 for (i=0;i<n;i++) {
346 if (mask[i]) {
347 zbuffer[i] = z[i];
348 passed++;
349 }
350 }
351 }
352 else {
353 /* Don't update Z buffer or mask */
354 passed = n;
355 }
356 break;
357 case GL_NEVER:
358 MEMSET(mask, 0, n * sizeof(GLubyte));
359 break;
360 default:
361 gl_problem(ctx, "Bad depth func in depth_test_span");
362 }
363
364 return passed;
365 }
366
367
368
369 /*
370 * Apply depth test to span of fragments. Hardware or software z buffer.
371 */
372 GLuint
373 gl_depth_test_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
374 const GLdepth z[], GLubyte mask[] )
375 {
376 GLdepth zbuffer[MAX_WIDTH];
377 GLdepth *zptr;
378 GLuint passed;
379
380 if (ctx->Driver.ReadDepthSpan) {
381 /* read depth values out of hardware Z buffer */
382 (*ctx->Driver.ReadDepthSpan)(ctx, n, x, y, zbuffer);
383 zptr = zbuffer;
384 }
385 else {
386 /* test against software depth buffer values */
387 zptr = Z_ADDRESS( ctx, x, y );
388 }
389
390 passed = depth_test_span( ctx, n, x, y, zptr, z, mask );
391
392 if (ctx->Driver.WriteDepthSpan) {
393 /* write updated depth values into hardware Z buffer */
394 assert(zptr == zbuffer);
395 (*ctx->Driver.WriteDepthSpan)(ctx, n, x, y, zbuffer, mask);
396 }
397
398 return passed;
399 }
400
401
402
403
404 /*
405 * Do depth testing for an array of fragments using software Z buffer.
406 */
407 static void
408 software_depth_test_pixels( GLcontext *ctx, GLuint n,
409 const GLint x[], const GLint y[],
410 const GLdepth z[], GLubyte mask[] )
411 {
412 /* switch cases ordered from most frequent to less frequent */
413 switch (ctx->Depth.Func) {
414 case GL_LESS:
415 if (ctx->Depth.Mask) {
416 /* Update Z buffer */
417 GLuint i;
418 for (i=0; i<n; i++) {
419 if (mask[i]) {
420 GLdepth *zptr = Z_ADDRESS(ctx,x[i],y[i]);
421 if (z[i] < *zptr) {
422 /* pass */
423 *zptr = z[i];
424 }
425 else {
426 /* fail */
427 mask[i] = 0;
428 }
429 }
430 }
431 }
432 else {
433 /* Don't update Z buffer */
434 GLuint i;
435 for (i=0; i<n; i++) {
436 if (mask[i]) {
437 GLdepth *zptr = Z_ADDRESS(ctx,x[i],y[i]);
438 if (z[i] < *zptr) {
439 /* pass */
440 }
441 else {
442 /* fail */
443 mask[i] = 0;
444 }
445 }
446 }
447 }
448 break;
449 case GL_LEQUAL:
450 if (ctx->Depth.Mask) {
451 /* Update Z buffer */
452 GLuint i;
453 for (i=0; i<n; i++) {
454 if (mask[i]) {
455 GLdepth *zptr = Z_ADDRESS(ctx,x[i],y[i]);
456 if (z[i] <= *zptr) {
457 /* pass */
458 *zptr = z[i];
459 }
460 else {
461 /* fail */
462 mask[i] = 0;
463 }
464 }
465 }
466 }
467 else {
468 /* Don't update Z buffer */
469 GLuint i;
470 for (i=0; i<n; i++) {
471 if (mask[i]) {
472 GLdepth *zptr = Z_ADDRESS(ctx,x[i],y[i]);
473 if (z[i] <= *zptr) {
474 /* pass */
475 }
476 else {
477 /* fail */
478 mask[i] = 0;
479 }
480 }
481 }
482 }
483 break;
484 case GL_GEQUAL:
485 if (ctx->Depth.Mask) {
486 /* Update Z buffer */
487 GLuint i;
488 for (i=0; i<n; i++) {
489 if (mask[i]) {
490 GLdepth *zptr = Z_ADDRESS(ctx,x[i],y[i]);
491 if (z[i] >= *zptr) {
492 /* pass */
493 *zptr = z[i];
494 }
495 else {
496 /* fail */
497 mask[i] = 0;
498 }
499 }
500 }
501 }
502 else {
503 /* Don't update Z buffer */
504 GLuint i;
505 for (i=0; i<n; i++) {
506 if (mask[i]) {
507 GLdepth *zptr = Z_ADDRESS(ctx,x[i],y[i]);
508 if (z[i] >= *zptr) {
509 /* pass */
510 }
511 else {
512 /* fail */
513 mask[i] = 0;
514 }
515 }
516 }
517 }
518 break;
519 case GL_GREATER:
520 if (ctx->Depth.Mask) {
521 /* Update Z buffer */
522 GLuint i;
523 for (i=0; i<n; i++) {
524 if (mask[i]) {
525 GLdepth *zptr = Z_ADDRESS(ctx,x[i],y[i]);
526 if (z[i] > *zptr) {
527 /* pass */
528 *zptr = z[i];
529 }
530 else {
531 /* fail */
532 mask[i] = 0;
533 }
534 }
535 }
536 }
537 else {
538 /* Don't update Z buffer */
539 GLuint i;
540 for (i=0; i<n; i++) {
541 if (mask[i]) {
542 GLdepth *zptr = Z_ADDRESS(ctx,x[i],y[i]);
543 if (z[i] > *zptr) {
544 /* pass */
545 }
546 else {
547 /* fail */
548 mask[i] = 0;
549 }
550 }
551 }
552 }
553 break;
554 case GL_NOTEQUAL:
555 if (ctx->Depth.Mask) {
556 /* Update Z buffer */
557 GLuint i;
558 for (i=0; i<n; i++) {
559 if (mask[i]) {
560 GLdepth *zptr = Z_ADDRESS(ctx,x[i],y[i]);
561 if (z[i] != *zptr) {
562 /* pass */
563 *zptr = z[i];
564 }
565 else {
566 /* fail */
567 mask[i] = 0;
568 }
569 }
570 }
571 }
572 else {
573 /* Don't update Z buffer */
574 GLuint i;
575 for (i=0; i<n; i++) {
576 if (mask[i]) {
577 GLdepth *zptr = Z_ADDRESS(ctx,x[i],y[i]);
578 if (z[i] != *zptr) {
579 /* pass */
580 }
581 else {
582 /* fail */
583 mask[i] = 0;
584 }
585 }
586 }
587 }
588 break;
589 case GL_EQUAL:
590 if (ctx->Depth.Mask) {
591 /* Update Z buffer */
592 GLuint i;
593 for (i=0; i<n; i++) {
594 if (mask[i]) {
595 GLdepth *zptr = Z_ADDRESS(ctx,x[i],y[i]);
596 if (z[i] == *zptr) {
597 /* pass */
598 *zptr = z[i];
599 }
600 else {
601 /* fail */
602 mask[i] = 0;
603 }
604 }
605 }
606 }
607 else {
608 /* Don't update Z buffer */
609 GLuint i;
610 for (i=0; i<n; i++) {
611 if (mask[i]) {
612 GLdepth *zptr = Z_ADDRESS(ctx,x[i],y[i]);
613 if (z[i] == *zptr) {
614 /* pass */
615 }
616 else {
617 /* fail */
618 mask[i] = 0;
619 }
620 }
621 }
622 }
623 break;
624 case GL_ALWAYS:
625 if (ctx->Depth.Mask) {
626 /* Update Z buffer */
627 GLuint i;
628 for (i=0; i<n; i++) {
629 if (mask[i]) {
630 GLdepth *zptr = Z_ADDRESS(ctx,x[i],y[i]);
631 *zptr = z[i];
632 }
633 }
634 }
635 else {
636 /* Don't update Z buffer or mask */
637 }
638 break;
639 case GL_NEVER:
640 /* depth test never passes */
641 MEMSET(mask, 0, n * sizeof(GLubyte));
642 break;
643 default:
644 gl_problem(ctx, "Bad depth func in software_depth_test_pixels");
645 }
646 }
647
648
649
650 /*
651 * Do depth testing for an array of pixels using hardware Z buffer.
652 * Input/output: zbuffer - array of depth values from Z buffer
653 * Input: z - array of fragment z values.
654 */
655 static void
656 hardware_depth_test_pixels( GLcontext *ctx, GLuint n, GLdepth zbuffer[],
657 const GLdepth z[], GLubyte mask[] )
658 {
659 /* switch cases ordered from most frequent to less frequent */
660 switch (ctx->Depth.Func) {
661 case GL_LESS:
662 if (ctx->Depth.Mask) {
663 /* Update Z buffer */
664 GLuint i;
665 for (i=0; i<n; i++) {
666 if (mask[i]) {
667 if (z[i] < zbuffer[i]) {
668 /* pass */
669 zbuffer[i] = z[i];
670 }
671 else {
672 /* fail */
673 mask[i] = 0;
674 }
675 }
676 }
677 }
678 else {
679 /* Don't update Z buffer */
680 GLuint i;
681 for (i=0; i<n; i++) {
682 if (mask[i]) {
683 if (z[i] < zbuffer[i]) {
684 /* pass */
685 }
686 else {
687 /* fail */
688 mask[i] = 0;
689 }
690 }
691 }
692 }
693 break;
694 case GL_LEQUAL:
695 if (ctx->Depth.Mask) {
696 /* Update Z buffer */
697 GLuint i;
698 for (i=0; i<n; i++) {
699 if (mask[i]) {
700 if (z[i] <= zbuffer[i]) {
701 /* pass */
702 zbuffer[i] = z[i];
703 }
704 else {
705 /* fail */
706 mask[i] = 0;
707 }
708 }
709 }
710 }
711 else {
712 /* Don't update Z buffer */
713 GLuint i;
714 for (i=0; i<n; i++) {
715 if (mask[i]) {
716 if (z[i] <= zbuffer[i]) {
717 /* pass */
718 }
719 else {
720 /* fail */
721 mask[i] = 0;
722 }
723 }
724 }
725 }
726 break;
727 case GL_GEQUAL:
728 if (ctx->Depth.Mask) {
729 /* Update Z buffer */
730 GLuint i;
731 for (i=0; i<n; i++) {
732 if (mask[i]) {
733 if (z[i] >= zbuffer[i]) {
734 /* pass */
735 zbuffer[i] = z[i];
736 }
737 else {
738 /* fail */
739 mask[i] = 0;
740 }
741 }
742 }
743 }
744 else {
745 /* Don't update Z buffer */
746 GLuint i;
747 for (i=0; i<n; i++) {
748 if (mask[i]) {
749 if (z[i] >= zbuffer[i]) {
750 /* pass */
751 }
752 else {
753 /* fail */
754 mask[i] = 0;
755 }
756 }
757 }
758 }
759 break;
760 case GL_GREATER:
761 if (ctx->Depth.Mask) {
762 /* Update Z buffer */
763 GLuint i;
764 for (i=0; i<n; i++) {
765 if (mask[i]) {
766 if (z[i] > zbuffer[i]) {
767 /* pass */
768 zbuffer[i] = z[i];
769 }
770 else {
771 /* fail */
772 mask[i] = 0;
773 }
774 }
775 }
776 }
777 else {
778 /* Don't update Z buffer */
779 GLuint i;
780 for (i=0; i<n; i++) {
781 if (mask[i]) {
782 if (z[i] > zbuffer[i]) {
783 /* pass */
784 }
785 else {
786 /* fail */
787 mask[i] = 0;
788 }
789 }
790 }
791 }
792 break;
793 case GL_NOTEQUAL:
794 if (ctx->Depth.Mask) {
795 /* Update Z buffer */
796 GLuint i;
797 for (i=0; i<n; i++) {
798 if (mask[i]) {
799 if (z[i] != zbuffer[i]) {
800 /* pass */
801 zbuffer[i] = z[i];
802 }
803 else {
804 /* fail */
805 mask[i] = 0;
806 }
807 }
808 }
809 }
810 else {
811 /* Don't update Z buffer */
812 GLuint i;
813 for (i=0; i<n; i++) {
814 if (mask[i]) {
815 if (z[i] != zbuffer[i]) {
816 /* pass */
817 }
818 else {
819 /* fail */
820 mask[i] = 0;
821 }
822 }
823 }
824 }
825 break;
826 case GL_EQUAL:
827 if (ctx->Depth.Mask) {
828 /* Update Z buffer */
829 GLuint i;
830 for (i=0; i<n; i++) {
831 if (mask[i]) {
832 if (z[i] == zbuffer[i]) {
833 /* pass */
834 zbuffer[i] = z[i];
835 }
836 else {
837 /* fail */
838 mask[i] = 0;
839 }
840 }
841 }
842 }
843 else {
844 /* Don't update Z buffer */
845 GLuint i;
846 for (i=0; i<n; i++) {
847 if (mask[i]) {
848 if (z[i] == zbuffer[i]) {
849 /* pass */
850 }
851 else {
852 /* fail */
853 mask[i] = 0;
854 }
855 }
856 }
857 }
858 break;
859 case GL_ALWAYS:
860 if (ctx->Depth.Mask) {
861 /* Update Z buffer */
862 GLuint i;
863 for (i=0; i<n; i++) {
864 if (mask[i]) {
865 zbuffer[i] = z[i];
866 }
867 }
868 }
869 else {
870 /* Don't update Z buffer or mask */
871 }
872 break;
873 case GL_NEVER:
874 /* depth test never passes */
875 MEMSET(mask, 0, n * sizeof(GLubyte));
876 break;
877 default:
878 gl_problem(ctx, "Bad depth func in hardware_depth_test_pixels");
879 }
880 }
881
882
883
884 void gl_depth_test_pixels( GLcontext *ctx,
885 GLuint n, const GLint x[], const GLint y[],
886 const GLdepth z[], GLubyte mask[] )
887 {
888 if (ctx->Driver.ReadDepthPixels) {
889 /* read depth values from hardware Z buffer */
890 GLdepth zbuffer[PB_SIZE];
891 (*ctx->Driver.ReadDepthPixels)(ctx, n, x, y, zbuffer);
892
893 hardware_depth_test_pixels( ctx, n, zbuffer, z, mask );
894
895 /* update hardware Z buffer with new values */
896 assert(ctx->Driver.WriteDepthPixels);
897 (*ctx->Driver.WriteDepthPixels)(ctx, n, x, y, z, mask );
898 }
899 else {
900 /* software depth testing */
901 software_depth_test_pixels(ctx, n, x, y, z, mask);
902 }
903 }
904
905
906
907
908
909 /**********************************************************************/
910 /***** Read Depth Buffer *****/
911 /**********************************************************************/
912
913
914 /*
915 * Return a span of depth values from the depth buffer as floats in [0,1].
916 * This is used for both hardware and software depth buffers.
917 * Input: n - how many pixels
918 * x,y - location of first pixel
919 * Output: depth - the array of depth values
920 */
921 void gl_read_depth_span_float( GLcontext* ctx,
922 GLuint n, GLint x, GLint y, GLfloat depth[] )
923 {
924 const GLfloat scale = 1.0F / DEPTH_SCALE;
925
926 if (ctx->DrawBuffer->Depth) {
927 /* read from software depth buffer */
928 const GLdepth *zptr = Z_ADDRESS( ctx, x, y );
929 GLuint i;
930 for (i = 0; i < n; i++) {
931 depth[i] = (GLfloat) zptr[i] * scale;
932 }
933 }
934 else if (ctx->Driver.ReadDepthSpan) {
935 /* read from hardware depth buffer */
936 GLdepth d[MAX_WIDTH];
937 GLuint i;
938 assert(n <= MAX_WIDTH);
939 (*ctx->Driver.ReadDepthSpan)( ctx, n, x, y, d );
940 for (i = 0; i < n; i++) {
941 depth[i] = d[i] * scale;
942 }
943 }
944 else {
945 /* no depth buffer */
946 MEMSET(depth, 0, n * sizeof(GLfloat));
947 }
948 }
949
950
951
952 /**********************************************************************/
953 /***** Allocate and Clear Depth Buffer *****/
954 /**********************************************************************/
955
956
957
958 /*
959 * Allocate a new depth buffer. If there's already a depth buffer allocated
960 * it will be free()'d. The new depth buffer will be uniniitalized.
961 * This function is only called through Driver.alloc_depth_buffer.
962 */
963 void gl_alloc_depth_buffer( GLcontext* ctx )
964 {
965 /* deallocate current depth buffer if present */
966 if (ctx->DrawBuffer->UseSoftwareDepthBuffer) {
967 if (ctx->DrawBuffer->Depth) {
968 FREE(ctx->DrawBuffer->Depth);
969 ctx->DrawBuffer->Depth = NULL;
970 }
971
972 /* allocate new depth buffer, but don't initialize it */
973 ctx->DrawBuffer->Depth = (GLdepth *) MALLOC( ctx->DrawBuffer->Width
974 * ctx->DrawBuffer->Height
975 * sizeof(GLdepth) );
976 if (!ctx->DrawBuffer->Depth) {
977 /* out of memory */
978 ctx->Depth.Test = GL_FALSE;
979 ctx->NewState |= NEW_RASTER_OPS;
980 gl_error( ctx, GL_OUT_OF_MEMORY, "Couldn't allocate depth buffer" );
981 }
982 }
983 }
984
985
986
987
988 /*
989 * Clear the depth buffer. If the depth buffer doesn't exist yet we'll
990 * allocate it now.
991 * This function is only called through Driver.clear_depth_buffer.
992 */
993 void gl_clear_depth_buffer( GLcontext* ctx )
994 {
995 GLdepth clear_value = (GLdepth) (ctx->Depth.Clear * DEPTH_SCALE);
996
997 if (ctx->Visual->DepthBits==0 || !ctx->DrawBuffer->Depth || !ctx->Depth.Mask) {
998 /* no depth buffer, or writing to it is disabled */
999 return;
1000 }
1001
1002 /* The loops in this function have been written so the IRIX 5.3
1003 * C compiler can unroll them. Hopefully other compilers can too!
1004 */
1005
1006 if (ctx->Scissor.Enabled) {
1007 /* only clear scissor region */
1008 GLint y;
1009 for (y=ctx->DrawBuffer->Ymin; y<=ctx->DrawBuffer->Ymax; y++) {
1010 GLdepth *d = Z_ADDRESS( ctx, ctx->DrawBuffer->Xmin, y );
1011 GLint n = ctx->DrawBuffer->Xmax - ctx->DrawBuffer->Xmin + 1;
1012 do {
1013 *d++ = clear_value;
1014 n--;
1015 } while (n);
1016 }
1017 }
1018 else {
1019 /* clear whole buffer */
1020 if (sizeof(GLdepth)==2 && (clear_value&0xff)==(clear_value>>8)) {
1021 /* lower and upper bytes of clear_value are same, use MEMSET */
1022 MEMSET( ctx->DrawBuffer->Depth, clear_value & 0xff,
1023 2*ctx->DrawBuffer->Width * ctx->DrawBuffer->Height);
1024 }
1025 else {
1026 GLdepth *d = ctx->DrawBuffer->Depth;
1027 GLint n = ctx->DrawBuffer->Width * ctx->DrawBuffer->Height;
1028 while (n>=16) {
1029 d[0] = clear_value; d[1] = clear_value;
1030 d[2] = clear_value; d[3] = clear_value;
1031 d[4] = clear_value; d[5] = clear_value;
1032 d[6] = clear_value; d[7] = clear_value;
1033 d[8] = clear_value; d[9] = clear_value;
1034 d[10] = clear_value; d[11] = clear_value;
1035 d[12] = clear_value; d[13] = clear_value;
1036 d[14] = clear_value; d[15] = clear_value;
1037 d += 16;
1038 n -= 16;
1039 }
1040 while (n>0) {
1041 *d++ = clear_value;
1042 n--;
1043 }
1044 }
1045 }
1046 }