summaryrefslogtreecommitdiff
path: root/sc
diff options
context:
space:
mode:
authorquou <quou@disroot.org>2025-02-09 18:49:00 +1100
committerquou <quou@disroot.org>2025-02-09 18:51:30 +1100
commit8c644dd120c63244f4b576b45cd4ae96842736f8 (patch)
tree6074b73b48f391634f6b8fd431d2391de3a2dbfc /sc
parentdf87506693471686140282e79f5513dfc27a7854 (diff)
support for structured buffers
Diffstat (limited to 'sc')
-rw-r--r--sc/sc.cpp87
1 files changed, 86 insertions, 1 deletions
diff --git a/sc/sc.cpp b/sc/sc.cpp
index 143c408..9b1789f 100644
--- a/sc/sc.cpp
+++ b/sc/sc.cpp
@@ -206,6 +206,10 @@ struct Desc {
std::string strct;
std::unordered_map<std::string, int> offsets;
};
+ struct SBuffer {
+ int stage;
+ std::string strct;
+ };
int type;
std::vector<Binding> bindings;
std::vector<Variable> trgts;
@@ -213,6 +217,7 @@ struct Desc {
std::unordered_map<std::string, Struct> structs;
std::unordered_map<std::string, Texture> textures;
std::unordered_map<std::string, CBuffer> cbuffers;
+ std::unordered_map<std::string, SBuffer> sbuffers;
std::vector<Descriptor> descriptors;
std::string entrypoints[shader_type_count];
void read_var(Variable& d, cfg_Object* desc) {
@@ -297,6 +302,7 @@ struct Desc {
}
desc = desc->next;
Struct& s = structs[n];
+ s.name = n;
while (desc && !strcmp(desc->name, "variable")) {
Variable v;
read_var(v, desc);
@@ -344,6 +350,36 @@ struct Desc {
buf.size = offset;
}
+ void read_sbuffer(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(951);
+ }
+ const char* stype = find_string_default(desc, "type", 0);
+ if (!stype) {
+ print_err("%s must define a type.\n", desc->name);
+ }
+ std::string n = std::string(sname);
+ std::string t = std::string(stype);
+ if (n.size() > 23) {
+ print_err("SBuffer name too long (max 23 chars).\n");
+ pbreak(952);
+ }
+ if (!structs.contains(t)) {
+ print_err("No such struct %s\n", stype);
+ pbreak(953);
+ }
+ const char* sstage = find_string_default(desc, "stage", 0);
+ if (!sstage) {
+ print_err("%s must define a stage.\n", sname);
+ pbreak(954);
+ }
+ SBuffer& buf = sbuffers[n];
+ buf.strct = t;
+ buf.stage |= 1 << stage_from_string(sstage);
+ }
+
void build(cfg_Object* desc) {
int i;
Binding* cur_binding = 0;
@@ -392,6 +428,8 @@ struct Desc {
read_texture(desc);
} else if (!strcmp(desc->name, "cbuffer")) {
read_cbuffer(desc);
+ } else if (!strcmp(desc->name, "sbuffer")) {
+ read_sbuffer(desc);
} else if (!strcmp(desc->name, "struct")) {
desc = read_struct(desc);
continue;
@@ -417,7 +455,11 @@ struct Desc {
void build_descriptors() {
int slot = 0;
- descriptors.resize(textures.size() + cbuffers.size());
+ descriptors.resize(
+ textures.size() +
+ cbuffers.size() +
+ sbuffers.size()
+ );
for (auto& i : textures) {
Descriptor* d = find_desc(i.first.c_str());
d->name = i.first;
@@ -432,6 +474,13 @@ struct Desc {
d->stage = i.second.stage;
slot++;
}
+ for (auto& i : sbuffers) {
+ 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) {
@@ -468,6 +517,40 @@ struct Desc {
}
}
+ void add_sbuffer_structs(std::stringstream& ss, Shader_Type stage) {
+ std::unordered_map<std::string, bool> used;
+ for (const auto& i : sbuffers) {
+ const auto& sbuffer = i.second;
+ if (
+ sbuffer.stage & (1 << stage) &&
+ used.find(sbuffer.strct) == used.end()
+ ) {
+ const Struct& s = structs[sbuffer.strct];
+ ss << "struct " << s.name << "{\n";
+ for (auto& v : s.vars)
+ ss << "\t" << v.tname << " " << v.name << ";\n";
+ ss << "};\n";
+ used[sbuffer.strct] = true;
+ }
+ }
+ }
+
+ void add_sbuffers(std::stringstream& ss, Shader_Type stage) {
+ add_sbuffer_structs(ss, stage);
+ for (const auto& i : sbuffers) {
+ const auto& sbuffer = i.second;
+ if (sbuffer.stage & (1 << stage)) {
+ Descriptor* d = find_desc(i.first.c_str());
+ assert(d != 0);
+ ss << "layout (std140, binding = " << d->slot << ") ";
+ ss << "readonly buffer _SBuffer" << d->slot << " {\n";
+ ss << "\t" << sbuffer.strct << " ";
+ ss << i.first << "[];\n";
+ ss << "};\n";
+ }
+ }
+ }
+
std::string build_vs() {
std::stringstream ss;
size_t i, li = bindings.size();
@@ -490,6 +573,7 @@ struct Desc {
}
add_textures(ss, shader_type_vertex);
add_cbuffers(ss, shader_type_vertex);
+ add_sbuffers(ss, shader_type_vertex);
return ss.str();
}
@@ -510,6 +594,7 @@ struct Desc {
}
add_textures(ss, shader_type_fragment);
add_cbuffers(ss, shader_type_fragment);
+ add_sbuffers(ss, shader_type_fragment);
return ss.str();
}
};