2 * Copyright 2019 Intel Corporation
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:
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
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.
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));
34 #define unreachable(str) return 0
37 #define assert(cond) do { \
44 /* How writes with an isl_aux_usage behave. */
46 /* Writes only touch the main surface. */
47 WRITES_ONLY_TOUCH_MAIN
= 0,
49 /* Writes using the 3D engine are compressed. */
52 /* Writes using the 3D engine are either compressed or substituted with
53 * fast-cleared blocks.
55 WRITES_COMPRESS_CLEAR
,
57 /* Writes implicitly fully resolve the compression block and write the data
58 * uncompressed into the main surface. The resolved aux blocks are
59 * ambiguated and left in the pass-through state.
61 WRITES_RESOLVE_AMBIGUATE
,
64 /* A set of features supported by an isl_aux_usage. */
65 struct aux_usage_info
{
67 /* How writes affect the surface(s) in use. */
68 enum write_behavior write_behavior
;
70 /* Aux supports "real" compression beyond just fast-clears. */
73 /* SW can perform ISL_AUX_OP_FAST_CLEAR. */
76 /* SW can perform ISL_AUX_OP_PARTIAL_RESOLVE. */
79 /* Performing ISL_AUX_OP_FULL_RESOLVE includes ISL_AUX_OP_AMBIGUATE. */
80 bool full_resolves_ambiguate
;
83 #define AUX(wb, c, fc, pr, fra, type) \
84 [ISL_AUX_USAGE_ ## type] = { WRITES_ ## wb, c, fc, pr, fra},
87 static const struct aux_usage_info info
[] = {
88 /* write_behavior c fc pr fra */
89 AUX( COMPRESS
, Y
, Y
, x
, x
, HIZ
)
90 AUX( COMPRESS
, Y
, Y
, x
, x
, HIZ_CCS
)
91 AUX( COMPRESS
, Y
, Y
, x
, x
, HIZ_CCS_WT
)
92 AUX( COMPRESS
, Y
, Y
, Y
, x
, MCS
)
93 AUX( COMPRESS
, Y
, Y
, Y
, x
, MCS_CCS
)
94 AUX( COMPRESS
, Y
, Y
, Y
, Y
, CCS_E
)
95 AUX( COMPRESS_CLEAR
, Y
, Y
, Y
, Y
, GEN12_CCS_E
)
96 AUX(RESOLVE_AMBIGUATE
, x
, Y
, x
, Y
, CCS_D
)
97 AUX(RESOLVE_AMBIGUATE
, Y
, x
, x
, Y
, MC
)
98 AUX( COMPRESS
, Y
, x
, x
, Y
, STC_CCS
)
105 aux_state_possible(enum isl_aux_state state
,
106 enum isl_aux_usage usage
)
109 case ISL_AUX_STATE_CLEAR
:
110 case ISL_AUX_STATE_PARTIAL_CLEAR
:
111 return info
[usage
].fast_clear
;
112 case ISL_AUX_STATE_COMPRESSED_CLEAR
:
113 return info
[usage
].fast_clear
&& info
[usage
].compressed
;
114 case ISL_AUX_STATE_COMPRESSED_NO_CLEAR
:
115 return info
[usage
].compressed
;
116 case ISL_AUX_STATE_RESOLVED
:
117 case ISL_AUX_STATE_PASS_THROUGH
:
118 case ISL_AUX_STATE_AUX_INVALID
:
121 case ISL_AUX_STATE_ASSERT
:
126 unreachable("Invalid aux state.");
130 isl_aux_prepare_access(enum isl_aux_state initial_state
,
131 enum isl_aux_usage usage
,
132 bool fast_clear_supported
)
134 if (usage
!= ISL_AUX_USAGE_NONE
) {
135 UNUSED
const enum isl_aux_usage state_superset_usage
=
136 usage
== ISL_AUX_USAGE_CCS_D
? ISL_AUX_USAGE_CCS_E
: usage
;
137 assert(aux_state_possible(initial_state
, state_superset_usage
));
139 assert(!fast_clear_supported
|| info
[usage
].fast_clear
);
141 switch (initial_state
) {
142 case ISL_AUX_STATE_COMPRESSED_CLEAR
:
143 if (!info
[usage
].compressed
)
144 return ISL_AUX_OP_FULL_RESOLVE
;
146 case ISL_AUX_STATE_CLEAR
:
147 case ISL_AUX_STATE_PARTIAL_CLEAR
:
148 return fast_clear_supported
?
150 info
[usage
].partial_resolve
?
151 ISL_AUX_OP_PARTIAL_RESOLVE
: ISL_AUX_OP_FULL_RESOLVE
;
152 case ISL_AUX_STATE_COMPRESSED_NO_CLEAR
:
153 return info
[usage
].compressed
?
154 ISL_AUX_OP_NONE
: ISL_AUX_OP_FULL_RESOLVE
;
155 case ISL_AUX_STATE_RESOLVED
:
156 case ISL_AUX_STATE_PASS_THROUGH
:
157 return ISL_AUX_OP_NONE
;
158 case ISL_AUX_STATE_AUX_INVALID
:
159 return info
[usage
].write_behavior
== WRITES_ONLY_TOUCH_MAIN
?
160 ISL_AUX_OP_NONE
: ISL_AUX_OP_AMBIGUATE
;
162 case ISL_AUX_STATE_ASSERT
:
167 unreachable("Invalid aux state.");
171 isl_aux_state_transition_aux_op(enum isl_aux_state initial_state
,
172 enum isl_aux_usage usage
,
175 assert(aux_state_possible(initial_state
, usage
));
176 assert(usage
!= ISL_AUX_USAGE_NONE
|| op
== ISL_AUX_OP_NONE
);
179 case ISL_AUX_OP_NONE
:
180 return initial_state
;
181 case ISL_AUX_OP_FAST_CLEAR
:
182 assert(info
[usage
].fast_clear
);
183 return ISL_AUX_STATE_CLEAR
;
184 case ISL_AUX_OP_PARTIAL_RESOLVE
:
185 assert(isl_aux_state_has_valid_aux(initial_state
));
186 assert(info
[usage
].partial_resolve
);
187 return initial_state
== ISL_AUX_STATE_CLEAR
||
188 initial_state
== ISL_AUX_STATE_PARTIAL_CLEAR
||
189 initial_state
== ISL_AUX_STATE_COMPRESSED_CLEAR
?
190 ISL_AUX_STATE_COMPRESSED_NO_CLEAR
: initial_state
;
191 case ISL_AUX_OP_FULL_RESOLVE
:
192 assert(isl_aux_state_has_valid_aux(initial_state
));
193 return info
[usage
].full_resolves_ambiguate
||
194 initial_state
== ISL_AUX_STATE_PASS_THROUGH
?
195 ISL_AUX_STATE_PASS_THROUGH
: ISL_AUX_STATE_RESOLVED
;
196 case ISL_AUX_OP_AMBIGUATE
:
197 return ISL_AUX_STATE_PASS_THROUGH
;
199 case ISL_AUX_OP_ASSERT
:
204 unreachable("Invalid aux op.");
208 isl_aux_state_transition_write(enum isl_aux_state initial_state
,
209 enum isl_aux_usage usage
,
212 if (info
[usage
].write_behavior
== WRITES_ONLY_TOUCH_MAIN
) {
213 assert(full_surface
|| isl_aux_state_has_valid_primary(initial_state
));
215 return initial_state
== ISL_AUX_STATE_PASS_THROUGH
?
216 ISL_AUX_STATE_PASS_THROUGH
: ISL_AUX_STATE_AUX_INVALID
;
219 assert(isl_aux_state_has_valid_aux(initial_state
));
220 assert(aux_state_possible(initial_state
, usage
));
221 assert(info
[usage
].write_behavior
== WRITES_COMPRESS
||
222 info
[usage
].write_behavior
== WRITES_COMPRESS_CLEAR
||
223 info
[usage
].write_behavior
== WRITES_RESOLVE_AMBIGUATE
);
226 return info
[usage
].write_behavior
== WRITES_COMPRESS
?
227 ISL_AUX_STATE_COMPRESSED_NO_CLEAR
:
228 info
[usage
].write_behavior
== WRITES_COMPRESS_CLEAR
?
229 ISL_AUX_STATE_COMPRESSED_CLEAR
: ISL_AUX_STATE_PASS_THROUGH
;
232 switch (initial_state
) {
233 case ISL_AUX_STATE_CLEAR
:
234 case ISL_AUX_STATE_PARTIAL_CLEAR
:
235 return info
[usage
].write_behavior
== WRITES_RESOLVE_AMBIGUATE
?
236 ISL_AUX_STATE_PARTIAL_CLEAR
: ISL_AUX_STATE_COMPRESSED_CLEAR
;
237 case ISL_AUX_STATE_RESOLVED
:
238 case ISL_AUX_STATE_PASS_THROUGH
:
239 case ISL_AUX_STATE_COMPRESSED_NO_CLEAR
:
240 return info
[usage
].write_behavior
== WRITES_COMPRESS
?
241 ISL_AUX_STATE_COMPRESSED_NO_CLEAR
:
242 info
[usage
].write_behavior
== WRITES_COMPRESS_CLEAR
?
243 ISL_AUX_STATE_COMPRESSED_CLEAR
: initial_state
;
244 case ISL_AUX_STATE_COMPRESSED_CLEAR
:
245 case ISL_AUX_STATE_AUX_INVALID
:
246 return initial_state
;
248 case ISL_AUX_STATE_ASSERT
:
253 unreachable("Invalid aux state.");
257 isl_aux_usage_has_fast_clears(enum isl_aux_usage usage
)
259 return info
[usage
].fast_clear
;