[v3,02/39] utils: gen-shader-headers: Add a utility to generate headers from shaders
diff mbox series

Message ID 20251015012251.17508-3-bryan.odonoghue@linaro.org
State New
Headers show
Series
  • Add GLES 2.0 GPUISP to libcamera
Related show

Commit Message

Bryan O'Donoghue Oct. 15, 2025, 1:22 a.m. UTC
Two simple script to generate a header that contains GLSL shaders translated
to C arrays.

Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
---
 utils/gen-shader-header.py  | 38 ++++++++++++++++++++++++++++++++
 utils/gen-shader-headers.sh | 44 +++++++++++++++++++++++++++++++++++++
 2 files changed, 82 insertions(+)
 create mode 100755 utils/gen-shader-header.py
 create mode 100755 utils/gen-shader-headers.sh

Comments

Kieran Bingham Oct. 15, 2025, 7:35 p.m. UTC | #1
Quoting Bryan O'Donoghue (2025-10-15 02:22:14)
> Two simple script to generate a header that contains GLSL shaders translated
> to C arrays.
> 
> Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
> ---
>  utils/gen-shader-header.py  | 38 ++++++++++++++++++++++++++++++++
>  utils/gen-shader-headers.sh | 44 +++++++++++++++++++++++++++++++++++++
>  2 files changed, 82 insertions(+)
>  create mode 100755 utils/gen-shader-header.py
>  create mode 100755 utils/gen-shader-headers.sh
> 
> diff --git a/utils/gen-shader-header.py b/utils/gen-shader-header.py
> new file mode 100755
> index 00000000..6668e648
> --- /dev/null
> +++ b/utils/gen-shader-header.py
> @@ -0,0 +1,38 @@
> +#!/usr/bin/env python3
> +# SPDX-License-Identifier: GPL-2.0-or-later
> +# Copyright (C) 2025, Bryan O'Donoghue.
> +#
> +# Author: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
> +#
> +# A python script which takes a list of shader files and converts into a C
> +# header.
> +#
> +import sys
> +
> +try:
> +    with open(sys.argv[2]) as file:
> +        data = file.read()
> +        data_len = len(data)
> +
> +        name = sys.argv[1].replace(".", "_")
> +        name_len = name + "_len"
> +
> +        j = 0
> +        print("unsigned char", name, "[] = {")
> +        for ch in data:
> +            print(f"0x{ord(ch):02x}, ", end="")
> +            j = j + 1
> +            if j == 16:
> +                print()
> +                j = 0
> +        if j != 0:
> +            print()
> +        print("};")
> +
> +        print()
> +        print(f"const unsigned int {name_len}={data_len};")
> +
> +except FileNotFoundError:
> +    print(f"File {sys.argv[2]} not found", file=sys.stderr)
> +except IOError:
> +    print(f"Unable to read {sys.argv[2]}", file=sys.stderr)
> diff --git a/utils/gen-shader-headers.sh b/utils/gen-shader-headers.sh
> new file mode 100755
> index 00000000..ca4f19f0
> --- /dev/null
> +++ b/utils/gen-shader-headers.sh
> @@ -0,0 +1,44 @@
> +#!/bin/sh
> +set -x
> +
> +if [ $# -lt 4 ]; then
> +       echo "Invalid arg count must be >= 5"


Maybe this help should explain what the arguments are expected to be  ?

> +       exit 1
> +fi
> +src_dir="$1"; shift
> +build_dir="$1"; shift
> +build_path=$build_dir/"$1"; shift
> +
> +cat <<EOF > "$build_path"
> +/* SPDX-License-Identifier: LGPL-2.1-or-later */
> +/* This file is auto-generated, do not edit! */
> +/*
> + * Copyright (C) 2025, Linaro Ltd.
> + *
> + */
> +
> +#pragma once
> +
> +EOF
> +
> +cat <<EOF >> "$build_path"

This EOF ... then re-opening the cat  <<EOF seems redundant... ?


But aside from those:

Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>

> +/*
> + * List the names of the shaders at the top of
> + * header for readability's sake
> + *
> +EOF
> +
> +for file in "$@"; do
> +       echo "file is $file"
> +       name=$(basename "$build_dir/$file" | tr '.' '_')
> +       echo " * unsigned char $name;" >> "$build_path"
> +done
> +
> +echo "*/" >> "$build_path"
> +
> +echo "/* Hex encoded shader data */" >> "$build_path"
> +for file in "$@"; do
> +       name=$(basename "$build_dir/$file")
> +       "$src_dir/utils/gen-shader-header.py" "$name" "$build_dir/$file" >> "$build_path"
> +       echo >> "$build_path"
> +done
> -- 
> 2.51.0
>
Kieran Bingham Oct. 15, 2025, 7:37 p.m. UTC | #2
Quoting Kieran Bingham (2025-10-15 20:35:36)
> Quoting Bryan O'Donoghue (2025-10-15 02:22:14)
> > Two simple script to generate a header that contains GLSL shaders translated
> > to C arrays.
> > 
> > Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
> > ---
> >  utils/gen-shader-header.py  | 38 ++++++++++++++++++++++++++++++++
> >  utils/gen-shader-headers.sh | 44 +++++++++++++++++++++++++++++++++++++
> >  2 files changed, 82 insertions(+)
> >  create mode 100755 utils/gen-shader-header.py
> >  create mode 100755 utils/gen-shader-headers.sh
> > 
> > diff --git a/utils/gen-shader-header.py b/utils/gen-shader-header.py
> > new file mode 100755
> > index 00000000..6668e648
> > --- /dev/null
> > +++ b/utils/gen-shader-header.py
> > @@ -0,0 +1,38 @@
> > +#!/usr/bin/env python3
> > +# SPDX-License-Identifier: GPL-2.0-or-later
> > +# Copyright (C) 2025, Bryan O'Donoghue.
> > +#
> > +# Author: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
> > +#
> > +# A python script which takes a list of shader files and converts into a C
> > +# header.
> > +#
> > +import sys
> > +
> > +try:
> > +    with open(sys.argv[2]) as file:
> > +        data = file.read()
> > +        data_len = len(data)
> > +
> > +        name = sys.argv[1].replace(".", "_")
> > +        name_len = name + "_len"
> > +
> > +        j = 0
> > +        print("unsigned char", name, "[] = {")
> > +        for ch in data:
> > +            print(f"0x{ord(ch):02x}, ", end="")
> > +            j = j + 1
> > +            if j == 16:
> > +                print()
> > +                j = 0
> > +        if j != 0:
> > +            print()
> > +        print("};")
> > +
> > +        print()
> > +        print(f"const unsigned int {name_len}={data_len};")
> > +
> > +except FileNotFoundError:
> > +    print(f"File {sys.argv[2]} not found", file=sys.stderr)
> > +except IOError:
> > +    print(f"Unable to read {sys.argv[2]}", file=sys.stderr)
> > diff --git a/utils/gen-shader-headers.sh b/utils/gen-shader-headers.sh
> > new file mode 100755
> > index 00000000..ca4f19f0
> > --- /dev/null
> > +++ b/utils/gen-shader-headers.sh
> > @@ -0,0 +1,44 @@
> > +#!/bin/sh
> > +set -x
> > +
> > +if [ $# -lt 4 ]; then
> > +       echo "Invalid arg count must be >= 5"
> 
> 
> Maybe this help should explain what the arguments are expected to be  ?

Also - it looks like the arguments should currently be 'exactly' 5 - not
greater than four ?
So perhaps

if [ $# -ne 5 ];

 ...

--
Kieran
Milan Zamazal Oct. 16, 2025, 7:20 a.m. UTC | #3
Hi Bryan,

my comments from v1 still apply:

https://lists.libcamera.org/pipermail/libcamera-devel/2025-June/050896.html

Bryan O'Donoghue <bryan.odonoghue@linaro.org> writes:

> Two simple script to generate a header that contains GLSL shaders translated
> to C arrays.
>
> Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
> ---
>  utils/gen-shader-header.py  | 38 ++++++++++++++++++++++++++++++++
>  utils/gen-shader-headers.sh | 44 +++++++++++++++++++++++++++++++++++++
>  2 files changed, 82 insertions(+)
>  create mode 100755 utils/gen-shader-header.py
>  create mode 100755 utils/gen-shader-headers.sh
>
> diff --git a/utils/gen-shader-header.py b/utils/gen-shader-header.py
> new file mode 100755
> index 00000000..6668e648
> --- /dev/null
> +++ b/utils/gen-shader-header.py
> @@ -0,0 +1,38 @@
> +#!/usr/bin/env python3
> +# SPDX-License-Identifier: GPL-2.0-or-later
> +# Copyright (C) 2025, Bryan O'Donoghue.
> +#
> +# Author: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
> +#
> +# A python script which takes a list of shader files and converts into a C
> +# header.
> +#
> +import sys
> +
> +try:
> +    with open(sys.argv[2]) as file:
> +        data = file.read()
> +        data_len = len(data)
> +
> +        name = sys.argv[1].replace(".", "_")
> +        name_len = name + "_len"
> +
> +        j = 0
> +        print("unsigned char", name, "[] = {")
> +        for ch in data:
> +            print(f"0x{ord(ch):02x}, ", end="")
> +            j = j + 1
> +            if j == 16:
> +                print()
> +                j = 0
> +        if j != 0:
> +            print()
> +        print("};")
> +
> +        print()
> +        print(f"const unsigned int {name_len}={data_len};")
> +
> +except FileNotFoundError:
> +    print(f"File {sys.argv[2]} not found", file=sys.stderr)
> +except IOError:
> +    print(f"Unable to read {sys.argv[2]}", file=sys.stderr)
> diff --git a/utils/gen-shader-headers.sh b/utils/gen-shader-headers.sh
> new file mode 100755
> index 00000000..ca4f19f0
> --- /dev/null
> +++ b/utils/gen-shader-headers.sh
> @@ -0,0 +1,44 @@
> +#!/bin/sh
> +set -x
> +
> +if [ $# -lt 4 ]; then
> +	echo "Invalid arg count must be >= 5"
> +	exit 1
> +fi
> +src_dir="$1"; shift
> +build_dir="$1"; shift
> +build_path=$build_dir/"$1"; shift
> +
> +cat <<EOF > "$build_path"
> +/* SPDX-License-Identifier: LGPL-2.1-or-later */
> +/* This file is auto-generated, do not edit! */
> +/*
> + * Copyright (C) 2025, Linaro Ltd.
> + *
> + */
> +
> +#pragma once
> +
> +EOF
> +
> +cat <<EOF >> "$build_path"
> +/*
> + * List the names of the shaders at the top of
> + * header for readability's sake
> + *
> +EOF
> +
> +for file in "$@"; do
> +	echo "file is $file"
> +	name=$(basename "$build_dir/$file" | tr '.' '_')
> +	echo " * unsigned char $name;" >> "$build_path"
> +done
> +
> +echo "*/" >> "$build_path"
> +
> +echo "/* Hex encoded shader data */" >> "$build_path"
> +for file in "$@"; do
> +	name=$(basename "$build_dir/$file")
> +	"$src_dir/utils/gen-shader-header.py" "$name" "$build_dir/$file" >> "$build_path"
> +	echo >> "$build_path"
> +done

Patch
diff mbox series

diff --git a/utils/gen-shader-header.py b/utils/gen-shader-header.py
new file mode 100755
index 00000000..6668e648
--- /dev/null
+++ b/utils/gen-shader-header.py
@@ -0,0 +1,38 @@ 
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (C) 2025, Bryan O'Donoghue.
+#
+# Author: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+#
+# A python script which takes a list of shader files and converts into a C
+# header.
+#
+import sys
+
+try:
+    with open(sys.argv[2]) as file:
+        data = file.read()
+        data_len = len(data)
+
+        name = sys.argv[1].replace(".", "_")
+        name_len = name + "_len"
+
+        j = 0
+        print("unsigned char", name, "[] = {")
+        for ch in data:
+            print(f"0x{ord(ch):02x}, ", end="")
+            j = j + 1
+            if j == 16:
+                print()
+                j = 0
+        if j != 0:
+            print()
+        print("};")
+
+        print()
+        print(f"const unsigned int {name_len}={data_len};")
+
+except FileNotFoundError:
+    print(f"File {sys.argv[2]} not found", file=sys.stderr)
+except IOError:
+    print(f"Unable to read {sys.argv[2]}", file=sys.stderr)
diff --git a/utils/gen-shader-headers.sh b/utils/gen-shader-headers.sh
new file mode 100755
index 00000000..ca4f19f0
--- /dev/null
+++ b/utils/gen-shader-headers.sh
@@ -0,0 +1,44 @@ 
+#!/bin/sh
+set -x
+
+if [ $# -lt 4 ]; then
+	echo "Invalid arg count must be >= 5"
+	exit 1
+fi
+src_dir="$1"; shift
+build_dir="$1"; shift
+build_path=$build_dir/"$1"; shift
+
+cat <<EOF > "$build_path"
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/* This file is auto-generated, do not edit! */
+/*
+ * Copyright (C) 2025, Linaro Ltd.
+ *
+ */
+
+#pragma once
+
+EOF
+
+cat <<EOF >> "$build_path"
+/*
+ * List the names of the shaders at the top of
+ * header for readability's sake
+ *
+EOF
+
+for file in "$@"; do
+	echo "file is $file"
+	name=$(basename "$build_dir/$file" | tr '.' '_')
+	echo " * unsigned char $name;" >> "$build_path"
+done
+
+echo "*/" >> "$build_path"
+
+echo "/* Hex encoded shader data */" >> "$build_path"
+for file in "$@"; do
+	name=$(basename "$build_dir/$file")
+	"$src_dir/utils/gen-shader-header.py" "$name" "$build_dir/$file" >> "$build_path"
+	echo >> "$build_path"
+done