mesa/src/panfrost/genxml/pan_pack_helpers.h
Mary Guillemard 455b93601a
Some checks are pending
macOS-CI / macOS-CI (dri) (push) Waiting to run
macOS-CI / macOS-CI (xlib) (push) Waiting to run
pan/genxml: Add missing parenthesis on pan_cast_and_pack macros
We were missing parenthesis on pan_cast_and_pack macros causing various
issues.

Signed-off-by: Mary Guillemard <mary.guillemard@collabora.com>
Fixes: 410e5a36ec ("pan/genxml: Rework gen_pack.py to support OpenCL")
Reviewed-by: Erik Faye-Lund <erik.faye-lund@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/36261>
2025-07-21 16:32:51 +00:00

181 lines
8 KiB
C

/*
* Copyright 2024 Collabora Ltd.
* SPDX-License-Identifier: MIT
*/
#ifndef PAN_PACK_HELPERS_H
#define PAN_PACK_HELPERS_H
#include "compiler/libcl/libcl.h"
#include "util/bitpack_helpers.h"
#ifndef __OPENCL_VERSION__
#include <inttypes.h>
#include <stdio.h>
#endif
#ifdef __OPENCL_VERSION__
#define fprintf(...) \
do { \
} while (0)
#endif
static inline uint32_t
__gen_padded(uint32_t v, uint32_t start, uint32_t end)
{
unsigned shift = __builtin_ctz(v);
unsigned odd = v >> (shift + 1);
#ifndef NDEBUG
assert((v >> shift) & 1);
assert(shift <= 31);
assert(odd <= 7);
assert((end - start + 1) == 8);
#endif
return util_bitpack_uint(shift | (odd << 5), start, end);
}
#define __gen_unpack_uint(out, cl, start, end) \
do { \
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); \
} \
\
(out) = (__val >> ((start) % 32)) & __mask; \
} while (0)
#define __gen_unpack_sint(out, cl, start, end) \
do { \
int size = (end) - (start) + 1; \
int64_t __tmp_sint; \
__gen_unpack_uint(__tmp_sint, cl, start, end); \
(out) = util_sign_extend(__tmp_sint, size); \
} while (0)
#define __gen_unpack_ulod(out, cl, start, end) \
do { \
uint32_t __tmp_ulod; \
__gen_unpack_uint(__tmp_ulod, cl, start, end); \
(out) = ((float)__tmp_ulod) / 256.0; \
} while (0)
#define __gen_unpack_slod(out, cl, start, end) \
do { \
int32_t __tmp_slod; \
__gen_unpack_sint(__tmp_slod, cl, start, end); \
(out) = ((float)__tmp_slod) / 256.0; \
} while (0)
#define __gen_unpack_float(out, cl, start, end) \
do { \
uint32_t __tmp_float; \
__gen_unpack_uint(__tmp_float, cl, start, end); \
(out) = uif(__tmp_float); \
} while (0)
#define __gen_unpack_padded(out, cl, start, end) \
do { \
uint32_t __tmp_padded; \
__gen_unpack_uint(__tmp_padded, cl, start, end); \
(out) = (2 * (__tmp_padded >> 5) + 1) << (__tmp_padded & 0b11111); \
} while (0)
#define PREFIX1(A) MALI_##A
#define PREFIX2(A, B) MALI_##A##_##B
#define PREFIX4(A, B, C, D) MALI_##A##_##B##_##C##_##D
#define pan_pack(dst, T, name) \
for (UNUSED struct PREFIX1(T) name = {PREFIX2(T, header)}, \
*_loop_terminate = &name; \
__builtin_expect(_loop_terminate != NULL, 1); ({ \
PREFIX2(T, pack)((dst), &name); \
_loop_terminate = NULL; \
}))
#define pan_pack_nodefaults(dst, T, name) \
for (UNUSED struct PREFIX1(T) name = {0}, *_loop_terminate = &name; \
__builtin_expect(_loop_terminate != NULL, 1); ({ \
PREFIX2(T, pack)((dst), &name); \
_loop_terminate = NULL; \
}))
#define pan_unpack(src, T, name) \
UNUSED struct PREFIX1(T) name; \
PREFIX2(T, unpack)((src), &name)
#define pan_print(fp, T, var, indent) PREFIX2(T, print)(fp, &(var), indent)
#define pan_size(T) PREFIX2(T, LENGTH)
#define pan_alignment(T) PREFIX2(T, ALIGN)
#define pan_section_offset(A, S) PREFIX4(A, SECTION, S, OFFSET)
/* Those APIs aren't safe in OpenCL C because we lose information on the
* pointer address space */
#ifndef __OPENCL_VERSION__
#define pan_cast_and_pack(dst, T, name) \
pan_pack((PREFIX2(T, PACKED_T) *)(dst), T, name)
#define pan_cast_and_pack_nodefaults(dst, T, name) \
pan_pack_nodefaults((PREFIX2(T, PACKED_T) *)(dst), T, name)
#define pan_cast_and_unpack(src, T, name) \
pan_unpack((const PREFIX2(T, PACKED_T) *)(src), T, name)
#define pan_section_ptr(base, A, S) \
((PREFIX4(A, SECTION, S, PACKED_TYPE) *)((uint8_t *)(base) + \
pan_section_offset(A, S)))
#define pan_section_pack(dst, A, S, name) \
for (UNUSED PREFIX4(A, SECTION, S, TYPE) \
name = {PREFIX4(A, SECTION, S, header)}, \
*_loop_terminate = (void *)(dst); \
__builtin_expect(_loop_terminate != NULL, 1); ({ \
PREFIX4(A, SECTION, S, pack)(pan_section_ptr(dst, A, S), &name); \
_loop_terminate = NULL; \
}))
#define pan_section_unpack(src, A, S, name) \
UNUSED PREFIX4(A, SECTION, S, TYPE) name; \
PREFIX4(A, SECTION, S, unpack)(pan_section_ptr(src, A, S), &name)
#endif
#define pan_section_print(fp, A, S, var, indent) \
PREFIX4(A, SECTION, S, print)(fp, &(var), indent)
#define pan_merge(packed1, packed2, type) \
do { \
size_t __tmp_bytes = pan_size(type); \
for (unsigned i = 0; i < (__tmp_bytes / 4); ++i) \
(packed1)->opaque[i] |= (packed2)->opaque[i]; \
} while (0);
#ifndef __OPENCL_VERSION__
static inline const char *
mali_component_swizzle(unsigned val)
{
static const char swiz_name[] = "RGBA01??";
static char out_str[5], *outp;
outp = out_str;
for (int i = 0; i < 12; i += 3) {
*outp++ = swiz_name[(val >> i) & 7];
}
*outp = 0;
return out_str;
}
#endif
/* From presentations, 16x16 tiles externally. Use shift for fast computation
* of tile numbers. */
#define MALI_TILE_SHIFT 4
#define MALI_TILE_LENGTH (1 << MALI_TILE_SHIFT)
#endif