From 8c644dd120c63244f4b576b45cd4ae96842736f8 Mon Sep 17 00:00:00 2001 From: quou Date: Sun, 9 Feb 2025 18:49:00 +1100 Subject: support for structured buffers --- sc/sc.cpp | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 86 insertions(+), 1 deletion(-) (limited to 'sc') 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 offsets; }; + struct SBuffer { + int stage; + std::string strct; + }; int type; std::vector bindings; std::vector trgts; @@ -213,6 +217,7 @@ struct Desc { std::unordered_map structs; std::unordered_map textures; std::unordered_map cbuffers; + std::unordered_map sbuffers; std::vector 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 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(); } }; -- cgit v1.2.3-54-g00ecf