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/macros.h"
29 #include "main/imports.h"
30 #include "main/fbobject.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 _mesa_bzero(mask
, 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 _mesa_bzero(mask
, n
* sizeof(GLubyte
));
494 _mesa_problem(ctx
, "Bad depth func in depth_test_span32");
503 * Apply depth test to span of fragments.
506 depth_test_span( GLcontext
*ctx
, SWspan
*span
)
508 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
509 struct gl_renderbuffer
*rb
= fb
->_DepthBuffer
;
510 const GLint x
= span
->x
;
511 const GLint y
= span
->y
;
512 const GLuint count
= span
->end
;
513 const GLuint
*zValues
= span
->array
->z
;
514 GLubyte
*mask
= span
->array
->mask
;
517 ASSERT((span
->arrayMask
& SPAN_XY
) == 0);
518 ASSERT(span
->arrayMask
& SPAN_Z
);
520 if (rb
->GetPointer(ctx
, rb
, 0, 0)) {
521 /* Directly access buffer */
522 if (rb
->DataType
== GL_UNSIGNED_SHORT
) {
523 GLushort
*zbuffer
= (GLushort
*) rb
->GetPointer(ctx
, rb
, x
, y
);
524 passed
= depth_test_span16(ctx
, count
, zbuffer
, zValues
, mask
);
527 GLuint
*zbuffer
= (GLuint
*) rb
->GetPointer(ctx
, rb
, x
, y
);
528 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
);
529 passed
= depth_test_span32(ctx
, count
, zbuffer
, zValues
, mask
);
533 /* read depth values from buffer, test, write back */
534 if (rb
->DataType
== GL_UNSIGNED_SHORT
) {
535 GLushort zbuffer
[MAX_WIDTH
];
536 rb
->GetRow(ctx
, rb
, count
, x
, y
, zbuffer
);
537 passed
= depth_test_span16(ctx
, count
, zbuffer
, zValues
, mask
);
538 rb
->PutRow(ctx
, rb
, count
, x
, y
, zbuffer
, mask
);
541 GLuint zbuffer
[MAX_WIDTH
];
542 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
);
543 rb
->GetRow(ctx
, rb
, count
, x
, y
, zbuffer
);
544 passed
= depth_test_span32(ctx
, count
, zbuffer
, zValues
, mask
);
545 rb
->PutRow(ctx
, rb
, count
, x
, y
, zbuffer
, mask
);
549 if (passed
< count
) {
550 span
->writeAll
= GL_FALSE
;
557 #define Z_ADDRESS(X, Y) (zStart + (Y) * stride + (X))
561 * Do depth testing for an array of fragments at assorted locations.
564 direct_depth_test_pixels16(GLcontext
*ctx
, GLushort
*zStart
, GLuint stride
,
565 GLuint n
, const GLint x
[], const GLint y
[],
566 const GLuint z
[], GLubyte mask
[] )
568 /* switch cases ordered from most frequent to less frequent */
569 switch (ctx
->Depth
.Func
) {
571 if (ctx
->Depth
.Mask
) {
572 /* Update Z buffer */
574 for (i
=0; i
<n
; i
++) {
576 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
589 /* Don't update Z buffer */
591 for (i
=0; i
<n
; i
++) {
593 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
606 if (ctx
->Depth
.Mask
) {
607 /* Update Z buffer */
609 for (i
=0; i
<n
; i
++) {
611 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
624 /* Don't update Z buffer */
626 for (i
=0; i
<n
; i
++) {
628 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
641 if (ctx
->Depth
.Mask
) {
642 /* Update Z buffer */
644 for (i
=0; i
<n
; i
++) {
646 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
659 /* Don't update Z buffer */
661 for (i
=0; i
<n
; i
++) {
663 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
676 if (ctx
->Depth
.Mask
) {
677 /* Update Z buffer */
679 for (i
=0; i
<n
; i
++) {
681 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
694 /* Don't update Z buffer */
696 for (i
=0; i
<n
; i
++) {
698 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
711 if (ctx
->Depth
.Mask
) {
712 /* Update Z buffer */
714 for (i
=0; i
<n
; i
++) {
716 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
729 /* Don't update Z buffer */
731 for (i
=0; i
<n
; i
++) {
733 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
746 if (ctx
->Depth
.Mask
) {
747 /* Update Z buffer */
749 for (i
=0; i
<n
; i
++) {
751 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
764 /* Don't update Z buffer */
766 for (i
=0; i
<n
; i
++) {
768 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
781 if (ctx
->Depth
.Mask
) {
782 /* Update Z buffer */
784 for (i
=0; i
<n
; i
++) {
786 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
792 /* Don't update Z buffer or mask */
796 /* depth test never passes */
797 _mesa_bzero(mask
, n
* sizeof(GLubyte
));
800 _mesa_problem(ctx
, "Bad depth func in direct_depth_test_pixels");
807 * Do depth testing for an array of fragments with direct access to zbuffer.
810 direct_depth_test_pixels32(GLcontext
*ctx
, GLuint
*zStart
, GLuint stride
,
811 GLuint n
, const GLint x
[], const GLint y
[],
812 const GLuint z
[], GLubyte mask
[] )
814 /* switch cases ordered from most frequent to less frequent */
815 switch (ctx
->Depth
.Func
) {
817 if (ctx
->Depth
.Mask
) {
818 /* Update Z buffer */
820 for (i
=0; i
<n
; i
++) {
822 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
835 /* Don't update Z buffer */
837 for (i
=0; i
<n
; i
++) {
839 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
852 if (ctx
->Depth
.Mask
) {
853 /* Update Z buffer */
855 for (i
=0; i
<n
; i
++) {
857 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
870 /* Don't update Z buffer */
872 for (i
=0; i
<n
; i
++) {
874 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
887 if (ctx
->Depth
.Mask
) {
888 /* Update Z buffer */
890 for (i
=0; i
<n
; i
++) {
892 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
905 /* Don't update Z buffer */
907 for (i
=0; i
<n
; i
++) {
909 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
922 if (ctx
->Depth
.Mask
) {
923 /* Update Z buffer */
925 for (i
=0; i
<n
; i
++) {
927 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
940 /* Don't update Z buffer */
942 for (i
=0; i
<n
; i
++) {
944 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
957 if (ctx
->Depth
.Mask
) {
958 /* Update Z buffer */
960 for (i
=0; i
<n
; i
++) {
962 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
975 /* Don't update Z buffer */
977 for (i
=0; i
<n
; i
++) {
979 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
992 if (ctx
->Depth
.Mask
) {
993 /* Update Z buffer */
995 for (i
=0; i
<n
; i
++) {
997 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
1010 /* Don't update Z buffer */
1012 for (i
=0; i
<n
; i
++) {
1014 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
1015 if (z
[i
] == *zptr
) {
1027 if (ctx
->Depth
.Mask
) {
1028 /* Update Z buffer */
1030 for (i
=0; i
<n
; i
++) {
1032 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
1038 /* Don't update Z buffer or mask */
1042 /* depth test never passes */
1043 _mesa_bzero(mask
, n
* sizeof(GLubyte
));
1046 _mesa_problem(ctx
, "Bad depth func in direct_depth_test_pixels");
1054 depth_test_pixels( GLcontext
*ctx
, SWspan
*span
)
1056 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
1057 struct gl_renderbuffer
*rb
= fb
->_DepthBuffer
;
1058 const GLuint count
= span
->end
;
1059 const GLint
*x
= span
->array
->x
;
1060 const GLint
*y
= span
->array
->y
;
1061 const GLuint
*z
= span
->array
->z
;
1062 GLubyte
*mask
= span
->array
->mask
;
1064 if (rb
->GetPointer(ctx
, rb
, 0, 0)) {
1065 /* Directly access values */
1066 if (rb
->DataType
== GL_UNSIGNED_SHORT
) {
1067 GLushort
*zStart
= (GLushort
*) rb
->Data
;
1068 GLuint stride
= rb
->Width
;
1069 direct_depth_test_pixels16(ctx
, zStart
, stride
, count
, x
, y
, z
, mask
);
1072 GLuint
*zStart
= (GLuint
*) rb
->Data
;
1073 GLuint stride
= rb
->Width
;
1074 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
);
1075 direct_depth_test_pixels32(ctx
, zStart
, stride
, count
, x
, y
, z
, mask
);
1079 /* read depth values from buffer, test, write back */
1080 if (rb
->DataType
== GL_UNSIGNED_SHORT
) {
1081 GLushort zbuffer
[MAX_WIDTH
];
1082 _swrast_get_values(ctx
, rb
, count
, x
, y
, zbuffer
, sizeof(GLushort
));
1083 depth_test_span16(ctx
, count
, zbuffer
, z
, mask
);
1084 rb
->PutValues(ctx
, rb
, count
, x
, y
, zbuffer
, mask
);
1087 GLuint zbuffer
[MAX_WIDTH
];
1088 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
);
1089 _swrast_get_values(ctx
, rb
, count
, x
, y
, zbuffer
, sizeof(GLuint
));
1090 depth_test_span32(ctx
, count
, zbuffer
, z
, mask
);
1091 rb
->PutValues(ctx
, rb
, count
, x
, y
, zbuffer
, mask
);
1095 return count
; /* not really correct, but OK */
1100 * Apply depth (Z) buffer testing to the span.
1101 * \return approx number of pixels that passed (only zero is reliable)
1104 _swrast_depth_test_span( GLcontext
*ctx
, SWspan
*span
)
1106 if (span
->arrayMask
& SPAN_XY
)
1107 return depth_test_pixels(ctx
, span
);
1109 return depth_test_span(ctx
, span
);
1114 * GL_EXT_depth_bounds_test extension.
1115 * Discard fragments depending on whether the corresponding Z-buffer
1116 * values are outside the depth bounds test range.
1117 * Note: we test the Z buffer values, not the fragment Z values!
1118 * \return GL_TRUE if any fragments pass, GL_FALSE if no fragments pass
1121 _swrast_depth_bounds_test( GLcontext
*ctx
, SWspan
*span
)
1123 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
1124 struct gl_renderbuffer
*rb
= fb
->_DepthBuffer
;
1125 GLuint zMin
= (GLuint
) (ctx
->Depth
.BoundsMin
* fb
->_DepthMaxF
+ 0.5F
);
1126 GLuint zMax
= (GLuint
) (ctx
->Depth
.BoundsMax
* fb
->_DepthMaxF
+ 0.5F
);
1127 GLubyte
*mask
= span
->array
->mask
;
1128 const GLuint count
= span
->end
;
1130 GLboolean anyPass
= GL_FALSE
;
1132 if (rb
->DataType
== GL_UNSIGNED_SHORT
) {
1133 /* get 16-bit values */
1134 GLushort zbuffer16
[MAX_WIDTH
], *zbuffer
;
1135 if (span
->arrayMask
& SPAN_XY
) {
1136 _swrast_get_values(ctx
, rb
, count
, span
->array
->x
, span
->array
->y
,
1137 zbuffer16
, sizeof(GLushort
));
1138 zbuffer
= zbuffer16
;
1141 zbuffer
= (GLushort
*) rb
->GetPointer(ctx
, rb
, span
->x
, span
->y
);
1143 rb
->GetRow(ctx
, rb
, count
, span
->x
, span
->y
, zbuffer16
);
1144 zbuffer
= zbuffer16
;
1149 /* Now do the tests */
1150 for (i
= 0; i
< count
; i
++) {
1152 if (zbuffer
[i
] < zMin
|| zbuffer
[i
] > zMax
)
1160 /* get 32-bit values */
1161 GLuint zbuffer32
[MAX_WIDTH
], *zbuffer
;
1162 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
);
1163 if (span
->arrayMask
& SPAN_XY
) {
1164 _swrast_get_values(ctx
, rb
, count
, span
->array
->x
, span
->array
->y
,
1165 zbuffer32
, sizeof(GLuint
));
1166 zbuffer
= zbuffer32
;
1169 zbuffer
= (GLuint
*) rb
->GetPointer(ctx
, rb
, span
->x
, span
->y
);
1171 rb
->GetRow(ctx
, rb
, count
, span
->x
, span
->y
, zbuffer32
);
1172 zbuffer
= zbuffer32
;
1177 /* Now do the tests */
1178 for (i
= 0; i
< count
; i
++) {
1180 if (zbuffer
[i
] < zMin
|| zbuffer
[i
] > zMax
)
1193 /**********************************************************************/
1194 /***** Read Depth Buffer *****/
1195 /**********************************************************************/
1199 * Read a span of depth values from the given depth renderbuffer, returning
1200 * the values as GLfloats.
1201 * This function does clipping to prevent reading outside the depth buffer's
1202 * bounds. Though the clipping is redundant when we're called from
1203 * _swrast_ReadPixels.
1206 _swrast_read_depth_span_float( GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
1207 GLint n
, GLint x
, GLint y
, GLfloat depth
[] )
1209 const GLfloat scale
= 1.0F
/ ctx
->DrawBuffer
->_DepthMaxF
;
1212 /* really only doing this to prevent FP exceptions later */
1213 _mesa_bzero(depth
, n
* sizeof(GLfloat
));
1216 ASSERT(rb
->_BaseFormat
== GL_DEPTH_COMPONENT
);
1218 if (y
< 0 || y
>= (GLint
) rb
->Height
||
1219 x
+ n
<= 0 || x
>= (GLint
) rb
->Width
) {
1220 /* span is completely outside framebuffer */
1221 _mesa_bzero(depth
, n
* sizeof(GLfloat
));
1228 for (i
= 0; i
< dx
; i
++)
1234 if (x
+ n
> (GLint
) rb
->Width
) {
1235 GLint dx
= x
+ n
- (GLint
) rb
->Width
;
1237 for (i
= 0; i
< dx
; i
++)
1238 depth
[n
- i
- 1] = 0.0;
1245 if (rb
->DataType
== GL_UNSIGNED_INT
) {
1246 GLuint temp
[MAX_WIDTH
];
1248 rb
->GetRow(ctx
, rb
, n
, x
, y
, temp
);
1249 for (i
= 0; i
< n
; i
++) {
1250 depth
[i
] = temp
[i
] * scale
;
1253 else if (rb
->DataType
== GL_UNSIGNED_SHORT
) {
1254 GLushort temp
[MAX_WIDTH
];
1256 rb
->GetRow(ctx
, rb
, n
, x
, y
, temp
);
1257 for (i
= 0; i
< n
; i
++) {
1258 depth
[i
] = temp
[i
] * scale
;
1262 _mesa_problem(ctx
, "Invalid depth renderbuffer data type");
1268 * As above, but return 32-bit GLuint values.
1271 _swrast_read_depth_span_uint( GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
1272 GLint n
, GLint x
, GLint y
, GLuint depth
[] )
1275 /* really only doing this to prevent FP exceptions later */
1276 _mesa_bzero(depth
, n
* sizeof(GLfloat
));
1279 ASSERT(rb
->_BaseFormat
== GL_DEPTH_COMPONENT
);
1281 if (y
< 0 || y
>= (GLint
) rb
->Height
||
1282 x
+ n
<= 0 || x
>= (GLint
) rb
->Width
) {
1283 /* span is completely outside framebuffer */
1284 _mesa_bzero(depth
, n
* sizeof(GLfloat
));
1291 for (i
= 0; i
< dx
; i
++)
1297 if (x
+ n
> (GLint
) rb
->Width
) {
1298 GLint dx
= x
+ n
- (GLint
) rb
->Width
;
1300 for (i
= 0; i
< dx
; i
++)
1301 depth
[n
- i
- 1] = 0;
1308 if (rb
->DataType
== GL_UNSIGNED_INT
) {
1309 rb
->GetRow(ctx
, rb
, n
, x
, y
, depth
);
1310 if (rb
->DepthBits
< 32) {
1311 GLuint shift
= 32 - rb
->DepthBits
;
1313 for (i
= 0; i
< n
; i
++) {
1314 GLuint z
= depth
[i
];
1315 depth
[i
] = z
<< shift
; /* XXX lsb bits? */
1319 else if (rb
->DataType
== GL_UNSIGNED_SHORT
) {
1320 GLushort temp
[MAX_WIDTH
];
1322 rb
->GetRow(ctx
, rb
, n
, x
, y
, temp
);
1323 if (rb
->DepthBits
== 16) {
1324 for (i
= 0; i
< n
; i
++) {
1326 depth
[i
] = (z
<< 16) | z
;
1330 GLuint shift
= 16 - rb
->DepthBits
;
1331 for (i
= 0; i
< n
; i
++) {
1333 depth
[i
] = (z
<< (shift
+ 16)) | (z
<< shift
); /* XXX lsb bits? */
1338 _mesa_problem(ctx
, "Invalid depth renderbuffer data type");
1345 * Clear the given z/depth renderbuffer.
1348 _swrast_clear_depth_buffer( GLcontext
*ctx
, struct gl_renderbuffer
*rb
)
1351 GLint x
, y
, width
, height
;
1353 if (!rb
|| !ctx
->Depth
.Mask
) {
1354 /* no depth buffer, or writing to it is disabled */
1358 /* compute integer clearing value */
1359 if (ctx
->Depth
.Clear
== 1.0) {
1360 clearValue
= ctx
->DrawBuffer
->_DepthMax
;
1363 clearValue
= (GLuint
) (ctx
->Depth
.Clear
* ctx
->DrawBuffer
->_DepthMaxF
);
1366 assert(rb
->_BaseFormat
== GL_DEPTH_COMPONENT
);
1368 /* compute region to clear */
1369 x
= ctx
->DrawBuffer
->_Xmin
;
1370 y
= ctx
->DrawBuffer
->_Ymin
;
1371 width
= ctx
->DrawBuffer
->_Xmax
- ctx
->DrawBuffer
->_Xmin
;
1372 height
= ctx
->DrawBuffer
->_Ymax
- ctx
->DrawBuffer
->_Ymin
;
1374 if (rb
->GetPointer(ctx
, rb
, 0, 0)) {
1375 /* Direct buffer access is possible. Either this is just malloc'd
1376 * memory, or perhaps the driver mmap'd the zbuffer memory.
1378 if (rb
->DataType
== GL_UNSIGNED_SHORT
) {
1379 if ((clearValue
& 0xff) == ((clearValue
>> 8) & 0xff) &&
1380 ((GLushort
*) rb
->GetPointer(ctx
, rb
, 0, 0) + width
==
1381 (GLushort
*) rb
->GetPointer(ctx
, rb
, 0, 1))) {
1382 /* optimized case */
1383 GLushort
*dst
= (GLushort
*) rb
->GetPointer(ctx
, rb
, x
, y
);
1384 GLuint len
= width
* height
* sizeof(GLushort
);
1385 _mesa_memset(dst
, (clearValue
& 0xff), len
);
1390 for (i
= 0; i
< height
; i
++) {
1391 GLushort
*dst
= (GLushort
*) rb
->GetPointer(ctx
, rb
, x
, y
+ i
);
1392 for (j
= 0; j
< width
; j
++) {
1393 dst
[j
] = clearValue
;
1400 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
);
1401 for (i
= 0; i
< height
; i
++) {
1402 GLuint
*dst
= (GLuint
*) rb
->GetPointer(ctx
, rb
, x
, y
+ i
);
1403 for (j
= 0; j
< width
; j
++) {
1404 dst
[j
] = clearValue
;
1410 /* Direct access not possible. Use PutRow to write new values. */
1411 if (rb
->DataType
== GL_UNSIGNED_SHORT
) {
1412 GLushort clearVal16
= (GLushort
) (clearValue
& 0xffff);
1414 for (i
= 0; i
< height
; i
++) {
1415 rb
->PutMonoRow(ctx
, rb
, width
, x
, y
+ i
, &clearVal16
, NULL
);
1418 else if (rb
->DataType
== GL_UNSIGNED_INT
) {
1420 ASSERT(sizeof(clearValue
) == sizeof(GLuint
));
1421 for (i
= 0; i
< height
; i
++) {
1422 rb
->PutMonoRow(ctx
, rb
, width
, x
, y
+ i
, &clearValue
, NULL
);
1426 _mesa_problem(ctx
, "bad depth renderbuffer DataType");