mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-23 19:28:11 +02:00
Most of the time, we can infer the type to append in
util_dynarray_append using __typeof__, which is standardized in C23 and
support in Jesse's MSMSVCV. This patch drops the type argument most of
the time, making util_dynarray a little more ergonomic to use.
This is done in four steps.
First, rename util_dynarray_append -> util_dynarray_append_typed
bash -c "find . -type f -exec sed -i -e 's/util_dynarray_append(/util_dynarray_append_typed(/g' \{} \;"
Then, add a new append that infers the type. This is much more ergonomic
for what you want most of the time.
Next, use type-inferred append as much as possible, via Coccinelle
patch (plus manual fixup):
@@
expression dynarray, element;
type type;
@@
-util_dynarray_append_typed(dynarray, type, element);
+util_dynarray_append(dynarray, element);
Finally, hand fixup cases that Coccinelle missed or incorrectly
translated, of which there were several because we can't used the
untyped append with a literal (since the sizeof won't do what you want).
All four steps are squashed to produce a single patch changing every
util_dynarray_append call site in tree to either drop a type parameter
(if possible) or insert a _typed suffix (if we can't infer). As such,
the final patch is best reviewed by hand even though it was
tool-assisted.
No Long Linguine Meals were involved in the making of this patch.
Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig@intel.com>
Acked-by: Faith Ekstrand <faith.ekstrand@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/38038>
157 lines
3.8 KiB
C
157 lines
3.8 KiB
C
/*
|
|
* Copyright © 2024 Imagination Technologies Ltd.
|
|
*
|
|
* SPDX-License-Identifier: MIT
|
|
*/
|
|
|
|
/**
|
|
* \file pco_binary.c
|
|
*
|
|
* \brief PCO binary-specific functions.
|
|
*/
|
|
|
|
#include "pco.h"
|
|
#include "pco_internal.h"
|
|
#include "pco_isa.h"
|
|
#include "pco_map.h"
|
|
#include "util/u_dynarray.h"
|
|
|
|
#include <assert.h>
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
|
|
/**
|
|
* \brief Encodes instruction group alignment.
|
|
*
|
|
* \param[in,out] buf Binary buffer.
|
|
* \param[in] igrp PCO instruction group.
|
|
*/
|
|
static inline unsigned pco_encode_align(struct util_dynarray *buf,
|
|
pco_igrp *igrp)
|
|
{
|
|
unsigned bytes_encoded = 0;
|
|
|
|
if (igrp->enc.len.word_padding) {
|
|
util_dynarray_append_typed(buf, uint8_t, 0xff);
|
|
bytes_encoded += 1;
|
|
}
|
|
|
|
if (igrp->enc.len.align_padding) {
|
|
assert(!(igrp->enc.len.align_padding % 2));
|
|
|
|
unsigned align_words = igrp->enc.len.align_padding / 2;
|
|
util_dynarray_append_typed(buf, uint8_t, 0xf0 | align_words);
|
|
bytes_encoded += 1;
|
|
|
|
for (unsigned u = 0; u < igrp->enc.len.align_padding - 1; ++u) {
|
|
util_dynarray_append_typed(buf, uint8_t, 0xff);
|
|
bytes_encoded += 1;
|
|
}
|
|
}
|
|
|
|
return bytes_encoded;
|
|
}
|
|
|
|
/**
|
|
* \brief Encodes a PCO instruction group into binary.
|
|
*
|
|
* \param[in,out] buf Binary buffer.
|
|
* \param[in] igrp PCO instruction group.
|
|
* \return The number of bytes encoded.
|
|
*/
|
|
static unsigned pco_encode_igrp(struct util_dynarray *buf, pco_igrp *igrp)
|
|
{
|
|
uint8_t *ptr;
|
|
unsigned bytes_encoded = 0;
|
|
|
|
/* Header. */
|
|
ptr = util_dynarray_grow(buf, uint8_t, igrp->enc.len.hdr);
|
|
bytes_encoded += pco_igrp_hdr_map_encode(ptr, igrp);
|
|
|
|
/* Instructions. */
|
|
pco_foreach_phase_in_igrp_rev (igrp, p) {
|
|
ptr = util_dynarray_grow(buf, uint8_t, igrp->enc.len.instrs[p]);
|
|
bytes_encoded += pco_instr_map_encode(ptr, igrp, p);
|
|
}
|
|
|
|
/* I/O. */
|
|
if (igrp->enc.len.lower_srcs) {
|
|
ptr = util_dynarray_grow(buf, uint8_t, igrp->enc.len.lower_srcs);
|
|
bytes_encoded += pco_srcs_map_encode(ptr, igrp, false);
|
|
}
|
|
|
|
if (igrp->enc.len.upper_srcs) {
|
|
ptr = util_dynarray_grow(buf, uint8_t, igrp->enc.len.upper_srcs);
|
|
bytes_encoded += pco_srcs_map_encode(ptr, igrp, true);
|
|
}
|
|
|
|
if (igrp->enc.len.iss) {
|
|
ptr = util_dynarray_grow(buf, uint8_t, igrp->enc.len.iss);
|
|
bytes_encoded += pco_iss_map_encode(ptr, igrp);
|
|
}
|
|
|
|
if (igrp->enc.len.dests) {
|
|
ptr = util_dynarray_grow(buf, uint8_t, igrp->enc.len.dests);
|
|
bytes_encoded += pco_dests_map_encode(ptr, igrp);
|
|
}
|
|
|
|
/* Word/alignment padding. */
|
|
bytes_encoded += pco_encode_align(buf, igrp);
|
|
|
|
assert(bytes_encoded == igrp->enc.len.total);
|
|
|
|
return bytes_encoded;
|
|
}
|
|
|
|
/**
|
|
* \brief Encodes a PCO shader into binary.
|
|
*
|
|
* \param[in] ctx PCO compiler context.
|
|
* \param[in,out] shader PCO shader.
|
|
*/
|
|
void pco_encode_ir(pco_ctx *ctx, pco_shader *shader)
|
|
{
|
|
assert(shader->is_grouped);
|
|
|
|
util_dynarray_init(&shader->binary, shader);
|
|
|
|
unsigned bytes_encoded = 0;
|
|
pco_foreach_func_in_shader (func, shader) {
|
|
func->enc_offset = bytes_encoded;
|
|
pco_foreach_block_in_func (block, func) {
|
|
pco_foreach_igrp_in_block (igrp, block) {
|
|
bytes_encoded += pco_encode_igrp(&shader->binary, igrp);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (pco_should_print_binary(shader))
|
|
pco_print_binary(shader, stdout, "after encoding");
|
|
}
|
|
|
|
/**
|
|
* \brief Returns the size in bytes of a PCO shader binary.
|
|
*
|
|
* \param[in] shader PCO shader.
|
|
* \return The size in bytes of the PCO shader binary.
|
|
*/
|
|
unsigned pco_shader_binary_size(pco_shader *shader)
|
|
{
|
|
if (!shader)
|
|
return 0;
|
|
|
|
return shader->binary.size;
|
|
}
|
|
|
|
/**
|
|
* \brief Returns the PCO shader binary data.
|
|
*
|
|
* \param[in] shader PCO shader.
|
|
* \return The PCO shader binary data.
|
|
*/
|
|
const void *pco_shader_binary_data(pco_shader *shader)
|
|
{
|
|
if (!shader)
|
|
return NULL;
|
|
return shader->binary.data;
|
|
}
|