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 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.
56 WRITES_RESOLVE_AMBIGUATE
,
59 /* A set of features supported by an isl_aux_usage. */
60 struct aux_usage_info
{
62 /* How writes affect the surface(s) in use. */
63 enum write_behavior write_behavior
;
65 /* Aux supports "real" compression beyond just fast-clears. */
68 /* SW can perform ISL_AUX_OP_FAST_CLEAR. */
71 /* SW can perform ISL_AUX_OP_PARTIAL_RESOLVE. */
74 /* Performing ISL_AUX_OP_FULL_RESOLVE includes ISL_AUX_OP_AMBIGUATE. */
75 bool full_resolves_ambiguate
;
78 #define AUX(wb, c, fc, pr, fra, type) \
79 [ISL_AUX_USAGE_ ## type] = { WRITES_ ## wb, c, fc, pr, fra},
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
)
99 aux_state_possible(enum isl_aux_state state
,
100 enum isl_aux_usage usage
)
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
:
115 case ISL_AUX_STATE_ASSERT
:
120 unreachable("Invalid aux state.");
124 isl_aux_prepare_access(enum isl_aux_state initial_state
,
125 enum isl_aux_usage usage
,
126 bool fast_clear_supported
)
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
));
133 assert(!fast_clear_supported
|| info
[usage
].fast_clear
);
135 switch (initial_state
) {
136 case ISL_AUX_STATE_COMPRESSED_CLEAR
:
137 if (!info
[usage
].compressed
)
138 return ISL_AUX_OP_FULL_RESOLVE
;
140 case ISL_AUX_STATE_CLEAR
:
141 case ISL_AUX_STATE_PARTIAL_CLEAR
:
142 return fast_clear_supported
?
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
;
156 case ISL_AUX_STATE_ASSERT
:
161 unreachable("Invalid aux state.");
165 isl_aux_state_transition_aux_op(enum isl_aux_state initial_state
,
166 enum isl_aux_usage usage
,
169 assert(aux_state_possible(initial_state
, usage
));
170 assert(usage
!= ISL_AUX_USAGE_NONE
|| op
== ISL_AUX_OP_NONE
);
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
;
193 case ISL_AUX_OP_ASSERT
:
198 unreachable("Invalid aux op.");
202 isl_aux_state_transition_write(enum isl_aux_state initial_state
,
203 enum isl_aux_usage usage
,
206 if (info
[usage
].write_behavior
== WRITES_ONLY_TOUCH_MAIN
) {
207 assert(full_surface
|| isl_aux_state_has_valid_primary(initial_state
));
209 return initial_state
== ISL_AUX_STATE_PASS_THROUGH
?
210 ISL_AUX_STATE_PASS_THROUGH
: ISL_AUX_STATE_AUX_INVALID
;
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
);
219 return info
[usage
].write_behavior
== WRITES_COMPRESS
?
220 ISL_AUX_STATE_COMPRESSED_NO_CLEAR
: ISL_AUX_STATE_PASS_THROUGH
;
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
;
237 case ISL_AUX_STATE_ASSERT
:
242 unreachable("Invalid aux state.");
246 isl_aux_usage_has_fast_clears(enum isl_aux_usage usage
)
248 return info
[usage
].fast_clear
;