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"
37 * Do depth test for a horizontal span of fragments.
38 * Input: zbuffer - array of z values in the zbuffer
39 * z - array of fragment z values
40 * Return: number of fragments which pass the test.
43 depth_test_span16( GLcontext
*ctx
, GLuint n
,
44 GLushort zbuffer
[], const GLuint z
[], GLubyte mask
[] )
48 /* switch cases ordered from most frequent to less frequent */
49 switch (ctx
->Depth
.Func
) {
51 if (ctx
->Depth
.Mask
) {
56 if (z
[i
] < zbuffer
[i
]) {
69 /* Don't update Z buffer */
73 if (z
[i
] < zbuffer
[i
]) {
85 if (ctx
->Depth
.Mask
) {
90 if (z
[i
] <= zbuffer
[i
]) {
101 /* Don't update Z buffer */
105 if (z
[i
] <= zbuffer
[i
]) {
117 if (ctx
->Depth
.Mask
) {
118 /* Update Z buffer */
122 if (z
[i
] >= zbuffer
[i
]) {
133 /* Don't update Z buffer */
137 if (z
[i
] >= zbuffer
[i
]) {
149 if (ctx
->Depth
.Mask
) {
150 /* Update Z buffer */
154 if (z
[i
] > zbuffer
[i
]) {
165 /* Don't update Z buffer */
169 if (z
[i
] > zbuffer
[i
]) {
181 if (ctx
->Depth
.Mask
) {
182 /* Update Z buffer */
186 if (z
[i
] != zbuffer
[i
]) {
197 /* Don't update Z buffer */
201 if (z
[i
] != zbuffer
[i
]) {
213 if (ctx
->Depth
.Mask
) {
214 /* Update Z buffer */
218 if (z
[i
] == zbuffer
[i
]) {
229 /* Don't update Z buffer */
233 if (z
[i
] == zbuffer
[i
]) {
245 if (ctx
->Depth
.Mask
) {
246 /* Update Z buffer */
256 /* Don't update Z buffer or mask */
261 memset(mask
, 0, n
* sizeof(GLubyte
));
264 _mesa_problem(ctx
, "Bad depth func in depth_test_span16");
272 depth_test_span32( GLcontext
*ctx
, GLuint n
,
273 GLuint zbuffer
[], const GLuint z
[], GLubyte mask
[] )
277 /* switch cases ordered from most frequent to less frequent */
278 switch (ctx
->Depth
.Func
) {
280 if (ctx
->Depth
.Mask
) {
281 /* Update Z buffer */
283 for (i
=0; i
<n
; i
++) {
285 if (z
[i
] < zbuffer
[i
]) {
298 /* Don't update Z buffer */
300 for (i
=0; i
<n
; i
++) {
302 if (z
[i
] < zbuffer
[i
]) {
314 if (ctx
->Depth
.Mask
) {
315 /* Update Z buffer */
319 if (z
[i
] <= zbuffer
[i
]) {
330 /* Don't update Z buffer */
334 if (z
[i
] <= zbuffer
[i
]) {
346 if (ctx
->Depth
.Mask
) {
347 /* Update Z buffer */
351 if (z
[i
] >= zbuffer
[i
]) {
362 /* Don't update Z buffer */
366 if (z
[i
] >= zbuffer
[i
]) {
378 if (ctx
->Depth
.Mask
) {
379 /* Update Z buffer */
383 if (z
[i
] > zbuffer
[i
]) {
394 /* Don't update Z buffer */
398 if (z
[i
] > zbuffer
[i
]) {
410 if (ctx
->Depth
.Mask
) {
411 /* Update Z buffer */
415 if (z
[i
] != zbuffer
[i
]) {
426 /* Don't update Z buffer */
430 if (z
[i
] != zbuffer
[i
]) {
442 if (ctx
->Depth
.Mask
) {
443 /* Update Z buffer */
447 if (z
[i
] == zbuffer
[i
]) {
458 /* Don't update Z buffer */
462 if (z
[i
] == zbuffer
[i
]) {
474 if (ctx
->Depth
.Mask
) {
475 /* Update Z buffer */
485 /* Don't update Z buffer or mask */
490 memset(mask
, 0, n
* sizeof(GLubyte
));
493 _mesa_problem(ctx
, "Bad depth func in depth_test_span32");
502 * Clamp fragment Z values to the depth near/far range (glDepthRange()).
503 * This is used when GL_ARB_depth_clamp/GL_DEPTH_CLAMP is turned on.
504 * In that case, vertexes are not clipped against the near/far planes
505 * so rasterization will produce fragment Z values outside the usual
509 _swrast_depth_clamp_span( GLcontext
*ctx
, SWspan
*span
)
511 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
512 const GLuint count
= span
->end
;
513 GLint
*zValues
= (GLint
*) span
->array
->z
; /* sign change */
515 GLfloat min_f
, max_f
;
518 if (ctx
->Viewport
.Near
< ctx
->Viewport
.Far
) {
519 min_f
= ctx
->Viewport
.Near
;
520 max_f
= ctx
->Viewport
.Far
;
522 min_f
= ctx
->Viewport
.Far
;
523 max_f
= ctx
->Viewport
.Near
;
526 /* Convert floating point values in [0,1] to device Z coordinates in
528 * ex: If the Z buffer has 24 bits, DepthMax = 0xffffff.
530 * XXX this all falls apart if we have 31 or more bits of Z because
531 * the triangle rasterization code produces unsigned Z values. Negative
532 * vertex Z values come out as large fragment Z uints.
534 min
= (GLint
) (min_f
* fb
->_DepthMaxF
);
535 max
= (GLint
) (max_f
* fb
->_DepthMaxF
);
537 max
= 0x7fffffff; /* catch over flow for 30-bit z */
539 /* Note that we do the comparisons here using signed integers.
541 for (i
= 0; i
< count
; i
++) {
542 if (zValues
[i
] < min
)
544 if (zValues
[i
] > max
)
552 * Apply depth test to span of fragments.
555 depth_test_span( GLcontext
*ctx
, SWspan
*span
)
557 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
558 struct gl_renderbuffer
*rb
= fb
->_DepthBuffer
;
559 const GLint x
= span
->x
;
560 const GLint y
= span
->y
;
561 const GLuint count
= span
->end
;
562 const GLuint
*zValues
= span
->array
->z
;
563 GLubyte
*mask
= span
->array
->mask
;
566 ASSERT((span
->arrayMask
& SPAN_XY
) == 0);
567 ASSERT(span
->arrayMask
& SPAN_Z
);
569 if (rb
->GetPointer(ctx
, rb
, 0, 0)) {
570 /* Directly access buffer */
571 if (rb
->DataType
== GL_UNSIGNED_SHORT
) {
572 GLushort
*zbuffer
= (GLushort
*) rb
->GetPointer(ctx
, rb
, x
, y
);
573 passed
= depth_test_span16(ctx
, count
, zbuffer
, zValues
, mask
);
576 GLuint
*zbuffer
= (GLuint
*) rb
->GetPointer(ctx
, rb
, x
, y
);
577 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
);
578 passed
= depth_test_span32(ctx
, count
, zbuffer
, zValues
, mask
);
582 /* read depth values from buffer, test, write back */
583 if (rb
->DataType
== GL_UNSIGNED_SHORT
) {
584 GLushort zbuffer
[MAX_WIDTH
];
585 rb
->GetRow(ctx
, rb
, count
, x
, y
, zbuffer
);
586 passed
= depth_test_span16(ctx
, count
, zbuffer
, zValues
, mask
);
587 rb
->PutRow(ctx
, rb
, count
, x
, y
, zbuffer
, mask
);
590 GLuint zbuffer
[MAX_WIDTH
];
591 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
);
592 rb
->GetRow(ctx
, rb
, count
, x
, y
, zbuffer
);
593 passed
= depth_test_span32(ctx
, count
, zbuffer
, zValues
, mask
);
594 rb
->PutRow(ctx
, rb
, count
, x
, y
, zbuffer
, mask
);
598 if (passed
< count
) {
599 span
->writeAll
= GL_FALSE
;
606 #define Z_ADDRESS(X, Y) (zStart + (Y) * stride + (X))
610 * Do depth testing for an array of fragments at assorted locations.
613 direct_depth_test_pixels16(GLcontext
*ctx
, GLushort
*zStart
, GLuint stride
,
614 GLuint n
, const GLint x
[], const GLint y
[],
615 const GLuint z
[], GLubyte mask
[] )
617 /* switch cases ordered from most frequent to less frequent */
618 switch (ctx
->Depth
.Func
) {
620 if (ctx
->Depth
.Mask
) {
621 /* Update Z buffer */
623 for (i
=0; i
<n
; i
++) {
625 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
638 /* Don't update Z buffer */
640 for (i
=0; i
<n
; i
++) {
642 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
655 if (ctx
->Depth
.Mask
) {
656 /* Update Z buffer */
658 for (i
=0; i
<n
; i
++) {
660 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
673 /* Don't update Z buffer */
675 for (i
=0; i
<n
; i
++) {
677 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
690 if (ctx
->Depth
.Mask
) {
691 /* Update Z buffer */
693 for (i
=0; i
<n
; i
++) {
695 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
708 /* Don't update Z buffer */
710 for (i
=0; i
<n
; i
++) {
712 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
725 if (ctx
->Depth
.Mask
) {
726 /* Update Z buffer */
728 for (i
=0; i
<n
; i
++) {
730 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
743 /* Don't update Z buffer */
745 for (i
=0; i
<n
; i
++) {
747 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
760 if (ctx
->Depth
.Mask
) {
761 /* Update Z buffer */
763 for (i
=0; i
<n
; i
++) {
765 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
778 /* Don't update Z buffer */
780 for (i
=0; i
<n
; i
++) {
782 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
795 if (ctx
->Depth
.Mask
) {
796 /* Update Z buffer */
798 for (i
=0; i
<n
; i
++) {
800 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
813 /* Don't update Z buffer */
815 for (i
=0; i
<n
; i
++) {
817 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
830 if (ctx
->Depth
.Mask
) {
831 /* Update Z buffer */
833 for (i
=0; i
<n
; i
++) {
835 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
841 /* Don't update Z buffer or mask */
845 /* depth test never passes */
846 memset(mask
, 0, n
* sizeof(GLubyte
));
849 _mesa_problem(ctx
, "Bad depth func in direct_depth_test_pixels");
856 * Do depth testing for an array of fragments with direct access to zbuffer.
859 direct_depth_test_pixels32(GLcontext
*ctx
, GLuint
*zStart
, GLuint stride
,
860 GLuint n
, const GLint x
[], const GLint y
[],
861 const GLuint z
[], GLubyte mask
[] )
863 /* switch cases ordered from most frequent to less frequent */
864 switch (ctx
->Depth
.Func
) {
866 if (ctx
->Depth
.Mask
) {
867 /* Update Z buffer */
869 for (i
=0; i
<n
; i
++) {
871 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
884 /* Don't update Z buffer */
886 for (i
=0; i
<n
; i
++) {
888 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
901 if (ctx
->Depth
.Mask
) {
902 /* Update Z buffer */
904 for (i
=0; i
<n
; i
++) {
906 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
919 /* Don't update Z buffer */
921 for (i
=0; i
<n
; i
++) {
923 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
936 if (ctx
->Depth
.Mask
) {
937 /* Update Z buffer */
939 for (i
=0; i
<n
; i
++) {
941 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
954 /* Don't update Z buffer */
956 for (i
=0; i
<n
; i
++) {
958 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
971 if (ctx
->Depth
.Mask
) {
972 /* Update Z buffer */
974 for (i
=0; i
<n
; i
++) {
976 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
989 /* Don't update Z buffer */
991 for (i
=0; i
<n
; i
++) {
993 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
1006 if (ctx
->Depth
.Mask
) {
1007 /* Update Z buffer */
1009 for (i
=0; i
<n
; i
++) {
1011 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
1012 if (z
[i
] != *zptr
) {
1024 /* Don't update Z buffer */
1026 for (i
=0; i
<n
; i
++) {
1028 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
1029 if (z
[i
] != *zptr
) {
1041 if (ctx
->Depth
.Mask
) {
1042 /* Update Z buffer */
1044 for (i
=0; i
<n
; i
++) {
1046 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
1047 if (z
[i
] == *zptr
) {
1059 /* Don't update Z buffer */
1061 for (i
=0; i
<n
; i
++) {
1063 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
1064 if (z
[i
] == *zptr
) {
1076 if (ctx
->Depth
.Mask
) {
1077 /* Update Z buffer */
1079 for (i
=0; i
<n
; i
++) {
1081 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
1087 /* Don't update Z buffer or mask */
1091 /* depth test never passes */
1092 memset(mask
, 0, n
* sizeof(GLubyte
));
1095 _mesa_problem(ctx
, "Bad depth func in direct_depth_test_pixels");
1103 depth_test_pixels( GLcontext
*ctx
, SWspan
*span
)
1105 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
1106 struct gl_renderbuffer
*rb
= fb
->_DepthBuffer
;
1107 const GLuint count
= span
->end
;
1108 const GLint
*x
= span
->array
->x
;
1109 const GLint
*y
= span
->array
->y
;
1110 const GLuint
*z
= span
->array
->z
;
1111 GLubyte
*mask
= span
->array
->mask
;
1113 if (rb
->GetPointer(ctx
, rb
, 0, 0)) {
1114 /* Directly access values */
1115 if (rb
->DataType
== GL_UNSIGNED_SHORT
) {
1116 GLushort
*zStart
= (GLushort
*) rb
->Data
;
1117 GLuint stride
= rb
->Width
;
1118 direct_depth_test_pixels16(ctx
, zStart
, stride
, count
, x
, y
, z
, mask
);
1121 GLuint
*zStart
= (GLuint
*) rb
->Data
;
1122 GLuint stride
= rb
->Width
;
1123 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
);
1124 direct_depth_test_pixels32(ctx
, zStart
, stride
, count
, x
, y
, z
, mask
);
1128 /* read depth values from buffer, test, write back */
1129 if (rb
->DataType
== GL_UNSIGNED_SHORT
) {
1130 GLushort zbuffer
[MAX_WIDTH
];
1131 _swrast_get_values(ctx
, rb
, count
, x
, y
, zbuffer
, sizeof(GLushort
));
1132 depth_test_span16(ctx
, count
, zbuffer
, z
, mask
);
1133 rb
->PutValues(ctx
, rb
, count
, x
, y
, zbuffer
, mask
);
1136 GLuint zbuffer
[MAX_WIDTH
];
1137 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
);
1138 _swrast_get_values(ctx
, rb
, count
, x
, y
, zbuffer
, sizeof(GLuint
));
1139 depth_test_span32(ctx
, count
, zbuffer
, z
, mask
);
1140 rb
->PutValues(ctx
, rb
, count
, x
, y
, zbuffer
, mask
);
1144 return count
; /* not really correct, but OK */
1149 * Apply depth (Z) buffer testing to the span.
1150 * \return approx number of pixels that passed (only zero is reliable)
1153 _swrast_depth_test_span( GLcontext
*ctx
, SWspan
*span
)
1155 if (span
->arrayMask
& SPAN_XY
)
1156 return depth_test_pixels(ctx
, span
);
1158 return depth_test_span(ctx
, span
);
1163 * GL_EXT_depth_bounds_test extension.
1164 * Discard fragments depending on whether the corresponding Z-buffer
1165 * values are outside the depth bounds test range.
1166 * Note: we test the Z buffer values, not the fragment Z values!
1167 * \return GL_TRUE if any fragments pass, GL_FALSE if no fragments pass
1170 _swrast_depth_bounds_test( GLcontext
*ctx
, SWspan
*span
)
1172 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
1173 struct gl_renderbuffer
*rb
= fb
->_DepthBuffer
;
1174 GLuint zMin
= (GLuint
) (ctx
->Depth
.BoundsMin
* fb
->_DepthMaxF
+ 0.5F
);
1175 GLuint zMax
= (GLuint
) (ctx
->Depth
.BoundsMax
* fb
->_DepthMaxF
+ 0.5F
);
1176 GLubyte
*mask
= span
->array
->mask
;
1177 const GLuint count
= span
->end
;
1179 GLboolean anyPass
= GL_FALSE
;
1181 if (rb
->DataType
== GL_UNSIGNED_SHORT
) {
1182 /* get 16-bit values */
1183 GLushort zbuffer16
[MAX_WIDTH
], *zbuffer
;
1184 if (span
->arrayMask
& SPAN_XY
) {
1185 _swrast_get_values(ctx
, rb
, count
, span
->array
->x
, span
->array
->y
,
1186 zbuffer16
, sizeof(GLushort
));
1187 zbuffer
= zbuffer16
;
1190 zbuffer
= (GLushort
*) rb
->GetPointer(ctx
, rb
, span
->x
, span
->y
);
1192 rb
->GetRow(ctx
, rb
, count
, span
->x
, span
->y
, zbuffer16
);
1193 zbuffer
= zbuffer16
;
1198 /* Now do the tests */
1199 for (i
= 0; i
< count
; i
++) {
1201 if (zbuffer
[i
] < zMin
|| zbuffer
[i
] > zMax
)
1209 /* get 32-bit values */
1210 GLuint zbuffer32
[MAX_WIDTH
], *zbuffer
;
1211 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
);
1212 if (span
->arrayMask
& SPAN_XY
) {
1213 _swrast_get_values(ctx
, rb
, count
, span
->array
->x
, span
->array
->y
,
1214 zbuffer32
, sizeof(GLuint
));
1215 zbuffer
= zbuffer32
;
1218 zbuffer
= (GLuint
*) rb
->GetPointer(ctx
, rb
, span
->x
, span
->y
);
1220 rb
->GetRow(ctx
, rb
, count
, span
->x
, span
->y
, zbuffer32
);
1221 zbuffer
= zbuffer32
;
1226 /* Now do the tests */
1227 for (i
= 0; i
< count
; i
++) {
1229 if (zbuffer
[i
] < zMin
|| zbuffer
[i
] > zMax
)
1242 /**********************************************************************/
1243 /***** Read Depth Buffer *****/
1244 /**********************************************************************/
1248 * Read a span of depth values from the given depth renderbuffer, returning
1249 * the values as GLfloats.
1250 * This function does clipping to prevent reading outside the depth buffer's
1251 * bounds. Though the clipping is redundant when we're called from
1252 * _swrast_ReadPixels.
1255 _swrast_read_depth_span_float( GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
1256 GLint n
, GLint x
, GLint y
, GLfloat depth
[] )
1258 const GLfloat scale
= 1.0F
/ ctx
->DrawBuffer
->_DepthMaxF
;
1261 /* really only doing this to prevent FP exceptions later */
1262 memset(depth
, 0, n
* sizeof(GLfloat
));
1266 ASSERT(rb
->_BaseFormat
== GL_DEPTH_COMPONENT
);
1268 if (y
< 0 || y
>= (GLint
) rb
->Height
||
1269 x
+ n
<= 0 || x
>= (GLint
) rb
->Width
) {
1270 /* span is completely outside framebuffer */
1271 memset(depth
, 0, n
* sizeof(GLfloat
));
1278 for (i
= 0; i
< dx
; i
++)
1284 if (x
+ n
> (GLint
) rb
->Width
) {
1285 GLint dx
= x
+ n
- (GLint
) rb
->Width
;
1287 for (i
= 0; i
< dx
; i
++)
1288 depth
[n
- i
- 1] = 0.0;
1295 if (rb
->DataType
== GL_UNSIGNED_INT
) {
1296 GLuint temp
[MAX_WIDTH
];
1298 rb
->GetRow(ctx
, rb
, n
, x
, y
, temp
);
1299 for (i
= 0; i
< n
; i
++) {
1300 depth
[i
] = temp
[i
] * scale
;
1303 else if (rb
->DataType
== GL_UNSIGNED_SHORT
) {
1304 GLushort temp
[MAX_WIDTH
];
1306 rb
->GetRow(ctx
, rb
, n
, x
, y
, temp
);
1307 for (i
= 0; i
< n
; i
++) {
1308 depth
[i
] = temp
[i
] * scale
;
1312 _mesa_problem(ctx
, "Invalid depth renderbuffer data type");
1318 * As above, but return 32-bit GLuint values.
1321 _swrast_read_depth_span_uint( GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
1322 GLint n
, GLint x
, GLint y
, GLuint depth
[] )
1327 /* really only doing this to prevent FP exceptions later */
1328 memset(depth
, 0, n
* sizeof(GLuint
));
1332 depthBits
= _mesa_get_format_bits(rb
->Format
, GL_DEPTH_BITS
);
1334 ASSERT(rb
->_BaseFormat
== GL_DEPTH_COMPONENT
);
1336 if (y
< 0 || y
>= (GLint
) rb
->Height
||
1337 x
+ n
<= 0 || x
>= (GLint
) rb
->Width
) {
1338 /* span is completely outside framebuffer */
1339 memset(depth
, 0, n
* sizeof(GLfloat
));
1346 for (i
= 0; i
< dx
; i
++)
1352 if (x
+ n
> (GLint
) rb
->Width
) {
1353 GLint dx
= x
+ n
- (GLint
) rb
->Width
;
1355 for (i
= 0; i
< dx
; i
++)
1356 depth
[n
- i
- 1] = 0;
1363 if (rb
->DataType
== GL_UNSIGNED_INT
) {
1364 rb
->GetRow(ctx
, rb
, n
, x
, y
, depth
);
1365 if (depthBits
< 32) {
1366 GLuint shift
= 32 - depthBits
;
1368 for (i
= 0; i
< n
; i
++) {
1369 GLuint z
= depth
[i
];
1370 depth
[i
] = z
<< shift
; /* XXX lsb bits? */
1374 else if (rb
->DataType
== GL_UNSIGNED_SHORT
) {
1375 GLushort temp
[MAX_WIDTH
];
1377 rb
->GetRow(ctx
, rb
, n
, x
, y
, temp
);
1378 if (depthBits
== 16) {
1379 for (i
= 0; i
< n
; i
++) {
1381 depth
[i
] = (z
<< 16) | z
;
1385 GLuint shift
= 16 - depthBits
;
1386 for (i
= 0; i
< n
; i
++) {
1388 depth
[i
] = (z
<< (shift
+ 16)) | (z
<< shift
); /* XXX lsb bits? */
1393 _mesa_problem(ctx
, "Invalid depth renderbuffer data type");
1400 * Clear the given z/depth renderbuffer.
1403 _swrast_clear_depth_buffer( GLcontext
*ctx
, struct gl_renderbuffer
*rb
)
1406 GLint x
, y
, width
, height
;
1408 if (!rb
|| !ctx
->Depth
.Mask
) {
1409 /* no depth buffer, or writing to it is disabled */
1413 /* compute integer clearing value */
1414 if (ctx
->Depth
.Clear
== 1.0) {
1415 clearValue
= ctx
->DrawBuffer
->_DepthMax
;
1418 clearValue
= (GLuint
) (ctx
->Depth
.Clear
* ctx
->DrawBuffer
->_DepthMaxF
);
1421 assert(rb
->_BaseFormat
== GL_DEPTH_COMPONENT
);
1423 /* compute region to clear */
1424 x
= ctx
->DrawBuffer
->_Xmin
;
1425 y
= ctx
->DrawBuffer
->_Ymin
;
1426 width
= ctx
->DrawBuffer
->_Xmax
- ctx
->DrawBuffer
->_Xmin
;
1427 height
= ctx
->DrawBuffer
->_Ymax
- ctx
->DrawBuffer
->_Ymin
;
1429 if (rb
->GetPointer(ctx
, rb
, 0, 0)) {
1430 /* Direct buffer access is possible. Either this is just malloc'd
1431 * memory, or perhaps the driver mmap'd the zbuffer memory.
1433 if (rb
->DataType
== GL_UNSIGNED_SHORT
) {
1434 if ((clearValue
& 0xff) == ((clearValue
>> 8) & 0xff) &&
1435 ((GLushort
*) rb
->GetPointer(ctx
, rb
, 0, 0) + width
==
1436 (GLushort
*) rb
->GetPointer(ctx
, rb
, 0, 1))) {
1437 /* optimized case */
1438 GLushort
*dst
= (GLushort
*) rb
->GetPointer(ctx
, rb
, x
, y
);
1439 GLuint len
= width
* height
* sizeof(GLushort
);
1440 memset(dst
, (clearValue
& 0xff), len
);
1445 for (i
= 0; i
< height
; i
++) {
1446 GLushort
*dst
= (GLushort
*) rb
->GetPointer(ctx
, rb
, x
, y
+ i
);
1447 for (j
= 0; j
< width
; j
++) {
1448 dst
[j
] = clearValue
;
1455 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
);
1456 for (i
= 0; i
< height
; i
++) {
1457 GLuint
*dst
= (GLuint
*) rb
->GetPointer(ctx
, rb
, x
, y
+ i
);
1458 for (j
= 0; j
< width
; j
++) {
1459 dst
[j
] = clearValue
;
1465 /* Direct access not possible. Use PutRow to write new values. */
1466 if (rb
->DataType
== GL_UNSIGNED_SHORT
) {
1467 GLushort clearVal16
= (GLushort
) (clearValue
& 0xffff);
1469 for (i
= 0; i
< height
; i
++) {
1470 rb
->PutMonoRow(ctx
, rb
, width
, x
, y
+ i
, &clearVal16
, NULL
);
1473 else if (rb
->DataType
== GL_UNSIGNED_INT
) {
1475 ASSERT(sizeof(clearValue
) == sizeof(GLuint
));
1476 for (i
= 0; i
< height
; i
++) {
1477 rb
->PutMonoRow(ctx
, rb
, width
, x
, y
+ i
, &clearValue
, NULL
);
1481 _mesa_problem(ctx
, "bad depth renderbuffer DataType");