softpipe: add missing stencil format case in convert_quad_stencil()
[mesa.git] / src / gallium / drivers / softpipe / sp_quad_depth_test.c
1 /**************************************************************************
2 *
3 * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
4 * Copyright 2010 VMware, Inc.
5 * All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the
9 * "Software"), to deal in the Software without restriction, including
10 * without limitation the rights to use, copy, modify, merge, publish,
11 * distribute, sub license, and/or sell copies of the Software, and to
12 * permit persons to whom the Software is furnished to do so, subject to
13 * the following conditions:
14 *
15 * The above copyright notice and this permission notice (including the
16 * next paragraph) shall be included in all copies or substantial portions
17 * of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22 * IN NO EVENT SHALL THE AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR
23 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 *
27 **************************************************************************/
28
29 /**
30 * \brief Quad depth / stencil testing
31 */
32
33 #include "pipe/p_defines.h"
34 #include "util/u_format.h"
35 #include "util/u_memory.h"
36 #include "tgsi/tgsi_scan.h"
37 #include "sp_context.h"
38 #include "sp_quad.h"
39 #include "sp_quad_pipe.h"
40 #include "sp_tile_cache.h"
41 #include "sp_state.h" /* for sp_fragment_shader */
42
43
44 struct depth_data {
45 struct pipe_surface *ps;
46 enum pipe_format format;
47 unsigned bzzzz[QUAD_SIZE]; /**< Z values fetched from depth buffer */
48 unsigned qzzzz[QUAD_SIZE]; /**< Z values from the quad */
49 ubyte stencilVals[QUAD_SIZE];
50 boolean use_shader_stencil_refs;
51 ubyte shader_stencil_refs[QUAD_SIZE];
52 struct softpipe_cached_tile *tile;
53 };
54
55
56
57 static void
58 get_depth_stencil_values( struct depth_data *data,
59 const struct quad_header *quad )
60 {
61 unsigned j;
62 const struct softpipe_cached_tile *tile = data->tile;
63
64 switch (data->format) {
65 case PIPE_FORMAT_Z16_UNORM:
66 for (j = 0; j < QUAD_SIZE; j++) {
67 int x = quad->input.x0 % TILE_SIZE + (j & 1);
68 int y = quad->input.y0 % TILE_SIZE + (j >> 1);
69 data->bzzzz[j] = tile->data.depth16[y][x];
70 }
71 break;
72 case PIPE_FORMAT_Z32_UNORM:
73 for (j = 0; j < QUAD_SIZE; j++) {
74 int x = quad->input.x0 % TILE_SIZE + (j & 1);
75 int y = quad->input.y0 % TILE_SIZE + (j >> 1);
76 data->bzzzz[j] = tile->data.depth32[y][x];
77 }
78 break;
79 case PIPE_FORMAT_Z24X8_UNORM:
80 case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
81 for (j = 0; j < QUAD_SIZE; j++) {
82 int x = quad->input.x0 % TILE_SIZE + (j & 1);
83 int y = quad->input.y0 % TILE_SIZE + (j >> 1);
84 data->bzzzz[j] = tile->data.depth32[y][x] & 0xffffff;
85 data->stencilVals[j] = tile->data.depth32[y][x] >> 24;
86 }
87 break;
88 case PIPE_FORMAT_X8Z24_UNORM:
89 case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
90 for (j = 0; j < QUAD_SIZE; j++) {
91 int x = quad->input.x0 % TILE_SIZE + (j & 1);
92 int y = quad->input.y0 % TILE_SIZE + (j >> 1);
93 data->bzzzz[j] = tile->data.depth32[y][x] >> 8;
94 data->stencilVals[j] = tile->data.depth32[y][x] & 0xff;
95 }
96 break;
97 case PIPE_FORMAT_S8_USCALED:
98 for (j = 0; j < QUAD_SIZE; j++) {
99 int x = quad->input.x0 % TILE_SIZE + (j & 1);
100 int y = quad->input.y0 % TILE_SIZE + (j >> 1);
101 data->bzzzz[j] = 0;
102 data->stencilVals[j] = tile->data.stencil8[y][x];
103 }
104 break;
105 default:
106 assert(0);
107 }
108 }
109
110
111 /**
112 * If the shader has not been run, interpolate the depth values
113 * ourselves.
114 */
115 static void
116 interpolate_quad_depth( struct quad_header *quad )
117 {
118 const float fx = (float) quad->input.x0;
119 const float fy = (float) quad->input.y0;
120 const float dzdx = quad->posCoef->dadx[2];
121 const float dzdy = quad->posCoef->dady[2];
122 const float z0 = quad->posCoef->a0[2] + dzdx * fx + dzdy * fy;
123
124 quad->output.depth[0] = z0;
125 quad->output.depth[1] = z0 + dzdx;
126 quad->output.depth[2] = z0 + dzdy;
127 quad->output.depth[3] = z0 + dzdx + dzdy;
128 }
129
130
131 /**
132 * Compute the depth_data::qzzzz[] values from the float fragment Z values.
133 */
134 static void
135 convert_quad_depth( struct depth_data *data,
136 const struct quad_header *quad )
137 {
138 unsigned j;
139
140 /* Convert quad's float depth values to int depth values (qzzzz).
141 * If the Z buffer stores integer values, we _have_ to do the depth
142 * compares with integers (not floats). Otherwise, the float->int->float
143 * conversion of Z values (which isn't an identity function) will cause
144 * Z-fighting errors.
145 */
146 switch (data->format) {
147 case PIPE_FORMAT_Z16_UNORM:
148 {
149 float scale = 65535.0;
150
151 for (j = 0; j < QUAD_SIZE; j++) {
152 data->qzzzz[j] = (unsigned) (quad->output.depth[j] * scale);
153 }
154 }
155 break;
156 case PIPE_FORMAT_Z32_UNORM:
157 {
158 double scale = (double) (uint) ~0UL;
159
160 for (j = 0; j < QUAD_SIZE; j++) {
161 data->qzzzz[j] = (unsigned) (quad->output.depth[j] * scale);
162 }
163 }
164 break;
165 case PIPE_FORMAT_Z24X8_UNORM:
166 case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
167 {
168 float scale = (float) ((1 << 24) - 1);
169
170 for (j = 0; j < QUAD_SIZE; j++) {
171 data->qzzzz[j] = (unsigned) (quad->output.depth[j] * scale);
172 }
173 }
174 break;
175 case PIPE_FORMAT_X8Z24_UNORM:
176 case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
177 {
178 float scale = (float) ((1 << 24) - 1);
179
180 for (j = 0; j < QUAD_SIZE; j++) {
181 data->qzzzz[j] = (unsigned) (quad->output.depth[j] * scale);
182 }
183 }
184 break;
185 default:
186 assert(0);
187 }
188 }
189
190
191 /**
192 * Compute the depth_data::shader_stencil_refs[] values from the float
193 * fragment stencil values.
194 */
195 static void
196 convert_quad_stencil( struct depth_data *data,
197 const struct quad_header *quad )
198 {
199 unsigned j;
200
201 data->use_shader_stencil_refs = TRUE;
202 /* Copy quads stencil values
203 */
204 switch (data->format) {
205 case PIPE_FORMAT_Z24X8_UNORM:
206 case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
207 case PIPE_FORMAT_X8Z24_UNORM:
208 case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
209 case PIPE_FORMAT_S8_USCALED:
210 for (j = 0; j < QUAD_SIZE; j++) {
211 data->shader_stencil_refs[j] = ((unsigned)(quad->output.stencil[j]));
212 }
213 break;
214 default:
215 assert(0);
216 }
217 }
218
219
220 /**
221 * Write data->bzzzz[] values and data->stencilVals into the Z/stencil buffer.
222 */
223 static void
224 write_depth_stencil_values( struct depth_data *data,
225 struct quad_header *quad )
226 {
227 struct softpipe_cached_tile *tile = data->tile;
228 unsigned j;
229
230 /* put updated Z values back into cached tile */
231 switch (data->format) {
232 case PIPE_FORMAT_Z16_UNORM:
233 for (j = 0; j < QUAD_SIZE; j++) {
234 int x = quad->input.x0 % TILE_SIZE + (j & 1);
235 int y = quad->input.y0 % TILE_SIZE + (j >> 1);
236 tile->data.depth16[y][x] = (ushort) data->bzzzz[j];
237 }
238 break;
239 case PIPE_FORMAT_Z24X8_UNORM:
240 case PIPE_FORMAT_Z32_UNORM:
241 for (j = 0; j < QUAD_SIZE; j++) {
242 int x = quad->input.x0 % TILE_SIZE + (j & 1);
243 int y = quad->input.y0 % TILE_SIZE + (j >> 1);
244 tile->data.depth32[y][x] = data->bzzzz[j];
245 }
246 break;
247 case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
248 for (j = 0; j < QUAD_SIZE; j++) {
249 int x = quad->input.x0 % TILE_SIZE + (j & 1);
250 int y = quad->input.y0 % TILE_SIZE + (j >> 1);
251 tile->data.depth32[y][x] = (data->stencilVals[j] << 24) | data->bzzzz[j];
252 }
253 break;
254 case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
255 for (j = 0; j < QUAD_SIZE; j++) {
256 int x = quad->input.x0 % TILE_SIZE + (j & 1);
257 int y = quad->input.y0 % TILE_SIZE + (j >> 1);
258 tile->data.depth32[y][x] = (data->bzzzz[j] << 8) | data->stencilVals[j];
259 }
260 break;
261 case PIPE_FORMAT_X8Z24_UNORM:
262 for (j = 0; j < QUAD_SIZE; j++) {
263 int x = quad->input.x0 % TILE_SIZE + (j & 1);
264 int y = quad->input.y0 % TILE_SIZE + (j >> 1);
265 tile->data.depth32[y][x] = data->bzzzz[j] << 8;
266 }
267 break;
268 case PIPE_FORMAT_S8_USCALED:
269 for (j = 0; j < QUAD_SIZE; j++) {
270 int x = quad->input.x0 % TILE_SIZE + (j & 1);
271 int y = quad->input.y0 % TILE_SIZE + (j >> 1);
272 tile->data.stencil8[y][x] = data->stencilVals[j];
273 }
274 break;
275
276 default:
277 assert(0);
278 }
279 }
280
281
282
283 /** Only 8-bit stencil supported */
284 #define STENCIL_MAX 0xff
285
286
287 /**
288 * Do the basic stencil test (compare stencil buffer values against the
289 * reference value.
290 *
291 * \param data->stencilVals the stencil values from the stencil buffer
292 * \param func the stencil func (PIPE_FUNC_x)
293 * \param ref the stencil reference value
294 * \param valMask the stencil value mask indicating which bits of the stencil
295 * values and ref value are to be used.
296 * \return mask indicating which pixels passed the stencil test
297 */
298 static unsigned
299 do_stencil_test(struct depth_data *data,
300 unsigned func,
301 unsigned ref, unsigned valMask)
302 {
303 unsigned passMask = 0x0;
304 unsigned j;
305 ubyte refs[QUAD_SIZE];
306
307 for (j = 0; j < QUAD_SIZE; j++) {
308 if (data->use_shader_stencil_refs)
309 refs[j] = data->shader_stencil_refs[j] & valMask;
310 else
311 refs[j] = ref & valMask;
312 }
313
314 switch (func) {
315 case PIPE_FUNC_NEVER:
316 /* passMask = 0x0 */
317 break;
318 case PIPE_FUNC_LESS:
319 for (j = 0; j < QUAD_SIZE; j++) {
320 if (refs[j] < (data->stencilVals[j] & valMask)) {
321 passMask |= (1 << j);
322 }
323 }
324 break;
325 case PIPE_FUNC_EQUAL:
326 for (j = 0; j < QUAD_SIZE; j++) {
327 if (refs[j] == (data->stencilVals[j] & valMask)) {
328 passMask |= (1 << j);
329 }
330 }
331 break;
332 case PIPE_FUNC_LEQUAL:
333 for (j = 0; j < QUAD_SIZE; j++) {
334 if (refs[j] <= (data->stencilVals[j] & valMask)) {
335 passMask |= (1 << j);
336 }
337 }
338 break;
339 case PIPE_FUNC_GREATER:
340 for (j = 0; j < QUAD_SIZE; j++) {
341 if (refs[j] > (data->stencilVals[j] & valMask)) {
342 passMask |= (1 << j);
343 }
344 }
345 break;
346 case PIPE_FUNC_NOTEQUAL:
347 for (j = 0; j < QUAD_SIZE; j++) {
348 if (refs[j] != (data->stencilVals[j] & valMask)) {
349 passMask |= (1 << j);
350 }
351 }
352 break;
353 case PIPE_FUNC_GEQUAL:
354 for (j = 0; j < QUAD_SIZE; j++) {
355 if (refs[j] >= (data->stencilVals[j] & valMask)) {
356 passMask |= (1 << j);
357 }
358 }
359 break;
360 case PIPE_FUNC_ALWAYS:
361 passMask = MASK_ALL;
362 break;
363 default:
364 assert(0);
365 }
366
367 return passMask;
368 }
369
370
371 /**
372 * Apply the stencil operator to stencil values.
373 *
374 * \param data->stencilVals the stencil buffer values (read and written)
375 * \param mask indicates which pixels to update
376 * \param op the stencil operator (PIPE_STENCIL_OP_x)
377 * \param ref the stencil reference value
378 * \param wrtMask writemask controlling which bits are changed in the
379 * stencil values
380 */
381 static void
382 apply_stencil_op(struct depth_data *data,
383 unsigned mask, unsigned op, ubyte ref, ubyte wrtMask)
384 {
385 unsigned j;
386 ubyte newstencil[QUAD_SIZE];
387 ubyte refs[QUAD_SIZE];
388
389 for (j = 0; j < QUAD_SIZE; j++) {
390 newstencil[j] = data->stencilVals[j];
391 if (data->use_shader_stencil_refs)
392 refs[j] = data->shader_stencil_refs[j];
393 else
394 refs[j] = ref;
395 }
396
397 switch (op) {
398 case PIPE_STENCIL_OP_KEEP:
399 /* no-op */
400 break;
401 case PIPE_STENCIL_OP_ZERO:
402 for (j = 0; j < QUAD_SIZE; j++) {
403 if (mask & (1 << j)) {
404 newstencil[j] = 0;
405 }
406 }
407 break;
408 case PIPE_STENCIL_OP_REPLACE:
409 for (j = 0; j < QUAD_SIZE; j++) {
410 if (mask & (1 << j)) {
411 newstencil[j] = refs[j];
412 }
413 }
414 break;
415 case PIPE_STENCIL_OP_INCR:
416 for (j = 0; j < QUAD_SIZE; j++) {
417 if (mask & (1 << j)) {
418 if (data->stencilVals[j] < STENCIL_MAX) {
419 newstencil[j] = data->stencilVals[j] + 1;
420 }
421 }
422 }
423 break;
424 case PIPE_STENCIL_OP_DECR:
425 for (j = 0; j < QUAD_SIZE; j++) {
426 if (mask & (1 << j)) {
427 if (data->stencilVals[j] > 0) {
428 newstencil[j] = data->stencilVals[j] - 1;
429 }
430 }
431 }
432 break;
433 case PIPE_STENCIL_OP_INCR_WRAP:
434 for (j = 0; j < QUAD_SIZE; j++) {
435 if (mask & (1 << j)) {
436 newstencil[j] = data->stencilVals[j] + 1;
437 }
438 }
439 break;
440 case PIPE_STENCIL_OP_DECR_WRAP:
441 for (j = 0; j < QUAD_SIZE; j++) {
442 if (mask & (1 << j)) {
443 newstencil[j] = data->stencilVals[j] - 1;
444 }
445 }
446 break;
447 case PIPE_STENCIL_OP_INVERT:
448 for (j = 0; j < QUAD_SIZE; j++) {
449 if (mask & (1 << j)) {
450 newstencil[j] = ~data->stencilVals[j];
451 }
452 }
453 break;
454 default:
455 assert(0);
456 }
457
458 /*
459 * update the stencil values
460 */
461 if (wrtMask != STENCIL_MAX) {
462 /* apply bit-wise stencil buffer writemask */
463 for (j = 0; j < QUAD_SIZE; j++) {
464 data->stencilVals[j] = (wrtMask & newstencil[j]) | (~wrtMask & data->stencilVals[j]);
465 }
466 }
467 else {
468 for (j = 0; j < QUAD_SIZE; j++) {
469 data->stencilVals[j] = newstencil[j];
470 }
471 }
472 }
473
474
475
476 /**
477 * To increase efficiency, we should probably have multiple versions
478 * of this function that are specifically for Z16, Z32 and FP Z buffers.
479 * Try to effectively do that with codegen...
480 */
481 static boolean
482 depth_test_quad(struct quad_stage *qs,
483 struct depth_data *data,
484 struct quad_header *quad)
485 {
486 struct softpipe_context *softpipe = qs->softpipe;
487 unsigned zmask = 0;
488 unsigned j;
489
490 switch (softpipe->depth_stencil->depth.func) {
491 case PIPE_FUNC_NEVER:
492 /* zmask = 0 */
493 break;
494 case PIPE_FUNC_LESS:
495 /* Note this is pretty much a single sse or cell instruction.
496 * Like this: quad->mask &= (quad->outputs.depth < zzzz);
497 */
498 for (j = 0; j < QUAD_SIZE; j++) {
499 if (data->qzzzz[j] < data->bzzzz[j])
500 zmask |= 1 << j;
501 }
502 break;
503 case PIPE_FUNC_EQUAL:
504 for (j = 0; j < QUAD_SIZE; j++) {
505 if (data->qzzzz[j] == data->bzzzz[j])
506 zmask |= 1 << j;
507 }
508 break;
509 case PIPE_FUNC_LEQUAL:
510 for (j = 0; j < QUAD_SIZE; j++) {
511 if (data->qzzzz[j] <= data->bzzzz[j])
512 zmask |= (1 << j);
513 }
514 break;
515 case PIPE_FUNC_GREATER:
516 for (j = 0; j < QUAD_SIZE; j++) {
517 if (data->qzzzz[j] > data->bzzzz[j])
518 zmask |= (1 << j);
519 }
520 break;
521 case PIPE_FUNC_NOTEQUAL:
522 for (j = 0; j < QUAD_SIZE; j++) {
523 if (data->qzzzz[j] != data->bzzzz[j])
524 zmask |= (1 << j);
525 }
526 break;
527 case PIPE_FUNC_GEQUAL:
528 for (j = 0; j < QUAD_SIZE; j++) {
529 if (data->qzzzz[j] >= data->bzzzz[j])
530 zmask |= (1 << j);
531 }
532 break;
533 case PIPE_FUNC_ALWAYS:
534 zmask = MASK_ALL;
535 break;
536 default:
537 assert(0);
538 }
539
540 quad->inout.mask &= zmask;
541 if (quad->inout.mask == 0)
542 return FALSE;
543
544 /* Update our internal copy only if writemask set. Even if
545 * depth.writemask is FALSE, may still need to write out buffer
546 * data due to stencil changes.
547 */
548 if (softpipe->depth_stencil->depth.writemask) {
549 for (j = 0; j < QUAD_SIZE; j++) {
550 if (quad->inout.mask & (1 << j)) {
551 data->bzzzz[j] = data->qzzzz[j];
552 }
553 }
554 }
555
556 return TRUE;
557 }
558
559
560
561 /**
562 * Do stencil (and depth) testing. Stenciling depends on the outcome of
563 * depth testing.
564 */
565 static void
566 depth_stencil_test_quad(struct quad_stage *qs,
567 struct depth_data *data,
568 struct quad_header *quad)
569 {
570 struct softpipe_context *softpipe = qs->softpipe;
571 unsigned func, zFailOp, zPassOp, failOp;
572 ubyte ref, wrtMask, valMask;
573 uint face = quad->input.facing;
574
575 if (!softpipe->depth_stencil->stencil[1].enabled) {
576 /* single-sided stencil test, use front (face=0) state */
577 face = 0;
578 }
579
580 /* 0 = front-face, 1 = back-face */
581 assert(face == 0 || face == 1);
582
583 /* choose front or back face function, operator, etc */
584 /* XXX we could do these initializations once per primitive */
585 func = softpipe->depth_stencil->stencil[face].func;
586 failOp = softpipe->depth_stencil->stencil[face].fail_op;
587 zFailOp = softpipe->depth_stencil->stencil[face].zfail_op;
588 zPassOp = softpipe->depth_stencil->stencil[face].zpass_op;
589 ref = softpipe->stencil_ref.ref_value[face];
590 wrtMask = softpipe->depth_stencil->stencil[face].writemask;
591 valMask = softpipe->depth_stencil->stencil[face].valuemask;
592
593 /* do the stencil test first */
594 {
595 unsigned passMask, failMask;
596 passMask = do_stencil_test(data, func, ref, valMask);
597 failMask = quad->inout.mask & ~passMask;
598 quad->inout.mask &= passMask;
599
600 if (failOp != PIPE_STENCIL_OP_KEEP) {
601 apply_stencil_op(data, failMask, failOp, ref, wrtMask);
602 }
603 }
604
605 if (quad->inout.mask) {
606 /* now the pixels that passed the stencil test are depth tested */
607 if (softpipe->depth_stencil->depth.enabled) {
608 const unsigned origMask = quad->inout.mask;
609
610 depth_test_quad(qs, data, quad); /* quad->mask is updated */
611
612 /* update stencil buffer values according to z pass/fail result */
613 if (zFailOp != PIPE_STENCIL_OP_KEEP) {
614 const unsigned zFailMask = origMask & ~quad->inout.mask;
615 apply_stencil_op(data, zFailMask, zFailOp, ref, wrtMask);
616 }
617
618 if (zPassOp != PIPE_STENCIL_OP_KEEP) {
619 const unsigned zPassMask = origMask & quad->inout.mask;
620 apply_stencil_op(data, zPassMask, zPassOp, ref, wrtMask);
621 }
622 }
623 else {
624 /* no depth test, apply Zpass operator to stencil buffer values */
625 apply_stencil_op(data, quad->inout.mask, zPassOp, ref, wrtMask);
626 }
627 }
628 }
629
630
631 #define ALPHATEST( FUNC, COMP ) \
632 static int \
633 alpha_test_quads_##FUNC( struct quad_stage *qs, \
634 struct quad_header *quads[], \
635 unsigned nr ) \
636 { \
637 const float ref = qs->softpipe->depth_stencil->alpha.ref_value; \
638 const uint cbuf = 0; /* only output[0].alpha is tested */ \
639 unsigned pass_nr = 0; \
640 unsigned i; \
641 \
642 for (i = 0; i < nr; i++) { \
643 const float *aaaa = quads[i]->output.color[cbuf][3]; \
644 unsigned passMask = 0; \
645 \
646 if (aaaa[0] COMP ref) passMask |= (1 << 0); \
647 if (aaaa[1] COMP ref) passMask |= (1 << 1); \
648 if (aaaa[2] COMP ref) passMask |= (1 << 2); \
649 if (aaaa[3] COMP ref) passMask |= (1 << 3); \
650 \
651 quads[i]->inout.mask &= passMask; \
652 \
653 if (quads[i]->inout.mask) \
654 quads[pass_nr++] = quads[i]; \
655 } \
656 \
657 return pass_nr; \
658 }
659
660
661 ALPHATEST( LESS, < )
662 ALPHATEST( EQUAL, == )
663 ALPHATEST( LEQUAL, <= )
664 ALPHATEST( GREATER, > )
665 ALPHATEST( NOTEQUAL, != )
666 ALPHATEST( GEQUAL, >= )
667
668
669 /* XXX: Incorporate into shader using KILP.
670 */
671 static int
672 alpha_test_quads(struct quad_stage *qs,
673 struct quad_header *quads[],
674 unsigned nr)
675 {
676 switch (qs->softpipe->depth_stencil->alpha.func) {
677 case PIPE_FUNC_LESS:
678 return alpha_test_quads_LESS( qs, quads, nr );
679 case PIPE_FUNC_EQUAL:
680 return alpha_test_quads_EQUAL( qs, quads, nr );
681 break;
682 case PIPE_FUNC_LEQUAL:
683 return alpha_test_quads_LEQUAL( qs, quads, nr );
684 case PIPE_FUNC_GREATER:
685 return alpha_test_quads_GREATER( qs, quads, nr );
686 case PIPE_FUNC_NOTEQUAL:
687 return alpha_test_quads_NOTEQUAL( qs, quads, nr );
688 case PIPE_FUNC_GEQUAL:
689 return alpha_test_quads_GEQUAL( qs, quads, nr );
690 case PIPE_FUNC_ALWAYS:
691 return nr;
692 case PIPE_FUNC_NEVER:
693 default:
694 return 0;
695 }
696 }
697
698
699 static unsigned mask_count[16] =
700 {
701 0, /* 0x0 */
702 1, /* 0x1 */
703 1, /* 0x2 */
704 2, /* 0x3 */
705 1, /* 0x4 */
706 2, /* 0x5 */
707 2, /* 0x6 */
708 3, /* 0x7 */
709 1, /* 0x8 */
710 2, /* 0x9 */
711 2, /* 0xa */
712 3, /* 0xb */
713 2, /* 0xc */
714 3, /* 0xd */
715 3, /* 0xe */
716 4, /* 0xf */
717 };
718
719
720
721 /**
722 * General depth/stencil test function. Used when there's no fast-path.
723 */
724 static void
725 depth_test_quads_fallback(struct quad_stage *qs,
726 struct quad_header *quads[],
727 unsigned nr)
728 {
729 unsigned i, pass = 0;
730 const struct sp_fragment_shader *fs = qs->softpipe->fs;
731 boolean interp_depth = !fs->info.writes_z;
732 boolean shader_stencil_ref = fs->info.writes_stencil;
733 struct depth_data data;
734
735 data.use_shader_stencil_refs = FALSE;
736
737 if (qs->softpipe->depth_stencil->alpha.enabled) {
738 nr = alpha_test_quads(qs, quads, nr);
739 }
740
741 if (qs->softpipe->framebuffer.zsbuf &&
742 (qs->softpipe->depth_stencil->depth.enabled ||
743 qs->softpipe->depth_stencil->stencil[0].enabled)) {
744
745 data.ps = qs->softpipe->framebuffer.zsbuf;
746 data.format = data.ps->format;
747 data.tile = sp_get_cached_tile(qs->softpipe->zsbuf_cache,
748 quads[0]->input.x0,
749 quads[0]->input.y0);
750
751 for (i = 0; i < nr; i++) {
752 get_depth_stencil_values(&data, quads[i]);
753
754 if (qs->softpipe->depth_stencil->depth.enabled) {
755 if (interp_depth)
756 interpolate_quad_depth(quads[i]);
757
758 convert_quad_depth(&data, quads[i]);
759 }
760
761 if (qs->softpipe->depth_stencil->stencil[0].enabled) {
762 if (shader_stencil_ref)
763 convert_quad_stencil(&data, quads[i]);
764
765 depth_stencil_test_quad(qs, &data, quads[i]);
766 write_depth_stencil_values(&data, quads[i]);
767 }
768 else {
769 if (!depth_test_quad(qs, &data, quads[i]))
770 continue;
771
772 if (qs->softpipe->depth_stencil->depth.writemask)
773 write_depth_stencil_values(&data, quads[i]);
774 }
775
776 quads[pass++] = quads[i];
777 }
778
779 nr = pass;
780 }
781
782 if (qs->softpipe->active_query_count) {
783 for (i = 0; i < nr; i++)
784 qs->softpipe->occlusion_count += mask_count[quads[i]->inout.mask];
785 }
786
787 if (nr)
788 qs->next->run(qs->next, quads, nr);
789 }
790
791
792 /**
793 * Special-case Z testing for 16-bit Zbuffer and Z buffer writes enabled.
794 */
795
796 #define NAME depth_interp_z16_less_write
797 #define OPERATOR <
798 #include "sp_quad_depth_test_tmp.h"
799
800 #define NAME depth_interp_z16_equal_write
801 #define OPERATOR ==
802 #include "sp_quad_depth_test_tmp.h"
803
804 #define NAME depth_interp_z16_lequal_write
805 #define OPERATOR <=
806 #include "sp_quad_depth_test_tmp.h"
807
808 #define NAME depth_interp_z16_greater_write
809 #define OPERATOR >
810 #include "sp_quad_depth_test_tmp.h"
811
812 #define NAME depth_interp_z16_notequal_write
813 #define OPERATOR !=
814 #include "sp_quad_depth_test_tmp.h"
815
816 #define NAME depth_interp_z16_gequal_write
817 #define OPERATOR >=
818 #include "sp_quad_depth_test_tmp.h"
819
820 #define NAME depth_interp_z16_always_write
821 #define ALWAYS 1
822 #include "sp_quad_depth_test_tmp.h"
823
824
825
826 static void
827 depth_noop(struct quad_stage *qs,
828 struct quad_header *quads[],
829 unsigned nr)
830 {
831 qs->next->run(qs->next, quads, nr);
832 }
833
834
835
836 static void
837 choose_depth_test(struct quad_stage *qs,
838 struct quad_header *quads[],
839 unsigned nr)
840 {
841 boolean interp_depth = !qs->softpipe->fs->info.writes_z;
842
843 boolean alpha = qs->softpipe->depth_stencil->alpha.enabled;
844
845 boolean depth = qs->softpipe->depth_stencil->depth.enabled;
846
847 unsigned depthfunc = qs->softpipe->depth_stencil->depth.func;
848
849 boolean stencil = qs->softpipe->depth_stencil->stencil[0].enabled;
850
851 boolean depthwrite = qs->softpipe->depth_stencil->depth.writemask;
852
853 boolean occlusion = qs->softpipe->active_query_count;
854
855 if(!qs->softpipe->framebuffer.zsbuf)
856 depth = depthwrite = stencil = FALSE;
857
858 /* default */
859 qs->run = depth_test_quads_fallback;
860
861 /* look for special cases */
862 if (!alpha &&
863 !depth &&
864 !occlusion &&
865 !stencil) {
866 qs->run = depth_noop;
867 }
868 else if (!alpha &&
869 interp_depth &&
870 depth &&
871 depthwrite &&
872 !occlusion &&
873 !stencil)
874 {
875 if (qs->softpipe->framebuffer.zsbuf->format == PIPE_FORMAT_Z16_UNORM) {
876 switch (depthfunc) {
877 case PIPE_FUNC_NEVER:
878 qs->run = depth_test_quads_fallback;
879 break;
880 case PIPE_FUNC_LESS:
881 qs->run = depth_interp_z16_less_write;
882 break;
883 case PIPE_FUNC_EQUAL:
884 qs->run = depth_interp_z16_equal_write;
885 break;
886 case PIPE_FUNC_LEQUAL:
887 qs->run = depth_interp_z16_lequal_write;
888 break;
889 case PIPE_FUNC_GREATER:
890 qs->run = depth_interp_z16_greater_write;
891 break;
892 case PIPE_FUNC_NOTEQUAL:
893 qs->run = depth_interp_z16_notequal_write;
894 break;
895 case PIPE_FUNC_GEQUAL:
896 qs->run = depth_interp_z16_gequal_write;
897 break;
898 case PIPE_FUNC_ALWAYS:
899 qs->run = depth_interp_z16_always_write;
900 break;
901 default:
902 qs->run = depth_test_quads_fallback;
903 break;
904 }
905 }
906 }
907
908 /* next quad/fragment stage */
909 qs->run( qs, quads, nr );
910 }
911
912
913
914 static void
915 depth_test_begin(struct quad_stage *qs)
916 {
917 qs->run = choose_depth_test;
918 qs->next->begin(qs->next);
919 }
920
921
922 static void
923 depth_test_destroy(struct quad_stage *qs)
924 {
925 FREE( qs );
926 }
927
928
929 struct quad_stage *
930 sp_quad_depth_test_stage(struct softpipe_context *softpipe)
931 {
932 struct quad_stage *stage = CALLOC_STRUCT(quad_stage);
933
934 stage->softpipe = softpipe;
935 stage->begin = depth_test_begin;
936 stage->run = choose_depth_test;
937 stage->destroy = depth_test_destroy;
938
939 return stage;
940 }