From 87da5d510afcaa233f8b062f465fa3ba82945c31 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marek=20Ol=C5=A1=C3=A1k?= <marek.olsak@amd.com>
Date: Wed, 24 Apr 2024 12:31:21 -0400
Subject: [PATCH] si-report.py: print shader output stats

---
 si-report.py | 63 ++++++++++++++++++++++++++++++++++------------------
 1 file changed, 41 insertions(+), 22 deletions(-)

diff --git a/si-report.py b/si-report.py
index 191f4e0..5fb9373 100755
--- a/si-report.py
+++ b/si-report.py
@@ -89,16 +89,21 @@ def cmp_min_per(current, comp):
 
 class si_stats:
     metrics = [
-        ('sgprs', 'SGPRS', ''),
-        ('vgprs', 'VGPRS', ''),
-        ('spilled_sgprs', 'Spilled SGPRs', ''),
-        ('spilled_vgprs', 'Spilled VGPRs', ''),
-        ('privmem_vgprs', 'Private memory VGPRs', ''),
-        ('scratch_size', 'Scratch size', 'dwords per thread'),
-        ('code_size', 'Code Size', 'bytes'),
-        ('maxwaves', 'Max Waves', ''),
-        ('outputs', 'Outputs', ''),
-        ('patchoutputs', 'Patch Outputs', ''),
+        # variable, full name, table name, units
+        ('sgprs', 'SGPRs', 'SGPRs', ''),
+        ('vgprs', 'VGPRs', 'VGPRs', ''),
+        ('spilled_sgprs', 'Spilled SGPRs', 'SpillSGPR', ''),
+        ('spilled_vgprs', 'Spilled VGPRs', 'SpillVGPR', ''),
+        ('privmem_vgprs', 'Private memory VGPRs', 'PrivVGPR', ''),
+        ('scratch_size', 'Scratch size', 'Scratch', 'dwords per thread'),
+        ('code_size', 'Code Size', 'CodeSize', 'bytes'),
+        ('maxwaves', 'Max Waves', 'MaxWaves', ''),
+        ('ls_outputs', 'LS Outputs', 'LSOutputs', ''),
+        ('hs_outputs', 'HS Outputs', 'HSOutputs', ''),
+        ('hs_patch_outputs', 'HS Patch Outputs', 'PatchOuts', ''),
+        ('es_outputs', 'ES Outputs', 'ESOutputs', ''),
+        ('gs_outputs', 'GS Outputs', 'GSOutputs', ''),
+        ('vs_outputs', 'VS Outputs', 'VSOutputs', ''),
     ]
 
     def __init__(self):
@@ -122,7 +127,7 @@ class si_stats:
 
     def to_string(self, suffixes=True):
         strings = []
-        for name, printname, suffix in si_stats.metrics:
+        for name, printname, _, suffix in si_stats.metrics:
             string = "  {}: {}".format(printname, get_str(self.__dict__[name]))
 
             if suffixes and len(suffix) > 0:
@@ -192,6 +197,12 @@ class si_stats:
 
 class si_parser(object):
     re_stats = [
+        re.compile(
+            r"^Shader Stats: SGPRS: ([0-9]+) VGPRS: ([0-9]+) Code Size: ([0-9]+) " +
+            r"LDS: ([0-9]+) Scratch: ([0-9]+) Max Waves: ([0-9]+) Spilled SGPRs: " +
+            r"([0-9]+) Spilled VGPRs: ([0-9]+) PrivMem VGPRs: ([0-9]+) LSOutputs: ([0-9]+) " +
+            r"HSOutputs: ([0-9]+) HSPatchOuts: ([0-9]+) ESOutputs: ([0-9]+) GSOutputs: ([0-9]+) " +
+            r"VSOutputs: ([0-9]+)"),
         re.compile(
             r"^Shader Stats: SGPRS: ([0-9]+) VGPRS: ([0-9]+) Code Size: ([0-9]+) " +
             r"LDS: ([0-9]+) Scratch: ([0-9]+) Max Waves: ([0-9]+) Spilled SGPRs: " +
@@ -233,13 +244,17 @@ class si_parser(object):
                 self._stats.sgprs = int(match.group(1))
                 self._stats.vgprs = int(match.group(2))
                 self._stats.code_size = int(match.group(3))
-                self._stats.scratch_size = int(match.group(5)) / (64 * 4)
+                self._stats.scratch_size = int(int(match.group(5)) / 64 / 4)
                 self._stats.maxwaves = int(match.group(6))
                 self._stats.spilled_sgprs = int(match.group(7))
                 self._stats.spilled_vgprs = int(match.group(8))
                 self._stats.privmem_vgprs = int(match.group(9)) if match.lastindex >= 9 else 0
-                self._stats.outputs = int(match.group(10)) if match.lastindex >= 10 else 0
-                self._stats.patchoutputs = int(match.group(11)) if match.lastindex >= 11 else 0
+                self._stats.ls_outputs = int(match.group(10)) if match.lastindex >= 17 else 0
+                self._stats.hs_outputs = int(match.group(11)) if match.lastindex >= 17 else 0
+                self._stats.hs_patch_outputs = int(match.group(12)) if match.lastindex >= 17 else 0
+                self._stats.es_outputs = int(match.group(13)) if match.lastindex >= 17 else 0
+                self._stats.gs_outputs = int(match.group(14)) if match.lastindex >= 17 else 0
+                self._stats.vs_outputs = int(match.group(15)) if match.lastindex >= 17 else 0
                 old_stats = self._stats
                 self._stats = None
                 return old_stats
@@ -323,16 +338,16 @@ def divide_stats(num, div):
     return result
 
 
-def print_before_after_stats(before, after, divisor=1):
+def print_before_after_stats(before, after):
     result = si_stats()
     for name in result.get_metrics():
-        b = before.__dict__[name] / divisor
-        a = after.__dict__[name] / divisor
+        b = before.__dict__[name]
+        a = after.__dict__[name]
         if b == 0:
             percent = format_float(0.0)
         else:
             percent = format_float(100 * float(a - b) / float(b))
-        result.__dict__[name] = '{} -> {} ({})'.format(get_str(b, ''), get_str(a, ''), percent)
+        result.__dict__[name] = '{} -> {} ({})'.format(b, a, percent)
 
     print(result)
 
@@ -485,7 +500,7 @@ class grouped_stats:
         if not is_different(self.before, self.after):
             return
 
-        print("| {:{app_width}} |{:{shader_width}}|{}|{}|{}|{}|{}|{}|{}|{}|{}|{}|".format(
+        print(("| {:{app_width}} |{:{shader_width}}|" + "{}|" * len(si_stats.metrics)).format(
             name,
             self.num_shaders,
             format_percent_change(self.before.sgprs, self.after.sgprs, min_width=len(legend[1])),
@@ -496,8 +511,12 @@ class grouped_stats:
             format_percent_change(self.before.scratch_size, self.after.scratch_size, min_width=len(legend[6])),
             format_percent_change(self.before.code_size, self.after.code_size, min_width=len(legend[7])),
             format_percent_change(self.before.maxwaves, self.after.maxwaves, min_width=len(legend[8]), more_is_better=True),
-            format_percent_change(self.before.outputs, self.after.outputs, min_width=len(legend[9])),
-            format_percent_change(self.before.patchoutputs, self.after.patchoutputs, min_width=len(legend[10])),
+            format_percent_change(self.before.ls_outputs, self.after.ls_outputs, min_width=len(legend[9])),
+            format_percent_change(self.before.hs_outputs, self.after.hs_outputs, min_width=len(legend[10])),
+            format_percent_change(self.before.hs_patch_outputs, self.after.hs_patch_outputs, min_width=len(legend[11])),
+            format_percent_change(self.before.es_outputs, self.after.es_outputs, min_width=len(legend[12])),
+            format_percent_change(self.before.gs_outputs, self.after.gs_outputs, min_width=len(legend[13])),
+            format_percent_change(self.before.vs_outputs, self.after.vs_outputs, min_width=len(legend[14])),
             app_width=align,
             shader_width=len(legend[0])))
 
@@ -683,7 +702,7 @@ def print_tables(before_all_results, after_all_results):
     # percentages
     longest_app_name = max(longest_app_name, len("Affected shaders"))
     title = "| {:^{width}} |".format("AFFECTED APPS", width=longest_app_name)
-    legend = ["{:^9}".format(s) for s in ["Shaders", "SGPRs", "VGPRs", "SpillSGPR", "SpillVGPR", "PrivVGPR", "Scratch", "CodeSize", "MaxWaves", "Outputs", "PatchOuts"]]
+    legend = ["{:^9}".format(s) for s in ["Shaders"] + [m[2] for m in metrics]]
     header = title + "|".join(legend) + "|"
     print_yellow(header)
     print("|".join(["-" * len(a) for a in (header).split("|")]))
-- 
GitLab