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"
31 #include "main/fbobject.h"
34 #include "s_context.h"
39 * Do depth test for a horizontal span of fragments.
40 * Input: zbuffer - array of z values in the zbuffer
41 * z - array of fragment z values
42 * Return: number of fragments which pass the test.
45 depth_test_span16( GLcontext
*ctx
, GLuint n
,
46 GLushort zbuffer
[], const GLuint z
[], GLubyte mask
[] )
50 /* switch cases ordered from most frequent to less frequent */
51 switch (ctx
->Depth
.Func
) {
53 if (ctx
->Depth
.Mask
) {
58 if (z
[i
] < zbuffer
[i
]) {
71 /* Don't update Z buffer */
75 if (z
[i
] < zbuffer
[i
]) {
87 if (ctx
->Depth
.Mask
) {
92 if (z
[i
] <= zbuffer
[i
]) {
103 /* Don't update Z buffer */
107 if (z
[i
] <= zbuffer
[i
]) {
119 if (ctx
->Depth
.Mask
) {
120 /* Update Z buffer */
124 if (z
[i
] >= zbuffer
[i
]) {
135 /* Don't update Z buffer */
139 if (z
[i
] >= zbuffer
[i
]) {
151 if (ctx
->Depth
.Mask
) {
152 /* Update Z buffer */
156 if (z
[i
] > zbuffer
[i
]) {
167 /* Don't update Z buffer */
171 if (z
[i
] > zbuffer
[i
]) {
183 if (ctx
->Depth
.Mask
) {
184 /* Update Z buffer */
188 if (z
[i
] != zbuffer
[i
]) {
199 /* Don't update Z buffer */
203 if (z
[i
] != zbuffer
[i
]) {
215 if (ctx
->Depth
.Mask
) {
216 /* Update Z buffer */
220 if (z
[i
] == zbuffer
[i
]) {
231 /* Don't update Z buffer */
235 if (z
[i
] == zbuffer
[i
]) {
247 if (ctx
->Depth
.Mask
) {
248 /* Update Z buffer */
258 /* Don't update Z buffer or mask */
263 _mesa_bzero(mask
, n
* sizeof(GLubyte
));
266 _mesa_problem(ctx
, "Bad depth func in depth_test_span16");
274 depth_test_span32( GLcontext
*ctx
, GLuint n
,
275 GLuint zbuffer
[], const GLuint z
[], GLubyte mask
[] )
279 /* switch cases ordered from most frequent to less frequent */
280 switch (ctx
->Depth
.Func
) {
282 if (ctx
->Depth
.Mask
) {
283 /* Update Z buffer */
285 for (i
=0; i
<n
; i
++) {
287 if (z
[i
] < zbuffer
[i
]) {
300 /* Don't update Z buffer */
302 for (i
=0; i
<n
; i
++) {
304 if (z
[i
] < zbuffer
[i
]) {
316 if (ctx
->Depth
.Mask
) {
317 /* Update Z buffer */
321 if (z
[i
] <= zbuffer
[i
]) {
332 /* Don't update Z buffer */
336 if (z
[i
] <= zbuffer
[i
]) {
348 if (ctx
->Depth
.Mask
) {
349 /* Update Z buffer */
353 if (z
[i
] >= zbuffer
[i
]) {
364 /* Don't update Z buffer */
368 if (z
[i
] >= zbuffer
[i
]) {
380 if (ctx
->Depth
.Mask
) {
381 /* Update Z buffer */
385 if (z
[i
] > zbuffer
[i
]) {
396 /* Don't update Z buffer */
400 if (z
[i
] > zbuffer
[i
]) {
412 if (ctx
->Depth
.Mask
) {
413 /* Update Z buffer */
417 if (z
[i
] != zbuffer
[i
]) {
428 /* Don't update Z buffer */
432 if (z
[i
] != zbuffer
[i
]) {
444 if (ctx
->Depth
.Mask
) {
445 /* Update Z buffer */
449 if (z
[i
] == zbuffer
[i
]) {
460 /* Don't update Z buffer */
464 if (z
[i
] == zbuffer
[i
]) {
476 if (ctx
->Depth
.Mask
) {
477 /* Update Z buffer */
487 /* Don't update Z buffer or mask */
492 _mesa_bzero(mask
, n
* sizeof(GLubyte
));
495 _mesa_problem(ctx
, "Bad depth func in depth_test_span32");
501 /* Apply ARB_depth_clamp to span of fragments. */
503 _swrast_depth_clamp_span( GLcontext
*ctx
, SWspan
*span
)
505 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
506 struct gl_renderbuffer
*rb
= fb
->_DepthBuffer
;
507 const GLuint count
= span
->end
;
508 GLuint
*zValues
= span
->array
->z
;
510 GLfloat min_f
, max_f
;
513 if (ctx
->Viewport
.Near
< ctx
->Viewport
.Far
) {
514 min_f
= ctx
->Viewport
.Near
;
515 max_f
= ctx
->Viewport
.Far
;
517 min_f
= ctx
->Viewport
.Far
;
518 max_f
= ctx
->Viewport
.Near
;
521 if (rb
->DataType
== GL_UNSIGNED_SHORT
) {
522 CLAMPED_FLOAT_TO_USHORT(min
, min_f
);
523 CLAMPED_FLOAT_TO_USHORT(max
, max_f
);
525 assert(rb
->DataType
== GL_UNSIGNED_INT
);
526 min
= FLOAT_TO_UINT(min_f
);
527 max
= FLOAT_TO_UINT(max_f
);
530 for (i
= 0; i
< count
; i
++) {
531 if (zValues
[i
] < min
)
533 if (zValues
[i
] > max
)
541 * Apply depth test to span of fragments.
544 depth_test_span( GLcontext
*ctx
, SWspan
*span
)
546 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
547 struct gl_renderbuffer
*rb
= fb
->_DepthBuffer
;
548 const GLint x
= span
->x
;
549 const GLint y
= span
->y
;
550 const GLuint count
= span
->end
;
551 const GLuint
*zValues
= span
->array
->z
;
552 GLubyte
*mask
= span
->array
->mask
;
555 ASSERT((span
->arrayMask
& SPAN_XY
) == 0);
556 ASSERT(span
->arrayMask
& SPAN_Z
);
558 if (rb
->GetPointer(ctx
, rb
, 0, 0)) {
559 /* Directly access buffer */
560 if (rb
->DataType
== GL_UNSIGNED_SHORT
) {
561 GLushort
*zbuffer
= (GLushort
*) rb
->GetPointer(ctx
, rb
, x
, y
);
562 passed
= depth_test_span16(ctx
, count
, zbuffer
, zValues
, mask
);
565 GLuint
*zbuffer
= (GLuint
*) rb
->GetPointer(ctx
, rb
, x
, y
);
566 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
);
567 passed
= depth_test_span32(ctx
, count
, zbuffer
, zValues
, mask
);
571 /* read depth values from buffer, test, write back */
572 if (rb
->DataType
== GL_UNSIGNED_SHORT
) {
573 GLushort zbuffer
[MAX_WIDTH
];
574 rb
->GetRow(ctx
, rb
, count
, x
, y
, zbuffer
);
575 passed
= depth_test_span16(ctx
, count
, zbuffer
, zValues
, mask
);
576 rb
->PutRow(ctx
, rb
, count
, x
, y
, zbuffer
, mask
);
579 GLuint zbuffer
[MAX_WIDTH
];
580 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
);
581 rb
->GetRow(ctx
, rb
, count
, x
, y
, zbuffer
);
582 passed
= depth_test_span32(ctx
, count
, zbuffer
, zValues
, mask
);
583 rb
->PutRow(ctx
, rb
, count
, x
, y
, zbuffer
, mask
);
587 if (passed
< count
) {
588 span
->writeAll
= GL_FALSE
;
595 #define Z_ADDRESS(X, Y) (zStart + (Y) * stride + (X))
599 * Do depth testing for an array of fragments at assorted locations.
602 direct_depth_test_pixels16(GLcontext
*ctx
, GLushort
*zStart
, GLuint stride
,
603 GLuint n
, const GLint x
[], const GLint y
[],
604 const GLuint z
[], GLubyte mask
[] )
606 /* switch cases ordered from most frequent to less frequent */
607 switch (ctx
->Depth
.Func
) {
609 if (ctx
->Depth
.Mask
) {
610 /* Update Z buffer */
612 for (i
=0; i
<n
; i
++) {
614 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
627 /* Don't update Z buffer */
629 for (i
=0; i
<n
; i
++) {
631 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
644 if (ctx
->Depth
.Mask
) {
645 /* Update Z buffer */
647 for (i
=0; i
<n
; i
++) {
649 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
662 /* Don't update Z buffer */
664 for (i
=0; i
<n
; i
++) {
666 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
679 if (ctx
->Depth
.Mask
) {
680 /* Update Z buffer */
682 for (i
=0; i
<n
; i
++) {
684 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
697 /* Don't update Z buffer */
699 for (i
=0; i
<n
; i
++) {
701 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
714 if (ctx
->Depth
.Mask
) {
715 /* Update Z buffer */
717 for (i
=0; i
<n
; i
++) {
719 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
732 /* Don't update Z buffer */
734 for (i
=0; i
<n
; i
++) {
736 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
749 if (ctx
->Depth
.Mask
) {
750 /* Update Z buffer */
752 for (i
=0; i
<n
; i
++) {
754 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
767 /* Don't update Z buffer */
769 for (i
=0; i
<n
; i
++) {
771 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
784 if (ctx
->Depth
.Mask
) {
785 /* Update Z buffer */
787 for (i
=0; i
<n
; i
++) {
789 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
802 /* Don't update Z buffer */
804 for (i
=0; i
<n
; i
++) {
806 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
819 if (ctx
->Depth
.Mask
) {
820 /* Update Z buffer */
822 for (i
=0; i
<n
; i
++) {
824 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
830 /* Don't update Z buffer or mask */
834 /* depth test never passes */
835 _mesa_bzero(mask
, n
* sizeof(GLubyte
));
838 _mesa_problem(ctx
, "Bad depth func in direct_depth_test_pixels");
845 * Do depth testing for an array of fragments with direct access to zbuffer.
848 direct_depth_test_pixels32(GLcontext
*ctx
, GLuint
*zStart
, GLuint stride
,
849 GLuint n
, const GLint x
[], const GLint y
[],
850 const GLuint z
[], GLubyte mask
[] )
852 /* switch cases ordered from most frequent to less frequent */
853 switch (ctx
->Depth
.Func
) {
855 if (ctx
->Depth
.Mask
) {
856 /* Update Z buffer */
858 for (i
=0; i
<n
; i
++) {
860 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
873 /* Don't update Z buffer */
875 for (i
=0; i
<n
; i
++) {
877 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
890 if (ctx
->Depth
.Mask
) {
891 /* Update Z buffer */
893 for (i
=0; i
<n
; i
++) {
895 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
908 /* Don't update Z buffer */
910 for (i
=0; i
<n
; i
++) {
912 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
925 if (ctx
->Depth
.Mask
) {
926 /* Update Z buffer */
928 for (i
=0; i
<n
; i
++) {
930 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
943 /* Don't update Z buffer */
945 for (i
=0; i
<n
; i
++) {
947 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
960 if (ctx
->Depth
.Mask
) {
961 /* Update Z buffer */
963 for (i
=0; i
<n
; i
++) {
965 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
978 /* Don't update Z buffer */
980 for (i
=0; i
<n
; i
++) {
982 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
995 if (ctx
->Depth
.Mask
) {
996 /* Update Z buffer */
998 for (i
=0; i
<n
; i
++) {
1000 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
1001 if (z
[i
] != *zptr
) {
1013 /* Don't update Z buffer */
1015 for (i
=0; i
<n
; i
++) {
1017 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
1018 if (z
[i
] != *zptr
) {
1030 if (ctx
->Depth
.Mask
) {
1031 /* Update Z buffer */
1033 for (i
=0; i
<n
; i
++) {
1035 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
1036 if (z
[i
] == *zptr
) {
1048 /* Don't update Z buffer */
1050 for (i
=0; i
<n
; i
++) {
1052 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
1053 if (z
[i
] == *zptr
) {
1065 if (ctx
->Depth
.Mask
) {
1066 /* Update Z buffer */
1068 for (i
=0; i
<n
; i
++) {
1070 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
1076 /* Don't update Z buffer or mask */
1080 /* depth test never passes */
1081 _mesa_bzero(mask
, n
* sizeof(GLubyte
));
1084 _mesa_problem(ctx
, "Bad depth func in direct_depth_test_pixels");
1092 depth_test_pixels( GLcontext
*ctx
, SWspan
*span
)
1094 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
1095 struct gl_renderbuffer
*rb
= fb
->_DepthBuffer
;
1096 const GLuint count
= span
->end
;
1097 const GLint
*x
= span
->array
->x
;
1098 const GLint
*y
= span
->array
->y
;
1099 const GLuint
*z
= span
->array
->z
;
1100 GLubyte
*mask
= span
->array
->mask
;
1102 if (rb
->GetPointer(ctx
, rb
, 0, 0)) {
1103 /* Directly access values */
1104 if (rb
->DataType
== GL_UNSIGNED_SHORT
) {
1105 GLushort
*zStart
= (GLushort
*) rb
->Data
;
1106 GLuint stride
= rb
->Width
;
1107 direct_depth_test_pixels16(ctx
, zStart
, stride
, count
, x
, y
, z
, mask
);
1110 GLuint
*zStart
= (GLuint
*) rb
->Data
;
1111 GLuint stride
= rb
->Width
;
1112 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
);
1113 direct_depth_test_pixels32(ctx
, zStart
, stride
, count
, x
, y
, z
, mask
);
1117 /* read depth values from buffer, test, write back */
1118 if (rb
->DataType
== GL_UNSIGNED_SHORT
) {
1119 GLushort zbuffer
[MAX_WIDTH
];
1120 _swrast_get_values(ctx
, rb
, count
, x
, y
, zbuffer
, sizeof(GLushort
));
1121 depth_test_span16(ctx
, count
, zbuffer
, z
, mask
);
1122 rb
->PutValues(ctx
, rb
, count
, x
, y
, zbuffer
, mask
);
1125 GLuint zbuffer
[MAX_WIDTH
];
1126 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
);
1127 _swrast_get_values(ctx
, rb
, count
, x
, y
, zbuffer
, sizeof(GLuint
));
1128 depth_test_span32(ctx
, count
, zbuffer
, z
, mask
);
1129 rb
->PutValues(ctx
, rb
, count
, x
, y
, zbuffer
, mask
);
1133 return count
; /* not really correct, but OK */
1138 * Apply depth (Z) buffer testing to the span.
1139 * \return approx number of pixels that passed (only zero is reliable)
1142 _swrast_depth_test_span( GLcontext
*ctx
, SWspan
*span
)
1144 if (span
->arrayMask
& SPAN_XY
)
1145 return depth_test_pixels(ctx
, span
);
1147 return depth_test_span(ctx
, span
);
1152 * GL_EXT_depth_bounds_test extension.
1153 * Discard fragments depending on whether the corresponding Z-buffer
1154 * values are outside the depth bounds test range.
1155 * Note: we test the Z buffer values, not the fragment Z values!
1156 * \return GL_TRUE if any fragments pass, GL_FALSE if no fragments pass
1159 _swrast_depth_bounds_test( GLcontext
*ctx
, SWspan
*span
)
1161 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
1162 struct gl_renderbuffer
*rb
= fb
->_DepthBuffer
;
1163 GLuint zMin
= (GLuint
) (ctx
->Depth
.BoundsMin
* fb
->_DepthMaxF
+ 0.5F
);
1164 GLuint zMax
= (GLuint
) (ctx
->Depth
.BoundsMax
* fb
->_DepthMaxF
+ 0.5F
);
1165 GLubyte
*mask
= span
->array
->mask
;
1166 const GLuint count
= span
->end
;
1168 GLboolean anyPass
= GL_FALSE
;
1170 if (rb
->DataType
== GL_UNSIGNED_SHORT
) {
1171 /* get 16-bit values */
1172 GLushort zbuffer16
[MAX_WIDTH
], *zbuffer
;
1173 if (span
->arrayMask
& SPAN_XY
) {
1174 _swrast_get_values(ctx
, rb
, count
, span
->array
->x
, span
->array
->y
,
1175 zbuffer16
, sizeof(GLushort
));
1176 zbuffer
= zbuffer16
;
1179 zbuffer
= (GLushort
*) rb
->GetPointer(ctx
, rb
, span
->x
, span
->y
);
1181 rb
->GetRow(ctx
, rb
, count
, span
->x
, span
->y
, zbuffer16
);
1182 zbuffer
= zbuffer16
;
1187 /* Now do the tests */
1188 for (i
= 0; i
< count
; i
++) {
1190 if (zbuffer
[i
] < zMin
|| zbuffer
[i
] > zMax
)
1198 /* get 32-bit values */
1199 GLuint zbuffer32
[MAX_WIDTH
], *zbuffer
;
1200 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
);
1201 if (span
->arrayMask
& SPAN_XY
) {
1202 _swrast_get_values(ctx
, rb
, count
, span
->array
->x
, span
->array
->y
,
1203 zbuffer32
, sizeof(GLuint
));
1204 zbuffer
= zbuffer32
;
1207 zbuffer
= (GLuint
*) rb
->GetPointer(ctx
, rb
, span
->x
, span
->y
);
1209 rb
->GetRow(ctx
, rb
, count
, span
->x
, span
->y
, zbuffer32
);
1210 zbuffer
= zbuffer32
;
1215 /* Now do the tests */
1216 for (i
= 0; i
< count
; i
++) {
1218 if (zbuffer
[i
] < zMin
|| zbuffer
[i
] > zMax
)
1231 /**********************************************************************/
1232 /***** Read Depth Buffer *****/
1233 /**********************************************************************/
1237 * Read a span of depth values from the given depth renderbuffer, returning
1238 * the values as GLfloats.
1239 * This function does clipping to prevent reading outside the depth buffer's
1240 * bounds. Though the clipping is redundant when we're called from
1241 * _swrast_ReadPixels.
1244 _swrast_read_depth_span_float( GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
1245 GLint n
, GLint x
, GLint y
, GLfloat depth
[] )
1247 const GLfloat scale
= 1.0F
/ ctx
->DrawBuffer
->_DepthMaxF
;
1250 /* really only doing this to prevent FP exceptions later */
1251 _mesa_bzero(depth
, n
* sizeof(GLfloat
));
1255 ASSERT(rb
->_BaseFormat
== GL_DEPTH_COMPONENT
);
1257 if (y
< 0 || y
>= (GLint
) rb
->Height
||
1258 x
+ n
<= 0 || x
>= (GLint
) rb
->Width
) {
1259 /* span is completely outside framebuffer */
1260 _mesa_bzero(depth
, n
* sizeof(GLfloat
));
1267 for (i
= 0; i
< dx
; i
++)
1273 if (x
+ n
> (GLint
) rb
->Width
) {
1274 GLint dx
= x
+ n
- (GLint
) rb
->Width
;
1276 for (i
= 0; i
< dx
; i
++)
1277 depth
[n
- i
- 1] = 0.0;
1284 if (rb
->DataType
== GL_UNSIGNED_INT
) {
1285 GLuint temp
[MAX_WIDTH
];
1287 rb
->GetRow(ctx
, rb
, n
, x
, y
, temp
);
1288 for (i
= 0; i
< n
; i
++) {
1289 depth
[i
] = temp
[i
] * scale
;
1292 else if (rb
->DataType
== GL_UNSIGNED_SHORT
) {
1293 GLushort temp
[MAX_WIDTH
];
1295 rb
->GetRow(ctx
, rb
, n
, x
, y
, temp
);
1296 for (i
= 0; i
< n
; i
++) {
1297 depth
[i
] = temp
[i
] * scale
;
1301 _mesa_problem(ctx
, "Invalid depth renderbuffer data type");
1307 * As above, but return 32-bit GLuint values.
1310 _swrast_read_depth_span_uint( GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
1311 GLint n
, GLint x
, GLint y
, GLuint depth
[] )
1316 /* really only doing this to prevent FP exceptions later */
1317 _mesa_bzero(depth
, n
* sizeof(GLuint
));
1321 depthBits
= _mesa_get_format_bits(rb
->Format
, GL_DEPTH_BITS
);
1323 ASSERT(rb
->_BaseFormat
== GL_DEPTH_COMPONENT
);
1325 if (y
< 0 || y
>= (GLint
) rb
->Height
||
1326 x
+ n
<= 0 || x
>= (GLint
) rb
->Width
) {
1327 /* span is completely outside framebuffer */
1328 _mesa_bzero(depth
, n
* sizeof(GLfloat
));
1335 for (i
= 0; i
< dx
; i
++)
1341 if (x
+ n
> (GLint
) rb
->Width
) {
1342 GLint dx
= x
+ n
- (GLint
) rb
->Width
;
1344 for (i
= 0; i
< dx
; i
++)
1345 depth
[n
- i
- 1] = 0;
1352 if (rb
->DataType
== GL_UNSIGNED_INT
) {
1353 rb
->GetRow(ctx
, rb
, n
, x
, y
, depth
);
1354 if (depthBits
< 32) {
1355 GLuint shift
= 32 - depthBits
;
1357 for (i
= 0; i
< n
; i
++) {
1358 GLuint z
= depth
[i
];
1359 depth
[i
] = z
<< shift
; /* XXX lsb bits? */
1363 else if (rb
->DataType
== GL_UNSIGNED_SHORT
) {
1364 GLushort temp
[MAX_WIDTH
];
1366 rb
->GetRow(ctx
, rb
, n
, x
, y
, temp
);
1367 if (depthBits
== 16) {
1368 for (i
= 0; i
< n
; i
++) {
1370 depth
[i
] = (z
<< 16) | z
;
1374 GLuint shift
= 16 - depthBits
;
1375 for (i
= 0; i
< n
; i
++) {
1377 depth
[i
] = (z
<< (shift
+ 16)) | (z
<< shift
); /* XXX lsb bits? */
1382 _mesa_problem(ctx
, "Invalid depth renderbuffer data type");
1389 * Clear the given z/depth renderbuffer.
1392 _swrast_clear_depth_buffer( GLcontext
*ctx
, struct gl_renderbuffer
*rb
)
1395 GLint x
, y
, width
, height
;
1397 if (!rb
|| !ctx
->Depth
.Mask
) {
1398 /* no depth buffer, or writing to it is disabled */
1402 /* compute integer clearing value */
1403 if (ctx
->Depth
.Clear
== 1.0) {
1404 clearValue
= ctx
->DrawBuffer
->_DepthMax
;
1407 clearValue
= (GLuint
) (ctx
->Depth
.Clear
* ctx
->DrawBuffer
->_DepthMaxF
);
1410 assert(rb
->_BaseFormat
== GL_DEPTH_COMPONENT
);
1412 /* compute region to clear */
1413 x
= ctx
->DrawBuffer
->_Xmin
;
1414 y
= ctx
->DrawBuffer
->_Ymin
;
1415 width
= ctx
->DrawBuffer
->_Xmax
- ctx
->DrawBuffer
->_Xmin
;
1416 height
= ctx
->DrawBuffer
->_Ymax
- ctx
->DrawBuffer
->_Ymin
;
1418 if (rb
->GetPointer(ctx
, rb
, 0, 0)) {
1419 /* Direct buffer access is possible. Either this is just malloc'd
1420 * memory, or perhaps the driver mmap'd the zbuffer memory.
1422 if (rb
->DataType
== GL_UNSIGNED_SHORT
) {
1423 if ((clearValue
& 0xff) == ((clearValue
>> 8) & 0xff) &&
1424 ((GLushort
*) rb
->GetPointer(ctx
, rb
, 0, 0) + width
==
1425 (GLushort
*) rb
->GetPointer(ctx
, rb
, 0, 1))) {
1426 /* optimized case */
1427 GLushort
*dst
= (GLushort
*) rb
->GetPointer(ctx
, rb
, x
, y
);
1428 GLuint len
= width
* height
* sizeof(GLushort
);
1429 _mesa_memset(dst
, (clearValue
& 0xff), len
);
1434 for (i
= 0; i
< height
; i
++) {
1435 GLushort
*dst
= (GLushort
*) rb
->GetPointer(ctx
, rb
, x
, y
+ i
);
1436 for (j
= 0; j
< width
; j
++) {
1437 dst
[j
] = clearValue
;
1444 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
);
1445 for (i
= 0; i
< height
; i
++) {
1446 GLuint
*dst
= (GLuint
*) rb
->GetPointer(ctx
, rb
, x
, y
+ i
);
1447 for (j
= 0; j
< width
; j
++) {
1448 dst
[j
] = clearValue
;
1454 /* Direct access not possible. Use PutRow to write new values. */
1455 if (rb
->DataType
== GL_UNSIGNED_SHORT
) {
1456 GLushort clearVal16
= (GLushort
) (clearValue
& 0xffff);
1458 for (i
= 0; i
< height
; i
++) {
1459 rb
->PutMonoRow(ctx
, rb
, width
, x
, y
+ i
, &clearVal16
, NULL
);
1462 else if (rb
->DataType
== GL_UNSIGNED_INT
) {
1464 ASSERT(sizeof(clearValue
) == sizeof(GLuint
));
1465 for (i
= 0; i
< height
; i
++) {
1466 rb
->PutMonoRow(ctx
, rb
, width
, x
, y
+ i
, &clearValue
, NULL
);
1470 _mesa_problem(ctx
, "bad depth renderbuffer DataType");