diff options
Diffstat (limited to 'sc/sc.cpp')
-rw-r--r-- | sc/sc.cpp | 125 |
1 files changed, 118 insertions, 7 deletions
@@ -7,11 +7,15 @@ extern "C" { #include "cfgparse.h" #include "plat.h" #include "sh_enums.h" +#include "str.h" } #include <sstream> -#include <tuple> #include <stdint.h> +#include <string> +#include <tuple> +#include <unordered_map> +#include <vector> const char* glsl_version_s = "#version 440 core"; const int glsl_version = 440; @@ -82,6 +86,12 @@ static const char* program_type_strings[] = { #undef x }; +static const char* stage_strings[] = { +#define x(n) #n, + shader_type_xmacro() +#undef x +}; + static const char* type_strings[] = { #define x(n) #n, svariable_type_xmacro() @@ -120,6 +130,16 @@ int type_from_string(const char* s) { return 0; } +int stage_from_string(const char* s) { + int i; + for (i = 0; i < shader_type_count; i++) + if (!strcmp(stage_strings[i], s)) + return i; + print_err("Invalid stage type %s\n", s); + pbreak(800); + return 0; +} + SBinding_Rate rate_from_string(const char* s) { int i; for (i = 0; i < sbinding_rate_count; i++) { @@ -142,10 +162,21 @@ struct Desc { std::string name; std::vector<Variable> attrs; }; + struct Texture { + int stage; + int dimension; + }; + struct Descriptor { + std::string name; + int slot; + int stage; + }; int type; std::vector<Binding> bindings; std::vector<Variable> trgts; std::vector<Variable> interp; + std::unordered_map<std::string, Texture> textures; + std::vector<Descriptor> descriptors; std::string entrypoints[shader_type_count]; void read_var(Variable& d, cfg_Object* desc) { const char* sname = find_string_default(desc, "name", 0); @@ -186,6 +217,32 @@ struct Desc { } return &b; } + void read_texture(cfg_Object* desc) { + const char* sname = find_string_default(desc, "name", 0); + if (!sname) { + print_err("%s must have a name.\n", desc->name); + pbreak(801); + } + const char* sstage = find_string_default(desc, "stage", 0); + if (!sstage) { + print_err("%s must define a stage.\n", sname); + pbreak(802); + } + std::string n = std::string(sname); + if (n.size() > 23) { + print_err("Texture name %s is too long (max 23 chars).\n", sname); + + pbreak(803); + } + if (!textures.contains(n)) { + Texture& t = textures[n]; + t.stage = 0; + t.dimension = 0; + } + Texture& t = textures[n]; + t.stage |= 1 << stage_from_string(sstage); + t.dimension = find_int_default(desc, "dimension", 2); + } void build(cfg_Object* desc) { int i; Binding* cur_binding = 0; @@ -230,12 +287,54 @@ struct Desc { } else if (!strcmp(desc->name, "interpolator")) { read_var(v, desc); interp.push_back(v); + } else if (!strcmp(desc->name, "texture")) { + read_texture(desc); } desc = desc->next; } + build_descriptors(); + } + + Descriptor* find_desc(const char* name) { + int count = descriptors.size(); + int i, bucket = (int)(hash_string(name) % count); + for (i = 0; i < count; i++) { + Descriptor& d = descriptors[bucket]; + if ( + d.name.empty() || + !strcmp(name, d.name.c_str()) + ) return &d; + bucket = (bucket + 1) % count; + } + return 0; + }; + + void build_descriptors() { + int slot = 0; + descriptors.resize(textures.size()); + for (auto& i : textures) { + Descriptor* d = find_desc(i.first.c_str()); + d->name = i.first; + d->slot = slot; + d->stage = i.second.stage; + slot++; + } + } + + void add_textures(std::stringstream& ss, Shader_Type stage) { + for (const auto& it : textures) { + const auto& texture = it.second; + if (texture.stage & (1 << stage)) { + Descriptor* d = find_desc(it.first.c_str()); + assert(d != 0); + ss << "layout (binding = " << d->slot << ") "; + ss << "uniform sampler" << texture.dimension << "D "; + ss << it.first << ";\n"; + } + } } - std::string build_vs() const { + std::string build_vs() { std::stringstream ss; size_t i, li = bindings.size(); size_t l = 0; @@ -253,10 +352,11 @@ struct Desc { for (const auto& i : interp) ss << i.tname << " " << i.name << ";\n"; ss << "} interpolator;\n"; + add_textures(ss, shader_type_vertex); return ss.str(); } - std::string build_fs() const { + std::string build_fs() { std::stringstream ss; size_t i, l = trgts.size(); for (i = 0; i < l; i++) { @@ -269,12 +369,13 @@ struct Desc { for (const auto& i : interp) ss << i.tname << " " << i.name << ";\n"; ss << "} interpolator;\n"; + add_textures(ss, shader_type_fragment); return ss.str(); } }; std::vector<uint32_t> compile_shader( - const Desc& d, + Desc& d, const char* presrc, const char* src, const char* define, @@ -345,7 +446,7 @@ std::vector<uint32_t> compile_shader( } void configure( - const Desc& d, + Desc& d, int stage, const char*& dfn, EShLanguage& l, @@ -368,7 +469,7 @@ void configure( void compile_shaders( std::vector<uint32_t>* spv, const char* src, - const Desc& d + Desc& d ) { const char* define; EShLanguage lang; @@ -394,7 +495,7 @@ void write_csh( const Desc& d, const std::vector<uint32_t>* stages ) { - int hsize = 16, i, coff; + int hsize = 20, i, coff; FILE* f = fopen(fname, "wb"); if (!f) { print_err("Failed to open %s\n", fname); @@ -405,6 +506,7 @@ void write_csh( fwrite(&d.type, 4, 1, f); c = d.bindings.size(); fwrite(&c, 4, 1, f); c = d.trgts.size(); fwrite(&c, 4, 1, f); + c = d.descriptors.size(); fwrite(&c, 4, 1, f); for (const auto& b : d.bindings) { char buf[24]; int count = b.attrs.size(); @@ -431,6 +533,15 @@ void write_csh( fwrite(&t.type, 4, 1, f); hsize += 32; } + for (const auto& d : d.descriptors) { + char buf[24]; + memset(buf, 0, sizeof buf); + strcpy(buf, d.name.c_str()); + fwrite(buf, 1, sizeof buf, f); + fwrite(&d.slot, 4, 1, f); + fwrite(&d.stage, 4, 1, f); + hsize += 32; + } hsize += shader_type_count * 32; for (i = 0, coff = 0; i < shader_type_count; i++) { int o = 0; |