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/format_unpack.h"
30 #include "main/format_pack.h"
31 #include "main/macros.h"
32 #include "main/imports.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( struct gl_context
*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 memset(mask
, 0, n
* sizeof(GLubyte
));
266 _mesa_problem(ctx
, "Bad depth func in depth_test_span16");
274 depth_test_span32( struct gl_context
*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 memset(mask
, 0, n
* sizeof(GLubyte
));
495 _mesa_problem(ctx
, "Bad depth func in depth_test_span32");
504 * Clamp fragment Z values to the depth near/far range (glDepthRange()).
505 * This is used when GL_ARB_depth_clamp/GL_DEPTH_CLAMP is turned on.
506 * In that case, vertexes are not clipped against the near/far planes
507 * so rasterization will produce fragment Z values outside the usual
511 _swrast_depth_clamp_span( struct gl_context
*ctx
, SWspan
*span
)
513 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
514 const GLuint count
= span
->end
;
515 GLint
*zValues
= (GLint
*) span
->array
->z
; /* sign change */
517 GLfloat min_f
, max_f
;
520 if (ctx
->Viewport
.Near
< ctx
->Viewport
.Far
) {
521 min_f
= ctx
->Viewport
.Near
;
522 max_f
= ctx
->Viewport
.Far
;
524 min_f
= ctx
->Viewport
.Far
;
525 max_f
= ctx
->Viewport
.Near
;
528 /* Convert floating point values in [0,1] to device Z coordinates in
530 * ex: If the Z buffer has 24 bits, DepthMax = 0xffffff.
532 * XXX this all falls apart if we have 31 or more bits of Z because
533 * the triangle rasterization code produces unsigned Z values. Negative
534 * vertex Z values come out as large fragment Z uints.
536 min
= (GLint
) (min_f
* fb
->_DepthMaxF
);
537 max
= (GLint
) (max_f
* fb
->_DepthMaxF
);
539 max
= 0x7fffffff; /* catch over flow for 30-bit z */
541 /* Note that we do the comparisons here using signed integers.
543 for (i
= 0; i
< count
; i
++) {
544 if (zValues
[i
] < min
)
546 if (zValues
[i
] > max
)
553 * Get array of 16-bit z values from the depth buffer. With clipping.
556 get_z16_values(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
557 GLuint count
, const GLint x
[], const GLint y
[],
560 const GLint w
= rb
->Width
, h
= rb
->Height
;
561 const GLubyte
*map
= (const GLubyte
*) rb
->Data
;
564 if (rb
->Format
== MESA_FORMAT_Z16
) {
565 const GLuint rowStride
= rb
->RowStride
* 2;
566 for (i
= 0; i
< count
; i
++) {
567 if (x
[i
] >= 0 && y
[i
] >= 0 && x
[i
] < w
&& y
[i
] < h
) {
568 zbuffer
[i
] = *((GLushort
*) (map
+ y
[i
] * rowStride
+ x
[i
] * 2));
573 const GLuint bpp
= _mesa_get_format_bytes(rb
->Format
);
574 const GLuint rowStride
= rb
->RowStride
* bpp
;
575 for (i
= 0; i
< count
; i
++) {
576 if (x
[i
] >= 0 && y
[i
] >= 0 && x
[i
] < w
&& y
[i
] < h
) {
578 const GLubyte
*src
= map
+ y
[i
] * rowStride
+ x
[i
] * bpp
;
579 _mesa_unpack_uint_z_row(rb
->Format
, 1, src
, &d32
);
580 zbuffer
[i
] = d32
>> 16;
588 * Get array of 32-bit z values from the depth buffer. With clipping.
591 get_z32_values(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
592 GLuint count
, const GLint x
[], const GLint y
[],
595 const GLint w
= rb
->Width
, h
= rb
->Height
;
596 const GLubyte
*map
= (const GLubyte
*) rb
->Data
;
599 if (rb
->Format
== MESA_FORMAT_Z32
) {
600 const GLuint rowStride
= rb
->RowStride
* 4;
601 for (i
= 0; i
< count
; i
++) {
602 if (x
[i
] >= 0 && y
[i
] >= 0 && x
[i
] < w
&& y
[i
] < h
) {
603 zbuffer
[i
] = *((GLuint
*) (map
+ y
[i
] * rowStride
+ x
[i
] * 4));
608 const GLuint bpp
= _mesa_get_format_bytes(rb
->Format
);
609 const GLuint rowStride
= rb
->RowStride
* bpp
;
610 for (i
= 0; i
< count
; i
++) {
611 if (x
[i
] >= 0 && y
[i
] >= 0 && x
[i
] < w
&& y
[i
] < h
) {
612 const GLubyte
*src
= map
+ y
[i
] * rowStride
+ x
[i
] * bpp
;
613 _mesa_unpack_uint_z_row(rb
->Format
, 1, src
, &zbuffer
[i
]);
622 * Apply depth test to span of fragments.
625 depth_test_span( struct gl_context
*ctx
, SWspan
*span
)
627 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
628 struct gl_renderbuffer
*rb
= fb
->_DepthBuffer
;
629 const GLint x
= span
->x
;
630 const GLint y
= span
->y
;
631 const GLuint count
= span
->end
;
632 const GLuint
*zValues
= span
->array
->z
;
633 GLubyte
*mask
= span
->array
->mask
;
636 ASSERT((span
->arrayMask
& SPAN_XY
) == 0);
637 ASSERT(span
->arrayMask
& SPAN_Z
);
639 if (rb
->GetPointer(ctx
, rb
, 0, 0)) {
640 /* Directly access buffer */
641 if (rb
->DataType
== GL_UNSIGNED_SHORT
) {
642 GLushort
*zbuffer
= (GLushort
*) rb
->GetPointer(ctx
, rb
, x
, y
);
643 passed
= depth_test_span16(ctx
, count
, zbuffer
, zValues
, mask
);
646 GLuint
*zbuffer
= (GLuint
*) rb
->GetPointer(ctx
, rb
, x
, y
);
647 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
);
648 passed
= depth_test_span32(ctx
, count
, zbuffer
, zValues
, mask
);
652 /* read depth values from buffer, test, write back */
653 if (rb
->DataType
== GL_UNSIGNED_SHORT
) {
654 GLushort zbuffer
[MAX_WIDTH
];
655 rb
->GetRow(ctx
, rb
, count
, x
, y
, zbuffer
);
656 passed
= depth_test_span16(ctx
, count
, zbuffer
, zValues
, mask
);
657 rb
->PutRow(ctx
, rb
, count
, x
, y
, zbuffer
, mask
);
660 GLuint zbuffer
[MAX_WIDTH
];
661 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
);
662 rb
->GetRow(ctx
, rb
, count
, x
, y
, zbuffer
);
663 passed
= depth_test_span32(ctx
, count
, zbuffer
, zValues
, mask
);
664 rb
->PutRow(ctx
, rb
, count
, x
, y
, zbuffer
, mask
);
668 if (passed
< count
) {
669 span
->writeAll
= GL_FALSE
;
676 #define Z_ADDRESS(X, Y) (zStart + (Y) * stride + (X))
680 * Do depth testing for an array of fragments at assorted locations.
683 direct_depth_test_pixels16(struct gl_context
*ctx
, GLushort
*zStart
, GLuint stride
,
684 GLuint n
, const GLint x
[], const GLint y
[],
685 const GLuint z
[], GLubyte mask
[] )
687 /* switch cases ordered from most frequent to less frequent */
688 switch (ctx
->Depth
.Func
) {
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
]);
848 /* Don't update Z buffer */
850 for (i
=0; i
<n
; i
++) {
852 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
865 if (ctx
->Depth
.Mask
) {
866 /* Update Z buffer */
868 for (i
=0; i
<n
; i
++) {
870 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
883 /* Don't update Z buffer */
885 for (i
=0; i
<n
; i
++) {
887 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
900 if (ctx
->Depth
.Mask
) {
901 /* Update Z buffer */
903 for (i
=0; i
<n
; i
++) {
905 GLushort
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
911 /* Don't update Z buffer or mask */
915 /* depth test never passes */
916 memset(mask
, 0, n
* sizeof(GLubyte
));
919 _mesa_problem(ctx
, "Bad depth func in direct_depth_test_pixels");
926 * Do depth testing for an array of fragments with direct access to zbuffer.
929 direct_depth_test_pixels32(struct gl_context
*ctx
, GLuint
*zStart
, GLuint stride
,
930 GLuint n
, const GLint x
[], const GLint y
[],
931 const GLuint z
[], GLubyte mask
[] )
933 /* switch cases ordered from most frequent to less frequent */
934 switch (ctx
->Depth
.Func
) {
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
]);
1059 /* Don't update Z buffer */
1061 for (i
=0; i
<n
; i
++) {
1063 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
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
]);
1082 if (z
[i
] != *zptr
) {
1094 /* Don't update Z buffer */
1096 for (i
=0; i
<n
; i
++) {
1098 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
1099 if (z
[i
] != *zptr
) {
1111 if (ctx
->Depth
.Mask
) {
1112 /* Update Z buffer */
1114 for (i
=0; i
<n
; i
++) {
1116 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
1117 if (z
[i
] == *zptr
) {
1129 /* Don't update Z buffer */
1131 for (i
=0; i
<n
; i
++) {
1133 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
1134 if (z
[i
] == *zptr
) {
1146 if (ctx
->Depth
.Mask
) {
1147 /* Update Z buffer */
1149 for (i
=0; i
<n
; i
++) {
1151 GLuint
*zptr
= Z_ADDRESS(x
[i
], y
[i
]);
1157 /* Don't update Z buffer or mask */
1161 /* depth test never passes */
1162 memset(mask
, 0, n
* sizeof(GLubyte
));
1165 _mesa_problem(ctx
, "Bad depth func in direct_depth_test_pixels");
1173 depth_test_pixels( struct gl_context
*ctx
, SWspan
*span
)
1175 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
1176 struct gl_renderbuffer
*rb
= fb
->_DepthBuffer
;
1177 const GLuint count
= span
->end
;
1178 const GLint
*x
= span
->array
->x
;
1179 const GLint
*y
= span
->array
->y
;
1180 const GLuint
*z
= span
->array
->z
;
1181 GLubyte
*mask
= span
->array
->mask
;
1183 if (rb
->GetPointer(ctx
, rb
, 0, 0)) {
1184 /* Directly access values */
1185 if (rb
->DataType
== GL_UNSIGNED_SHORT
) {
1186 GLushort
*zStart
= (GLushort
*) rb
->Data
;
1187 GLuint stride
= rb
->Width
;
1188 direct_depth_test_pixels16(ctx
, zStart
, stride
, count
, x
, y
, z
, mask
);
1191 GLuint
*zStart
= (GLuint
*) rb
->Data
;
1192 GLuint stride
= rb
->Width
;
1193 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
);
1194 direct_depth_test_pixels32(ctx
, zStart
, stride
, count
, x
, y
, z
, mask
);
1198 /* read depth values from buffer, test, write back */
1199 if (rb
->DataType
== GL_UNSIGNED_SHORT
) {
1200 GLushort zbuffer
[MAX_WIDTH
];
1201 get_z16_values(ctx
, rb
, count
, x
, y
, zbuffer
);
1202 depth_test_span16(ctx
, count
, zbuffer
, z
, mask
);
1203 rb
->PutValues(ctx
, rb
, count
, x
, y
, zbuffer
, mask
);
1206 GLuint zbuffer
[MAX_WIDTH
];
1207 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
);
1208 get_z32_values(ctx
, rb
, count
, x
, y
, zbuffer
);
1209 depth_test_span32(ctx
, count
, zbuffer
, z
, mask
);
1210 rb
->PutValues(ctx
, rb
, count
, x
, y
, zbuffer
, mask
);
1214 return count
; /* not really correct, but OK */
1219 * Apply depth (Z) buffer testing to the span.
1220 * \return approx number of pixels that passed (only zero is reliable)
1223 _swrast_depth_test_span( struct gl_context
*ctx
, SWspan
*span
)
1225 if (span
->arrayMask
& SPAN_XY
)
1226 return depth_test_pixels(ctx
, span
);
1228 return depth_test_span(ctx
, span
);
1233 * GL_EXT_depth_bounds_test extension.
1234 * Discard fragments depending on whether the corresponding Z-buffer
1235 * values are outside the depth bounds test range.
1236 * Note: we test the Z buffer values, not the fragment Z values!
1237 * \return GL_TRUE if any fragments pass, GL_FALSE if no fragments pass
1240 _swrast_depth_bounds_test( struct gl_context
*ctx
, SWspan
*span
)
1242 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
1243 struct gl_renderbuffer
*rb
= fb
->_DepthBuffer
;
1244 GLuint zMin
= (GLuint
) (ctx
->Depth
.BoundsMin
* fb
->_DepthMaxF
+ 0.5F
);
1245 GLuint zMax
= (GLuint
) (ctx
->Depth
.BoundsMax
* fb
->_DepthMaxF
+ 0.5F
);
1246 GLubyte
*mask
= span
->array
->mask
;
1247 const GLuint count
= span
->end
;
1249 GLboolean anyPass
= GL_FALSE
;
1251 if (rb
->DataType
== GL_UNSIGNED_SHORT
) {
1252 /* get 16-bit values */
1253 GLushort zbuffer16
[MAX_WIDTH
], *zbuffer
;
1254 if (span
->arrayMask
& SPAN_XY
) {
1255 get_z16_values(ctx
, rb
, count
, span
->array
->x
, span
->array
->y
,
1257 zbuffer
= zbuffer16
;
1260 zbuffer
= (GLushort
*) rb
->GetPointer(ctx
, rb
, span
->x
, span
->y
);
1262 rb
->GetRow(ctx
, rb
, count
, span
->x
, span
->y
, zbuffer16
);
1263 zbuffer
= zbuffer16
;
1268 /* Now do the tests */
1269 for (i
= 0; i
< count
; i
++) {
1271 if (zbuffer
[i
] < zMin
|| zbuffer
[i
] > zMax
)
1279 /* get 32-bit values */
1280 GLuint zbuffer32
[MAX_WIDTH
], *zbuffer
;
1281 ASSERT(rb
->DataType
== GL_UNSIGNED_INT
);
1282 if (span
->arrayMask
& SPAN_XY
) {
1283 get_z32_values(ctx
, rb
, count
, span
->array
->x
, span
->array
->y
,
1285 zbuffer
= zbuffer32
;
1288 zbuffer
= (GLuint
*) rb
->GetPointer(ctx
, rb
, span
->x
, span
->y
);
1290 rb
->GetRow(ctx
, rb
, count
, span
->x
, span
->y
, zbuffer32
);
1291 zbuffer
= zbuffer32
;
1296 /* Now do the tests */
1297 for (i
= 0; i
< count
; i
++) {
1299 if (zbuffer
[i
] < zMin
|| zbuffer
[i
] > zMax
)
1312 /**********************************************************************/
1313 /***** Read Depth Buffer *****/
1314 /**********************************************************************/
1318 * Read a span of depth values from the given depth renderbuffer, returning
1319 * the values as GLfloats.
1320 * This function does clipping to prevent reading outside the depth buffer's
1324 _swrast_read_depth_span_float( struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
1325 GLint n
, GLint x
, GLint y
, GLfloat depth
[] )
1327 const GLfloat scale
= 1.0F
/ ctx
->DrawBuffer
->_DepthMaxF
;
1330 /* really only doing this to prevent FP exceptions later */
1331 memset(depth
, 0, n
* sizeof(GLfloat
));
1335 ASSERT(rb
->_BaseFormat
== GL_DEPTH_COMPONENT
);
1337 if (y
< 0 || y
>= (GLint
) rb
->Height
||
1338 x
+ n
<= 0 || x
>= (GLint
) rb
->Width
) {
1339 /* span is completely outside framebuffer */
1340 memset(depth
, 0, n
* sizeof(GLfloat
));
1347 for (i
= 0; i
< dx
; i
++)
1353 if (x
+ n
> (GLint
) rb
->Width
) {
1354 GLint dx
= x
+ n
- (GLint
) rb
->Width
;
1356 for (i
= 0; i
< dx
; i
++)
1357 depth
[n
- i
- 1] = 0.0;
1364 if (rb
->DataType
== GL_UNSIGNED_INT
) {
1365 GLuint temp
[MAX_WIDTH
];
1367 rb
->GetRow(ctx
, rb
, n
, x
, y
, temp
);
1368 for (i
= 0; i
< n
; i
++) {
1369 depth
[i
] = temp
[i
] * scale
;
1372 else if (rb
->DataType
== GL_UNSIGNED_SHORT
) {
1373 GLushort temp
[MAX_WIDTH
];
1375 rb
->GetRow(ctx
, rb
, n
, x
, y
, temp
);
1376 for (i
= 0; i
< n
; i
++) {
1377 depth
[i
] = temp
[i
] * scale
;
1381 _mesa_problem(ctx
, "Invalid depth renderbuffer data type");
1387 * Clear the given z/depth renderbuffer. If the buffer is a combined
1388 * depth+stencil buffer, only the Z bits will be touched.
1391 _swrast_clear_depth_buffer(struct gl_context
*ctx
)
1393 struct gl_renderbuffer
*rb
=
1394 ctx
->DrawBuffer
->Attachment
[BUFFER_DEPTH
].Renderbuffer
;
1396 GLint x
, y
, width
, height
;
1398 GLint rowStride
, i
, j
;
1401 if (!rb
|| !ctx
->Depth
.Mask
) {
1402 /* no depth buffer, or writing to it is disabled */
1406 /* compute integer clearing value */
1407 if (ctx
->Depth
.Clear
== 1.0) {
1408 clearValue
= ctx
->DrawBuffer
->_DepthMax
;
1411 clearValue
= (GLuint
) (ctx
->Depth
.Clear
* ctx
->DrawBuffer
->_DepthMaxF
);
1414 /* compute region to clear */
1415 x
= ctx
->DrawBuffer
->_Xmin
;
1416 y
= ctx
->DrawBuffer
->_Ymin
;
1417 width
= ctx
->DrawBuffer
->_Xmax
- ctx
->DrawBuffer
->_Xmin
;
1418 height
= ctx
->DrawBuffer
->_Ymax
- ctx
->DrawBuffer
->_Ymin
;
1420 mapMode
= GL_MAP_WRITE_BIT
;
1421 if (rb
->Format
== MESA_FORMAT_S8_Z24
||
1422 rb
->Format
== MESA_FORMAT_X8_Z24
||
1423 rb
->Format
== MESA_FORMAT_Z24_S8
||
1424 rb
->Format
== MESA_FORMAT_Z24_X8
) {
1425 mapMode
|= GL_MAP_READ_BIT
;
1428 ctx
->Driver
.MapRenderbuffer(ctx
, rb
, x
, y
, width
, height
,
1429 mapMode
, &map
, &rowStride
);
1431 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glClear(depth)");
1435 switch (rb
->Format
) {
1436 case MESA_FORMAT_Z16
:
1438 GLfloat clear
= (GLfloat
) ctx
->Depth
.Clear
;
1439 GLushort clearVal
= 0;
1440 _mesa_pack_float_z_row(rb
->Format
, 1, &clear
, &clearVal
);
1441 if (clearVal
== 0xffff && width
* 2 == rowStride
) {
1443 memset(map
, 0xff, width
* height
* 2);
1446 for (i
= 0; i
< height
; i
++) {
1447 GLushort
*row
= (GLushort
*) map
;
1448 for (j
= 0; j
< width
; j
++) {
1456 case MESA_FORMAT_Z32
:
1457 case MESA_FORMAT_Z32_FLOAT
:
1459 GLfloat clear
= (GLfloat
) ctx
->Depth
.Clear
;
1460 GLuint clearVal
= 0;
1461 _mesa_pack_float_z_row(rb
->Format
, 1, &clear
, &clearVal
);
1462 for (i
= 0; i
< height
; i
++) {
1463 GLuint
*row
= (GLuint
*) map
;
1464 for (j
= 0; j
< width
; j
++) {
1471 case MESA_FORMAT_S8_Z24
:
1472 case MESA_FORMAT_X8_Z24
:
1473 case MESA_FORMAT_Z24_S8
:
1474 case MESA_FORMAT_Z24_X8
:
1476 GLfloat clear
= (GLfloat
) ctx
->Depth
.Clear
;
1477 GLuint clearVal
= 0;
1480 if (rb
->Format
== MESA_FORMAT_S8_Z24
||
1481 rb
->Format
== MESA_FORMAT_X8_Z24
)
1486 _mesa_pack_float_z_row(rb
->Format
, 1, &clear
, &clearVal
);
1487 for (i
= 0; i
< height
; i
++) {
1488 GLuint
*row
= (GLuint
*) map
;
1489 for (j
= 0; j
< width
; j
++) {
1490 row
[j
] = (row
[j
] & mask
) | clearVal
;
1497 case MESA_FORMAT_Z32_FLOAT_X24S8
:
1500 GLfloat clearVal
= (GLfloat
) ctx
->Depth
.Clear
;
1501 for (i
= 0; i
< height
; i
++) {
1502 GLfloat
*row
= (GLfloat
*) map
;
1503 for (j
= 0; j
< width
; j
++) {
1504 row
[j
* 2] = clearVal
;
1511 _mesa_problem(ctx
, "Unexpected depth buffer format %s"
1512 " in _swrast_clear_depth_buffer()",
1513 _mesa_get_format_name(rb
->Format
));
1516 ctx
->Driver
.UnmapRenderbuffer(ctx
, rb
);
1523 * Clear both depth and stencil values in a combined depth+stencil buffer.
1526 _swrast_clear_depth_stencil_buffer(struct gl_context
*ctx
)
1528 const GLubyte stencilBits
= ctx
->DrawBuffer
->Visual
.stencilBits
;
1529 const GLuint writeMask
= ctx
->Stencil
.WriteMask
[0];
1530 const GLuint stencilMax
= (1 << stencilBits
) - 1;
1531 struct gl_renderbuffer
*rb
=
1532 ctx
->DrawBuffer
->Attachment
[BUFFER_DEPTH
].Renderbuffer
;
1533 GLint x
, y
, width
, height
;
1536 GLint rowStride
, i
, j
;
1538 /* check that we really have a combined depth+stencil buffer */
1539 assert(rb
== ctx
->DrawBuffer
->Attachment
[BUFFER_STENCIL
].Renderbuffer
);
1541 /* compute region to clear */
1542 x
= ctx
->DrawBuffer
->_Xmin
;
1543 y
= ctx
->DrawBuffer
->_Ymin
;
1544 width
= ctx
->DrawBuffer
->_Xmax
- ctx
->DrawBuffer
->_Xmin
;
1545 height
= ctx
->DrawBuffer
->_Ymax
- ctx
->DrawBuffer
->_Ymin
;
1547 mapMode
= GL_MAP_WRITE_BIT
;
1548 if ((writeMask
& stencilMax
) != stencilMax
) {
1549 /* need to mask stencil values */
1550 mapMode
|= GL_MAP_READ_BIT
;
1553 ctx
->Driver
.MapRenderbuffer(ctx
, rb
, x
, y
, width
, height
,
1554 mapMode
, &map
, &rowStride
);
1556 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glClear(depth+stencil)");
1560 switch (rb
->Format
) {
1561 case MESA_FORMAT_S8_Z24
:
1562 case MESA_FORMAT_Z24_S8
:
1564 GLfloat zClear
= (GLfloat
) ctx
->Depth
.Clear
;
1565 GLuint clear
= 0, mask
;
1567 _mesa_pack_float_z_row(rb
->Format
, 1, &zClear
, &clear
);
1569 if (rb
->Format
== MESA_FORMAT_S8_Z24
) {
1570 mask
= ((~writeMask
) & 0xff) << 24;
1571 clear
|= (ctx
->Stencil
.Clear
& writeMask
& 0xff) << 24;
1574 mask
= ((~writeMask
) & 0xff);
1575 clear
|= (ctx
->Stencil
.Clear
& writeMask
& 0xff);
1578 for (i
= 0; i
< height
; i
++) {
1579 GLuint
*row
= (GLuint
*) map
;
1581 for (j
= 0; j
< width
; j
++) {
1582 row
[j
] = (row
[j
] & mask
) | clear
;
1586 for (j
= 0; j
< width
; j
++) {
1594 case MESA_FORMAT_Z32_FLOAT_X24S8
:
1597 const GLfloat zClear
= (GLfloat
) ctx
->Depth
.Clear
;
1598 const GLuint sClear
= ctx
->Stencil
.Clear
& writeMask
;
1599 const GLuint sMask
= (~writeMask
) & 0xff;
1600 for (i
= 0; i
< height
; i
++) {
1601 GLfloat
*zRow
= (GLfloat
*) map
;
1602 GLuint
*sRow
= (GLuint
*) map
;
1603 for (j
= 0; j
< width
; j
++) {
1604 zRow
[j
* 2 + 0] = zClear
;
1607 for (j
= 0; j
< width
; j
++) {
1608 sRow
[j
* 2 + 1] = (sRow
[j
* 2 + 1] & sMask
) | sClear
;
1612 for (j
= 0; j
< width
; j
++) {
1613 sRow
[j
* 2 + 1] = sClear
;
1621 _mesa_problem(ctx
, "Unexpected depth buffer format %s"
1622 " in _swrast_clear_depth_buffer()",
1623 _mesa_get_format_name(rb
->Format
));
1626 ctx
->Driver
.UnmapRenderbuffer(ctx
, rb
);