intel: drop unused include directories
[mesa.git] / src / intel / isl / isl_aux_info.c
1 /*
2 * Copyright 2019 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23
24 #include "isl/isl.h"
25
26 #ifdef IN_UNIT_TEST
27 /* STATIC_ASSERT is a do { ... } while(0) statement */
28 UNUSED static void static_assert_func(void) {
29 STATIC_ASSERT(ISL_AUX_OP_ASSERT == ((enum isl_aux_op) 0));
30 STATIC_ASSERT(ISL_AUX_STATE_ASSERT == ((enum isl_aux_state) 0));
31 }
32
33 #undef unreachable
34 #define unreachable(str) return 0
35
36 #undef assert
37 #define assert(cond) do { \
38 if (!(cond)) { \
39 return 0; \
40 } \
41 } while (0)
42 #endif
43
44 /* How writes with an isl_aux_usage behave. */
45 enum write_behavior {
46 /* Writes only touch the main surface. */
47 WRITES_ONLY_TOUCH_MAIN = 0,
48
49 /* Writes using the 3D engine are compressed. */
50 WRITES_COMPRESS,
51
52 /* Writes implicitly fully resolve the compression block and write the data
53 * uncompressed into the main surface. The resolved aux blocks are
54 * ambiguated and left in the pass-through state.
55 */
56 WRITES_RESOLVE_AMBIGUATE,
57 };
58
59 /* A set of features supported by an isl_aux_usage. */
60 struct aux_usage_info {
61
62 /* How writes affect the surface(s) in use. */
63 enum write_behavior write_behavior;
64
65 /* Aux supports "real" compression beyond just fast-clears. */
66 bool compressed;
67
68 /* SW can perform ISL_AUX_OP_FAST_CLEAR. */
69 bool fast_clear;
70
71 /* SW can perform ISL_AUX_OP_PARTIAL_RESOLVE. */
72 bool partial_resolve;
73
74 /* Performing ISL_AUX_OP_FULL_RESOLVE includes ISL_AUX_OP_AMBIGUATE. */
75 bool full_resolves_ambiguate;
76 };
77
78 #define AUX(wb, c, fc, pr, fra, type) \
79 [ISL_AUX_USAGE_ ## type] = { WRITES_ ## wb, c, fc, pr, fra},
80 #define Y true
81 #define x false
82 static const struct aux_usage_info info[] = {
83 /* write_behavior c fc pr fra */
84 AUX( COMPRESS, Y, Y, x, x, HIZ)
85 AUX( COMPRESS, Y, Y, x, x, HIZ_CCS)
86 AUX( COMPRESS, Y, Y, x, x, HIZ_CCS_WT)
87 AUX( COMPRESS, Y, Y, Y, x, MCS)
88 AUX( COMPRESS, Y, Y, Y, x, MCS_CCS)
89 AUX( COMPRESS, Y, Y, Y, Y, CCS_E)
90 AUX(RESOLVE_AMBIGUATE, x, Y, x, Y, CCS_D)
91 AUX(RESOLVE_AMBIGUATE, Y, x, x, Y, MC)
92 AUX( COMPRESS, Y, x, x, Y, STC_CCS)
93 };
94 #undef x
95 #undef Y
96 #undef AUX
97
98 ASSERTED static bool
99 aux_state_possible(enum isl_aux_state state,
100 enum isl_aux_usage usage)
101 {
102 switch (state) {
103 case ISL_AUX_STATE_CLEAR:
104 case ISL_AUX_STATE_PARTIAL_CLEAR:
105 return info[usage].fast_clear;
106 case ISL_AUX_STATE_COMPRESSED_CLEAR:
107 return info[usage].fast_clear && info[usage].compressed;
108 case ISL_AUX_STATE_COMPRESSED_NO_CLEAR:
109 return info[usage].compressed;
110 case ISL_AUX_STATE_RESOLVED:
111 case ISL_AUX_STATE_PASS_THROUGH:
112 case ISL_AUX_STATE_AUX_INVALID:
113 return true;
114 #ifdef IN_UNIT_TEST
115 case ISL_AUX_STATE_ASSERT:
116 break;
117 #endif
118 }
119
120 unreachable("Invalid aux state.");
121 }
122
123 enum isl_aux_op
124 isl_aux_prepare_access(enum isl_aux_state initial_state,
125 enum isl_aux_usage usage,
126 bool fast_clear_supported)
127 {
128 if (usage != ISL_AUX_USAGE_NONE) {
129 UNUSED const enum isl_aux_usage state_superset_usage =
130 usage == ISL_AUX_USAGE_CCS_D ? ISL_AUX_USAGE_CCS_E : usage;
131 assert(aux_state_possible(initial_state, state_superset_usage));
132 }
133 assert(!fast_clear_supported || info[usage].fast_clear);
134
135 switch (initial_state) {
136 case ISL_AUX_STATE_COMPRESSED_CLEAR:
137 if (!info[usage].compressed)
138 return ISL_AUX_OP_FULL_RESOLVE;
139 /* Fall-through */
140 case ISL_AUX_STATE_CLEAR:
141 case ISL_AUX_STATE_PARTIAL_CLEAR:
142 return fast_clear_supported ?
143 ISL_AUX_OP_NONE :
144 info[usage].partial_resolve ?
145 ISL_AUX_OP_PARTIAL_RESOLVE : ISL_AUX_OP_FULL_RESOLVE;
146 case ISL_AUX_STATE_COMPRESSED_NO_CLEAR:
147 return info[usage].compressed ?
148 ISL_AUX_OP_NONE : ISL_AUX_OP_FULL_RESOLVE;
149 case ISL_AUX_STATE_RESOLVED:
150 case ISL_AUX_STATE_PASS_THROUGH:
151 return ISL_AUX_OP_NONE;
152 case ISL_AUX_STATE_AUX_INVALID:
153 return info[usage].write_behavior == WRITES_ONLY_TOUCH_MAIN ?
154 ISL_AUX_OP_NONE : ISL_AUX_OP_AMBIGUATE;
155 #ifdef IN_UNIT_TEST
156 case ISL_AUX_STATE_ASSERT:
157 break;
158 #endif
159 }
160
161 unreachable("Invalid aux state.");
162 }
163
164 enum isl_aux_state
165 isl_aux_state_transition_aux_op(enum isl_aux_state initial_state,
166 enum isl_aux_usage usage,
167 enum isl_aux_op op)
168 {
169 assert(aux_state_possible(initial_state, usage));
170 assert(usage != ISL_AUX_USAGE_NONE || op == ISL_AUX_OP_NONE);
171
172 switch (op) {
173 case ISL_AUX_OP_NONE:
174 return initial_state;
175 case ISL_AUX_OP_FAST_CLEAR:
176 assert(info[usage].fast_clear);
177 return ISL_AUX_STATE_CLEAR;
178 case ISL_AUX_OP_PARTIAL_RESOLVE:
179 assert(isl_aux_state_has_valid_aux(initial_state));
180 assert(info[usage].partial_resolve);
181 return initial_state == ISL_AUX_STATE_CLEAR ||
182 initial_state == ISL_AUX_STATE_PARTIAL_CLEAR ||
183 initial_state == ISL_AUX_STATE_COMPRESSED_CLEAR ?
184 ISL_AUX_STATE_COMPRESSED_NO_CLEAR : initial_state;
185 case ISL_AUX_OP_FULL_RESOLVE:
186 assert(isl_aux_state_has_valid_aux(initial_state));
187 return info[usage].full_resolves_ambiguate ||
188 initial_state == ISL_AUX_STATE_PASS_THROUGH ?
189 ISL_AUX_STATE_PASS_THROUGH : ISL_AUX_STATE_RESOLVED;
190 case ISL_AUX_OP_AMBIGUATE:
191 return ISL_AUX_STATE_PASS_THROUGH;
192 #if IN_UNIT_TEST
193 case ISL_AUX_OP_ASSERT:
194 break;
195 #endif
196 }
197
198 unreachable("Invalid aux op.");
199 }
200
201 enum isl_aux_state
202 isl_aux_state_transition_write(enum isl_aux_state initial_state,
203 enum isl_aux_usage usage,
204 bool full_surface)
205 {
206 if (info[usage].write_behavior == WRITES_ONLY_TOUCH_MAIN) {
207 assert(full_surface || isl_aux_state_has_valid_primary(initial_state));
208
209 return initial_state == ISL_AUX_STATE_PASS_THROUGH ?
210 ISL_AUX_STATE_PASS_THROUGH : ISL_AUX_STATE_AUX_INVALID;
211 }
212
213 assert(isl_aux_state_has_valid_aux(initial_state));
214 assert(aux_state_possible(initial_state, usage));
215 assert(info[usage].write_behavior == WRITES_COMPRESS ||
216 info[usage].write_behavior == WRITES_RESOLVE_AMBIGUATE);
217
218 if (full_surface) {
219 return info[usage].write_behavior == WRITES_COMPRESS ?
220 ISL_AUX_STATE_COMPRESSED_NO_CLEAR : ISL_AUX_STATE_PASS_THROUGH;
221 }
222
223 switch (initial_state) {
224 case ISL_AUX_STATE_CLEAR:
225 case ISL_AUX_STATE_PARTIAL_CLEAR:
226 return info[usage].write_behavior == WRITES_COMPRESS ?
227 ISL_AUX_STATE_COMPRESSED_CLEAR : ISL_AUX_STATE_PARTIAL_CLEAR;
228 case ISL_AUX_STATE_RESOLVED:
229 case ISL_AUX_STATE_PASS_THROUGH:
230 return info[usage].write_behavior == WRITES_COMPRESS ?
231 ISL_AUX_STATE_COMPRESSED_NO_CLEAR : initial_state;
232 case ISL_AUX_STATE_COMPRESSED_CLEAR:
233 case ISL_AUX_STATE_COMPRESSED_NO_CLEAR:
234 case ISL_AUX_STATE_AUX_INVALID:
235 return initial_state;
236 #ifdef IN_UNIT_TEST
237 case ISL_AUX_STATE_ASSERT:
238 break;
239 #endif
240 }
241
242 unreachable("Invalid aux state.");
243 }
244
245 bool
246 isl_aux_usage_has_fast_clears(enum isl_aux_usage usage)
247 {
248 return info[usage].fast_clear;
249 }