summaryrefslogtreecommitdiff
path: root/sc/sc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sc/sc.cpp')
-rw-r--r--sc/sc.cpp138
1 files changed, 116 insertions, 22 deletions
diff --git a/sc/sc.cpp b/sc/sc.cpp
index 617d5ce..6218f7a 100644
--- a/sc/sc.cpp
+++ b/sc/sc.cpp
@@ -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()) {