mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-01 05:58:05 +02:00
asahi: Make GenXML compatible with OpenCL
Adapt gen_pack.py to generate an OpenCL compatible header, capable of both packing and unpacking but not printing (due to no known use case and no fprintf in CL). This is useful as a building block for manipulating descriptors from shader code, for example in texture lowering or device-generated commands. To accomplish this, we need to inline in some CL-compatible variants of mesa util functions (no doubles, etc), avoid FILE * use in the CL path, and use __constant pointers where applicable for performance. Otherwise, there are surprisingly few changes required, thanks mainly to CL 2.0 generic pointers. Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25498>
This commit is contained in:
parent
59499d8dbc
commit
0df82f76c4
1 changed files with 70 additions and 7 deletions
|
|
@ -24,19 +24,76 @@ pack_header = """
|
|||
#ifndef AGX_PACK_H
|
||||
#define AGX_PACK_H
|
||||
|
||||
#ifndef __OPENCL_VERSION__
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "util/bitpack_helpers.h"
|
||||
#define FILE_TYPE FILE
|
||||
#define CONSTANT const
|
||||
#else
|
||||
|
||||
#include "libagx.h"
|
||||
#define assert(x)
|
||||
#define FILE_TYPE void
|
||||
#define CONSTANT constant
|
||||
|
||||
static uint64_t
|
||||
util_bitpack_uint(uint64_t v, uint32_t start, uint32_t end)
|
||||
{
|
||||
return v << start;
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
util_bitpack_sint(int64_t v, uint32_t start, uint32_t end)
|
||||
{
|
||||
const int bits = end - start + 1;
|
||||
const uint64_t mask = (bits == 64) ? ~((uint64_t)0) : (1ull << bits) - 1;
|
||||
return (v & mask) << start;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
util_bitpack_float(float v)
|
||||
{
|
||||
union { float f; uint32_t dw; } x;
|
||||
x.f = v;
|
||||
return x.dw;
|
||||
}
|
||||
|
||||
static inline float
|
||||
uif(uint32_t ui)
|
||||
{
|
||||
union { float f; uint32_t dw; } fi;
|
||||
fi.dw = ui;
|
||||
return fi.f;
|
||||
}
|
||||
|
||||
#define DIV_ROUND_UP( A, B ) ( ((A) + (B) - 1) / (B) )
|
||||
#define CLAMP( X, MIN, MAX ) ( (X)>(MIN) ? ((X)>(MAX) ? (MAX) : (X)) : (MIN) )
|
||||
#define ALIGN_POT(x, pot_align) (((x) + (pot_align) - 1) & ~((pot_align) - 1))
|
||||
|
||||
static inline unsigned
|
||||
util_logbase2(unsigned n)
|
||||
{
|
||||
return ((sizeof(unsigned) * 8 - 1) - __builtin_clz(n | 1));
|
||||
}
|
||||
|
||||
static inline int64_t
|
||||
util_sign_extend(uint64_t val, unsigned width)
|
||||
{
|
||||
unsigned shift = 64 - width;
|
||||
return (int64_t)(val << shift) >> shift;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#define __gen_unpack_float(x, y, z) uif(__gen_unpack_uint(x, y, z))
|
||||
|
||||
static inline uint64_t
|
||||
__gen_unpack_uint(const uint8_t *restrict cl, uint32_t start, uint32_t end)
|
||||
__gen_unpack_uint(CONSTANT uint8_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 ? ~0 : (1ull << width) - 1 );
|
||||
const uint64_t mask = (width == 64) ? ~((uint64_t)0) : ((uint64_t)1 << width) - 1;
|
||||
|
||||
for (unsigned byte = start / 8; byte <= end / 8; byte++) {
|
||||
val |= ((uint64_t) cl[byte]) << ((byte - start / 8) * 8);
|
||||
|
|
@ -57,13 +114,13 @@ __gen_pack_lod(float f, uint32_t start, uint32_t end)
|
|||
}
|
||||
|
||||
static inline float
|
||||
__gen_unpack_lod(const uint8_t *restrict cl, uint32_t start, uint32_t end)
|
||||
__gen_unpack_lod(CONSTANT uint8_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 uint8_t *restrict cl, uint32_t start, uint32_t end)
|
||||
__gen_unpack_sint(CONSTANT uint8_t *restrict cl, uint32_t start, uint32_t end)
|
||||
{
|
||||
int size = end - start + 1;
|
||||
int64_t val = __gen_unpack_uint(cl, start, end);
|
||||
|
|
@ -106,7 +163,7 @@ __gen_from_groups(uint32_t value, uint32_t group_size, uint32_t length)
|
|||
|
||||
#define agx_unpack(fp, src, T, name) \\
|
||||
struct AGX_ ## T name; \\
|
||||
AGX_ ## T ## _unpack(fp, (uint8_t *)(src), &name)
|
||||
AGX_ ## T ## _unpack(fp, (CONSTANT uint8_t *)(src), &name)
|
||||
|
||||
#define agx_print(fp, T, var, indent) \\
|
||||
AGX_ ## T ## _print(fp, &(var), indent)
|
||||
|
|
@ -438,6 +495,7 @@ class Group(object):
|
|||
words = {}
|
||||
self.collect_words(self.fields, 0, '', words)
|
||||
|
||||
print('#ifndef __OPENCL_VERSION__')
|
||||
for index in range(self.length // 4):
|
||||
base = index * 32
|
||||
word = words.get(index, self.Word())
|
||||
|
|
@ -449,6 +507,7 @@ class Group(object):
|
|||
if mask != ALL_ONES:
|
||||
TMPL = ' if (((const uint32_t *) cl)[{}] & {}) fprintf(fp, "XXX: Unknown field of {} unpacked at word {}: got %X, bad mask %X\\n", ((const uint32_t *) cl)[{}], ((const uint32_t *) cl)[{}] & {});'
|
||||
print(TMPL.format(index, hex(mask ^ ALL_ONES), self.label, index, index, index, hex(mask ^ ALL_ONES)))
|
||||
print('#endif')
|
||||
|
||||
fieldrefs = []
|
||||
self.collect_fields(self.fields, 0, '', fieldrefs)
|
||||
|
|
@ -624,7 +683,7 @@ class Parser(object):
|
|||
|
||||
def emit_unpack_function(self, name, group):
|
||||
print("static inline void")
|
||||
print("%s_unpack(FILE *fp, const uint8_t * restrict cl,\n%sstruct %s * restrict values)\n{" %
|
||||
print("%s_unpack(FILE_TYPE *fp, CONSTANT uint8_t * restrict cl,\n%sstruct %s * restrict values)\n{" %
|
||||
(name.upper(), ' ' * (len(name) + 8), name))
|
||||
|
||||
group.emit_unpack_function()
|
||||
|
|
@ -632,12 +691,14 @@ class Parser(object):
|
|||
print("}\n")
|
||||
|
||||
def emit_print_function(self, name, group):
|
||||
print("#ifndef __OPENCL_VERSION__")
|
||||
print("static inline void")
|
||||
print("{}_print(FILE *fp, const struct {} * values, unsigned indent)\n{{".format(name.upper(), name))
|
||||
|
||||
group.emit_print_function()
|
||||
|
||||
print("}\n")
|
||||
print("#endif")
|
||||
|
||||
def emit_struct(self):
|
||||
name = self.struct
|
||||
|
|
@ -662,6 +723,7 @@ class Parser(object):
|
|||
print(' % -36s = %6d,' % (name, value.value))
|
||||
print('};\n')
|
||||
|
||||
print("#ifndef __OPENCL_VERSION__")
|
||||
print("static inline const char *")
|
||||
print("{}_as_str(enum {} imm)\n{{".format(e_name.lower(), e_name))
|
||||
print(" switch (imm) {")
|
||||
|
|
@ -673,6 +735,7 @@ class Parser(object):
|
|||
print(" }")
|
||||
print(" return NULL;")
|
||||
print("}\n")
|
||||
print("#endif")
|
||||
|
||||
def parse(self, filename):
|
||||
file = open(filename, "rb")
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue