X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Futil%2Fmacros.h;h=57beaf72fae31f8f4bfba7cafb7e2ef33c31b057;hb=848e7b947d0d505d54d27780b052e5532c721678;hp=5c5c92ec610ebac9dcce2d7e5e9164306e67f313;hpb=be1f49bda90425b7fd009ac177b307e61da0f994;p=mesa.git diff --git a/src/util/macros.h b/src/util/macros.h index 5c5c92ec610..57beaf72fae 100644 --- a/src/util/macros.h +++ b/src/util/macros.h @@ -24,9 +24,14 @@ #ifndef UTIL_MACROS_H #define UTIL_MACROS_H +#include + +#include "c99_compat.h" +#include "c11_compat.h" + /* Compute the size of an array */ #ifndef ARRAY_SIZE -# define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x))) +# define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) #endif /* For compatibility with Clang's __has_builtin() */ @@ -67,7 +72,7 @@ * Unreachable macro. Useful for suppressing "control reaches end of non-void * function" warnings. */ -#ifdef HAVE___BUILTIN_UNREACHABLE +#if defined(HAVE___BUILTIN_UNREACHABLE) || __has_builtin(__builtin_unreachable) #define unreachable(str) \ do { \ assert(!str); \ @@ -132,6 +137,18 @@ do { \ #define MALLOCLIKE #endif +/* Forced function inlining */ +/* Note: Clang also sets __GNUC__ (see other cases below) */ +#ifndef ALWAYS_INLINE +# if defined(__GNUC__) +# define ALWAYS_INLINE inline __attribute__((always_inline)) +# elif defined(_MSC_VER) +# define ALWAYS_INLINE __forceinline +# else +# define ALWAYS_INLINE inline +# endif +#endif + /* Used to optionally mark structures with misaligned elements or size as * packed, to trade off performance for space. */ @@ -145,9 +162,25 @@ do { \ * return value. As a result, calls to it can be dead code eliminated. */ #ifdef HAVE_FUNC_ATTRIBUTE_PURE -#define PURE __attribute__((__pure__)) +#define ATTRIBUTE_PURE __attribute__((__pure__)) #else -#define PURE +#define ATTRIBUTE_PURE +#endif + +#ifdef HAVE_FUNC_ATTRIBUTE_RETURNS_NONNULL +#define ATTRIBUTE_RETURNS_NONNULL __attribute__((__returns_nonnull__)) +#else +#define ATTRIBUTE_RETURNS_NONNULL +#endif + +#ifndef NORETURN +# ifdef _MSC_VER +# define NORETURN __declspec(noreturn) +# elif defined HAVE_FUNC_ATTRIBUTE_NORETURN +# define NORETURN __attribute__((__noreturn__)) +# else +# define NORETURN +# endif #endif #ifdef __cplusplus @@ -157,14 +190,16 @@ do { \ * performs no action and all member variables and base classes are * trivially destructible themselves. */ -# if defined(__GNUC__) -# if ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3))) +# if (defined(__clang__) && defined(__has_feature)) +# if __has_feature(has_trivial_destructor) # define HAS_TRIVIAL_DESTRUCTOR(T) __has_trivial_destructor(T) # endif -# elif (defined(__clang__) && defined(__has_feature)) -# if __has_feature(has_trivial_destructor) +# elif defined(__GNUC__) +# if ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3))) # define HAS_TRIVIAL_DESTRUCTOR(T) __has_trivial_destructor(T) # endif +# elif defined(_MSC_VER) && !defined(__INTEL_COMPILER) +# define HAS_TRIVIAL_DESTRUCTOR(T) __has_trivial_destructor(T) # endif # ifndef HAS_TRIVIAL_DESTRUCTOR /* It's always safe (if inefficient) to assume that a @@ -184,7 +219,7 @@ do { \ * inline a static function that we later use in an alias. - ajax */ #ifndef PUBLIC -# if defined(__GNUC__) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) +# if defined(__GNUC__) # define PUBLIC __attribute__((visibility("default"))) # define USED __attribute__((used)) # elif defined(_MSC_VER) @@ -196,19 +231,122 @@ do { \ # endif #endif +/** + * UNUSED marks variables (or sometimes functions) that have to be defined, + * but are sometimes (or always) unused beyond that. A common case is for + * a function parameter to be used in some build configurations but not others. + * Another case is fallback vfuncs that don't do anything with their params. + * + * Note that this should not be used for identifiers used in `assert()`; + * see ASSERTED below. + */ #ifdef HAVE_FUNC_ATTRIBUTE_UNUSED #define UNUSED __attribute__((unused)) #else #define UNUSED #endif +/** + * Use ASSERTED to indicate that an identifier is unused outside of an `assert()`, + * so that assert-free builds don't get "unused variable" warnings. + */ +#ifdef NDEBUG +#define ASSERTED UNUSED +#else +#define ASSERTED +#endif + #ifdef HAVE_FUNC_ATTRIBUTE_WARN_UNUSED_RESULT #define MUST_CHECK __attribute__((warn_unused_result)) #else #define MUST_CHECK #endif +#if defined(__GNUC__) +#define ATTRIBUTE_NOINLINE __attribute__((noinline)) +#else +#define ATTRIBUTE_NOINLINE +#endif + + +/** + * Check that STRUCT::FIELD can hold MAXVAL. We use a lot of bitfields + * in Mesa/gallium. We have to be sure they're of sufficient size to + * hold the largest expected value. + * Note that with MSVC, enums are signed and enum bitfields need one extra + * high bit (always zero) to ensure the max value is handled correctly. + * This macro will detect that with MSVC, but not GCC. + */ +#define ASSERT_BITFIELD_SIZE(STRUCT, FIELD, MAXVAL) \ + do { \ + ASSERTED STRUCT s; \ + s.FIELD = (MAXVAL); \ + assert((int) s.FIELD == (MAXVAL) && "Insufficient bitfield size!"); \ + } while (0) + + /** Compute ceiling of integer quotient of A divided by B. */ -#define DIV_ROUND_UP( A, B ) ( (A) % (B) == 0 ? (A)/(B) : (A)/(B)+1 ) +#define DIV_ROUND_UP( A, B ) ( ((A) + (B) - 1) / (B) ) + +/** Clamp X to [MIN,MAX]. Turn NaN into MIN, arbitrarily. */ +#define CLAMP( X, MIN, MAX ) ( (X)>(MIN) ? ((X)>(MAX) ? (MAX) : (X)) : (MIN) ) + +/* Syntax sugar occuring frequently in graphics code */ +#define SATURATE( X ) CLAMP(X, 0.0f, 1.0f) + +/** Minimum of two values: */ +#define MIN2( A, B ) ( (A)<(B) ? (A) : (B) ) + +/** Maximum of two values: */ +#define MAX2( A, B ) ( (A)>(B) ? (A) : (B) ) + +/** Minimum and maximum of three values: */ +#define MIN3( A, B, C ) ((A) < (B) ? MIN2(A, C) : MIN2(B, C)) +#define MAX3( A, B, C ) ((A) > (B) ? MAX2(A, C) : MAX2(B, C)) + +/** Align a value to a power of two */ +#define ALIGN_POT(x, pot_align) (((x) + (pot_align) - 1) & ~((pot_align) - 1)) + +/** + * Macro for declaring an explicit conversion operator. Defaults to an + * implicit conversion if C++11 is not supported. + */ +#if __cplusplus >= 201103L +#define EXPLICIT_CONVERSION explicit +#elif defined(__cplusplus) +#define EXPLICIT_CONVERSION +#endif + +/** Set a single bit */ +#define BITFIELD_BIT(b) (1u << (b)) +/** Set all bits up to excluding bit b */ +#define BITFIELD_MASK(b) \ + ((b) == 32 ? (~0u) : BITFIELD_BIT((b) % 32) - 1) +/** Set count bits starting from bit b */ +#define BITFIELD_RANGE(b, count) \ + (BITFIELD_MASK((b) + (count)) & ~BITFIELD_MASK(b)) + +/** Set a single bit */ +#define BITFIELD64_BIT(b) (1ull << (b)) +/** Set all bits up to excluding bit b */ +#define BITFIELD64_MASK(b) \ + ((b) == 64 ? (~0ull) : BITFIELD64_BIT(b) - 1) +/** Set count bits starting from bit b */ +#define BITFIELD64_RANGE(b, count) \ + (BITFIELD64_MASK((b) + (count)) & ~BITFIELD64_MASK(b)) + +/* TODO: In future we should try to move this to u_debug.h once header + * dependencies are reorganised to allow this. + */ +enum pipe_debug_type +{ + PIPE_DEBUG_TYPE_OUT_OF_MEMORY = 1, + PIPE_DEBUG_TYPE_ERROR, + PIPE_DEBUG_TYPE_SHADER_INFO, + PIPE_DEBUG_TYPE_PERF_INFO, + PIPE_DEBUG_TYPE_INFO, + PIPE_DEBUG_TYPE_FALLBACK, + PIPE_DEBUG_TYPE_CONFORMANCE, +}; #endif /* UTIL_MACROS_H */