From 32de6285a857d92983cba8aae55bc1ffb1d10c62 Mon Sep 17 00:00:00 2001 From: Thaddeus Crews Date: Tue, 18 Mar 2025 12:07:23 -0500 Subject: [PATCH] SCons: Modernize shader builders --- gles3_builders.py | 607 ++++++++---------- glsl_builders.py | 109 ++-- methods.py | 14 +- .../fixtures/gles3/vertex_fragment.out | 41 +- tests/python_build/fixtures/glsl/compute.out | 3 - .../fixtures/glsl/vertex_fragment.out | 3 - .../python_build/fixtures/rd_glsl/compute.out | 10 +- .../fixtures/rd_glsl/vertex_fragment.out | 9 +- 8 files changed, 339 insertions(+), 457 deletions(-) diff --git a/gles3_builders.py b/gles3_builders.py index d7e9edee568..c10af00024e 100644 --- a/gles3_builders.py +++ b/gles3_builders.py @@ -1,9 +1,8 @@ """Functions used to generate source files during build time""" import os.path -from typing import Optional -from methods import print_error, to_raw_cstring +from methods import generated_wrapper, print_error, to_raw_cstring class GLES3HeaderStruct: @@ -189,399 +188,333 @@ def include_file_in_gles3_header(filename: str, header_data: GLES3HeaderStruct, return header_data -def build_gles3_header( - filename: str, - include: str, - class_suffix: str, - optional_output_filename: Optional[str] = None, - header_data: Optional[GLES3HeaderStruct] = None, -): - header_data = header_data or GLES3HeaderStruct() - include_file_in_gles3_header(filename, header_data, 0) +def build_gles3_header(filename: str, shader: str) -> None: + include_file_in_gles3_header(shader, header_data := GLES3HeaderStruct(), 0) + out_file_class = ( + os.path.basename(shader).replace(".glsl", "").title().replace("_", "").replace(".", "") + "ShaderGLES3" + ) - if optional_output_filename is None: - out_file = filename + ".gen.h" - else: - out_file = optional_output_filename - - with open(out_file, "w", encoding="utf-8", newline="\n") as fd: + with generated_wrapper(filename) as file: defspec = 0 defvariant = "" - fd.write("/* WARNING, THIS FILE WAS GENERATED, DO NOT EDIT */\n") - fd.write("#pragma once\n") + file.write(f"""\ +#include "drivers/gles3/shader_gles3.h" - 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_class = ( - out_file_base.replace(".glsl.gen.h", "").title().replace("_", "").replace(".", "") + "Shader" + class_suffix - ) - fd.write("\n\n") - fd.write('#include "' + include + '"\n\n\n') - fd.write("class " + out_file_class + " : public Shader" + class_suffix + " {\n\n") - - fd.write("public:\n\n") +class {out_file_class} : public ShaderGLES3 {{ +public: +""") if header_data.uniforms: - fd.write("\tenum Uniforms {\n") - for x in header_data.uniforms: - fd.write("\t\t" + x.upper() + ",\n") - fd.write("\t};\n\n") + uniforms = ",\n\t\t".join(uniform.upper() for uniform in header_data.uniforms) + file.write(f"""\ + enum Uniforms {{ + {uniforms}, + }}; + +""") if header_data.variant_names: - fd.write("\tenum ShaderVariant {\n") - for x in header_data.variant_names: - fd.write("\t\t" + x + ",\n") - fd.write("\t};\n\n") + variant_names = ",\n\t\t".join(name for name in header_data.variant_names) else: - fd.write("\tenum ShaderVariant { DEFAULT };\n\n") - defvariant = "=DEFAULT" + variant_names = "DEFAULT" + defvariant = " = DEFAULT" + file.write(f"""\ + enum ShaderVariant {{ + {variant_names}, + }}; + +""") if header_data.specialization_names: - fd.write("\tenum Specializations {\n") - counter = 0 - for x in header_data.specialization_names: - fd.write("\t\t" + x.upper() + "=" + str(1 << counter) + ",\n") - counter += 1 - fd.write("\t};\n\n") + specialization_names = ",\n\t\t".join( + f"{name.upper()} = {1 << index}" for index, name in enumerate(header_data.specialization_names) + ) + file.write(f"""\ + enum Specializations {{ + {specialization_names}, + }}; - for i in range(len(header_data.specialization_names)): - defval = header_data.specialization_values[i].strip() - if defval.upper() == "TRUE" or defval == "1": - defspec |= 1 << i +""") + for index, specialization_value in enumerate(header_data.specialization_values): + if specialization_value.strip().upper() in ["TRUE", "1"]: + defspec |= 1 << index - fd.write( - "\t_FORCE_INLINE_ bool version_bind_shader(RID p_version,ShaderVariant p_variant" - + defvariant - + ",uint64_t p_specialization=" - + str(defspec) - + ") { return _version_bind_shader(p_version,p_variant,p_specialization); }\n\n" - ) + file.write(f"""\ + _FORCE_INLINE_ bool version_bind_shader(RID p_version, ShaderVariant p_variant{defvariant}, uint64_t p_specialization = {defspec}) {{ + return _version_bind_shader(p_version, p_variant, p_specialization); + }} + +""") if header_data.uniforms: - fd.write( - "\t_FORCE_INLINE_ int version_get_uniform(Uniforms p_uniform,RID p_version,ShaderVariant p_variant" - + defvariant - + ",uint64_t p_specialization=" - + str(defspec) - + ") { return _version_get_uniform(p_uniform,p_version,p_variant,p_specialization); }\n\n" - ) + file.write(f"""\ + _FORCE_INLINE_ int version_get_uniform(Uniforms p_uniform, RID p_version, ShaderVariant p_variant{defvariant}, uint64_t p_specialization = {defspec}) {{ + return _version_get_uniform(p_uniform, p_version, p_variant, p_specialization); + }} - fd.write( - "\t#define _FU if (version_get_uniform(p_uniform,p_version,p_variant,p_specialization)<0) return; \n\n " - ) - fd.write( - "\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, float p_value,RID p_version,ShaderVariant p_variant" - + defvariant - + ",uint64_t p_specialization=" - + str(defspec) - + ") { _FU glUniform1f(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),p_value); }\n\n" - ) - fd.write( - "\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, double p_value,RID p_version,ShaderVariant p_variant" - + defvariant - + ",uint64_t p_specialization=" - + str(defspec) - + ") { _FU glUniform1f(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),p_value); }\n\n" - ) - fd.write( - "\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, uint8_t p_value,RID p_version,ShaderVariant p_variant" - + defvariant - + ",uint64_t p_specialization=" - + str(defspec) - + ") { _FU glUniform1ui(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),p_value); }\n\n" - ) - fd.write( - "\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, int8_t p_value,RID p_version,ShaderVariant p_variant" - + defvariant - + ",uint64_t p_specialization=" - + str(defspec) - + ") { _FU glUniform1i(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),p_value); }\n\n" - ) - fd.write( - "\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, uint16_t p_value,RID p_version,ShaderVariant p_variant" - + defvariant - + ",uint64_t p_specialization=" - + str(defspec) - + ") { _FU glUniform1ui(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),p_value); }\n\n" - ) - fd.write( - "\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, int16_t p_value,RID p_version,ShaderVariant p_variant" - + defvariant - + ",uint64_t p_specialization=" - + str(defspec) - + ") { _FU glUniform1i(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),p_value); }\n\n" - ) - fd.write( - "\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, uint32_t p_value,RID p_version,ShaderVariant p_variant" - + defvariant - + ",uint64_t p_specialization=" - + str(defspec) - + ") { _FU glUniform1ui(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),p_value); }\n\n" - ) - fd.write( - "\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, int32_t p_value,RID p_version,ShaderVariant p_variant" - + defvariant - + ",uint64_t p_specialization=" - + str(defspec) - + ") { _FU glUniform1i(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),p_value); }\n\n" - ) - fd.write( - "\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, const Color& p_color,RID p_version,ShaderVariant p_variant" - + defvariant - + ",uint64_t p_specialization=" - + str(defspec) - + ") { _FU GLfloat col[4]={p_color.r,p_color.g,p_color.b,p_color.a}; glUniform4fv(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),1,col); }\n\n" - ) - fd.write( - "\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, const Vector2& p_vec2,RID p_version,ShaderVariant p_variant" - + defvariant - + ",uint64_t p_specialization=" - + str(defspec) - + ") { _FU GLfloat vec2[2]={float(p_vec2.x),float(p_vec2.y)}; glUniform2fv(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),1,vec2); }\n\n" - ) - fd.write( - "\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, const Size2i& p_vec2,RID p_version,ShaderVariant p_variant" - + defvariant - + ",uint64_t p_specialization=" - + str(defspec) - + ") { _FU GLint vec2[2]={GLint(p_vec2.x),GLint(p_vec2.y)}; glUniform2iv(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),1,vec2); }\n\n" - ) - fd.write( - "\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, const Vector3& p_vec3,RID p_version,ShaderVariant p_variant" - + defvariant - + ",uint64_t p_specialization=" - + str(defspec) - + ") { _FU GLfloat vec3[3]={float(p_vec3.x),float(p_vec3.y),float(p_vec3.z)}; glUniform3fv(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),1,vec3); }\n\n" - ) - fd.write( - "\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, const Vector4& p_vec4,RID p_version,ShaderVariant p_variant" - + defvariant - + ",uint64_t p_specialization=" - + str(defspec) - + ") { _FU GLfloat vec4[4]={float(p_vec4.x),float(p_vec4.y),float(p_vec4.z),float(p_vec4.w)}; glUniform4fv(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),1,vec4); }\n\n" - ) - fd.write( - "\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, float p_a, float p_b,RID p_version,ShaderVariant p_variant" - + defvariant - + ",uint64_t p_specialization=" - + str(defspec) - + ") { _FU glUniform2f(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),p_a,p_b); }\n\n" - ) - fd.write( - "\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, float p_a, float p_b, float p_c,RID p_version,ShaderVariant p_variant" - + defvariant - + ",uint64_t p_specialization=" - + str(defspec) - + ") { _FU glUniform3f(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),p_a,p_b,p_c); }\n\n" - ) - fd.write( - "\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, float p_a, float p_b, float p_c, float p_d,RID p_version,ShaderVariant p_variant" - + defvariant - + ",uint64_t p_specialization=" - + str(defspec) - + ") { _FU glUniform4f(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),p_a,p_b,p_c,p_d); }\n\n" - ) + /* clang-format off */ +#define TRY_GET_UNIFORM if (version_get_uniform(p_uniform, p_version, p_variant, p_specialization) < 0) return + /* clang-format on */ - fd.write( - """\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, const Transform3D& p_transform,RID p_version,ShaderVariant p_variant""" - + defvariant - + """,uint64_t p_specialization=""" - + str(defspec) - + """) { _FU + _FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, float p_value, RID p_version, ShaderVariant p_variant{defvariant}, uint64_t p_specialization = {defspec}) {{ + TRY_GET_UNIFORM; + glUniform1f(version_get_uniform(p_uniform, p_version, p_variant, p_specialization), p_value); + }} - const Transform3D &tr = p_transform; + _FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, double p_value, RID p_version, ShaderVariant p_variant{defvariant}, uint64_t p_specialization = {defspec}) {{ + TRY_GET_UNIFORM; + glUniform1f(version_get_uniform(p_uniform, p_version, p_variant, p_specialization), p_value); + }} - GLfloat matrix[16]={ /* build a 16x16 matrix */ - (GLfloat)tr.basis.rows[0][0], - (GLfloat)tr.basis.rows[1][0], - (GLfloat)tr.basis.rows[2][0], - (GLfloat)0, - (GLfloat)tr.basis.rows[0][1], - (GLfloat)tr.basis.rows[1][1], - (GLfloat)tr.basis.rows[2][1], - (GLfloat)0, - (GLfloat)tr.basis.rows[0][2], - (GLfloat)tr.basis.rows[1][2], - (GLfloat)tr.basis.rows[2][2], - (GLfloat)0, - (GLfloat)tr.origin.x, - (GLfloat)tr.origin.y, - (GLfloat)tr.origin.z, - (GLfloat)1 - }; + _FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, uint8_t p_value, RID p_version, ShaderVariant p_variant{defvariant}, uint64_t p_specialization = {defspec}) {{ + TRY_GET_UNIFORM; + glUniform1ui(version_get_uniform(p_uniform, p_version, p_variant, p_specialization), p_value); + }} - glUniformMatrix4fv(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),1,false,matrix); + _FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, int8_t p_value, RID p_version, ShaderVariant p_variant{defvariant}, uint64_t p_specialization = {defspec}) {{ + TRY_GET_UNIFORM; + glUniform1i(version_get_uniform(p_uniform, p_version, p_variant, p_specialization), p_value); + }} - } + _FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, uint16_t p_value, RID p_version, ShaderVariant p_variant{defvariant}, uint64_t p_specialization = {defspec}) {{ + TRY_GET_UNIFORM; + glUniform1ui(version_get_uniform(p_uniform, p_version, p_variant, p_specialization), p_value); + }} - """ - ) + _FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, int16_t p_value, RID p_version, ShaderVariant p_variant{defvariant}, uint64_t p_specialization = {defspec}) {{ + TRY_GET_UNIFORM; + glUniform1i(version_get_uniform(p_uniform, p_version, p_variant, p_specialization), p_value); + }} - fd.write( - """_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, const Transform2D& p_transform,RID p_version,ShaderVariant p_variant""" - + defvariant - + """,uint64_t p_specialization=""" - + str(defspec) - + """) { _FU + _FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, uint32_t p_value, RID p_version, ShaderVariant p_variant{defvariant}, uint64_t p_specialization = {defspec}) {{ + TRY_GET_UNIFORM; + glUniform1ui(version_get_uniform(p_uniform, p_version, p_variant, p_specialization), p_value); + }} - const Transform2D &tr = p_transform; + _FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, int32_t p_value, RID p_version, ShaderVariant p_variant{defvariant}, uint64_t p_specialization = {defspec}) {{ + TRY_GET_UNIFORM; + glUniform1i(version_get_uniform(p_uniform, p_version, p_variant, p_specialization), p_value); + }} - GLfloat matrix[16]={ /* build a 16x16 matrix */ - (GLfloat)tr.columns[0][0], - (GLfloat)tr.columns[0][1], - (GLfloat)0, - (GLfloat)0, - (GLfloat)tr.columns[1][0], - (GLfloat)tr.columns[1][1], - (GLfloat)0, - (GLfloat)0, - (GLfloat)0, - (GLfloat)0, - (GLfloat)1, - (GLfloat)0, - (GLfloat)tr.columns[2][0], - (GLfloat)tr.columns[2][1], - (GLfloat)0, - (GLfloat)1 - }; + _FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, const Color &p_color, RID p_version, ShaderVariant p_variant{defvariant}, uint64_t p_specialization = {defspec}) {{ + TRY_GET_UNIFORM; + GLfloat col[4] = {{ p_color.r, p_color.g, p_color.b, p_color.a }}; + glUniform4fv(version_get_uniform(p_uniform, p_version, p_variant, p_specialization), 1, col); + }} - glUniformMatrix4fv(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),1,false,matrix); + _FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, const Vector2 &p_vec2, RID p_version, ShaderVariant p_variant{defvariant}, uint64_t p_specialization = {defspec}) {{ + TRY_GET_UNIFORM; + GLfloat vec2[2] = {{ float(p_vec2.x), float(p_vec2.y) }}; + glUniform2fv(version_get_uniform(p_uniform, p_version, p_variant, p_specialization), 1, vec2); + }} - } + _FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, const Size2i &p_vec2, RID p_version, ShaderVariant p_variant{defvariant}, uint64_t p_specialization = {defspec}) {{ + TRY_GET_UNIFORM; + GLint vec2[2] = {{ GLint(p_vec2.x), GLint(p_vec2.y) }}; + glUniform2iv(version_get_uniform(p_uniform, p_version, p_variant, p_specialization), 1, vec2); + }} - """ - ) + _FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, const Vector3 &p_vec3, RID p_version, ShaderVariant p_variant{defvariant}, uint64_t p_specialization = {defspec}) {{ + TRY_GET_UNIFORM; + GLfloat vec3[3] = {{ float(p_vec3.x), float(p_vec3.y), float(p_vec3.z) }}; + glUniform3fv(version_get_uniform(p_uniform, p_version, p_variant, p_specialization), 1, vec3); + }} - fd.write( - """_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, const Projection& p_matrix, RID p_version, ShaderVariant p_variant""" - + defvariant - + """,uint64_t p_specialization=""" - + str(defspec) - + """) { _FU + _FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, const Vector4 &p_vec4, RID p_version, ShaderVariant p_variant{defvariant}, uint64_t p_specialization = {defspec}) {{ + TRY_GET_UNIFORM; + GLfloat vec4[4] = {{ float(p_vec4.x), float(p_vec4.y), float(p_vec4.z), float(p_vec4.w) }}; + glUniform4fv(version_get_uniform(p_uniform, p_version, p_variant, p_specialization), 1, vec4); + }} - GLfloat matrix[16]; + _FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, float p_a, float p_b, RID p_version, ShaderVariant p_variant{defvariant}, uint64_t p_specialization = {defspec}) {{ + TRY_GET_UNIFORM; + glUniform2f(version_get_uniform(p_uniform, p_version, p_variant, p_specialization), p_a, p_b); + }} - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - matrix[i * 4 + j] = p_matrix.columns[i][j]; - } - } + _FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, float p_a, float p_b, float p_c, RID p_version, ShaderVariant p_variant{defvariant}, uint64_t p_specialization = {defspec}) {{ + TRY_GET_UNIFORM; + glUniform3f(version_get_uniform(p_uniform, p_version, p_variant, p_specialization), p_a, p_b, p_c); + }} - glUniformMatrix4fv(version_get_uniform(p_uniform, p_version, p_variant, p_specialization), 1, false, matrix); - }""" - ) + _FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, float p_a, float p_b, float p_c, float p_d, RID p_version, ShaderVariant p_variant{defvariant}, uint64_t p_specialization = {defspec}) {{ + TRY_GET_UNIFORM; + glUniform4f(version_get_uniform(p_uniform, p_version, p_variant, p_specialization), p_a, p_b, p_c, p_d); + }} - fd.write("\n\n#undef _FU\n\n\n") + _FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, const Transform3D &p_transform, RID p_version, ShaderVariant p_variant{defvariant}, uint64_t p_specialization = {defspec}) {{ + TRY_GET_UNIFORM; + const Transform3D &tr = p_transform; - fd.write("protected:\n\n") + GLfloat matrix[16] = {{ /* build a 16x16 matrix */ + (GLfloat)tr.basis.rows[0][0], + (GLfloat)tr.basis.rows[1][0], + (GLfloat)tr.basis.rows[2][0], + (GLfloat)0, + (GLfloat)tr.basis.rows[0][1], + (GLfloat)tr.basis.rows[1][1], + (GLfloat)tr.basis.rows[2][1], + (GLfloat)0, + (GLfloat)tr.basis.rows[0][2], + (GLfloat)tr.basis.rows[1][2], + (GLfloat)tr.basis.rows[2][2], + (GLfloat)0, + (GLfloat)tr.origin.x, + (GLfloat)tr.origin.y, + (GLfloat)tr.origin.z, + (GLfloat)1 + }}; - fd.write("\tvirtual void _init() override {\n\n") + glUniformMatrix4fv(version_get_uniform(p_uniform, p_version, p_variant, p_specialization), 1, false, matrix); + }} + + _FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, const Transform2D &p_transform, RID p_version, ShaderVariant p_variant{defvariant}, uint64_t p_specialization = {defspec}) {{ + TRY_GET_UNIFORM; + const Transform2D &tr = p_transform; + + GLfloat matrix[16] = {{ /* build a 16x16 matrix */ + (GLfloat)tr.columns[0][0], + (GLfloat)tr.columns[0][1], + (GLfloat)0, + (GLfloat)0, + (GLfloat)tr.columns[1][0], + (GLfloat)tr.columns[1][1], + (GLfloat)0, + (GLfloat)0, + (GLfloat)0, + (GLfloat)0, + (GLfloat)1, + (GLfloat)0, + (GLfloat)tr.columns[2][0], + (GLfloat)tr.columns[2][1], + (GLfloat)0, + (GLfloat)1 + }}; + + glUniformMatrix4fv(version_get_uniform(p_uniform, p_version, p_variant, p_specialization), 1, false, matrix); + }} + + _FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, const Projection &p_matrix, RID p_version, ShaderVariant p_variant{defvariant}, uint64_t p_specialization = {defspec}) {{ + TRY_GET_UNIFORM; + GLfloat matrix[16]; + + for (int i = 0; i < 4; i++) {{ + for (int j = 0; j < 4; j++) {{ + matrix[i * 4 + j] = p_matrix.columns[i][j]; + }} + }} + + glUniformMatrix4fv(version_get_uniform(p_uniform, p_version, p_variant, p_specialization), 1, false, matrix); + }} + +#undef TRY_GET_UNIFORM + +""") + + file.write("""\ +protected: + virtual void _init() override { +""") if header_data.uniforms: - fd.write("\t\tstatic const char* _uniform_strings[]={\n") - if header_data.uniforms: - for x in header_data.uniforms: - fd.write('\t\t\t"' + x + '",\n') - fd.write("\t\t};\n\n") + uniforms = ",\n\t\t\t".join(f'"{uniform}"' for uniform in header_data.uniforms) + file.write(f"""\ + static const char *_uniform_strings[] = {{ + {uniforms} + }}; +""") else: - fd.write("\t\tstatic const char **_uniform_strings=nullptr;\n") + file.write("""\ + static const char **_uniform_strings = nullptr; +""") - variant_count = 1 - if len(header_data.variant_defines) > 0: - fd.write("\t\tstatic const char* _variant_defines[]={\n") - for x in header_data.variant_defines: - fd.write('\t\t\t"' + x + '",\n') - fd.write("\t\t};\n\n") + if header_data.variant_defines: variant_count = len(header_data.variant_defines) + variant_defines = ",\n\t\t\t".join(f'"{define}"' for define in header_data.variant_defines) + file.write(f"""\ + static const char *_variant_defines[] = {{ + {variant_defines}, + }}; +""") else: - fd.write('\t\tstatic const char **_variant_defines[]={" "};\n') + variant_count = 1 + file.write("""\ + static const char **_variant_defines[] = {" "}; +""") if header_data.texunits: - fd.write("\t\tstatic TexUnitPair _texunit_pairs[]={\n") - for x in header_data.texunits: - fd.write('\t\t\t{"' + x[0] + '",' + x[1] + "},\n") - fd.write("\t\t};\n\n") + texunits = ",\n\t\t\t".join(f'{{ "{name}", {texunit} }}' for name, texunit in header_data.texunits) + file.write(f"""\ + static TexUnitPair _texunit_pairs[] = {{ + {texunits}, + }}; +""") else: - fd.write("\t\tstatic TexUnitPair *_texunit_pairs=nullptr;\n") + file.write("""\ + static TexUnitPair *_texunit_pairs = nullptr; +""") if header_data.ubos: - fd.write("\t\tstatic UBOPair _ubo_pairs[]={\n") - for x in header_data.ubos: - fd.write('\t\t\t{"' + x[0] + '",' + x[1] + "},\n") - fd.write("\t\t};\n\n") + ubos = ",\n\t\t\t".join(f'{{ "{name}", {ubo} }}' for name, ubo in header_data.ubos) + file.write(f"""\ + static UBOPair _ubo_pairs[] = {{ + {ubos}, + }}; +""") else: - fd.write("\t\tstatic UBOPair *_ubo_pairs=nullptr;\n") - - specializations_found = [] + file.write("""\ + static UBOPair *_ubo_pairs = nullptr; +""") if header_data.specialization_names: - fd.write("\t\tstatic Specialization _spec_pairs[]={\n") - for i in range(len(header_data.specialization_names)): - defval = header_data.specialization_values[i].strip() - if defval.upper() == "TRUE" or defval == "1": - defval = "true" - else: - defval = "false" - - fd.write('\t\t\t{"' + header_data.specialization_names[i] + '",' + defval + "},\n") - specializations_found.append(header_data.specialization_names[i]) - fd.write("\t\t};\n\n") + specializations = ",\n\t\t\t".join( + f'{{ "{name}", {"true" if header_data.specialization_values[index].strip().upper() in ["TRUE", "1"] else "false"} }}' + for index, name in enumerate(header_data.specialization_names) + ) + file.write(f"""\ + static Specialization _spec_pairs[] = {{ + {specializations}, + }}; +""") else: - fd.write("\t\tstatic Specialization *_spec_pairs=nullptr;\n") - - feedback_count = 0 + file.write("""\ + static Specialization *_spec_pairs = nullptr; +""") if header_data.feedbacks: - fd.write("\t\tstatic const Feedback _feedbacks[]={\n") - for x in header_data.feedbacks: - name = x[0] - spec = x[1] - if spec in specializations_found: - fd.write('\t\t\t{"' + name + '",' + str(1 << specializations_found.index(spec)) + "},\n") - else: - fd.write('\t\t\t{"' + name + '",0},\n') - - feedback_count += 1 - - fd.write("\t\t};\n\n") + feedbacks = ",\n\t\t\t".join( + f'{{ "{name}", {0 if spec not in header_data.specialization_names else (1 << header_data.specialization_names.index(spec))} }}' + for name, spec in header_data.feedbacks + ) + file.write(f"""\ + static const Feedback _feedbacks[] = {{ + {feedbacks}, + }}; +""") else: - fd.write("\t\tstatic const Feedback* _feedbacks=nullptr;\n") + file.write("""\ + static const Feedback *_feedbacks = nullptr; +""") - fd.write("\t\tstatic const char _vertex_code[]={\n") - fd.write(to_raw_cstring(header_data.vertex_lines)) - fd.write("\n\t\t};\n\n") + file.write(f"""\ + static const char _vertex_code[] = {{ +{to_raw_cstring(header_data.vertex_lines)} + }}; - fd.write("\t\tstatic const char _fragment_code[]={\n") - fd.write(to_raw_cstring(header_data.fragment_lines)) - fd.write("\n\t\t};\n\n") + static const char _fragment_code[] = {{ +{to_raw_cstring(header_data.fragment_lines)} + }}; - fd.write( - '\t\t_setup(_vertex_code,_fragment_code,"' - + out_file_class - + '",' - + str(len(header_data.uniforms)) - + ",_uniform_strings," - + str(len(header_data.ubos)) - + ",_ubo_pairs," - + str(feedback_count) - + ",_feedbacks," - + str(len(header_data.texunits)) - + ",_texunit_pairs," - + str(len(header_data.specialization_names)) - + ",_spec_pairs," - + str(variant_count) - + ",_variant_defines);\n" - ) - - fd.write("\t}\n\n") - - fd.write("};\n") + _setup(_vertex_code, _fragment_code, "{out_file_class}", + {len(header_data.uniforms)}, _uniform_strings, {len(header_data.ubos)}, _ubo_pairs, + {len(header_data.feedbacks)}, _feedbacks, {len(header_data.texunits)}, _texunit_pairs, + {len(header_data.specialization_names)}, _spec_pairs, {variant_count}, _variant_defines); + }} +}}; +""") def build_gles3_headers(target, source, env): env.NoCache(target) - for x in source: - build_gles3_header(str(x), include="drivers/gles3/shader_gles3.h", class_suffix="GLES3") + for src in source: + build_gles3_header(f"{src}.gen.h", str(src)) diff --git a/glsl_builders.py b/glsl_builders.py index cac7f8636c6..dbe9d5adf1f 100644 --- a/glsl_builders.py +++ b/glsl_builders.py @@ -1,9 +1,8 @@ """Functions used to generate source files during build time""" import os.path -from typing import Optional -from methods import print_error, to_raw_cstring +from methods import generated_wrapper, print_error, to_raw_cstring class RDHeaderStruct: @@ -92,61 +91,49 @@ def include_file_in_rd_header(filename: str, header_data: RDHeaderStruct, depth: return header_data -def build_rd_header( - filename: str, optional_output_filename: Optional[str] = None, header_data: Optional[RDHeaderStruct] = None -) -> None: - header_data = header_data or RDHeaderStruct() - include_file_in_rd_header(filename, header_data, 0) - - if optional_output_filename is None: - out_file = filename + ".gen.h" - else: - out_file = optional_output_filename - - 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_class = out_file_base.replace(".glsl.gen.h", "").title().replace("_", "").replace(".", "") + "ShaderRD" - - if header_data.compute_lines: - body_parts = [ - "static const char _compute_code[] = {\n%s\n\t\t};" % to_raw_cstring(header_data.compute_lines), - f'setup(nullptr, nullptr, _compute_code, "{out_file_class}");', - ] - else: - body_parts = [ - "static const char _vertex_code[] = {\n%s\n\t\t};" % to_raw_cstring(header_data.vertex_lines), - "static const char _fragment_code[] = {\n%s\n\t\t};" % to_raw_cstring(header_data.fragment_lines), - f'setup(_vertex_code, _fragment_code, nullptr, "{out_file_class}");', - ] - - body_content = "\n\t\t".join(body_parts) - - # Intended curly brackets are doubled so f-string doesn't eat them up. - shader_template = f"""/* WARNING, THIS FILE WAS GENERATED, DO NOT EDIT */ -#pragma once +def build_rd_header(filename: str, shader: str) -> None: + include_file_in_rd_header(shader, header_data := RDHeaderStruct(), 0) + class_name = os.path.basename(shader).replace(".glsl", "").title().replace("_", "").replace(".", "") + "ShaderRD" + with generated_wrapper(filename) as file: + file.write(f"""\ #include "servers/rendering/renderer_rd/shader_rd.h" -class {out_file_class} : public ShaderRD {{ - +class {class_name} : public ShaderRD {{ public: + {class_name}() {{ +""") - {out_file_class}() {{ + if header_data.compute_lines: + file.write(f"""\ + static const char *_vertex_code = nullptr; + static const char *_fragment_code = nullptr; + static const char _compute_code[] = {{ +{to_raw_cstring(header_data.compute_lines)} + }}; +""") + else: + file.write(f"""\ + static const char _vertex_code[] = {{ +{to_raw_cstring(header_data.vertex_lines)} + }}; + static const char _fragment_code[] = {{ +{to_raw_cstring(header_data.fragment_lines)} + }}; + static const char *_compute_code = nullptr; +""") - {body_content} + file.write(f"""\ + setup(_vertex_code, _fragment_code, _compute_code, "{class_name}"); }} }}; -""" - - with open(out_file, "w", encoding="utf-8", newline="\n") as fd: - fd.write(shader_template) +""") def build_rd_headers(target, source, env): env.NoCache(target) - for x in source: - build_rd_header(filename=str(x)) + for src in source: + build_rd_header(f"{src}.gen.h", str(src)) class RAWHeaderStruct: @@ -171,34 +158,18 @@ def include_file_in_raw_header(filename: str, header_data: RAWHeaderStruct, dept line = fs.readline() -def build_raw_header( - filename: str, optional_output_filename: Optional[str] = None, header_data: Optional[RAWHeaderStruct] = None -): - header_data = header_data or RAWHeaderStruct() - include_file_in_raw_header(filename, header_data, 0) +def build_raw_header(filename: str, shader: str) -> None: + include_file_in_raw_header(shader, header_data := RAWHeaderStruct(), 0) - if optional_output_filename is None: - out_file = filename + ".gen.h" - else: - out_file = optional_output_filename - - 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 :] - - shader_template = f"""/* WARNING, THIS FILE WAS GENERATED, DO NOT EDIT */ -#pragma once - -static const char {out_file_base}[] = {{ + with generated_wrapper(filename) as file: + file.write(f"""\ +static const char {os.path.basename(shader).replace(".glsl", "_shader_glsl")}[] = {{ {to_raw_cstring(header_data.code)} }}; -""" - - with open(out_file, "w", encoding="utf-8", newline="\n") as f: - f.write(shader_template) +""") def build_raw_headers(target, source, env): env.NoCache(target) - for x in source: - build_raw_header(filename=str(x)) + for src in source: + build_raw_header(f"{src}.gen.h", str(src)) diff --git a/methods.py b/methods.py index 0bde3aa5457..dd7a46e05ed 100644 --- a/methods.py +++ b/methods.py @@ -1503,15 +1503,15 @@ def generated_wrapper( unassigned, the value is determined by file extension. """ - if guard is None: - guard = path.endswith((".h", ".hh", ".hpp", ".hxx", ".inc")) - with open(path, "wt", encoding="utf-8", newline="\n") as file: - file.write(generate_copyright_header(path)) - file.write("\n/* THIS FILE IS GENERATED. EDITS WILL BE LOST. */\n\n") + if not path.endswith(".out"): # For test output, we only care about the content. + file.write(generate_copyright_header(path)) + file.write("\n/* THIS FILE IS GENERATED. EDITS WILL BE LOST. */\n\n") - if guard: - file.write("#pragma once\n\n") + if guard is None: + guard = path.endswith((".h", ".hh", ".hpp", ".hxx", ".inc")) + if guard: + file.write("#pragma once\n\n") with StringIO(newline="\n") as str_io: yield str_io diff --git a/tests/python_build/fixtures/gles3/vertex_fragment.out b/tests/python_build/fixtures/gles3/vertex_fragment.out index c0e8d5c43da..886ed7de7be 100644 --- a/tests/python_build/fixtures/gles3/vertex_fragment.out +++ b/tests/python_build/fixtures/gles3/vertex_fragment.out @@ -1,41 +1,32 @@ -/* WARNING, THIS FILE WAS GENERATED, DO NOT EDIT */ -#pragma once - - #include "drivers/gles3/shader_gles3.h" - class VertexFragmentShaderGLES3 : public ShaderGLES3 { - public: - enum ShaderVariant { MODE_NINEPATCH, }; enum Specializations { - DISABLE_LIGHTING=1, + DISABLE_LIGHTING = 1, }; - _FORCE_INLINE_ bool version_bind_shader(RID p_version,ShaderVariant p_variant,uint64_t p_specialization=0) { return _version_bind_shader(p_version,p_variant,p_specialization); } + _FORCE_INLINE_ bool version_bind_shader(RID p_version, ShaderVariant p_variant, uint64_t p_specialization = 0) { + return _version_bind_shader(p_version, p_variant, p_specialization); + } protected: - virtual void _init() override { - - static const char **_uniform_strings=nullptr; - static const char* _variant_defines[]={ + static const char **_uniform_strings = nullptr; + static const char *_variant_defines[] = { "#define USE_NINEPATCH", }; - - static TexUnitPair *_texunit_pairs=nullptr; - static UBOPair *_ubo_pairs=nullptr; - static Specialization _spec_pairs[]={ - {"DISABLE_LIGHTING",false}, + static TexUnitPair *_texunit_pairs = nullptr; + static UBOPair *_ubo_pairs = nullptr; + static Specialization _spec_pairs[] = { + { "DISABLE_LIGHTING", false }, }; - - static const Feedback* _feedbacks=nullptr; - static const char _vertex_code[]={ + static const Feedback *_feedbacks = nullptr; + static const char _vertex_code[] = { R"( precision highp float; precision highp int; @@ -51,7 +42,7 @@ void main() { )" }; - static const char _fragment_code[]={ + static const char _fragment_code[] = { R"( precision highp float; precision highp int; @@ -65,7 +56,9 @@ void main() { )" }; - _setup(_vertex_code,_fragment_code,"VertexFragmentShaderGLES3",0,_uniform_strings,0,_ubo_pairs,0,_feedbacks,0,_texunit_pairs,1,_spec_pairs,1,_variant_defines); + _setup(_vertex_code, _fragment_code, "VertexFragmentShaderGLES3", + 0, _uniform_strings, 0, _ubo_pairs, + 0, _feedbacks, 0, _texunit_pairs, + 1, _spec_pairs, 1, _variant_defines); } - }; diff --git a/tests/python_build/fixtures/glsl/compute.out b/tests/python_build/fixtures/glsl/compute.out index 310a4241e15..9d8e112bc5f 100644 --- a/tests/python_build/fixtures/glsl/compute.out +++ b/tests/python_build/fixtures/glsl/compute.out @@ -1,6 +1,3 @@ -/* WARNING, THIS FILE WAS GENERATED, DO NOT EDIT */ -#pragma once - static const char compute_shader_glsl[] = { R"(#[compute] diff --git a/tests/python_build/fixtures/glsl/vertex_fragment.out b/tests/python_build/fixtures/glsl/vertex_fragment.out index 2ccc7daf4fe..9cd7f5562f2 100644 --- a/tests/python_build/fixtures/glsl/vertex_fragment.out +++ b/tests/python_build/fixtures/glsl/vertex_fragment.out @@ -1,6 +1,3 @@ -/* WARNING, THIS FILE WAS GENERATED, DO NOT EDIT */ -#pragma once - static const char vertex_fragment_shader_glsl[] = { R"(#[versions] diff --git a/tests/python_build/fixtures/rd_glsl/compute.out b/tests/python_build/fixtures/rd_glsl/compute.out index 7d4cdb43864..c57461f7c9a 100644 --- a/tests/python_build/fixtures/rd_glsl/compute.out +++ b/tests/python_build/fixtures/rd_glsl/compute.out @@ -1,14 +1,10 @@ -/* WARNING, THIS FILE WAS GENERATED, DO NOT EDIT */ -#pragma once - #include "servers/rendering/renderer_rd/shader_rd.h" class ComputeShaderRD : public ShaderRD { - public: - ComputeShaderRD() { - + static const char *_vertex_code = nullptr; + static const char *_fragment_code = nullptr; static const char _compute_code[] = { R"( #version 450 @@ -24,6 +20,6 @@ void main() { } )" }; - setup(nullptr, nullptr, _compute_code, "ComputeShaderRD"); + setup(_vertex_code, _fragment_code, _compute_code, "ComputeShaderRD"); } }; diff --git a/tests/python_build/fixtures/rd_glsl/vertex_fragment.out b/tests/python_build/fixtures/rd_glsl/vertex_fragment.out index 7e86dd73106..a053b3e3215 100644 --- a/tests/python_build/fixtures/rd_glsl/vertex_fragment.out +++ b/tests/python_build/fixtures/rd_glsl/vertex_fragment.out @@ -1,14 +1,8 @@ -/* WARNING, THIS FILE WAS GENERATED, DO NOT EDIT */ -#pragma once - #include "servers/rendering/renderer_rd/shader_rd.h" class VertexFragmentShaderRD : public ShaderRD { - public: - VertexFragmentShaderRD() { - static const char _vertex_code[] = { R"( #version 450 @@ -38,6 +32,7 @@ void main() { } )" }; - setup(_vertex_code, _fragment_code, nullptr, "VertexFragmentShaderRD"); + static const char *_compute_code = nullptr; + setup(_vertex_code, _fragment_code, _compute_code, "VertexFragmentShaderRD"); } };