From d913363394fb8f9213a7627ee7b1c7b68b0287ec Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Wed, 25 Nov 2020 13:22:26 +0200 Subject: [PATCH] gl-renderer: move vertex shader into new file This patch adds the tooling for incorporating files as C data, so that files can be built into the binaries. The tool is in Python to avoid adding extra dependencies like xxd. xxd.py is copied from Mesa as-is, from commit b729cd58d76f97f3fc04a67569535ee5ef2f5278 (master branch on 2021-01-26), a.k.a 21.0-branchpoint-635-gb729cd58d76. Moving the GLSL vertex shader into a separate file is not that interesting, the purpose of this commit is to provide a simple demonstration of the tooling. The real benefits come in a following patch where the fragment shaders are re-written and externalized. Signed-off-by: Pekka Paalanen --- libweston/renderer-gl/gl-shaders.c | 12 +--- libweston/renderer-gl/meson.build | 8 +++ libweston/renderer-gl/vertex.glsl | 37 +++++++++++ meson.build | 4 ++ tools/xxd.py | 100 +++++++++++++++++++++++++++++ 5 files changed, 151 insertions(+), 10 deletions(-) create mode 100644 libweston/renderer-gl/vertex.glsl create mode 100644 tools/xxd.py diff --git a/libweston/renderer-gl/gl-shaders.c b/libweston/renderer-gl/gl-shaders.c index c1f454e3..9199abab 100644 --- a/libweston/renderer-gl/gl-shaders.c +++ b/libweston/renderer-gl/gl-shaders.c @@ -32,16 +32,8 @@ #include "gl-renderer.h" #include "gl-renderer-internal.h" -static const char vertex_shader[] = - "uniform mat4 proj;\n" - "attribute vec2 position;\n" - "attribute vec2 texcoord;\n" - "varying vec2 v_texcoord;\n" - "void main()\n" - "{\n" - " gl_Position = proj * vec4(position, 0.0, 1.0);\n" - " v_texcoord = texcoord;\n" - "}\n"; +/* static const char vertex_shader[]; vertex.glsl */ +#include "vertex-shader.h" /* Declare common fragment shader uniforms */ #define FRAGMENT_CONVERT_YUV \ diff --git a/libweston/renderer-gl/meson.build b/libweston/renderer-gl/meson.build index f2f58fac..4687b5b0 100644 --- a/libweston/renderer-gl/meson.build +++ b/libweston/renderer-gl/meson.build @@ -4,12 +4,20 @@ endif config_h.set('ENABLE_EGL', '1') +vertex_glsl = custom_target( + 'vertex-shader.h', + command: cmd_xxd + [ '-n', 'vertex_shader' ], + input: 'vertex.glsl', + output: 'vertex-shader.h', +) + srcs_renderer_gl = [ 'egl-glue.c', 'gl-renderer.c', 'gl-shaders.c', linux_dmabuf_unstable_v1_protocol_c, linux_dmabuf_unstable_v1_server_protocol_h, + vertex_glsl, ] deps_renderer_gl = [ diff --git a/libweston/renderer-gl/vertex.glsl b/libweston/renderer-gl/vertex.glsl new file mode 100644 index 00000000..03282e33 --- /dev/null +++ b/libweston/renderer-gl/vertex.glsl @@ -0,0 +1,37 @@ +/* + * Copyright 2012 Intel Corporation + * Copyright 2015,2019 Collabora, Ltd. + * Copyright 2016 NVIDIA 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. + */ + +uniform mat4 proj; +attribute vec2 position; +attribute vec2 texcoord; +varying vec2 v_texcoord; + +void main() +{ + gl_Position = proj * vec4(position, 0.0, 1.0); + v_texcoord = texcoord; +} diff --git a/meson.build b/meson.build index fa828e4c..1b5c2e00 100644 --- a/meson.build +++ b/meson.build @@ -149,6 +149,10 @@ dep_libdrm = dependency('libdrm', version: '>= 2.4.95') dep_libdrm_headers = dep_libdrm.partial_dependency(compile_args: true) dep_threads = dependency('threads') +prog_python = import('python').find_installation('python3') +files_xxd_py = files('tools/xxd.py') +cmd_xxd = [ prog_python, files_xxd_py, '@INPUT@', '@OUTPUT@' ] + subdir('include') subdir('protocol') subdir('shared') diff --git a/tools/xxd.py b/tools/xxd.py new file mode 100644 index 00000000..efff14d1 --- /dev/null +++ b/tools/xxd.py @@ -0,0 +1,100 @@ +# encoding=utf-8 +# Copyright © 2018 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. + +# Converts a file to a C/C++ #include containing a string + +from __future__ import unicode_literals +import argparse +import io +import os + + +def get_args(): + parser = argparse.ArgumentParser() + parser.add_argument('input', help="Name of input file") + parser.add_argument('output', help="Name of output file") + parser.add_argument("-n", "--name", + help="Name of C variable") + parser.add_argument("-b", "--binary", dest='binary', action='store_const', + const=True, default=False) + args = parser.parse_args() + return args + + +def filename_to_C_identifier(n): + if n[0] != '_' and not n[0].isalpha(): + n = "_" + n[1:] + + return "".join([c if c.isalnum() or c == "_" else "_" for c in n]) + + +def emit_byte(f, b): + f.write("0x{:02x}, ".format(ord(b)).encode('utf-8')) + + +def process_file(args): + with io.open(args.input, "rb") as infile: + try: + with io.open(args.output, "wb") as outfile: + # If a name was not specified on the command line, pick one based on the + # name of the input file. If no input filename was specified, use + # from_stdin. + if args.name is not None: + name = args.name + else: + name = filename_to_C_identifier(args.input) + + outfile.write("static const char {}[] = {{\n".format(name).encode('utf-8')) + + linecount = 0 + while True: + byte = infile.read(1) + if byte == b"": + break + + if not args.binary: + assert(ord(byte) != 0) + + emit_byte(outfile, byte) + linecount = linecount + 1 + if linecount > 20: + outfile.write(b"\n ") + linecount = 0 + if not args.binary: + outfile.write(b"\n0") + outfile.write(b"\n};\n\n") + except Exception: + # In the event that anything goes wrong, delete the output file, + # then re-raise the exception. Deleteing the output file should + # ensure that the build system doesn't try to use the stale, + # half-generated file. + os.unlink(args.output) + raise + + +def main(): + args = get_args() + process_file(args) + + +if __name__ == "__main__": + main()