2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 #include "main/glheader.h"
27 #include "main/context.h"
28 #include "main/formats.h"
29 #include "main/macros.h"
30 #include "main/imports.h"
33 #include "s_context.h"
38 * Do depth test for a horizontal span of fragments.
39 * Input: zbuffer - array of z values in the zbuffer
40 * z - array of fragment z values
41 * Return: number of fragments which pass the test.
44 depth_test_span16( GLcontext
*ctx
, GLuint n
,
45 GLushort zbuffer
[], const GLuint z
[], GLubyte mask
[] )
49 /* switch cases ordered from most frequent to less frequent */
50 switch (ctx
->Depth
.Func
) {
52 if (ctx
->Depth
.Mask
) {
57 if (z
[i
] < zbuffer
[i
]) {
70 /* Don't update Z buffer */
74 if (z
[i
] < zbuffer
[i
]) {
86 if (ctx
->Depth
.Mask
) {
91 if (z
[i
] <= zbuffer
[i
]) {
102 /* Don't update Z buffer */
106 if (z
[i
] <= zbuffer
[i
]) {
118 if (ctx
->Depth
.Mask
) {
119 /* Update Z buffer */
123 if (z
[i
] >= zbuffer
[i
]) {
134 /* Don't update Z buffer */
138 if (z
[i
] >= zbuffer
[i
]) {
150 if (ctx
->Depth
.Mask
) {
151 /* Update Z buffer */
155 if (z
[i
] > zbuffer
[i
]) {
166 /* Don't update Z buffer */
170 if (z
[i
] > zbuffer
[i
]) {
182 if (ctx
->Depth
.Mask
) {
183 /* Update Z buffer */
187 if (z
[i
] != zbuffer
[i
]) {
198 /* Don't update Z buffer */
202 if (z
[i
] != zbuffer
[i
]) {
214 if (ctx
->Depth
.Mask
) {
215 /* Update Z buffer */
219 if (z
[i
] == zbuffer
[i
]) {
230 /* Don't update Z buffer */
234 if (z
[i
] == zbuffer
[i
]) {
246 if (ctx
->Depth
.Mask
) {
247 /* Update Z buffer */
257 /* Don't update Z buffer or mask */
262 memset(mask
, 0, n
* sizeof(GLubyte
));
265 _mesa_problem(ctx
, "Bad depth func in depth_test_span16");
273 depth_test_span32( GLcontext
*ctx
, GLuint n
,
274 GLuint zbuffer
[], const GLuint z
[], GLubyte mask
[] )
278 /* switch cases ordered from most frequent to less frequent */
279 switch (ctx
->Depth
.Func
) {
281 if (ctx
->Depth
.Mask
) {
282 /* Update Z buffer */
284 for (i
=0; i
<n
; i
++) {
286 if (z
[i
] < zbuffer
[i
]) {
299 /* Don't update Z buffer */
301 for (i
=0; i
<n
; i
++) {
303 if (z
[i
] < zbuffer
[i
]) {
315 if (ctx
->Depth
.Mask
) {
316 /* Update Z buffer */
320 if (z
[i
] <= zbuffer
[i
]) {
331 /* Don't update Z buffer */
335 if (z
[i
] <= zbuffer
[i
]) {
347 if (ctx
->Depth
.Mask
) {
348 /* Update Z buffer */
352 if (z
[i
] >= zbuffer
[i
]) {
363 /* Don't update Z buffer */
367 if (z
[i
] >= zbuffer
[i
]) {
379 if (ctx
->Depth
.Mask
) {
380 /* Update Z buffer */
384 if (z
[i
] > zbuffer
[i
]) {
395 /* Don't update Z buffer */
399 if (z
[i
] > zbuffer
[i
]) {
411 if (ctx
->Depth
.Mask
) {
412 /* Update Z buffer */
416 if (z
[i
] != zbuffer
[i
]) {
427 /* Don't update Z buffer */
431 if (z
[i
] != zbuffer
[i
]) {
443 if (ctx
->Depth
.Mask
) {
444 /* Update Z buffer */
448 if (z
[i
] == zbuffer
[i
]) {
459 /* Don't update Z buffer */
463 if (z
[i
] == zbuffer
[i
]) {
475 if (ctx
->Depth
.Mask
) {
476 /* Update Z buffer */
486 /* Don't update Z buffer or mask */
491 memset(mask
, 0, n
* sizeof(GLubyte
));
494 _mesa_problem(ctx
, "Bad depth func in depth_test_span32");
503 * Clamp fragment Z values to the depth near/far range (glDepthRange()).
504 * This is used when GL_ARB_depth_clamp/GL_DEPTH_CLAMP is turned on.
505 * In that case, vertexes are not clipped against the near/far planes
506 * so rasterization will produce fragment Z values outside the usual
510 _swrast_depth_clamp_span( GLcontext
*ctx
, SWspan
*span
)
512 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
513 const GLuint count
= span
->end
;
514 GLint
*zValues
= (GLint
*) span
->array
->z
; /* sign change */
516 GLfloat min_f
, max_f
;
519 if (ctx
->Viewport
.Near
< ctx
->Viewport
.Far
) {
520 min_f
= ctx
->Viewport
.Near
;
521 max_f
= ctx
->Viewport
.Far
;
523 min_f
= ctx
->Viewport
.Far
;
524 max_f
= ctx
->Viewport
.Near
;
527 /* Convert floating point values in [0,1] to device Z coordinates in
529 * ex: If the Z buffer has 24 bits, DepthMax = 0xffffff.
531 * XXX this all falls apart if we have 31 or more bits of Z because
532 * the triangle rasterization code produces unsigned Z values. Negative
533 * vertex Z values come out as large fragment Z uints.
535 min
= (GLint
) (min_f
* fb
->_DepthMaxF
);
536 max
= (GLint
) (max_f
* fb
->_DepthMaxF
);
538 max
= 0x7fffffff; /* catch over flow for 30-bit z */
540 /* Note that we do the comparisons here using signed integers.
542 for (i
= 0; i
< count
; i
++) {
543 if (zValues
[i
] < min
)
545 if (zValues
[i
] > max
)
553 * Apply depth test to span of fragments.
556 depth_test_span( GLcontext
*ctx
, SWspan
*span
)
558 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
559 struct gl_renderbuffer
*rb
= fb
->_DepthBuffer
;
560 const GLint x
= span
->x
;
561 const GLint y
= span
->y
;
562 const GLuint count
= span
->end
;
563 const GLuint
*zValues
= span
->array
->z
;
564 GLubyte
*mask
= span
->array
->mask
;
567 ASSERT((span
->arrayMask
& SPAN_XY
) == 0);
568 ASSERT(span
->arrayMask
& SPAN_Z
);
570 if (rb
->GetPointer(ctx
, rb
, 0, 0)) {
571 /* Directly access buffer */
572 if (rb
->DataType
== GL_UNSIGNED_SHORT
) {
573 GLushort
*zbuffer
= (GLushort
*) rb
->GetPointer(ctx
, rb
, x
, y
);
574 passed
= depth_test_span16(ctx
, count
, zbuffer
, zValues
, mask
);
577 GLuint
*zbuffer
= (GLuint
*) rb
->GetPointer(ctx
, rb
, x
, y
);
578 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
);
579 passed
= depth_test_span32(ctx
, count
, zbuffer
, zValues
, mask
);
583 /* read depth values from buffer, test, write back */
584 if (rb
->DataType
== GL_UNSIGNED_SHORT
) {
585 GLushort zbuffer
[MAX_WIDTH
];
586 rb
->GetRow(ctx
, rb
, count
, x
, y
, zbuffer
);
587 passed
= depth_test_span16(ctx
, count
, zbuffer
, zValues
, mask
);
588 rb
->PutRow(ctx
, rb
, count
, x
, y
, zbuffer
, mask
);
591 GLuint zbuffer
[MAX_WIDTH
];
592 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
);
593 rb
->GetRow(ctx
, rb
, count
, x
, y
, zbuffer
);
594 passed
= depth_test_span32(ctx
, count
, zbuffer
, zValues
, mask
);
595 rb
->PutRow(ctx
, rb
, count
, x
, y
, zbuffer
, mask
);
599 if (passed
< count
) {
600 span
->writeAll
= GL_FALSE
;
607 #define Z_ADDRESS(X, Y) (zStart + (Y) * stride + (X))
611 * Do depth testing for an array of fragments at assorted locations.
614 direct_depth_test_pixels16(GLcontext
*ctx
, GLushort
*zStart
, GLuint stride
,
615 GLuint n
, const GLint x
[], const GLint y
[],
616 const GLuint z
[], GLubyte mask
[] )
618 /* switch cases ordered from most frequent to less frequent */
619 switch (ctx
->Depth
.Func
) {
621 if (ctx
->Depth
.Mask
) {
622 /* Update Z buffer */
624 for (i
=0; i
<n
; i
++) {
626 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
639 /* Don't update Z buffer */
641 for (i
=0; i
<n
; i
++) {
643 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
656 if (ctx
->Depth
.Mask
) {
657 /* Update Z buffer */
659 for (i
=0; i
<n
; i
++) {
661 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
674 /* Don't update Z buffer */
676 for (i
=0; i
<n
; i
++) {
678 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
691 if (ctx
->Depth
.Mask
) {
692 /* Update Z buffer */
694 for (i
=0; i
<n
; i
++) {
696 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
709 /* Don't update Z buffer */
711 for (i
=0; i
<n
; i
++) {
713 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
726 if (ctx
->Depth
.Mask
) {
727 /* Update Z buffer */
729 for (i
=0; i
<n
; i
++) {
731 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
744 /* Don't update Z buffer */
746 for (i
=0; i
<n
; i
++) {
748 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
761 if (ctx
->Depth
.Mask
) {
762 /* Update Z buffer */
764 for (i
=0; i
<n
; i
++) {
766 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
779 /* Don't update Z buffer */
781 for (i
=0; i
<n
; i
++) {
783 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
796 if (ctx
->Depth
.Mask
) {
797 /* Update Z buffer */
799 for (i
=0; i
<n
; i
++) {
801 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
814 /* Don't update Z buffer */
816 for (i
=0; i
<n
; i
++) {
818 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
831 if (ctx
->Depth
.Mask
) {
832 /* Update Z buffer */
834 for (i
=0; i
<n
; i
++) {
836 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
842 /* Don't update Z buffer or mask */
846 /* depth test never passes */
847 memset(mask
, 0, n
* sizeof(GLubyte
));
850 _mesa_problem(ctx
, "Bad depth func in direct_depth_test_pixels");
857 * Do depth testing for an array of fragments with direct access to zbuffer.
860 direct_depth_test_pixels32(GLcontext
*ctx
, GLuint
*zStart
, GLuint stride
,
861 GLuint n
, const GLint x
[], const GLint y
[],
862 const GLuint z
[], GLubyte mask
[] )
864 /* switch cases ordered from most frequent to less frequent */
865 switch (ctx
->Depth
.Func
) {
867 if (ctx
->Depth
.Mask
) {
868 /* Update Z buffer */
870 for (i
=0; i
<n
; i
++) {
872 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
885 /* Don't update Z buffer */
887 for (i
=0; i
<n
; i
++) {
889 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
902 if (ctx
->Depth
.Mask
) {
903 /* Update Z buffer */
905 for (i
=0; i
<n
; i
++) {
907 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
920 /* Don't update Z buffer */
922 for (i
=0; i
<n
; i
++) {
924 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
937 if (ctx
->Depth
.Mask
) {
938 /* Update Z buffer */
940 for (i
=0; i
<n
; i
++) {
942 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
955 /* Don't update Z buffer */
957 for (i
=0; i
<n
; i
++) {
959 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
972 if (ctx
->Depth
.Mask
) {
973 /* Update Z buffer */
975 for (i
=0; i
<n
; i
++) {
977 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
990 /* Don't update Z buffer */
992 for (i
=0; i
<n
; i
++) {
994 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
1007 if (ctx
->Depth
.Mask
) {
1008 /* Update Z buffer */
1010 for (i
=0; i
<n
; i
++) {
1012 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
1013 if (z
[i
] != *zptr
) {
1025 /* Don't update Z buffer */
1027 for (i
=0; i
<n
; i
++) {
1029 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
1030 if (z
[i
] != *zptr
) {
1042 if (ctx
->Depth
.Mask
) {
1043 /* Update Z buffer */
1045 for (i
=0; i
<n
; i
++) {
1047 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
1048 if (z
[i
] == *zptr
) {
1060 /* Don't update Z buffer */
1062 for (i
=0; i
<n
; i
++) {
1064 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
1065 if (z
[i
] == *zptr
) {
1077 if (ctx
->Depth
.Mask
) {
1078 /* Update Z buffer */
1080 for (i
=0; i
<n
; i
++) {
1082 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
1088 /* Don't update Z buffer or mask */
1092 /* depth test never passes */
1093 memset(mask
, 0, n
* sizeof(GLubyte
));
1096 _mesa_problem(ctx
, "Bad depth func in direct_depth_test_pixels");
1104 depth_test_pixels( GLcontext
*ctx
, SWspan
*span
)
1106 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
1107 struct gl_renderbuffer
*rb
= fb
->_DepthBuffer
;
1108 const GLuint count
= span
->end
;
1109 const GLint
*x
= span
->array
->x
;
1110 const GLint
*y
= span
->array
->y
;
1111 const GLuint
*z
= span
->array
->z
;
1112 GLubyte
*mask
= span
->array
->mask
;
1114 if (rb
->GetPointer(ctx
, rb
, 0, 0)) {
1115 /* Directly access values */
1116 if (rb
->DataType
== GL_UNSIGNED_SHORT
) {
1117 GLushort
*zStart
= (GLushort
*) rb
->Data
;
1118 GLuint stride
= rb
->Width
;
1119 direct_depth_test_pixels16(ctx
, zStart
, stride
, count
, x
, y
, z
, mask
);
1122 GLuint
*zStart
= (GLuint
*) rb
->Data
;
1123 GLuint stride
= rb
->Width
;
1124 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
);
1125 direct_depth_test_pixels32(ctx
, zStart
, stride
, count
, x
, y
, z
, mask
);
1129 /* read depth values from buffer, test, write back */
1130 if (rb
->DataType
== GL_UNSIGNED_SHORT
) {
1131 GLushort zbuffer
[MAX_WIDTH
];
1132 _swrast_get_values(ctx
, rb
, count
, x
, y
, zbuffer
, sizeof(GLushort
));
1133 depth_test_span16(ctx
, count
, zbuffer
, z
, mask
);
1134 rb
->PutValues(ctx
, rb
, count
, x
, y
, zbuffer
, mask
);
1137 GLuint zbuffer
[MAX_WIDTH
];
1138 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
);
1139 _swrast_get_values(ctx
, rb
, count
, x
, y
, zbuffer
, sizeof(GLuint
));
1140 depth_test_span32(ctx
, count
, zbuffer
, z
, mask
);
1141 rb
->PutValues(ctx
, rb
, count
, x
, y
, zbuffer
, mask
);
1145 return count
; /* not really correct, but OK */
1150 * Apply depth (Z) buffer testing to the span.
1151 * \return approx number of pixels that passed (only zero is reliable)
1154 _swrast_depth_test_span( GLcontext
*ctx
, SWspan
*span
)
1156 if (span
->arrayMask
& SPAN_XY
)
1157 return depth_test_pixels(ctx
, span
);
1159 return depth_test_span(ctx
, span
);
1164 * GL_EXT_depth_bounds_test extension.
1165 * Discard fragments depending on whether the corresponding Z-buffer
1166 * values are outside the depth bounds test range.
1167 * Note: we test the Z buffer values, not the fragment Z values!
1168 * \return GL_TRUE if any fragments pass, GL_FALSE if no fragments pass
1171 _swrast_depth_bounds_test( GLcontext
*ctx
, SWspan
*span
)
1173 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
1174 struct gl_renderbuffer
*rb
= fb
->_DepthBuffer
;
1175 GLuint zMin
= (GLuint
) (ctx
->Depth
.BoundsMin
* fb
->_DepthMaxF
+ 0.5F
);
1176 GLuint zMax
= (GLuint
) (ctx
->Depth
.BoundsMax
* fb
->_DepthMaxF
+ 0.5F
);
1177 GLubyte
*mask
= span
->array
->mask
;
1178 const GLuint count
= span
->end
;
1180 GLboolean anyPass
= GL_FALSE
;
1182 if (rb
->DataType
== GL_UNSIGNED_SHORT
) {
1183 /* get 16-bit values */
1184 GLushort zbuffer16
[MAX_WIDTH
], *zbuffer
;
1185 if (span
->arrayMask
& SPAN_XY
) {
1186 _swrast_get_values(ctx
, rb
, count
, span
->array
->x
, span
->array
->y
,
1187 zbuffer16
, sizeof(GLushort
));
1188 zbuffer
= zbuffer16
;
1191 zbuffer
= (GLushort
*) rb
->GetPointer(ctx
, rb
, span
->x
, span
->y
);
1193 rb
->GetRow(ctx
, rb
, count
, span
->x
, span
->y
, zbuffer16
);
1194 zbuffer
= zbuffer16
;
1199 /* Now do the tests */
1200 for (i
= 0; i
< count
; i
++) {
1202 if (zbuffer
[i
] < zMin
|| zbuffer
[i
] > zMax
)
1210 /* get 32-bit values */
1211 GLuint zbuffer32
[MAX_WIDTH
], *zbuffer
;
1212 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
);
1213 if (span
->arrayMask
& SPAN_XY
) {
1214 _swrast_get_values(ctx
, rb
, count
, span
->array
->x
, span
->array
->y
,
1215 zbuffer32
, sizeof(GLuint
));
1216 zbuffer
= zbuffer32
;
1219 zbuffer
= (GLuint
*) rb
->GetPointer(ctx
, rb
, span
->x
, span
->y
);
1221 rb
->GetRow(ctx
, rb
, count
, span
->x
, span
->y
, zbuffer32
);
1222 zbuffer
= zbuffer32
;
1227 /* Now do the tests */
1228 for (i
= 0; i
< count
; i
++) {
1230 if (zbuffer
[i
] < zMin
|| zbuffer
[i
] > zMax
)
1243 /**********************************************************************/
1244 /***** Read Depth Buffer *****/
1245 /**********************************************************************/
1249 * Read a span of depth values from the given depth renderbuffer, returning
1250 * the values as GLfloats.
1251 * This function does clipping to prevent reading outside the depth buffer's
1252 * bounds. Though the clipping is redundant when we're called from
1253 * _swrast_ReadPixels.
1256 _swrast_read_depth_span_float( GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
1257 GLint n
, GLint x
, GLint y
, GLfloat depth
[] )
1259 const GLfloat scale
= 1.0F
/ ctx
->DrawBuffer
->_DepthMaxF
;
1262 /* really only doing this to prevent FP exceptions later */
1263 memset(depth
, 0, n
* sizeof(GLfloat
));
1267 ASSERT(rb
->_BaseFormat
== GL_DEPTH_COMPONENT
);
1269 if (y
< 0 || y
>= (GLint
) rb
->Height
||
1270 x
+ n
<= 0 || x
>= (GLint
) rb
->Width
) {
1271 /* span is completely outside framebuffer */
1272 memset(depth
, 0, n
* sizeof(GLfloat
));
1279 for (i
= 0; i
< dx
; i
++)
1285 if (x
+ n
> (GLint
) rb
->Width
) {
1286 GLint dx
= x
+ n
- (GLint
) rb
->Width
;
1288 for (i
= 0; i
< dx
; i
++)
1289 depth
[n
- i
- 1] = 0.0;
1296 if (rb
->DataType
== GL_UNSIGNED_INT
) {
1297 GLuint temp
[MAX_WIDTH
];
1299 rb
->GetRow(ctx
, rb
, n
, x
, y
, temp
);
1300 for (i
= 0; i
< n
; i
++) {
1301 depth
[i
] = temp
[i
] * scale
;
1304 else if (rb
->DataType
== GL_UNSIGNED_SHORT
) {
1305 GLushort temp
[MAX_WIDTH
];
1307 rb
->GetRow(ctx
, rb
, n
, x
, y
, temp
);
1308 for (i
= 0; i
< n
; i
++) {
1309 depth
[i
] = temp
[i
] * scale
;
1313 _mesa_problem(ctx
, "Invalid depth renderbuffer data type");
1319 * As above, but return 32-bit GLuint values.
1322 _swrast_read_depth_span_uint( GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
1323 GLint n
, GLint x
, GLint y
, GLuint depth
[] )
1328 /* really only doing this to prevent FP exceptions later */
1329 memset(depth
, 0, n
* sizeof(GLuint
));
1333 depthBits
= _mesa_get_format_bits(rb
->Format
, GL_DEPTH_BITS
);
1335 ASSERT(rb
->_BaseFormat
== GL_DEPTH_COMPONENT
);
1337 if (y
< 0 || y
>= (GLint
) rb
->Height
||
1338 x
+ n
<= 0 || x
>= (GLint
) rb
->Width
) {
1339 /* span is completely outside framebuffer */
1340 memset(depth
, 0, n
* sizeof(GLfloat
));
1347 for (i
= 0; i
< dx
; i
++)
1353 if (x
+ n
> (GLint
) rb
->Width
) {
1354 GLint dx
= x
+ n
- (GLint
) rb
->Width
;
1356 for (i
= 0; i
< dx
; i
++)
1357 depth
[n
- i
- 1] = 0;
1364 if (rb
->DataType
== GL_UNSIGNED_INT
) {
1365 rb
->GetRow(ctx
, rb
, n
, x
, y
, depth
);
1366 if (depthBits
< 32) {
1367 GLuint shift
= 32 - depthBits
;
1369 for (i
= 0; i
< n
; i
++) {
1370 GLuint z
= depth
[i
];
1371 depth
[i
] = z
<< shift
; /* XXX lsb bits? */
1375 else if (rb
->DataType
== GL_UNSIGNED_SHORT
) {
1376 GLushort temp
[MAX_WIDTH
];
1378 rb
->GetRow(ctx
, rb
, n
, x
, y
, temp
);
1379 if (depthBits
== 16) {
1380 for (i
= 0; i
< n
; i
++) {
1382 depth
[i
] = (z
<< 16) | z
;
1386 GLuint shift
= 16 - depthBits
;
1387 for (i
= 0; i
< n
; i
++) {
1389 depth
[i
] = (z
<< (shift
+ 16)) | (z
<< shift
); /* XXX lsb bits? */
1394 _mesa_problem(ctx
, "Invalid depth renderbuffer data type");
1401 * Clear the given z/depth renderbuffer.
1404 _swrast_clear_depth_buffer( GLcontext
*ctx
, struct gl_renderbuffer
*rb
)
1407 GLint x
, y
, width
, height
;
1409 if (!rb
|| !ctx
->Depth
.Mask
) {
1410 /* no depth buffer, or writing to it is disabled */
1414 /* compute integer clearing value */
1415 if (ctx
->Depth
.Clear
== 1.0) {
1416 clearValue
= ctx
->DrawBuffer
->_DepthMax
;
1419 clearValue
= (GLuint
) (ctx
->Depth
.Clear
* ctx
->DrawBuffer
->_DepthMaxF
);
1422 assert(rb
->_BaseFormat
== GL_DEPTH_COMPONENT
);
1424 /* compute region to clear */
1425 x
= ctx
->DrawBuffer
->_Xmin
;
1426 y
= ctx
->DrawBuffer
->_Ymin
;
1427 width
= ctx
->DrawBuffer
->_Xmax
- ctx
->DrawBuffer
->_Xmin
;
1428 height
= ctx
->DrawBuffer
->_Ymax
- ctx
->DrawBuffer
->_Ymin
;
1430 if (rb
->GetPointer(ctx
, rb
, 0, 0)) {
1431 /* Direct buffer access is possible. Either this is just malloc'd
1432 * memory, or perhaps the driver mmap'd the zbuffer memory.
1434 if (rb
->DataType
== GL_UNSIGNED_SHORT
) {
1435 if ((clearValue
& 0xff) == ((clearValue
>> 8) & 0xff) &&
1436 ((GLushort
*) rb
->GetPointer(ctx
, rb
, 0, 0) + width
==
1437 (GLushort
*) rb
->GetPointer(ctx
, rb
, 0, 1))) {
1438 /* optimized case */
1439 GLushort
*dst
= (GLushort
*) rb
->GetPointer(ctx
, rb
, x
, y
);
1440 GLuint len
= width
* height
* sizeof(GLushort
);
1441 memset(dst
, (clearValue
& 0xff), len
);
1446 for (i
= 0; i
< height
; i
++) {
1447 GLushort
*dst
= (GLushort
*) rb
->GetPointer(ctx
, rb
, x
, y
+ i
);
1448 for (j
= 0; j
< width
; j
++) {
1449 dst
[j
] = clearValue
;
1456 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
);
1457 for (i
= 0; i
< height
; i
++) {
1458 GLuint
*dst
= (GLuint
*) rb
->GetPointer(ctx
, rb
, x
, y
+ i
);
1459 for (j
= 0; j
< width
; j
++) {
1460 dst
[j
] = clearValue
;
1466 /* Direct access not possible. Use PutRow to write new values. */
1467 if (rb
->DataType
== GL_UNSIGNED_SHORT
) {
1468 GLushort clearVal16
= (GLushort
) (clearValue
& 0xffff);
1470 for (i
= 0; i
< height
; i
++) {
1471 rb
->PutMonoRow(ctx
, rb
, width
, x
, y
+ i
, &clearVal16
, NULL
);
1474 else if (rb
->DataType
== GL_UNSIGNED_INT
) {
1476 ASSERT(sizeof(clearValue
) == sizeof(GLuint
));
1477 for (i
= 0; i
< height
; i
++) {
1478 rb
->PutMonoRow(ctx
, rb
, width
, x
, y
+ i
, &clearValue
, NULL
);
1482 _mesa_problem(ctx
, "bad depth renderbuffer DataType");