source: trunk/src/opengl/mesa/depth.c@ 3993

Last change on this file since 3993 was 3598, checked in by jeroen, 25 years ago

* empty log message *

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