mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 09:38:07 +02:00
spirv: Rework logging
This commit reworks the way that logging works in SPIR-V to provide
richer and more detailed logging infrastructure. This commit contains
several improvements over the old mechanism:
1) Log messages are now more detailed. They contain the SPIR-V byte
offset as well as source language information from OpSource and
OpLine.
2) There is now a logging callback mechanism so that errors can get
propagated to the client through debug callbak extensions.
Reviewed-by: Tapani Pälli <tapani.palli@intel.com>
Reviewed-by: Ian Romanick <idr@freedesktop.org>
This commit is contained in:
parent
11bd753c4e
commit
16dfdeefc8
4 changed files with 121 additions and 20 deletions
|
|
@ -42,6 +42,12 @@ struct nir_spirv_specialization {
|
|||
};
|
||||
};
|
||||
|
||||
enum nir_spirv_debug_level {
|
||||
NIR_SPIRV_DEBUG_LEVEL_INFO,
|
||||
NIR_SPIRV_DEBUG_LEVEL_WARNING,
|
||||
NIR_SPIRV_DEBUG_LEVEL_ERROR,
|
||||
};
|
||||
|
||||
struct spirv_to_nir_options {
|
||||
struct {
|
||||
bool float64;
|
||||
|
|
@ -54,6 +60,14 @@ struct spirv_to_nir_options {
|
|||
bool multiview;
|
||||
bool variable_pointers;
|
||||
} caps;
|
||||
|
||||
struct {
|
||||
void (*func)(void *private_data,
|
||||
enum nir_spirv_debug_level level,
|
||||
size_t spirv_offset,
|
||||
const char *message);
|
||||
void *private_data;
|
||||
} debug;
|
||||
};
|
||||
|
||||
nir_function *spirv_to_nir(const uint32_t *words, size_t word_count,
|
||||
|
|
|
|||
|
|
@ -72,8 +72,11 @@ int main(int argc, char **argv)
|
|||
return 1;
|
||||
}
|
||||
|
||||
struct spirv_to_nir_options spirv_opts = {};
|
||||
|
||||
nir_function *func = spirv_to_nir(map, word_count, NULL, 0,
|
||||
MESA_SHADER_FRAGMENT, "main", NULL, NULL);
|
||||
MESA_SHADER_FRAGMENT, "main",
|
||||
&spirv_opts, NULL);
|
||||
nir_print_shader(func->shader, stderr);
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -31,6 +31,81 @@
|
|||
#include "nir/nir_constant_expressions.h"
|
||||
#include "spirv_info.h"
|
||||
|
||||
void
|
||||
vtn_log(struct vtn_builder *b, enum nir_spirv_debug_level level,
|
||||
size_t spirv_offset, const char *message)
|
||||
{
|
||||
if (b->options->debug.func) {
|
||||
b->options->debug.func(b->options->debug.private_data,
|
||||
level, spirv_offset, message);
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
if (level >= NIR_SPIRV_DEBUG_LEVEL_WARNING)
|
||||
fprintf(stderr, "%s\n", message);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
vtn_logf(struct vtn_builder *b, enum nir_spirv_debug_level level,
|
||||
size_t spirv_offset, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
char *msg;
|
||||
|
||||
va_start(args, fmt);
|
||||
msg = ralloc_vasprintf(NULL, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
vtn_log(b, level, spirv_offset, msg);
|
||||
|
||||
ralloc_free(msg);
|
||||
}
|
||||
|
||||
static void
|
||||
vtn_log_err(struct vtn_builder *b,
|
||||
enum nir_spirv_debug_level level, const char *prefix,
|
||||
const char *file, unsigned line,
|
||||
const char *fmt, va_list args)
|
||||
{
|
||||
char *msg;
|
||||
|
||||
msg = ralloc_strdup(NULL, prefix);
|
||||
|
||||
#ifndef NDEBUG
|
||||
ralloc_asprintf_append(&msg, " In file %s:%u\n", file, line);
|
||||
#endif
|
||||
|
||||
ralloc_asprintf_append(&msg, " ");
|
||||
|
||||
ralloc_vasprintf_append(&msg, fmt, args);
|
||||
|
||||
ralloc_asprintf_append(&msg, "\n %zu bytes into the SPIR-V binary",
|
||||
b->spirv_offset);
|
||||
|
||||
if (b->file) {
|
||||
ralloc_asprintf_append(&msg,
|
||||
"\n in SPIR-V source file %s, line %d, col %d",
|
||||
b->file, b->line, b->col);
|
||||
}
|
||||
|
||||
vtn_log(b, level, b->spirv_offset, msg);
|
||||
|
||||
ralloc_free(msg);
|
||||
}
|
||||
|
||||
void
|
||||
_vtn_warn(struct vtn_builder *b, const char *file, unsigned line,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
vtn_log_err(b, NIR_SPIRV_DEBUG_LEVEL_WARNING, "SPIR-V WARNING:\n",
|
||||
file, line, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
struct spec_constant_value {
|
||||
bool is_double;
|
||||
union {
|
||||
|
|
@ -39,21 +114,6 @@ struct spec_constant_value {
|
|||
};
|
||||
};
|
||||
|
||||
void
|
||||
_vtn_warn(const char *file, int line, const char *msg, ...)
|
||||
{
|
||||
char *formatted;
|
||||
va_list args;
|
||||
|
||||
va_start(args, msg);
|
||||
formatted = ralloc_vasprintf(NULL, msg, args);
|
||||
va_end(args);
|
||||
|
||||
fprintf(stderr, "%s:%d WARNING: %s\n", file, line, formatted);
|
||||
|
||||
ralloc_free(formatted);
|
||||
}
|
||||
|
||||
static struct vtn_ssa_value *
|
||||
vtn_undef_ssa_value(struct vtn_builder *b, const struct glsl_type *type)
|
||||
{
|
||||
|
|
@ -224,6 +284,8 @@ vtn_foreach_instruction(struct vtn_builder *b, const uint32_t *start,
|
|||
unsigned count = w[0] >> SpvWordCountShift;
|
||||
assert(count >= 1 && w + count <= end);
|
||||
|
||||
b->spirv_offset = (uint8_t *)w - (uint8_t *)b->spirv;
|
||||
|
||||
switch (opcode) {
|
||||
case SpvOpNop:
|
||||
break; /* Do nothing */
|
||||
|
|
@ -248,6 +310,12 @@ vtn_foreach_instruction(struct vtn_builder *b, const uint32_t *start,
|
|||
|
||||
w += count;
|
||||
}
|
||||
|
||||
b->spirv_offset = 0;
|
||||
b->file = NULL;
|
||||
b->line = -1;
|
||||
b->col = -1;
|
||||
|
||||
assert(w == end);
|
||||
return w;
|
||||
}
|
||||
|
|
@ -3321,6 +3389,10 @@ spirv_to_nir(const uint32_t *words, size_t word_count,
|
|||
{
|
||||
/* Initialize the stn_builder object */
|
||||
struct vtn_builder *b = rzalloc(NULL, struct vtn_builder);
|
||||
b->spirv = words;
|
||||
b->file = NULL;
|
||||
b->line = -1;
|
||||
b->col = -1;
|
||||
exec_list_make_empty(&b->functions);
|
||||
b->entry_point_stage = stage;
|
||||
b->entry_point_name = entry_point_name;
|
||||
|
|
|
|||
|
|
@ -37,6 +37,18 @@
|
|||
struct vtn_builder;
|
||||
struct vtn_decoration;
|
||||
|
||||
void vtn_log(struct vtn_builder *b, enum nir_spirv_debug_level level,
|
||||
size_t spirv_offset, const char *message);
|
||||
|
||||
void vtn_logf(struct vtn_builder *b, enum nir_spirv_debug_level level,
|
||||
size_t spirv_offset, const char *fmt, ...) PRINTFLIKE(4, 5);
|
||||
|
||||
#define vtn_info(...) vtn_logf(b, NIR_SPIRV_DEBUG_LEVEL_INFO, 0, __VA_ARGS__)
|
||||
|
||||
void _vtn_warn(struct vtn_builder *b, const char *file, unsigned line,
|
||||
const char *fmt, ...) PRINTFLIKE(4, 5);
|
||||
#define vtn_warn(...) _vtn_warn(b, __FILE__, __LINE__, __VA_ARGS__)
|
||||
|
||||
enum vtn_value_type {
|
||||
vtn_value_type_invalid = 0,
|
||||
vtn_value_type_undef,
|
||||
|
|
@ -466,13 +478,16 @@ struct vtn_decoration {
|
|||
struct vtn_builder {
|
||||
nir_builder nb;
|
||||
|
||||
const uint32_t *spirv;
|
||||
|
||||
nir_shader *shader;
|
||||
const struct spirv_to_nir_options *options;
|
||||
struct vtn_block *block;
|
||||
|
||||
/* Current file, line, and column. Useful for debugging. Set
|
||||
/* Current offset, file, line, and column. Useful for debugging. Set
|
||||
* automatically by vtn_foreach_instruction.
|
||||
*/
|
||||
size_t spirv_offset;
|
||||
char *file;
|
||||
int line, col;
|
||||
|
||||
|
|
@ -560,9 +575,6 @@ vtn_value(struct vtn_builder *b, uint32_t value_id,
|
|||
return val;
|
||||
}
|
||||
|
||||
void _vtn_warn(const char *file, int line, const char *msg, ...);
|
||||
#define vtn_warn(...) _vtn_warn(__FILE__, __LINE__, __VA_ARGS__)
|
||||
|
||||
struct vtn_ssa_value *vtn_ssa_value(struct vtn_builder *b, uint32_t value_id);
|
||||
|
||||
struct vtn_ssa_value *vtn_create_ssa_value(struct vtn_builder *b,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue