diff options
Diffstat (limited to 'glsl_builders.py')
| -rw-r--r-- | glsl_builders.py | 225 | 
1 files changed, 225 insertions, 0 deletions
diff --git a/glsl_builders.py b/glsl_builders.py new file mode 100644 index 0000000000..af9afcae70 --- /dev/null +++ b/glsl_builders.py @@ -0,0 +1,225 @@ +"""Functions used to generate source files during build time + +All such functions are invoked in a subprocess on Windows to prevent build flakiness. + +""" +from platform_methods import subprocess_main + + +class RDHeaderStruct: +    def __init__(self): +        self.vertex_lines = [] +        self.fragment_lines = [] +        self.compute_lines = [] + +        self.vertex_included_files = [] +        self.fragment_included_files = [] +        self.compute_included_files = [] + +        self.reading = "" +        self.line_offset = 0 +        self.vertex_offset = 0 +        self.fragment_offset = 0 +        self.compute_offset = 0 + + +def include_file_in_rd_header(filename, header_data, depth): +    fs = open(filename, "r") +    line = fs.readline() + +    while line: + +        if line.find("#[vertex]") != -1: +            header_data.reading = "vertex" +            line = fs.readline() +            header_data.line_offset += 1 +            header_data.vertex_offset = header_data.line_offset +            continue + +        if line.find("#[fragment]") != -1: +            header_data.reading = "fragment" +            line = fs.readline() +            header_data.line_offset += 1 +            header_data.fragment_offset = header_data.line_offset +            continue + +        if line.find("#[compute]") != -1: +            header_data.reading = "compute" +            line = fs.readline() +            header_data.line_offset += 1 +            header_data.compute_offset = header_data.line_offset +            continue + +        while line.find("#include ") != -1: +            includeline = line.replace("#include ", "").strip()[1:-1] + +            import os.path + +            included_file = os.path.relpath(os.path.dirname(filename) + "/" + includeline) +            if not included_file in header_data.vertex_included_files and header_data.reading == "vertex": +                header_data.vertex_included_files += [included_file] +                if include_file_in_rd_header(included_file, header_data, depth + 1) is None: +                    print("Error in file '" + filename + "': #include " + includeline + "could not be found!") +            elif not included_file in header_data.fragment_included_files and header_data.reading == "fragment": +                header_data.fragment_included_files += [included_file] +                if include_file_in_rd_header(included_file, header_data, depth + 1) is None: +                    print("Error in file '" + filename + "': #include " + includeline + "could not be found!") +            elif not included_file in header_data.compute_included_files and header_data.reading == "compute": +                header_data.compute_included_files += [included_file] +                if include_file_in_rd_header(included_file, header_data, depth + 1) is None: +                    print("Error in file '" + filename + "': #include " + includeline + "could not be found!") + +            line = fs.readline() + +        line = line.replace("\r", "") +        line = line.replace("\n", "") + +        if header_data.reading == "vertex": +            header_data.vertex_lines += [line] +        if header_data.reading == "fragment": +            header_data.fragment_lines += [line] +        if header_data.reading == "compute": +            header_data.compute_lines += [line] + +        line = fs.readline() +        header_data.line_offset += 1 + +    fs.close() + +    return header_data + + +def build_rd_header(filename): +    header_data = RDHeaderStruct() +    include_file_in_rd_header(filename, header_data, 0) + +    out_file = filename + ".gen.h" +    fd = open(out_file, "w") + +    enum_constants = [] + +    fd.write("/* WARNING, THIS FILE WAS GENERATED, DO NOT EDIT */\n") + +    out_file_base = out_file +    out_file_base = out_file_base[out_file_base.rfind("/") + 1 :] +    out_file_base = out_file_base[out_file_base.rfind("\\") + 1 :] +    out_file_ifdef = out_file_base.replace(".", "_").upper() +    fd.write("#ifndef " + out_file_ifdef + "_RD\n") +    fd.write("#define " + out_file_ifdef + "_RD\n") + +    out_file_class = out_file_base.replace(".glsl.gen.h", "").title().replace("_", "").replace(".", "") + "ShaderRD" +    fd.write("\n") +    fd.write('#include "servers/rendering/rasterizer_rd/shader_rd.h"\n\n') +    fd.write("class " + out_file_class + " : public ShaderRD {\n\n") +    fd.write("public:\n\n") + +    fd.write("\t" + out_file_class + "() {\n\n") + +    if len(header_data.compute_lines): + +        fd.write("\t\tstatic const char _compute_code[] = {\n") +        for x in header_data.compute_lines: +            for c in x: +                fd.write(str(ord(c)) + ",") +            fd.write(str(ord("\n")) + ",") +        fd.write("\t\t0};\n\n") + +        fd.write('\t\tsetup(nullptr, nullptr, _compute_code, "' + out_file_class + '");\n') +        fd.write("\t}\n") + +    else: + +        fd.write("\t\tstatic const char _vertex_code[] = {\n") +        for x in header_data.vertex_lines: +            for c in x: +                fd.write(str(ord(c)) + ",") +            fd.write(str(ord("\n")) + ",") +        fd.write("\t\t0};\n\n") + +        fd.write("\t\tstatic const char _fragment_code[]={\n") +        for x in header_data.fragment_lines: +            for c in x: +                fd.write(str(ord(c)) + ",") +            fd.write(str(ord("\n")) + ",") +        fd.write("\t\t0};\n\n") + +        fd.write('\t\tsetup(_vertex_code, _fragment_code, nullptr, "' + out_file_class + '");\n') +        fd.write("\t}\n") + +    fd.write("};\n\n") + +    fd.write("#endif\n") +    fd.close() + + +def build_rd_headers(target, source, env): +    for x in source: +        build_rd_header(str(x)) + + +class RAWHeaderStruct: +    def __init__(self): +        self.code = "" + + +def include_file_in_raw_header(filename, header_data, depth): +    fs = open(filename, "r") +    line = fs.readline() +    text = "" + +    while line: + +        while line.find("#include ") != -1: +            includeline = line.replace("#include ", "").strip()[1:-1] + +            import os.path + +            included_file = os.path.relpath(os.path.dirname(filename) + "/" + includeline) +            include_file_in_raw_header(included_file, header_data, depth + 1) + +            line = fs.readline() + +        header_data.code += line +        line = fs.readline() + +    fs.close() + + +def build_raw_header(filename): +    header_data = RAWHeaderStruct() +    include_file_in_raw_header(filename, header_data, 0) + +    out_file = filename + ".gen.h" +    fd = open(out_file, "w") + +    enum_constants = [] + +    fd.write("/* WARNING, THIS FILE WAS GENERATED, DO NOT EDIT */\n") + +    out_file_base = out_file.replace(".glsl.gen.h", "_shader_glsl") +    out_file_base = out_file_base[out_file_base.rfind("/") + 1 :] +    out_file_base = out_file_base[out_file_base.rfind("\\") + 1 :] +    out_file_ifdef = out_file_base.replace(".", "_").upper() +    fd.write("#ifndef " + out_file_ifdef + "_RAW_H\n") +    fd.write("#define " + out_file_ifdef + "_RAW_H\n") +    fd.write("\n") +    fd.write("static const char " + out_file_base + "[] = {\n") +    for c in header_data.code: +        fd.write(str(ord(c)) + ",") +    fd.write("\t\t0};\n\n") +    fd.write("#endif\n") +    fd.close() + + +def build_rd_headers(target, source, env): +    for x in source: +        build_rd_header(str(x)) + + +def build_raw_headers(target, source, env): +    for x in source: +        build_raw_header(str(x)) + + +if __name__ == "__main__": +    subprocess_main(globals())  |