2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2005 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 * \brief Quad depth testing
29 #include "pipe/p_defines.h"
30 #include "pipe/p_util.h"
31 #include "sp_context.h"
32 #include "sp_headers.h"
33 #include "sp_surface.h"
38 * Do depth testing for a quad.
39 * Not static since it's used by the stencil code.
42 sp_depth_test_quad(struct quad_stage
*qs
, struct quad_header
*quad
)
44 struct softpipe_context
*softpipe
= qs
->softpipe
;
45 struct softpipe_surface
*sps
= softpipe_surface(softpipe
->framebuffer
.zbuf
);
46 unsigned bzzzz
[QUAD_SIZE
]; /**< Z values fetched from depth buffer */
47 unsigned qzzzz
[QUAD_SIZE
]; /**< Z values from the quad */
52 assert(sps
); /* shouldn't get here if there's no zbuffer */
55 * To increase efficiency, we should probably have multiple versions
56 * of this function that are specifically for Z16, Z32 and FP Z buffers.
57 * Try to effectively do that with codegen...
59 if (sps
->surface
.format
== PIPE_FORMAT_U_Z16
)
61 else if (sps
->surface
.format
== PIPE_FORMAT_S8_Z24
)
62 scale
= (float) ((1 << 24) - 1);
64 assert(0); /* XXX fix this someday */
67 * Convert quad's float depth values to int depth values.
68 * If the Z buffer stores integer values, we _have_ to do the depth
69 * compares with integers (not floats). Otherwise, the float->int->float
70 * conversion of Z values (which isn't an identity function) will cause
73 for (j
= 0; j
< QUAD_SIZE
; j
++) {
74 qzzzz
[j
] = (unsigned) (quad
->outputs
.depth
[j
] * scale
);
77 /* get zquad from zbuffer */
78 sps
->read_quad_z(sps
, quad
->x0
, quad
->y0
, bzzzz
);
80 switch (softpipe
->depth_stencil
->depth
.func
) {
85 /* Note this is pretty much a single sse or cell instruction.
86 * Like this: quad->mask &= (quad->outputs.depth < zzzz);
88 for (j
= 0; j
< QUAD_SIZE
; j
++) {
89 if (qzzzz
[j
] < bzzzz
[j
])
94 for (j
= 0; j
< QUAD_SIZE
; j
++) {
95 if (qzzzz
[j
] == bzzzz
[j
])
99 case PIPE_FUNC_LEQUAL
:
100 for (j
= 0; j
< QUAD_SIZE
; j
++) {
101 if (qzzzz
[j
] <= bzzzz
[j
])
105 case PIPE_FUNC_GREATER
:
106 for (j
= 0; j
< QUAD_SIZE
; j
++) {
107 if (qzzzz
[j
] > bzzzz
[j
])
111 case PIPE_FUNC_NOTEQUAL
:
112 for (j
= 0; j
< QUAD_SIZE
; j
++) {
113 if (qzzzz
[j
] != bzzzz
[j
])
117 case PIPE_FUNC_GEQUAL
:
118 for (j
= 0; j
< QUAD_SIZE
; j
++) {
119 if (qzzzz
[j
] >= bzzzz
[j
])
123 case PIPE_FUNC_ALWAYS
:
132 if (softpipe
->depth_stencil
->depth
.writemask
) {
134 /* This is also efficient with sse / spe instructions:
136 for (j
= 0; j
< QUAD_SIZE
; j
++) {
137 if (quad
->mask
& (1 << j
)) {
142 /* write updated zquad to zbuffer */
143 sps
->write_quad_z(sps
, quad
->x0
, quad
->y0
, bzzzz
);
149 depth_test_quad(struct quad_stage
*qs
, struct quad_header
*quad
)
151 sp_depth_test_quad(qs
, quad
);
154 qs
->next
->run(qs
->next
, quad
);
158 static void depth_test_begin(struct quad_stage
*qs
)
161 qs
->next
->begin(qs
->next
);
165 struct quad_stage
*sp_quad_depth_test_stage( struct softpipe_context
*softpipe
)
167 struct quad_stage
*stage
= CALLOC_STRUCT(quad_stage
);
169 stage
->softpipe
= softpipe
;
170 stage
->begin
= depth_test_begin
;
171 stage
->run
= depth_test_quad
;