Mesa (master): spirv: Rework logging

Jason Ekstrand jekstrand at kemper.freedesktop.org
Mon Dec 4 17:21:23 UTC 2017


Module: Mesa
Branch: master
Commit: 16dfdeefc8469c9bb8770bab763fd943b62f875d
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=16dfdeefc8469c9bb8770bab763fd943b62f875d

Author: Jason Ekstrand <jason.ekstrand at intel.com>
Date:   Wed Aug 16 16:04:08 2017 -0700

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 at intel.com>
Reviewed-by: Ian Romanick <idr at freedesktop.org>

---

 src/compiler/spirv/nir_spirv.h    | 14 ++++++
 src/compiler/spirv/spirv2nir.c    |  5 +-
 src/compiler/spirv/spirv_to_nir.c | 98 +++++++++++++++++++++++++++++++++------
 src/compiler/spirv/vtn_private.h  | 20 ++++++--
 4 files changed, 119 insertions(+), 18 deletions(-)

diff --git a/src/compiler/spirv/nir_spirv.h b/src/compiler/spirv/nir_spirv.h
index 234b0ce344..f129a20576 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 0ae14fb19b..5957f064b4 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 46ba005945..a918985daa 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 b438029404..cac4d45864 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,




More information about the mesa-commit mailing list