[Piglit] [v3 03/11] ext_memory_object: Add script for turning glsl into spirv c-array

Topi Pohjolainen topi.pohjolainen at gmail.com
Thu Dec 21 12:02:46 UTC 2017


This stripped down version of glsl_scraper.py found in crucible.

Signed-off-by: Topi Pohjolainen <topi.pohjolainen at intel.com>
---
 .../compile_and_dump_glsl_as_spirv.py              | 139 +++++++++++++++++++++
 1 file changed, 139 insertions(+)
 create mode 100644 tests/spec/ext_memory_object/compile_and_dump_glsl_as_spirv.py

diff --git a/tests/spec/ext_memory_object/compile_and_dump_glsl_as_spirv.py b/tests/spec/ext_memory_object/compile_and_dump_glsl_as_spirv.py
new file mode 100644
index 000000000..b7fdeafe2
--- /dev/null
+++ b/tests/spec/ext_memory_object/compile_and_dump_glsl_as_spirv.py
@@ -0,0 +1,139 @@
+#! /usr/bin/env python3
+
+import argparse
+import io
+import os
+import re
+import shutil
+import struct
+import subprocess
+import sys
+import tempfile
+from textwrap import dedent
+
+class ShaderCompileError(RuntimeError):
+    def __init__(self, *args):
+        super(ShaderCompileError, self).__init__(*args)
+
+class Shader:
+    def __init__(self, stage, infname):
+        self.stage = stage
+        self.infname = infname
+        self.dwords = None
+        self.var_prefix = os.path.basename(infname).replace('.', '_')
+
+    def __run_glslc(self, extra_args=[]):
+        stage_flag = '-fshader-stage=' + self.stage
+
+        with subprocess.Popen([glslc] + extra_args +
+                              [stage_flag, '-std=430core', '-o', '-',
+                               self.infname],
+                              stdout = subprocess.PIPE,
+                              stderr = subprocess.PIPE,
+                              stdin = subprocess.PIPE) as proc:
+
+            out, err = proc.communicate(timeout=30)
+
+            if proc.returncode != 0:
+                # Unfortunately, glslang dumps errors to standard out.
+                # However, since we don't really want to count on that,
+                # we'll grab the output of both
+                message = out.decode('utf-8') + '\n' + err.decode('utf-8')
+                raise ShaderCompileError(message.strip())
+
+            return out
+
+    def compile(self):
+        def dwords(f):
+            while True:
+                dword_str = f.read(4)
+                if not dword_str:
+                    return
+                assert len(dword_str) == 4
+                yield struct.unpack('I', dword_str)[0]
+
+        spirv = self.__run_glslc()
+        self.dwords = list(dwords(io.BytesIO(spirv)))
+        self.assembly = str(self.__run_glslc(['-S']), 'utf-8')
+
+    def _dump_glsl_code(self, f, var_name):
+        # First dump the GLSL source as strings
+        f.write('static const char {0}[] ='.format(var_name))
+        f.write('\n    "#version 330\\n"')
+
+        infile = open_file(self.infname, 'r')
+        for line in infile:
+            f.write('\n    "{0}\\n"'.format(line.strip('\n')))
+        f.write(';\n\n')
+
+    def _dump_spirv_code(self, f, var_name):
+        f.write('/* SPIR-V Assembly:\n')
+        f.write(' *\n')
+        for line in self.assembly.splitlines():
+            f.write(' * ' + line + '\n')
+        f.write(' */\n')
+
+        f.write('static const uint32_t {0}[] = {{'.format(var_name))
+        line_start = 0
+        while line_start < len(self.dwords):
+            f.write('\n    ')
+            for i in range(line_start, min(line_start + 6, len(self.dwords))):
+                f.write(' 0x{:08x},'.format(self.dwords[i]))
+            line_start += 6
+        f.write('\n};\n')
+
+    def dump_c_code(self, f):
+        self._dump_glsl_code(f, self.var_prefix + '_glsl_src')
+        self._dump_spirv_code(f, self.var_prefix + '_spir_v_src')
+
+def parse_args():
+    description = dedent("""\
+        This program compiles the given glsl source file into SPIR-V and
+        writes it to another C file as an array of 32-bit words.
+
+        If '-' is passed as the input file or output file, stdin or stdout
+        will be used instead of a file on disc.""")
+
+    p = argparse.ArgumentParser(
+            description=description,
+            formatter_class=argparse.RawDescriptionHelpFormatter)
+    p.add_argument('-o', '--outfile', default='-',
+                        help='Output to the given file (default: stdout).')
+    p.add_argument('--with-glslc', metavar='PATH',
+                        default='glslc',
+                        dest='glslc',
+                        help='Full path to the glslc shader compiler.')
+    p.add_argument('--stage', dest='stage')
+    p.add_argument('infile', metavar='INFILE')
+
+    return p.parse_args()
+
+def open_file(name, mode):
+    if name == '-':
+        if mode == 'w':
+            return sys.stdout
+        elif mode == 'r':
+            return sys.stdin
+        else:
+            assert False
+    else:
+        return open(name, mode)
+
+args = parse_args()
+outfname = args.outfile
+glslc = args.glslc
+
+shader = Shader(args.stage, args.infile)
+shader.compile()
+
+with open_file(outfname, 'w') as outfile:
+    outfile.write(dedent("""\
+        /* ==========================  DO NOT EDIT!  ========================
+         *  This file is autogenerated by compile_and_dump_glsl_as_spirv.py.
+         */
+
+        #include <stdint.h>
+
+        """))
+
+    shader.dump_c_code(outfile)
-- 
2.14.1



More information about the Piglit mailing list