diff options
Diffstat (limited to 'sc/sc.cpp')
-rw-r--r-- | sc/sc.cpp | 138 |
1 files changed, 116 insertions, 22 deletions
@@ -88,6 +88,12 @@ static const char* type_strings[] = { #undef x }; +static const char* rate_strings[] = { +#define x(n) #n, + sbinding_rate_xmacro() +#undef x +}; + int get_program_type(cfg_Object* desc) { int i; const char* s = find_string_default(desc, "type", 0); @@ -114,36 +120,75 @@ int type_from_string(const char* s) { return 0; } +SBinding_Rate rate_from_string(const char* s) { + int i; + for (i = 0; i < sbinding_rate_count; i++) { + if (!strcmp(rate_strings[i], s)) + return (SBinding_Rate)i; + } + print_err("Invalid binding rate %s\n", s); + pbreak(315); + return (SBinding_Rate)0; +} + struct Desc { struct Variable { int type; std::string name; std::string tname; }; + struct Binding { + SBinding_Rate rate; + std::string name; + std::vector<Variable> attrs; + }; int type; - std::vector<Variable> attrs; + std::vector<Binding> bindings; std::vector<Variable> trgts; + std::vector<Variable> interp; std::string entrypoints[shader_type_count]; void read_var(Variable& d, cfg_Object* desc) { - const char* stype = find_string_default(desc, "type", 0); - if (!stype) { - print_err("%s needs to have a type\n", desc->name); - pbreak(303); - } const char* sname = find_string_default(desc, "name", 0); if (!sname) { print_err("%s needs to have a name\n", desc->name); + pbreak(303); + } + const char* stype = find_string_default(desc, "type", 0); + if (!stype) { + print_err("%s needs to have a type\n", sname); pbreak(304); } d.type = type_from_string(stype); d.tname = std::string(stype); d.name = std::string(sname); - if (d.name.size() > 28) { - print_err("variable name %s is too long (max 28 chars).\n", sname); + if (d.name.size() > 27) { + print_err("variable name %s is too long (max 27 chars).\n", sname); pbreak(305); } } + Binding* read_binding(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(310); + } + const char* srate = find_string_default(desc, "rate", 0); + if (!srate) { + print_err("%s must specify a rate.\n", sname); + pbreak(311); + } + Binding& b = bindings.emplace_back(); + b.rate = rate_from_string(srate); + b.name = std::string(sname); + if (b.name.size() > 23) { + print_err("Binding name %s is too long (max 23 chars).\n", sname); + pbreak(312); + } + return &b; + } void build(cfg_Object* desc) { + int i; + Binding* cur_binding = 0; type = get_program_type(desc); if (type != sprogram_type_graphics) { assert(0); /* todo */ @@ -161,15 +206,30 @@ struct Desc { pbreak(302); } entrypoints[shader_type_fragment] = sf; + for (i = 0; i < (int)shader_type_count; i++) { + if (entrypoints[i].size() > 23) { + print_err("Entry point name is too long.\n"); + pbreak(3000); + } + } desc = desc->next; while (desc) { Variable v; - if (!strcmp(desc->name, "attribute")) { + if (!strcmp(desc->name, "binding")) { + cur_binding = read_binding(desc); + } else if (!strcmp(desc->name, "attribute")) { + if (!cur_binding) { + print_err("Can't specify a vertex attribute with no binding.\n"); + pbreak(303); + } read_var(v, desc); - attrs.push_back(v); + cur_binding->attrs.push_back(v); } else if (!strcmp(desc->name, "target")) { read_var(v, desc); trgts.push_back(v); + } else if (!strcmp(desc->name, "interpolator")) { + read_var(v, desc); + interp.push_back(v); } desc = desc->next; } @@ -177,13 +237,22 @@ struct Desc { std::string build_vs() const { std::stringstream ss; - size_t i, l = attrs.size(); - for (i = 0; i < l; i++) { - auto& attr = attrs[i]; - ss << "layout (location = 0) in "; - ss << attr.tname << " "; - ss << attr.name << ";\n"; + size_t i, li = bindings.size(); + size_t l = 0; + for (i = 0; i < li; i++) { + auto& binding = bindings[i]; + size_t j, lj = binding.attrs.size(); + for (j = 0; j < lj; j++, l++) { + auto& attr = binding.attrs[j]; + ss << "layout (location = " << l << ") in "; + ss << attr.tname << " "; + ss << attr.name << ";\n"; + } } + ss << "layout (location = 0) out _Interpolator {\n"; + for (const auto& i : interp) + ss << i.tname << " " << i.name << ";\n"; + ss << "} interpolator;\n"; return ss.str(); } @@ -196,6 +265,10 @@ struct Desc { ss << attr.tname << " "; ss << attr.name << ";\n"; } + ss << "layout (location = 0) in _Interpolator {\n"; + for (const auto& i : interp) + ss << i.tname << " " << i.name << ";\n"; + ss << "} interpolator;\n"; return ss.str(); } }; @@ -223,6 +296,13 @@ std::vector<uint32_t> compile_shader( Includer inc; std::string prepr; std::vector<uint32_t> spv; +#ifdef DEBUG + options.disableOptimizer = true; + options.generateDebugInfo = true; +#else + options.disableOptimizer = false; + options.stripDebugInfo = true; +#endif EShMessages msg = (EShMessages)(EShMsgSpvRules | EShMsgVulkanRules); shader.setStrings(srcs, sizeof srcs / sizeof *srcs); shader.setEnvClient(glslang::EShClientVulkan, client_version); @@ -323,14 +403,24 @@ void write_csh( int c; fwrite("CSH2", 4, 1, f); fwrite(&d.type, 4, 1, f); - c = d.attrs.size(); fwrite(&c, 4, 1, f); + c = d.bindings.size(); fwrite(&c, 4, 1, f); c = d.trgts.size(); fwrite(&c, 4, 1, f); - for (const auto& a : d.attrs) { - char buf[28]; + for (const auto& b : d.bindings) { + char buf[24]; + int count = b.attrs.size(); memset(buf, 0, sizeof buf); - strcpy(buf, a.name.c_str()); + strcpy(buf, b.name.c_str()); fwrite(buf, 1, sizeof buf, f); - fwrite(&a.type, 4, 1, f); + fwrite(&b.rate, 4, 1, f); + fwrite(&count, 4, 1, f); + for (const auto& a : b.attrs) { + char buf[28]; + memset(buf, 0, sizeof buf); + strcpy(buf, a.name.c_str()); + fwrite(buf, 1, sizeof buf, f); + fwrite(&a.type, 4, 1, f); + hsize += 32; + } hsize += 32; } for (const auto& t : d.trgts) { @@ -341,19 +431,23 @@ void write_csh( fwrite(&t.type, 4, 1, f); hsize += 32; } - hsize += shader_type_count * 8; + hsize += shader_type_count * 32; for (i = 0, coff = 0; i < shader_type_count; i++) { int o = 0; + char buf[24]; + memset(buf, 0, sizeof buf); if (d.entrypoints[i].empty()) { fwrite(&o, 4, 1, f); fwrite(&o, 4, 1, f); } else { int size = stages[i].size() * sizeof(uint32_t); + strcpy(buf, d.entrypoints[i].c_str()); o = hsize + coff; fwrite(&o, 4, 1, f); fwrite(&size, 4, 1, f); coff += size; } + fwrite(buf, 1, sizeof buf, f); } for (i = 0; i < shader_type_count; i++) if (!d.entrypoints[i].empty()) { |