nir: add a low level printf emission helper

Uses the same memory layout as the print intrinsic lowering. This one
just let's you do the emission without having to deal with variables.

This useful for debug traces.

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Reviewed-by: Karol Herbst <kherbst@redhat.com>
Reviewed-by: Ivan Briano <ivan.briano@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25814>
This commit is contained in:
Lionel Landwerlin 2024-02-27 18:45:46 +02:00 committed by Marge Bot
parent c518a176f5
commit c16e58eabd
2 changed files with 101 additions and 0 deletions

View file

@ -2165,6 +2165,14 @@ nir_scoped_memory_barrier(nir_builder *b,
nir_def *
nir_gen_rect_vertices(nir_builder *b, nir_def *z, nir_def *w);
/* Emits a printf in the same way nir_lower_printf(). Each of the variadic
* argument is a pointer to a nir_def value.
*/
void nir_printf_fmt(nir_builder *b,
bool use_printf_base_identifier,
unsigned ptr_bit_size,
const char *fmt, ...);
#ifdef __cplusplus
} /* extern "C" */
#endif

View file

@ -132,3 +132,96 @@ nir_lower_printf(nir_shader *nir, const nir_lower_printf_options *options)
nir_metadata_none,
(void *)options);
}
void
nir_printf_fmt(nir_builder *b,
bool use_printf_base_identifier,
unsigned ptr_bit_size,
const char *fmt, ...)
{
b->shader->printf_info_count++;
b->shader->printf_info = reralloc(b->shader,
b->shader->printf_info,
u_printf_info,
b->shader->printf_info_count);
u_printf_info *info =
&b->shader->printf_info[b->shader->printf_info_count - 1];
*info = (u_printf_info) {
.strings = ralloc_strdup(b->shader, fmt),
.string_size = strlen(fmt) + 1,
};
va_list ap;
size_t pos = 0;
size_t args_size = 0;
va_start(ap, fmt);
while ((pos = util_printf_next_spec_pos(fmt, pos)) != -1) {
unsigned arg_size;
switch (fmt[pos]) {
case 'c': arg_size = 1; break;
case 'd': arg_size = 4; break;
case 'e': arg_size = 4; break;
case 'E': arg_size = 4; break;
case 'f': arg_size = 4; break;
case 'F': arg_size = 4; break;
case 'G': arg_size = 4; break;
case 'a': arg_size = 4; break;
case 'A': arg_size = 4; break;
case 'i': arg_size = 4; break;
case 'u': arg_size = 4; break;
case 'x': arg_size = 4; break;
case 'X': arg_size = 4; break;
case 'p': arg_size = 8; break;
default: unreachable("invalid");
}
nir_def *def = va_arg(ap, nir_def*);
assert(def->bit_size / 8 == arg_size);
info->num_args++;
info->arg_sizes = reralloc(b->shader,
info->arg_sizes,
unsigned, info->num_args);
info->arg_sizes[info->num_args - 1] = arg_size;
args_size += arg_size;
}
va_end(ap);
nir_def *buffer_addr =
nir_load_printf_buffer_address(
b, ptr_bit_size ? ptr_bit_size : nir_get_ptr_bitsize(b->shader));
nir_def *buffer_offset =
nir_global_atomic(b, 32, buffer_addr,
nir_imm_int(b, args_size + sizeof(uint32_t)),
.atomic_op = nir_atomic_op_iadd);
/* Identifier */
nir_def *identifier =
use_printf_base_identifier ?
nir_iadd_imm(b,
nir_load_printf_base_identifier(b),
b->shader->printf_info_count) :
nir_imm_int(b, b->shader->printf_info_count);
nir_def *store_addr =
nir_iadd(b, buffer_addr, nir_i2iN(b, buffer_offset,
buffer_addr->bit_size));
nir_store_global(b, store_addr, 4, identifier, 0x1);
/* Arguments */
va_start(ap, fmt);
unsigned store_offset = sizeof(uint32_t);
for (unsigned a = 0; a < info->num_args; a++) {
nir_def *def = va_arg(ap, nir_def*);
nir_store_global(b, nir_iadd_imm(b, store_addr, store_offset),
4, def, 0x1);
store_offset += info->arg_sizes[a];
}
va_end(ap);
}