summaryrefslogtreecommitdiff
path: root/sc/sc.cpp
diff options
context:
space:
mode:
authorquou <quou@disroot.org>2024-12-23 21:30:13 +1100
committerquou <quou@disroot.org>2024-12-23 21:30:13 +1100
commit078b97e48b5ad5fcf3f5a16bb081ea0efb1f931b (patch)
treed04bfb2d25952b214a4df303823ff7c5d2743681 /sc/sc.cpp
parentb293168cc158d65f1a5146f155921ff82119d1bc (diff)
send textures to shaders
Diffstat (limited to 'sc/sc.cpp')
-rw-r--r--sc/sc.cpp125
1 files changed, 118 insertions, 7 deletions
diff --git a/sc/sc.cpp b/sc/sc.cpp
index 6218f7a..f7acc1a 100644
--- a/sc/sc.cpp
+++ b/sc/sc.cpp
@@ -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;