Merge branch '7.8'
[mesa.git] / src / gallium / drivers / r300 / r300_hyperz.c
1 /*
2 * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
3 * Copyright 2009 Marek Olšák <maraeo@gmail.com>
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * on the rights to use, copy, modify, merge, publish, distribute, sub
9 * license, and/or sell copies of the Software, and to permit persons to whom
10 * the Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
20 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
22 * USE OR OTHER DEALINGS IN THE SOFTWARE. */
23
24
25 #include "r300_hyperz.h"
26 #include "r300_context.h"
27 #include "r300_reg.h"
28 #include "r300_fs.h"
29
30 /*****************************************************************************/
31 /* The ZTOP state */
32 /*****************************************************************************/
33
34 static boolean r300_dsa_writes_depth_stencil(struct r300_dsa_state* dsa)
35 {
36 /* We are interested only in the cases when a new depth or stencil value
37 * can be written and changed. */
38
39 /* We might optionally check for [Z func: never] and inspect the stencil
40 * state in a similar fashion, but it's not terribly important. */
41 return (dsa->z_buffer_control & R300_Z_WRITE_ENABLE) ||
42 (dsa->stencil_ref_mask & R300_STENCILWRITEMASK_MASK) ||
43 ((dsa->z_buffer_control & R500_STENCIL_REFMASK_FRONT_BACK) &&
44 (dsa->stencil_ref_bf & R300_STENCILWRITEMASK_MASK));
45 }
46
47 static boolean r300_dsa_alpha_test_enabled(struct r300_dsa_state* dsa)
48 {
49 /* We are interested only in the cases when alpha testing can kill
50 * a fragment. */
51 uint32_t af = dsa->alpha_function;
52
53 return (af & R300_FG_ALPHA_FUNC_ENABLE) &&
54 (af & R300_FG_ALPHA_FUNC_ALWAYS) != R300_FG_ALPHA_FUNC_ALWAYS;
55 }
56
57 static void r300_update_ztop(struct r300_context* r300)
58 {
59 struct r300_ztop_state* ztop_state =
60 (struct r300_ztop_state*)r300->ztop_state.state;
61
62 /* This is important enough that I felt it warranted a comment.
63 *
64 * According to the docs, these are the conditions where ZTOP must be
65 * disabled:
66 * 1) Alpha testing enabled
67 * 2) Texture kill instructions in fragment shader
68 * 3) Chroma key culling enabled
69 * 4) W-buffering enabled
70 *
71 * The docs claim that for the first three cases, if no ZS writes happen,
72 * then ZTOP can be used.
73 *
74 * (3) will never apply since we do not support chroma-keyed operations.
75 * (4) will need to be re-examined (and this comment updated) if/when
76 * Hyper-Z becomes supported.
77 *
78 * Additionally, the following conditions require disabled ZTOP:
79 * 5) Depth writes in fragment shader
80 * 6) Outstanding occlusion queries
81 *
82 * This register causes stalls all the way from SC to CB when changed,
83 * but it is buffered on-chip so it does not hurt to write it if it has
84 * not changed.
85 *
86 * ~C.
87 */
88
89 /* ZS writes */
90 if (r300_dsa_writes_depth_stencil(r300->dsa_state.state) &&
91 (r300_dsa_alpha_test_enabled(r300->dsa_state.state) || /* (1) */
92 r300_fs(r300)->shader->info.uses_kill)) { /* (2) */
93 ztop_state->z_buffer_top = R300_ZTOP_DISABLE;
94 } else if (r300_fragment_shader_writes_depth(r300_fs(r300))) { /* (5) */
95 ztop_state->z_buffer_top = R300_ZTOP_DISABLE;
96 } else if (r300->query_current) { /* (6) */
97 ztop_state->z_buffer_top = R300_ZTOP_DISABLE;
98 } else {
99 ztop_state->z_buffer_top = R300_ZTOP_ENABLE;
100 }
101
102 r300->ztop_state.dirty = TRUE;
103 }
104
105 void r300_update_hyperz_state(struct r300_context* r300)
106 {
107 r300_update_ztop(r300);
108 }