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 "main/glheader.h"
30 #include "main/imports.h"
31 #include "pipe/p_defines.h"
32 #include "sp_context.h"
33 #include "sp_headers.h"
34 #include "sp_surface.h"
39 * Do depth testing for a quad.
40 * Not static since it's used by the stencil code.
43 sp_depth_test_quad(struct quad_stage
*qs
, struct quad_header
*quad
)
45 struct softpipe_context
*softpipe
= qs
->softpipe
;
46 struct softpipe_surface
*sps
= softpipe_surface(softpipe
->framebuffer
.zbuf
);
47 GLuint bzzzz
[QUAD_SIZE
]; /**< Z values fetched from depth buffer */
48 GLuint qzzzz
[QUAD_SIZE
]; /**< Z values from the quad */
53 assert(sps
); /* shouldn't get here if there's no zbuffer */
56 * To increase efficiency, we should probably have multiple versions
57 * of this function that are specifically for Z16, Z32 and FP Z buffers.
58 * Try to effectively do that with codegen...
60 if (sps
->surface
.format
== PIPE_FORMAT_U_Z16
)
62 else if (sps
->surface
.format
== PIPE_FORMAT_S8_Z24
)
63 scale
= (float) ((1 << 24) - 1);
65 assert(0); /* XXX fix this someday */
68 * Convert quad's float depth values to int depth values.
69 * If the Z buffer stores integer values, we _have_ to do the depth
70 * compares with integers (not floats). Otherwise, the float->int->float
71 * conversion of Z values (which isn't an identity function) will cause
74 for (j
= 0; j
< QUAD_SIZE
; j
++) {
75 qzzzz
[j
] = (GLuint
) (quad
->outputs
.depth
[j
] * scale
);
78 /* get zquad from zbuffer */
79 sps
->read_quad_z(sps
, quad
->x0
, quad
->y0
, bzzzz
);
81 switch (softpipe
->depth_test
.func
) {
86 /* Note this is pretty much a single sse or cell instruction.
87 * Like this: quad->mask &= (quad->outputs.depth < zzzz);
89 for (j
= 0; j
< QUAD_SIZE
; j
++) {
90 if (qzzzz
[j
] < bzzzz
[j
])
95 for (j
= 0; j
< QUAD_SIZE
; j
++) {
96 if (qzzzz
[j
] == bzzzz
[j
])
100 case PIPE_FUNC_LEQUAL
:
101 for (j
= 0; j
< QUAD_SIZE
; j
++) {
102 if (qzzzz
[j
] <= bzzzz
[j
])
106 case PIPE_FUNC_GREATER
:
107 for (j
= 0; j
< QUAD_SIZE
; j
++) {
108 if (qzzzz
[j
] > bzzzz
[j
])
112 case PIPE_FUNC_NOTEQUAL
:
113 for (j
= 0; j
< QUAD_SIZE
; j
++) {
114 if (qzzzz
[j
] != bzzzz
[j
])
118 case PIPE_FUNC_GEQUAL
:
119 for (j
= 0; j
< QUAD_SIZE
; j
++) {
120 if (qzzzz
[j
] >= bzzzz
[j
])
124 case PIPE_FUNC_ALWAYS
:
133 if (softpipe
->depth_test
.writemask
) {
135 /* This is also efficient with sse / spe instructions:
137 for (j
= 0; j
< QUAD_SIZE
; j
++) {
138 if (quad
->mask
& (1 << j
)) {
143 /* write updated zquad to zbuffer */
144 sps
->write_quad_z(sps
, quad
->x0
, quad
->y0
, bzzzz
);
150 depth_test_quad(struct quad_stage
*qs
, struct quad_header
*quad
)
152 sp_depth_test_quad(qs
, quad
);
155 qs
->next
->run(qs
->next
, quad
);
159 static void depth_test_begin(struct quad_stage
*qs
)
162 qs
->next
->begin(qs
->next
);
166 struct quad_stage
*sp_quad_depth_test_stage( struct softpipe_context
*softpipe
)
168 struct quad_stage
*stage
= CALLOC_STRUCT(quad_stage
);
170 stage
->softpipe
= softpipe
;
171 stage
->begin
= depth_test_begin
;
172 stage
->run
= depth_test_quad
;