mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-25 04:20:08 +01:00
isl: Add a module which manages aux resolves
Provide a generic interface which manages aux resolves in ISL. The
feature differences between this and what's in iris is:
* Support for media compression. ISL_AUX_USAGE_MC behaves differently
from many other usages of CCS, so it was useful to implement this
support upfront, while designing the interfaces.
* Optimizations for full-surface writes. For example, after a
full-surface write occurs with ISL_AUX_USAGE_CCS_E in the PARTIAL_CLEAR
state, isl_aux_state_transition_write() returns COMPRESSED_NO_CLEAR
instead of COMPRESSED_CLEAR.
A performance suggestion for main-surface-invalidating/replacing writes
is given as a comment instead of adding a boolean to
isl_aux_prepare_access(). This avoids extra validation and should be
simple enough for the caller to handle.
v2. Add assertions. (Jason)
v3. Use switches in 2 more functions. (Jason)
Store aux metadata in a static table. (Jason)
Change prepare and finish function signatures. (Jason)
Keep isl_aux_state_transition_* functions separate.
v4. (Jason)
Assert against resolving in AUX_INVALID.
Rename aux_info struct to aux_usage_info.
Drop the justification for each aux_usage_info field.
Split out the NONE case in write function.
Restructure tests to more easily confirm coverage.
Rename access_compressed field to compressed.
Make write behavior less ambiguous.
v5. (Jason)
Add more detail above WRITES_RESOLVE_AMBIGUATE.
Add ISL_AUX_USAGE_MC to WritesResolveAmbiguate.
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/2957>
This commit is contained in:
parent
daa4020948
commit
58d4749e56
4 changed files with 702 additions and 0 deletions
|
|
@ -1682,6 +1682,57 @@ isl_tiling_to_i915_tiling(enum isl_tiling tiling);
|
|||
enum isl_tiling
|
||||
isl_tiling_from_i915_tiling(uint32_t tiling);
|
||||
|
||||
/**
|
||||
* Return an isl_aux_op needed to enable an access to occur in an
|
||||
* isl_aux_state suitable for the isl_aux_usage.
|
||||
*
|
||||
* NOTE: If the access will invalidate the main surface, this function should
|
||||
* not be called and the isl_aux_op of NONE should be used instead.
|
||||
* Otherwise, an extra (but still lossless) ambiguate may occur.
|
||||
*
|
||||
* @invariant initial_state is possible with an isl_aux_usage compatible with
|
||||
* the given usage. Two usages are compatible if it's possible to
|
||||
* switch between them (e.g. CCS_E <-> CCS_D).
|
||||
* @invariant fast_clear is false if the aux doesn't support fast clears.
|
||||
*/
|
||||
enum isl_aux_op
|
||||
isl_aux_prepare_access(enum isl_aux_state initial_state,
|
||||
enum isl_aux_usage usage,
|
||||
bool fast_clear_supported);
|
||||
|
||||
/**
|
||||
* Return the isl_aux_state entered after performing an isl_aux_op.
|
||||
*
|
||||
* @invariant initial_state is possible with the given usage.
|
||||
* @invariant op is possible with the given usage.
|
||||
* @invariant op must not cause HW to read from an invalid aux.
|
||||
*/
|
||||
enum isl_aux_state
|
||||
isl_aux_state_transition_aux_op(enum isl_aux_state initial_state,
|
||||
enum isl_aux_usage usage,
|
||||
enum isl_aux_op op);
|
||||
|
||||
/**
|
||||
* Return the isl_aux_state entered after performing a write.
|
||||
*
|
||||
* NOTE: full_surface should be true if the write covers the entire
|
||||
* slice. Setting it to false in this case will still result in a
|
||||
* correct (but imprecise) aux state.
|
||||
*
|
||||
* @invariant if usage is not ISL_AUX_USAGE_NONE, then initial_state is
|
||||
* possible with the given usage.
|
||||
* @invariant usage can be ISL_AUX_USAGE_NONE iff:
|
||||
* * the main surface is valid, or
|
||||
* * the main surface is being invalidated/replaced.
|
||||
*/
|
||||
enum isl_aux_state
|
||||
isl_aux_state_transition_write(enum isl_aux_state initial_state,
|
||||
enum isl_aux_usage usage,
|
||||
bool full_surface);
|
||||
|
||||
bool
|
||||
isl_aux_usage_has_fast_clears(enum isl_aux_usage usage);
|
||||
|
||||
static inline bool
|
||||
isl_aux_usage_has_hiz(enum isl_aux_usage usage)
|
||||
{
|
||||
|
|
|
|||
213
src/intel/isl/isl_aux_info.c
Normal file
213
src/intel/isl/isl_aux_info.c
Normal file
|
|
@ -0,0 +1,213 @@
|
|||
/*
|
||||
* Copyright 2019 Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "isl/isl.h"
|
||||
|
||||
/* How writes with an isl_aux_usage behave. */
|
||||
enum write_behavior {
|
||||
/* Writes only touch the main surface. */
|
||||
WRITES_ONLY_TOUCH_MAIN = 0,
|
||||
|
||||
/* Writes using the 3D engine are compressed. */
|
||||
WRITES_COMPRESS,
|
||||
|
||||
/* Writes implicitly fully resolve the compression block and write the data
|
||||
* uncompressed into the main surface. The resolved aux blocks are
|
||||
* ambiguated and left in the pass-through state.
|
||||
*/
|
||||
WRITES_RESOLVE_AMBIGUATE,
|
||||
};
|
||||
|
||||
/* A set of features supported by an isl_aux_usage. */
|
||||
struct aux_usage_info {
|
||||
|
||||
/* How writes affect the surface(s) in use. */
|
||||
enum write_behavior write_behavior;
|
||||
|
||||
/* Aux supports "real" compression beyond just fast-clears. */
|
||||
bool compressed;
|
||||
|
||||
/* SW can perform ISL_AUX_OP_FAST_CLEAR. */
|
||||
bool fast_clear;
|
||||
|
||||
/* SW can perform ISL_AUX_OP_PARTIAL_RESOLVE. */
|
||||
bool partial_resolve;
|
||||
|
||||
/* Performing ISL_AUX_OP_FULL_RESOLVE includes ISL_AUX_OP_AMBIGUATE. */
|
||||
bool full_resolves_ambiguate;
|
||||
};
|
||||
|
||||
#define AUX(wb, c, fc, pr, fra, type) \
|
||||
[ISL_AUX_USAGE_ ## type] = { WRITES_ ## wb, c, fc, pr, fra},
|
||||
#define Y true
|
||||
#define x false
|
||||
static const struct aux_usage_info info[] = {
|
||||
/* write_behavior c fc pr fra */
|
||||
AUX( COMPRESS, Y, Y, x, x, HIZ)
|
||||
AUX( COMPRESS, Y, Y, x, x, HIZ_CCS)
|
||||
AUX( COMPRESS, Y, Y, Y, x, MCS)
|
||||
AUX( COMPRESS, Y, Y, Y, x, MCS_CCS)
|
||||
AUX( COMPRESS, Y, Y, Y, Y, CCS_E)
|
||||
AUX(RESOLVE_AMBIGUATE, x, Y, x, Y, CCS_D)
|
||||
AUX(RESOLVE_AMBIGUATE, Y, x, x, Y, MC)
|
||||
};
|
||||
#undef x
|
||||
#undef Y
|
||||
#undef AUX
|
||||
|
||||
ASSERTED static bool
|
||||
aux_state_possible(enum isl_aux_state state,
|
||||
enum isl_aux_usage usage)
|
||||
{
|
||||
switch (state) {
|
||||
case ISL_AUX_STATE_CLEAR:
|
||||
case ISL_AUX_STATE_PARTIAL_CLEAR:
|
||||
return info[usage].fast_clear;
|
||||
case ISL_AUX_STATE_COMPRESSED_CLEAR:
|
||||
return info[usage].fast_clear && info[usage].compressed;
|
||||
case ISL_AUX_STATE_COMPRESSED_NO_CLEAR:
|
||||
return info[usage].compressed;
|
||||
case ISL_AUX_STATE_RESOLVED:
|
||||
case ISL_AUX_STATE_PASS_THROUGH:
|
||||
case ISL_AUX_STATE_AUX_INVALID:
|
||||
return true;
|
||||
}
|
||||
|
||||
unreachable("Invalid aux state.");
|
||||
}
|
||||
|
||||
enum isl_aux_op
|
||||
isl_aux_prepare_access(enum isl_aux_state initial_state,
|
||||
enum isl_aux_usage usage,
|
||||
bool fast_clear_supported)
|
||||
{
|
||||
if (usage != ISL_AUX_USAGE_NONE) {
|
||||
UNUSED const enum isl_aux_usage state_superset_usage =
|
||||
usage == ISL_AUX_USAGE_CCS_D ? ISL_AUX_USAGE_CCS_E : usage;
|
||||
assert(aux_state_possible(initial_state, state_superset_usage));
|
||||
}
|
||||
assert(!fast_clear_supported || info[usage].fast_clear);
|
||||
|
||||
switch (initial_state) {
|
||||
case ISL_AUX_STATE_COMPRESSED_CLEAR:
|
||||
if (!info[usage].compressed)
|
||||
return ISL_AUX_OP_FULL_RESOLVE;
|
||||
/* Fall-through */
|
||||
case ISL_AUX_STATE_CLEAR:
|
||||
case ISL_AUX_STATE_PARTIAL_CLEAR:
|
||||
return fast_clear_supported ?
|
||||
ISL_AUX_OP_NONE :
|
||||
info[usage].partial_resolve ?
|
||||
ISL_AUX_OP_PARTIAL_RESOLVE : ISL_AUX_OP_FULL_RESOLVE;
|
||||
case ISL_AUX_STATE_COMPRESSED_NO_CLEAR:
|
||||
return info[usage].compressed ?
|
||||
ISL_AUX_OP_NONE : ISL_AUX_OP_FULL_RESOLVE;
|
||||
case ISL_AUX_STATE_RESOLVED:
|
||||
case ISL_AUX_STATE_PASS_THROUGH:
|
||||
return ISL_AUX_OP_NONE;
|
||||
case ISL_AUX_STATE_AUX_INVALID:
|
||||
return info[usage].write_behavior == WRITES_ONLY_TOUCH_MAIN ?
|
||||
ISL_AUX_OP_NONE : ISL_AUX_OP_AMBIGUATE;
|
||||
}
|
||||
|
||||
unreachable("Invalid aux state.");
|
||||
}
|
||||
|
||||
enum isl_aux_state
|
||||
isl_aux_state_transition_aux_op(enum isl_aux_state initial_state,
|
||||
enum isl_aux_usage usage,
|
||||
enum isl_aux_op op)
|
||||
{
|
||||
assert(aux_state_possible(initial_state, usage));
|
||||
assert(usage != ISL_AUX_USAGE_NONE || op == ISL_AUX_OP_NONE);
|
||||
|
||||
switch (op) {
|
||||
case ISL_AUX_OP_NONE:
|
||||
return initial_state;
|
||||
case ISL_AUX_OP_FAST_CLEAR:
|
||||
assert(info[usage].fast_clear);
|
||||
return ISL_AUX_STATE_CLEAR;
|
||||
case ISL_AUX_OP_PARTIAL_RESOLVE:
|
||||
assert(isl_aux_state_has_valid_aux(initial_state));
|
||||
assert(info[usage].partial_resolve);
|
||||
return initial_state == ISL_AUX_STATE_CLEAR ||
|
||||
initial_state == ISL_AUX_STATE_PARTIAL_CLEAR ||
|
||||
initial_state == ISL_AUX_STATE_COMPRESSED_CLEAR ?
|
||||
ISL_AUX_STATE_COMPRESSED_NO_CLEAR : initial_state;
|
||||
case ISL_AUX_OP_FULL_RESOLVE:
|
||||
assert(isl_aux_state_has_valid_aux(initial_state));
|
||||
return info[usage].full_resolves_ambiguate ||
|
||||
initial_state == ISL_AUX_STATE_PASS_THROUGH ?
|
||||
ISL_AUX_STATE_PASS_THROUGH : ISL_AUX_STATE_RESOLVED;
|
||||
case ISL_AUX_OP_AMBIGUATE:
|
||||
return ISL_AUX_STATE_PASS_THROUGH;
|
||||
}
|
||||
|
||||
unreachable("Invalid aux op.");
|
||||
}
|
||||
|
||||
enum isl_aux_state
|
||||
isl_aux_state_transition_write(enum isl_aux_state initial_state,
|
||||
enum isl_aux_usage usage,
|
||||
bool full_surface)
|
||||
{
|
||||
if (info[usage].write_behavior == WRITES_ONLY_TOUCH_MAIN) {
|
||||
assert(full_surface || isl_aux_state_has_valid_primary(initial_state));
|
||||
|
||||
return initial_state == ISL_AUX_STATE_PASS_THROUGH ?
|
||||
ISL_AUX_STATE_PASS_THROUGH : ISL_AUX_STATE_AUX_INVALID;
|
||||
}
|
||||
|
||||
assert(isl_aux_state_has_valid_aux(initial_state));
|
||||
assert(aux_state_possible(initial_state, usage));
|
||||
assert(info[usage].write_behavior == WRITES_COMPRESS ||
|
||||
info[usage].write_behavior == WRITES_RESOLVE_AMBIGUATE);
|
||||
|
||||
if (full_surface) {
|
||||
return info[usage].write_behavior == WRITES_COMPRESS ?
|
||||
ISL_AUX_STATE_COMPRESSED_NO_CLEAR : ISL_AUX_STATE_PASS_THROUGH;
|
||||
}
|
||||
|
||||
switch (initial_state) {
|
||||
case ISL_AUX_STATE_CLEAR:
|
||||
case ISL_AUX_STATE_PARTIAL_CLEAR:
|
||||
return info[usage].write_behavior == WRITES_COMPRESS ?
|
||||
ISL_AUX_STATE_COMPRESSED_CLEAR : ISL_AUX_STATE_PARTIAL_CLEAR;
|
||||
case ISL_AUX_STATE_RESOLVED:
|
||||
case ISL_AUX_STATE_PASS_THROUGH:
|
||||
return info[usage].write_behavior == WRITES_COMPRESS ?
|
||||
ISL_AUX_STATE_COMPRESSED_NO_CLEAR : initial_state;
|
||||
case ISL_AUX_STATE_COMPRESSED_CLEAR:
|
||||
case ISL_AUX_STATE_COMPRESSED_NO_CLEAR:
|
||||
case ISL_AUX_STATE_AUX_INVALID:
|
||||
return initial_state;
|
||||
}
|
||||
|
||||
unreachable("Invalid aux state.");
|
||||
}
|
||||
|
||||
bool
|
||||
isl_aux_usage_has_fast_clears(enum isl_aux_usage usage)
|
||||
{
|
||||
return info[usage].fast_clear;
|
||||
}
|
||||
|
|
@ -111,6 +111,7 @@ endif
|
|||
libisl_files = files(
|
||||
'isl.c',
|
||||
'isl.h',
|
||||
'isl_aux_info.c',
|
||||
'isl_drm.c',
|
||||
'isl_genX_priv.h',
|
||||
'isl_format.c',
|
||||
|
|
@ -138,4 +139,15 @@ if with_tests
|
|||
),
|
||||
suite : ['intel'],
|
||||
)
|
||||
test(
|
||||
'isl_aux_info',
|
||||
executable(
|
||||
'isl_aux_info_test',
|
||||
'tests/isl_aux_info_test.cpp',
|
||||
dependencies : [dep_m, idep_gtest, idep_mesautil],
|
||||
include_directories : [inc_common, inc_intel],
|
||||
link_with : [libisl],
|
||||
),
|
||||
suite : ['intel'],
|
||||
)
|
||||
endif
|
||||
|
|
|
|||
426
src/intel/isl/tests/isl_aux_info_test.cpp
Normal file
426
src/intel/isl/tests/isl_aux_info_test.cpp
Normal file
|
|
@ -0,0 +1,426 @@
|
|||
/*
|
||||
* Copyright 2019 Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "isl/isl.h"
|
||||
|
||||
#define ISL_AUX_OP_ASSERT ((enum isl_aux_op) 100)
|
||||
#define ISL_AUX_STATE_ASSERT ((enum isl_aux_state) 100)
|
||||
|
||||
#ifndef NDEBUG
|
||||
#define ASSERTS_ENABLED true
|
||||
#else
|
||||
#define ASSERTS_ENABLED false
|
||||
#endif
|
||||
|
||||
void
|
||||
PrintTo(const enum isl_aux_op &op, ::std::ostream* os) {
|
||||
*os << (const char *[]) {
|
||||
[ISL_AUX_OP_NONE ] = "ISL_AUX_OP_NONE",
|
||||
[ISL_AUX_OP_FAST_CLEAR ] = "ISL_AUX_OP_FAST_CLEAR",
|
||||
[ISL_AUX_OP_FULL_RESOLVE ] = "ISL_AUX_OP_FULL_RESOLVE",
|
||||
[ISL_AUX_OP_PARTIAL_RESOLVE] = "ISL_AUX_OP_PARTIAL_RESOLVE",
|
||||
[ISL_AUX_OP_AMBIGUATE ] = "ISL_AUX_OP_AMBIGUATE",
|
||||
}[op];
|
||||
}
|
||||
|
||||
#define E(state, usage, fc, op) \
|
||||
do { \
|
||||
if (ISL_AUX_OP_ ## op != ISL_AUX_OP_ASSERT) { \
|
||||
EXPECT_EQ(isl_aux_prepare_access(ISL_AUX_STATE_ ## state, \
|
||||
ISL_AUX_USAGE_ ## usage, fc), \
|
||||
ISL_AUX_OP_ ## op); \
|
||||
} else if (ASSERTS_ENABLED) { \
|
||||
EXPECT_DEATH(isl_aux_prepare_access(ISL_AUX_STATE_ ## state, \
|
||||
ISL_AUX_USAGE_ ## usage, fc), ""); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
TEST(PrepareAccess, CompressedFalseFastClearFalsePartialResolveFalse) {
|
||||
E(CLEAR, NONE, false, FULL_RESOLVE);
|
||||
E(CLEAR, NONE, true, ASSERT);
|
||||
E(PARTIAL_CLEAR, NONE, false, FULL_RESOLVE);
|
||||
E(PARTIAL_CLEAR, NONE, true, ASSERT);
|
||||
E(COMPRESSED_CLEAR, NONE, false, FULL_RESOLVE);
|
||||
E(COMPRESSED_CLEAR, NONE, true, ASSERT);
|
||||
E(COMPRESSED_NO_CLEAR, NONE, false, FULL_RESOLVE);
|
||||
E(COMPRESSED_NO_CLEAR, NONE, true, ASSERT);
|
||||
E(RESOLVED, NONE, false, NONE);
|
||||
E(RESOLVED, NONE, true, ASSERT);
|
||||
E(PASS_THROUGH, NONE, false, NONE);
|
||||
E(PASS_THROUGH, NONE, true, ASSERT);
|
||||
E(AUX_INVALID, NONE, false, NONE);
|
||||
E(AUX_INVALID, NONE, true, ASSERT);
|
||||
}
|
||||
|
||||
TEST(PrepareAccess, CompressedFalseFastClearTruePartialResolveFalse) {
|
||||
E(CLEAR, CCS_D, false, FULL_RESOLVE);
|
||||
E(CLEAR, CCS_D, true, NONE);
|
||||
E(PARTIAL_CLEAR, CCS_D, false, FULL_RESOLVE);
|
||||
E(PARTIAL_CLEAR, CCS_D, true, NONE);
|
||||
E(COMPRESSED_CLEAR, CCS_D, false, FULL_RESOLVE);
|
||||
E(COMPRESSED_CLEAR, CCS_D, true, FULL_RESOLVE);
|
||||
E(COMPRESSED_NO_CLEAR, CCS_D, false, FULL_RESOLVE);
|
||||
E(COMPRESSED_NO_CLEAR, CCS_D, true, FULL_RESOLVE);
|
||||
E(RESOLVED, CCS_D, false, NONE);
|
||||
E(RESOLVED, CCS_D, true, NONE);
|
||||
E(PASS_THROUGH, CCS_D, false, NONE);
|
||||
E(PASS_THROUGH, CCS_D, true, NONE);
|
||||
E(AUX_INVALID, CCS_D, false, AMBIGUATE);
|
||||
E(AUX_INVALID, CCS_D, true, AMBIGUATE);
|
||||
}
|
||||
|
||||
TEST(PrepareAccess, CompressedTrueFastClearFalsePartialResolveFalse) {
|
||||
E(CLEAR, MC, false, ASSERT);
|
||||
E(CLEAR, MC, true, ASSERT);
|
||||
E(PARTIAL_CLEAR, MC, false, ASSERT);
|
||||
E(PARTIAL_CLEAR, MC, true, ASSERT);
|
||||
E(COMPRESSED_CLEAR, MC, false, ASSERT);
|
||||
E(COMPRESSED_CLEAR, MC, true, ASSERT);
|
||||
E(COMPRESSED_NO_CLEAR, MC, false, NONE);
|
||||
E(COMPRESSED_NO_CLEAR, MC, true, ASSERT);
|
||||
E(RESOLVED, MC, false, NONE);
|
||||
E(RESOLVED, MC, true, ASSERT);
|
||||
E(PASS_THROUGH, MC, false, NONE);
|
||||
E(PASS_THROUGH, MC, true, ASSERT);
|
||||
E(AUX_INVALID, MC, false, AMBIGUATE);
|
||||
E(AUX_INVALID, MC, true, ASSERT);
|
||||
}
|
||||
|
||||
TEST(PrepareAccess, CompressedTrueFastClearTruePartialResolveFalse) {
|
||||
E(CLEAR, HIZ, false, FULL_RESOLVE);
|
||||
E(CLEAR, HIZ, true, NONE);
|
||||
E(PARTIAL_CLEAR, HIZ, false, FULL_RESOLVE);
|
||||
E(PARTIAL_CLEAR, HIZ, true, NONE);
|
||||
E(COMPRESSED_CLEAR, HIZ, false, FULL_RESOLVE);
|
||||
E(COMPRESSED_CLEAR, HIZ, true, NONE);
|
||||
E(COMPRESSED_NO_CLEAR, HIZ, false, NONE);
|
||||
E(COMPRESSED_NO_CLEAR, HIZ, true, NONE);
|
||||
E(RESOLVED, HIZ, false, NONE);
|
||||
E(RESOLVED, HIZ, true, NONE);
|
||||
E(PASS_THROUGH, HIZ, false, NONE);
|
||||
E(PASS_THROUGH, HIZ, true, NONE);
|
||||
E(AUX_INVALID, HIZ, false, AMBIGUATE);
|
||||
E(AUX_INVALID, HIZ, true, AMBIGUATE);
|
||||
}
|
||||
|
||||
TEST(PrepareAccess, CompressedTrueFastClearTruePartialResolveTrue) {
|
||||
E(CLEAR, MCS, false, PARTIAL_RESOLVE);
|
||||
E(CLEAR, MCS, true, NONE);
|
||||
E(PARTIAL_CLEAR, MCS, false, PARTIAL_RESOLVE);
|
||||
E(PARTIAL_CLEAR, MCS, true, NONE);
|
||||
E(COMPRESSED_CLEAR, MCS, false, PARTIAL_RESOLVE);
|
||||
E(COMPRESSED_CLEAR, MCS, true, NONE);
|
||||
E(COMPRESSED_NO_CLEAR, MCS, false, NONE);
|
||||
E(COMPRESSED_NO_CLEAR, MCS, true, NONE);
|
||||
E(RESOLVED, MCS, false, NONE);
|
||||
E(RESOLVED, MCS, true, NONE);
|
||||
E(PASS_THROUGH, MCS, false, NONE);
|
||||
E(PASS_THROUGH, MCS, true, NONE);
|
||||
E(AUX_INVALID, MCS, false, AMBIGUATE);
|
||||
E(AUX_INVALID, MCS, true, AMBIGUATE);
|
||||
}
|
||||
|
||||
void
|
||||
PrintTo(const enum isl_aux_state &state, ::std::ostream* os) {
|
||||
*os << (const char *[]) {
|
||||
[ISL_AUX_STATE_CLEAR ] = "ISL_AUX_STATE_CLEAR",
|
||||
[ISL_AUX_STATE_PARTIAL_CLEAR ] = "ISL_AUX_STATE_PARTIAL_CLEAR",
|
||||
[ISL_AUX_STATE_COMPRESSED_CLEAR ] = "ISL_AUX_STATE_COMPRESSED_CLEAR",
|
||||
[ISL_AUX_STATE_COMPRESSED_NO_CLEAR] = "ISL_AUX_STATE_COMPRESSED_NO_CLEAR",
|
||||
[ISL_AUX_STATE_RESOLVED ] = "ISL_AUX_STATE_RESOLVED",
|
||||
[ISL_AUX_STATE_PASS_THROUGH ] = "ISL_AUX_STATE_PASS_THROUGH",
|
||||
[ISL_AUX_STATE_AUX_INVALID ] = "ISL_AUX_STATE_AUX_INVALID"
|
||||
}[state];
|
||||
}
|
||||
|
||||
#undef E
|
||||
#define E(state1, usage, op, state2) \
|
||||
do { \
|
||||
if (ISL_AUX_STATE_ ## state2 != ISL_AUX_STATE_ASSERT) { \
|
||||
EXPECT_EQ(isl_aux_state_transition_aux_op(ISL_AUX_STATE_ ## state1, \
|
||||
ISL_AUX_USAGE_ ## usage, \
|
||||
ISL_AUX_OP_ ## op), \
|
||||
ISL_AUX_STATE_ ## state2); \
|
||||
} else if (ASSERTS_ENABLED) { \
|
||||
EXPECT_DEATH(isl_aux_state_transition_aux_op(ISL_AUX_STATE_ ## state1, \
|
||||
ISL_AUX_USAGE_ ## usage, \
|
||||
ISL_AUX_OP_ ## op), ""); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* The usages used in each test of this suite represent all combinations of
|
||||
* ::fast_clear and ::full_resolves_ambiguate.
|
||||
*/
|
||||
TEST(StateTransitionAuxOp, None) {
|
||||
E(CLEAR, NONE, NONE, ASSERT);
|
||||
E(PARTIAL_CLEAR, NONE, NONE, ASSERT);
|
||||
E(COMPRESSED_CLEAR, NONE, NONE, ASSERT);
|
||||
E(COMPRESSED_NO_CLEAR, NONE, NONE, ASSERT);
|
||||
E(RESOLVED, NONE, NONE, RESOLVED);
|
||||
E(PASS_THROUGH, NONE, NONE, PASS_THROUGH);
|
||||
E(AUX_INVALID, NONE, NONE, AUX_INVALID);
|
||||
|
||||
E(CLEAR, MC, NONE, ASSERT);
|
||||
E(PARTIAL_CLEAR, MC, NONE, ASSERT);
|
||||
E(COMPRESSED_CLEAR, MC, NONE, ASSERT);
|
||||
E(COMPRESSED_NO_CLEAR, MC, NONE, COMPRESSED_NO_CLEAR);
|
||||
E(RESOLVED, MC, NONE, RESOLVED);
|
||||
E(PASS_THROUGH, MC, NONE, PASS_THROUGH);
|
||||
E(AUX_INVALID, MC, NONE, AUX_INVALID);
|
||||
|
||||
E(CLEAR, HIZ, NONE, CLEAR);
|
||||
E(PARTIAL_CLEAR, HIZ, NONE, PARTIAL_CLEAR);
|
||||
E(COMPRESSED_CLEAR, HIZ, NONE, COMPRESSED_CLEAR);
|
||||
E(COMPRESSED_NO_CLEAR, HIZ, NONE, COMPRESSED_NO_CLEAR);
|
||||
E(RESOLVED, HIZ, NONE, RESOLVED);
|
||||
E(PASS_THROUGH, HIZ, NONE, PASS_THROUGH);
|
||||
E(AUX_INVALID, HIZ, NONE, AUX_INVALID);
|
||||
|
||||
E(CLEAR, CCS_E, NONE, CLEAR);
|
||||
E(PARTIAL_CLEAR, CCS_E, NONE, PARTIAL_CLEAR);
|
||||
E(COMPRESSED_CLEAR, CCS_E, NONE, COMPRESSED_CLEAR);
|
||||
E(COMPRESSED_NO_CLEAR, CCS_E, NONE, COMPRESSED_NO_CLEAR);
|
||||
E(RESOLVED, CCS_E, NONE, RESOLVED);
|
||||
E(PASS_THROUGH, CCS_E, NONE, PASS_THROUGH);
|
||||
E(AUX_INVALID, CCS_E, NONE, AUX_INVALID);
|
||||
}
|
||||
|
||||
TEST(StateTransitionAuxOp, FastClear) {
|
||||
E(CLEAR, NONE, FAST_CLEAR, ASSERT);
|
||||
E(PARTIAL_CLEAR, NONE, FAST_CLEAR, ASSERT);
|
||||
E(COMPRESSED_CLEAR, NONE, FAST_CLEAR, ASSERT);
|
||||
E(COMPRESSED_NO_CLEAR, NONE, FAST_CLEAR, ASSERT);
|
||||
E(RESOLVED, NONE, FAST_CLEAR, ASSERT);
|
||||
E(PASS_THROUGH, NONE, FAST_CLEAR, ASSERT);
|
||||
E(AUX_INVALID, NONE, FAST_CLEAR, ASSERT);
|
||||
|
||||
E(CLEAR, MC, FAST_CLEAR, ASSERT);
|
||||
E(PARTIAL_CLEAR, MC, FAST_CLEAR, ASSERT);
|
||||
E(COMPRESSED_CLEAR, MC, FAST_CLEAR, ASSERT);
|
||||
E(COMPRESSED_NO_CLEAR, MC, FAST_CLEAR, ASSERT);
|
||||
E(RESOLVED, MC, FAST_CLEAR, ASSERT);
|
||||
E(PASS_THROUGH, MC, FAST_CLEAR, ASSERT);
|
||||
E(AUX_INVALID, MC, FAST_CLEAR, ASSERT);
|
||||
|
||||
E(CLEAR, HIZ, FAST_CLEAR, CLEAR);
|
||||
E(PARTIAL_CLEAR, HIZ, FAST_CLEAR, CLEAR);
|
||||
E(COMPRESSED_CLEAR, HIZ, FAST_CLEAR, CLEAR);
|
||||
E(COMPRESSED_NO_CLEAR, HIZ, FAST_CLEAR, CLEAR);
|
||||
E(RESOLVED, HIZ, FAST_CLEAR, CLEAR);
|
||||
E(PASS_THROUGH, HIZ, FAST_CLEAR, CLEAR);
|
||||
E(AUX_INVALID, HIZ, FAST_CLEAR, CLEAR);
|
||||
|
||||
E(CLEAR, CCS_E, FAST_CLEAR, CLEAR);
|
||||
E(PARTIAL_CLEAR, CCS_E, FAST_CLEAR, CLEAR);
|
||||
E(COMPRESSED_CLEAR, CCS_E, FAST_CLEAR, CLEAR);
|
||||
E(COMPRESSED_NO_CLEAR, CCS_E, FAST_CLEAR, CLEAR);
|
||||
E(RESOLVED, CCS_E, FAST_CLEAR, CLEAR);
|
||||
E(PASS_THROUGH, CCS_E, FAST_CLEAR, CLEAR);
|
||||
E(AUX_INVALID, CCS_E, FAST_CLEAR, CLEAR);
|
||||
}
|
||||
|
||||
TEST(StateTransitionAuxOp, PartialResolve) {
|
||||
E(CLEAR, NONE, PARTIAL_RESOLVE, ASSERT);
|
||||
E(PARTIAL_CLEAR, NONE, PARTIAL_RESOLVE, ASSERT);
|
||||
E(COMPRESSED_CLEAR, NONE, PARTIAL_RESOLVE, ASSERT);
|
||||
E(COMPRESSED_NO_CLEAR, NONE, PARTIAL_RESOLVE, ASSERT);
|
||||
E(RESOLVED, NONE, PARTIAL_RESOLVE, ASSERT);
|
||||
E(PASS_THROUGH, NONE, PARTIAL_RESOLVE, ASSERT);
|
||||
E(AUX_INVALID, NONE, PARTIAL_RESOLVE, ASSERT);
|
||||
|
||||
E(CLEAR, MC, PARTIAL_RESOLVE, ASSERT);
|
||||
E(PARTIAL_CLEAR, MC, PARTIAL_RESOLVE, ASSERT);
|
||||
E(COMPRESSED_CLEAR, MC, PARTIAL_RESOLVE, ASSERT);
|
||||
E(COMPRESSED_NO_CLEAR, MC, PARTIAL_RESOLVE, ASSERT);
|
||||
E(RESOLVED, MC, PARTIAL_RESOLVE, ASSERT);
|
||||
E(PASS_THROUGH, MC, PARTIAL_RESOLVE, ASSERT);
|
||||
E(AUX_INVALID, MC, PARTIAL_RESOLVE, ASSERT);
|
||||
|
||||
E(CLEAR, HIZ, PARTIAL_RESOLVE, ASSERT);
|
||||
E(PARTIAL_CLEAR, HIZ, PARTIAL_RESOLVE, ASSERT);
|
||||
E(COMPRESSED_CLEAR, HIZ, PARTIAL_RESOLVE, ASSERT);
|
||||
E(COMPRESSED_NO_CLEAR, HIZ, PARTIAL_RESOLVE, ASSERT);
|
||||
E(RESOLVED, HIZ, PARTIAL_RESOLVE, ASSERT);
|
||||
E(PASS_THROUGH, HIZ, PARTIAL_RESOLVE, ASSERT);
|
||||
E(AUX_INVALID, HIZ, PARTIAL_RESOLVE, ASSERT);
|
||||
|
||||
E(CLEAR, CCS_E, PARTIAL_RESOLVE, COMPRESSED_NO_CLEAR);
|
||||
E(PARTIAL_CLEAR, CCS_E, PARTIAL_RESOLVE, COMPRESSED_NO_CLEAR);
|
||||
E(COMPRESSED_CLEAR, CCS_E, PARTIAL_RESOLVE, COMPRESSED_NO_CLEAR);
|
||||
E(COMPRESSED_NO_CLEAR, CCS_E, PARTIAL_RESOLVE, COMPRESSED_NO_CLEAR);
|
||||
E(RESOLVED, CCS_E, PARTIAL_RESOLVE, RESOLVED);
|
||||
E(PASS_THROUGH, CCS_E, PARTIAL_RESOLVE, PASS_THROUGH);
|
||||
E(AUX_INVALID, CCS_E, PARTIAL_RESOLVE, ASSERT);
|
||||
}
|
||||
|
||||
TEST(StateTransitionAuxOp, FullResolve) {
|
||||
E(CLEAR, NONE, FULL_RESOLVE, ASSERT);
|
||||
E(PARTIAL_CLEAR, NONE, FULL_RESOLVE, ASSERT);
|
||||
E(COMPRESSED_CLEAR, NONE, FULL_RESOLVE, ASSERT);
|
||||
E(COMPRESSED_NO_CLEAR, NONE, FULL_RESOLVE, ASSERT);
|
||||
E(RESOLVED, NONE, FULL_RESOLVE, ASSERT);
|
||||
E(PASS_THROUGH, NONE, FULL_RESOLVE, ASSERT);
|
||||
E(AUX_INVALID, NONE, FULL_RESOLVE, ASSERT);
|
||||
|
||||
E(CLEAR, MC, FULL_RESOLVE, ASSERT);
|
||||
E(PARTIAL_CLEAR, MC, FULL_RESOLVE, ASSERT);
|
||||
E(COMPRESSED_CLEAR, MC, FULL_RESOLVE, ASSERT);
|
||||
E(COMPRESSED_NO_CLEAR, MC, FULL_RESOLVE, PASS_THROUGH);
|
||||
E(RESOLVED, MC, FULL_RESOLVE, PASS_THROUGH);
|
||||
E(PASS_THROUGH, MC, FULL_RESOLVE, PASS_THROUGH);
|
||||
E(AUX_INVALID, MC, FULL_RESOLVE, ASSERT);
|
||||
|
||||
E(CLEAR, HIZ, FULL_RESOLVE, RESOLVED);
|
||||
E(PARTIAL_CLEAR, HIZ, FULL_RESOLVE, RESOLVED);
|
||||
E(COMPRESSED_CLEAR, HIZ, FULL_RESOLVE, RESOLVED);
|
||||
E(COMPRESSED_NO_CLEAR, HIZ, FULL_RESOLVE, RESOLVED);
|
||||
E(RESOLVED, HIZ, FULL_RESOLVE, RESOLVED);
|
||||
E(PASS_THROUGH, HIZ, FULL_RESOLVE, PASS_THROUGH);
|
||||
E(AUX_INVALID, HIZ, FULL_RESOLVE, ASSERT);
|
||||
|
||||
E(CLEAR, CCS_E, FULL_RESOLVE, PASS_THROUGH);
|
||||
E(PARTIAL_CLEAR, CCS_E, FULL_RESOLVE, PASS_THROUGH);
|
||||
E(COMPRESSED_CLEAR, CCS_E, FULL_RESOLVE, PASS_THROUGH);
|
||||
E(COMPRESSED_NO_CLEAR, CCS_E, FULL_RESOLVE, PASS_THROUGH);
|
||||
E(RESOLVED, CCS_E, FULL_RESOLVE, PASS_THROUGH);
|
||||
E(PASS_THROUGH, CCS_E, FULL_RESOLVE, PASS_THROUGH);
|
||||
E(AUX_INVALID, CCS_E, FULL_RESOLVE, ASSERT);
|
||||
}
|
||||
|
||||
TEST(StateTransitionAuxOp, Ambiguate) {
|
||||
E(CLEAR, NONE, AMBIGUATE, ASSERT);
|
||||
E(PARTIAL_CLEAR, NONE, AMBIGUATE, ASSERT);
|
||||
E(COMPRESSED_CLEAR, NONE, AMBIGUATE, ASSERT);
|
||||
E(COMPRESSED_NO_CLEAR, NONE, AMBIGUATE, ASSERT);
|
||||
E(RESOLVED, NONE, AMBIGUATE, ASSERT);
|
||||
E(PASS_THROUGH, NONE, AMBIGUATE, ASSERT);
|
||||
E(AUX_INVALID, NONE, AMBIGUATE, ASSERT);
|
||||
|
||||
E(CLEAR, MC, AMBIGUATE, ASSERT);
|
||||
E(PARTIAL_CLEAR, MC, AMBIGUATE, ASSERT);
|
||||
E(COMPRESSED_CLEAR, MC, AMBIGUATE, ASSERT);
|
||||
E(COMPRESSED_NO_CLEAR, MC, AMBIGUATE, PASS_THROUGH);
|
||||
E(RESOLVED, MC, AMBIGUATE, PASS_THROUGH);
|
||||
E(PASS_THROUGH, MC, AMBIGUATE, PASS_THROUGH);
|
||||
E(AUX_INVALID, MC, AMBIGUATE, PASS_THROUGH);
|
||||
|
||||
E(CLEAR, HIZ, AMBIGUATE, PASS_THROUGH);
|
||||
E(PARTIAL_CLEAR, HIZ, AMBIGUATE, PASS_THROUGH);
|
||||
E(COMPRESSED_CLEAR, HIZ, AMBIGUATE, PASS_THROUGH);
|
||||
E(COMPRESSED_NO_CLEAR, HIZ, AMBIGUATE, PASS_THROUGH);
|
||||
E(RESOLVED, HIZ, AMBIGUATE, PASS_THROUGH);
|
||||
E(PASS_THROUGH, HIZ, AMBIGUATE, PASS_THROUGH);
|
||||
E(AUX_INVALID, HIZ, AMBIGUATE, PASS_THROUGH);
|
||||
|
||||
E(CLEAR, CCS_E, AMBIGUATE, PASS_THROUGH);
|
||||
E(PARTIAL_CLEAR, CCS_E, AMBIGUATE, PASS_THROUGH);
|
||||
E(COMPRESSED_CLEAR, CCS_E, AMBIGUATE, PASS_THROUGH);
|
||||
E(COMPRESSED_NO_CLEAR, CCS_E, AMBIGUATE, PASS_THROUGH);
|
||||
E(RESOLVED, CCS_E, AMBIGUATE, PASS_THROUGH);
|
||||
E(PASS_THROUGH, CCS_E, AMBIGUATE, PASS_THROUGH);
|
||||
E(AUX_INVALID, CCS_E, AMBIGUATE, PASS_THROUGH);
|
||||
}
|
||||
|
||||
#undef E
|
||||
#define E(state1, usage, full_surface, state2) \
|
||||
do { \
|
||||
if (ISL_AUX_STATE_ ## state2 != ISL_AUX_STATE_ASSERT) { \
|
||||
EXPECT_EQ(isl_aux_state_transition_write(ISL_AUX_STATE_ ## state1, \
|
||||
ISL_AUX_USAGE_ ## usage, \
|
||||
full_surface), \
|
||||
ISL_AUX_STATE_ ## state2); \
|
||||
} else if (ASSERTS_ENABLED) { \
|
||||
EXPECT_DEATH(isl_aux_state_transition_write(ISL_AUX_STATE_ ## state1, \
|
||||
ISL_AUX_USAGE_ ## usage, \
|
||||
full_surface), ""); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
TEST(StateTransitionWrite, WritesOnlyTouchMain) {
|
||||
E(CLEAR, NONE, false, ASSERT);
|
||||
E(CLEAR, NONE, true, AUX_INVALID);
|
||||
E(PARTIAL_CLEAR, NONE, false, ASSERT);
|
||||
E(PARTIAL_CLEAR, NONE, true, AUX_INVALID);
|
||||
E(COMPRESSED_CLEAR, NONE, false, ASSERT);
|
||||
E(COMPRESSED_CLEAR, NONE, true, AUX_INVALID);
|
||||
E(COMPRESSED_NO_CLEAR, NONE, false, ASSERT);
|
||||
E(COMPRESSED_NO_CLEAR, NONE, true, AUX_INVALID);
|
||||
E(RESOLVED, NONE, false, AUX_INVALID);
|
||||
E(RESOLVED, NONE, true, AUX_INVALID);
|
||||
E(PASS_THROUGH, NONE, false, PASS_THROUGH);
|
||||
E(PASS_THROUGH, NONE, true, PASS_THROUGH);
|
||||
E(AUX_INVALID, NONE, false, AUX_INVALID);
|
||||
E(AUX_INVALID, NONE, true, AUX_INVALID);
|
||||
}
|
||||
|
||||
TEST(StateTransitionWrite, WritesCompress) {
|
||||
E(CLEAR, MCS, false, COMPRESSED_CLEAR);
|
||||
E(CLEAR, MCS, true, COMPRESSED_NO_CLEAR);
|
||||
E(PARTIAL_CLEAR, MCS, false, COMPRESSED_CLEAR);
|
||||
E(PARTIAL_CLEAR, MCS, true, COMPRESSED_NO_CLEAR);
|
||||
E(COMPRESSED_CLEAR, MCS, false, COMPRESSED_CLEAR);
|
||||
E(COMPRESSED_CLEAR, MCS, true, COMPRESSED_NO_CLEAR);
|
||||
E(COMPRESSED_NO_CLEAR, MCS, false, COMPRESSED_NO_CLEAR);
|
||||
E(COMPRESSED_NO_CLEAR, MCS, true, COMPRESSED_NO_CLEAR);
|
||||
E(RESOLVED, MCS, false, COMPRESSED_NO_CLEAR);
|
||||
E(RESOLVED, MCS, true, COMPRESSED_NO_CLEAR);
|
||||
E(PASS_THROUGH, MCS, false, COMPRESSED_NO_CLEAR);
|
||||
E(PASS_THROUGH, MCS, true, COMPRESSED_NO_CLEAR);
|
||||
E(AUX_INVALID, MCS, false, ASSERT);
|
||||
E(AUX_INVALID, MCS, true, ASSERT);
|
||||
}
|
||||
|
||||
TEST(StateTransitionWrite, WritesResolveAmbiguate) {
|
||||
E(CLEAR, CCS_D, false, PARTIAL_CLEAR);
|
||||
E(CLEAR, CCS_D, true, PASS_THROUGH);
|
||||
E(PARTIAL_CLEAR, CCS_D, false, PARTIAL_CLEAR);
|
||||
E(PARTIAL_CLEAR, CCS_D, true, PASS_THROUGH);
|
||||
E(COMPRESSED_CLEAR, CCS_D, false, ASSERT);
|
||||
E(COMPRESSED_CLEAR, CCS_D, true, ASSERT);
|
||||
E(COMPRESSED_NO_CLEAR, CCS_D, false, ASSERT);
|
||||
E(COMPRESSED_NO_CLEAR, CCS_D, true, ASSERT);
|
||||
E(RESOLVED, CCS_D, false, RESOLVED);
|
||||
E(RESOLVED, CCS_D, true, PASS_THROUGH);
|
||||
E(PASS_THROUGH, CCS_D, false, PASS_THROUGH);
|
||||
E(PASS_THROUGH, CCS_D, true, PASS_THROUGH);
|
||||
E(AUX_INVALID, CCS_D, false, ASSERT);
|
||||
E(AUX_INVALID, CCS_D, true, ASSERT);
|
||||
|
||||
E(CLEAR, MC, false, ASSERT);
|
||||
E(CLEAR, MC, true, ASSERT);
|
||||
E(PARTIAL_CLEAR, MC, false, ASSERT);
|
||||
E(PARTIAL_CLEAR, MC, true, ASSERT);
|
||||
E(COMPRESSED_CLEAR, MC, false, ASSERT);
|
||||
E(COMPRESSED_CLEAR, MC, true, ASSERT);
|
||||
E(COMPRESSED_NO_CLEAR, MC, false, COMPRESSED_NO_CLEAR);
|
||||
E(COMPRESSED_NO_CLEAR, MC, true, PASS_THROUGH);
|
||||
E(RESOLVED, MC, false, RESOLVED);
|
||||
E(RESOLVED, MC, true, PASS_THROUGH);
|
||||
E(PASS_THROUGH, MC, false, PASS_THROUGH);
|
||||
E(PASS_THROUGH, MC, true, PASS_THROUGH);
|
||||
E(AUX_INVALID, MC, false, ASSERT);
|
||||
E(AUX_INVALID, MC, true, ASSERT);
|
||||
}
|
||||
|
||||
#undef E
|
||||
Loading…
Add table
Reference in a new issue