1 /**************************************************************************
3 * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 **************************************************************************/
29 * \brief Quad depth testing
32 #include "pipe/p_defines.h"
33 #include "util/u_memory.h"
34 #include "tgsi/tgsi_scan.h"
35 #include "sp_context.h"
37 #include "sp_quad_pipe.h"
38 #include "sp_tile_cache.h"
39 #include "sp_state.h" /* for sp_fragment_shader */
43 struct pipe_surface
*ps
;
44 enum pipe_format format
;
45 unsigned bzzzz
[QUAD_SIZE
]; /**< Z values fetched from depth buffer */
46 unsigned qzzzz
[QUAD_SIZE
]; /**< Z values from the quad */
47 ubyte stencilVals
[QUAD_SIZE
];
48 struct softpipe_cached_tile
*tile
;
54 get_depth_stencil_values( struct depth_data
*data
,
55 const struct quad_header
*quad
)
58 const struct softpipe_cached_tile
*tile
= data
->tile
;
60 switch (data
->format
) {
61 case PIPE_FORMAT_Z16_UNORM
:
62 for (j
= 0; j
< QUAD_SIZE
; j
++) {
63 int x
= quad
->input
.x0
% TILE_SIZE
+ (j
& 1);
64 int y
= quad
->input
.y0
% TILE_SIZE
+ (j
>> 1);
65 data
->bzzzz
[j
] = tile
->data
.depth16
[y
][x
];
68 case PIPE_FORMAT_Z32_UNORM
:
69 for (j
= 0; j
< QUAD_SIZE
; j
++) {
70 int x
= quad
->input
.x0
% TILE_SIZE
+ (j
& 1);
71 int y
= quad
->input
.y0
% TILE_SIZE
+ (j
>> 1);
72 data
->bzzzz
[j
] = tile
->data
.depth32
[y
][x
];
75 case PIPE_FORMAT_X8Z24_UNORM
:
76 case PIPE_FORMAT_S8Z24_UNORM
:
77 for (j
= 0; j
< QUAD_SIZE
; j
++) {
78 int x
= quad
->input
.x0
% TILE_SIZE
+ (j
& 1);
79 int y
= quad
->input
.y0
% TILE_SIZE
+ (j
>> 1);
80 data
->bzzzz
[j
] = tile
->data
.depth32
[y
][x
] & 0xffffff;
81 data
->stencilVals
[j
] = tile
->data
.depth32
[y
][x
] >> 24;
84 case PIPE_FORMAT_Z24X8_UNORM
:
85 case PIPE_FORMAT_Z24S8_UNORM
:
86 for (j
= 0; j
< QUAD_SIZE
; j
++) {
87 int x
= quad
->input
.x0
% TILE_SIZE
+ (j
& 1);
88 int y
= quad
->input
.y0
% TILE_SIZE
+ (j
>> 1);
89 data
->bzzzz
[j
] = tile
->data
.depth32
[y
][x
] >> 8;
90 data
->stencilVals
[j
] = tile
->data
.depth32
[y
][x
] & 0xff;
98 /* If the shader has not been run, interpolate the depth values
102 interpolate_quad_depth( struct quad_header
*quad
)
104 const float fx
= (float) quad
->input
.x0
;
105 const float fy
= (float) quad
->input
.y0
;
106 const float dzdx
= quad
->posCoef
->dadx
[2];
107 const float dzdy
= quad
->posCoef
->dady
[2];
108 const float z0
= quad
->posCoef
->a0
[2] + dzdx
* fx
+ dzdy
* fy
;
110 quad
->output
.depth
[0] = z0
;
111 quad
->output
.depth
[1] = z0
+ dzdx
;
112 quad
->output
.depth
[2] = z0
+ dzdy
;
113 quad
->output
.depth
[3] = z0
+ dzdx
+ dzdy
;
118 convert_quad_depth( struct depth_data
*data
,
119 const struct quad_header
*quad
)
123 /* Convert quad's float depth values to int depth values (qzzzz).
124 * If the Z buffer stores integer values, we _have_ to do the depth
125 * compares with integers (not floats). Otherwise, the float->int->float
126 * conversion of Z values (which isn't an identity function) will cause
129 switch (data
->format
) {
130 case PIPE_FORMAT_Z16_UNORM
:
132 float scale
= 65535.0;
134 for (j
= 0; j
< QUAD_SIZE
; j
++) {
135 data
->qzzzz
[j
] = (unsigned) (quad
->output
.depth
[j
] * scale
);
139 case PIPE_FORMAT_Z32_UNORM
:
141 double scale
= (double) (uint
) ~0UL;
143 for (j
= 0; j
< QUAD_SIZE
; j
++) {
144 data
->qzzzz
[j
] = (unsigned) (quad
->output
.depth
[j
] * scale
);
148 case PIPE_FORMAT_X8Z24_UNORM
:
149 case PIPE_FORMAT_S8Z24_UNORM
:
151 float scale
= (float) ((1 << 24) - 1);
153 for (j
= 0; j
< QUAD_SIZE
; j
++) {
154 data
->qzzzz
[j
] = (unsigned) (quad
->output
.depth
[j
] * scale
);
158 case PIPE_FORMAT_Z24X8_UNORM
:
159 case PIPE_FORMAT_Z24S8_UNORM
:
161 float scale
= (float) ((1 << 24) - 1);
163 for (j
= 0; j
< QUAD_SIZE
; j
++) {
164 data
->qzzzz
[j
] = (unsigned) (quad
->output
.depth
[j
] * scale
);
176 write_depth_stencil_values( struct depth_data
*data
,
177 struct quad_header
*quad
)
179 struct softpipe_cached_tile
*tile
= data
->tile
;
182 /* put updated Z values back into cached tile */
183 switch (data
->format
) {
184 case PIPE_FORMAT_Z16_UNORM
:
185 for (j
= 0; j
< QUAD_SIZE
; j
++) {
186 int x
= quad
->input
.x0
% TILE_SIZE
+ (j
& 1);
187 int y
= quad
->input
.y0
% TILE_SIZE
+ (j
>> 1);
188 tile
->data
.depth16
[y
][x
] = (ushort
) data
->bzzzz
[j
];
191 case PIPE_FORMAT_X8Z24_UNORM
:
192 case PIPE_FORMAT_Z32_UNORM
:
193 for (j
= 0; j
< QUAD_SIZE
; j
++) {
194 int x
= quad
->input
.x0
% TILE_SIZE
+ (j
& 1);
195 int y
= quad
->input
.y0
% TILE_SIZE
+ (j
>> 1);
196 tile
->data
.depth32
[y
][x
] = data
->bzzzz
[j
];
199 case PIPE_FORMAT_S8Z24_UNORM
:
200 for (j
= 0; j
< QUAD_SIZE
; j
++) {
201 int x
= quad
->input
.x0
% TILE_SIZE
+ (j
& 1);
202 int y
= quad
->input
.y0
% TILE_SIZE
+ (j
>> 1);
203 tile
->data
.depth32
[y
][x
] = (data
->stencilVals
[j
] << 24) | data
->bzzzz
[j
];
206 case PIPE_FORMAT_Z24S8_UNORM
:
207 for (j
= 0; j
< QUAD_SIZE
; j
++) {
208 int x
= quad
->input
.x0
% TILE_SIZE
+ (j
& 1);
209 int y
= quad
->input
.y0
% TILE_SIZE
+ (j
>> 1);
210 tile
->data
.depth32
[y
][x
] = (data
->bzzzz
[j
] << 8) | data
->stencilVals
[j
];
213 case PIPE_FORMAT_Z24X8_UNORM
:
214 for (j
= 0; j
< QUAD_SIZE
; j
++) {
215 int x
= quad
->input
.x0
% TILE_SIZE
+ (j
& 1);
216 int y
= quad
->input
.y0
% TILE_SIZE
+ (j
>> 1);
217 tile
->data
.depth32
[y
][x
] = data
->bzzzz
[j
] << 8;
228 /** Only 8-bit stencil supported */
229 #define STENCIL_MAX 0xff
233 * Do the basic stencil test (compare stencil buffer values against the
236 * \param data->stencilVals the stencil values from the stencil buffer
237 * \param func the stencil func (PIPE_FUNC_x)
238 * \param ref the stencil reference value
239 * \param valMask the stencil value mask indicating which bits of the stencil
240 * values and ref value are to be used.
241 * \return mask indicating which pixels passed the stencil test
244 do_stencil_test(struct depth_data
*data
,
246 unsigned ref
, unsigned valMask
)
248 unsigned passMask
= 0x0;
254 case PIPE_FUNC_NEVER
:
258 for (j
= 0; j
< QUAD_SIZE
; j
++) {
259 if (ref
< (data
->stencilVals
[j
] & valMask
)) {
260 passMask
|= (1 << j
);
264 case PIPE_FUNC_EQUAL
:
265 for (j
= 0; j
< QUAD_SIZE
; j
++) {
266 if (ref
== (data
->stencilVals
[j
] & valMask
)) {
267 passMask
|= (1 << j
);
271 case PIPE_FUNC_LEQUAL
:
272 for (j
= 0; j
< QUAD_SIZE
; j
++) {
273 if (ref
<= (data
->stencilVals
[j
] & valMask
)) {
274 passMask
|= (1 << j
);
278 case PIPE_FUNC_GREATER
:
279 for (j
= 0; j
< QUAD_SIZE
; j
++) {
280 if (ref
> (data
->stencilVals
[j
] & valMask
)) {
281 passMask
|= (1 << j
);
285 case PIPE_FUNC_NOTEQUAL
:
286 for (j
= 0; j
< QUAD_SIZE
; j
++) {
287 if (ref
!= (data
->stencilVals
[j
] & valMask
)) {
288 passMask
|= (1 << j
);
292 case PIPE_FUNC_GEQUAL
:
293 for (j
= 0; j
< QUAD_SIZE
; j
++) {
294 if (ref
>= (data
->stencilVals
[j
] & valMask
)) {
295 passMask
|= (1 << j
);
299 case PIPE_FUNC_ALWAYS
:
311 * Apply the stencil operator to stencil values.
313 * \param data->stencilVals the stencil buffer values (read and written)
314 * \param mask indicates which pixels to update
315 * \param op the stencil operator (PIPE_STENCIL_OP_x)
316 * \param ref the stencil reference value
317 * \param wrtMask writemask controlling which bits are changed in the
321 apply_stencil_op(struct depth_data
*data
,
322 unsigned mask
, unsigned op
, ubyte ref
, ubyte wrtMask
)
325 ubyte newstencil
[QUAD_SIZE
];
327 for (j
= 0; j
< QUAD_SIZE
; j
++) {
328 newstencil
[j
] = data
->stencilVals
[j
];
332 case PIPE_STENCIL_OP_KEEP
:
335 case PIPE_STENCIL_OP_ZERO
:
336 for (j
= 0; j
< QUAD_SIZE
; j
++) {
337 if (mask
& (1 << j
)) {
342 case PIPE_STENCIL_OP_REPLACE
:
343 for (j
= 0; j
< QUAD_SIZE
; j
++) {
344 if (mask
& (1 << j
)) {
349 case PIPE_STENCIL_OP_INCR
:
350 for (j
= 0; j
< QUAD_SIZE
; j
++) {
351 if (mask
& (1 << j
)) {
352 if (data
->stencilVals
[j
] < STENCIL_MAX
) {
353 newstencil
[j
] = data
->stencilVals
[j
] + 1;
358 case PIPE_STENCIL_OP_DECR
:
359 for (j
= 0; j
< QUAD_SIZE
; j
++) {
360 if (mask
& (1 << j
)) {
361 if (data
->stencilVals
[j
] > 0) {
362 newstencil
[j
] = data
->stencilVals
[j
] - 1;
367 case PIPE_STENCIL_OP_INCR_WRAP
:
368 for (j
= 0; j
< QUAD_SIZE
; j
++) {
369 if (mask
& (1 << j
)) {
370 newstencil
[j
] = data
->stencilVals
[j
] + 1;
374 case PIPE_STENCIL_OP_DECR_WRAP
:
375 for (j
= 0; j
< QUAD_SIZE
; j
++) {
376 if (mask
& (1 << j
)) {
377 newstencil
[j
] = data
->stencilVals
[j
] - 1;
381 case PIPE_STENCIL_OP_INVERT
:
382 for (j
= 0; j
< QUAD_SIZE
; j
++) {
383 if (mask
& (1 << j
)) {
384 newstencil
[j
] = ~data
->stencilVals
[j
];
393 * update the stencil values
395 if (wrtMask
!= STENCIL_MAX
) {
396 /* apply bit-wise stencil buffer writemask */
397 for (j
= 0; j
< QUAD_SIZE
; j
++) {
398 data
->stencilVals
[j
] = (wrtMask
& newstencil
[j
]) | (~wrtMask
& data
->stencilVals
[j
]);
402 for (j
= 0; j
< QUAD_SIZE
; j
++) {
403 data
->stencilVals
[j
] = newstencil
[j
];
411 * To increase efficiency, we should probably have multiple versions
412 * of this function that are specifically for Z16, Z32 and FP Z buffers.
413 * Try to effectively do that with codegen...
417 depth_test_quad(struct quad_stage
*qs
,
418 struct depth_data
*data
,
419 struct quad_header
*quad
)
421 struct softpipe_context
*softpipe
= qs
->softpipe
;
425 switch (softpipe
->depth_stencil
->depth
.func
) {
426 case PIPE_FUNC_NEVER
:
430 /* Note this is pretty much a single sse or cell instruction.
431 * Like this: quad->mask &= (quad->outputs.depth < zzzz);
433 for (j
= 0; j
< QUAD_SIZE
; j
++) {
434 if (data
->qzzzz
[j
] < data
->bzzzz
[j
])
438 case PIPE_FUNC_EQUAL
:
439 for (j
= 0; j
< QUAD_SIZE
; j
++) {
440 if (data
->qzzzz
[j
] == data
->bzzzz
[j
])
444 case PIPE_FUNC_LEQUAL
:
445 for (j
= 0; j
< QUAD_SIZE
; j
++) {
446 if (data
->qzzzz
[j
] <= data
->bzzzz
[j
])
450 case PIPE_FUNC_GREATER
:
451 for (j
= 0; j
< QUAD_SIZE
; j
++) {
452 if (data
->qzzzz
[j
] > data
->bzzzz
[j
])
456 case PIPE_FUNC_NOTEQUAL
:
457 for (j
= 0; j
< QUAD_SIZE
; j
++) {
458 if (data
->qzzzz
[j
] != data
->bzzzz
[j
])
462 case PIPE_FUNC_GEQUAL
:
463 for (j
= 0; j
< QUAD_SIZE
; j
++) {
464 if (data
->qzzzz
[j
] >= data
->bzzzz
[j
])
468 case PIPE_FUNC_ALWAYS
:
475 quad
->inout
.mask
&= zmask
;
476 if (quad
->inout
.mask
== 0)
479 /* Update our internal copy only if writemask set. Even if
480 * depth.writemask is FALSE, may still need to write out buffer
481 * data due to stencil changes.
483 if (softpipe
->depth_stencil
->depth
.writemask
) {
484 for (j
= 0; j
< QUAD_SIZE
; j
++) {
485 if (quad
->inout
.mask
& (1 << j
)) {
486 data
->bzzzz
[j
] = data
->qzzzz
[j
];
497 * Do stencil (and depth) testing. Stenciling depends on the outcome of
501 depth_stencil_test_quad(struct quad_stage
*qs
,
502 struct depth_data
*data
,
503 struct quad_header
*quad
)
505 struct softpipe_context
*softpipe
= qs
->softpipe
;
506 unsigned func
, zFailOp
, zPassOp
, failOp
;
507 ubyte ref
, wrtMask
, valMask
;
508 uint face
= quad
->input
.facing
;
510 if (!softpipe
->depth_stencil
->stencil
[1].enabled
) {
511 /* single-sided stencil test, use front (face=0) state */
515 /* choose front or back face function, operator, etc */
516 /* XXX we could do these initializations once per primitive */
517 func
= softpipe
->depth_stencil
->stencil
[face
].func
;
518 failOp
= softpipe
->depth_stencil
->stencil
[face
].fail_op
;
519 zFailOp
= softpipe
->depth_stencil
->stencil
[face
].zfail_op
;
520 zPassOp
= softpipe
->depth_stencil
->stencil
[face
].zpass_op
;
521 ref
= softpipe
->depth_stencil
->stencil
[face
].ref_value
;
522 wrtMask
= softpipe
->depth_stencil
->stencil
[face
].writemask
;
523 valMask
= softpipe
->depth_stencil
->stencil
[face
].valuemask
;
526 /* do the stencil test first */
528 unsigned passMask
, failMask
;
529 passMask
= do_stencil_test(data
, func
, ref
, valMask
);
530 failMask
= quad
->inout
.mask
& ~passMask
;
531 quad
->inout
.mask
&= passMask
;
533 if (failOp
!= PIPE_STENCIL_OP_KEEP
) {
534 apply_stencil_op(data
, failMask
, failOp
, ref
, wrtMask
);
538 if (quad
->inout
.mask
) {
539 /* now the pixels that passed the stencil test are depth tested */
540 if (softpipe
->depth_stencil
->depth
.enabled
) {
541 const unsigned origMask
= quad
->inout
.mask
;
543 depth_test_quad(qs
, data
, quad
); /* quad->mask is updated */
545 /* update stencil buffer values according to z pass/fail result */
546 if (zFailOp
!= PIPE_STENCIL_OP_KEEP
) {
547 const unsigned zFailMask
= origMask
& ~quad
->inout
.mask
;
548 apply_stencil_op(data
, zFailMask
, zFailOp
, ref
, wrtMask
);
551 if (zPassOp
!= PIPE_STENCIL_OP_KEEP
) {
552 const unsigned zPassMask
= origMask
& quad
->inout
.mask
;
553 apply_stencil_op(data
, zPassMask
, zPassOp
, ref
, wrtMask
);
557 /* no depth test, apply Zpass operator to stencil buffer values */
558 apply_stencil_op(data
, quad
->inout
.mask
, zPassOp
, ref
, wrtMask
);
564 #define ALPHATEST( FUNC, COMP ) \
566 alpha_test_quads_##FUNC( struct quad_stage *qs, \
567 struct quad_header *quads[], \
570 const float ref = qs->softpipe->depth_stencil->alpha.ref_value; \
571 const uint cbuf = 0; /* only output[0].alpha is tested */ \
572 unsigned pass_nr = 0; \
575 for (i = 0; i < nr; i++) { \
576 const float *aaaa = quads[i]->output.color[cbuf][3]; \
577 unsigned passMask = 0; \
579 if (aaaa[0] COMP ref) passMask |= (1 << 0); \
580 if (aaaa[1] COMP ref) passMask |= (1 << 1); \
581 if (aaaa[2] COMP ref) passMask |= (1 << 2); \
582 if (aaaa[3] COMP ref) passMask |= (1 << 3); \
584 quads[i]->inout.mask &= passMask; \
586 if (quads[i]->inout.mask) \
587 quads[pass_nr++] = quads[i]; \
595 ALPHATEST( EQUAL
, == )
596 ALPHATEST( LEQUAL
, <= )
597 ALPHATEST( GREATER
, > )
598 ALPHATEST( NOTEQUAL
, != )
599 ALPHATEST( GEQUAL
, >= )
602 /* XXX: Incorporate into shader using KILP.
605 alpha_test_quads(struct quad_stage
*qs
,
606 struct quad_header
*quads
[],
609 switch (qs
->softpipe
->depth_stencil
->alpha
.func
) {
611 return alpha_test_quads_LESS( qs
, quads
, nr
);
612 case PIPE_FUNC_EQUAL
:
613 return alpha_test_quads_EQUAL( qs
, quads
, nr
);
615 case PIPE_FUNC_LEQUAL
:
616 return alpha_test_quads_LEQUAL( qs
, quads
, nr
);
617 case PIPE_FUNC_GREATER
:
618 return alpha_test_quads_GREATER( qs
, quads
, nr
);
619 case PIPE_FUNC_NOTEQUAL
:
620 return alpha_test_quads_NOTEQUAL( qs
, quads
, nr
);
621 case PIPE_FUNC_GEQUAL
:
622 return alpha_test_quads_GEQUAL( qs
, quads
, nr
);
623 case PIPE_FUNC_ALWAYS
:
625 case PIPE_FUNC_NEVER
:
631 static unsigned mask_count
[16] =
654 depth_test_quads_fallback(struct quad_stage
*qs
,
655 struct quad_header
*quads
[],
658 unsigned i
, pass
= 0;
659 const struct sp_fragment_shader
*fs
= qs
->softpipe
->fs
;
660 boolean interp_depth
= !fs
->info
.writes_z
;
661 struct depth_data data
;
664 if (qs
->softpipe
->depth_stencil
->alpha
.enabled
) {
665 nr
= alpha_test_quads(qs
, quads
, nr
);
668 if (qs
->softpipe
->framebuffer
.zsbuf
&&
669 pf_get_component_bits(qs
->softpipe
->framebuffer
.zsbuf
->format
, PIPE_FORMAT_COMP_Z
) &&
670 (qs
->softpipe
->depth_stencil
->depth
.enabled
||
671 qs
->softpipe
->depth_stencil
->stencil
[0].enabled
)) {
673 data
.ps
= qs
->softpipe
->framebuffer
.zsbuf
;
674 data
.format
= data
.ps
->format
;
675 data
.tile
= sp_get_cached_tile(qs
->softpipe
->zsbuf_cache
,
679 for (i
= 0; i
< nr
; i
++) {
680 get_depth_stencil_values(&data
, quads
[i
]);
682 if (qs
->softpipe
->depth_stencil
->depth
.enabled
) {
684 interpolate_quad_depth(quads
[i
]);
686 convert_quad_depth(&data
, quads
[i
]);
689 if (qs
->softpipe
->depth_stencil
->stencil
[0].enabled
) {
690 depth_stencil_test_quad(qs
, &data
, quads
[i
]);
691 write_depth_stencil_values(&data
, quads
[i
]);
694 if (!depth_test_quad(qs
, &data
, quads
[i
]))
697 if (qs
->softpipe
->depth_stencil
->depth
.writemask
)
698 write_depth_stencil_values(&data
, quads
[i
]);
702 quads
[pass
++] = quads
[i
];
708 if (qs
->softpipe
->active_query_count
) {
709 for (i
= 0; i
< nr
; i
++)
710 qs
->softpipe
->occlusion_count
+= mask_count
[quads
[i
]->inout
.mask
];
714 qs
->next
->run(qs
->next
, quads
, nr
);
717 /* XXX: this function assumes setup function actually emits linear
718 * spans of quads. It seems a lot more natural to do (early)
719 * depth-testing on spans rather than quads.
722 depth_interp_z16_less_write(struct quad_stage
*qs
,
723 struct quad_header
*quads
[],
726 unsigned i
, pass
= 0;
727 const unsigned ix
= quads
[0]->input
.x0
;
728 const unsigned iy
= quads
[0]->input
.y0
;
729 const float fx
= (float) ix
;
730 const float fy
= (float) iy
;
731 const float dzdx
= quads
[0]->posCoef
->dadx
[2];
732 const float dzdy
= quads
[0]->posCoef
->dady
[2];
733 const float z0
= quads
[0]->posCoef
->a0
[2] + dzdx
* fx
+ dzdy
* fy
;
734 struct softpipe_cached_tile
*tile
;
735 ushort (*depth16
)[TILE_SIZE
];
736 ushort idepth
[4], depth_step
;
737 const float scale
= 65535.0;
739 idepth
[0] = (ushort
)((z0
) * scale
);
740 idepth
[1] = (ushort
)((z0
+ dzdx
) * scale
);
741 idepth
[2] = (ushort
)((z0
+ dzdy
) * scale
);
742 idepth
[3] = (ushort
)((z0
+ dzdx
+ dzdy
) * scale
);
744 depth_step
= (ushort
)(dzdx
* 2 * scale
);
746 tile
= sp_get_cached_tile(qs
->softpipe
->zsbuf_cache
, ix
, iy
);
748 depth16
= (ushort (*)[TILE_SIZE
])
749 &tile
->data
.depth16
[iy
% TILE_SIZE
][ix
% TILE_SIZE
];
751 for (i
= 0; i
< nr
; i
++) {
752 unsigned outmask
= quads
[i
]->inout
.mask
;
755 if ((outmask
& 1) && idepth
[0] < depth16
[0][0]) {
756 depth16
[0][0] = idepth
[0];
760 if ((outmask
& 2) && idepth
[1] < depth16
[0][1]) {
761 depth16
[0][1] = idepth
[1];
765 if ((outmask
& 4) && idepth
[2] < depth16
[1][0]) {
766 depth16
[1][0] = idepth
[2];
770 if ((outmask
& 8) && idepth
[3] < depth16
[1][1]) {
771 depth16
[1][1] = idepth
[3];
775 idepth
[0] += depth_step
;
776 idepth
[1] += depth_step
;
777 idepth
[2] += depth_step
;
778 idepth
[3] += depth_step
;
780 depth16
= (ushort (*)[TILE_SIZE
]) &depth16
[0][2];
782 quads
[i
]->inout
.mask
= mask
;
783 if (quads
[i
]->inout
.mask
)
784 quads
[pass
++] = quads
[i
];
788 qs
->next
->run(qs
->next
, quads
, pass
);
794 depth_interp_z16_lequal_write(struct quad_stage
*qs
,
795 struct quad_header
*quads
[],
798 unsigned i
, pass
= 0;
799 const unsigned ix
= quads
[0]->input
.x0
;
800 const unsigned iy
= quads
[0]->input
.y0
;
801 const float fx
= (float) ix
;
802 const float fy
= (float) iy
;
803 const float dzdx
= quads
[0]->posCoef
->dadx
[2];
804 const float dzdy
= quads
[0]->posCoef
->dady
[2];
805 const float z0
= quads
[0]->posCoef
->a0
[2] + dzdx
* fx
+ dzdy
* fy
;
806 struct softpipe_cached_tile
*tile
;
807 ushort (*depth16
)[TILE_SIZE
];
808 ushort idepth
[4], depth_step
;
809 const float scale
= 65535.0;
811 idepth
[0] = (ushort
)((z0
) * scale
);
812 idepth
[1] = (ushort
)((z0
+ dzdx
) * scale
);
813 idepth
[2] = (ushort
)((z0
+ dzdy
) * scale
);
814 idepth
[3] = (ushort
)((z0
+ dzdx
+ dzdy
) * scale
);
816 depth_step
= (ushort
)(dzdx
* 2 * scale
);
818 tile
= sp_get_cached_tile(qs
->softpipe
->zsbuf_cache
, ix
, iy
);
820 depth16
= (ushort (*)[TILE_SIZE
])
821 &tile
->data
.depth16
[iy
% TILE_SIZE
][ix
% TILE_SIZE
];
823 for (i
= 0; i
< nr
; i
++) {
824 unsigned outmask
= quads
[i
]->inout
.mask
;
827 if ((outmask
& 1) && idepth
[0] <= depth16
[0][0]) {
828 depth16
[0][0] = idepth
[0];
832 if ((outmask
& 2) && idepth
[1] <= depth16
[0][1]) {
833 depth16
[0][1] = idepth
[1];
837 if ((outmask
& 4) && idepth
[2] <= depth16
[1][0]) {
838 depth16
[1][0] = idepth
[2];
842 if ((outmask
& 8) && idepth
[3] <= depth16
[1][1]) {
843 depth16
[1][1] = idepth
[3];
847 idepth
[0] += depth_step
;
848 idepth
[1] += depth_step
;
849 idepth
[2] += depth_step
;
850 idepth
[3] += depth_step
;
852 depth16
= (ushort (*)[TILE_SIZE
]) &depth16
[0][2];
854 quads
[i
]->inout
.mask
= mask
;
855 if (quads
[i
]->inout
.mask
)
856 quads
[pass
++] = quads
[i
];
860 qs
->next
->run(qs
->next
, quads
, pass
);
869 depth_noop(struct quad_stage
*qs
,
870 struct quad_header
*quads
[],
873 qs
->next
->run(qs
->next
, quads
, nr
);
879 choose_depth_test(struct quad_stage
*qs
,
880 struct quad_header
*quads
[],
883 boolean interp_depth
= !qs
->softpipe
->fs
->info
.writes_z
;
885 boolean alpha
= qs
->softpipe
->depth_stencil
->alpha
.enabled
;
887 boolean depth
= (qs
->softpipe
->framebuffer
.zsbuf
&&
888 pf_get_component_bits(qs
->softpipe
->framebuffer
.zsbuf
->format
, PIPE_FORMAT_COMP_Z
) &&
889 qs
->softpipe
->depth_stencil
->depth
.enabled
);
891 unsigned depthfunc
= qs
->softpipe
->depth_stencil
->depth
.func
;
893 boolean stencil
= qs
->softpipe
->depth_stencil
->stencil
[0].enabled
;
895 boolean depthwrite
= qs
->softpipe
->depth_stencil
->depth
.writemask
;
897 boolean occlusion
= qs
->softpipe
->active_query_count
;
902 qs
->run
= depth_noop
;
913 switch (qs
->softpipe
->framebuffer
.zsbuf
->format
) {
914 case PIPE_FORMAT_Z16_UNORM
:
915 qs
->run
= depth_interp_z16_less_write
;
918 qs
->run
= depth_test_quads_fallback
;
922 case PIPE_FUNC_LEQUAL
:
923 switch (qs
->softpipe
->framebuffer
.zsbuf
->format
) {
924 case PIPE_FORMAT_Z16_UNORM
:
925 qs
->run
= depth_interp_z16_lequal_write
;
928 qs
->run
= depth_test_quads_fallback
;
933 qs
->run
= depth_test_quads_fallback
;
937 qs
->run
= depth_test_quads_fallback
;
941 qs
->run( qs
, quads
, nr
);
948 static void depth_test_begin(struct quad_stage
*qs
)
950 qs
->run
= choose_depth_test
;
951 qs
->next
->begin(qs
->next
);
955 static void depth_test_destroy(struct quad_stage
*qs
)
961 struct quad_stage
*sp_quad_depth_test_stage( struct softpipe_context
*softpipe
)
963 struct quad_stage
*stage
= CALLOC_STRUCT(quad_stage
);
965 stage
->softpipe
= softpipe
;
966 stage
->begin
= depth_test_begin
;
967 stage
->run
= choose_depth_test
;
968 stage
->destroy
= depth_test_destroy
;