util: add u_tristate data structure

rip the pan_tristate enum from panfrost and move it to common.

I've often wanted some sort of "yes/no/maybe" or "true/false/unknown" or
"always/never/sometimes" data structure. This adds a common one that is
hopefully neutral enough to cover all of the above.

Asahi will use this.

The Intel drivers could be ported to this (brw_sometimes/elk_sometimes), it
should be straightforward but I don't want to do that without being able to
easily test those changes.

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Reviewed-by: Eric Engestrom <eric@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/32224>
This commit is contained in:
Alyssa Rosenzweig 2024-11-19 12:18:06 -04:00 committed by Marge Bot
parent 1cf5ae4854
commit 847e0e78f8
2 changed files with 73 additions and 0 deletions

View file

@ -153,6 +153,7 @@ files_mesa_util = files(
'u_cpu_detect.h',
'u_printf.c',
'u_printf.h',
'u_tristate.h',
'u_worklist.c',
'u_worklist.h',
'vl_vlc.h',

72
src/util/u_tristate.h Normal file
View file

@ -0,0 +1,72 @@
/*
* Copyright 2024 Valve Corporation
* Copyright 2022 Collabora Ltd
* SPDX-License-Identifier: MIT
*/
#include "util/macros.h"
#include <stdbool.h>
#ifndef U_TRISTATE_H
#define U_TRISTATE_H
/*
* Simple tri-state data structure.
*
* The tri-state can be set to a boolean or unset. The semantics of "unset"
* depend on the application, it could be either "don't care" or "maybe".
*/
enum u_tristate {
U_TRISTATE_UNSET,
U_TRISTATE_NO,
U_TRISTATE_YES,
};
/*
* Construct a tristate from an immediate value.
*/
static inline enum u_tristate
u_tristate_make(bool value)
{
return value ? U_TRISTATE_YES : U_TRISTATE_NO;
}
/*
* Try to set a tristate value to a specific boolean value, returning whether
* the operation is successful.
*/
static inline bool
u_tristate_set(enum u_tristate *state, bool value)
{
switch (*state) {
case U_TRISTATE_UNSET:
*state = u_tristate_make(value);
return true;
case U_TRISTATE_NO:
return (value == false);
case U_TRISTATE_YES:
return (value == true);
default:
unreachable("Invalid tristate value");
}
}
/*
* Invert a tristate, returning the new value.
*/
static inline enum u_tristate
u_tristate_invert(enum u_tristate tri)
{
switch (tri) {
case U_TRISTATE_UNSET: return U_TRISTATE_UNSET;
case U_TRISTATE_YES: return U_TRISTATE_NO;
case U_TRISTATE_NO: return U_TRISTATE_YES;
}
unreachable("invalid tristate");
}
#endif