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");
500 /* Apply ARB_depth_clamp to span of fragments. */
502 _swrast_depth_clamp_span( GLcontext
*ctx
, SWspan
*span
)
504 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
505 struct gl_renderbuffer
*rb
= fb
->_DepthBuffer
;
506 const GLuint count
= span
->end
;
507 GLuint
*zValues
= span
->array
->z
;
511 if (rb
->DataType
== GL_UNSIGNED_SHORT
) {
512 near
= FLOAT_TO_UINT(ctx
->Viewport
.Near
);
513 far
= FLOAT_TO_UINT(ctx
->Viewport
.Far
);
515 assert(rb
->DataType
== GL_UNSIGNED_INT
);
516 CLAMPED_FLOAT_TO_USHORT(near
, ctx
->Viewport
.Near
);
517 CLAMPED_FLOAT_TO_USHORT(far
, ctx
->Viewport
.Far
);
519 for (i
= 0; i
< count
; i
++) {
520 if (zValues
[i
] < near
)
522 if (zValues
[i
] > far
)
530 * Apply depth test to span of fragments.
533 depth_test_span( GLcontext
*ctx
, SWspan
*span
)
535 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
536 struct gl_renderbuffer
*rb
= fb
->_DepthBuffer
;
537 const GLint x
= span
->x
;
538 const GLint y
= span
->y
;
539 const GLuint count
= span
->end
;
540 const GLuint
*zValues
= span
->array
->z
;
541 GLubyte
*mask
= span
->array
->mask
;
544 ASSERT((span
->arrayMask
& SPAN_XY
) == 0);
545 ASSERT(span
->arrayMask
& SPAN_Z
);
547 if (rb
->GetPointer(ctx
, rb
, 0, 0)) {
548 /* Directly access buffer */
549 if (rb
->DataType
== GL_UNSIGNED_SHORT
) {
550 GLushort
*zbuffer
= (GLushort
*) rb
->GetPointer(ctx
, rb
, x
, y
);
551 passed
= depth_test_span16(ctx
, count
, zbuffer
, zValues
, mask
);
554 GLuint
*zbuffer
= (GLuint
*) rb
->GetPointer(ctx
, rb
, x
, y
);
555 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
);
556 passed
= depth_test_span32(ctx
, count
, zbuffer
, zValues
, mask
);
560 /* read depth values from buffer, test, write back */
561 if (rb
->DataType
== GL_UNSIGNED_SHORT
) {
562 GLushort zbuffer
[MAX_WIDTH
];
563 rb
->GetRow(ctx
, rb
, count
, x
, y
, zbuffer
);
564 passed
= depth_test_span16(ctx
, count
, zbuffer
, zValues
, mask
);
565 rb
->PutRow(ctx
, rb
, count
, x
, y
, zbuffer
, mask
);
568 GLuint zbuffer
[MAX_WIDTH
];
569 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
);
570 rb
->GetRow(ctx
, rb
, count
, x
, y
, zbuffer
);
571 passed
= depth_test_span32(ctx
, count
, zbuffer
, zValues
, mask
);
572 rb
->PutRow(ctx
, rb
, count
, x
, y
, zbuffer
, mask
);
576 if (passed
< count
) {
577 span
->writeAll
= GL_FALSE
;
584 #define Z_ADDRESS(X, Y) (zStart + (Y) * stride + (X))
588 * Do depth testing for an array of fragments at assorted locations.
591 direct_depth_test_pixels16(GLcontext
*ctx
, GLushort
*zStart
, GLuint stride
,
592 GLuint n
, const GLint x
[], const GLint y
[],
593 const GLuint z
[], GLubyte mask
[] )
595 /* switch cases ordered from most frequent to less frequent */
596 switch (ctx
->Depth
.Func
) {
598 if (ctx
->Depth
.Mask
) {
599 /* Update Z buffer */
601 for (i
=0; i
<n
; i
++) {
603 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
616 /* Don't update Z buffer */
618 for (i
=0; i
<n
; i
++) {
620 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
633 if (ctx
->Depth
.Mask
) {
634 /* Update Z buffer */
636 for (i
=0; i
<n
; i
++) {
638 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
651 /* Don't update Z buffer */
653 for (i
=0; i
<n
; i
++) {
655 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
668 if (ctx
->Depth
.Mask
) {
669 /* Update Z buffer */
671 for (i
=0; i
<n
; i
++) {
673 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
686 /* Don't update Z buffer */
688 for (i
=0; i
<n
; i
++) {
690 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
703 if (ctx
->Depth
.Mask
) {
704 /* Update Z buffer */
706 for (i
=0; i
<n
; i
++) {
708 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
721 /* Don't update Z buffer */
723 for (i
=0; i
<n
; i
++) {
725 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
738 if (ctx
->Depth
.Mask
) {
739 /* Update Z buffer */
741 for (i
=0; i
<n
; i
++) {
743 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
756 /* Don't update Z buffer */
758 for (i
=0; i
<n
; i
++) {
760 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
773 if (ctx
->Depth
.Mask
) {
774 /* Update Z buffer */
776 for (i
=0; i
<n
; i
++) {
778 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
791 /* Don't update Z buffer */
793 for (i
=0; i
<n
; i
++) {
795 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
808 if (ctx
->Depth
.Mask
) {
809 /* Update Z buffer */
811 for (i
=0; i
<n
; i
++) {
813 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
819 /* Don't update Z buffer or mask */
823 /* depth test never passes */
824 _mesa_bzero(mask
, n
* sizeof(GLubyte
));
827 _mesa_problem(ctx
, "Bad depth func in direct_depth_test_pixels");
834 * Do depth testing for an array of fragments with direct access to zbuffer.
837 direct_depth_test_pixels32(GLcontext
*ctx
, GLuint
*zStart
, GLuint stride
,
838 GLuint n
, const GLint x
[], const GLint y
[],
839 const GLuint z
[], GLubyte mask
[] )
841 /* switch cases ordered from most frequent to less frequent */
842 switch (ctx
->Depth
.Func
) {
844 if (ctx
->Depth
.Mask
) {
845 /* Update Z buffer */
847 for (i
=0; i
<n
; i
++) {
849 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
862 /* Don't update Z buffer */
864 for (i
=0; i
<n
; i
++) {
866 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
879 if (ctx
->Depth
.Mask
) {
880 /* Update Z buffer */
882 for (i
=0; i
<n
; i
++) {
884 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
897 /* Don't update Z buffer */
899 for (i
=0; i
<n
; i
++) {
901 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
914 if (ctx
->Depth
.Mask
) {
915 /* Update Z buffer */
917 for (i
=0; i
<n
; i
++) {
919 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
932 /* Don't update Z buffer */
934 for (i
=0; i
<n
; i
++) {
936 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
949 if (ctx
->Depth
.Mask
) {
950 /* Update Z buffer */
952 for (i
=0; i
<n
; i
++) {
954 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
967 /* Don't update Z buffer */
969 for (i
=0; i
<n
; i
++) {
971 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
984 if (ctx
->Depth
.Mask
) {
985 /* Update Z buffer */
987 for (i
=0; i
<n
; i
++) {
989 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
1002 /* Don't update Z buffer */
1004 for (i
=0; i
<n
; i
++) {
1006 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
1007 if (z
[i
] != *zptr
) {
1019 if (ctx
->Depth
.Mask
) {
1020 /* Update Z buffer */
1022 for (i
=0; i
<n
; i
++) {
1024 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
1025 if (z
[i
] == *zptr
) {
1037 /* Don't update Z buffer */
1039 for (i
=0; i
<n
; i
++) {
1041 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
1042 if (z
[i
] == *zptr
) {
1054 if (ctx
->Depth
.Mask
) {
1055 /* Update Z buffer */
1057 for (i
=0; i
<n
; i
++) {
1059 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
1065 /* Don't update Z buffer or mask */
1069 /* depth test never passes */
1070 _mesa_bzero(mask
, n
* sizeof(GLubyte
));
1073 _mesa_problem(ctx
, "Bad depth func in direct_depth_test_pixels");
1081 depth_test_pixels( GLcontext
*ctx
, SWspan
*span
)
1083 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
1084 struct gl_renderbuffer
*rb
= fb
->_DepthBuffer
;
1085 const GLuint count
= span
->end
;
1086 const GLint
*x
= span
->array
->x
;
1087 const GLint
*y
= span
->array
->y
;
1088 const GLuint
*z
= span
->array
->z
;
1089 GLubyte
*mask
= span
->array
->mask
;
1091 if (rb
->GetPointer(ctx
, rb
, 0, 0)) {
1092 /* Directly access values */
1093 if (rb
->DataType
== GL_UNSIGNED_SHORT
) {
1094 GLushort
*zStart
= (GLushort
*) rb
->Data
;
1095 GLuint stride
= rb
->Width
;
1096 direct_depth_test_pixels16(ctx
, zStart
, stride
, count
, x
, y
, z
, mask
);
1099 GLuint
*zStart
= (GLuint
*) rb
->Data
;
1100 GLuint stride
= rb
->Width
;
1101 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
);
1102 direct_depth_test_pixels32(ctx
, zStart
, stride
, count
, x
, y
, z
, mask
);
1106 /* read depth values from buffer, test, write back */
1107 if (rb
->DataType
== GL_UNSIGNED_SHORT
) {
1108 GLushort zbuffer
[MAX_WIDTH
];
1109 _swrast_get_values(ctx
, rb
, count
, x
, y
, zbuffer
, sizeof(GLushort
));
1110 depth_test_span16(ctx
, count
, zbuffer
, z
, mask
);
1111 rb
->PutValues(ctx
, rb
, count
, x
, y
, zbuffer
, mask
);
1114 GLuint zbuffer
[MAX_WIDTH
];
1115 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
);
1116 _swrast_get_values(ctx
, rb
, count
, x
, y
, zbuffer
, sizeof(GLuint
));
1117 depth_test_span32(ctx
, count
, zbuffer
, z
, mask
);
1118 rb
->PutValues(ctx
, rb
, count
, x
, y
, zbuffer
, mask
);
1122 return count
; /* not really correct, but OK */
1127 * Apply depth (Z) buffer testing to the span.
1128 * \return approx number of pixels that passed (only zero is reliable)
1131 _swrast_depth_test_span( GLcontext
*ctx
, SWspan
*span
)
1133 if (span
->arrayMask
& SPAN_XY
)
1134 return depth_test_pixels(ctx
, span
);
1136 return depth_test_span(ctx
, span
);
1141 * GL_EXT_depth_bounds_test extension.
1142 * Discard fragments depending on whether the corresponding Z-buffer
1143 * values are outside the depth bounds test range.
1144 * Note: we test the Z buffer values, not the fragment Z values!
1145 * \return GL_TRUE if any fragments pass, GL_FALSE if no fragments pass
1148 _swrast_depth_bounds_test( GLcontext
*ctx
, SWspan
*span
)
1150 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
1151 struct gl_renderbuffer
*rb
= fb
->_DepthBuffer
;
1152 GLuint zMin
= (GLuint
) (ctx
->Depth
.BoundsMin
* fb
->_DepthMaxF
+ 0.5F
);
1153 GLuint zMax
= (GLuint
) (ctx
->Depth
.BoundsMax
* fb
->_DepthMaxF
+ 0.5F
);
1154 GLubyte
*mask
= span
->array
->mask
;
1155 const GLuint count
= span
->end
;
1157 GLboolean anyPass
= GL_FALSE
;
1159 if (rb
->DataType
== GL_UNSIGNED_SHORT
) {
1160 /* get 16-bit values */
1161 GLushort zbuffer16
[MAX_WIDTH
], *zbuffer
;
1162 if (span
->arrayMask
& SPAN_XY
) {
1163 _swrast_get_values(ctx
, rb
, count
, span
->array
->x
, span
->array
->y
,
1164 zbuffer16
, sizeof(GLushort
));
1165 zbuffer
= zbuffer16
;
1168 zbuffer
= (GLushort
*) rb
->GetPointer(ctx
, rb
, span
->x
, span
->y
);
1170 rb
->GetRow(ctx
, rb
, count
, span
->x
, span
->y
, zbuffer16
);
1171 zbuffer
= zbuffer16
;
1176 /* Now do the tests */
1177 for (i
= 0; i
< count
; i
++) {
1179 if (zbuffer
[i
] < zMin
|| zbuffer
[i
] > zMax
)
1187 /* get 32-bit values */
1188 GLuint zbuffer32
[MAX_WIDTH
], *zbuffer
;
1189 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
);
1190 if (span
->arrayMask
& SPAN_XY
) {
1191 _swrast_get_values(ctx
, rb
, count
, span
->array
->x
, span
->array
->y
,
1192 zbuffer32
, sizeof(GLuint
));
1193 zbuffer
= zbuffer32
;
1196 zbuffer
= (GLuint
*) rb
->GetPointer(ctx
, rb
, span
->x
, span
->y
);
1198 rb
->GetRow(ctx
, rb
, count
, span
->x
, span
->y
, zbuffer32
);
1199 zbuffer
= zbuffer32
;
1204 /* Now do the tests */
1205 for (i
= 0; i
< count
; i
++) {
1207 if (zbuffer
[i
] < zMin
|| zbuffer
[i
] > zMax
)
1220 /**********************************************************************/
1221 /***** Read Depth Buffer *****/
1222 /**********************************************************************/
1226 * Read a span of depth values from the given depth renderbuffer, returning
1227 * the values as GLfloats.
1228 * This function does clipping to prevent reading outside the depth buffer's
1229 * bounds. Though the clipping is redundant when we're called from
1230 * _swrast_ReadPixels.
1233 _swrast_read_depth_span_float( GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
1234 GLint n
, GLint x
, GLint y
, GLfloat depth
[] )
1236 const GLfloat scale
= 1.0F
/ ctx
->DrawBuffer
->_DepthMaxF
;
1239 /* really only doing this to prevent FP exceptions later */
1240 _mesa_bzero(depth
, n
* sizeof(GLfloat
));
1243 ASSERT(rb
->_BaseFormat
== GL_DEPTH_COMPONENT
);
1245 if (y
< 0 || y
>= (GLint
) rb
->Height
||
1246 x
+ n
<= 0 || x
>= (GLint
) rb
->Width
) {
1247 /* span is completely outside framebuffer */
1248 _mesa_bzero(depth
, n
* sizeof(GLfloat
));
1255 for (i
= 0; i
< dx
; i
++)
1261 if (x
+ n
> (GLint
) rb
->Width
) {
1262 GLint dx
= x
+ n
- (GLint
) rb
->Width
;
1264 for (i
= 0; i
< dx
; i
++)
1265 depth
[n
- i
- 1] = 0.0;
1272 if (rb
->DataType
== GL_UNSIGNED_INT
) {
1273 GLuint temp
[MAX_WIDTH
];
1275 rb
->GetRow(ctx
, rb
, n
, x
, y
, temp
);
1276 for (i
= 0; i
< n
; i
++) {
1277 depth
[i
] = temp
[i
] * scale
;
1280 else if (rb
->DataType
== GL_UNSIGNED_SHORT
) {
1281 GLushort temp
[MAX_WIDTH
];
1283 rb
->GetRow(ctx
, rb
, n
, x
, y
, temp
);
1284 for (i
= 0; i
< n
; i
++) {
1285 depth
[i
] = temp
[i
] * scale
;
1289 _mesa_problem(ctx
, "Invalid depth renderbuffer data type");
1295 * As above, but return 32-bit GLuint values.
1298 _swrast_read_depth_span_uint( GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
1299 GLint n
, GLint x
, GLint y
, GLuint depth
[] )
1302 /* really only doing this to prevent FP exceptions later */
1303 _mesa_bzero(depth
, n
* sizeof(GLfloat
));
1306 ASSERT(rb
->_BaseFormat
== GL_DEPTH_COMPONENT
);
1308 if (y
< 0 || y
>= (GLint
) rb
->Height
||
1309 x
+ n
<= 0 || x
>= (GLint
) rb
->Width
) {
1310 /* span is completely outside framebuffer */
1311 _mesa_bzero(depth
, n
* sizeof(GLfloat
));
1318 for (i
= 0; i
< dx
; i
++)
1324 if (x
+ n
> (GLint
) rb
->Width
) {
1325 GLint dx
= x
+ n
- (GLint
) rb
->Width
;
1327 for (i
= 0; i
< dx
; i
++)
1328 depth
[n
- i
- 1] = 0;
1335 if (rb
->DataType
== GL_UNSIGNED_INT
) {
1336 rb
->GetRow(ctx
, rb
, n
, x
, y
, depth
);
1337 if (rb
->DepthBits
< 32) {
1338 GLuint shift
= 32 - rb
->DepthBits
;
1340 for (i
= 0; i
< n
; i
++) {
1341 GLuint z
= depth
[i
];
1342 depth
[i
] = z
<< shift
; /* XXX lsb bits? */
1346 else if (rb
->DataType
== GL_UNSIGNED_SHORT
) {
1347 GLushort temp
[MAX_WIDTH
];
1349 rb
->GetRow(ctx
, rb
, n
, x
, y
, temp
);
1350 if (rb
->DepthBits
== 16) {
1351 for (i
= 0; i
< n
; i
++) {
1353 depth
[i
] = (z
<< 16) | z
;
1357 GLuint shift
= 16 - rb
->DepthBits
;
1358 for (i
= 0; i
< n
; i
++) {
1360 depth
[i
] = (z
<< (shift
+ 16)) | (z
<< shift
); /* XXX lsb bits? */
1365 _mesa_problem(ctx
, "Invalid depth renderbuffer data type");
1372 * Clear the given z/depth renderbuffer.
1375 _swrast_clear_depth_buffer( GLcontext
*ctx
, struct gl_renderbuffer
*rb
)
1378 GLint x
, y
, width
, height
;
1380 if (!rb
|| !ctx
->Depth
.Mask
) {
1381 /* no depth buffer, or writing to it is disabled */
1385 /* compute integer clearing value */
1386 if (ctx
->Depth
.Clear
== 1.0) {
1387 clearValue
= ctx
->DrawBuffer
->_DepthMax
;
1390 clearValue
= (GLuint
) (ctx
->Depth
.Clear
* ctx
->DrawBuffer
->_DepthMaxF
);
1393 assert(rb
->_BaseFormat
== GL_DEPTH_COMPONENT
);
1395 /* compute region to clear */
1396 x
= ctx
->DrawBuffer
->_Xmin
;
1397 y
= ctx
->DrawBuffer
->_Ymin
;
1398 width
= ctx
->DrawBuffer
->_Xmax
- ctx
->DrawBuffer
->_Xmin
;
1399 height
= ctx
->DrawBuffer
->_Ymax
- ctx
->DrawBuffer
->_Ymin
;
1401 if (rb
->GetPointer(ctx
, rb
, 0, 0)) {
1402 /* Direct buffer access is possible. Either this is just malloc'd
1403 * memory, or perhaps the driver mmap'd the zbuffer memory.
1405 if (rb
->DataType
== GL_UNSIGNED_SHORT
) {
1406 if ((clearValue
& 0xff) == ((clearValue
>> 8) & 0xff) &&
1407 ((GLushort
*) rb
->GetPointer(ctx
, rb
, 0, 0) + width
==
1408 (GLushort
*) rb
->GetPointer(ctx
, rb
, 0, 1))) {
1409 /* optimized case */
1410 GLushort
*dst
= (GLushort
*) rb
->GetPointer(ctx
, rb
, x
, y
);
1411 GLuint len
= width
* height
* sizeof(GLushort
);
1412 _mesa_memset(dst
, (clearValue
& 0xff), len
);
1417 for (i
= 0; i
< height
; i
++) {
1418 GLushort
*dst
= (GLushort
*) rb
->GetPointer(ctx
, rb
, x
, y
+ i
);
1419 for (j
= 0; j
< width
; j
++) {
1420 dst
[j
] = clearValue
;
1427 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
);
1428 for (i
= 0; i
< height
; i
++) {
1429 GLuint
*dst
= (GLuint
*) rb
->GetPointer(ctx
, rb
, x
, y
+ i
);
1430 for (j
= 0; j
< width
; j
++) {
1431 dst
[j
] = clearValue
;
1437 /* Direct access not possible. Use PutRow to write new values. */
1438 if (rb
->DataType
== GL_UNSIGNED_SHORT
) {
1439 GLushort clearVal16
= (GLushort
) (clearValue
& 0xffff);
1441 for (i
= 0; i
< height
; i
++) {
1442 rb
->PutMonoRow(ctx
, rb
, width
, x
, y
+ i
, &clearVal16
, NULL
);
1445 else if (rb
->DataType
== GL_UNSIGNED_INT
) {
1447 ASSERT(sizeof(clearValue
) == sizeof(GLuint
));
1448 for (i
= 0; i
< height
; i
++) {
1449 rb
->PutMonoRow(ctx
, rb
, width
, x
, y
+ i
, &clearValue
, NULL
);
1453 _mesa_problem(ctx
, "bad depth renderbuffer DataType");