Subversion Repositories shark

Rev

Rev 57 | Details | Compare with Previous | Last modification | View Log | RSS feed

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