[Mesa-dev] [PATCH v2 2/5] intel/isl: Add support for saving surface debug info to files

Jordan Justen jordan.l.justen at intel.com
Thu Dec 1 03:57:00 UTC 2016


Signed-off-by: Jordan Justen <jordan.l.justen at intel.com>
---
 src/intel/Makefile.sources |   1 +
 src/intel/isl/isl.h        |  14 +++
 src/intel/isl/isl_dump.c   | 217 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 232 insertions(+)
 create mode 100644 src/intel/isl/isl_dump.c

diff --git a/src/intel/Makefile.sources b/src/intel/Makefile.sources
index be6bdef..00bcaaf 100644
--- a/src/intel/Makefile.sources
+++ b/src/intel/Makefile.sources
@@ -34,6 +34,7 @@ AUBINATOR_GENERATED_FILES = \
 ISL_FILES = \
 	isl/isl.c \
 	isl/isl.h \
+	isl/isl_dump.c \
 	isl/isl_format.c \
 	isl/isl_priv.h \
 	isl/isl_storage_image.c
diff --git a/src/intel/isl/isl.h b/src/intel/isl/isl.h
index 07368f9..a1d431a 100644
--- a/src/intel/isl/isl.h
+++ b/src/intel/isl/isl.h
@@ -1486,6 +1486,20 @@ uint32_t
 isl_surf_get_depth_format(const struct isl_device *dev,
                           const struct isl_surf *surf);
 
+/**
+ * @brief Save the isl_surf information out to files for debug purposes.
+ *
+ */
+void
+isl_surf_dump(const struct isl_device *dev,
+              const struct isl_surf *surf,
+              const void *map_addr,
+              unsigned int map_size,
+              const struct isl_surf *aux_surf,
+              const void *aux_map_addr,
+              unsigned int aux_map_size,
+              const char *basename);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/intel/isl/isl_dump.c b/src/intel/isl/isl_dump.c
new file mode 100644
index 0000000..17ec8c0
--- /dev/null
+++ b/src/intel/isl/isl_dump.c
@@ -0,0 +1,217 @@
+/*
+ * Copyright 2016 Intel Corporation
+ *
+ *  Permission is hereby granted, free of charge, to any person obtaining a
+ *  copy of this software and associated documentation files (the "Software"),
+ *  to deal in the Software without restriction, including without limitation
+ *  the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ *  and/or sell copies of the Software, and to permit persons to whom the
+ *  Software is furnished to do so, subject to the following conditions:
+ *
+ *  The above copyright notice and this permission notice (including the next
+ *  paragraph) shall be included in all copies or substantial portions of the
+ *  Software.
+ *
+ *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ *  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ *  IN THE SOFTWARE.
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "isl.h"
+#include "isl_priv.h"
+#include "common/gen_device_info.h"
+
+#include "util/format_srgb.h"
+#include "util/ralloc.h"
+
+#include "main/macros.h"
+
+/**
+ * @brief Determine if a surface should be dumped.
+ *
+ * Since dumping a surface can produce a lot of data and be time consuming,
+ * this function allows you to filter whether a surface should actually be
+ * dumped. If the application is deterministic, then you can use the sequence
+ * id number to filter output. Other examples are shown commented out.
+ *
+ * Return true when the surface should be dumped.
+ */
+static inline bool
+filter_surface_dumping(uint64_t sequence_id,
+                       const struct isl_surf *surf,
+                       const void *map_addr,
+                       unsigned int map_size,
+                       const struct isl_surf *aux_surf,
+                       const void *aux_map_addr,
+                       unsigned int aux_map_size,
+                       const char *basename)
+{
+   const uint64_t single_id = 0;
+   const uint64_t min_id = 0;
+   const uint64_t max_id = 0;
+   return
+      (min_id == 0 || sequence_id >= min_id) &&
+      (max_id == 0 || sequence_id <= max_id) &&
+      (single_id == 0 || sequence_id == single_id) &&
+      /* surf->format == ISL_FORMAT_R8_UINT && */
+      /* surf->msaa_layout == ISL_MSAA_LAYOUT_NONE && */
+      true;
+}
+
+static const char *
+tiling_name(enum isl_tiling tiling)
+{
+#define TILENAME(t) case ISL_TILING_##t: return #t
+   switch(tiling) {
+   TILENAME(LINEAR);
+   TILENAME(W);
+   TILENAME(X);
+   TILENAME(Y0);
+   TILENAME(Yf);
+   TILENAME(Ys);
+   TILENAME(HIZ);
+   TILENAME(CCS);
+   default:
+      return NULL;
+   }
+}
+
+static const char *
+msaa_name(enum isl_msaa_layout layout)
+{
+#define MSAA_NAME(l) case ISL_MSAA_LAYOUT_##l: return #l
+   switch(layout) {
+   MSAA_NAME(NONE);
+   MSAA_NAME(INTERLEAVED);
+   MSAA_NAME(ARRAY);
+   default:
+      return NULL;
+   }
+}
+
+static bool
+dump_surf_info(const struct isl_device *dev,
+               const struct isl_surf *surf,
+               const char *filename)
+{
+   FILE *f = fopen(filename, "w");
+   if (!f)
+      goto fail_open;
+
+   fprintf(f, "Format: %s\n", isl_format_get_name(surf->format));
+   fprintf(f, "Tiling: %s\n", tiling_name(surf->tiling));
+   fprintf(f, "Row pitch: %d\n", surf->row_pitch);
+   fprintf(f, "Array pitch (q-pitch): %d\n", surf->array_pitch_el_rows);
+   fprintf(f, "Bit6 swizzle: %sabled\n", dev->has_bit6_swizzling ? "En" : "Dis");
+   fprintf(f, "Samples: %d\n", surf->samples);
+   fprintf(f, "MSAA layout: %s\n", msaa_name(surf->msaa_layout));
+   fprintf(f, "Logical size LOD0 (px): %d x %d\n",
+           surf->logical_level0_px.w, surf->logical_level0_px.h);
+   fprintf(f, "Physical size LOD0 (sa): %d x %d\n",
+           surf->phys_level0_sa.w, surf->phys_level0_sa.h);
+
+   fclose(f);
+   return true;
+
+ fail_open:
+   fprintf(stderr, "%s:%s: couldn't open file: %s\n", __FILE__, __func__, filename);
+   return false;
+}
+
+static bool
+dump_surf_binary(const void *map_addr,
+                 unsigned int map_size,
+                 const char *filename)
+{
+   FILE *f = fopen(filename, "w");
+   if (!f)
+      goto fail_open;
+
+   fwrite(map_addr, 1, map_size, f);
+
+   fclose(f);
+   return true;
+
+ fail_open:
+   fprintf(stderr, "%s:%s: couldn't open file: %s\n", __FILE__, __func__, filename);
+   return false;
+}
+
+void
+isl_surf_dump(const struct isl_device *dev,
+              const struct isl_surf *surf,
+              const void *map_addr,
+              unsigned int map_size,
+              const struct isl_surf *aux_surf,
+              const void *aux_map_addr,
+              unsigned int aux_map_size,
+              const char *basename)
+{
+   int ret;
+
+   char filename[1024];
+   static uint64_t sequence_id = 0;
+
+   sequence_id++;
+
+   if (!filter_surface_dumping(sequence_id, surf, map_addr, map_size, aux_surf,
+                               aux_map_addr, aux_map_size, basename))
+      return;
+
+   ret = snprintf(filename, sizeof(filename), "%04lu-%s.txt",
+                  sequence_id, basename);
+   if (ret < -1 || ret >= sizeof(filename))
+      goto fail_basename_too_big;
+
+   if (!dump_surf_info(dev, surf, filename))
+      goto fail_dump_info;
+
+   if (map_addr != NULL && map_size > 0) {
+      ret = snprintf(filename, sizeof(filename), "%04lu-%s.bin",
+                     sequence_id, basename);
+      if (ret < -1 || ret >= sizeof(filename))
+         goto fail_basename_too_big;
+
+      if (!dump_surf_binary(map_addr, map_size, filename))
+         goto fail_dump_info;
+   }
+
+   if (aux_surf) {
+      ret = snprintf(filename, sizeof(filename), "%04lu-%s-aux.txt",
+                     sequence_id, basename);
+      if (ret < -1 || ret >= sizeof(filename))
+         goto fail_basename_too_big;
+
+      if (!dump_surf_info(dev, aux_surf, filename))
+         goto fail_dump_info;
+
+      if (aux_map_addr != NULL && aux_map_size > 0) {
+         ret = snprintf(filename, sizeof(filename), "%04lu-%s-aux.bin",
+                        sequence_id, basename);
+         if (ret < -1 || ret >= sizeof(filename))
+            goto fail_basename_too_big;
+
+         if (!dump_surf_binary(aux_map_addr, aux_map_size, filename))
+            goto fail_dump_info;
+      }
+   }
+
+   return;
+
+ fail_basename_too_big:
+   fprintf(stderr, "%s:%s: basename too big\n", __FILE__, __func__);
+   abort();
+
+ fail_dump_info:
+   fprintf(stderr, "%s:%s: failed to dump surface info\n", __FILE__, __func__);
+   abort();
+}
-- 
2.10.2



More information about the mesa-dev mailing list