diff --git a/src/shdc/generators/generator.cc b/src/shdc/generators/generator.cc index c9dbc9c7..46bef284 100644 --- a/src/shdc/generators/generator.cc +++ b/src/shdc/generators/generator.cc @@ -41,11 +41,11 @@ void Generator::gen_prolog(const GenInput& gen) { // create a default comment header void Generator::gen_header(const GenInput& gen, Slang::Enum slang) { - begin_comment_block(); - cbl("\n"); + l("{}\n", comment_block_start()); cbl("#version:{} (machine generated, don't edit!)\n\n", gen.args.gen_version); cbl("Generated by sokol-shdc (https://github.com/floooh/sokol-tools)\n\n"); - cbl("Cmdline: {}\n\n", gen.args.cmdline); + cbl("Cmdline:\n"); + cbl(" {}\n\n", gen.args.cmdline); // FIXME: instead of the first valid slang, GenInput should instead give us pre-processed and merged reflection info! cbl("Overview:\n"); @@ -59,8 +59,8 @@ void Generator::gen_header(const GenInput& gen, Slang::Enum slang) { gen_vertex_shader_info(gen, prog, *vs_src); gen_fragment_shader_info(gen, prog, *fs_src); } - cbl("\n"); - end_comment_block(); + l("{}\n", comment_block_end()); + l("\n"); } void Generator::gen_vertex_shader_info(const GenInput& gen, const Program& prog, const SpirvcrossSource& src) { @@ -69,7 +69,7 @@ void Generator::gen_vertex_shader_info(const GenInput& gen, const Program& prog, const Snippet& vs_snippet = gen.inp.snippets[src.snippet_index]; for (const VertexAttr& attr: src.refl.inputs) { if (attr.slot >= 0) { - cbl(" {} => {}\n", to_vertex_attr_name(mod_prefix(gen.inp), vs_snippet.name, attr), attr.slot); + cbl(" {} => {}\n", to_vertex_attr_name(mod_prefix(gen.inp), vs_snippet.name, attr), attr.slot); } } gen_bindings_info(gen, src.refl.bindings); @@ -88,14 +88,14 @@ void Generator::gen_bindings_info(const GenInput& gen, const Bindings& bindings) } for (const Image& img: bindings.images) { cbl(" Image '{}':\n", img.name); - cbl(" Image type: {}\n", to_type(img.type)); - cbl(" Sample type: {}\n", to_type(img.sample_type)); + cbl(" Image type: {}\n", to_image_type(img.type)); + cbl(" Sample type: {}\n", to_image_sample_type(img.sample_type)); cbl(" Multisampled: {}\n", img.multisampled); cbl(" Bind slot: {} => {}\n", to_image_bind_slot_name(mod_prefix(gen.inp), img), img.slot); } for (const Sampler& smp: bindings.samplers) { cbl(" Sampler '{}':\n", smp.name); - cbl(" Type: {}\n", to_type(smp.type)); + cbl(" Type: {}\n", to_sampler_type(smp.type)); cbl(" Bind slot: {} => {}\n", to_sampler_bind_slot_name(mod_prefix(gen.inp), smp), smp.slot); } for (const ImageSampler& img_smp: bindings.image_samplers) { @@ -181,4 +181,4 @@ ErrMsg Generator::check_errors(const GenInput& gen) { return ErrMsg(); } -} // namespace \ No newline at end of file +} // namespace diff --git a/src/shdc/generators/generator.h b/src/shdc/generators/generator.h index 5ce9f6b4..64ea7631 100644 --- a/src/shdc/generators/generator.h +++ b/src/shdc/generators/generator.h @@ -24,12 +24,10 @@ class Generator { // highlevel code generation methods virtual ErrMsg begin(const GenInput& gen); - virtual void gen_prolog(const GenInput& gen); virtual void gen_header(const GenInput& gen, Slang::Enum slang); virtual void gen_vertex_attrs(const GenInput& gen, Slang::Enum slang); virtual void gen_bind_slots(const GenInput& gen); virtual void gen_uniform_blocks(const GenInput& gen); - virtual void gen_epilog(const GenInput& gen); virtual ErrMsg end(const GenInput& gen); virtual void gen_vertex_shader_info(const GenInput& gen, const Program& prog, const SpirvcrossSource& vs_src); @@ -37,18 +35,21 @@ class Generator { virtual void gen_bindings_info(const GenInput& gen, const refl::Bindings& bindings); // override at least those methods in a concrete generator subclass - virtual void begin_comment_block() { assert(false && "implement me"); }; - virtual void end_comment_block() { assert(false && "implement me"); }; + virtual void gen_prolog(const GenInput& gen); + virtual void gen_epilog(const GenInput& gen); - virtual std::string comment_block_line(std::string l) { assert(false && "implement me"); return ""; }; + virtual std::string comment_block_start() { assert(false && "implement me"); return ""; }; + virtual std::string comment_block_line(const std::string& l) { assert(false && "implement me"); return ""; }; + virtual std::string comment_block_end() { assert(false && "implement me"); return ""; }; virtual std::string lang_name() { assert(false && "implement me"); return ""; }; virtual std::string get_shader_desc_help(const std::string& mod_prefix, const std::string& prog_name) { assert(false && "implement me"); return ""; }; - virtual std::string to_type(refl::Uniform::Type t) { assert(false && "implement me"); return ""; }; - virtual std::string to_type(refl::ImageType::Enum e) { assert(false && "implement me"); return ""; }; - virtual std::string to_type(refl::ImageSampleType::Enum e) { assert(false && "implement me"); return ""; }; - virtual std::string to_type(refl::SamplerType::Enum e) { assert(false && "implement me"); return ""; }; + virtual std::string to_uniform_type(refl::Uniform::Type t) { assert(false && "implement me"); return ""; }; + virtual std::string to_flattened_uniform_type(refl::Uniform::Type t) { assert(false && "implement me"); return ""; }; + virtual std::string to_image_type(refl::ImageType::Enum e) { assert(false && "implement me"); return ""; }; + virtual std::string to_image_sample_type(refl::ImageSampleType::Enum e) { assert(false && "implement me"); return ""; }; + virtual std::string to_sampler_type(refl::SamplerType::Enum e) { assert(false && "implement me"); return ""; }; virtual std::string to_backend(Slang::Enum e) { assert(false && "implement me"); return ""; }; virtual std::string to_struct_name(const std::string& mod_prefix, const std::string& name) { assert(false && "implement me"); return ""; }; @@ -58,12 +59,12 @@ class Generator { virtual std::string to_uniform_block_bind_slot_name(const std::string& mod_prefix, const refl::UniformBlock& ub) { assert(false && "implement me"); return ""; }; virtual std::string to_vertex_attr_definition(const std::string& mod_prefix, const std::string& snippet_name, const refl::VertexAttr& attr) { assert(false && "implement me"); return ""; }; - virtual std::string to_image_bind_slot_definition(const std::string& mod_prefix, const refl::Image img) { assert(false && "implement me"); return ""; }; - virtual std::string to_sampler_bind_slot_definition(const std::string& mod_prefix, const refl::Sampler smp) { assert(false && "implement me"); return ""; }; + virtual std::string to_image_bind_slot_definition(const std::string& mod_prefix, const refl::Image& img) { assert(false && "implement me"); return ""; }; + virtual std::string to_sampler_bind_slot_definition(const std::string& mod_prefix, const refl::Sampler& smp) { assert(false && "implement me"); return ""; }; virtual std::string to_uniform_block_bind_slot_definition(const std::string& mod_prefix, const refl::UniformBlock& ub) { assert(false && "implement me"); return ""; }; // utility methods static ErrMsg check_errors(const GenInput& gen); }; -} // namespace \ No newline at end of file +} // namespace diff --git a/src/shdc/generators/sokol.cc b/src/shdc/generators/sokol.cc index 4fdefeeb..2fb168d9 100644 --- a/src/shdc/generators/sokol.cc +++ b/src/shdc/generators/sokol.cc @@ -861,8 +861,150 @@ static ErrMsg _generate(const GenInput& gen) { } //------------------------------------------------------------------------------ -ErrMsg SokolGenerator::generate(const GenInput& gen) { - return _generate(gen); +//ErrMsg SokolGenerator::generate(const GenInput& gen) { +// return _generate(gen); +//} + +void SokolGenerator::gen_prolog(const GenInput& gen) { + l("#pragma once\n"); +} + +void SokolGenerator::gen_epilog(const GenInput& gen) { + // empty +} + +std::string SokolGenerator::comment_block_start() { + return "/*"; +} + +std::string SokolGenerator::comment_block_end() { + return "*/"; +} + +std::string SokolGenerator::comment_block_line(const std::string& str) { + return fmt::format(" {}", str); +} + +std::string SokolGenerator::lang_name() { + return "C"; +} + +std::string SokolGenerator::get_shader_desc_help(const std::string& mod_prefix, const std::string& prog_name) { + return fmt::format("{}{}_shader_desc(sg_query_backend());\n", mod_prefix, prog_name); +} + +std::string SokolGenerator::to_uniform_type(Uniform::Type t) { + switch (t) { + case Uniform::FLOAT: return "SG_UNIFORMTYPE_FLOAT"; + case Uniform::FLOAT2: return "SG_UNIFORMTYPE_FLOAT2"; + case Uniform::FLOAT3: return "SG_UNIFORMTYPE_FLOAT3"; + case Uniform::FLOAT4: return "SG_UNIFORMTYPE_FLOAT4"; + case Uniform::INT: return "SG_UNIFORMTYPE_INT"; + case Uniform::INT2: return "SG_UNIFORMTYPE_INT2"; + case Uniform::INT3: return "SG_UNIFORMTYPE_INT3"; + case Uniform::INT4: return "SG_UNIFORMTYPE_INT4"; + case Uniform::MAT4: return "SG_UNIFORMTYPE_MAT4"; + default: return "INVALID"; + } +} + +std::string SokolGenerator::to_flattened_uniform_type(Uniform::Type t) { + switch (t) { + case Uniform::FLOAT: + case Uniform::FLOAT2: + case Uniform::FLOAT3: + case Uniform::FLOAT4: + case Uniform::MAT4: + return "SG_UNIFORMTYPE_FLOAT4"; + case Uniform::INT: + case Uniform::INT2: + case Uniform::INT3: + case Uniform::INT4: + return "SG_UNIFORMTYPE_INT4"; + default: + return "INVALID"; + } +} + +std::string SokolGenerator::to_image_type(ImageType::Enum e) { + switch (e) { + case ImageType::_2D: return "SG_IMAGETYPE_2D"; + case ImageType::CUBE: return "SG_IMAGETYPE_CUBE"; + case ImageType::_3D: return "SG_IMAGETYPE_3D"; + case ImageType::ARRAY: return "SG_IMAGETYPE_ARRAY"; + default: return "INVALID"; + } +} + +std::string SokolGenerator::to_image_sample_type(refl::ImageSampleType::Enum e) { + switch (e) { + case ImageSampleType::FLOAT: return "SG_IMAGESAMPLETYPE_FLOAT"; + case ImageSampleType::DEPTH: return "SG_IMAGESAMPLETYPE_DEPTH"; + case ImageSampleType::SINT: return "SG_IMAGESAMPLETYPE_SINT"; + case ImageSampleType::UINT: return "SG_IMAGESAMPLETYPE_UINT"; + case ImageSampleType::UNFILTERABLE_FLOAT: return "SG_IMAGESAMPLETYPE_UNFILTERABLE_FLOAT"; + default: return "INVALID"; + } +} + +std::string SokolGenerator::to_sampler_type(refl::SamplerType::Enum e) { + switch (e) { + case SamplerType::FILTERING: return "SG_SAMPLERTYPE_FILTERING"; + case SamplerType::COMPARISON: return "SG_SAMPLERTYPE_COMPARISON"; + case SamplerType::NONFILTERING: return "SG_SAMPLERTYPE_NONFILTERING"; + default: return "INVALID"; + } +} + +std::string SokolGenerator::to_backend(Slang::Enum e) { + switch (e) { + case Slang::GLSL410: return "SG_BACKEND_GLCORE"; + case Slang::GLSL430: return "SG_BACKEND_GLCORE"; + case Slang::GLSL300ES: return "SG_BACKEND_GLES3"; + case Slang::HLSL4: return "SG_BACKEND_D3D11"; + case Slang::HLSL5: return "SG_BACKEND_D3D11"; + case Slang::METAL_MACOS: return "SG_BACKEND_METAL_MACOS"; + case Slang::METAL_IOS: return "SG_BACKEND_METAL_IOS"; + case Slang::METAL_SIM: return "SG_BACKEND_METAL_SIMULATOR"; + case Slang::WGSL: return "SG_BACKEND_WGPU"; + default: return ""; + } +} + +std::string SokolGenerator::to_struct_name(const std::string& mod_prefix, const std::string& name) { + return fmt::format("{}{}_t", mod_prefix, name); +} + +std::string SokolGenerator::to_vertex_attr_name(const std::string& mod_prefix, const std::string& snippet_name, const refl::VertexAttr& attr) { + return fmt::format("ATTR_{}{}_{}", mod_prefix, snippet_name, attr.name); +} + +std::string SokolGenerator::to_image_bind_slot_name(const std::string& mod_prefix, const refl::Image& img) { + return fmt::format("SLOT_{}{}", mod_prefix, img.name); +} + +std::string SokolGenerator::to_sampler_bind_slot_name(const std::string& mod_prefix, const refl::Sampler& smp) { + return fmt::format("SLOT_{}{}", mod_prefix, smp.name); +} + +std::string SokolGenerator::to_uniform_block_bind_slot_name(const std::string& mod_prefix, const refl::UniformBlock& ub) { + return fmt::format("SLOT_{}{}", mod_prefix, ub.struct_name); +} + +std::string SokolGenerator::to_vertex_attr_definition(const std::string& mod_prefix, const std::string& snippet_name, const refl::VertexAttr& attr) { + return fmt::format("#define {} ({})", to_vertex_attr_name(mod_prefix, snippet_name, attr), attr.slot); +} + +std::string SokolGenerator::to_image_bind_slot_definition(const std::string& mod_prefix, const refl::Image& img) { + return fmt::format("#define {} ({})", to_image_bind_slot_name(mod_prefix, img), img.slot); +} + +std::string SokolGenerator::to_sampler_bind_slot_definition(const std::string& mod_prefix, const refl::Sampler& smp) { + return fmt::format("#define {} ({})", to_sampler_bind_slot_name(mod_prefix, smp), smp.slot); +} + +std::string SokolGenerator::to_uniform_block_bind_slot_definition(const std::string& mod_prefix, const refl::UniformBlock& ub) { + return fmt::format("#define {} ({})", to_uniform_block_bind_slot_name(mod_prefix, ub), ub.slot); } } // namespace diff --git a/src/shdc/generators/sokol.h b/src/shdc/generators/sokol.h index 36aadbe2..34e7bc28 100644 --- a/src/shdc/generators/sokol.h +++ b/src/shdc/generators/sokol.h @@ -4,8 +4,29 @@ namespace shdc::gen { class SokolGenerator: public Generator { -public: - virtual ErrMsg generate(const GenInput& gen); +protected: + virtual void gen_prolog(const GenInput& gen); + virtual void gen_epilog(const GenInput& gen); + virtual std::string comment_block_start(); + virtual std::string comment_block_line(const std::string& l); + virtual std::string comment_block_end(); + virtual std::string lang_name(); + virtual std::string get_shader_desc_help(const std::string& mod_prefix, const std::string& prog_name); + virtual std::string to_uniform_type(refl::Uniform::Type t); + virtual std::string to_flattened_uniform_type(refl::Uniform::Type t); + virtual std::string to_image_type(refl::ImageType::Enum e); + virtual std::string to_image_sample_type(refl::ImageSampleType::Enum e); + virtual std::string to_sampler_type(refl::SamplerType::Enum e); + virtual std::string to_backend(Slang::Enum e); + virtual std::string to_struct_name(const std::string& mod_prefix, const std::string& name); + virtual std::string to_vertex_attr_name(const std::string& mod_prefix, const std::string& snippet_name, const refl::VertexAttr& attr); + virtual std::string to_image_bind_slot_name(const std::string& mod_prefix, const refl::Image& img); + virtual std::string to_sampler_bind_slot_name(const std::string& mod_prefix, const refl::Sampler& smp); + virtual std::string to_uniform_block_bind_slot_name(const std::string& mod_prefix, const refl::UniformBlock& ub); + virtual std::string to_vertex_attr_definition(const std::string& mod_prefix, const std::string& snippet_name, const refl::VertexAttr& attr); + virtual std::string to_image_bind_slot_definition(const std::string& mod_prefix, const refl::Image& img); + virtual std::string to_sampler_bind_slot_definition(const std::string& mod_prefix, const refl::Sampler& smp); + virtual std::string to_uniform_block_bind_slot_definition(const std::string& mod_prefix, const refl::UniformBlock& ub); }; } // namespace