summaryrefslogtreecommitdiffstats
path: root/src/compiler
diff options
context:
space:
mode:
authorJason Ekstrand <[email protected]>2017-08-16 16:04:08 -0700
committerJason Ekstrand <[email protected]>2017-12-04 09:21:09 -0800
commit16dfdeefc8469c9bb8770bab763fd943b62f875d (patch)
treec25774a8a13baf150dc0686df1c6c1bf11a8e7e8 /src/compiler
parent11bd753c4ece5eafa6fc7c416d25f60371758e1b (diff)
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 <[email protected]> Reviewed-by: Ian Romanick <[email protected]>
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/spirv/nir_spirv.h14
-rw-r--r--src/compiler/spirv/spirv2nir.c5
-rw-r--r--src/compiler/spirv/spirv_to_nir.c98
-rw-r--r--src/compiler/spirv/vtn_private.h20
4 files changed, 119 insertions, 18 deletions
diff --git a/src/compiler/spirv/nir_spirv.h b/src/compiler/spirv/nir_spirv.h
index 234b0ce3444..f129a205764 100644
--- a/src/compiler/spirv/nir_spirv.h
+++ b/src/compiler/spirv/nir_spirv.h
@@ -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,
diff --git a/src/compiler/spirv/spirv2nir.c b/src/compiler/spirv/spirv2nir.c
index 0ae14fb19b1..5957f064b49 100644
--- a/src/compiler/spirv/spirv2nir.c
+++ b/src/compiler/spirv/spirv2nir.c
@@ -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;
diff --git a/src/compiler/spirv/spirv_to_nir.c b/src/compiler/spirv/spirv_to_nir.c
index 46ba005945d..a918985daab 100644
--- a/src/compiler/spirv/spirv_to_nir.c
+++ b/src/compiler/spirv/spirv_to_nir.c
@@ -31,29 +31,89 @@
#include "nir/nir_constant_expressions.h"
#include "spirv_info.h"
-struct spec_constant_value {
- bool is_double;
- union {
- uint32_t data32;
- uint64_t data64;
- };
-};
+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_warn(const char *file, int line, const char *msg, ...)
+vtn_logf(struct vtn_builder *b, enum nir_spirv_debug_level level,
+ size_t spirv_offset, const char *fmt, ...)
{
- char *formatted;
va_list args;
+ char *msg;
- va_start(args, msg);
- formatted = ralloc_vasprintf(NULL, msg, args);
+ va_start(args, fmt);
+ msg = ralloc_vasprintf(NULL, fmt, args);
va_end(args);
- fprintf(stderr, "%s:%d WARNING: %s\n", file, line, formatted);
+ 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(formatted);
+ 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 {
+ uint32_t data32;
+ uint64_t data64;
+ };
+};
+
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;
diff --git a/src/compiler/spirv/vtn_private.h b/src/compiler/spirv/vtn_private.h
index b4380294048..cac4d45864b 100644
--- a/src/compiler/spirv/vtn_private.h
+++ b/src/compiler/spirv/vtn_private.h
@@ -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,