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 _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
;
509 GLfloat min_f
, max_f
;
512 if (ctx
->Viewport
.Near
< ctx
->Viewport
.Far
) {
513 min_f
= ctx
->Viewport
.Near
;
514 max_f
= ctx
->Viewport
.Far
;
516 min_f
= ctx
->Viewport
.Far
;
517 max_f
= ctx
->Viewport
.Near
;
520 if (rb
->DataType
== GL_UNSIGNED_SHORT
) {
521 CLAMPED_FLOAT_TO_USHORT(min
, min_f
);
522 CLAMPED_FLOAT_TO_USHORT(max
, max_f
);
524 assert(rb
->DataType
== GL_UNSIGNED_INT
);
525 min
= FLOAT_TO_UINT(min_f
);
526 max
= FLOAT_TO_UINT(max_f
);
529 for (i
= 0; i
< count
; i
++) {
530 if (zValues
[i
] < min
)
532 if (zValues
[i
] > max
)
540 * Apply depth test to span of fragments.
543 depth_test_span( GLcontext
*ctx
, SWspan
*span
)
545 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
546 struct gl_renderbuffer
*rb
= fb
->_DepthBuffer
;
547 const GLint x
= span
->x
;
548 const GLint y
= span
->y
;
549 const GLuint count
= span
->end
;
550 const GLuint
*zValues
= span
->array
->z
;
551 GLubyte
*mask
= span
->array
->mask
;
554 ASSERT((span
->arrayMask
& SPAN_XY
) == 0);
555 ASSERT(span
->arrayMask
& SPAN_Z
);
557 if (rb
->GetPointer(ctx
, rb
, 0, 0)) {
558 /* Directly access buffer */
559 if (rb
->DataType
== GL_UNSIGNED_SHORT
) {
560 GLushort
*zbuffer
= (GLushort
*) rb
->GetPointer(ctx
, rb
, x
, y
);
561 passed
= depth_test_span16(ctx
, count
, zbuffer
, zValues
, mask
);
564 GLuint
*zbuffer
= (GLuint
*) rb
->GetPointer(ctx
, rb
, x
, y
);
565 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
);
566 passed
= depth_test_span32(ctx
, count
, zbuffer
, zValues
, mask
);
570 /* read depth values from buffer, test, write back */
571 if (rb
->DataType
== GL_UNSIGNED_SHORT
) {
572 GLushort zbuffer
[MAX_WIDTH
];
573 rb
->GetRow(ctx
, rb
, count
, x
, y
, zbuffer
);
574 passed
= depth_test_span16(ctx
, count
, zbuffer
, zValues
, mask
);
575 rb
->PutRow(ctx
, rb
, count
, x
, y
, zbuffer
, mask
);
578 GLuint zbuffer
[MAX_WIDTH
];
579 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
);
580 rb
->GetRow(ctx
, rb
, count
, x
, y
, zbuffer
);
581 passed
= depth_test_span32(ctx
, count
, zbuffer
, zValues
, mask
);
582 rb
->PutRow(ctx
, rb
, count
, x
, y
, zbuffer
, mask
);
586 if (passed
< count
) {
587 span
->writeAll
= GL_FALSE
;
594 #define Z_ADDRESS(X, Y) (zStart + (Y) * stride + (X))
598 * Do depth testing for an array of fragments at assorted locations.
601 direct_depth_test_pixels16(GLcontext
*ctx
, GLushort
*zStart
, GLuint stride
,
602 GLuint n
, const GLint x
[], const GLint y
[],
603 const GLuint z
[], GLubyte mask
[] )
605 /* switch cases ordered from most frequent to less frequent */
606 switch (ctx
->Depth
.Func
) {
608 if (ctx
->Depth
.Mask
) {
609 /* Update Z buffer */
611 for (i
=0; i
<n
; i
++) {
613 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
626 /* Don't update Z buffer */
628 for (i
=0; i
<n
; i
++) {
630 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
643 if (ctx
->Depth
.Mask
) {
644 /* Update Z buffer */
646 for (i
=0; i
<n
; i
++) {
648 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
661 /* Don't update Z buffer */
663 for (i
=0; i
<n
; i
++) {
665 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
678 if (ctx
->Depth
.Mask
) {
679 /* Update Z buffer */
681 for (i
=0; i
<n
; i
++) {
683 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
696 /* Don't update Z buffer */
698 for (i
=0; i
<n
; i
++) {
700 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
713 if (ctx
->Depth
.Mask
) {
714 /* Update Z buffer */
716 for (i
=0; i
<n
; i
++) {
718 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
731 /* Don't update Z buffer */
733 for (i
=0; i
<n
; i
++) {
735 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
748 if (ctx
->Depth
.Mask
) {
749 /* Update Z buffer */
751 for (i
=0; i
<n
; i
++) {
753 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
766 /* Don't update Z buffer */
768 for (i
=0; i
<n
; i
++) {
770 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
783 if (ctx
->Depth
.Mask
) {
784 /* Update Z buffer */
786 for (i
=0; i
<n
; i
++) {
788 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
801 /* Don't update Z buffer */
803 for (i
=0; i
<n
; i
++) {
805 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
818 if (ctx
->Depth
.Mask
) {
819 /* Update Z buffer */
821 for (i
=0; i
<n
; i
++) {
823 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
829 /* Don't update Z buffer or mask */
833 /* depth test never passes */
834 _mesa_bzero(mask
, n
* sizeof(GLubyte
));
837 _mesa_problem(ctx
, "Bad depth func in direct_depth_test_pixels");
844 * Do depth testing for an array of fragments with direct access to zbuffer.
847 direct_depth_test_pixels32(GLcontext
*ctx
, GLuint
*zStart
, GLuint stride
,
848 GLuint n
, const GLint x
[], const GLint y
[],
849 const GLuint z
[], GLubyte mask
[] )
851 /* switch cases ordered from most frequent to less frequent */
852 switch (ctx
->Depth
.Func
) {
854 if (ctx
->Depth
.Mask
) {
855 /* Update Z buffer */
857 for (i
=0; i
<n
; i
++) {
859 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
872 /* Don't update Z buffer */
874 for (i
=0; i
<n
; i
++) {
876 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
889 if (ctx
->Depth
.Mask
) {
890 /* Update Z buffer */
892 for (i
=0; i
<n
; i
++) {
894 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
907 /* Don't update Z buffer */
909 for (i
=0; i
<n
; i
++) {
911 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
924 if (ctx
->Depth
.Mask
) {
925 /* Update Z buffer */
927 for (i
=0; i
<n
; i
++) {
929 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
942 /* Don't update Z buffer */
944 for (i
=0; i
<n
; i
++) {
946 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
959 if (ctx
->Depth
.Mask
) {
960 /* Update Z buffer */
962 for (i
=0; i
<n
; i
++) {
964 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
977 /* Don't update Z buffer */
979 for (i
=0; i
<n
; i
++) {
981 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
994 if (ctx
->Depth
.Mask
) {
995 /* Update Z buffer */
997 for (i
=0; i
<n
; i
++) {
999 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
1000 if (z
[i
] != *zptr
) {
1012 /* Don't update Z buffer */
1014 for (i
=0; i
<n
; i
++) {
1016 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
1017 if (z
[i
] != *zptr
) {
1029 if (ctx
->Depth
.Mask
) {
1030 /* Update Z buffer */
1032 for (i
=0; i
<n
; i
++) {
1034 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
1035 if (z
[i
] == *zptr
) {
1047 /* Don't update Z buffer */
1049 for (i
=0; i
<n
; i
++) {
1051 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
1052 if (z
[i
] == *zptr
) {
1064 if (ctx
->Depth
.Mask
) {
1065 /* Update Z buffer */
1067 for (i
=0; i
<n
; i
++) {
1069 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
1075 /* Don't update Z buffer or mask */
1079 /* depth test never passes */
1080 _mesa_bzero(mask
, n
* sizeof(GLubyte
));
1083 _mesa_problem(ctx
, "Bad depth func in direct_depth_test_pixels");
1091 depth_test_pixels( GLcontext
*ctx
, SWspan
*span
)
1093 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
1094 struct gl_renderbuffer
*rb
= fb
->_DepthBuffer
;
1095 const GLuint count
= span
->end
;
1096 const GLint
*x
= span
->array
->x
;
1097 const GLint
*y
= span
->array
->y
;
1098 const GLuint
*z
= span
->array
->z
;
1099 GLubyte
*mask
= span
->array
->mask
;
1101 if (rb
->GetPointer(ctx
, rb
, 0, 0)) {
1102 /* Directly access values */
1103 if (rb
->DataType
== GL_UNSIGNED_SHORT
) {
1104 GLushort
*zStart
= (GLushort
*) rb
->Data
;
1105 GLuint stride
= rb
->Width
;
1106 direct_depth_test_pixels16(ctx
, zStart
, stride
, count
, x
, y
, z
, mask
);
1109 GLuint
*zStart
= (GLuint
*) rb
->Data
;
1110 GLuint stride
= rb
->Width
;
1111 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
);
1112 direct_depth_test_pixels32(ctx
, zStart
, stride
, count
, x
, y
, z
, mask
);
1116 /* read depth values from buffer, test, write back */
1117 if (rb
->DataType
== GL_UNSIGNED_SHORT
) {
1118 GLushort zbuffer
[MAX_WIDTH
];
1119 _swrast_get_values(ctx
, rb
, count
, x
, y
, zbuffer
, sizeof(GLushort
));
1120 depth_test_span16(ctx
, count
, zbuffer
, z
, mask
);
1121 rb
->PutValues(ctx
, rb
, count
, x
, y
, zbuffer
, mask
);
1124 GLuint zbuffer
[MAX_WIDTH
];
1125 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
);
1126 _swrast_get_values(ctx
, rb
, count
, x
, y
, zbuffer
, sizeof(GLuint
));
1127 depth_test_span32(ctx
, count
, zbuffer
, z
, mask
);
1128 rb
->PutValues(ctx
, rb
, count
, x
, y
, zbuffer
, mask
);
1132 return count
; /* not really correct, but OK */
1137 * Apply depth (Z) buffer testing to the span.
1138 * \return approx number of pixels that passed (only zero is reliable)
1141 _swrast_depth_test_span( GLcontext
*ctx
, SWspan
*span
)
1143 if (span
->arrayMask
& SPAN_XY
)
1144 return depth_test_pixels(ctx
, span
);
1146 return depth_test_span(ctx
, span
);
1151 * GL_EXT_depth_bounds_test extension.
1152 * Discard fragments depending on whether the corresponding Z-buffer
1153 * values are outside the depth bounds test range.
1154 * Note: we test the Z buffer values, not the fragment Z values!
1155 * \return GL_TRUE if any fragments pass, GL_FALSE if no fragments pass
1158 _swrast_depth_bounds_test( GLcontext
*ctx
, SWspan
*span
)
1160 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
1161 struct gl_renderbuffer
*rb
= fb
->_DepthBuffer
;
1162 GLuint zMin
= (GLuint
) (ctx
->Depth
.BoundsMin
* fb
->_DepthMaxF
+ 0.5F
);
1163 GLuint zMax
= (GLuint
) (ctx
->Depth
.BoundsMax
* fb
->_DepthMaxF
+ 0.5F
);
1164 GLubyte
*mask
= span
->array
->mask
;
1165 const GLuint count
= span
->end
;
1167 GLboolean anyPass
= GL_FALSE
;
1169 if (rb
->DataType
== GL_UNSIGNED_SHORT
) {
1170 /* get 16-bit values */
1171 GLushort zbuffer16
[MAX_WIDTH
], *zbuffer
;
1172 if (span
->arrayMask
& SPAN_XY
) {
1173 _swrast_get_values(ctx
, rb
, count
, span
->array
->x
, span
->array
->y
,
1174 zbuffer16
, sizeof(GLushort
));
1175 zbuffer
= zbuffer16
;
1178 zbuffer
= (GLushort
*) rb
->GetPointer(ctx
, rb
, span
->x
, span
->y
);
1180 rb
->GetRow(ctx
, rb
, count
, span
->x
, span
->y
, zbuffer16
);
1181 zbuffer
= zbuffer16
;
1186 /* Now do the tests */
1187 for (i
= 0; i
< count
; i
++) {
1189 if (zbuffer
[i
] < zMin
|| zbuffer
[i
] > zMax
)
1197 /* get 32-bit values */
1198 GLuint zbuffer32
[MAX_WIDTH
], *zbuffer
;
1199 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
);
1200 if (span
->arrayMask
& SPAN_XY
) {
1201 _swrast_get_values(ctx
, rb
, count
, span
->array
->x
, span
->array
->y
,
1202 zbuffer32
, sizeof(GLuint
));
1203 zbuffer
= zbuffer32
;
1206 zbuffer
= (GLuint
*) rb
->GetPointer(ctx
, rb
, span
->x
, span
->y
);
1208 rb
->GetRow(ctx
, rb
, count
, span
->x
, span
->y
, zbuffer32
);
1209 zbuffer
= zbuffer32
;
1214 /* Now do the tests */
1215 for (i
= 0; i
< count
; i
++) {
1217 if (zbuffer
[i
] < zMin
|| zbuffer
[i
] > zMax
)
1230 /**********************************************************************/
1231 /***** Read Depth Buffer *****/
1232 /**********************************************************************/
1236 * Read a span of depth values from the given depth renderbuffer, returning
1237 * the values as GLfloats.
1238 * This function does clipping to prevent reading outside the depth buffer's
1239 * bounds. Though the clipping is redundant when we're called from
1240 * _swrast_ReadPixels.
1243 _swrast_read_depth_span_float( GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
1244 GLint n
, GLint x
, GLint y
, GLfloat depth
[] )
1246 const GLfloat scale
= 1.0F
/ ctx
->DrawBuffer
->_DepthMaxF
;
1249 /* really only doing this to prevent FP exceptions later */
1250 _mesa_bzero(depth
, n
* sizeof(GLfloat
));
1254 ASSERT(rb
->_BaseFormat
== GL_DEPTH_COMPONENT
);
1256 if (y
< 0 || y
>= (GLint
) rb
->Height
||
1257 x
+ n
<= 0 || x
>= (GLint
) rb
->Width
) {
1258 /* span is completely outside framebuffer */
1259 _mesa_bzero(depth
, n
* sizeof(GLfloat
));
1266 for (i
= 0; i
< dx
; i
++)
1272 if (x
+ n
> (GLint
) rb
->Width
) {
1273 GLint dx
= x
+ n
- (GLint
) rb
->Width
;
1275 for (i
= 0; i
< dx
; i
++)
1276 depth
[n
- i
- 1] = 0.0;
1283 if (rb
->DataType
== GL_UNSIGNED_INT
) {
1284 GLuint temp
[MAX_WIDTH
];
1286 rb
->GetRow(ctx
, rb
, n
, x
, y
, temp
);
1287 for (i
= 0; i
< n
; i
++) {
1288 depth
[i
] = temp
[i
] * scale
;
1291 else if (rb
->DataType
== GL_UNSIGNED_SHORT
) {
1292 GLushort temp
[MAX_WIDTH
];
1294 rb
->GetRow(ctx
, rb
, n
, x
, y
, temp
);
1295 for (i
= 0; i
< n
; i
++) {
1296 depth
[i
] = temp
[i
] * scale
;
1300 _mesa_problem(ctx
, "Invalid depth renderbuffer data type");
1306 * As above, but return 32-bit GLuint values.
1309 _swrast_read_depth_span_uint( GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
1310 GLint n
, GLint x
, GLint y
, GLuint depth
[] )
1315 /* really only doing this to prevent FP exceptions later */
1316 _mesa_bzero(depth
, n
* sizeof(GLuint
));
1320 depthBits
= _mesa_get_format_bits(rb
->Format
, GL_DEPTH_BITS
);
1322 ASSERT(rb
->_BaseFormat
== GL_DEPTH_COMPONENT
);
1324 if (y
< 0 || y
>= (GLint
) rb
->Height
||
1325 x
+ n
<= 0 || x
>= (GLint
) rb
->Width
) {
1326 /* span is completely outside framebuffer */
1327 _mesa_bzero(depth
, n
* sizeof(GLfloat
));
1334 for (i
= 0; i
< dx
; i
++)
1340 if (x
+ n
> (GLint
) rb
->Width
) {
1341 GLint dx
= x
+ n
- (GLint
) rb
->Width
;
1343 for (i
= 0; i
< dx
; i
++)
1344 depth
[n
- i
- 1] = 0;
1351 if (rb
->DataType
== GL_UNSIGNED_INT
) {
1352 rb
->GetRow(ctx
, rb
, n
, x
, y
, depth
);
1353 if (depthBits
< 32) {
1354 GLuint shift
= 32 - depthBits
;
1356 for (i
= 0; i
< n
; i
++) {
1357 GLuint z
= depth
[i
];
1358 depth
[i
] = z
<< shift
; /* XXX lsb bits? */
1362 else if (rb
->DataType
== GL_UNSIGNED_SHORT
) {
1363 GLushort temp
[MAX_WIDTH
];
1365 rb
->GetRow(ctx
, rb
, n
, x
, y
, temp
);
1366 if (depthBits
== 16) {
1367 for (i
= 0; i
< n
; i
++) {
1369 depth
[i
] = (z
<< 16) | z
;
1373 GLuint shift
= 16 - depthBits
;
1374 for (i
= 0; i
< n
; i
++) {
1376 depth
[i
] = (z
<< (shift
+ 16)) | (z
<< shift
); /* XXX lsb bits? */
1381 _mesa_problem(ctx
, "Invalid depth renderbuffer data type");
1388 * Clear the given z/depth renderbuffer.
1391 _swrast_clear_depth_buffer( GLcontext
*ctx
, struct gl_renderbuffer
*rb
)
1394 GLint x
, y
, width
, height
;
1396 if (!rb
|| !ctx
->Depth
.Mask
) {
1397 /* no depth buffer, or writing to it is disabled */
1401 /* compute integer clearing value */
1402 if (ctx
->Depth
.Clear
== 1.0) {
1403 clearValue
= ctx
->DrawBuffer
->_DepthMax
;
1406 clearValue
= (GLuint
) (ctx
->Depth
.Clear
* ctx
->DrawBuffer
->_DepthMaxF
);
1409 assert(rb
->_BaseFormat
== GL_DEPTH_COMPONENT
);
1411 /* compute region to clear */
1412 x
= ctx
->DrawBuffer
->_Xmin
;
1413 y
= ctx
->DrawBuffer
->_Ymin
;
1414 width
= ctx
->DrawBuffer
->_Xmax
- ctx
->DrawBuffer
->_Xmin
;
1415 height
= ctx
->DrawBuffer
->_Ymax
- ctx
->DrawBuffer
->_Ymin
;
1417 if (rb
->GetPointer(ctx
, rb
, 0, 0)) {
1418 /* Direct buffer access is possible. Either this is just malloc'd
1419 * memory, or perhaps the driver mmap'd the zbuffer memory.
1421 if (rb
->DataType
== GL_UNSIGNED_SHORT
) {
1422 if ((clearValue
& 0xff) == ((clearValue
>> 8) & 0xff) &&
1423 ((GLushort
*) rb
->GetPointer(ctx
, rb
, 0, 0) + width
==
1424 (GLushort
*) rb
->GetPointer(ctx
, rb
, 0, 1))) {
1425 /* optimized case */
1426 GLushort
*dst
= (GLushort
*) rb
->GetPointer(ctx
, rb
, x
, y
);
1427 GLuint len
= width
* height
* sizeof(GLushort
);
1428 _mesa_memset(dst
, (clearValue
& 0xff), len
);
1433 for (i
= 0; i
< height
; i
++) {
1434 GLushort
*dst
= (GLushort
*) rb
->GetPointer(ctx
, rb
, x
, y
+ i
);
1435 for (j
= 0; j
< width
; j
++) {
1436 dst
[j
] = clearValue
;
1443 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
);
1444 for (i
= 0; i
< height
; i
++) {
1445 GLuint
*dst
= (GLuint
*) rb
->GetPointer(ctx
, rb
, x
, y
+ i
);
1446 for (j
= 0; j
< width
; j
++) {
1447 dst
[j
] = clearValue
;
1453 /* Direct access not possible. Use PutRow to write new values. */
1454 if (rb
->DataType
== GL_UNSIGNED_SHORT
) {
1455 GLushort clearVal16
= (GLushort
) (clearValue
& 0xffff);
1457 for (i
= 0; i
< height
; i
++) {
1458 rb
->PutMonoRow(ctx
, rb
, width
, x
, y
+ i
, &clearVal16
, NULL
);
1461 else if (rb
->DataType
== GL_UNSIGNED_INT
) {
1463 ASSERT(sizeof(clearValue
) == sizeof(GLuint
));
1464 for (i
= 0; i
< height
; i
++) {
1465 rb
->PutMonoRow(ctx
, rb
, width
, x
, y
+ i
, &clearValue
, NULL
);
1469 _mesa_problem(ctx
, "bad depth renderbuffer DataType");