mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-28 20:48:13 +02:00
In the C23 standard unreachable() is now a predefined function-like macro in <stddef.h> See https://android.googlesource.com/platform/bionic/+/HEAD/docs/c23.md#is-now-a-predefined-function_like-macro-in And this causes build errors when building for C23: ----------------------------------------------------------------------- In file included from ../src/util/log.h:30, from ../src/util/log.c:30: ../src/util/macros.h:123:9: warning: "unreachable" redefined 123 | #define unreachable(str) \ | ^~~~~~~~~~~ In file included from ../src/util/macros.h:31: /usr/lib/gcc/x86_64-linux-gnu/14/include/stddef.h:456:9: note: this is the location of the previous definition 456 | #define unreachable() (__builtin_unreachable ()) | ^~~~~~~~~~~ ----------------------------------------------------------------------- So don't redefine it with the same name, but use the name UNREACHABLE() to also signify it's a macro. Using a different name also makes sense because the behavior of the macro was extending the one of __builtin_unreachable() anyway, and it also had a different signature, accepting one argument, compared to the standard unreachable() with no arguments. This change improves the chances of building mesa with the C23 standard, which for instance is the default in recent AOSP versions. All the instances of the macro, including the definition, were updated with the following command line: git grep -l '[^_]unreachable(' -- "src/**" | sort | uniq | \ while read file; \ do \ sed -e 's/\([^_]\)unreachable(/\1UNREACHABLE(/g' -i "$file"; \ done && \ sed -e 's/#undef unreachable/#undef UNREACHABLE/g' -i src/intel/isl/isl_aux_info.c Reviewed-by: Erik Faye-Lund <erik.faye-lund@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/36437>
165 lines
4.9 KiB
C
165 lines
4.9 KiB
C
/*
|
|
* Copyright 2016 Intel Corporation
|
|
* Copyright 2016 Broadcom
|
|
* Copyright 2020 Collabora, Ltd.
|
|
* Copyright 2024 Alyssa Rosenzweig
|
|
* SPDX-License-Identifier: MIT
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include "compiler/libcl/libcl.h"
|
|
#include "util/bitpack_helpers.h"
|
|
|
|
#ifndef __OPENCL_VERSION__
|
|
#include <inttypes.h>
|
|
#include <stdio.h>
|
|
#include "util/half_float.h"
|
|
#endif
|
|
|
|
#define __gen_unpack_float(x, y, z) uif(__gen_unpack_uint(x, y, z))
|
|
#define __gen_unpack_half(x, y, z) \
|
|
_mesa_half_to_float(__gen_unpack_uint(x, y, z))
|
|
|
|
static inline uint64_t
|
|
__gen_unpack_uint(CONST uint32_t *restrict cl, uint32_t start, uint32_t end)
|
|
{
|
|
uint64_t val = 0;
|
|
const int width = end - start + 1;
|
|
const uint64_t mask =
|
|
(width == 64) ? ~((uint64_t)0) : ((uint64_t)1 << width) - 1;
|
|
|
|
for (unsigned word = start / 32; word < (end / 32) + 1; word++) {
|
|
val |= ((uint64_t)cl[word]) << ((word - start / 32) * 32);
|
|
}
|
|
|
|
return (val >> (start % 32)) & mask;
|
|
}
|
|
|
|
/*
|
|
* LODs are 4:6 fixed point. We must clamp before converting to integers to
|
|
* avoid undefined behaviour for out-of-bounds inputs like +/- infinity.
|
|
*/
|
|
static inline uint32_t
|
|
__gen_pack_lod(float f, uint32_t start, uint32_t end)
|
|
{
|
|
uint32_t fixed = CLAMP(f * (1 << 6), 0 /* 0.0 */, 0x380 /* 14.0 */);
|
|
return util_bitpack_uint(fixed, start, end);
|
|
}
|
|
|
|
static inline float
|
|
__gen_unpack_lod(CONST uint32_t *restrict cl, uint32_t start, uint32_t end)
|
|
{
|
|
return ((float)__gen_unpack_uint(cl, start, end)) / (1 << 6);
|
|
}
|
|
|
|
static inline uint64_t
|
|
__gen_unpack_sint(CONST uint32_t *restrict cl, uint32_t start, uint32_t end)
|
|
{
|
|
int size = end - start + 1;
|
|
int64_t val = __gen_unpack_uint(cl, start, end);
|
|
|
|
return util_sign_extend(val, size);
|
|
}
|
|
|
|
static inline uint64_t
|
|
__gen_to_groups(uint32_t value, uint32_t group_size, uint32_t length)
|
|
{
|
|
/* Zero is not representable, clamp to minimum */
|
|
if (value == 0)
|
|
return 1;
|
|
|
|
/* Round up to the nearest number of groups */
|
|
uint32_t groups = DIV_ROUND_UP(value, group_size);
|
|
|
|
/* The 0 encoding means "all" */
|
|
if (groups == ((uint64_t)1) << length)
|
|
return 0;
|
|
|
|
/* Otherwise it's encoded as the identity */
|
|
assert(groups < (1u << length) && "out of bounds");
|
|
assert(groups >= 1 && "exhaustive");
|
|
return groups;
|
|
}
|
|
|
|
static inline uint64_t
|
|
__gen_from_groups(uint32_t value, uint32_t group_size, uint32_t length)
|
|
{
|
|
return group_size * (value ? value : (1 << length));
|
|
}
|
|
|
|
#define agx_pack(dst, T, name) \
|
|
for (struct AGX_##T name = {AGX_##T##_header}, \
|
|
*_loop_count = (GLOBAL void *)((uintptr_t)0); \
|
|
(uintptr_t)_loop_count < 1; ( \
|
|
{ \
|
|
AGX_##T##_pack((GLOBAL uint32_t *)(dst), &name); \
|
|
_loop_count = (GLOBAL void *)(((uintptr_t)_loop_count) + 1); \
|
|
}))
|
|
|
|
#define agx_unpack(fp, src, T, name) \
|
|
struct AGX_##T name; \
|
|
AGX_##T##_unpack(fp, (CONST uint8_t *)(src), &name)
|
|
|
|
#define agx_print(fp, T, var, indent) AGX_##T##_print(fp, &(var), indent)
|
|
|
|
static inline void
|
|
agx_merge_helper(uint32_t *dst, const uint32_t *src, size_t bytes)
|
|
{
|
|
assert((bytes & 3) == 0);
|
|
|
|
for (unsigned i = 0; i < (bytes / 4); ++i)
|
|
dst[i] |= src[i];
|
|
}
|
|
|
|
#define agx_merge(packed1, packed2, type) \
|
|
agx_merge_helper((packed1).opaque, (packed2).opaque, AGX_##type##_LENGTH)
|
|
|
|
#if defined(NDEBUG) || defined(__OPENCL_VERSION__)
|
|
#define agx_genxml_validate_bounds(a, b, c)
|
|
#define agx_genxml_validate_mask(a, b, c, d, e) true
|
|
#define agx_genxml_validate_exact(a, b, c, d) true
|
|
#else
|
|
static inline void
|
|
agx_genxml_validate_bounds(const char *name, uint64_t value, uint64_t bound)
|
|
{
|
|
if (unlikely(value >= bound)) {
|
|
fprintf(stderr, "%s out-of-bounds, got 0x%" PRIx64 ", max %" PRIx64 "\n",
|
|
name, value, bound);
|
|
|
|
UNREACHABLE("Out-of-bounds pack");
|
|
}
|
|
}
|
|
|
|
static inline bool
|
|
agx_genxml_validate_mask(FILE *fp, const char *name, const void *cl_,
|
|
uint32_t index, uint32_t bad_mask)
|
|
{
|
|
const uint32_t *cl = (const uint32_t *)cl_;
|
|
uint32_t bad = cl[index] & bad_mask;
|
|
|
|
if (bad && fp != NULL) {
|
|
fprintf(
|
|
fp,
|
|
"XXX: Unknown field of %s unpacked at word %u got %X, bad mask %X\n",
|
|
name, index, cl[index], bad);
|
|
}
|
|
|
|
return bad == 0;
|
|
}
|
|
|
|
static bool
|
|
agx_genxml_validate_exact(FILE *fp, const char *name, uint64_t value,
|
|
uint64_t exact)
|
|
{
|
|
if (value != exact && fp != NULL) {
|
|
fprintf(fp, "XXX: Expected %s to equal %" PRIx64 " but got %" PRIx64 "\n",
|
|
name, value, exact);
|
|
}
|
|
|
|
return value == exact;
|
|
}
|
|
|
|
#endif
|
|
|
|
/* Everything after this is autogenerated from XML. Do not hand edit. */
|